Merge 13831:14550 from trunk
authorCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 10 Apr 2005 14:32:30 +0000 (14:32 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Sun, 10 Apr 2005 14:32:30 +0000 (14:32 +0000)
svn path=/branches/xmlbuildsystem/; revision=14575

1089 files changed:
reactos/Makefile
reactos/ReactOS.xml
reactos/apps/testsets/loadlib/makefile
reactos/apps/utils/Makefile
reactos/apps/utils/binpatch/Makefile [moved from reactos/apps/utils/consw/makefile with 56% similarity]
reactos/apps/utils/binpatch/patch.c [new file with mode: 0644]
reactos/apps/utils/consw/consw.c [deleted file]
reactos/apps/utils/consw/runprg.bat [deleted file]
reactos/apps/utils/net/ftp/makefile
reactos/apps/utils/net/ping/makefile
reactos/apps/utils/net/ping/ping.xml
reactos/apps/utils/net/route/makefile
reactos/apps/utils/net/route/route.xml
reactos/apps/utils/partinfo/makefile
reactos/apps/utils/partinfo/partinfo.c
reactos/apps/utils/pnpdump/makefile
reactos/apps/utils/pnpdump/pnpdump.c
reactos/apps/utils/ps/makefile
reactos/apps/utils/sc/makefile
reactos/apps/utils/winetest/config.h [new file with mode: 0644]
reactos/apps/utils/winetest/dist.rc [moved from reactos/include/wine/ver.h with 72% similarity]
reactos/apps/utils/winetest/gui.c [new file with mode: 0644]
reactos/apps/utils/winetest/main.c [new file with mode: 0644]
reactos/apps/utils/winetest/makefile [new file with mode: 0644]
reactos/apps/utils/winetest/port.h [new file with mode: 0644]
reactos/apps/utils/winetest/resource.h [new file with mode: 0644]
reactos/apps/utils/winetest/send.c [new file with mode: 0644]
reactos/apps/utils/winetest/tests.rc [new file with mode: 0644]
reactos/apps/utils/winetest/util.c [new file with mode: 0644]
reactos/apps/utils/winetest/wine.ico [new file with mode: 0644]
reactos/apps/utils/winetest/winetest.h [new file with mode: 0644]
reactos/apps/utils/winetest/winetest.rc [new file with mode: 0644]
reactos/baseaddress.xml
reactos/boot/freeldr/Makefile
reactos/boot/freeldr/bootsect/Makefile
reactos/boot/freeldr/bootsect/Makefile.i386 [new file with mode: 0644]
reactos/boot/freeldr/bootsect/Makefile.powerpc [new file with mode: 0644]
reactos/boot/freeldr/bootsect/ofwboot.s [new file with mode: 0644]
reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c
reactos/boot/freeldr/freeldr/arch/powerpc/boot.s [new file with mode: 0644]
reactos/boot/freeldr/freeldr/arch/powerpc/mach.c [new file with mode: 0644]
reactos/boot/freeldr/freeldr/fs/ntfs.c
reactos/boot/freeldr/freeldr/include/multiboot.h
reactos/boot/freeldr/freeldr/math/libgcc2.c
reactos/boot/freeldr/freeldr/math/powerpc.h [new file with mode: 0644]
reactos/boot/freeldr/freeldr/mm/mem.h
reactos/boot/freeldr/freeldr/multiboot.c
reactos/boot/freeldr/freeldr/reactos/reactos.c
reactos/boot/freeldr/freeldr/rtl/print.c
reactos/boot/freeldr/freeldr/rtl/stdlib.c
reactos/bootdata/hivecls.inf
reactos/bootdata/hivesys.inf
reactos/bootdata/icon.ico
reactos/bootdata/packages/reactos.dff
reactos/doc/README.WINE
reactos/doc/irp cancel boilerplate.c [new file with mode: 0644]
reactos/drivers/bus/Makefile
reactos/drivers/bus/acpi/ospm/fdo.c
reactos/drivers/bus/acpi/ospm/include/acpisys.h
reactos/drivers/bus/acpi/ospm/osl.c
reactos/drivers/bus/acpi/ospm/pdo.c
reactos/drivers/bus/acpi/tables/tbget.c
reactos/drivers/bus/acpi/utils/cmglobal.c
reactos/drivers/bus/serenum/detect.c [new file with mode: 0644]
reactos/drivers/bus/serenum/fdo.c [new file with mode: 0644]
reactos/drivers/bus/serenum/makefile [new file with mode: 0644]
reactos/drivers/bus/serenum/misc.c [new file with mode: 0644]
reactos/drivers/bus/serenum/pdo.c [new file with mode: 0644]
reactos/drivers/bus/serenum/serenum.c [new file with mode: 0644]
reactos/drivers/bus/serenum/serenum.h [new file with mode: 0644]
reactos/drivers/bus/serenum/serenum.rc [new file with mode: 0644]
reactos/drivers/dd/serial/circularbuffer.c [new file with mode: 0644]
reactos/drivers/dd/serial/cleanup.c [new file with mode: 0644]
reactos/drivers/dd/serial/close.c [new file with mode: 0644]
reactos/drivers/dd/serial/create.c [new file with mode: 0644]
reactos/drivers/dd/serial/devctrl.c [new file with mode: 0644]
reactos/drivers/dd/serial/info.c [new file with mode: 0644]
reactos/drivers/dd/serial/legacy.c [new file with mode: 0644]
reactos/drivers/dd/serial/makefile
reactos/drivers/dd/serial/misc.c [new file with mode: 0644]
reactos/drivers/dd/serial/pnp.c [new file with mode: 0644]
reactos/drivers/dd/serial/power.c [new file with mode: 0644]
reactos/drivers/dd/serial/rw.c [new file with mode: 0644]
reactos/drivers/dd/serial/serial.c
reactos/drivers/dd/serial/serial.h [new file with mode: 0644]
reactos/drivers/dd/serial/serial.xml
reactos/drivers/fs/np/create.c
reactos/drivers/fs/np/fsctrl.c
reactos/drivers/fs/np/npfs.c
reactos/drivers/fs/np/npfs.h
reactos/drivers/fs/np/rw.c
reactos/drivers/fs/np/volume.c
reactos/drivers/fs/vfat/cleanup.c
reactos/drivers/fs/vfat/close.c
reactos/drivers/fs/vfat/fcb.c
reactos/drivers/fs/vfat/finfo.c
reactos/drivers/fs/vfat/fsctl.c
reactos/drivers/fs/vfat/vfat.h
reactos/drivers/input/keyboard/keyboard.c
reactos/drivers/lib/ip/network/interface.c
reactos/drivers/lib/ip/network/ip.c
reactos/drivers/lib/ip/network/ports.c
reactos/drivers/lib/ip/transport/tcp/accept.c
reactos/drivers/lib/ip/transport/tcp/tcp.c
reactos/drivers/net/afd/afd/listen.c
reactos/drivers/net/afd/afd/lock.c
reactos/drivers/net/afd/afd/main.c
reactos/drivers/net/afd/afd/read.c
reactos/drivers/net/afd/include/afd.h
reactos/drivers/net/ndis/ndis/protocol.c
reactos/drivers/net/tcpip/datalink/lan.c
reactos/drivers/net/tcpip/include/dispatch.h
reactos/drivers/net/tcpip/include/interface.h
reactos/drivers/net/tcpip/include/ip.h
reactos/drivers/net/tcpip/include/lan.h
reactos/drivers/net/tcpip/include/precomp.h
reactos/drivers/net/tcpip/include/tcpip.h
reactos/drivers/net/tcpip/include/ticonsts.h
reactos/drivers/net/tcpip/tcpip/dispatch.c
reactos/drivers/net/tcpip/tcpip/iinfo.c
reactos/drivers/net/tcpip/tcpip/main.c
reactos/drivers/storage/floppy/floppy.c
reactos/drivers/storage/floppy/readwrite.c
reactos/drivers/video/displays/framebuf/screen.c
reactos/drivers/video/displays/vga/main/enable.c
reactos/drivers/video/videoprt/dispatch.c
reactos/drivers/video/videoprt/interrupt.c
reactos/drivers/video/videoprt/resource.c
reactos/drivers/video/videoprt/videoprt.h
reactos/hal/hal/hal.c
reactos/hal/hal/hal.def
reactos/hal/halx86/generic/dma.c
reactos/hal/halx86/generic/spinlock.c
reactos/hal/halx86/generic/timer.c
reactos/hal/halx86/include/apic.h
reactos/hal/halx86/include/hal.h
reactos/hal/halx86/include/ioapic.h [new file with mode: 0644]
reactos/hal/halx86/include/mps.h
reactos/hal/halx86/mp/Makefile
reactos/hal/halx86/mp/apic.c
reactos/hal/halx86/mp/halinit_mp.c
reactos/hal/halx86/mp/halmp.xml
reactos/hal/halx86/mp/ioapic.c [new file with mode: 0644]
reactos/hal/halx86/mp/mpconfig.c [new file with mode: 0644]
reactos/hal/halx86/mp/mpsirql.c
reactos/hal/halx86/mp/processor_mp.c
reactos/include/WinDNS.h [deleted file]
reactos/include/WinError.h [deleted file]
reactos/include/ascii.h [deleted file]
reactos/include/coff.h [deleted file]
reactos/include/d3d.h
reactos/include/d3d8.h [new file with mode: 0644]
reactos/include/d3d8caps.h [new file with mode: 0644]
reactos/include/d3d8types.h [new file with mode: 0644]
reactos/include/d3d9.h [new file with mode: 0644]
reactos/include/d3d9caps.h [new file with mode: 0644]
reactos/include/d3d9types.h [new file with mode: 0644]
reactos/include/d3drm.h [new file with mode: 0644]
reactos/include/d3dtypes.h
reactos/include/d3dvec.inl [new file with mode: 0644]
reactos/include/d3dx8core.h [new file with mode: 0644]
reactos/include/ddk/cmtypes.h
reactos/include/ddk/defines.h
reactos/include/ddk/extypes.h
reactos/include/ddk/iotypes.h
reactos/include/ddk/kefuncs.h
reactos/include/ddk/ketypes.h
reactos/include/ddk/ldrfuncs.h
reactos/include/ddk/mmfuncs.h
reactos/include/ddk/psfuncs.h
reactos/include/ddk/pstypes.h
reactos/include/ddk/setypes.h
reactos/include/ddraw.h
reactos/include/ddrawi.h
reactos/include/directory.xml [new file with mode: 0644]
reactos/include/errors.h [deleted file]
reactos/include/funcs.h
reactos/include/idl/idl.xml [new file with mode: 0644]
reactos/include/idl/pnp.idl [new file with mode: 0644]
reactos/include/messages.h [deleted file]
reactos/include/ntdll/rtl.h
reactos/include/ntos/obtypes.h
reactos/include/ntos/rtl.h
reactos/include/ntos/security.h
reactos/include/ntos/types.h
reactos/include/ntos/zwtypes.h
reactos/include/pe.h
reactos/include/pseh.h
reactos/include/pseh/excpt.h
reactos/include/pseh/framebased.h
reactos/include/pseh/framebased/internal.h
reactos/include/pseh/native.h [new file with mode: 0644]
reactos/include/pseh/setjmp.h
reactos/include/sm/helper.h
reactos/include/sockets.h [deleted file]
reactos/include/tcpioctl.h
reactos/include/win32k/bitmaps.h
reactos/include/win32k/brush.h
reactos/include/win32k/dc.h
reactos/include/win32k/ntuser.h
reactos/include/win32k/text.h
reactos/include/windows.h
reactos/include/wine/cfgmgr32.h
reactos/include/wine/commctrl.h
reactos/include/wine/cpl.h [deleted file]
reactos/include/wine/msidefs.h
reactos/include/wine/richole.h [new file with mode: 0644]
reactos/include/wine/setupapi.h
reactos/lib/aclui/aclui.rc
reactos/lib/aclui/aclui_De.rc [new file with mode: 0644]
reactos/lib/aclui/aclui_Sv.rc [new file with mode: 0644]
reactos/lib/adns/adns.xml
reactos/lib/advapi32/advapi32.def
reactos/lib/advapi32/crypt/crypt.c
reactos/lib/advapi32/misc/sysfunc.c
reactos/lib/advapi32/reg/reg.c
reactos/lib/advapi32/sec/lsa.c
reactos/lib/advapi32/winetests/crypt.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/crypt_lmhash.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/crypt_md4.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/crypt_md5.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/crypt_sha.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/makefile [new file with mode: 0644]
reactos/lib/advapi32/winetests/registry.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/security.c [new file with mode: 0644]
reactos/lib/advapi32/winetests/testlist.c [new file with mode: 0644]
reactos/lib/comctl32/comctl32.spec
reactos/lib/comctl32/comctl_Es.rc
reactos/lib/comctl32/comctl_Sv.rc [new file with mode: 0644]
reactos/lib/comctl32/draglist.c
reactos/lib/comctl32/header.c
reactos/lib/comctl32/imagelist.c
reactos/lib/comctl32/listview.c
reactos/lib/comctl32/rebar.c
reactos/lib/comctl32/rsrc.rc
reactos/lib/comctl32/status.c
reactos/lib/comctl32/string.c
reactos/lib/comctl32/syslink.c
reactos/lib/comctl32/tab.c
reactos/lib/comctl32/treeview.c
reactos/lib/comctl32/winetests/dpa.c [new file with mode: 0644]
reactos/lib/comctl32/winetests/imagelist.c [new file with mode: 0644]
reactos/lib/comctl32/winetests/makefile [new file with mode: 0644]
reactos/lib/comctl32/winetests/mru.c [new file with mode: 0644]
reactos/lib/comctl32/winetests/subclass.c [new file with mode: 0644]
reactos/lib/comctl32/winetests/tab.c [new file with mode: 0644]
reactos/lib/comctl32/winetests/testlist.c [new file with mode: 0644]
reactos/lib/comdlg32/cdlg32.c
reactos/lib/comdlg32/cdlg_En.rc
reactos/lib/comdlg32/cdlg_Es.rc
reactos/lib/comdlg32/cdlg_Pt.rc
reactos/lib/comdlg32/cdlg_xx.rc
reactos/lib/comdlg32/colordlg.c
reactos/lib/comdlg32/colordlg16.c
reactos/lib/comdlg32/filedlg.c
reactos/lib/comdlg32/finddlg.c
reactos/lib/comdlg32/fontdlg.c
reactos/lib/comdlg32/fontdlg16.c
reactos/lib/commctrl/Makefile [deleted file]
reactos/lib/commctrl/commctrl.def [deleted file]
reactos/lib/commctrl/commctrl.rc [deleted file]
reactos/lib/commctrl/commctrl_main.c [deleted file]
reactos/lib/coredll/Makefile [deleted file]
reactos/lib/coredll/coredll.def [deleted file]
reactos/lib/coredll/coredll.rc [deleted file]
reactos/lib/cpl/appwiz/De.rc [new file with mode: 0644]
reactos/lib/cpl/appwiz/Dk.rc [new file with mode: 0644]
reactos/lib/cpl/appwiz/En.rc [new file with mode: 0644]
reactos/lib/cpl/appwiz/Ru.rc [new file with mode: 0644]
reactos/lib/cpl/appwiz/appwiz.rc
reactos/lib/cpl/appwiz/resources/applet.ico
reactos/lib/cpl/control/De.rc [new file with mode: 0644]
reactos/lib/cpl/control/Dk.rc [new file with mode: 0644]
reactos/lib/cpl/control/En.rc [new file with mode: 0644]
reactos/lib/cpl/control/Ru.rc [new file with mode: 0644]
reactos/lib/cpl/control/control.rc
reactos/lib/cpl/desk/de.rc
reactos/lib/cpl/desk/en.rc
reactos/lib/cpl/desk/resource.h
reactos/lib/cpl/desk/settings.c
reactos/lib/cpl/intl/de.rc [new file with mode: 0644]
reactos/lib/cpl/intl/en.rc [new file with mode: 0644]
reactos/lib/cpl/intl/intl.rc
reactos/lib/cpl/intl/locale.c
reactos/lib/cpl/intl/resource.h
reactos/lib/cpl/intl/resources/flags.ico [new file with mode: 0644]
reactos/lib/cpl/liccpa/Makefile [new file with mode: 0644]
reactos/lib/cpl/liccpa/liccpa.c [new file with mode: 0644]
reactos/lib/cpl/liccpa/liccpa.def [new file with mode: 0644]
reactos/lib/cpl/liccpa/liccpa.h [new file with mode: 0644]
reactos/lib/cpl/liccpa/liccpa.rc [new file with mode: 0644]
reactos/lib/cpl/liccpa/resource.h [new file with mode: 0644]
reactos/lib/cpl/liccpa/resources/cpl_icon1.ico [new file with mode: 0644]
reactos/lib/cpl/ncpa/de.rc [new file with mode: 0644]
reactos/lib/cpl/ncpa/dk.rc [new file with mode: 0644]
reactos/lib/cpl/ncpa/en.rc [new file with mode: 0644]
reactos/lib/cpl/ncpa/ncpa.rc
reactos/lib/cpl/sysdm/de.rc
reactos/lib/cpl/sysdm/dk.rc [new file with mode: 0644]
reactos/lib/cpl/sysdm/en.rc
reactos/lib/cpl/sysdm/fr.rc [new file with mode: 0644]
reactos/lib/cpl/sysdm/sysdm.rc
reactos/lib/cpl/sysdm/sysdm.xml
reactos/lib/cpl/timedate/Dk.rc [new file with mode: 0644]
reactos/lib/cpl/timedate/Ru.rc [new file with mode: 0644]
reactos/lib/cpl/timedate/Sv.rc [new file with mode: 0644]
reactos/lib/cpl/timedate/timedate.rc
reactos/lib/crt/except/matherr.c
reactos/lib/crt/float/fpecode.c
reactos/lib/crt/include/internal/file.h
reactos/lib/crt/include/internal/tls.h
reactos/lib/crt/io/isatty.c
reactos/lib/crt/io/open.c
reactos/lib/crt/stdio/fopen.c
reactos/lib/crt/stdio/freopen.c
reactos/lib/crt/stdio/fsopen.c
reactos/lib/crt/stdio/vfprintf.c
reactos/lib/crt/stdio/vfwprint.c
reactos/lib/crt/stdlib/errno.c
reactos/lib/crt/stdlib/qsort.c
reactos/lib/crt/stdlib/rand.c
reactos/lib/crt/string/lasttok.c
reactos/lib/crt/string/strtok.c
reactos/lib/crt/wine/scanf.h
reactos/lib/dbghelp/msc.c
reactos/lib/ddraw/Makefile
reactos/lib/ddraw/ddraw.c
reactos/lib/ddraw/ddraw_hal.c [new file with mode: 0644]
reactos/lib/ddraw/ddraw_private.h [new file with mode: 0644]
reactos/lib/ddraw/ddraw_user.c [new file with mode: 0644]
reactos/lib/ddraw/regsvr.c [new file with mode: 0644]
reactos/lib/ddraw/rosddraw.h [new file with mode: 0644]
reactos/lib/dinput/joystick_linuxinput.c
reactos/lib/dinput/keyboard.c
reactos/lib/dinput/mouse.c
reactos/lib/directory.xml
reactos/lib/dnsapi/dnsapi/adns.c
reactos/lib/dnsapi/dnsapi/context.c
reactos/lib/dnsapi/dnsapi/free.c
reactos/lib/dnsapi/dnsapi/names.c
reactos/lib/dnsapi/dnsapi/query.c
reactos/lib/dnsapi/dnsapi/stubs.c
reactos/lib/epsapi/makefile
reactos/lib/fslib/vfatlib/vfatlib.c
reactos/lib/fslib/vfatxlib/vfatxlib.c
reactos/lib/gdi32/gdi32.def
reactos/lib/gdi32/gdi32.xml
reactos/lib/gdi32/include/precomp.h
reactos/lib/gdi32/makefile
reactos/lib/gdi32/misc/stubs.c
reactos/lib/gdi32/objects/bitblt.c [deleted file]
reactos/lib/gdi32/objects/bitmap.c [new file with mode: 0644]
reactos/lib/gdi32/objects/brush.c [new file with mode: 0644]
reactos/lib/gdi32/objects/dc.c
reactos/lib/gdi32/objects/utils.c [new file with mode: 0644]
reactos/lib/iphlpapi/ifenum_reactos.c
reactos/lib/iphlpapi/iphlpapi_main.c
reactos/lib/iphlpapi/iphlpapi_private.h
reactos/lib/kernel32/debug/output.c
reactos/lib/kernel32/except/except.c
reactos/lib/kernel32/file/bintype.c
reactos/lib/kernel32/file/cnotify.c
reactos/lib/kernel32/file/copy.c
reactos/lib/kernel32/file/create.c
reactos/lib/kernel32/file/curdir.c
reactos/lib/kernel32/file/delete.c
reactos/lib/kernel32/file/dir.c
reactos/lib/kernel32/file/file.c
reactos/lib/kernel32/file/hardlink.c
reactos/lib/kernel32/file/lock.c
reactos/lib/kernel32/file/move.c
reactos/lib/kernel32/file/npipe.c
reactos/lib/kernel32/file/volume.c
reactos/lib/kernel32/include/kernel32.h
reactos/lib/kernel32/kernel32.xml
reactos/lib/kernel32/makefile
reactos/lib/kernel32/misc/comm.c
reactos/lib/kernel32/misc/dllmain.c
reactos/lib/kernel32/misc/env.c
reactos/lib/kernel32/misc/ldr.c
reactos/lib/kernel32/misc/profile.c
reactos/lib/kernel32/misc/res.c
reactos/lib/kernel32/misc/stubs.c
reactos/lib/kernel32/misc/time.c
reactos/lib/kernel32/misc/version.c [new file with mode: 0644]
reactos/lib/kernel32/process/create.c
reactos/lib/kernel32/thread/thread.c
reactos/lib/mpr/mpr_De.rc
reactos/lib/mpr/mpr_En.rc
reactos/lib/mpr/mpr_Es.rc
reactos/lib/mpr/mpr_Fr.rc
reactos/lib/mpr/mpr_Pt.rc
reactos/lib/msafd/include/msafd.h
reactos/lib/msafd/misc/dllmain.c
reactos/lib/msgina/msgina.c
reactos/lib/msgina/stubs.c
reactos/lib/msi/Makefile.in
reactos/lib/msi/action.c
reactos/lib/msi/action.h
reactos/lib/msi/appsearch.c
reactos/lib/msi/custom.c
reactos/lib/msi/delete.c [new file with mode: 0644]
reactos/lib/msi/dialog.c
reactos/lib/msi/format.c
reactos/lib/msi/msi.c
reactos/lib/msi/msi.rc
reactos/lib/msi/msi.spec
reactos/lib/msi/msi_De.rc [moved from reactos/include/wine/heap.h with 53% similarity]
reactos/lib/msi/msi_Es.rc [new file with mode: 0644]
reactos/lib/msi/msi_Fr.rc [new file with mode: 0644]
reactos/lib/msi/msi_Pt.rc [new file with mode: 0644]
reactos/lib/msi/msipriv.h
reactos/lib/msi/msiquery.c
reactos/lib/msi/package.c
reactos/lib/msi/preview.c
reactos/lib/msi/query.h
reactos/lib/msi/record.c
reactos/lib/msi/registry.c
reactos/lib/msi/sql.tab.c
reactos/lib/msi/sql.y
reactos/lib/msi/suminfo.c
reactos/lib/msi/table.c
reactos/lib/msi/where.c
reactos/lib/ntdll/def/ntdll.def
reactos/lib/ntdll/ldr/res.c
reactos/lib/ntdll/ldr/startup.c
reactos/lib/ntdll/ldr/utils.c
reactos/lib/ntdll/makefile
reactos/lib/ntdll/ntdll.xml
reactos/lib/ntdll/rtl/critical.c
reactos/lib/ntdll/rtl/exception.c
reactos/lib/ntdll/rtl/libsupp.c
reactos/lib/ntdll/rtl/misc.c
reactos/lib/ntdll/rtl/path.c
reactos/lib/ntdll/rtl/process.c
reactos/lib/ntdll/rtl/teb.c
reactos/lib/ntdll/stdio/scanf.h
reactos/lib/ole32/Makefile.in
reactos/lib/ole32/clipboard.c
reactos/lib/ole32/compobj.c
reactos/lib/ole32/compobj_private.h
reactos/lib/ole32/errorinfo.c
reactos/lib/ole32/filemoniker.c
reactos/lib/ole32/git.c
reactos/lib/ole32/itemmoniker.c
reactos/lib/ole32/marshal.c
reactos/lib/ole32/ole2.c
reactos/lib/ole32/ole32.spec
reactos/lib/ole32/ole32.xml
reactos/lib/ole32/oleproxy.c
reactos/lib/ole32/rpc.c
reactos/lib/ole32/stg_bigblockfile.c
reactos/lib/ole32/stg_prop.c [new file with mode: 0644]
reactos/lib/ole32/stg_stream.c
reactos/lib/ole32/storage32.c
reactos/lib/ole32/storage32.h
reactos/lib/ole32/stubmanager.c
reactos/lib/oleaut32/Makefile.in
reactos/lib/oleaut32/Makefile.ros-template
reactos/lib/oleaut32/oleaut.c
reactos/lib/oleaut32/oleaut32.rc
reactos/lib/oleaut32/oleaut32.spec
reactos/lib/oleaut32/oleaut32.xml
reactos/lib/oleaut32/oleaut32_Es.rc
reactos/lib/oleaut32/olefont.c
reactos/lib/oleaut32/olepicture.c
reactos/lib/oleaut32/recinfo.c [new file with mode: 0644]
reactos/lib/oleaut32/typelib.c
reactos/lib/oleaut32/typelib2.c
reactos/lib/oleaut32/usrmarshal.c
reactos/lib/oleaut32/varformat.c
reactos/lib/oleaut32/variant.c
reactos/lib/oledlg/oledlg_Es.rc
reactos/lib/oledlg/oledlg_Fr.rc
reactos/lib/psapi/makefile
reactos/lib/psapi/psapi.c
reactos/lib/psapi/psapi.xml
reactos/lib/riched20/riched20.xml [new file with mode: 0644]
reactos/lib/richedit/Makefile.in
reactos/lib/richedit/riched32.xml
reactos/lib/richedit/richedit.c
reactos/lib/rosrtl/misc/intrlck.c
reactos/lib/rpcrt4/ndr_marshall.c
reactos/lib/rpcrt4/ndr_midl.c
reactos/lib/rpcrt4/rpc_binding.c
reactos/lib/rpcrt4/rpc_binding.h
reactos/lib/rpcrt4/rpc_message.c
reactos/lib/rpcrt4/rpc_server.c
reactos/lib/rpcrt4/rpcrt4.spec
reactos/lib/rpcrt4/rpcss_np_client.c
reactos/lib/rtl/bitmap.c
reactos/lib/rtl/error.c
reactos/lib/rtl/i386/chkstk.s [moved from reactos/lib/ntdll/rtl/i386/chkstk.s with 100% similarity]
reactos/lib/rtl/makefile
reactos/lib/rtl/ppb.c [moved from reactos/lib/ntdll/rtl/ppb.c with 94% similarity]
reactos/lib/rtl/process.c [new file with mode: 0644]
reactos/lib/rtl/rtl.xml
reactos/lib/rtl/sid.c
reactos/lib/rtl/thread.c [moved from reactos/lib/ntdll/rtl/thread.c with 99% similarity]
reactos/lib/rtl/unicode.c
reactos/lib/rtl/version.c
reactos/lib/samlib/dllmain.c
reactos/lib/samlib/samlib.c
reactos/lib/serialui/Makefile [new file with mode: 0644]
reactos/lib/serialui/resource.h [new file with mode: 0644]
reactos/lib/serialui/serialui.c [new file with mode: 0644]
reactos/lib/serialui/serialui.def [new file with mode: 0644]
reactos/lib/serialui/serialui.h [new file with mode: 0644]
reactos/lib/serialui/serialui.rc [new file with mode: 0644]
reactos/lib/setupapi/Cs.rc
reactos/lib/setupapi/Da.rc [new file with mode: 0644]
reactos/lib/setupapi/De.rc
reactos/lib/setupapi/En.rc
reactos/lib/setupapi/Es.rc
reactos/lib/setupapi/Fr.rc
reactos/lib/setupapi/It.rc
reactos/lib/setupapi/Ja.rc
reactos/lib/setupapi/Makefile.in
reactos/lib/setupapi/Nl.rc
reactos/lib/setupapi/Pt.rc
reactos/lib/setupapi/Ru.rc
reactos/lib/setupapi/cfgmgr.c
reactos/lib/setupapi/devinst.c
reactos/lib/setupapi/devinst16.c
reactos/lib/setupapi/dirid.c
reactos/lib/setupapi/diskspace.c
reactos/lib/setupapi/infparse.c
reactos/lib/setupapi/install.c
reactos/lib/setupapi/misc.c
reactos/lib/setupapi/parser.c
reactos/lib/setupapi/queue.c
reactos/lib/setupapi/rpc.c [new file with mode: 0644]
reactos/lib/setupapi/setupapi.rc
reactos/lib/setupapi/setupapi.spec
reactos/lib/setupapi/setupapi.xml
reactos/lib/setupapi/setupapi_private.h
reactos/lib/setupapi/setupcab.c
reactos/lib/setupapi/setupx.spec
reactos/lib/setupapi/setupx16.h
reactos/lib/setupapi/setupx_main.c
reactos/lib/setupapi/stubs.c
reactos/lib/setupapi/virtcopy.c
reactos/lib/shdocvw/De.rc [new file with mode: 0644]
reactos/lib/shdocvw/En.rc [new file with mode: 0644]
reactos/lib/shdocvw/Fr.rc [new file with mode: 0644]
reactos/lib/shdocvw/Pt.rc [new file with mode: 0644]
reactos/lib/shdocvw/shdocvw.rc
reactos/lib/shdocvw/shdocvw_main.c
reactos/lib/shell32/Makefile.in
reactos/lib/shell32/brsfolder.c
reactos/lib/shell32/classes.c
reactos/lib/shell32/clipboard.c
reactos/lib/shell32/dialogs.c
reactos/lib/shell32/enumidlist.c
reactos/lib/shell32/enumidlist.h
reactos/lib/shell32/folders.c
reactos/lib/shell32/pidl.c
reactos/lib/shell32/pidl.h
reactos/lib/shell32/shell32.spec
reactos/lib/shell32/shell32_Es.rc
reactos/lib/shell32/shell32_Pt.rc
reactos/lib/shell32/shell32_Sv.rc
reactos/lib/shell32/shell32_main.c
reactos/lib/shell32/shell32_main.h
reactos/lib/shell32/shelllink.c
reactos/lib/shell32/shellpath.c
reactos/lib/shell32/shfldr.h
reactos/lib/shell32/shfldr_desktop.c
reactos/lib/shell32/shfldr_fs.c
reactos/lib/shell32/shfldr_mycomp.c
reactos/lib/shell32/shfldr_unixfs.c [new file with mode: 0644]
reactos/lib/shell32/shlexec.c
reactos/lib/shell32/shlfileop.c
reactos/lib/shell32/shlfolder.c
reactos/lib/shell32/shlfsbind.c
reactos/lib/shell32/shlview.c
reactos/lib/shell32/shres.rc
reactos/lib/shell32/shv_bg_cmenu.c
reactos/lib/shellext/slayer/De.rc [new file with mode: 0644]
reactos/lib/shellext/slayer/en.rc [deleted file]
reactos/lib/shellext/slayer/slayer.rc
reactos/lib/shlwapi/assoc.c
reactos/lib/shlwapi/msgbox.c
reactos/lib/shlwapi/ordinal.c
reactos/lib/shlwapi/shlwapi.spec
reactos/lib/shlwapi/shlwapi_Es.rc
reactos/lib/shlwapi/string.c
reactos/lib/smdll/makefile
reactos/lib/smdll/query.c [new file with mode: 0644]
reactos/lib/smdll/smdll.def
reactos/lib/smdll/smdll.xml
reactos/lib/smlib/compses.c [moved from reactos/lib/smdll/compses.c with 88% similarity]
reactos/lib/smlib/connect.c [moved from reactos/lib/smdll/connect.c with 81% similarity]
reactos/lib/smlib/execpgm.c [moved from reactos/lib/smdll/execpgm.c with 87% similarity]
reactos/lib/smlib/makefile [new file with mode: 0644]
reactos/lib/smlib/smlib.xml [new file with mode: 0644]
reactos/lib/string/Makefile
reactos/lib/syssetup/wizard.c
reactos/lib/tgetopt/Makefile
reactos/lib/urlmon/urlmon.spec
reactos/lib/user32/Da.rc [new file with mode: 0644]
reactos/lib/user32/Sv.rc [new file with mode: 0644]
reactos/lib/user32/user32.rc
reactos/lib/user32/windows/accel.c
reactos/lib/user32/windows/bitmap.c
reactos/lib/user32/windows/defwnd.c
reactos/lib/user32/windows/dialog.c
reactos/lib/user32/windows/hook.c
reactos/lib/user32/windows/icon.c
reactos/lib/user32/windows/messagebox.c
reactos/lib/user32/windows/nonclient.c
reactos/lib/user32/windows/window.c
reactos/lib/userenv/De.rc
reactos/lib/uuid/uuid.c
reactos/lib/wininet/stubs.c
reactos/lib/winmm/driver.c
reactos/lib/winmm/mci.c
reactos/lib/winmm/time.c
reactos/lib/winmm/wavemap/wavemap.c
reactos/lib/winmm/winmm_Es.rc
reactos/lib/winspool/stubs.c
reactos/lib/winsta/main.c [moved from reactos/lib/coredll/coredll_main.c with 53% similarity]
reactos/lib/winsta/makefile [new file with mode: 0644]
reactos/lib/winsta/misc.c [new file with mode: 0644]
reactos/lib/winsta/server.c [new file with mode: 0644]
reactos/lib/winsta/winsta.def [new file with mode: 0644]
reactos/lib/winsta/winsta.h [new file with mode: 0644]
reactos/lib/winsta/winsta.rc [new file with mode: 0644]
reactos/lib/winsta/ws.c [new file with mode: 0644]
reactos/lib/wintrust/wintrust.def
reactos/lib/ws2_32/include/ws2_32.h
reactos/media/drivers/etc/KDBinit [new file with mode: 0644]
reactos/media/themes/.gitignore [new file with mode: 0644]
reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/ntfunc.c
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/cm/regobj.c
reactos/ntoskrnl/dbg/i386/i386-dis.c
reactos/ntoskrnl/dbg/i386/kdb_help.S
reactos/ntoskrnl/dbg/i386/longjmp.S [new file with mode: 0644]
reactos/ntoskrnl/dbg/i386/setjmp.S [new file with mode: 0644]
reactos/ntoskrnl/dbg/kdb.c
reactos/ntoskrnl/dbg/kdb.h
reactos/ntoskrnl/dbg/kdb_cli.c [new file with mode: 0644]
reactos/ntoskrnl/dbg/kdb_expr.c [new file with mode: 0644]
reactos/ntoskrnl/dbg/kdb_keyboard.c
reactos/ntoskrnl/dbg/kdb_serial.c
reactos/ntoskrnl/dbg/kdb_string.c [new file with mode: 0644]
reactos/ntoskrnl/dbg/kdb_symbols.c
reactos/ntoskrnl/dbg/profile.c [deleted file]
reactos/ntoskrnl/ex/btree.c [deleted file]
reactos/ntoskrnl/ex/error.c [new file with mode: 0644]
reactos/ntoskrnl/ex/event.c
reactos/ntoskrnl/ex/evtpair.c
reactos/ntoskrnl/ex/handle.c [new file with mode: 0644]
reactos/ntoskrnl/ex/hashtab.c [deleted file]
reactos/ntoskrnl/ex/init.c
reactos/ntoskrnl/ex/list.c
reactos/ntoskrnl/ex/mutant.c
reactos/ntoskrnl/ex/napi.c [deleted file]
reactos/ntoskrnl/ex/profile.c
reactos/ntoskrnl/ex/rundown.c
reactos/ntoskrnl/ex/sem.c
reactos/ntoskrnl/ex/stree.c [deleted file]
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/ex/timer.c
reactos/ntoskrnl/ex/win32k.c
reactos/ntoskrnl/ex/work.c
reactos/ntoskrnl/fs/notify.c
reactos/ntoskrnl/include/internal/debug.h
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/i386/fpu.h
reactos/ntoskrnl/include/internal/i386/ke.h
reactos/ntoskrnl/include/internal/i386/ps.h
reactos/ntoskrnl/include/internal/id.h [deleted file]
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/kd.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/include/internal/nls.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/include/internal/ob.h
reactos/ntoskrnl/include/internal/po.h
reactos/ntoskrnl/include/internal/port.h
reactos/ntoskrnl/include/internal/ps.h
reactos/ntoskrnl/include/internal/se.h
reactos/ntoskrnl/include/ntoskrnl.h
reactos/ntoskrnl/io/bootlog.c
reactos/ntoskrnl/io/buildirp.c
reactos/ntoskrnl/io/cancel.c
reactos/ntoskrnl/io/cleanup.c
reactos/ntoskrnl/io/create.c
reactos/ntoskrnl/io/device.c
reactos/ntoskrnl/io/dir.c
reactos/ntoskrnl/io/driver.c
reactos/ntoskrnl/io/file.c
reactos/ntoskrnl/io/iocomp.c
reactos/ntoskrnl/io/iomgr.c
reactos/ntoskrnl/io/irp.c
reactos/ntoskrnl/io/irq.c
reactos/ntoskrnl/io/mdl.c
reactos/ntoskrnl/io/pnpmgr.c
reactos/ntoskrnl/io/pnpreport.c
reactos/ntoskrnl/io/rw.c
reactos/ntoskrnl/io/share.c
reactos/ntoskrnl/io/vpb.c
reactos/ntoskrnl/io/wmi.c
reactos/ntoskrnl/kd/dlog.c
reactos/ntoskrnl/kd/gdbstub.c
reactos/ntoskrnl/kd/kdebug.c
reactos/ntoskrnl/ke/alert.c [deleted file]
reactos/ntoskrnl/ke/apc.c
reactos/ntoskrnl/ke/bug.c
reactos/ntoskrnl/ke/catch.c
reactos/ntoskrnl/ke/clock.c
reactos/ntoskrnl/ke/critical.c [deleted file]
reactos/ntoskrnl/ke/device.c
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/ke/error.c [deleted file]
reactos/ntoskrnl/ke/event.c
reactos/ntoskrnl/ke/i386/brkpoint.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/fpu.c
reactos/ntoskrnl/ke/i386/irq.c
reactos/ntoskrnl/ke/i386/kernel.c
reactos/ntoskrnl/ke/i386/trap.s
reactos/ntoskrnl/ke/i386/tskswitch.S
reactos/ntoskrnl/ke/i386/usercall.S [new file with mode: 0644]
reactos/ntoskrnl/ke/i386/usercall.c [deleted file]
reactos/ntoskrnl/ke/ipi.c
reactos/ntoskrnl/ke/kqueue.c
reactos/ntoskrnl/ke/kthread.c
reactos/ntoskrnl/ke/main.c
reactos/ntoskrnl/ke/mutex.c
reactos/ntoskrnl/ke/process.c
reactos/ntoskrnl/ke/profile.c
reactos/ntoskrnl/ke/queue.c
reactos/ntoskrnl/ke/sem.c
reactos/ntoskrnl/ke/spinlock.c
reactos/ntoskrnl/ke/timer.c
reactos/ntoskrnl/ke/usercall.c [moved from reactos/ntoskrnl/ps/w32call.c with 63% similarity]
reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/ldr/init.c
reactos/ntoskrnl/ldr/loader.c
reactos/ntoskrnl/ldr/sysdll.c
reactos/ntoskrnl/lpc/close.c
reactos/ntoskrnl/mm/RPoolMgr.h
reactos/ntoskrnl/mm/freelist.c
reactos/ntoskrnl/mm/marea.c
reactos/ntoskrnl/mm/mdl.c
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/mm/section.c
reactos/ntoskrnl/mm/virtual.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.mc
reactos/ntoskrnl/ntoskrnl.xml
reactos/ntoskrnl/ob/handle.c
reactos/ntoskrnl/ob/object.c
reactos/ntoskrnl/ob/wait.c [new file with mode: 0644]
reactos/ntoskrnl/po/power.c
reactos/ntoskrnl/ps/cid.c
reactos/ntoskrnl/ps/create.c
reactos/ntoskrnl/ps/debug.c
reactos/ntoskrnl/ps/i386/continue.c
reactos/ntoskrnl/ps/idle.c
reactos/ntoskrnl/ps/job.c
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/process.c
reactos/ntoskrnl/ps/psmgr.c
reactos/ntoskrnl/ps/query.c [new file with mode: 0644]
reactos/ntoskrnl/ps/security.c [new file with mode: 0644]
reactos/ntoskrnl/ps/suspend.c
reactos/ntoskrnl/ps/thread.c
reactos/ntoskrnl/ps/tinfo.c [deleted file]
reactos/ntoskrnl/ps/win32.c
reactos/ntoskrnl/rtl/libsupp.c
reactos/ntoskrnl/rtl/nls.c
reactos/ntoskrnl/se/access.c
reactos/ntoskrnl/se/acl.c
reactos/ntoskrnl/se/luid.c
reactos/ntoskrnl/se/sd.c
reactos/ntoskrnl/se/sid.c
reactos/ntoskrnl/se/token.c
reactos/regtests/regtests/Makefile
reactos/regtests/regtests/regtests.xml
reactos/services/rpcss/makefile
reactos/services/rpcss/rpcss.xml
reactos/services/umpnpmgr/makefile
reactos/services/umpnpmgr/umpnpmgr.c
reactos/services/umpnpmgr/umpnpmgr.xml
reactos/subsys/csrss/api/process.c
reactos/subsys/csrss/api/wapi.c
reactos/subsys/csrss/csrss.c
reactos/subsys/csrss/include/api.h
reactos/subsys/csrss/init.c
reactos/subsys/csrss/win32csr/conio.c
reactos/subsys/smss/client.c
reactos/subsys/smss/init.c
reactos/subsys/smss/initss.c
reactos/subsys/smss/initwkdll.c
reactos/subsys/smss/makefile
reactos/subsys/smss/smapi.c
reactos/subsys/smss/smapicomp.c
reactos/subsys/smss/smapiexec.c
reactos/subsys/smss/smapiquery.c [new file with mode: 0644]
reactos/subsys/smss/smss.c
reactos/subsys/smss/smss.h
reactos/subsys/smss/smss.xml
reactos/subsys/system/calc/De.rc
reactos/subsys/system/calc/Sv.rc [new file with mode: 0644]
reactos/subsys/system/calc/calc.rc
reactos/subsys/system/calc/rsrc.rc
reactos/subsys/system/cmd/En.rc [new file with mode: 0644]
reactos/subsys/system/cmd/alias.c
reactos/subsys/system/cmd/attrib.c
reactos/subsys/system/cmd/batch.c
reactos/subsys/system/cmd/beep.c
reactos/subsys/system/cmd/call.c
reactos/subsys/system/cmd/chcp.c
reactos/subsys/system/cmd/choice.c
reactos/subsys/system/cmd/cls.c
reactos/subsys/system/cmd/cmd.c
reactos/subsys/system/cmd/cmd.h
reactos/subsys/system/cmd/cmd.rc
reactos/subsys/system/cmd/color.c
reactos/subsys/system/cmd/config.h
reactos/subsys/system/cmd/console.c
reactos/subsys/system/cmd/copy.c
reactos/subsys/system/cmd/date.c
reactos/subsys/system/cmd/del.c
reactos/subsys/system/cmd/delay.c
reactos/subsys/system/cmd/dir.c
reactos/subsys/system/cmd/dirstack.c
reactos/subsys/system/cmd/error.c
reactos/subsys/system/cmd/internal.c
reactos/subsys/system/cmd/precomp.h
reactos/subsys/system/cmd/res/terminal.ico
reactos/subsys/system/cmd/resource.h [new file with mode: 0644]
reactos/subsys/system/cmd/todo.txt
reactos/subsys/system/dhcp/Makefile [new file with mode: 0644]
reactos/subsys/system/dhcp/adapter.c [new file with mode: 0644]
reactos/subsys/system/dhcp/alloc.c [new file with mode: 0644]
reactos/subsys/system/dhcp/compat.c [new file with mode: 0644]
reactos/subsys/system/dhcp/design.txt [new file with mode: 0644]
reactos/subsys/system/dhcp/dhclient.c [new file with mode: 0644]
reactos/subsys/system/dhcp/dhcp.rc [new file with mode: 0644]
reactos/subsys/system/dhcp/dhcpmain.c [new file with mode: 0644]
reactos/subsys/system/dhcp/dispatch.c [new file with mode: 0644]
reactos/subsys/system/dhcp/hash.c [new file with mode: 0644]
reactos/subsys/system/dhcp/include/cdefs.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/debug.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/dhcp.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/dhcpd.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/dhctoken.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/hash.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/inet.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/osdep.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/predec.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/privsep.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/rosdhcp.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/site.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/stdint.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/sysconf.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/tree.h [new file with mode: 0644]
reactos/subsys/system/dhcp/include/version.h [new file with mode: 0644]
reactos/subsys/system/dhcp/memory.c [new file with mode: 0644]
reactos/subsys/system/dhcp/options.c [new file with mode: 0644]
reactos/subsys/system/dhcp/privsep.c [new file with mode: 0644]
reactos/subsys/system/dhcp/socket.c [new file with mode: 0644]
reactos/subsys/system/dhcp/tables.c [new file with mode: 0644]
reactos/subsys/system/dhcp/timer.c [new file with mode: 0644]
reactos/subsys/system/dhcp/tree.c [new file with mode: 0644]
reactos/subsys/system/dhcp/util.c [new file with mode: 0644]
reactos/subsys/system/explorer/Jamfile
reactos/subsys/system/explorer/Makefile
reactos/subsys/system/explorer/Makefile.MinGW
reactos/subsys/system/explorer/Makefile.PCH
reactos/subsys/system/explorer/Makefile.Wine
reactos/subsys/system/explorer/bak/shellhook.cpp [deleted file]
reactos/subsys/system/explorer/bak/shellhook.dsp [deleted file]
reactos/subsys/system/explorer/desktop/desktop.cpp
reactos/subsys/system/explorer/desktop/desktop.h
reactos/subsys/system/explorer/dialogs/searchprogram.cpp
reactos/subsys/system/explorer/doc/TODO.txt
reactos/subsys/system/explorer/explorer.cpp
reactos/subsys/system/explorer/explorer.dsp
reactos/subsys/system/explorer/explorer.xml
reactos/subsys/system/explorer/explorer_intres.h
reactos/subsys/system/explorer/explorer_intres.rc
reactos/subsys/system/explorer/externals.h
reactos/subsys/system/explorer/make_explorer.dsp
reactos/subsys/system/explorer/res/computer.ico
reactos/subsys/system/explorer/res/explorer.ico
reactos/subsys/system/explorer/res/folder.ico
reactos/subsys/system/explorer/res/logov.bmp
reactos/subsys/system/explorer/res/reactos.ico
reactos/subsys/system/explorer/res/ros-big.ico
reactos/subsys/system/explorer/res/startmenu.ico
reactos/subsys/system/explorer/services/shellservices.cpp [new file with mode: 0644]
reactos/subsys/system/explorer/services/shellservices.h [moved from reactos/subsys/system/explorer/bak/shellhook.h with 64% similarity]
reactos/subsys/system/explorer/services/startup.c [moved from reactos/subsys/system/explorer/shell/startup.c with 100% similarity]
reactos/subsys/system/explorer/shell/entries.cpp
reactos/subsys/system/explorer/shell/mainframe.cpp
reactos/subsys/system/explorer/shell/mainframe.h
reactos/subsys/system/explorer/shell/pane.cpp
reactos/subsys/system/explorer/shell/regfs.cpp
reactos/subsys/system/explorer/shell/shellbrowser.cpp
reactos/subsys/system/explorer/shell/shellbrowser.h
reactos/subsys/system/explorer/shell/shellfs.cpp
reactos/subsys/system/explorer/shell/shellfs.h
reactos/subsys/system/explorer/taskbar/desktopbar.cpp
reactos/subsys/system/explorer/taskbar/desktopbar.h
reactos/subsys/system/explorer/taskbar/quicklaunch.cpp
reactos/subsys/system/explorer/taskbar/startmenu.cpp
reactos/subsys/system/explorer/taskbar/startmenu.h
reactos/subsys/system/explorer/taskbar/taskbar.cpp
reactos/subsys/system/explorer/taskbar/taskbar.h
reactos/subsys/system/explorer/taskbar/traynotify.cpp
reactos/subsys/system/explorer/taskbar/traynotify.h
reactos/subsys/system/explorer/utility/utility.cpp
reactos/subsys/system/explorer/utility/utility.h
reactos/subsys/system/explorer/utility/window.cpp
reactos/subsys/system/explorer/utility/window.h
reactos/subsys/system/explorer/utility/xmlstorage.cpp
reactos/subsys/system/explorer/utility/xmlstorage.h
reactos/subsys/system/format/format.xml
reactos/subsys/system/format/makefile
reactos/subsys/system/msiexec/msiexec.c
reactos/subsys/system/notepad/Da.rc
reactos/subsys/system/reactos/Sv.rc [new file with mode: 0644]
reactos/subsys/system/reactos/reactos.rc
reactos/subsys/system/reactos/res/reactos.ico
reactos/subsys/system/reporterror/En.rc
reactos/subsys/system/reporterror/dk.rc [new file with mode: 0644]
reactos/subsys/system/reporterror/reporterror.rc
reactos/subsys/system/services/database.c
reactos/subsys/system/services/makefile
reactos/subsys/system/services/services.c
reactos/subsys/system/services/services.xml
reactos/subsys/system/sndvol32/Sv.rc [new file with mode: 0644]
reactos/subsys/system/sndvol32/sndvol32.rc
reactos/subsys/system/taskmgr/De.rc
reactos/subsys/system/taskmgr/Dk.rc [new file with mode: 0644]
reactos/subsys/system/taskmgr/En.rc
reactos/subsys/system/taskmgr/Es.rc
reactos/subsys/system/taskmgr/Sv.rc [new file with mode: 0644]
reactos/subsys/system/taskmgr/about.c
reactos/subsys/system/taskmgr/affinity.c
reactos/subsys/system/taskmgr/applpage.c
reactos/subsys/system/taskmgr/column.c
reactos/subsys/system/taskmgr/dbgchnl.c
reactos/subsys/system/taskmgr/debug.c
reactos/subsys/system/taskmgr/endproc.c
reactos/subsys/system/taskmgr/font.c
reactos/subsys/system/taskmgr/graph.c
reactos/subsys/system/taskmgr/graphctl.c
reactos/subsys/system/taskmgr/makefile
reactos/subsys/system/taskmgr/optnmenu.c
reactos/subsys/system/taskmgr/perfdata.c
reactos/subsys/system/taskmgr/perfdata.h
reactos/subsys/system/taskmgr/perfpage.c
reactos/subsys/system/taskmgr/precomp.h
reactos/subsys/system/taskmgr/priority.c
reactos/subsys/system/taskmgr/proclist.c
reactos/subsys/system/taskmgr/procpage.c
reactos/subsys/system/taskmgr/resource.h
reactos/subsys/system/taskmgr/run.c
reactos/subsys/system/taskmgr/taskmgr.c
reactos/subsys/system/taskmgr/taskmgr.rc
reactos/subsys/system/taskmgr/trayicon.c
reactos/subsys/system/vmwinst/Dk.rc [new file with mode: 0644]
reactos/subsys/system/vmwinst/vmwinst.c
reactos/subsys/system/vmwinst/vmwinst.rc
reactos/subsys/system/welcome/Dk.rc [new file with mode: 0644]
reactos/subsys/system/welcome/Sv.rc [new file with mode: 0644]
reactos/subsys/system/welcome/res/welcome.ico
reactos/subsys/system/welcome/welcome.rc
reactos/subsys/system/winlogon/setup.c
reactos/subsys/system/winlogon/winlogon.h
reactos/subsys/system/winlogon/wlx.c
reactos/subsys/win32k/eng/objects.h
reactos/subsys/win32k/eng/window.c
reactos/subsys/win32k/include/desktop.h
reactos/subsys/win32k/include/dib.h
reactos/subsys/win32k/include/eng.h
reactos/subsys/win32k/include/input.h
reactos/subsys/win32k/include/intgdi.h
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/include/winsta.h
reactos/subsys/win32k/main/dllmain.c
reactos/subsys/win32k/misc/object.c
reactos/subsys/win32k/ntddraw/ddraw.c
reactos/subsys/win32k/ntddraw/stubs.c
reactos/subsys/win32k/ntuser/class.c
reactos/subsys/win32k/ntuser/desktop.c
reactos/subsys/win32k/ntuser/focus.c
reactos/subsys/win32k/ntuser/input.c
reactos/subsys/win32k/ntuser/keyboard.c
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/metric.c
reactos/subsys/win32k/ntuser/misc.c
reactos/subsys/win32k/ntuser/msgqueue.c
reactos/subsys/win32k/ntuser/painting.c
reactos/subsys/win32k/ntuser/stubs.c
reactos/subsys/win32k/ntuser/timer.c
reactos/subsys/win32k/ntuser/windc.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winpos.c
reactos/subsys/win32k/ntuser/winsta.c
reactos/subsys/win32k/objects/bitmaps.c
reactos/subsys/win32k/objects/brush.c
reactos/subsys/win32k/objects/color.c
reactos/subsys/win32k/objects/dc.c
reactos/subsys/win32k/objects/dib.c
reactos/subsys/win32k/objects/fillshap.c
reactos/subsys/win32k/objects/gdiobj.c
reactos/subsys/win32k/objects/line.c
reactos/subsys/win32k/objects/pen.c
reactos/subsys/win32k/objects/print.c
reactos/subsys/win32k/objects/stockobj.c
reactos/subsys/win32k/objects/text.c
reactos/tools/hack-coff.c [new file with mode: 0644]
reactos/tools/make_ctests.c [new file with mode: 0644]
reactos/tools/nci/sysfuncs.lst
reactos/tools/nci/w32ksvc.db
reactos/tools/ppc-le2be.c [new file with mode: 0644]
reactos/tools/raddr2line.c [new file with mode: 0644]
reactos/tools/rbuild/backend/mingw/mingw.cpp
reactos/tools/rbuild/backend/mingw/modulehandler.cpp
reactos/tools/rbuild/backend/mingw/modulehandler.h
reactos/tools/rbuild/bootstrap.cpp
reactos/tools/rbuild/module.cpp
reactos/tools/rbuild/rbuild.h
reactos/tools/rbuild/rbuild.txt
reactos/tools/rs6000.h [new file with mode: 0644]
reactos/tools/rsym.c
reactos/tools/rsym.h [new file with mode: 0644]
reactos/tools/rsym_common.c [new file with mode: 0644]
reactos/tools/tools-check.c [new file with mode: 0644]
reactos/tools/tools-check.mak [new file with mode: 0644]
reactos/tools/tools.mak
reactos/tools/unicode/mbtowc.c
reactos/tools/unicode/string.c
reactos/tools/unicode/wctomb.c
reactos/tools/widl/ChangeLog
reactos/tools/widl/Makefile
reactos/tools/widl/client.c
reactos/tools/widl/hash.c
reactos/tools/widl/header.c
reactos/tools/widl/header.h
reactos/tools/widl/lex.yy.c
reactos/tools/widl/parser.l
reactos/tools/widl/parser.y
reactos/tools/widl/server.c
reactos/tools/widl/widl.c
reactos/tools/widl/widl.h
reactos/tools/widl/widl.mak [new file with mode: 0644]
reactos/tools/widl/widltypes.h
reactos/tools/widl/write_msft.c
reactos/tools/widl/y.tab.c
reactos/tools/widl/y.tab.h
reactos/tools/wpp/lex.yy.c
reactos/tools/wpp/ppl.l
reactos/tools/wrc/newstruc.c
reactos/tools/wrc/parser.y
reactos/tools/wrc/wrc.mak
reactos/tools/wrc/y.tab.c
reactos/w32api/include/aclui.h [moved from reactos/include/aclui.h with 100% similarity]
reactos/w32api/include/ddk/ntifs.h
reactos/w32api/include/ddk/winddk.h
reactos/w32api/include/fci.h [moved from reactos/include/wine/fci.h with 100% similarity]
reactos/w32api/include/fdi.h [moved from reactos/include/wine/fdi.h with 100% similarity]
reactos/w32api/include/icmpapi.h [moved from reactos/include/icmpapi.h with 100% similarity]
reactos/w32api/include/ntdef.h
reactos/w32api/include/objbase.h
reactos/w32api/include/oleauto.h
reactos/w32api/include/richedit.h
reactos/w32api/include/setupapi.h
reactos/w32api/include/shellapi.h
reactos/w32api/include/winerror.h
reactos/w32api/include/winfax.h [moved from reactos/include/WinFax.h with 100% similarity]
reactos/w32api/include/wingdi.h
reactos/w32api/include/winioctl.h
reactos/w32api/include/winnt.h
reactos/w32api/include/winres.h [new file with mode: 0644]
reactos/w32api/include/winscard.h [moved from reactos/include/WinSCard.h with 100% similarity]
reactos/w32api/include/winsmcrd.h [moved from reactos/include/WinSmCrd.h with 100% similarity]
reactos/w32api/include/winuser.h
reactos/w32api/include/winwlx.h [moved from reactos/include/WinWlx.h with 100% similarity]

index dd66e4b..d702845 100644 (file)
@@ -79,6 +79,7 @@ ifeq ($(HALFVERBOSEECHO),yes)
   ECHO_AR      =@echo [AR]       $@
   ECHO_WINEBLD =@echo [WINEBLD]  $@
   ECHO_WRC     =@echo [WRC]      $@
+  ECHO_WIDL    =@echo [WIDL]     $@
   ECHO_BIN2RES =@echo [BIN2RES]  $<
   ECHO_DLLTOOL =@echo [DLLTOOL]  $@
   ECHO_LD      =@echo [LD]       $@
@@ -105,6 +106,7 @@ else
   ECHO_AR      =
   ECHO_WINEBLD =
   ECHO_WRC     =
+  ECHO_WIDL    =
   ECHO_BIN2RES =
   ECHO_DLLTOOL =
   ECHO_LD      =
index 284e19b..12437ee 100644 (file)
@@ -38,6 +38,9 @@
        <directory name="hal">\r
                <xi:include href="hal/directory.xml" />\r
        </directory>\r
+       <directory name="include">\r
+               <xi:include href="include/directory.xml" />\r
+       </directory>\r
        <directory name="lib">\r
                <xi:include href="lib/directory.xml" />\r
        </directory>\r
index f3e2288..1a256b2 100644 (file)
@@ -11,7 +11,7 @@ TARGET_APPTYPE = console
 
 TARGET_NAME = loadlib
 
-TARGET_CFLAGS = -Wall -Werror -D_USE_W32API -DUNICODE -D_UNICODE
+TARGET_CFLAGS = -Wall -Werror -D__USE_W32API -DUNICODE -D_UNICODE
 
 TARGET_SDKLIBS = kernel32.a ntdll.a 
 
index 86e8921..8ce2f87 100644 (file)
@@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak
 
 # Console system utilities
 # cabman cat net objdir partinfo pice ps sc stats
-UTIL_APPS = cat objdir partinfo pnpdump sc shutdown stats tickcount consw ps
+UTIL_APPS = cat objdir pnpdump sc shutdown stats tickcount ps
 
 UTIL_NET_APPS = arp finger ftp ipconfig netstat ping route telnet whois
 
similarity index 56%
rename from reactos/apps/utils/consw/makefile
rename to reactos/apps/utils/binpatch/Makefile
index 2009ee0..4ff7b6b 100644 (file)
@@ -1,23 +1,21 @@
-# $Id$
-
-PATH_TO_TOP = ../../..
-
-TARGET_NORC = yes
-
-TARGET_TYPE = program
-
-TARGET_APPTYPE = console
-
-TARGET_NAME = consw
-
-TARGET_SDKLIBS = ntdll.a kernel32.a
-
-TARGET_OBJECTS = $(TARGET_NAME).o
-
-TARGET_CFLAGS = -Wall -Werror
-
-include $(PATH_TO_TOP)/rules.mak
-
-include $(TOOLS_PATH)/helper.mk
-
-# EOF
+PATH_TO_TOP = ../../..\r
+\r
+TARGET_NORC = yes\r
+\r
+TARGET_TYPE = program\r
+\r
+TARGET_APPTYPE = console\r
+\r
+TARGET_NAME = binpatch\r
+\r
+TARGET_SDKLIBS = \r
+\r
+TARGET_OBJECTS = patch.o\r
+\r
+TARGET_CFLAGS += -Wall -Werror\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+# EOF\r
diff --git a/reactos/apps/utils/binpatch/patch.c b/reactos/apps/utils/binpatch/patch.c
new file mode 100644 (file)
index 0000000..93ae748
--- /dev/null
@@ -0,0 +1,615 @@
+#include <conio.h>\r
+#include <io.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <sys/stat.h>\r
+\r
+/** DEFINES *******************************************************************/\r
+\r
+#define PATCH_BUFFER_SIZE           4096    /* Maximum size of a patch */\r
+#define PATCH_BUFFER_MAGIC          "\xde\xad\xbe\xef MaGiC MaRk "\r
+#define SIZEOF_PATCH_BUFFER_MAGIC   (sizeof (PATCH_BUFFER_MAGIC) - 1)\r
+\r
+/** TYPES *********************************************************************/\r
+\r
+typedef struct _PatchedByte\r
+{\r
+   int            offset;    /*!< File offset of the patched byte. */\r
+   unsigned char  expected;  /*!< Expected (original) value of the byte. */\r
+   unsigned char  patched;   /*!< Patched (new) value for the byte. */\r
+} PatchedByte;\r
+\r
+typedef struct _PatchedFile\r
+{\r
+   const char  *name;        /*!< Name of the file to be patched. */\r
+   int          fileSize;    /*!< Size of the file in bytes. */\r
+   int          patchCount;  /*!< Number of patches for the file. */\r
+   PatchedByte *patches;     /*!< Patches for the file. */\r
+} PatchedFile;\r
+\r
+typedef struct _Patch\r
+{\r
+   const char   *name;       /*!< Name of the patch. */\r
+   int           fileCount;  /*!< Number of files in the patch. */\r
+   PatchedFile  *files;      /*!< Files for the patch. */\r
+} Patch;\r
+\r
+/** FUNCTION PROTOTYPES *******************************************************/\r
+\r
+static void printUsage();\r
+\r
+/** GLOBALS *******************************************************************/\r
+\r
+static Patch m_patch = { NULL, 0, NULL };\r
+static int m_argc = 0;\r
+static char **m_argv = NULL;\r
+\r
+/* patch buffer where we put the patch info into */\r
+static unsigned char m_patchBuffer[SIZEOF_PATCH_BUFFER_MAGIC + PATCH_BUFFER_SIZE] =\r
+   PATCH_BUFFER_MAGIC;\r
+\r
+/** HELPER FUNCTIONS **********************************************************/\r
+\r
+static void *\r
+loadFile(const char *fileName, int *fileSize_)\r
+{\r
+   FILE *f;\r
+   struct stat sb;\r
+   int fileSize;\r
+   void *p;\r
+   \r
+   /* Open the file */\r
+   f = fopen(fileName, "rb");\r
+   if (f == NULL)\r
+   {\r
+      printf("Couldn't open file %s for reading!\n", fileName);\r
+      return NULL;\r
+   }\r
+   \r
+   /* Get file size */\r
+   if (fstat(fileno(f), &sb) < 0)\r
+   {\r
+      fclose(f);\r
+      printf("Couldn't get size of file %s!\n", fileName);\r
+      return NULL;\r
+   }\r
+   fileSize = sb.st_size;\r
+   \r
+   /* Load file */\r
+   p = malloc(fileSize);\r
+   if (p == NULL)\r
+   {\r
+      fclose(f);\r
+      printf("Couldn't allocate %d bytes for file %s!\n", fileSize, fileName);\r
+      return NULL;\r
+   }\r
+   \r
+   if (fread(p, fileSize, 1, f) != 1)\r
+   {\r
+      fclose(f);\r
+      free(p);\r
+      printf("Couldn't read file %s into memory!\n", fileName);\r
+      return NULL;\r
+   }\r
+   \r
+   /* Close file */\r
+   fclose(f);\r
+   \r
+   *fileSize_ = fileSize;\r
+   return p;\r
+}\r
+\r
+\r
+static int\r
+saveFile(const char *fileName, void *file, int fileSize)\r
+{\r
+   FILE *f;\r
+\r
+   /* Open the file */\r
+   f = fopen(fileName, "wb");\r
+   if (f == NULL)\r
+   {\r
+      printf("Couldn't open file %s for writing!\n", fileName);\r
+      return -1;\r
+   }\r
+\r
+   /* Write file */\r
+   if (fwrite(file, fileSize, 1, f) != 1)\r
+   {\r
+      fclose(f);\r
+      printf("Couldn't write file %s!\n", fileName);\r
+      return -1;\r
+   }\r
+\r
+   /* Close file */\r
+   fclose(f);\r
+   return 0;\r
+}\r
+\r
+\r
+static int\r
+compareFiles(\r
+   PatchedFile *patchedFile,\r
+   const char *originalFileName)\r
+{\r
+   const char *patchedFileName = patchedFile->name;\r
+   unsigned char *origChunk, *patchedChunk;\r
+   int origSize, patchedSize, i, patchCount;\r
+   PatchedByte *patches = NULL;\r
+   int patchesArrayCount = 0;\r
+   \r
+   /* Load both files */\r
+   origChunk = loadFile(originalFileName, &origSize);\r
+   if (origChunk == NULL)\r
+      return -1;\r
+   patchedChunk = loadFile(patchedFileName, &patchedSize);\r
+   if (patchedChunk == NULL)\r
+   {\r
+      free(origChunk);\r
+      return -1;\r
+   }\r
+   if (origSize != patchedSize)\r
+   {\r
+      free(origChunk);\r
+      free(patchedChunk);\r
+      printf("File size of %s and %s differs (%d != %d)\n",\r
+             originalFileName, patchedFileName,\r
+             origSize, patchedSize);\r
+      return -1;\r
+   }\r
+   \r
+   /* Compare the files and record any differences */\r
+   printf("Comparing %s to %s", originalFileName, patchedFileName);\r
+   for (i = 0, patchCount = 0; i < origSize; i++)\r
+   {\r
+      if (origChunk[i] != patchedChunk[i])\r
+      {\r
+         patchCount++;\r
+         \r
+         /* Resize patches array if needed */\r
+         if (patchesArrayCount < patchCount)\r
+         {\r
+            PatchedByte *newPatches;\r
+            newPatches = realloc(patches, patchCount * sizeof (PatchedByte));\r
+            if (newPatches == NULL)\r
+            {\r
+              if (patches != NULL)\r
+                free(patches);\r
+              free(origChunk);\r
+              free(patchedChunk);\r
+              printf("\nOut of memory (tried to allocated %d bytes)\n",\r
+                     patchCount * sizeof (PatchedByte));\r
+              return -1;\r
+            }\r
+            patches = newPatches;\r
+         }\r
+         \r
+         /* Fill in patch info */\r
+         patches[patchCount - 1].offset = i;\r
+         patches[patchCount - 1].expected = origChunk[i];\r
+         patches[patchCount - 1].patched = patchedChunk[i];\r
+      }\r
+      if ((i % (origSize / 40)) == 0)\r
+         printf(".");\r
+   }\r
+   printf(" %d changed bytes found.\n", patchCount);\r
+   \r
+   /* Unload the files */\r
+   free(origChunk);\r
+   free(patchedChunk);\r
+   \r
+   /* Save patch info */\r
+   patchedFile->fileSize = patchedSize;\r
+   patchedFile->patchCount = patchCount;\r
+   patchedFile->patches = patches;\r
+   \r
+   return 0;\r
+}\r
+\r
+\r
+static int\r
+outputPatch(const char *outputFileName)\r
+{\r
+   unsigned char *patchExe, *patchBuffer;\r
+   int i, size, patchExeSize, patchSize, stringSize, stringOffset, patchOffset;\r
+   Patch *patch;\r
+   PatchedFile *files;\r
+   \r
+   printf("Putting patch into %s...\n", outputFileName);\r
+   \r
+   /* Calculate size of the patch */\r
+   patchSize = sizeof (Patch) + sizeof (PatchedFile) * m_patch.fileCount;\r
+   stringSize = strlen(m_patch.name) + 1;\r
+   for (i = 0; i < m_patch.fileCount; i++)\r
+   {\r
+      stringSize += strlen(m_patch.files[i].name) + 1;\r
+      patchSize += sizeof (PatchedByte) * m_patch.files[i].patchCount;\r
+   }\r
+   if ((stringSize + patchSize) > PATCH_BUFFER_SIZE)\r
+   {\r
+      printf("Patch is too big - %d bytes maximum, %d bytes needed\n",\r
+             PATCH_BUFFER_SIZE, stringSize + patchSize);\r
+      return -1;\r
+   }\r
+\r
+   /* Load patch.exe file into memory... */\r
+   patchExe = loadFile(m_argv[0], &patchExeSize);\r
+   if (patchExe == NULL)\r
+   {\r
+      return -1;\r
+   }\r
+   \r
+   /* Try to find the magic mark for the patch buffer */\r
+   for (i = 0; i < (patchExeSize - SIZEOF_PATCH_BUFFER_MAGIC); i++)\r
+   {\r
+      if (memcmp(patchExe + i, m_patchBuffer, SIZEOF_PATCH_BUFFER_MAGIC) == 0)\r
+      {\r
+         patchBuffer = patchExe + i + SIZEOF_PATCH_BUFFER_MAGIC;\r
+         \r
+         break;\r
+      }\r
+   }\r
+   if (!(i < (patchExeSize - SIZEOF_PATCH_BUFFER_MAGIC)))\r
+   {\r
+      free(patchExe);\r
+      printf("Couldn't find patch buffer magic in file %s - this shouldn't happen!!!\n", m_argv[0]);\r
+      return -1;\r
+   }\r
+   \r
+   /* Pack patch together and replace string pointers by offsets */\r
+   patch = (Patch *)patchBuffer;\r
+   files = (PatchedFile *)(patchBuffer + sizeof (Patch));\r
+   patchOffset = sizeof (Patch) + sizeof (PatchedFile) * m_patch.fileCount;\r
+   stringOffset = patchSize;\r
+   \r
+   patch->fileCount = m_patch.fileCount;\r
+   patch->files = (PatchedFile *)sizeof (Patch);\r
+\r
+   patch->name = (const char *)stringOffset;\r
+   strcpy(patchBuffer + stringOffset, m_patch.name);\r
+   stringOffset += strlen(m_patch.name) + 1;\r
+   \r
+   for (i = 0; i < m_patch.fileCount; i++)\r
+   {\r
+      files[i].fileSize = m_patch.files[i].fileSize;\r
+      files[i].patchCount = m_patch.files[i].patchCount;\r
+      \r
+      files[i].name = (const char *)stringOffset;\r
+      strcpy(patchBuffer + stringOffset, m_patch.files[i].name);\r
+      stringOffset += strlen(m_patch.files[i].name) + 1;\r
+      \r
+      size = files[i].patchCount * sizeof (PatchedByte);\r
+      files[i].patches = (PatchedByte *)patchOffset;\r
+      memcpy(patchBuffer + patchOffset, m_patch.files[i].patches, size);\r
+      patchOffset += size;\r
+   }\r
+   size = patchSize + stringSize;\r
+   memset(patchBuffer + size, 0, PATCH_BUFFER_SIZE - size);\r
+\r
+   /* Save file */\r
+   if (saveFile(outputFileName, patchExe, patchExeSize) < 0)\r
+   {\r
+      free(patchExe);\r
+      return -1;\r
+   }\r
+   free(patchExe);\r
+\r
+   printf("Patch saved!\n");\r
+   return 0;\r
+}\r
+\r
+\r
+static int\r
+loadPatch()\r
+{\r
+   char *p;\r
+   Patch *patch;\r
+   int i;\r
+   \r
+   p = m_patchBuffer + SIZEOF_PATCH_BUFFER_MAGIC;\r
+   patch = (Patch *)p;\r
+   \r
+   if (patch->name == NULL)\r
+   {\r
+      return -1;\r
+   }\r
+   \r
+   m_patch.name = p + (int)patch->name;\r
+   m_patch.fileCount = patch->fileCount;\r
+   m_patch.files = (PatchedFile *)(p + (int)patch->files);\r
+\r
+   for (i = 0; i < m_patch.fileCount; i++)\r
+   {\r
+      m_patch.files[i].name = p + (int)m_patch.files[i].name;\r
+      m_patch.files[i].patches = (PatchedByte *)(p + (int)m_patch.files[i].patches);\r
+   }\r
+   \r
+   printf("Patch %s loaded...\n", m_patch.name);\r
+   return 0;\r
+}\r
+\r
+\r
+/** MAIN FUNCTIONS ************************************************************/\r
+\r
+static int\r
+createPatch()\r
+{\r
+   int i, status;\r
+   const char *outputFileName;\r
+\r
+   /* Check argument count */\r
+   if (m_argc < 6 || (m_argc % 2) != 0)\r
+   {\r
+      printUsage();\r
+      return -1;\r
+   }\r
+\r
+   outputFileName = m_argv[3];\r
+   m_patch.name = m_argv[2];\r
+\r
+   /* Allocate PatchedFiles array */\r
+   m_patch.fileCount = (m_argc - 4) / 2;\r
+   m_patch.files = malloc(m_patch.fileCount * sizeof (PatchedFile));\r
+   if (m_patch.files == NULL)\r
+   {\r
+      printf("Out of memory!\n");\r
+      return -1;\r
+   }\r
+   memset(m_patch.files, 0, m_patch.fileCount * sizeof (PatchedFile));\r
+\r
+   /* Compare original to patched files and fill m_patch.files array */\r
+   for (i = 0; i < m_patch.fileCount; i++)\r
+   {\r
+      m_patch.files[i].name = m_argv[4 + (i * 2) + 1];\r
+      status = compareFiles(m_patch.files + i, m_argv[4 + (i * 2) + 0]);\r
+      if (status < 0)\r
+      {\r
+         for (i = 0; i < m_patch.fileCount; i++)\r
+         {\r
+            if (m_patch.files[i].patches != NULL)\r
+               free(m_patch.files[i].patches);\r
+         }\r
+         free(m_patch.files);\r
+         m_patch.files = NULL;\r
+         m_patch.fileCount = 0;\r
+         return status;\r
+      }\r
+   }\r
+   \r
+   /* Output patch */\r
+   return outputPatch(outputFileName);\r
+}\r
+\r
+\r
+static int\r
+applyPatch()\r
+{\r
+   int c, i, j, fileSize, makeBackup;\r
+   unsigned char *file;\r
+   char *p;\r
+   const char *fileName;\r
+   char buffer[MAX_PATH];\r
+   \r
+\r
+   if (m_argc > 1 && strcmp(m_argv[1], "-d") != 0)\r
+   {\r
+      printUsage();\r
+      return -1;\r
+   }\r
+\r
+   /* Load patch */\r
+   if (loadPatch() < 0)\r
+   {\r
+      printf("This executable doesn't contain a patch, use -c to create one.\n");\r
+      return -1;\r
+   }\r
+\r
+   if (m_argc > 1)\r
+   {\r
+      /* Dump patch */\r
+      printf("Patch name: %s\n", m_patch.name);\r
+      printf("File count: %d\n", m_patch.fileCount);\r
+      for (i = 0; i < m_patch.fileCount; i++)\r
+      {\r
+         printf("----------------------\n"\r
+                "File name:   %s\n"\r
+                "File size:   %d bytes\n",\r
+                m_patch.files[i].name, m_patch.files[i].fileSize);\r
+         printf("Patch count: %d\n", m_patch.files[i].patchCount);\r
+         for (j = 0; j < m_patch.files[i].patchCount; j++)\r
+         {\r
+            printf("  Offset 0x%x   0x%02x -> 0x%02x\n",\r
+                   m_patch.files[i].patches[j].offset,\r
+                   m_patch.files[i].patches[j].expected,\r
+                   m_patch.files[i].patches[j].patched);\r
+         }\r
+      }\r
+   }\r
+   else\r
+   {\r
+      /* Apply patch */\r
+      printf("Applying patch...\n");\r
+      for (i = 0; i < m_patch.fileCount; i++)\r
+      {\r
+         /* Load original file */\r
+         fileName = m_patch.files[i].name;\r
+applyPatch_retry_file:\r
+         file = loadFile(fileName, &fileSize);\r
+         if (file == NULL)\r
+         {\r
+            printf("File %s not found! ", fileName);\r
+applyPatch_file_open_error:\r
+            printf("(S)kip, (R)etry, (A)bort, (M)anually enter filename");\r
+            do\r
+            {\r
+               c = getch();\r
+            }\r
+            while (c != 's' && c != 'r' && c != 'a' && c != 'm');\r
+            printf("\n");\r
+            if (c == 's')\r
+            {\r
+               continue;\r
+            }\r
+            else if (c == 'r')\r
+            {\r
+               goto applyPatch_retry_file;\r
+            }\r
+            else if (c == 'a')\r
+            {\r
+               return 0;\r
+            }\r
+            else if (c == 'm')\r
+            {\r
+               if (fgets(buffer, sizeof (buffer), stdin) == NULL)\r
+               {\r
+                  printf("fgets() failed!\n");\r
+                  return -1;\r
+               }\r
+               p = strchr(buffer, '\r');\r
+               if (p != NULL)\r
+                  *p = '\0';\r
+               p = strchr(buffer, '\n');\r
+               if (p != NULL)\r
+                  *p = '\0';\r
+\r
+               fileName = buffer;\r
+               goto applyPatch_retry_file;\r
+            }\r
+         }\r
+\r
+         /* Check file size */\r
+         if (fileSize != m_patch.files[i].fileSize)\r
+         {\r
+            free(file);\r
+            printf("File %s has unexpected filesize of %d bytes (%d bytes expected)\n",\r
+                   fileName, fileSize, m_patch.files[i].fileSize);\r
+            if (fileName != m_patch.files[i].name) /* manually entered filename */\r
+            {\r
+               goto applyPatch_file_open_error;\r
+            }\r
+            return -1;\r
+         }\r
+         \r
+         /* Ask for backup */\r
+         printf("Do you want to make a backup of %s? (Y)es, (N)o, (A)bort", fileName);\r
+         do\r
+         {\r
+            c = getch();\r
+         }\r
+         while (c != 'y' && c != 'n' && c != 'a');\r
+         printf("\n");\r
+         if (c == 'y')\r
+         {\r
+            char buffer[MAX_PATH];\r
+            snprintf(buffer, MAX_PATH, "%s.bak", fileName);\r
+            buffer[MAX_PATH-1] = '\0';\r
+            makeBackup = 1;\r
+            if (access(buffer, 0) >= 0) /* file exists */\r
+            {\r
+               printf("File %s already exists, overwrite? (Y)es, (N)o, (A)bort", buffer);\r
+               do\r
+               {\r
+                  c = getch();\r
+               }\r
+               while (c != 'y' && c != 'n' && c != 'a');\r
+               printf("\n");\r
+               if (c == 'n')\r
+                  makeBackup = 0;\r
+               else if (c == 'a')\r
+               {\r
+                  free(file);\r
+                  return 0;\r
+               }\r
+            }\r
+            if (makeBackup && saveFile(buffer, file, fileSize) < 0)\r
+            {\r
+               free(file);\r
+               return -1;\r
+            }\r
+         }\r
+         else if (c == 'a')\r
+         {\r
+            free(file);\r
+            return 0;\r
+         }\r
+         \r
+         /* Patch file */\r
+         for (j = 0; j < m_patch.files[i].patchCount; j++)\r
+         {\r
+            int offset = m_patch.files[i].patches[j].offset;\r
+            if (file[offset] != m_patch.files[i].patches[j].expected)\r
+            {\r
+               printf("Unexpected value in file %s at offset 0x%x: expected = 0x%02x, found = 0x%02x\n",\r
+                      fileName, offset, m_patch.files[i].patches[j].expected, file[offset]);\r
+               free(file);\r
+               return -1;\r
+            }\r
+            file[offset] = m_patch.files[i].patches[j].patched;\r
+         }\r
+         \r
+         /* Save file */\r
+         if (saveFile(fileName, file, fileSize) < 0)\r
+         {\r
+            free(file);\r
+            return -1;\r
+         }\r
+         free(file);\r
+      }\r
+      \r
+      printf("Patch applied sucessfully!\n");\r
+   }\r
+\r
+   return 0;\r
+}\r
+\r
+\r
+static void\r
+printUsage()\r
+{\r
+   printf("Usage:\n"\r
+          "%s -c     - Create patch\n"\r
+          "%s -d     - Dump patch\n"\r
+          "%s        - Apply patch\n"\r
+          "\n"\r
+          "A patch can be created like this:\n"\r
+          "%s -c \"patch name\" output.exe file1.orig file1.patched[ file2.orig file2.patched[ ...]]\n",\r
+          m_argv[0], m_argv[0], m_argv[0], m_argv[0]);\r
+}\r
+\r
+\r
+int\r
+main(\r
+   int argc,\r
+   char *argv[])\r
+{\r
+   m_argc = argc;\r
+   m_argv = argv;\r
+\r
+   if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0))\r
+   {\r
+      printUsage();\r
+      return 0;\r
+   }\r
+   else if (argc >= 2 && argv[1][0] == '-')\r
+   {\r
+      if (strcmp(argv[1], "-c") == 0)\r
+      {\r
+         return createPatch();\r
+      }\r
+      else if (strcmp(argv[1], "-d") == 0)\r
+      {\r
+         return applyPatch();\r
+      }\r
+      else\r
+      {\r
+         printf("Unknown option: %s\n"\r
+                "Use -h for help.\n",\r
+                argv[1]);\r
+         return -1;\r
+      }\r
+   }\r
+   \r
+   return applyPatch();\r
+}\r
+\r
diff --git a/reactos/apps/utils/consw/consw.c b/reactos/apps/utils/consw/consw.c
deleted file mode 100644 (file)
index 98c0d36..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $Id$
- *
- * DESCRIPTION: Console mode switcher
- * PROGRAMMER:  Art Yerkes
- * REVISIONS
- *     2003-07-26 (arty)
- */
-
-#include <windows.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-void STDCALL SetConsoleHardwareState( HANDLE conhandle,
-                                     DWORD flags,
-                                     DWORD state );
-
-int main(int argc, char* argv[])
-{
-  if( argc > 1 ) {
-    SetConsoleHardwareState( GetStdHandle( STD_INPUT_HANDLE ), 
-                            0,
-                            !strcmp( argv[1], "hw" ) );
-  }
-  return 0;
-}
-
-
-/* EOF */
diff --git a/reactos/apps/utils/consw/runprg.bat b/reactos/apps/utils/consw/runprg.bat
deleted file mode 100644 (file)
index 989cf85..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-@echo off
-rem Turn off cosole, run a program, turn console on
-\reactos\bin\consw sw
-"%1" "%2" "%3" "%4" "%5" "%6" "%7" "%8" "%9"
-\reactos\bin\consw hw
index a32c246..ab481c2 100644 (file)
@@ -8,6 +8,8 @@ TARGET_NAME = ftp
 
 TARGET_INSTALLDIR = system32
 
+TARGET_CFLAGS = -D__USE_W32API
+
 TARGET_SDKLIBS = ws2_32.a iphlpapi.a
 # ntdll.a
 
index 4e7a078..3459fc5 100644 (file)
@@ -8,7 +8,7 @@ TARGET_NAME = ping
 
 TARGET_INSTALLDIR = system32
 
-TARGET_CFLAGS = -D__USE_W32_SOCKETS
+TARGET_CFLAGS = -D__USE_W32API -D__USE_W32_SOCKETS
 
 TARGET_SDKLIBS = ws2_32.a
 
index 2e6a501..c604abd 100644 (file)
@@ -1,5 +1,6 @@
 <module name="ping" type="win32cui" installbase="system32" installname="ping.exe">\r
        <include base="ping">.</include>\r
+       <define name="__USE_W32API" />\r
        <define name="__USE_W32_SOCKETS" />\r
        <define name="_WIN32_IE">0x600</define>\r
        <define name="_WIN32_WINNT">0x501</define>\r
index 28c948f..e7c5e4d 100644 (file)
@@ -12,7 +12,7 @@ TARGET_SDKLIBS = ws2_32.a iphlpapi.a ntdll.a
 
 TARGET_OBJECTS = $(TARGET_NAME).o
 
-TARGET_GCCLIBS = 
+TARGET_CFLAGS = -D__USE_W32API
 
 include $(PATH_TO_TOP)/rules.mak
 
index c1a435e..0760122 100644 (file)
@@ -1,5 +1,6 @@
 <module name="route" type="win32cui">\r
        <include base="route">.</include>\r
+       <define name="__USE_W32API" />\r
        <library>kernel32</library>\r
        <library>ws2_32</library>\r
        <library>iphlpapi</library>\r
index 8978908..483df1e 100644 (file)
@@ -10,7 +10,7 @@ TARGET_APPTYPE = console
 
 TARGET_NAME = partinfo
 
-TARGET_CFLAGS = -Wall -Werror -Wno-format
+TARGET_CFLAGS = -D__USE_W32API -Wall -Werror -Wno-format
 
 TARGET_SDKLIBS = ntdll.a kernel32.a
 
index 844fe8f..252e465 100644 (file)
@@ -8,9 +8,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <ddk/ntddk.h>
+
 //#define DUMP_DATA
 #define DUMP_SIZE_INFO
-
+#define UNICODE
 
 #ifdef DUMP_DATA
 void HexDump(char *buffer, ULONG size)
index 2404538..5cecb16 100644 (file)
@@ -10,7 +10,7 @@ TARGET_APPTYPE = console
 
 TARGET_NAME = pnpdump
 
-TARGET_CFLAGS = -Wall -Werror
+TARGET_CFLAGS = -D__USE_W32API -Wall -Werror
 
 TARGET_SDKLIBS = ntdll.a kernel32.a
 
index b02bc2b..4557e69 100644 (file)
@@ -8,6 +8,8 @@
 #include <stdlib.h>
 #include <conio.h>
 
+#include <ddk/ntddk.h>
+
 #include <pshpack1.h>
 
 typedef struct _CM_PNP_BIOS_DEVICE_NODE
index b86b573..46c3601 100644 (file)
@@ -10,7 +10,7 @@ TARGET_APPTYPE = console
 
 TARGET_NAME = ps
 
-TARGET_CFLAGS = -DANONYMOUSUNIONS -Werror -Wall
+TARGET_CFLAGS = -D__USE_W32API -DANONYMOUSUNIONS -Werror -Wall
 
 TARGET_SDKLIBS = ntdll.a kernel32.a user32.a
 
index ba118f3..0c7f629 100644 (file)
@@ -13,7 +13,7 @@ TARGET_INSTALLDIR = system32
 
 TARGET_NAME = sc
 
-TARGET_CFLAGS = -DDBG -Werror -Wall
+TARGET_CFLAGS = -D__USE_W32API -DDBG -Werror -Wall
 
 TARGET_SDKLIBS = kernel32.a ntdll.a advapi32.a
 
diff --git a/reactos/apps/utils/winetest/config.h b/reactos/apps/utils/winetest/config.h
new file mode 100644 (file)
index 0000000..949acf8
--- /dev/null
@@ -0,0 +1,949 @@
+/* include/config.h.  Generated by configure.  */
+/* include/config.h.in.  Generated from configure.ac by autoheader.  */
+
+#define __WINE_CONFIG_H
+
+/* Specifies the compiler flag that forces a short wchar_t */
+#define CC_FLAG_SHORT_WCHAR "-fshort-wchar"
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you have ALSA 1.x including devel headers */
+/* #undef HAVE_ALSA */
+
+/* Define to 1 if you have the <alsa/asoundlib.h> header file. */
+/* #undef HAVE_ALSA_ASOUNDLIB_H */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+/* #undef HAVE_ARPA_INET_H */
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+/* #undef HAVE_ARPA_NAMESER_H */
+
+/* Define if you have ARTS sound server */
+/* #undef HAVE_ARTS */
+
+/* Define if the assembler keyword .size is accepted */
+/* #undef HAVE_ASM_DOT_SIZE */
+
+/* Define to 1 if you have the <audio/audiolib.h> header file. */
+/* #undef HAVE_AUDIO_AUDIOLIB_H */
+
+/* Define to 1 if you have the <audio/soundlib.h> header file. */
+/* #undef HAVE_AUDIO_SOUNDLIB_H */
+
+/* Define to 1 if you have the <capi20.h> header file. */
+/* #undef HAVE_CAPI20_H */
+
+/* Define if you have capi4linux libs and headers */
+/* #undef HAVE_CAPI4LINUX */
+
+/* Define to 1 if you have the `chsize' function. */
+#define HAVE_CHSIZE 1
+
+/* Define to 1 if you have the `clone' function. */
+/* #undef HAVE_CLONE */
+
+/* Define to 1 if you have the `connect' function. */
+/* #undef HAVE_CONNECT */
+
+/* Define if we have linux/input.h AND it contains the INPUT event API */
+/* #undef HAVE_CORRECT_LINUXINPUT_H */
+
+/* Define to 1 if you have the <cups/cups.h> header file. */
+/* #undef HAVE_CUPS_CUPS_H */
+
+/* Define to 1 if you have the <curses.h> header file. */
+/* #undef HAVE_CURSES_H */
+
+/* Define to 1 if you have the <direct.h> header file. */
+#define HAVE_DIRECT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define if you have dlopen */
+/* #undef HAVE_DLOPEN */
+
+/* Define to 1 if you have the <elf.h> header file. */
+/* #undef HAVE_ELF_H */
+
+/* Define to 1 if you have the `epoll_create' function. */
+/* #undef HAVE_EPOLL_CREATE */
+
+/* Define to 1 if you have the `ffs' function. */
+/* #undef HAVE_FFS */
+
+/* Define to 1 if you have the `finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the <fontconfig/fontconfig.h> header file. */
+/* #undef HAVE_FONTCONFIG_FONTCONFIG_H */
+
+/* Define to 1 if you have the `fork' function. */
+/* #undef HAVE_FORK */
+
+/* Define to 1 if you have the `fpclass' function. */
+#define HAVE_FPCLASS 1
+
+/* Define if FreeType 2 is installed */
+/* #undef HAVE_FREETYPE */
+
+/* Define to 1 if you have the <freetype/freetype.h> header file. */
+/* #undef HAVE_FREETYPE_FREETYPE_H */
+
+/* Define to 1 if you have the <freetype/ftglyph.h> header file. */
+/* #undef HAVE_FREETYPE_FTGLYPH_H */
+
+/* Define to 1 if you have the <freetype/ftnames.h> header file. */
+/* #undef HAVE_FREETYPE_FTNAMES_H */
+
+/* Define to 1 if you have the <freetype/ftoutln.h> header file. */
+/* #undef HAVE_FREETYPE_FTOUTLN_H */
+
+/* Define to 1 if you have the <freetype/ftsnames.h> header file. */
+/* #undef HAVE_FREETYPE_FTSNAMES_H */
+
+/* Define if you have the <freetype/fttrigon.h> header file. */
+/* #undef HAVE_FREETYPE_FTTRIGON_H */
+
+/* Define to 1 if you have the <freetype/ftwinfnt.h> header file. */
+/* #undef HAVE_FREETYPE_FTWINFNT_H */
+
+/* Define to 1 if you have the <freetype/internal/sfnt.h> header file. */
+/* #undef HAVE_FREETYPE_INTERNAL_SFNT_H */
+
+/* Define to 1 if you have the <freetype/ttnameid.h> header file. */
+/* #undef HAVE_FREETYPE_TTNAMEID_H */
+
+/* Define to 1 if you have the <freetype/tttables.h> header file. */
+/* #undef HAVE_FREETYPE_TTTABLES_H */
+
+/* Define to 1 if the system has the type `fsblkcnt_t'. */
+/* #undef HAVE_FSBLKCNT_T */
+
+/* Define to 1 if the system has the type `fsfilcnt_t'. */
+/* #undef HAVE_FSFILCNT_T */
+
+/* Define to 1 if you have the `fstatfs' function. */
+/* #undef HAVE_FSTATFS */
+
+/* Define to 1 if you have the `fstatvfs' function. */
+/* #undef HAVE_FSTATVFS */
+
+/* Define to 1 if you have the <ft2build.h> header file. */
+/* #undef HAVE_FT2BUILD_H */
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `futimes' function. */
+/* #undef HAVE_FUTIMES */
+
+/* Define to 1 if you have the `gethostbyname' function. */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define to 1 if you have the `getnetbyname' function. */
+/* #undef HAVE_GETNETBYNAME */
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `getopt_long' function. */
+#define HAVE_GETOPT_LONG 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getprotobyname' function. */
+/* #undef HAVE_GETPROTOBYNAME */
+
+/* Define to 1 if you have the `getprotobynumber' function. */
+/* #undef HAVE_GETPROTOBYNUMBER */
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #undef HAVE_GETPWUID */
+
+/* Define to 1 if you have the `getservbyport' function. */
+/* #undef HAVE_GETSERVBYPORT */
+
+/* Define to 1 if you have the `gettid' function. */
+/* #undef HAVE_GETTID */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+/* #undef HAVE_GETTIMEOFDAY */
+
+/* Define to 1 if you have the `getuid' function. */
+/* #undef HAVE_GETUID */
+
+/* Define to 1 if you have the <gif_lib.h> header file. */
+/* #undef HAVE_GIF_LIB_H */
+
+/* Define to 1 if you have the <GL/glext.h> header file. */
+/* #undef HAVE_GL_GLEXT_H */
+
+/* Define to 1 if you have the <GL/glx.h> header file. */
+/* #undef HAVE_GL_GLX_H */
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+/* #undef HAVE_GL_GL_H */
+
+/* Define to 1 if the ICU libraries are installed */
+/* #undef HAVE_ICU */
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+/* #undef HAVE_IEEEFP_H */
+
+/* Define to 1 if you have the `inet_aton' function. */
+/* #undef HAVE_INET_ATON */
+
+/* Define to 1 if you have the `inet_network' function. */
+/* #undef HAVE_INET_NETWORK */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* Define if IPX should use netipx/ipx.h from libc */
+/* #undef HAVE_IPX_GNU */
+
+/* Define if IPX includes are taken from Linux kernel */
+/* #undef HAVE_IPX_LINUX */
+
+/* Define to 1 if you have the `iswalnum' function. */
+#define HAVE_ISWALNUM 1
+
+/* Define to 1 if you have the <jack/jack.h> header file. */
+/* #undef HAVE_JACK_JACK_H */
+
+/* Define to 1 if you have the <jpeglib.h> header file. */
+/* #undef HAVE_JPEGLIB_H */
+
+/* Define to 1 if you have the <lcms.h> header file. */
+/* #undef HAVE_LCMS_H */
+
+/* Define to 1 if you have the <lcms/lcms.h> header file. */
+/* #undef HAVE_LCMS_LCMS_H */
+
+/* Define if you have libaudioIO */
+/* #undef HAVE_LIBAUDIOIO */
+
+/* Define to 1 if you have the <libaudioio.h> header file. */
+/* #undef HAVE_LIBAUDIOIO_H */
+
+/* Define if you have the curses library (-lcurses) */
+/* #undef HAVE_LIBCURSES */
+
+/* Define to 1 if you have the `i386' library (-li386). */
+/* #undef HAVE_LIBI386 */
+
+/* Define if you have the ncurses library (-lncurses) */
+/* #undef HAVE_LIBNCURSES */
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define to 1 if you have the `ossaudio' library (-lossaudio). */
+/* #undef HAVE_LIBOSSAUDIO */
+
+/* Define to 1 if you have the `poll' library (-lpoll). */
+/* #undef HAVE_LIBPOLL */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `w' library (-lw). */
+/* #undef HAVE_LIBW */
+
+/* Define to 1 if you have the `xpg4' library (-lxpg4). */
+/* #undef HAVE_LIBXPG4 */
+
+/* Define if you have the Xrandr library */
+/* #undef HAVE_LIBXRANDR */
+
+/* Define if you have the X Shape extension */
+/* #undef HAVE_LIBXSHAPE */
+
+/* Define if you have the Xxf86dga library version 2 */
+/* #undef HAVE_LIBXXF86DGA2 */
+
+/* Define if you have the Xxf86vm library */
+/* #undef HAVE_LIBXXF86VM */
+
+/* Define if you have the X Shm extension */
+/* #undef HAVE_LIBXXSHM */
+
+/* Define to 1 if you have the <link.h> header file. */
+/* #undef HAVE_LINK_H */
+
+/* Define if <linux/joystick.h> defines the Linux 2.2 joystick API */
+/* #undef HAVE_LINUX_22_JOYSTICK_API */
+
+/* Define to 1 if you have the <linux/capi.h> header file. */
+/* #undef HAVE_LINUX_CAPI_H */
+
+/* Define to 1 if you have the <linux/cdrom.h> header file. */
+/* #undef HAVE_LINUX_CDROM_H */
+
+/* Define to 1 if you have the <linux/compiler.h> header file. */
+/* #undef HAVE_LINUX_COMPILER_H */
+
+/* Define if Linux-style gethostbyname_r and gethostbyaddr_r are available */
+/* #undef HAVE_LINUX_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the <linux/hdreg.h> header file. */
+/* #undef HAVE_LINUX_HDREG_H */
+
+/* Define to 1 if you have the <linux/input.h> header file. */
+/* #undef HAVE_LINUX_INPUT_H */
+
+/* Define to 1 if you have the <linux/ioctl.h> header file. */
+/* #undef HAVE_LINUX_IOCTL_H */
+
+/* Define to 1 if you have the <linux/joystick.h> header file. */
+/* #undef HAVE_LINUX_JOYSTICK_H */
+
+/* Define to 1 if you have the <linux/major.h> header file. */
+/* #undef HAVE_LINUX_MAJOR_H */
+
+/* Define to 1 if you have the <linux/param.h> header file. */
+/* #undef HAVE_LINUX_PARAM_H */
+
+/* Define to 1 if you have the <linux/serial.h> header file. */
+/* #undef HAVE_LINUX_SERIAL_H */
+
+/* Define to 1 if you have the <linux/ucdrom.h> header file. */
+/* #undef HAVE_LINUX_UCDROM_H */
+
+/* Define to 1 if the system has the type `long long'. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the `lstat' function. */
+/* #undef HAVE_LSTAT */
+
+/* Define to 1 if you have the <machine/cpu.h> header file. */
+/* #undef HAVE_MACHINE_CPU_H */
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the <mntent.h> header file. */
+/* #undef HAVE_MNTENT_H */
+
+/* Define to 1 if the system has the type `mode_t'. */
+#define HAVE_MODE_T 1
+
+/* Define if you have NAS including devel headers */
+/* #undef HAVE_NAS */
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+/* #undef HAVE_NCURSES_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+/* #undef HAVE_NETDB_H */
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+/* #undef HAVE_NETINET_IN_H */
+
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+/* #undef HAVE_NETINET_IN_SYSTM_H */
+
+/* Define to 1 if you have the <netinet/tcp_fsm.h> header file. */
+/* #undef HAVE_NETINET_TCP_FSM_H */
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* #undef HAVE_NETINET_TCP_H */
+
+/* Define to 1 if you have the <net/if_arp.h> header file. */
+/* #undef HAVE_NET_IF_ARP_H */
+
+/* Define to 1 if you have the <net/if_dl.h> header file. */
+/* #undef HAVE_NET_IF_DL_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+/* #undef HAVE_NET_IF_H */
+
+/* Define to 1 if you have the <net/if_types.h> header file. */
+/* #undef HAVE_NET_IF_TYPES_H */
+
+/* Define to 1 if you have the <net/route.h> header file. */
+/* #undef HAVE_NET_ROUTE_H */
+
+/* Define to 1 if the system has the type `off_t'. */
+#define HAVE_OFF_T 1
+
+/* Define if OpenGL is present on the system */
+/* #undef HAVE_OPENGL */
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/* #undef HAVE_OPENSSL_SSL_H */
+
+/* Define if you have the Open Sound system */
+/* #undef HAVE_OSS */
+
+/* Define if you have the Open Sound system (MIDI interface) */
+/* #undef HAVE_OSS_MIDI */
+
+/* Define to 1 if you have the `pclose' function. */
+#define HAVE_PCLOSE 1
+
+/* Define to 1 if the system has the type `pid_t'. */
+#define HAVE_PID_T 1
+
+/* Define to 1 if you have the `popen' function. */
+#define HAVE_POPEN 1
+
+/* Define if we can use ppdev.h for parallel port access */
+/* #undef HAVE_PPDEV */
+
+/* Define to 1 if you have the `pread' function. */
+/* #undef HAVE_PREAD */
+
+/* Define to 1 if you have the <process.h> header file. */
+#define HAVE_PROCESS_H 1
+
+/* Define to 1 if you have the `pthread_getattr_np' function. */
+/* #undef HAVE_PTHREAD_GETATTR_NP */
+
+/* Define to 1 if you have the `pthread_get_stackaddr_np' function. */
+/* #undef HAVE_PTHREAD_GET_STACKADDR_NP */
+
+/* Define to 1 if you have the `pthread_get_stacksize_np' function. */
+/* #undef HAVE_PTHREAD_GET_STACKSIZE_NP */
+
+/* Define to 1 if you have the <pthread.h> header file. */
+/* #undef HAVE_PTHREAD_H */
+
+/* Define to 1 if the system has the type `pthread_rwlockattr_t'. */
+/* #undef HAVE_PTHREAD_RWLOCKATTR_T */
+
+/* Define to 1 if the system has the type `pthread_rwlock_t'. */
+/* #undef HAVE_PTHREAD_RWLOCK_T */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 if you have the `pwrite' function. */
+/* #undef HAVE_PWRITE */
+
+/* Define to 1 if you have the `readlink' function. */
+/* #undef HAVE_READLINK */
+
+/* Define to 1 if you have the <regex.h> header file. */
+/* #undef HAVE_REGEX_H */
+
+/* Define to 1 if you have the <resolv.h> header file. */
+/* #undef HAVE_RESOLV_H */
+
+/* Define to 1 if you have the `rfork' function. */
+/* #undef HAVE_RFORK */
+
+/* Define if we have SANE development environment */
+/* #undef HAVE_SANE */
+
+/* Define to 1 if you have the <sched.h> header file. */
+/* #undef HAVE_SCHED_H */
+
+/* Define to 1 if you have the `sched_yield' function. */
+/* #undef HAVE_SCHED_YIELD */
+
+/* Define to 1 if you have the <scsi/scsi.h> header file. */
+/* #undef HAVE_SCSI_SCSI_H */
+
+/* Define to 1 if you have the <scsi/scsi_ioctl.h> header file. */
+/* #undef HAVE_SCSI_SCSI_IOCTL_H */
+
+/* Define to 1 if you have the <scsi/sg.h> header file. */
+/* #undef HAVE_SCSI_SG_H */
+
+/* Define to 1 if you have the `select' function. */
+/* #undef HAVE_SELECT */
+
+/* Define to 1 if you have the `sendmsg' function. */
+/* #undef HAVE_SENDMSG */
+
+/* Define to 1 if you have the `settimeofday' function. */
+/* #undef HAVE_SETTIMEOFDAY */
+
+/* Define if sigaddset is supported */
+/* #undef HAVE_SIGADDSET */
+
+/* Define to 1 if you have the `sigaltstack' function. */
+/* #undef HAVE_SIGALTSTACK */
+
+/* Define to 1 if `si_fd' is member of `siginfo_t'. */
+/* #undef HAVE_SIGINFO_T_SI_FD */
+
+/* Define to 1 if you have the `sigprocmask' function. */
+/* #undef HAVE_SIGPROCMASK */
+
+/* Define to 1 if you have the sigsetjmp (and siglongjmp) function */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if the system has the type `sigset_t'. */
+/* #undef HAVE_SIGSET_T */
+
+/* Define to 1 if the system has the type `size_t'. */
+#define HAVE_SIZE_T 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the <soundcard.h> header file. */
+/* #undef HAVE_SOUNDCARD_H */
+
+/* Define to 1 if you have the `spawnvp' function. */
+#define HAVE_SPAWNVP 1
+
+/* Define to 1 if the system has the type `ssize_t'. */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if you have the `statfs' function. */
+/* #undef HAVE_STATFS */
+
+/* Define to 1 if you have the `statvfs' function. */
+/* #undef HAVE_STATVFS */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if `msg_accrights' is member of `struct msghdr'. */
+/* #undef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+
+/* Define to 1 if `name' is member of `struct option'. */
+#define HAVE_STRUCT_OPTION_NAME 1
+
+/* Define to 1 if `sa_len' is member of `struct sockaddr'. */
+/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+/* Define to 1 if `sun_len' is member of `struct sockaddr_un'. */
+/* #undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
+
+/* Define to 1 if `f_bavail' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_BAVAIL */
+
+/* Define to 1 if `f_bfree' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_BFREE */
+
+/* Define to 1 if `f_favail' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FAVAIL */
+
+/* Define to 1 if `f_ffree' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FFREE */
+
+/* Define to 1 if `f_frsize' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FRSIZE */
+
+/* Define to 1 if `f_namelen' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_NAMELEN */
+
+/* Define to 1 if `f_blocks' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_BLOCKS */
+
+/* Define to 1 if `st_blocks' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_BLOCKS */
+
+/* Define to 1 if you have the <syscall.h> header file. */
+/* #undef HAVE_SYSCALL_H */
+
+/* Define to 1 if you have the <sys/asoundlib.h> header file. */
+/* #undef HAVE_SYS_ASOUNDLIB_H */
+
+/* Define to 1 if you have the <sys/cdio.h> header file. */
+/* #undef HAVE_SYS_CDIO_H */
+
+/* Define to 1 if you have the <sys/elf32.h> header file. */
+/* #undef HAVE_SYS_ELF32_H */
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+/* #undef HAVE_SYS_EPOLL_H */
+
+/* Define to 1 if you have the <sys/errno.h> header file. */
+/* #undef HAVE_SYS_ERRNO_H */
+
+/* Define to 1 if you have the <sys/exec_elf.h> header file. */
+/* #undef HAVE_SYS_EXEC_ELF_H */
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+/* #undef HAVE_SYS_IOCTL_H */
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+/* #undef HAVE_SYS_IPC_H */
+
+/* Define to 1 if you have the <sys/link.h> header file. */
+/* #undef HAVE_SYS_LINK_H */
+
+/* Define to 1 if you have the <sys/lwp.h> header file. */
+/* #undef HAVE_SYS_LWP_H */
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+/* #undef HAVE_SYS_MODEM_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+/* #undef HAVE_SYS_MOUNT_H */
+
+/* Define to 1 if you have the <sys/msg.h> header file. */
+/* #undef HAVE_SYS_MSG_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/ptrace.h> header file. */
+/* #undef HAVE_SYS_PTRACE_H */
+
+/* Define to 1 if you have the <sys/reg.h> header file. */
+/* #undef HAVE_SYS_REG_H */
+
+/* Define to 1 if you have the <sys/scsiio.h> header file. */
+/* #undef HAVE_SYS_SCSIIO_H */
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+/* #undef HAVE_SYS_SHM_H */
+
+/* Define to 1 if you have the <sys/signal.h> header file. */
+/* #undef HAVE_SYS_SIGNAL_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+/* #undef HAVE_SYS_SOUNDCARD_H */
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+/* #undef HAVE_SYS_STATFS_H */
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+/* #undef HAVE_SYS_STATVFS_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/strtio.h> header file. */
+/* #undef HAVE_SYS_STRTIO_H */
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+/* #undef HAVE_SYS_SYSCALL_H */
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+/* #undef HAVE_SYS_SYSCTL_H */
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+/* #undef HAVE_SYS_TIMES_H */
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+/* #undef HAVE_SYS_UIO_H */
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+/* #undef HAVE_SYS_UN_H */
+
+/* Define to 1 if you have the <sys/user.h> header file. */
+/* #undef HAVE_SYS_USER_H */
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* Define to 1 if you have the <sys/vm86.h> header file. */
+/* #undef HAVE_SYS_VM86_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define to 1 if you have the `tcgetattr' function. */
+/* #undef HAVE_TCGETATTR */
+
+/* Define to 1 if you have the <termios.h> header file. */
+/* #undef HAVE_TERMIOS_H */
+
+/* Define to 1 if you have the `timegm' function. */
+/* #undef HAVE_TIMEGM */
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+/* #undef HAVE_UCONTEXT_H */
+
+/* Define to 1 if you have the <unicode/ubidi.h> header file. */
+/* #undef HAVE_UNICODE_UBIDI_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `usleep' function. */
+/* #undef HAVE_USLEEP */
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <valgrind/memcheck.h> header file. */
+/* #undef HAVE_VALGRIND_MEMCHECK_H */
+
+/* Define if we have va_copy */
+#define HAVE_VA_COPY 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `wait4' function. */
+/* #undef HAVE_WAIT4 */
+
+/* Define to 1 if you have the `waitpid' function. */
+/* #undef HAVE_WAITPID */
+
+/* Define to 1 if you have the <X11/extensions/shape.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_SHAPE_H */
+
+/* Define to 1 if you have the <X11/extensions/xf86dga.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XF86DGA_H */
+
+/* Define to 1 if you have the <X11/extensions/xf86vmode.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XF86VMODE_H */
+
+/* Define to 1 if you have the <X11/extensions/XInput.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XINPUT_H */
+
+/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XRANDR_H */
+
+/* Define to 1 if you have the <X11/extensions/Xrender.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XRENDER_H */
+
+/* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
+/* #undef HAVE_X11_EXTENSIONS_XSHM_H */
+
+/* Define to 1 if you have the <X11/XKBlib.h> header file. */
+/* #undef HAVE_X11_XKBLIB_H */
+
+/* Define to 1 if you have the <X11/Xlib.h> header file. */
+/* #undef HAVE_X11_XLIB_H */
+
+/* Define to 1 if you have the <X11/Xutil.h> header file. */
+/* #undef HAVE_X11_XUTIL_H */
+
+/* Define if you have the XKB extension */
+/* #undef HAVE_XKB */
+
+/* Define if Xrender has the XRenderSetPictureTransform function */
+/* #undef HAVE_XRENDERSETPICTURETRANSFORM */
+
+/* Define to 1 if you have the `_lwp_create' function. */
+/* #undef HAVE__LWP_CREATE */
+
+/* Define to 1 if you have the `_lwp_self' function. */
+/* #undef HAVE__LWP_SELF */
+
+/* Define to 1 if you have the `_pclose' function. */
+#define HAVE__PCLOSE 1
+
+/* Define to 1 if you have the `_popen' function. */
+#define HAVE__POPEN 1
+
+/* Define to 1 if you have the `_snprintf' function. */
+#define HAVE__SNPRINTF 1
+
+/* Define to 1 if you have the `_spawnvp' function. */
+#define HAVE__SPAWNVP 1
+
+/* Define to 1 if you have the `_stricmp' function. */
+#define HAVE__STRICMP 1
+
+/* Define to 1 if you have the `_strnicmp' function. */
+#define HAVE__STRNICMP 1
+
+/* Define to 1 if you have the `_vsnprintf' function. */
+#define HAVE__VSNPRINTF 1
+
+/* Define if we have __va_copy */
+#define HAVE___VA_COPY 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "wine-devel@winehq.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Wine"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Wine 20050211"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "wine"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "20050211"
+
+/* Define to the soname of the libcapi20 library. */
+/* #undef SONAME_LIBCAPI20 */
+
+/* Define to the soname of the libcrypto library. */
+/* #undef SONAME_LIBCRYPTO */
+
+/* Define to the soname of the libcups library. */
+/* #undef SONAME_LIBCUPS */
+
+/* Define to the soname of the libcurses library. */
+/* #undef SONAME_LIBCURSES */
+
+/* Define to the soname of the libfontconfig library. */
+/* #undef SONAME_LIBFONTCONFIG */
+
+/* Define to the soname of the libfreetype library. */
+/* #undef SONAME_LIBFREETYPE */
+
+/* Define to the soname of the libgif library. */
+/* #undef SONAME_LIBGIF */
+
+/* Define to the soname of the libGL library. */
+/* #undef SONAME_LIBGL */
+
+/* Define to the soname of the libjack library. */
+/* #undef SONAME_LIBJACK */
+
+/* Define to the soname of the libjpeg library. */
+/* #undef SONAME_LIBJPEG */
+
+/* Define to the soname of the liblcms library. */
+/* #undef SONAME_LIBLCMS */
+
+/* Define to the soname of the libncurses library. */
+/* #undef SONAME_LIBNCURSES */
+
+/* Define to the soname of the libssl library. */
+/* #undef SONAME_LIBSSL */
+
+/* Define to the soname of the libtxc_dxtn library. */
+/* #undef SONAME_LIBTXC_DXTN */
+
+/* Define to the soname of the libungif library. */
+/* #undef SONAME_LIBUNGIF */
+
+/* Define to the soname of the libX11 library. */
+/* #undef SONAME_LIBX11 */
+
+/* Define to the soname of the libXext library. */
+/* #undef SONAME_LIBXEXT */
+
+/* Define to the soname of the libXi library. */
+/* #undef SONAME_LIBXI */
+
+/* Define to the soname of the libXrandr library. */
+/* #undef SONAME_LIBXRANDR */
+
+/* Define to the soname of the libXrender library. */
+/* #undef SONAME_LIBXRENDER */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define if the struct statfs is defined by <sys/mount.h> */
+/* #undef STATFS_DEFINED_BY_SYS_MOUNT */
+
+/* Define if the struct statfs is defined by <sys/statfs.h> */
+/* #undef STATFS_DEFINED_BY_SYS_STATFS */
+
+/* Define if the struct statfs is defined by <sys/vfs.h> */
+/* #undef STATFS_DEFINED_BY_SYS_VFS */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#define X_DISPLAY_MISSING 1
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#define YYTEXT_POINTER 1
+
+/* Set this to 64 to enable 64-bit file support on Linux */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to a macro to generate an assembly function directive */
+#define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef"
+
+/* Define to a macro to generate an assembly name from a C symbol */
+#define __ASM_NAME(name) "_" name
+
+/* Define to the assembler keyword used to specify a word value */
+#define __ASM_SHORT ".short"
+
+/* Define to the assembler keyword used to specify an ASCII string */
+#define __ASM_STRING ".string"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
similarity index 72%
rename from reactos/include/wine/ver.h
rename to reactos/apps/utils/winetest/dist.rc
index 277f95d..989ba2d 100644 (file)
@@ -1,27 +1,25 @@
-/* Definitions for the VERsion infolibrary (VER.DLL)
- *
- * Copyright 1996 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Marked as obsolete:  Albert den Haan (Corel Corp) 1999-04-28
- * VER.H obsolete, include winver.h instead
- */
-#ifndef __WINE_VER_H
-#define __WINE_VER_H
-
-#include <winver.h>
-
-#endif /* __WINE_VER_H */
+/*\r
+ * Resources for the binary we distribute to testers\r
+ *\r
+ * Copyright 2004 Ferenc Wagner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include "winetest.rc"\r
+\r
+WINE_BUILD STRINGRES "build.id"\r
+BUILD_INFO STRINGRES "build.nfo"\r
+TESTS_URL  STRINGRES "tests.url"\r
diff --git a/reactos/apps/utils/winetest/gui.c b/reactos/apps/utils/winetest/gui.c
new file mode 100644 (file)
index 0000000..89a3108
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * GUI support
+ *
+ * Copyright 2004 Ferenc Wagner
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <windows.h>
+#include <commctrl.h>
+
+#include "resource.h"
+#include "winetest.h"
+
+/* Event object to signal successful window creation to main thread.
+ */
+HANDLE initEvent;
+
+/* Dialog handle
+ */
+HWND dialog;
+
+/* Progress data for the text* functions and for scaling.
+ */
+unsigned int progressMax, progressCurr;
+double progressScale;
+
+/* Progress group counter for the gui* functions.
+ */
+int progressGroup;
+
+char *
+renderString (va_list ap)
+{
+    const char *fmt = va_arg (ap, char*);
+    static char buffer[128];
+
+    vsnprintf (buffer, sizeof buffer, fmt, ap);
+    return buffer;
+}
+
+int
+MBdefault (int uType)
+{
+    static const int matrix[][4] = {{IDOK,    0,        0,        0},
+                                    {IDOK,    IDCANCEL, 0,        0},
+                                    {IDABORT, IDRETRY,  IDIGNORE, 0},
+                                    {IDYES,   IDNO,     IDCANCEL, 0},
+                                    {IDYES,   IDNO,     0,        0},
+                                    {IDRETRY, IDCANCEL, 0,        0}};
+    int type = uType & MB_TYPEMASK;
+    int def  = (uType & MB_DEFMASK) / MB_DEFBUTTON2;
+
+    return matrix[type][def];
+}
+
+/* report (R_STATUS, fmt, ...) */
+int
+textStatus (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    fputs (str, stderr);
+    fputc ('\n', stderr);
+    free (str);
+    return 0;
+}
+
+int
+guiStatus (va_list ap)
+{
+    size_t len;
+    char *str = vstrmake (&len, ap);
+
+    if (len > 128) str[129] = 0;
+    SetDlgItemText (dialog, IDC_SB, str);
+    free (str);
+    return 0;
+}
+
+/* report (R_PROGRESS, barnum, steps) */
+int
+textProgress (va_list ap)
+{
+    progressGroup = va_arg (ap, int);
+    progressMax = va_arg (ap, int);
+    progressCurr = 0;
+    return 0;
+}
+
+int
+guiProgress (va_list ap)
+{
+    unsigned int max;
+    HWND pb;
+
+    progressGroup = va_arg (ap, int);
+    progressMax = max = va_arg (ap, int);
+    progressCurr = 0;
+    if (max > 0xffff) {
+        progressScale = (double)0xffff / max;
+        max = 0xffff;
+    }
+    else progressScale = 1;
+    pb = GetDlgItem (dialog, IDC_PB0 + progressGroup * 2);
+    SendMessage (pb, PBM_SETRANGE, 0, MAKELPARAM (0, max));
+    SendMessage (pb, PBM_SETSTEP, (WPARAM)1, 0);
+    return 0;
+}
+
+/* report (R_STEP, fmt, ...) */
+int
+textStep (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    progressCurr++;
+    fputs (str, stderr);
+    fprintf (stderr, " (%d of %d)\n", progressCurr, progressMax);
+    free (str);
+    return 0;
+}
+
+int
+guiStep (va_list ap)
+{
+    const int pgID = IDC_ST0 + progressGroup * 2;
+    char *str = vstrmake (NULL, ap);
+    
+    progressCurr++;
+    SetDlgItemText (dialog, pgID, str);
+    SendDlgItemMessage (dialog, pgID+1, PBM_SETPOS,
+                        (WPARAM)(progressScale * progressCurr), 0);
+    free (str);
+    return 0;
+}
+
+/* report (R_DELTA, inc, fmt, ...) */
+int
+textDelta (va_list ap)
+{
+    const int inc = va_arg (ap, int);
+    char *str = vstrmake (NULL, ap);
+
+    progressCurr += inc;
+    fputs (str, stderr);
+    fprintf (stderr, " (%d of %d)\n", progressCurr, progressMax);
+    free (str);
+    return 0;
+}
+
+int
+guiDelta (va_list ap)
+{
+    const int inc = va_arg (ap, int);
+    const int pgID = IDC_ST0 + progressGroup * 2;
+    char *str = vstrmake (NULL, ap);
+
+    progressCurr += inc;
+    SetDlgItemText (dialog, pgID, str);
+    SendDlgItemMessage (dialog, pgID+1, PBM_SETPOS,
+                        (WPARAM)(progressScale * progressCurr), 0);
+    free (str);
+    return 0;
+}
+
+/* report (R_DIR, fmt, ...) */
+int
+textDir (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    fputs ("Temporary directory: ", stderr);
+    fputs (str, stderr);
+    fputc ('\n', stderr);
+    free (str);
+    return 0;
+}
+
+int
+guiDir (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    SetDlgItemText (dialog, IDC_DIR, str);
+    free (str);
+    return 0;
+}
+
+/* report (R_OUT, fmt, ...) */
+int
+textOut (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    fputs ("Log file: ", stderr);
+    fputs (str, stderr);
+    fputc ('\n', stderr);
+    free (str);
+    return 0;
+}
+
+int
+guiOut (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    SetDlgItemText (dialog, IDC_OUT, str);
+    free (str);
+    return 0;
+}
+
+/* report (R_WARNING, fmt, ...) */
+int
+textWarning (va_list ap)
+{
+    fputs ("Warning: ", stderr);
+    textStatus (ap);
+    return 0;
+}
+
+int
+guiWarning (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    MessageBox (dialog, str, "Warning", MB_ICONWARNING | MB_OK);
+    free (str);
+    return 0;
+}
+
+/* report (R_ERROR, fmt, ...) */
+int
+textError (va_list ap)
+{
+    fputs ("Error: ", stderr);
+    textStatus (ap);
+    return 0;
+}
+
+int
+guiError (va_list ap)
+{
+    char *str = vstrmake (NULL, ap);
+
+    MessageBox (dialog, str, "Error", MB_ICONERROR | MB_OK);
+    free (str);
+    return 0;
+}
+
+/* report (R_FATAL, fmt, ...) */
+int
+textFatal (va_list ap)
+{
+    textError (ap);
+    exit (1);
+}
+
+int
+guiFatal (va_list ap)
+{
+    guiError (ap);
+    exit (1);
+}
+
+/* report (R_ASK, type, fmt, ...) */
+int
+textAsk (va_list ap)
+{
+    int uType = va_arg (ap, int);
+    int ret = MBdefault (uType);
+    char *str = vstrmake (NULL, ap);
+
+    fprintf (stderr, "Question of type %d: %s\n"
+             "Returning default: %d\n", uType, str, ret);
+    free (str);
+    return ret;
+}
+
+int
+guiAsk (va_list ap)
+{
+    int uType = va_arg (ap, int);
+    char *str = vstrmake (NULL, ap);
+    int ret = MessageBox (dialog, str, "Question",
+                          MB_ICONQUESTION | uType);
+
+    free (str);
+    return ret;
+}
+
+/* Quiet functions */
+int
+qNoOp (va_list ap)
+{
+    return 0;
+}
+
+int
+qFatal (va_list ap)
+{
+    exit (1);
+}
+
+int
+qAsk (va_list ap)
+{
+    return MBdefault (va_arg (ap, int));
+}
+
+BOOL CALLBACK
+AboutProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg) {
+    case WM_COMMAND:
+        switch (LOWORD (wParam)) {
+        case IDCANCEL:
+            EndDialog (hwnd, IDCANCEL);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+BOOL CALLBACK
+DlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg) {
+    case WM_INITDIALOG:
+        SendMessage (hwnd, WM_SETICON, ICON_SMALL,
+                     (LPARAM)LoadIcon (GetModuleHandle (NULL),
+                                       MAKEINTRESOURCE (IDI_WINE)));
+        SendMessage (hwnd, WM_SETICON, ICON_BIG,
+                     (LPARAM)LoadIcon (GetModuleHandle (NULL),
+                                       MAKEINTRESOURCE (IDI_WINE)));
+        dialog = hwnd;
+        if (!SetEvent (initEvent)) {
+            report (R_STATUS, "Can't signal main thread: %d",
+                    GetLastError ());
+            EndDialog (hwnd, 2);
+        }
+        return TRUE;
+    case WM_CLOSE:
+        EndDialog (hwnd, 3);
+        return TRUE;
+    case WM_COMMAND:
+        switch (LOWORD (wParam)) {
+        case IDHELP:
+            DialogBox (GetModuleHandle (NULL),
+                       MAKEINTRESOURCE (IDD_ABOUT), hwnd, AboutProc);
+            return TRUE;
+        case IDABORT:
+            report (R_WARNING, "Not implemented");
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+DWORD WINAPI
+DlgThreadProc ()
+{
+    int ret;
+
+    InitCommonControls ();
+    ret = DialogBox (GetModuleHandle (NULL),
+                     MAKEINTRESOURCE (IDD_STATUS),
+                     NULL, DlgProc);
+    switch (ret) {
+    case 0:
+        report (R_WARNING, "Invalid parent handle");
+        break;
+    case 1:
+        report (R_WARNING, "DialogBox failed: %d",
+                GetLastError ());
+        break;
+    case 3:
+        exit (0);
+    default:
+        report (R_STATUS, "Dialog exited: %d", ret);
+    }
+    return 0;
+}
+
+int
+report (enum report_type t, ...)
+{
+    typedef int r_fun_t (va_list);
+
+    va_list ap;
+    int ret = 0;
+    static r_fun_t * const text_funcs[] =
+        {textStatus, textProgress, textStep, textDelta,
+         textDir, textOut,
+         textWarning, textError, textFatal, textAsk};
+    static r_fun_t * const GUI_funcs[] =
+        {guiStatus, guiProgress, guiStep, guiDelta,
+         guiDir, guiOut,
+         guiWarning, guiError, guiFatal, guiAsk};
+    static r_fun_t * const quiet_funcs[] =
+        {qNoOp, qNoOp, qNoOp, qNoOp,
+         qNoOp, qNoOp,
+         qNoOp, qNoOp, qFatal, qAsk};
+    static r_fun_t * const * funcs = NULL;
+
+    switch (t) {
+    case R_TEXTMODE:
+        funcs = text_funcs;
+        return 0;
+    case R_QUIET:
+        funcs = quiet_funcs;
+        return 0;
+    default:
+        break;
+    }
+
+    if (!funcs) {
+        HANDLE DlgThread;
+        DWORD DlgThreadID;
+
+        funcs = text_funcs;
+        initEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+        if (!initEvent)
+            report (R_STATUS, "Can't create event object: %d",
+                    GetLastError ());
+        else {
+            DlgThread = CreateThread (NULL, 0, DlgThreadProc,
+                                      NULL, 0, &DlgThreadID);
+            if (!DlgThread)
+                report (R_STATUS, "Can't create GUI thread: %d",
+                        GetLastError ());
+            else {
+                DWORD ret = WaitForSingleObject (initEvent, INFINITE);
+                switch (ret) {
+                case WAIT_OBJECT_0:
+                    funcs = GUI_funcs;
+                    break;
+                case WAIT_TIMEOUT:
+                    report (R_STATUS, "GUI creation timed out");
+                    break;
+                case WAIT_FAILED:
+                    report (R_STATUS, "Wait for GUI failed: %d",
+                            GetLastError ());
+                    break;
+                default:
+                    report (R_STATUS, "Wait returned %d",
+                            ret);
+                    break;
+                }
+            }
+        }
+    }
+        
+    va_start (ap, t);
+    if (t < sizeof text_funcs / sizeof text_funcs[0] &&
+        t < sizeof GUI_funcs / sizeof GUI_funcs[0] &&
+        t >= 0) ret = funcs[t](ap);
+    else report (R_WARNING, "unimplemented report type: %d", t);
+    va_end (ap);
+    return ret;
+}
diff --git a/reactos/apps/utils/winetest/main.c b/reactos/apps/utils/winetest/main.c
new file mode 100644 (file)
index 0000000..30f1cab
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Wine Conformance Test EXE
+ *
+ * Copyright 2003, 2004 Jakob Eriksson   (for Solid Form Sweden AB)
+ * Copyright 2003 Dimitrie O. Paun
+ * Copyright 2003 Ferenc Wagner
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This program is dedicated to Anna Lindh,
+ * Swedish Minister of Foreign Affairs.
+ * Anna was murdered September 11, 2003.
+ *
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+#include <windows.h>
+
+#include "winetest.h"
+#include "resource.h"
+
+struct wine_test
+{
+    char *name;
+    int resource;
+    int subtest_count;
+    char **subtests;
+    char *exename;
+};
+
+struct rev_info
+{
+    const char* file;
+    const char* rev;
+};
+
+static struct wine_test *wine_tests;
+static struct rev_info *rev_infos = NULL;
+static const char whitespace[] = " \t\r\n";
+
+static int running_under_wine ()
+{
+    HMODULE module = GetModuleHandleA("ntdll.dll");
+
+    if (!module) return 0;
+    return (GetProcAddress(module, "wine_server_call") != NULL);
+}
+
+static int running_on_visible_desktop ()
+{
+    FARPROC pGetProcessWindowStation = GetProcAddress(GetModuleHandle("user32.dll"), "GetProcessWindowStation");
+
+    if (pGetProcessWindowStation)
+    {
+        DWORD len;
+        HWINSTA wstation;
+        USEROBJECTFLAGS uoflags;
+        FARPROC pGetUserObjectInformationA = GetProcAddress(GetModuleHandle("user32.dll"), "GetUserObjectInformationA");
+
+        wstation = (HWINSTA)pGetProcessWindowStation();
+        assert(pGetUserObjectInformationA(wstation, UOI_FLAGS, &uoflags, sizeof(uoflags), &len));
+        return (uoflags.dwFlags & WSF_VISIBLE) != 0;
+    }
+    else
+        return IsWindowVisible(GetDesktopWindow());
+}
+
+void print_version ()
+{
+    OSVERSIONINFOEX ver;
+    BOOL ext;
+
+    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+    if (!(ext = GetVersionEx ((OSVERSIONINFO *) &ver)))
+    {
+       ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+       if (!GetVersionEx ((OSVERSIONINFO *) &ver))
+           report (R_FATAL, "Can't get OS version.");
+    }
+
+    xprintf ("    bRunningUnderWine=%d\n", running_under_wine ());
+    xprintf ("    bRunningOnVisibleDesktop=%d\n", running_on_visible_desktop ());
+    xprintf ("    dwMajorVersion=%ld\n    dwMinorVersion=%ld\n"
+             "    dwBuildNumber=%ld\n    PlatformId=%ld\n    szCSDVersion=%s\n",
+             ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
+             ver.dwPlatformId, ver.szCSDVersion);
+
+    if (!ext) return;
+
+    xprintf ("    wServicePackMajor=%d\n    wServicePackMinor=%d\n"
+             "    wSuiteMask=%d\n    wProductType=%d\n    wReserved=%d\n",
+             ver.wServicePackMajor, ver.wServicePackMinor, ver.wSuiteMask,
+             ver.wProductType, ver.wReserved);
+}
+
+static inline int is_dot_dir(const char* x)
+{
+    return ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))));
+}
+
+void remove_dir (const char *dir)
+{
+    HANDLE  hFind;
+    WIN32_FIND_DATA wfd;
+    char path[MAX_PATH];
+    size_t dirlen = strlen (dir);
+
+    /* Make sure the directory exists before going further */
+    memcpy (path, dir, dirlen);
+    strcpy (path + dirlen++, "\\*");
+    hFind = FindFirstFile (path, &wfd);
+    if (hFind == INVALID_HANDLE_VALUE) return;
+
+    do {
+        char *lp = wfd.cFileName;
+
+        if (!lp[0]) lp = wfd.cAlternateFileName; /* ? FIXME not (!lp) ? */
+        if (is_dot_dir (lp)) continue;
+        strcpy (path + dirlen, lp);
+        if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
+            remove_dir(path);
+        else if (!DeleteFile (path))
+            report (R_WARNING, "Can't delete file %s: error %d",
+                    path, GetLastError ());
+    } while (FindNextFile (hFind, &wfd));
+    FindClose (hFind);
+    if (!RemoveDirectory (dir))
+        report (R_WARNING, "Can't remove directory %s: error %d",
+                dir, GetLastError ());
+}
+
+const char* get_test_source_file(const char* test, const char* subtest)
+{
+    static const char* special_dirs[][2] = {
+       { "gdi32", "gdi"}, { "kernel32", "kernel" },
+        { "msacm32", "msacm" },
+       { "user32", "user" }, { "winspool.drv", "winspool" },
+       { "ws2_32", "winsock" }, { 0, 0 }
+    };
+    static char buffer[MAX_PATH];
+    int i;
+
+    for (i = 0; special_dirs[i][0]; i++) {
+       if (strcmp(test, special_dirs[i][0]) == 0) {
+           test = special_dirs[i][1];
+           break;
+       }
+    }
+
+    snprintf(buffer, sizeof(buffer), "dlls/%s/tests/%s.c", test, subtest);
+    return buffer;
+}
+
+const char* get_file_rev(const char* file)
+{
+    const struct rev_info* rev;
+    for(rev = rev_infos; rev->file; rev++) {
+       if (strcmp(rev->file, file) == 0) return rev->rev;
+    }
+
+    return "-";
+}
+
+void extract_rev_infos ()
+{
+    char revinfo[256], *p;
+    int size = 0, i, len;
+    HMODULE module = GetModuleHandle (NULL);
+
+    for (i = 0; TRUE; i++) {
+       if (i >= size) {
+           size += 100;
+           rev_infos = xrealloc (rev_infos, size * sizeof (*rev_infos));
+       }
+       memset(rev_infos + i, 0, sizeof(rev_infos[i]));
+
+        len = LoadStringA (module, REV_INFO+i, revinfo, sizeof(revinfo));
+        if (len == 0) break; /* end of revision info */
+       if (len >= sizeof(revinfo) - 1) 
+           report (R_FATAL, "Revision info too long.");
+       if(!(p = strrchr(revinfo, ':')))
+           report (R_FATAL, "Revision info malformed (i=%d)", i);
+       *p = 0;
+       rev_infos[i].file = strdup(revinfo);
+       rev_infos[i].rev = strdup(p + 1);
+    }
+}
+
+void* extract_rcdata (int id, int type, DWORD* size)
+{
+    HRSRC rsrc;
+    HGLOBAL hdl;
+    LPVOID addr;
+    
+    if (!(rsrc = FindResource (NULL, (LPTSTR)id, MAKEINTRESOURCE(type))) ||
+        !(*size = SizeofResource (0, rsrc)) ||
+        !(hdl = LoadResource (0, rsrc)) ||
+        !(addr = LockResource (hdl)))
+        return NULL;
+    return addr;
+}
+
+/* Fills in the name and exename fields */
+void
+extract_test (struct wine_test *test, const char *dir, int id)
+{
+    BYTE* code;
+    DWORD size;
+    FILE* fout;
+    int strlen, bufflen = 128;
+    char *exepos;
+
+    code = extract_rcdata (id, TESTRES, &size);
+    if (!code) report (R_FATAL, "Can't find test resource %d: %d",
+                       id, GetLastError ());
+    test->name = xmalloc (bufflen);
+    while ((strlen = LoadStringA (NULL, id, test->name, bufflen))
+           == bufflen - 1) {
+        bufflen *= 2;
+        test->name = xrealloc (test->name, bufflen);
+    }
+    if (!strlen) report (R_FATAL, "Can't read name of test %d.", id);
+    test->exename = strmake (NULL, "%s/%s", dir, test->name);
+    exepos = strstr (test->name, "_test.exe");
+    if (!exepos) report (R_FATAL, "Not an .exe file: %s", test->name);
+    *exepos = 0;
+    test->name = xrealloc (test->name, exepos - test->name + 1);
+    report (R_STEP, "Extracting: %s", test->name);
+
+    if (!(fout = fopen (test->exename, "wb")) ||
+        (fwrite (code, size, 1, fout) != 1) ||
+        fclose (fout)) report (R_FATAL, "Failed to write file %s.",
+                               test->exename);
+}
+
+/* Run a command for MS milliseconds.  If OUT != NULL, also redirect
+   stdout to there.
+
+   Return the exit status, -2 if can't create process or the return
+   value of WaitForSingleObject.
+ */
+int
+run_ex (char *cmd, const char *out, DWORD ms)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    int fd, oldstdout = -1;
+    DWORD wait, status;
+
+    GetStartupInfo (&si);
+    si.wShowWindow = SW_HIDE;
+    si.dwFlags = STARTF_USESHOWWINDOW;
+
+    if (out) {
+        fd = open (out, O_WRONLY | O_CREAT, 0666);
+        if (-1 == fd)
+            report (R_FATAL, "Can't open '%s': %d", out, errno);
+        oldstdout = dup (1);
+        if (-1 == oldstdout)
+            report (R_FATAL, "Can't save stdout: %d", errno);
+        if (-1 == dup2 (fd, 1))
+            report (R_FATAL, "Can't redirect stdout: %d", errno);
+        close (fd);
+    }
+
+    if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, 0,
+                         NULL, NULL, &si, &pi)) {
+        status = -2;
+    } else {
+        CloseHandle (pi.hThread);
+        wait = WaitForSingleObject (pi.hProcess, ms);
+        if (wait == WAIT_OBJECT_0) {
+            GetExitCodeProcess (pi.hProcess, &status);
+        } else {
+            switch (wait) {
+            case WAIT_FAILED:
+                report (R_ERROR, "Wait for '%s' failed: %d", cmd,
+                        GetLastError ());
+                break;
+            case WAIT_TIMEOUT:
+                report (R_ERROR, "Process '%s' timed out.", cmd);
+                break;
+            default:
+                report (R_ERROR, "Wait returned %d", wait);
+            }
+            status = wait;
+            if (!TerminateProcess (pi.hProcess, 257))
+                report (R_ERROR, "TerminateProcess failed: %d",
+                        GetLastError ());
+            wait = WaitForSingleObject (pi.hProcess, 5000);
+            switch (wait) {
+            case WAIT_FAILED:
+                report (R_ERROR,
+                        "Wait for termination of '%s' failed: %d",
+                        cmd, GetLastError ());
+                break;
+            case WAIT_OBJECT_0:
+                break;
+            case WAIT_TIMEOUT:
+                report (R_ERROR, "Can't kill process '%s'", cmd);
+                break;
+            default:
+                report (R_ERROR, "Waiting for termination: %d",
+                        wait);
+            }
+        }
+        CloseHandle (pi.hProcess);
+    }
+
+    if (out) {
+        close (1);
+        if (-1 == dup2 (oldstdout, 1))
+            report (R_FATAL, "Can't recover stdout: %d", errno);
+        close (oldstdout);
+    }
+    return status;
+}
+
+void
+get_subtests (const char *tempdir, struct wine_test *test, int id)
+{
+    char *subname;
+    FILE *subfile;
+    size_t total;
+    char buffer[8192], *index;
+    static const char header[] = "Valid test names:";
+    int allocated;
+
+    test->subtest_count = 0;
+
+    subname = tempnam (0, "sub");
+    if (!subname) report (R_FATAL, "Can't name subtests file.");
+
+    extract_test (test, tempdir, id);
+    run_ex (test->exename, subname, 5000);
+
+    subfile = fopen (subname, "r");
+    if (!subfile) {
+        report (R_ERROR, "Can't open subtests output of %s: %d",
+                test->name, errno);
+        goto quit;
+    }
+    total = fread (buffer, 1, sizeof buffer, subfile);
+    fclose (subfile);
+    if (sizeof buffer == total) {
+        report (R_ERROR, "Subtest list of %s too big.",
+                test->name, sizeof buffer);
+        goto quit;
+    }
+    buffer[total] = 0;
+
+    index = strstr (buffer, header);
+    if (!index) {
+        report (R_ERROR, "Can't parse subtests output of %s",
+                test->name);
+        goto quit;
+    }
+    index += sizeof header;
+
+    allocated = 10;
+    test->subtests = xmalloc (allocated * sizeof(char*));
+    index = strtok (index, whitespace);
+    while (index) {
+        if (test->subtest_count == allocated) {
+            allocated *= 2;
+            test->subtests = xrealloc (test->subtests,
+                                       allocated * sizeof(char*));
+        }
+        test->subtests[test->subtest_count++] = strdup (index);
+        index = strtok (NULL, whitespace);
+    }
+    test->subtests = xrealloc (test->subtests,
+                               test->subtest_count * sizeof(char*));
+
+ quit:
+    if (remove (subname))
+        report (R_WARNING, "Can't delete file '%s': %d",
+                subname, errno);
+    free (subname);
+}
+
+void
+run_test (struct wine_test* test, const char* subtest)
+{
+    int status;
+    const char* file = get_test_source_file(test->name, subtest);
+    const char* rev = get_file_rev(file);
+    char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
+
+    xprintf ("%s:%s start %s %s\n", test->name, subtest, file, rev);
+    status = run_ex (cmd, NULL, 120000);
+    free (cmd);
+    xprintf ("%s:%s done (%d)\n", test->name, subtest, status);
+}
+
+BOOL CALLBACK
+EnumTestFileProc (HMODULE hModule, LPCTSTR lpszType,
+                  LPTSTR lpszName, LONG_PTR lParam)
+{
+    (*(int*)lParam)++;
+    return TRUE;
+}
+
+char *
+run_tests (char *logname, const char *tag)
+{
+    int nr_of_files = 0, nr_of_tests = 0, i;
+    char *tempdir;
+    int logfile;
+    char *strres, *eol, *nextline;
+    DWORD strsize;
+
+    SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+
+    if (!logname) {
+        logname = tempnam (0, "res");
+        if (!logname) report (R_FATAL, "Can't name logfile.");
+    }
+    report (R_OUT, logname);
+
+    logfile = open (logname, O_WRONLY | O_CREAT | O_EXCL | O_APPEND,
+                    0666);
+    if (-1 == logfile) {
+        if (EEXIST == errno)
+            report (R_FATAL, "File %s already exists.", logname);
+        else report (R_FATAL, "Could not open logfile: %d", errno);
+    }
+    if (-1 == dup2 (logfile, 1))
+        report (R_FATAL, "Can't redirect stdout: %d", errno);
+    close (logfile);
+
+    tempdir = tempnam (0, "wct");
+    if (!tempdir)
+        report (R_FATAL, "Can't name temporary dir (check %%TEMP%%).");
+    report (R_DIR, tempdir);
+    if (!CreateDirectory (tempdir, NULL))
+        report (R_FATAL, "Could not create directory: %s", tempdir);
+
+    xprintf ("Version 3\n");
+    strres = extract_rcdata (WINE_BUILD, STRINGRES, &strsize);
+    xprintf ("Tests from build ");
+    if (strres) xprintf ("%.*s", strsize, strres);
+    else xprintf ("-\n");
+    strres = extract_rcdata (TESTS_URL, STRINGRES, &strsize);
+    xprintf ("Archive: ");
+    if (strres) xprintf ("%.*s", strsize, strres);
+    else xprintf ("-\n");
+    xprintf ("Tag: %s\n", tag?tag:"");
+    xprintf ("Build info:\n");
+    strres = extract_rcdata (BUILD_INFO, STRINGRES, &strsize);
+    while (strres) {
+        eol = memchr (strres, '\n', strsize);
+        if (!eol) {
+            nextline = NULL;
+            eol = strres + strsize;
+        } else {
+            strsize -= eol - strres + 1;
+            nextline = strsize?eol+1:NULL;
+            if (eol > strres && *(eol-1) == '\r') eol--;
+        }
+        xprintf ("    %.*s\n", eol-strres, strres);
+        strres = nextline;
+    }
+    xprintf ("Operating system version:\n");
+    print_version ();
+    xprintf ("Test output:\n" );
+
+    report (R_STATUS, "Counting tests");
+    if (!EnumResourceNames (NULL, MAKEINTRESOURCE(TESTRES),
+                            EnumTestFileProc, (LPARAM)&nr_of_files))
+        report (R_FATAL, "Can't enumerate test files: %d",
+                GetLastError ());
+    wine_tests = xmalloc (nr_of_files * sizeof wine_tests[0]);
+
+    report (R_STATUS, "Extracting tests");
+    report (R_PROGRESS, 0, nr_of_files);
+    for (i = 0; i < nr_of_files; i++) {
+        get_subtests (tempdir, wine_tests+i, i);
+        nr_of_tests += wine_tests[i].subtest_count;
+    }
+    report (R_DELTA, 0, "Extracting: Done");
+
+    report (R_STATUS, "Running tests");
+    report (R_PROGRESS, 1, nr_of_tests);
+    for (i = 0; i < nr_of_files; i++) {
+        struct wine_test *test = wine_tests + i;
+        int j;
+
+       for (j = 0; j < test->subtest_count; j++) {
+            report (R_STEP, "Running: %s:%s", test->name,
+                    test->subtests[j]);
+           run_test (test, test->subtests[j]);
+        }
+    }
+    report (R_DELTA, 0, "Running: Done");
+
+    report (R_STATUS, "Cleaning up");
+    close (1);
+    remove_dir (tempdir);
+    free (tempdir);
+    free (wine_tests);
+
+    return logname;
+}
+
+void
+usage ()
+{
+    fprintf (stderr, "\
+Usage: winetest [OPTION]...\n\n\
+  -c       console mode, no GUI\n\
+  -e       preserve the environment\n\
+  -h       print this message and exit\n\
+  -q       quiet mode, no output at all\n\
+  -o FILE  put report into FILE, do not submit\n\
+  -s FILE  submit FILE, do not run tests\n\
+  -t TAG   include TAG of characters [-.0-9a-zA-Z] in the report\n");
+}
+
+int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
+                    LPSTR cmdLine, int cmdShow)
+{
+    char *logname = NULL;
+    const char *cp, *submit = NULL, *tag = NULL;
+    int reset_env = 1;
+
+    if (!running_on_visible_desktop ()) {
+        report (R_ERROR, "Tests must be run on a visible desktop");
+        exit (2);
+    }
+
+    /* initialize the revision information first */
+    extract_rev_infos();
+
+    cmdLine = strtok (cmdLine, whitespace);
+    while (cmdLine) {
+        if (cmdLine[0] != '-' || cmdLine[2]) {
+            report (R_ERROR, "Not a single letter option: %s", cmdLine);
+            usage ();
+            exit (2);
+        }
+        switch (cmdLine[1]) {
+        case 'c':
+            report (R_TEXTMODE);
+            break;
+        case 'e':
+            reset_env = 0;
+            break;
+        case 'h':
+            usage ();
+            exit (0);
+        case 'q':
+            report (R_QUIET);
+            break;
+        case 's':
+            submit = strtok (NULL, whitespace);
+            if (tag)
+                report (R_WARNING, "ignoring tag for submission");
+            send_file (submit);
+            break;
+        case 'o':
+            logname = strtok (NULL, whitespace);
+            break;
+        case 't':
+            tag = strtok (NULL, whitespace);
+            cp = badtagchar (tag);
+            if (cp) {
+                report (R_ERROR, "invalid char in tag: %c", *cp);
+                usage ();
+                exit (2);
+            }
+            break;
+        default:
+            report (R_ERROR, "invalid option: -%c", cmdLine[1]);
+            usage ();
+            exit (2);
+        }
+        cmdLine = strtok (NULL, whitespace);
+    }
+    if (!submit) {
+        if (reset_env && (putenv ("WINETEST_PLATFORM=windows") ||
+                          putenv ("WINETEST_DEBUG=1") || 
+                          putenv ("WINETEST_INTERACTIVE=0") ||
+                          putenv ("WINETEST_REPORT_SUCCESS=0")))
+            report (R_FATAL, "Could not reset environment: %d", errno);
+
+        report (R_STATUS, "Starting up");
+        if (!logname) {
+            logname = run_tests (NULL, tag);
+            if (report (R_ASK, MB_YESNO, "Do you want to submit the "
+                        "test results?") == IDYES)
+                if (!send_file (logname) && remove (logname))
+                    report (R_WARNING, "Can't remove logfile: %d.", errno);
+            free (logname);
+        } else run_tests (logname, tag);
+        report (R_STATUS, "Finished");
+    }
+    exit (0);
+}
diff --git a/reactos/apps/utils/winetest/makefile b/reactos/apps/utils/winetest/makefile
new file mode 100644 (file)
index 0000000..08fb0f3
--- /dev/null
@@ -0,0 +1,23 @@
+PATH_TO_TOP = ../../..\r
+\r
+TARGET_TYPE = program\r
+\r
+TARGET_APPTYPE = console\r
+\r
+TARGET_NAME = winetest\r
+\r
+TARGET_SDKLIBS = comctl32.a comdlg32.a ws2_32.a\r
+\r
+TARGET_OBJECTS = \\r
+       main.o \\r
+       send.o \\r
+       util.o \\r
+       gui.o\r
+\r
+TARGET_CFLAGS = -Wall -Werror -D__USE_W32API\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+# EOF\r
diff --git a/reactos/apps/utils/winetest/port.h b/reactos/apps/utils/winetest/port.h
new file mode 100644 (file)
index 0000000..57a7a87
--- /dev/null
@@ -0,0 +1,469 @@
+/*\r
+ * Wine porting definitions\r
+ *\r
+ * Copyright 1996 Alexandre Julliard\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#ifndef __WINE_WINE_PORT_H\r
+#define __WINE_WINE_PORT_H\r
+\r
+#ifndef __WINE_CONFIG_H\r
+# error You must include config.h to use this header\r
+#endif\r
+\r
+#define _GNU_SOURCE  /* for pread/pwrite */\r
+#include <fcntl.h>\r
+#include <math.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#ifdef HAVE_DIRECT_H\r
+# include <direct.h>\r
+#endif\r
+#ifdef HAVE_IO_H\r
+# include <io.h>\r
+#endif\r
+#ifdef HAVE_PROCESS_H\r
+# include <process.h>\r
+#endif\r
+#include <string.h>\r
+#ifdef HAVE_UNISTD_H\r
+# include <unistd.h>\r
+#endif\r
+\r
+\r
+/****************************************************************\r
+ * Type definitions\r
+ */\r
+\r
+#ifndef HAVE_MODE_T\r
+typedef int mode_t;\r
+#endif\r
+#ifndef HAVE_OFF_T\r
+typedef long off_t;\r
+#endif\r
+#ifndef HAVE_PID_T\r
+typedef int pid_t;\r
+#endif\r
+#ifndef HAVE_SIZE_T\r
+typedef unsigned int size_t;\r
+#endif\r
+#ifndef HAVE_SSIZE_T\r
+typedef int ssize_t;\r
+#endif\r
+#ifndef HAVE_FSBLKCNT_T\r
+typedef unsigned long fsblkcnt_t;\r
+#endif\r
+#ifndef HAVE_FSFILCNT_T\r
+typedef unsigned long fsfilcnt_t;\r
+#endif\r
+\r
+#ifndef HAVE_STRUCT_STATVFS_F_BLOCKS\r
+struct statvfs\r
+{\r
+    unsigned long f_bsize;\r
+    unsigned long f_frsize;\r
+    fsblkcnt_t    f_blocks;\r
+    fsblkcnt_t    f_bfree;\r
+    fsblkcnt_t    f_bavail;\r
+    fsfilcnt_t    f_files;\r
+    fsfilcnt_t    f_ffree;\r
+    fsfilcnt_t    f_favail;\r
+    unsigned long f_fsid;\r
+    unsigned long f_flag;\r
+    unsigned long f_namemax;\r
+};\r
+#endif /* HAVE_STRUCT_STATVFS_F_BLOCKS */\r
+\r
+\r
+/****************************************************************\r
+ * Macro definitions\r
+ */\r
+\r
+#ifdef HAVE_DLFCN_H\r
+#include <dlfcn.h>\r
+#else\r
+#define RTLD_LAZY    0x001\r
+#define RTLD_NOW     0x002\r
+#define RTLD_GLOBAL  0x100\r
+#endif\r
+\r
+#if !defined(HAVE_FTRUNCATE) && defined(HAVE_CHSIZE)\r
+#define ftruncate chsize\r
+#endif\r
+\r
+#if !defined(HAVE_POPEN) && defined(HAVE__POPEN)\r
+#define popen _popen\r
+#endif\r
+\r
+#if !defined(HAVE_PCLOSE) && defined(HAVE__PCLOSE)\r
+#define pclose _pclose\r
+#endif\r
+\r
+#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)\r
+#define snprintf _snprintf\r
+#endif\r
+\r
+#if !defined(HAVE_VSNPRINTF) && defined(HAVE__VSNPRINTF)\r
+#define vsnprintf _vsnprintf\r
+#endif\r
+\r
+#ifndef S_ISLNK\r
+# define S_ISLNK(mod) (0)\r
+#endif\r
+\r
+#ifndef S_ISSOCK\r
+# define S_ISSOCK(mod) (0)\r
+#endif\r
+\r
+#ifndef S_ISDIR\r
+# define S_ISDIR(mod) (((mod) & _S_IFMT) == _S_IFDIR)\r
+#endif\r
+\r
+#ifndef S_ISCHR\r
+# define S_ISCHR(mod) (((mod) & _S_IFMT) == _S_IFCHR)\r
+#endif\r
+\r
+#ifndef S_ISFIFO\r
+# define S_ISFIFO(mod) (((mod) & _S_IFMT) == _S_IFIFO)\r
+#endif\r
+\r
+#ifndef S_ISREG\r
+# define S_ISREG(mod) (((mod) & _S_IFMT) == _S_IFREG)\r
+#endif\r
+\r
+#ifndef S_IWUSR\r
+# define S_IWUSR 0\r
+#endif\r
+\r
+/* So we open files in 64 bit access mode on Linux */\r
+#ifndef O_LARGEFILE\r
+# define O_LARGEFILE 0\r
+#endif\r
+\r
+#ifndef O_NONBLOCK\r
+# define O_NONBLOCK 0\r
+#endif\r
+\r
+#ifndef O_BINARY\r
+# define O_BINARY 0\r
+#endif\r
+\r
+#if !defined(S_IXUSR) && defined(S_IEXEC)\r
+# define S_IXUSR S_IEXEC\r
+#endif\r
+#if !defined(S_IXGRP) && defined(S_IEXEC)\r
+# define S_IXGRP S_IEXEC\r
+#endif\r
+#if !defined(S_IXOTH) && defined(S_IEXEC)\r
+# define S_IXOTH S_IEXEC\r
+#endif\r
+\r
+\r
+/****************************************************************\r
+ * Constants\r
+ */\r
+\r
+#ifndef M_PI\r
+#define M_PI 3.14159265358979323846\r
+#endif\r
+\r
+#ifndef M_PI_2\r
+#define M_PI_2 1.570796326794896619\r
+#endif\r
+\r
+\r
+/* Macros to define assembler functions somewhat portably */\r
+\r
+#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__APPLE__)\r
+# define __ASM_GLOBAL_FUNC(name,code) \\r
+      __asm__( ".text\n\t" \\r
+               ".align 4\n\t" \\r
+               ".globl " __ASM_NAME(#name) "\n\t" \\r
+               __ASM_FUNC(#name) "\n" \\r
+               __ASM_NAME(#name) ":\n\t" \\r
+               code \\r
+               "\n\t.previous" );\r
+#else  /* defined(__GNUC__) && !defined(__MINGW32__) && !defined(__APPLE__)  */\r
+# define __ASM_GLOBAL_FUNC(name,code) \\r
+      void __asm_dummy_##name(void) { \\r
+          asm( ".align 4\n\t" \\r
+               ".globl " __ASM_NAME(#name) "\n\t" \\r
+               __ASM_FUNC(#name) "\n" \\r
+               __ASM_NAME(#name) ":\n\t" \\r
+               code ); \\r
+      }\r
+#endif  /* __GNUC__ */\r
+\r
+\r
+/* Constructor functions */\r
+\r
+#ifdef __GNUC__\r
+# define DECL_GLOBAL_CONSTRUCTOR(func) \\r
+    static void func(void) __attribute__((constructor)); \\r
+    static void func(void)\r
+#elif defined(__i386__)\r
+# define DECL_GLOBAL_CONSTRUCTOR(func) \\r
+    static void __dummy_init_##func(void) { \\r
+        asm(".section .init,\"ax\"\n\t" \\r
+            "call " #func "\n\t" \\r
+            ".previous"); } \\r
+    static void func(void)\r
+#elif defined(__sparc__)\r
+# define DECL_GLOBAL_CONSTRUCTOR(func) \\r
+    static void __dummy_init_##func(void) { \\r
+        asm("\t.section \".init\",#alloc,#execinstr\n" \\r
+            "\tcall " #func "\n" \\r
+            "\tnop\n" \\r
+            "\t.section \".text\",#alloc,#execinstr\n" ); } \\r
+    static void func(void)\r
+#else\r
+# error You must define the DECL_GLOBAL_CONSTRUCTOR macro for your platform\r
+#endif\r
+\r
+\r
+/* Register functions */\r
+\r
+#ifdef __i386__\r
+#define DEFINE_REGS_ENTRYPOINT( name, fn, args, pop_args ) \\r
+    __ASM_GLOBAL_FUNC( name, \\r
+                       "call " __ASM_NAME("__wine_call_from_32_regs") "\n\t" \\r
+                       ".long " __ASM_NAME(#fn) "\n\t" \\r
+                       ".byte " #args "," #pop_args )\r
+/* FIXME: add support for other CPUs */\r
+#endif  /* __i386__ */\r
+\r
+\r
+/****************************************************************\r
+ * Function definitions (only when using libwine_port)\r
+ */\r
+\r
+#ifndef NO_LIBWINE_PORT\r
+\r
+#ifndef HAVE_FSTATVFS\r
+int fstatvfs( int fd, struct statvfs *buf );\r
+#endif\r
+\r
+#ifndef HAVE_GETOPT_LONG\r
+extern char *optarg;\r
+extern int optind;\r
+extern int opterr;\r
+extern int optopt;\r
+struct option;\r
+\r
+#ifndef HAVE_STRUCT_OPTION_NAME\r
+struct option\r
+{\r
+    const char *name;\r
+    int has_arg;\r
+    int *flag;\r
+    int val;\r
+};\r
+#endif\r
+\r
+extern int getopt_long (int ___argc, char *const *___argv,\r
+                        const char *__shortopts,\r
+                        const struct option *__longopts, int *__longind);\r
+extern int getopt_long_only (int ___argc, char *const *___argv,\r
+                             const char *__shortopts,\r
+                             const struct option *__longopts, int *__longind);\r
+#endif  /* HAVE_GETOPT_LONG */\r
+\r
+#ifndef HAVE_FFS\r
+int ffs( int x );\r
+#endif\r
+\r
+#ifndef HAVE_FUTIMES\r
+struct timeval;\r
+int futimes(int fd, const struct timeval tv[2]);\r
+#endif\r
+\r
+#ifndef HAVE_GETPAGESIZE\r
+size_t getpagesize(void);\r
+#endif  /* HAVE_GETPAGESIZE */\r
+\r
+#ifndef HAVE_GETTID\r
+pid_t gettid(void);\r
+#endif /* HAVE_GETTID */\r
+\r
+#ifndef HAVE_LSTAT\r
+int lstat(const char *file_name, struct stat *buf);\r
+#endif /* HAVE_LSTAT */\r
+\r
+#ifndef HAVE_MEMMOVE\r
+void *memmove(void *dest, const void *src, size_t len);\r
+#endif /* !defined(HAVE_MEMMOVE) */\r
+\r
+#ifndef HAVE_PREAD\r
+ssize_t pread( int fd, void *buf, size_t count, off_t offset );\r
+#endif /* HAVE_PREAD */\r
+\r
+#ifndef HAVE_PWRITE\r
+ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset );\r
+#endif /* HAVE_PWRITE */\r
+\r
+#ifndef HAVE_READLINK\r
+int readlink( const char *path, char *buf, size_t size );\r
+#endif /* HAVE_READLINK */\r
+\r
+#ifndef HAVE_SIGSETJMP\r
+# include <setjmp.h>\r
+typedef jmp_buf sigjmp_buf;\r
+int sigsetjmp( sigjmp_buf buf, int savesigs );\r
+void siglongjmp( sigjmp_buf buf, int val );\r
+#endif /* HAVE_SIGSETJMP */\r
+\r
+#ifndef HAVE_STATVFS\r
+int statvfs( const char *path, struct statvfs *buf );\r
+#endif\r
+\r
+#ifndef HAVE_STRNCASECMP\r
+# ifndef HAVE__STRNICMP\r
+int strncasecmp(const char *str1, const char *str2, size_t n);\r
+# else\r
+# define strncasecmp _strnicmp\r
+# endif\r
+#endif /* !defined(HAVE_STRNCASECMP) */\r
+\r
+#ifndef HAVE_STRERROR\r
+const char *strerror(int err);\r
+#endif /* !defined(HAVE_STRERROR) */\r
+\r
+#ifndef HAVE_STRCASECMP\r
+# ifndef HAVE__STRICMP\r
+int strcasecmp(const char *str1, const char *str2);\r
+# else\r
+# define strcasecmp _stricmp\r
+# endif\r
+#endif /* !defined(HAVE_STRCASECMP) */\r
+\r
+#ifndef HAVE_USLEEP\r
+int usleep (unsigned int useconds);\r
+#endif /* !defined(HAVE_USLEEP) */\r
+\r
+#ifdef __i386__\r
+static inline void *memcpy_unaligned( void *dst, const void *src, size_t size )\r
+{\r
+    return memcpy( dst, src, size );\r
+}\r
+#else\r
+extern void *memcpy_unaligned( void *dst, const void *src, size_t size );\r
+#endif /* __i386__ */\r
+\r
+extern int mkstemps(char *template, int suffix_len);\r
+\r
+/* Process creation flags */\r
+#ifndef _P_WAIT\r
+# define _P_WAIT    0\r
+# define _P_NOWAIT  1\r
+# define _P_OVERLAY 2\r
+# define _P_NOWAITO 3\r
+# define _P_DETACH  4\r
+#endif\r
+#ifndef HAVE_SPAWNVP\r
+extern int spawnvp(int mode, const char *cmdname, const char * const argv[]);\r
+#endif\r
+\r
+/* Interlocked functions */\r
+\r
+#if defined(__i386__) && defined(__GNUC__)\r
+\r
+extern inline long interlocked_cmpxchg( long *dest, long xchg, long compare );\r
+extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );\r
+extern inline long interlocked_xchg( long *dest, long val );\r
+extern inline void *interlocked_xchg_ptr( void **dest, void *val );\r
+extern inline long interlocked_xchg_add( long *dest, long incr );\r
+\r
+extern inline long interlocked_cmpxchg( long *dest, long xchg, long compare )\r
+{\r
+    long ret;\r
+    __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"\r
+                          : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );\r
+    return ret;\r
+}\r
+\r
+extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )\r
+{\r
+    void *ret;\r
+    __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"\r
+                          : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );\r
+    return ret;\r
+}\r
+\r
+extern inline long interlocked_xchg( long *dest, long val )\r
+{\r
+    long ret;\r
+    __asm__ __volatile__( "lock; xchgl %0,(%1)"\r
+                          : "=r" (ret) : "r" (dest), "0" (val) : "memory" );\r
+    return ret;\r
+}\r
+\r
+extern inline void *interlocked_xchg_ptr( void **dest, void *val )\r
+{\r
+    void *ret;\r
+    __asm__ __volatile__( "lock; xchgl %0,(%1)"\r
+                          : "=r" (ret) : "r" (dest), "0" (val) : "memory" );\r
+    return ret;\r
+}\r
+\r
+extern inline long interlocked_xchg_add( long *dest, long incr )\r
+{\r
+    long ret;\r
+    __asm__ __volatile__( "lock; xaddl %0,(%1)"\r
+                          : "=r" (ret) : "r" (dest), "0" (incr) : "memory" );\r
+    return ret;\r
+}\r
+\r
+#else  /* __i386___ && __GNUC__ */\r
+\r
+extern long interlocked_cmpxchg( long *dest, long xchg, long compare );\r
+extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );\r
+extern long interlocked_xchg( long *dest, long val );\r
+extern void *interlocked_xchg_ptr( void **dest, void *val );\r
+extern long interlocked_xchg_add( long *dest, long incr );\r
+\r
+#endif  /* __i386___ && __GNUC__ */\r
+\r
+#else /* NO_LIBWINE_PORT */\r
+\r
+#define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable\r
+\r
+#define ffs                     __WINE_NOT_PORTABLE(ffs)\r
+#define fstatvfs                __WINE_NOT_PORTABLE(fstatvfs)\r
+#define futimes                 __WINE_NOT_PORTABLE(futimes)\r
+#define getopt_long             __WINE_NOT_PORTABLE(getopt_long)\r
+#define getopt_long_only        __WINE_NOT_PORTABLE(getopt_long_only)\r
+#define getpagesize             __WINE_NOT_PORTABLE(getpagesize)\r
+#define interlocked_cmpxchg     __WINE_NOT_PORTABLE(interlocked_cmpxchg)\r
+#define interlocked_cmpxchg_ptr __WINE_NOT_PORTABLE(interlocked_cmpxchg_ptr)\r
+#define interlocked_xchg        __WINE_NOT_PORTABLE(interlocked_xchg)\r
+#define interlocked_xchg_ptr    __WINE_NOT_PORTABLE(interlocked_xchg_ptr)\r
+#define interlocked_xchg_add    __WINE_NOT_PORTABLE(interlocked_xchg_add)\r
+#define lstat                   __WINE_NOT_PORTABLE(lstat)\r
+#define memcpy_unaligned        __WINE_NOT_PORTABLE(memcpy_unaligned)\r
+#define memmove                 __WINE_NOT_PORTABLE(memmove)\r
+#define pread                   __WINE_NOT_PORTABLE(pread)\r
+#define pwrite                  __WINE_NOT_PORTABLE(pwrite)\r
+#define spawnvp                 __WINE_NOT_PORTABLE(spawnvp)\r
+#define statvfs                 __WINE_NOT_PORTABLE(statvfs)\r
+#define strcasecmp              __WINE_NOT_PORTABLE(strcasecmp)\r
+#define strerror                __WINE_NOT_PORTABLE(strerror)\r
+#define strncasecmp             __WINE_NOT_PORTABLE(strncasecmp)\r
+#define usleep                  __WINE_NOT_PORTABLE(usleep)\r
+\r
+#endif /* NO_LIBWINE_PORT */\r
+\r
+#endif /* !defined(__WINE_WINE_PORT_H) */\r
diff --git a/reactos/apps/utils/winetest/resource.h b/reactos/apps/utils/winetest/resource.h
new file mode 100644 (file)
index 0000000..0c6a5af
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Resource definitions\r
+ *\r
+ * Copyright 2004 Ferenc Wagner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#define IDI_WINE 1\r
+\r
+#define IDD_STATUS 100\r
+#define IDD_ABOUT  101\r
+\r
+#define IDC_ST0 1000\r
+#define IDC_PB0 1001\r
+#define IDC_ST1 1002\r
+#define IDC_PB1 1003\r
+#define IDC_ST2 1004\r
+#define IDC_PB2 1005\r
+\r
+#define IDC_DIR 2000\r
+#define IDC_OUT 2001\r
+\r
+#define IDC_SB  3000\r
+\r
+#define IDC_EDIT  4000\r
+#define IDC_ABOUT 4001\r
+\r
+/* Resource types */\r
+\r
+#define TESTRES   1000\r
+#define STRINGRES 1001\r
+\r
+/* String resources */\r
+\r
+#define WINE_BUILD 10000\r
+#define BUILD_INFO 10001\r
+#define TESTS_URL  10002\r
+\r
+/* Revision info strings start from this index: */\r
+#define REV_INFO 30000\r
diff --git a/reactos/apps/utils/winetest/send.c b/reactos/apps/utils/winetest/send.c
new file mode 100644 (file)
index 0000000..8ec105a
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * HTTP handling functions.
+ *
+ * Copyright 2003 Ferenc Wagner
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <winsock.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "winetest.h"
+
+SOCKET
+open_http (const char *server)
+{
+    WSADATA wsad;
+    struct sockaddr_in sa;
+    SOCKET s;
+
+    report (R_STATUS, "Opening HTTP connection to %s", server);
+    if (WSAStartup (MAKEWORD (2,2), &wsad)) return INVALID_SOCKET;
+
+    sa.sin_family = AF_INET;
+    sa.sin_port = htons (80);
+    sa.sin_addr.s_addr = inet_addr (server);
+    if (sa.sin_addr.s_addr == INADDR_NONE) {
+        struct hostent *host = gethostbyname (server);
+        if (!host) {
+            report (R_ERROR, "Hostname lookup failed for %s", server);
+            goto failure;
+        }
+        sa.sin_addr.s_addr = ((struct in_addr *)host->h_addr)->s_addr;
+    }
+    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (s == INVALID_SOCKET) {
+        report (R_ERROR, "Can't open network socket: %d",
+                WSAGetLastError ());
+        goto failure;
+    }
+    if (!connect (s, (struct sockaddr*)&sa, sizeof (struct sockaddr_in)))
+        return s;
+
+    report (R_ERROR, "Can't connect: %d", WSAGetLastError ());
+    closesocket (s);
+ failure:
+    WSACleanup ();
+    return INVALID_SOCKET;
+}
+
+int
+close_http (SOCKET s)
+{
+    int ret;
+
+    ret = closesocket (s);
+    return (WSACleanup () || ret);
+}
+
+int
+send_buf (SOCKET s, const char *buf, size_t length)
+{
+    int sent;
+
+    while (length > 0) {
+        sent = send (s, buf, length, 0);
+        if (sent == SOCKET_ERROR) return 1;
+        buf += sent;
+        length -= sent;
+    }
+    return 0;
+}
+
+int
+send_str (SOCKET s, ...)
+{
+    va_list ap;
+    char *p;
+    int ret;
+    size_t len;
+
+    va_start (ap, s);
+    p = vstrmake (&len, ap);
+    va_end (ap);
+    if (!p) return 1;
+    ret = send_buf (s, p, len);
+    free (p);
+    return ret;
+}
+
+int
+send_file (const char *name)
+{
+    SOCKET s;
+    FILE *f;
+#define BUFLEN 8192
+    unsigned char buffer[BUFLEN+1];
+    size_t bytes_read, total, filesize;
+    char *str;
+    int ret;
+
+    /* RFC 2616 */
+#define SEP "--8<--cut-here--8<--"
+    static const char head[] = "POST /submit HTTP/1.0\r\n"
+        "Host: test.winehq.org\r\n"
+        "User-Agent: Winetest Shell\r\n"
+        "Content-Type: multipart/form-data; boundary=\"" SEP "\"\r\n"
+        "Content-Length: %u\r\n\r\n";
+    static const char body1[] = "--" SEP "\r\n"
+        "Content-Disposition: form-data; name=\"reportfile\"; filename=\"%s\"\r\n"
+        "Content-Type: application/octet-stream\r\n\r\n";
+    static const char body2[] = "\r\n--" SEP "\r\n"
+        "Content-Disposition: form-data; name=\"submit\"\r\n\r\n"
+        "Upload File\r\n"
+        "--" SEP "--\r\n";
+
+    s = open_http ("test.winehq.org");
+    if (s == INVALID_SOCKET) return 1;
+
+    f = fopen (name, "rb");
+    if (!f) {
+        report (R_WARNING, "Can't open file '%s': %d", name, errno);
+        goto abort1;
+    }
+    fseek (f, 0, SEEK_END);
+    filesize = ftell (f);
+    if (filesize > 1024*1024) {
+        report (R_WARNING,
+                "File too big (%.1f MB > 1 MB); submitting partial report.",
+                filesize/1024.0/1024);
+        filesize = 1024*1024;
+    }
+    fseek (f, 0, SEEK_SET);
+
+    report (R_STATUS, "Sending header");
+    str = strmake (&total, body1, name);
+    ret = send_str (s, head, filesize + total + sizeof body2 - 1) ||
+        send_buf (s, str, total);
+    free (str);
+    if (ret) {
+        report (R_WARNING, "Error sending header: %d, %d",
+                errno, WSAGetLastError ());
+        goto abort2;
+    }
+
+    report (R_STATUS, "Sending %u bytes of data", filesize);
+    report (R_PROGRESS, 2, filesize);
+    total = 0;
+    while (total < filesize && (bytes_read = fread (buffer, 1, BUFLEN/2, f))) {
+        if ((signed)bytes_read == -1) {
+            report (R_WARNING, "Error reading log file: %d", errno);
+            goto abort2;
+        }
+        total += bytes_read;
+        if (total > filesize) bytes_read -= total - filesize;
+        if (send_buf (s, buffer, bytes_read)) {
+            report (R_WARNING, "Error sending body: %d, %d",
+                    errno, WSAGetLastError ());
+            goto abort2;
+        }
+        report (R_DELTA, bytes_read, "Network transfer: In progress");
+    }
+    fclose (f);
+
+    if (send_buf (s, body2, sizeof body2 - 1)) {
+        report (R_WARNING, "Error sending trailer: %d, %d",
+                errno, WSAGetLastError ());
+        goto abort2;
+    }
+    report (R_DELTA, 0, "Network transfer: Done");
+
+    total = 0;
+    while ((bytes_read = recv (s, buffer+total, BUFLEN-total, 0))) {
+        if ((signed)bytes_read == SOCKET_ERROR) {
+            report (R_WARNING, "Error receiving reply: %d, %d",
+                    errno, WSAGetLastError ());
+            goto abort1;
+        }
+        total += bytes_read;
+        if (total == BUFLEN) {
+            report (R_WARNING, "Buffer overflow");
+            goto abort1;
+        }
+    }
+    if (close_http (s)) {
+        report (R_WARNING, "Error closing connection: %d, %d",
+                errno, WSAGetLastError ());
+        return 1;
+    }
+
+    str = strmake (&bytes_read, "Received %s (%d bytes).\n",
+                   name, filesize);
+    ret = memcmp (str, buffer + total - bytes_read, bytes_read);
+    free (str);
+    if (ret) {
+        buffer[total] = 0;
+        str = strstr (buffer, "\r\n\r\n");
+        if (!str) str = buffer;
+        else str = str + 4;
+        report (R_ERROR, "Can't submit logfile '%s'. "
+                "Server response: %s", name, str);
+    }
+    return ret;
+
+ abort2:
+    fclose (f);
+ abort1:
+    close_http (s);
+    return 1;
+}
diff --git a/reactos/apps/utils/winetest/tests.rc b/reactos/apps/utils/winetest/tests.rc
new file mode 100644 (file)
index 0000000..90752f0
--- /dev/null
@@ -0,0 +1,20 @@
+/* Automatically generated -- do not edit! */\r
+#include "resource.h"\r
+STRINGTABLE {\r
+0 "advapi32_test.exe"\r
+1 "comctl32_test.exe"\r
+REV_INFO+0 "lib/advapi32/winetests/crypt_lmhash.c:1.1"\r
+REV_INFO+1 "lib/advapi32/winetests/crypt_md4.c:1.1"\r
+REV_INFO+2 "lib/advapi32/winetests/crypt_md5.c:1.1"\r
+REV_INFO+3 "lib/advapi32/winetests/crypt_sha.c:1.1"\r
+REV_INFO+4 "lib/advapi32/winetests/registry.c:1.1"\r
+REV_INFO+5 "lib/advapi32/winetests/security.c:1."\r
+REV_INFO+6 "lib/advapi32/winetests/crypt.c:1.1"\r
+REV_INFO+7 "dlls/comctl32/tests/imagelist.c:1.1"\r
+REV_INFO+8 "dlls/comctl32/tests/mru.c:1.1"\r
+REV_INFO+9 "dlls/comctl32/tests/subclass.c:1.1"\r
+REV_INFO+10 "dlls/comctl32/tests/tab.c:1.1"\r
+\r
+}\r
+0 TESTRES "../../../lib/advapi32/winetests/advapi32_test.exe"\r
+1 TESTRES "../../../lib/comctl32/winetests/comctl32_test.exe"\r
diff --git a/reactos/apps/utils/winetest/util.c b/reactos/apps/utils/winetest/util.c
new file mode 100644 (file)
index 0000000..bd75e5f
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+ * Utility functions.\r
+ *\r
+ * Copyright 2003 Dimitrie O. Paun\r
+ * Copyright 2003 Ferenc Wagner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <errno.h>\r
+\r
+#include "winetest.h"\r
+\r
+void *xmalloc (size_t len)\r
+{\r
+    void *p = malloc (len);\r
+\r
+    if (!p) report (R_FATAL, "Out of memory.");\r
+    return p;\r
+}\r
+\r
+void *xrealloc (void *op, size_t len)\r
+{\r
+    void *p = realloc (op, len);\r
+\r
+    if (!p) report (R_FATAL, "Out of memory.");\r
+    return p;\r
+}\r
+\r
+char *vstrfmtmake (size_t *lenp, const char *fmt, va_list ap)\r
+{\r
+    size_t size = 1000;\r
+    char *p, *q;\r
+    int n;\r
+\r
+    p = malloc (size);\r
+    if (!p) return NULL;\r
+    while (1) {\r
+        n = vsnprintf (p, size, fmt, ap);\r
+        if (n < 0) size *= 2;   /* Windows */\r
+        else if ((unsigned)n >= size) size = n+1; /* glibc */\r
+        else break;\r
+        q = realloc (p, size);\r
+        if (!q) {\r
+          free (p);\r
+          return NULL;\r
+       }\r
+       p = q;\r
+    }\r
+    if (lenp) *lenp = n;\r
+    return p;\r
+}\r
+\r
+char *vstrmake (size_t *lenp, va_list ap)\r
+{\r
+    const char *fmt;\r
+\r
+    fmt = va_arg (ap, const char*);\r
+    return vstrfmtmake (lenp, fmt, ap);\r
+}\r
+\r
+char *strmake (size_t *lenp, ...)\r
+{\r
+    va_list ap;\r
+    char *p;\r
+\r
+    va_start (ap, lenp);\r
+    p = vstrmake (lenp, ap);\r
+    if (!p) report (R_FATAL, "Out of memory.");\r
+    va_end (ap);\r
+    return p;\r
+}\r
+\r
+void xprintf (const char *fmt, ...)\r
+{\r
+    va_list ap;\r
+    size_t size;\r
+    ssize_t written;\r
+    char *buffer, *head;\r
+\r
+    va_start (ap, fmt);\r
+    buffer = vstrfmtmake (&size, fmt, ap);\r
+    head = buffer;\r
+    va_end (ap);\r
+    while ((written = write (1, head, size)) != size) {\r
+        if (written == -1)\r
+            report (R_FATAL, "Can't write logs: %d", errno);\r
+        head += written;\r
+        size -= written;\r
+    }\r
+    free (buffer);\r
+}\r
+\r
+const char *\r
+badtagchar (const char *tag)\r
+{\r
+    while (*tag)\r
+        if (('a'<=*tag && *tag<='z') ||\r
+            ('A'<=*tag && *tag<='Z') ||\r
+            ('0'<=*tag && *tag<='9') ||\r
+            *tag=='-' || *tag=='.')\r
+            tag++;\r
+        else return tag;\r
+    return NULL;\r
+}\r
diff --git a/reactos/apps/utils/winetest/wine.ico b/reactos/apps/utils/winetest/wine.ico
new file mode 100644 (file)
index 0000000..fc394c9
Binary files /dev/null and b/reactos/apps/utils/winetest/wine.ico differ
diff --git a/reactos/apps/utils/winetest/winetest.h b/reactos/apps/utils/winetest/winetest.h
new file mode 100644 (file)
index 0000000..ba9a70d
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * winetest definitions\r
+ *\r
+ * Copyright 2003 Dimitrie O. Paun\r
+ * Copyright 2003 Ferenc Wagner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#ifndef __WINETESTS_H\r
+#define __WINETESTS_H\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+\r
+void fatal (const char* msg);\r
+void warning (const char* msg);\r
+void *xmalloc (size_t len);\r
+void *xrealloc (void *op, size_t len);\r
+void xprintf (const char *fmt, ...);\r
+char *vstrmake (size_t *lenp, va_list ap);\r
+char *strmake (size_t *lenp, ...);\r
+const char *badtagchar (const char *tag);\r
+\r
+int send_file (const char *name);\r
+\r
+/* GUI definitions */\r
+\r
+#include <windows.h>\r
+\r
+enum report_type {\r
+    R_STATUS = 0,\r
+    R_PROGRESS,\r
+    R_STEP,\r
+    R_DELTA,\r
+    R_DIR,\r
+    R_OUT,\r
+    R_WARNING,\r
+    R_ERROR,\r
+    R_FATAL,\r
+    R_ASK,\r
+    R_TEXTMODE,\r
+    R_QUIET\r
+};\r
+\r
+int report (enum report_type t, ...);\r
+\r
+#endif /* __WINETESTS_H */\r
diff --git a/reactos/apps/utils/winetest/winetest.rc b/reactos/apps/utils/winetest/winetest.rc
new file mode 100644 (file)
index 0000000..2e43f08
--- /dev/null
@@ -0,0 +1,132 @@
+/*\r
+ * Winetest resources\r
+ *\r
+ * Copyright 2004 Ferenc Wagner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <windows.h>\r
+#include <winres.h>\r
+#include "resource.h"\r
+#include "tests.rc"\r
+\r
+IDD_STATUS DIALOG 0, 0, 160, 140\r
+STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX\r
+CAPTION "Wine Test Shell"\r
+BEGIN\r
+    LTEXT   "Extracting:",       IDC_ST0,        10,   5, 140, 10\r
+    CONTROL "PB0", IDC_PB0, PROGRESS_CLASS, 0,    5,  15, 150, 10\r
+    LTEXT   "Running:",          IDC_ST1,        10,  30, 140, 10\r
+    CONTROL "PB1", IDC_PB1, PROGRESS_CLASS, 0,    5,  40, 150, 15\r
+    LTEXT   "Network transfer:", IDC_ST2,        10,  60, 140, 10\r
+    CONTROL "PB2", IDC_PB2, PROGRESS_CLASS, 0,    5,  70, 150, 10\r
+                                               \r
+    LTEXT   "Working directory:", IDC_STATIC,    10,  89, 100, 10\r
+    EDITTEXT                      IDC_DIR,       71,  88,  79, 10,\r
+             ES_READONLY | ES_AUTOHSCROLL\r
+    LTEXT   "Output file:",       IDC_STATIC,    10, 100, 100, 10\r
+    EDITTEXT                      IDC_OUT,       46,  99, 104, 10,\r
+             ES_READONLY | ES_AUTOHSCROLL\r
+\r
+    DEFPUSHBUTTON "About", IDHELP,               20, 113,  30, 14\r
+    PUSHBUTTON    "Edit",  IDCANCEL,             65, 113,  30, 14,\r
+                   WS_DISABLED\r
+    PUSHBUTTON    "Stop",  IDABORT,             110, 113,  30, 14\r
+\r
+    CONTROL "Created", IDC_SB, STATUSCLASSNAME, 0, 0,0,0,0\r
+END\r
+\r
+IDD_ABOUT DIALOG 0, 0, 150, 60\r
+STYLE WS_POPUP\r
+CAPTION "About Wine Test Shell"\r
+BEGIN\r
+    CTEXT "This program extracts and runs a series of tests which check Wine's conformance to the Windows API.",\r
+        IDC_STATIC, 10, 5, 130, 30\r
+    DEFPUSHBUTTON "Close", IDCANCEL, 55, 40, 40, 14\r
+END\r
+\r
+/* BINRES wine.ico */\r
+IDI_WINE ICON "wine.ico"\r
+/* {\r
+ '00 00 01 00 02 00 20 20 10 00 00 00 00 00 E8 02'\r
+ '00 00 26 00 00 00 10 10 10 00 00 00 00 00 28 01'\r
+ '00 00 0E 03 00 00 28 00 00 00 20 00 00 00 40 00'\r
+ '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'\r
+ '00 00 00 00 00 00 10 00 00 00 00 00 00 00 39 02'\r
+ 'B1 00 23 02 6C 00 0F 03 29 00 1B 02 51 00 FF FF'\r
+ 'FF 00 1B 1A 1B 00 1E 02 63 00 33 02 A1 00 08 08'\r
+ '08 00 14 03 3C 00 0C 04 1E 00 2E 02 8E 00 10 0F'\r
+ '10 00 2A 02 82 00 29 02 7D 00 03 02 04 00 44 44'\r
+ '44 44 44 44 44 44 55 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 8F FF 84 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 8F F8 F8 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 8F FF F5 44 44 44 44 44 44 44 44 44 44 44'\r
+ '44 5C F8 C8 F5 44 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 85 44 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 4C 44 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 4C 44 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 45 54 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 45 F4 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 45 FF 44 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 48 FF F4 44 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 48 23 9A 84 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 42 B7 7E AF 44 44 44 44 44 44 44 44'\r
+ '44 44 44 44 49 00 00 EA C4 44 44 44 44 44 44 44'\r
+ '44 44 44 44 46 00 00 01 F4 44 44 44 44 44 44 44'\r
+ '44 44 44 44 46 00 00 00 9F 44 44 44 44 44 44 44'\r
+ '44 44 44 44 46 00 70 00 EF 44 44 44 44 44 44 44'\r
+ '44 44 44 44 43 00 00 00 79 F4 44 44 44 44 44 44'\r
+ '44 44 44 44 49 00 00 00 0E F4 44 44 44 44 44 44'\r
+ '44 44 44 44 42 00 00 00 07 24 44 44 44 44 44 44'\r
+ '44 44 44 44 43 B0 00 00 00 34 44 44 44 44 44 44'\r
+ '44 44 44 44 4C 30 00 00 00 1F 44 44 44 44 44 44'\r
+ '44 44 44 44 48 27 E1 1D B1 2C 44 44 44 44 44 44'\r
+ '44 44 44 44 44 A9 CC CF F8 48 C4 44 44 44 44 44'\r
+ '44 44 44 44 44 58 44 44 44 45 C4 44 44 44 44 44'\r
+ '44 44 44 44 44 4C 44 44 44 44 84 44 44 44 44 44'\r
+ '44 44 44 44 44 48 44 44 44 44 C4 44 44 44 44 44'\r
+ '44 44 44 44 44 48 C4 44 44 44 C4 44 44 44 44 44'\r
+ '44 44 44 44 44 44 F4 44 44 4C C4 44 44 44 44 44'\r
+ '44 44 44 44 44 44 84 44 F8 84 44 44 44 44 44 44'\r
+ '44 44 44 44 44 44 48 F8 44 44 44 44 44 44 FF FF'\r
+ '3F FF FF F0 7F FF FF C0 FF FF FF 03 FF FF FC 03'\r
+ 'FF FF FF F3 FF FF FF FB FF FF FF FB FF FF FF F9'\r
+ 'FF FF FF F9 FF FF FF F8 FF FF FF F8 7F FF FF F8'\r
+ '1F FF FF F8 0F FF FF F8 07 FF FF F8 07 FF FF F8'\r
+ '03 FF FF F8 03 FF FF F8 01 FF FF F8 01 FF FF F8'\r
+ '01 FF FF F8 01 FF FF F8 00 FF FF F8 00 FF FF FC'\r
+ '02 7F FF FC FE 7F FF FE FF 7F FF FE FF 7F FF FE'\r
+ '7F 7F FF FF 7E 7F FF FF 71 FF FF FF 8F FF 28 00'\r
+ '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'\r
+ '00 00 80 00 00 00 00 00 00 00 00 00 00 00 10 00'\r
+ '00 00 00 00 00 00 3A 02 B1 00 0A 06 14 00 12 03'\r
+ '33 00 FF FF FF 00 12 12 12 00 0B 0B 0B 00 1B 1B'\r
+ '1B 00 25 02 6F 00 2E 02 92 00 1A 02 52 00 36 02'\r
+ 'A6 00 15 03 3E 00 04 04 05 00 13 11 19 00 1E 02'\r
+ '62 00 2A 02 82 00 33 33 33 CC 43 33 33 33 33 33'\r
+ 'CC 5C 33 33 33 33 33 36 C5 53 33 33 33 33 33 33'\r
+ '33 43 33 33 33 33 33 33 33 65 33 33 33 33 33 33'\r
+ '33 DC 33 33 33 33 33 33 33 17 EC 33 33 33 33 33'\r
+ '33 B0 07 53 33 33 33 33 33 90 00 B3 33 33 33 33'\r
+ '33 B0 00 FC 33 33 33 33 33 BA 00 A2 33 33 33 33'\r
+ '33 C7 88 82 33 33 33 33 33 3D D5 14 43 33 33 33'\r
+ '33 35 33 33 53 33 33 33 33 33 53 33 53 33 33 33'\r
+ '33 33 C5 5C 33 33 FC 7F 00 00 F0 FF 00 00 E1 FF'\r
+ '00 00 FD FF 00 00 FC FF 00 00 FC FF 00 00 FC 3F'\r
+ '00 00 FC 1F 00 00 FC 1F 00 00 FC 0F 00 00 FC 0F'\r
+ '00 00 FC 0F 00 00 FE 07 00 00 FE F7 00 00 FF 77'\r
+ '00 00 FF 0F 00 00'\r
+} */\r
index 56dafd3..2af4618 100644 (file)
@@ -45,6 +45,7 @@
 <property name="BASEADDRESS_COMDLG32" value="0x76200000" />\r
 <property name="BASEADDRESS_OLEAUT32" value="0x76260000" />\r
 <property name="BASEADDRESS_RICHED32" value="0x76340000" />\r
+<property name="BASEADDRESS_RICHED20" value="0x76360000" />\r
 <property name="BASEADDRESS_TWAIN_32" value="0x76380000" />\r
 <property name="BASEADDRESS_MIDIMAP" value="0x76600000" />\r
 <property name="BASEADDRESS_MPR" value="0x76620000" />\r
index fcfb083..00eae1a 100644 (file)
@@ -29,7 +29,7 @@ all:
        $(MAKE) -C fdebug
 
 test:
-       
+
 clean:
        $(MAKE) -C bootsect clean
        $(MAKE) -C freeldr clean
@@ -38,6 +38,7 @@ clean:
        $(MAKE) -C tools clean
 
 bootcd:
+ifeq ($(ARCH),i386)
        $(CP) bootsect/isoboot.bin ${BOOTCD_DIR}/../isoboot.bin
        $(CP) bootsect/dosmbr.bin ${BOOTCD_DIR}/loader/dosmbr.bin
        $(CP) bootsect/ext2.bin ${BOOTCD_DIR}/loader/ext2.bin
@@ -46,5 +47,7 @@ bootcd:
        $(CP) bootsect/isoboot.bin ${BOOTCD_DIR}/loader/isoboot.bin
        $(CP) freeldr/freeldr.sys ${BOOTCD_DIR}/loader/freeldr.sys
        $(CP) freeldr/setupldr.sys ${BOOTCD_DIR}/loader/setupldr.sys
+endif
 
 .PHONY : clean
+
index d8b79d7..e78fd12 100644 (file)
@@ -25,56 +25,8 @@ BOOTCD_DIR   = $(PATH_TO_TOP)/../bootcd
 
 .PHONY : clean bootcd
 
-all: $(BIN2C) dosmbr.bin fat.bin fat32.bin isoboot.bin ext2.bin
-
-
-$(BIN2C) :
-       @$(MAKE) --no-print-directory -C $(FREELDR_TOOLS_PATH)
-
-dosmbr.bin : dosmbr.asm
-       @echo freeldr: Assembling dosmbr
-       @$(NASM_CMD) $(NFLAGS) -o dosmbr.bin -f bin dosmbr.asm
-
-fat.bin : fat.asm $(BIN2C)
-       @echo freeldr: Assembling fat
-       @$(NASM_CMD) $(NFLAGS) -o fat.bin -f bin fat.asm
-       @$(BIN2C) fat.bin fat.h fat_data
-
-
-fat32.bin : fat32.asm $(BIN2C)
-       @echo freeldr: Assembling fat32
-       @$(NASM_CMD) $(NFLAGS) -o fat32.bin -f bin fat32.asm
-       @$(BIN2C) fat32.bin fat32.h fat32_data
-
-isoboot.bin : isoboot.asm
-       @echo freeldr: Assembling isoboot
-       @$(NASM_CMD) $(NFLAGS) -o isoboot.bin -f bin isoboot.asm
-
-ext2.bin : ext2.asm
-       @echo freeldr: Assembling ext2
-       @$(NASM_CMD) $(NFLAGS) -o ext2.bin -f bin ext2.asm
-       @$(BIN2C) ext2.bin ext2.h ext2_data
-
-
-.PHONY : bootcd
-bootcd: bootcd_dirs isoboot.bin
-       $(CP) isoboot.bin $(BOOTCD_DIR)
-       $(CP) dosmbr.bin $(BOOTCD_DIR)/disk/loader
-       $(CP) ext2.bin $(BOOTCD_DIR)/disk/loader
-       $(CP) fat.bin $(BOOTCD_DIR)/disk/loader
-       $(CP) fat32.bin $(BOOTCD_DIR)/disk/loader
-       $(CP) isoboot.bin $(BOOTCD_DIR)/disk/loader
-
-.PHONY : bootcd_dirs
-bootcd_dirs:
-       $(MKDIR) $(BOOTCD_DIR)
-       $(MKDIR) $(BOOTCD_DIR)/disk
-       $(MKDIR) $(BOOTCD_DIR)/disk/reactos
-       $(MKDIR) $(BOOTCD_DIR)/disk/install
-       $(MKDIR) $(BOOTCD_DIR)/disk/bootdisk
-       $(MKDIR) $(BOOTCD_DIR)/disk/loader
-
-clean:
-       @-$(RM) *.bin
-       @-$(RM) *.h
-       @echo freeldr: Clean ALL done.
+ifeq ($(ARCH),powerpc)
+include Makefile.powerpc
+else
+include Makefile.i386
+endif
diff --git a/reactos/boot/freeldr/bootsect/Makefile.i386 b/reactos/boot/freeldr/bootsect/Makefile.i386
new file mode 100644 (file)
index 0000000..bf7c113
--- /dev/null
@@ -0,0 +1,52 @@
+all: $(BIN2C) dosmbr.bin fat.bin fat32.bin isoboot.bin ext2.bin
+
+$(BIN2C) :
+       @$(MAKE) --no-print-directory -C $(FREELDR_TOOLS_PATH)
+
+dosmbr.bin : dosmbr.asm
+       @echo ===================================================== Assembling dosmbr
+       @$(NASM_CMD) $(NFLAGS) -o dosmbr.bin -f bin dosmbr.asm
+
+fat.bin : fat.asm $(BIN2C)
+       @echo ===================================================== Assembling fat
+       @$(NASM_CMD) $(NFLAGS) -o fat.bin -f bin fat.asm
+       @$(BIN2C) fat.bin fat.h fat_data
+
+
+fat32.bin : fat32.asm $(BIN2C)
+       @echo ===================================================== Assembling fat32
+       @$(NASM_CMD) $(NFLAGS) -o fat32.bin -f bin fat32.asm
+       @$(BIN2C) fat32.bin fat32.h fat32_data
+
+isoboot.bin : isoboot.asm
+       @echo ===================================================== Assembling isoboot
+       @$(NASM_CMD) $(NFLAGS) -o isoboot.bin -f bin isoboot.asm
+
+ext2.bin : ext2.asm
+       @echo ===================================================== Assembling ext2
+       @$(NASM_CMD) $(NFLAGS) -o ext2.bin -f bin ext2.asm
+       @$(BIN2C) ext2.bin ext2.h ext2_data
+
+
+.PHONY : bootcd
+bootcd: bootcd_dirs isoboot.bin
+       $(CP) isoboot.bin $(BOOTCD_DIR)
+       $(CP) dosmbr.bin $(BOOTCD_DIR)/disk/loader
+       $(CP) ext2.bin $(BOOTCD_DIR)/disk/loader
+       $(CP) fat.bin $(BOOTCD_DIR)/disk/loader
+       $(CP) fat32.bin $(BOOTCD_DIR)/disk/loader
+       $(CP) isoboot.bin $(BOOTCD_DIR)/disk/loader
+
+.PHONY : bootcd_dirs
+bootcd_dirs:
+       $(MKDIR) $(BOOTCD_DIR)
+       $(MKDIR) $(BOOTCD_DIR)/disk
+       $(MKDIR) $(BOOTCD_DIR)/disk/reactos
+       $(MKDIR) $(BOOTCD_DIR)/disk/install
+       $(MKDIR) $(BOOTCD_DIR)/disk/bootdisk
+       $(MKDIR) $(BOOTCD_DIR)/disk/loader
+
+clean:
+       @-$(RM) *.bin
+       @-$(RM) *.h
+       @echo Clean ALL done.
diff --git a/reactos/boot/freeldr/bootsect/Makefile.powerpc b/reactos/boot/freeldr/bootsect/Makefile.powerpc
new file mode 100644 (file)
index 0000000..ebbf847
--- /dev/null
@@ -0,0 +1,35 @@
+TOOLS=$(PATH_TO_TOP)/tools
+SECTIONS= \
+       --only-section=.text \
+       --only-section=.data \
+       --only-section=.bss
+LDSECT=        -Ttext 0xe00000 -Tdata 0xe10000
+OBJS=ofwboot.o freeldr.o
+CFLAGS=-mbig -meabi -fPIC -fno-builtin -I../freeldr/include
+FREELDR=../freeldr/freeldr.sys
+
+.SUFFIXES: .c .o
+
+all: ofwldr 
+
+hack-coff$(EXEEXT):
+       $(HOST_CC) -I../freeldr/include hack-coff.c -o $@
+
+ofwboot.o: ofwboot.s
+       $(NASM_CMD) $< -c -o $@
+
+$(FREELDR):
+       $(MAKE) -C ../freeldr
+
+freeldr.o: $(FREELDR)
+       $(TOOLS)/ppc-le2be $< freeldr.tmp
+       $(OBJCOPY) -I binary -O elf32-powerpc -B powerpc:common freeldr.tmp $@
+       rm freeldr.tmp
+
+ofwldr: $(OBJS)
+       mppcw32-ld --no-omagic $(LDSECT) $(OBJS) -g -o $@.elf
+       mppcw32-objcopy $(SECTIONS) -O aixcoff-rs6000 $@.elf $@
+       $(TOOLS)/hack-coff $@
+
+clean:
+       rm -rf ofwldr *.o *.elf *.tmp
diff --git a/reactos/boot/freeldr/bootsect/ofwboot.s b/reactos/boot/freeldr/bootsect/ofwboot.s
new file mode 100644 (file)
index 0000000..36e0434
--- /dev/null
@@ -0,0 +1,960 @@
+       .section .text
+_start:        
+       .long   0xe00000 + 12
+       .long   0
+       .long   0
+       
+/*
+ * LIFTED FROM arch/macppc/stand/ofwboot/Locore.c
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;  LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+       
+_begin:
+       sync                    
+       isync
+
+       lis     %r1,stack@ha    
+       addi    %r1,%r1,stack@l 
+       addi    %r1,%r1,16384 - 0x10
+          
+       mfmsr   %r8             
+       li      %r0,0
+       mtmsr   %r0             
+       isync                   
+                               
+       mtibatu 0,%r0           
+       mtibatu 1,%r0           
+       mtibatu 2,%r0           
+       mtibatu 3,%r0           
+       mtdbatu 0,%r0           
+       mtdbatu 1,%r0           
+       mtdbatu 2,%r0           
+       mtdbatu 3,%r0           
+       
+       li      %r9,0x12             /* BATL(0, BAT_M, BAT_PP_RW) */
+       mtibatl 0,%r9           
+       mtdbatl 0,%r9           
+       li      %r9,0x1ffe           /* BATU(0, BAT_BL_256M, BAT_Vs) */
+       mtibatu 0,%r9           
+       mtdbatu 0,%r9           
+       isync                   
+
+       li      %r8,0x3030
+       mtmsr   %r8
+
+       /* Store ofw call addr */
+       mr      %r21,%r5
+       lis     %r10,0xe00000@ha
+       stw     %r5,ofw_call_addr - _start@l(%r10)
+
+       lis     %r4,_binary_freeldr_tmp_end@ha
+       addi    %r4,%r4,_binary_freeldr_tmp_end@l
+       lis     %r3,_binary_freeldr_tmp_start@ha
+       addi    %r3,%r3,_binary_freeldr_tmp_start@l
+
+       lis     %r5,0x8000@ha
+       addi    %r5,%r5,0x8000@l
+
+       bl      copy_bits
+
+       bl      zero_registers
+
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_banner - _start
+
+       bl      ofw_print_string
+
+       bl      ofw_print_eol
+
+       /* Zero CTR */
+       mtcr    %r31
+       
+       lis     %r3,0x8000@ha
+       addi    %r3,%r3,0x8000@l
+
+       mtlr    %r3
+       
+       lis     %r3,call_ofw@ha
+       addi    %r3,%r3,call_ofw - _start
+       
+       b       call_freeldr
+               
+       .align  4
+call_freeldr:
+       /* Get the address of the functions list --
+        * Note:
+        * Because of little endian switch we must use an even number of
+        * instructions here..  Pad with a nop if needed. */
+       mfmsr   %r10
+       ori     %r10,%r10,1
+       mtmsr   %r10
+
+       nop
+       
+       /* Note that this is little-endian from here on */
+       blr
+       nop
+
+       .align  4
+call_ofw:
+       /* R3 has the function offset to call (n * 4) 
+        * Other arg registers are unchanged.
+        * Note that these 4 instructions are in reverse order due to
+        * little-endian convention */
+       andi.   %r0,%r0,65534
+       mfmsr   %r0
+       mtmsr   %r0
+       /* Now normal ordering resumes */
+       subi    %r1,%r1,0x100
+
+       stw     %r8,4(%r1)
+       stw     %r9,8(%r1)
+       stw     %r10,12(%r1)
+       mflr    %r8
+       stw     %r8,16(%r1)
+
+       lis     %r10,0xe00000@ha
+       add     %r9,%r3,%r10
+       lwz     %r3,ofw_functions - _start@l(%r9)
+       mtctr   %r3
+       
+       mr      %r3,%r4
+       mr      %r4,%r5
+       mr      %r5,%r6
+       mr      %r6,%r7
+       mr      %r7,%r8
+
+       /* Goto the swapped function */
+       bctrl
+
+       lwz     %r8,16(%r1)
+       mtlr    %r8
+
+       lwz     %r8,4(%r1)
+       lwz     %r9,8(%r1)
+       lwz     %r10,12(%r1)
+
+       addi    %r1,%r1,0x100
+       /* Ok, go back to little endian */
+       mfmsr   %r0
+       ori     %r0,%r0,1
+       mtmsr   %r0
+
+       /* Note that this is little-endian from here on */
+       blr
+       nop
+
+zero_registers:
+       xor     %r2,%r2,%r2
+       mr      %r0,%r2
+       mr      %r3,%r2
+       
+       mr      %r4,%r2
+       mr      %r5,%r2
+       mr      %r6,%r2
+       mr      %r7,%r2
+
+       mr      %r8,%r2
+       mr      %r9,%r2
+       mr      %r10,%r2
+       mr      %r11,%r2
+
+       mr      %r12,%r2
+       mr      %r13,%r2
+       mr      %r14,%r2
+       mr      %r15,%r2
+       
+       mr      %r12,%r2
+       mr      %r13,%r2
+       mr      %r14,%r2
+       mr      %r15,%r2
+       
+       mr      %r16,%r2
+       mr      %r17,%r2
+       mr      %r18,%r2
+       mr      %r19,%r2
+       
+       mr      %r20,%r2
+       mr      %r21,%r2
+       mr      %r22,%r2
+       mr      %r23,%r2
+       
+       mr      %r24,%r2
+       mr      %r25,%r2
+       mr      %r26,%r2
+       mr      %r27,%r2
+       
+       mr      %r28,%r2
+       mr      %r29,%r2
+       mr      %r30,%r2
+       mr      %r31,%r2
+
+       blr
+       
+prim_strlen:
+       mr      %r5,%r3
+prim_strlen_loop:      
+       lbz     %r4,0(%r3)
+       cmpi    0,0,%r4,0
+       beq     prim_strlen_done
+       addi    %r3,%r3,1
+       b       prim_strlen_loop
+       
+prim_strlen_done:
+       sub     %r3,%r3,%r5
+       blr
+       
+copy_bits:
+       cmp     0,0,%r3,%r4
+       beqlr
+       lwz     %r6,0(%r3)
+       stw     %r6,0(%r5)
+       addi    %r3,%r3,4
+       addi    %r5,%r5,4
+       b       copy_bits
+
+ofw_print_string_hook:
+       bl      ofw_print_number
+       bl      ofw_exit
+       
+ofw_print_string:
+       /* Reserve some stack space */
+       subi    %r1,%r1,32
+
+       /* Save args */
+       stw     %r3,0(%r1)
+       
+       /* Save the lr, a scratch register */
+       stw     %r8,8(%r1)
+       mflr    %r8
+       stw     %r8,12(%r1)
+
+       /* Load the package name */
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,ofw_chosen_name - _start
+
+       /* Fire */
+       bl      ofw_finddevice
+
+       /* Load up for getprop */
+       stw     %r3,16(%r1)
+
+       lis     %r4,0xe00000@ha
+       addi    %r4,%r4,ofw_stdout_name - _start
+
+       addi    %r5,%r1,20
+
+       li      %r6,4
+
+       bl      ofw_getprop
+
+       /* Measure the string and remember the length */
+       lwz     %r3,0(%r1)
+       bl      prim_strlen
+       mr      %r5,%r3
+       
+       lwz     %r3,20(%r1)
+       lwz     %r4,0(%r1)
+
+       /* Write the string */
+       bl      ofw_write
+
+       /* Return */
+       lwz     %r8,12(%r1)
+       mtlr    %r8
+       lwz     %r8,8(%r1)
+       
+       addi    %r1,%r1,32
+       blr
+
+       /* Print 8 hex digits representing a number in r3 */
+ofw_print_number:
+       subi    %r1,%r1,32
+       stw     %r8,0(%r1)
+       mflr    %r8
+       stw     %r8,4(%r1)
+       stw     %r9,8(%r1)
+
+       xor     %r9,%r9,%r9
+       stw     %r9,12(%r1)
+
+       /* Set up and, devide, shift */
+       mr      %r8,%r3
+       lis     %r6,0xf0000000@ha
+       lis     %r7,0x10000000@ha
+       li      %r9,8
+
+ofw_number_loop:
+       nop
+       cmpi    0,0,%r9,0
+       beq     ofw_number_return
+       subi    %r9,%r9,1
+
+       /* Body: isolate digit, divide, print */
+       and     %r5,%r6,%r8
+       divwu   %r4,%r5,%r7
+       srwi    %r6,%r6,4
+       srwi    %r7,%r7,4
+
+       nop
+       
+       cmpi    0,0,%r4,10
+       bge     ofw_number_letter
+       addi    %r4,%r4,'0'
+       b       ofw_number_digit_out
+       
+ofw_number_letter:
+       addi    %r4,%r4,'A' - 10
+
+ofw_number_digit_out:  
+       stb     %r4,12(%r1)
+       addi    %r3,%r1,12
+
+       stw     %r6,16(%r1)
+       stw     %r7,20(%r1)
+       stw     %r8,24(%r1)
+       stw     %r9,28(%r1)
+       
+       bl      ofw_print_string
+
+       lwz     %r6,16(%r1)
+       lwz     %r7,20(%r1)
+       lwz     %r8,24(%r1)
+       lwz     %r9,28(%r1)
+       
+       b       ofw_number_loop
+
+ofw_number_return:     
+       /* Return */
+       lwz     %r9,8(%r1)
+       lwz     %r8,4(%r1)
+       mtlr    %r8
+       lwz     %r8,0(%r1)
+       addi    %r1,%r1,32
+       blr
+
+ofw_print_eol:
+       subi    %r1,%r1,16
+       stw     %r8,0(%r1)
+       mflr    %r8
+       stw     %r8,4(%r1)
+       li      %r4,0x0d0a
+       sth     %r4,8(%r1)
+       xor     %r4,%r4,%r4
+       sth     %r4,10(%r1)
+       addi    %r3,%r1,8
+       bl      ofw_print_string
+       lwz     %r8,4(%r1)
+       mtlr    %r8
+       lwz     %r8,0(%r1)
+       addi    %r1,%r1,16
+       blr
+
+ofw_print_nothing:
+       subi    %r1,%r1,16
+       stw     %r8,0(%r1)
+       mflr    %r8
+       stw     %r8,4(%r1)
+       li      %r4,0
+       sth     %r4,8(%r1)
+       xor     %r4,%r4,%r4
+       sth     %r4,10(%r1)
+       addi    %r3,%r1,8
+       bl      ofw_print_string
+       lwz     %r8,4(%r1)
+       mtlr    %r8
+       lwz     %r8,0(%r1)
+       addi    %r1,%r1,16
+       blr
+
+ofw_print_space:
+       subi    %r1,%r1,16
+       stw     %r8,0(%r1)
+       mflr    %r8
+       stw     %r8,4(%r1)
+       li      %r4,0x2000
+       sth     %r4,8(%r1)
+       xor     %r4,%r4,%r4
+       sth     %r4,10(%r1)
+       addi    %r3,%r1,8
+       bl      ofw_print_string
+       lwz     %r8,4(%r1)
+       mtlr    %r8
+       lwz     %r8,0(%r1)
+       addi    %r1,%r1,16
+       blr
+
+ofw_print_regs:        
+       /* Construct ofw exit call */
+       subi    %r1,%r1,0xa0
+
+       stw     %r0,0(%r1)
+       stw     %r1,4(%r1)
+       stw     %r2,8(%r1)
+       stw     %r3,12(%r1)
+
+       stw     %r4,16(%r1)
+       stw     %r5,20(%r1)
+       stw     %r6,24(%r1)
+       stw     %r7,28(%r1)
+       
+       stw     %r8,32(%r1)
+       stw     %r9,36(%r1)
+       stw     %r10,40(%r1)
+       stw     %r11,44(%r1)
+       
+       stw     %r12,48(%r1)
+       stw     %r13,52(%r1)
+       stw     %r14,56(%r1)
+       stw     %r15,60(%r1)
+       
+       stw     %r16,64(%r1)
+       stw     %r17,68(%r1)
+       stw     %r18,72(%r1)
+       stw     %r19,76(%r1)
+       
+       stw     %r20,80(%r1)
+       stw     %r21,84(%r1)
+       stw     %r22,88(%r1)
+       stw     %r23,92(%r1)
+       
+       stw     %r24,96(%r1)
+       stw     %r25,100(%r1)
+       stw     %r26,104(%r1)
+       stw     %r27,108(%r1)
+       
+       stw     %r28,112(%r1)
+       stw     %r29,116(%r1)
+       stw     %r30,120(%r1)
+       stw     %r31,124(%r1)
+
+       mflr    %r0
+       stw     %r0,128(%r1)
+       mfcr    %r0
+       stw     %r0,132(%r1)
+       mfctr   %r0
+       stw     %r0,136(%r1)
+       mfmsr   %r0
+       stw     %r0,140(%r1)
+
+       /* Count at zero */
+       xor     %r0,%r0,%r0
+       stw     %r0,144(%r1)
+       mr      %r3,%r1
+       stw     %r3,148(%r1)
+       
+       /* Body, print the regname, then the register */
+ofw_register_loop:
+       lwz     %r3,144(%r1)
+       cmpi    0,0,%r3,32
+       beq     ofw_register_special
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_reg_init - _start
+       bl      ofw_print_string
+       lwz     %r3,144(%r1)
+       bl      ofw_print_number
+       bl      ofw_print_space
+       lwz     %r3,144(%r1)
+       mulli   %r3,%r3,4
+       add     %r3,%r1,%r3
+       lwz     %r3,0(%r3)
+       stw     %r3,152(%r1)
+       bl      ofw_print_number
+       lwz     %r3,144(%r1)
+       addi    %r3,%r3,1
+       stw     %r3,144(%r1)
+       b       done_dump
+
+dump_optional: 
+       bl      ofw_print_space
+       bl      ofw_print_space
+       lwz     %r3,152(%r1)
+       lwz     %r3,0(%r3)
+       bl      ofw_print_number
+       bl      ofw_print_space 
+       lwz     %r3,152(%r1)
+       lwz     %r3,4(%r3)
+       bl      ofw_print_number
+       bl      ofw_print_space 
+       lwz     %r3,152(%r1)
+       lwz     %r3,8(%r3)
+       bl      ofw_print_number
+       bl      ofw_print_space 
+       lwz     %r3,152(%r1)
+       lwz     %r3,12(%r3)
+       bl      ofw_print_number
+       bl      ofw_print_space
+done_dump:     
+       bl      ofw_print_eol
+       b       ofw_register_loop
+
+ofw_register_special:
+       /* LR */
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_reg_lr - _start
+       bl      ofw_print_string
+       bl      ofw_print_space
+       lwz     %r3,128(%r1)
+       bl      ofw_print_number
+       bl      ofw_print_eol
+       
+       /* CR */
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_reg_cr - _start
+       bl      ofw_print_string
+       bl      ofw_print_space
+       lwz     %r3,132(%r1)
+       bl      ofw_print_number
+       bl      ofw_print_eol
+       
+       /* CTR */
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_reg_ctr - _start
+       bl      ofw_print_string
+       bl      ofw_print_space
+       lwz     %r3,136(%r1)
+       bl      ofw_print_number
+       bl      ofw_print_eol
+       
+       /* MSR */
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_reg_msr - _start
+       bl      ofw_print_string
+       bl      ofw_print_space
+       lwz     %r3,140(%r1)
+       bl      ofw_print_number
+       bl      ofw_print_eol
+
+       /* Return */
+       lwz     %r0,128(%r1)
+       mtlr    %r0
+       
+       lwz     %r0,0(%r1)
+       lwz     %r2,8(%r1)
+       lwz     %r3,12(%r1)
+
+       lwz     %r4,16(%r1)
+       lwz     %r5,20(%r1)
+       lwz     %r6,24(%r1)
+       lwz     %r7,28(%r1)
+
+       addi    %r1,%r1,0xa0
+               
+       blr
+       
+ofw_finddevice_hook:
+       subi    %r1,%r1,32
+       stw     %r3,0(%r1)
+       mflr    %r3
+       stw     %r3,4(%r1)
+       lwz     %r3,0(%r1)
+       bl      ofw_finddevice
+       stw     %r3,0(%r1)
+       lwz     %r3,4(%r1)
+       mtlr    %r3
+       lwz     %r3,0(%r1)
+       addi    %r1,%r1,32      
+       blr
+       
+ofw_finddevice:
+       /* Reserve stack space ...
+        * 20 bytes for the ofw call,
+        * r8, r9, and lr */
+       subi    %r1,%r1,32
+
+       /* Store r8, r9, lr */
+       stw     %r8,20(%r1)
+       stw     %r9,24(%r1)
+       mflr    %r8
+       stw     %r8,28(%r1)
+       
+       /* Get finddevice name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_finddevice_name - _start
+       stw     %r9,0(%r1)
+
+       /* 1 Argument and 1 return */
+       li      %r9,1
+       stw     %r9,4(%r1)
+       stw     %r9,8(%r1)
+
+       stw     %r3,12(%r1)
+
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       /* Set argument */
+       mr      %r3,%r1
+       
+       /* Fire */
+       blrl
+       
+       lwz     %r3,16(%r1)
+       
+       /* Restore registers */
+       lwz     %r8,28(%r1)
+       mtlr    %r8
+       lwz     %r9,24(%r1)
+       lwz     %r8,20(%r1)
+       
+       addi    %r1,%r1,32
+       
+       /* Return */
+       blr
+
+ofw_getprop_hook:
+       /* Reserve stack space:
+        * 32 bytes for the ofw call
+        * 12 bytes for r8, r9, lr
+        */             
+       /* Reserve stack space ...
+        * 20 bytes for the ofw call,
+        * r8, r9, and lr */
+       subi    %r1,%r1,48
+
+       /* Store r8, r9, lr */
+       stw     %r8,32(%r1)
+       stw     %r9,36(%r1)
+       mflr    %r8
+       stw     %r8,40(%r1)
+       
+       /* Get getprop name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_getprop_name - _start
+       stw     %r9,0(%r1)
+
+       /* 4 Argument and 1 return */
+       li      %r9,4
+       stw     %r9,4(%r1)
+       li      %r9,1
+       stw     %r9,8(%r1)
+
+       stw     %r3,12(%r1) /* Package */
+       stw     %r4,16(%r1) /* Property */
+       stw     %r5,20(%r1) /* Return buffer */
+       stw     %r6,24(%r1) /* Buffer size */
+       
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       /* Set argument */
+       mr      %r3,%r1
+
+       /* Fire */
+       blrl
+
+       /* Workaround to a wierd crash ... not sure what causes it.
+        * XXX investigate me */
+       bl      ofw_print_nothing
+       
+       /* Return */
+       lwz     %r3,28(%r1)
+
+       /* Restore registers */
+       lwz     %r8,40(%r1)
+       mtlr    %r8
+       lwz     %r9,36(%r1)
+       lwz     %r8,32(%r1)
+       
+       addi    %r1,%r1,48
+               
+       /* Return */
+       blr
+
+ofw_getprop:
+       /* Reserve stack space:
+        * 32 bytes for the ofw call
+        * 12 bytes for r8, r9, lr
+        */             
+       /* Reserve stack space ...
+        * 20 bytes for the ofw call,
+        * r8, r9, and lr */
+       subi    %r1,%r1,48
+
+       /* Store r8, r9, lr */
+       stw     %r8,32(%r1)
+       stw     %r9,36(%r1)
+       mflr    %r8
+       stw     %r8,40(%r1)
+       
+       /* Get getprop name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_getprop_name - _start
+       stw     %r9,0(%r1)
+
+       /* 4 Argument and 1 return */
+       li      %r9,4
+       stw     %r9,4(%r1)
+       li      %r9,1
+       stw     %r9,8(%r1)
+
+       stw     %r3,12(%r1) /* Package */
+       stw     %r4,16(%r1) /* Property */
+       stw     %r5,20(%r1) /* Return buffer */
+       stw     %r6,24(%r1) /* Buffer size */
+       
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       /* Set argument */
+       mr      %r3,%r1
+
+       /* Fire */
+       blrl
+       
+       /* Return */
+       lwz     %r3,28(%r1)
+
+       /* Restore registers */
+       lwz     %r8,40(%r1)
+
+       mtlr    %r8
+       lwz     %r9,36(%r1)
+       lwz     %r8,32(%r1)
+       
+       addi    %r1,%r1,48
+               
+       /* Return */
+       blr
+               
+ofw_write:
+       /* Reserve stack space:
+        * 28 bytes for the ofw call
+        * 12 bytes for r8, r9, lr
+        */             
+       /* Reserve stack space ...
+        * 20 bytes for the ofw call,
+        * r8, r9, and lr */
+       subi    %r1,%r1,48
+
+       nop
+       
+       /* Store r8, r9, lr */
+       stw     %r8,28(%r1)
+       stw     %r9,32(%r1)
+       mflr    %r8
+       stw     %r8,36(%r1)
+       
+       /* Get write name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_write_name - _start
+       stw     %r9,0(%r1)
+
+       /* 3 Arguments and 1 return */
+       li      %r9,3
+       stw     %r9,4(%r1)
+       li      %r9,1
+       stw     %r9,8(%r1)
+
+       stw     %r3,12(%r1)
+       stw     %r4,16(%r1)
+       stw     %r5,20(%r1)
+       
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       /* Set argument */
+       mr      %r3,%r1
+
+       /* Fire */
+       blrl
+
+       /* Return */
+       lwz     %r3,24(%r1)
+
+       /* Restore registers */
+       lwz     %r8,36(%r1)
+       mtlr    %r8
+       lwz     %r9,32(%r1)
+       lwz     %r8,28(%r1)
+       
+       addi    %r1,%r1,48
+       
+       /* Return */
+       blr
+
+ofw_read:
+       /* Reserve stack space:
+        * 28 bytes for the ofw call
+        * 12 bytes for r8, r9, lr
+        */             
+       /* Reserve stack space ...
+        * 20 bytes for the ofw call,
+        * r8, r9, and lr */
+       subi    %r1,%r1,48
+
+       nop
+       
+       /* Store r8, r9, lr */
+       stw     %r8,28(%r1)
+       stw     %r9,32(%r1)
+       mflr    %r8
+       stw     %r8,36(%r1)
+       
+       /* Get read name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_read_name - _start
+       stw     %r9,0(%r1)
+
+       /* 3 Arguments and 1 return */
+       li      %r9,3
+       stw     %r9,4(%r1)
+       li      %r9,1
+       stw     %r9,8(%r1)
+
+       stw     %r3,12(%r1)
+       stw     %r4,16(%r1)
+       stw     %r5,20(%r1)
+       
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       /* Set argument */
+       mr      %r3,%r1
+
+       /* Fire */
+       blrl
+
+       /* Return */
+       lwz     %r3,24(%r1)
+
+       /* Restore registers */
+       lwz     %r8,36(%r1)
+       mtlr    %r8
+       lwz     %r9,32(%r1)
+       lwz     %r8,28(%r1)
+       
+       addi    %r1,%r1,48
+       
+       /* Return */
+       blr
+               
+ofw_exit:
+       lis     %r3,0xe00000@ha
+       addi    %r3,%r3,freeldr_halt - _start
+
+       bl      ofw_print_string
+/*     
+ofw_exit_loop: 
+       b       ofw_exit_loop
+*/
+       /* Load the exit name */
+       lis     %r8,0xe00000@ha
+       addi    %r9,%r8,ofw_exit_name - _start
+       stw     %r9,0(%r1)
+
+       /* Zero args, zero returns */
+       xor     %r9,%r9,%r9
+       stw     %r9,4(%r1)
+       stw     %r9,8(%r1)
+       
+       /* Load up the call address */
+       lwz     %r9,ofw_call_addr - _start(%r8)
+       mtlr    %r9
+
+       mr      %r3,%r1
+
+       /* Fire */
+       blrl
+       /* No return from exit */
+               
+       .org    0x1000
+freeldr_banner:
+       .ascii  "ReactOS OpenFirmware Boot Program\r\n\0"
+
+freeldr_halt:
+       .ascii  "ReactOS OpenFirmware Boot Program Halting\r\n\0"
+
+freeldr_reg_init:
+       .ascii  "r\0"
+
+freeldr_reg_lr:        
+       .ascii  "lr \0"
+freeldr_reg_cr:        
+       .ascii  "cr \0"
+freeldr_reg_ctr:       
+       .ascii  "ctr\0"
+freeldr_reg_msr:       
+       .ascii  "msr\0"
+                       
+ofw_call_addr: 
+       .long   0
+
+ofw_memory_size:
+       .long   0
+       .long   0
+       .long   0
+       .long   0
+       
+ofw_finddevice_name:
+       .ascii  "finddevice\0"
+               
+ofw_getprop_name:
+       .ascii  "getprop\0"
+
+ofw_write_name:
+       .ascii  "write\0"
+
+ofw_read_name:
+       .ascii  "read\0"
+       
+ofw_exit_name:
+       .ascii  "exit\0"
+
+ofw_chosen_name:
+       .ascii  "/chosen\0"
+
+ofw_stdout_name:
+       .ascii  "stdout\0"
+
+ofw_memory_name:
+       .ascii  "/memory@0\0"
+
+ofw_reg_name:
+       .ascii  "reg\0"
+       
+ofw_functions:
+       .long   ofw_finddevice_hook
+       .long   ofw_getprop_hook
+       .long   ofw_write
+       .long   ofw_read
+       .long   ofw_exit
+       .long   ofw_print_regs
+       .long   ofw_print_string
+       .long   ofw_print_number
+       
+       .org    0x2000
+stack:
+       .space  0x4000
index 733f71a..f7c7fd8 100644 (file)
@@ -28,6 +28,7 @@
 #include "../../reactos/registry.h"
 #include "hardware.h"
 
+BOOLEAN AcpiPresent = FALSE;
 
 static BOOL
 FindAcpiBios(VOID)
@@ -63,6 +64,7 @@ DetectAcpiBios(FRLDRHKEY SystemKey, ULONG *BusNumber)
 
   if (FindAcpiBios())
     {
+      AcpiPresent = TRUE;
       /* Create new bus key */
       sprintf(Buffer,
              "MultifunctionAdapter\\%u", *BusNumber);
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s b/reactos/boot/freeldr/freeldr/arch/powerpc/boot.s
new file mode 100644 (file)
index 0000000..30c1f1c
--- /dev/null
@@ -0,0 +1,3 @@
+       .extern PpcInit
+_start:
+       b       PpcInit
diff --git a/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c b/reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
new file mode 100644 (file)
index 0000000..b5405cc
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ *  FreeLoader PowerPC Part
+ *  Copyright (C) 2005  Art Yerkes
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "freeldr.h"
+#include "machine.h"
+#include "of.h"
+
+extern void BootMain( char * );
+extern char *GetFreeLoaderVersionString();
+ULONG BootPartition = 0;
+ULONG BootDrive = 0;
+
+of_proxy ofproxy;
+void *PageDirectoryStart, *PageDirectoryEnd;
+static int chosen_package, stdin_handle;
+BOOLEAN AcpiPresent = FALSE;
+char BootPath[0x100];
+
+void le_swap( const void *start_addr_v, 
+              const void *end_addr_v, 
+              const void *target_addr_v ) {
+    long *start_addr = (long *)ROUND_DOWN((long)start_addr_v,8), 
+        *end_addr = (long *)ROUND_UP((long)end_addr_v,8), 
+        *target_addr = (long *)ROUND_DOWN((long)target_addr_v,8);
+    long tmp;
+    while( start_addr <= end_addr ) {
+        tmp = start_addr[0];
+        target_addr[0] = REV(start_addr[1]);
+        target_addr[1] = REV(tmp);
+        start_addr += 2;
+        target_addr += 2;
+    }
+}
+
+int ofw_finddevice( const char *name ) {
+    int ret, len;
+
+    len = strlen(name);
+    le_swap( name, name + len, name );
+    ret = ofproxy( 0, (char *)name, NULL, NULL, NULL );
+    le_swap( name, name + len, name );
+    return ret;
+}
+
+int ofw_getprop( int package, const char *name, void *buffer, int buflen ) {
+    int ret, len = strlen(name);
+    le_swap( name, name + len, name );
+    le_swap( buffer, buffer + buflen, buffer );
+    ret = ofproxy
+        ( 4, (void *)package, (char *)name, buffer, (void *)buflen );
+    le_swap( buffer, buffer + buflen, buffer );
+    le_swap( name, name + len, name );
+    return ret;
+}
+
+int ofw_write( int handle, const char *data, int len ) {
+    int ret;
+    le_swap( data, data + len, data );
+    ret = ofproxy
+        ( 8, (void *)handle, (char *)data, (void *)len, NULL );
+    le_swap( data, data + len, data );
+    return ret;
+}
+
+int ofw_read( int handle, const char *data, int len ) {
+    int ret;
+    le_swap( data, data + len, data );
+    ret = ofproxy
+        ( 12, (void *)handle, (char *)data, (void *)len, NULL );
+    le_swap( data, data + len, data );
+    return ret;
+}
+
+void ofw_exit() {
+    ofproxy( 16, NULL, NULL, NULL, NULL );
+}
+
+void ofw_dumpregs() {
+    ofproxy( 20, NULL, NULL, NULL, NULL );
+}
+
+void ofw_print_string( const char *str ) {
+    int len = strlen(str);
+    le_swap( (char *)str, str + len, (char *)str );
+    ofproxy( 24, (void *)str, NULL, NULL, NULL );
+    le_swap( (char *)str, str + len, (char *)str );
+}
+
+void ofw_print_number( int num ) {
+    ofproxy( 28, (void *)num, NULL, NULL, NULL );
+}
+
+void PpcPutChar( int ch ) {
+    char buf[3];
+    if( ch == 0x0a ) { buf[0] = 0x0d; buf[1] = 0x0a; } 
+    else { buf[0] = ch; buf[1] = 0; }
+    buf[2] = 0;
+    ofw_print_string( buf );
+}
+
+BOOL PpcConsKbHit() {
+    return TRUE;
+}
+
+int PpcConsGetCh() {
+    char buf;
+    ofw_read( stdin_handle, &buf, 1 );
+    return buf;
+}
+
+void PpcVideoClearScreen( UCHAR Attr ) {
+    ofw_print_string("ClearScreen\n");
+}
+
+VIDEODISPLAYMODE PpcVideoSetDisplayMode( char *DisplayMode, BOOL Init ) {
+    printf( "DisplayMode: %s %s\n", DisplayMode, Init ? "true" : "false" );
+    return VideoGraphicsMode;
+}
+
+/* FIXME: Query */
+VOID PpcVideoGetDisplaySize( PULONG Width, PULONG Height, PULONG Depth ) {
+    ofw_print_string("GetDisplaySize\n");
+    *Width = 640;
+    *Height = 480;
+    *Depth = 8;
+}
+
+ULONG PpcVideoGetBufferSize() {
+    ULONG Width, Height, Depth;
+    ofw_print_string("PpcVideoGetBufferSize\n");
+    PpcVideoGetDisplaySize( &Width, &Height, &Depth );
+    return Width * Height * Depth / 8;
+}
+
+VOID PpcVideoSetTextCursorPosition( ULONG X, ULONG Y ) {
+    printf("SetTextCursorPosition(%d,%d)\n", X,Y);
+}
+
+VOID PpcVideoHideShowTextCursor( BOOL Show ) {
+    printf("HideShowTextCursor(%s)\n", Show ? "true" : "false");
+}
+
+VOID PpcVideoPutChar( int Ch, UCHAR Attr, unsigned X, unsigned Y ) {
+    printf( "\033[%d;%dH%c", Y, X, Ch );
+}
+
+VOID PpcVideoCopyOffScreenBufferToVRAM( PVOID Buffer ) {
+    printf( "CopyOffScreenBufferToVRAM(%x)\n", Buffer );
+}
+
+BOOL PpcVideoIsPaletteFixed() {
+    return FALSE;
+}
+
+VOID PpcVideoSetPaletteColor( UCHAR Color, 
+                              UCHAR Red, UCHAR Green, UCHAR Blue ) {
+    printf( "SetPaletteColor(%x,%x,%x,%x)\n", Color, Red, Green, Blue );
+}
+
+VOID PpcVideoGetPaletteColor( UCHAR Color, 
+                              UCHAR *Red, UCHAR *Green, UCHAR *Blue ) {
+    printf( "GetPaletteColor(%x)\n", Color);
+}
+
+VOID PpcVideoSync() {
+    printf( "Sync\n" );
+}
+
+VOID PpcVideoPrepareForReactOS() {
+    printf( "PrepareForReactOS\n");
+}
+/* XXX FIXME:
+ * According to the linux people (this is backed up by my own experience),
+ * the memory object in older ofw does not do getprop right.
+ *
+ * The "right" way is to probe the pci bridge. *sigh*
+ */
+ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
+                       ULONG MaxMemoryMapSize ) {
+    printf("GetMemoryMap(chosen=%x)\n", chosen_package);
+
+    BiosMemoryMap[0].Type = MEMTYPE_USABLE;
+    BiosMemoryMap[0].BaseAddress = 0;
+    BiosMemoryMap[0].Length = 32 * 1024 * 1024; /* Assume 32 meg for now */
+
+    printf( "Returning memory map (%dk total)\n", 
+            (int)BiosMemoryMap[0].Length / 1024 );
+
+    return 1;
+}
+
+BOOL PpcDiskReadLogicalSectors( ULONG DriveNumber, ULONGLONG SectorNumber,
+                                ULONG SectorCount, PVOID Buffer ) {
+    printf("DiskReadLogicalSectors\n");
+    return FALSE;
+}
+
+BOOL PpcDiskGetPartitionEntry( ULONG DriveNumber, ULONG PartitionNumber,
+                               PPARTITION_TABLE_ENTRY PartitionTableEntry ) {
+    printf("GetPartitionEntry(%d,%d)\n", DriveNumber, PartitionNumber);
+    return FALSE;
+}
+
+BOOL PpcDiskGetDriveGeometry( ULONG DriveNumber, PGEOMETRY DriveGeometry ) {
+    printf("GetGeometry(%d)\n", DriveNumber);
+    return FALSE;
+}
+
+ULONG PpcDiskGetCacheableBlockCount( ULONG DriveNumber ) {
+    printf("GetCacheableBlockCount\n");
+    return 0;
+}
+
+VOID PpcRTCGetCurrentDateTime( PULONG Hear, PULONG Month, PULONG Day, 
+                               PULONG Hour, PULONG Minute, PULONG Second ) {
+    printf("RTCGeturrentDateTime\n");
+}
+
+VOID PpcHwDetect() {
+}
+
+void PpcInit( of_proxy the_ofproxy ) {
+    ofproxy = the_ofproxy;
+    chosen_package = ofw_finddevice( "/chosen" );
+
+    ofw_getprop( chosen_package, "stdin",
+                 &stdin_handle, sizeof(stdin_handle) );
+
+    stdin_handle = REV(stdin_handle);
+
+    MachVtbl.ConsPutChar = PpcPutChar;
+    MachVtbl.ConsKbHit   = PpcConsKbHit;
+    MachVtbl.ConsGetCh   = PpcConsGetCh;
+
+    printf("chosen_package = %x\n", chosen_package);
+
+    MachVtbl.VideoClearScreen = PpcVideoClearScreen;
+    MachVtbl.VideoSetDisplayMode = PpcVideoSetDisplayMode;
+    MachVtbl.VideoGetDisplaySize = PpcVideoGetDisplaySize;
+    MachVtbl.VideoGetBufferSize = PpcVideoGetBufferSize;
+    MachVtbl.VideoSetTextCursorPosition = PpcVideoSetTextCursorPosition;
+    MachVtbl.VideoHideShowTextCursor = PpcVideoHideShowTextCursor;
+    MachVtbl.VideoPutChar = PpcVideoPutChar;
+    MachVtbl.VideoCopyOffScreenBufferToVRAM = 
+        PpcVideoCopyOffScreenBufferToVRAM;
+    MachVtbl.VideoIsPaletteFixed = PpcVideoIsPaletteFixed;
+    MachVtbl.VideoSetPaletteColor = PpcVideoSetPaletteColor;
+    MachVtbl.VideoGetPaletteColor = PpcVideoGetPaletteColor;
+    MachVtbl.VideoSync = PpcVideoSync;
+    MachVtbl.VideoPrepareForReactOS = PpcVideoPrepareForReactOS;
+
+    MachVtbl.GetMemoryMap = PpcGetMemoryMap;
+
+    MachVtbl.DiskReadLogicalSectors = PpcDiskReadLogicalSectors;
+    MachVtbl.DiskGetPartitionEntry = PpcDiskGetPartitionEntry;
+    MachVtbl.DiskGetDriveGeometry = PpcDiskGetDriveGeometry;
+    MachVtbl.DiskGetCacheableBlockCount = PpcDiskGetCacheableBlockCount;
+
+    MachVtbl.RTCGetCurrentDateTime = PpcRTCGetCurrentDateTime;
+
+    MachVtbl.HwDetect = PpcHwDetect;
+
+    printf( "FreeLDR version [%s]\n", GetFreeLoaderVersionString() );
+    BootMain("freeldr-ppc");    
+}
+
+void MachInit() {
+    int len;
+    printf( "Determining boot device:\n" );
+    len = ofw_getprop(chosen_package, "bootpath", 
+                      BootPath, sizeof(BootPath));
+    printf( "Got %d bytes of path\n", len );
+    BootPath[len] = 0;
+    printf( "Boot Path: %s\n", BootPath );
+
+    printf( "FreeLDR starting\n" );
+}
+
+void FrLdrSetupPageDirectory() {
+}
+
+void beep() {
+}
+
+UCHAR STDCALL READ_PORT_UCHAR(PUCHAR Address) {
+    return 0xff;
+}
+
+void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value) {
+}
index 625020a..fc8505a 100644 (file)
@@ -21,7 +21,7 @@
  * Limitations:
  * - No support for compressed files.
  * - No attribute list support.
- * - May crash on currupted filesystem.
+ * - May crash on corrupted filesystem.
  */
 
 #include <freeldr.h>
index f4e2cb4..0e50e08 100644 (file)
@@ -52,6 +52,7 @@
 #define MB_INFO_FLAG_BOOT_LOADER_NAME  0x00000200
 #define MB_INFO_FLAG_APM_TABLE                 0x00000400
 #define MB_INFO_FLAG_GRAPHICS_TABLE            0x00000800
+#define MB_INFO_FLAG_ACPI_TABLE         0x00001000
 
 #ifndef ASM
 /* Do not include here in boot.S. */
index 7dbb41d..7fcd53c 100644 (file)
@@ -38,6 +38,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  */
 #ifdef __i386__
 #include "i386.h"
+#elif defined(_M_PPC)
+#include "powerpc.h"
 #endif
 #define L_clz
 #define L_udivdi3
diff --git a/reactos/boot/freeldr/freeldr/math/powerpc.h b/reactos/boot/freeldr/freeldr/math/powerpc.h
new file mode 100644 (file)
index 0000000..ba13f91
--- /dev/null
@@ -0,0 +1,3208 @@
+/* Definitions of target machine for GNU compiler for IA-32.
+   Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+   2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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, or (at your option)
+any later version.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* The purpose of this file is to define the characteristics of the i386,
+   independent of assembler syntax or operating system.
+
+   Three other files build on this one to describe a specific assembler syntax:
+   bsd386.h, att386.h, and sun386.h.
+
+   The actual tm.h file for a particular system should include
+   this file, and then the file for the appropriate assembler syntax.
+
+   Many macros that specify assembler syntax are omitted entirely from
+   this file because they really belong in the files for particular
+   assemblers.  These include RP, IP, LPREFIX, PUT_OP_SIZE, USE_STAR,
+   ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many
+   that start with ASM_ or end in ASM_OP.  */
+
+/* Stubs for half-pic support if not OSF/1 reference platform.  */
+
+#ifndef HALF_PIC_P
+#define HALF_PIC_P() 0
+#define HALF_PIC_NUMBER_PTRS 0
+#define HALF_PIC_NUMBER_REFS 0
+#define HALF_PIC_ENCODE(DECL)
+#define HALF_PIC_DECLARE(NAME)
+#define HALF_PIC_INIT()        error ("half-pic init called on systems that don't support it")
+#define HALF_PIC_ADDRESS_P(X) 0
+#define HALF_PIC_PTR(X) (X)
+#define HALF_PIC_FINISH(STREAM)
+#endif
+
+/* Define the specific costs for a given cpu */
+
+struct processor_costs {
+  const int add;               /* cost of an add instruction */
+  const int lea;               /* cost of a lea instruction */
+  const int shift_var;         /* variable shift costs */
+  const int shift_const;       /* constant shift costs */
+  const int mult_init;         /* cost of starting a multiply */
+  const int mult_bit;          /* cost of multiply per each bit set */
+  const int divide;            /* cost of a divide/mod */
+  int movsx;                   /* The cost of movsx operation.  */
+  int movzx;                   /* The cost of movzx operation.  */
+  const int large_insn;                /* insns larger than this cost more */
+  const int move_ratio;                /* The threshold of number of scalar
+                                  memory-to-memory move insns.  */
+  const int movzbl_load;       /* cost of loading using movzbl */
+  const int int_load[3];       /* cost of loading integer registers
+                                  in QImode, HImode and SImode relative
+                                  to reg-reg move (2).  */
+  const int int_store[3];      /* cost of storing integer register
+                                  in QImode, HImode and SImode */
+  const int fp_move;           /* cost of reg,reg fld/fst */
+  const int fp_load[3];                /* cost of loading FP register
+                                  in SFmode, DFmode and XFmode */
+  const int fp_store[3];       /* cost of storing FP register
+                                  in SFmode, DFmode and XFmode */
+  const int mmx_move;          /* cost of moving MMX register.  */
+  const int mmx_load[2];       /* cost of loading MMX register
+                                  in SImode and DImode */
+  const int mmx_store[2];      /* cost of storing MMX register
+                                  in SImode and DImode */
+  const int sse_move;          /* cost of moving SSE register.  */
+  const int sse_load[3];       /* cost of loading SSE register
+                                  in SImode, DImode and TImode*/
+  const int sse_store[3];      /* cost of storing SSE register
+                                  in SImode, DImode and TImode*/
+  const int mmxsse_to_integer; /* cost of moving mmxsse register to
+                                  integer and vice versa.  */
+  const int prefetch_block;    /* bytes moved to cache for prefetch.  */
+  const int simultaneous_prefetches; /* number of parallel prefetch
+                                  operations.  */
+};
+
+extern const struct processor_costs *ix86_cost;
+
+/* Run-time compilation parameters selecting different hardware subsets.  */
+
+extern int target_flags;
+
+/* Macros used in the machine description to test the flags.  */
+
+/* configure can arrange to make this 2, to force a 486.  */
+
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT 0
+#endif
+
+/* Masks for the -m switches */
+#define MASK_80387             0x00000001      /* Hardware floating point */
+#define MASK_RTD               0x00000002      /* Use ret that pops args */
+#define MASK_ALIGN_DOUBLE      0x00000004      /* align doubles to 2 word boundary */
+#define MASK_SVR3_SHLIB                0x00000008      /* Uninit locals into bss */
+#define MASK_IEEE_FP           0x00000010      /* IEEE fp comparisons */
+#define MASK_FLOAT_RETURNS     0x00000020      /* Return float in st(0) */
+#define MASK_NO_FANCY_MATH_387 0x00000040      /* Disable sin, cos, sqrt */
+#define MASK_OMIT_LEAF_FRAME_POINTER 0x080      /* omit leaf frame pointers */
+#define MASK_STACK_PROBE       0x00000100      /* Enable stack probing */
+#define MASK_NO_ALIGN_STROPS   0x00000200      /* Enable aligning of string ops.  */
+#define MASK_INLINE_ALL_STROPS 0x00000400      /* Inline stringops in all cases */
+#define MASK_NO_PUSH_ARGS      0x00000800      /* Use push instructions */
+#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00001000/* Accumulate outgoing args */
+#define MASK_ACCUMULATE_OUTGOING_ARGS_SET 0x00002000
+#define MASK_MMX               0x00004000      /* Support MMX regs/builtins */
+#define MASK_MMX_SET           0x00008000
+#define MASK_SSE               0x00010000      /* Support SSE regs/builtins */
+#define MASK_SSE_SET           0x00020000
+#define MASK_SSE2              0x00040000      /* Support SSE2 regs/builtins */
+#define MASK_SSE2_SET          0x00080000
+#define MASK_3DNOW             0x00100000      /* Support 3Dnow builtins */
+#define MASK_3DNOW_SET         0x00200000
+#define MASK_3DNOW_A           0x00400000      /* Support Athlon 3Dnow builtins */
+#define MASK_3DNOW_A_SET       0x00800000
+#define MASK_128BIT_LONG_DOUBLE 0x01000000     /* long double size is 128bit */
+#define MASK_64BIT             0x02000000      /* Produce 64bit code */
+/* ... overlap with subtarget options starts by 0x04000000.  */
+#define MASK_NO_RED_ZONE       0x04000000      /* Do not use red zone */
+
+/* Use the floating point instructions */
+#define TARGET_80387 (target_flags & MASK_80387)
+
+/* Compile using ret insn that pops args.
+   This will not work unless you use prototypes at least
+   for all functions that can take varying numbers of args.  */  
+#define TARGET_RTD (target_flags & MASK_RTD)
+
+/* Align doubles to a two word boundary.  This breaks compatibility with
+   the published ABI's for structures containing doubles, but produces
+   faster code on the pentium.  */
+#define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE)
+
+/* Use push instructions to save outgoing args.  */
+#define TARGET_PUSH_ARGS (!(target_flags & MASK_NO_PUSH_ARGS))
+
+/* Accumulate stack adjustments to prologue/epilogue.  */
+#define TARGET_ACCUMULATE_OUTGOING_ARGS \
+ (target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
+
+/* Put uninitialized locals into bss, not data.
+   Meaningful only on svr3.  */
+#define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB)
+
+/* Use IEEE floating point comparisons.  These handle correctly the cases
+   where the result of a comparison is unordered.  Normally SIGFPE is
+   generated in such cases, in which case this isn't needed.  */
+#define TARGET_IEEE_FP (target_flags & MASK_IEEE_FP)
+
+/* Functions that return a floating point value may return that value
+   in the 387 FPU or in 386 integer registers.  If set, this flag causes
+   the 387 to be used, which is compatible with most calling conventions.  */
+#define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & MASK_FLOAT_RETURNS)
+
+/* Long double is 128bit instead of 96bit, even when only 80bits are used.
+   This mode wastes cache, but avoid misaligned data accesses and simplifies
+   address calculations.  */
+#define TARGET_128BIT_LONG_DOUBLE (target_flags & MASK_128BIT_LONG_DOUBLE)
+
+/* Disable generation of FP sin, cos and sqrt operations for 387.
+   This is because FreeBSD lacks these in the math-emulator-code */
+#define TARGET_NO_FANCY_MATH_387 (target_flags & MASK_NO_FANCY_MATH_387)
+
+/* Don't create frame pointers for leaf functions */
+#define TARGET_OMIT_LEAF_FRAME_POINTER \
+  (target_flags & MASK_OMIT_LEAF_FRAME_POINTER)
+
+/* Debug GO_IF_LEGITIMATE_ADDRESS */
+#define TARGET_DEBUG_ADDR (ix86_debug_addr_string != 0)
+
+/* Debug FUNCTION_ARG macros */
+#define TARGET_DEBUG_ARG (ix86_debug_arg_string != 0)
+
+#if 0
+/* 64bit Sledgehammer mode */
+#ifdef TARGET_BI_ARCH
+#define TARGET_64BIT (target_flags & MASK_64BIT)
+#else
+#ifdef TARGET_64BIT_DEFAULT
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+#define TARGET_386 (ix86_cpu == PROCESSOR_I386)
+#define TARGET_486 (ix86_cpu == PROCESSOR_I486)
+#define TARGET_PENTIUM (ix86_cpu == PROCESSOR_PENTIUM)
+#define TARGET_PENTIUMPRO (ix86_cpu == PROCESSOR_PENTIUMPRO)
+#define TARGET_K6 (ix86_cpu == PROCESSOR_K6)
+#define TARGET_ATHLON (ix86_cpu == PROCESSOR_ATHLON)
+#define TARGET_PENTIUM4 (ix86_cpu == PROCESSOR_PENTIUM4)
+
+#define CPUMASK (1 << ix86_cpu)
+extern const int x86_use_leave, x86_push_memory, x86_zero_extend_with_and;
+extern const int x86_use_bit_test, x86_cmove, x86_deep_branch;
+extern const int x86_branch_hints, x86_unroll_strlen;
+extern const int x86_double_with_add, x86_partial_reg_stall, x86_movx;
+extern const int x86_use_loop, x86_use_fiop, x86_use_mov0;
+extern const int x86_use_cltd, x86_read_modify_write;
+extern const int x86_read_modify, x86_split_long_moves;
+extern const int x86_promote_QImode, x86_single_stringop;
+extern const int x86_himode_math, x86_qimode_math, x86_promote_qi_regs;
+extern const int x86_promote_hi_regs, x86_integer_DFmode_moves;
+extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8;
+extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
+extern const int x86_accumulate_outgoing_args, x86_prologue_using_move;
+extern const int x86_epilogue_using_move, x86_decompose_lea;
+extern const int x86_arch_always_fancy_math_387;
+extern int x86_prefetch_sse;
+
+#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
+#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
+#define TARGET_ZERO_EXTEND_WITH_AND (x86_zero_extend_with_and & CPUMASK)
+#define TARGET_USE_BIT_TEST (x86_use_bit_test & CPUMASK)
+#define TARGET_UNROLL_STRLEN (x86_unroll_strlen & CPUMASK)
+/* For sane SSE instruction set generation we need fcomi instruction.  It is
+   safe to enable all CMOVE instructions.  */
+#define TARGET_CMOVE ((x86_cmove & (1 << ix86_arch)) || TARGET_SSE)
+#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK)
+#define TARGET_BRANCH_PREDICTION_HINTS (x86_branch_hints & CPUMASK)
+#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
+#define TARGET_USE_SAHF ((x86_use_sahf & CPUMASK) && !TARGET_64BIT)
+#define TARGET_MOVX (x86_movx & CPUMASK)
+#define TARGET_PARTIAL_REG_STALL (x86_partial_reg_stall & CPUMASK)
+#define TARGET_USE_LOOP (x86_use_loop & CPUMASK)
+#define TARGET_USE_FIOP (x86_use_fiop & CPUMASK)
+#define TARGET_USE_MOV0 (x86_use_mov0 & CPUMASK)
+#define TARGET_USE_CLTD (x86_use_cltd & CPUMASK)
+#define TARGET_SPLIT_LONG_MOVES (x86_split_long_moves & CPUMASK)
+#define TARGET_READ_MODIFY_WRITE (x86_read_modify_write & CPUMASK)
+#define TARGET_READ_MODIFY (x86_read_modify & CPUMASK)
+#define TARGET_PROMOTE_QImode (x86_promote_QImode & CPUMASK)
+#define TARGET_SINGLE_STRINGOP (x86_single_stringop & CPUMASK)
+#define TARGET_QIMODE_MATH (x86_qimode_math & CPUMASK)
+#define TARGET_HIMODE_MATH (x86_himode_math & CPUMASK)
+#define TARGET_PROMOTE_QI_REGS (x86_promote_qi_regs & CPUMASK)
+#define TARGET_PROMOTE_HI_REGS (x86_promote_hi_regs & CPUMASK)
+#define TARGET_ADD_ESP_4 (x86_add_esp_4 & CPUMASK)
+#define TARGET_ADD_ESP_8 (x86_add_esp_8 & CPUMASK)
+#define TARGET_SUB_ESP_4 (x86_sub_esp_4 & CPUMASK)
+#define TARGET_SUB_ESP_8 (x86_sub_esp_8 & CPUMASK)
+#define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & CPUMASK)
+#define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & CPUMASK)
+#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK)
+#define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & CPUMASK)
+#define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & CPUMASK)
+#define TARGET_DECOMPOSE_LEA (x86_decompose_lea & CPUMASK)
+#define TARGET_PREFETCH_SSE (x86_prefetch_sse)
+
+#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
+
+#define TARGET_ALIGN_STRINGOPS (!(target_flags & MASK_NO_ALIGN_STROPS))
+#define TARGET_INLINE_ALL_STRINGOPS (target_flags & MASK_INLINE_ALL_STROPS)
+
+#define ASSEMBLER_DIALECT (ix86_asm_dialect)
+
+#define TARGET_SSE ((target_flags & (MASK_SSE | MASK_SSE2)) != 0)
+#define TARGET_SSE2 ((target_flags & MASK_SSE2) != 0)
+#define TARGET_SSE_MATH ((ix86_fpmath & FPMATH_SSE) != 0)
+#define TARGET_MIX_SSE_I387 ((ix86_fpmath & FPMATH_SSE) \
+                            && (ix86_fpmath & FPMATH_387))
+#define TARGET_MMX ((target_flags & MASK_MMX) != 0)
+#define TARGET_3DNOW ((target_flags & MASK_3DNOW) != 0)
+#define TARGET_3DNOW_A ((target_flags & MASK_3DNOW_A) != 0)
+#endif
+
+#define TARGET_RED_ZONE (!(target_flags & MASK_NO_RED_ZONE))
+
+/* WARNING: Do not mark empty strings for translation, as calling
+            gettext on an empty string does NOT return an empty
+            string. */
+
+#if 0
+#define TARGET_SWITCHES                                                              \
+{ { "80387",                    MASK_80387, N_("Use hardware fp") },         \
+  { "no-80387",                        -MASK_80387, N_("Do not use hardware fp") },  \
+  { "hard-float",               MASK_80387, N_("Use hardware fp") },         \
+  { "soft-float",              -MASK_80387, N_("Do not use hardware fp") },  \
+  { "no-soft-float",            MASK_80387, N_("Use hardware fp") },         \
+  { "386",                      0, "" /*Deprecated.*/},                      \
+  { "486",                      0, "" /*Deprecated.*/},                      \
+  { "pentium",                  0, "" /*Deprecated.*/},                      \
+  { "pentiumpro",               0, "" /*Deprecated.*/},                      \
+  { "intel-syntax",             0, "" /*Deprecated.*/},                      \
+  { "no-intel-syntax",          0, "" /*Deprecated.*/},                      \
+  { "rtd",                      MASK_RTD,                                    \
+    N_("Alternate calling convention") },                                    \
+  { "no-rtd",                  -MASK_RTD,                                    \
+    N_("Use normal calling convention") },                                   \
+  { "align-double",             MASK_ALIGN_DOUBLE,                           \
+    N_("Align some doubles on dword boundary") },                            \
+  { "no-align-double",         -MASK_ALIGN_DOUBLE,                           \
+    N_("Align doubles on word boundary") },                                  \
+  { "svr3-shlib",               MASK_SVR3_SHLIB,                             \
+    N_("Uninitialized locals in .bss")  },                                   \
+  { "no-svr3-shlib",           -MASK_SVR3_SHLIB,                             \
+    N_("Uninitialized locals in .data") },                                   \
+  { "ieee-fp",                  MASK_IEEE_FP,                                \
+    N_("Use IEEE math for fp comparisons") },                                \
+  { "no-ieee-fp",              -MASK_IEEE_FP,                                \
+    N_("Do not use IEEE math for fp comparisons") },                         \
+  { "fp-ret-in-387",            MASK_FLOAT_RETURNS,                          \
+    N_("Return values of functions in FPU registers") },                     \
+  { "no-fp-ret-in-387",                -MASK_FLOAT_RETURNS ,                         \
+    N_("Do not return values of functions in FPU registers")},               \
+  { "no-fancy-math-387",        MASK_NO_FANCY_MATH_387,                      \
+    N_("Do not generate sin, cos, sqrt for FPU") },                          \
+  { "fancy-math-387",          -MASK_NO_FANCY_MATH_387,                      \
+     N_("Generate sin, cos, sqrt for FPU")},                                 \
+  { "omit-leaf-frame-pointer",  MASK_OMIT_LEAF_FRAME_POINTER,                \
+    N_("Omit the frame pointer in leaf functions") },                        \
+  { "no-omit-leaf-frame-pointer",-MASK_OMIT_LEAF_FRAME_POINTER, "" },        \
+  { "stack-arg-probe",          MASK_STACK_PROBE,                            \
+    N_("Enable stack probing") },                                            \
+  { "no-stack-arg-probe",      -MASK_STACK_PROBE, "" },                      \
+  { "windows",                 0, 0 /* undocumented */ },                    \
+  { "dll",                     0,  0 /* undocumented */ },                   \
+  { "align-stringops",         -MASK_NO_ALIGN_STROPS,                        \
+    N_("Align destination of the string operations") },                              \
+  { "no-align-stringops",       MASK_NO_ALIGN_STROPS,                        \
+    N_("Do not align destination of the string operations") },               \
+  { "inline-all-stringops",     MASK_INLINE_ALL_STROPS,                      \
+    N_("Inline all known string operations") },                                      \
+  { "no-inline-all-stringops", -MASK_INLINE_ALL_STROPS,                      \
+    N_("Do not inline all known string operations") },                       \
+  { "push-args",               -MASK_NO_PUSH_ARGS,                           \
+    N_("Use push instructions to save outgoing arguments") },                \
+  { "no-push-args",            MASK_NO_PUSH_ARGS,                            \
+    N_("Do not use push instructions to save outgoing arguments") },         \
+  { "accumulate-outgoing-args",        (MASK_ACCUMULATE_OUTGOING_ARGS                \
+                                | MASK_ACCUMULATE_OUTGOING_ARGS_SET),        \
+    N_("Use push instructions to save outgoing arguments") },                \
+  { "no-accumulate-outgoing-args",MASK_ACCUMULATE_OUTGOING_ARGS_SET,         \
+    N_("Do not use push instructions to save outgoing arguments") },         \
+  { "mmx",                      MASK_MMX | MASK_MMX_SET,                     \
+    N_("Support MMX built-in functions") },                                  \
+  { "no-mmx",                   -MASK_MMX,                                   \
+    N_("Do not support MMX built-in functions") },                           \
+  { "no-mmx",                   MASK_MMX_SET, "" },                          \
+  { "3dnow",                     MASK_3DNOW | MASK_3DNOW_SET,                \
+    N_("Support 3DNow! built-in functions") },                               \
+  { "no-3dnow",                  -MASK_3DNOW, "" },                          \
+  { "no-3dnow",                  MASK_3DNOW_SET,                             \
+    N_("Do not support 3DNow! built-in functions") },                        \
+  { "sse",                      MASK_SSE | MASK_SSE_SET,                     \
+    N_("Support MMX and SSE built-in functions and code generation") },              \
+  { "no-sse",                   -MASK_SSE, "" },                             \
+  { "no-sse",                   MASK_SSE_SET,                                \
+    N_("Do not support MMX and SSE built-in functions and code generation") },\
+  { "sse2",                     MASK_SSE2 | MASK_SSE2_SET,                   \
+    N_("Support MMX, SSE and SSE2 built-in functions and code generation") }, \
+  { "no-sse2",                  -MASK_SSE2, "" },                            \
+  { "no-sse2",                  MASK_SSE2_SET,                               \
+    N_("Do not support MMX, SSE and SSE2 built-in functions and code generation") },    \
+  { "128bit-long-double",       MASK_128BIT_LONG_DOUBLE,                     \
+    N_("sizeof(long double) is 16") },                                       \
+  { "96bit-long-double",       -MASK_128BIT_LONG_DOUBLE,                     \
+    N_("sizeof(long double) is 12") },                                       \
+  { "64",                      MASK_64BIT,                                   \
+    N_("Generate 64bit x86-64 code") },                                              \
+  { "32",                      -MASK_64BIT,                                  \
+    N_("Generate 32bit i386 code") },                                        \
+  { "red-zone",                        -MASK_NO_RED_ZONE,                            \
+    N_("Use red-zone in the x86-64 code") },                                 \
+  { "no-red-zone",             MASK_NO_RED_ZONE,                             \
+    N_("Do not use red-zone in the x86-64 code") },                          \
+  SUBTARGET_SWITCHES                                                         \
+  { "", TARGET_DEFAULT, 0 }}
+
+#ifdef TARGET_64BIT_DEFAULT
+#define TARGET_DEFAULT (MASK_64BIT | TARGET_SUBTARGET_DEFAULT)
+#else
+#define TARGET_DEFAULT TARGET_SUBTARGET_DEFAULT
+#endif
+
+/* Which processor to schedule for. The cpu attribute defines a list that
+   mirrors this list, so changes to i386.md must be made at the same time.  */
+
+enum processor_type
+{
+  PROCESSOR_I386,                      /* 80386 */
+  PROCESSOR_I486,                      /* 80486DX, 80486SX, 80486DX[24] */
+  PROCESSOR_PENTIUM,
+  PROCESSOR_PENTIUMPRO,
+  PROCESSOR_K6,
+  PROCESSOR_ATHLON,
+  PROCESSOR_PENTIUM4,
+  PROCESSOR_max
+};
+enum fpmath_unit
+{
+  FPMATH_387 = 1,
+  FPMATH_SSE = 2
+};
+
+extern enum processor_type ix86_cpu;
+extern enum fpmath_unit ix86_fpmath;
+
+extern int ix86_arch;
+
+/* This macro is similar to `TARGET_SWITCHES' but defines names of
+   command options that have values.  Its definition is an
+   initializer with a subgrouping for each command option.
+
+   Each subgrouping contains a string constant, that defines the
+   fixed part of the option name, and the address of a variable.  The
+   variable, type `char *', is set to the variable part of the given
+   option if the fixed part matches.  The actual option name is made
+   by appending `-m' to the specified name.  */
+#define TARGET_OPTIONS                                         \
+{ { "cpu=",            &ix86_cpu_string,                       \
+    N_("Schedule code for given CPU")},                                \
+  { "fpmath=",         &ix86_fpmath_string,                    \
+    N_("Generate floating point mathematics using given instruction set")},\
+  { "arch=",           &ix86_arch_string,                      \
+    N_("Generate code for given CPU")},                                \
+  { "regparm=",                &ix86_regparm_string,                   \
+    N_("Number of registers used to pass integer arguments") },        \
+  { "align-loops=",    &ix86_align_loops_string,               \
+    N_("Loop code aligned to this power of 2") },              \
+  { "align-jumps=",    &ix86_align_jumps_string,               \
+    N_("Jump targets are aligned to this power of 2") },       \
+  { "align-functions=",        &ix86_align_funcs_string,               \
+    N_("Function starts are aligned to this power of 2") },    \
+  { "preferred-stack-boundary=",                               \
+    &ix86_preferred_stack_boundary_string,                     \
+    N_("Attempt to keep stack aligned to this power of 2") },  \
+  { "branch-cost=",    &ix86_branch_cost_string,               \
+    N_("Branches are this expensive (1-5, arbitrary units)") },        \
+  { "cmodel=", &ix86_cmodel_string,                            \
+    N_("Use given x86-64 code model") },                       \
+  { "debug-arg", &ix86_debug_arg_string,                       \
+    "" /* Undocumented. */ },                                  \
+  { "debug-addr", &ix86_debug_addr_string,                     \
+    "" /* Undocumented. */ },                                  \
+  { "asm=", &ix86_asm_string,                                  \
+    N_("Use given assembler dialect") },                       \
+  SUBTARGET_OPTIONS                                            \
+}
+#endif
+
+/* Sometimes certain combinations of command options do not make
+   sense on a particular target machine.  You can define a macro
+   `OVERRIDE_OPTIONS' to take account of this.  This macro, if
+   defined, is executed once just after all the command options have
+   been parsed.
+
+   Don't use this macro to turn on various extra optimizations for
+   `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
+
+#define OVERRIDE_OPTIONS override_options ()
+
+/* These are meant to be redefined in the host dependent files */
+#define SUBTARGET_SWITCHES
+#define SUBTARGET_OPTIONS
+
+/* Define this to change the optimizations performed by default.  */
+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
+  optimization_options ((LEVEL), (SIZE))
+
+/* Specs for the compiler proper */
+
+#if 0
+#ifndef CC1_CPU_SPEC
+#define CC1_CPU_SPEC "\
+%{!mcpu*: \
+%{m386:-mcpu=i386 \
+%n`-m386' is deprecated. Use `-march=i386' or `-mcpu=i386' instead.\n} \
+%{m486:-mcpu=i486 \
+%n`-m486' is deprecated. Use `-march=i486' or `-mcpu=i486' instead.\n} \
+%{mpentium:-mcpu=pentium \
+%n`-mpentium' is deprecated. Use `-march=pentium' or `-mcpu=pentium' instead.\n} \
+%{mpentiumpro:-mcpu=pentiumpro \
+%n`-mpentiumpro' is deprecated. Use `-march=pentiumpro' or `-mcpu=pentiumpro' instead.\n}} \
+%{mintel-syntax:-masm=intel \
+%n`-mintel-syntax' is deprecated. Use `-masm=intel' instead.\n} \
+%{mno-intel-syntax:-masm=att \
+%n`-mno-intel-syntax' is deprecated. Use `-masm=att' instead.\n}"
+#endif
+\f
+#define TARGET_CPU_DEFAULT_i386 0
+#define TARGET_CPU_DEFAULT_i486 1
+#define TARGET_CPU_DEFAULT_pentium 2
+#define TARGET_CPU_DEFAULT_pentium_mmx 3
+#define TARGET_CPU_DEFAULT_pentiumpro 4
+#define TARGET_CPU_DEFAULT_pentium2 5
+#define TARGET_CPU_DEFAULT_pentium3 6
+#define TARGET_CPU_DEFAULT_pentium4 7
+#define TARGET_CPU_DEFAULT_k6 8
+#define TARGET_CPU_DEFAULT_k6_2 9
+#define TARGET_CPU_DEFAULT_k6_3 10
+#define TARGET_CPU_DEFAULT_athlon 11
+#define TARGET_CPU_DEFAULT_athlon_sse 12
+
+#define TARGET_CPU_DEFAULT_NAMES {"i386", "i486", "pentium", "pentium-mmx",\
+                                 "pentiumpro", "pentium2", "pentium3", \
+                                 "pentium4", "k6", "k6-2", "k6-3",\
+                                 "athlon", "athlon-4"}
+#ifndef CPP_CPU_DEFAULT_SPEC
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_i486
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i486__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentium
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i586__ -D__tune_pentium__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentium_mmx
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i586__ -D__tune_pentium__ -D__tune_pentium_mmx__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentiumpro
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i686__ -D__tune_pentiumpro__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentium2
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i686__ -D__tune_pentiumpro__\
+-D__tune_pentium2__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentium3
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i686__ -D__tune_pentiumpro__\
+-D__tune_pentium2__ -D__tune_pentium3__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_pentium4
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_pentium4__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_k6
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_k6__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_k6_2
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_k6__ -D__tune_k6_2__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_k6_3
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_k6__ -D__tune_k6_3__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_athlon
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_athlon__"
+#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_DEFAULT_athlon_sse
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_athlon__ -D__tune_athlon_sse__"
+#endif
+#ifndef CPP_CPU_DEFAULT_SPEC
+#define CPP_CPU_DEFAULT_SPEC "-D__tune_i386__"
+#endif
+#endif /* CPP_CPU_DEFAULT_SPEC */
+
+#ifdef TARGET_BI_ARCH
+#define NO_BUILTIN_SIZE_TYPE
+#define NO_BUILTIN_PTRDIFF_TYPE
+#endif
+
+#ifdef NO_BUILTIN_SIZE_TYPE
+#define CPP_CPU32_SIZE_TYPE_SPEC \
+  " -D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int"
+#define CPP_CPU64_SIZE_TYPE_SPEC \
+  " -D__SIZE_TYPE__=unsigned\\ long\\ int -D__PTRDIFF_TYPE__=long\\ int"
+#else
+#define CPP_CPU32_SIZE_TYPE_SPEC ""
+#define CPP_CPU64_SIZE_TYPE_SPEC ""
+#endif
+
+#define CPP_CPU32_SPEC \
+  "-Acpu=i386 -Amachine=i386 %{!ansi:%{!std=c*:%{!std=i*:-Di386}}} -D__i386 \
+-D__i386__ %(cpp_cpu32sizet)"
+
+#define CPP_CPU64_SPEC \
+  "-Acpu=x86_64 -Amachine=x86_64 -D__x86_64 -D__x86_64__ %(cpp_cpu64sizet)"
+
+#define CPP_CPUCOMMON_SPEC "\
+%{march=i386:%{!mcpu*:-D__tune_i386__ }}\
+%{march=i486:-D__i486 -D__i486__ %{!mcpu*:-D__tune_i486__ }}\
+%{march=pentium|march=i586:-D__i586 -D__i586__ -D__pentium -D__pentium__ \
+  %{!mcpu*:-D__tune_i586__ -D__tune_pentium__ }}\
+%{march=pentium-mmx:-D__i586 -D__i586__ -D__pentium -D__pentium__ \
+  -D__pentium__mmx__ \
+  %{!mcpu*:-D__tune_i586__ -D__tune_pentium__ -D__tune_pentium_mmx__}}\
+%{march=pentiumpro|march=i686:-D__i686 -D__i686__ \
+  -D__pentiumpro -D__pentiumpro__ \
+  %{!mcpu*:-D__tune_i686__ -D__tune_pentiumpro__ }}\
+%{march=k6:-D__k6 -D__k6__ %{!mcpu*:-D__tune_k6__ }}\
+%{march=k6-2:-D__k6 -D__k6__ -D__k6_2__ \
+  %{!mcpu*:-D__tune_k6__ -D__tune_k6_2__ }}\
+%{march=k6-3:-D__k6 -D__k6__ -D__k6_3__ \
+  %{!mcpu*:-D__tune_k6__ -D__tune_k6_3__ }}\
+%{march=athlon|march=athlon-tbird:-D__athlon -D__athlon__ \
+  %{!mcpu*:-D__tune_athlon__ }}\
+%{march=athlon-4|march=athlon-xp|march=athlon-mp:-D__athlon -D__athlon__ \
+  -D__athlon_sse__ \
+  %{!mcpu*:-D__tune_athlon__ -D__tune_athlon_sse__ }}\
+%{march=pentium4:-D__pentium4 -D__pentium4__ %{!mcpu*:-D__tune_pentium4__ }}\
+%{m386|mcpu=i386:-D__tune_i386__ }\
+%{m486|mcpu=i486:-D__tune_i486__ }\
+%{mpentium|mcpu=pentium|mcpu=i586|mcpu=pentium-mmx:-D__tune_i586__ -D__tune_pentium__ }\
+%{mpentiumpro|mcpu=pentiumpro|mcpu=i686|cpu=pentium2|cpu=pentium3:-D__tune_i686__ \
+-D__tune_pentiumpro__ }\
+%{mcpu=k6|mcpu=k6-2|mcpu=k6-3:-D__tune_k6__ }\
+%{mcpu=athlon|mcpu=athlon-tbird|mcpu=athlon-4|mcpu=athlon-xp|mcpu=athlon-mp:\
+-D__tune_athlon__ }\
+%{mcpu=athlon-4|mcpu=athlon-xp|mcpu=athlon-mp:\
+-D__tune_athlon_sse__ }\
+%{mcpu=pentium4:-D__tune_pentium4__ }\
+%{march=athlon-tbird|march=athlon-xp|march=athlon-mp|march=pentium3|march=pentium4:\
+-D__SSE__ }\
+%{march=pentium-mmx|march=k6|march=k6-2|march=k6-3\
+|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
+|march=athlon-mp|march=pentium2|march=pentium3|march=pentium4: -D__MMX__ }\
+%{march=k6-2|march=k6-3\
+|march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
+|march=athlon-mp: -D__3dNOW__ }\
+%{march=athlon|march=athlon-tbird|march=athlon-4|march=athlon-xp\
+|march=athlon-mp: -D__3dNOW_A__ }\
+%{march=pentium4: -D__SSE2__ }\
+%{!march*:%{!mcpu*:%{!m386:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}}}"
+
+#ifndef CPP_CPU_SPEC
+#ifdef TARGET_BI_ARCH
+#ifdef TARGET_64BIT_DEFAULT
+#define CPP_CPU_SPEC "%{m32:%(cpp_cpu32)}%{!m32:%(cpp_cpu64)} %(cpp_cpucommon)"
+#else
+#define CPP_CPU_SPEC "%{m64:%(cpp_cpu64)}%{!m64:%(cpp_cpu32)} %(cpp_cpucommon)"
+#endif
+#else
+#ifdef TARGET_64BIT_DEFAULT
+#define CPP_CPU_SPEC "%(cpp_cpu64) %(cpp_cpucommon)"
+#else
+#define CPP_CPU_SPEC "%(cpp_cpu32) %(cpp_cpucommon)"
+#endif
+#endif
+#endif
+
+#ifndef CC1_SPEC
+#define CC1_SPEC "%(cc1_cpu) "
+#endif
+
+/* This macro defines names of additional specifications to put in the
+   specs that can be used in various specifications like CC1_SPEC.  Its
+   definition is an initializer with a subgrouping for each command option.
+
+   Each subgrouping contains a string constant, that defines the
+   specification name, and a string constant that used by the GNU CC driver
+   program.
+
+   Do not define this macro if it does not need to do anything.  */
+
+#ifndef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS
+#endif
+
+#define EXTRA_SPECS                                                    \
+  { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC },                         \
+  { "cpp_cpu", CPP_CPU_SPEC },                                         \
+  { "cpp_cpu32", CPP_CPU32_SPEC },                                     \
+  { "cpp_cpu64", CPP_CPU64_SPEC },                                     \
+  { "cpp_cpu32sizet", CPP_CPU32_SIZE_TYPE_SPEC },                      \
+  { "cpp_cpu64sizet", CPP_CPU64_SIZE_TYPE_SPEC },                      \
+  { "cpp_cpucommon", CPP_CPUCOMMON_SPEC },                             \
+  { "cc1_cpu",  CC1_CPU_SPEC },                                                \
+  SUBTARGET_EXTRA_SPECS
+#endif
+\f
+/* target machine storage layout */
+
+/* Define for XFmode or TFmode extended real floating point support.
+   This will automatically cause REAL_ARITHMETIC to be defined.
+   The XFmode is specified by i386 ABI, while TFmode may be faster
+   due to alignment and simplifications in the address calculations.
+ */
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_128BIT_LONG_DOUBLE ? 128 : 96)
+#define MAX_LONG_DOUBLE_TYPE_SIZE 64
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+/* Tell real.c that this is the 80-bit Intel extended float format
+   packaged in a 128-bit or 96bit entity.  */
+#define INTEL_EXTENDED_IEEE_FORMAT 1
+
+
+#define SHORT_TYPE_SIZE 16
+#define INT_TYPE_SIZE 32
+#define FLOAT_TYPE_SIZE 32
+#define LONG_TYPE_SIZE BITS_PER_WORD
+#define MAX_WCHAR_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 64
+#define LONG_LONG_TYPE_SIZE 64
+
+#if defined (TARGET_BI_ARCH) || defined (TARGET_64BIT_DEFAULT)
+#define MAX_BITS_PER_WORD 64
+#define MAX_LONG_TYPE_SIZE 64
+#else
+#define MAX_BITS_PER_WORD 32
+#define MAX_LONG_TYPE_SIZE 32
+#endif
+
+/* Define if you don't want extended real, but do want to use the
+   software floating point emulator for REAL_ARITHMETIC and
+   decimal <-> binary conversion.  */
+/* #define REAL_ARITHMETIC */
+
+/* Define this if most significant byte of a word is the lowest numbered.  */
+/* That is true on the 80386.  */
+
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered.  */
+/* That is not true on the 80386.  */
+#define BYTES_BIG_ENDIAN 0
+
+/* Define this if most significant word of a multiword number is the lowest
+   numbered.  */
+/* Not true for 80386 */
+#define WORDS_BIG_ENDIAN 0
+
+/* number of bits in an addressable storage unit */
+#define BITS_PER_UNIT 8
+
+/* Width in bits of a "word", which is the contents of a machine register.
+   Note that this is not necessarily the width of data type `int';
+   if using 16-bit ints on a 80386, this would still be 32.
+   But on a machine with 16-bit registers, this would be 16.  */
+#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
+
+/* Width of a word, in units (bytes).  */
+#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
+#define MIN_UNITS_PER_WORD 4
+
+/* Width in bits of a pointer.
+   See also the macro `Pmode' defined below.  */
+#define POINTER_SIZE BITS_PER_WORD
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list.  */
+#define PARM_BOUNDARY BITS_PER_WORD
+
+/* Boundary (in *bits*) on which stack pointer should be aligned.  */
+#define STACK_BOUNDARY BITS_PER_WORD
+
+/* Boundary (in *bits*) on which the stack pointer preferrs to be
+   aligned; the compiler cannot rely on having this alignment.  */
+#define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary
+
+/* As of July 2001, many runtimes to not align the stack properly when
+   entering main.  This causes expand_main_function to forcably align
+   the stack, which results in aligned frames for functions called from
+   main, though it does nothing for the alignment of main itself.  */
+#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \
+  (ix86_preferred_stack_boundary > STACK_BOUNDARY && !TARGET_64BIT)
+
+/* Allocation boundary for the code of a function.  */
+#define FUNCTION_BOUNDARY 16
+
+/* Alignment of field after `int : 0' in a structure.  */
+
+#define EMPTY_FIELD_BOUNDARY BITS_PER_WORD
+
+/* Minimum size in bits of the largest boundary to which any
+   and all fundamental data types supported by the hardware
+   might need to be aligned. No data type wants to be aligned
+   rounder than this.
+   
+   Pentium+ preferrs DFmode values to be aligned to 64 bit boundary
+   and Pentium Pro XFmode values at 128 bit boundaries.  */
+
+#define BIGGEST_ALIGNMENT 128
+
+/* Decide whether a variable of mode MODE must be 128 bit aligned.  */
+#define ALIGN_MODE_128(MODE) \
+ ((MODE) == XFmode || (MODE) == TFmode || ((MODE) == TImode) \
+  || (MODE) == V4SFmode        || (MODE) == V4SImode)
+
+/* The published ABIs say that doubles should be aligned on word
+   boundaries, so lower the aligment for structure fields unless
+   -malign-double is set.  */
+/* BIGGEST_FIELD_ALIGNMENT is also used in libobjc, where it must be
+   constant.  Use the smaller value in that context.  */
+#ifndef IN_TARGET_LIBS
+#define BIGGEST_FIELD_ALIGNMENT (TARGET_64BIT ? 128 : (TARGET_ALIGN_DOUBLE ? 64 : 32))
+#else
+#define BIGGEST_FIELD_ALIGNMENT 32
+#endif
+
+/* If defined, a C expression to compute the alignment given to a
+   constant that is being placed in memory.  EXP is the constant
+   and ALIGN is the alignment that the object would ordinarily have.
+   The value of this macro is used instead of that alignment to align
+   the object.
+
+   If this macro is not defined, then ALIGN is used.
+
+   The typical use of this macro is to increase alignment for string
+   constants to be word aligned so that `strcpy' calls that copy
+   constants can be done inline.  */
+
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) ix86_constant_alignment ((EXP), (ALIGN))
+
+/* If defined, a C expression to compute the alignment for a static
+   variable.  TYPE is the data type, and ALIGN is the alignment that
+   the object would ordinarily have.  The value of this macro is used
+   instead of that alignment to align the object.
+
+   If this macro is not defined, then ALIGN is used.
+
+   One use of this macro is to increase alignment of medium-size
+   data to make it all fit in fewer cache lines.  Another is to
+   cause character arrays to be word-aligned so that `strcpy' calls
+   that copy constants to character arrays can be done inline.  */
+
+#define DATA_ALIGNMENT(TYPE, ALIGN) ix86_data_alignment ((TYPE), (ALIGN))
+
+/* If defined, a C expression to compute the alignment for a local
+   variable.  TYPE is the data type, and ALIGN is the alignment that
+   the object would ordinarily have.  The value of this macro is used
+   instead of that alignment to align the object.
+
+   If this macro is not defined, then ALIGN is used.
+
+   One use of this macro is to increase alignment of medium-size
+   data to make it all fit in fewer cache lines.  */
+
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) ix86_local_alignment ((TYPE), (ALIGN))
+
+/* If defined, a C expression that gives the alignment boundary, in
+   bits, of an argument with the specified mode and type.  If it is
+   not defined, `PARM_BOUNDARY' is used for all arguments.  */
+
+#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+  ix86_function_arg_boundary ((MODE), (TYPE))
+
+/* Set this non-zero if move instructions will actually fail to work
+   when given unaligned data.  */
+#define STRICT_ALIGNMENT 0
+
+/* If bit field type is int, don't let it cross an int,
+   and give entire struct the alignment of an int.  */
+/* Required on the 386 since it doesn't have bitfield insns.  */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+\f
+/* Standard register usage.  */
+
+/* This processor has special stack-like registers.  See reg-stack.c
+   for details.  */
+
+#define STACK_REGS
+#define IS_STACK_MODE(MODE)                                    \
+  ((MODE) == DFmode || (MODE) == SFmode || (MODE) == XFmode    \
+   || (MODE) == TFmode)
+
+/* Number of actual hardware registers.
+   The hardware registers are assigned numbers for the compiler
+   from 0 to just below FIRST_PSEUDO_REGISTER.
+   All registers that the compiler knows about must be given numbers,
+   even those that are not normally considered general registers.
+
+   In the 80386 we give the 8 general purpose registers the numbers 0-7.
+   We number the floating point registers 8-15.
+   Note that registers 0-7 can be accessed as a  short or int,
+   while only 0-3 may be used with byte `mov' instructions.
+
+   Reg 16 does not correspond to any hardware register, but instead
+   appears in the RTL as an argument pointer prior to reload, and is
+   eliminated during reloading in favor of either the stack or frame
+   pointer.  */
+
+#define FIRST_PSEUDO_REGISTER 53
+
+/* Number of hardware registers that go into the DWARF-2 unwind info.
+   If not defined, equals FIRST_PSEUDO_REGISTER.  */
+
+#define DWARF_FRAME_REGISTERS 17
+
+/* 1 for registers that have pervasive standard uses
+   and are not available for the register allocator.
+   On the 80386, the stack pointer is such, as is the arg pointer.
+   The value is an mask - bit 1 is set for fixed registers
+   for 32bit target, while 2 is set for fixed registers for 64bit.
+   Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
+ */
+#define FIXED_REGISTERS                                                \
+/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/     \
+{  0, 0, 0, 0, 0, 0, 0, 3, 0,  0,  0,  0,  0,  0,  0,  0,      \
+/*arg,flags,fpsr,dir,frame*/                                   \
+    3,    3,   3,  3,    3,                                    \
+/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/                    \
+     0,   0,   0,   0,   0,   0,   0,   0,                     \
+/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/                    \
+     0,   0,   0,   0,   0,   0,   0,   0,                     \
+/*  r8,  r9, r10, r11, r12, r13, r14, r15*/                    \
+     1,   1,   1,   1,   1,   1,   1,   1,                     \
+/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/              \
+     1,   1,    1,    1,    1,    1,    1,    1}
+
+/* 1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like. 
+   The value is an mask - bit 1 is set for call used
+   for 32bit target, while 2 is set for call used for 64bit.
+   Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
+*/
+#define CALL_USED_REGISTERS                                    \
+/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/     \
+{  3, 3, 3, 0, 2, 2, 0, 3, 3,  3,  3,  3,  3,  3,  3,  3,      \
+/*arg,flags,fpsr,dir,frame*/                                   \
+     3,   3,   3,  3,    3,                                    \
+/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/                    \
+     3,   3,   3,   3,   3,  3,    3,   3,                     \
+/*mmx0,mmx1,mmx2,mmx3,mmx4,mmx5,mmx6,mmx7*/                    \
+     3,   3,   3,   3,   3,   3,   3,   3,                     \
+/*  r8,  r9, r10, r11, r12, r13, r14, r15*/                    \
+     3,   3,   3,   3,   1,   1,   1,   1,                     \
+/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/              \
+     3,   3,    3,    3,    3,    3,    3,    3}               \
+
+/* Order in which to allocate registers.  Each register must be
+   listed once, even those in FIXED_REGISTERS.  List frame pointer
+   late and fixed registers last.  Note that, in general, we prefer
+   registers listed in CALL_USED_REGISTERS, keeping the others
+   available for storage of persistent values.
+
+   The ORDER_REGS_FOR_LOCAL_ALLOC actually overwrite the order,
+   so this is just empty initializer for array.  */
+
+#define REG_ALLOC_ORDER                                        \
+{  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\
+   18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \
+   33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,  \
+   48, 49, 50, 51, 52 }
+
+/* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
+   to be rearranged based on a particular function.  When using sse math,
+   we want to allocase SSE before x87 registers and vice vera.  */
+
+#define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
+
+
+/* Macro to conditionally modify fixed_regs/call_used_regs.  */
+#define CONDITIONAL_REGISTER_USAGE                                     \
+do {                                                                   \
+    int i;                                                             \
+    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                                \
+      {                                                                        \
+        fixed_regs[i] = (fixed_regs[i] & (TARGET_64BIT ? 2 : 1)) != 0; \
+        call_used_regs[i] = (call_used_regs[i]                         \
+                            & (TARGET_64BIT ? 2 : 1)) != 0;            \
+      }                                                                        \
+    if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)                     \
+      {                                                                        \
+       fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                        \
+       call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;                    \
+      }                                                                        \
+    if (! TARGET_MMX)                                                  \
+      {                                                                        \
+       int i;                                                          \
+        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                    \
+          if (TEST_HARD_REG_BIT (reg_class_contents[(int)MMX_REGS], i))        \
+           fixed_regs[i] = call_used_regs[i] = 1;                      \
+      }                                                                        \
+    if (! TARGET_SSE)                                                  \
+      {                                                                        \
+       int i;                                                          \
+        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                    \
+          if (TEST_HARD_REG_BIT (reg_class_contents[(int)SSE_REGS], i))        \
+           fixed_regs[i] = call_used_regs[i] = 1;                      \
+      }                                                                        \
+    if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387)             \
+      {                                                                        \
+       int i;                                                          \
+       HARD_REG_SET x;                                                 \
+        COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]);    \
+        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)                    \
+          if (TEST_HARD_REG_BIT (x, i))                                \
+           fixed_regs[i] = call_used_regs[i] = 1;                      \
+      }                                                                        \
+  } while (0)
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+   to hold something of mode MODE.
+   This is ordinarily the length in words of a value of mode MODE
+   but can be less for certain modes in special long registers.
+
+   Actually there are no two word move instructions for consecutive 
+   registers.  And only registers 0-3 may have mov byte instructions
+   applied to them.
+   */
+
+#define HARD_REGNO_NREGS(REGNO, MODE)   \
+  (FP_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO)    \
+   ? (COMPLEX_MODE_P (MODE) ? 2 : 1)                                   \
+   : ((MODE) == TFmode                                                 \
+      ? (TARGET_64BIT ? 2 : 3)                                         \
+      : (MODE) == TCmode                                               \
+      ? (TARGET_64BIT ? 4 : 6)                                         \
+      : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
+
+#define VALID_SSE_REG_MODE(MODE)                                       \
+    ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode      \
+     || (MODE) == SFmode                                               \
+     || (TARGET_SSE2 && ((MODE) == DFmode || VALID_MMX_REG_MODE (MODE))))
+
+#define VALID_MMX_REG_MODE_3DNOW(MODE) \
+    ((MODE) == V2SFmode || (MODE) == SFmode)
+
+#define VALID_MMX_REG_MODE(MODE)                                       \
+    ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode      \
+     || (MODE) == V2SImode || (MODE) == SImode)
+
+#define VECTOR_MODE_SUPPORTED_P(MODE)                                  \
+    (VALID_SSE_REG_MODE (MODE) && TARGET_SSE ? 1                       \
+     : VALID_MMX_REG_MODE (MODE) && TARGET_MMX ? 1                     \
+     : VALID_MMX_REG_MODE_3DNOW (MODE) && TARGET_3DNOW ? 1 : 0)
+
+#define VALID_FP_MODE_P(MODE)                                          \
+    ((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode          \
+     || (!TARGET_64BIT && (MODE) == XFmode)                            \
+     || (MODE) == SCmode || (MODE) == DCmode || (MODE) == TCmode       \
+     || (!TARGET_64BIT && (MODE) == XCmode))
+
+#define VALID_INT_MODE_P(MODE)                                         \
+    ((MODE) == QImode || (MODE) == HImode || (MODE) == SImode          \
+     || (MODE) == DImode                                               \
+     || (MODE) == CQImode || (MODE) == CHImode || (MODE) == CSImode    \
+     || (MODE) == CDImode                                              \
+     || (TARGET_64BIT && ((MODE) == TImode || (MODE) == CTImode)))
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE)        \
+   ix86_hard_regno_mode_ok ((REGNO), (MODE))
+
+/* Value is 1 if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be 0 for correct output.  */
+
+#define MODES_TIEABLE_P(MODE1, MODE2)                          \
+  ((MODE1) == (MODE2)                                          \
+   || (((MODE1) == HImode || (MODE1) == SImode                 \
+       || ((MODE1) == QImode                                   \
+           && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL))     \
+        || ((MODE1) == DImode && TARGET_64BIT))                        \
+       && ((MODE2) == HImode || (MODE2) == SImode              \
+          || ((MODE1) == QImode                                \
+              && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL))  \
+          || ((MODE2) == DImode && TARGET_64BIT))))
+
+
+/* Specify the modes required to caller save a given hard regno.
+   We do this on i386 to prevent flags from being saved at all.
+
+   Kill any attempts to combine saving of modes.  */
+
+#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE)                        \
+  (CC_REGNO_P (REGNO) ? VOIDmode                                       \
+   : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode                     \
+   : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS))      \
+   : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode            \
+   : (MODE) == QImode && (REGNO) >= 4 && !TARGET_64BIT ? SImode        \
+   : (MODE))
+/* Specify the registers used for certain standard purposes.
+   The values of these macros are register numbers.  */
+
+/* on the 386 the pc register is %eip, and is not usable as a general
+   register.  The ordinary mov instructions won't work */
+/* #define PC_REGNUM  */
+
+/* Register to use for pushing function arguments.  */
+#define STACK_POINTER_REGNUM 7
+
+/* Base register for access to local variables of the function.  */
+#define HARD_FRAME_POINTER_REGNUM 6
+
+/* Base register for access to local variables of the function.  */
+#define FRAME_POINTER_REGNUM 20
+
+/* First floating point reg */
+#define FIRST_FLOAT_REG 8
+
+/* First & last stack-like regs */
+#define FIRST_STACK_REG FIRST_FLOAT_REG
+#define LAST_STACK_REG (FIRST_FLOAT_REG + 7)
+
+#define FLAGS_REG 17
+#define FPSR_REG 18
+#define DIRFLAG_REG 19
+
+#define FIRST_SSE_REG (FRAME_POINTER_REGNUM + 1)
+#define LAST_SSE_REG  (FIRST_SSE_REG + 7)
+#define FIRST_MMX_REG  (LAST_SSE_REG + 1)
+#define LAST_MMX_REG   (FIRST_MMX_REG + 7)
+
+#define FIRST_REX_INT_REG  (LAST_MMX_REG + 1)
+#define LAST_REX_INT_REG   (FIRST_REX_INT_REG + 7)
+
+#define FIRST_REX_SSE_REG  (LAST_REX_INT_REG + 1)
+#define LAST_REX_SSE_REG   (FIRST_REX_SSE_REG + 7)
+
+/* Value should be nonzero if functions must have frame pointers.
+   Zero means the frame pointer need not be set up (and parms
+   may be accessed via the stack pointer) in functions that seem suitable.
+   This is computed in `reload', in reload1.c.  */
+#define FRAME_POINTER_REQUIRED  ix86_frame_pointer_required ()
+
+/* Override this in other tm.h files to cope with various OS losage
+   requiring a frame pointer.  */
+#ifndef SUBTARGET_FRAME_POINTER_REQUIRED
+#define SUBTARGET_FRAME_POINTER_REQUIRED 0
+#endif
+
+/* Make sure we can access arbitrary call frames.  */
+#define SETUP_FRAME_ADDRESSES()  ix86_setup_frame_addresses ()
+
+/* Base register for access to arguments of the function.  */
+#define ARG_POINTER_REGNUM 16
+
+/* Register in which static-chain is passed to a function.
+   We do use ECX as static chain register for 32 bit ABI.  On the
+   64bit ABI, ECX is an argument register, so we use R10 instead.  */
+#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? FIRST_REX_INT_REG + 10 - 8 : 2)
+
+/* Register to hold the addressing base for position independent
+   code access to data items.  We don't use PIC pointer for 64bit
+   mode.  Define the regnum to dummy value to prevent gcc from
+   pessimizing code dealing with EBX.  */
+#define PIC_OFFSET_TABLE_REGNUM \
+  (TARGET_64BIT || !flag_pic ? INVALID_REGNUM : 3)
+
+/* Register in which address to store a structure value
+   arrives in the function.  On the 386, the prologue
+   copies this from the stack to register %eax.  */
+#define STRUCT_VALUE_INCOMING 0
+
+/* Place in which caller passes the structure value address.
+   0 means push the value on the stack like an argument.  */
+#define STRUCT_VALUE 0
+
+/* A C expression which can inhibit the returning of certain function
+   values in registers, based on the type of value.  A nonzero value
+   says to return the function value in memory, just as large
+   structures are always returned.  Here TYPE will be a C expression
+   of type `tree', representing the data type of the value.
+
+   Note that values of mode `BLKmode' must be explicitly handled by
+   this macro.  Also, the option `-fpcc-struct-return' takes effect
+   regardless of this macro.  On most systems, it is possible to
+   leave the macro undefined; this causes a default definition to be
+   used, whose value is the constant 1 for `BLKmode' values, and 0
+   otherwise.
+
+   Do not use this macro to indicate that structures and unions
+   should always be returned in memory.  You should instead use
+   `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
+
+#define RETURN_IN_MEMORY(TYPE) \
+  ix86_return_in_memory (TYPE)
+
+\f
+/* Define the classes of registers for register constraints in the
+   machine description.  Also define ranges of constants.
+
+   One of the classes must always be named ALL_REGS and include all hard regs.
+   If there is more than one class, another class must be named NO_REGS
+   and contain no registers.
+
+   The name GENERAL_REGS must be the name of a class (or an alias for
+   another name such as ALL_REGS).  This is the class of registers
+   that is allowed by "g" or "r" in a register constraint.
+   Also, registers outside this class are allocated only when
+   instructions express preferences for them.
+
+   The classes must be numbered in nondecreasing order; that is,
+   a larger-numbered class must never be contained completely
+   in a smaller-numbered class.
+
+   For any two classes, it is very desirable that there be another
+   class that represents their union.
+
+   It might seem that class BREG is unnecessary, since no useful 386
+   opcode needs reg %ebx.  But some systems pass args to the OS in ebx,
+   and the "b" register constraint is useful in asms for syscalls.
+
+   The flags and fpsr registers are in no class.  */
+
+enum reg_class
+{
+  NO_REGS,
+  AREG, DREG, CREG, BREG, SIREG, DIREG,
+  AD_REGS,                     /* %eax/%edx for DImode */
+  Q_REGS,                      /* %eax %ebx %ecx %edx */
+  NON_Q_REGS,                  /* %esi %edi %ebp %esp */
+  INDEX_REGS,                  /* %eax %ebx %ecx %edx %esi %edi %ebp */
+  LEGACY_REGS,                 /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
+  GENERAL_REGS,                        /* %eax %ebx %ecx %edx %esi %edi %ebp %esp %r8 - %r15*/
+  FP_TOP_REG, FP_SECOND_REG,   /* %st(0) %st(1) */
+  FLOAT_REGS,
+  SSE_REGS,
+  MMX_REGS,
+  FP_TOP_SSE_REGS,
+  FP_SECOND_SSE_REGS,
+  FLOAT_SSE_REGS,
+  FLOAT_INT_REGS,
+  INT_SSE_REGS,
+  FLOAT_INT_SSE_REGS,
+  ALL_REGS, LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES ((int) LIM_REG_CLASSES)
+
+#define INTEGER_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), GENERAL_REGS)
+#define FLOAT_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), FLOAT_REGS)
+#define SSE_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), SSE_REGS)
+#define MMX_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), MMX_REGS)
+#define MAYBE_INTEGER_CLASS_P(CLASS) \
+  reg_classes_intersect_p ((CLASS), GENERAL_REGS)
+#define MAYBE_FLOAT_CLASS_P(CLASS) \
+  reg_classes_intersect_p ((CLASS), FLOAT_REGS)
+#define MAYBE_SSE_CLASS_P(CLASS) \
+  reg_classes_intersect_p (SSE_REGS, (CLASS))
+#define MAYBE_MMX_CLASS_P(CLASS) \
+  reg_classes_intersect_p (MMX_REGS, (CLASS))
+
+#define Q_CLASS_P(CLASS) \
+  reg_class_subset_p ((CLASS), Q_REGS)
+
+/* Give names of register classes as strings for dump file.   */
+
+#define REG_CLASS_NAMES \
+{  "NO_REGS",                          \
+   "AREG", "DREG", "CREG", "BREG",     \
+   "SIREG", "DIREG",                   \
+   "AD_REGS",                          \
+   "Q_REGS", "NON_Q_REGS",             \
+   "INDEX_REGS",                       \
+   "LEGACY_REGS",                      \
+   "GENERAL_REGS",                     \
+   "FP_TOP_REG", "FP_SECOND_REG",      \
+   "FLOAT_REGS",                       \
+   "SSE_REGS",                         \
+   "MMX_REGS",                         \
+   "FP_TOP_SSE_REGS",                  \
+   "FP_SECOND_SSE_REGS",               \
+   "FLOAT_SSE_REGS",                   \
+   "FLOAT_INT_REGS",                   \
+   "INT_SSE_REGS",                     \
+   "FLOAT_INT_SSE_REGS",               \
+   "ALL_REGS" }
+
+/* Define which registers fit in which classes.
+   This is an initializer for a vector of HARD_REG_SET
+   of length N_REG_CLASSES.  */
+
+#define REG_CLASS_CONTENTS                                             \
+{     { 0x00,     0x0 },                                               \
+      { 0x01,     0x0 }, { 0x02, 0x0 },        /* AREG, DREG */                \
+      { 0x04,     0x0 }, { 0x08, 0x0 },        /* CREG, BREG */                \
+      { 0x10,     0x0 }, { 0x20, 0x0 },        /* SIREG, DIREG */              \
+      { 0x03,     0x0 },               /* AD_REGS */                   \
+      { 0x0f,     0x0 },               /* Q_REGS */                    \
+  { 0x1100f0,  0x1fe0 },               /* NON_Q_REGS */                \
+      { 0x7f,  0x1fe0 },               /* INDEX_REGS */                \
+  { 0x1100ff,  0x0 },                  /* LEGACY_REGS */               \
+  { 0x1100ff,  0x1fe0 },               /* GENERAL_REGS */              \
+     { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
+    { 0xff00,     0x0 },               /* FLOAT_REGS */                \
+{ 0x1fe00000,0x1fe000 },               /* SSE_REGS */                  \
+{ 0xe0000000,    0x1f },               /* MMX_REGS */                  \
+{ 0x1fe00100,0x1fe000 },               /* FP_TOP_SSE_REG */            \
+{ 0x1fe00200,0x1fe000 },               /* FP_SECOND_SSE_REG */         \
+{ 0x1fe0ff00,0x1fe000 },               /* FLOAT_SSE_REGS */            \
+   { 0x1ffff,  0x1fe0 },               /* FLOAT_INT_REGS */            \
+{ 0x1fe100ff,0x1fffe0 },               /* INT_SSE_REGS */              \
+{ 0x1fe1ffff,0x1fffe0 },               /* FLOAT_INT_SSE_REGS */        \
+{ 0xffffffff,0x1fffff }                                                        \
+}
+
+/* The same information, inverted:
+   Return the class number of the smallest class containing
+   reg number REGNO.  This could be a conditional expression
+   or could index an array.  */
+
+#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
+
+/* When defined, the compiler allows registers explicitly used in the
+   rtl to be used as spill registers but prevents the compiler from
+   extending the lifetime of these registers.  */
+
+#define SMALL_REGISTER_CLASSES 1
+
+#define QI_REG_P(X) \
+  (REG_P (X) && REGNO (X) < 4)
+
+#define GENERAL_REGNO_P(N) \
+  ((N) < 8 || REX_INT_REGNO_P (N))
+
+#define GENERAL_REG_P(X) \
+  (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
+
+#define ANY_QI_REG_P(X) (TARGET_64BIT ? GENERAL_REG_P(X) : QI_REG_P (X))
+
+#define NON_QI_REG_P(X) \
+  (REG_P (X) && REGNO (X) >= 4 && REGNO (X) < FIRST_PSEUDO_REGISTER)
+
+#define REX_INT_REGNO_P(N) ((N) >= FIRST_REX_INT_REG && (N) <= LAST_REX_INT_REG)
+#define REX_INT_REG_P(X) (REG_P (X) && REX_INT_REGNO_P (REGNO (X)))
+
+#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
+#define FP_REGNO_P(N) ((N) >= FIRST_STACK_REG && (N) <= LAST_STACK_REG)
+#define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
+#define ANY_FP_REGNO_P(N) (FP_REGNO_P (N) || SSE_REGNO_P (N))
+
+#define SSE_REGNO_P(N) \
+  (((N) >= FIRST_SSE_REG && (N) <= LAST_SSE_REG) \
+   || ((N) >= FIRST_REX_SSE_REG && (N) <= LAST_REX_SSE_REG))
+
+#define SSE_REGNO(N) \
+  ((N) < 8 ? FIRST_SSE_REG + (N) : FIRST_REX_SSE_REG + (N) - 8)
+#define SSE_REG_P(N) (REG_P (N) && SSE_REGNO_P (REGNO (N)))
+
+#define SSE_FLOAT_MODE_P(MODE) \
+  ((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode))
+
+#define MMX_REGNO_P(N) ((N) >= FIRST_MMX_REG && (N) <= LAST_MMX_REG)
+#define MMX_REG_P(XOP) (REG_P (XOP) && MMX_REGNO_P (REGNO (XOP)))
+  
+#define STACK_REG_P(XOP)               \
+  (REG_P (XOP) &&                      \
+   REGNO (XOP) >= FIRST_STACK_REG &&   \
+   REGNO (XOP) <= LAST_STACK_REG)
+
+#define NON_STACK_REG_P(XOP) (REG_P (XOP) && ! STACK_REG_P (XOP))
+
+#define STACK_TOP_P(XOP) (REG_P (XOP) && REGNO (XOP) == FIRST_STACK_REG)
+
+#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
+#define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG)
+
+/* Indicate whether hard register numbered REG_NO should be converted
+   to SSA form.  */
+#define CONVERT_HARD_REGISTER_TO_SSA_P(REG_NO) \
+  ((REG_NO) == FLAGS_REG || (REG_NO) == ARG_POINTER_REGNUM)
+
+/* The class value for index registers, and the one for base regs.  */
+
+#define INDEX_REG_CLASS INDEX_REGS
+#define BASE_REG_CLASS GENERAL_REGS
+
+/* Get reg_class from a letter such as appears in the machine description.  */
+
+#define REG_CLASS_FROM_LETTER(C)       \
+  ((C) == 'r' ? GENERAL_REGS :                                 \
+   (C) == 'R' ? LEGACY_REGS :                                  \
+   (C) == 'q' ? TARGET_64BIT ? GENERAL_REGS : Q_REGS :         \
+   (C) == 'Q' ? Q_REGS :                                       \
+   (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
+                ? FLOAT_REGS                                   \
+                : NO_REGS) :                                   \
+   (C) == 't' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
+                ? FP_TOP_REG                                   \
+                : NO_REGS) :                                   \
+   (C) == 'u' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \
+                ? FP_SECOND_REG                                \
+                : NO_REGS) :                                   \
+   (C) == 'a' ? AREG :                                         \
+   (C) == 'b' ? BREG :                                         \
+   (C) == 'c' ? CREG :                                         \
+   (C) == 'd' ? DREG :                                         \
+   (C) == 'x' ? TARGET_SSE ? SSE_REGS : NO_REGS :              \
+   (C) == 'Y' ? TARGET_SSE2? SSE_REGS : NO_REGS :              \
+   (C) == 'y' ? TARGET_MMX ? MMX_REGS : NO_REGS :              \
+   (C) == 'A' ? AD_REGS :                                      \
+   (C) == 'D' ? DIREG :                                                \
+   (C) == 'S' ? SIREG : NO_REGS)
+
+/* The letters I, J, K, L and M in a register constraint string
+   can be used to stand for particular ranges of immediate operands.
+   This macro defines what the ranges are.
+   C is the letter, and VALUE is a constant value.
+   Return 1 if VALUE is in the range specified by C.
+
+   I is for non-DImode shifts.
+   J is for DImode shifts.
+   K is for signed imm8 operands.
+   L is for andsi as zero-extending move.
+   M is for shifts that can be executed by the "lea" opcode.
+   N is for immedaite operands for out/in instructions (0-255)
+   */
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C)                                \
+  ((C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 31                  \
+   : (C) == 'J' ? (VALUE) >= 0 && (VALUE) <= 63                        \
+   : (C) == 'K' ? (VALUE) >= -128 && (VALUE) <= 127            \
+   : (C) == 'L' ? (VALUE) == 0xff || (VALUE) == 0xffff         \
+   : (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3                 \
+   : (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255               \
+   : 0)
+
+/* Similar, but for floating constants, and defining letters G and H.
+   Here VALUE is the CONST_DOUBLE rtx itself.  We allow constants even if
+   TARGET_387 isn't set, because the stack register converter may need to
+   load 0.0 into the function value register.  */
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)  \
+  ((C) == 'G' ? standard_80387_constant_p (VALUE) \
+   : ((C) == 'H' ? standard_sse_constant_p (VALUE) : 0))
+
+/* A C expression that defines the optional machine-dependent
+   constraint letters that can be used to segregate specific types of
+   operands, usually memory references, for the target machine.  Any
+   letter that is not elsewhere defined and not matched by
+   `REG_CLASS_FROM_LETTER' may be used.  Normally this macro will not
+   be defined.
+
+   If it is required for a particular target machine, it should
+   return 1 if VALUE corresponds to the operand type represented by
+   the constraint letter C.  If C is not defined as an extra
+   constraint, the value returned should be 0 regardless of VALUE.  */
+
+#define EXTRA_CONSTRAINT(VALUE, C)                             \
+  ((C) == 'e' ? x86_64_sign_extended_value (VALUE)             \
+   : (C) == 'Z' ? x86_64_zero_extended_value (VALUE)           \
+   : 0)
+
+/* Place additional restrictions on the register class to use when it
+   is necessary to be able to hold a value of mode MODE in a reload
+   register for which class CLASS would ordinarily be used.  */
+
+#define LIMIT_RELOAD_CLASS(MODE, CLASS)                        \
+  ((MODE) == QImode && !TARGET_64BIT                           \
+   && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS          \
+       || (CLASS) == LEGACY_REGS || (CLASS) == INDEX_REGS)     \
+   ? Q_REGS : (CLASS))
+
+/* Given an rtx X being reloaded into a reg required to be
+   in class CLASS, return the class of reg to actually use.
+   In general this is just CLASS; but on some machines
+   in some cases it is preferable to use a more restrictive class.
+   On the 80386 series, we prevent floating constants from being
+   reloaded into floating registers (since no move-insn can do that)
+   and we ensure that QImodes aren't reloaded into the esi or edi reg.  */
+
+/* Put float CONST_DOUBLE in the constant pool instead of fp regs.
+   QImode must go into class Q_REGS.
+   Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
+   movdf to do mem-to-mem moves through integer regs.  */
+
+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
+   ix86_preferred_reload_class ((X), (CLASS))
+
+/* If we are copying between general and FP registers, we need a memory
+   location. The same is true for SSE and MMX registers.  */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+  ix86_secondary_memory_needed ((CLASS1), (CLASS2), (MODE), 1)
+
+/* QImode spills from non-QI registers need a scratch.  This does not
+   happen often -- the only example so far requires an uninitialized 
+   pseudo.  */
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT)                        \
+  (((CLASS) == GENERAL_REGS || (CLASS) == LEGACY_REGS                  \
+    || (CLASS) == INDEX_REGS) && !TARGET_64BIT && (MODE) == QImode     \
+   ? Q_REGS : NO_REGS)
+
+/* Return the maximum number of consecutive registers
+   needed to represent mode MODE in a register of class CLASS.  */
+/* On the 80386, this is the size of MODE in words,
+   except in the FP regs, where a single reg is always enough.
+   The TFmodes are really just 80bit values, so we use only 3 registers
+   to hold them, instead of 4, as the size would suggest.
+ */
+#define CLASS_MAX_NREGS(CLASS, MODE)                                   \
+ (!MAYBE_INTEGER_CLASS_P (CLASS)                                       \
+  ? (COMPLEX_MODE_P (MODE) ? 2 : 1)                                    \
+  : ((GET_MODE_SIZE ((MODE) == TFmode ? XFmode : (MODE))               \
+     + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+
+/* A C expression whose value is nonzero if pseudos that have been
+   assigned to registers of class CLASS would likely be spilled
+   because registers of CLASS are needed for spill registers.
+
+   The default value of this macro returns 1 if CLASS has exactly one
+   register and zero otherwise.  On most machines, this default
+   should be used.  Only define this macro to some other expression
+   if pseudo allocated by `local-alloc.c' end up in memory because
+   their hard registers were needed for spill registers.  If this
+   macro returns nonzero for those classes, those pseudos will only
+   be allocated by `global.c', which knows how to reallocate the
+   pseudo to another register.  If there would not be another
+   register available for reallocation, you should not change the
+   definition of this macro since the only effect of such a
+   definition would be to slow down register allocation.  */
+
+#define CLASS_LIKELY_SPILLED_P(CLASS)                                  \
+  (((CLASS) == AREG)                                                   \
+   || ((CLASS) == DREG)                                                        \
+   || ((CLASS) == CREG)                                                        \
+   || ((CLASS) == BREG)                                                        \
+   || ((CLASS) == AD_REGS)                                             \
+   || ((CLASS) == SIREG)                                               \
+   || ((CLASS) == DIREG))
+
+/* A C statement that adds to CLOBBERS any hard regs the port wishes
+   to automatically clobber for all asms. 
+
+   We do this in the new i386 backend to maintain source compatibility
+   with the old cc0-based compiler.  */
+
+#define MD_ASM_CLOBBERS(CLOBBERS)                                      \
+  do {                                                                 \
+    (CLOBBERS) = tree_cons (NULL_TREE, build_string (5, "flags"),      \
+                           (CLOBBERS));                                \
+    (CLOBBERS) = tree_cons (NULL_TREE, build_string (4, "fpsr"),       \
+                           (CLOBBERS));                                \
+    (CLOBBERS) = tree_cons (NULL_TREE, build_string (7, "dirflag"),    \
+                           (CLOBBERS));                                \
+  } while (0)
+\f
+/* Stack layout; function entry, exit and calling.  */
+
+/* Define this if pushing a word on the stack
+   makes the stack pointer a smaller address.  */
+#define STACK_GROWS_DOWNWARD
+
+/* Define this if the nominal address of the stack frame
+   is at the high-address end of the local variables;
+   that is, each additional local variable allocated
+   goes at a more negative offset in the frame.  */
+#define FRAME_GROWS_DOWNWARD
+
+/* Offset within stack frame to start allocating local variables at.
+   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
+   first local allocated.  Otherwise, it is the offset to the BEGINNING
+   of the first local allocated.  */
+#define STARTING_FRAME_OFFSET 0
+
+/* If we generate an insn to push BYTES bytes,
+   this says how many the stack pointer really advances by.
+   On 386 pushw decrements by exactly 2 no matter what the position was.
+   On the 386 there is no pushb; we use pushw instead, and this
+   has the effect of rounding up to 2.
+   For 64bit ABI we round up to 8 bytes.
+ */
+
+#define PUSH_ROUNDING(BYTES) \
+  (TARGET_64BIT                     \
+   ? (((BYTES) + 7) & (-8))  \
+   : (((BYTES) + 1) & (-2)))
+
+/* If defined, the maximum amount of space required for outgoing arguments will
+   be computed and placed into the variable
+   `current_function_outgoing_args_size'.  No space will be pushed onto the
+   stack for each call; instead, the function prologue should increase the stack
+   frame size by this amount.  */
+
+#define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
+
+/* If defined, a C expression whose value is nonzero when we want to use PUSH
+   instructions to pass outgoing arguments.  */
+
+#define PUSH_ARGS (TARGET_PUSH_ARGS && !ACCUMULATE_OUTGOING_ARGS)
+
+/* Offset of first parameter from the argument pointer register value.  */
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* Define this macro if functions should assume that stack space has been
+   allocated for arguments even when their values are passed in registers.
+
+   The value of this macro is the size, in bytes, of the area reserved for
+   arguments passed in registers for the function represented by FNDECL.
+
+   This space can be allocated by the caller, or be a part of the
+   machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
+   which.  */
+#define REG_PARM_STACK_SPACE(FNDECL) 0
+
+/* Define as a C expression that evaluates to nonzero if we do not know how
+   to pass TYPE solely in registers.  The file expr.h defines a
+   definition that is usually appropriate, refer to expr.h for additional
+   documentation. If `REG_PARM_STACK_SPACE' is defined, the argument will be
+   computed in the stack and then loaded into a register.  */
+#define MUST_PASS_IN_STACK(MODE, TYPE)                         \
+  ((TYPE) != 0                                                 \
+   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST             \
+       || TREE_ADDRESSABLE (TYPE)                              \
+       || ((MODE) == TImode)                                   \
+       || ((MODE) == BLKmode                                   \
+          && ! ((TYPE) != 0                                    \
+                && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
+                && 0 == (int_size_in_bytes (TYPE)              \
+                         % (PARM_BOUNDARY / BITS_PER_UNIT)))   \
+          && (FUNCTION_ARG_PADDING (MODE, TYPE)                \
+              == (BYTES_BIG_ENDIAN ? upward : downward)))))
+
+/* Value is the number of bytes of arguments automatically
+   popped when returning from a subroutine call.
+   FUNDECL is the declaration node of the function (as a tree),
+   FUNTYPE is the data type of the function (as a tree),
+   or for a library call it is an identifier node for the subroutine name.
+   SIZE is the number of bytes of arguments passed on the stack.
+
+   On the 80386, the RTD insn may be used to pop them if the number
+     of args is fixed, but if the number is variable then the caller
+     must pop them all.  RTD can't be used for library calls now
+     because the library is compiled with the Unix compiler.
+   Use of RTD is a selectable option, since it is incompatible with
+   standard Unix calling sequences.  If the option is not selected,
+   the caller must always pop the args.
+
+   The attribute stdcall is equivalent to RTD on a per module basis.  */
+
+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \
+  ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE))
+
+/* Define how to find the value returned by a function.
+   VALTYPE is the data type of the value (as a tree).
+   If the precise function being called is known, FUNC is its FUNCTION_DECL;
+   otherwise, FUNC is 0.  */
+#define FUNCTION_VALUE(VALTYPE, FUNC)  \
+   ix86_function_value (VALTYPE)
+
+#define FUNCTION_VALUE_REGNO_P(N) \
+  ix86_function_value_regno_p (N)
+
+/* Define how to find the value returned by a library function
+   assuming the value has mode MODE.  */
+
+#define LIBCALL_VALUE(MODE) \
+  ix86_libcall_value (MODE)
+
+/* Define the size of the result block used for communication between
+   untyped_call and untyped_return.  The block contains a DImode value
+   followed by the block used by fnsave and frstor.  */
+
+#define APPLY_RESULT_SIZE (8+108)
+
+/* 1 if N is a possible register number for function argument passing.  */
+#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p (N)
+
+/* Define a data type for recording info about an argument list
+   during the scan of that argument list.  This data type should
+   hold all necessary information about the function itself
+   and about the args processed so far, enough to enable macros
+   such as FUNCTION_ARG to determine where the next arg should go.  */
+
+typedef struct ix86_args {
+  int words;                   /* # words passed so far */
+  int nregs;                   /* # registers available for passing */
+  int regno;                   /* next available register number */
+  int sse_words;               /* # sse words passed so far */
+  int sse_nregs;               /* # sse registers available for passing */
+  int sse_regno;               /* next available sse register number */
+  int maybe_vaarg;             /* true for calls to possibly vardic fncts.  */
+} CUMULATIVE_ARGS;
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+   for a call to a function whose data type is FNTYPE.
+   For a library call, FNTYPE is 0.  */
+
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+  init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME))
+
+/* Update the data in CUM to advance over an argument
+   of mode MODE and data type TYPE.
+   (TYPE is null for libcalls where that information may not be available.)  */
+
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+  function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
+
+/* Define where to put the arguments to a function.
+   Value is zero to push the argument on the stack,
+   or a hard register in which to store the argument.
+
+   MODE is the argument's machine mode.
+   TYPE is the data type of the argument (as a tree).
+    This is null for libcalls where that information may
+    not be available.
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+    the preceding args and about the function being called.
+   NAMED is nonzero if this argument is a named parameter
+    (otherwise it is an extra parameter matching an ellipsis).  */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+  function_arg (&(CUM), (MODE), (TYPE), (NAMED))
+
+/* For an arg passed partly in registers and partly in memory,
+   this is the number of registers used.
+   For args passed entirely in registers or entirely in memory, zero.  */
+
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
+
+/* If PIC, we cannot make sibling calls to global functions
+   because the PLT requires %ebx live.
+   If we are returning floats on the register stack, we cannot make
+   sibling calls to functions that return floats.  (The stack adjust
+   instruction will wind up after the sibcall jump, and not be executed.) */
+#define FUNCTION_OK_FOR_SIBCALL(DECL)                                  \
+  ((DECL)                                                              \
+   && (! flag_pic || ! TREE_PUBLIC (DECL))                             \
+   && (! TARGET_FLOAT_RETURNS_IN_80387                                 \
+       || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL))))    \
+       || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))))
+
+/* Perform any needed actions needed for a function that is receiving a
+   variable number of arguments.
+
+   CUM is as above.
+
+   MODE and TYPE are the mode and type of the current parameter.
+
+   PRETEND_SIZE is a variable that should be set to the amount of stack
+   that must be pushed by the prolog to pretend that our caller pushed
+   it.
+
+   Normally, this macro will push all remaining incoming registers on the
+   stack and set PRETEND_SIZE to the length of the registers pushed.  */
+
+#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL)  \
+  ix86_setup_incoming_varargs (&(CUM), (MODE), (TYPE), &(PRETEND_SIZE), \
+                              (NO_RTL))
+
+/* Define the `__builtin_va_list' type for the ABI.  */
+#define BUILD_VA_LIST_TYPE(VALIST) \
+  ((VALIST) = ix86_build_va_list ())
+
+/* Implement `va_start' for varargs and stdarg.  */
+#define EXPAND_BUILTIN_VA_START(STDARG, VALIST, NEXTARG) \
+  ix86_va_start ((STDARG), (VALIST), (NEXTARG))
+
+/* Implement `va_arg'.  */
+#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \
+  ix86_va_arg ((VALIST), (TYPE))
+
+/* This macro is invoked at the end of compilation.  It is used here to
+   output code for -fpic that will load the return address into %ebx.  */
+
+#undef ASM_FILE_END
+#define ASM_FILE_END(FILE)  ix86_asm_file_end (FILE)
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+   for profiling a function entry.  */
+
+#define FUNCTION_PROFILER(FILE, LABELNO)                               \
+do {                                                                   \
+  if (flag_pic)                                                                \
+    {                                                                  \
+      fprintf ((FILE), "\tleal\t%sP%d@GOTOFF(%%ebx),%%edx\n",          \
+              LPREFIX, (LABELNO));                                     \
+      fprintf ((FILE), "\tcall\t*_mcount@GOT(%%ebx)\n");               \
+    }                                                                  \
+  else                                                                 \
+    {                                                                  \
+      fprintf ((FILE), "\tmovl\t$%sP%d,%%edx\n", LPREFIX, (LABELNO));  \
+      fprintf ((FILE), "\tcall\t_mcount\n");                           \
+    }                                                                  \
+} while (0)
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+   the stack pointer does not matter.  The value is tested only in
+   functions that have frame pointers.
+   No definition is equivalent to always zero.  */
+/* Note on the 386 it might be more efficient not to define this since 
+   we have to restore it ourselves from the frame pointer, in order to
+   use pop */
+
+#define EXIT_IGNORE_STACK 1
+
+/* Output assembler code for a block containing the constant parts
+   of a trampoline, leaving space for the variable parts.  */
+
+/* On the 386, the trampoline contains two instructions:
+     mov #STATIC,ecx
+     jmp FUNCTION
+   The trampoline is generated entirely at runtime.  The operand of JMP
+   is the address of FUNCTION relative to the instruction following the
+   JMP (which is 5 bytes long).  */
+
+/* Length in units of the trampoline for entering a nested function.  */
+
+#define TRAMPOLINE_SIZE (TARGET_64BIT ? 23 : 10)
+
+/* Emit RTL insns to initialize the variable parts of a trampoline.
+   FNADDR is an RTX for the address of the function's pure code.
+   CXT is an RTX for the static chain value for the function.  */
+
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+  x86_initialize_trampoline ((TRAMP), (FNADDR), (CXT))
+\f
+/* Definitions for register eliminations.
+
+   This is an array of structures.  Each structure initializes one pair
+   of eliminable registers.  The "from" register number is given first,
+   followed by "to".  Eliminations of the same "from" register are listed
+   in order of preference.
+
+   There are two registers that can always be eliminated on the i386.
+   The frame pointer and the arg pointer can be replaced by either the
+   hard frame pointer or to the stack pointer, depending upon the
+   circumstances.  The hard frame pointer is not used before reload and
+   so it is not eligible for elimination.  */
+
+#define ELIMINABLE_REGS                                        \
+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},          \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},     \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}   \
+
+/* Given FROM and TO register numbers, say whether this elimination is
+   allowed.  Frame pointer elimination is automatically handled.
+
+   All other eliminations are valid.  */
+
+#define CAN_ELIMINATE(FROM, TO) \
+  ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1)
+
+/* Define the offset between two registers, one to be eliminated, and the other
+   its replacement, at the start of a routine.  */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = ix86_initial_elimination_offset ((FROM), (TO)))
+\f
+/* Addressing modes, and classification of registers for them.  */
+
+/* #define HAVE_POST_INCREMENT 0 */
+/* #define HAVE_POST_DECREMENT 0 */
+
+/* #define HAVE_PRE_DECREMENT 0 */
+/* #define HAVE_PRE_INCREMENT 0 */
+
+/* Macros to check register numbers against specific register classes.  */
+
+/* These assume that REGNO is a hard or pseudo reg number.
+   They give nonzero only if REGNO is a hard reg of the suitable class
+   or a pseudo reg currently allocated to a suitable hard reg.
+   Since they use reg_renumber, they are safe only once reg_renumber
+   has been allocated, which happens in local-alloc.c.  */
+
+#define REGNO_OK_FOR_INDEX_P(REGNO)                                    \
+  ((REGNO) < STACK_POINTER_REGNUM                                      \
+   || (REGNO >= FIRST_REX_INT_REG                                      \
+       && (REGNO) <= LAST_REX_INT_REG)                                 \
+   || ((unsigned) reg_renumber[(REGNO)] >= FIRST_REX_INT_REG           \
+       && (unsigned) reg_renumber[(REGNO)] <= LAST_REX_INT_REG)                \
+   || (unsigned) reg_renumber[(REGNO)] < STACK_POINTER_REGNUM)
+
+#define REGNO_OK_FOR_BASE_P(REGNO)                                     \
+  ((REGNO) <= STACK_POINTER_REGNUM                                     \
+   || (REGNO) == ARG_POINTER_REGNUM                                    \
+   || (REGNO) == FRAME_POINTER_REGNUM                                  \
+   || (REGNO >= FIRST_REX_INT_REG                                      \
+       && (REGNO) <= LAST_REX_INT_REG)                                 \
+   || ((unsigned) reg_renumber[(REGNO)] >= FIRST_REX_INT_REG           \
+       && (unsigned) reg_renumber[(REGNO)] <= LAST_REX_INT_REG)                \
+   || (unsigned) reg_renumber[(REGNO)] <= STACK_POINTER_REGNUM)
+
+#define REGNO_OK_FOR_SIREG_P(REGNO) \
+  ((REGNO) == 4 || reg_renumber[(REGNO)] == 4)
+#define REGNO_OK_FOR_DIREG_P(REGNO) \
+  ((REGNO) == 5 || reg_renumber[(REGNO)] == 5)
+
+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
+   and check its validity for a certain class.
+   We have two alternate definitions for each of them.
+   The usual definition accepts all pseudo regs; the other rejects
+   them unless they have been allocated suitable hard regs.
+   The symbol REG_OK_STRICT causes the latter definition to be used.
+
+   Most source files want to accept pseudo regs in the hope that
+   they will get allocated to the class that the insn wants them to be in.
+   Source files for reload pass need to be strict.
+   After reload, it makes no difference, since pseudo regs have
+   been eliminated by then.  */
+
+
+/* Non strict versions, pseudos are ok */
+#define REG_OK_FOR_INDEX_NONSTRICT_P(X)                                        \
+  (REGNO (X) < STACK_POINTER_REGNUM                                    \
+   || (REGNO (X) >= FIRST_REX_INT_REG                                  \
+       && REGNO (X) <= LAST_REX_INT_REG)                               \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+
+#define REG_OK_FOR_BASE_NONSTRICT_P(X)                                 \
+  (REGNO (X) <= STACK_POINTER_REGNUM                                   \
+   || REGNO (X) == ARG_POINTER_REGNUM                                  \
+   || REGNO (X) == FRAME_POINTER_REGNUM                                \
+   || (REGNO (X) >= FIRST_REX_INT_REG                                  \
+       && REGNO (X) <= LAST_REX_INT_REG)                               \
+   || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+
+/* Strict versions, hard registers only */
+#define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+#define REG_OK_FOR_BASE_STRICT_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
+
+#ifndef REG_OK_STRICT
+#define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P (X)
+#define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P (X)
+
+#else
+#define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P (X)
+#define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P (X)
+#endif
+
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+   that is a valid memory address for an instruction.
+   The MODE argument is the machine mode for the MEM expression
+   that wants to use this address.
+
+   The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
+   except for CONSTANT_ADDRESS_P which is usually machine-independent.
+
+   See legitimize_pic_address in i386.c for details as to what
+   constitutes a legitimate address when -fpic is used.  */
+
+#define MAX_REGS_PER_ADDRESS 2
+
+#define CONSTANT_ADDRESS_P(X)                                  \
+  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF     \
+   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST       \
+   || GET_CODE (X) == CONST_DOUBLE)
+
+/* Nonzero if the constant value X is a legitimate general operand.
+   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
+
+#define LEGITIMATE_CONSTANT_P(X) 1
+
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
+do {                                                                   \
+  if (legitimate_address_p ((MODE), (X), 1))                           \
+    goto ADDR;                                                         \
+} while (0)
+
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
+do {                                                                   \
+  if (legitimate_address_p ((MODE), (X), 0))                           \
+    goto ADDR;                                                         \
+} while (0)
+
+#endif
+
+/* If defined, a C expression to determine the base term of address X.
+   This macro is used in only one place: `find_base_term' in alias.c.
+
+   It is always safe for this macro to not be defined.  It exists so
+   that alias analysis can understand machine-dependent addresses.
+
+   The typical use of this macro is to handle addresses containing
+   a label_ref or symbol_ref within an UNSPEC.  */
+
+#define FIND_BASE_TERM(X) ix86_find_base_term (X)
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.
+   This macro is used in only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE and WIN are passed so that this macro can use
+   GO_IF_LEGITIMATE_ADDRESS.
+
+   It is always safe for this macro to do nothing.  It exists to recognize
+   opportunities to optimize the output.
+
+   For the 80386, we handle X+REG by loading X into a register R and
+   using R+REG.  R will go in a general reg and indexing will be used.
+   However, if REG is a broken-out memory address or multiplication,
+   nothing needs to be done because REG can certainly go in a general reg.
+
+   When -fpic is used, special handling is needed for symbolic references.
+   See comments by legitimize_pic_address in i386.c for details.  */
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                         \
+do {                                                                   \
+  (X) = legitimize_address ((X), (OLDX), (MODE));                      \
+  if (memory_address_p ((MODE), (X)))                                  \
+    goto WIN;                                                          \
+} while (0)
+
+#define REWRITE_ADDRESS(X) rewrite_address (X)
+
+/* Nonzero if the constant value X is a legitimate general operand
+   when generating PIC code.  It is given that flag_pic is on and 
+   that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
+
+#define LEGITIMATE_PIC_OPERAND_P(X)            \
+  (! SYMBOLIC_CONST (X)                                \
+   || legitimate_pic_address_disp_p (X))
+
+#define SYMBOLIC_CONST(X)      \
+  (GET_CODE (X) == SYMBOL_REF                                          \
+   || GET_CODE (X) == LABEL_REF                                                \
+   || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+   has an effect that depends on the machine mode it is used for.
+   On the 80386, only postdecrement and postincrement address depend thus
+   (the amount of decrement or increment being the length of the operand).  */
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)      \
+do {                                                   \
+ if (GET_CODE (ADDR) == POST_INC                       \
+     || GET_CODE (ADDR) == POST_DEC)                   \
+   goto LABEL;                                         \
+} while (0)
+\f
+/* Codes for all the SSE/MMX builtins.  */
+enum ix86_builtins
+{
+  IX86_BUILTIN_ADDPS,
+  IX86_BUILTIN_ADDSS,
+  IX86_BUILTIN_DIVPS,
+  IX86_BUILTIN_DIVSS,
+  IX86_BUILTIN_MULPS,
+  IX86_BUILTIN_MULSS,
+  IX86_BUILTIN_SUBPS,
+  IX86_BUILTIN_SUBSS,
+
+  IX86_BUILTIN_CMPEQPS,
+  IX86_BUILTIN_CMPLTPS,
+  IX86_BUILTIN_CMPLEPS,
+  IX86_BUILTIN_CMPGTPS,
+  IX86_BUILTIN_CMPGEPS,
+  IX86_BUILTIN_CMPNEQPS,
+  IX86_BUILTIN_CMPNLTPS,
+  IX86_BUILTIN_CMPNLEPS,
+  IX86_BUILTIN_CMPNGTPS,
+  IX86_BUILTIN_CMPNGEPS,
+  IX86_BUILTIN_CMPORDPS,
+  IX86_BUILTIN_CMPUNORDPS,
+  IX86_BUILTIN_CMPNEPS,
+  IX86_BUILTIN_CMPEQSS,
+  IX86_BUILTIN_CMPLTSS,
+  IX86_BUILTIN_CMPLESS,
+  IX86_BUILTIN_CMPGTSS,
+  IX86_BUILTIN_CMPGESS,
+  IX86_BUILTIN_CMPNEQSS,
+  IX86_BUILTIN_CMPNLTSS,
+  IX86_BUILTIN_CMPNLESS,
+  IX86_BUILTIN_CMPNGTSS,
+  IX86_BUILTIN_CMPNGESS,
+  IX86_BUILTIN_CMPORDSS,
+  IX86_BUILTIN_CMPUNORDSS,
+  IX86_BUILTIN_CMPNESS,
+
+  IX86_BUILTIN_COMIEQSS,
+  IX86_BUILTIN_COMILTSS,
+  IX86_BUILTIN_COMILESS,
+  IX86_BUILTIN_COMIGTSS,
+  IX86_BUILTIN_COMIGESS,
+  IX86_BUILTIN_COMINEQSS,
+  IX86_BUILTIN_UCOMIEQSS,
+  IX86_BUILTIN_UCOMILTSS,
+  IX86_BUILTIN_UCOMILESS,
+  IX86_BUILTIN_UCOMIGTSS,
+  IX86_BUILTIN_UCOMIGESS,
+  IX86_BUILTIN_UCOMINEQSS,
+
+  IX86_BUILTIN_CVTPI2PS,
+  IX86_BUILTIN_CVTPS2PI,
+  IX86_BUILTIN_CVTSI2SS,
+  IX86_BUILTIN_CVTSS2SI,
+  IX86_BUILTIN_CVTTPS2PI,
+  IX86_BUILTIN_CVTTSS2SI,
+
+  IX86_BUILTIN_MAXPS,
+  IX86_BUILTIN_MAXSS,
+  IX86_BUILTIN_MINPS,
+  IX86_BUILTIN_MINSS,
+
+  IX86_BUILTIN_LOADAPS,
+  IX86_BUILTIN_LOADUPS,
+  IX86_BUILTIN_STOREAPS,
+  IX86_BUILTIN_STOREUPS,
+  IX86_BUILTIN_LOADSS,
+  IX86_BUILTIN_STORESS,
+  IX86_BUILTIN_MOVSS,
+
+  IX86_BUILTIN_MOVHLPS,
+  IX86_BUILTIN_MOVLHPS,
+  IX86_BUILTIN_LOADHPS,
+  IX86_BUILTIN_LOADLPS,
+  IX86_BUILTIN_STOREHPS,
+  IX86_BUILTIN_STORELPS,
+
+  IX86_BUILTIN_MASKMOVQ,
+  IX86_BUILTIN_MOVMSKPS,
+  IX86_BUILTIN_PMOVMSKB,
+
+  IX86_BUILTIN_MOVNTPS,
+  IX86_BUILTIN_MOVNTQ,
+
+  IX86_BUILTIN_PACKSSWB,
+  IX86_BUILTIN_PACKSSDW,
+  IX86_BUILTIN_PACKUSWB,
+
+  IX86_BUILTIN_PADDB,
+  IX86_BUILTIN_PADDW,
+  IX86_BUILTIN_PADDD,
+  IX86_BUILTIN_PADDSB,
+  IX86_BUILTIN_PADDSW,
+  IX86_BUILTIN_PADDUSB,
+  IX86_BUILTIN_PADDUSW,
+  IX86_BUILTIN_PSUBB,
+  IX86_BUILTIN_PSUBW,
+  IX86_BUILTIN_PSUBD,
+  IX86_BUILTIN_PSUBSB,
+  IX86_BUILTIN_PSUBSW,
+  IX86_BUILTIN_PSUBUSB,
+  IX86_BUILTIN_PSUBUSW,
+
+  IX86_BUILTIN_PAND,
+  IX86_BUILTIN_PANDN,
+  IX86_BUILTIN_POR,
+  IX86_BUILTIN_PXOR,
+
+  IX86_BUILTIN_PAVGB,
+  IX86_BUILTIN_PAVGW,
+
+  IX86_BUILTIN_PCMPEQB,
+  IX86_BUILTIN_PCMPEQW,
+  IX86_BUILTIN_PCMPEQD,
+  IX86_BUILTIN_PCMPGTB,
+  IX86_BUILTIN_PCMPGTW,
+  IX86_BUILTIN_PCMPGTD,
+
+  IX86_BUILTIN_PEXTRW,
+  IX86_BUILTIN_PINSRW,
+
+  IX86_BUILTIN_PMADDWD,
+
+  IX86_BUILTIN_PMAXSW,
+  IX86_BUILTIN_PMAXUB,
+  IX86_BUILTIN_PMINSW,
+  IX86_BUILTIN_PMINUB,
+
+  IX86_BUILTIN_PMULHUW,
+  IX86_BUILTIN_PMULHW,
+  IX86_BUILTIN_PMULLW,
+
+  IX86_BUILTIN_PSADBW,
+  IX86_BUILTIN_PSHUFW,
+
+  IX86_BUILTIN_PSLLW,
+  IX86_BUILTIN_PSLLD,
+  IX86_BUILTIN_PSLLQ,
+  IX86_BUILTIN_PSRAW,
+  IX86_BUILTIN_PSRAD,
+  IX86_BUILTIN_PSRLW,
+  IX86_BUILTIN_PSRLD,
+  IX86_BUILTIN_PSRLQ,
+  IX86_BUILTIN_PSLLWI,
+  IX86_BUILTIN_PSLLDI,
+  IX86_BUILTIN_PSLLQI,
+  IX86_BUILTIN_PSRAWI,
+  IX86_BUILTIN_PSRADI,
+  IX86_BUILTIN_PSRLWI,
+  IX86_BUILTIN_PSRLDI,
+  IX86_BUILTIN_PSRLQI,
+
+  IX86_BUILTIN_PUNPCKHBW,
+  IX86_BUILTIN_PUNPCKHWD,
+  IX86_BUILTIN_PUNPCKHDQ,
+  IX86_BUILTIN_PUNPCKLBW,
+  IX86_BUILTIN_PUNPCKLWD,
+  IX86_BUILTIN_PUNPCKLDQ,
+
+  IX86_BUILTIN_SHUFPS,
+
+  IX86_BUILTIN_RCPPS,
+  IX86_BUILTIN_RCPSS,
+  IX86_BUILTIN_RSQRTPS,
+  IX86_BUILTIN_RSQRTSS,
+  IX86_BUILTIN_SQRTPS,
+  IX86_BUILTIN_SQRTSS,
+  
+  IX86_BUILTIN_UNPCKHPS,
+  IX86_BUILTIN_UNPCKLPS,
+
+  IX86_BUILTIN_ANDPS,
+  IX86_BUILTIN_ANDNPS,
+  IX86_BUILTIN_ORPS,
+  IX86_BUILTIN_XORPS,
+
+  IX86_BUILTIN_EMMS,
+  IX86_BUILTIN_LDMXCSR,
+  IX86_BUILTIN_STMXCSR,
+  IX86_BUILTIN_SFENCE,
+
+  /* 3DNow! Original */
+  IX86_BUILTIN_FEMMS,
+  IX86_BUILTIN_PAVGUSB,
+  IX86_BUILTIN_PF2ID,
+  IX86_BUILTIN_PFACC,
+  IX86_BUILTIN_PFADD,
+  IX86_BUILTIN_PFCMPEQ,
+  IX86_BUILTIN_PFCMPGE,
+  IX86_BUILTIN_PFCMPGT,
+  IX86_BUILTIN_PFMAX,
+  IX86_BUILTIN_PFMIN,
+  IX86_BUILTIN_PFMUL,
+  IX86_BUILTIN_PFRCP,
+  IX86_BUILTIN_PFRCPIT1,
+  IX86_BUILTIN_PFRCPIT2,
+  IX86_BUILTIN_PFRSQIT1,
+  IX86_BUILTIN_PFRSQRT,
+  IX86_BUILTIN_PFSUB,
+  IX86_BUILTIN_PFSUBR,
+  IX86_BUILTIN_PI2FD,
+  IX86_BUILTIN_PMULHRW,
+
+  /* 3DNow! Athlon Extensions */
+  IX86_BUILTIN_PF2IW,
+  IX86_BUILTIN_PFNACC,
+  IX86_BUILTIN_PFPNACC,
+  IX86_BUILTIN_PI2FW,
+  IX86_BUILTIN_PSWAPDSI,
+  IX86_BUILTIN_PSWAPDSF,
+
+  IX86_BUILTIN_SSE_ZERO,
+  IX86_BUILTIN_MMX_ZERO,
+
+  IX86_BUILTIN_MAX
+};
+\f
+/* Define this macro if references to a symbol must be treated
+   differently depending on something about the variable or
+   function named by the symbol (such as what section it is in).
+
+   On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol
+   so that we may access it directly in the GOT.  */
+
+#define ENCODE_SECTION_INFO(DECL)                              \
+do {                                                           \
+    if (flag_pic)                                              \
+      {                                                                \
+       rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'    \
+                  ? TREE_CST_RTL (DECL) : DECL_RTL (DECL));    \
+                                                               \
+       if (GET_CODE (rtl) == MEM)                              \
+         {                                                     \
+           if (TARGET_DEBUG_ADDR                               \
+               && TREE_CODE_CLASS (TREE_CODE (DECL)) == 'd')   \
+             {                                                 \
+               fprintf (stderr, "Encode %s, public = %d\n",    \
+                        IDENTIFIER_POINTER (DECL_NAME (DECL)), \
+                        TREE_PUBLIC (DECL));                   \
+             }                                                 \
+                                                               \
+           SYMBOL_REF_FLAG (XEXP (rtl, 0))                     \
+             = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'      \
+                || ! TREE_PUBLIC (DECL));                      \
+         }                                                     \
+      }                                                                \
+} while (0)
+
+/* The `FINALIZE_PIC' macro serves as a hook to emit these special
+   codes once the function is being compiled into assembly code, but
+   not before.  (It is not done before, because in the case of
+   compiling an inline function, it would lead to multiple PIC
+   prologues being included in functions which used inline functions
+   and were compiled to assembly language.)  */
+
+#define FINALIZE_PIC \
+  (current_function_uses_pic_offset_table |= current_function_profile)
+
+\f
+/* Max number of args passed in registers.  If this is more than 3, we will
+   have problems with ebx (register #4), since it is a caller save register and
+   is also used as the pic register in ELF.  So for now, don't allow more than
+   3 registers to be passed in registers.  */
+
+#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
+
+#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : 0)
+
+\f
+/* Specify the machine mode that this machine uses
+   for the index in the tablejump instruction.  */
+#define CASE_VECTOR_MODE (!TARGET_64BIT || flag_pic ? SImode : DImode)
+
+/* Define as C expression which evaluates to nonzero if the tablejump
+   instruction expects the table to contain offsets from the address of the
+   table.
+   Do not define this if the table should contain absolute addresses.  */
+/* #define CASE_VECTOR_PC_RELATIVE 1 */
+
+/* Define this as 1 if `char' should by default be signed; else as 0.  */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* Number of bytes moved into a data cache for a single prefetch operation.  */
+#define PREFETCH_BLOCK ix86_cost->prefetch_block
+
+/* Number of prefetch operations that can be done in parallel.  */
+#define SIMULTANEOUS_PREFETCHES ix86_cost->simultaneous_prefetches
+
+/* Max number of bytes we can move from memory to memory
+   in one reasonably fast instruction.  */
+#define MOVE_MAX 16
+
+/* MOVE_MAX_PIECES is the number of bytes at a time which we can
+   move efficiently, as opposed to  MOVE_MAX which is the maximum
+   number of bytes we can move with a single instruction.  */
+#define MOVE_MAX_PIECES (TARGET_64BIT ? 8 : 4)
+
+/* If a memory-to-memory move would take MOVE_RATIO or more simple
+   move-instruction pairs, we will do a movstr or libcall instead.
+   Increasing the value will always make code faster, but eventually
+   incurs high cost in increased code size.
+
+   If you don't define this, a reasonable default is used.  */
+
+#define MOVE_RATIO (optimize_size ? 3 : ix86_cost->move_ratio)
+
+/* Define if shifts truncate the shift count
+   which implies one can omit a sign-extension or zero-extension
+   of a shift count.  */
+/* On i386, shifts do truncate the count.  But bit opcodes don't.  */
+
+/* #define SHIFT_COUNT_TRUNCATED */
+
+/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
+   is done just by pretending it is already truncated.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/* We assume that the store-condition-codes instructions store 0 for false
+   and some other value for true.  This is the value stored for true.  */
+
+#define STORE_FLAG_VALUE 1
+
+/* When a prototype says `char' or `short', really pass an `int'.
+   (The 386 can't easily push less than an int.)  */
+
+#define PROMOTE_PROTOTYPES (!TARGET_64BIT)
+
+/* A macro to update M and UNSIGNEDP when an object whose type is
+   TYPE and which has the specified mode and signedness is to be
+   stored in a register.  This macro is only called when TYPE is a
+   scalar type.
+
+   On i386 it is sometimes useful to promote HImode and QImode
+   quantities to SImode.  The choice depends on target type.  */
+
+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)            \
+do {                                                   \
+  if (((MODE) == HImode && TARGET_PROMOTE_HI_REGS)     \
+      || ((MODE) == QImode && TARGET_PROMOTE_QI_REGS)) \
+    (MODE) = SImode;                                   \
+} while (0)
+
+/* Specify the machine mode that pointers have.
+   After generation of rtl, the compiler makes no further distinction
+   between pointers and any other objects of this machine mode.  */
+#define Pmode (TARGET_64BIT ? DImode : SImode)
+
+/* A function address in a call instruction
+   is a byte address (for indexing purposes)
+   so give the MEM rtx a byte's mode.  */
+#define FUNCTION_MODE QImode
+\f
+/* A part of a C `switch' statement that describes the relative costs
+   of constant RTL expressions.  It must contain `case' labels for
+   expression codes `const_int', `const', `symbol_ref', `label_ref'
+   and `const_double'.  Each case must ultimately reach a `return'
+   statement to return the relative cost of the use of that kind of
+   constant value in an expression.  The cost may depend on the
+   precise value of the constant, which is available for examination
+   in X, and the rtx code of the expression in which it is contained,
+   found in OUTER_CODE.
+  
+   CODE is the expression code--redundant, since it can be obtained
+   with `GET_CODE (X)'.  */
+
+#define CONST_COSTS(RTX, CODE, OUTER_CODE)                     \
+  case CONST_INT:                                              \
+  case CONST:                                                  \
+  case LABEL_REF:                                              \
+  case SYMBOL_REF:                                             \
+    if (TARGET_64BIT && !x86_64_sign_extended_value (RTX))     \
+      return 3;                                                        \
+    if (TARGET_64BIT && !x86_64_zero_extended_value (RTX))     \
+      return 2;                                                        \
+    return flag_pic && SYMBOLIC_CONST (RTX) ? 1 : 0;           \
+                                                               \
+  case CONST_DOUBLE:                                           \
+    {                                                          \
+      int code;                                                        \
+      if (GET_MODE (RTX) == VOIDmode)                          \
+       return 0;                                               \
+                                                               \
+      code = standard_80387_constant_p (RTX);                  \
+      return code == 1 ? 1 :                                   \
+            code == 2 ? 2 :                                    \
+                        3;                                     \
+    }
+
+/* Delete the definition here when TOPLEVEL_COSTS_N_INSNS gets added to cse.c */
+#define TOPLEVEL_COSTS_N_INSNS(N) \
+  do { total = COSTS_N_INSNS (N); goto egress_rtx_costs; } while (0)
+
+/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
+   This can be used, for example, to indicate how costly a multiply
+   instruction is.  In writing this macro, you can use the construct
+   `COSTS_N_INSNS (N)' to specify a cost equal to N fast
+   instructions.  OUTER_CODE is the code of the expression in which X
+   is contained.
+
+   This macro is optional; do not define it if the default cost
+   assumptions are adequate for the target machine.  */
+
+#define RTX_COSTS(X, CODE, OUTER_CODE)                                 \
+  case ZERO_EXTEND:                                                    \
+    /* The zero extensions is often completely free on x86_64, so make \
+       it as cheap as possible.  */                                    \
+    if (TARGET_64BIT && GET_MODE (X) == DImode                         \
+       && GET_MODE (XEXP (X, 0)) == SImode)                            \
+      {                                                                        \
+       total = 1; goto egress_rtx_costs;                               \
+      }                                                                \
+    else                                                               \
+      TOPLEVEL_COSTS_N_INSNS (TARGET_ZERO_EXTEND_WITH_AND ?            \
+                             ix86_cost->add : ix86_cost->movzx);       \
+    break;                                                             \
+  case SIGN_EXTEND:                                                    \
+    TOPLEVEL_COSTS_N_INSNS (ix86_cost->movsx);                         \
+    break;                                                             \
+  case ASHIFT:                                                         \
+    if (GET_CODE (XEXP (X, 1)) == CONST_INT                            \
+       && (GET_MODE (XEXP (X, 0)) != DImode || TARGET_64BIT))          \
+      {                                                                        \
+       HOST_WIDE_INT value = INTVAL (XEXP (X, 1));                     \
+       if (value == 1)                                                 \
+         TOPLEVEL_COSTS_N_INSNS (ix86_cost->add);                      \
+       if ((value == 2 || value == 3)                                  \
+           && !TARGET_DECOMPOSE_LEA                                    \
+           && ix86_cost->lea <= ix86_cost->shift_const)                \
+         TOPLEVEL_COSTS_N_INSNS (ix86_cost->lea);                      \
+      }                                                                        \
+    /* fall through */                                                 \
+                                                                       \
+  case ROTATE:                                                         \
+  case ASHIFTRT:                                                       \
+  case LSHIFTRT:                                                       \
+  case ROTATERT:                                                       \
+    if (!TARGET_64BIT && GET_MODE (XEXP (X, 0)) == DImode)             \
+      {                                                                        \
+       if (GET_CODE (XEXP (X, 1)) == CONST_INT)                        \
+         {                                                             \
+           if (INTVAL (XEXP (X, 1)) > 32)                              \
+             TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const + 2);       \
+           else                                                        \
+             TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const * 2);       \
+         }                                                             \
+       else                                                            \
+         {                                                             \
+           if (GET_CODE (XEXP (X, 1)) == AND)                          \
+             TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 2);         \
+           else                                                        \
+             TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2);     \
+         }                                                             \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       if (GET_CODE (XEXP (X, 1)) == CONST_INT)                        \
+         TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_const);              \
+       else                                                            \
+         TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_var);                \
+      }                                                                        \
+    break;                                                             \
+                                                                       \
+  case MULT:                                                           \
+    if (GET_CODE (XEXP (X, 1)) == CONST_INT)                           \
+      {                                                                        \
+       unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1));            \
+       int nbits = 0;                                                  \
+                                                                       \
+       while (value != 0)                                              \
+         {                                                             \
+           nbits++;                                                    \
+           value >>= 1;                                                \
+         }                                                             \
+                                                                       \
+       TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init                    \
+                               + nbits * ix86_cost->mult_bit);         \
+      }                                                                        \
+    else                       /* This is arbitrary */                 \
+      TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init                     \
+                             + 7 * ix86_cost->mult_bit);               \
+                                                                       \
+  case DIV:                                                            \
+  case UDIV:                                                           \
+  case MOD:                                                            \
+  case UMOD:                                                           \
+    TOPLEVEL_COSTS_N_INSNS (ix86_cost->divide);                                \
+                                                                       \
+  case PLUS:                                                           \
+    if (!TARGET_DECOMPOSE_LEA                                          \
+       && INTEGRAL_MODE_P (GET_MODE (X))                               \
+       && GET_MODE_BITSIZE (GET_MODE (X)) <= GET_MODE_BITSIZE (Pmode)) \
+      {                                                                        \
+        if (GET_CODE (XEXP (X, 0)) == PLUS                             \
+           && GET_CODE (XEXP (XEXP (X, 0), 0)) == MULT                 \
+           && GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 1)) == CONST_INT  \
+           && CONSTANT_P (XEXP (X, 1)))                                \
+         {                                                             \
+           HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 0), 0), 1));\
+           if (val == 2 || val == 4 || val == 8)                       \
+             {                                                         \
+               return (COSTS_N_INSNS (ix86_cost->lea)                  \
+                       + rtx_cost (XEXP (XEXP (X, 0), 1),              \
+                                   (OUTER_CODE))                       \
+                       + rtx_cost (XEXP (XEXP (XEXP (X, 0), 0), 0),    \
+                                   (OUTER_CODE))                       \
+                       + rtx_cost (XEXP (X, 1), (OUTER_CODE)));        \
+             }                                                         \
+         }                                                             \
+       else if (GET_CODE (XEXP (X, 0)) == MULT                         \
+                && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT)      \
+         {                                                             \
+           HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1));         \
+           if (val == 2 || val == 4 || val == 8)                       \
+             {                                                         \
+               return (COSTS_N_INSNS (ix86_cost->lea)                  \
+                       + rtx_cost (XEXP (XEXP (X, 0), 0),              \
+                                   (OUTER_CODE))                       \
+                       + rtx_cost (XEXP (X, 1), (OUTER_CODE)));        \
+             }                                                         \
+         }                                                             \
+       else if (GET_CODE (XEXP (X, 0)) == PLUS)                        \
+         {                                                             \
+           return (COSTS_N_INSNS (ix86_cost->lea)                      \
+                   + rtx_cost (XEXP (XEXP (X, 0), 0), (OUTER_CODE))    \
+                   + rtx_cost (XEXP (XEXP (X, 0), 1), (OUTER_CODE))    \
+                   + rtx_cost (XEXP (X, 1), (OUTER_CODE)));            \
+         }                                                             \
+      }                                                                        \
+                                                                       \
+    /* fall through */                                                 \
+  case AND:                                                            \
+  case IOR:                                                            \
+  case XOR:                                                            \
+  case MINUS:                                                          \
+    if (!TARGET_64BIT && GET_MODE (X) == DImode)                       \
+      return (COSTS_N_INSNS (ix86_cost->add) * 2                       \
+             + (rtx_cost (XEXP (X, 0), (OUTER_CODE))                   \
+                << (GET_MODE (XEXP (X, 0)) != DImode))                 \
+             + (rtx_cost (XEXP (X, 1), (OUTER_CODE))                   \
+                << (GET_MODE (XEXP (X, 1)) != DImode)));               \
+                                                                       \
+    /* fall through */                                                 \
+  case NEG:                                                            \
+  case NOT:                                                            \
+    if (!TARGET_64BIT && GET_MODE (X) == DImode)                       \
+      TOPLEVEL_COSTS_N_INSNS (ix86_cost->add * 2);                     \
+    TOPLEVEL_COSTS_N_INSNS (ix86_cost->add);                           \
+                                                                       \
+  egress_rtx_costs:                                                    \
+    break;
+
+
+/* An expression giving the cost of an addressing mode that contains
+   ADDRESS.  If not defined, the cost is computed from the ADDRESS
+   expression and the `CONST_COSTS' values.
+
+   For most CISC machines, the default cost is a good approximation
+   of the true cost of the addressing mode.  However, on RISC
+   machines, all instructions normally have the same length and
+   execution time.  Hence all addresses will have equal costs.
+
+   In cases where more than one form of an address is known, the form
+   with the lowest cost will be used.  If multiple forms have the
+   same, lowest, cost, the one that is the most complex will be used.
+
+   For example, suppose an address that is equal to the sum of a
+   register and a constant is used twice in the same basic block.
+   When this macro is not defined, the address will be computed in a
+   register and memory references will be indirect through that
+   register.  On machines where the cost of the addressing mode
+   containing the sum is no higher than that of a simple indirect
+   reference, this will produce an additional instruction and
+   possibly require an additional register.  Proper specification of
+   this macro eliminates this overhead for such machines.
+
+   Similar use of this macro is made in strength reduction of loops.
+
+   ADDRESS need not be valid as an address.  In such a case, the cost
+   is not relevant and can be any value; invalid addresses need not be
+   assigned a different cost.
+
+   On machines where an address involving more than one register is as
+   cheap as an address computation involving only one register,
+   defining `ADDRESS_COST' to reflect this can cause two registers to
+   be live over a region of code where only one would have been if
+   `ADDRESS_COST' were not defined in that manner.  This effect should
+   be considered in the definition of this macro.  Equivalent costs
+   should probably only be given to addresses with different numbers
+   of registers on machines with lots of registers.
+
+   This macro will normally either not be defined or be defined as a
+   constant.
+
+   For i386, it is better to use a complex address than let gcc copy
+   the address into a reg and make a new pseudo.  But not if the address
+   requires to two regs - that would mean more pseudos with longer
+   lifetimes.  */
+
+#define ADDRESS_COST(RTX) \
+  ix86_address_cost (RTX)
+
+/* A C expression for the cost of moving data from a register in class FROM to
+   one in class TO.  The classes are expressed using the enumeration values
+   such as `GENERAL_REGS'.  A value of 2 is the default; other values are
+   interpreted relative to that.
+
+   It is not required that the cost always equal 2 when FROM is the same as TO;
+   on some machines it is expensive to move between registers if they are not
+   general registers.  */
+
+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
+   ix86_register_move_cost ((MODE), (CLASS1), (CLASS2))
+
+/* A C expression for the cost of moving data of mode M between a
+   register and memory.  A value of 2 is the default; this cost is
+   relative to those in `REGISTER_MOVE_COST'.
+
+   If moving between registers and memory is more expensive than
+   between two registers, you should define this macro to express the
+   relative cost.  */
+
+#define MEMORY_MOVE_COST(MODE, CLASS, IN)      \
+  ix86_memory_move_cost ((MODE), (CLASS), (IN))
+
+/* A C expression for the cost of a branch instruction.  A value of 1
+   is the default; other values are interpreted relative to that.  */
+
+#define BRANCH_COST ix86_branch_cost
+
+/* Define this macro as a C expression which is nonzero if accessing
+   less than a word of memory (i.e. a `char' or a `short') is no
+   faster than accessing a word of memory, i.e., if such access
+   require more than one instruction or if there is no difference in
+   cost between byte and (aligned) word loads.
+
+   When this macro is not defined, the compiler will access a field by
+   finding the smallest containing object; when it is defined, a
+   fullword load will be used if alignment permits.  Unless bytes
+   accesses are faster than word accesses, using word accesses is
+   preferable since it may eliminate subsequent memory access if
+   subsequent accesses occur to other fields in the same word of the
+   structure, but to different bytes.  */
+
+#define SLOW_BYTE_ACCESS 0
+
+/* Nonzero if access to memory by shorts is slow and undesirable.  */
+#define SLOW_SHORT_ACCESS 0
+
+/* Define this macro to be the value 1 if unaligned accesses have a
+   cost many times greater than aligned accesses, for example if they
+   are emulated in a trap handler.
+
+   When this macro is non-zero, the compiler will act as if
+   `STRICT_ALIGNMENT' were non-zero when generating code for block
+   moves.  This can cause significantly more instructions to be
+   produced.  Therefore, do not set this macro non-zero if unaligned
+   accesses only add a cycle or two to the time for a memory access.
+
+   If the value of this macro is always zero, it need not be defined.  */
+
+/* #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 0 */
+
+/* Define this macro to inhibit strength reduction of memory
+   addresses.  (On some machines, such strength reduction seems to do
+   harm rather than good.)  */
+
+/* #define DONT_REDUCE_ADDR */
+
+/* Define this macro if it is as good or better to call a constant
+   function address than to call an address kept in a register.
+
+   Desirable on the 386 because a CALL with a constant address is
+   faster than one with a register address.  */
+
+#define NO_FUNCTION_CSE
+
+/* Define this macro if it is as good or better for a function to call
+   itself with an explicit address than to call an address kept in a
+   register.  */
+
+#define NO_RECURSIVE_FUNCTION_CSE
+\f
+/* Add any extra modes needed to represent the condition code.
+
+   For the i386, we need separate modes when floating-point
+   equality comparisons are being done. 
+   
+   Add CCNO to indicate comparisons against zero that requires
+   Overflow flag to be unset.  Sign bit test is used instead and
+   thus can be used to form "a&b>0" type of tests.
+
+   Add CCGC to indicate comparisons agains zero that allows
+   unspecified garbage in the Carry flag.  This mode is used
+   by inc/dec instructions.
+
+   Add CCGOC to indicate comparisons agains zero that allows
+   unspecified garbage in the Carry and Overflow flag. This
+   mode is used to simulate comparisons of (a-b) and (a+b)
+   against zero using sub/cmp/add operations.
+
+   Add CCZ to indicate that only the Zero flag is valid.  */
+
+#define EXTRA_CC_MODES         \
+       CC (CCGCmode, "CCGC")   \
+       CC (CCGOCmode, "CCGOC") \
+       CC (CCNOmode, "CCNO")   \
+       CC (CCZmode, "CCZ")     \
+       CC (CCFPmode, "CCFP")   \
+       CC (CCFPUmode, "CCFPU")
+
+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
+   return the mode to be used for the comparison.
+
+   For floating-point equality comparisons, CCFPEQmode should be used.
+   VOIDmode should be used in all other cases.
+
+   For integer comparisons against zero, reduce to CCNOmode or CCZmode if
+   possible, to allow for more combinations.  */
+
+#define SELECT_CC_MODE(OP, X, Y) ix86_cc_mode ((OP), (X), (Y))
+
+/* Return non-zero if MODE implies a floating point inequality can be
+   reversed.  */
+
+#define REVERSIBLE_CC_MODE(MODE) 1
+
+/* A C expression whose value is reversed condition code of the CODE for
+   comparison done in CC_MODE mode.  */
+#define REVERSE_CONDITION(CODE, MODE) \
+  ((MODE) != CCFPmode && (MODE) != CCFPUmode ? reverse_condition (CODE) \
+   : reverse_condition_maybe_unordered (CODE))
+
+\f
+/* Control the assembler format that we output, to the extent
+   this does not vary between assemblers.  */
+
+/* How to refer to registers in assembler output.
+   This sequence is indexed by compiler's hard-register-number (see above).  */
+
+/* In order to refer to the first 8 regs as 32 bit regs prefix an "e"
+   For non floating point regs, the following are the HImode names.
+
+   For float regs, the stack top is sometimes referred to as "%st(0)"
+   instead of just "%st".  PRINT_REG handles this with the "y" code.  */
+
+#undef  HI_REGISTER_NAMES                                              
+#define HI_REGISTER_NAMES                                              \
+{"ax","dx","cx","bx","si","di","bp","sp",                              \
+ "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","",      \
+ "flags","fpsr", "dirflag", "frame",                                   \
+ "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7",              \
+ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"        ,               \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",                 \
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}
+
+#define REGISTER_NAMES HI_REGISTER_NAMES
+
+/* Table of additional register names to use in user input.  */
+
+#define ADDITIONAL_REGISTER_NAMES \
+{ { "eax", 0 }, { "edx", 1 }, { "ecx", 2 }, { "ebx", 3 },      \
+  { "esi", 4 }, { "edi", 5 }, { "ebp", 6 }, { "esp", 7 },      \
+  { "rax", 0 }, { "rdx", 1 }, { "rcx", 2 }, { "rbx", 3 },      \
+  { "rsi", 4 }, { "rdi", 5 }, { "rbp", 6 }, { "rsp", 7 },      \
+  { "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 },          \
+  { "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 },          \
+  { "mm0", 8},  { "mm1", 9},  { "mm2", 10}, { "mm3", 11},      \
+  { "mm4", 12}, { "mm5", 13}, { "mm6", 14}, { "mm7", 15} }
+
+/* Note we are omitting these since currently I don't know how
+to get gcc to use these, since they want the same but different
+number as al, and ax.
+*/
+
+#define QI_REGISTER_NAMES \
+{"al", "dl", "cl", "bl", "sil", "dil", "bpl", "spl",}
+
+/* These parallel the array above, and can be used to access bits 8:15
+   of regs 0 through 3.  */
+
+#define QI_HIGH_REGISTER_NAMES \
+{"ah", "dh", "ch", "bh", }
+
+/* How to renumber registers for dbx and gdb.  */
+
+#define DBX_REGISTER_NUMBER(N) \
+  (TARGET_64BIT ? dbx64_register_map[(N)] : dbx_register_map[(N)])
+
+extern int const dbx_register_map[FIRST_PSEUDO_REGISTER];
+extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER];
+extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
+
+/* Before the prologue, RA is at 0(%esp).  */
+#define INCOMING_RETURN_ADDR_RTX \
+  gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM))
+/* After the prologue, RA is at -4(AP) in the current frame.  */
+#define RETURN_ADDR_RTX(COUNT, FRAME)                                     \
+  ((COUNT) == 0                                                                   \
+   ? gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, -UNITS_PER_WORD)) \
+   : gen_rtx_MEM (Pmode, plus_constant (FRAME, UNITS_PER_WORD)))
+
+/* PC is dbx register 8; let's use that column for RA.  */
+#define DWARF_FRAME_RETURN_COLUMN      (TARGET_64BIT ? 16 : 8)
+
+/* Before the prologue, the top of the frame is at 4(%esp).  */
+#define INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD
+
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_DATA_REGNO(N)        ((N) < 2 ? (N) : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2)
+
+
+/* Select a format to encode pointers in exception handling data.  CODE
+   is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
+   true if the symbol may be affected by dynamic relocations.
+
+   ??? All x86 object file formats are capable of representing this.
+   After all, the relocation needed is the same as for the call insn.
+   Whether or not a particular assembler allows us to enter such, I
+   guess we'll have to see.  */
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)                     \
+  (flag_pic                                                            \
+    ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
+   : DW_EH_PE_absptr)
+
+/* This is how to output the definition of a user-level label named NAME,
+   such as the label on a static function or variable NAME.  */
+
+#define ASM_OUTPUT_LABEL(FILE, NAME)   \
+  (assemble_name ((FILE), (NAME)), fputs (":\n", (FILE)))
+
+/* Store in OUTPUT a string (made with alloca) containing
+   an assembler-name for a local static variable named NAME.
+   LABELNO is an integer which is different for each call.  */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
+  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+
+/* This is how to output an insn to push a register on the stack.
+   It need not be very fast code.  */
+
+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)  \
+  asm_fprintf ((FILE), "\tpush{l}\t%%e%s\n", reg_names[(REGNO)])
+
+/* This is how to output an insn to pop a register from the stack.
+   It need not be very fast code.  */
+
+#define ASM_OUTPUT_REG_POP(FILE, REGNO)  \
+  asm_fprintf ((FILE), "\tpop{l}\t%%e%s\n", reg_names[(REGNO)])
+
+/* This is how to output an element of a case-vector that is absolute.  */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
+  ix86_output_addr_vec_elt ((FILE), (VALUE))
+
+/* This is how to output an element of a case-vector that is relative.  */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+  ix86_output_addr_diff_elt ((FILE), (VALUE), (REL))
+
+/* Under some conditions we need jump tables in the text section, because
+   the assembler cannot handle label differences between sections.  */
+
+#define JUMP_TABLES_IN_TEXT_SECTION \
+  (!TARGET_64BIT && flag_pic && !HAVE_AS_GOTOFF_IN_DATA)
+
+/* A C statement that outputs an address constant appropriate to 
+   for DWARF debugging.  */
+
+#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE, X) \
+  i386_dwarf_output_addr_const ((FILE), (X))
+
+/* Either simplify a location expression, or return the original.  */
+
+#define ASM_SIMPLIFY_DWARF_ADDR(X) \
+  i386_simplify_dwarf_addr (X)
+
+/* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
+   and switch back.  For x86 we do this only to save a few bytes that
+   would otherwise be unused in the text section.  */
+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)     \
+   asm (SECTION_OP "\n\t"                              \
+       "call " USER_LABEL_PREFIX #FUNC "\n"            \
+       TEXT_SECTION_ASM_OP);
+\f
+/* Print operand X (an rtx) in assembler syntax to file FILE.
+   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
+   Effect of various CODE letters is described in i386.c near
+   print_operand function.  */
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
+  ((CODE) == '*' || (CODE) == '+')
+
+/* Print the name of a register based on its machine mode and number.
+   If CODE is 'w', pretend the mode is HImode.
+   If CODE is 'b', pretend the mode is QImode.
+   If CODE is 'k', pretend the mode is SImode.
+   If CODE is 'q', pretend the mode is DImode.
+   If CODE is 'h', pretend the reg is the `high' byte register.
+   If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.  */
+
+#define PRINT_REG(X, CODE, FILE)  \
+  print_reg ((X), (CODE), (FILE))
+
+#define PRINT_OPERAND(FILE, X, CODE)  \
+  print_operand ((FILE), (X), (CODE))
+
+#define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
+  print_operand_address ((FILE), (ADDR))
+
+/* Print the name of a register for based on its machine mode and number.
+   This macro is used to print debugging output.
+   This macro is different from PRINT_REG in that it may be used in
+   programs that are not linked with aux-output.o.  */
+
+#define DEBUG_PRINT_REG(X, CODE, FILE)                 \
+  do { static const char * const hi_name[] = HI_REGISTER_NAMES;        \
+       static const char * const qi_name[] = QI_REGISTER_NAMES;        \
+       fprintf ((FILE), "%d ", REGNO (X));             \
+       if (REGNO (X) == FLAGS_REG)                     \
+        { fputs ("flags", (FILE)); break; }            \
+       if (REGNO (X) == DIRFLAG_REG)                   \
+        { fputs ("dirflag", (FILE)); break; }          \
+       if (REGNO (X) == FPSR_REG)                      \
+        { fputs ("fpsr", (FILE)); break; }             \
+       if (REGNO (X) == ARG_POINTER_REGNUM)            \
+        { fputs ("argp", (FILE)); break; }             \
+       if (REGNO (X) == FRAME_POINTER_REGNUM)          \
+        { fputs ("frame", (FILE)); break; }            \
+       if (STACK_TOP_P (X))                            \
+        { fputs ("st(0)", (FILE)); break; }            \
+       if (FP_REG_P (X))                               \
+        { fputs (hi_name[REGNO(X)], (FILE)); break; }  \
+       if (REX_INT_REG_P (X))                          \
+        {                                              \
+          switch (GET_MODE_SIZE (GET_MODE (X)))        \
+            {                                          \
+            default:                                   \
+            case 8:                                    \
+              fprintf ((FILE), "r%i", REGNO (X)        \
+                       - FIRST_REX_INT_REG + 8);       \
+              break;                                   \
+            case 4:                                    \
+              fprintf ((FILE), "r%id", REGNO (X)       \
+                       - FIRST_REX_INT_REG + 8);       \
+              break;                                   \
+            case 2:                                    \
+              fprintf ((FILE), "r%iw", REGNO (X)       \
+                       - FIRST_REX_INT_REG + 8);       \
+              break;                                   \
+            case 1:                                    \
+              fprintf ((FILE), "r%ib", REGNO (X)       \
+                       - FIRST_REX_INT_REG + 8);       \
+              break;                                   \
+            }                                          \
+          break;                                       \
+        }                                              \
+       switch (GET_MODE_SIZE (GET_MODE (X)))           \
+        {                                              \
+        case 8:                                        \
+          fputs ("r", (FILE));                         \
+          fputs (hi_name[REGNO (X)], (FILE));          \
+          break;                                       \
+        default:                                       \
+          fputs ("e", (FILE));                         \
+        case 2:                                        \
+          fputs (hi_name[REGNO (X)], (FILE));          \
+          break;                                       \
+        case 1:                                        \
+          fputs (qi_name[REGNO (X)], (FILE));          \
+          break;                                       \
+        }                                              \
+     } while (0)
+
+/* a letter which is not needed by the normal asm syntax, which
+   we can use for operand syntax in the extended asm */
+
+#define ASM_OPERAND_LETTER '#'
+#define RET return ""
+#define AT_SP(MODE) (gen_rtx_MEM ((MODE), stack_pointer_rtx))
+\f
+/* Define the codes that are matched by predicates in i386.c.  */
+
+#define PREDICATE_CODES                                                        \
+  {"x86_64_immediate_operand", {CONST_INT, SUBREG, REG,                        \
+                               SYMBOL_REF, LABEL_REF, CONST}},         \
+  {"x86_64_nonmemory_operand", {CONST_INT, SUBREG, REG,                        \
+                               SYMBOL_REF, LABEL_REF, CONST}},         \
+  {"x86_64_movabs_operand", {CONST_INT, SUBREG, REG,                   \
+                               SYMBOL_REF, LABEL_REF, CONST}},         \
+  {"x86_64_szext_nonmemory_operand", {CONST_INT, SUBREG, REG,          \
+                                    SYMBOL_REF, LABEL_REF, CONST}},    \
+  {"x86_64_general_operand", {CONST_INT, SUBREG, REG, MEM,             \
+                             SYMBOL_REF, LABEL_REF, CONST}},           \
+  {"x86_64_szext_general_operand", {CONST_INT, SUBREG, REG, MEM,       \
+                                  SYMBOL_REF, LABEL_REF, CONST}},      \
+  {"x86_64_zext_immediate_operand", {CONST_INT, CONST_DOUBLE, CONST,   \
+                                      SYMBOL_REF, LABEL_REF}},         \
+  {"shiftdi_operand", {SUBREG, REG, MEM}},                             \
+  {"const_int_1_operand", {CONST_INT}},                                        \
+  {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}},                        \
+  {"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,     \
+                      LABEL_REF, SUBREG, REG, MEM}},                   \
+  {"pic_symbolic_operand", {CONST}},                                   \
+  {"call_insn_operand", {REG, SUBREG, MEM, SYMBOL_REF}},               \
+  {"constant_call_address_operand", {SYMBOL_REF, CONST}},              \
+  {"const0_operand", {CONST_INT, CONST_DOUBLE}},                       \
+  {"const1_operand", {CONST_INT}},                                     \
+  {"const248_operand", {CONST_INT}},                                   \
+  {"incdec_operand", {CONST_INT}},                                     \
+  {"mmx_reg_operand", {REG}},                                          \
+  {"reg_no_sp_operand", {SUBREG, REG}},                                        \
+  {"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST,         \
+                       SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}},      \
+  {"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}},             \
+  {"q_regs_operand", {SUBREG, REG}},                                   \
+  {"non_q_regs_operand", {SUBREG, REG}},                               \
+  {"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU, UNORDERED, \
+                                ORDERED, LT, UNLT, GT, UNGT, LE, UNLE, \
+                                GE, UNGE, LTGT, UNEQ}},                \
+  {"sse_comparison_operator", {EQ, LT, LE, UNORDERED, NE, UNGE, UNGT,  \
+                              ORDERED, UNEQ, UNLT, UNLE, LTGT, GE, GT  \
+                              }},                                      \
+  {"ix86_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \
+                              GTU, UNORDERED, ORDERED, UNLE, UNLT,     \
+                              UNGE, UNGT, LTGT, UNEQ }},               \
+  {"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}},       \
+  {"ext_register_operand", {SUBREG, REG}},                             \
+  {"binary_fp_operator", {PLUS, MINUS, MULT, DIV}},                    \
+  {"mult_operator", {MULT}},                                           \
+  {"div_operator", {DIV}},                                             \
+  {"arith_or_logical_operator", {PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, \
+                                UMIN, UMAX, COMPARE, MINUS, DIV, MOD,  \
+                                UDIV, UMOD, ASHIFT, ROTATE, ASHIFTRT,  \
+                                LSHIFTRT, ROTATERT}},                  \
+  {"promotable_binary_operator", {PLUS, MULT, AND, IOR, XOR, ASHIFT}}, \
+  {"memory_displacement_operand", {MEM}},                              \
+  {"cmpsi_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,       \
+                    LABEL_REF, SUBREG, REG, MEM, AND}},                \
+  {"long_memory_operand", {MEM}},
+
+/* A list of predicates that do special things with modes, and so
+   should not elicit warnings for VOIDmode match_operand.  */
+
+#define SPECIAL_MODE_PREDICATES \
+  "ext_register_operand",
+\f
+/* CM_32 is used by 32bit ABI
+   CM_SMALL is small model assuming that all code and data fits in the first
+   31bits of address space.
+   CM_KERNEL is model assuming that all code and data fits in the negative
+   31bits of address space.
+   CM_MEDIUM is model assuming that code fits in the first 31bits of address
+   space.  Size of data is unlimited.
+   CM_LARGE is model making no assumptions about size of particular sections.
+  
+   CM_SMALL_PIC is model for PIC libraries assuming that code+data+got/plt
+   tables first in 31bits of address space.
+ */
+enum cmodel {
+  CM_32,
+  CM_SMALL,
+  CM_KERNEL,
+  CM_MEDIUM,
+  CM_LARGE,
+  CM_SMALL_PIC
+};
+
+/* Size of the RED_ZONE area.  */
+#define RED_ZONE_SIZE 128
+/* Reserved area of the red zone for temporaries.  */
+#define RED_ZONE_RESERVE 8
+extern const char *ix86_debug_arg_string, *ix86_debug_addr_string;
+
+enum asm_dialect {
+  ASM_ATT,
+  ASM_INTEL
+};
+extern const char *ix86_asm_string;
+extern enum asm_dialect ix86_asm_dialect;
+/* Value of -mcmodel specified by user.  */
+extern const char *ix86_cmodel_string;
+extern enum cmodel ix86_cmodel;
+\f
+/* Variables in i386.c */
+extern const char *ix86_cpu_string;            /* for -mcpu=<xxx> */
+extern const char *ix86_arch_string;           /* for -march=<xxx> */
+extern const char *ix86_fpmath_string;         /* for -mfpmath=<xxx> */
+extern const char *ix86_regparm_string;                /* # registers to use to pass args */
+extern const char *ix86_align_loops_string;    /* power of two alignment for loops */
+extern const char *ix86_align_jumps_string;    /* power of two alignment for non-loop jumps */
+extern const char *ix86_align_funcs_string;    /* power of two alignment for functions */
+extern const char *ix86_preferred_stack_boundary_string;/* power of two alignment for stack boundary */
+extern const char *ix86_branch_cost_string;    /* values 1-5: see jump.c */
+extern int ix86_regparm;                       /* ix86_regparm_string as a number */
+extern int ix86_preferred_stack_boundary;      /* preferred stack boundary alignment in bits */
+extern int ix86_branch_cost;                   /* values 1-5: see jump.c */
+extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER]; /* smalled class containing REGNO */
+// Commented out the following two lines due to lack of definition for "rtx" - Brian
+//extern rtx ix86_compare_op0; /* operand 0 for comparisons */
+//extern rtx ix86_compare_op1; /* operand 1 for comparisons */
+\f
+/* To properly truncate FP values into integers, we need to set i387 control
+   word.  We can't emit proper mode switching code before reload, as spills
+   generated by reload may truncate values incorrectly, but we still can avoid
+   redundant computation of new control word by the mode switching pass.
+   The fldcw instructions are still emitted redundantly, but this is probably
+   not going to be noticeable problem, as most CPUs do have fast path for
+   the sequence.  
+
+   The machinery is to emit simple truncation instructions and split them
+   before reload to instructions having USEs of two memory locations that
+   are filled by this code to old and new control word.
+   Post-reload pass may be later used to eliminate the redundant fildcw if
+   needed.  */
+
+enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
+
+/* Define this macro if the port needs extra instructions inserted
+   for mode switching in an optimizing compilation.  */
+
+#define OPTIMIZE_MODE_SWITCHING(ENTITY) 1
+
+/* If you define `OPTIMIZE_MODE_SWITCHING', you have to define this as
+   initializer for an array of integers.  Each initializer element N
+   refers to an entity that needs mode switching, and specifies the
+   number of different modes that might need to be set for this
+   entity.  The position of the initializer in the initializer -
+   starting counting at zero - determines the integer that is used to
+   refer to the mode-switched entity in question.  */
+
+#define NUM_MODES_FOR_MODE_SWITCHING { FP_CW_ANY }
+
+/* ENTITY is an integer specifying a mode-switched entity.  If
+   `OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
+   return an integer value not larger than the corresponding element
+   in `NUM_MODES_FOR_MODE_SWITCHING', to denote the mode that ENTITY
+   must be switched into prior to the execution of INSN.  */
+
+#define MODE_NEEDED(ENTITY, I)                                         \
+  (GET_CODE (I) == CALL_INSN                                           \
+   || (GET_CODE (I) == INSN && (asm_noperands (PATTERN (I)) >= 0       \
+                               || GET_CODE (PATTERN (I)) == ASM_INPUT))\
+   ? FP_CW_UNINITIALIZED                                               \
+   : recog_memoized (I) < 0 || get_attr_type (I) != TYPE_FISTP         \
+   ? FP_CW_ANY                                                         \
+   : FP_CW_STORED)
+
+/* This macro specifies the order in which modes for ENTITY are
+   processed.  0 is the highest priority.  */
+
+#define MODE_PRIORITY_TO_MODE(ENTITY, N) (N)
+
+/* Generate one or more insns to set ENTITY to MODE.  HARD_REG_LIVE
+   is the set of hard registers live at the point where the insn(s)
+   are to be inserted.  */
+
+#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE)                    \
+  ((MODE) == FP_CW_STORED                                              \
+   ? emit_i387_cw_initialization (assign_386_stack_local (HImode, 1),  \
+                                 assign_386_stack_local (HImode, 2)), 0\
+   : 0)
+\f
+/* Avoid renaming of stack registers, as doing so in combination with
+   scheduling just increases amount of live registers at time and in
+   the turn amount of fxch instructions needed.
+
+   ??? Maybe Pentium chips benefits from renaming, someone can try...  */
+
+#define HARD_REGNO_RENAME_OK(SRC, TARGET)  \
+   ((SRC) < FIRST_STACK_REG || (SRC) > LAST_STACK_REG)
+
+\f
+/*
+Local variables:
+version-control: t
+End:
+*/
index 168f3f4..89b96cd 100644 (file)
 #define __MEM_H
 
 
-#ifdef __i386__
+#if  defined(__i386__) || defined(_PPC_)
 
 #define MM_PAGE_SIZE   4096
 
-#endif // defined __i386__
+#endif // defined __i386__ or _PPC_
 
 typedef struct
 {
index d932303..cea179e 100644 (file)
@@ -164,9 +164,7 @@ FrLdrStartup(ULONG Magic)
     /* Re-initalize EFLAGS */
     Ke386EraseFlags();
     
-    /* Get Kernel Base and Set MmSystemRangeStart */  
-    FrLdrGetKernelBase();
-
+    /* Get the PAE Mode */
     FrLdrGetPaeMode();
        
     /* Initialize the page directory */
@@ -531,6 +529,14 @@ FrLdrMapKernel(FILE *KernelImage)
     ULONG_PTR TargetSection;
     ULONG SectionSize;
     LONG i;
+    PIMAGE_DATA_DIRECTORY RelocationDDir;
+    PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+    ULONG Count;
+    ULONG_PTR Address, MaxAddress;
+    PUSHORT TypeOffset;
+    ULONG_PTR Delta;
+    PUSHORT ShortPtr;
+    PULONG LongPtr;
 
     /* Allocate 1024 bytes for PE Header */
     ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
@@ -552,8 +558,9 @@ FrLdrMapKernel(FILE *KernelImage)
     /* Now read the MZ header to get the offset to the PE Header */
     NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
      
-    /* Save the Image Base */
-    KernelBase = NtHeader->OptionalHeader.ImageBase;
+    /* Get Kernel Base */
+    KernelBase = NtHeader->OptionalHeader.ImageBase;  
+    FrLdrGetKernelBase();
     
     /* Save Entrypoint */
     KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
@@ -603,9 +610,64 @@ FrLdrMapKernel(FILE *KernelImage)
                    Section->Misc.VirtualSize - Section->SizeOfRawData);
         }
     }
+       
+    /* Get the Relocation Data Directory */
+    RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+    
+    /* Get the Relocation Section Start and End*/
+    RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
+    RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
+   
+    /* Calculate Difference between Real Base and Compiled Base*/
+    Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
     
-    /* Now relocate the file */
-    /* FIXME: ADD RELOC CODE */
+    /* Determine how far we shoudl relocate */
+    MaxAddress = KERNEL_BASE_PHYS + ImageSize;
+    
+    /* Relocate until we've processed all the blocks */
+    while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
+        
+        /* See how many Relocation Blocks we have */
+        Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
+        
+        /* Calculate the Address of this Directory */
+        Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
+        
+        /* Calculate the Offset of the Type */
+        TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+        for (i = 0; i < Count; i++) {
+            
+            ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
+
+            /* Don't relocate after the end of the loaded driver */
+            if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
+
+            switch (*TypeOffset >> 12) {
+                
+                case IMAGE_REL_BASED_ABSOLUTE:
+                    break;
+
+                case IMAGE_REL_BASED_HIGH:
+                    *ShortPtr += HIWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_LOW:
+                    *ShortPtr += LOWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_HIGHLOW:
+                    LongPtr = (PULONG)ShortPtr;
+                    *LongPtr += Delta;
+                    break;
+            }
+            
+            TypeOffset++;
+        }
+        
+        /* Move to the next Relocation Table */
+        RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
+    }
     
     /* Increase the next Load Base */
     NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
index 427f34e..9cafa6a 100644 (file)
@@ -578,8 +578,9 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
        PARTITION_TABLE_ENTRY PartitionTableEntry;
        ULONG rosPartition;
  
-    extern ULONG PageDirectoryStart;
-    extern ULONG PageDirectoryEnd;
+       extern ULONG PageDirectoryStart;
+       extern ULONG PageDirectoryEnd;
+       extern BOOLEAN AcpiPresent;
 
        //
        // Open the operating system section
@@ -596,8 +597,8 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
         * Setup multiboot information structure
         */
        LoaderBlock.Flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
-    LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
-    LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
+       LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
+       LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
        LoaderBlock.BootDevice = 0xffffffff;
        LoaderBlock.CommandLine = (unsigned long)multiboot_kernel_cmdline;
        LoaderBlock.ModsCount = 0;
@@ -734,6 +735,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
         */
        MachHwDetect();
 
+       if (AcpiPresent) LoaderBlock.Flags |= MB_INFO_FLAG_ACPI_TABLE;
 
        UiDrawStatusText("Loading...");
        UiDrawProgressBarCenter(0, 100, "Loading ReactOS...");
index da31d66..6e5b9b4 100644 (file)
@@ -20,6 +20,7 @@
 #include <freeldr.h>
 #include <machine.h>
 #include <rtl.h>
+#include <stdarg.h>
 
 /*
  * print() - prints unformatted text to stdout
@@ -38,12 +39,11 @@ void print(char *str)
  */
 void printf(char *format, ... )
 {
-       int *dataptr = (int *)(void *)&format;
+       va_list ap;
+       va_start(ap,format);
        char c, *ptr, str[16];
        int ll;
 
-       dataptr++;
-
        while ((c = *(format++)))
        {
                if (c != '%')
@@ -66,11 +66,11 @@ void printf(char *format, ... )
                        case 'd': case 'u': case 'x':
                                if (ll)
                                {
-                                       *convert_i64_to_ascii(str, c, *((unsigned long long *) dataptr++)) = 0;
+                                       *convert_i64_to_ascii(str, c, va_arg(ap, unsigned long long)) = 0;
                                }
                                else
                                {
-                                       *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
+                                       *convert_to_ascii(str, c, va_arg(ap, unsigned long)) = 0;
                                }
 
                                ptr = str;
@@ -81,10 +81,10 @@ void printf(char *format, ... )
                                }
                                break;
 
-                       case 'c': MachConsPutChar((*(dataptr++))&0xff); break;
+                       case 'c': MachConsPutChar((va_arg(ap,int))&0xff); break;
 
                        case 's':
-                               ptr = (char *)(*(dataptr++));
+                               ptr = va_arg(ap,char *);
 
                                while ((c = *(ptr++)))
                                {
@@ -100,16 +100,18 @@ void printf(char *format, ... )
                        }
                }
        }
+
+       va_end(ap);
 }
 
 void sprintf(char *buffer, char *format, ... )
 {
-       int *dataptr = (int *)(void *)&format;
+       va_list ap;
        char c, *ptr, str[16];
        char *p = buffer;
        int ll;
 
-       dataptr++;
+       va_start(ap,format);
 
        while ((c = *(format++)))
        {
@@ -134,11 +136,11 @@ void sprintf(char *buffer, char *format, ... )
                        case 'd': case 'u': case 'x':
                                if (ll)
                                {
-                                       *convert_i64_to_ascii(str, c, *((unsigned long long*) dataptr++)) = 0;
+                                       *convert_i64_to_ascii(str, c, va_arg(ap, unsigned long long)) = 0;
                                }
                                else
                                {
-                                       *convert_to_ascii(str, c, *((unsigned long *) dataptr++)) = 0;
+                                       *convert_to_ascii(str, c, va_arg(ap, unsigned long)) = 0;
                                }
                                        
                                ptr = str;
@@ -151,12 +153,12 @@ void sprintf(char *buffer, char *format, ... )
                                break;
 
                        case 'c':
-                               *p = (*(dataptr++))&0xff;
+                               *p = va_arg(ap,int)&0xff;
                                p++;
                                break;
 
                        case 's':
-                               ptr = (char *)(*(dataptr++));
+                               ptr = va_arg(ap,char *);
 
                                while ((c = *(ptr++)))
                                {
@@ -174,5 +176,6 @@ void sprintf(char *buffer, char *format, ... )
                        }
                }
        }
+       va_end(ap);
        *p=0;
 }
index 0e55516..7ea68c4 100644 (file)
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 /*
  * convert_to_ascii() - converts a number to it's ascii equivalent
  * from:
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 1996   Erich Boleyn  <erich@uruk.org>
  */
-char *convert_to_ascii(char *buf, int c, ...)
+char *convert_to_ascii(char *buf, int c, int num)
 {
-  unsigned long num = *((&c) + 1), mult = 10;
+  unsigned long mult = 10;
   char *ptr = buf;
 
   if (c == 'x')
@@ -63,9 +62,8 @@ char *convert_to_ascii(char *buf, int c, ...)
   return ptr;
 }
 
-char *convert_i64_to_ascii(char *buf, int c, ...)
+char *convert_i64_to_ascii(char *buf, int c, unsigned long long num)
 {
-  unsigned long long num = *(long long*)((&c) + 1);
   int mult = 10;
   char *ptr = buf;
 
index abf3bf6..081503c 100644 (file)
@@ -344,4 +344,133 @@ HKCR,"NDS\Clsid","",0x00000002,"{323991f0-7bad-11cf-b03d-00aa006e0975}"
 
 HKCR,"WinNT\Clsid","",0x00000002,"{8b20cd60-0f29-11cf-abc4-02608c9e7553}"
 
+
+; For language support:
+
+HKCR,"MIME",,0x00000012
+HKCR,"MIME\Database",,0x00000012
+HKCR,"MIME\Database\Rfc1766",,0x00000012
+HKCR,"MIME\Database\Rfc1766","0436",0x00000000,"af;Afrikaans"
+HKCR,"MIME\Database\Rfc1766","041C",0x00000000,"sq;Albanian"
+HKCR,"MIME\Database\Rfc1766","0001",0x00000000,"ar;Arabic"
+HKCR,"MIME\Database\Rfc1766","0401",0x00000000,"ar-sa;Arabic (Saudi Arabia)"
+HKCR,"MIME\Database\Rfc1766","0801",0x00000000,"ar-iq;Arabic (Iraq)"
+HKCR,"MIME\Database\Rfc1766","0C01",0x00000000,"ar-eg;Arabic (Egypt)"
+HKCR,"MIME\Database\Rfc1766","1001",0x00000000,"ar-ly;Arabic (Libya)"
+HKCR,"MIME\Database\Rfc1766","1401",0x00000000,"ar-dz;Arabic (Algeria)"
+HKCR,"MIME\Database\Rfc1766","1801",0x00000000,"ar-ma;Arabic (Morocco)"
+HKCR,"MIME\Database\Rfc1766","1C01",0x00000000,"ar-tn;Arabic (Tunisia)"
+HKCR,"MIME\Database\Rfc1766","2001",0x00000000,"ar-om;Arabic (Oman)"
+HKCR,"MIME\Database\Rfc1766","2401",0x00000000,"ar-ye;Arabic (Yemen)"
+HKCR,"MIME\Database\Rfc1766","2801",0x00000000,"ar-sy;Arabic (Syria)"
+HKCR,"MIME\Database\Rfc1766","2C01",0x00000000,"ar-jo;Arabic (Jordan)"
+HKCR,"MIME\Database\Rfc1766","3001",0x00000000,"ar-lb;Arabic (Lebanon)"
+HKCR,"MIME\Database\Rfc1766","3401",0x00000000,"ar-kw;Arabic (Kuwait)"
+HKCR,"MIME\Database\Rfc1766","3801",0x00000000,"ar-ae;Arabic (U.A.E.)"
+HKCR,"MIME\Database\Rfc1766","3C01",0x00000000,"ar-bh;Arabic (Bahrain)"
+HKCR,"MIME\Database\Rfc1766","4001",0x00000000,"ar-qa;Arabic (Qatar)"
+HKCR,"MIME\Database\Rfc1766","042D",0x00000000,"eu;Basque"
+HKCR,"MIME\Database\Rfc1766","0402",0x00000000,"bg;Bulgarian"
+HKCR,"MIME\Database\Rfc1766","0423",0x00000000,"be;Belarusian"
+HKCR,"MIME\Database\Rfc1766","0403",0x00000000,"ca;Catalan"
+HKCR,"MIME\Database\Rfc1766","0004",0x00000000,"zh;Chinese"
+HKCR,"MIME\Database\Rfc1766","0404",0x00000000,"zh-tw;Chinese (Taiwan)"
+HKCR,"MIME\Database\Rfc1766","0804",0x00000000,"zh-cn;Chinese (China)"
+HKCR,"MIME\Database\Rfc1766","0C04",0x00000000,"zh-hk;Chinese (Hong Kong SAR)"
+HKCR,"MIME\Database\Rfc1766","1004",0x00000000,"zh-sg;Chinese (Singapore)"
+HKCR,"MIME\Database\Rfc1766","041A",0x00000000,"hr;Croatian"
+HKCR,"MIME\Database\Rfc1766","0405",0x00000000,"cs;Czech"
+HKCR,"MIME\Database\Rfc1766","0406",0x00000000,"da;Danish"
+HKCR,"MIME\Database\Rfc1766","0413",0x00000000,"nl;Dutch (Netherlands)"
+HKCR,"MIME\Database\Rfc1766","0813",0x00000000,"nl-be;Dutch (Belgium)"
+HKCR,"MIME\Database\Rfc1766","0009",0x00000000,"en;English"
+HKCR,"MIME\Database\Rfc1766","0409",0x00000000,"en-us;English (United States)"
+HKCR,"MIME\Database\Rfc1766","0809",0x00000000,"en-gb;English (United Kingdom)"
+HKCR,"MIME\Database\Rfc1766","0C09",0x00000000,"en-au;English (Australia)"
+HKCR,"MIME\Database\Rfc1766","1009",0x00000000,"en-ca;English (Canada)"
+HKCR,"MIME\Database\Rfc1766","1409",0x00000000,"en-nz;English (New Zealand)"
+HKCR,"MIME\Database\Rfc1766","1809",0x00000000,"en-ie;English (Ireland)"
+HKCR,"MIME\Database\Rfc1766","1C09",0x00000000,"en-za;English (South Africa)"
+HKCR,"MIME\Database\Rfc1766","2009",0x00000000,"en-jm;English (Jamaica)"
+HKCR,"MIME\Database\Rfc1766","2809",0x00000000,"en-bz;English (Belize)"
+HKCR,"MIME\Database\Rfc1766","2C09",0x00000000,"en-tt;English (Trinidad)"
+HKCR,"MIME\Database\Rfc1766","0425",0x00000000,"et;Estonian"
+HKCR,"MIME\Database\Rfc1766","0438",0x00000000,"fo;Faeroese"
+HKCR,"MIME\Database\Rfc1766","0429",0x00000000,"fa;Farsi"
+HKCR,"MIME\Database\Rfc1766","040B",0x00000000,"fi;Finnish"
+HKCR,"MIME\Database\Rfc1766","040C",0x00000000,"fr;French (France)"
+HKCR,"MIME\Database\Rfc1766","080C",0x00000000,"fr-be;French (Belgium)"
+HKCR,"MIME\Database\Rfc1766","0C0C",0x00000000,"fr-ca;French (Canada)"
+HKCR,"MIME\Database\Rfc1766","100C",0x00000000,"fr-ch;French (Switzerland)"
+HKCR,"MIME\Database\Rfc1766","140C",0x00000000,"fr-lu;French (Luxembourg)"
+HKCR,"MIME\Database\Rfc1766","043C",0x00000000,"gd;Gaelic"
+HKCR,"MIME\Database\Rfc1766","0407",0x00000000,"de;German (Germany)"
+HKCR,"MIME\Database\Rfc1766","0807",0x00000000,"de-ch;German (Switzerland)"
+HKCR,"MIME\Database\Rfc1766","0C07",0x00000000,"de-at;German (Austria)"
+HKCR,"MIME\Database\Rfc1766","1007",0x00000000,"de-lu;German (Luxembourg)"
+HKCR,"MIME\Database\Rfc1766","1407",0x00000000,"de-li;German (Liechtenstein)"
+HKCR,"MIME\Database\Rfc1766","0408",0x00000000,"el;Greek"
+HKCR,"MIME\Database\Rfc1766","040D",0x00000000,"he;Hebrew"
+HKCR,"MIME\Database\Rfc1766","0439",0x00000000,"hi;Hindi"
+HKCR,"MIME\Database\Rfc1766","040E",0x00000000,"hu;Hungarian"
+HKCR,"MIME\Database\Rfc1766","040F",0x00000000,"is;Icelandic"
+HKCR,"MIME\Database\Rfc1766","0421",0x00000000,"in;Indonesian"
+HKCR,"MIME\Database\Rfc1766","0410",0x00000000,"it;Italian (Italy)"
+HKCR,"MIME\Database\Rfc1766","0810",0x00000000,"it-ch;Italian (Switzerland)"
+HKCR,"MIME\Database\Rfc1766","0411",0x00000000,"ja;Japanese"
+HKCR,"MIME\Database\Rfc1766","0412",0x00000000,"ko;Korean"
+HKCR,"MIME\Database\Rfc1766","0426",0x00000000,"lv;Latvian"
+HKCR,"MIME\Database\Rfc1766","0427",0x00000000,"lt;Lithuanian"
+HKCR,"MIME\Database\Rfc1766","042F",0x00000000,"mk;FYRO Macedonian"
+HKCR,"MIME\Database\Rfc1766","043E",0x00000000,"ms;Malay (Malaysia)"
+HKCR,"MIME\Database\Rfc1766","043A",0x00000000,"mt;Maltese"
+HKCR,"MIME\Database\Rfc1766","0414",0x00000000,"no;Norwegian (Bokmal)"
+HKCR,"MIME\Database\Rfc1766","0814",0x00000000,"no;Norwegian (Nynorsk)"
+HKCR,"MIME\Database\Rfc1766","0415",0x00000000,"pl;Polish"
+HKCR,"MIME\Database\Rfc1766","0416",0x00000000,"pt-br;Portuguese (Brazil)"
+HKCR,"MIME\Database\Rfc1766","0816",0x00000000,"pt;Portuguese (Portugal)"
+HKCR,"MIME\Database\Rfc1766","0417",0x00000000,"rm;Rhaeto-Romanic"
+HKCR,"MIME\Database\Rfc1766","0418",0x00000000,"ro;Romanian"
+HKCR,"MIME\Database\Rfc1766","0818",0x00000000,"ro-mo;Romanian (Moldova)"
+HKCR,"MIME\Database\Rfc1766","0419",0x00000000,"ru;Russian"
+HKCR,"MIME\Database\Rfc1766","0819",0x00000000,"ru-mo;Russian (Moldova)"
+HKCR,"MIME\Database\Rfc1766","0C1A",0x00000000,"sr;Serbian (Cyrillic)"
+HKCR,"MIME\Database\Rfc1766","081A",0x00000000,"sr;Serbian (Latin)"
+HKCR,"MIME\Database\Rfc1766","041B",0x00000000,"sk;Slovak"
+HKCR,"MIME\Database\Rfc1766","0424",0x00000000,"sl;Slovenian"
+HKCR,"MIME\Database\Rfc1766","042E",0x00000000,"sb;Sorbian"
+HKCR,"MIME\Database\Rfc1766","040A",0x00000000,"es;Spanish (Traditional Sort)"
+HKCR,"MIME\Database\Rfc1766","080A",0x00000000,"es-mx;Spanish (Mexico)"
+HKCR,"MIME\Database\Rfc1766","0C0A",0x00000000,"es;Spanish (International Sort)"
+HKCR,"MIME\Database\Rfc1766","100A",0x00000000,"es-gt;Spanish (Guatemala)"
+HKCR,"MIME\Database\Rfc1766","140A",0x00000000,"es-cr;Spanish (Costa Rica)"
+HKCR,"MIME\Database\Rfc1766","180A",0x00000000,"es-pa;Spanish (Panama)"
+HKCR,"MIME\Database\Rfc1766","1C0A",0x00000000,"es-do;Spanish (Dominican Republic)"
+HKCR,"MIME\Database\Rfc1766","200A",0x00000000,"es-ve;Spanish (Venezuela)"
+HKCR,"MIME\Database\Rfc1766","240A",0x00000000,"es-co;Spanish (Colombia)"
+HKCR,"MIME\Database\Rfc1766","280A",0x00000000,"es-pe;Spanish (Peru)"
+HKCR,"MIME\Database\Rfc1766","2C0A",0x00000000,"es-ar;Spanish (Argentina)"
+HKCR,"MIME\Database\Rfc1766","300A",0x00000000,"es-ec;Spanish (Ecuador)"
+HKCR,"MIME\Database\Rfc1766","340A",0x00000000,"es-cl;Spanish (Chile)"
+HKCR,"MIME\Database\Rfc1766","380A",0x00000000,"es-uy;Spanish (Uruguay)"
+HKCR,"MIME\Database\Rfc1766","3C0A",0x00000000,"es-py;Spanish (Paraguay)"
+HKCR,"MIME\Database\Rfc1766","400A",0x00000000,"es-bo;Spanish (Bolivia)"
+HKCR,"MIME\Database\Rfc1766","440A",0x00000000,"es-sv;Spanish (El Salvador)"
+HKCR,"MIME\Database\Rfc1766","480A",0x00000000,"es-hn;Spanish (Honduras)"
+HKCR,"MIME\Database\Rfc1766","4C0A",0x00000000,"es-ni;Spanish (Nicaragua)"
+HKCR,"MIME\Database\Rfc1766","500A",0x00000000,"es-pr;Spanish (Puerto Rico)"
+HKCR,"MIME\Database\Rfc1766","0430",0x00000000,"sx;Sutu"
+HKCR,"MIME\Database\Rfc1766","041D",0x00000000,"sv;Swedish"
+HKCR,"MIME\Database\Rfc1766","081D",0x00000000,"sv-fi;Swedish (Finland)"
+HKCR,"MIME\Database\Rfc1766","041E",0x00000000,"th;Thai"
+HKCR,"MIME\Database\Rfc1766","0431",0x00000000,"ts;Tsonga"
+HKCR,"MIME\Database\Rfc1766","0432",0x00000000,"tn;Tswana"
+HKCR,"MIME\Database\Rfc1766","041F",0x00000000,"tr;Turkish"
+HKCR,"MIME\Database\Rfc1766","0422",0x00000000,"uk;Ukrainian"
+HKCR,"MIME\Database\Rfc1766","0420",0x00000000,"ur;Urdu"
+HKCR,"MIME\Database\Rfc1766","042A",0x00000000,"vi;Vietnamese"
+HKCR,"MIME\Database\Rfc1766","0434",0x00000000,"xh;Xhosa"
+HKCR,"MIME\Database\Rfc1766","043D",0x00000000,"ji;Yiddish"
+HKCR,"MIME\Database\Rfc1766","0435",0x00000000,"zu;Zulu"
+
 ; EOF
index 86121fc..71a302b 100644 (file)
@@ -257,10 +257,10 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","Pagin
 ; Subsystems
 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Debug",0x00020000,""
 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Kmode",0x00020000,"%SystemRoot%\system32\win32k.sys"
-HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Optional",0x00070001,50,00,6f,00,73,00,69,00,78,00,00,00,4f,00,73,00,32,00,00,00,00,00
+HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Optional",0x00010000,"Posix","Os2"
 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Os2",0x00020000,"%SystemRoot%\system32\os2ss.exe"
 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Posix",0x00020000,"%SystemRoot%\system32\psxss.exe"
-HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Required",0x00070001,44,00,65,00,62,00,75,00,67,00,00,00,57,00,69,00,6e,00,64,00,6f,00,77,00,73,00,00,00,00,00
+HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Required",0x00010000,"Debug","Windows"
 HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems","Windows",0x00020000,"%SystemRoot%\system32\csrss.exe"
 
 ; 3Com 3c905 Driver
@@ -469,6 +469,19 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","ImagePath",0x00020000,"system
 HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Start",0x00010001,0x00000001
 HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Type",0x00010001,0x00000001
 
+; Serial port enumerator
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum","ErrorControl",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum","Group",0x00000000,"PNP Filter"
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum","ImagePath",0x00020000,"system32\drivers\serenum.sys"
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum","Start",0x00010001,0x00000003
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum","Type",0x00010001,0x00000001
+;hard coded values
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum\Enum","0",0x00000000,"ACPI\PNP0501"
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum\Enum","Count",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\serenum\Enum","NextInstance",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\1","UpperFilters",0x00010000,"serenum"
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\2","UpperFilters",0x00010000,"serenum"
+
 ; SB16 driver
 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","Group",0x00000000,"Base"
 HKLM,"SYSTEM\CurrentControlSet\Services\sndblst","ServiceType",0x00010001,0x00000001
@@ -676,6 +689,12 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Group",0x00000000,"Base"
 HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ImagePath",0x00020000,"system32\drivers\serial.sys"
 HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Start",0x00010001,0x00000001
 HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Type",0x00010001,0x00000001
+;hard coded values
+HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","0",0x00000000,"ACPI\PNP0501"
+HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","Count",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Services\Serial\Enum","NextInstance",0x00010001,0x00000001
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\1","Service",0x00000000,"serial"
+HKLM,"SYSTEM\CurrentControlSet\Enum\ACPI\PNP0501\2","Service",0x00000000,"serial"
 
 ; Packet driver
 HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001
index 761344d..1be85f5 100755 (executable)
Binary files a/reactos/bootdata/icon.ico and b/reactos/bootdata/icon.ico differ
index 2a3248c..5c5eb72 100755 (executable)
@@ -29,6 +29,7 @@ Signature = "$ReactOS$"
 drivers\bus\acpi\acpi.sys               2
 drivers\bus\isapnp\isapnp.sys           2
 drivers\bus\pci\pci.sys                 2
+drivers\bus\serenum\serenum.sys         2
 drivers\dd\beep\beep.sys                2
 drivers\dd\bootvid\bootvid.sys          2
 drivers\dd\null\null.sys                2
@@ -99,6 +100,7 @@ lib\mpr\mpr.dll                         1
 lib\msacm\msacm32.dll                   1
 lib\msafd\msafd.dll                     1
 lib\msgina\msgina.dll                   1
+lib\msi\msi.dll                         1
 lib\msimg32\msimg32.dll                 1
 lib\msvcrt\msvcrt.dll                   1
 lib\msvcrt20\msvcrt20.dll               1
@@ -108,10 +110,12 @@ lib\ole32\ole32.dll                     1
 lib\oleaut32\oleaut32.dll               1
 lib\olepro32\olepro32.dll               1
 lib\psapi\psapi.dll                     1
+lib\riched20\riched20.dll               1
 lib\richedit\riched32.dll               1
 lib\rpcrt4\rpcrt4.dll                   1
 lib\samlib\samlib.dll                   1
 lib\secur32\secur32.dll                 1
+lib\serialui\serialui.dll               1
 lib\setupapi\setupapi.dll               1
 lib\shdocvw\shdocvw.dll                 1
 lib\shell32\shell32.dll                 1
@@ -146,8 +150,9 @@ subsys\system\cmd\cmd.exe               1
 subsys\system\explorer\explorer.exe     4
 subsys\system\explorer\explorer-cfg-template.xml 4
 subsys\system\explorer\notifyhook\notifyhook.dll 1
-subsys\system\ibrowser\ibrowser.exe     1
 subsys\system\format\format.exe         1
+subsys\system\ibrowser\ibrowser.exe     1
+subsys\system\msiexec\msiexec.exe       1
 subsys\system\notepad\notepad.exe       1
 subsys\system\regedit\regedit.exe       4
 subsys\system\regsvr32\regsvr32.exe     1
index c2c3e38..10bf324 100644 (file)
@@ -26,52 +26,55 @@ This will allow you to use the WINE tools and librarys with very little
 work to import a new dll.
 
 The following build tools are derived from Wine.
+reactos/tools/unicode          # Synced to Wine-20050310
+reactos/tools/wpp              # Synced to Wine-20050310
 reactos/tools/bin2res          # Resource to binary converter
-reactos/tools/winebuild                # Synced to Wine-20050211
+reactos/tools/winebuild                # Synced to Wine-20050310
 reactos/tools/wmc              # Wine Message Compiler
-reactos/tools/wrc              # Synced to Wine-20050211
+reactos/tools/wrc              # Synced to Wine-20050310
+reactos/tools/widl             # Synced to Wine-20050310
 
 The following shared libraries are a 100% port from Winehq sources.
 
-reactos/lib/cabinet             # Synced to Wine-20050211
-reactos/lib/comctl32            # Synced to Wine-20050211
-reactos/lib/comdlg32           # Synced to Wine-20050211
-reactos/lib/dinput             # Synced to Wine-20050211
-reactos/lib/dinput8            # Synced to Wine-20050211
-reactos/lib/icmp               # Synced to Wine-20050211
+reactos/lib/cabinet             # Synced to Wine-20050310
+reactos/lib/comctl32            # Synced to Wine-20050310
+reactos/lib/comdlg32           # Synced to Wine-20050310
+reactos/lib/dinput             # Synced to Wine-20050310
+reactos/lib/dinput8            # Synced to Wine-20050310
+reactos/lib/icmp               # Synced to Wine-20050310
 reactos/lib/iphlpapi           # Out of sync
 reactos/lib/imagehlp           # Patches for BindImage need review and submission to winehq.
 reactos/lib/msvcrt20           # Out of sync
-reactos/lib/mpr                 # Synced to Wine-20050211
+reactos/lib/mpr                 # Synced to Wine-20050310
 reactos/lib/msacm              # Out of sync
-reactos/lib/msimg32            # Synced to Wine-20050211
-reactos/lib/msi                        # Synced to Wine-20050211
+reactos/lib/msimg32            # Synced to Wine-20050310
+reactos/lib/msi                        # Synced to Wine-20050310
 reactos/lib/msvideo            # Out of sync
 reactos/lib/netapi32           # Out of sync
 reactos/lib/odbc32             # In sync. Depends on port of Linux ODBC.
-reactos/lib/ole32               # Synced to Wine-20050211
-reactos/lib/oleaut32           # Synced to Wine-20050211
-reactos/lib/oledlg              # Synced to Wine-20050211
-reactos/lib/olepro32           # Synced to Wine-20050211
-reactos/lib/richedit           # Synced to Wine-20050211
-reactos/lib/rpcrt4             # Synced to Wine-20050211
-reactos/lib/setupapi           # Synced to Wine-20050125 # CVS
-reactos/lib/shell32             # Synced to Wine-20050211
-reactos/lib/shdocvw             # Synced to Wine-20050211
-reactos/lib/shlwapi             # Synced to Wine-20050211
+reactos/lib/ole32               # Synced to Wine-20050310
+reactos/lib/oleaut32           # Synced to Wine-20050310
+reactos/lib/oledlg              # Synced to Wine-20050310
+reactos/lib/olepro32           # Synced to Wine-20050310
+reactos/lib/riched20           # Synced to Wine-20050310
+reactos/lib/richedit           # Synced to Wine-20050310
+reactos/lib/rpcrt4             # Synced to Wine-20050310
+reactos/lib/setupapi           # Synced to Wine-20050310
+reactos/lib/shell32             # Synced to Wine-20050310
+reactos/lib/shdocvw             # Synced to Wine-20050310
+reactos/lib/shlwapi             # Synced to Wine-20050310
 reactos/lib/twain              # Out of sync
-reactos/lib/unicode            # Dependancy on this lib needs to be removed. Synced to Wine-20050211
-reactos/lib/urlmon             # Synced to Wine-20050211
+reactos/lib/urlmon             # Synced to Wine-20050310
 reactos/lib/version            # Out of sync
 reactos/lib/wininet            # Out of sync
-reactos/lib/winmm              # Synced to Wine-20050211
-reactos/lib/winmm/midimap       # Synced to Wine-20050211
-reactos/lib/winmm/wavemap       # Synced to Wine-20050211
+reactos/lib/winmm              # Synced to Wine-20050310
+reactos/lib/winmm/midimap       # Synced to Wine-20050310
+reactos/lib/winmm/wavemap       # Synced to Wine-20050310
 
 ReactOS shares the following programs with Winehq.
 reactos/subsys/system/regedit  # Out of sync
 reactos/subsys/system/expand   # Out of sync
-reactos/subsys/system/msiexec  # Synced to Wine-20050211
+reactos/subsys/system/msiexec  # Synced to Wine-20050311
 
 In addition the following libs, dlls and source files are mostly based on code ported
 from Winehq CVS. If you are looking to update something in these files
diff --git a/reactos/doc/irp cancel boilerplate.c b/reactos/doc/irp cancel boilerplate.c
new file mode 100644 (file)
index 0000000..d56d3bc
--- /dev/null
@@ -0,0 +1,103 @@
+\r
+\r
+/*\r
+Boiler plate for irp cancelation, for irp queues you manage yourself\r
+-Gunnar\r
+*/\r
+\r
+\r
+\r
+CancelRoutine(\r
+   DEV_OBJ Dev,\r
+   Irp\r
+   )\r
+{\r
+   //don't need this since we have our own sync. protecting irp cancellation\r
+   IoReleaseCancelSpinLock(Irp->CancelIrql); \r
\r
+   theLock = Irp->Tail.Overlay.DriverContext[3];\r
\r
+   Lock(theLock);   \r
+   RemoveEntryList(&Irp->Tail.Overlay.ListEntry);\r
+   Unlock(theLock);\r
\r
+   Irp->IoStatus.Status = STATUS_CANCELLED;\r
+   Irp->IoStatus.Information = 0;\r
\r
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
\r
+}\r
\r
\r
+QUEUE_BOLIERPLATE\r
+{\r
+   Lock(theLock);\r
\r
+   Irp->Tail.Overlay.DriverContext[3] = &theLock;\r
\r
+   IoSetCancelRoutine(Irp, CancelRoutine);\r
+   if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))\r
+   {              \r
+      /*\r
+      Irp has already been cancelled (before we got to queue it),\r
+      and we got to remove the cancel routine before the canceler could, \r
+      so we cancel/complete the irp ourself.\r
+      */\r
+      \r
+      Unlock(theLock);\r
\r
+      Irp->IoStatus.Status = STATUS_CANCELLED;\r
+      Irp->IoStatus.Information = 0;\r
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
\r
+      return FALSE;\r
+   }\r
\r
+   //else were ok   \r
\r
\r
+   Irp->IoStatus.Status = STATUS_PENDING;\r
+   IoMarkIrpPending(Irp);\r
\r
+   InsertTailList(Queue);\r
+   \r
+   Unlock(theLock);\r
\r
+}\r
\r
\r
+DEQUEUE_BOILERPLATE\r
+{\r
+   Lock(theLock);\r
\r
+   Irp = RemoveHeadList(Queue);\r
\r
+   if (!IoSetCancelRoutine(Irp, NULL))\r
+   {\r
+      /*\r
+      Cancel routine WILL be called after we release the spinlock. It will try to remove \r
+      the irp from the list and cancel/complete this irp. Since we allready removed it, \r
+      make its ListEntry point to itself.\r
+      */\r
\r
+      InitializeListHead(&Irp->Tail.Overlay.ListEntry);\r
+      \r
+      Unlock(theLock);\r
+      \r
+      return;\r
+   } \r
\r
\r
+   /*\r
+   Cancel routine will NOT be called, canceled or not.\r
+   The Irp might have been canceled (Irp->Cancel flag set) but we don't care,\r
+   since we are to complete this Irp now anyways.\r
+   */\r
\r
+   Unlock(theLock);\r
\r
+   Irp->IoStatus.Status = STATUS_SUCCESS;\r
+   Irp->IoStatus.Information = 0;\r
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
\r
+}\r
index 808ee46..d75290a 100644 (file)
@@ -6,7 +6,7 @@ PATH_TO_TOP = ../..
 
 include $(PATH_TO_TOP)/rules.mak
 
-DRIVERS = acpi isapnp pci
+DRIVERS = acpi isapnp pci serenum
 
 all: $(DRIVERS)
 
index 968510a..09224d6 100644 (file)
@@ -4,6 +4,7 @@
  * FILE:            acpi/ospm/fdo.c
  * PURPOSE:         ACPI device object dispatch routines
  * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *                  Hervé Poussineau (hpoussin@reactos.com)
  * UPDATE HISTORY:
  *      08-08-2001  CSH  Created
  */
@@ -60,12 +61,7 @@ AcpiCreateDeviceIDString(PUNICODE_STRING DeviceID,
            L"ACPI\\%S",
            Node->device.id.hid);
 
-  if (!AcpiCreateUnicodeString(DeviceID, Buffer, PagedPool))
-  {
-    return FALSE;
-  }
-
-  return TRUE;
+  return AcpiCreateUnicodeString(DeviceID, Buffer, PagedPool);
 }
 
 
@@ -108,8 +104,158 @@ BOOLEAN
 AcpiCreateInstanceIDString(PUNICODE_STRING InstanceID,
                            BM_NODE *Node)
 {
-  /* FIXME: Create unique instnce id. */
-  return AcpiCreateUnicodeString(InstanceID, L"0000", PagedPool);
+  WCHAR Buffer[10];
+
+  if (Node->device.id.uid[0])
+    swprintf(Buffer, L"%S", Node->device.id.uid);
+  else
+    /* FIXME: Generate unique id! */
+    swprintf(Buffer, L"0000");
+
+  return AcpiCreateUnicodeString(InstanceID, Buffer, PagedPool);
+}
+
+
+static BOOLEAN
+AcpiCreateResourceList(PCM_RESOURCE_LIST* pResourceList,
+                       PULONG ResourceListSize,
+                       RESOURCE* resources)
+{
+  BOOLEAN Done;
+  ULONG NumberOfResources = 0;
+  PCM_RESOURCE_LIST ResourceList;
+  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+  RESOURCE* resource;
+  ULONG i;
+  KIRQL Dirql;
+  
+  /* Count number of resources */
+  Done = FALSE;
+  resource = resources;
+  while (!Done)
+  {
+    switch (resource->id)
+    {
+      case irq:
+      {
+        IRQ_RESOURCE *irq_data = (IRQ_RESOURCE*) &resource->data;
+        NumberOfResources += irq_data->number_of_interrupts;
+        break;
+      }
+      case dma:
+      {
+        DMA_RESOURCE *dma_data = (DMA_RESOURCE*) &resource->data;
+        NumberOfResources += dma_data->number_of_channels;
+        break;
+      }
+      case io:
+      {
+        NumberOfResources++;
+        break;
+      }
+      case end_tag:
+      {
+        Done = TRUE;
+        break;
+      }
+    }
+    resource = (RESOURCE *) ((NATIVE_UINT) resource + (NATIVE_UINT) resource->length);
+  }
+  
+  /* Allocate memory */
+  *ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (NumberOfResources - 1);
+  ResourceList = (PCM_RESOURCE_LIST)ExAllocatePool(PagedPool, *ResourceListSize);
+  *pResourceList = ResourceList;
+  if (!ResourceList)
+    return FALSE;
+  ResourceList->Count = 1;
+  ResourceList->List[0].InterfaceType = Internal; /* FIXME */
+  ResourceList->List[0].BusNumber = 0; /* We're the only ACPI bus device in the system */
+  ResourceList->List[0].PartialResourceList.Version = 1;
+  ResourceList->List[0].PartialResourceList.Revision = 1;
+  ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
+  ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
+  
+  /* Fill resources list structure */
+  Done = FALSE;
+  resource = resources;
+  while (!Done)
+  {
+    switch (resource->id)
+    {
+      case irq:
+      {
+        IRQ_RESOURCE *irq_data = (IRQ_RESOURCE*) &resource->data;
+        for (i = 0; i < irq_data->number_of_interrupts; i++)
+        {
+          ResourceDescriptor->Type = CmResourceTypeInterrupt;
+          
+          ResourceDescriptor->ShareDisposition =
+            (irq_data->shared_exclusive == SHARED ? CmResourceShareShared : CmResourceShareDeviceExclusive);
+          ResourceDescriptor->Flags =
+            (irq_data->edge_level == LEVEL_SENSITIVE ? CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE : CM_RESOURCE_INTERRUPT_LATCHED);
+          ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
+            Internal, 0, 0, irq_data->interrupts[i],
+            &Dirql,
+            &ResourceDescriptor->u.Interrupt.Affinity);
+          ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
+          ResourceDescriptor++;
+        }
+        break;
+      }
+      case dma:
+      {
+        DMA_RESOURCE *dma_data = (DMA_RESOURCE*) &resource->data;
+        for (i = 0; i < dma_data->number_of_channels; i++)
+        {
+          ResourceDescriptor->Type = CmResourceTypeDma;
+          ResourceDescriptor->Flags = 0;
+          switch (dma_data->type)
+          {
+            case TYPE_A: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break;
+            case TYPE_B: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break;
+            case TYPE_F: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break;
+          }
+          if (dma_data->bus_master == BUS_MASTER)
+            ResourceDescriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER;
+          switch (dma_data->transfer)
+          {
+            case TRANSFER_8: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8; break;
+            case TRANSFER_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16; break;
+            case TRANSFER_8_16: ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break;
+          }
+          ResourceDescriptor->u.Dma.Channel = dma_data->channels[i];
+          ResourceDescriptor++;
+        }
+        break;
+      }
+      case io:
+      {
+        IO_RESOURCE *io_data = (IO_RESOURCE*) &resource->data;
+        ResourceDescriptor->Type = CmResourceTypePort;
+        ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
+        ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
+        if (io_data->io_decode == DECODE_16)
+          ResourceDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
+        else
+          ResourceDescriptor->Flags |= CM_RESOURCE_PORT_10_BIT_DECODE;
+        ResourceDescriptor->u.Port.Start.u.HighPart = 0;
+        ResourceDescriptor->u.Port.Start.u.LowPart = io_data->min_base_address;
+        ResourceDescriptor->u.Port.Length = io_data->range_length;
+        ResourceDescriptor++;
+        break;
+      }
+      case end_tag:
+      {
+        Done = TRUE;
+        break;
+      }
+    }
+    resource = (RESOURCE *) ((NATIVE_UINT) resource + (NATIVE_UINT) resource->length);
+  }
+  
+  acpi_rs_dump_resource_list(resource);
+  return TRUE;
 }
 
 
@@ -126,7 +272,7 @@ FdoQueryBusRelations(
   ANSI_STRING AnsiString;
   ACPI_STATUS AcpiStatus;
   PACPI_DEVICE Device;
-  NTSTATUS Status;
+  NTSTATUS Status = STATUS_SUCCESS;
   BM_NODE *Node;
   ULONG Size;
   ULONG i;
@@ -147,6 +293,7 @@ FdoQueryBusRelations(
   CurrentEntry = DeviceExtension->DeviceListHead.Flink;
   while (CurrentEntry != &DeviceExtension->DeviceListHead)
   {
+    ACPI_BUFFER Buffer;
     Device = CONTAINING_RECORD(CurrentEntry, ACPI_DEVICE, DeviceListEntry);
 
     /* FIXME: For ACPI namespace devices on the motherboard create filter DOs
@@ -198,6 +345,34 @@ FdoQueryBusRelations(
       AcpiStatus = bm_get_node(Device->BmHandle, 0, &Node);
       if (ACPI_SUCCESS(AcpiStatus))
       {
+        /* Get current resources */
+        Buffer.length = 0;
+        Status = acpi_get_current_resources(Node->device.acpi_handle, &Buffer);
+        if ((Status & ACPI_OK) == 0)
+        {
+          ASSERT(FALSE);
+        }
+        if (Buffer.length > 0)
+        {
+          Buffer.pointer = ExAllocatePool(PagedPool, Buffer.length);
+          if (!Buffer.pointer)
+          {
+            ASSERT(FALSE);
+          }
+          Status = acpi_get_current_resources(Node->device.acpi_handle, &Buffer);
+          if (ACPI_FAILURE(Status))
+          {
+            ASSERT(FALSE);
+          }
+          if (!AcpiCreateResourceList(&PdoDeviceExtension->ResourceList,
+                                      &PdoDeviceExtension->ResourceListSize,
+                                      (RESOURCE*)Buffer.pointer))
+          {
+            ASSERT(FALSE);
+          }
+          ExFreePool(Buffer.pointer);
+        }
+
         /* Add Device ID string */
         if (!AcpiCreateDeviceIDString(&PdoDeviceExtension->DeviceID,
                                       Node))
index e999d37..c7154cd 100644 (file)
@@ -47,6 +47,9 @@ typedef struct _PDO_DEVICE_EXTENSION
   UNICODE_STRING InstanceID;
   // Hardware IDs
   UNICODE_STRING HardwareIDs;
+  // Resource list
+  PCM_RESOURCE_LIST ResourceList;
+  ULONG ResourceListSize;
 } PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
 
 
index 741f071..ed11cd6 100644 (file)
@@ -601,5 +601,5 @@ acpi_os_writable(void *ptr, u32 len)
 u32
 acpi_os_get_thread_id (void)
 {
-  return (ULONG)PsGetCurrentThreadId();
+  return (ULONG)PsGetCurrentThreadId() + 1;
 }
index 342d084..cf8aa65 100644 (file)
@@ -107,6 +107,35 @@ PdoQueryId(
 }
 
 
+static NTSTATUS
+PdoQueryResources(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp,
+  PIO_STACK_LOCATION IrpSp)
+{
+  PPDO_DEVICE_EXTENSION DeviceExtension;
+  PCM_RESOURCE_LIST ResourceList;
+  
+  DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  
+  if (DeviceExtension->ResourceListSize == 0)
+  {
+    return Irp->IoStatus.Status;
+  }
+  
+  ResourceList = ExAllocatePool(PagedPool, DeviceExtension->ResourceListSize);
+  if (!ResourceList)
+  {
+    Irp->IoStatus.Information = 0;
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+  
+  RtlCopyMemory(ResourceList, DeviceExtension->ResourceList, DeviceExtension->ResourceListSize);
+  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+  return STATUS_SUCCESS;
+}
+
+
 static NTSTATUS
 PdoSetPower(
   IN PDEVICE_OBJECT DeviceObject,
@@ -201,6 +230,9 @@ PdoPnpControl(
     break;
 
   case IRP_MN_QUERY_RESOURCES:
+    Status = PdoQueryResources(DeviceObject,
+                               Irp,
+                               IrpSp);
     break;
 
   case IRP_MN_QUERY_STOP_DEVICE:
@@ -213,6 +245,7 @@ PdoPnpControl(
     break;
 
   case IRP_MN_START_DEVICE:
+    Status = STATUS_SUCCESS;
     break;
 
   case IRP_MN_STOP_DEVICE:
index 68dab85..ef38751 100644 (file)
@@ -503,7 +503,7 @@ acpi_tb_get_table_rsdt (
                REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n",
                                  table_signature));
 
-               return (status);
+               return (AE_NO_ACPI_TABLES);
        }
 
 
index 121bcda..c2d1237 100644 (file)
@@ -389,6 +389,7 @@ acpi_cm_init_globals (
                acpi_gbl_acpi_mutex_info[i].mutex   = NULL;
                acpi_gbl_acpi_mutex_info[i].locked  = FALSE;
                acpi_gbl_acpi_mutex_info[i].use_count = 0;
+               acpi_gbl_acpi_mutex_info[i].owner_id = 0;
        }
 
        /* Global notify handlers */
diff --git a/reactos/drivers/bus/serenum/detect.c b/reactos/drivers/bus/serenum/detect.c
new file mode 100644 (file)
index 0000000..4a7ca07
--- /dev/null
@@ -0,0 +1,541 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Serial enumerator driver
+ * FILE:            drivers/bus/serenum/detect.c
+ * PURPOSE:         Detection of serial devices
+ * 
+ * PROGRAMMERS:     Jason Filby (jasonfilby@yahoo.com)
+ *                  Filip Navara (xnavara@volny.cz)
+ *                  Hervé Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "serenum.h"
+
+static NTSTATUS
+SerenumDeviceIoControl(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN ULONG CtlCode,
+       IN PVOID InputBuffer OPTIONAL,
+       IN ULONG InputBufferSize,
+       IN OUT PVOID OutputBuffer OPTIONAL,
+       IN OUT PULONG OutputBufferSize)
+{
+       KEVENT Event;
+       PIRP Irp;
+       IO_STATUS_BLOCK IoStatus;
+       NTSTATUS Status;
+       
+       KeInitializeEvent (&Event, NotificationEvent, FALSE);
+       
+       Irp = IoBuildDeviceIoControlRequest(CtlCode,
+               DeviceObject,
+               InputBuffer,
+               InputBufferSize,
+               OutputBuffer,
+               (OutputBufferSize) ? *OutputBufferSize : 0,
+               FALSE,
+               &Event,
+               &IoStatus);
+       if (Irp == NULL)
+       {
+               DPRINT("Serenum: IoBuildDeviceIoControlRequest() failed\n");
+               return STATUS_INSUFFICIENT_RESOURCES;
+       }
+       
+       Status = IoCallDriver(DeviceObject, Irp);
+       
+       if (Status == STATUS_PENDING)
+       {
+               DPRINT("Serenum: Operation pending\n");
+               KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+               Status = IoStatus.Status;
+       }
+       
+       if (OutputBufferSize)
+       {
+               *OutputBufferSize = IoStatus.Information;
+       }
+       
+       return Status;
+}
+
+static NTSTATUS
+ReadBytes(
+       IN PDEVICE_OBJECT LowerDevice,
+       OUT PUCHAR Buffer,
+       IN ULONG BufferSize,
+       OUT PULONG FilledBytes)
+{
+       PIRP Irp;
+       IO_STATUS_BLOCK ioStatus;
+       KEVENT event;
+       NTSTATUS Status;
+       
+       KeInitializeEvent(&event, NotificationEvent, FALSE);
+       Irp = IoBuildSynchronousFsdRequest(
+               IRP_MJ_READ,
+               LowerDevice,
+               Buffer, BufferSize,
+               0,
+               &event,
+               &ioStatus);
+       if (!Irp)
+               return FALSE;
+       
+       Status = IoCallDriver(LowerDevice, Irp);
+       if (Status == STATUS_PENDING)
+       {
+               KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
+               Status = ioStatus.Status;
+       }
+       DPRINT("Serenum: bytes received: %lu/%lu\n",
+               ioStatus.Information, BufferSize);
+       *FilledBytes = ioStatus.Information;
+       return Status;
+}
+
+static NTSTATUS
+ReportDetectedDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PUNICODE_STRING DeviceDescription,
+       IN PUNICODE_STRING DeviceId,
+       IN PUNICODE_STRING HardwareIds,
+       IN PUNICODE_STRING CompatibleIds)
+{
+       PDEVICE_OBJECT Pdo = NULL;
+       PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
+       PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+       NTSTATUS Status;
+       
+       DPRINT("Serenum: SerenumReportDetectedDevice() called with %wZ (%wZ) detected\n", DeviceId, DeviceDescription);
+       
+       Status = IoCreateDevice(
+               DeviceObject->DriverObject,
+               sizeof(PDO_DEVICE_EXTENSION),
+               NULL,
+               FILE_DEVICE_CONTROLLER,
+               FILE_AUTOGENERATED_DEVICE_NAME,
+               FALSE,
+               &Pdo);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       
+       Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+       Pdo->Flags |= DO_POWER_PAGABLE;
+       PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
+       FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
+       PdoDeviceExtension->Common.IsFDO = FALSE;
+       Status = SerenumDuplicateUnicodeString(&PdoDeviceExtension->DeviceDescription, DeviceDescription, PagedPool);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       Status = SerenumDuplicateUnicodeString(&PdoDeviceExtension->DeviceId, DeviceId, PagedPool);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       Status = SerenumDuplicateUnicodeString(&PdoDeviceExtension->HardwareIds, HardwareIds, PagedPool);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       Status = SerenumDuplicateUnicodeString(&PdoDeviceExtension->CompatibleIds, CompatibleIds, PagedPool);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       
+       /* Device attached to serial port (Pdo) may delegate work to
+        * serial port stack (Fdo = DeviceObject variable) */
+       Pdo->StackSize = DeviceObject->StackSize + 1;
+       
+       FdoDeviceExtension->AttachedPdo = Pdo;
+       PdoDeviceExtension->AttachedFdo = DeviceObject;
+       
+       Pdo->Flags |= DO_BUFFERED_IO;
+       Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+       
+       return STATUS_SUCCESS;
+
+ByeBye:
+       if (Pdo)
+       {
+               if (PdoDeviceExtension->DeviceDescription.Buffer)
+                       RtlFreeUnicodeString(&PdoDeviceExtension->DeviceDescription);
+               if (PdoDeviceExtension->DeviceId.Buffer)
+                       RtlFreeUnicodeString(&PdoDeviceExtension->DeviceId);
+               if (PdoDeviceExtension->HardwareIds.Buffer)
+                       RtlFreeUnicodeString(&PdoDeviceExtension->HardwareIds);
+               if (PdoDeviceExtension->CompatibleIds.Buffer)
+                       RtlFreeUnicodeString(&PdoDeviceExtension->CompatibleIds);
+               IoDeleteDevice(Pdo);
+       }
+       return Status;
+}
+
+static BOOLEAN
+SerenumIsValidPnpIdString(
+       IN PUCHAR Buffer,
+       IN ULONG BufferLength)
+{
+       /* FIXME: SerenumIsValidPnpIdString not implemented */
+       DPRINT1("Serenum: SerenumIsValidPnpIdString() unimplemented\n");
+       return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+ReportDetectedPnpDevice(
+       IN PUCHAR Buffer,
+       IN ULONG BufferLength)
+{
+       ULONG i;
+       /* FIXME: ReportDetectedPnpDevice not implemented */
+       DPRINT1("Serenum: ReportDetectedPnpDevice() unimplemented\n");
+       DPRINT1("");
+       for (i = 0; i < BufferLength; i++)
+               DbgPrint("%c", Buffer[i]);
+       DbgPrint("\n");
+       /* Call ReportDetectedDevice */
+       return STATUS_SUCCESS;
+}
+
+#define BEGIN_ID '('
+#define END_ID ')'
+
+static NTSTATUS
+SerenumWait(ULONG milliseconds)
+{
+       KTIMER Timer;
+       LARGE_INTEGER DueTime;
+       
+       DueTime.QuadPart = -milliseconds * 10;
+       KeInitializeTimer(&Timer);
+       KeSetTimer(&Timer, DueTime, NULL);
+       return KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, NULL);
+}
+
+NTSTATUS
+SerenumDetectPnpDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PDEVICE_OBJECT LowerDevice)
+{
+       UCHAR Buffer[256];
+       ULONG BaudRate;
+       ULONG TotalBytesReceived = 0;
+       ULONG Size;
+       ULONG Msr, Purge;
+       ULONG i;
+       BOOLEAN BufferContainsBeginId, BufferContainsEndId;
+       SERIAL_LINE_CONTROL Lcr;
+       SERIAL_TIMEOUTS Timeouts;
+       SERIALPERF_STATS PerfStats;
+       NTSTATUS Status;
+       
+       /* 1. COM port initialization, check for device enumerate */
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       SerenumWait(200);
+       Size = sizeof(Msr);
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
+               NULL, 0, &Msr, &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       if ((Msr & SR_MSR_DSR) == 0) goto SerenumDisconnectIdle;
+       
+       /* 2. COM port setup, 1st phase */
+       CHECKPOINT;
+       BaudRate = SERIAL_BAUD_1200;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+               &BaudRate, sizeof(BaudRate), NULL, 0);
+       if (!NT_SUCCESS(Status)) return Status;
+       Lcr.WordLength = 7;
+       Lcr.Parity = NO_PARITY;
+       Lcr.StopBits = STOP_BIT_1;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+               &Lcr, sizeof(Lcr), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       SerenumWait(200);
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       SerenumWait(200);
+       
+       /* 3. Wait for response, 1st phase */
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Timeouts.ReadIntervalTimeout = 0;
+       Timeouts.ReadTotalTimeoutMultiplier = 0;
+       Timeouts.ReadTotalTimeoutConstant = 200;
+       Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
+               &Timeouts, sizeof(Timeouts), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer), &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       if (Size != 0) goto SerenumCollectPnpComDeviceId;
+       
+       /* 4. COM port setup, 2nd phase */
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Purge = SERIAL_PURGE_RXABORT | SERIAL_PURGE_RXCLEAR;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_PURGE,
+               &Purge, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       SerenumWait(200);
+       
+       /* 5. Wait for response, 2nd phase */
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = ReadBytes(LowerDevice, Buffer, 1, &TotalBytesReceived);
+       if (!NT_SUCCESS(Status)) return Status;
+       if (TotalBytesReceived != 0) goto SerenumCollectPnpComDeviceId;
+       Size = sizeof(Msr);
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
+               NULL, 0, &Msr, &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       if ((Msr & SR_MSR_DSR) == 0) goto SerenumVerifyDisconnect; else goto SerenumConnectIdle;
+       
+       /* 6. Collect PnP COM device ID */
+SerenumCollectPnpComDeviceId:
+       CHECKPOINT;
+       Timeouts.ReadIntervalTimeout = 200;
+       Timeouts.ReadTotalTimeoutMultiplier = 0;
+       Timeouts.ReadTotalTimeoutConstant = 2200;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
+               &Timeouts, sizeof(Timeouts), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = ReadBytes(LowerDevice, &Buffer[TotalBytesReceived], sizeof(Buffer) - TotalBytesReceived, &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       TotalBytesReceived += Size;
+       Size = sizeof(PerfStats);
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_STATS,
+               NULL, 0, &PerfStats, &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       if (PerfStats.FrameErrorCount + PerfStats.ParityErrorCount != 0) goto SerenumConnectIdle;
+       BufferContainsBeginId = BufferContainsEndId = FALSE;
+       for (i = 0; i < TotalBytesReceived; i++)
+       {
+               if (Buffer[i] == BEGIN_ID) BufferContainsBeginId = TRUE;
+               if (Buffer[i] == END_ID) BufferContainsEndId = TRUE;
+       }
+       if (TotalBytesReceived == 1 || BufferContainsEndId)
+       {
+               if (SerenumIsValidPnpIdString(Buffer, TotalBytesReceived))
+                       return ReportDetectedPnpDevice(Buffer, TotalBytesReceived);
+               goto SerenumConnectIdle;
+       }
+       if (!BufferContainsBeginId) goto SerenumConnectIdle;
+       if (!BufferContainsEndId) goto SerenumConnectIdle;
+       Size = sizeof(Msr);
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
+               NULL, 0, &Msr, &Size);
+       if (!NT_SUCCESS(Status)) return Status;
+       if ((Msr & SR_MSR_DSR) == 0) goto SerenumVerifyDisconnect;
+       
+       /* 7. Verify disconnect */
+SerenumVerifyDisconnect:
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       SerenumWait(5000);
+       goto SerenumDisconnectIdle;
+       
+       /* 8. Connect idle */
+SerenumConnectIdle:
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       BaudRate = SERIAL_BAUD_300;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+               &BaudRate, sizeof(BaudRate), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Lcr.WordLength = 7;
+       Lcr.Parity = NO_PARITY;
+       Lcr.StopBits = STOP_BIT_1;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+               &Lcr, sizeof(Lcr), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       if (TotalBytesReceived == 0)
+               return STATUS_DEVICE_NOT_CONNECTED;
+       else
+               return STATUS_SUCCESS;
+       
+       /* 9. Disconnect idle */
+SerenumDisconnectIdle:
+       CHECKPOINT;
+       /* FIXME: report to OS device removal, if it was present */
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       BaudRate = SERIAL_BAUD_300;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+               &BaudRate, sizeof(BaudRate), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Lcr.WordLength = 7;
+       Lcr.Parity = NO_PARITY;
+       Lcr.StopBits = STOP_BIT_1;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+               &Lcr, sizeof(Lcr), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       return STATUS_DEVICE_NOT_CONNECTED;
+}
+
+NTSTATUS
+SerenumDetectLegacyDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PDEVICE_OBJECT LowerDevice)
+{
+       ULONG Fcr, Mcr;
+       ULONG BaudRate;
+       ULONG Command;
+       SERIAL_TIMEOUTS Timeouts;
+       SERIAL_LINE_CONTROL LCR;
+       ULONG i, Count;
+       UCHAR Buffer[16];
+       UNICODE_STRING DeviceDescription;
+       UNICODE_STRING DeviceId;
+       UNICODE_STRING HardwareIds;
+       UNICODE_STRING CompatibleIds;
+       NTSTATUS Status;
+       
+       RtlZeroMemory(Buffer, sizeof(Buffer));
+       
+       /* Reset UART */
+       CHECKPOINT;
+       Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
+               &Mcr, sizeof(Mcr), NULL, NULL); 
+       if (!NT_SUCCESS(Status)) return Status;
+       
+       /* Set communications parameters */
+       CHECKPOINT;
+       /* DLAB off */
+       Fcr = 0;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
+               &Fcr, sizeof(Fcr), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       /* Set serial port speed */
+       BaudRate = SERIAL_BAUD_1200;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
+               &BaudRate, sizeof(BaudRate), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       /* Set LCR */
+       LCR.WordLength = 7;
+       LCR.Parity = NO_PARITY;
+       LCR.StopBits = STOP_BITS_2;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
+               &LCR, sizeof(LCR), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       
+       /* Flush receive buffer */
+       CHECKPOINT;
+       Command = SERIAL_PURGE_RXCLEAR;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
+               &Command, sizeof(Command), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       /* Wait 100 ms */
+       SerenumWait(100);
+       
+       /* Enable DTR/RTS */
+       CHECKPOINT;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
+               NULL, 0, NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       
+       /* Set timeout to 500 microseconds */
+       CHECKPOINT;
+       Timeouts.ReadIntervalTimeout = 100;
+       Timeouts.ReadTotalTimeoutMultiplier = 0;
+       Timeouts.ReadTotalTimeoutConstant = 500;
+       Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
+       Status = SerenumDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
+               &Timeouts, sizeof(Timeouts), NULL, NULL);
+       if (!NT_SUCCESS(Status)) return Status;
+       
+       /* Fill the read buffer */
+       CHECKPOINT;
+       Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), &Count);
+       if (!NT_SUCCESS(Status)) return Status;
+       
+       for (i = 0; i < Count; i++)
+       {
+               if (Buffer[i] == 'B')
+               {
+                       /* Sign for Microsoft Ballpoint */
+                       /* Hardware id: *PNP0F09
+                        * Compatible id: *PNP0F0F, SERIAL_MOUSE
+                        */
+                       RtlInitUnicodeString(&DeviceDescription, L"Microsoft Ballpoint device");
+                       RtlInitUnicodeString(&DeviceId, L"*PNP0F09");
+                       SerenumInitMultiSzString(&HardwareIds, "*PNP0F09", NULL);
+                       SerenumInitMultiSzString(&CompatibleIds, "*PNP0F0F", "SERIAL_MOUSE", NULL);
+                       Status = ReportDetectedDevice(DeviceObject,
+                               &DeviceDescription, &DeviceId, &HardwareIds, &CompatibleIds);
+                       RtlFreeUnicodeString(&HardwareIds);
+                       RtlFreeUnicodeString(&CompatibleIds);
+                       return Status;
+               }
+               else if (Buffer[i] == 'M')
+               {
+                       /* Sign for Microsoft Mouse protocol followed by button specifier */
+                       if (i == sizeof(Buffer) - 1)
+                       {
+                               /* Overflow Error */
+                               return STATUS_DEVICE_NOT_CONNECTED;
+                       }
+                       switch (Buffer[i + 1])
+                       {
+                               case '3':
+                                       /* Hardware id: *PNP0F08
+                                        * Compatible id: SERIAL_MOUSE
+                                        */
+                                       RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 3-buttons");
+                                       RtlInitUnicodeString(&DeviceId, L"*PNP0F08");
+                                       SerenumInitMultiSzString(&HardwareIds, "*PNP0F08", NULL);
+                                       SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
+                               default:
+                                       /* Hardware id: *PNP0F01
+                                        * Compatible id: SERIAL_MOUSE
+                                        */
+                                       RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 2-buttons or Microsoft Wheel Mouse");
+                                       RtlInitUnicodeString(&DeviceId, L"*PNP0F01");
+                                       SerenumInitMultiSzString(&HardwareIds, "*PNP0F01", NULL);
+                                       SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
+                       }
+                       Status = ReportDetectedDevice(DeviceObject,
+                               &DeviceDescription, &DeviceId, &HardwareIds, &CompatibleIds);
+                       RtlFreeUnicodeString(&HardwareIds);
+                       RtlFreeUnicodeString(&CompatibleIds);
+                       return Status;
+               }
+       }
+
+       return STATUS_DEVICE_NOT_CONNECTED;
+}
diff --git a/reactos/drivers/bus/serenum/fdo.c b/reactos/drivers/bus/serenum/fdo.c
new file mode 100644 (file)
index 0000000..fbad393
--- /dev/null
@@ -0,0 +1,213 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Serial enumerator driver
+ * FILE:            drivers/bus/serenum/fdo.c
+ * PURPOSE:         IRP_MJ_PNP operations for FDOs
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "serenum.h"
+
+NTSTATUS STDCALL
+SerenumAddDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo)
+{
+       PDEVICE_OBJECT Fdo;
+       PFDO_DEVICE_EXTENSION DeviceExtension;
+       //UNICODE_STRING SymbolicLinkName;
+       NTSTATUS Status;
+
+       DPRINT("Serenum: SerenumAddDevice called. Pdo = %p\n", Pdo);
+   
+       /* Create new device object */
+       Status = IoCreateDevice(DriverObject,
+                               sizeof(FDO_DEVICE_EXTENSION),
+                               NULL,
+                               FILE_DEVICE_BUS_EXTENDER,
+                               FILE_DEVICE_SECURE_OPEN,
+                               FALSE,
+                               &Fdo);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serenum: IoCreateDevice() failed with status 0x%08lx\n", Status);
+               return Status;
+       }
+       
+       /* Register device interface */
+#if 0 /* FIXME: activate */
+       Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, NULL, &SymbolicLinkName);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serenum: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
+               goto ByeBye;
+       }
+       DPRINT1("Serenum: IoRegisterDeviceInterface() returned '%wZ'\n", &SymbolicLinkName);
+       Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serenum: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
+               goto ByeBye;
+       }
+       RtlFreeUnicodeString(&SymbolicLinkName);
+#endif
+       
+       DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
+       RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
+       DeviceExtension->Common.IsFDO = TRUE;
+       DeviceExtension->Common.PnpState = dsStopped;
+       DeviceExtension->Pdo = Pdo;
+       IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERENUM_TAG, 0, 0);
+       Fdo->Flags |= DO_POWER_PAGABLE;
+       Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serenum: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+               IoDeleteDevice(Fdo);
+               return Status;
+       }
+       Fdo->Flags |= DO_BUFFERED_IO;
+       Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+       
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+SerenumFdoStartDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PCOMMON_DEVICE_EXTENSION DeviceExtension;
+       
+       DPRINT("Serenum: SerenumFdoStartDevice() called\n");
+       DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       
+       ASSERT(DeviceExtension->PnpState == dsStopped);
+       DeviceExtension->PnpState = dsStarted;
+       
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+SerenumFdoQueryBusRelations(
+       IN PDEVICE_OBJECT DeviceObject,
+       OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+       PFDO_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_RELATIONS DeviceRelations;
+       ULONG NumPDO;
+       ULONG i;
+       NTSTATUS Status = STATUS_SUCCESS;
+       
+       DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ASSERT(DeviceExtension->Common.IsFDO);
+       
+       /* Do enumeration if needed */
+       if (!(DeviceExtension->Flags & FLAG_ENUMERATION_DONE))
+       {
+               ASSERT(DeviceExtension->AttachedPdo == NULL);
+               /* Detect plug-and-play devices */
+               Status = SerenumDetectPnpDevice(DeviceObject, DeviceExtension->LowerDevice);
+               if (Status == STATUS_DEVICE_NOT_CONNECTED)
+               {
+                       /* Detect legacy devices */
+                       Status = SerenumDetectLegacyDevice(DeviceObject, DeviceExtension->LowerDevice);
+                       if (Status == STATUS_DEVICE_NOT_CONNECTED)
+                               Status = STATUS_SUCCESS;
+               }
+               DeviceExtension->Flags |= FLAG_ENUMERATION_DONE;
+       }
+       NumPDO = (DeviceExtension->AttachedPdo != NULL ? 1 : 0);
+       
+       DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(
+               PagedPool,
+               sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (NumPDO - 1),
+               SERENUM_TAG);
+       if (!DeviceRelations)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       
+       /* Fill returned structure */
+       DeviceRelations->Count = NumPDO;
+       for (i = 0; i < NumPDO; i++)
+       {
+               ObReferenceObject(DeviceExtension->AttachedPdo);
+               DeviceRelations->Objects[i] = DeviceExtension->AttachedPdo;
+       }
+       
+       *pDeviceRelations = DeviceRelations;
+       return Status;
+}
+
+NTSTATUS
+SerenumFdoPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       ULONG MinorFunction;
+       PIO_STACK_LOCATION Stack;
+       ULONG_PTR Information = 0;
+       NTSTATUS Status;
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       MinorFunction = Stack->MinorFunction;
+       
+       switch (MinorFunction)
+       {
+               /* FIXME: do all these minor functions
+               IRP_MN_QUERY_REMOVE_DEVICE 0x1
+               IRP_MN_REMOVE_DEVICE 0x2
+               IRP_MN_CANCEL_REMOVE_DEVICE 0x3
+               IRP_MN_STOP_DEVICE 0x4
+               IRP_MN_QUERY_STOP_DEVICE 0x5
+               IRP_MN_CANCEL_STOP_DEVICE 0x6
+               IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
+               IRP_MN_QUERY_INTERFACE (optional) 0x8
+               IRP_MN_QUERY_CAPABILITIES (optional) 0x9
+               IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional or required) 0xb
+               IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
+               IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
+               IRP_MN_SURPRISE_REMOVAL 0x17
+               */
+               case IRP_MN_START_DEVICE: /* 0x0 */
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+                       /* Call lower driver */
+                       Status = ForwardIrpAndWait(DeviceObject, Irp);
+                       if (NT_SUCCESS(Status))
+                               Status = SerenumFdoStartDevice(DeviceObject, Irp);
+                       break;
+               }
+               case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x7 */
+               {
+                       switch (Stack->Parameters.QueryDeviceRelations.Type)
+                       {
+                               case BusRelations:
+                               {
+                                       PDEVICE_RELATIONS DeviceRelations;
+                                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
+                                       Status = SerenumFdoQueryBusRelations(DeviceObject, &DeviceRelations);
+                                       Information = (ULONG_PTR)DeviceRelations;
+                                       break;
+                               }
+                               default:
+                                       DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", 
+                                               Stack->Parameters.QueryDeviceRelations.Type);
+                                       return ForwardIrpAndForget(DeviceObject, Irp);
+                       }
+                       break;
+               }
+               default:
+               {
+                       DPRINT1("Serenum: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+                       return ForwardIrpAndForget(DeviceObject, Irp);
+               }
+       }
+       
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/bus/serenum/makefile b/reactos/drivers/bus/serenum/makefile
new file mode 100644 (file)
index 0000000..8c3c924
--- /dev/null
@@ -0,0 +1,20 @@
+# $Id: makefile 12852 2005-01-06 13:58:04Z mf $
+
+PATH_TO_TOP = ../../..
+
+TARGET_TYPE = driver
+
+TARGET_NAME = serenum
+
+TARGET_CFLAGS = -Wall -Werror -D__USE_W32API
+
+TARGET_OBJECTS = \
+       detect.o      \
+       fdo.o         \
+       misc.o        \
+       pdo.o         \
+       serenum.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
diff --git a/reactos/drivers/bus/serenum/misc.c b/reactos/drivers/bus/serenum/misc.c
new file mode 100644 (file)
index 0000000..94eb393
--- /dev/null
@@ -0,0 +1,201 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Serial enumerator driver
+ * FILE:            drivers/dd/serenum/misc.c
+ * PURPOSE:         Misceallenous operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "serenum.h"
+#include <stdarg.h>
+
+NTSTATUS
+SerenumDuplicateUnicodeString(
+  OUT PUNICODE_STRING Destination,
+  IN PUNICODE_STRING Source,
+  IN POOL_TYPE PoolType)
+{
+       if (Source == NULL)
+       {
+               RtlInitUnicodeString(Destination, NULL);
+               return STATUS_SUCCESS;
+       }
+       
+       Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
+       if (Destination->Buffer == NULL)
+       {
+               return STATUS_INSUFFICIENT_RESOURCES;
+       }
+       
+       Destination->MaximumLength = Source->MaximumLength;
+       Destination->Length = Source->Length;
+       RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
+       
+       return STATUS_SUCCESS;
+}
+
+/* I really want ANSI strings as last arguments because
+ * PnP ids are ANSI-encoded in PnP device string
+ * identification */
+NTSTATUS
+SerenumInitMultiSzString(
+       OUT PUNICODE_STRING Destination,
+       ... /* list of PCSZ */)
+{
+       va_list args;
+       PCSZ Source;
+       ANSI_STRING AnsiString;
+       UNICODE_STRING UnicodeString;
+       ULONG DestinationSize = 0;
+       NTSTATUS Status = STATUS_SUCCESS;
+       
+       /* Calculate length needed for destination unicode string */
+       va_start(args, Destination);
+       Source = va_arg(args, PCSZ);
+       while (Source != NULL)
+       {
+               RtlInitAnsiString(&AnsiString, Source);
+               DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
+                       + sizeof(WCHAR) /* final NULL */;
+               Source = va_arg(args, PCSZ);
+       }
+       va_end(args);
+       if (DestinationSize == 0)
+       {
+               RtlInitUnicodeString(Destination, NULL);
+               return STATUS_SUCCESS;
+       }
+       
+       /* Initialize destination string */
+       DestinationSize += sizeof(WCHAR); // final NULL
+       Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, SERENUM_TAG);
+       if (!Destination->Buffer)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       Destination->Length = 0;
+       Destination->MaximumLength = (USHORT)DestinationSize;
+       
+       /* Copy arguments to destination string */
+       /* Use a temporary unicode string, which buffer is shared with
+        * destination string, to copy arguments */
+       UnicodeString.Length = Destination->Length;
+       UnicodeString.MaximumLength = Destination->MaximumLength;
+       UnicodeString.Buffer = Destination->Buffer;
+       va_start(args, Destination);
+       Source = va_arg(args, PCSZ);
+       while (Source != NULL)
+       {
+               RtlInitAnsiString(&AnsiString, Source);
+               Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
+               if (!NT_SUCCESS(Status))
+               {
+                       ExFreePoolWithTag(Destination->Buffer, SERENUM_TAG);
+                       break;
+               }
+               Destination->Length += UnicodeString.Length + sizeof(WCHAR);
+               UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR);
+               UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1;
+               UnicodeString.Length = 0;
+               Source = va_arg(args, PCSZ);
+       }
+       va_end(args);
+       if (NT_SUCCESS(Status))
+       {
+               /* Finish multi-sz string */
+               Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0';
+               Destination->Length += sizeof(WCHAR);
+       }
+       return Status;
+}
+
+NTSTATUS STDCALL
+ForwardIrpAndWaitCompletion(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       IN PVOID Context)
+{
+       if (Irp->PendingReturned)
+               KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+       return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+ForwardIrpAndWait(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PDEVICE_OBJECT LowerDevice;
+       KEVENT Event;
+       NTSTATUS Status;
+       
+       ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
+       LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+       
+       KeInitializeEvent(&Event, NotificationEvent, FALSE);
+       IoCopyCurrentIrpStackLocationToNext(Irp);
+       
+       DPRINT("Serenum: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
+       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;
+}
+
+NTSTATUS STDCALL
+ForwardIrpToLowerDeviceAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PFDO_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_OBJECT LowerDevice;
+       
+       DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ASSERT(DeviceExtension->Common.IsFDO);
+       
+       LowerDevice = DeviceExtension->LowerDevice;
+       DPRINT("Serenum: calling lower device 0x%p [%wZ]\n",
+               LowerDevice, &LowerDevice->DriverObject->DriverName);
+       IoSkipCurrentIrpStackLocation(Irp);
+       return IoCallDriver(LowerDevice, Irp);
+}
+
+NTSTATUS STDCALL
+ForwardIrpToAttachedFdoAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PPDO_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_OBJECT Fdo;
+       
+       DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ASSERT(!DeviceExtension->Common.IsFDO);
+       
+       Fdo = DeviceExtension->AttachedFdo;
+       DPRINT("Serenum: calling attached Fdo 0x%p [%wZ]\n",
+               Fdo, &Fdo->DriverObject->DriverName);
+       IoSkipCurrentIrpStackLocation(Irp);
+       return IoCallDriver(Fdo, Irp);
+}
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PDEVICE_OBJECT LowerDevice;
+       
+       ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
+       LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+       
+       IoSkipCurrentIrpStackLocation(Irp);
+       return IoCallDriver(LowerDevice, Irp);
+}
diff --git a/reactos/drivers/bus/serenum/pdo.c b/reactos/drivers/bus/serenum/pdo.c
new file mode 100644 (file)
index 0000000..54ade59
--- /dev/null
@@ -0,0 +1,313 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Serial enumerator driver
+ * FILE:            drivers/bus/serenum/pdo.c
+ * PURPOSE:         IRP_MJ_PNP operations for PDOs
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.com)
+ */
+
+#define NDEBUG
+#include "serenum.h"
+
+static NTSTATUS
+SerenumPdoStartDevice(
+       IN PDEVICE_OBJECT DeviceObject)
+{
+       PPDO_DEVICE_EXTENSION DeviceExtension;
+       
+       DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       
+       ASSERT(DeviceExtension->Common.PnpState == dsStopped);
+       
+       DeviceExtension->Common.PnpState = dsStarted;
+       return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+SerenumPdoQueryId(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       OUT ULONG_PTR* Information)
+{
+       PPDO_DEVICE_EXTENSION DeviceExtension;
+       ULONG IdType;
+       PUNICODE_STRING SourceString;
+       UNICODE_STRING String;
+       NTSTATUS Status;
+       
+       IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+       DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       RtlInitUnicodeString(&String, NULL);
+       
+       switch (IdType)
+       {
+               case BusQueryDeviceID:
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+                       SourceString = &DeviceExtension->DeviceId;
+                       break;
+               }
+               case BusQueryHardwareIDs:
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+                       SourceString = &DeviceExtension->HardwareIds;
+                       break;
+               }
+               case BusQueryCompatibleIDs:
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+                       SourceString = &DeviceExtension->CompatibleIds;
+                       break;
+               case BusQueryInstanceID:
+               {
+                       /* We don't have any instance id to report, and
+                        * this query is optional, so ignore it.
+                        */
+                       *Information = Irp->IoStatus.Information;
+                       return Irp->IoStatus.Status;
+               }
+               default:
+                       DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
+                       return STATUS_NOT_SUPPORTED;
+       }
+       
+       Status = SerenumDuplicateUnicodeString(
+               &String,
+               SourceString,
+               PagedPool);
+       *Information = (ULONG_PTR)String.Buffer;
+       return Status;
+}
+
+static NTSTATUS
+SerenumPdoQueryDeviceRelations(
+       IN PDEVICE_OBJECT DeviceObject,
+       OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+       PFDO_DEVICE_EXTENSION DeviceExtension;
+       PDEVICE_RELATIONS DeviceRelations;
+       
+       DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ASSERT(DeviceExtension->Common.IsFDO);
+       
+       DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(
+               PagedPool,
+               sizeof(DEVICE_RELATIONS),
+               SERENUM_TAG);
+       if (!DeviceRelations)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       
+       ObReferenceObject(DeviceObject);
+       DeviceRelations->Objects[0] = DeviceObject;
+       
+       *pDeviceRelations = DeviceRelations;
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+SerenumPdoPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       ULONG MinorFunction;
+       PIO_STACK_LOCATION Stack;
+       ULONG_PTR Information = 0;
+       NTSTATUS Status;
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       MinorFunction = Stack->MinorFunction;
+       
+       switch (MinorFunction)
+       {
+               /* FIXME: do all these minor functions
+               IRP_MN_QUERY_REMOVE_DEVICE 0x1
+               IRP_MN_REMOVE_DEVICE 0x2
+               IRP_MN_CANCEL_REMOVE_DEVICE 0x3
+               IRP_MN_STOP_DEVICE 0x4
+               IRP_MN_QUERY_STOP_DEVICE 0x5
+               IRP_MN_CANCEL_STOP_DEVICE 0x6
+               IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations (optional) 0x7
+               IRP_MN_QUERY_INTERFACE (required or optional) 0x8
+               IRP_MN_READ_CONFIG (required or optional) 0xf
+               IRP_MN_WRITE_CONFIG (required or optional) 0x10
+               IRP_MN_EJECT (required or optional) 0x11
+               IRP_MN_SET_LOCK (required or optional) 0x12
+               IRP_MN_QUERY_ID / BusQueryDeviceID 0x13
+               IRP_MN_QUERY_ID / BusQueryCompatibleIDs (optional) 0x13
+               IRP_MN_QUERY_ID / BusQueryInstanceID (optional) 0x13
+               IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
+               IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
+               IRP_MN_SURPRISE_REMOVAL 0x17
+               */
+               case IRP_MN_START_DEVICE: /* 0x0 */
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+                       Status = SerenumPdoStartDevice(DeviceObject);
+                       break;
+               }
+               case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x7 */
+               {
+                       switch (Stack->Parameters.QueryDeviceRelations.Type)
+                       {
+                               case  RemovalRelations:
+                               {
+                                       return ForwardIrpToAttachedFdoAndForget(DeviceObject, Irp);
+                               }
+                               case TargetDeviceRelation:
+                               {
+                                       PDEVICE_RELATIONS DeviceRelations;
+                                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
+                                       Status = SerenumPdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
+                                       Information = (ULONG_PTR)DeviceRelations;
+                                       break;
+                               }
+                               default:
+                               {
+                                       DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", 
+                                               Stack->Parameters.QueryDeviceRelations.Type);
+                                       Status = STATUS_NOT_IMPLEMENTED;
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case IRP_MN_QUERY_CAPABILITIES: /* 0x9 */
+               {
+                       PDEVICE_CAPABILITIES DeviceCapabilities;
+                       ULONG i;
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
+                       
+                       DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
+                       /* FIXME: capabilities can change with connected device */
+                       DeviceCapabilities->LockSupported = FALSE;
+                       DeviceCapabilities->EjectSupported = FALSE;
+                       DeviceCapabilities->Removable = TRUE;
+                       DeviceCapabilities->DockDevice = FALSE;
+                       DeviceCapabilities->UniqueID = FALSE;
+                       DeviceCapabilities->SilentInstall = FALSE;
+                       DeviceCapabilities->RawDeviceOK = TRUE;
+                       DeviceCapabilities->SurpriseRemovalOK = TRUE;
+                       DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
+                       //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
+                       DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
+                       for (i = 0; i < PowerSystemMaximum; i++)
+                               DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
+                       //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
+                       DeviceCapabilities->D1Latency = 0; /* FIXME */
+                       DeviceCapabilities->D2Latency = 0; /* FIXME */
+                       DeviceCapabilities->D3Latency = 0; /* FIXME */
+                       Status = STATUS_SUCCESS;
+                       break;
+               }
+               case IRP_MN_QUERY_RESOURCES: /* 0xa */
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
+                       /* Serial devices don't need resources, except the ones of
+                        * the serial port. This PDO is the serial device PDO, so
+                        * report no resource by not changing Information and
+                        * Status
+                        */
+                       Information = Irp->IoStatus.Information;
+                       Status = Irp->IoStatus.Status;
+                       break;
+               }
+               case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0xb */
+               {
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+                       /* Serial devices don't need resources, except the ones of
+                        * the serial port. This PDO is the serial device PDO, so
+                        * report no resource by not changing Information and
+                        * Status
+                        */
+                       Information = Irp->IoStatus.Information;
+                       Status = Irp->IoStatus.Status;
+                       break;
+               }
+               case IRP_MN_QUERY_DEVICE_TEXT: /* 0xc */
+               {
+                       switch (Stack->Parameters.QueryDeviceText.DeviceTextType)
+                       {
+                               case DeviceTextDescription:
+                               {
+                                       PUNICODE_STRING Source;
+                                       PWSTR Description;
+                                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
+                                       
+                                       Source = &((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->DeviceDescription;
+                                       Description = ExAllocatePool(PagedPool, Source->Length + sizeof(WCHAR));
+                                       if (!Description)
+                                               Status = STATUS_INSUFFICIENT_RESOURCES;
+                                       else
+                                       {
+                                               RtlCopyMemory(Description, Source->Buffer, Source->Length);
+                                               Description[Source->Length / sizeof(WCHAR)] = L'\0';
+                                               Information = (ULONG_PTR)Description;
+                                               Status = STATUS_SUCCESS;
+                                       }
+                                       break;
+                               }
+                               case DeviceTextLocationInformation:
+                               {
+                                       /* We don't have any text location to report,
+                                        * and this query is optional, so ignore it.
+                                        */
+                                       Information = Irp->IoStatus.Information;
+                                       Status = Irp->IoStatus.Status;
+                                       break;
+                               }
+                               default:
+                               {
+                                       DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
+                                               Stack->Parameters.QueryDeviceText.DeviceTextType);
+                                       Status = STATUS_NOT_SUPPORTED;
+                               }
+                       }
+                       break;
+               }
+               case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0xd */
+               {
+                       return ForwardIrpToAttachedFdoAndForget(DeviceObject, Irp);
+               }
+               case IRP_MN_QUERY_ID: /* 0x13 */
+               {
+                       Status = SerenumPdoQueryId(DeviceObject, Irp, &Information);
+                       break;
+               }
+               case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
+               {
+                       PPNP_BUS_INFORMATION BusInfo;
+                       DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
+                       
+                       BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
+                       if (!BusInfo)
+                               Status = STATUS_INSUFFICIENT_RESOURCES;
+                       else
+                       {
+                               BusInfo->BusTypeGuid = GUID_BUS_TYPE_SERENUM;
+                               /* FIXME: real value should be PNPBus, but PNPBus seems to be
+                                * the only value in INTERFACE_TYPE enum that doesn't work...
+                                */
+                               BusInfo->LegacyBusType = PNPISABus;
+                               /* We're the only serial bus enumerator on the computer */
+                               BusInfo->BusNumber = 0;
+                               Information = (ULONG_PTR)BusInfo;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               default:
+               {
+                       /* We can't forward request to the lower driver, because
+                        * we are a Pdo, so we don't have lower driver... */
+                       DPRINT1("Serenum: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+                       Information = Irp->IoStatus.Information;
+                       Status = Irp->IoStatus.Status;
+               }
+       }
+       
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/bus/serenum/serenum.c b/reactos/drivers/bus/serenum/serenum.c
new file mode 100644 (file)
index 0000000..ead4e82
--- /dev/null
@@ -0,0 +1,114 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Serial enumerator driver
+ * FILE:            drivers/bus/serenum/serenum.c
+ * PURPOSE:         Serial enumeration driver entry point
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.com)
+ */
+
+//#define NDEBUG
+#define INITGUID
+#include "serenum.h"
+
+NTSTATUS STDCALL
+SerenumPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+               return SerenumFdoPnp(DeviceObject, Irp);
+       else
+               return SerenumPdoPnp(DeviceObject, Irp);
+}
+
+VOID STDCALL
+DriverUnload(IN PDRIVER_OBJECT DriverObject)
+{
+       // nothing to do here yet
+}
+
+NTSTATUS STDCALL
+IrpStub(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       NTSTATUS Status = STATUS_NOT_SUPPORTED;
+       
+       if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+       {
+               /* Forward some IRPs to lower device */
+               switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
+               {
+                       case IRP_MJ_CREATE:
+                       case IRP_MJ_CLOSE:
+                       case IRP_MJ_CLEANUP:
+                       case IRP_MJ_READ:
+                       case IRP_MJ_WRITE:
+                       case IRP_MJ_DEVICE_CONTROL:
+                               return ForwardIrpToLowerDeviceAndForget(DeviceObject, Irp);
+                       default:
+                       {
+                               DPRINT1("Serenum: FDO stub for major function 0x%lx\n",
+                                       IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+                               DbgBreakPoint();
+                               Status = Irp->IoStatus.Status;
+                       }
+               }
+       }
+       else
+       {
+               /* Forward some IRPs to attached FDO */
+               switch (IoGetCurrentIrpStackLocation(Irp)->MajorFunction)
+               {
+                       case IRP_MJ_CREATE:
+                       case IRP_MJ_CLOSE:
+                       case IRP_MJ_CLEANUP:
+                       case IRP_MJ_READ:
+                       case IRP_MJ_WRITE:
+                       case IRP_MJ_DEVICE_CONTROL:
+                               return ForwardIrpToAttachedFdoAndForget(DeviceObject, Irp);
+                       default:
+                       {
+                               DPRINT1("Serenum: PDO stub for major function 0x%lx\n",
+                                       IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+                               DbgBreakPoint();
+                               Status = Irp->IoStatus.Status;
+                       }
+               }
+       }
+       
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
+
+/*
+ * Standard DriverEntry method.
+ */
+NTSTATUS STDCALL
+DriverEntry(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PUNICODE_STRING RegPath)
+{
+       ULONG i;
+       
+       DriverObject->DriverUnload = DriverUnload;
+       DriverObject->DriverExtension->AddDevice = SerenumAddDevice;
+       
+       for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+               DriverObject->MajorFunction[i] = IrpStub;
+       
+       /*DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialCreate;
+       DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialClose;
+       DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SerialCleanup;
+       DriverObject->MajorFunction[IRP_MJ_READ] = SerialRead;
+       DriverObject->MajorFunction[IRP_MJ_WRITE] = SerialWrite;*/
+       //DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Serenum;
+       //DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = SerialQueryInformation;
+       DriverObject->MajorFunction[IRP_MJ_PNP] = SerenumPnp;
+       //DriverObject->MajorFunction[IRP_MJ_POWER] = SerialPower;
+       
+       return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/bus/serenum/serenum.h b/reactos/drivers/bus/serenum/serenum.h
new file mode 100644 (file)
index 0000000..cab635a
--- /dev/null
@@ -0,0 +1,152 @@
+#if defined(__GNUC__)
+  #include <ddk/ntddk.h>
+  #include <ddk/ntddser.h>
+  #include <ddk/wdmguid.h>
+  #include <stdio.h>
+  
+  #include <debug.h>
+
+  #define SR_MSR_DSR 0x20
+  #define ExFreePoolWithTag(p, tag) ExFreePool(p)
+  
+  /* FIXME: these prototypes MUST NOT be here! */
+  NTSTATUS STDCALL
+  IoAttachDeviceToDeviceStackSafe(
+    IN PDEVICE_OBJECT SourceDevice,
+    IN PDEVICE_OBJECT TargetDevice,
+    OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+  
+#elif defined(_MSC_VER)
+  #include <ntddk.h>
+  #include <ntddser.h>
+  #include <c:/progra~1/winddk/inc/ddk/wdm/wxp/wdmguid.h>
+  #include <stdio.h>
+  
+  #define STDCALL
+  
+  #define DPRINT1 DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
+  #define CHECKPOINT1 DbgPrint("(%s:%d)\n")
+  
+  #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
+  
+  NTSTATUS STDCALL
+  IoAttachDeviceToDeviceStackSafe(
+    IN PDEVICE_OBJECT SourceDevice,
+    IN PDEVICE_OBJECT TargetDevice,
+    OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+  
+  #define DPRINT DPRINT1
+  #define CHECKPOINT CHECKPOINT1
+  
+  #define SR_MSR_DSR 0x20
+#else
+  #error Unknown compiler!
+#endif
+
+typedef enum
+{
+  dsStopped,
+  dsStarted,
+  dsPaused,
+  dsRemoved,
+  dsSurpriseRemoved
+} SERENUM_DEVICE_STATE;
+
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+       BOOLEAN IsFDO;
+       SERENUM_DEVICE_STATE PnpState;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _FDO_DEVICE_EXTENSION
+{
+       COMMON_DEVICE_EXTENSION Common;
+       
+       PDEVICE_OBJECT LowerDevice;
+       PDEVICE_OBJECT Pdo;
+       IO_REMOVE_LOCK RemoveLock;
+       
+       PDEVICE_OBJECT AttachedPdo;
+       ULONG Flags;
+} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
+
+typedef struct _PDO_DEVICE_EXTENSION
+{
+       COMMON_DEVICE_EXTENSION Common;
+       
+       PDEVICE_OBJECT AttachedFdo;
+       
+       UNICODE_STRING DeviceDescription; // REG_SZ
+       UNICODE_STRING DeviceId;          // REG_SZ
+       UNICODE_STRING HardwareIds;       // REG_MULTI_SZ
+       UNICODE_STRING CompatibleIds;     // REG_MULTI_SZ
+} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+#define SERENUM_TAG TAG('S', 'e', 'r', 'e')
+
+/* Flags */
+#define FLAG_ENUMERATION_DONE    0x01
+
+/************************************ detect.c */
+
+NTSTATUS
+SerenumDetectPnpDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PDEVICE_OBJECT LowerDevice);
+
+NTSTATUS
+SerenumDetectLegacyDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PDEVICE_OBJECT LowerDevice);
+
+/************************************ fdo.c */
+
+NTSTATUS STDCALL
+SerenumAddDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo);
+
+NTSTATUS
+SerenumFdoPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ misc.c */
+
+NTSTATUS
+SerenumDuplicateUnicodeString(
+  OUT PUNICODE_STRING Destination,
+  IN PUNICODE_STRING Source,
+  IN POOL_TYPE PoolType);
+
+NTSTATUS
+SerenumInitMultiSzString(
+       OUT PUNICODE_STRING Destination,
+       ... /* list of ANSI_STRINGs */);
+
+NTSTATUS
+ForwardIrpAndWait(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+ForwardIrpToLowerDeviceAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+ForwardIrpToAttachedFdoAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ pdo.c */
+
+NTSTATUS
+SerenumPdoPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
diff --git a/reactos/drivers/bus/serenum/serenum.rc b/reactos/drivers/bus/serenum/serenum.rc
new file mode 100644 (file)
index 0000000..a88af0f
--- /dev/null
@@ -0,0 +1,7 @@
+/* $Id$ */
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "Serial port enumerator\0"
+#define REACTOS_STR_INTERNAL_NAME      "serenum\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "serenum.sys\0"
+#include <reactos/version.rc>
diff --git a/reactos/drivers/dd/serial/circularbuffer.c b/reactos/drivers/dd/serial/circularbuffer.c
new file mode 100644 (file)
index 0000000..31c9cc2
--- /dev/null
@@ -0,0 +1,97 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/circularbuffer.c
+ * PURPOSE:         Operations on a circular buffer
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS
+InitializeCircularBuffer(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN ULONG BufferSize)
+{
+       DPRINT("Serial: InitializeCircularBuffer(pBuffer %p, BufferSize %lu)\n", pBuffer, BufferSize);
+       pBuffer->Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferSize * sizeof(UCHAR), SERIAL_TAG);
+       if (!pBuffer->Buffer)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       pBuffer->Length = BufferSize;
+       pBuffer->ReadPosition = pBuffer->WritePosition = 0;
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+FreeCircularBuffer(
+       IN PCIRCULAR_BUFFER pBuffer)
+{
+       DPRINT("Serial: FreeCircularBuffer(pBuffer %p)\n", pBuffer);
+       ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
+       return STATUS_SUCCESS;
+}
+
+BOOLEAN
+IsCircularBufferEmpty(
+       IN PCIRCULAR_BUFFER pBuffer)
+{
+       DPRINT("Serial: IsCircularBufferEmpty(pBuffer %p)\n", pBuffer);
+       return (pBuffer->ReadPosition == pBuffer->WritePosition);
+}
+
+NTSTATUS
+PushCircularBufferEntry(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN UCHAR Entry)
+{
+       ULONG NextPosition;
+       DPRINT("Serial: PushCircularBufferEntry(pBuffer %p, Entry 0x%x)\n", pBuffer, Entry);
+       ASSERT(pBuffer->Length);
+       NextPosition = (pBuffer->WritePosition + 1) % pBuffer->Length;
+       if (NextPosition == pBuffer->ReadPosition)
+               return STATUS_BUFFER_TOO_SMALL;
+       pBuffer->Buffer[pBuffer->WritePosition] = Entry;
+       pBuffer->WritePosition = NextPosition;
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+PopCircularBufferEntry(
+       IN PCIRCULAR_BUFFER pBuffer,
+       OUT PUCHAR Entry)
+{
+       DPRINT("Serial: PopCircularBufferEntry(pBuffer %p)\n", pBuffer);
+       ASSERT(pBuffer->Length);
+       if (IsCircularBufferEmpty(pBuffer))
+               return STATUS_ARRAY_BOUNDS_EXCEEDED;
+       *Entry = pBuffer->Buffer[pBuffer->ReadPosition];
+       pBuffer->ReadPosition = (pBuffer->ReadPosition + 1) % pBuffer->Length;
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+IncreaseCircularBufferSize(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN ULONG NewBufferSize)
+{
+       PUCHAR NewBuffer;
+       
+       DPRINT("Serial: IncreaseCircularBufferSize(pBuffer %p, NewBufferSize %lu)\n", pBuffer, NewBufferSize);
+       ASSERT(pBuffer->Length);
+       if (pBuffer->Length > NewBufferSize)
+               return STATUS_INVALID_PARAMETER;
+       else if (pBuffer->Length == NewBufferSize)
+               return STATUS_SUCCESS;
+       
+       NewBuffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, NewBufferSize * sizeof(UCHAR), SERIAL_TAG);
+       if (!NewBuffer)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       RtlCopyMemory(NewBuffer, pBuffer->Buffer, pBuffer->Length * sizeof(UCHAR));
+       ExFreePoolWithTag(pBuffer->Buffer, SERIAL_TAG);
+       pBuffer->Buffer = NewBuffer;
+       pBuffer->Length = NewBufferSize;
+       return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/dd/serial/cleanup.c b/reactos/drivers/dd/serial/cleanup.c
new file mode 100644 (file)
index 0000000..a22cb9c
--- /dev/null
@@ -0,0 +1,24 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/cleanup.c
+ * PURPOSE:         Serial IRP_MJ_CLEANUP operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialCleanup(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       DPRINT("Serial: IRP_MJ_CLEANUP\n");
+       Irp->IoStatus.Information = 0;
+       Irp->IoStatus.Status = STATUS_SUCCESS;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/dd/serial/close.c b/reactos/drivers/dd/serial/close.c
new file mode 100644 (file)
index 0000000..2b048d2
--- /dev/null
@@ -0,0 +1,29 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/close.c
+ * PURPOSE:         Serial IRP_MJ_CLOSE operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialClose(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PSERIAL_DEVICE_EXTENSION pDeviceExtension;
+       
+       DPRINT("Serial: IRP_MJ_CLOSE\n");
+       pDeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       pDeviceExtension->IsOpened = FALSE;
+       
+       Irp->IoStatus.Information = 0;
+       Irp->IoStatus.Status = STATUS_SUCCESS;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/dd/serial/create.c b/reactos/drivers/dd/serial/create.c
new file mode 100644 (file)
index 0000000..e823916
--- /dev/null
@@ -0,0 +1,60 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/create.c
+ * PURPOSE:         Serial IRP_MJ_CREATE operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialCreate(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PIO_STACK_LOCATION Stack;
+       PFILE_OBJECT FileObject;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       NTSTATUS Status;
+       
+       DPRINT("Serial: IRP_MJ_CREATE\n");
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       FileObject = Stack->FileObject;
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       
+       if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
+       {
+               CHECKPOINT;
+               Status = STATUS_NOT_A_DIRECTORY;
+               goto ByeBye;
+       }
+       
+       if (FileObject->FileName.Length != 0 || 
+               FileObject->RelatedFileObject != NULL)
+       {
+               CHECKPOINT;
+               Status = STATUS_ACCESS_DENIED;
+               goto ByeBye;
+       }
+       
+       if(DeviceExtension->IsOpened)
+       {
+               DPRINT("Serial: COM%lu is already opened", DeviceExtension->ComPort);
+               Status = STATUS_ACCESS_DENIED;
+               goto ByeBye;
+       }
+       
+       DPRINT("Serial: open COM%lu: successfull\n", DeviceExtension->ComPort);
+       DeviceExtension->IsOpened = TRUE;
+       Status = STATUS_SUCCESS;
+       
+ByeBye:
+       Irp->IoStatus.Status = Status;
+       Irp->IoStatus.Information = 0;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/dd/serial/devctrl.c b/reactos/drivers/dd/serial/devctrl.c
new file mode 100644 (file)
index 0000000..72e8a51
--- /dev/null
@@ -0,0 +1,840 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/devctrl.c
+ * PURPOSE:         Serial IRP_MJ_DEVICE_CONTROL operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+static VOID
+SerialGetUserBuffers(
+       IN PIRP Irp,
+       IN ULONG IoControlCode,
+       OUT PVOID* BufferIn,
+       OUT PVOID* BufferOut)
+{
+   ASSERT(Irp);
+   ASSERT(BufferIn);
+   ASSERT(BufferOut);
+   
+       switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+       {
+               case METHOD_BUFFERED:
+                       *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
+                       return;
+               case METHOD_IN_DIRECT:
+               case METHOD_OUT_DIRECT:
+                       *BufferIn = Irp->AssociatedIrp.SystemBuffer;
+                       *BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress);
+                       return;
+               case METHOD_NEITHER:
+                       *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
+                       *BufferOut = Irp->UserBuffer;
+                       return;
+       }
+       
+       /* Should never happen */
+}
+
+NTSTATUS STDCALL
+SerialSetBaudRate(
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
+       IN ULONG NewBaudRate)
+{
+       USHORT divisor;
+       PUCHAR ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       ULONG BaudRate;
+       NTSTATUS Status = STATUS_SUCCESS;
+       
+       if (NewBaudRate & SERIAL_BAUD_USER)
+       {
+               BaudRate = NewBaudRate & ~SERIAL_BAUD_USER;
+               divisor = (USHORT)(BAUD_CLOCK / (CLOCKS_PER_BIT * BaudRate));
+       }
+       else
+       {
+               switch (NewBaudRate)
+               {
+                       case SERIAL_BAUD_075:    divisor = 0x600; BaudRate = 75; break;
+                       case SERIAL_BAUD_110:    divisor = 0x400; BaudRate = 110; break;
+                       case SERIAL_BAUD_134_5:  divisor = 0x360; BaudRate = 134; break;
+                       case SERIAL_BAUD_150:    divisor = 0x300; BaudRate = 150; break;
+                       case SERIAL_BAUD_300:    divisor = 0x180; BaudRate = 300; break;
+                       case SERIAL_BAUD_600:    divisor = 0xc0;  BaudRate = 600; break;
+                       case SERIAL_BAUD_1200:   divisor = 0x60;  BaudRate = 1200; break;
+                       case SERIAL_BAUD_1800:   divisor = 0x40;  BaudRate = 1800; break;
+                       case SERIAL_BAUD_2400:   divisor = 0x30;  BaudRate = 2400; break;
+                       case SERIAL_BAUD_4800:   divisor = 0x18;  BaudRate = 4800; break;
+                       case SERIAL_BAUD_7200:   divisor = 0x10;  BaudRate = 7200; break;
+                       case SERIAL_BAUD_9600:   divisor = 0xc;   BaudRate = 9600; break;
+                       case SERIAL_BAUD_14400:  divisor = 0x8;   BaudRate = 14400; break;
+                       case SERIAL_BAUD_38400:  divisor = 0x3;   BaudRate = 38400; break;
+                       case SERIAL_BAUD_57600:  divisor = 0x2;   BaudRate = 57600; break;
+                       case SERIAL_BAUD_115200: divisor = 0x1;   BaudRate = 115200; break;
+                       case SERIAL_BAUD_56K:    divisor = 0x2;   BaudRate = 57600; break;
+                       case SERIAL_BAUD_128K:   divisor = 0x1;   BaudRate = 115200; break;
+                       default: Status = STATUS_INVALID_PARAMETER;
+               }
+       }
+       
+       if (NT_SUCCESS(Status))
+       {
+               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+               if (NT_SUCCESS(Status))
+               {
+                       UCHAR Lcr;
+                       DPRINT("Serial: SerialSetBaudRate(COM%lu, %lu Bauds)\n", DeviceExtension->ComPort, BaudRate);
+                       /* Set Bit 7 of LCR to expose baud registers */
+                       Lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase));
+                       WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr | SR_LCR_DLAB);
+                       /* Write the baud rate */
+                       WRITE_PORT_UCHAR(SER_DLL(ComPortBase), divisor & 0xff);
+                       WRITE_PORT_UCHAR(SER_DLM(ComPortBase), divisor >> 8);
+                       /* Switch back to normal registers */
+                       WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
+                       
+                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+               }
+       }
+       
+       if (NT_SUCCESS(Status))
+               DeviceExtension->BaudRate = BaudRate;
+       return Status;
+}
+
+NTSTATUS STDCALL
+SerialSetLineControl(
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
+       IN PSERIAL_LINE_CONTROL NewSettings)
+{
+       PUCHAR ComPortBase;
+       UCHAR Lcr = 0;
+       NTSTATUS Status;
+       
+       DPRINT("Serial: SerialSetLineControl(COM%lu, Settings { %lu %lu %lu })\n",
+               DeviceExtension->ComPort, NewSettings->StopBits, NewSettings->Parity, NewSettings->WordLength);
+       
+       /* Verify parameters */
+       switch (NewSettings->WordLength)
+       {
+               case 5: Lcr |= SR_LCR_CS5; break;
+               case 6: Lcr |= SR_LCR_CS6; break;
+               case 7: Lcr |= SR_LCR_CS7; break;
+               case 8: Lcr |= SR_LCR_CS8; break;
+               default: return STATUS_INVALID_PARAMETER;
+       }
+       
+       if (NewSettings->WordLength < 5 || NewSettings->WordLength > 8)
+               return STATUS_INVALID_PARAMETER;
+       
+       switch (NewSettings->Parity)
+       {
+               case NO_PARITY:    Lcr |= SR_LCR_PNO; break;
+               case ODD_PARITY:   Lcr |= SR_LCR_POD; break;
+               case EVEN_PARITY:  Lcr |= SR_LCR_PEV; break;
+               case MARK_PARITY:  Lcr |= SR_LCR_PMK; break;
+               case SPACE_PARITY: Lcr |= SR_LCR_PSP; break;
+               default: return STATUS_INVALID_PARAMETER;
+       }
+       
+       switch (NewSettings->StopBits)
+       {
+               case STOP_BIT_1:
+                       Lcr |= SR_LCR_ST1;
+                       break;
+               case STOP_BITS_1_5:
+                       if (NewSettings->WordLength != 5)
+                               return STATUS_INVALID_PARAMETER;
+                       Lcr |= SR_LCR_ST2;
+                       break;
+               case STOP_BITS_2:
+                       if (NewSettings->WordLength < 6 || NewSettings->WordLength > 8)
+                               return STATUS_INVALID_PARAMETER;
+                       Lcr |= SR_LCR_ST2;
+                       break;
+               default:
+                       return STATUS_INVALID_PARAMETER;
+       }
+       
+       /* Update current parameters */
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+       if (!NT_SUCCESS(Status))
+               return Status;
+       WRITE_PORT_UCHAR(SER_LCR(ComPortBase), Lcr);
+       
+       /* Read junk out of RBR */
+       READ_PORT_UCHAR(SER_RBR(ComPortBase));
+       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+       
+       if (NT_SUCCESS(Status))
+               DeviceExtension->SerialLineControl = *NewSettings;
+       
+       return Status;
+}
+
+BOOLEAN
+SerialClearPerfStats(
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
+{
+       RtlZeroMemory(&DeviceExtension->SerialPerfStats, sizeof(SERIALPERF_STATS));
+       DeviceExtension->BreakInterruptErrorCount = 0;
+       return TRUE;
+}
+
+BOOLEAN
+SerialGetPerfStats(IN PIRP pIrp)
+{
+       PSERIAL_DEVICE_EXTENSION pDeviceExtension;
+       pDeviceExtension = (PSERIAL_DEVICE_EXTENSION)
+               IoGetCurrentIrpStackLocation(pIrp)->DeviceObject->DeviceExtension;
+       /*
+        * we assume buffer is big enough to hold SerialPerfStats structure
+        * caller must verify this
+        */
+       RtlCopyMemory(
+               pIrp->AssociatedIrp.SystemBuffer,
+               &pDeviceExtension->SerialPerfStats,
+               sizeof(SERIALPERF_STATS)
+       );
+       return TRUE;
+}
+
+NTSTATUS
+SerialGetCommProp(
+       OUT PSERIAL_COMMPROP pCommProp,
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
+{
+       RtlZeroMemory(pCommProp, sizeof(SERIAL_COMMPROP));
+       
+       pCommProp->PacketLength = sizeof(SERIAL_COMMPROP);
+       pCommProp->PacketVersion = 2;
+       pCommProp->ServiceMask = SERIAL_SP_SERIALCOMM;
+       pCommProp->MaxTxQueue = pCommProp->CurrentTxQueue = DeviceExtension->OutputBuffer.Length - 1;
+       pCommProp->MaxRxQueue = pCommProp->CurrentRxQueue = DeviceExtension->InputBuffer.Length - 1;
+       pCommProp->ProvSubType = 1; // PST_RS232;
+       pCommProp->ProvCapabilities = SERIAL_PCF_DTRDSR | SERIAL_PCF_INTTIMEOUTS | SERIAL_PCF_PARITY_CHECK
+               | SERIAL_PCF_RTSCTS | SERIAL_PCF_SETXCHAR | SERIAL_PCF_SPECIALCHARS | SERIAL_PCF_TOTALTIMEOUTS
+               | SERIAL_PCF_XONXOFF;
+       pCommProp->SettableParams = SERIAL_SP_BAUD | SERIAL_SP_DATABITS | SERIAL_SP_HANDSHAKING
+               | SERIAL_SP_PARITY | SERIAL_SP_PARITY_CHECK | SERIAL_SP_STOPBITS;
+       
+       /* SettableBaud is related to Uart type */
+       pCommProp->SettableBaud = SERIAL_BAUD_075 | SERIAL_BAUD_110 | SERIAL_BAUD_134_5
+               | SERIAL_BAUD_150 | SERIAL_BAUD_300 | SERIAL_BAUD_600 | SERIAL_BAUD_1200
+               | SERIAL_BAUD_1800 | SERIAL_BAUD_2400 | SERIAL_BAUD_4800 | SERIAL_BAUD_7200
+               | SERIAL_BAUD_9600 | SERIAL_BAUD_USER;
+       pCommProp->MaxBaud = SERIAL_BAUD_9600;
+       if (DeviceExtension->UartType >= Uart16450)
+       {
+               pCommProp->SettableBaud |= SERIAL_BAUD_14400 | SERIAL_BAUD_19200 | SERIAL_BAUD_38400;
+               pCommProp->MaxBaud = SERIAL_BAUD_38400;
+       }
+       if (DeviceExtension->UartType >= Uart16550)
+       {
+               pCommProp->SettableBaud |= SERIAL_BAUD_56K | SERIAL_BAUD_57600 | SERIAL_BAUD_115200 | SERIAL_BAUD_128K;
+               pCommProp->MaxBaud = SERIAL_BAUD_115200;
+       }
+       
+       pCommProp->SettableData = SERIAL_DATABITS_5 | SERIAL_DATABITS_6 | SERIAL_DATABITS_7 | SERIAL_DATABITS_8;
+       pCommProp->SettableStopParity = SERIAL_STOPBITS_10 | SERIAL_STOPBITS_15 | SERIAL_STOPBITS_20
+               | SERIAL_PARITY_NONE | SERIAL_PARITY_ODD | SERIAL_PARITY_EVEN | SERIAL_PARITY_MARK | SERIAL_PARITY_SPACE;
+       
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS
+SerialGetCommStatus(
+       OUT PSERIAL_STATUS pSerialStatus,
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension)
+{
+       KIRQL Irql;
+       
+       RtlZeroMemory(pSerialStatus, sizeof(SERIAL_STATUS));
+       
+       pSerialStatus->Errors = 0;
+       if (DeviceExtension->BreakInterruptErrorCount)
+               pSerialStatus->Errors |= SERIAL_ERROR_BREAK;
+       if (DeviceExtension->SerialPerfStats.FrameErrorCount)
+               pSerialStatus->Errors |= SERIAL_ERROR_FRAMING;
+       if (DeviceExtension->SerialPerfStats.SerialOverrunErrorCount)
+               pSerialStatus->Errors |= SERIAL_ERROR_OVERRUN;
+       if (DeviceExtension->SerialPerfStats.BufferOverrunErrorCount)
+               pSerialStatus->Errors |= SERIAL_ERROR_QUEUEOVERRUN;
+       if (DeviceExtension->SerialPerfStats.ParityErrorCount)
+               pSerialStatus->Errors |= SERIAL_ERROR_PARITY;
+       
+       pSerialStatus->HoldReasons = 0; /* FIXME */
+       
+       KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+       pSerialStatus->AmountInInQueue = (DeviceExtension->InputBuffer.WritePosition + DeviceExtension->InputBuffer.Length
+               - DeviceExtension->InputBuffer.ReadPosition) % DeviceExtension->InputBuffer.Length;
+       KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
+       
+       KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
+       pSerialStatus->AmountInOutQueue = (DeviceExtension->OutputBuffer.WritePosition + DeviceExtension->OutputBuffer.Length
+               - DeviceExtension->OutputBuffer.ReadPosition) % DeviceExtension->OutputBuffer.Length;
+       KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+       
+       pSerialStatus->EofReceived = FALSE; /* always FALSE */
+       pSerialStatus->WaitForImmediate = FALSE; /* always FALSE */
+       
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+SerialDeviceControl(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PIO_STACK_LOCATION Stack;
+       ULONG IoControlCode;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       ULONG LengthIn, LengthOut;
+       ULONG_PTR Information = 0;
+       PVOID BufferIn, BufferOut;
+       PUCHAR ComPortBase;
+       NTSTATUS Status;
+       
+       DPRINT("Serial: IRP_MJ_DEVICE_CONTROL dispatch\n");
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
+       LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+       SerialGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
+       
+       /* FIXME: need to probe buffers */
+       /* FIXME: see http://www.osronline.com/ddkx/serial/serref_61bm.htm */
+       switch (IoControlCode)
+       {
+               case IOCTL_SERIAL_CLEAR_STATS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_CLEAR_STATS\n");
+                       KeSynchronizeExecution(
+                               DeviceExtension->Interrupt,
+                               (PKSYNCHRONIZE_ROUTINE)SerialClearPerfStats,
+                               DeviceExtension);
+                       Status = STATUS_SUCCESS;
+                       break;
+               }
+               case IOCTL_SERIAL_CLR_DTR:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_CLR_DTR\n");
+                       /* FIXME: If the handshake flow control of the device is configured to 
+                        * automatically use DTR, return STATUS_INVALID_PARAMETER */
+                       Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                       if (NT_SUCCESS(Status))
+                       {
+                               DeviceExtension->MCR &= ~SR_MCR_DTR;
+                               WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+                               IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_CLR_RTS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_CLR_RTS\n");
+                       /* FIXME: If the handshake flow control of the device is configured to 
+                        * automatically use RTS, return STATUS_INVALID_PARAMETER */
+                       Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                       if (NT_SUCCESS(Status))
+                       {
+                               DeviceExtension->MCR &= ~SR_MCR_RTS;
+                               WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+                               IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_CONFIG_SIZE:
+               {
+                       /* Obsolete on Microsoft Windows 2000+ */
+                       PULONG pConfigSize;
+                       DPRINT("Serial: IOCTL_SERIAL_CONFIG_SIZE\n");
+                       if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pConfigSize = (PULONG)BufferOut;
+                               *pConfigSize = 0;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_BAUD_RATE:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_BAUD_RATE\n");
+                       if (LengthOut < sizeof(SERIAL_BAUD_RATE))
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       else if (BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               ((PSERIAL_BAUD_RATE)BufferOut)->BaudRate = DeviceExtension->BaudRate;
+                               Information = sizeof(SERIAL_BAUD_RATE);
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_CHARS:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_GET_CHARS not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_GET_COMMSTATUS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_COMMSTATUS\n");
+                       if (LengthOut < sizeof(SERIAL_STATUS))
+                       {
+                               DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n");
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       }
+                       else if (BufferOut == NULL)
+                       {
+                               DPRINT("Serial: return STATUS_INVALID_PARAMETER\n");
+                               Status = STATUS_INVALID_PARAMETER;
+                       }
+                       else
+                       {
+                               Status = SerialGetCommStatus((PSERIAL_STATUS)BufferOut, DeviceExtension);
+                               Information = sizeof(SERIAL_STATUS);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_DTRRTS:
+               {
+                       PULONG pDtrRts;
+                       DPRINT("Serial: IOCTL_SERIAL_GET_DTRRTS\n");
+                       if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pDtrRts = (PULONG)BufferOut;
+                               *pDtrRts = 0;
+                               if (DeviceExtension->MCR & SR_MCR_DTR)
+                                       *pDtrRts |= SERIAL_DTR_STATE;
+                               if (DeviceExtension->MCR & SR_MCR_RTS)
+                                       *pDtrRts |= SERIAL_RTS_STATE;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_HANDFLOW:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_GET_HANDFLOW not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_GET_LINE_CONTROL:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_LINE_CONTROL\n");
+                       if (LengthOut < sizeof(SERIAL_LINE_CONTROL))
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       else if (BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               *((PSERIAL_LINE_CONTROL)BufferOut) = DeviceExtension->SerialLineControl;
+                               Information = sizeof(SERIAL_LINE_CONTROL);
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_MODEM_CONTROL:
+               {
+                       PULONG pMCR;
+                       DPRINT("Serial: IOCTL_SERIAL_GET_MODEM_CONTROL\n");
+                       if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pMCR = (PULONG)BufferOut;
+                               *pMCR = DeviceExtension->MCR;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_MODEMSTATUS:
+               {
+                       PULONG pMSR;
+                       DPRINT("Serial: IOCTL_SERIAL_GET_MODEMSTATUS\n");
+                       if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pMSR = (PULONG)BufferOut;
+                               *pMSR = DeviceExtension->MSR;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_PROPERTIES:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_PROPERTIES\n");
+                       if (LengthOut < sizeof(SERIAL_COMMPROP))
+                       {
+                               DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n");
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       }
+                       else if (BufferOut == NULL)
+                       {
+                               DPRINT("Serial: return STATUS_INVALID_PARAMETER\n");
+                               Status = STATUS_INVALID_PARAMETER;
+                       }
+                       else
+                       {
+                               Status = SerialGetCommProp((PSERIAL_COMMPROP)BufferOut, DeviceExtension);
+                               Information = sizeof(SERIAL_COMMPROP);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_STATS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_STATS\n");
+                       if (LengthOut < sizeof(SERIALPERF_STATS))
+                       {
+                               DPRINT("Serial: return STATUS_BUFFER_TOO_SMALL\n");
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       }
+                       else if (BufferOut == NULL)
+                       {
+                               DPRINT("Serial: return STATUS_INVALID_PARAMETER\n");
+                               Status = STATUS_INVALID_PARAMETER;
+                       }
+                       else
+                       {
+                               KeSynchronizeExecution(DeviceExtension->Interrupt,
+                                       (PKSYNCHRONIZE_ROUTINE)SerialGetPerfStats, Irp);
+                               Status = STATUS_SUCCESS;
+                               Information = sizeof(SERIALPERF_STATS);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_TIMEOUTS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_GET_TIMEOUTS\n");
+                       if (LengthOut != sizeof(SERIAL_TIMEOUTS) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               *(PSERIAL_TIMEOUTS)BufferOut = DeviceExtension->SerialTimeOuts;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_GET_WAIT_MASK:
+               {
+                       PULONG pWaitMask;
+                       DPRINT("Serial: IOCTL_SERIAL_GET_WAIT_MASK\n");
+                       if (LengthOut != sizeof(ULONG) || BufferOut == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pWaitMask = (PULONG)BufferOut;
+                               *pWaitMask = DeviceExtension->WaitMask;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_IMMEDIATE_CHAR:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_IMMEDIATE_CHAR not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_LSRMST_INSERT:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_LSRMST_INSERT not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_PURGE:
+               {
+                       KIRQL Irql;
+                       DPRINT("Serial: IOCTL_SERIAL_PURGE\n");
+                       /* FIXME: SERIAL_PURGE_RXABORT and SERIAL_PURGE_TXABORT
+                        * should stop current request */
+                       if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               ULONG PurgeMask = *(PULONG)BufferIn;
+                               
+                               Status = STATUS_SUCCESS;
+                               /* FIXME: use SERIAL_PURGE_RXABORT and SERIAL_PURGE_TXABORT flags */
+                               if (PurgeMask & SERIAL_PURGE_RXCLEAR)
+                               {
+                                       KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+                                       DeviceExtension->InputBuffer.ReadPosition = DeviceExtension->InputBuffer.WritePosition = 0;
+                                       if (DeviceExtension->UartType >= Uart16550A)
+                                       {
+                                               /* Clear also Uart FIFO */
+                                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                                               if (NT_SUCCESS(Status))
+                                               {
+                                                       WRITE_PORT_UCHAR(SER_FCR(ComPortBase), SR_FCR_CLEAR_RCVR);
+                                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                                               }
+                                       }
+                                       KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
+                               }
+                               
+                               if (PurgeMask & SERIAL_PURGE_TXCLEAR)
+                               {
+                                       KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
+                                       DeviceExtension->OutputBuffer.ReadPosition = DeviceExtension->OutputBuffer.WritePosition = 0;
+                                       if (DeviceExtension->UartType >= Uart16550A)
+                                       {
+                                               /* Clear also Uart FIFO */
+                                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                                               if (NT_SUCCESS(Status))
+                                               {
+                                                       WRITE_PORT_UCHAR(SER_FCR(ComPortBase), SR_FCR_CLEAR_XMIT);
+                                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                                               }
+                                       }
+                                       KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+                               }
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_RESET_DEVICE:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_RESET_DEVICE not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_BAUD_RATE:
+               {
+                       PULONG pNewBaudRate;
+                       DPRINT("Serial: IOCTL_SERIAL_SET_BAUD_RATE\n");
+                       if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pNewBaudRate = (PULONG)BufferIn;
+                               Status = SerialSetBaudRate(DeviceExtension, *pNewBaudRate);
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_BREAK_OFF:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_OFF not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_BREAK_ON:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_BREAK_ON not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_CHARS:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_CHARS not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_DTR:
+               {
+                       /* FIXME: If the handshake flow control of the device is configured to 
+                        * automatically use DTR, return STATUS_INVALID_PARAMETER */
+                       DPRINT("Serial: IOCTL_SERIAL_SET_DTR\n");
+                       if (!(DeviceExtension->MCR & SR_MCR_DTR))
+                       {
+                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               if (NT_SUCCESS(Status))
+                               {
+                                       DeviceExtension->MCR |= SR_MCR_DTR;
+                                       WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               }
+                       }
+                       else
+                               Status = STATUS_SUCCESS;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_FIFO_CONTROL:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_SET_FIFO_CONTROL\n");
+                       if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               if (NT_SUCCESS(Status))
+                               {
+                                       WRITE_PORT_UCHAR(SER_FCR(ComPortBase), (UCHAR)((*(PULONG)BufferIn) & 0xff));
+                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               }
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_HANDFLOW:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_HANDFLOW not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_LINE_CONTROL:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_SET_LINE_CONTROL\n");
+                       if (LengthIn < sizeof(SERIAL_LINE_CONTROL))
+                               Status = STATUS_BUFFER_TOO_SMALL;
+                       else if (BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                               Status = SerialSetLineControl(DeviceExtension, (PSERIAL_LINE_CONTROL)BufferIn);
+                       break;
+               }
+               case IOCTL_SERIAL_SET_MODEM_CONTROL:
+               {
+                       PULONG pMCR;
+                       DPRINT("Serial: IOCTL_SERIAL_SET_MODEM_CONTROL\n");
+                       if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               if (NT_SUCCESS(Status))
+                               {
+                                       pMCR = (PULONG)BufferIn;
+                                       DeviceExtension->MCR = (UCHAR)(*pMCR & 0xff);
+                                       WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               }
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_QUEUE_SIZE:
+               {
+                       if (LengthIn < sizeof(SERIAL_QUEUE_SIZE ))
+                               return STATUS_BUFFER_TOO_SMALL;
+                       else if (BufferIn == NULL)
+                               return STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               KIRQL Irql;
+                               PSERIAL_QUEUE_SIZE NewQueueSize = (PSERIAL_QUEUE_SIZE)BufferIn;
+                               Status = STATUS_SUCCESS;
+                               if (NewQueueSize->InSize > DeviceExtension->InputBuffer.Length)
+                               {
+                                       KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+                                       Status = IncreaseCircularBufferSize(&DeviceExtension->InputBuffer, NewQueueSize->InSize);
+                                       KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
+                               }
+                               if (NT_SUCCESS(Status) && NewQueueSize->OutSize > DeviceExtension->OutputBuffer.Length)
+                               {
+                                       KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
+                                       Status = IncreaseCircularBufferSize(&DeviceExtension->OutputBuffer, NewQueueSize->OutSize);
+                                       KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+                               }
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_RTS:
+               {
+                       /* FIXME: If the handshake flow control of the device is configured to 
+                        * automatically use DTR, return STATUS_INVALID_PARAMETER */
+                       DPRINT("Serial: IOCTL_SERIAL_SET_RTS\n");
+                       if (!(DeviceExtension->MCR & SR_MCR_RTS))
+                       {
+                               Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               if (NT_SUCCESS(Status))
+                               {
+                                       DeviceExtension->MCR |= SR_MCR_RTS;
+                                       WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+                                       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+                               }
+                       }
+                       else
+                               Status = STATUS_SUCCESS;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_TIMEOUTS:
+               {
+                       DPRINT("Serial: IOCTL_SERIAL_SET_TIMEOUTS\n");
+                       if (LengthIn != sizeof(SERIAL_TIMEOUTS) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               DeviceExtension->SerialTimeOuts = *(PSERIAL_TIMEOUTS)BufferIn;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_WAIT_MASK:
+               {
+                       PULONG pWaitMask;
+                       DPRINT("Serial: IOCTL_SERIAL_SET_WAIT_MASK\n");
+                       if (LengthIn != sizeof(ULONG) || BufferIn == NULL)
+                               Status = STATUS_INVALID_PARAMETER;
+                       else
+                       {
+                               pWaitMask = (PULONG)BufferIn;
+                               DeviceExtension->WaitMask = *pWaitMask;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case IOCTL_SERIAL_SET_XOFF:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_XOFF not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_SET_XON:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_SET_XON not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_WAIT_ON_MASK:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_WAIT_ON_MASK not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               case IOCTL_SERIAL_XOFF_COUNTER:
+               {
+                       /* FIXME */
+                       DPRINT1("Serial: IOCTL_SERIAL_XOFF_COUNTER not implemented.\n");
+                       Status = STATUS_NOT_IMPLEMENTED;
+                       break;
+               }
+               default:
+               {
+                       /* Pass Irp to lower driver */
+                       DPRINT("Serial: Unknown IOCTL code 0x%x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+                       IoSkipCurrentIrpStackLocation(Irp);
+                       return IoCallDriver(DeviceExtension->LowerDevice, Irp);
+               }
+       }
+       
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/dd/serial/info.c b/reactos/drivers/dd/serial/info.c
new file mode 100644 (file)
index 0000000..0b63deb
--- /dev/null
@@ -0,0 +1,76 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/info.c
+ * PURPOSE:         Serial IRP_MJ_QUERY_INFORMATION operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG2
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialQueryInformation(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       PIO_STACK_LOCATION Stack;
+       PVOID SystemBuffer;
+       ULONG BufferLength;
+       ULONG_PTR Information = 0;
+       NTSTATUS Status;
+       
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+       BufferLength = Stack->Parameters.QueryFile.Length;
+       
+       switch (Stack->Parameters.QueryFile.FileInformationClass)
+       {
+               case FileStandardInformation:
+               {
+                       PFILE_STANDARD_INFORMATION StandardInfo = (PFILE_STANDARD_INFORMATION)SystemBuffer;
+                       
+                       DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FileStandardInformation\n");
+                       if (BufferLength < sizeof(FILE_STANDARD_INFORMATION))
+                               Status = STATUS_BUFFER_OVERFLOW;
+                       else
+                       {
+                               StandardInfo->AllocationSize.QuadPart = 0;
+                               StandardInfo->EndOfFile.QuadPart = 0;
+               StandardInfo->Directory = FALSE;
+               StandardInfo->NumberOfLinks = 0;
+                               StandardInfo->DeletePending = FALSE; /* FIXME: should be TRUE sometimes */
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               case FilePositionInformation:
+               {
+                       PFILE_POSITION_INFORMATION PositionInfo = (PFILE_POSITION_INFORMATION)SystemBuffer;
+                       
+                       DPRINT("Serial: IRP_MJ_QUERY_INFORMATION / FilePositionInformation\n");
+                       if (BufferLength < sizeof(PFILE_POSITION_INFORMATION))
+                               Status = STATUS_BUFFER_OVERFLOW;
+                       else
+                       {
+                               PositionInfo->CurrentByteOffset.QuadPart = 0;
+                               Status = STATUS_SUCCESS;
+                       }
+                       break;
+               }
+               default:
+               {
+                       DPRINT("Serial: IRP_MJ_QUERY_INFORMATION: Unexpected file information class 0x%02x\n", Stack->Parameters.QueryFile.FileInformationClass);
+                       return ForwardIrpAndForget(DeviceObject, Irp);
+               }
+       }
+       
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/dd/serial/legacy.c b/reactos/drivers/dd/serial/legacy.c
new file mode 100644 (file)
index 0000000..f47c9dd
--- /dev/null
@@ -0,0 +1,194 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/bus/serial/legacy.c
+ * PURPOSE:         Legacy serial port enumeration
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ *                  Mark Junker (mjscod@gmx.de)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+UART_TYPE
+SerialDetectUartType(
+       IN PUCHAR BaseAddress)
+{
+       UCHAR Lcr, TestLcr;
+       UCHAR OldScr, Scr5A, ScrA5;
+       BOOLEAN FifoEnabled;
+       UCHAR NewFifoStatus;
+       
+       Lcr = READ_PORT_UCHAR(SER_LCR(BaseAddress));
+       WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr ^ 0xFF);
+       TestLcr = READ_PORT_UCHAR(SER_LCR(BaseAddress)) ^ 0xFF;
+       WRITE_PORT_UCHAR(SER_LCR(BaseAddress), Lcr);
+       
+       /* Accessing the LCR must work for a usable serial port */
+       if (TestLcr != Lcr)
+               return UartUnknown;
+       
+       /* Ensure that all following accesses are done as required */
+       READ_PORT_UCHAR(SER_RBR(BaseAddress));
+       READ_PORT_UCHAR(SER_IER(BaseAddress));
+       READ_PORT_UCHAR(SER_IIR(BaseAddress));
+       READ_PORT_UCHAR(SER_LCR(BaseAddress));
+       READ_PORT_UCHAR(SER_MCR(BaseAddress));
+       READ_PORT_UCHAR(SER_LSR(BaseAddress));
+       READ_PORT_UCHAR(SER_MSR(BaseAddress));
+       READ_PORT_UCHAR(SER_SCR(BaseAddress));
+       
+       /* Test scratch pad */
+       OldScr = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+       WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0x5A);
+       Scr5A = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+       WRITE_PORT_UCHAR(SER_SCR(BaseAddress), 0xA5);
+       ScrA5 = READ_PORT_UCHAR(SER_SCR(BaseAddress));
+       WRITE_PORT_UCHAR(SER_SCR(BaseAddress), OldScr);
+       
+       /* When non-functional, we have a 8250 */
+       if (Scr5A != 0x5A || ScrA5 != 0xA5)
+               return Uart8250;
+       
+       /* Test FIFO type */
+       FifoEnabled = (READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0x80) != 0;
+       WRITE_PORT_UCHAR(SER_FCR(BaseAddress), SR_FCR_ENABLE_FIFO);
+       NewFifoStatus = READ_PORT_UCHAR(SER_IIR(BaseAddress)) & 0xC0;
+       if (!FifoEnabled)
+               WRITE_PORT_UCHAR(SER_FCR(BaseAddress), 0);
+       switch (NewFifoStatus)
+       {
+               case 0x00:
+                       return Uart16450;
+               case 0x40:
+               case 0x80:
+                       /* Not sure about this but the documentation says that 0x40
+                        * indicates an unusable FIFO but my tests only worked
+                        * with 0x80 */
+                       return Uart16550;
+       }
+       
+       /* FIFO is only functional for 16550A+ */
+       return Uart16550A;
+}
+
+static NTSTATUS
+DetectLegacyDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN ULONG ComPortBase,
+       IN ULONG Irq,
+       IN PULONG pComPortNumber OPTIONAL)
+{
+       ULONG ResourceListSize;
+       PCM_RESOURCE_LIST ResourceList;
+       PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+       BOOLEAN ConflictDetected;
+       UART_TYPE UartType;
+       PDEVICE_OBJECT Pdo = NULL;
+       PDEVICE_OBJECT Fdo;
+       KIRQL Dirql;
+       NTSTATUS Status;
+       
+       /* Create resource list */
+       ResourceListSize = sizeof(CM_RESOURCE_LIST) + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+       ResourceList = (PCM_RESOURCE_LIST)ExAllocatePoolWithTag(PagedPool, ResourceListSize, SERIAL_TAG);
+       if (!ResourceList)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       ResourceList->Count = 1;
+       ResourceList->List[0].InterfaceType = InterfaceTypeUndefined;
+       ResourceList->List[0].BusNumber = -1; /* unknown */
+       ResourceList->List[0].PartialResourceList.Version = 1;
+       ResourceList->List[0].PartialResourceList.Revision = 1;
+       ResourceList->List[0].PartialResourceList.Count = 2;
+       ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0];
+       ResourceDescriptor->Type = CmResourceTypePort;
+       ResourceDescriptor->ShareDisposition = CmResourceShareDriverExclusive;
+       ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
+       ResourceDescriptor->u.Port.Start.u.HighPart = 0;
+       ResourceDescriptor->u.Port.Start.u.LowPart = ComPortBase;
+       ResourceDescriptor->u.Port.Length = 8;
+       
+       ResourceDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[1];
+       ResourceDescriptor->Type = CmResourceTypeInterrupt;
+       ResourceDescriptor->ShareDisposition = CmResourceShareShared;
+       ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+       ResourceDescriptor->u.Interrupt.Vector = HalGetInterruptVector(
+               Internal, 0, 0, Irq,
+               &Dirql,
+               &ResourceDescriptor->u.Interrupt.Affinity);
+       ResourceDescriptor->u.Interrupt.Level = (ULONG)Dirql;
+       
+       /* Report resource list */
+       Status = IoReportResourceForDetection(
+               DriverObject, ResourceList, ResourceListSize,
+               NULL, NULL, 0,
+               &ConflictDetected);
+       if (Status == STATUS_CONFLICTING_ADDRESSES)
+       {
+               DPRINT("Serial: conflict detected for serial port at 0x%lx (Irq %lu)\n", ComPortBase, Irq);
+               ExFreePoolWithTag(ResourceList, SERIAL_TAG);
+               return STATUS_DEVICE_NOT_CONNECTED;
+       }
+       if (!NT_SUCCESS(Status))
+       {
+               ExFreePoolWithTag(ResourceList, SERIAL_TAG);
+               return Status;
+       }
+       
+       /* Test if port exists */
+       UartType = SerialDetectUartType((PUCHAR)ComPortBase);
+       
+       /* Report device if detected... */
+       if (UartType != UartUnknown)
+       {
+               Status = IoReportDetectedDevice(
+                       DriverObject,
+                       ResourceList->List[0].InterfaceType, ResourceList->List[0].BusNumber, -1 /* unknown */,
+                       ResourceList, NULL,
+                       TRUE,
+                       &Pdo);
+               if (NT_SUCCESS(Status))
+               {
+                       Status = SerialAddDeviceInternal(DriverObject, Pdo, UartType, pComPortNumber, &Fdo);
+                       if (NT_SUCCESS(Status))
+                       {
+                               Status = SerialPnpStartDevice(Fdo, ResourceList);
+                       }
+               }
+       }
+       else
+       {
+               /* Release resources */
+               Status = IoReportResourceForDetection(
+                       DriverObject, NULL, 0,
+                       NULL, NULL, 0,
+                       &ConflictDetected);
+               Status = STATUS_DEVICE_NOT_CONNECTED;
+       }
+       ExFreePoolWithTag(ResourceList, SERIAL_TAG);
+       return Status;
+}
+
+NTSTATUS
+DetectLegacyDevices(
+       IN PDRIVER_OBJECT DriverObject)
+{
+       ULONG ComPortBase[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+       ULONG Irq[] = { 4, 3, 4, 3 };
+       ULONG ComPortNumber[] = { 1, 2, 3, 4 };
+       ULONG i;
+       NTSTATUS Status;
+       NTSTATUS ReturnedStatus = STATUS_SUCCESS;
+       
+       for (i = 0; i < sizeof(ComPortBase)/sizeof(ComPortBase[0]); i++)
+       {
+               Status = DetectLegacyDevice(DriverObject, ComPortBase[i], Irq[i], &ComPortNumber[i]);
+               if (!NT_SUCCESS(Status) && Status != STATUS_DEVICE_NOT_CONNECTED)
+                       ReturnedStatus = Status;
+               DPRINT("Serial: Legacy device at 0x%x (IRQ %lu): status = 0x%08lx\n", ComPortBase[i], Irq[i], Status);
+       }
+       
+       return ReturnedStatus;
+}
index 8bf5143..f780382 100644 (file)
@@ -6,7 +6,19 @@ TARGET_TYPE = driver
 
 TARGET_NAME = serial
 
-TARGET_OBJECTS = serial.o
+TARGET_OBJECTS = \
+       circularbuffer.o \
+       cleanup.o \
+       close.o \
+       create.o \
+       devctrl.o \
+       info.o \
+       legacy.o \
+       misc.o \
+       pnp.o \
+       power.o \
+       rw.o \
+       serial.o
 
 TARGET_CFLAGS = -Wall -Werror -D__USE_W32API 
 
diff --git a/reactos/drivers/dd/serial/misc.c b/reactos/drivers/dd/serial/misc.c
new file mode 100644 (file)
index 0000000..04c2205
--- /dev/null
@@ -0,0 +1,215 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/misc.c
+ * PURPOSE:         Misceallenous operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+ForwardIrpAndWaitCompletion(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       IN PVOID Context)
+{
+       if (Irp->PendingReturned)
+               KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+       return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+ForwardIrpAndWait(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+       KEVENT Event;
+       NTSTATUS Status;
+       
+       KeInitializeEvent(&Event, NotificationEvent, FALSE);
+       IoCopyCurrentIrpStackLocationToNext(Irp);
+       
+       DPRINT("Serial: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
+       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;
+}
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PDEVICE_OBJECT LowerDevice = ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+       
+       IoSkipCurrentIrpStackLocation(Irp);
+       return IoCallDriver(LowerDevice, Irp);
+}
+
+VOID STDCALL
+SerialReceiveByte(
+       IN PKDPC Dpc,
+       IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION
+       IN PVOID Unused1,
+       IN PVOID Unused2)
+{
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       PUCHAR ComPortBase;
+       UCHAR Byte;
+       KIRQL Irql;
+       UCHAR IER;
+       NTSTATUS Status;
+       
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       
+       KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+       while (READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DATA_RECEIVED)
+       {
+               Byte = READ_PORT_UCHAR(SER_RBR(ComPortBase));
+               DPRINT("Serial: Byte received on COM%lu: 0x%02x\n",
+                       DeviceExtension->ComPort, Byte);
+               Status = PushCircularBufferEntry(&DeviceExtension->InputBuffer, Byte);
+               if (NT_SUCCESS(Status))
+                       DeviceExtension->SerialPerfStats.ReceivedCount++;
+               else
+                       DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++;
+       }
+       KeSetEvent(&DeviceExtension->InputBufferNotEmpty, 0, FALSE);
+       KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
+       
+       /* allow new interrupts */
+       IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+       WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_DATA_RECEIVED);
+}
+
+VOID STDCALL
+SerialSendByte(
+       IN PKDPC Dpc,
+       IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION
+       IN PVOID Unused1,
+       IN PVOID Unused2)
+{
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       PUCHAR ComPortBase;
+       UCHAR Byte;
+       KIRQL Irql;
+       UCHAR IER;
+       NTSTATUS Status;
+       
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)pDeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       
+       KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
+       while (!IsCircularBufferEmpty(&DeviceExtension->OutputBuffer)
+               && READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_THR_EMPTY)
+       {
+               Status = PopCircularBufferEntry(&DeviceExtension->OutputBuffer, &Byte);
+               if (!NT_SUCCESS(Status))
+                       break;
+               WRITE_PORT_UCHAR(SER_THR(ComPortBase), Byte);
+               DPRINT("Serial: Byte sent to COM%lu: 0x%02x\n",
+                       DeviceExtension->ComPort, Byte);
+               DeviceExtension->SerialPerfStats.TransmittedCount++;
+       }
+       KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+       
+       /* allow new interrupts */
+       IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+       WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_THR_EMPTY);
+}
+
+BOOLEAN STDCALL
+SerialInterruptService(
+       IN PKINTERRUPT Interrupt,
+       IN OUT PVOID ServiceContext)
+{
+       PDEVICE_OBJECT DeviceObject;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       PUCHAR ComPortBase;
+       UCHAR Iir;
+       
+       DeviceObject = (PDEVICE_OBJECT)ServiceContext;
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       
+       Iir = READ_PORT_UCHAR(SER_IIR(ComPortBase));
+       if (Iir == 0xff)
+               return TRUE;
+       Iir &= SR_IIR_ID_MASK;
+       if ((Iir & SR_IIR_SELF) != 0) { return FALSE; }
+       
+       switch (Iir)
+       {
+               case SR_IIR_MSR_CHANGE:
+               {
+                       UCHAR MSR, IER;
+                       DPRINT("Serial: SR_IIR_MSR_CHANGE\n");
+                       
+                       MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
+                       if (MSR & SR_MSR_CTS_CHANGED)
+                       {
+                               if (MSR & SR_MSR_CTS)
+                                       KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
+                               else
+                                       ; /* FIXME: stop transmission */
+                       }
+                       if (MSR & SR_MSR_DSR_CHANGED)
+                       {
+                               if (MSR & SR_MSR_DSR)
+                                       KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
+                               else
+                                       ; /* FIXME: stop reception */
+                       }
+                       IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+                       WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER | SR_IER_MSR_CHANGE);
+                       return TRUE;
+               }
+               case SR_IIR_THR_EMPTY:
+               {
+                       DPRINT("Serial: SR_IIR_THR_EMPTY\n");
+                       
+                       KeInsertQueueDpc(&DeviceExtension->SendByteDpc, NULL, NULL);
+                       return TRUE;
+               }
+               case SR_IIR_DATA_RECEIVED:
+               {
+                       DPRINT("Serial: SR_IIR_DATA_RECEIVED\n");
+                       
+                       KeInsertQueueDpc(&DeviceExtension->ReceivedByteDpc, NULL, NULL);
+                       return TRUE;
+               }
+               case SR_IIR_ERROR:
+               {
+                       UCHAR LSR;
+                       DPRINT("Serial: SR_IIR_ERROR\n");
+                       
+                       LSR = READ_PORT_UCHAR(SER_LSR(ComPortBase));
+                       if (LSR & SR_LSR_OVERRUN_ERROR)
+                               InterlockedIncrement(&DeviceExtension->SerialPerfStats.SerialOverrunErrorCount);
+                       if (LSR & SR_LSR_PARITY_ERROR)
+                               InterlockedIncrement(&DeviceExtension->SerialPerfStats.ParityErrorCount);
+                       if (LSR & SR_LSR_FRAMING_ERROR)
+                               InterlockedIncrement(&DeviceExtension->SerialPerfStats.FrameErrorCount);
+                       if (LSR & SR_LSR_BREAK_INT)
+                               InterlockedIncrement(&DeviceExtension->BreakInterruptErrorCount);
+                       
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
diff --git a/reactos/drivers/dd/serial/pnp.c b/reactos/drivers/dd/serial/pnp.c
new file mode 100644 (file)
index 0000000..211f7ae
--- /dev/null
@@ -0,0 +1,389 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/pnp.c
+ * PURPOSE:         Serial IRP_MJ_PNP operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+/* FIXME: call IoAcquireRemoveLock/IoReleaseRemoveLock around each I/O operation */
+
+#define INITGUID
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialAddDeviceInternal(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo,
+       IN UART_TYPE UartType,
+       IN PULONG pComPortNumber OPTIONAL,
+       OUT PDEVICE_OBJECT* pFdo OPTIONAL)
+{
+       PDEVICE_OBJECT Fdo = NULL;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension = NULL;
+       NTSTATUS Status;
+       WCHAR DeviceNameBuffer[32];
+       UNICODE_STRING DeviceName;
+       //UNICODE_STRING SymbolicLinkName;
+       static ULONG DeviceNumber = 0;
+       static ULONG ComPortNumber = 1;
+
+       DPRINT("Serial: SerialAddDeviceInternal called\n");
+   
+       /* Create new device object */
+       swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceNumber);
+       RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
+       Status = IoCreateDevice(DriverObject,
+                               sizeof(SERIAL_DEVICE_EXTENSION),
+                               &DeviceName,
+                               FILE_DEVICE_SERIAL_PORT,
+                               FILE_DEVICE_SECURE_OPEN,
+                               FALSE,
+                               &Fdo);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoCreateDevice() failed with status 0x%08x\n", Status);
+               Fdo = NULL;
+               goto ByeBye;
+       }
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)Fdo->DeviceExtension;
+       RtlZeroMemory(DeviceExtension, sizeof(SERIAL_DEVICE_EXTENSION));
+       
+       /* Register device interface */
+#if 0 /* FIXME: activate */
+       Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_COMPORT, NULL, &SymbolicLinkName);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoRegisterDeviceInterface() failed with status 0x%08x\n", Status);
+               goto ByeBye;
+       }
+       DPRINT1("Serial: IoRegisterDeviceInterface() returned '%wZ'\n", &SymbolicLinkName);
+       Status = IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoSetDeviceInterfaceState() failed with status 0x%08x\n", Status);
+               goto ByeBye;
+       }
+       RtlFreeUnicodeString(&SymbolicLinkName);
+#endif
+
+       DeviceExtension->SerialPortNumber = DeviceNumber++;
+       if (pComPortNumber == NULL)
+               DeviceExtension->ComPort = ComPortNumber++;
+       else
+               DeviceExtension->ComPort = *pComPortNumber;
+       DeviceExtension->Pdo = Pdo;
+       DeviceExtension->PnpState = dsStopped;
+       DeviceExtension->UartType = UartType;
+       Status = InitializeCircularBuffer(&DeviceExtension->InputBuffer, 16);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       Status = InitializeCircularBuffer(&DeviceExtension->OutputBuffer, 16);
+       if (!NT_SUCCESS(Status)) goto ByeBye;
+       IoInitializeRemoveLock(&DeviceExtension->RemoveLock, SERIAL_TAG, 0, 0);
+       KeInitializeSpinLock(&DeviceExtension->InputBufferLock);
+       KeInitializeSpinLock(&DeviceExtension->OutputBufferLock);
+       KeInitializeEvent(&DeviceExtension->InputBufferNotEmpty, NotificationEvent, FALSE);
+       KeInitializeDpc(&DeviceExtension->ReceivedByteDpc, SerialReceiveByte, DeviceExtension);
+       KeInitializeDpc(&DeviceExtension->SendByteDpc, SerialSendByte, DeviceExtension);
+       Fdo->Flags |= DO_POWER_PAGABLE;
+       Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08x\n", Status);
+               goto ByeBye;
+       }
+       Fdo->Flags |= DO_BUFFERED_IO;
+       Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+       if (pFdo)
+       {
+               *pFdo = Fdo;
+       }
+       
+       return STATUS_SUCCESS;
+
+ByeBye:
+       if (Fdo)
+       {
+               FreeCircularBuffer(&DeviceExtension->InputBuffer);
+               FreeCircularBuffer(&DeviceExtension->OutputBuffer);
+               IoDeleteDevice(Fdo);
+       }
+       return Status;
+}
+
+NTSTATUS STDCALL
+SerialAddDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo)
+{
+       /* Serial.sys is a legacy driver. AddDevice is called once
+        * with a NULL Pdo just after the driver initialization.
+        * Detect this case and return success.
+        */
+       if (Pdo == NULL)
+               return STATUS_SUCCESS;
+       
+       /* We have here a PDO that does not correspond to a legacy
+        * serial port. So call the internal AddDevice function.
+        */
+       return SerialAddDeviceInternal(DriverObject, Pdo, UartUnknown, NULL, NULL);
+
+
+}
+
+NTSTATUS STDCALL
+SerialPnpStartDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PCM_RESOURCE_LIST ResourceList)
+{
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       WCHAR DeviceNameBuffer[32];
+       UNICODE_STRING DeviceName;
+       WCHAR LinkNameBuffer[32];
+       UNICODE_STRING LinkName;
+       WCHAR ComPortBuffer[32];
+       UNICODE_STRING ComPort;
+       ULONG Vector = 0;
+       ULONG i, j;
+       UCHAR IER;
+       KIRQL Dirql;
+       KAFFINITY Affinity = 0;
+       KINTERRUPT_MODE InterruptMode = Latched;
+       BOOLEAN ShareInterrupt = TRUE;
+       OBJECT_ATTRIBUTES objectAttributes;
+       PUCHAR ComPortBase;
+       UNICODE_STRING KeyName;
+       HANDLE hKey;
+       NTSTATUS Status;
+       
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       
+       ASSERT(DeviceExtension->PnpState == dsStopped);
+       
+       DeviceExtension->BaudRate = 19200 | SERIAL_BAUD_USER;
+       DeviceExtension->BaseAddress = 0;
+       Dirql = 0;
+       for (i = 0; i < ResourceList->Count; i++)
+       {
+               for (j = 0; j < ResourceList->List[i].PartialResourceList.Count; j++)
+               {
+                       PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[i].PartialResourceList.PartialDescriptors[j];
+                       switch (PartialDescriptor->Type)
+                       {
+                               case CmResourceTypePort:
+                                       if (PartialDescriptor->u.Port.Length < 8)
+                                               return STATUS_INSUFFICIENT_RESOURCES;
+                                       if (DeviceExtension->BaseAddress != 0)
+                                               return STATUS_UNSUCCESSFUL;
+                                       DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
+                                       break;
+                               case CmResourceTypeInterrupt:
+                                       if (Dirql != 0)
+                                               return STATUS_UNSUCCESSFUL;
+                                       Dirql = (KIRQL)PartialDescriptor->u.Interrupt.Level;
+                                       Vector = PartialDescriptor->u.Interrupt.Vector;
+                                       Affinity = PartialDescriptor->u.Interrupt.Affinity;
+                                       if (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
+                                               InterruptMode = Latched;
+                                       else
+                                               InterruptMode = LevelSensitive;
+                                       ShareInterrupt = (PartialDescriptor->ShareDisposition == CmResourceShareShared);
+                                       break;
+                       }
+               }
+       }
+       DPRINT("Serial: New COM port. Base = 0x%lx, Irql = %u\n",
+               DeviceExtension->BaseAddress, Dirql);
+       if (!DeviceExtension->BaseAddress)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       if (!Dirql)
+               return STATUS_INSUFFICIENT_RESOURCES;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       
+       if (DeviceExtension->UartType == UartUnknown)
+               DeviceExtension->UartType = SerialDetectUartType(ComPortBase);
+       
+       /* Get current settings */
+       DeviceExtension->MCR = READ_PORT_UCHAR(SER_MCR(ComPortBase));
+       DeviceExtension->MSR = READ_PORT_UCHAR(SER_MSR(ComPortBase));
+       DeviceExtension->WaitMask = 0;
+       
+       /* Set baud rate */
+       Status = SerialSetBaudRate(DeviceExtension, DeviceExtension->BaudRate);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: SerialSetBaudRate() failed with status 0x%08x\n", Status);
+               return Status;
+       }
+       
+       /* Set line control */
+       DeviceExtension->SerialLineControl.StopBits = STOP_BIT_1;
+       DeviceExtension->SerialLineControl.Parity = NO_PARITY;
+       DeviceExtension->SerialLineControl.WordLength = 8;
+       Status = SerialSetLineControl(DeviceExtension, &DeviceExtension->SerialLineControl);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: SerialSetLineControl() failed with status 0x%08x\n", Status);
+               return Status;
+       }
+       
+       /* Clear receive/transmit buffers */
+       if (DeviceExtension->UartType >= Uart16550A)
+       {
+               /* 16550 UARTs also have FIFO queues, but they are unusable due to a bug */
+               WRITE_PORT_UCHAR(SER_FCR(ComPortBase),
+                       SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT);
+       }
+       
+       /* Create link \DosDevices\COMX -> \Device\SerialX */
+       swprintf(DeviceNameBuffer, L"\\Device\\Serial%lu", DeviceExtension->SerialPortNumber);
+       swprintf(LinkNameBuffer, L"\\DosDevices\\COM%lu", DeviceExtension->ComPort);
+       swprintf(ComPortBuffer, L"COM%lu", DeviceExtension->ComPort);
+       RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
+       RtlInitUnicodeString(&LinkName, LinkNameBuffer);
+       RtlInitUnicodeString(&ComPort, ComPortBuffer);
+       Status = IoCreateSymbolicLink(&LinkName, &DeviceName);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoCreateSymbolicLink() failed with status 0x%08x\n", Status);
+               return Status;
+       }
+       
+       /* Connect interrupt and enable them */
+       Status = IoConnectInterrupt(
+               &DeviceExtension->Interrupt, SerialInterruptService,
+               DeviceObject, NULL,
+               Vector, Dirql, Dirql,
+               InterruptMode, ShareInterrupt,
+               Affinity, FALSE);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT("Serial: IoConnectInterrupt() failed with status 0x%08x\n", Status);
+               IoDeleteSymbolicLink(&LinkName);
+               return Status;
+       }
+       
+       /* Write an entry value under HKLM\HARDWARE\DeviceMap\SERIALCOMM */
+       /* This step is not mandatory, so don't exit in case of error */
+       RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE\\DeviceMap\\SERIALCOMM");
+       InitializeObjectAttributes(&objectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+       Status = ZwCreateKey(&hKey, KEY_SET_VALUE, &objectAttributes, 0, NULL, REG_OPTION_VOLATILE, NULL);
+       if (NT_SUCCESS(Status))
+       {
+               /* Key = \Device\Serialx, Value = COMx */
+               ZwSetValueKey(hKey, &DeviceName, 0, REG_SZ, &ComPortBuffer, ComPort.Length + sizeof(WCHAR));
+               ZwClose(hKey);
+       }
+       
+       DeviceExtension->PnpState = dsStarted;
+       
+       /* Activate interrupt modes */
+       IER = READ_PORT_UCHAR(SER_IER(ComPortBase));
+       IER |= SR_IER_DATA_RECEIVED | SR_IER_THR_EMPTY | SR_IER_LSR_CHANGE | SR_IER_MSR_CHANGE;
+       WRITE_PORT_UCHAR(SER_IER(ComPortBase), IER);
+       
+       /* Activate DTR, RTS */
+       DeviceExtension->MCR |= SR_MCR_DTR | SR_MCR_RTS;
+       WRITE_PORT_UCHAR(SER_MCR(ComPortBase), DeviceExtension->MCR);
+       
+       return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+SerialPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       ULONG MinorFunction;
+       PIO_STACK_LOCATION Stack;
+       ULONG_PTR Information = 0;
+       NTSTATUS Status;
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       MinorFunction = Stack->MinorFunction;
+       
+       switch (MinorFunction)
+       {
+               case IRP_MN_START_DEVICE:
+               {
+                       BOOLEAN ConflictDetected;
+                       DPRINT("Serial: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+                       
+                       /* FIXME: first HACK: PnP manager can send multiple
+                        * IRP_MN_START_DEVICE for one device
+                        */
+                       if (((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PnpState != dsStopped)
+                       {
+                               DPRINT1("Serial: device already started. Ignoring this irp!\n");
+                               Status = STATUS_SUCCESS;
+                               break;
+                       }
+                       /* FIXME: second HACK: verify that we have some allocated resources.
+                        * It seems not to be always the case on some hardware
+                        */
+                       if (Stack->Parameters.StartDevice.AllocatedResources == NULL)
+                       {
+                               DPRINT1("Serial: no allocated resources. Can't start COM%lu\n",
+                                       ((PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ComPort);
+                               Status = STATUS_INSUFFICIENT_RESOURCES;
+                               break;
+                       }
+                       /* FIXME: third HACK: verify that we don't have resource conflict,
+                        * because PnP manager doesn't do it automatically
+                        */
+                       Status = IoReportResourceForDetection(
+                               DeviceObject->DriverObject, Stack->Parameters.StartDevice.AllocatedResources, 0,
+                               NULL, NULL, 0,
+                               &ConflictDetected);
+                       if (!NT_SUCCESS(Status))
+                       {
+                               Irp->IoStatus.Information = 0;
+                               Irp->IoStatus.Status = Status;
+                               IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                               return Status;
+                       }
+                       
+                       /* Call lower driver */
+                       Status = ForwardIrpAndWait(DeviceObject, Irp);
+                       if (NT_SUCCESS(Status))
+                               Status = SerialPnpStartDevice(
+                                       DeviceObject,
+                                       Stack->Parameters.StartDevice.AllocatedResources);
+                       break;
+               }
+               /* IRP_MN_QUERY_STOP_DEVICE (FIXME: required) */
+               /* IRP_MN_STOP_DEVICE (FIXME: required) */
+               /* IRP_MN_CANCEL_STOP_DEVICE (FIXME: required) */
+               /* IRP_MN_QUERY_REMOVE_DEVICE (FIXME: required) */
+               /* case IRP_MN_REMOVE_DEVICE (FIXME: required) */
+               /*{
+                       DPRINT("Serial: IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
+                       IoAcquireRemoveLock
+                       IoReleaseRemoveLockAndWait
+                       pass request to DeviceExtension-LowerDriver
+                       IoDeleteDevice(Fdo) and/or IoDetachDevice
+                       break;
+               }*/
+               /* IRP_MN_CANCEL_REMOVE_DEVICE (FIXME: required) */
+               /* IRP_MN_SURPRISE_REMOVAL (FIXME: required) */
+               /* IRP_MN_QUERY_CAPABILITIES (optional) */
+               /* IRP_MN_QUERY_PNP_DEVICE_STATE (optional) */
+               /* IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional) */
+               /* IRP_MN_DEVICE_USAGE_NOTIFICATION (FIXME: required or optional ???) */
+               /* IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) */
+               /* IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) */
+               /* IRP_MN_QUERY_INTERFACE (optional) */
+               default:
+               {
+                       DPRINT1("Serial: unknown minor function 0x%x\n", MinorFunction);
+                       return ForwardIrpAndForget(DeviceObject, Irp);
+               }
+       }
+       
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
diff --git a/reactos/drivers/dd/serial/power.c b/reactos/drivers/dd/serial/power.c
new file mode 100644 (file)
index 0000000..75249ce
--- /dev/null
@@ -0,0 +1,24 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/power.c
+ * PURPOSE:         Serial IRP_MJ_POWER operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+NTSTATUS STDCALL
+SerialPower(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       DPRINT("Serial: IRP_MJ_POWER dispatch\n");
+       Irp->IoStatus.Information = 0;
+       Irp->IoStatus.Status = STATUS_SUCCESS;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/dd/serial/rw.c b/reactos/drivers/dd/serial/rw.c
new file mode 100644 (file)
index 0000000..f58b4f2
--- /dev/null
@@ -0,0 +1,305 @@
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/create.c
+ * PURPOSE:         Serial IRP_MJ_READ/IRP_MJ_WRITE operations
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
+ */
+
+#define NDEBUG
+#include "serial.h"
+
+static PVOID
+SerialGetUserBuffer(IN PIRP Irp)
+{
+       ASSERT(Irp);
+       
+       return Irp->AssociatedIrp.SystemBuffer;
+}
+
+static VOID
+ReadBytes(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       PWORKITEM_DATA WorkItemData)
+{
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       PUCHAR ComPortBase;
+       ULONG Length;
+       PUCHAR Buffer;
+       UCHAR ReceivedByte;
+       KTIMER TotalTimeoutTimer;
+       KIRQL Irql;
+       ULONG ObjectCount;
+       PVOID ObjectsArray[2];
+       ULONG_PTR Information = 0;
+       NTSTATUS Status;
+       
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length;
+       Buffer = SerialGetUserBuffer(Irp);
+       
+       DPRINT("Serial: UseIntervalTimeout = %s, IntervalTimeout = %lu\n",
+               WorkItemData->UseIntervalTimeout ? "YES" : "NO",
+               WorkItemData->UseIntervalTimeout ? WorkItemData->IntervalTimeout.QuadPart : 0);
+       DPRINT("Serial: UseTotalTimeout = %s\n",
+               WorkItemData->UseTotalTimeout ? "YES" : "NO");
+       
+       ObjectCount = 1;
+       ObjectsArray[0] = &DeviceExtension->InputBufferNotEmpty;
+       if (WorkItemData->UseTotalTimeout)
+       {
+               KeInitializeTimer(&TotalTimeoutTimer);
+               KeSetTimer(&TotalTimeoutTimer, WorkItemData->TotalTimeoutTime, NULL);
+               ObjectsArray[ObjectCount] = &TotalTimeoutTimer;
+               ObjectCount++;
+       }
+       
+       /* while buffer is not fully filled */
+       while (Length > 0)
+       {
+               /* read already received bytes from buffer */
+               KeAcquireSpinLock(&DeviceExtension->InputBufferLock, &Irql);
+               while (!IsCircularBufferEmpty(&DeviceExtension->InputBuffer)
+                       && Length > 0)
+               {
+                       PopCircularBufferEntry(&DeviceExtension->InputBuffer, &ReceivedByte);
+                       DPRINT("Serial: reading byte from buffer: 0x%02x\n", ReceivedByte);
+                       
+                       Buffer[Information++] = ReceivedByte;
+                       Length--;
+               }
+               KeClearEvent(&DeviceExtension->InputBufferNotEmpty);
+               KeReleaseSpinLock(&DeviceExtension->InputBufferLock, Irql);
+               
+               if (WorkItemData->DontWait
+                       && !(WorkItemData->ReadAtLeastOneByte && Information == 0))
+               {
+                       DPRINT("Serial: buffer empty. Don't wait more bytes\n");
+                       break;
+               }
+               
+               Status = KeWaitForMultipleObjects(
+                       ObjectCount,
+                       ObjectsArray,
+                       WaitAny,
+                       Executive,
+                       KernelMode,
+                       FALSE,
+                       (WorkItemData->UseIntervalTimeout && Information > 0) ? &WorkItemData->IntervalTimeout : NULL,
+                       NULL);
+               
+               if (Status == STATUS_TIMEOUT /* interval timeout */
+                       || Status == STATUS_WAIT_1) /* total timeout */
+               {
+                       DPRINT("Serial: timeout when reading bytes. Status = 0x%08lx\n", Status);
+                       break;
+               }
+       }
+       
+       /* stop total timeout timer */
+       if (WorkItemData->UseTotalTimeout)
+               KeCancelTimer(&TotalTimeoutTimer);
+       
+       Irp->IoStatus.Information = Information;
+       if (Information == 0)
+               Irp->IoStatus.Status = STATUS_TIMEOUT;
+       else
+               Irp->IoStatus.Status = STATUS_SUCCESS;
+}
+
+static VOID STDCALL
+SerialReadWorkItem(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PVOID pWorkItemData /* real type PWORKITEM_DATA */)
+{
+       PWORKITEM_DATA WorkItemData;
+       PIRP Irp;
+       
+       DPRINT("Serial: SerialReadWorkItem() called\n");
+       
+       WorkItemData = (PWORKITEM_DATA)pWorkItemData;
+       Irp = WorkItemData->Irp;
+       
+       ReadBytes(DeviceObject, Irp, WorkItemData);
+       
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       
+       IoFreeWorkItem(WorkItemData->IoWorkItem);
+       ExFreePoolWithTag(pWorkItemData, SERIAL_TAG);
+}
+
+NTSTATUS STDCALL
+SerialRead(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PIO_STACK_LOCATION Stack;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       ULONG Length;
+       PUCHAR Buffer;
+       PWORKITEM_DATA WorkItemData;
+       PIO_WORKITEM WorkItem;
+       NTSTATUS Status;
+       
+       DPRINT("Serial: IRP_MJ_READ\n");
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       Length = Stack->Parameters.Read.Length;
+       Buffer = SerialGetUserBuffer(Irp);
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       
+       if (Stack->Parameters.Read.ByteOffset.QuadPart != 0 || Buffer == NULL)
+       {
+               Status = STATUS_INVALID_PARAMETER;
+               goto ByeBye;
+       }
+       
+       if (Length == 0)
+       {
+               Status = STATUS_SUCCESS;
+               goto ByeBye;
+       }
+       
+       /* Allocate memory for parameters */
+       WorkItemData = ExAllocatePoolWithTag(PagedPool, sizeof(WORKITEM_DATA), SERIAL_TAG);
+       if (!WorkItemData)
+       {
+               Status = STATUS_INSUFFICIENT_RESOURCES;
+               goto ByeBye;
+       }
+       RtlZeroMemory(WorkItemData, sizeof(WORKITEM_DATA));
+       WorkItemData->Irp = Irp;
+       
+       /* Calculate time outs */
+       if (DeviceExtension->SerialTimeOuts.ReadIntervalTimeout == INFINITE &&
+                DeviceExtension->SerialTimeOuts.ReadTotalTimeoutMultiplier == INFINITE &&
+                DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant > 0 &&
+                DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant < INFINITE)
+       {
+               /* read at least one byte, and at most bytes already received */
+               WorkItemData->DontWait = TRUE;
+               WorkItemData->ReadAtLeastOneByte = TRUE;
+       }
+       else if (DeviceExtension->SerialTimeOuts.ReadIntervalTimeout == INFINITE &&
+                DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant == 0 &&
+                DeviceExtension->SerialTimeOuts.ReadTotalTimeoutMultiplier == 0)
+       {
+               /* read only bytes that are already in buffer */
+               WorkItemData->DontWait = TRUE;
+       }
+       else
+       {
+               /* use timeouts */
+               if (DeviceExtension->SerialTimeOuts.ReadIntervalTimeout != 0)
+                       {
+                               WorkItemData->UseIntervalTimeout = TRUE;
+                               WorkItemData->IntervalTimeout.QuadPart = DeviceExtension->SerialTimeOuts.ReadIntervalTimeout;
+               }
+               if (DeviceExtension->SerialTimeOuts.ReadTotalTimeoutMultiplier != 0 ||
+                        DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant != 0)
+               {
+                       ULONG TotalTimeout;
+                       LARGE_INTEGER SystemTime;
+                       
+                       WorkItemData->UseTotalTimeout = TRUE;
+                       TotalTimeout = DeviceExtension->SerialTimeOuts.ReadTotalTimeoutConstant +
+                               DeviceExtension->SerialTimeOuts.ReadTotalTimeoutMultiplier * Length;
+                       KeQuerySystemTime(&SystemTime);
+                       WorkItemData->TotalTimeoutTime.QuadPart = SystemTime.QuadPart +
+                               TotalTimeout * 10000;
+               }
+       }
+       
+       /* Pend IRP */
+       WorkItem = IoAllocateWorkItem(DeviceObject);
+       if (WorkItem)
+       {
+                WorkItemData->IoWorkItem = WorkItem;
+                IoQueueWorkItem(WorkItem, SerialReadWorkItem, DelayedWorkQueue, WorkItemData);
+               IoMarkIrpPending(Irp);
+               return STATUS_PENDING;
+       }
+       
+       /* insufficient resources, we can't pend the Irp */
+       CHECKPOINT;
+       Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+       if (!NT_SUCCESS(Status))
+       {
+               ExFreePoolWithTag(WorkItemData, SERIAL_TAG);
+               goto ByeBye;
+       }
+       ReadBytes(DeviceObject, Irp, WorkItemData);
+       Status = Irp->IoStatus.Status;
+       
+       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+
+ByeBye:
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
+
+NTSTATUS STDCALL
+SerialWrite(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp)
+{
+       PIO_STACK_LOCATION Stack;
+       PSERIAL_DEVICE_EXTENSION DeviceExtension;
+       ULONG Length;
+       ULONG_PTR Information = 0;
+       PUCHAR Buffer;
+       PUCHAR ComPortBase;
+       KIRQL Irql;
+       NTSTATUS Status = STATUS_SUCCESS;
+       
+       DPRINT("Serial: IRP_MJ_WRITE\n");
+       
+       /* FIXME: pend operation if possible */
+       /* FIXME: use write timeouts */
+       
+       Stack = IoGetCurrentIrpStackLocation(Irp);
+       Length = Stack->Parameters.Write.Length;
+       Buffer = SerialGetUserBuffer(Irp);
+       DeviceExtension = (PSERIAL_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       ComPortBase = (PUCHAR)DeviceExtension->BaseAddress;
+       
+       if (Stack->Parameters.Write.ByteOffset.QuadPart != 0 || Buffer == NULL)
+       {
+               Status = STATUS_INVALID_PARAMETER;
+               goto ByeBye;
+       }
+       
+       Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+       if (!NT_SUCCESS(Status))
+               goto ByeBye;
+       
+       /* push  bytes into output buffer */
+       KeAcquireSpinLock(&DeviceExtension->OutputBufferLock, &Irql);
+       while (Information < Length)
+       {
+               Status = PushCircularBufferEntry(&DeviceExtension->OutputBuffer, Buffer[Information]);
+               if (!NT_SUCCESS(Status))
+               {
+                       DPRINT("Serial: buffer overrun on COM%lu\n", DeviceExtension->ComPort);
+                       DeviceExtension->SerialPerfStats.BufferOverrunErrorCount++;
+                       break;
+               }
+               Information++;
+       }
+       KeReleaseSpinLock(&DeviceExtension->OutputBufferLock, Irql);
+       IoReleaseRemoveLock(&DeviceExtension->RemoveLock, (PVOID)DeviceExtension->ComPort);
+       
+       /* send bytes */
+       SerialSendByte(NULL, DeviceExtension, NULL, NULL);
+
+ByeBye:
+       Irp->IoStatus.Information = Information;
+       Irp->IoStatus.Status = Status;
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+       return Status;
+}
index e5f0bb7..7d66d15 100644 (file)
-/* $Id$
- *
- * Serial driver
- * Written by Jason Filby (jasonfilby@yahoo.com)
- * For ReactOS (www.reactos.com)
- *
+/* $Id:
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/dd/serial/serial.c
+ * PURPOSE:         Serial driver loading/unloading
+ * 
+ * PROGRAMMERS:     Hervé Poussineau (poussine@freesurf.fr)
  */
 
-#include <ddk/ntddk.h>
-//#include <internal/mmhal.h>
-//#include "../../../ntoskrnl/include/internal/i386/io.h"
-//#include "../../../ntoskrnl/include/internal/io.h"
+//#define NDEBUG
+#include "serial.h"
 
-#define outb_p(a,p) WRITE_PORT_UCHAR((PUCHAR)a,p)
-#define outw_p(a,p) WRITE_PORT_USHORT((PUSHORT)a,p)
-#define inb_p(p)    READ_PORT_UCHAR((PUCHAR)p)
-
-#define NDEBUG
-#include <debug.h>
-
-
-#define COM1    0x3F8
-#define COM2    0x2F8
-#define COM3    0x3E8
-#define COM4    0x2E8
-
-#define UART_BAUDRATE   96      // 1200 BPS
-#define UART_LCRVAL     0x1b    // 0x1b for 8e1
-#define UARY_FCRVAL     0x7
-
-int uart_detect(unsigned base)
-{
-        // Returns 0 if no UART detected
-
-        outb_p(base+4, 0x10);
-        if ((inb_p(base+6) & 0xf0)) return 0;
-        return 1;
-};
-
-int irq_setup(unsigned base)
-{
-        // Returns -1 if not found -- otherwise returns interrupt level
-
-        char ier, mcr, imrm, imrs, maskm, masks, irqm, irqs;
-
-        __asm("cli");          // disable all CPU interrupts
-        ier = inb_p(base+1);   // read IER
-        outb_p(base+1,0);      // disable all UART ints
-        while (!(inb_p(base+5)&0x20));  // wait for the THR to be empty
-        mcr = inb_p(base+4);   // read MCR
-        outb_p(base+4,0x0F);   // connect UART to irq line
-        imrm = inb_p(0x21);    // read contents of master ICU mask register
-        imrs = inb_p(0xA1);    // read contents of slave ICU mask register
-        outb_p(0xA0,0x0A);     // next read access to 0xA0 reads out IRR
-        outb_p(0x20,0x0A);     // next read access to 0x20 reads out IRR
-        outb_p(base+1,2);      // let's generate interrupts...
-        maskm = inb_p(0x20);   // this clears all bits except for the one
-        masks = inb_p(0xA0);   // that corresponds to the int
-        outb_p(base+1,0);      // drop the int line
-        maskm &= ~inb_p(0x20); // this clears all bits except for the one
-        masks &= ~inb_p(0xA0); // that corresponds to the int
-        outb_p(base+1,2);      // and raise it again just to be sure...
-        maskm &= inb_p(0x20);  // this clears all bits except for the one
-        masks &= inb_p(0xA0);  // that corresponds to the int
-        outb_p(0xA1,~masks);   // now let us unmask this interrupt only
-        outb_p(0x21,~maskm);
-        outb_p(0xA0,0x0C);     // enter polled mode
-        outb_p(0x20,0x0C);     // that order is important with Pentium/PCI systems
-        irqs = inb_p(0xA0);    // and accept the interrupt
-        irqm = inb_p(0x20);
-        inb_p(base+2);         // reset transmitter interrupt in UART
-        outb_p(base+4,mcr);    // restore old value of MCR
-        outb_p(base+1,ier);    // restore old value of IER
-        if (masks) outb_p(0xA0,0x20);  // send an EOI to slave
-        if (maskm) outb_p(0x20,0x20);  // send an EOI to master
-        outb_p(0x21,imrm);     // restore old mask register contents
-        outb_p(0xA1,imrs);
-        __asm("sti");
-        if (irqs&0x80)       // slave interrupt occured
-          return (irqs&0x07)+8;
-        if (irqm&0x80)       // master interrupt occured
-          return irqm&0x07;
-        return -1;
-};
-
-void uart_init(unsigned uart_base)
-{
-        // Initialize the UART
-        outb_p(uart_base+3, 0x80);
-        outw_p(uart_base, UART_BAUDRATE);
-        outb_p(uart_base+3, UART_LCRVAL);
-        outb_p(uart_base+4, 0);
-};
-
-unsigned uart_getchar(unsigned uart_base)
+VOID STDCALL
+DriverUnload(IN PDRIVER_OBJECT DriverObject)
 {
-        unsigned x;
-
-        x=(inb_p(uart_base+5) & 0x9f) << 8;
-        if(x & 0x100) x|=((unsigned)inb_p(uart_base)) & 0xff;
-        return x;
-};
-
-void InitializeSerial(void)
-{
-        unsigned comports[4] = { COM1, COM2, COM3, COM4 };
-        char *comname[4] = { "COM1", "COM2", "COM3", "COM4" };
-        int i, irq_level;
-
-        for (i=0; i<4; i++)
-        {
-                if(uart_detect(comports[i])==0)
-                {
-                          DbgPrint("%s not detected\n", comname[i]);
-                } else {
-                          uart_init(comports[i]);
-                          irq_level=irq_setup(comports[i]);
-                          if(irq_level==-1)
-                          {
-                                    DbgPrint("Warning: IRQ not detected!\n");
-                          } else {
-                                    DbgPrint("%s hooked to interrupt level %d\n", comname[i], irq_level);
-                          };
-                };
-        };
-};
-
-// For testing purposes
-void testserial(void)
-{
-        int i=0;
-        char testc;
-
-        union {
-          unsigned val;
-          char character;
-        } x;
-
-        DbgPrint("Testing serial input...\n");
-
-        while(i==0) {
-          x.val=uart_getchar(COM1);
-//    if(!x.val) continue;
-//    if(x.val & 0x100)
-
-                testc=inb_p(COM1);
-
-//    DbgPrint("(%x-%c)  %c\n", x.val, x.character, testc);
-        };
-};
+       // nothing to do here yet
+}
 
+/*
+ * Standard DriverEntry method.
+ */
 NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+DriverEntry(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PUNICODE_STRING RegPath)
 {
-        DbgPrint("Serial Driver 0.0.2\n");
-//        InitializeSerial();
-//        testserial();
-        return(STATUS_SUCCESS);
-};
-
+       ULONG i;
+       static BOOLEAN FirstTime = TRUE;
+       
+       DriverObject->DriverUnload = DriverUnload;
+       DriverObject->DriverExtension->AddDevice = SerialAddDevice;
+       
+       for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+               DriverObject->MajorFunction[i] = ForwardIrpAndForget;
+       DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialCreate;
+       DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialClose;
+       DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SerialCleanup;
+       DriverObject->MajorFunction[IRP_MJ_READ] = SerialRead;
+       DriverObject->MajorFunction[IRP_MJ_WRITE] = SerialWrite;
+       DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SerialDeviceControl;
+       DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = SerialQueryInformation;
+       DriverObject->MajorFunction[IRP_MJ_PNP] = SerialPnp;
+       DriverObject->MajorFunction[IRP_MJ_POWER] = SerialPower;
+       
+       /* FIXME: It seems that DriverEntry function may be called more
+        * than once. Do only legacy detection the first time. */
+       if (FirstTime)
+       {
+               FirstTime = FALSE;
+               return DetectLegacyDevices(DriverObject);
+       }
+       else
+       {
+               DPRINT1("Serial: DriverEntry called for the second time!\n");
+               return STATUS_SUCCESS;
+       }
+}
diff --git a/reactos/drivers/dd/serial/serial.h b/reactos/drivers/dd/serial/serial.h
new file mode 100644 (file)
index 0000000..a57afe4
--- /dev/null
@@ -0,0 +1,353 @@
+#if defined(__GNUC__)
+  #include <ddk/ntddk.h>
+  #include <ddk/ntddser.h>
+  #include <stdio.h>
+  
+  #include <debug.h>
+  
+  /* FIXME: these prototypes MUST NOT be here! */
+  NTSTATUS STDCALL
+  IoAttachDeviceToDeviceStackSafe(
+    IN PDEVICE_OBJECT SourceDevice,
+    IN PDEVICE_OBJECT TargetDevice,
+    OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+  
+#elif defined(_MSC_VER)
+  #include <ntddk.h>
+  #include <ntddser.h>
+  #include <stdio.h>
+  
+  #define STDCALL
+  
+  #define DPRINT1 DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint
+  #define CHECKPOINT1 DbgPrint("(%s:%d)\n", __FILE__, __LINE__)
+  
+  #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
+  
+  NTSTATUS STDCALL
+  IoAttachDeviceToDeviceStackSafe(
+    IN PDEVICE_OBJECT SourceDevice,
+    IN PDEVICE_OBJECT TargetDevice,
+    OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+  
+  #ifdef NDEBUG2
+    #define DPRINT
+    #define CHECKPOINT
+  #else
+    #define DPRINT DPRINT1
+    #define CHECKPOINT CHECKPOINT1
+    #undef NDEBUG
+  #endif
+#else
+  #error Unknown compiler!
+#endif
+
+typedef enum
+{
+  dsStopped,
+  dsStarted,
+  dsPaused,
+  dsRemoved,
+  dsSurpriseRemoved
+} SERIAL_DEVICE_STATE;
+
+typedef enum
+{
+       UartUnknown,
+       Uart8250,  /* initial version */
+       Uart16450, /* + 38.4 Kbps */
+       Uart16550, /* + 115 Kbps */
+       Uart16550A,/* + FIFO 16 bytes */
+       Uart16650, /* + FIFO 32 bytes, 230 Kbps, power management, auto-flow */
+       Uart16750  /* + FIFO 64 bytes, 460 Kbps */
+} UART_TYPE;
+
+typedef struct _CIRCULAR_BUFFER
+{
+       PUCHAR Buffer;
+       ULONG Length;
+       ULONG ReadPosition;
+       ULONG WritePosition;
+} CIRCULAR_BUFFER, *PCIRCULAR_BUFFER;
+
+typedef struct _SERIAL_DEVICE_EXTENSION
+{
+       PDEVICE_OBJECT Pdo;
+       PDEVICE_OBJECT LowerDevice;
+       SERIAL_DEVICE_STATE PnpState;
+       IO_REMOVE_LOCK RemoveLock;
+       
+       ULONG SerialPortNumber;
+       
+       ULONG ComPort;
+       ULONG BaudRate;
+       ULONG BaseAddress;
+       PKINTERRUPT Interrupt;
+       KDPC ReceivedByteDpc;
+       KDPC SendByteDpc;
+       
+       SERIAL_LINE_CONTROL SerialLineControl;
+       UART_TYPE UartType;
+       ULONG WaitMask;
+       
+       ULONG BreakInterruptErrorCount;
+       SERIALPERF_STATS SerialPerfStats;
+       SERIAL_TIMEOUTS SerialTimeOuts;
+       BOOLEAN IsOpened;
+       KEVENT InputBufferNotEmpty;
+       CIRCULAR_BUFFER InputBuffer;
+       KSPIN_LOCK InputBufferLock;
+       CIRCULAR_BUFFER OutputBuffer;
+       KSPIN_LOCK OutputBufferLock;
+       
+       /* Current values */
+       UCHAR MCR; /* Base+4, Modem Control Register */
+       UCHAR MSR; /* Base+6, Modem Status Register */
+} SERIAL_DEVICE_EXTENSION, *PSERIAL_DEVICE_EXTENSION;
+
+typedef struct _WORKITEM_DATA
+{
+       PIRP Irp;
+       PIO_WORKITEM IoWorkItem;
+       
+       BOOLEAN UseIntervalTimeout;
+       BOOLEAN UseTotalTimeout;
+       LARGE_INTEGER IntervalTimeout;
+       LARGE_INTEGER TotalTimeoutTime;
+       BOOLEAN DontWait;
+       BOOLEAN ReadAtLeastOneByte;
+} WORKITEM_DATA, *PWORKITEM_DATA;
+
+#define SERIAL_TAG TAG('S', 'e', 'r', 'l')
+
+#define INFINITE ((ULONG)-1)
+
+/* Baud master clock */
+#define BAUD_CLOCK      1843200
+#define CLOCKS_PER_BIT  16
+
+/* UART registers and bits */
+#define   SER_RBR(x)   ((x)+0) /* Receive Register */
+#define   SER_THR(x)   ((x)+0) /* Transmit Register */
+#define   SER_DLL(x)   ((x)+0) /* Baud Rate Divisor LSB */
+#define   SER_IER(x)   ((x)+1) /* Interrupt Enable Register */
+#define     SR_IER_DATA_RECEIVED 0x01
+#define     SR_IER_THR_EMPTY     0x02
+#define     SR_IER_LSR_CHANGE    0x04
+#define     SR_IER_MSR_CHANGE    0x08
+#define     SR_IER_SLEEP_MODE    0x10 /* Uart >= 16750 */
+#define     SR_IER_LOW_POWER     0x20 /* Uart >= 16750 */
+#define   SER_DLM(x)   ((x)+1) /* Baud Rate Divisor MSB */
+#define   SER_IIR(x)   ((x)+2) /* Interrupt Identification Register */
+#define     SR_IIR_SELF          0x00
+#define     SR_IIR_ID_MASK       0x07
+#define     SR_IIR_MSR_CHANGE    SR_IIR_SELF
+#define     SR_IIR_THR_EMPTY     (SR_IIR_SELF | 2)
+#define     SR_IIR_DATA_RECEIVED (SR_IIR_SELF | 4)
+#define     SR_IIR_ERROR         (SR_IIR_SELF | 6)
+#define   SER_FCR(x)   ((x)+2) /* FIFO Control Register (Uart >= 16550A) */
+#define     SR_FCR_ENABLE_FIFO 0x01
+#define     SR_FCR_CLEAR_RCVR  (0x02 | SR_FCR_ENABLE_FIFO)
+#define     SR_FCR_CLEAR_XMIT  (0x04 | SR_FCR_ENABLE_FIFO)
+#define     SR_FCR_1_BYTE      (0x00 | SR_FCR_ENABLE_FIFO)
+#define     SR_FCR_4_BYTES     (0x40 | SR_FCR_ENABLE_FIFO)
+#define     SR_FCR_8_BYTES     (0x80 | SR_FCR_ENABLE_FIFO)
+#define     SR_FCR_14_BYTES    (0xC0 | SR_FCR_ENABLE_FIFO)
+#define   SER_LCR(x)   ((x)+3) /* Line Control Register */
+#define     SR_LCR_CS5 0x00
+#define     SR_LCR_CS6 0x01
+#define     SR_LCR_CS7 0x02
+#define     SR_LCR_CS8 0x03
+#define     SR_LCR_ST1 0x00
+#define     SR_LCR_ST2 0x04
+#define     SR_LCR_PNO 0x00
+#define     SR_LCR_POD 0x08
+#define     SR_LCR_PEV 0x18
+#define     SR_LCR_PMK 0x28
+#define     SR_LCR_PSP 0x38
+#define     SR_LCR_BRK 0x40
+#define     SR_LCR_DLAB 0x80
+#define   SER_MCR(x)   ((x)+4) /* Modem Control Register */
+#define     SR_MCR_DTR 0x01
+#define     SR_MCR_RTS 0x02
+#define   SER_LSR(x)   ((x)+5) /* Line Status Register */
+#define     SR_LSR_DATA_RECEIVED  0x01
+#define     SR_LSR_OVERRUN_ERROR  0x02
+#define     SR_LSR_PARITY_ERROR   0x04
+#define     SR_LSR_FRAMING_ERROR  0x08
+#define     SR_LSR_BREAK_INT      0x10
+#define     SR_LSR_THR_EMPTY      0x20
+#define     SR_LSR_TSR_EMPTY      0x40
+#define     SR_LSR_ERROR_IN_FIFO  0x80 /* Uart >= 16550A */
+#define   SER_MSR(x)   ((x)+6) /* Modem Status Register */
+#define     SR_MSR_CTS_CHANGED    0x01
+#define     SR_MSR_DSR_CHANGED    0x02
+#define     SR_MSR_RI_CHANGED     0x04
+#define     SR_MSR_DCD_CHANGED    0x08
+#define     SR_MSR_CTS            0x10 /* Clear To Send */
+#define     SR_MSR_DSR            0x20 /* Data Set Ready */
+#define     SI_MSR_RI             0x40 /* Ring Indicator */
+#define     SR_MSR_DCD            0x80 /* Data Carrier Detect */
+#define   SER_SCR(x)   ((x)+7) /* Scratch Pad Register */
+
+/************************************ circularbuffer.c */
+
+/* FIXME: transform these functions into #define? */
+NTSTATUS
+InitializeCircularBuffer(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN ULONG BufferSize);
+
+NTSTATUS
+FreeCircularBuffer(
+       IN PCIRCULAR_BUFFER pBuffer);
+
+BOOLEAN
+IsCircularBufferEmpty(
+       IN PCIRCULAR_BUFFER pBuffer);
+
+NTSTATUS
+PushCircularBufferEntry(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN UCHAR Entry);
+
+NTSTATUS
+PopCircularBufferEntry(
+       IN PCIRCULAR_BUFFER pBuffer,
+       OUT PUCHAR Entry);
+
+NTSTATUS
+IncreaseCircularBufferSize(
+       IN PCIRCULAR_BUFFER pBuffer,
+       IN ULONG NewBufferSize);
+
+/************************************ cleanup.c */
+
+NTSTATUS STDCALL
+SerialCleanup(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ close.c */
+
+NTSTATUS STDCALL
+SerialClose(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ create.c */
+
+NTSTATUS STDCALL
+SerialCreate(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ devctrl.c */
+
+NTSTATUS STDCALL
+SerialDeviceControl(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+SerialSetBaudRate(
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
+       IN ULONG NewBaudRate);
+
+NTSTATUS STDCALL
+SerialSetLineControl(
+       IN PSERIAL_DEVICE_EXTENSION DeviceExtension,
+       IN PSERIAL_LINE_CONTROL NewSettings);
+
+/************************************ info.c */
+
+NTSTATUS STDCALL
+SerialQueryInformation(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ legacy.c */
+
+UART_TYPE
+SerialDetectUartType(
+       IN PUCHAR ComPortBase);
+
+NTSTATUS
+DetectLegacyDevices(
+       IN PDRIVER_OBJECT DriverObject);
+
+/************************************ misc.c */
+
+NTSTATUS
+ForwardIrpAndWait(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+ForwardIrpAndForget(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+VOID STDCALL
+SerialReceiveByte(
+       IN PKDPC Dpc,
+       IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION
+       IN PVOID pByte,            // real type UCHAR
+       IN PVOID Unused);
+
+VOID STDCALL
+SerialSendByte(
+       IN PKDPC Dpc,
+       IN PVOID pDeviceExtension, // real type PSERIAL_DEVICE_EXTENSION
+       IN PVOID Unused1,
+       IN PVOID Unused2);
+
+BOOLEAN STDCALL
+SerialInterruptService(
+       IN PKINTERRUPT Interrupt,
+       IN OUT PVOID ServiceContext);
+
+/************************************ pnp.c */
+
+NTSTATUS STDCALL
+SerialAddDeviceInternal(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo,
+       IN UART_TYPE UartType,
+       IN PULONG pComPortNumber OPTIONAL,
+       OUT PDEVICE_OBJECT* pFdo OPTIONAL);
+
+NTSTATUS STDCALL
+SerialAddDevice(
+       IN PDRIVER_OBJECT DriverObject,
+       IN PDEVICE_OBJECT Pdo);
+
+NTSTATUS STDCALL
+SerialPnpStartDevice(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PCM_RESOURCE_LIST ResourceList);
+
+NTSTATUS STDCALL
+SerialPnp(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ power.c */
+
+NTSTATUS STDCALL
+SerialPower(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+/************************************ rw.c */
+
+NTSTATUS STDCALL
+SerialRead(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
+NTSTATUS STDCALL
+SerialWrite(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp);
+
index 4d23158..04c24f4 100644 (file)
@@ -1,6 +1,17 @@
 <module name="serial" type="kernelmodedriver" installbase="system32/drivers" installname="serial.sys">\r
+       <define name="__USE_W32API" />\r
        <library>ntoskrnl</library>\r
        <library>hal</library>\r
-       <file>serial.c</file>\r
+       <file>circularbuffer.c</file>\r
+       <file>cleanup.c</file>\r
+       <file>close.c</file>\r
+       <file>create.c</file>\r
+       <file>devctrl.c</file>\r
+       <file>info.c</file>\r
+       <file>legacy.c</file>\r
+       <file>misc.c</file>\r
+       <file>pnp.c</file>\r
+       <file>power.c</file>\r
+       <file>rw.c</file>\r
        <file>serial.rc</file>\r
 </module>\r
index 106c511..b42f0e8 100644 (file)
@@ -49,15 +49,26 @@ NpfsFindListeningServerInstance(PNPFS_PIPE Pipe)
 {
   PLIST_ENTRY CurrentEntry;
   PNPFS_WAITER_ENTRY Waiter;
+  KIRQL oldIrql;
+  PIRP Irp;
 
   CurrentEntry = Pipe->WaiterListHead.Flink;
   while (CurrentEntry != &Pipe->WaiterListHead)
     {
       Waiter = CONTAINING_RECORD(CurrentEntry, NPFS_WAITER_ENTRY, Entry);
+      Irp = CONTAINING_RECORD(Waiter, IRP, Tail.Overlay.DriverContext);
       if (Waiter->Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
        {
          DPRINT("Server found! Fcb %p\n", Waiter->Fcb);
-         return Waiter->Fcb;
+  
+         IoAcquireCancelSpinLock(&oldIrql);
+          if (!Irp->Cancel)
+           {
+             IoSetCancelRoutine(Irp, NULL);
+              IoReleaseCancelSpinLock(oldIrql);
+              return Waiter->Fcb;
+            }
+          IoReleaseCancelSpinLock(oldIrql);
        }
 
       CurrentEntry = CurrentEntry->Flink;
@@ -73,6 +84,7 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe,
 {
   PLIST_ENTRY CurrentEntry;
   PNPFS_WAITER_ENTRY Waiter;
+  PIRP Irp;
 
   CurrentEntry = Pipe->WaiterListHead.Flink;
   while (CurrentEntry != &Pipe->WaiterListHead)
@@ -82,14 +94,12 @@ NpfsSignalAndRemoveListeningServerInstance(PNPFS_PIPE Pipe,
        {
          DPRINT("Server found! Fcb %p\n", Waiter->Fcb);
 
-         KeSetEvent(Waiter->Irp->UserEvent, 0, FALSE);
-         Waiter->Irp->UserIosb->Status = FILE_PIPE_CONNECTED_STATE;
-         Waiter->Irp->UserIosb->Information = 0;
-         IoCompleteRequest(Waiter->Irp, IO_NO_INCREMENT);
-
          RemoveEntryList(&Waiter->Entry);
-         ExFreePool(Waiter);
-         return;
+         Irp = CONTAINING_RECORD(Waiter, IRP, Tail.Overlay.DriverContext);
+         Irp->IoStatus.Status = STATUS_PIPE_CONNECTED;
+         Irp->IoStatus.Information = 0;
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+         break;
        }
       CurrentEntry = CurrentEntry->Flink;
     }
@@ -142,40 +152,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
 
   KeUnlockMutex(&DeviceExt->PipeListLock);
 
-  /*
-   * Step 2. Search for listening server FCB.
-   */
-
   /*
    * Acquire the lock for FCB lists. From now on no modifications to the
    * FCB lists are allowed, because it can cause various misconsistencies.
    */
   KeLockMutex(&Pipe->FcbListLock);
 
-  if (!SpecialAccess)
-    {
-      ServerFcb = NpfsFindListeningServerInstance(Pipe);
-      if (ServerFcb == NULL)
-        {
-          /* Not found, bail out with error for FILE_OPEN requests. */
-          DPRINT("No listening server fcb found!\n");
-          KeUnlockMutex(&Pipe->FcbListLock);
-          Irp->IoStatus.Status = STATUS_PIPE_BUSY;
-          IoCompleteRequest(Irp, IO_NO_INCREMENT);
-          return STATUS_PIPE_BUSY;
-        }
-    }
-  else if (IsListEmpty(&Pipe->ServerFcbListHead))
-    {
-      DPRINT("No server fcb found!\n");
-      KeUnlockMutex(&Pipe->FcbListLock);
-      Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-      IoCompleteRequest(Irp, IO_NO_INCREMENT);
-      return STATUS_UNSUCCESSFUL;
-    }
-
   /*
-   * Step 3. Create the client FCB.
+   * Step 2. Create the client FCB.
    */
   ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
   if (ClientFcb == NULL)
@@ -192,11 +176,14 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
   ClientFcb->PipeEnd = FILE_PIPE_CLIENT_END;
   ClientFcb->OtherSide = NULL;
   ClientFcb->PipeState = SpecialAccess ? 0 : FILE_PIPE_DISCONNECTED_STATE;
+  InitializeListHead(&ClientFcb->ReadRequestListHead);
+
+  DPRINT("Fcb: %x\n", ClientFcb);
 
   /* Initialize data list. */
   if (Pipe->OutboundQuota)
     {
-      ClientFcb->Data = ExAllocatePool(NonPagedPool, Pipe->OutboundQuota);
+      ClientFcb->Data = ExAllocatePool(PagedPool, Pipe->OutboundQuota);
       if (ClientFcb->Data == NULL)
         {
           DPRINT("No memory!\n");
@@ -217,9 +204,78 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
   ClientFcb->ReadDataAvailable = 0;
   ClientFcb->WriteQuotaAvailable = Pipe->OutboundQuota;
   ClientFcb->MaxDataLength = Pipe->OutboundQuota;
-  KeInitializeSpinLock(&ClientFcb->DataListLock);
+  ExInitializeFastMutex(&ClientFcb->DataListLock);
   KeInitializeEvent(&ClientFcb->ConnectEvent, SynchronizationEvent, FALSE);
-  KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
+  KeInitializeEvent(&ClientFcb->ReadEvent, SynchronizationEvent, FALSE);
+  KeInitializeEvent(&ClientFcb->WriteEvent, SynchronizationEvent, FALSE);
+
+
+  /*
+   * Step 3. Search for listening server FCB.
+   */
+
+  if (!SpecialAccess)
+    {
+      /*
+       * WARNING: Point of no return! Once we get the server FCB it's
+       * possible that we completed a wait request and so we have to
+       * complete even this request.
+       */
+
+      ServerFcb = NpfsFindListeningServerInstance(Pipe);
+      if (ServerFcb == NULL)
+        {
+          PLIST_ENTRY CurrentEntry;
+          PNPFS_FCB Fcb;
+
+          /*
+           * If no waiting server FCB was found then try to pick
+           * one of the listing server FCB on the pipe.
+           */
+
+          CurrentEntry = Pipe->ServerFcbListHead.Flink;
+          while (CurrentEntry != &Pipe->ServerFcbListHead)
+            {
+              Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB, FcbListEntry);
+              if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+                {
+                  ServerFcb = Fcb;
+                  break;
+                }
+              CurrentEntry = CurrentEntry->Flink;
+            }
+
+          /*
+           * No one is listening to me?! I'm so lonely... :(
+           */
+
+          if (ServerFcb == NULL)
+            {
+              /* Not found, bail out with error for FILE_OPEN requests. */
+              DPRINT("No listening server fcb found!\n");
+              if (ClientFcb->Data)
+                ExFreePool(ClientFcb->Data);
+              KeUnlockMutex(&Pipe->FcbListLock);
+              Irp->IoStatus.Status = STATUS_PIPE_BUSY;
+              IoCompleteRequest(Irp, IO_NO_INCREMENT);
+              return STATUS_PIPE_BUSY;
+            }
+        }
+      else
+        {
+          /* Signal the server thread and remove it from the waiter list */
+          /* FIXME: Merge this with the NpfsFindListeningServerInstance routine. */
+          NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
+        }
+    }
+  else if (IsListEmpty(&Pipe->ServerFcbListHead))
+    {
+      DPRINT("No server fcb found!\n");
+      KeUnlockMutex(&Pipe->FcbListLock);
+      Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      return STATUS_UNSUCCESSFUL;
+    }
 
   /*
    * Step 4. Add the client FCB to a list and connect it if possible.
@@ -235,9 +291,6 @@ NpfsCreate(PDEVICE_OBJECT DeviceObject,
       ServerFcb->OtherSide = ClientFcb;
       ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
       ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
-
-      /* Signal the server thread and remove it from the waiter list */
-      NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
     }
 
   KeUnlockMutex(&Pipe->FcbListLock);
@@ -413,13 +466,16 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
    if (Pipe->InboundQuota)
      {
-       Fcb->Data = ExAllocatePool(NonPagedPool, Pipe->InboundQuota);
+       Fcb->Data = ExAllocatePool(PagedPool, Pipe->InboundQuota);
        if (Fcb->Data == NULL)
          {
            ExFreePool(Fcb);
 
            if (NewPipe)
              {
+               KeLockMutex(&DeviceExt->PipeListLock);
+              RemoveEntryList(&Pipe->PipeListEntry);
+               KeUnlockMutex(&DeviceExt->PipeListLock);
                RtlFreeUnicodeString(&Pipe->PipeName);
                ExFreePool(Pipe);
              }
@@ -439,26 +495,25 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
    Fcb->ReadDataAvailable = 0;
    Fcb->WriteQuotaAvailable = Pipe->InboundQuota;
    Fcb->MaxDataLength = Pipe->InboundQuota;
-   KeInitializeSpinLock(&Fcb->DataListLock);
+   InitializeListHead(&Fcb->ReadRequestListHead);
+   ExInitializeFastMutex(&Fcb->DataListLock);
 
    Pipe->CurrentInstances++;
 
-   KeLockMutex(&Pipe->FcbListLock);
-   InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
-   KeUnlockMutex(&Pipe->FcbListLock);
-
    Fcb->Pipe = Pipe;
    Fcb->PipeEnd = FILE_PIPE_SERVER_END;
    Fcb->PipeState = FILE_PIPE_LISTENING_STATE;
    Fcb->OtherSide = NULL;
 
-   KeInitializeEvent(&Fcb->ConnectEvent,
-                    SynchronizationEvent,
-                    FALSE);
+   DPRINT("Fcb: %x\n", Fcb);
+
+   KeInitializeEvent(&Fcb->ConnectEvent, SynchronizationEvent, FALSE);
+   KeInitializeEvent(&Fcb->ReadEvent, SynchronizationEvent, FALSE);
+   KeInitializeEvent(&Fcb->WriteEvent, SynchronizationEvent, FALSE);
 
-   KeInitializeEvent(&Fcb->Event,
-                    SynchronizationEvent,
-                    FALSE);
+   KeLockMutex(&Pipe->FcbListLock);
+   InsertTailList(&Pipe->ServerFcbListHead, &Fcb->FcbListEntry);
+   KeUnlockMutex(&Pipe->FcbListLock);
 
    FileObject->FsContext = Fcb;
 
@@ -472,17 +527,17 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
 
 
 NTSTATUS STDCALL
-NpfsClose(PDEVICE_OBJECT DeviceObject,
-          PIRP Irp)
+NpfsCleanup(PDEVICE_OBJECT DeviceObject,
+           PIRP Irp)
 {
    PNPFS_DEVICE_EXTENSION DeviceExt;
    PIO_STACK_LOCATION IoStack;
    PFILE_OBJECT FileObject;
-   PNPFS_FCB Fcb;
+   PNPFS_FCB Fcb, OtherSide;
    PNPFS_PIPE Pipe;
    BOOL Server;
 
-   DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+   DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
 
    IoStack = IoGetCurrentIrpStackLocation(Irp);
    DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -501,7 +556,7 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
    DPRINT("Fcb %x\n", Fcb);
    Pipe = Fcb->Pipe;
 
-   DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
+   DPRINT("Cleaning pipe %wZ\n", &Pipe->PipeName);
 
    KeLockMutex(&Pipe->FcbListLock);
 
@@ -511,34 +566,154 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
    {
       /* FIXME: Clean up existing connections here ?? */
       DPRINT("Server\n");
-      Pipe->CurrentInstances--;
    }
    else
    {
       DPRINT("Client\n");
    }
-
    if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
    {
-      if (Fcb->OtherSide)
+      OtherSide = Fcb->OtherSide;
+      /* Lock the server first */
+      if (Server)
+      {
+         ExAcquireFastMutex(&Fcb->DataListLock);
+        ExAcquireFastMutex(&OtherSide->DataListLock);
+      }
+      else
+      {
+        ExAcquireFastMutex(&OtherSide->DataListLock);
+         ExAcquireFastMutex(&Fcb->DataListLock);
+      }
+      OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+      OtherSide->OtherSide = NULL;
+      /*
+       * Signaling the write event. If is possible that an other
+       * thread waits for an empty buffer.
+       */
+      KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
+      KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+      if (Server)
+      {
+         ExReleaseFastMutex(&Fcb->DataListLock);
+        ExReleaseFastMutex(&OtherSide->DataListLock);
+      }
+      else
+      {
+        ExReleaseFastMutex(&OtherSide->DataListLock);
+        ExReleaseFastMutex(&Fcb->DataListLock);
+      }
+   }
+   else if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+   {
+      PLIST_ENTRY Entry;
+      PNPFS_WAITER_ENTRY WaitEntry = NULL;
+      BOOLEAN Complete = FALSE; 
+      KIRQL oldIrql;
+      PIRP tmpIrp;
+
+      Entry = Fcb->Pipe->WaiterListHead.Flink;
+      while (Entry != &Fcb->Pipe->WaiterListHead)
       {
-         Fcb->OtherSide->PipeState = FILE_PIPE_CLOSING_STATE;
-         Fcb->OtherSide->OtherSide = NULL;
-         /*
-          * Signaling the write event. If is possible that an other
-          * thread waits for an empty buffer.
-          */
-         KeSetEvent(&Fcb->OtherSide->Event, IO_NO_INCREMENT, FALSE);
+         WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
+        if (WaitEntry->Fcb == Fcb)
+        {
+            RemoveEntryList(Entry);
+           tmpIrp = CONTAINING_RECORD(WaitEntry, IRP, Tail.Overlay.DriverContext);
+           IoAcquireCancelSpinLock(&oldIrql);
+           if (!tmpIrp->Cancel)
+           {
+               IoSetCancelRoutine(tmpIrp, NULL);
+              Complete = TRUE;
+           }
+           IoReleaseCancelSpinLock(oldIrql);
+            if (Complete)
+           {
+              tmpIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
+               tmpIrp->IoStatus.Information = 0;
+               IoCompleteRequest(tmpIrp, IO_NO_INCREMENT);
+           }
+           break;
+        }
+        Entry = Entry->Flink;
       }
 
-      Fcb->PipeState = 0;
    }
+   Fcb->PipeState = FILE_PIPE_CLOSING_STATE;
 
-   FileObject->FsContext = NULL;
+   KeUnlockMutex(&Pipe->FcbListLock);
 
-   RemoveEntryList(&Fcb->FcbListEntry);
+   ExAcquireFastMutex(&Fcb->DataListLock);
    if (Fcb->Data)
+   {
       ExFreePool(Fcb->Data);
+      Fcb->Data = NULL;
+      Fcb->ReadPtr = NULL;
+      Fcb->WritePtr = NULL;
+   }
+   ExReleaseFastMutex(&Fcb->DataListLock);
+
+   Irp->IoStatus.Status = STATUS_SUCCESS;
+   Irp->IoStatus.Information = 0;
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+   DPRINT("Success!\n");
+
+   return STATUS_SUCCESS;
+}
+
+NTSTATUS STDCALL
+NpfsClose(PDEVICE_OBJECT DeviceObject,
+          PIRP Irp)
+{
+   PNPFS_DEVICE_EXTENSION DeviceExt;
+   PIO_STACK_LOCATION IoStack;
+   PFILE_OBJECT FileObject;
+   PNPFS_FCB Fcb;
+   PNPFS_PIPE Pipe;
+   BOOL Server;
+
+   DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
+
+   IoStack = IoGetCurrentIrpStackLocation(Irp);
+   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+   FileObject = IoStack->FileObject;
+   Fcb = FileObject->FsContext;
+
+   if (Fcb == NULL)
+   {
+      DPRINT("Success!\n");
+      Irp->IoStatus.Status = STATUS_SUCCESS;
+      Irp->IoStatus.Information = 0;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+      return STATUS_SUCCESS;
+   }
+
+   DPRINT("Fcb %x\n", Fcb);
+   Pipe = Fcb->Pipe;
+
+   DPRINT("Closing pipe %wZ\n", &Pipe->PipeName);
+
+   KeLockMutex(&Pipe->FcbListLock);
+
+   Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
+
+   if (Server)
+   {
+      DPRINT("Server\n");
+      Pipe->CurrentInstances--;
+   }
+   else
+   {
+      DPRINT("Client\n");
+   }
+
+   ASSERT (Fcb->PipeState == FILE_PIPE_CLOSING_STATE);
+
+   FileObject->FsContext = NULL;
+
+   RemoveEntryList(&Fcb->FcbListEntry);
+
    ExFreePool(Fcb);
 
    KeUnlockMutex(&Pipe->FcbListLock);
index 8151989..1413589 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
-static VOID
+static VOID STDCALL
 NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
                            IN PIRP Irp)
 {
   PNPFS_WAITER_ENTRY Waiter;
 
   DPRINT1("NpfsListeningCancelRoutine() called\n");
-  /* FIXME: Not tested. */
 
-  Waiter = Irp->Tail.Overlay.DriverContext[0];
-
-  RemoveEntryList(&Waiter->Entry);
-  ExFreePool(Waiter);
+  Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
 
   IoReleaseCancelSpinLock(Irp->CancelIrql);
 
+
+  KeLockMutex(&Waiter->Fcb->Pipe->FcbListLock);
+  RemoveEntryList(&Waiter->Entry);
+  KeUnlockMutex(&Waiter->Fcb->Pipe->FcbListLock);
+
   Irp->IoStatus.Status = STATUS_CANCELLED;
   Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -45,31 +46,33 @@ NpfsAddListeningServerInstance(PIRP Irp,
                               PNPFS_FCB Fcb)
 {
   PNPFS_WAITER_ENTRY Entry;
-  KIRQL OldIrql;
+  KIRQL oldIrql;
 
-  Entry = ExAllocatePool(NonPagedPool, sizeof(NPFS_WAITER_ENTRY));
-  if (Entry == NULL)
-    return STATUS_INSUFFICIENT_RESOURCES;
+  Entry = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
 
-  Entry->Irp = Irp;
   Entry->Fcb = Fcb;
+
+  KeLockMutex(&Fcb->Pipe->FcbListLock);
+
+  IoMarkIrpPending(Irp);
   InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
 
-  IoAcquireCancelSpinLock(&OldIrql);
+  IoAcquireCancelSpinLock(&oldIrql);
   if (!Irp->Cancel)
     {
-      Irp->Tail.Overlay.DriverContext[0] = Entry;
-      IoMarkIrpPending(Irp);
       IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
-      IoReleaseCancelSpinLock(OldIrql);
+      IoReleaseCancelSpinLock(oldIrql);
+      KeUnlockMutex(&Fcb->Pipe->FcbListLock);
       return STATUS_PENDING;
     }
-  /* IRP has already been cancelled */
-  IoReleaseCancelSpinLock(OldIrql);
-
-  DPRINT1("FIXME: Remove waiter entry!\n");
+  IoReleaseCancelSpinLock(oldIrql);
+  
   RemoveEntryList(&Entry->Entry);
-  ExFreePool(Entry);
+  
+  Irp->IoStatus.Status = STATUS_CANCELLED;
+  Irp->IoStatus.Information = 0;
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+  KeUnlockMutex(&Fcb->Pipe->FcbListLock);
 
   return STATUS_CANCELLED;
 }
@@ -164,38 +167,100 @@ NpfsConnectPipe(PIRP Irp,
 static NTSTATUS
 NpfsDisconnectPipe(PNPFS_FCB Fcb)
 {
-  DPRINT("NpfsDisconnectPipe()\n");
-
-  if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
-    return STATUS_SUCCESS;
-
-  if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
-    {
-      Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
-      /* FIXME: Shouldn't this be FILE_PIPE_CLOSING_STATE? */
-      Fcb->OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
-
-      /* FIXME: remove data queue(s) */
-
-      Fcb->OtherSide->OtherSide = NULL;
+   NTSTATUS Status;
+   PNPFS_FCB OtherSide;
+   PNPFS_PIPE Pipe;
+   BOOL Server;
+
+   DPRINT("NpfsDisconnectPipe()\n");
+
+   Pipe = Fcb->Pipe;
+   KeLockMutex(&Pipe->FcbListLock);
+
+   if (Fcb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
+   {
+      DPRINT("Pipe is already disconnected\n");
+      Status = STATUS_SUCCESS;
+   }
+   else if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+   {
+      Server = (Fcb->PipeEnd == FILE_PIPE_SERVER_END);
+      OtherSide = Fcb->OtherSide;
       Fcb->OtherSide = NULL;
-
-      DPRINT("Pipe disconnected\n");
-      return STATUS_SUCCESS;
-    }
-
-  if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
-    {
+      /* Lock the server first */
+      if (Server)
+      {
+         ExAcquireFastMutex(&Fcb->DataListLock);
+        ExAcquireFastMutex(&OtherSide->DataListLock);
+      }
+      else
+      {
+        ExAcquireFastMutex(&OtherSide->DataListLock);
+         ExAcquireFastMutex(&Fcb->DataListLock);
+      }
+      OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
+      OtherSide->OtherSide = NULL;
+      /*
+       * Signaling the write event. If is possible that an other
+       * thread waits for an empty buffer.
+       */
+      KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
+      KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+      if (Server)
+      {
+         ExReleaseFastMutex(&Fcb->DataListLock);
+        ExReleaseFastMutex(&OtherSide->DataListLock);
+      }
+      else
+      {
+        ExReleaseFastMutex(&OtherSide->DataListLock);
+        ExReleaseFastMutex(&OtherSide->DataListLock);
+      }
+      Status = STATUS_SUCCESS;
+   }
+   else if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+   {
+      PLIST_ENTRY Entry;
+      PNPFS_WAITER_ENTRY WaitEntry = NULL;
+      BOOLEAN Complete = FALSE; 
+      PIRP Irp = NULL;
+
+      Entry = Fcb->Pipe->WaiterListHead.Flink;
+      while (Entry != &Fcb->Pipe->WaiterListHead)
+      {
+         WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
+        if (WaitEntry->Fcb == Fcb)
+        {
+            RemoveEntryList(Entry);
+           Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
+           Complete = (NULL == IoSetCancelRoutine(Irp, NULL));
+            break;
+        }
+        Entry = Entry->Flink;
+      }
+
+      if (Irp)
+      {
+         if (Complete)
+        {
+           Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
+            Irp->IoStatus.Information = 0;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        }
+      }
       Fcb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
-      Fcb->OtherSide = NULL;
-
-      /* FIXME: remove data queue(s) */
-
-      DPRINT("Pipe disconnected\n");
-      return STATUS_SUCCESS;
-    }
-
-  return STATUS_UNSUCCESSFUL;
+      Status = STATUS_SUCCESS;
+   }
+   else if (Fcb->PipeState == FILE_PIPE_CLOSING_STATE)
+   {
+      Status = STATUS_PIPE_CLOSING;
+   }
+   else
+   {
+      Status = STATUS_UNSUCCESSFUL;
+   }
+   KeUnlockMutex(&Pipe->FcbListLock);
+   return Status;
 }
 
 
index 9075ac7..753f5d1 100644 (file)
@@ -27,6 +27,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    NTSTATUS Status;
    
    DPRINT("Named Pipe FSD 0.0.2\n");
+
+   ASSERT (sizeof(NPFS_CONTEXT) <= sizeof (((PIRP)NULL)->Tail.Overlay.DriverContext));
+   ASSERT (sizeof(NPFS_WAITER_ENTRY) <= sizeof(((PIRP)NULL)->Tail.Overlay.DriverContext));
    
    DriverObject->MajorFunction[IRP_MJ_CREATE] = NpfsCreate;
    DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =
@@ -40,7 +43,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
      NpfsSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = 
      NpfsQueryVolumeInformation;
-//   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
+   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = NpfsCleanup;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;
 //   DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
 //     NpfsDirectoryControl;
@@ -73,8 +76,9 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    /* initialize the device extension */
    DeviceExtension = DeviceObject->DeviceExtension;
    InitializeListHead(&DeviceExtension->PipeListHead);
-   KeInitializeMutex(&DeviceExtension->PipeListLock,
-                    0);
+   InitializeListHead(&DeviceExtension->ThreadListHead);
+   KeInitializeMutex(&DeviceExtension->PipeListLock, 0);
+   DeviceExtension->EmptyWaiterCount = 0;
 
    /* set the size quotas */
    DeviceExtension->MinQuota = PAGE_SIZE;
index 1038411..052b79f 100644 (file)
@@ -6,7 +6,9 @@
 typedef struct _NPFS_DEVICE_EXTENSION
 {
   LIST_ENTRY PipeListHead;
+  LIST_ENTRY ThreadListHead;
   KMUTEX PipeListLock;
+  ULONG EmptyWaiterCount;
   ULONG MinQuota;
   ULONG DefaultQuota;
   ULONG MaxQuota;
@@ -20,6 +22,7 @@ typedef struct _NPFS_PIPE
   LIST_ENTRY ServerFcbListHead;
   LIST_ENTRY ClientFcbListHead;
   LIST_ENTRY WaiterListHead;
+  LIST_ENTRY EmptyBufferListHead;
   ULONG PipeType;
   ULONG ReadMode;
   ULONG WriteMode;
@@ -39,25 +42,43 @@ typedef struct _NPFS_FCB
   struct ETHREAD *Thread;
   PNPFS_PIPE Pipe;
   KEVENT ConnectEvent;
-  KEVENT Event;
+  KEVENT ReadEvent;
+  KEVENT WriteEvent;
   ULONG PipeEnd;
   ULONG PipeState;
   ULONG ReadDataAvailable;
   ULONG WriteQuotaAvailable;
 
+  LIST_ENTRY ReadRequestListHead;
+
   PVOID Data;
   PVOID ReadPtr;
   PVOID WritePtr;
   ULONG MaxDataLength;
 
-  KSPIN_LOCK DataListLock;     /* Data queue lock */
+  FAST_MUTEX DataListLock;     /* Data queue lock */
 } NPFS_FCB, *PNPFS_FCB;
 
+typedef struct _NPFS_CONTEXT
+{
+  LIST_ENTRY ListEntry;
+  PKEVENT WaitEvent;
+} NPFS_CONTEXT, *PNPFS_CONTEXT;
+
+typedef struct _NPFS_THREAD_CONTEXT
+{
+  ULONG Count;
+  KEVENT Event;
+  PNPFS_DEVICE_EXTENSION DeviceExt;
+  LIST_ENTRY ListEntry;
+  PVOID WaitObjectArray[MAXIMUM_WAIT_OBJECTS];
+  KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
+  PIRP WaitIrpArray[MAXIMUM_WAIT_OBJECTS];
+} NPFS_THREAD_CONTEXT, *PNPFS_THREAD_CONTEXT;
+
 typedef struct _NPFS_WAITER_ENTRY
 {
   LIST_ENTRY Entry;
-  PIRP Irp;
-  PNPFS_PIPE Pipe;
   PNPFS_FCB Fcb;
 } NPFS_WAITER_ENTRY, *PNPFS_WAITER_ENTRY;
 
@@ -76,6 +97,7 @@ extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
 
 NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS STDCALL NpfsCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
 
 NTSTATUS STDCALL NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
index 5338323..d07796b 100644 (file)
@@ -46,114 +46,427 @@ VOID HexDump(PUCHAR Buffer, ULONG Length)
 }
 #endif
 
+static VOID STDCALL 
+NpfsReadWriteCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
+                           IN PIRP Irp)
+{
+   PNPFS_CONTEXT Context;
+   PNPFS_DEVICE_EXTENSION DeviceExt;
+   PIO_STACK_LOCATION IoStack;
+   PNPFS_FCB Fcb;
+   BOOLEAN Complete = FALSE;
+
+   DPRINT("NpfsReadWriteCancelRoutine(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
+
+   IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+   Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+   DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+   IoStack = IoGetCurrentIrpStackLocation(Irp);
+   Fcb = IoStack->FileObject->FsContext;
+
+   KeLockMutex(&DeviceExt->PipeListLock);
+   ExAcquireFastMutex(&Fcb->DataListLock);
+   switch(IoStack->MajorFunction)   
+   {
+      case IRP_MJ_READ:
+         if (Fcb->ReadRequestListHead.Flink != &Context->ListEntry)
+        {
+           /* we are not the first in the list, remove an complete us */
+           RemoveEntryList(&Context->ListEntry);
+           Complete = TRUE;
+        }
+        else
+        {
+           KeSetEvent(&Fcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+        }
+        break;
+      default:
+         KEBUGCHECK(0);
+   }
+   ExReleaseFastMutex(&Fcb->DataListLock);
+   KeUnlockMutex(&DeviceExt->PipeListLock);
+   if (Complete)
+   {
+      Irp->IoStatus.Status = STATUS_CANCELLED;
+      Irp->IoStatus.Information = 0;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+   }
+}
+
+static VOID STDCALL
+NpfsWaiterThread(PVOID InitContext)
+{
+   PNPFS_THREAD_CONTEXT ThreadContext = (PNPFS_THREAD_CONTEXT) InitContext;
+   ULONG CurrentCount;
+   ULONG Count = 0;
+   PIRP Irp = NULL;
+   PIRP NextIrp;
+   NTSTATUS Status;
+   BOOLEAN Terminate = FALSE;
+   BOOLEAN Cancel = FALSE;
+   PIO_STACK_LOCATION IoStack = NULL;
+   PNPFS_CONTEXT Context;
+   PNPFS_CONTEXT NextContext;
+   PNPFS_FCB Fcb;
+
+   KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+
+   while (1)
+     {
+       CurrentCount = ThreadContext->Count;
+       KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+       if (Irp)
+         {
+           if (Cancel)
+             {
+              Irp->IoStatus.Status = STATUS_CANCELLED;
+               Irp->IoStatus.Information = 0;
+               IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            }
+          else
+            {
+               switch (IoStack->MajorFunction)
+                {
+                  case IRP_MJ_READ:
+                     NpfsRead(IoStack->DeviceObject, Irp);
+                    break;
+                  default:
+                    KEBUGCHECK(0);
+                }
+            }
+         }
+       if (Terminate)
+         {
+          break;
+        }
+       Status = KeWaitForMultipleObjects(CurrentCount,
+                                        ThreadContext->WaitObjectArray,
+                                        WaitAny,
+                                        Executive,
+                                        KernelMode,
+                                        FALSE,
+                                        NULL,
+                                        ThreadContext->WaitBlockArray);
+       if (!NT_SUCCESS(Status))
+         {
+           KEBUGCHECK(0);
+         }
+       KeLockMutex(&ThreadContext->DeviceExt->PipeListLock);
+       Count = Status - STATUS_SUCCESS;
+       ASSERT (Count < CurrentCount);
+       if (Count > 0)
+       {
+         Irp = ThreadContext->WaitIrpArray[Count];
+         ThreadContext->Count--;
+         ThreadContext->DeviceExt->EmptyWaiterCount++;
+         ThreadContext->WaitObjectArray[Count] = ThreadContext->WaitObjectArray[ThreadContext->Count];
+         ThreadContext->WaitIrpArray[Count] = ThreadContext->WaitIrpArray[ThreadContext->Count];
+
+          Cancel = (NULL == IoSetCancelRoutine(Irp, NULL));
+         Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+         IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+         if (Cancel)
+         {
+            Fcb = IoStack->FileObject->FsContext;
+            ExAcquireFastMutex(&Fcb->DataListLock);
+            RemoveEntryList(&Context->ListEntry);
+            switch (IoStack->MajorFunction)
+            {
+               case IRP_MJ_READ:
+                   if (!IsListEmpty(&Fcb->ReadRequestListHead))
+                  {
+                     /* put the next request on the wait list */
+                      NextContext = CONTAINING_RECORD(Fcb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+                     ThreadContext->WaitObjectArray[ThreadContext->Count] = NextContext->WaitEvent;
+                     NextIrp = CONTAINING_RECORD(NextContext, IRP, Tail.Overlay.DriverContext);
+                     ThreadContext->WaitIrpArray[ThreadContext->Count] = NextIrp;
+                     ThreadContext->Count++;
+                      ThreadContext->DeviceExt->EmptyWaiterCount--;               
+                  }
+                  break;
+               default:
+                  KEBUGCHECK(0);
+            }
+            ExReleaseFastMutex(&Fcb->DataListLock);
+         }         
+       }
+       else
+       {  
+         /* someone has add a new wait request */
+          Irp = NULL;
+       }
+       if (ThreadContext->Count == 1 && ThreadContext->DeviceExt->EmptyWaiterCount >= MAXIMUM_WAIT_OBJECTS)
+        {
+          /* it exist an other thread with empty wait slots, we can remove our thread from the list */
+          RemoveEntryList(&ThreadContext->ListEntry);
+          ThreadContext->DeviceExt->EmptyWaiterCount -= MAXIMUM_WAIT_OBJECTS - 1;
+         Terminate = TRUE;
+        }
+     }
+   KeUnlockMutex(&ThreadContext->DeviceExt->PipeListLock);
+   ExFreePool(ThreadContext);
+}
+
+static NTSTATUS
+NpfsAddWaitingReadWriteRequest(IN PDEVICE_OBJECT DeviceObject,
+                              IN PIRP Irp)
+{
+   PLIST_ENTRY ListEntry;
+   PNPFS_THREAD_CONTEXT ThreadContext = NULL;
+   NTSTATUS Status;
+   HANDLE hThread;
+   KIRQL oldIrql;
+
+   PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+   PNPFS_DEVICE_EXTENSION DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;;
+
+   DPRINT("NpfsAddWaitingReadWriteRequest(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
+
+   KeLockMutex(&DeviceExt->PipeListLock);
+
+   ListEntry = DeviceExt->ThreadListHead.Flink;
+   while (ListEntry != &DeviceExt->ThreadListHead)
+     {
+       ThreadContext = CONTAINING_RECORD(ListEntry, NPFS_THREAD_CONTEXT, ListEntry);
+       if (ThreadContext->Count < MAXIMUM_WAIT_OBJECTS)
+         {
+           break;
+         }
+       ListEntry = ListEntry->Flink;
+     }
+   if (ListEntry == &DeviceExt->ThreadListHead)
+     {
+       ThreadContext = ExAllocatePool(NonPagedPool, sizeof(NPFS_THREAD_CONTEXT));
+       if (ThreadContext == NULL)
+         {
+           KeUnlockMutex(&DeviceExt->PipeListLock);
+           return STATUS_NO_MEMORY;
+         }
+       ThreadContext->DeviceExt = DeviceExt;
+       KeInitializeEvent(&ThreadContext->Event, SynchronizationEvent, FALSE);
+       ThreadContext->Count = 1;
+       ThreadContext->WaitObjectArray[0] = &ThreadContext->Event;
+
+   
+       DPRINT("Creating a new system thread for waiting read/write requests\n");
+      
+       Status = PsCreateSystemThread(&hThread,
+                                    THREAD_ALL_ACCESS,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NpfsWaiterThread,
+                                    (PVOID)ThreadContext);
+       if (!NT_SUCCESS(Status))
+         {
+           ExFreePool(ThreadContext);
+           KeUnlockMutex(&DeviceExt->PipeListLock);
+           return Status;
+        }
+       InsertHeadList(&DeviceExt->ThreadListHead, &ThreadContext->ListEntry);
+       DeviceExt->EmptyWaiterCount += MAXIMUM_WAIT_OBJECTS - 1;       
+     }
+   IoMarkIrpPending(Irp);
+
+   IoAcquireCancelSpinLock(&oldIrql);
+   if (Irp->Cancel)
+     {
+       IoReleaseCancelSpinLock(oldIrql);
+       Status = STATUS_CANCELLED;
+     }
+   else
+     {
+       IoSetCancelRoutine(Irp, NpfsReadWriteCancelRoutine);
+       IoReleaseCancelSpinLock(oldIrql);
+       ThreadContext->WaitObjectArray[ThreadContext->Count] = Context->WaitEvent;
+       ThreadContext->WaitIrpArray[ThreadContext->Count] = Irp;
+       ThreadContext->Count++;
+       DeviceExt->EmptyWaiterCount--;
+       KeSetEvent(&ThreadContext->Event, IO_NO_INCREMENT, FALSE);
+       Status = STATUS_SUCCESS;
+     }
+   KeUnlockMutex(&DeviceExt->PipeListLock);
+   return Status;
+}
 
 NTSTATUS STDCALL
-NpfsRead(PDEVICE_OBJECT DeviceObject,
-        PIRP Irp)
+NpfsRead(IN PDEVICE_OBJECT DeviceObject,
+        IN PIRP Irp)
 {
-  PIO_STACK_LOCATION IoStack;
   PFILE_OBJECT FileObject;
   NTSTATUS Status;
-  PNPFS_DEVICE_EXTENSION DeviceExt;
-  KIRQL OldIrql;
-  ULONG Information;
+  NTSTATUS OriginalStatus = STATUS_SUCCESS;
   PNPFS_FCB Fcb;
-  PNPFS_FCB WriterFcb;
-  PNPFS_PIPE Pipe;
+  PNPFS_CONTEXT Context;
+  KEVENT Event;
   ULONG Length;
-  PVOID Buffer;
+  ULONG Information;
   ULONG CopyLength;
   ULONG TempLength;
+  BOOLEAN IsOriginalRequest = TRUE;
+  PVOID Buffer;
 
-  DPRINT("NpfsRead(DeviceObject %p  Irp %p)\n", DeviceObject, Irp);
-
-  DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-  IoStack = IoGetCurrentIrpStackLocation(Irp);
-  FileObject = IoStack->FileObject;
-  Fcb = FileObject->FsContext;
-  Pipe = Fcb->Pipe;
-  WriterFcb = Fcb->OtherSide;
+  DPRINT("NpfsRead(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
 
   if (Irp->MdlAddress == NULL)
-    {
-      DPRINT("Irp->MdlAddress == NULL\n");
-      Status = STATUS_UNSUCCESSFUL;
-      Information = 0;
-      goto done;
-    }
+  {
+     DPRINT("Irp->MdlAddress == NULL\n");
+     Status = STATUS_UNSUCCESSFUL;
+     Irp->IoStatus.Information = 0;
+     goto done;
+  }
+
+  FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
+  Fcb = FileObject->FsContext;
+  Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
 
   if (Fcb->Data == NULL)
-    {
-      DPRINT("Pipe is NOT readable!\n");
-      Status = STATUS_UNSUCCESSFUL;
-      Information = 0;
-      goto done;
-    }
-
-  Status = STATUS_SUCCESS;
-  Length = IoStack->Parameters.Read.Length;
-  Information = 0;
-
-  Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
-  KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
-  while (1)
-    {
-      /* FIXME: check if in blocking mode */
-      if (Fcb->ReadDataAvailable == 0)
+  {
+     DPRINT1("Pipe is NOT readable!\n");
+     Status = STATUS_UNSUCCESSFUL;
+     Irp->IoStatus.Information = 0;
+     goto done;
+  }
+
+  ExAcquireFastMutex(&Fcb->DataListLock);
+
+  if (IoIsOperationSynchronous(Irp))
+  {
+     InsertTailList(&Fcb->ReadRequestListHead, &Context->ListEntry);
+     if (Fcb->ReadRequestListHead.Flink != &Context->ListEntry)
+     {
+        KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+       Context->WaitEvent = &Event;
+        ExReleaseFastMutex(&Fcb->DataListLock);
+        Status = KeWaitForSingleObject(&Event,
+                                      Executive,
+                                      KernelMode,
+                                      FALSE,
+                                      NULL);
+       if (!NT_SUCCESS(Status))
        {
-         if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
-           {
-             KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
-           }
-         KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
-         if (Information > 0)
-           {
-             Status = STATUS_SUCCESS;
+          KEBUGCHECK(0);
+       }
+        ExAcquireFastMutex(&Fcb->DataListLock);
+     }
+     Irp->IoStatus.Information = 0;
+  }
+  else
+  {
+     KIRQL oldIrql;
+     if (IsListEmpty(&Fcb->ReadRequestListHead) ||
+        Fcb->ReadRequestListHead.Flink != &Context->ListEntry)
+     {
+        /* this is a new request */
+        Irp->IoStatus.Information = 0;
+       Context->WaitEvent = &Fcb->ReadEvent;
+        InsertTailList(&Fcb->ReadRequestListHead, &Context->ListEntry);
+       if (Fcb->ReadRequestListHead.Flink != &Context->ListEntry)
+       {
+          /* there was already a request on the list */
+           IoAcquireCancelSpinLock(&oldIrql);
+           if (Irp->Cancel)
+           {
+             IoReleaseCancelSpinLock(oldIrql);
+             RemoveEntryList(&Context->ListEntry);
+             ExReleaseFastMutex(&Fcb->DataListLock);
+             Status = STATUS_CANCELLED;
              goto done;
-           }
+           }
+           IoSetCancelRoutine(Irp, NpfsReadWriteCancelRoutine);
+           IoReleaseCancelSpinLock(oldIrql);
+          ExReleaseFastMutex(&Fcb->DataListLock);
+           IoMarkIrpPending(Irp);
+          Status = STATUS_PENDING;
+          goto done;
+       }
+     }
+  }
 
-         if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
-           {
+  while (1)
+  {
+     Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+     Information = Irp->IoStatus.Information;
+     Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length;
+     ASSERT (Information <= Length);
+     Buffer += Information;
+     Length -= Information;
+     Status = STATUS_SUCCESS;
+
+     while (1)
+     {
+        if (Fcb->ReadDataAvailable == 0)
+        {
+          if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+          {
+             KeSetEvent(&Fcb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+          }
+          if (Information > 0 &&
+              (Fcb->Pipe->ReadMode != FILE_PIPE_BYTE_STREAM_MODE ||
+               Fcb->PipeState != FILE_PIPE_CONNECTED_STATE))
+          {
+             break;
+          }
+          if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
+          {
              DPRINT("PipeState: %x\n", Fcb->PipeState);
              Status = STATUS_PIPE_BROKEN;
-             goto done;
-           }
-
-         /* Wait for ReadEvent to become signaled */
-         DPRINT("Waiting for readable data (%S)\n", Pipe->PipeName.Buffer);
-         Status = KeWaitForSingleObject(&Fcb->Event,
-                                        UserRequest,
-                                        KernelMode,
-                                        FALSE,
-                                        NULL);
-         DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
-
-         KeAcquireSpinLock(&Fcb->DataListLock, &OldIrql);
-       }
-
-      if (Pipe->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
-       {
-         DPRINT("Byte stream mode\n");
-         /* Byte stream mode */
-         while (Length > 0 && Fcb->ReadDataAvailable > 0)
-           {
+             break;
+           }
+          ExReleaseFastMutex(&Fcb->DataListLock);
+          if (IoIsOperationSynchronous(Irp))
+          {
+             /* Wait for ReadEvent to become signaled */
+
+             DPRINT("Waiting for readable data (%wZ)\n", &Fcb->Pipe->PipeName);
+             Status = KeWaitForSingleObject(&Fcb->ReadEvent,
+                                            UserRequest,
+                                            KernelMode,
+                                            FALSE,
+                                            NULL);
+             DPRINT("Finished waiting (%wZ)! Status: %x\n", &Fcb->Pipe->PipeName, Status);
+             ExAcquireFastMutex(&Fcb->DataListLock);
+          }
+          else
+          {
+              PNPFS_CONTEXT Context = (PNPFS_CONTEXT)&Irp->Tail.Overlay.DriverContext;
+           
+              Context->WaitEvent = &Fcb->ReadEvent;
+             Status = NpfsAddWaitingReadWriteRequest(DeviceObject, Irp);
+                
+             if (NT_SUCCESS(Status))
+             {
+                Status = STATUS_PENDING;
+             }
+             ExAcquireFastMutex(&Fcb->DataListLock);
+             break;
+          }
+        } 
+        if (Fcb->Pipe->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
+        {
+          DPRINT("Byte stream mode\n");
+          /* Byte stream mode */
+          while (Length > 0 && Fcb->ReadDataAvailable > 0)
+          {
              CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
              if (Fcb->ReadPtr + CopyLength <= Fcb->Data + Fcb->MaxDataLength)
-               {
-                 memcpy(Buffer, Fcb->ReadPtr, CopyLength);
-                 Fcb->ReadPtr += CopyLength;
-                 if (Fcb->ReadPtr == Fcb->Data + Fcb->MaxDataLength)
-                   {
-                     Fcb->ReadPtr = Fcb->Data;
-                   }
-               }
-             else
-               {
-                 TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->ReadPtr;
-                 memcpy(Buffer, Fcb->ReadPtr, TempLength);
-                 memcpy(Buffer + TempLength, Fcb->Data, CopyLength - TempLength);
-                 Fcb->ReadPtr = Fcb->Data + CopyLength - TempLength;
-               }
+             {
+                memcpy(Buffer, Fcb->ReadPtr, CopyLength);
+                Fcb->ReadPtr += CopyLength;
+                if (Fcb->ReadPtr == Fcb->Data + Fcb->MaxDataLength)
+                {
+                   Fcb->ReadPtr = Fcb->Data;
+                }
+             }
+              else
+             {
+                TempLength = Fcb->Data + Fcb->MaxDataLength - Fcb->ReadPtr;
+                memcpy(Buffer, Fcb->ReadPtr, TempLength);
+                memcpy(Buffer + TempLength, Fcb->Data, CopyLength - TempLength);
+                Fcb->ReadPtr = Fcb->Data + CopyLength - TempLength;
+             }
 
              Buffer += CopyLength;
              Length -= CopyLength;
@@ -161,22 +474,25 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
 
              Fcb->ReadDataAvailable -= CopyLength;
              Fcb->WriteQuotaAvailable += CopyLength;
-           }
+          }
 
-         if (Length == 0)
-           {
-             KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
-             KeResetEvent(&Fcb->Event);
-             break;
-           }
-       }
-      else
-       {
-         DPRINT("Message mode\n");
+          if (Length == 0)
+          {
+             if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+             {
+                KeSetEvent(&Fcb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+             }
+             KeResetEvent(&Fcb->ReadEvent);
+              break;
+          }
+        }
+        else
+        {
+          DPRINT("Message mode\n");
 
-         /* Message mode */
-         if (Fcb->ReadDataAvailable)
-           {
+          /* Message mode */
+          if (Fcb->ReadDataAvailable)
+          {
              /* Truncate the message if the receive buffer is too small */
              CopyLength = RtlRosMin(Fcb->ReadDataAvailable, Length);
              memcpy(Buffer, Fcb->Data, CopyLength);
@@ -189,45 +505,85 @@ NpfsRead(PDEVICE_OBJECT DeviceObject,
              Information = CopyLength;
 
              if (Fcb->ReadDataAvailable > Length)
-               {
-                 memmove(Fcb->Data, Fcb->Data + Length,
-                         Fcb->ReadDataAvailable - Length);
-                 Fcb->ReadDataAvailable -= Length;
-                 Status = STATUS_MORE_ENTRIES;
-               }
+             {
+                memmove(Fcb->Data, Fcb->Data + Length,
+                        Fcb->ReadDataAvailable - Length);
+                Fcb->ReadDataAvailable -= Length;
+                Status = STATUS_MORE_ENTRIES;
+             }
              else
-               {
-                 Fcb->ReadDataAvailable = 0;
-                 Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
-               }
-           }
-
-         if (Information > 0)
-           {
-             if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
-               {
-                 KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
-               }
-             KeResetEvent(&Fcb->Event);
-             break;
-           }
+             {
+                 KeResetEvent(&Fcb->ReadEvent);
+                 if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+                 {
+                    KeSetEvent(&Fcb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
+                 }
+                Fcb->ReadDataAvailable = 0;
+                Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
+             }
+          }
+
+          if (Information > 0)
+          {
+              break;
+          }
+        }
+     }   
+     Irp->IoStatus.Information = Information;
+     Irp->IoStatus.Status = Status;
+
+     if (IoIsOperationSynchronous(Irp))
+     {
+        RemoveEntryList(&Context->ListEntry);
+        if (!IsListEmpty(&Fcb->ReadRequestListHead))
+       {
+          Context = CONTAINING_RECORD(Fcb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+           KeSetEvent(Context->WaitEvent, IO_NO_INCREMENT, FALSE);
        }
-    }
-
-  KeReleaseSpinLock(&Fcb->DataListLock, OldIrql);
+        ExReleaseFastMutex(&Fcb->DataListLock);
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+       DPRINT("NpfsRead done (Status %lx)\n", Status);
+        return Status;
+     }
+     else
+     {
+        if (IsOriginalRequest)
+       {
+          IsOriginalRequest = FALSE;
+          OriginalStatus = Status;
+       }
+        if (Status == STATUS_PENDING)
+       {
+           ExReleaseFastMutex(&Fcb->DataListLock);
+          DPRINT("NpfsRead done (Status %lx)\n", OriginalStatus);
+           return OriginalStatus;
+       }
+       RemoveEntryList(&Context->ListEntry);
+       IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        if (IsListEmpty(&Fcb->ReadRequestListHead))
+       {
+           ExReleaseFastMutex(&Fcb->DataListLock);
+          DPRINT("NpfsRead done (Status %lx)\n", OriginalStatus);
+           return OriginalStatus;
+       }
+        Context = CONTAINING_RECORD(Fcb->ReadRequestListHead.Flink, NPFS_CONTEXT, ListEntry);
+       Irp = CONTAINING_RECORD(Context, IRP, Tail.Overlay.DriverContext);
+     }
+  }    
 
 done:
   Irp->IoStatus.Status = Status;
-  Irp->IoStatus.Information = Information;
-
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
+  if (Status != STATUS_PENDING)
+    {
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
   DPRINT("NpfsRead done (Status %lx)\n", Status);
 
   return Status;
 }
 
-
 NTSTATUS STDCALL
 NpfsWrite(PDEVICE_OBJECT DeviceObject,
          PIRP Irp)
@@ -241,7 +597,6 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
   NTSTATUS Status = STATUS_SUCCESS;
   ULONG Length;
   ULONG Offset;
-  KIRQL OldIrql;
   ULONG Information;
   ULONG CopyLength;
   ULONG TempLength;
@@ -293,7 +648,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
   Status = STATUS_SUCCESS;
   Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
 
-  KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
+  ExAcquireFastMutex(&ReaderFcb->DataListLock);
 #ifndef NDEBUG
   DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
   HexDump(Buffer, Length);
@@ -303,22 +658,24 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
     {
       if (ReaderFcb->WriteQuotaAvailable == 0)
        {
-         KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
-         KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
+         KeSetEvent(&ReaderFcb->ReadEvent, IO_NO_INCREMENT, FALSE);
          if (Fcb->PipeState != FILE_PIPE_CONNECTED_STATE)
            {
              Status = STATUS_PIPE_BROKEN;
+             ExReleaseFastMutex(&ReaderFcb->DataListLock);
              goto done;
            }
+         ExReleaseFastMutex(&ReaderFcb->DataListLock);
 
          DPRINT("Waiting for buffer space (%S)\n", Pipe->PipeName.Buffer);
-         Status = KeWaitForSingleObject(&Fcb->Event,
-                                        UserRequest,
+         Status = KeWaitForSingleObject(&Fcb->WriteEvent, 
+                                        UserRequest,
                                         KernelMode,
                                         FALSE,
                                         NULL);
          DPRINT("Finished waiting (%S)! Status: %x\n", Pipe->PipeName.Buffer, Status);
 
+         ExAcquireFastMutex(&ReaderFcb->DataListLock);
          /*
           * It's possible that the event was signaled because the
           * other side of pipe was closed.
@@ -327,9 +684,9 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
            {
              DPRINT("PipeState: %x\n", Fcb->PipeState);
              Status = STATUS_PIPE_BROKEN;
+             ExReleaseFastMutex(&ReaderFcb->DataListLock);
              goto done;
            }
-         KeAcquireSpinLock(&ReaderFcb->DataListLock, &OldIrql);
        }
 
       if (Pipe->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
@@ -365,8 +722,8 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
 
          if (Length == 0)
            {
-             KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
-             KeResetEvent(&Fcb->Event);
+             KeSetEvent(&ReaderFcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+             KeResetEvent(&Fcb->WriteEvent);
              break;
            }
        }
@@ -383,16 +740,16 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
              ReaderFcb->WriteQuotaAvailable = 0;
            }
 
-         if (Information > 0)
-           {
-             KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
-             KeResetEvent(&Fcb->Event);
-             break;
-           }
+         if (Information > 0)
+           {
+             KeSetEvent(&ReaderFcb->ReadEvent, IO_NO_INCREMENT, FALSE);
+             KeResetEvent(&Fcb->WriteEvent);
+             break;
+           }
        }
     }
 
-  KeReleaseSpinLock(&ReaderFcb->DataListLock, OldIrql);
+  ExReleaseFastMutex(&ReaderFcb->DataListLock);
 
 done:
   Irp->IoStatus.Status = Status;
index 98314fc..1ea4168 100644 (file)
@@ -36,7 +36,7 @@ NpfsQueryFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
 
   DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
 
-   return STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
 
index df24e8c..7b3a26a 100644 (file)
@@ -49,6 +49,19 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext)
      if (pFcb->Flags & FCB_DELETE_PENDING &&
          pFcb->OpenHandleCount == 1)
        {
+        PFILE_OBJECT tmpFileObject;
+        tmpFileObject = pFcb->FileObject;
+        if (tmpFileObject != NULL)
+          {
+            pFcb->FileObject = NULL;
+#ifdef USE_ROS_CC_AND_FS
+             CcRosReleaseFileCache(tmpFileObject);
+#else
+             CcUninitializeCacheMap(tmpFileObject, NULL, NULL);
+#endif
+             ObDereferenceObject(tmpFileObject);
+           }
+
 #if 0
          /* FIXME:
          *  CcPurgeCacheSection is unimplemented.
index a3ae43f..bf171ec 100644 (file)
@@ -43,11 +43,8 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
      pFcb->RefCount--;
      FileObject->FsContext2 = NULL;
   }
-  else if (FileObject->FileName.Buffer)
+  else
   {
-    // This a FO, that was created outside from FSD.
-    // Some FO's are created with IoCreateStreamFileObject() insid from FSD.
-    // This FO's haven't a FileName.
     if (FileObject->DeletePending)
     {
       if (pFcb->Flags & FCB_DELETE_PENDING)
index aa44814..7e7a3bc 100644 (file)
@@ -191,10 +191,10 @@ vfatReleaseFCB(PDEVICE_EXTENSION  pVCB,  PVFATFCB  pFCB)
 
   while (pFCB)
   {
-     Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
-     ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
+     Index = pFCB->Hash.Hash % pVCB->HashTableSize;
+     ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
      pFCB->RefCount--;
-     if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
+     if (pFCB->RefCount == 0)
      {
         tmpFcb = pFCB->parentFcb;
         RemoveEntryList (&pFCB->FcbListEntry);  
@@ -227,22 +227,6 @@ vfatReleaseFCB(PDEVICE_EXTENSION  pVCB,  PVFATFCB  pFCB)
           }
            entry->next = pFCB->Hash.next;
         }
-        if (vfatFCBIsDirectory(pFCB))
-        {
-           /* Uninitialize file cache if initialized for this file object. */
-           if (pFCB->FileObject->SectionObjectPointer->SharedCacheMap)
-          {
-#ifdef USE_ROS_CC_AND_FS
-              CcRosReleaseFileCache(pFCB->FileObject);
-#else
-              CcUninitializeCacheMap(pFCB->FileObject, NULL, NULL);
-#endif
-          }
-           vfatDestroyCCB(pFCB->FileObject->FsContext2);
-           pFCB->FileObject->FsContext2 = NULL;
-          pFCB->FileObject->FsContext = NULL;
-           ObDereferenceObject(pFCB->FileObject);
-        }
         vfatDestroyFCB (pFCB);
      }
      else
@@ -259,8 +243,8 @@ vfatAddFCBToTable(PDEVICE_EXTENSION  pVCB,  PVFATFCB  pFCB)
   ULONG Index;
   ULONG ShortIndex;
 
-  Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
-  ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
+  Index = pFCB->Hash.Hash % pVCB->HashTableSize;
+  ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
 
   InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry);
    
@@ -292,7 +276,7 @@ vfatGrabFCBFromTable(PDEVICE_EXTENSION  pVCB, PUNICODE_STRING  PathNameU)
   
   Hash = vfatNameHash(0, PathNameU);
 
-  entry = pVCB->FcbHashTable[Hash % FCB_HASH_TABLE_SIZE];
+  entry = pVCB->FcbHashTable[Hash % pVCB->HashTableSize];
   if (entry)
     {
       vfatSplitPathName(PathNameU, &DirNameU, &FileNameU);
@@ -353,6 +337,7 @@ vfatFCBInitializeCacheFromVolume (PVCB  vcb, PVFATFCB  fcb)
   fileObject->FsContext = fcb;
   fileObject->FsContext2 = newCCB;
   fcb->FileObject = fileObject;
+  fcb->RefCount++;
 
 #ifdef USE_ROS_CC_AND_FS
   fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGE_SIZE) ?
@@ -375,12 +360,7 @@ vfatFCBInitializeCacheFromVolume (PVCB  vcb, PVFATFCB  fcb)
 #endif
 
   fcb->Flags |= FCB_CACHE_INITIALIZED;
-
-#ifdef USE_ROS_CC_AND_FS
-  return  status;
-#else
   return STATUS_SUCCESS;
-#endif
 }
 
 PVFATFCB
index 1f8015f..bb03ad7 100644 (file)
@@ -268,69 +268,65 @@ VfatSetDispositionInformation(PFILE_OBJECT FileObject,
                              PDEVICE_OBJECT DeviceObject,
                              PFILE_DISPOSITION_INFORMATION DispositionInfo)
 {
-  NTSTATUS Status = STATUS_SUCCESS;
 #ifdef DBG
-  PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+   PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
 #endif
 
-  DPRINT ("FsdSetDispositionInformation()\n");
+   DPRINT ("FsdSetDispositionInformation()\n");
 
-  ASSERT(DeviceExt != NULL);
-  ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
-  ASSERT(FCB != NULL);
+   ASSERT(DeviceExt != NULL);
+   ASSERT(DeviceExt->FatInfo.BytesPerCluster != 0);
+   ASSERT(FCB != NULL);
 
-  if (*FCB->Attributes & FILE_ATTRIBUTE_READONLY) 
-    {
+   if (!DispositionInfo->DeleteFile)
+   {
+      /* undelete the file */
+      FCB->Flags &= ~FCB_DELETE_PENDING;
+      FileObject->DeletePending = FALSE;
+      return STATUS_SUCCESS;
+   }
+  
+   if (FCB->Flags & FCB_DELETE_PENDING)
+   {
+      /* stream already marked for deletion. just update the file object */
+      FileObject->DeletePending = TRUE;
+      return STATUS_SUCCESS;
+   }
+  
+   if (*FCB->Attributes & FILE_ATTRIBUTE_READONLY) 
+   {
       return STATUS_CANNOT_DELETE;
-    }
+   }
 
-  if (vfatFCBIsRoot(FCB) || 
+   if (vfatFCBIsRoot(FCB) || 
      (FCB->LongNameU.Length == sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.') ||
      (FCB->LongNameU.Length == 2 * sizeof(WCHAR) && FCB->LongNameU.Buffer[0] == L'.' && FCB->LongNameU.Buffer[1] == L'.'))
-    {
+   {
       // we cannot delete a '.', '..' or the root directory
       return STATUS_ACCESS_DENIED;
-    }
+   }
 
-  if (DispositionInfo->DeleteFile)
-    {
-      if (MmFlushImageSection (FileObject->SectionObjectPointer, MmFlushForDelete))
-        {
-          if (FCB->OpenHandleCount > 1)
-            {
-             DPRINT1("%d %x\n", FCB->OpenHandleCount, CcGetFileObjectFromSectionPtrs(FileObject->SectionObjectPointer));
-              Status = STATUS_ACCESS_DENIED;
-            }
-          else
-            {
-              FCB->Flags |= FCB_DELETE_PENDING;
-              FileObject->DeletePending = TRUE;
-            }
-        }
-      else
-        {
-          DPRINT("MmFlushImageSection returned FALSE\n");
-          Status = STATUS_CANNOT_DELETE;
-        }
-      if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
-        {
-          if (!VfatIsDirectoryEmpty(FCB))
-            {
-              Status = STATUS_DIRECTORY_NOT_EMPTY;
-              FCB->Flags &= ~FCB_DELETE_PENDING;
-              FileObject->DeletePending = FALSE;
-            }
-          else
-            {
-              Status = STATUS_SUCCESS;
-            }
-        }
-     }
-   else
-     {
-       FileObject->DeletePending = FALSE;
-     }
-  return Status;
+
+   if (!MmFlushImageSection (FileObject->SectionObjectPointer, MmFlushForDelete))
+   {
+      /* can't delete a file if its mapped into a process */
+      
+      DPRINT("MmFlushImageSection returned FALSE\n");
+      return STATUS_CANNOT_DELETE;      
+   }
+
+   if (vfatFCBIsDirectory(FCB) && !VfatIsDirectoryEmpty(FCB))
+   {
+      /* can't delete a non-empty directory */
+      
+      return STATUS_DIRECTORY_NOT_EMPTY;
+   }
+
+   /* all good */
+   FCB->Flags |= FCB_DELETE_PENDING;
+   FileObject->DeletePending = TRUE;
+     
+   return STATUS_SUCCESS;
 }
 
 static NTSTATUS
index eb22588..2e13e70 100644 (file)
@@ -372,6 +372,8 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
    PDEVICE_OBJECT DeviceToMount;
    UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
    UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
+   ULONG HashTableSize;
+   FATINFO FatInfo;
 
    DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
 
@@ -385,7 +387,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
 
    DeviceToMount = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
 
-   Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS, NULL);
+   Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS, &FatInfo);
    if (!NT_SUCCESS(Status))
    {
       goto ByeBye;
@@ -398,9 +400,24 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
       goto ByeBye;
    }
 
+   /* Use prime numbers for the table size */
+   if (FatInfo.FatType == FAT12)
+   {
+      HashTableSize = 4099; // 4096 = 4 * 1024
+   }
+   else if (FatInfo.FatType == FAT16 ||
+            FatInfo.FatType == FATX16)
+   {
+      HashTableSize = 16411; // 16384 = 16 * 1024
+   }
+   else
+   {
+      HashTableSize = 65537; // 65536 = 64 * 1024;
+   }
+   HashTableSize = FCB_HASH_TABLE_SIZE;
    DPRINT("VFAT: Recognized volume\n");
    Status = IoCreateDevice(VfatGlobalData->DriverObject,
-                          sizeof (DEVICE_EXTENSION),
+                          ROUND_UP(sizeof (DEVICE_EXTENSION), sizeof(DWORD)) + sizeof(HASHENTRY*) * HashTableSize,
                           NULL,
                           FILE_DEVICE_FILE_SYSTEM,
                           0,
@@ -413,7 +430,9 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
 
    DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
    DeviceExt = (PVOID) DeviceObject->DeviceExtension;
-   RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
+   RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(DWORD)) + sizeof(HASHENTRY*) * HashTableSize);
+   DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(DWORD)));
+   DeviceExt->HashTableSize = HashTableSize;
 
    /* use same vpb as device disk */
    DeviceObject->Vpb = DeviceToMount->Vpb;
@@ -557,7 +576,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
 
    /* read volume label */
    ReadVolumeLabel(DeviceExt,  DeviceObject->Vpb);
-   
+
    Status = STATUS_SUCCESS;
 ByeBye:
 
index ed42a31..37a6d01 100644 (file)
@@ -241,7 +241,8 @@ typedef struct DEVICE_EXTENSION
 
   KSPIN_LOCK FcbListLock;
   LIST_ENTRY FcbListHead;
-  struct _HASHENTRY* FcbHashTable[FCB_HASH_TABLE_SIZE];
+  ULONG HashTableSize;
+  struct _HASHENTRY** FcbHashTable;
 
   PDEVICE_OBJECT StorageDevice;
   PFILE_OBJECT FATFileObject;
index d87d142..2a5c318 100644 (file)
@@ -38,6 +38,7 @@ static BYTE capsDown,numDown,scrollDown;
 static DWORD ctrlKeyState;
 static PKINTERRUPT KbdInterrupt;
 static KDPC KbdDpc;
+static PIO_WORKITEM KbdWorkItem = NULL;
 static BOOLEAN AlreadyOpened = FALSE;
 
 /*
@@ -407,6 +408,24 @@ static WORD ScanToVirtual(BYTE scanCode)
 }
 
 
+/*
+ * Debug request handler
+ */
+
+static VOID STDCALL
+KbdWorkItemRoutine(IN PDEVICE_OBJECT DeviceObject,
+                   IN PVOID Context)
+{
+   LONG Debug;
+
+   Debug = InterlockedExchange(&DoSystemDebug, -1);
+   if (Debug != -1)
+     {
+       KdSystemDebugControl(Debug);
+     }
+}
+
+
 /*
  * Keyboard IRQ handler
  */
@@ -419,14 +438,21 @@ KbdDpcRoutine(PKDPC Dpc,
 {
    PIRP Irp = (PIRP)SystemArgument2;
    PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
-   
+
    if (SystemArgument1 == NULL && DoSystemDebug != -1)
      {
-       KdSystemDebugControl(DoSystemDebug);
-       DoSystemDebug = -1;
+       if (KbdWorkItem != NULL && DoSystemDebug == 10) /* 10 is Tab + K (enter kernel debugger) */
+         {
+           IoQueueWorkItem(KbdWorkItem, (PIO_WORKITEM_ROUTINE)KbdWorkItemRoutine, DelayedWorkQueue, NULL);
+         }
+       else
+         {
+           KdSystemDebugControl(DoSystemDebug);
+           DoSystemDebug = -1;
+         }
        return;
      }
-
+     
    CHECKPOINT;
    DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
            DeviceObject,Irp);
@@ -436,6 +462,7 @@ KbdDpcRoutine(PKDPC Dpc,
    IoStartNextPacket(DeviceObject,FALSE);
 }
 
+
 static BOOLEAN STDCALL
 KeyboardHandler(PKINTERRUPT Interrupt,
                PVOID Context)
@@ -538,7 +565,7 @@ KeyboardHandler(PKINTERRUPT Interrupt,
    else if (InSysRq == TRUE && ScanToVirtual(thisKey) >= VK_A &&
            ScanToVirtual(thisKey) <= VK_Z && isDown)
      {
-       DoSystemDebug = ScanToVirtual(thisKey) - VK_A;
+       InterlockedExchange(&DoSystemDebug, ScanToVirtual(thisKey) - VK_A);
        KeInsertQueueDpc(&KbdDpc, NULL, NULL);
        return(TRUE);
      }
@@ -659,6 +686,11 @@ static int InitializeKeyboard(PDEVICE_OBJECT DeviceObject)
    KbdClearInput();
    KeyboardConnectInterrupt(DeviceObject);
    KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
+   KbdWorkItem = IoAllocateWorkItem(DeviceObject);
+   if (KbdWorkItem == NULL)
+     {
+        DPRINT("Warning: Couldn't allocate work item!\n");
+     }
    return 0;
 }
 
index 8094c43..0080352 100644 (file)
@@ -209,3 +209,28 @@ PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
 
     return NULL;
 }
+
+NTSTATUS GetInterfaceConnectionStatus
+( PIP_INTERFACE Interface, PDWORD Result ) {
+    NTSTATUS Status = TcpipLanGetDwordOid
+        ( Interface, OID_GEN_HARDWARE_STATUS, Result );
+    if( NT_SUCCESS(Status) ) switch( *Result ) {
+    case NdisHardwareStatusReady:
+        *Result = MIB_IF_OPER_STATUS_OPERATIONAL;
+        break;
+    case NdisHardwareStatusInitializing:
+        *Result = MIB_IF_OPER_STATUS_CONNECTING;
+        break;
+    case NdisHardwareStatusReset:
+        *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
+        break;
+    case NdisHardwareStatusNotReady:
+        *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
+        break;
+    case NdisHardwareStatusClosing:
+    default:
+        *Result = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
+        break;
+    }
+    return Status;
+}
index 4b6871e..ef23f27 100644 (file)
@@ -244,13 +244,29 @@ BOOLEAN IPRegisterInterface(
  */
 {
     KIRQL OldIrql;
+    UINT ChosenIndex = 1;
+    BOOLEAN IndexHasBeenChosen;
     IP_ADDRESS NetworkAddress;
     PNEIGHBOR_CACHE_ENTRY NCE;
+    IF_LIST_ITER(Interface);
 
     TI_DbgPrint(MID_TRACE, ("Called. IF (0x%X).\n", IF));
 
     TcpipAcquireSpinLock(&IF->Lock, &OldIrql);
 
+    /* Choose an index */
+    do {
+        IndexHasBeenChosen = TRUE;
+        ForEachInterface(Interface) {
+            if( Interface->Index == ChosenIndex ) {
+                ChosenIndex++;
+                IndexHasBeenChosen = FALSE;
+            }
+        } EndFor(Interface);
+    } while( !IndexHasBeenChosen );
+
+    IF->Index = ChosenIndex;
+
     /* Add a permanent neighbor for this NTE */
     NCE = NBAddNeighbor(IF, &IF->Unicast, 
                        IF->Address, IF->AddressLength, 
index 62be2ef..17e65ff 100644 (file)
@@ -20,8 +20,7 @@ VOID PortsStartup( PPORT_SET PortSet,
     RtlInitializeBitMap( &PortSet->ProtoBitmap, 
                         PortSet->ProtoBitBuffer,
                         PortSet->PortsToOversee );
-    RtlClearBits( &PortSet->ProtoBitmap, 
-                  PortSet->StartingPort, PortsToManage );
+    RtlClearAllBits( &PortSet->ProtoBitmap );
     ExInitializeFastMutex( &PortSet->Mutex );
 }
 
@@ -30,13 +29,17 @@ VOID PortsShutdown( PPORT_SET PortSet ) {
 }
 
 VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
-    RtlClearBits( &PortSet->ProtoBitmap, 
-                 PortSet->StartingPort + Port, 1 );
+    Port = htons(Port);
+    ASSERT(Port >= PortSet->StartingPort);
+    ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
+    RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
 }
 
 BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
     BOOLEAN Clear;
 
+    Port = htons(Port);
+    ASSERT(Port >= PortSet->StartingPort);
     Port -= PortSet->StartingPort;
 
     ExAcquireFastMutex( &PortSet->Mutex );
@@ -58,6 +61,8 @@ ULONG AllocateAnyPort( PPORT_SET PortSet ) {
     }
     ExReleaseFastMutex( &PortSet->Mutex );
 
+    AllocatedPort = htons(AllocatedPort);
+
     return AllocatedPort;
 }
 
@@ -76,5 +81,7 @@ ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
     }
     ExReleaseFastMutex( &PortSet->Mutex );
 
+    AllocatedPort = htons(AllocatedPort);
+
     return AllocatedPort;
 }
index 4028718..52b7097 100644 (file)
@@ -109,16 +109,16 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
     
     TcpipRecursiveMutexEnter( &TCPLock, TRUE );
     
-    for( ListEntry = Listener->ListenRequest.Flink;
-        ListEntry != &Listener->ListenRequest;
-        ListEntry = ListEntry->Flink ) {
+    ListEntry = Listener->ListenRequest.Flink;
+    while ( ListEntry != &Listener->ListenRequest ) {
        Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
+       ListEntry = ListEntry->Flink;
 
-       if( Bucket->Request.Handle.ConnectionContext == Connection ) {
+       if( Bucket->AssociatedEndpoint == Connection ) {
 #ifdef MEMTRACK
            UntrackFL( __FILE__, __LINE__, Bucket->Request.RequestContext );
 #endif
-           RemoveEntryList( ListEntry );
+           RemoveEntryList( ListEntry->Blink );
            ExFreePool( Bucket );
        }
     }
index 167add7..7ea8373 100644 (file)
@@ -155,15 +155,28 @@ static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
     }
 
     if( NewState & SEL_FIN ) {
+        PLIST_ENTRY ListsToErase[4];
+        NTSTATUS    IrpStatus[4];
+        UINT i;
+
        TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
        
-       while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
-           Entry = RemoveHeadList( &Connection->ReceiveRequest );
-           Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
-       }
+        ListsToErase[0] = &Connection->ReceiveRequest;
+        IrpStatus   [0] = STATUS_SUCCESS;
+        ListsToErase[1] = &Connection->ListenRequest;
+        IrpStatus   [1] = STATUS_UNSUCCESSFUL;
+        ListsToErase[2] = &Connection->ConnectRequest;
+        IrpStatus   [2] = STATUS_UNSUCCESSFUL;
+        ListsToErase[3] = 0;
+
+        for( i = 0; ListsToErase[i]; i++ ) {
+            while( !IsListEmpty( ListsToErase[i] ) ) {
+                Entry = RemoveHeadList( ListsToErase[i] );
+                Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+                Complete = Bucket->Request.RequestNotifyObject;
+                Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
+            }
+        }
     }
 
     Connection->Signalled = FALSE;
@@ -371,39 +384,6 @@ NTSTATUS TCPTranslateError( int OskitError ) {
     return Status;
 }
 
-#if 0
-NTSTATUS TCPBind
-( PCONNECTION_ENDPOINT Connection,
-  PTDI_CONNECTION_INFORMATION ConnInfo ) {
-    NTSTATUS Status;
-    SOCKADDR_IN AddressToConnect;
-    PIP_ADDRESS LocalAddress;
-    USHORT LocalPort;
-
-    TI_DbgPrint(DEBUG_TCP,("Called\n"));
-
-    Status = AddrBuildAddress
-       ((PTA_ADDRESS)ConnInfo->LocalAddress,
-        &LocalAddress,
-        &LocalPort);
-
-    AddressToBind.sin_family = AF_INET;
-    memcpy( &AddressToBind.sin_addr, 
-           &LocalAddress->Address.IPv4Address,
-           sizeof(AddressToBind.sin_addr) );
-    AddressToBind.sin_port = LocalPort;
-
-    Status = OskitTCPBind( Connection->SocketContext,
-                          Connection,
-                          &AddressToBind, 
-                          sizeof(AddressToBind));
-
-    TI_DbgPrint(DEBUG_TCP,("Leaving %x\n", Status));
-
-    return Status;
-}
-#endif
-
 NTSTATUS TCPConnect
 ( PCONNECTION_ENDPOINT Connection,
   PTDI_CONNECTION_INFORMATION ConnInfo,
@@ -518,8 +498,9 @@ NTSTATUS TCPClose
 
     Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
 
-    if( Connection->Signalled ) 
-       RemoveEntryList( &Connection->SignalList );
+    /* Make our code remove all pending IRPs */
+    Connection->State |= SEL_FIN;
+    DrainSignals();
 
     TcpipRecursiveMutexLeave( &TCPLock );
     
@@ -648,6 +629,8 @@ NTSTATUS TCPGetPeerAddress
     OSK_UI16 LocalPort, RemotePort;
     PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
 
+    TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
     OskitTCPGetAddress
         ( Connection->SocketContext,
           &LocalAddress, &LocalPort,
@@ -658,6 +641,8 @@ NTSTATUS TCPGetPeerAddress
     AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
     AddressIP->Address[0].Address[0].sin_port = RemotePort;
     AddressIP->Address[0].Address[0].in_addr = RemoteAddress;
+
+    TcpipRecursiveMutexLeave( &TCPLock );
     
     return STATUS_SUCCESS;
 }
index 26ef02e..ad72595 100644 (file)
@@ -80,6 +80,11 @@ NTSTATUS DDKAPI ListenComplete
     PAFD_FCB FCB = (PAFD_FCB)Context;
     PAFD_TDI_OBJECT_QELT Qelt;
 
+    if ( Irp->Cancel ) {
+       /* FIXME: is this anything else we need to do? */
+       return STATUS_SUCCESS;
+    }
+
     if( !SocketAcquireStateLock( FCB ) ) return Status;
 
     FCB->ListenIrp.InFlightRequest = NULL;
index 2ecc315..c173ead 100644 (file)
@@ -11,6 +11,7 @@
 #include "tdi_proto.h"
 #include "tdiconn.h"
 #include "debug.h"
+#include "pseh.h"
 
 /* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
@@ -49,21 +50,31 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
     UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
     PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
     PMDL NewMdl;
+    INT NewBufferLen;
 
     AFD_DbgPrint(MID_TRACE,("Called\n"));
 
     if( NewBuf ) {
        PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
 
-       RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
-
-       if( LockAddress ) {
-           NewBuf[Count].buf = AddressBuf;
-           NewBuf[Count].len = *AddressLen;
-           Count++;
-           NewBuf[Count].buf = (PVOID)AddressLen;
-           NewBuf[Count].len = sizeof(*AddressLen);
-           Count++;
+        _SEH_TRY {
+            RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
+            NewBufferLen = *AddressLen;
+        } _SEH_HANDLE {
+            AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "
+                                    "from userland (%x %x)\n", 
+                                    Buf, AddressLen));
+            ExFreePool( NewBuf );
+            return NULL;
+        } _SEH_END;
+
+        if( LockAddress ) {
+            NewBuf[Count].buf = AddressBuf;
+            NewBuf[Count].len = NewBufferLen;
+            Count++;
+            NewBuf[Count].buf = (PVOID)AddressLen;
+            NewBuf[Count].len = sizeof(*AddressLen);
+            Count++;
        }
 
        for( i = 0; i < Count; i++ ) {
@@ -126,6 +137,7 @@ PAFD_HANDLE LockHandles( PAFD_HANDLE HandleArray, UINT HandleCount ) {
     for( i = 0; FileObjects && i < HandleCount; i++ ) {
        HandleArray[i].Status = 0;
        HandleArray[i].Events = HandleArray[i].Events;
+        FileObjects[i].Handle = 0;
        Status = ObReferenceObjectByHandle
            ( (PVOID)HandleArray[i].Handle,
              FILE_ALL_ACCESS,
index 1b9ab1d..d348151 100644 (file)
@@ -20,8 +20,8 @@
 #ifdef DBG
 
 /* See debug.h for debug/trace constants */
-//DWORD DebugTraceLevel = DEBUG_ULTRA;
-DWORD DebugTraceLevel = 0;
+DWORD DebugTraceLevel = DEBUG_ULTRA;
+//DWORD DebugTraceLevel = 0;
 
 #endif /* DBG */
 
index b815d7e..569da46 100644 (file)
@@ -26,8 +26,6 @@
 #include "tdiconn.h"
 #include "debug.h"
 
-static VOID ProcessClose( PAFD_FCB FCB );
-
 BOOLEAN CantReadMore( PAFD_FCB FCB ) {
     UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
     
@@ -35,6 +33,14 @@ BOOLEAN CantReadMore( PAFD_FCB FCB ) {
         (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
 }
 
+VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, UINT Information ) {
+    if( Status == STATUS_SUCCESS && Information == 0 ) {
+        AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
+        FCB->PollState |= AFD_EVENT_CLOSE /*| AFD_EVENT_DISCONNECT */;
+        PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+}
+
 NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
                                            PAFD_RECV_INFO RecvReq,
                                            PUINT TotalBytesCopied ) {
@@ -103,14 +109,9 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
                                 ReceiveComplete,
                                 FCB );
 
-           if( Status == STATUS_SUCCESS ) {
-               if( !FCB->ReceiveIrp.Iosb.Information ) {
-                   AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
-                   ProcessClose( FCB );
-               }
-               FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
-           }
-           
+            if( Status == STATUS_SUCCESS ) 
+                FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
+            HandleEOFOnIrp( FCB, Status, FCB->Recv.Content );
            SocketCalloutLeave( FCB );
        }
     }
@@ -118,66 +119,42 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
     return STATUS_SUCCESS;
 }
 
-static VOID ProcessClose( PAFD_FCB FCB ) {
-    PLIST_ENTRY NextIrpEntry;
-    PIRP NextIrp;
-
-    AFD_DbgPrint(MID_TRACE,("Socket shutdown from remote side\n"));
-
-    /* Kill remaining recv irps */
-    while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
-       NextIrpEntry = 
-           RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
-       NextIrp = 
-           CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
-       AFD_DbgPrint(MID_TRACE,("Completing recv %x (%x)\n", 
-                               NextIrp, STATUS_END_OF_FILE));
-       NextIrp->IoStatus.Status = STATUS_SUCCESS;
-       NextIrp->IoStatus.Information = 0;
-       IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
-    }
-    
-    /* Handle closing signal */
-    FCB->PollState |= AFD_EVENT_DISCONNECT | SOCKET_STATE_EOF_READ;
-
-    PollReeval( FCB->DeviceExt, FCB->FileObject );
-}
-
-NTSTATUS DDKAPI ReceiveComplete
-( PDEVICE_OBJECT DeviceObject,
-  PIRP Irp,
-  PVOID Context ) {
-    NTSTATUS Status = Irp->IoStatus.Status;
-    PAFD_FCB FCB = (PAFD_FCB)Context;
+NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
     PLIST_ENTRY NextIrpEntry;
     PIRP NextIrp;
     PIO_STACK_LOCATION NextIrpSp;
     PAFD_RECV_INFO RecvReq;
     UINT TotalBytesCopied = 0;
+    NTSTATUS Status = STATUS_SUCCESS, RetStatus = STATUS_PENDING;
 
-    AFD_DbgPrint(MID_TRACE,("Called\n"));
-
-    ASSERT_IRQL(APC_LEVEL);
-
-    if( !SocketAcquireStateLock( FCB ) ) return Status;
-
-    FCB->ReceiveIrp.InFlightRequest = NULL;
-    FCB->Recv.Content = Irp->IoStatus.Information;
-    FCB->Recv.BytesUsed = 0;
+    AFD_DbgPrint(MID_TRACE,("%x %x\n", FCB, Irp));
 
-    if( FCB->State == SOCKET_STATE_CLOSED ) {
-        AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n"));
-       SocketStateUnlock( FCB );
-       DestroySocket( FCB );
-       return STATUS_SUCCESS;
-    } else if( FCB->State == SOCKET_STATE_LISTENING ) {
-        AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
-        SocketStateUnlock( FCB );
-        return STATUS_UNSUCCESSFUL;
-    }
-    
-    if( NT_SUCCESS(Irp->IoStatus.Status) && 
-       Irp->IoStatus.Information ) {
+    if( CantReadMore( FCB ) ) {
+        /* Success here means that we got an EOF.  Complete a pending read
+         * with zero bytes if we haven't yet overread, then kill the others.
+         */
+        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
+            NextIrpEntry = 
+                RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
+            NextIrp = 
+                CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+            NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
+            RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+            
+            AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
+                                    TotalBytesCopied));
+            UnlockBuffers( RecvReq->BufferArray, 
+                           RecvReq->BufferCount, FALSE );
+            Status = NextIrp->IoStatus.Status = 
+                FCB->Overread ? STATUS_END_OF_FILE : STATUS_SUCCESS;
+            NextIrp->IoStatus.Information = 0;
+            if( NextIrp == Irp ) RetStatus = Status;
+            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+            FCB->Overread = TRUE;
+            //FCB->PollState |= AFD_EVENT_DISCONNECT;
+            PollReeval( FCB->DeviceExt, FCB->FileObject );
+        }
+    } else {
        /* Kick the user that receive would be possible now */
        /* XXX Not implemented yet */
 
@@ -214,31 +191,10 @@ NTSTATUS DDKAPI ReceiveComplete
                               RecvReq->BufferCount, FALSE );
                NextIrp->IoStatus.Status = Status;
                NextIrp->IoStatus.Information = TotalBytesCopied;
+                if( NextIrp == Irp ) RetStatus = Status;
                IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
            }
        }
-
-       Status = STATUS_SUCCESS;
-    } else {
-        /* Success here means that we got an EOF.  Close all pending reads
-         * with EOF.  Data won't have been available before. */
-        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) {
-            NextIrpEntry = 
-                RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]);
-            NextIrp = 
-                CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
-            NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp );
-            RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
-            
-            AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp,
-                                    TotalBytesCopied));
-            UnlockBuffers( RecvReq->BufferArray, 
-                           RecvReq->BufferCount, FALSE );
-            NextIrp->IoStatus.Status = Status;
-            NextIrp->IoStatus.Information = 0;
-            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
-        }
-       ProcessClose( FCB );
     }
 
     if( FCB->Recv.Content ) {
@@ -248,13 +204,50 @@ NTSTATUS DDKAPI ReceiveComplete
 
     PollReeval( FCB->DeviceExt, FCB->FileObject );    
 
-    SocketStateUnlock( FCB );
+    AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus));
+
+    return RetStatus;
+}
+
+NTSTATUS DDKAPI ReceiveComplete
+( PDEVICE_OBJECT DeviceObject,
+  PIRP Irp,
+  PVOID Context ) {
+    NTSTATUS Status = Irp->IoStatus.Status;
+    PAFD_FCB FCB = (PAFD_FCB)Context;
+
+    AFD_DbgPrint(MID_TRACE,("Called\n"));
+
+    ASSERT_IRQL(APC_LEVEL);
+
+    if( !SocketAcquireStateLock( FCB ) ) return Status;
+
+    FCB->ReceiveIrp.InFlightRequest = NULL;
+    FCB->Recv.Content = Irp->IoStatus.Information;
+    FCB->Recv.BytesUsed = 0;
+
+    if( FCB->State == SOCKET_STATE_CLOSED ) {
+        AFD_DbgPrint(MIN_TRACE,("!!! CLOSED SOCK GOT A RECEIVE COMPLETE !!!\n"));
+       SocketStateUnlock( FCB );
+       DestroySocket( FCB );
+       return STATUS_SUCCESS;
+    } else if( FCB->State == SOCKET_STATE_LISTENING ) {
+        AFD_DbgPrint(MIN_TRACE,("!!! LISTENER GOT A RECEIVE COMPLETE !!!\n"));
+        SocketStateUnlock( FCB );
+        return STATUS_UNSUCCESSFUL;
+    }
+    
+    HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
 
-    if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
+    ReceiveActivity( FCB, NULL );
+    
+    PollReeval( FCB->DeviceExt, FCB->FileObject );
+
+    SocketStateUnlock( FCB );
 
     AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
 
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS STDCALL
@@ -265,7 +258,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_RECV_INFO RecvReq;
     UINT TotalBytesCopied = 0;
-
+    
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
@@ -274,7 +267,8 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
         FCB->State != SOCKET_STATE_CONNECTING ) {
         AFD_DbgPrint(MID_TRACE,("Called recv on wrong kind of socket (s%x)\n",
                                 FCB->State));
-        return STATUS_UNSUCCESSFUL;
+        return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, 
+                                      Irp, 0, NULL, FALSE );
     }
 
     if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
@@ -291,57 +285,45 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, 
                                       Irp, 0, NULL, FALSE );
 
+    AFD_DbgPrint(MID_TRACE,("Recv flags %x\n", RecvReq->AfdFlags));
+
     RecvReq->BufferArray = LockBuffers( RecvReq->BufferArray, 
                                        RecvReq->BufferCount,
                                        NULL, NULL,
                                        TRUE, FALSE );
 
-    /* Check if we're not closed down yet */
-
-    if( !CantReadMore(FCB) ) {
-       AFD_DbgPrint(MID_TRACE,("Not EOF yet\n"));
-       if( FCB->ReceiveIrp.InFlightRequest ) {
-           AFD_DbgPrint(MID_TRACE,("We're waiting on a previous irp\n"));
-           Status = STATUS_PENDING;
-       } else {
-           AFD_DbgPrint(MID_TRACE,("The buffer is likely not empty\n"));
-           Status = STATUS_SUCCESS;
-       }
-    } else {
-       if( FCB->PollState & SOCKET_STATE_EOF_READ )
-            Status = STATUS_END_OF_FILE;
-        else
-            Status = STATUS_SUCCESS;
-        
-        AFD_DbgPrint(MID_TRACE,("EOF Happened already\n"));
-        FCB->Recv.Content = 0;
-        FCB->Recv.BytesUsed = 0;
-
-       ProcessClose( FCB );
-
-        return UnlockAndMaybeComplete
-            ( FCB, Status, Irp, 0, NULL, FALSE);
+    if( !RecvReq->BufferArray ) {
+        return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
+                                       Irp, 0, NULL, FALSE );
     }
 
-    if( NT_SUCCESS(Status) ) {
-       AFD_DbgPrint(MID_TRACE,("TryToSatisfy\n"));
-        Status = TryToSatisfyRecvRequestFromBuffer
-            ( FCB, RecvReq, &TotalBytesCopied );
-    }
+    Irp->IoStatus.Status = STATUS_PENDING;
+    Irp->IoStatus.Information = 0;
+
+    InsertTailList( &FCB->PendingIrpList[FUNCTION_RECV], 
+                    &Irp->Tail.Overlay.ListEntry );
+
+    /************ From this point, the IRP is not ours ************/
+
+    Status = ReceiveActivity( FCB, Irp );
     
-    if( Status != STATUS_PENDING || RecvReq->AfdFlags & AFD_IMMEDIATE ) {
-       if( Status == STATUS_PENDING ) {
-           AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
-           Status = STATUS_CANT_WAIT;
-           TotalBytesCopied = 0;
-       }
-       UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
-       return UnlockAndMaybeComplete( FCB, Status, Irp, 
-                                     TotalBytesCopied, NULL, TRUE );
-    } else {
+    if( Status == STATUS_PENDING && RecvReq->AfdFlags & AFD_IMMEDIATE ) {
+        AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
+        Status = STATUS_CANT_WAIT;
+        TotalBytesCopied = 0;
+        RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
+        UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE );
+        return UnlockAndMaybeComplete( FCB, Status, Irp, 
+                                       TotalBytesCopied, NULL, TRUE );
+    } else if( Status == STATUS_PENDING ) {
         AFD_DbgPrint(MID_TRACE,("Leaving read irp\n"));
-       return LeaveIrpUntilLater( FCB, Irp, FUNCTION_RECV );
+        IoMarkIrpPending( Irp );
+    } else {
+        AFD_DbgPrint(MID_TRACE,("Completed with status %x\n", Status));
     }
+
+    SocketStateUnlock( FCB );
+    return Status;
 }
 
 
index 85e491d..54909ef 100644 (file)
@@ -132,7 +132,7 @@ typedef struct _AFD_STORED_DATAGRAM {
 } AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM;
 
 typedef struct _AFD_FCB {
-    BOOLEAN Locked, Critical;
+    BOOLEAN Locked, Critical, Overread;
     UINT State, Flags;
     KIRQL OldIrql;
     UINT LockCount;
index f0d61d0..e6c227c 100644 (file)
@@ -159,6 +159,7 @@ ProRequest(
   if (QueueWorkItem) 
     {
       MiniQueueWorkItem(Adapter, NdisWorkItemRequest, (PVOID)NdisRequest);
+      KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
       return NDIS_STATUS_PENDING;
     } 
 
index 4633b63..79972b7 100644 (file)
@@ -165,6 +165,28 @@ VOID FreeAdapter(
 }
 
 
+NTSTATUS TcpipLanGetDwordOid
+( PIP_INTERFACE Interface,
+  NDIS_OID Oid,
+  PDWORD Result ) {
+    /* Get maximum frame size */
+    if( Interface->Context ) {
+        return NDISCall((PLAN_ADAPTER)Interface->Context,
+                        NdisRequestQueryInformation,
+                        Oid,
+                        Result,
+                        sizeof(DWORD));
+    } else switch( Oid ) { /* Loopback Case */
+    case OID_GEN_HARDWARE_STATUS:
+        *Result = NdisHardwareStatusReady;
+        return STATUS_SUCCESS;
+
+    default:
+        return STATUS_INVALID_PARAMETER;
+    }
+}
+
+
 VOID STDCALL ProtocolOpenAdapterComplete(
     NDIS_HANDLE BindingContext,
     NDIS_STATUS Status,
@@ -916,11 +938,10 @@ VOID BindAdapter(
     TI_DbgPrint(MID_TRACE,("BCAST(IF) %s\n", A2S(&IF->Broadcast)));
 
     if(NT_SUCCESS(Status)) {
+        RtlZeroMemory( &IF->Name, sizeof(IF->Name) );
        Status = ReadStringFromRegistry( RegHandle, L"DeviceDesc",
                                         &IF->Name );
 
-       RtlZeroMemory( &IF->Name, sizeof( IF->Name ) );
-
        /* I think that not getting a devicedesc is not a fatal error */
        if( !NT_SUCCESS(Status) ) {
            if( IF->Name.Buffer ) exFreePool( IF->Name.Buffer );
@@ -929,6 +950,8 @@ VOID BindAdapter(
        Status = STATUS_SUCCESS;
     }
 
+    TI_DbgPrint(MID_TRACE,("Adapter Name: %wZ\n", &IF->Name));
+
     if(!NT_SUCCESS(Status))
     {
        TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
index 5108ff5..bd55951 100644 (file)
@@ -56,6 +56,14 @@ NTSTATUS DispTdiSetInformationEx(
     PIRP Irp,
     PIO_STACK_LOCATION IrpSp);
 
+NTSTATUS DispTdiSetIPAddress(
+    PIRP Irp,
+    PIO_STACK_LOCATION IrpSp);
+
+NTSTATUS DispTdiDeleteIPAddress(
+    PIRP Irp,
+    PIO_STACK_LOCATION IrpSp);
+
 #endif /* __DISPATCH_H */
 
 /* EOF */
index a8ad99f..8f08235 100644 (file)
@@ -13,6 +13,8 @@ UINT CountInterfaceAddresses( PIP_INTERFACE Interface );
 NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed );
 NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer,
                           UINT NameMaxLen );
+NTSTATUS GetInterfaceConnectionStatus( PIP_INTERFACE Interface,
+                                       PDWORD OperStatus );
 PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address);
 
 #endif//_TCPIP_INTERFACE_H
index 9986897..68950ce 100644 (file)
@@ -153,10 +153,16 @@ typedef struct _IP_INTERFACE {
     UNICODE_STRING Name;          /* Adapter name */
     PUCHAR Address;               /* Pointer to interface address */
     UINT  AddressLength;          /* Length of address in bytes */
+    UINT  Index;                  /* Index of adapter (used to add ip addr) */
     LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */
     PVOID TCPContext;             /* TCP Content for this interface */
 } IP_INTERFACE, *PIP_INTERFACE;
 
+typedef struct _IP_SET_ADDRESS {
+    ULONG NteIndex;
+    IPv4_RAW_ADDRESS Address;
+    IPv4_RAW_ADDRESS Netmask;
+} IP_SET_ADDRESS, *PIP_SET_ADDRESS;
 
 #define IP_PROTOCOL_TABLE_SIZE 0x100
 
index bbfeda5..e88bd9e 100644 (file)
@@ -98,6 +98,9 @@ VOID LANUnregisterProtocol(
 VOID LANStartup();
 VOID LANShutdown();
 
+NTSTATUS TcpipLanGetDwordOid( PIP_INTERFACE Interface, NDIS_OID Oid, 
+                              PDWORD Result );
+
 NDIS_STATUS NDISCall(
     PLAN_ADAPTER Adapter,
     NDIS_REQUEST_TYPE Type,
index 568c4a7..3b2ff7b 100644 (file)
@@ -35,5 +35,6 @@
 #include <oskittcp.h>
 #include <interface.h>
 #include <ports.h>
+#include <ipifcons.h>
 #define NTOS_MODE_USER
 #include <ntos.h>
index fbc7448..b40f568 100644 (file)
@@ -136,7 +136,7 @@ typedef struct {
 } TDIEntityInfo;
 
 #ifndef htons
-#define htons(x) (((x) << 16) | (((x) >> 8) & 0xff))
+#define htons(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
 #endif
 
 /* Global variable */
index ab0b242..ca26064 100644 (file)
 #define IOCTL_TCP_SET_INFORMATION_EX \
     _TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 
+#define IOCTL_SET_IP_ADDRESS \
+    _TCP_CTL_CODE(14, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_DELETE_IP_ADDRESS \
+    _TCP_CTL_CODE(16, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
 /* Unique error values for log entries */
 #define TI_ERROR_DRIVERENTRY 0
 
index 378f266..0f25e9e 100644 (file)
@@ -219,6 +219,52 @@ VOID DDKAPI DispCancelRequest(
 }
 
 
+VOID DDKAPI DispCancelListenRequest(
+    PDEVICE_OBJECT Device,
+    PIRP Irp)
+/*
+ * FUNCTION: Cancels a listen IRP
+ * ARGUMENTS:
+ *     Device = Pointer to device object
+ *     Irp    = Pointer to an I/O request packet
+ */
+{
+    PIO_STACK_LOCATION IrpSp;
+    PTRANSPORT_CONTEXT TranContext;
+    PFILE_OBJECT FileObject;
+    PCONNECTION_ENDPOINT Connection;
+    /*NTSTATUS Status = STATUS_SUCCESS;*/
+
+    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+    IrpSp         = IoGetCurrentIrpStackLocation(Irp);
+    FileObject    = IrpSp->FileObject;
+    TranContext   = (PTRANSPORT_CONTEXT)FileObject->FsContext;
+    ASSERT( TDI_LISTEN == IrpSp->MinorFunction);
+
+    TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X).\n", Irp));
+
+#ifdef DBG
+    if (!Irp->Cancel)
+        TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
+#endif
+
+    /* Try canceling the request */
+    Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+    TCPAbortListenForSocket(
+           Connection->AddressFile->Listener,
+           Connection );
+
+    IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+    DispDataRequestComplete(Irp, STATUS_CANCELLED, 0);
+    
+    DispCancelComplete(FileObject);
+
+    TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
+
+
 NTSTATUS DispTdiAccept(
   PIRP Irp)
 /*
@@ -536,6 +582,12 @@ NTSTATUS DispTdiListen(
          Status = TCPListen( Connection->AddressFile->Listener, 1024 ); 
          /* BACKLOG */
   }
+  if( NT_SUCCESS(Status) ) {
+      Status = DispPrepareIrpForCancel
+          (TranContext->Handle.ConnectionContext, 
+           Irp, 
+           (PDRIVER_CANCEL)DispCancelListenRequest);
+  }
 
   if( NT_SUCCESS(Status) ) {
       Status = TCPAccept
@@ -1413,4 +1465,56 @@ NTSTATUS DispTdiSetInformationEx(
     return Status;
 }
 
+/* TODO: Support multiple addresses per interface.
+ * For now just set the nte context to the interface index.
+ *
+ * Later on, create an NTE context and NTE instance
+ */
+
+NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+    NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
+    PIP_SET_ADDRESS IpAddrChange = 
+        (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
+    IF_LIST_ITER(IF);
+
+    ForEachInterface(IF) {
+        if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) {
+            Status = STATUS_DUPLICATE_OBJECTID;
+            break;
+        }
+        if( IF->Index == IpAddrChange->NteIndex ) {
+            IF->Unicast.Type = IP_ADDRESS_V4;
+            IF->Unicast.Address.IPv4Address = IpAddrChange->Address;
+            IF->Netmask.Type = IP_ADDRESS_V4;
+            IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
+            IpAddrChange->Address = IF->Index;
+            Status = STATUS_SUCCESS;
+            Irp->IoStatus.Information = IF->Index;
+            break;
+        }
+    } EndFor(IF);
+
+    Irp->IoStatus.Status = Status;
+    return Status;
+}
+
+NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer;
+    IF_LIST_ITER(IF);
+
+    ForEachInterface(IF) {
+        if( IF->Index == *NteIndex ) {
+            IF->Unicast.Type = IP_ADDRESS_V4;
+            IF->Unicast.Address.IPv4Address = 0;
+            IF->Netmask.Type = IP_ADDRESS_V4;
+            IF->Netmask.Address.IPv4Address = 0;
+            Status = STATUS_SUCCESS;
+        }
+    } EndFor(IF);
+
+    Irp->IoStatus.Status = Status;
+    return Status;
+}
+
 /* EOF */
index d0afdfd..2c14402 100644 (file)
@@ -33,15 +33,21 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
 
     RtlZeroMemory( OutData, sizeof(IFENTRY) + MAX_IFDESCR_LEN );
 
-    OutData->Index = ID->tei_instance + 1; 
+    OutData->Index = Interface->Index;
     /* viz: tcpip keeps those indices */
-    OutData->Type = Interface == Loopback ? IFENT_SOFTWARE_LOOPBACK : 0;
+    OutData->Type = Interface == 
+        Loopback ? MIB_IF_TYPE_LOOPBACK : MIB_IF_TYPE_ETHERNET;
     OutData->Mtu = Interface->MTU;
     TI_DbgPrint(MAX_TRACE, 
                ("Getting interface speed\n"));
     OutData->PhysAddrLen = Interface->AddressLength;
-    OutData->AdminStatus = 1; /* XXX Up -- How do I know? */
-    OutData->OperStatus = 1; /* XXX Up -- How do I know? */
+    OutData->AdminStatus = MIB_IF_ADMIN_STATUS_UP;
+    /* NDIS_HARDWARE_STATUS -> ROUTER_CONNECTION_STATE */
+    Status = GetInterfaceConnectionStatus( Interface, &OutData->OperStatus );
+
+    /* Not sure what to do here, but not ready seems a safe bet on failure */
+    if( !NT_SUCCESS(Status) ) 
+        OutData->OperStatus = NdisHardwareStatusNotReady;
 
     IFDescr = (PCHAR)&OutData[1];
 
@@ -98,5 +104,7 @@ TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
                                  TDIEntityID *id,
                                  PCHAR Buffer,
                                  UINT BufferSize ) {
+    TI_DbgPrint(MAX_TRACE, ("Got Request: Class %x Type %x Id %x, EntityID %x:%x\n",
+                InfoClass, InfoId, id->tei_entity, id->tei_instance));
     return TDI_INVALID_REQUEST;
 }
index 21aa80e..e98a7ad 100644 (file)
@@ -9,7 +9,7 @@
  */
 #include "precomp.h"
 
-#define NDEBUG
+//#define NDEBUG
 
 #ifndef NDEBUG
 DWORD DebugTraceLevel = DEBUG_ULTRA & ~(DEBUG_LOCK | DEBUG_PBUFFER);
@@ -578,6 +578,16 @@ TiDispatch(
       Status = DispTdiSetInformationEx(Irp, IrpSp);
       break;
 
+    case IOCTL_SET_IP_ADDRESS:
+      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
+      Status = DispTdiSetIPAddress(Irp, IrpSp);
+      break;
+
+    case IOCTL_DELETE_IP_ADDRESS:
+      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
+      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
+      break;
+
     default:
       TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
           IrpSp->Parameters.DeviceIoControl.IoControlCode));
index 987eb2f..1dc6743 100644 (file)
@@ -58,7 +58,7 @@ static ULONG gNumberOfControllers = 0;
 
 /* Queue thread management */
 static KEVENT QueueThreadTerminate;
-static PVOID ThreadObject;
+static PVOID QueueThreadObject;
 
 \f
 static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc,
@@ -378,8 +378,8 @@ static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
   KdPrint(("floppy: unloading\n"));
 
   KeSetEvent(&QueueThreadTerminate, 0, FALSE);
-  KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, 0);
-  ObDereferenceObject(ThreadObject);
+  KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode, FALSE, 0);
+  ObDereferenceObject(QueueThreadObject);
 
   for(i = 0; i < gNumberOfControllers; i++)
     {
@@ -861,6 +861,7 @@ static BOOLEAN NTAPI AddControllers(PDRIVER_OBJECT DriverObject)
       DeviceDescription.DmaChannel = gControllerInfo[i].Dma;
       DeviceDescription.InterfaceType = gControllerInfo[i].InterfaceType;
       DeviceDescription.BusNumber = gControllerInfo[i].BusNumber;
+      DeviceDescription.MaximumLength = 2*18*512; /* based on a 1.44MB floppy */
 
       /* DMA 0,1,2,3 are 8-bit; 4,5,6,7 are 16-bit (4 is chain i think) */
       DeviceDescription.DmaWidth = gControllerInfo[i].Dma > 3 ? Width16Bits: Width8Bits;
@@ -1152,7 +1153,7 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
       return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-  if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS)
+  if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: Unable to reference returned thread handle; failing init\n"));
       return STATUS_UNSUCCESSFUL;
index d3d0b68..c703b23 100644 (file)
@@ -654,10 +654,10 @@ VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo,
       KdPrint(("floppy: ReadWritePassive(): computing number of sectors to transfer (StartSector 0x%x): ", StartSector));
 
       /* 1-based sector number */
-      if( ((DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1) < 
+      if( (((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1 ) < 
          (Length - TransferByteOffset) / DriveInfo->DiskGeometry.BytesPerSector)
        {
-         CurrentTransferSectors = (UCHAR)(DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1;
+         CurrentTransferSectors = (UCHAR)((DriveInfo->DiskGeometry.TracksPerCylinder - Head) * DriveInfo->DiskGeometry.SectorsPerTrack - StartSector) + 1;
        }
       else
        {
@@ -703,7 +703,7 @@ VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo,
 
       /* Issue the read/write command to the controller.  Note that it expects the opposite of WriteToDevice. */ 
       if(HwReadWriteData(DriveInfo->ControllerInfo, !WriteToDevice, DriveInfo->UnitNumber, Cylinder, Head, StartSector, 
-                        DriveInfo->BytesPerSectorCode, StartSector + CurrentTransferSectors, 0, 0xff) != STATUS_SUCCESS)
+                        DriveInfo->BytesPerSectorCode, DriveInfo->DiskGeometry.SectorsPerTrack, 0, 0xff) != STATUS_SUCCESS)
        {
          KdPrint(("floppy: ReadWritePassive(): HwReadWriteData returned failure; unable to read; completing with STATUS_UNSUCCESSFUL\n"));
          RWFreeAdapterChannel(DriveInfo->ControllerInfo->AdapterObject);
@@ -723,7 +723,7 @@ VOID NTAPI ReadWritePassive(PDRIVE_INFO DriveInfo,
       /* Read is complete; flush & free adapter channel */
       IoFlushAdapterBuffers(DriveInfo->ControllerInfo->AdapterObject, Irp->MdlAddress, 
                            DriveInfo->ControllerInfo->MapRegisterBase, 
-                           MmGetMdlVirtualAddress(Irp->MdlAddress),
+                           (PVOID)((ULONG_PTR)MmGetMdlVirtualAddress(Irp->MdlAddress) + TransferByteOffset),
                            CurrentTransferBytes, WriteToDevice);
 
       /* Read the results from the drive */
index 0ecfb87..a1fe160 100644 (file)
@@ -210,6 +210,7 @@ IntInitScreenInfo(
    pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
    pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
    pGdiInfo->flTextCaps = TC_RA_ABLE;
+   pGdiInfo->flRaster = 0;
    pGdiInfo->ulDACRed = SelectedMode->NumberRedBits;
    pGdiInfo->ulDACGreen = SelectedMode->NumberGreenBits;
    pGdiInfo->ulDACBlue = SelectedMode->NumberBlueBits;
index 9c06d9a..1dae9cd 100644 (file)
@@ -266,6 +266,9 @@ DrvEnablePDEV(IN DEVMODEW *DM,
     GDIInfoSize = sizeof(GDIINFO);
     }
   memcpy(GDIInfo, &gaulCap, GDIInfoSize);
+  DM->dmBitsPerPel = gaulCap.cBitsPixel * gaulCap.cPlanes;
+  DM->dmPelsWidth = gaulCap.ulHorzRes;
+  DM->dmPelsHeight = gaulCap.ulVertRes;
 
   devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16, (ULONG *) VGApalette.PaletteEntry, 0, 0, 0);
   if (sizeof(DEVINFO) < DevInfoSize)
index 504cbbd..a8831ce 100644 (file)
@@ -329,6 +329,10 @@ IntVideoPortPnPStartDevice(
             {
                DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
                DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
+               if (Descriptor->ShareDisposition == CmResourceShareShared)
+                  DeviceExtension->InterruptShared = TRUE;
+               else
+                  DeviceExtension->InterruptShared = FALSE;
             }
          }
       }
index 7b856a1..04fa84a 100644 (file)
@@ -85,7 +85,7 @@ IntVideoPortSetupInterrupt(
          Irql,
          Irql,
          ConfigInfo->InterruptMode,
-         FALSE,
+         DeviceExtension->InterruptShared,
          Affinity,
          FALSE);
 
index ece08ed..00cd872 100644 (file)
@@ -559,6 +559,10 @@ VideoPortGetAccessRanges(
             {
                DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
                DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
+               if (Descriptor->ShareDisposition == CmResourceShareShared)
+                  DeviceExtension->InterruptShared = TRUE;
+               else
+                  DeviceExtension->InterruptShared = FALSE;
             }
          }
       }
index f25ed08..3a5df1c 100644 (file)
@@ -93,6 +93,7 @@ typedef struct _VIDEO_PORT_DEVICE_EXTENSTION
    PCM_RESOURCE_LIST AllocatedResources;
    ULONG InterruptVector;
    ULONG InterruptLevel;
+   BOOLEAN InterruptShared;
    ULONG AdapterInterfaceType;
    ULONG SystemIoBusNumber;
    ULONG SystemIoSlotNumber;
index e9d7243..9208b3c 100644 (file)
@@ -757,6 +757,27 @@ KeAcquireSpinLockRaiseToSynch(
 }
 
 
+VOID
+FASTCALL
+KeAcquireInStackQueuedSpinLock(
+    IN PKSPIN_LOCK SpinLock,
+    IN PKLOCK_QUEUE_HANDLE LockHandle
+    )
+{
+  UNIMPLEMENTED;
+}
+
+
+VOID
+FASTCALL
+KeReleaseInStackQueuedSpinLock(
+    IN PKLOCK_QUEUE_HANDLE LockHandle
+    )
+{
+  UNIMPLEMENTED;
+}
+
+
 VOID
 STDCALL
 KeFlushWriteBuffer(VOID)
index e0cdbc3..9f9d7fd 100644 (file)
@@ -70,6 +70,7 @@ KdPortSave@0
 KdPortDisableInterrupts@0
 KdPortEnableInterrupts@0
 KeAcquireSpinLock@8
+@KeAcquireInStackQueuedSpinLock@8
 @KeAcquireSpinLockRaiseToSynch@4
 KeGetCurrentIrql@0
 KeFlushWriteBuffer@0
@@ -78,6 +79,7 @@ KeQueryPerformanceCounter@4
 KeRaiseIrql@8
 KeRaiseIrqlToDpcLevel@0
 KeRaiseIrqlToSynchLevel@0
+@KeReleaseInStackQueuedSpinLock@4
 KeReleaseSpinLock@8
 KeStallExecutionProcessor@4
 @KfAcquireSpinLock@4
index d2b0507..63eb758 100644 (file)
@@ -121,8 +121,8 @@ HalGetAdapter (PDEVICE_DESCRIPTION  DeviceDescription,
        DWORD ChannelSelect;
        DWORD Controller;
        ULONG MaximumLength;
-       BOOLEAN ChannelSetup = FALSE;
-       DMA_MODE DmaMode;       
+       BOOLEAN ChannelSetup = TRUE;
+       DMA_MODE DmaMode = {0}; 
 
        DPRINT("Entered Function\n");
   
@@ -174,6 +174,7 @@ HalGetAdapter (PDEVICE_DESCRIPTION  DeviceDescription,
        
        /* Set the Channel Selection */
        ChannelSelect = DeviceDescription->DmaChannel & 0x03;
+       DmaMode.Channel = ChannelSelect;
        
        /* Get the Controller Setup */
        Controller = (DeviceDescription->DmaChannel & 0x04) ? 2 : 1;
index 9d73c23..553e51c 100644 (file)
@@ -98,4 +98,31 @@ KfReleaseSpinLock (
    KfLowerIrql(NewIrql);
 }
 
+
+/*
+ * @unimplemented
+ */
+VOID
+FASTCALL
+KeAcquireInStackQueuedSpinLock(
+    IN PKSPIN_LOCK SpinLock,
+    IN PKLOCK_QUEUE_HANDLE LockHandle
+    )
+{
+   UNIMPLEMENTED;
+}
+
+
+/*
+ * @unimplemented
+ */
+VOID
+FASTCALL
+KeReleaseInStackQueuedSpinLock(
+    IN PKLOCK_QUEUE_HANDLE LockHandle
+    )
+{
+   UNIMPLEMENTED;
+}
+
 /* EOF */
index 78a2a3d..4f41d35 100644 (file)
@@ -165,7 +165,7 @@ static ULONG Read8254Timer(VOID)
 }
 
 
-static VOID WaitFor8254Wraparound(VOID)
+VOID WaitFor8254Wraparound(VOID)
 {
   ULONG CurCount, PrevCount = ~0;
   LONG Delta;
index 89bba37..b60d4df 100644 (file)
 
 #define APIC_INTEGRATED(version) (version & 0xF0)
 
+typedef enum {
+  amPIC = 0,    /* IMCR and PIC compatibility mode */
+  amVWIRE       /* Virtual Wire compatibility mode */
+} APIC_MODE;
+
+#ifdef CONFIG_SMP
 #define MAX_CPU   32
+#else
+#define MAX_CPU          1
+#endif
 
 /*
  * Local APIC timer IRQ vector is on a different priority level,
 #define ERROR_VECTOR               0xFE
 #define SPURIOUS_VECTOR                    0xFF  /* Must be 0xXF */
 
+/* CPU flags */
+#define CPU_USABLE   0x01  /* 1 if the CPU is usable (ie. can be used) */
+#define CPU_ENABLED  0x02  /* 1 if the CPU is enabled */
+#define CPU_BSP      0x04  /* 1 if the CPU is the bootstrap processor */
+#define CPU_TSC      0x08  /* 1 if the CPU has a time stamp counter */
 
 typedef struct _CPU_INFO
 {
@@ -170,23 +184,26 @@ typedef struct _CPU_INFO
    UCHAR    Padding[16-12];   /* Padding to 16-byte */
 } CPU_INFO, *PCPU_INFO;
 
+extern ULONG CPUCount;                 /* Total number of CPUs */
+extern ULONG BootCPU;                                  /* Bootstrap processor */
+extern ULONG OnlineCPUs;               /* Bitmask of online CPUs */
+extern CPU_INFO CPUMap[MAX_CPU];       /* Map of all CPUs in the system */
 
 /* Prototypes */
 
-
-inline ULONG APICRead(ULONG Offset);
 inline VOID APICWrite(ULONG Offset, ULONG Value);
+inline ULONG APICRead(ULONG Offset);
 VOID APICSendIPI(ULONG Target, ULONG Mode); 
-
-ULONG APICGetMaxLVT(VOID);
 VOID APICSetup(VOID);
 VOID HaliInitBSP(VOID);
 VOID APICSyncArbIDs(VOID);
 inline VOID APICSendEOI(VOID);
+VOID APICCalibrateTimer(ULONG CPU);
+VOID HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack);
 
 static inline ULONG ThisCPU(VOID)
 {
-   return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+    return (APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
 }
 
 
index d826619..18c9195 100644 (file)
@@ -413,17 +413,19 @@ HalQueryDisplayOwnership();
 #define Ki386EnableInterrupts()            __asm__ __volatile__("sti\n\t")
 #define Ki386HaltProcessor()       __asm__ __volatile__("hlt\n\t")
 #define Ki386RdTSC(x)              __asm__ __volatile__("rdtsc\n\t" : "=A" (x.u.LowPart), "=d" (x.u.HighPart));
+#define Ki386Rdmsr(msr,val1,val2)   __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
+#define Ki386Wrmsr(msr,val1,val2)   __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
 
 static inline BYTE Ki386ReadFsByte(ULONG offset)
 {
    BYTE b;
-   __asm__ __volatile__("movb %%fs:(%1),%0":"=q" (b):"0" (offset));
+   __asm__ __volatile__("movb %%fs:(%1),%0":"=r" (b):"r" (offset));
    return b;
 }
 
 static inline VOID Ki386WriteFsByte(ULONG offset, BYTE value)
 {
-    __asm__ __volatile__("movb %0,%%fs:(%1)"::"q" (value), "r" (offset));
+   __asm__ __volatile__("movb %0,%%fs:(%1)"::"r" (value), "r" (offset));
 }
 
 #elif defined(_MSC_VER)
diff --git a/reactos/hal/halx86/include/ioapic.h b/reactos/hal/halx86/include/ioapic.h
new file mode 100644 (file)
index 0000000..540f341
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+ *\r
+ */\r
+\r
+#ifndef __INTERNAL_HAL_IOAPIC_H\r
+#define __INTERNAL_HAL_IOAPIC_H\r
+\r
+/* I/O APIC Register Address Map */\r
+#define IOAPIC_IOREGSEL 0x0000  /* I/O Register Select (index) (R/W) */\r
+#define IOAPIC_IOWIN    0x0010  /* I/O window (data) (R/W) */\r
+\r
+#define IOAPIC_ID       0x0000  /* IO APIC ID (R/W) */\r
+#define IOAPIC_VER      0x0001  /* IO APIC Version (R) */\r
+#define IOAPIC_ARB      0x0002  /* IO APIC Arbitration ID (R) */\r
+#define IOAPIC_REDTBL   0x0010  /* Redirection Table (0-23 64-bit registers) (R/W) */\r
+\r
+#define IOAPIC_ID_MASK        (0xF << 24)\r
+#define GET_IOAPIC_ID(x)           (((x) & IOAPIC_ID_MASK) >> 24)\r
+#define SET_IOAPIC_ID(x)           ((x) << 24)\r
+\r
+#define IOAPIC_VER_MASK       (0xFF)\r
+#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))\r
+#define IOAPIC_MRE_MASK       (0xFF << 16)  /* Maximum Redirection Entry */\r
+#define GET_IOAPIC_MRE(x)     (((x) & IOAPIC_MRE_MASK) >> 16)\r
+\r
+#define IOAPIC_ARB_MASK       (0xF << 24)\r
+#define GET_IOAPIC_ARB(x)          (((x) & IOAPIC_ARB_MASK) >> 24)\r
+\r
+#define IOAPIC_TBL_DELMOD   (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */\r
+#define IOAPIC_TBL_DM       (0x1 << 11) /* Destination Mode */\r
+#define IOAPIC_TBL_DS       (0x1 << 12) /* Delivery Status */\r
+#define IOAPIC_TBL_INTPOL   (0x1 << 13) /* Interrupt Input Pin Polarity */\r
+#define IOAPIC_TBL_RIRR     (0x1 << 14) /* Remote IRR */\r
+#define IOAPIC_TBL_TM       (0x1 << 15) /* Trigger Mode */\r
+#define IOAPIC_TBL_IM       (0x1 << 16) /* Interrupt Mask */\r
+#define IOAPIC_TBL_DF0      (0xF << 56) /* Destination Field (physical mode) */\r
+#define IOAPIC_TBL_DF1      (0xFF<< 56) /* Destination Field (logical mode) */\r
+#define IOAPIC_TBL_VECTOR   (0xFF << 0) /* Vector (10h - FEh) */\r
+\r
+typedef struct _IOAPIC_ROUTE_ENTRY {\r
+   ULONG vector            :  8,\r
+   delivery_mode    :  3,   /* 000: FIXED\r
+                            * 001: lowest priority\r
+                            * 111: ExtINT\r
+                            */\r
+   dest_mode       :  1,   /* 0: physical, 1: logical */\r
+   delivery_status  :  1,\r
+   polarity        :  1,\r
+   irr             :  1,\r
+   trigger         :  1,   /* 0: edge, 1: level */\r
+   mask                    :  1,   /* 0: enabled, 1: disabled */\r
+   __reserved_2            : 15;\r
+\r
+   union {             \r
+      struct { \r
+         ULONG __reserved_1  : 24,\r
+               physical_dest :  4,\r
+               __reserved_2  :  4;\r
+      } physical;\r
+      struct { \r
+         ULONG __reserved_1  : 24,\r
+               logical_dest  :  8;\r
+      } logical;\r
+   } dest;\r
+} __attribute__ ((packed)) IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;\r
+\r
+typedef struct _IOAPIC_INFO\r
+{\r
+   ULONG  ApicId;         /* APIC ID */\r
+   ULONG  ApicVersion;    /* APIC version */\r
+   ULONG  ApicAddress;    /* APIC address */\r
+   ULONG  EntryCount;     /* Number of redirection entries */\r
+} IOAPIC_INFO, *PIOAPIC_INFO;\r
+\r
+#define IOAPIC_DEFAULT_BASE   0xFEC00000    /* Default I/O APIC Base Register Address */\r
+\r
+extern ULONG IRQCount;                                 /* Number of IRQs  */\r
+extern UCHAR BUSMap[MAX_BUS];                          /* Map of all buses in the system */\r
+extern UCHAR PCIBUSMap[MAX_BUS];                       /* Map of all PCI buses in the system */\r
+extern IOAPIC_INFO IOAPICMap[MAX_IOAPIC];              /* Map of all I/O APICs in the system */\r
+extern ULONG IOAPICCount;                              /* Number of I/O APICs in the system */\r
+extern ULONG APICMode;                                 /* APIC mode at startup */\r
+extern MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */\r
+\r
+VOID IOAPICSetupIrqs(VOID);\r
+VOID IOAPICEnable(VOID);\r
+VOID IOAPICSetupIds(VOID);\r
+VOID IOAPICMaskIrq(ULONG Irq);\r
+VOID IOAPICUnmaskIrq(ULONG Irq);\r
+\r
+VOID HaliReconfigurePciInterrupts(VOID);\r
+\r
+/* For debugging */\r
+VOID IOAPICDump(VOID);\r
+\r
+#endif\r
+\r
+\r
+\r
+/* EOF */\r
+\r
index f53b935..b25a415 100644 (file)
@@ -9,76 +9,6 @@
 
 #define IRQL2TPR(irql)     ((irql) >= IPI_LEVEL ? IPI_VECTOR : ((irql) >= PROFILE_LEVEL ? LOCAL_TIMER_VECTOR : ((irql) > DISPATCH_LEVEL ? IRQL2VECTOR(irql) : 0)))
 
-#define IOAPIC_DEFAULT_BASE   0xFEC00000    /* Default I/O APIC Base Register Address */
-
-/* I/O APIC Register Address Map */
-#define IOAPIC_IOREGSEL 0x0000  /* I/O Register Select (index) (R/W) */
-#define IOAPIC_IOWIN    0x0010  /* I/O window (data) (R/W) */
-
-#define IOAPIC_ID       0x0000  /* IO APIC ID (R/W) */
-#define IOAPIC_VER      0x0001  /* IO APIC Version (R) */
-#define IOAPIC_ARB      0x0002  /* IO APIC Arbitration ID (R) */
-#define IOAPIC_REDTBL   0x0010  /* Redirection Table (0-23 64-bit registers) (R/W) */
-
-#define IOAPIC_ID_MASK        (0xF << 24)
-#define GET_IOAPIC_ID(x)           (((x) & IOAPIC_ID_MASK) >> 24)
-#define SET_IOAPIC_ID(x)           ((x) << 24)
-
-#define IOAPIC_VER_MASK       (0xFF)
-#define GET_IOAPIC_VERSION(x) (((x) & IOAPIC_VER_MASK))
-#define IOAPIC_MRE_MASK       (0xFF << 16)  /* Maximum Redirection Entry */
-#define GET_IOAPIC_MRE(x)     (((x) & IOAPIC_MRE_MASK) >> 16)
-
-#define IOAPIC_ARB_MASK       (0xF << 24)
-#define GET_IOAPIC_ARB(x)          (((x) & IOAPIC_ARB_MASK) >> 24)
-
-#define IOAPIC_TBL_DELMOD   (0x7 << 10) /* Delivery Mode (see APIC_DM_*) */
-#define IOAPIC_TBL_DM       (0x1 << 11) /* Destination Mode */
-#define IOAPIC_TBL_DS       (0x1 << 12) /* Delivery Status */
-#define IOAPIC_TBL_INTPOL   (0x1 << 13) /* Interrupt Input Pin Polarity */
-#define IOAPIC_TBL_RIRR     (0x1 << 14) /* Remote IRR */
-#define IOAPIC_TBL_TM       (0x1 << 15) /* Trigger Mode */
-#define IOAPIC_TBL_IM       (0x1 << 16) /* Interrupt Mask */
-#define IOAPIC_TBL_DF0      (0xF << 56) /* Destination Field (physical mode) */
-#define IOAPIC_TBL_DF1      (0xFF<< 56) /* Destination Field (logical mode) */
-#define IOAPIC_TBL_VECTOR   (0xFF << 0) /* Vector (10h - FEh) */
-
-typedef struct _IOAPIC_ROUTE_ENTRY {
-       ULONG   vector          :  8,
-               delivery_mode   :  3,   /* 000: FIXED
-                                                      * 001: lowest priority
-                                                      * 111: ExtINT
-                                                      */
-               dest_mode       :  1,       /* 0: physical, 1: logical */
-               delivery_status :  1,
-               polarity        :  1,
-               irr             :  1,
-               trigger         :  1,       /* 0: edge, 1: level */
-               mask            :  1,         /* 0: enabled, 1: disabled */
-               __reserved_2    : 15;
-
-       union {         struct { ULONG
-                                       __reserved_1    : 24,
-                                       physical_dest   :  4,
-                                       __reserved_2    :  4;
-                       } physical;
-
-                       struct { ULONG
-                                       __reserved_1    : 24,
-                                       logical_dest    :  8;
-                       } logical;
-       } dest;
-} __attribute__ ((packed)) IOAPIC_ROUTE_ENTRY, *PIOAPIC_ROUTE_ENTRY;
-
-typedef struct _IOAPIC_INFO
-{
-   ULONG  ApicId;         /* APIC ID */
-   ULONG  ApicVersion;    /* APIC version */
-   ULONG  ApicAddress;    /* APIC address */
-   ULONG  EntryCount;     /* Number of redirection entries */
-} IOAPIC_INFO, *PIOAPIC_INFO;
-
-
 
 #if 0
 /* This values are defined in halirql.h */
@@ -148,12 +78,6 @@ typedef struct __attribute__((packed)) _MP_CONFIGURATION_PROCESSOR
 } __attribute__((packed)) MP_CONFIGURATION_PROCESSOR, 
   *PMP_CONFIGURATION_PROCESSOR;
 
-#define CPU_FLAG_ENABLED         1  /* Processor is available */
-#define CPU_FLAG_BSP             2  /* Processor is the bootstrap processor */
-
-#define CPU_STEPPING_MASK  0x0F
-#define CPU_MODEL_MASK    0xF0
-#define CPU_FAMILY_MASK           0xF00
 
 
 typedef struct __attribute__((packed)) _MP_CONFIGURATION_BUS
@@ -239,54 +163,20 @@ typedef struct __attribute__((packed)) _MP_CONFIGURATION_INTLOCAL
 } MP_CONFIGURATION_INTLOCAL, *PMP_CONFIGURATION_INTLOCAL;
 
 #define MP_APIC_ALL    0xFF
-
-
-static inline VOID ReadPentiumClock(PULARGE_INTEGER Count)
-{
-   register ULONG nLow;
-   register ULONG nHigh;
   
-#if defined(__GNUC__)
-   __asm__ __volatile__ ("rdtsc" : "=a" (nLow), "=d" (nHigh));
-#elif defined(_MSC_VER)
-   __asm rdtsc
-   __asm mov nLow, eax
-   __asm mov nHigh, edx
-#else
-#error Unknown compiler for inline assembler
-#endif
-
-   Count->u.LowPart = nLow;
-   Count->u.HighPart = nHigh;
-}
-
-
-
-
-/* CPU flags */
-#define CPU_USABLE   0x01  /* 1 if the CPU is usable (ie. can be used) */
-#define CPU_ENABLED  0x02  /* 1 if the CPU is enabled */
-#define CPU_BSP      0x04  /* 1 if the CPU is the bootstrap processor */
-
-
-typedef enum {
-  amPIC = 0,    /* IMCR and PIC compatibility mode */
-  amVWIRE       /* Virtual Wire compatibility mode */
-} APIC_MODE;
+#define CPU_FLAG_ENABLED         1  /* Processor is available */
+#define CPU_FLAG_BSP             2  /* Processor is the bootstrap processor */
 
+#define CPU_STEPPING_MASK  0x0F
+#define CPU_MODEL_MASK    0xF0
+#define CPU_FAMILY_MASK           0xF00
 
 #define PIC_IRQS  16
 
 /* Prototypes */
 
 VOID HalpInitMPS(VOID);
-ULONG IOAPICRead(ULONG Apic, ULONG Offset);
-VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
-VOID IOAPICMaskIrq(ULONG Irq);
-VOID IOAPICUnmaskIrq(ULONG Irq);
 
-/* For debugging */
-VOID IOAPICDump(VOID);
 
 #endif /* __INCLUDE_HAL_MPS */
 
index 837237d..54c331e 100644 (file)
@@ -61,7 +61,9 @@ GENERIC_OBJECTS = \
 MP_OBJECTS = \
        apic.o \
        halinit_mp.o \
+       ioapic.o \
        ipi_mp.o \
+       mpconfig.o \
        mpsirql.o \
        mpsboot.o \
        mps.o \
index f87fe83..f6efcb4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS kernel
- *  Copyright (C) 2004 ReactOS Team
+ *  Copyright (C) 2004, 2005 ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -25,6 +25,8 @@
  * PROGRAMMER:  
  */
 
+/* INCLUDE ***********************************************************************/
+
 #include <ddk/ntddk.h>
 #include <internal/i386/ps.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
-BOOLEAN VerifyLocalAPIC(VOID);
-VOID APICCalibrateTimer(ULONG CPU);
+/* GLOBALS ***********************************************************************/
 
-extern VOID MpsTimerInterrupt(VOID);
-extern VOID MpsErrorInterrupt(VOID);
-extern VOID MpsSpuriousInterrupt(VOID);
-extern VOID MpsIpiInterrupt(VOID);
+ULONG CPUCount;                                        /* Total number of CPUs */
+ULONG BootCPU;                                 /* Bootstrap processor */
+ULONG OnlineCPUs;                              /* Bitmask of online CPUs */
+CPU_INFO CPUMap[MAX_CPU];                      /* Map of all CPUs in the system */
+
+#ifdef CONFIG_SMP
+PULONG BIOSBase;                               /* Virtual address of BIOS data segment */
+PULONG CommonBase;                             /* Virtual address of common area */
+#endif
+
+PULONG APICBase = (PULONG)APIC_DEFAULT_BASE;   /* Virtual address of local APIC */
+
+ULONG APICMode;                                        /* APIC mode at startup */
+
+/* For debugging */
+ULONG lastregr[MAX_CPU];
+ULONG lastvalr[MAX_CPU];
+ULONG lastregw[MAX_CPU];
+ULONG lastvalw[MAX_CPU];
 
-extern ULONG APICMode;         /* APIC mode at startup */
-extern PULONG BIOSBase;         /* Virtual address of BIOS data segment */
-extern PULONG CommonBase;       /* Virtual address of common area */
-extern ULONG BootCPU;           /* Bootstrap processor */
-extern ULONG OnlineCPUs;        /* Bitmask of online CPUs */
+#ifdef CONFIG_SMP
+typedef struct __attribute__((packed)) _COMMON_AREA_INFO
+{
+   ULONG Stack;                    /* Location of AP stack */
+   ULONG PageDirectory;            /* Page directory for an AP */
+   ULONG NtProcessStartup;  /* Kernel entry point for an AP */
+   ULONG PaeModeEnabled;    /* PAE mode is enabled */
+   ULONG Debug[16];        /* For debugging */
+} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
+#endif
+
+CHAR *APstart, *APend;
+
+#define BIOS_AREA      0x0
+#define COMMON_AREA    0x2000
 
-extern CHAR *APstart, *APend;
-extern VOID (*APflush)(VOID);
+#define HZ             (100)
+#define APIC_DIVISOR   (16)
 
 #define CMOS_READ(address) ({ \
    WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
@@ -63,19 +89,16 @@ extern VOID (*APflush)(VOID);
    WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
 })
 
-#define BIOS_AREA    0x0
-#define COMMON_AREA  0x2000
+extern PVOID IMPORTED MmSystemRangeStart;
 
+/* FUNCTIONS *********************************************************************/
 
-extern CPU_INFO CPUMap[MAX_CPU];               /* Map of all CPUs in the system */
-
-PULONG APICBase = (PULONG)APIC_DEFAULT_BASE;   /* Virtual address of local APIC */
-
-/* For debugging */
-ULONG lastregr[MAX_CPU];
-ULONG lastvalr[MAX_CPU];
-ULONG lastregw[MAX_CPU];
-ULONG lastvalw[MAX_CPU];
+extern ULONG Read8254Timer(VOID);
+extern VOID WaitFor8254Wraparound(VOID);
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
 
 ULONG APICGetMaxLVT(VOID)
 {
@@ -152,7 +175,7 @@ VOID APICClear(VOID)
 }
 
 /* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
-VOID EnableSMPMode(VOID)
+VOID EnableApicMode(VOID)
 {
    /*
     * Do not trust the local APIC being empty at bootup.
@@ -203,63 +226,6 @@ VOID APICDisable(VOID)
   APICWrite(APIC_SIVR, tmp);
 }
 
-VOID HaliInitBSP(VOID)
-{
-   PUSHORT ps;
-   static BOOLEAN BSPInitialized = FALSE;
-
-   /* Only initialize the BSP once */
-   if (BSPInitialized)
-   {
-      KEBUGCHECK(0);
-      return;
-   }
-
-   BSPInitialized = TRUE;
-
-   DPRINT("APIC is mapped at 0x%X\n", APICBase);
-
-   if (VerifyLocalAPIC()) 
-   {
-      DPRINT("APIC found\n");
-   } 
-   else 
-   {
-      DPRINT("No APIC found\n");
-      KEBUGCHECK(0);
-   }
-
-   if (APICMode == amPIC) 
-   {
-      EnableSMPMode();
-   }
-
-   APICSetup();
-
-   /* BIOS data segment */
-   BIOSBase = (PULONG)BIOS_AREA;
-   
-   /* Area for communicating with the APs */
-   CommonBase = (PULONG)COMMON_AREA;
-   /* Copy bootstrap code to common area */
-   memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
-         &APstart,
-         (ULONG)&APend - (ULONG)&APstart + 1);
-
-   /* Set shutdown code */
-   CMOS_WRITE(0xF, 0xA);
-
-   /* Set warm reset vector */
-   ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
-   *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
-   ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
-   *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
-
-   /* Calibrate APIC timer */
-   APICCalibrateTimer(BootCPU);
-}
 
 inline ULONG _APICRead(ULONG Offset)
 {
@@ -455,7 +421,6 @@ VOID APICDump(VOID)
 BOOLEAN VerifyLocalAPIC(VOID)
 {
    UINT reg0, reg1;
-   CHECKPOINT1;
    /* The version register is read-only in a real APIC */
    reg0 = APICRead(APIC_VER);
    DPRINT1("Getting VERSION: %x\n", reg0);
@@ -502,9 +467,23 @@ BOOLEAN VerifyLocalAPIC(VOID)
       return FALSE;
    }
 
+   ULONG l, h;
+   Ki386Rdmsr(0x1b /*MSR_IA32_APICBASE*/, l, h);
+
+   if (!(l & /*MSR_IA32_APICBASE_ENABLE*/(1<<11))) 
+   {
+      DPRINT1("Local APIC disabled by BIOS -- reenabling.\n");
+      l &= ~/*MSR_IA32_APICBASE_BASE*/(1<<11);
+      l |= /*MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE*/(1<<11)|0xfee00000;
+      Ki386Wrmsr(0x1b/*MSR_IA32_APICBASE*/, l, h);
+   }
+
+    
+
    return TRUE;
 }
 
+#ifdef CONFIG_SMP
 VOID APICSendIPI(ULONG Target, ULONG Mode)
 {
    ULONG tmp, i, flags;
@@ -568,6 +547,7 @@ VOID APICSendIPI(ULONG Target, ULONG Mode)
    }
    Ki386RestoreFlags(flags);
 }
+#endif
 
 VOID APICSetup(VOID)
 {
@@ -651,7 +631,6 @@ VOID APICSetup(VOID)
   }
   APICWrite(APIC_LINT0, tmp);
 
-
   /*
    * Only the BSP should see the LINT1 NMI signal, obviously.
    */
@@ -697,7 +676,7 @@ VOID APICSetup(VOID)
      DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
   }
 }
-
+#ifdef CONFIG_SMP
 VOID APICSyncArbIDs(VOID)
 {
    ULONG i, tmp;
@@ -720,6 +699,7 @@ VOID APICSyncArbIDs(VOID)
    DPRINT("Synchronizing Arb IDs.\n");
    APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
 }
+#endif
 
 VOID MpsErrorHandler(VOID)
 {
@@ -769,12 +749,13 @@ VOID MpsSpuriousHandler(VOID)
 #endif
 }
 
+#ifdef CONFIG_SMP
 VOID MpsIpiHandler(VOID)
 {
    KIRQL oldIrql;
 
    HalBeginSystemInterrupt(IPI_VECTOR, 
-                           VECTOR2IRQL(IPI_VECTOR)
+                           IPI_LEVEL
                           &oldIrql);
    Ki386EnableInterrupts();
 #if 0
@@ -791,6 +772,7 @@ VOID MpsIpiHandler(VOID)
    Ki386DisableInterrupts();
    HalEndSystemInterrupt(oldIrql, 0);
 }
+#endif
 
 VOID
 MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
@@ -823,7 +805,7 @@ MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
    static ULONG Count[MAX_CPU] = {0,};
 #endif
    HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR, 
-                           VECTOR2IRQL(LOCAL_TIMER_VECTOR)
+                           PROFILE_LEVEL
                           &oldIrql);
    Ki386EnableInterrupts();
 
@@ -850,4 +832,318 @@ MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
    HalEndSystemInterrupt (oldIrql, 0);
 }
 
+VOID APICSetupLVTT(ULONG ClockTicks)
+{
+   ULONG tmp;
+
+   tmp = GET_APIC_VERSION(APICRead(APIC_VER));
+   if (!APIC_INTEGRATED(tmp))
+   {
+      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+   }
+   else
+   {
+      /* Periodic timer */
+      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+   }
+   APICWrite(APIC_LVTT, tmp);
+
+   tmp = APICRead(APIC_TDCR);
+   tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
+   tmp |= APIC_TDCR_16;
+   APICWrite(APIC_TDCR, tmp);
+   APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
+}
+
+VOID 
+APICCalibrateTimer(ULONG CPU)
+{
+   ULARGE_INTEGER t1, t2;
+   LONG tt1, tt2;
+   BOOLEAN TSCPresent;
+
+   DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
+
+   APICSetupLVTT(1000000000);
+
+   TSCPresent = KeGetCurrentKPCR()->PrcbData.FeatureBits & X86_FEATURE_TSC ? TRUE : FALSE;
+
+   /*
+    * The timer chip counts down to zero. Let's wait
+    * for a wraparound to start exact measurement:
+    * (the current tick might have been already half done)
+    */
+   WaitFor8254Wraparound();
+
+   /*
+    * We wrapped around just now. Let's start
+    */
+   if (TSCPresent)
+   {
+      Ki386RdTSC(t1);
+   }
+   tt1 = APICRead(APIC_CCRT);
+
+   WaitFor8254Wraparound();
+
+
+   tt2 = APICRead(APIC_CCRT);
+   if (TSCPresent)
+   {
+      Ki386RdTSC(t2);
+      CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+      DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
+            CPUMap[CPU].CoreSpeed/1000000,
+            CPUMap[CPU].CoreSpeed%1000000);
+      KeGetCurrentKPCR()->PrcbData.MHz = CPUMap[CPU].CoreSpeed/1000000;
+   }
+
+   CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
+
+   /* Setup timer for normal operation */
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100);    // 100ns
+   APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000);  // 10ms
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
+
+   DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
+         CPUMap[CPU].BusSpeed/1000000,
+         CPUMap[CPU].BusSpeed%1000000);
+}
+
+VOID 
+SetInterruptGate(ULONG index, ULONG address)
+{
+  IDT_DESCRIPTOR *idt;
+
+  idt = (IDT_DESCRIPTOR*)((ULONG)KeGetCurrentKPCR()->IDT + index * sizeof(IDT_DESCRIPTOR));
+  idt->a = (((ULONG)address)&0xffff) + (KERNEL_CS << 16);
+  idt->b = 0x8e00 + (((ULONG)address)&0xffff0000);
+}
+
+VOID HaliInitBSP(VOID)
+{
+#ifdef CONFIG_SMP
+   PUSHORT ps;
+#endif
+
+   static BOOLEAN BSPInitialized = FALSE;
+
+   /* Only initialize the BSP once */
+   if (BSPInitialized)
+   {
+      KEBUGCHECK(0);
+      return;
+   }
+
+   BSPInitialized = TRUE;
+
+   /* Setup interrupt handlers */
+   SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG)MpsTimerInterrupt);
+   SetInterruptGate(ERROR_VECTOR, (ULONG)MpsErrorInterrupt);
+   SetInterruptGate(SPURIOUS_VECTOR, (ULONG)MpsSpuriousInterrupt);
+#ifdef CONFIG_SMP
+   SetInterruptGate(IPI_VECTOR, (ULONG)MpsIpiInterrupt);
+#endif
+   DPRINT("APIC is mapped at 0x%X\n", APICBase);
+
+   if (VerifyLocalAPIC()) 
+   {
+      DPRINT("APIC found\n");
+   } 
+   else 
+   {
+      DPRINT("No APIC found\n");
+      KEBUGCHECK(0);
+   }
+
+   if (APICMode == amPIC) 
+   {
+      EnableApicMode();
+   }
+
+   APICSetup();
+
+#ifdef CONFIG_SMP
+   /* BIOS data segment */
+   BIOSBase = (PULONG)BIOS_AREA;
+   
+   /* Area for communicating with the APs */
+   CommonBase = (PULONG)COMMON_AREA;
+   /* Copy bootstrap code to common area */
+   memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+         &APstart,
+         (ULONG)&APend - (ULONG)&APstart + 1);
+
+   /* Set shutdown code */
+   CMOS_WRITE(0xF, 0xA);
+
+   /* Set warm reset vector */
+   ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+   *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
+   ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+   *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
+#endif
+
+   /* Calibrate APIC timer */
+   APICCalibrateTimer(BootCPU);
+}
+
+#ifdef CONFIG_SMP
+VOID
+HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
+{
+   ULONG tmp, maxlvt;
+   PCOMMON_AREA_INFO Common;
+   ULONG StartupCount;
+   ULONG i, j;
+   ULONG DeliveryStatus = 0;
+   ULONG AcceptStatus = 0;
+
+   if (Cpu >= MAX_CPU ||
+       Cpu >= CPUCount ||
+       OnlineCPUs & (1 << Cpu))
+   {
+     KEBUGCHECK(0);
+   }
+   DPRINT1("Attempting to boot CPU %d\n", Cpu);
+
+   /* Send INIT IPI */
+
+   APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_ASSERT);
+   KeStallExecutionProcessor(200);
+
+   /* Deassert INIT */
+
+   APICSendIPI(Cpu, APIC_DM_INIT|APIC_ICR0_LEVEL_DEASSERT);
+
+   if (APIC_INTEGRATED(CPUMap[Cpu].APICVersion)) 
+   {
+      /* Clear APIC errors */
+      APICWrite(APIC_ESR, 0);
+      tmp = (APICRead(APIC_ESR) & APIC_ESR_MASK);
+   }
+
+   Common = (PCOMMON_AREA_INFO)CommonBase;
+
+   /* Write the location of the AP stack */
+   Common->Stack = (ULONG)Stack;
+   /* Write the page directory page */
+   Ke386GetPageTableDirectory(Common->PageDirectory);
+   /* Write the kernel entry point */
+   Common->NtProcessStartup = (ULONG_PTR)RtlImageNtHeader(MmSystemRangeStart)->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)MmSystemRangeStart;
+   /* Write the state of the mae mode */
+   Common->PaeModeEnabled = Ke386GetCr4() & X86_CR4_PAE ? 1 : 0;
+
+   DPRINT1("%x %x %x %x\n", Common->Stack, Common->PageDirectory, Common->NtProcessStartup, Common->PaeModeEnabled);
+
+   DPRINT("Cpu %d got stack at 0x%X\n", Cpu, Common->Stack);
+#if 0
+   for (j = 0; j < 16; j++) 
+   {
+      Common->Debug[j] = 0;
+   }
+#endif
+
+   maxlvt = APICGetMaxLVT();
+
+   /* Is this a local APIC or an 82489DX? */
+   StartupCount = (APIC_INTEGRATED(CPUMap[Cpu].APICVersion)) ? 2 : 0;
+
+   for (i = 1; i <= StartupCount; i++)
+   {
+      /* It's a local APIC, so send STARTUP IPI */
+      DPRINT("Sending startup signal %d\n", i);
+      /* Clear errors */
+      APICWrite(APIC_ESR, 0);
+      APICRead(APIC_ESR);
+
+      APICSendIPI(Cpu, APIC_DM_STARTUP | ((COMMON_AREA + PAGE_SIZE) >> 12)|APIC_ICR0_LEVEL_DEASSERT);
+
+      /* Wait up to 10ms for IPI to be delivered */
+      j = 0;
+      do 
+      {
+         KeStallExecutionProcessor(10);
+
+         /* Check Delivery Status */
+         DeliveryStatus = APICRead(APIC_ICR0) & APIC_ICR0_DS;
+
+         j++;
+      } while ((DeliveryStatus) && (j < 1000));
+
+      KeStallExecutionProcessor(200);
+
+      /*
+       * Due to the Pentium erratum 3AP.
+       */
+      if (maxlvt > 3) 
+      {
+        APICRead(APIC_SIVR);
+        APICWrite(APIC_ESR, 0);
+      }
+
+      AcceptStatus = APICRead(APIC_ESR) & APIC_ESR_MASK;
+
+      if (DeliveryStatus || AcceptStatus) 
+      {
+         break;
+      }
+   }
+
+   if (DeliveryStatus) 
+   {
+      DPRINT("STARTUP IPI for CPU %d was never delivered.\n", Cpu);
+   }
+
+   if (AcceptStatus) 
+   {
+      DPRINT("STARTUP IPI for CPU %d was never accepted.\n", Cpu);
+   }
+
+   if (!(DeliveryStatus || AcceptStatus)) 
+   {
+
+      /* Wait no more than 5 seconds for processor to boot */
+      DPRINT("Waiting for 5 seconds for CPU %d to boot\n", Cpu);
+
+      /* Wait no more than 5 seconds */
+      for (j = 0; j < 50000; j++) 
+      {
+         if (CPUMap[Cpu].Flags & CPU_ENABLED)
+        {
+            break;
+        }
+         KeStallExecutionProcessor(100);
+      }
+   }
+
+   if (CPUMap[Cpu].Flags & CPU_ENABLED) 
+   {
+      DbgPrint("CPU %d is now running\n", Cpu);
+   } 
+   else 
+   {
+      DbgPrint("Initialization of CPU %d failed\n", Cpu);
+   }
+
+#if 0
+   DPRINT("Debug bytes are:\n");
+
+   for (j = 0; j < 4; j++) 
+   {
+      DPRINT("0x%08X 0x%08X 0x%08X 0x%08X.\n",
+             Common->Debug[j*4+0],
+             Common->Debug[j*4+1],
+             Common->Debug[j*4+2],
+             Common->Debug[j*4+3]);
+   }
+
+#endif
+}
+
+#endif
+
 /* EOF */
index 92c0b05..0501f5d 100644 (file)
 
 /* FUNCTIONS ***************************************************************/
 
+extern BOOLEAN HaliFindSmpConfig(VOID);
+
+/***************************************************************************/
 VOID
 HalpInitPhase0(VOID)
+
 {
-  HalpInitMPS();
+   static BOOLEAN MPSInitialized = FALSE;
+
+
+   /* Only initialize MP system once. Once called the first time,
+      each subsequent call is part of the initialization sequence
+                       for an application processor. */
+
+   DPRINT("HalpInitPhase0()\n");
+
+
+   if (MPSInitialized) 
+   {
+      KEBUGCHECK(0);
+   }
+
+   MPSInitialized = TRUE;
+
+   if (!HaliFindSmpConfig())
+   {
+      KEBUGCHECK(0);
+   }
 }
 
 /* EOF */
index 1f83ac9..6b2d2e1 100644 (file)
@@ -10,7 +10,9 @@
        <library>ntoskrnl</library>\r
        <file>apic.c</file>\r
        <file>halinit_mp.c</file>\r
+       <file>ioapic.c</file>\r
        <file>ipi_mp.c</file>\r
+       <file>mpconfig.c</file>\r
        <file>mps.S</file>\r
        <file>mpsboot.asm</file>\r
        <file>mpsirql.c</file>\r
diff --git a/reactos/hal/halx86/mp/ioapic.c b/reactos/hal/halx86/mp/ioapic.c
new file mode 100644 (file)
index 0000000..9b0a624
--- /dev/null
@@ -0,0 +1,712 @@
+/* $Id$\r
+ *\r
+ * COPYRIGHT:             See COPYING in the top level directory\r
+ * PROJECT:               ReactOS kernel\r
+ * FILE:                  hal/halx86/generic/ioapic.c\r
+ * PURPOSE:               \r
+ * PROGRAMMER:            \r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <ddk/ntddk.h>\r
+#include <hal.h>\r
+\r
+#include <mps.h>\r
+#include <halirq.h>\r
+#include <apic.h>\r
+#include <ioapic.h>\r
+\r
+#include <internal/ntoskrnl.h>\r
+#include <internal/i386/segment.h>\r
+#include <internal/ke.h>\r
+#include <internal/ps.h>\r
+\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS *****************************************************************/\r
+\r
+MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */\r
+ULONG IRQCount = 0;                             /* Number of IRQs  */\r
+ULONG IrqApicMap[MAX_IRQ_SOURCE];\r
+\r
+UCHAR BUSMap[MAX_BUS];                         /* Map of all buses in the system */\r
+UCHAR PCIBUSMap[MAX_BUS];                      /* Map of all PCI buses in the system */\r
+\r
+IOAPIC_INFO IOAPICMap[MAX_IOAPIC];             /* Map of all I/O APICs in the system */\r
+ULONG IOAPICCount;                             /* Number of I/O APICs in the system */\r
+\r
+ULONG IRQVectorMap[MAX_IRQ_SOURCE];             /* IRQ to vector map */\r
+\r
+/* EISA interrupts are always polarity zero and can be edge or level\r
+ * trigger depending on the ELCR value.  If an interrupt is listed as\r
+ * EISA conforming in the MP table, that means its trigger type must\r
+ * be read in from the ELCR */\r
+\r
+#define default_EISA_trigger(idx)      (EISA_ELCR(IRQMap[idx].SrcBusIrq))\r
+#define default_EISA_polarity(idx)     (0)\r
+\r
+/* ISA interrupts are always polarity zero edge triggered,\r
+ * when listed as conforming in the MP table. */\r
+\r
+#define default_ISA_trigger(idx)       (0)\r
+#define default_ISA_polarity(idx)      (0)\r
+\r
+/* PCI interrupts are always polarity one level triggered,\r
+ * when listed as conforming in the MP table. */\r
+\r
+#define default_PCI_trigger(idx)       (1)\r
+#define default_PCI_polarity(idx)      (1)\r
+\r
+/* MCA interrupts are always polarity zero level triggered,\r
+ * when listed as conforming in the MP table. */\r
+\r
+#define default_MCA_trigger(idx)       (1)\r
+#define default_MCA_polarity(idx)      (0)\r
+\r
+/***************************************************************************/\r
+\r
+extern VOID Disable8259AIrq(ULONG irq);\r
+ULONG IOAPICRead(ULONG Apic, ULONG Offset);\r
+VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);\r
+\r
+/* FUNCTIONS ***************************************************************/\r
+\r
+/*\r
+ * EISA Edge/Level control register, ELCR\r
+ */\r
+static ULONG EISA_ELCR(ULONG irq)\r
+{\r
+   if (irq < 16) \r
+   {\r
+      PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));\r
+      return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;\r
+   }\r
+   DPRINT("Broken MPtable reports ISA irq %d\n", irq);\r
+   return 0;\r
+}\r
+\r
+static ULONG \r
+IRQPolarity(ULONG idx)\r
+{\r
+   ULONG bus = IRQMap[idx].SrcBusId;\r
+   ULONG polarity;\r
+\r
+   /*\r
+    * Determine IRQ line polarity (high active or low active):\r
+    */\r
+   switch (IRQMap[idx].IrqFlag & 3)\r
+   {\r
+      case 0: /* conforms, ie. bus-type dependent polarity */\r
+         {\r
+            switch (BUSMap[bus])\r
+           {\r
+              case MP_BUS_ISA: /* ISA pin */\r
+                 polarity = default_ISA_polarity(idx);\r
+                 break;\r
+                 \r
+              case MP_BUS_EISA: /* EISA pin */\r
+                 polarity = default_EISA_polarity(idx);\r
+                 break;\r
+               \r
+              case MP_BUS_PCI: /* PCI pin */\r
+                 polarity = default_PCI_polarity(idx);\r
+                 break;\r
+\r
+              case MP_BUS_MCA: /* MCA pin */\r
+                  polarity = default_MCA_polarity(idx);\r
+                 break;\r
+               \r
+              default:\r
+                 DPRINT("Broken BIOS!!\n");\r
+                 polarity = 1;\r
+           }\r
+        }\r
+        break;\r
+\r
+      case 1: /* high active */\r
+        polarity = 0;\r
+        break;\r
+\r
+      case 2: /* reserved */\r
+        DPRINT("Broken BIOS!!\n");\r
+        polarity = 1;\r
+        break;\r
+\r
+      case 3: /* low active */\r
+         polarity = 1;\r
+        break;\r
+\r
+      default: /* invalid */\r
+        DPRINT("Broken BIOS!!\n");\r
+        polarity = 1;\r
+   }\r
+   return polarity;\r
+}\r
+\r
+static ULONG \r
+IRQTrigger(ULONG idx)\r
+{\r
+   ULONG bus = IRQMap[idx].SrcBusId;\r
+   ULONG trigger;\r
+\r
+   /*\r
+    * Determine IRQ trigger mode (edge or level sensitive):\r
+    */\r
+   switch ((IRQMap[idx].IrqFlag >> 2) & 3)\r
+   {\r
+      case 0: /* conforms, ie. bus-type dependent */\r
+        {\r
+            switch (BUSMap[bus])\r
+           {\r
+              case MP_BUS_ISA: /* ISA pin */\r
+                 trigger = default_ISA_trigger(idx);\r
+                 break;\r
+\r
+              case MP_BUS_EISA: /* EISA pin */\r
+                 trigger = default_EISA_trigger(idx);\r
+                 break;\r
+               \r
+              case MP_BUS_PCI: /* PCI pin */\r
+                 trigger = default_PCI_trigger(idx);\r
+                 break;\r
+\r
+               case MP_BUS_MCA: /* MCA pin */\r
+                 trigger = default_MCA_trigger(idx);\r
+                 break;\r
+               \r
+               default:\r
+                  DPRINT("Broken BIOS!!\n");\r
+                 trigger = 1;\r
+           }\r
+        }\r
+        break;\r
+\r
+      case 1: /* edge */\r
+        trigger = 0;\r
+        break;\r
+\r
+      case 2: /* reserved */\r
+        DPRINT("Broken BIOS!!\n");\r
+        trigger = 1;\r
+        break;\r
+\r
+      case 3: /* level */\r
+        trigger = 1;\r
+        break;\r
+       \r
+      default: /* invalid */\r
+        DPRINT("Broken BIOS!!\n");\r
+        trigger = 0;                                   \r
+   }\r
+   return trigger;\r
+}\r
+\r
+static ULONG \r
+Pin2Irq(ULONG idx,\r
+       ULONG apic,\r
+       ULONG pin)\r
+{\r
+   ULONG irq, i;\r
+   ULONG bus = IRQMap[idx].SrcBusId;\r
+\r
+   /*\r
+    * Debugging check, we are in big trouble if this message pops up!\r
+    */\r
+   if (IRQMap[idx].DstApicInt != pin) \r
+   {\r
+      DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");\r
+   }\r
+\r
+   switch (BUSMap[bus])\r
+   {\r
+      case MP_BUS_ISA: /* ISA pin */\r
+      case MP_BUS_EISA:\r
+      case MP_BUS_MCA:\r
+       irq = IRQMap[idx].SrcBusIrq;\r
+       break;\r
+\r
+      case MP_BUS_PCI: /* PCI pin */\r
+        /*\r
+         * PCI IRQs are mapped in order\r
+         */\r
+        i = irq = 0;\r
+        while (i < apic)\r
+        {\r
+           irq += IOAPICMap[i++].EntryCount;\r
+        }\r
+        irq += pin;\r
+        break;\r
+       \r
+      default:\r
+        DPRINT("Unknown bus type %d.\n",bus);\r
+        irq = 0;\r
+   }\r
+   return irq;\r
+}\r
+\r
+static ULONG \r
+AssignIrqVector(ULONG irq)\r
+{\r
+#if 0\r
+   static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;\r
+#endif\r
+   ULONG vector;\r
+   /* There may already have been assigned a vector for this IRQ */\r
+   vector = IRQVectorMap[irq];\r
+   if (vector > 0)\r
+   {\r
+      return vector;\r
+   }\r
+#if 0\r
+   if (current_vector > FIRST_SYSTEM_VECTOR) \r
+   {\r
+      vector_offset++;\r
+      current_vector = FIRST_DEVICE_VECTOR + vector_offset;\r
+   } \r
+   else if (current_vector == FIRST_SYSTEM_VECTOR) \r
+   {\r
+      DPRINT1("Ran out of interrupt sources!");\r
+      KEBUGCHECK(0);\r
+   }\r
+\r
+   vector = current_vector;\r
+   IRQVectorMap[irq] = vector;\r
+   current_vector += 8;\r
+   return vector;\r
+#else\r
+   vector = IRQ2VECTOR(irq);\r
+   IRQVectorMap[irq] = vector;\r
+   return vector;\r
+#endif\r
+}\r
+\r
+/*\r
+ * Find the IRQ entry number of a certain pin.\r
+ */\r
+static ULONG \r
+IOAPICGetIrqEntry(ULONG apic,\r
+                 ULONG pin,\r
+                 ULONG type)\r
+{\r
+   ULONG i;\r
+\r
+   for (i = 0; i < IRQCount; i++)\r
+   {\r
+      if (IRQMap[i].IrqType == type &&\r
+         (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&\r
+         IRQMap[i].DstApicInt == pin)\r
+      {\r
+         return i;\r
+      }\r
+   }\r
+   return -1;\r
+}\r
+\r
+\r
+VOID \r
+IOAPICSetupIrqs(VOID)\r
+{\r
+   IOAPIC_ROUTE_ENTRY entry;\r
+   ULONG apic, pin, idx, irq, first_notcon = 1, vector, trigger;\r
+\r
+   DPRINT("Init IO_APIC IRQs\n");\r
+\r
+   /* Setup IRQ to vector translation map */\r
+   memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));\r
+\r
+   for (apic = 0; apic < IOAPICCount; apic++) \r
+   {\r
+      for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++) \r
+      {\r
+         /*\r
+         * add it to the IO-APIC irq-routing table\r
+         */\r
+        memset(&entry,0,sizeof(entry));\r
+\r
+        entry.delivery_mode = (APIC_DM_LOWEST >> 8);\r
+        entry.dest_mode = 1;  /* logical delivery */\r
+        entry.mask = 1;       /* disable IRQ */\r
+         entry.dest.logical.logical_dest = 0;\r
+\r
+        idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);\r
+        if (idx == -1) \r
+        {\r
+           if (first_notcon) \r
+           {\r
+              DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);\r
+              first_notcon = 0;\r
+           } \r
+           else \r
+           {\r
+              DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);\r
+            }\r
+           continue;\r
+        }\r
+\r
+         trigger = IRQTrigger(idx);\r
+        entry.polarity = IRQPolarity(idx);\r
+\r
+        if (trigger) \r
+        {\r
+           entry.trigger = 1;\r
+        }\r
+\r
+        irq = Pin2Irq(idx, apic, pin);\r
+\r
+        vector = AssignIrqVector(irq);\r
+        entry.vector = vector;\r
+\r
+        DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);\r
+\r
+         if (irq == 0)\r
+         {\r
+            /* Mask timer IRQ */\r
+            entry.mask = 1;\r
+         }\r
+\r
+         if ((apic == 0) && (irq < 16))\r
+        {\r
+           Disable8259AIrq(irq);\r
+        }\r
+         IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));\r
+        IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));\r
+\r
+        IrqApicMap[irq] = apic;\r
+\r
+        DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);\r
+      }\r
+   }\r
+}\r
+\r
+static VOID \r
+IOAPICClearPin(ULONG Apic, ULONG Pin)\r
+{\r
+   IOAPIC_ROUTE_ENTRY Entry;\r
+\r
+   DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);\r
+   /*\r
+    * Disable it in the IO-APIC irq-routing table\r
+    */\r
+   memset(&Entry, 0, sizeof(Entry));\r
+   Entry.mask = 1;\r
+\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));\r
+}\r
+\r
+static VOID \r
+IOAPICClear(ULONG Apic)\r
+{\r
+   ULONG Pin;\r
+\r
+   for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)\r
+   {\r
+     IOAPICClearPin(Apic, Pin);\r
+   }\r
+}\r
+\r
+static VOID \r
+IOAPICClearAll(VOID)\r
+{\r
+   ULONG Apic;\r
+\r
+   for (Apic = 0; Apic < IOAPICCount; Apic++)\r
+   {\r
+      IOAPICClear(Apic);\r
+   }\r
+}\r
+\r
+VOID \r
+IOAPICEnable(VOID)\r
+{\r
+   ULONG i, tmp;\r
+\r
+   /* Setup IRQ to vector translation map */\r
+   memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));\r
+\r
+   /*\r
+    * The number of IO-APIC IRQ registers (== #pins):\r
+    */\r
+   for (i = 0; i < IOAPICCount; i++) \r
+   {\r
+      tmp = IOAPICRead(i, IOAPIC_VER);\r
+      IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;\r
+   }\r
+\r
+   /*\r
+    * Do not trust the IO-APIC being empty at bootup\r
+    */\r
+   IOAPICClearAll();\r
+}\r
+\r
+VOID \r
+IOAPICSetupIds(VOID)\r
+{\r
+  ULONG tmp, apic, i;\r
+  UCHAR old_id;\r
+  \r
+  /*\r
+   * Set the IOAPIC ID to the value stored in the MPC table.\r
+   */\r
+  for (apic = 0; apic < IOAPICCount; apic++) \r
+  {\r
+    \r
+    /* Read the register 0 value */\r
+    tmp = IOAPICRead(apic, IOAPIC_ID);\r
+    \r
+    old_id = IOAPICMap[apic].ApicId;\r
+    \r
+    if (IOAPICMap[apic].ApicId >= 0xf) \r
+    {\r
+      DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",\r
+             apic, IOAPICMap[apic].ApicId);\r
+      DPRINT1("... fixing up to %d. (tell your hw vendor)\n", \r
+             GET_IOAPIC_ID(tmp));\r
+      IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);\r
+    }\r
+    \r
+    /*\r
+     * We need to adjust the IRQ routing table\r
+     * if the ID changed.\r
+     */\r
+    if (old_id != IOAPICMap[apic].ApicId)\r
+    {\r
+      for (i = 0; i < IRQCount; i++)\r
+      {\r
+       if (IRQMap[i].DstApicId == old_id)\r
+       {\r
+         IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;\r
+       }\r
+      }\r
+    }\r
+    \r
+    /*\r
+     * Read the right value from the MPC table and\r
+     * write it into the ID register.\r
+     */\r
+    DPRINT("Changing IO-APIC physical APIC ID to %d\n",\r
+          IOAPICMap[apic].ApicId);\r
+    \r
+    tmp &= ~IOAPIC_ID_MASK;\r
+    tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);\r
+\r
+    IOAPICWrite(apic, IOAPIC_ID, tmp);\r
+    \r
+    /*\r
+     * Sanity check\r
+     */\r
+    tmp = IOAPICRead(apic, 0);\r
+    if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId) \r
+    {\r
+      DPRINT1("Could not set I/O APIC ID!\n");\r
+      KEBUGCHECK(0);\r
+    }\r
+  }\r
+}\r
+\r
+/* This is performance critical and should probably be done in assembler */\r
+VOID IOAPICMaskIrq(ULONG Irq)\r
+{\r
+   IOAPIC_ROUTE_ENTRY Entry;\r
+   ULONG Apic = IrqApicMap[Irq];\r
+\r
+   *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);\r
+   *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);\r
+   Entry.dest.logical.logical_dest &= ~(1 << KeGetCurrentProcessorNumber());\r
+   if (Entry.dest.logical.logical_dest == 0)\r
+   {\r
+      Entry.mask = 1;\r
+   }\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));\r
+}\r
+\r
+/* This is performance critical and should probably be done in assembler */\r
+VOID IOAPICUnmaskIrq(ULONG Irq)\r
+{\r
+   IOAPIC_ROUTE_ENTRY Entry;\r
+   ULONG Apic = IrqApicMap[Irq];\r
+\r
+   *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);\r
+   *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);\r
+   Entry.dest.logical.logical_dest |= 1 << KeGetCurrentProcessorNumber();\r
+   Entry.mask = 0;\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));\r
+   IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));\r
+}\r
+\r
+VOID IOAPICDump(VOID)\r
+{\r
+   ULONG apic, i;\r
+   ULONG reg0, reg1, reg2=0;\r
+\r
+   DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);\r
+   for (i = 0; i < IOAPICCount; i++) \r
+   {\r
+      DbgPrint("Number of IO-APIC #%d registers: %d.\n",\r
+              IOAPICMap[i].ApicId,\r
+               IOAPICMap[i].EntryCount);\r
+   }\r
+\r
+   /*\r
+    * We are a bit conservative about what we expect.  We have to\r
+    * know about every hardware change ASAP.\r
+    */\r
+   DbgPrint("Testing the IO APIC.......................\n");\r
+\r
+   for (apic = 0; apic < IOAPICCount; apic++) \r
+   {\r
+      reg0 = IOAPICRead(apic, IOAPIC_ID);\r
+      reg1 = IOAPICRead(apic, IOAPIC_VER);\r
+      if (GET_IOAPIC_VERSION(reg1) >= 0x10) \r
+      {\r
+         reg2 = IOAPICRead(apic, IOAPIC_ARB);\r
+      }\r
+\r
+      DbgPrint("\n");\r
+      DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);\r
+      DbgPrint(".... register #00: %08X\n", reg0);\r
+      DbgPrint(".......    : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));\r
+      if (reg0 & 0xF0FFFFFF) \r
+      {\r
+         DbgPrint("  WARNING: Unexpected IO-APIC\n");\r
+      }\r
+\r
+      DbgPrint(".... register #01: %08X\n", reg1);\r
+      i = GET_IOAPIC_MRE(reg1);\r
+\r
+      DbgPrint(".......     : max redirection entries: %04X\n", i);\r
+      if ((i != 0x0f) &&    /* older (Neptune) boards */\r
+         (i != 0x17) &&    /* typical ISA+PCI boards */\r
+         (i != 0x1b) &&    /* Compaq Proliant boards */\r
+         (i != 0x1f) &&    /* dual Xeon boards */\r
+          (i != 0x22) &&   /* bigger Xeon boards */\r
+         (i != 0x2E) &&\r
+         (i != 0x3F)) \r
+      {\r
+         DbgPrint("  WARNING: Unexpected IO-APIC\n");\r
+      }\r
+\r
+      i = GET_IOAPIC_VERSION(reg1);\r
+      DbgPrint(".......     : IO APIC version: %04X\n", i);\r
+      if ((i != 0x01) &&    /* 82489DX IO-APICs */\r
+         (i != 0x10) &&    /* oldest IO-APICs */\r
+         (i != 0x11) &&    /* Pentium/Pro IO-APICs */\r
+         (i != 0x13))      /* Xeon IO-APICs */\r
+      {\r
+         DbgPrint("  WARNING: Unexpected IO-APIC\n");\r
+      }\r
+\r
+      if (reg1 & 0xFF00FF00) \r
+      {\r
+         DbgPrint("  WARNING: Unexpected IO-APIC\n");\r
+      }\r
+\r
+      if (GET_IOAPIC_VERSION(reg1) >= 0x10) \r
+      {\r
+        DbgPrint(".... register #02: %08X\n", reg2);\r
+        DbgPrint(".......     : arbitration: %02X\n",\r
+                 GET_IOAPIC_ARB(reg2));\r
+        if (reg2 & 0xF0FFFFFF) \r
+        {\r
+            DbgPrint("  WARNING: Unexpected IO-APIC\n");\r
+         }\r
+      }\r
+\r
+      DbgPrint(".... IRQ redirection table:\n");\r
+      DbgPrint(" NR Log Phy Mask Trig IRR Pol"\r
+              " Stat Dest Deli Vect:   \n");\r
+\r
+      for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++) \r
+      {\r
+         IOAPIC_ROUTE_ENTRY entry;\r
+\r
+        *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);\r
+        *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);\r
+\r
+        DbgPrint(" %02x %03X %02X  ",\r
+                 i,\r
+                 entry.dest.logical.logical_dest,\r
+                 entry.dest.physical.physical_dest);\r
+\r
+         DbgPrint("%C    %C    %1d  %C    %C    %C     %03X    %02X\n",\r
+                 (entry.mask == 0) ? 'U' : 'M',            // Unmasked/masked\r
+                 (entry.trigger == 0) ? 'E' : 'L',         // Edge/level sensitive\r
+                 entry.irr,\r
+                 (entry.polarity == 0) ? 'H' : 'L',        // Active high/active low\r
+                 (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending\r
+                 (entry.dest_mode == 0) ? 'P' : 'L',       // Physical logical\r
+                 entry.delivery_mode,\r
+                 entry.vector);\r
+      }\r
+   }\r
+\r
+   DbgPrint(".................................... done.\n");\r
+}\r
+\r
+VOID\r
+HaliReconfigurePciInterrupts(VOID)\r
+{\r
+   ULONG i;\r
+\r
+   for (i = 0; i < IRQCount; i++)\r
+   {\r
+      if (BUSMap[IRQMap[i].SrcBusId] == MP_BUS_PCI)\r
+      {\r
+         DPRINT("%02x: IrqType %02x, IrqFlag %02x, SrcBusId %02x, SrcBusIrq %02x"\r
+               ", DstApicId %02x, DstApicInt %02x\n",\r
+               i, IRQMap[i].IrqType, IRQMap[i].IrqFlag, IRQMap[i].SrcBusId, \r
+               IRQMap[i].SrcBusIrq, IRQMap[i].DstApicId, IRQMap[i].DstApicInt);\r
+\r
+        if(1 != HalSetBusDataByOffset(PCIConfiguration, \r
+                                      IRQMap[i].SrcBusId, \r
+                                      (IRQMap[i].SrcBusIrq >> 2) & 0x1f, \r
+                                      &IRQMap[i].DstApicInt, \r
+                                      0x3c /*PCI_INTERRUPT_LINE*/, \r
+                                      1))\r
+        {\r
+           CHECKPOINT;\r
+        }\r
+      }\r
+   }\r
+}\r
+\r
+VOID Disable8259AIrq(ULONG irq)\r
+{\r
+    ULONG tmp;\r
+\r
+    if (irq >= 8) \r
+    {\r
+       tmp = READ_PORT_UCHAR((PUCHAR)0xA1);\r
+       tmp |= (1 << (irq - 8));\r
+       WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);\r
+    } \r
+    else \r
+    {\r
+       tmp = READ_PORT_UCHAR((PUCHAR)0x21);\r
+       tmp |= (1 << irq);\r
+       WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);\r
+    }\r
+}\r
+\r
+ULONG IOAPICRead(ULONG Apic, ULONG Offset)\r
+{\r
+  PULONG Base;\r
+\r
+  Base = (PULONG)IOAPICMap[Apic].ApicAddress;\r
+  *Base = Offset;\r
+  return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));\r
+}\r
+\r
+VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)\r
+{\r
+  PULONG Base;\r
+\r
+  Base = (PULONG)IOAPICMap[Apic].ApicAddress;\r
+  *Base = Offset;\r
+  *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;\r
+}\r
+\r
+/* EOF */\r
diff --git a/reactos/hal/halx86/mp/mpconfig.c b/reactos/hal/halx86/mp/mpconfig.c
new file mode 100644 (file)
index 0000000..e624887
--- /dev/null
@@ -0,0 +1,649 @@
+/* $Id$\r
+ *\r
+ * COPYRIGHT:             See COPYING in the top level directory\r
+ * PROJECT:               ReactOS kernel\r
+ * FILE:                  hal/halx86/generic/mpconfig.c\r
+ * PURPOSE:               \r
+ * PROGRAMMER:            \r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <ddk/ntddk.h>\r
+#include <ntos/types.h>\r
+#include <hal.h>\r
+#include <mps.h>\r
+#include <apic.h>\r
+#include <ioapic.h>\r
+\r
+//#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* GLOBALS ******************************************************************/\r
+\r
+MP_FLOATING_POINTER* Mpf = NULL;\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+static UCHAR \r
+MPChecksum(PUCHAR Base,\r
+          ULONG Size)\r
+/*\r
+ * Checksum an MP configuration block\r
+ */\r
+{\r
+   UCHAR Sum = 0;\r
+\r
+   while (Size--)\r
+      Sum += *Base++;\r
+\r
+   return Sum;\r
+}\r
+\r
+static VOID \r
+HaliMPIntSrcInfo(PMP_CONFIGURATION_INTSRC m)\r
+{\r
+  DPRINT("Int: type %d, pol %d, trig %d, bus %d,"\r
+         " IRQ %02x, APIC ID %x, APIC INT %02x\n",\r
+         m->IrqType, m->IrqFlag & 3,\r
+         (m->IrqFlag >> 2) & 3, m->SrcBusId,\r
+         m->SrcBusIrq, m->DstApicId, m->DstApicInt);\r
+  if (IRQCount > MAX_IRQ_SOURCE) \r
+  {\r
+    DPRINT1("Max # of irq sources exceeded!!\n");\r
+    KEBUGCHECK(0);\r
+  }\r
+\r
+  IRQMap[IRQCount] = *m;\r
+  IRQCount++;\r
+}\r
+\r
+static PCHAR \r
+HaliMPFamily(ULONG Family,\r
+            ULONG Model)\r
+{\r
+   static CHAR str[64];\r
+   static PCHAR CPUs[] =\r
+   {\r
+      "80486DX", "80486DX",\r
+      "80486SX", "80486DX/2 or 80487",\r
+      "80486SL", "Intel5X2(tm)",\r
+      "Unknown", "Unknown",\r
+      "80486DX/4"\r
+   };\r
+   if (Family == 0x6)\r
+      return ("Pentium(tm) Pro");\r
+   if (Family == 0x5)\r
+      return ("Pentium(tm)");\r
+   if (Family == 0x0F && Model == 0x0F)\r
+      return("Special controller");\r
+   if (Family == 0x0F && Model == 0x00)\r
+      return("Pentium 4(tm)");\r
+   if (Family == 0x04 && Model < 9)\r
+      return CPUs[Model];\r
+   sprintf(str, "Unknown CPU with family ID %ld and model ID %ld", Family, Model);\r
+   return str;\r
+}\r
+\r
+\r
+static VOID \r
+HaliMPProcessorInfo(PMP_CONFIGURATION_PROCESSOR m)\r
+{\r
+  ULONG ver;\r
+\r
+  if (!(m->CpuFlags & CPU_FLAG_ENABLED))\r
+    return;\r
+\r
+  DPRINT("Processor #%d %s APIC version %d\n",\r
+         m->ApicId,\r
+         HaliMPFamily((m->FeatureFlags & CPU_FAMILY_MASK) >> 8,\r
+                      (m->FeatureFlags & CPU_MODEL_MASK) >> 4),\r
+         m->ApicVersion);\r
+\r
+  if (m->FeatureFlags & (1 << 0))\r
+    DPRINT("    Floating point unit present.\n");\r
+  if (m->FeatureFlags & (1 << 7))\r
+    DPRINT("    Machine Exception supported.\n");\r
+  if (m->FeatureFlags & (1 << 8))\r
+    DPRINT("    64 bit compare & exchange supported.\n");\r
+  if (m->FeatureFlags & (1 << 9))\r
+    DPRINT("    Internal APIC present.\n");\r
+  if (m->FeatureFlags & (1 << 11))\r
+    DPRINT("    SEP present.\n");\r
+  if (m->FeatureFlags & (1 << 12))\r
+    DPRINT("    MTRR present.\n");\r
+  if (m->FeatureFlags & (1 << 13))\r
+    DPRINT("    PGE  present.\n");\r
+  if (m->FeatureFlags & (1 << 14))\r
+    DPRINT("    MCA  present.\n");\r
+  if (m->FeatureFlags & (1 << 15))\r
+    DPRINT("    CMOV  present.\n");\r
+  if (m->FeatureFlags & (1 << 16))\r
+    DPRINT("    PAT  present.\n");\r
+  if (m->FeatureFlags & (1 << 17))\r
+    DPRINT("    PSE  present.\n");\r
+  if (m->FeatureFlags & (1 << 18))\r
+    DPRINT("    PSN  present.\n");\r
+  if (m->FeatureFlags & (1 << 19))\r
+    DPRINT("    Cache Line Flush Instruction present.\n");\r
+  /* 20 Reserved */\r
+  if (m->FeatureFlags & (1 << 21))\r
+    DPRINT("    Debug Trace and EMON Store present.\n");\r
+  if (m->FeatureFlags & (1 << 22))\r
+    DPRINT("    ACPI Thermal Throttle Registers present.\n");\r
+  if (m->FeatureFlags & (1 << 23))\r
+    DPRINT("    MMX  present.\n");\r
+  if (m->FeatureFlags & (1 << 24))\r
+    DPRINT("    FXSR  present.\n");\r
+  if (m->FeatureFlags & (1 << 25))\r
+    DPRINT("    XMM  present.\n");\r
+  if (m->FeatureFlags & (1 << 26))\r
+    DPRINT("    Willamette New Instructions present.\n");\r
+  if (m->FeatureFlags & (1 << 27))\r
+    DPRINT("    Self Snoop present.\n");\r
+  /* 28 Reserved */\r
+  if (m->FeatureFlags & (1 << 29))\r
+    DPRINT("    Thermal Monitor present.\n");\r
+  /* 30, 31 Reserved */\r
+\r
+  CPUMap[CPUCount].APICId = m->ApicId;\r
+\r
+  CPUMap[CPUCount].Flags = CPU_USABLE;\r
+\r
+  if (m->CpuFlags & CPU_FLAG_BSP) \r
+  {\r
+    DPRINT("    Bootup CPU\n");\r
+    CPUMap[CPUCount].Flags |= CPU_BSP;\r
+    BootCPU = m->ApicId;\r
+  }\r
+\r
+  if (m->ApicId > MAX_CPU) \r
+  {\r
+    DPRINT("Processor #%d INVALID. (Max ID: %d).\n", m->ApicId, MAX_CPU);\r
+    return;\r
+  }\r
+  ver = m->ApicVersion;\r
+\r
+  /*\r
+   * Validate version\r
+   */\r
+  if (ver == 0x0) \r
+  {\r
+     DPRINT("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->ApicId);\r
+     ver = 0x10;\r
+  }\r
+//  ApicVersion[m->ApicId] = Ver;\r
+//  BiosCpuApicId[CPUCount] = m->ApicId;\r
+  CPUMap[CPUCount].APICVersion = ver;\r
+  \r
+  CPUCount++;\r
+}\r
+\r
+static VOID \r
+HaliMPBusInfo(PMP_CONFIGURATION_BUS m)\r
+{\r
+  static ULONG CurrentPCIBusId = 0;\r
+\r
+  DPRINT("Bus #%d is %.*s\n", m->BusId, 6, m->BusType);\r
+\r
+  if (strncmp(m->BusType, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) \r
+  {\r
+     BUSMap[m->BusId] = MP_BUS_ISA;\r
+  } \r
+  else if (strncmp(m->BusType, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) \r
+  {\r
+     BUSMap[m->BusId] = MP_BUS_EISA;\r
+  } \r
+  else if (strncmp(m->BusType, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) \r
+  {\r
+     BUSMap[m->BusId] = MP_BUS_PCI;\r
+     PCIBUSMap[m->BusId] = CurrentPCIBusId;\r
+     CurrentPCIBusId++;\r
+  } \r
+  else if (strncmp(m->BusType, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) \r
+  {\r
+     BUSMap[m->BusId] = MP_BUS_MCA;\r
+  } \r
+  else \r
+  {\r
+     DPRINT("Unknown bustype %.*s - ignoring\n", 6, m->BusType);\r
+  }\r
+}\r
+\r
+static VOID \r
+HaliMPIOApicInfo(PMP_CONFIGURATION_IOAPIC m)\r
+{\r
+  if (!(m->ApicFlags & CPU_FLAG_ENABLED))\r
+    return;\r
+\r
+  DPRINT("I/O APIC #%d Version %d at 0x%lX.\n",\r
+         m->ApicId, m->ApicVersion, m->ApicAddress);\r
+  if (IOAPICCount > MAX_IOAPIC) \r
+  {\r
+    DPRINT("Max # of I/O APICs (%d) exceeded (found %d).\n",\r
+           MAX_IOAPIC, IOAPICCount);\r
+    DPRINT1("Recompile with bigger MAX_IOAPIC!.\n");\r
+    KEBUGCHECK(0);\r
+  }\r
+\r
+  IOAPICMap[IOAPICCount].ApicId = m->ApicId;\r
+  IOAPICMap[IOAPICCount].ApicVersion = m->ApicVersion;\r
+  IOAPICMap[IOAPICCount].ApicAddress = m->ApicAddress;\r
+  IOAPICCount++;\r
+}\r
+\r
+\r
+static VOID \r
+HaliMPIntLocalInfo(PMP_CONFIGURATION_INTLOCAL m)\r
+{\r
+  DPRINT("Lint: type %d, pol %d, trig %d, bus %d,"\r
+         " IRQ %02x, APIC ID %x, APIC LINT %02x\n",\r
+         m->IrqType, m->SrcBusIrq & 3,\r
+         (m->SrcBusIrq >> 2) & 3, m->SrcBusId,\r
+          m->SrcBusIrq, m->DstApicId, m->DstApicLInt);\r
+  /*\r
+   * Well it seems all SMP boards in existence\r
+   * use ExtINT/LVT1 == LINT0 and\r
+   * NMI/LVT2 == LINT1 - the following check\r
+   * will show us if this assumptions is false.\r
+   * Until then we do not have to add baggage.\r
+   */\r
+  if ((m->IrqType == INT_EXTINT) && (m->DstApicLInt != 0)) \r
+  {\r
+    DPRINT1("Invalid MP table!\n");\r
+    KEBUGCHECK(0);\r
+  }\r
+  if ((m->IrqType == INT_NMI) && (m->DstApicLInt != 1)) \r
+  {\r
+    DPRINT1("Invalid MP table!\n");\r
+    KEBUGCHECK(0);\r
+  }\r
+}\r
+\r
+\r
+static BOOLEAN\r
+HaliReadMPConfigTable(PMP_CONFIGURATION_TABLE Table)\r
+/*\r
+   PARAMETERS:\r
+      Table = Pointer to MP configuration table\r
+ */\r
+{\r
+   PUCHAR Entry;\r
+   ULONG Count;\r
+\r
+   if (Table->Signature != MPC_SIGNATURE)\r
+     {\r
+       PUCHAR pc = (PUCHAR)&Table->Signature;\r
+       \r
+       DPRINT1("Bad MP configuration block signature: %c%c%c%c\n", \r
+               pc[0], pc[1], pc[2], pc[3]);\r
+       KEBUGCHECK(0);\r
+       return FALSE;\r
+     }\r
+\r
+   if (MPChecksum((PUCHAR)Table, Table->Length))\r
+     {\r
+       DPRINT1("Bad MP configuration block checksum\n");\r
+       KEBUGCHECK(0);\r
+       return FALSE;\r
+     }\r
+\r
+   if (Table->Specification != 0x01 && Table->Specification != 0x04)\r
+     {\r
+       DPRINT1("Bad MP configuration table version (%d)\n",\r
+              Table->Specification);\r
+       KEBUGCHECK(0);\r
+       return FALSE;\r
+     }\r
+\r
+   if (Table->LocalAPICAddress != APIC_DEFAULT_BASE)\r
+     {\r
+       DPRINT1("APIC base address is at 0x%X. I cannot handle non-standard adresses\n", \r
+              Table->LocalAPICAddress);\r
+       KEBUGCHECK(0);\r
+       return FALSE;\r
+     }\r
+\r
+   DPRINT("Oem: %.*s, ProductId: %.*s\n", 8, Table->Oem, 12, Table->ProductId);\r
+   DPRINT("APIC at: %08x\n", Table->LocalAPICAddress);\r
+\r
+\r
+   Entry = (PUCHAR)((PVOID)Table + sizeof(MP_CONFIGURATION_TABLE));\r
+   Count = 0;\r
+   while (Count < (Table->Length - sizeof(MP_CONFIGURATION_TABLE)))\r
+   {\r
+     /* Switch on type */\r
+     switch (*Entry)\r
+       {\r
+       case MPCTE_PROCESSOR:\r
+         {\r
+          HaliMPProcessorInfo((PMP_CONFIGURATION_PROCESSOR)Entry);\r
+          Entry += sizeof(MP_CONFIGURATION_PROCESSOR);\r
+          Count += sizeof(MP_CONFIGURATION_PROCESSOR);\r
+          break;\r
+        }\r
+       case MPCTE_BUS:\r
+        {\r
+          HaliMPBusInfo((PMP_CONFIGURATION_BUS)Entry);\r
+          Entry += sizeof(MP_CONFIGURATION_BUS);\r
+          Count += sizeof(MP_CONFIGURATION_BUS);\r
+          break;\r
+        }\r
+       case MPCTE_IOAPIC:\r
+        {\r
+          HaliMPIOApicInfo((PMP_CONFIGURATION_IOAPIC)Entry);\r
+          Entry += sizeof(MP_CONFIGURATION_IOAPIC);\r
+          Count += sizeof(MP_CONFIGURATION_IOAPIC);\r
+          break;\r
+        }\r
+       case MPCTE_INTSRC:\r
+        {\r
+          HaliMPIntSrcInfo((PMP_CONFIGURATION_INTSRC)Entry);\r
+          Entry += sizeof(MP_CONFIGURATION_INTSRC);\r
+          Count += sizeof(MP_CONFIGURATION_INTSRC);\r
+          break;\r
+        }\r
+       case MPCTE_LINTSRC:\r
+        {\r
+          HaliMPIntLocalInfo((PMP_CONFIGURATION_INTLOCAL)Entry);\r
+          Entry += sizeof(MP_CONFIGURATION_INTLOCAL);\r
+          Count += sizeof(MP_CONFIGURATION_INTLOCAL);\r
+          break;\r
+        }\r
+       default:\r
+        DPRINT1("Unknown entry in MPC table\n");\r
+        KEBUGCHECK(0);\r
+        return FALSE;\r
+       }\r
+   }\r
+   return TRUE;\r
+}\r
+\r
+static VOID \r
+HaliConstructDefaultIOIrqMPTable(ULONG Type)\r
+{\r
+       MP_CONFIGURATION_INTSRC intsrc;\r
+       ULONG i;\r
+\r
+       intsrc.Type = MPCTE_INTSRC;\r
+       intsrc.IrqFlag = 0;                     /* conforming */\r
+       intsrc.SrcBusId = 0;\r
+       intsrc.DstApicId = IOAPICMap[0].ApicId;\r
+\r
+       intsrc.IrqType = INT_VECTORED;\r
+       for (i = 0; i < 16; i++) {\r
+               switch (Type) {\r
+               case 2:\r
+                       if (i == 0 || i == 13)\r
+                               continue;       /* IRQ0 & IRQ13 not connected */\r
+                       /* Fall through */\r
+               default:\r
+                       if (i == 2)\r
+                               continue;       /* IRQ2 is never connected */\r
+               }\r
+\r
+               intsrc.SrcBusIrq = i;\r
+               intsrc.DstApicInt = i ? i : 2; /* IRQ0 to INTIN2 */\r
+               HaliMPIntSrcInfo(&intsrc);\r
+       }\r
+\r
+       intsrc.IrqType = INT_EXTINT;\r
+       intsrc.SrcBusIrq = 0;\r
+       intsrc.DstApicInt = 0; /* 8259A to INTIN0 */\r
+       HaliMPIntSrcInfo(&intsrc);\r
+}\r
+\r
+static VOID \r
+HaliConstructDefaultISAMPTable(ULONG Type)\r
+{\r
+  MP_CONFIGURATION_PROCESSOR processor;\r
+  MP_CONFIGURATION_BUS bus;\r
+  MP_CONFIGURATION_IOAPIC ioapic;\r
+  MP_CONFIGURATION_INTLOCAL lintsrc;\r
+  ULONG linttypes[2] = { INT_EXTINT, INT_NMI };\r
+  ULONG i;\r
+\r
+  /*\r
+   * 2 CPUs, numbered 0 & 1.\r
+   */\r
+  processor.Type = MPCTE_PROCESSOR;\r
+  /* Either an integrated APIC or a discrete 82489DX. */\r
+  processor.ApicVersion = Type > 4 ? 0x10 : 0x01;\r
+  processor.CpuFlags = CPU_FLAG_ENABLED | CPU_FLAG_BSP;\r
+  /* FIXME: Get this from the bootstrap processor */\r
+  processor.CpuSignature = 0;\r
+  processor.FeatureFlags = 0;\r
+  processor.Reserved[0] = 0;\r
+  processor.Reserved[1] = 0;\r
+  for (i = 0; i < 2; i++) \r
+  {\r
+    processor.ApicId = i;\r
+    HaliMPProcessorInfo(&processor);\r
+    processor.CpuFlags &= ~CPU_FLAG_BSP;\r
+  }\r
+\r
+  bus.Type = MPCTE_BUS;\r
+  bus.BusId = 0;\r
+  switch (Type) \r
+  {\r
+    default:\r
+    DPRINT("Unknown standard configuration %d\n", Type);\r
+      /* Fall through */\r
+    case 1:\r
+    case 5:\r
+      memcpy(bus.BusType, "ISA   ", 6);\r
+      break;\r
+    case 2:\r
+    case 6:\r
+    case 3:\r
+      memcpy(bus.BusType, "EISA  ", 6);\r
+      break;\r
+    case 4:\r
+    case 7:\r
+      memcpy(bus.BusType, "MCA   ", 6);\r
+  }\r
+  HaliMPBusInfo(&bus);\r
+  if (Type > 4) \r
+  {\r
+    bus.Type = MPCTE_BUS;\r
+    bus.BusId = 1;\r
+    memcpy(bus.BusType, "PCI   ", 6);\r
+    HaliMPBusInfo(&bus);\r
+  }\r
+\r
+  ioapic.Type = MPCTE_IOAPIC;\r
+  ioapic.ApicId = 2;\r
+  ioapic.ApicVersion = Type > 4 ? 0x10 : 0x01;\r
+  ioapic.ApicFlags = MP_IOAPIC_USABLE;\r
+  ioapic.ApicAddress = IOAPIC_DEFAULT_BASE;\r
+  HaliMPIOApicInfo(&ioapic);\r
+\r
+  /*\r
+   * We set up most of the low 16 IO-APIC pins according to MPS rules.\r
+   */\r
+  HaliConstructDefaultIOIrqMPTable(Type);\r
+\r
+  lintsrc.Type = MPCTE_LINTSRC;\r
+  lintsrc.IrqType = 0;\r
+  lintsrc.IrqFlag = 0;  /* conforming */\r
+  lintsrc.SrcBusId = 0;\r
+  lintsrc.SrcBusIrq = 0;\r
+  lintsrc.DstApicId = MP_APIC_ALL;\r
+  for (i = 0; i < 2; i++) \r
+  {\r
+    lintsrc.IrqType = linttypes[i];\r
+    lintsrc.DstApicLInt = i;\r
+    HaliMPIntLocalInfo(&lintsrc);\r
+  }\r
+}\r
+\r
+\r
+static BOOLEAN\r
+HaliScanForMPConfigTable(ULONG Base,\r
+                        ULONG Size)\r
+{\r
+/*\r
+   PARAMETERS:\r
+      Base = Base address of region\r
+      Size = Length of region to check\r
+   RETURNS:\r
+      TRUE if a valid MP configuration table was found\r
+ */\r
+\r
+   PULONG bp = (PULONG)Base;\r
+   MP_FLOATING_POINTER* mpf;\r
+   UCHAR Checksum;\r
+\r
+   while (Size > 0)\r
+   {\r
+      mpf = (MP_FLOATING_POINTER*)bp;\r
+      if (mpf->Signature == MPF_SIGNATURE)\r
+      {\r
+        Checksum = MPChecksum((PUCHAR)bp, 16);\r
+        DPRINT("Found MPF signature at %x, checksum %x\n", bp, Checksum);\r
+         if (Checksum == 0 &&\r
+            mpf->Length == 1)\r
+         {\r
+            DPRINT("Intel MultiProcessor Specification v1.%d compliant system.\n",\r
+                   mpf->Specification);\r
+\r
+            if (mpf->Feature2 & FEATURE2_IMCRP) \r
+           {\r
+               DPRINT("Running in IMCR and PIC compatibility mode.\n");\r
+            } \r
+           else \r
+           {\r
+               DPRINT("Running in Virtual Wire compatibility mode.\n");\r
+           }\r
+       \r
+\r
+            switch (mpf->Feature1)\r
+            {\r
+               case 0:\r
+                  /* Non standard configuration */\r
+                  break;\r
+               case 1:\r
+                  DPRINT("ISA\n");\r
+                  break;\r
+               case 2:\r
+                  DPRINT("EISA with no IRQ8 chaining\n");\r
+                  break;\r
+               case 3:\r
+                  DPRINT("EISA\n");\r
+                  break;\r
+               case 4:\r
+                  DPRINT("MCA\n");\r
+                  break;\r
+               case 5:\r
+                  DPRINT("ISA and PCI\n");\r
+                  break;\r
+               case 6:\r
+                  DPRINT("EISA and PCI\n");\r
+                  break;\r
+               case 7:\r
+                  DPRINT("MCA and PCI\n");\r
+                  break;\r
+               default:\r
+                  DPRINT("Unknown standard configuration %d\n", mpf->Feature1);\r
+                  return FALSE;\r
+            }\r
+            Mpf = mpf; \r
+            return TRUE;\r
+         }\r
+      }\r
+      bp += 4;\r
+      Size -= 16;\r
+   }\r
+   return FALSE;\r
+}\r
+\r
+static BOOLEAN\r
+HaliGetSmpConfig(VOID)\r
+{\r
+   if (Mpf == NULL)\r
+   {\r
+      return FALSE;\r
+   }\r
+\r
+   if (Mpf->Feature2 & FEATURE2_IMCRP)\r
+   {\r
+      DPRINT("Running in IMCR and PIC compatibility mode.\n");\r
+      APICMode = amPIC;\r
+   }\r
+   else\r
+   {\r
+      DPRINT("Running in Virtual Wire compatibility mode.\n");\r
+      APICMode = amVWIRE;\r
+   }\r
+\r
+   if (Mpf->Feature1 == 0 && Mpf->Address)\r
+   {\r
+      if(!HaliReadMPConfigTable((PMP_CONFIGURATION_TABLE)Mpf->Address))\r
+      {\r
+         DPRINT("BIOS bug, MP table errors detected!...\n");\r
+        DPRINT("... disabling SMP support. (tell your hw vendor)\n");\r
+        return FALSE;\r
+      }\r
+      if (IRQCount == 0)\r
+      {\r
+         MP_CONFIGURATION_BUS bus;\r
+\r
+         DPRINT("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");\r
+\r
+         bus.BusId = 1;\r
+        memcpy(bus.BusType, "ISA   ", 6);\r
+         HaliMPBusInfo(&bus);\r
+        HaliConstructDefaultIOIrqMPTable(bus.BusId);\r
+      }\r
+\r
+   } \r
+   else if(Mpf->Feature1 != 0)\r
+   {\r
+      HaliConstructDefaultISAMPTable(Mpf->Feature1);\r
+   }\r
+   else\r
+   {\r
+      KEBUGCHECK(0);\r
+   }\r
+   return TRUE;\r
+}    \r
+\r
+BOOLEAN \r
+HaliFindSmpConfig(VOID)\r
+{\r
+   /*\r
+     Scan the system memory for an MP configuration table\r
+       1) Scan the first KB of system base memory\r
+       2) Scan the last KB of system base memory\r
+       3) Scan the BIOS ROM address space between 0F0000h and 0FFFFFh\r
+       4) Scan the first KB from the Extended BIOS Data Area\r
+   */\r
+\r
+   if (!HaliScanForMPConfigTable(0x0, 0x400)) \r
+   {\r
+      if (!HaliScanForMPConfigTable(0x9FC00, 0x400)) \r
+      {\r
+         if (!HaliScanForMPConfigTable(0xF0000, 0x10000)) \r
+         {\r
+            if (!HaliScanForMPConfigTable(*((PUSHORT)0x040E) << 4, 0x400)) \r
+           {\r
+               DPRINT("No multiprocessor compliant system found.\n");\r
+               return FALSE;\r
+            }\r
+         }\r
+      }\r
+   }\r
+\r
+   if (HaliGetSmpConfig())\r
+   {\r
+      return TRUE;\r
+   }\r
+   else\r
+   {\r
+      DPRINT("No MP config table found\n");\r
+      return FALSE;\r
+   }\r
+\r
+}\r
+\r
+/* EOF */\r
index 48be827..9c13f46 100644 (file)
@@ -19,6 +19,7 @@
 #include <hal.h>
 #include <mps.h>
 #include <apic.h>
+#include <ioapic.h>
 
 #define NDEBUG
 #include <internal/debug.h>
index db82d9d..861647d 100644 (file)
@@ -18,6 +18,8 @@
 #include <hal.h>
 #include <halirq.h>
 #include <mps.h>
+
+#include <ioapic.h>
 #include <apic.h>
 
 #include <internal/ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
-/*
-   Address of area to be used for communication between Application
-   Processors (APs) and the BootStrap Processor (BSP)
- */
-#define COMMON_AREA  0x2000
-
-#define BIOS_AREA    0x0
-
-typedef struct __attribute__((packed)) _COMMON_AREA_INFO
-{
-   ULONG Stack;                    /* Location of AP stack */
-   ULONG PageDirectory;            /* Page directory for an AP */
-   ULONG NtProcessStartup;  /* Kernel entry point for an AP */
-   ULONG PaeModeEnabled;    /* PAE mode is enabled */
-   ULONG Debug[16];        /* For debugging */
-} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
-
-CPU_INFO CPUMap[MAX_CPU];          /* Map of all CPUs in the system */
-ULONG CPUCount;                    /* Total number of CPUs */
-ULONG OnlineCPUs;                  /* Bitmask of online CPUs */
-
-UCHAR BUSMap[MAX_BUS];             /* Map of all buses in the system */
-UCHAR PCIBUSMap[MAX_BUS];          /* Map of all PCI buses in the system */
-
-IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
-ULONG IOAPICCount;                 /* Number of I/O APICs in the system */
-
-MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
-ULONG IRQVectorMap[MAX_IRQ_SOURCE];             /* IRQ to vector map */
-ULONG IrqPinMap[MAX_IRQ_SOURCE];               /* IRQ to Pin map */
-ULONG IrqApicMap[MAX_IRQ_SOURCE];
-ULONG IRQCount;                                 /* Number of IRQs  */
-
-ULONG APICMode;                     /* APIC mode at startup */
-ULONG BootCPU;                      /* Bootstrap processor */
-PULONG BIOSBase;                    /* Virtual address of BIOS data segment */
-PULONG CommonBase;                  /* Virtual address of common area */
-
-extern CHAR *APstart, *APend;
-extern VOID (*APflush)(VOID);
-
-extern VOID MpsTimerInterrupt(VOID);
-extern VOID MpsErrorInterrupt(VOID);
-extern VOID MpsSpuriousInterrupt(VOID);
-extern VOID MpsIpiInterrupt(VOID);
-
-#define CMOS_READ(address) ({ \
-   WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
-   READ_PORT_UCHAR((PUCHAR)0x71)); \
-})
-
-#define CMOS_WRITE(address, value) ({ \
-   WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
-   WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
-})
 
-extern PVOID IMPORTED MmSystemRangeStart;
 
 /* FUNCTIONS *****************************************************************/
 
-/* Functions for handling 8259A PICs */
-
-VOID Disable8259AIrq(ULONG irq)
-{
-    ULONG tmp;
-
-    if (irq >= 8) 
-    {
-       tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
-       tmp |= (1 << (irq - 8));
-       WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
-    } 
-    else 
-    {
-       tmp = READ_PORT_UCHAR((PUCHAR)0x21);
-       tmp |= (1 << irq);
-       WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
-    }
-}
-
-
-VOID Enable8259AIrq(ULONG irq)
-{
-    ULONG tmp;
-
-    if (irq >= 8) 
-    {
-       tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
-       tmp &= ~(1 << (irq - 8));
-       WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
-    } 
-    else 
-    {
-       tmp = READ_PORT_UCHAR((PUCHAR)0x21);
-       tmp &= ~(1 << irq);
-       WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
-    }
-}
-
-
-/* Functions for handling I/O APICs */
-
-ULONG IOAPICRead(ULONG Apic, ULONG Offset)
-{
-  PULONG Base;
-
-  Base = (PULONG)IOAPICMap[Apic].ApicAddress;
-  *Base = Offset;
-  return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
-}
-
-VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
-{
-  PULONG Base;
-
-  Base = (PULONG)IOAPICMap[Apic].ApicAddress;
-  *Base = Offset;
-  *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;
-}
-
-
-VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
-{
-  IOAPIC_ROUTE_ENTRY Entry;
-
-  DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);
-  /*
-   * Disable it in the IO-APIC irq-routing table
-   */
-  memset(&Entry, 0, sizeof(Entry));
-  Entry.mask = 1;
-
-  IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
-  IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
-}
-
-static VOID IOAPICClear(ULONG Apic)
-{
-  ULONG Pin;
-
-  for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
-  {
-    IOAPICClearPin(Apic, Pin);
-  }
-}
-
-static VOID IOAPICClearAll(VOID)
-{
-  ULONG Apic;
-
-  for (Apic = 0; Apic < IOAPICCount; Apic++)
-  {
-    IOAPICClear(Apic);
-  }
-}
-
-/* This is performance critical and should probably be done in assembler */
-VOID IOAPICMaskIrq(ULONG Irq)
-{
-  IOAPIC_ROUTE_ENTRY Entry;
-  ULONG Apic = IrqApicMap[Irq];
-
-  *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
-  *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
-  Entry.dest.logical.logical_dest &= ~(1 << KeGetCurrentProcessorNumber());
-  if (Entry.dest.logical.logical_dest == 0)
-  {
-     Entry.mask = 1;
-  }
-  IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
-  IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
-}
-
-
-/* This is performance critical and should probably be done in assembler */
-VOID IOAPICUnmaskIrq(ULONG Irq)
-{
-  IOAPIC_ROUTE_ENTRY Entry;
-  ULONG Apic = IrqApicMap[Irq];
-
-  *(((PULONG)&Entry)+0) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
-  *(((PULONG)&Entry)+1) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq+1);
-  Entry.dest.logical.logical_dest |= 1 << KeGetCurrentProcessorNumber();
-  Entry.mask = 0;
-  IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq+1, *(((PULONG)&Entry)+1));
-  IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *(((PULONG)&Entry)+0));
-}
-
-static VOID 
-IOAPICSetupIds(VOID)
-{
-  ULONG tmp, apic, i;
-  UCHAR old_id;
-  
-  /*
-   * Set the IOAPIC ID to the value stored in the MPC table.
-   */
-  for (apic = 0; apic < IOAPICCount; apic++) 
-  {
-    
-    /* Read the register 0 value */
-    tmp = IOAPICRead(apic, IOAPIC_ID);
-    
-    old_id = IOAPICMap[apic].ApicId;
-    
-    if (IOAPICMap[apic].ApicId >= 0xf) 
-    {
-      DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-             apic, IOAPICMap[apic].ApicId);
-      DPRINT1("... fixing up to %d. (tell your hw vendor)\n", 
-             GET_IOAPIC_ID(tmp));
-      IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
-    }
-    
-    /*
-     * We need to adjust the IRQ routing table
-     * if the ID changed.
-     */
-    if (old_id != IOAPICMap[apic].ApicId)
-    {
-      for (i = 0; i < IRQCount; i++)
-      {
-       if (IRQMap[i].DstApicId == old_id)
-       {
-         IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
-       }
-      }
-    }
-    
-    /*
-     * Read the right value from the MPC table and
-     * write it into the ID register.
-     */
-    DPRINT("Changing IO-APIC physical APIC ID to %d\n",
-          IOAPICMap[apic].ApicId);
-    
-    tmp &= ~IOAPIC_ID_MASK;
-    tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
-
-    IOAPICWrite(apic, IOAPIC_ID, tmp);
-    
-    /*
-     * Sanity check
-     */
-    tmp = IOAPICRead(apic, 0);
-    if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId) 
-    {
-      DPRINT1("Could not set I/O APIC ID!\n");
-      KEBUGCHECK(0);
-    }
-  }
-}
-
-
-/*
- * EISA Edge/Level control register, ELCR
- */
-static ULONG EISA_ELCR(ULONG irq)
-{
-   if (irq < 16) 
-   {
-      PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
-      return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
-   }
-   DPRINT("Broken MPtable reports ISA irq %d\n", irq);
-   return 0;
-}
-
-/* EISA interrupts are always polarity zero and can be edge or level
- * trigger depending on the ELCR value.  If an interrupt is listed as
- * EISA conforming in the MP table, that means its trigger type must
- * be read in from the ELCR */
-
-#define default_EISA_trigger(idx)      (EISA_ELCR(IRQMap[idx].SrcBusIrq))
-#define default_EISA_polarity(idx)     (0)
-
-/* ISA interrupts are always polarity zero edge triggered,
- * when listed as conforming in the MP table. */
-
-#define default_ISA_trigger(idx)       (0)
-#define default_ISA_polarity(idx)      (0)
-
-/* PCI interrupts are always polarity one level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_PCI_trigger(idx)       (1)
-#define default_PCI_polarity(idx)      (1)
-
-/* MCA interrupts are always polarity zero level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_MCA_trigger(idx)       (1)
-#define default_MCA_polarity(idx)      (0)
-
-static ULONG IRQPolarity(ULONG idx)
-{
-       ULONG bus = IRQMap[idx].SrcBusId;
-       ULONG polarity;
-
-       /*
-        * Determine IRQ line polarity (high active or low active):
-        */
-       switch (IRQMap[idx].IrqFlag & 3)
-       {
-               case 0: /* conforms, ie. bus-type dependent polarity */
-               {
-                       switch (BUSMap[bus])
-                       {
-                               case MP_BUS_ISA: /* ISA pin */
-                               {
-                                       polarity = default_ISA_polarity(idx);
-                                       break;
-                               }
-                               case MP_BUS_EISA: /* EISA pin */
-                               {
-                                       polarity = default_EISA_polarity(idx);
-                                       break;
-                               }
-                               case MP_BUS_PCI: /* PCI pin */
-                               {
-                                       polarity = default_PCI_polarity(idx);
-                                       break;
-                               }
-                               case MP_BUS_MCA: /* MCA pin */
-                               {
-                                       polarity = default_MCA_polarity(idx);
-                                       break;
-                               }
-                               default:
-                               {
-                                       DPRINT("Broken BIOS!!\n");
-                                       polarity = 1;
-                                       break;
-                               }
-                       }
-                       break;
-               }
-               case 1: /* high active */
-               {
-                       polarity = 0;
-                       break;
-               }
-               case 2: /* reserved */
-               {
-                       DPRINT("Broken BIOS!!\n");
-                       polarity = 1;
-                       break;
-               }
-               case 3: /* low active */
-               {
-                       polarity = 1;
-                       break;
-               }
-               default: /* invalid */
-               {
-                       DPRINT("Broken BIOS!!\n");
-                       polarity = 1;
-                       break;
-               }
-       }
-       return polarity;
-}
-
-static ULONG IRQTrigger(ULONG idx)
-{
-       ULONG bus = IRQMap[idx].SrcBusId;
-       ULONG trigger;
-
-       /*
-        * Determine IRQ trigger mode (edge or level sensitive):
-        */
-       switch ((IRQMap[idx].IrqFlag >> 2) & 3)
-       {
-               case 0: /* conforms, ie. bus-type dependent */
-               {
-                       switch (BUSMap[bus])
-                       {
-                               case MP_BUS_ISA: /* ISA pin */
-                               {
-                                       trigger = default_ISA_trigger(idx);
-                                       break;
-                               }
-                               case MP_BUS_EISA: /* EISA pin */
-                               {
-                                       trigger = default_EISA_trigger(idx);
-                                       break;
-                               }
-                               case MP_BUS_PCI: /* PCI pin */
-                               {
-                                       trigger = default_PCI_trigger(idx);
-                                       break;
-                               }
-                               case MP_BUS_MCA: /* MCA pin */
-                               {
-                                       trigger = default_MCA_trigger(idx);
-                                       break;
-                               }
-                               default:
-                               {
-                                       DPRINT("Broken BIOS!!\n");
-                                       trigger = 1;
-                                       break;
-                               }
-                       }
-                       break;
-               }
-               case 1: /* edge */
-               {
-                       trigger = 0;
-                       break;
-               }
-               case 2: /* reserved */
-               {
-                       DPRINT("Broken BIOS!!\n");
-                       trigger = 1;
-                       break;
-               }
-               case 3: /* level */
-               {
-                       trigger = 1;
-                       break;
-               }
-               default: /* invalid */
-               {
-                       DPRINT("Broken BIOS!!\n");
-                       trigger = 0;
-                       break;
-               }
-       }
-       return trigger;
-}
-
-
-static ULONG Pin2Irq(ULONG idx,
-                    ULONG apic,
-                    ULONG pin)
-{
-       ULONG irq, i;
-       ULONG bus = IRQMap[idx].SrcBusId;
-
-       /*
-        * Debugging check, we are in big trouble if this message pops up!
-        */
-       if (IRQMap[idx].DstApicInt != pin) {
-               DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");
-  }
-
-       switch (BUSMap[bus])
-       {
-               case MP_BUS_ISA: /* ISA pin */
-               case MP_BUS_EISA:
-               case MP_BUS_MCA:
-               {
-                       irq = IRQMap[idx].SrcBusIrq;
-                       break;
-               }
-               case MP_BUS_PCI: /* PCI pin */
-               {
-                       /*
-                        * PCI IRQs are mapped in order
-                        */
-                       i = irq = 0;
-                       while (i < apic)
-                               irq += IOAPICMap[i++].EntryCount;
-                       irq += pin;
-                       break;
-               }
-               default:
-               {
-                       DPRINT("Unknown bus type %d.\n",bus);
-                       irq = 0;
-                       break;
-               }
-       }
-
-       return irq;
-}
-
-
-/*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
- */
-#define MAX_PLUS_SHARED_IRQS PIC_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + PIC_IRQS)
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
-static struct irq_pin_list {
-       ULONG apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
-
-/*
- * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
- * shared ISA-space IRQs, so we have to support them. We are super
- * fast in the common case, and fast for shared ISA-space IRQs.
- */
-static VOID AddPinToIrq(ULONG irq,
-                       ULONG apic,
-                       ULONG pin)
-{
-   static ULONG first_free_entry = PIC_IRQS;
-   struct irq_pin_list *entry = irq_2_pin + irq;
-
-   while (entry->next)
-   {
-      entry = irq_2_pin + entry->next;
-   }
-   
-   if (entry->pin != -1) 
-   {
-      entry->next = first_free_entry;
-      entry = irq_2_pin + entry->next;
-      if (++first_free_entry >= PIN_MAP_SIZE) 
-      {
-         DPRINT1("Ohh no!");
-        KEBUGCHECK(0);
-      }
-   }
-   entry->apic = apic;
-   entry->pin = pin;
-}
-
-
-/*
- * Find the IRQ entry number of a certain pin.
- */
-static ULONG IOAPICGetIrqEntry(ULONG apic,
-                              ULONG pin,
-                              ULONG type)
-{
-   ULONG i;
-
-   for (i = 0; i < IRQCount; i++)
-   {
-      if (IRQMap[i].IrqType == type &&
-         (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
-         IRQMap[i].DstApicInt == pin)
-      {
-         return i;
-      }
-   }
-   return -1;
-}
-
-
-static ULONG AssignIrqVector(ULONG irq)
-{
-#if 0
-  static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
-#endif
-  ULONG vector;
-  /* There may already have been assigned a vector for this IRQ */
-  vector = IRQVectorMap[irq];
-  if (vector > 0)
-  {
-    return vector;
-  }
-#if 0
-  if (current_vector > FIRST_SYSTEM_VECTOR) {
-      vector_offset++;
-         current_vector = FIRST_DEVICE_VECTOR + vector_offset;
-  } else if (current_vector == FIRST_SYSTEM_VECTOR) {
-     DPRINT1("Ran out of interrupt sources!");
-     KEBUGCHECK(0);
-  }
-
-  vector = current_vector;
-  IRQVectorMap[irq] = vector;
-  current_vector += 8;
-  return vector;
-#else
-  vector = IRQ2VECTOR(irq);
-  IRQVectorMap[irq] = vector;
-  return vector;
-#endif
-}
-
-
-VOID IOAPICSetupIrqs(VOID)
-{
-   IOAPIC_ROUTE_ENTRY entry;
-   ULONG apic, pin, idx, irq, first_notcon = 1, vector;
-
-   DPRINT("Init IO_APIC IRQs\n");
-
-   for (apic = 0; apic < IOAPICCount; apic++) 
-   {
-      for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++) 
-      {
-         /*
-         * add it to the IO-APIC irq-routing table
-         */
-        memset(&entry,0,sizeof(entry));
-
-        entry.delivery_mode = (APIC_DM_LOWEST >> 8);
-        entry.dest_mode = 1;  /* logical delivery */
-        entry.mask = 1;       /* disable IRQ */
-         entry.dest.logical.logical_dest = 0;
-
-        idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
-        if (idx == -1) 
-        {
-           if (first_notcon) 
-           {
-              DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
-              first_notcon = 0;
-           } 
-           else 
-           {
-              DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
-            }
-           continue;
-        }
-
-         entry.trigger = IRQTrigger(idx);
-        entry.polarity = IRQPolarity(idx);
-
-        if (entry.trigger) 
-        {
-           entry.trigger = 1;
-           entry.mask = 1; // disable
-           entry.dest.logical.logical_dest = 0;
-        }
-
-        irq = Pin2Irq(idx, apic, pin);
-        AddPinToIrq(irq, apic, pin);
-
-        vector = AssignIrqVector(irq);
-        entry.vector = vector;
-
-        DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
-
-         if (irq == 0)
-         {
-            /* Mask timer IRQ */
-            entry.mask = 1;
-         }
-
-         if ((apic == 0) && (irq < 16))
-        {
-           Disable8259AIrq(irq);
-        }
-         IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
-        IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
-
-        IrqPinMap[irq] = pin;
-        IrqApicMap[irq] = apic;
-
-        DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
-      }
-   }
-}
-
-
-static VOID IOAPICEnable(VOID)
-{
-   ULONG i, tmp;
-
-   for (i = 0; i < PIN_MAP_SIZE; i++) 
-   {
-      irq_2_pin[i].pin = -1;
-      irq_2_pin[i].next = 0;
-   }
-
-   /*
-    * The number of IO-APIC IRQ registers (== #pins):
-    */
-   for (i = 0; i < IOAPICCount; i++) 
-   {
-      tmp = IOAPICRead(i, IOAPIC_VER);
-      IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
-   }
-
-   /*
-    * Do not trust the IO-APIC being empty at bootup
-    */
-   IOAPICClearAll();
-}
-
-#if 0
-static VOID IOAPICDisable(VOID)
-{
-   /*
-    * Clear the IO-APIC before rebooting
-    */
-   IOAPICClearAll();
-   APICDisable();
-}
-#endif
-
-
-static VOID IOAPICSetup(VOID)
-{
-  IOAPICEnable();
-  IOAPICSetupIds();
-  APICSyncArbIDs();
-  IOAPICSetupIrqs();
-}
-
-
-VOID IOAPICDump(VOID)
-{
-   ULONG apic, i;
-   ULONG reg0, reg1, reg2=0;
-
-   DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
-   for (i = 0; i < IOAPICCount; i++) 
-   {
-      DbgPrint("Number of IO-APIC #%d registers: %d.\n",
-              IOAPICMap[i].ApicId,
-               IOAPICMap[i].EntryCount);
-   }
-
-   /*
-    * We are a bit conservative about what we expect.  We have to
-    * know about every hardware change ASAP.
-    */
-   DbgPrint("Testing the IO APIC.......................\n");
-
-   for (apic = 0; apic < IOAPICCount; apic++) 
-   {
-      reg0 = IOAPICRead(apic, IOAPIC_ID);
-      reg1 = IOAPICRead(apic, IOAPIC_VER);
-      if (GET_IOAPIC_VERSION(reg1) >= 0x10) 
-      {
-         reg2 = IOAPICRead(apic, IOAPIC_ARB);
-      }
-
-      DbgPrint("\n");
-      DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
-      DbgPrint(".... register #00: %08X\n", reg0);
-      DbgPrint(".......    : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
-      if (reg0 & 0xF0FFFFFF) 
-      {
-         DbgPrint("  WARNING: Unexpected IO-APIC\n");
-      }
-
-      DbgPrint(".... register #01: %08X\n", reg1);
-      i = GET_IOAPIC_MRE(reg1);
-
-      DbgPrint(".......     : max redirection entries: %04X\n", i);
-      if ((i != 0x0f) &&    /* older (Neptune) boards */
-         (i != 0x17) &&    /* typical ISA+PCI boards */
-         (i != 0x1b) &&    /* Compaq Proliant boards */
-         (i != 0x1f) &&    /* dual Xeon boards */
-          (i != 0x22) &&   /* bigger Xeon boards */
-         (i != 0x2E) &&
-         (i != 0x3F)) 
-      {
-         DbgPrint("  WARNING: Unexpected IO-APIC\n");
-      }
-
-      i = GET_IOAPIC_VERSION(reg1);
-      DbgPrint(".......     : IO APIC version: %04X\n", i);
-      if ((i != 0x01) &&    /* 82489DX IO-APICs */
-         (i != 0x10) &&    /* oldest IO-APICs */
-         (i != 0x11) &&    /* Pentium/Pro IO-APICs */
-         (i != 0x13))      /* Xeon IO-APICs */
-      {
-         DbgPrint("  WARNING: Unexpected IO-APIC\n");
-      }
-
-      if (reg1 & 0xFF00FF00) 
-      {
-         DbgPrint("  WARNING: Unexpected IO-APIC\n");
-      }
-
-      if (GET_IOAPIC_VERSION(reg1) >= 0x10) 
-      {
-        DbgPrint(".... register #02: %08X\n", reg2);
-        DbgPrint(".......     : arbitration: %02X\n",
-                 GET_IOAPIC_ARB(reg2));
-        if (reg2 & 0xF0FFFFFF) 
-        {
-            DbgPrint("  WARNING: Unexpected IO-APIC\n");
-         }
-      }
-
-      DbgPrint(".... IRQ redirection table:\n");
-      DbgPrint(" NR Log Phy Mask Trig IRR Pol"
-              " Stat Dest Deli Vect:   \n");
-
-      for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++) 
-      {
-         IOAPIC_ROUTE_ENTRY entry;
-
-        *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
-        *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
-
-        DbgPrint(" %02x %03X %02X  ",
-                 i,
-                 entry.dest.logical.logical_dest,
-                 entry.dest.physical.physical_dest);
-
-         DbgPrint("%C    %C    %1d  %C    %C    %C     %03X    %02X\n",
-                 (entry.mask == 0) ? 'U' : 'M',            // Unmasked/masked
-                 (entry.trigger == 0) ? 'E' : 'L',         // Edge/level sensitive
-                 entry.irr,
-                 (entry.polarity == 0) ? 'H' : 'L',        // Active high/active low
-                 (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
-                 (entry.dest_mode == 0) ? 'P' : 'L',       // Physical logical
-                 entry.delivery_mode,
-                 entry.vector);
-      }
-   }
-   DbgPrint("IRQ to pin mappings:\n");
-   for (i = 0; i < PIC_IRQS; i++) 
-   {
-      struct irq_pin_list *entry = irq_2_pin + i;
-      if (entry->pin < 0)
-      {
-         continue;
-      }
-      DbgPrint("IRQ%d ", i);
-      for (;;) 
-      {
-        DbgPrint("-> %d", entry->pin);
-        if (!entry->next)
-        {
-            break;
-        }
-        entry = irq_2_pin + entry->next;
-      }
-      if (i % 2) 
-      {
-         DbgPrint("\n");
-      } 
-      else 
-      {
-         DbgPrint("        ");
-      }
-   }
-
-   DbgPrint(".................................... done.\n");
-}
-
-
-
-/* Functions for handling local APICs */
-
-ULONG Read8254Timer(VOID)
-{
-       ULONG Count;
-
-       WRITE_PORT_UCHAR((PUCHAR)0x43, 0x00);
-       Count = READ_PORT_UCHAR((PUCHAR)0x40);
-       Count |= READ_PORT_UCHAR((PUCHAR)0x40) << 8;
-
-       return Count;
-}
-
-VOID WaitFor8254Wraparound(VOID)
-{
-   ULONG CurCount, PrevCount = ~0;
-   LONG Delta;
-
-   CurCount = Read8254Timer();
-   do 
-   {
-      PrevCount = CurCount;
-      CurCount = Read8254Timer();
-      Delta = CurCount - PrevCount;
-
-      /*
-       * This limit for delta seems arbitrary, but it isn't, it's
-       * slightly above the level of error a buggy Mercury/Neptune
-       * chipset timer can cause.
-       */
-
-   } 
-   while (Delta < 300);
-}
-
-#define HZ (100)
-#define APIC_DIVISOR (16)
-
-VOID APICSetupLVTT(ULONG ClockTicks)
-{
-   ULONG tmp;
-
-   tmp = GET_APIC_VERSION(APICRead(APIC_VER));
-   if (!APIC_INTEGRATED(tmp))
-   {
-      tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
-   }
-   else
-   {
-      /* Periodic timer */
-      tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
-   }
-   APICWrite(APIC_LVTT, tmp);
-
-   tmp = APICRead(APIC_TDCR);
-   tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
-   tmp |= APIC_TDCR_16;
-   APICWrite(APIC_TDCR, tmp);
-   APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
-}
-
-
-VOID APICCalibrateTimer(ULONG CPU)
-{
-   ULARGE_INTEGER t1, t2;
-   LONG tt1, tt2;
-
-   DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
-
-   APICSetupLVTT(1000000000);
-
-   /*
-    * The timer chip counts down to zero. Let's wait
-    * for a wraparound to start exact measurement:
-    * (the current tick might have been already half done)
-    */
-   WaitFor8254Wraparound();
-
-   /*
-    * We wrapped around just now. Let's start
-    */
-   ReadPentiumClock(&t1);
-   tt1 = APICRead(APIC_CCRT);
-
-   WaitFor8254Wraparound();
-
-
-   tt2 = APICRead(APIC_CCRT);
-   ReadPentiumClock(&t2);
-
-   CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
-   CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
-
-   /* Setup timer for normal operation */
-// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100);    // 100ns
-   APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000);  // 10ms
-// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
-
-   DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
-         CPUMap[CPU].CoreSpeed/1000000,
-         CPUMap[CPU].CoreSpeed%1000000);
-
-   DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
-         CPUMap[CPU].BusSpeed/1000000,
-         CPUMap[CPU].BusSpeed%1000000);
-}
-
-VOID 
-SetInterruptGate(ULONG index, ULONG address)
-{
-  IDT_DESCRIPTOR *idt;
-
-  idt = (IDT_DESCRIPTOR*)((ULONG)KeGetCurrentKPCR()->IDT + index * sizeof(IDT_DESCRIPTOR));
-  idt->a = (((ULONG)address)&0xffff) + (KERNEL_CS << 16);
-  idt->b = 0x8e00 + (((ULONG)address)&0xffff0000);
-}
-
 VOID STDCALL
 HalInitializeProcessor(ULONG ProcessorNumber,
                       PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
@@ -1043,7 +88,15 @@ HalAllProcessorsStarted (VOID)
     }
     else if (CPUs == CPUCount)
     {
-       IOAPICSetup();
+
+       IOAPICEnable();
+       IOAPICSetupIds();
+       if (CPUCount > 1)
+       {
+          APICSyncArbIDs();
+       }
+       IOAPICSetupIrqs();
+
        return TRUE;
     }
     return FALSE;
@@ -1053,12 +106,7 @@ BOOLEAN STDCALL
 HalStartNextProcessor(ULONG Unknown1,
                      ULONG ProcessorStack)
 {
-   PCOMMON_AREA_INFO Common;
-   ULONG StartupCount;
-   ULONG DeliveryStatus = 0;
-   ULONG AcceptStatus = 0;
-   ULONG CPU, i, j;
-   ULONG tmp, maxlvt;
+   ULONG CPU;
 
    DPRINT("HalStartNextProcessor(%x %x)\n", Unknown1, ProcessorStack);
 
@@ -1077,741 +125,8 @@ HalStartNextProcessor(ULONG Unknown1,
 
    DPRINT1("Attempting to boot CPU %d\n", CPU);
 
-   /* Send INIT IPI */
-
-   APICSendIPI(CPU, APIC_DM_INIT|APIC_ICR0_LEVEL_ASSERT);
-   KeStallExecutionProcessor(200);
-
-   /* Deassert INIT */
-
-   APICSendIPI(CPU, APIC_DM_INIT|APIC_ICR0_LEVEL_DEASSERT);
-
-   if (APIC_INTEGRATED(CPUMap[CPU].APICVersion)) 
-   {
-      /* Clear APIC errors */
-      APICWrite(APIC_ESR, 0);
-      tmp = (APICRead(APIC_ESR) & APIC_ESR_MASK);
-   }
-
-   Common = (PCOMMON_AREA_INFO)CommonBase;
-
-   /* Write the location of the AP stack */
-   Common->Stack = (ULONG)ProcessorStack;
-   /* Write the page directory page */
-   Ke386GetPageTableDirectory(Common->PageDirectory);
-   /* Write the kernel entry point */
-   Common->NtProcessStartup = (ULONG_PTR)RtlImageNtHeader(MmSystemRangeStart)->OptionalHeader.AddressOfEntryPoint + (ULONG_PTR)MmSystemRangeStart;
-   /* Write the state of the mae mode */
-   Common->PaeModeEnabled = Ke386GetCr4() & X86_CR4_PAE ? 1 : 0;
-
-   DPRINT1("%x %x %x %x\n", Common->Stack, Common->PageDirectory, Common->NtProcessStartup, Common->PaeModeEnabled);
-
-
-   DPRINT("CPU %d got stack at 0x%X\n", CPU, Common->Stack);
-#if 0
-   for (j = 0; j < 16; j++) 
-   {
-      Common->Debug[j] = 0;
-   }
-#endif
-
-   maxlvt = APICGetMaxLVT();
-
-   /* Is this a local APIC or an 82489DX? */
-   StartupCount = (APIC_INTEGRATED(CPUMap[CPU].APICVersion)) ? 2 : 0;
-
-   for (i = 1; i <= StartupCount; i++)
-   {
-      /* It's a local APIC, so send STARTUP IPI */
-      DPRINT("Sending startup signal %d\n", i);
-      /* Clear errors */
-      APICWrite(APIC_ESR, 0);
-      APICRead(APIC_ESR);
-
-      APICSendIPI(CPU, APIC_DM_STARTUP | ((COMMON_AREA + PAGE_SIZE) >> 12)|APIC_ICR0_LEVEL_DEASSERT);
-
-      /* Wait up to 10ms for IPI to be delivered */
-      j = 0;
-      do 
-      {
-         KeStallExecutionProcessor(10);
-
-         /* Check Delivery Status */
-         DeliveryStatus = APICRead(APIC_ICR0) & APIC_ICR0_DS;
-
-         j++;
-      } while ((DeliveryStatus) && (j < 1000));
-
-      KeStallExecutionProcessor(200);
-
-      /*
-       * Due to the Pentium erratum 3AP.
-       */
-      if (maxlvt > 3) 
-      {
-        APICRead(APIC_SIVR);
-        APICWrite(APIC_ESR, 0);
-      }
-
-      AcceptStatus = APICRead(APIC_ESR) & APIC_ESR_MASK;
-
-      if (DeliveryStatus || AcceptStatus) 
-      {
-         break;
-      }
-   }
-
-   if (DeliveryStatus) 
-   {
-      DPRINT("STARTUP IPI for CPU %d was never delivered.\n", CPU);
-   }
-
-   if (AcceptStatus) 
-   {
-      DPRINT("STARTUP IPI for CPU %d was never accepted.\n", CPU);
-   }
-
-   if (!(DeliveryStatus || AcceptStatus)) 
-   {
-
-      /* Wait no more than 5 seconds for processor to boot */
-      DPRINT("Waiting for 5 seconds for CPU %d to boot\n", CPU);
-
-      /* Wait no more than 5 seconds */
-      for (j = 0; j < 50000; j++) 
-      {
-         if (CPUMap[CPU].Flags & CPU_ENABLED)
-        {
-            break;
-        }
-         KeStallExecutionProcessor(100);
-      }
-   }
-
-   if (CPUMap[CPU].Flags & CPU_ENABLED) 
-   {
-      DbgPrint("CPU %d is now running\n", CPU);
-   } 
-   else 
-   {
-      DbgPrint("Initialization of CPU %d failed\n", CPU);
-   }
-
-#if 0
-   DPRINT("Debug bytes are:\n");
-
-   for (j = 0; j < 4; j++) 
-   {
-      DPRINT("0x%08X 0x%08X 0x%08X 0x%08X.\n",
-             Common->Debug[j*4+0],
-             Common->Debug[j*4+1],
-             Common->Debug[j*4+2],
-             Common->Debug[j*4+3]);
-   }
-#endif
+   HaliStartApplicationProcessor(CPU, ProcessorStack);
 
    return TRUE;
 }
-
-
-ULONG MPChecksum(PUCHAR Base,
-                 ULONG Size)
-/*
- *     Checksum an MP configuration block
- */
-{
-   ULONG Sum = 0;
-
-   while (Size--)
-      Sum += *Base++;
-
-   return((UCHAR)Sum);
-}
-
-
-PCHAR HaliMPFamily(ULONG Family,
-                  ULONG Model)
-{
-   static CHAR str[64];
-   static PCHAR CPUs[] =
-   {
-      "80486DX", "80486DX",
-      "80486SX", "80486DX/2 or 80487",
-      "80486SL", "Intel5X2(tm)",
-      "Unknown", "Unknown",
-      "80486DX/4"
-   };
-   if (Family == 0x6)
-      return ("Pentium(tm) Pro");
-   if (Family == 0x5)
-      return ("Pentium(tm)");
-   if (Family == 0x0F && Model == 0x0F)
-      return("Special controller");
-   if (Family == 0x0F && Model == 0x00)
-      return("Pentium 4(tm)");
-   if (Family == 0x04 && Model < 9)
-      return CPUs[Model];
-   sprintf(str, "Unknown CPU with family ID %ld and model ID %ld", Family, Model);
-   return str;
-}
-
-static VOID HaliMPProcessorInfo(PMP_CONFIGURATION_PROCESSOR m)
-{
-  ULONG ver;
-
-  if (!(m->CpuFlags & CPU_FLAG_ENABLED))
-    return;
-
-  DPRINT("Processor #%d %s APIC version %d\n",
-         m->ApicId,
-         HaliMPFamily((m->FeatureFlags & CPU_FAMILY_MASK) >> 8,
-                      (m->FeatureFlags & CPU_MODEL_MASK) >> 4),
-         m->ApicVersion);
-
-  if (m->FeatureFlags & (1 << 0))
-    DPRINT("    Floating point unit present.\n");
-  if (m->FeatureFlags & (1 << 7))
-    DPRINT("    Machine Exception supported.\n");
-  if (m->FeatureFlags & (1 << 8))
-    DPRINT("    64 bit compare & exchange supported.\n");
-  if (m->FeatureFlags & (1 << 9))
-    DPRINT("    Internal APIC present.\n");
-  if (m->FeatureFlags & (1 << 11))
-    DPRINT("    SEP present.\n");
-  if (m->FeatureFlags & (1 << 12))
-    DPRINT("    MTRR present.\n");
-  if (m->FeatureFlags & (1 << 13))
-    DPRINT("    PGE  present.\n");
-  if (m->FeatureFlags & (1 << 14))
-    DPRINT("    MCA  present.\n");
-  if (m->FeatureFlags & (1 << 15))
-    DPRINT("    CMOV  present.\n");
-  if (m->FeatureFlags & (1 << 16))
-    DPRINT("    PAT  present.\n");
-  if (m->FeatureFlags & (1 << 17))
-    DPRINT("    PSE  present.\n");
-  if (m->FeatureFlags & (1 << 18))
-    DPRINT("    PSN  present.\n");
-  if (m->FeatureFlags & (1 << 19))
-    DPRINT("    Cache Line Flush Instruction present.\n");
-  /* 20 Reserved */
-  if (m->FeatureFlags & (1 << 21))
-    DPRINT("    Debug Trace and EMON Store present.\n");
-  if (m->FeatureFlags & (1 << 22))
-    DPRINT("    ACPI Thermal Throttle Registers present.\n");
-  if (m->FeatureFlags & (1 << 23))
-    DPRINT("    MMX  present.\n");
-  if (m->FeatureFlags & (1 << 24))
-    DPRINT("    FXSR  present.\n");
-  if (m->FeatureFlags & (1 << 25))
-    DPRINT("    XMM  present.\n");
-  if (m->FeatureFlags & (1 << 26))
-    DPRINT("    Willamette New Instructions present.\n");
-  if (m->FeatureFlags & (1 << 27))
-    DPRINT("    Self Snoop present.\n");
-  /* 28 Reserved */
-  if (m->FeatureFlags & (1 << 29))
-    DPRINT("    Thermal Monitor present.\n");
-  /* 30, 31 Reserved */
-
-  CPUMap[CPUCount].APICId = m->ApicId;
-
-  CPUMap[CPUCount].Flags = CPU_USABLE;
-
-  if (m->CpuFlags & CPU_FLAG_BSP) 
-  {
-    DPRINT("    Bootup CPU\n");
-    CPUMap[CPUCount].Flags |= CPU_BSP;
-    BootCPU = m->ApicId;
-  }
-
-  if (m->ApicId > MAX_CPU) 
-  {
-    DPRINT("Processor #%d INVALID. (Max ID: %d).\n", m->ApicId, MAX_CPU);
-    return;
-  }
-  ver = m->ApicVersion;
-
-  /*
-  * Validate version
-  */
-  if (ver == 0x0) 
-  {
-    DPRINT("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->ApicId);
-    ver = 0x10;
-  }
-  CPUMap[CPUCount].APICVersion = ver;
-  
-  CPUCount++;
-}
-
-static VOID HaliMPBusInfo(PMP_CONFIGURATION_BUS m)
-{
-  static ULONG CurrentPCIBusId = 0;
-  CHAR str[7];
-
-  memcpy(str, m->BusType, 6);
-  str[6] = 0;
-  DPRINT("Bus #%d is %s\n", m->BusId, str);
-
-  if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) 
-  {
-     BUSMap[m->BusId] = MP_BUS_ISA;
-  } 
-  else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) 
-  {
-     BUSMap[m->BusId] = MP_BUS_EISA;
-  } 
-  else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) 
-  {
-     BUSMap[m->BusId] = MP_BUS_PCI;
-     PCIBUSMap[m->BusId] = CurrentPCIBusId;
-     CurrentPCIBusId++;
-  } 
-  else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) 
-  {
-     BUSMap[m->BusId] = MP_BUS_MCA;
-  } 
-  else 
-  {
-     DPRINT("Unknown bustype %s - ignoring\n", str);
-  }
-}
-
-static VOID HaliMPIOApicInfo(PMP_CONFIGURATION_IOAPIC m)
-{
-  if (!(m->ApicFlags & CPU_FLAG_ENABLED))
-    return;
-
-  DPRINT("I/O APIC #%d Version %d at 0x%lX.\n",
-         m->ApicId, m->ApicVersion, m->ApicAddress);
-  if (IOAPICCount > MAX_IOAPIC) 
-  {
-    DPRINT("Max # of I/O APICs (%d) exceeded (found %d).\n",
-           MAX_IOAPIC, IOAPICCount);
-    DPRINT1("Recompile with bigger MAX_IOAPIC!.\n");
-    KEBUGCHECK(0);
-  }
-  IOAPICMap[IOAPICCount].ApicId = m->ApicId;
-  IOAPICMap[IOAPICCount].ApicVersion = m->ApicVersion;
-  IOAPICMap[IOAPICCount].ApicAddress = m->ApicAddress;
-  IOAPICCount++;
-}
-
-static VOID HaliMPIntSrcInfo(PMP_CONFIGURATION_INTSRC m)
-{
-  DPRINT("Int: type %d, pol %d, trig %d, bus %d,"
-         " IRQ %02x, APIC ID %x, APIC INT %02x\n",
-         m->IrqType, m->IrqFlag & 3,
-         (m->IrqFlag >> 2) & 3, m->SrcBusId,
-         m->SrcBusIrq, m->DstApicId, m->DstApicInt);
-  if (IRQCount > MAX_IRQ_SOURCE) 
-  {
-    DPRINT1("Max # of irq sources exceeded!!\n");
-    KEBUGCHECK(0);
-  }
-
-  IRQMap[IRQCount] = *m;
-  IRQCount++;
-}
-
-static VOID HaliMPIntLocalInfo(PMP_CONFIGURATION_INTLOCAL m)
-{
-  DPRINT("Lint: type %d, pol %d, trig %d, bus %d,"
-         " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
-         m->IrqType, m->IrqFlag & 3,
-         (m->IrqFlag >> 2) & 3, m->SrcBusId,
-          m->SrcBusIrq, m->DstApicId, m->DstApicLInt);
-  /*
-   * Well it seems all SMP boards in existence
-   * use ExtINT/LVT1 == LINT0 and
-   * NMI/LVT2 == LINT1 - the following check
-   * will show us if this assumptions is false.
-   * Until then we do not have to add baggage.
-   */
-  if ((m->IrqType == INT_EXTINT) && (m->DstApicLInt != 0)) 
-  {
-    DPRINT1("Invalid MP table!\n");
-    KEBUGCHECK(0);
-  }
-  if ((m->IrqType == INT_NMI) && (m->DstApicLInt != 1)) 
-  {
-    DPRINT1("Invalid MP table!\n");
-    KEBUGCHECK(0);
-  }
-}
-
-VOID
-HaliReadMPConfigTable(PMP_CONFIGURATION_TABLE Table)
-/*
-   PARAMETERS:
-      Table = Pointer to MP configuration table
- */
-{
-   PUCHAR Entry;
-   ULONG Count;
-
-   if (Table->Signature != MPC_SIGNATURE)
-     {
-       PUCHAR pc = (PUCHAR)&Table->Signature;
-       
-       DbgPrint("Bad MP configuration block signature: %c%c%c%c\n", 
-               pc[0], pc[1], pc[2], pc[3]);
-       KEBUGCHECK(0);
-       return;
-     }
-
-   if (MPChecksum((PUCHAR)Table, Table->Length))
-     {
-       DbgPrint("Bad MP configuration block checksum\n");
-       KEBUGCHECK(0);
-       return;
-     }
-
-   if (Table->Specification < 0x04)
-     {
-       DbgPrint("Bad MP configuration table version (%d)\n",
-               Table->Specification);
-       KEBUGCHECK(0);
-       return;
-     }
-
-   if (Table->LocalAPICAddress != APIC_DEFAULT_BASE)
-     {
-       DbgPrint("APIC base address is at 0x%X. " \
-               "I cannot handle non-standard adresses\n", Table->LocalAPICAddress);
-       KEBUGCHECK(0);
-     }
-
-   Entry = (PUCHAR)((PVOID)Table + sizeof(MP_CONFIGURATION_TABLE));
-   Count = 0;
-   while (Count < (Table->Length - sizeof(MP_CONFIGURATION_TABLE)))
-   {
-     /* Switch on type */
-     switch (*Entry)
-       {
-       case MPCTE_PROCESSOR:
-         {
-          HaliMPProcessorInfo((PMP_CONFIGURATION_PROCESSOR)Entry);
-          Entry += sizeof(MP_CONFIGURATION_PROCESSOR);
-          Count += sizeof(MP_CONFIGURATION_PROCESSOR);
-          break;
-        }
-       case MPCTE_BUS:
-        {
-          HaliMPBusInfo((PMP_CONFIGURATION_BUS)Entry);
-          Entry += sizeof(MP_CONFIGURATION_BUS);
-          Count += sizeof(MP_CONFIGURATION_BUS);
-          break;
-        }
-       case MPCTE_IOAPIC:
-        {
-          HaliMPIOApicInfo((PMP_CONFIGURATION_IOAPIC)Entry);
-          Entry += sizeof(MP_CONFIGURATION_IOAPIC);
-          Count += sizeof(MP_CONFIGURATION_IOAPIC);
-          break;
-        }
-       case MPCTE_INTSRC:
-        {
-          HaliMPIntSrcInfo((PMP_CONFIGURATION_INTSRC)Entry);
-          Entry += sizeof(MP_CONFIGURATION_INTSRC);
-          Count += sizeof(MP_CONFIGURATION_INTSRC);
-          break;
-        }
-       case MPCTE_LINTSRC:
-        {
-          HaliMPIntLocalInfo((PMP_CONFIGURATION_INTLOCAL)Entry);
-          Entry += sizeof(MP_CONFIGURATION_INTLOCAL);
-          Count += sizeof(MP_CONFIGURATION_INTLOCAL);
-          break;
-        }
-       default:
-        DbgPrint("Unknown entry in MPC table\n");
-        KEBUGCHECK(0);
-       }
-   }
-}
-
-static VOID HaliConstructDefaultIOIrqMPTable(ULONG Type)
-{
-       MP_CONFIGURATION_INTSRC intsrc;
-       ULONG i;
-
-       intsrc.Type = MPCTE_INTSRC;
-       intsrc.IrqFlag = 0;                     /* conforming */
-       intsrc.SrcBusId = 0;
-       intsrc.DstApicId = IOAPICMap[0].ApicId;
-
-       intsrc.IrqType = INT_VECTORED;
-       for (i = 0; i < 16; i++) {
-               switch (Type) {
-               case 2:
-                       if (i == 0 || i == 13)
-                               continue;       /* IRQ0 & IRQ13 not connected */
-                       /* Fall through */
-               default:
-                       if (i == 2)
-                               continue;       /* IRQ2 is never connected */
-               }
-
-               intsrc.SrcBusIrq = i;
-               intsrc.DstApicInt = i ? i : 2; /* IRQ0 to INTIN2 */
-               HaliMPIntSrcInfo(&intsrc);
-       }
-
-       intsrc.IrqType = INT_EXTINT;
-       intsrc.SrcBusIrq = 0;
-       intsrc.DstApicInt = 0; /* 8259A to INTIN0 */
-       HaliMPIntSrcInfo(&intsrc);
-}
-
-static VOID HaliConstructDefaultISAMPTable(ULONG Type)
-{
-  MP_CONFIGURATION_PROCESSOR processor;
-  MP_CONFIGURATION_BUS bus;
-  MP_CONFIGURATION_IOAPIC ioapic;
-  MP_CONFIGURATION_INTLOCAL lintsrc;
-  ULONG linttypes[2] = { INT_EXTINT, INT_NMI };
-  ULONG i;
-
-  /*
-   * 2 CPUs, numbered 0 & 1.
-   */
-  processor.Type = MPCTE_PROCESSOR;
-  /* Either an integrated APIC or a discrete 82489DX. */
-  processor.ApicVersion = Type > 4 ? 0x10 : 0x01;
-  processor.CpuFlags = CPU_FLAG_ENABLED | CPU_FLAG_BSP;
-  /* FIXME: Get this from the bootstrap processor */
-  processor.CpuSignature = 0;
-  processor.FeatureFlags = 0;
-  processor.Reserved[0] = 0;
-  processor.Reserved[1] = 0;
-  for (i = 0; i < 2; i++) 
-  {
-    processor.ApicId = i;
-    HaliMPProcessorInfo(&processor);
-    processor.CpuFlags &= ~CPU_FLAG_BSP;
-  }
-
-  bus.Type = MPCTE_BUS;
-  bus.BusId = 0;
-  switch (Type) 
-  {
-    default:
-    DPRINT("Unknown standard configuration %d\n", Type);
-      /* Fall through */
-    case 1:
-    case 5:
-      memcpy(bus.BusType, "ISA   ", 6);
-      break;
-    case 2:
-    case 6:
-    case 3:
-      memcpy(bus.BusType, "EISA  ", 6);
-      break;
-    case 4:
-    case 7:
-      memcpy(bus.BusType, "MCA   ", 6);
-  }
-  HaliMPBusInfo(&bus);
-  if (Type > 4) 
-  {
-    bus.Type = MPCTE_BUS;
-    bus.BusId = 1;
-    memcpy(bus.BusType, "PCI   ", 6);
-    HaliMPBusInfo(&bus);
-  }
-
-  ioapic.Type = MPCTE_IOAPIC;
-  ioapic.ApicId = 2;
-  ioapic.ApicVersion = Type > 4 ? 0x10 : 0x01;
-  ioapic.ApicFlags = MP_IOAPIC_USABLE;
-  ioapic.ApicAddress = IOAPIC_DEFAULT_BASE;
-  HaliMPIOApicInfo(&ioapic);
-
-  /*
-   * We set up most of the low 16 IO-APIC pins according to MPS rules.
-   */
-  HaliConstructDefaultIOIrqMPTable(Type);
-
-  lintsrc.Type = MPCTE_LINTSRC;
-  lintsrc.IrqType = 0;
-  lintsrc.IrqFlag = 0;  /* conforming */
-  lintsrc.SrcBusId = 0;
-  lintsrc.SrcBusIrq = 0;
-  lintsrc.DstApicId = MP_APIC_ALL;
-  for (i = 0; i < 2; i++) 
-  {
-    lintsrc.IrqType = linttypes[i];
-    lintsrc.DstApicLInt = i;
-    HaliMPIntLocalInfo(&lintsrc);
-  }
-}
-
-
-BOOLEAN
-HaliScanForMPConfigTable(ULONG Base,
-                        ULONG Size)
-/*
-   PARAMETERS:
-      Base = Base address of region
-      Size = Length of region to check
-   RETURNS:
-      TRUE if a valid MP configuration table was found
- */
-{
-   PULONG bp = (PULONG)Base;
-   MP_FLOATING_POINTER* mpf;
-
-   while (Size > 0)
-   {
-      if (*bp == MPF_SIGNATURE)
-      {
-       DbgPrint("Found MPF signature at %x, checksum %x\n", bp,
-                MPChecksum((PUCHAR)bp, 16));
-         if (MPChecksum((PUCHAR)bp, 16) == 0)
-         {
-            mpf = (MP_FLOATING_POINTER*)bp;
-
-            DbgPrint("Intel MultiProcessor Specification v1.%d compliant system.\n",
-              mpf->Specification);
-
-            if (mpf->Feature2 & FEATURE2_IMCRP) {
-               APICMode = amPIC;
-               DPRINT("Running in IMCR and PIC compatibility mode.\n");
-            } else {
-               APICMode = amVWIRE;
-               DPRINT("Running in Virtual Wire compatibility mode.\n");
-                                   }
-
-            switch (mpf->Feature1)
-            {
-               case 0:
-                  /* Non standard configuration */
-                  break;
-               case 1:
-                  DPRINT("ISA\n");
-                  break;
-               case 2:
-                  DPRINT("EISA with no IRQ8 chaining\n");
-                  break;
-               case 3:
-                  DPRINT("EISA\n");
-                  break;
-               case 4:
-                  DPRINT("MCA\n");
-                  break;
-               case 5:
-                  DPRINT("ISA and PCI\n");
-                  break;
-               case 6:
-                  DPRINT("EISA and PCI\n");
-                  break;
-               case 7:
-                  DPRINT("MCA and PCI\n");
-                  break;
-               default:
-                  DbgPrint("Unknown standard configuration %d\n", mpf->Feature1);
-                  return FALSE;
-            }
-
-            CPUCount = 0;
-            IOAPICCount = 0;
-            IRQCount = 0;
-
-            if ((mpf->Feature1 == 0) && (mpf->Address)) {
-              HaliReadMPConfigTable((PMP_CONFIGURATION_TABLE)mpf->Address);
-            } else {
-              HaliConstructDefaultISAMPTable(mpf->Feature1);
-            }
-
-            return TRUE;
-         }
-      }
-      bp += 4;
-      Size -= 16;
-   }
-   return FALSE;
-}
-
-VOID
-HalpInitMPS(VOID)
-{
-   USHORT EBDA;
-   static BOOLEAN MPSInitialized = FALSE;
-
-
-   /* Only initialize MP system once. Once called the first time,
-      each subsequent call is part of the initialization sequence
-                       for an application processor. */
-
-   DPRINT("HalpInitMPS()\n");
-
-
-   if (MPSInitialized) 
-   {
-      KEBUGCHECK(0);
-   }
-
-   MPSInitialized = TRUE;
-
-   /*
-     Scan the system memory for an MP configuration table
-       1) Scan the first KB of system base memory
-       2) Scan the last KB of system base memory
-       3) Scan the BIOS ROM address space between 0F0000h and 0FFFFFh
-       4) Scan the Extended BIOS Data Area
-   */
-
-   if (!HaliScanForMPConfigTable(0x0, 0x400)) 
-   {
-      if (!HaliScanForMPConfigTable(0x9FC00, 0x400)) 
-      {
-         if (!HaliScanForMPConfigTable(0xF0000, 0x10000)) 
-         {
-            EBDA = *((PUSHORT)0x040E);
-            EBDA <<= 4;
-            if (!HaliScanForMPConfigTable((ULONG)EBDA, 0x1000)) 
-           {
-               DbgPrint("No multiprocessor compliant system found.\n");
-               KEBUGCHECK(0);
-            }
-         }
-      }
-   }
-
-   /* Setup IRQ to vector translation map */
-   memset(&IRQVectorMap, 0, sizeof(IRQVectorMap));
-
-   /* Setup interrupt handlers */
-   SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG)MpsTimerInterrupt);
-   SetInterruptGate(ERROR_VECTOR, (ULONG)MpsErrorInterrupt);
-   SetInterruptGate(SPURIOUS_VECTOR, (ULONG)MpsSpuriousInterrupt);
-   SetInterruptGate(IPI_VECTOR, (ULONG)MpsIpiInterrupt);
-
-}
-
-VOID
-HaliReconfigurePciInterrupts(VOID)
-{
-   ULONG i;
-
-   for (i = 0; i < IRQCount; i++)
-   {
-      if (BUSMap[IRQMap[i].SrcBusId] == MP_BUS_PCI)
-      {
-         DPRINT("%02x: IrqType %02x, IrqFlag %02x, SrcBusId %02x, SrcBusIrq %02x, DstApicId %02x, DstApicInt %02x\n",
-               i, IRQMap[i].IrqType, IRQMap[i].IrqFlag, IRQMap[i].SrcBusId, 
-               IRQMap[i].SrcBusIrq, IRQMap[i].DstApicId, IRQMap[i].DstApicInt);
-
-        if(1 != HalSetBusDataByOffset(PCIConfiguration, IRQMap[i].SrcBusId, (IRQMap[i].SrcBusIrq >> 2) & 0x1f, &IRQMap[i].DstApicInt, 0x3c /*PCI_INTERRUPT_LINE*/, 1))
-        {
-           CHECKPOINT;
-        }
-      }
-   }
-
-}
-
 /* EOF */
diff --git a/reactos/include/WinDNS.h b/reactos/include/WinDNS.h
deleted file mode 100644 (file)
index 88ea162..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS system libraries
- * FILE:        include/WinDNS.h
- * PURPOSE:     Structures and definitions needed for DNSAPI compatibility.
- * PROGRAMER:   Art Yerkes
- * UPDATE HISTORY:
- *              12/15/03 -- Created
- */
-
-#ifndef WINDNS_H
-#define WINDNS_H
-
-/* The WinDNS Header */
-#ifdef __USE_W32API
-#include_next <windns.h>
-#else
-
-/* Constants provided by DNSAPI */
-#define DNS_CONFIG_FLAG_ALLOC TRUE
-
-#define BIT(n) (1<<(n))
-#define DNS_QUERY_STANDARD 0
-#define DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE BIT(0)
-#define DNS_QUERY_USE_TCP_ONLY BIT(1)
-#define DNS_QUERY_NO_RECURSION BIT(2)
-#define DNS_QUERY_BYPASS_CACHE BIT(3)
-#define DNS_QUERY_NO_WIRE_QUERY BIT(4)
-#define DNS_QUERY_NO_LOCAL_NAME BIT(5)
-#define DNS_QUERY_NO_HOSTS_FILE BIT(6)
-#define DNS_QUERY_NO_NETBT BIT(7)
-#define DNS_QUERY_WIRE_ONLY BIT(8)
-#define DNS_QUERY_RETURN_MESSAGE BIT(9)
-#define DNS_QUERY_TREAT_AS_FQDN BIT(12)
-#define DNS_QUERY_DONT_RESET_TTL_VALUES BIT(23)
-#define DNS_QUERY_RESERVED (0xff << 24)
-#define DNS_QUERY_CACHE_ONLY BIT(4)
-
-#define DNS_TYPE_ZERO 0
-#define DNS_TYPE_A 1
-#define DNS_TYPE_NS 2
-#define DNS_TYPE_MD 3
-#define DNS_TYPE_MF 4
-#define DNS_TYPE_CNAME 5
-#define DNS_TYPE_SOA 6
-#define DNS_TYPE_MB 7
-#define DNS_TYPE_MG 8
-#define DNS_TYPE_MR 9
-#define DNS_TYPE_NULL 10
-#define DNS_TYPE_WKS 11
-#define DNS_TYPE_PTR 12
-#define DNS_TYPE_HINFO 13
-#define DNS_TYPE_MINFO 14
-#define DNS_TYPE_MX 15
-#define DNS_TYPE_TXT 16
-#define DNS_TYPE_RP 17
-#define DNS_TYPE_AFSDB 18
-#define DNS_TYPE_X25 19
-#define DNS_TYPE_ISDN 20
-#define DNS_TYPE_RT 21
-#define DNS_TYPE_NSAP 22
-#define DNS_TYPE_NSAPPTR 23
-#define DNS_TYPE_SIG 24
-#define DNS_TYPE_KEY 25
-#define DNS_TYPE_PX 26
-#define DNS_TYPE_GPOS 27
-#define DNS_TYPE_AAAA 28
-#define DNS_TYPE_LOC 29
-#define DNS_TYPE_NXT 30
-#define DNS_TYPE_EID 31 /* I've never heard of nimrod before. */
-#define DNS_TYPE_NIMLOC 32 /* But it does exist. */
-#define DNS_TYPE_SRV 33
-#define DNS_TYPE_ATMA 34
-#define DNS_TYPE_NAPTR 35
-#define DNS_TYPE_KX 36
-#define DNS_TYPE_CERT 37
-#define DNS_TYPE_A6 38
-#define DNS_TYPE_DNAME 39
-#define DNS_TYPE_SINK 40
-#define DNS_TYPE_OPT 41
-
-#define DNS_TYPE_UINFO 100
-#define DNS_TYPE_UID 101
-#define DNS_TYPE_GID 102
-#define DNS_TYPE_UNSPEC 103
-
-#define DNS_TYPE_ADDRS 248
-#define DNS_TYPE_TKEY 249
-#define DNS_TYPE_TSIG 250
-#define DNS_TYPE_IXFR 251
-#define DNS_TYPE_AXFR 252
-#define DNS_TYPE_MAILB 253
-#define DNS_TYPE_MAILA 254
-#define DNS_TYPE_ANY 255
-
-#define DNS_SWAPX(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
-
-#define DNS_RTYPE_ZERO DNS_SWAPX(DNS_TYPE_ZERO)
-#define DNS_RTYPE_A DNS_SWAPX(DNS_TYPE_A)
-#define DNS_RTYPE_NS DNS_SWAPX(DNS_TYPE_NS)
-#define DNS_RTYPE_MD DNS_SWAPX(DNS_TYPE_MD)
-#define DNS_RTYPE_MF DNS_SWAPX(DNS_TYPE_MF)
-#define DNS_RTYPE_CNAME DNS_SWAPX(DNS_TYPE_CNAME)
-#define DNS_RTYPE_SOA DNS_SWAPX(DNS_TYPE_SOA)
-#define DNS_RTYPE_MB DNS_SWAPX(DNS_TYPE_MB)
-#define DNS_RTYPE_MG DNS_SWAPX(DNS_TYPE_MG)
-#define DNS_RTYPE_MR DNS_SWAPX(DNS_TYPE_MR)
-#define DNS_RTYPE_NULL DNS_SWAPX(DNS_TYPE_NULL)
-#define DNS_RTYPE_WKS DNS_SWAPX(DNS_TYPE_WKS)
-#define DNS_RTYPE_PTR DNS_SWAPX(DNS_TYPE_PTR)
-#define DNS_RTYPE_HINFO DNS_SWAPX(DNS_TYPE_HINFO)
-#define DNS_RTYPE_MINFO DNS_SWAPX(DNS_TYPE_MINFO)
-#define DNS_RTYPE_MX DNS_SWAPX(DNS_TYPE_MX)
-#define DNS_RTYPE_TEXT DNS_SWAPX(DNS_TYPE_TEXT)
-#define DNS_RTYPE_RP DNS_SWAPX(DNS_TYPE_RP)
-#define DNS_RTYPE_AFSDB DNS_SWAPX(DNS_TYPE_AFSDB)
-#define DNS_RTYPE_X25 DNS_SWAPX(DNS_TYPE_X25)
-#define DNS_RTYPE_ISDN DNS_SWAPX(DNS_TYPE_ISDN)
-#define DNS_RTYPE_RT DNS_SWAPX(DNS_TYPE_RT)
-#define DNS_RTYPE_NSAP DNS_SWAPX(DNS_TYPE_NSAP)
-#define DNS_RTYPE_NSAPPTR DNS_SWAPX(DNS_TYPE_NSAPPTR)
-#define DNS_RTYPE_SIG DNS_SWAPX(DNS_TYPE_SIG)
-#define DNS_RTYPE_KEY DNS_SWAPX(DNS_TYPE_KEY)
-#define DNS_RTYPE_PX DNS_SWAPX(DNS_TYPE_PX)
-#define DNS_RTYPE_GPOS DNS_SWAPX(DNS_TYPE_GPOS)
-#define DNS_RTYPE_AAAA DNS_SWAPX(DNS_TYPE_AAAA)
-#define DNS_RTYPE_LOC DNS_SWAPX(DNS_TYPE_LOC)
-#define DNS_RTYPE_NXT DNS_SWAPX(DNS_TYPE_NXT)
-#define DNS_RTYPE_EID DNS_SWAPX(DNS_TYPE_EID)
-#define DNS_RTYPE_NIMLOC DNS_SWAPX(DNS_TYPE_NIMLOC)
-#define DNS_RTYPE_SRV DNS_SWAPX(DNS_TYPE_SRV)
-#define DNS_RTYPE_ATMA DNS_SWAPX(DNS_TYPE_ATMA)
-#define DNS_RTYPE_NAPTR DNS_SWAPX(DNS_TYPE_NAPTR)
-#define DNS_RTYPE_KX DNS_SWAPX(DNS_TYPE_KX)
-#define DNS_RTYPE_CERT DNS_SWAPX(DNS_TYPE_CERT)
-#define DNS_RTYPE_A6 DNS_SWAPX(DNS_TYPE_A6)
-#define DNS_RTYPE_DNAME DNS_SWAPX(DNS_TYPE_DNAME)
-#define DNS_RTYPE_SINK DNS_SWAPX(DNS_TYPE_SINK)
-#define DNS_RTYPE_OPT DNS_SWAPX(DNS_TYPE_OPT)
-#define DNS_RTYPE_UINFO DNS_SWAPX(DNS_TYPE_UINFO)
-#define DNS_RTYPE_UID DNS_SWAPX(DNS_TYPE_UID)
-#define DNS_RTYPE_GID DNS_SWAPX(DNS_TYPE_GID)
-#define DNS_RTYPE_UNSPEC DNS_SWAPX(DNS_TYPE_UNSPEC)
-#define DNS_RTYPE_ADDRS DNS_SWAPX(DNS_TYPE_ADDRS)
-#define DNS_RTYPE_TKEY DNS_SWAPX(DNS_TYPE_TKEY)
-#define DNS_RTYPE_TSIG DNS_SWAPX(DNS_TYPE_TSIG)
-#define DNS_RTYPE_IXFR DNS_SWAPX(DNS_TYPE_IXFR)
-#define DNS_RTYPE_AXFR DNS_SWAPX(DNS_TYPE_AXFR)
-#define DNS_RTYPE_MAILB DNS_SWAPX(DNS_TYPE_MAILB)
-#define DNS_RTYPE_MAILA DNS_SWAPX(DNS_TYPE_MAILA)
-#define DNS_RTYPE_ANY DNS_SWAPX(DNS_TYPE_ANY)
-
-/* Simple types */
-typedef LONG DNS_STATUS;
-typedef DNS_STATUS *PDNS_STATUS;
-typedef DWORD IP4_ADDRESS;
-typedef IP4_ADDRESS *PIP4_ADDRESS;
-typedef struct {
-  DWORD IP6Dword[4];
-} IP6_ADDRESS, *PIP6_ADDRESS;
-
-typedef enum {
-  DnsFreeFlat,
-  DnsFreeRecordList,
-  DnsFreeParsedMessageFields
-} DNS_FREE_TYPE;
-
-typedef enum {
-  DnsNameDomain,
-  DnsNameDomainLabel,
-  DnsNameHostnameFull,
-  DnsNameHostnameLabel,
-  DnsNameWildcard,
-  DnsNameSrvRecord
-} DNS_NAME_FORMAT;
-
-/* The below is for repetitive names that distinguish character coding */
-#define DNS_PASTE(x,y) x ## y
-#define DNSCT_TRIPLET(x) DNS_PASTE(x,_W), DNS_PASTE(x,_A), DNS_PASTE(x,_UTF8)
-
-typedef enum {
-  DNSCT_TRIPLET(DnsConfigPrimaryDomainName),
-  DNSCT_TRIPLET(DnsConfigAdapterDomainName),
-  DnsConfigDnsServerList,
-  DnsConfigSearchList,
-  DnsConfigAdapterInfo,
-  DnsConfigPrimaryHostNameRegistrationEnabled,
-  DnsConfigAdapterHostNameRegistrationEnabled,
-  DnsConfigAddressRegistrationMaxCount,
-  DNSCT_TRIPLET(DnsConfigHostName),
-  DNSCT_TRIPLET(DnsConfigFullHostName)
-} DNS_CONFIG_TYPE;
-
-/* Aggregates provided by DNSAPI */
-
-typedef struct {
-  DWORD Section : 2;
-  DWORD Delete : 1;
-  DWORD CharSet : 2;
-  DWORD Unused : 3;
-  DWORD Reserved : 24;
-} DNS_RECORD_FLAGS;
-
-typedef struct _IP4_ARRAY {
-  DWORD AddrCount;
-  IP4_ADDRESS AddrArray[1]; /* Avoid zero-length array warning */
-} IP4_ARRAY, *PIP4_ARRAY;
-
-typedef struct _DNS_HEADER {
-  WORD Xid;
-  BYTE RecursionDesired;
-  BYTE Truncation;
-  BYTE Authoritative;
-  BYTE Opcode;
-  BYTE IsResponse;
-  BYTE ResponseCode;
-  BYTE Reserved;
-  BYTE RecursionAvailable;
-  WORD QuestionCount;
-  WORD NameServerCount;
-  WORD AdditionalCount;
-} DNS_HEADER, *PDNS_HEADER;
-
-typedef struct _DNS_MESSAGE_BUFFER {
-  DNS_HEADER MessageHead;
-  CHAR MessageBody[1];
-} DNS_MESSAGE_BUFFER, *PDNS_MESSAGE_BUFFER;
-
-/* Some DNSAPI structs are sensitive to character coding.  This will allow
- * us to define them once. 
- *
- * the XNAME(n) macro turns the name into either nA or nW
- * the PSTR type expands to either LPWSTR or LPSTR.
- */
-
-/* A record, indicates an IPv4 address. */
-typedef struct {
-  IP4_ADDRESS IpAddress;
-} DNS_A_DATA, *PDNS_A_DATA;
-
-typedef struct {
-  DWORD dwByteCount;
-  BYTE Data[1];
-} DNS_NULL_DATA, *PDNS_NULL_DATA;
-
-typedef struct {
-  IP4_ADDRESS IpAddress;
-  UCHAR chProtocol;
-  BYTE BitMask[1];
-} DNS_WKS_DATA, *PDNS_WKS_DATA;
-
-typedef struct {
-  IP6_ADDRESS Ip6Address;
-} DNS_AAAA_DATA, *PDNS_AAAA_DATA;
-
-typedef struct {
-  WORD wFlags;
-  BYTE chProtocol;
-  BYTE chAlgorithm;
-  BYTE Key[1];
-} DNS_KEY_DATA, *PDNS_KEY_DATA;
-
-typedef struct {
-  WORD wVersion;
-  WORD wSize;
-  WORD wHorPrec;
-  WORD wVerPrec;
-  DWORD dwLatitude;
-  DWORD dwLongitude;
-  DWORD dwAltitude;
-} DNS_LOC_DATA, *PDNS_LOC_DATA;
-
-/* Here's the ugly bit, we import twice; once for wchar and once for char. */
-#define XNAME(a) a ## A
-#define PSTR LPSTR
-#define _WINDNS_STRUCT_DEFINITIONS
-#include "WinDNS.h"
-#undef XNAME
-#undef PSTR
-#define XNAME(a) a ## W
-#define PSTR LPWSTR
-#include "WinDNS.h"
-#undef XNAME
-#undef PSTR
-#undef _WINDNS_STRUCT_DEFINITIONS
-
-#ifndef _DISABLE_TIDENTS
-#ifdef _UNICODE
-#define DECLARE_STRUCT(x) typedef DNS_PASTE(x,W) x , *DNS_PASTE(P,x)
-#define DECLARE_FUNC(x) DNS_PASTE(x,_W)
-#else /* _UNICODE */
-#define DECLARE_STRUCT(x) typedef DNS_PASTE(x,A) x , *DNS_PASTE(P,x)
-#define DECLARE_FUNC(x) DNS_PASTE(x,_A)
-#endif /* _UNICODE */
-
-/* Now, all the declarations go off. */
-
-DECLARE_STRUCT(DNS_PTR_DATA);
-DECLARE_STRUCT(DNS_SOA_DATA);
-DECLARE_STRUCT(DNS_MINFO_DATA);
-DECLARE_STRUCT(DNS_MX_DATA);
-DECLARE_STRUCT(DNS_TXT_DATA);
-DECLARE_STRUCT(DNS_SIG_DATA);
-DECLARE_STRUCT(DNS_NXT_DATA);
-DECLARE_STRUCT(DNS_SRV_DATA);
-DECLARE_STRUCT(DNS_RECORD);
-
-#define DnsAcquireContextHandle DECLARE_FUNC(DnsAcquireContextHandle)
-#define DnsValidateName DECLARE_FUNC(DnsValidateName)
-#define DnsQuery DECLARE_FUNC(DnsQuery)
-
-#endif /* _DISABLE_TIDENTS */
-
-/* Prototypes */
-
-void WINAPI DnsReleaseContextHandle( HANDLE ContextHandle );
-
-DNS_STATUS WINAPI DnsAcquireContextHandle_W
-( DWORD CredentialsFlags, 
-  PVOID Credentials, 
-  HANDLE *ContextHandle );
-DNS_STATUS WINAPI DnsAcquireContextHandle_UTF8
-( DWORD CredentialsFlags, 
-  PVOID Credentials, 
-  HANDLE *ContextHandle );
-DNS_STATUS WINAPI DnsAcquireContextHandle_A
-( DWORD CredentialsFlags, 
-  PVOID Credentials, 
-  HANDLE *ContextHandle );
-
-DNS_STATUS WINAPI DnsValidateName_W
-( LPCWSTR Name, DNS_NAME_FORMAT Format );
-DNS_STATUS WINAPI DnsValidateName_UTF8
-( LPCSTR Name, DNS_NAME_FORMAT Format );
-DNS_STATUS WINAPI DnsValidateName_A
-( LPCSTR Name, DNS_NAME_FORMAT Format );
-
-DNS_STATUS WINAPI DnsQuery_W
-( LPCWSTR Name, WORD Type, DWORD Options, PIP4_ARRAY Servers,
-  PDNS_RECORDW *Result, PVOID *Reserved );
-DNS_STATUS WINAPI DnsQuery_UTF8
-( LPCSTR Name, WORD Type, DWORD Options, PIP4_ARRAY Servers,
-  PDNS_RECORDA *Result, PVOID *Reserved );
-DNS_STATUS WINAPI DnsQuery_A
-( LPCSTR Name, WORD Type, DWORD Options, PIP4_ARRAY Servers,
-  PDNS_RECORDA *Result, PVOID *Reserved );
-VOID WINAPI DnsFree( PVOID Data, DNS_FREE_TYPE FreeType );
-VOID WINAPI DnsRecordListFree( PVOID RecordList, 
-                              DNS_FREE_TYPE FreeType );
-
-#endif//WINDNS_H
-
-#ifdef _WINDNS_STRUCT_DEFINITIONS
-
-/* PTR record, indicates an additional lookup for the given name is needed. */
-typedef struct {
-  PSTR pNameHost;
-} XNAME(DNS_PTR_DATA), *XNAME(PDNS_PTR_DATA);
-
-typedef struct {
-  PSTR pNamePrimaryServer;
-  PSTR pNameAdministrator;
-  DWORD dwSerialNo;
-  DWORD dwRefresh;
-  DWORD dwRetry;
-  DWORD dwExpire;
-  DWORD dwDefaultTtl;
-} XNAME(DNS_SOA_DATA), *XNAME(PDNS_SOA_DATA);
-
-/* MINFO record, who to mail about questions or problems. */
-typedef struct {
-  PSTR pNameMailbox;
-  PSTR pNameErrorsMailbox;
-} XNAME(DNS_MINFO_DATA), *XNAME(PNDS_MINFO_DATA);
-
-/* MX record, who processes the mail for this domain? */
-typedef struct {
-  PSTR pNameExchange;
-  WORD wPreference;
-  WORD Pad;
-} XNAME(DNS_MX_DATA), *XNAME(PDNS_MX_DATA);
-
-/* TXT record, miscellaneous information. */
-typedef struct {
-  DWORD dwStringCount;
-  PSTR pStringArray[1];
-} XNAME(DNS_TXT_DATA), *XNAME(PDNS_TXT_DATA);
-
-typedef struct {
-  PSTR pNameSigner;
-  WORD wTypeCovered;
-  BYTE cbAlgorithm;
-  BYTE cbLabelCount;
-  DWORD dwOriginalTtl;
-  DWORD dwExpiration;
-  DWORD dwTimeSigned;
-  WORD wKeyTag;
-  WORD Pad;
-  BYTE Signature[1];
-} XNAME(DNS_SIG_DATA), *XNAME(PDNS_SIG_DATA);
-
-typedef struct {
-  PSTR pNameNext;
-  WORD wNumTypes;
-  WORD wTypes[1];
-} XNAME(DNS_NXT_DATA), *XNAME(PDNS_NXT_DATA);
-
-typedef struct {
-  PSTR pNameTarget;
-  WORD wPriority;
-  WORD wWeight;
-  WORD wPort;
-  WORD Pad;
-} XNAME(DNS_SRV_DATA), *XNAME(PDNS_SRV_DATA);
-
-typedef struct XNAME(_DNS_RECORD_) {
-  struct XNAME(_DNS_RECORD_) *pNext;
-  PSTR pName;
-  WORD wType;
-  WORD wDataLength;
-  
-  union {
-    DWORD DW;
-    DNS_RECORD_FLAGS S;
-  } Flags;
-  
-  DWORD dwTtl;
-  DWORD dwReserved;
-  
-  union {
-    DNS_A_DATA A;
-    XNAME(DNS_SOA_DATA) SOA, Soa;
-    XNAME(DNS_PTR_DATA) PTR, Ptr, NS, Ns, CNAME, Cname, MB, Mb, MD, Md, MF, Mf, MG, Mg, MR, Mr;
-    XNAME(DNS_MINFO_DATA) MINFO, Minfo, RP, Rp;
-    XNAME(DNS_MX_DATA) MX, Mx, AFSDB, Afsdb, RT, Rt;
-    XNAME(DNS_TXT_DATA) HINFO, Hinfo, ISDN, Isdn, TXT, Txt;
-    DNS_NULL_DATA Null;
-    DNS_WKS_DATA WKS, Wks;
-    DNS_AAAA_DATA AAAA;
-    DNS_KEY_DATA KEY, Key;
-    XNAME(DNS_SIG_DATA) SIG, Sig;
-    XNAME(DNS_NXT_DATA) NXT, Nxt;
-    XNAME(DNS_SRV_DATA) SRV, Srv;
-  } Data;
-} XNAME(DNS_RECORD), *XNAME(PDNS_RECORD);
-
-#endif /* __USE_W32API */
-#endif /* _WINDNS_STRUCT_DEFINITIONS */
-
diff --git a/reactos/include/WinError.h b/reactos/include/WinError.h
deleted file mode 100644 (file)
index 6fc1628..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS system libraries
- * FILE:        include/WinError.h
- * PURPOSE:     Miscellaneous error codes.
- * PROGRAMER:   Art Yerkes
- * UPDATE HISTORY:
- *              12/15/03 -- Created
- */
-
-#ifndef WINERROR_H
-#define WINERROR_H
-
-#ifdef __USE_W32API
-
-#include_next <winerror.h>
-
-#else
-
-#include <errors.h> /* Current locations of reactos errors */
-
-/* Used generally */
-#define DNS_ERROR_NO_MEMORY 14 /* ERROR_OUTOFMEMORY */
-
-/* Used by DnsValidateName */
-/* Returned by DnsValidateName to indicate that the name is too long or
-   doesn't fit some other obvious constraint. */
-#define DNS_ERROR_INVALID_NAME 123 /* ERROR_INVALID_NAME */
-/* Returned by DnsValidateName to indicate a name that contains a non-special
- * and non-ascii character. */
-#define DNS_ERROR_NON_RFC_NAME 9556
-/* Returned by DnsValidateName to indicate that a 'special' char was used
- * in the name.  These are the punctuation " {|}~[\]^':;<=>?@!"#$%^`()+/," */
-#define DNS_ERROR_INVALID_NAME_CHAR 9560
-/* Returned by DnsValidateName to indicate that the name consisted entirely
- * of digits, and so collides with the network numbers. */
-#define DNS_ERROR_NUMERIC_NAME 9561
-
-#endif /* __USE_W32API */
-
-#endif//WINERROR_H
diff --git a/reactos/include/ascii.h b/reactos/include/ascii.h
deleted file mode 100644 (file)
index c694424..0000000
+++ /dev/null
@@ -1,3624 +0,0 @@
-/* 
-   ASCIIFunctions.h
-
-   Declarations for all the Win32 ASCII Functions
-
-   Copyright (C) 1996 Free Software Foundation, Inc.
-
-   Author:  Scott Christley <scottc@net-community.com>
-
-   This file is part of the Windows32 API Library.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 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
-   Library General Public License for more details.
-
-   If you are interested in a warranty or support for this source code,
-   contact Scott Christley <scottc@net-community.com> for more information.
-   
-   You should have received a copy of the GNU Library General Public
-   License along with this library; see the file COPYING.LIB.
-   If not, write to the Free Software Foundation, 
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/ 
-
-#ifndef _GNU_H_WINDOWS32_ASCIIFUNCTIONS
-#define _GNU_H_WINDOWS32_ASCIIFUNCTIONS
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-WINBOOL
-STDCALL
-BackupEventLogA (
- HANDLE hEventLog,
- LPCSTR lpBackupFileName
- );
-
-WINBOOL
-STDCALL
-ClearEventLogA (
- HANDLE hEventLog,
- LPCSTR lpBackupFileName
- );
-
-WINBOOL
-STDCALL
-CreateProcessAsUserA (
- HANDLE hToken,
- LPCSTR lpApplicationName,
- LPSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- WINBOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCSTR lpCurrentDirectory,
- LPSTARTUPINFOA lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation
- );
-
-WINBOOL
-STDCALL
-DecryptFileA(
- LPCSTR lpFileName,
- DWORD dwReserved
- );
-
-WINBOOL
-STDCALL
-EncryptFileA(
- LPCSTR lpFileName
- );
-
-WINBOOL
-STDCALL
-FileEncryptionStatusA(
- LPCSTR lpFileName,
- LPDWORD lpStatus
- );
-
-WINBOOL
-STDCALL
-GetCurrentHwProfileA (
- LPHW_PROFILE_INFOA lpHwProfileInfo
- );
-
-WINBOOL
-STDCALL
-LogonUserA (
- LPSTR lpszUsername,
- LPSTR lpszDomain,
- LPSTR lpszPassword,
- DWORD dwLogonType,
- DWORD dwLogonProvider,
- PHANDLE phToken
- );
-
-WINBOOL
-STDCALL
-LogonUserExA (
- LPCSTR lpszUsername,
- LPCSTR lpszDomain,
- LPCSTR lpszPassword,
- DWORD dwLogonType,
- DWORD dwLogonProvider,
- PHANDLE phToken ,
- PSID *ppLogonSid ,
- PVOID *ppProfileBuffer ,
- LPDWORD pdwProfileLength ,
- PQUOTA_LIMITS pQuotaLimits
- );
-
-HANDLE
-STDCALL
-OpenBackupEventLogA (
- LPCSTR lpUNCServerName,
- LPCSTR lpFileName
- );
-
-DWORD
-STDCALL
-OpenEncryptedFileRawA(
- LPCSTR lpFileName,
- ULONG ulFlags,
- PVOID * pvContext
- );
-
-HANDLE
-STDCALL
-OpenEventLogA (
- LPCSTR lpUNCServerName,
- LPCSTR lpSourceName
- );
-
-WINBOOL
-STDCALL
-ReadEventLogA (
- HANDLE hEventLog,
- DWORD dwReadFlags,
- DWORD dwRecordOffset,
- LPVOID lpBuffer,
- DWORD nNumberOfBytesToRead,
- DWORD *pnBytesRead,
- DWORD *pnMinNumberOfBytesNeeded
- );
-
-WINBOOL
-STDCALL
-ChangeServiceConfig2A(
-    SC_HANDLE    hService,
-    DWORD        dwInfoLevel,
-    LPVOID       lpInfo
-    );
-
-WINBOOL
-STDCALL
-EnumServicesStatusExA(
-    SC_HANDLE                  hSCManager,
-    SC_ENUM_TYPE               InfoLevel,
-    DWORD                      dwServiceType,
-    DWORD                      dwServiceState,
-    LPBYTE                     lpServices,
-    DWORD                      cbBufSize,
-    LPDWORD                    pcbBytesNeeded,
-    LPDWORD                    lpServicesReturned,
-    LPDWORD                    lpResumeHandle,
-    LPCSTR                   pszGroupName
-    );
-
-WINBOOL
-STDCALL
-QueryServiceConfig2A(
-    SC_HANDLE   hService,
-    DWORD       dwInfoLevel,
-    LPBYTE      lpBuffer,
-    DWORD       cbBufSize,
-    LPDWORD     pcbBytesNeeded
-    );
-
-SERVICE_STATUS_HANDLE
-STDCALL
-RegisterServiceCtrlHandlerExA(
-    LPCSTR                lpServiceName,
-    LPHANDLER_FUNCTION_EX   lpHandlerProc,
-    LPVOID                  lpContext
-    );
-
-LRESULT 
-STDCALL
-SendIMEMessageExA(HWND hwnd, LPARAM lparam);
-
-WINBOOL
-STDCALL
-IMPSetIMEA( HWND hwnd, LPIMEPROA ime);
-
-WINBOOL
-STDCALL
-IMPQueryIMEA( LPIMEPROA ime);
-
-WINBOOL
-STDCALL
-IMPGetIMEA( HWND hwnd, LPIMEPROA ime);
-
-WINBOOL
-STDCALL
-SetCalendarInfoA(
-    LCID     Locale,
-    CALID    Calendar,
-    CALTYPE  CalType,
-    LPCSTR  lpCalData);
-
-WINBOOL
-STDCALL
-EnumUILanguagesA(
-    UILANGUAGE_ENUMPROCA lpUILanguageEnumProc,
-    DWORD                dwFlags,
-    LONG_PTR             lParam);
-
-WINBOOL
-STDCALL
-EnumLanguageGroupLocalesA(
-    LANGGROUPLOCALE_ENUMPROCA lpLangGroupLocaleEnumProc,
-    LGRPID                    LanguageGroup,
-    DWORD                     dwFlags,
-    LONG_PTR                  lParam);
-
-WINBOOL
-STDCALL
-EnumSystemLanguageGroupsA(
-    LANGUAGEGROUP_ENUMPROCA lpLanguageGroupEnumProc,
-    DWORD                   dwFlags,
-    LONG_PTR                lParam);
-
-int
-STDCALL
-GetGeoInfoA(
-    GEOID       Location,
-    GEOTYPE     GeoType,
-    LPSTR     lpGeoData,
-    int         cchData,
-    LANGID      LangId);
-
-WINBOOL
-STDCALL
-EnumDateFormatsExA(
-    DATEFMT_ENUMPROCEXA lpDateFmtEnumProcEx,
-    LCID                Locale,
-    DWORD               dwFlags);
-
-WINBOOL
-STDCALL
-EnumCalendarInfoExA(
-    CALINFO_ENUMPROCEXA lpCalInfoEnumProcEx,
-    LCID                Locale,
-    CALID               Calendar,
-    CALTYPE             CalType);
-
-int
-STDCALL
-GetCalendarInfoA(
-    LCID     Locale,
-    CALID    Calendar,
-    CALTYPE  CalType,
-    LPSTR   lpCalData,
-    int      cchData,
-    LPDWORD  lpValue);
-
-WINBOOL
-STDCALL
-GetCPInfoExA(
-    UINT          CodePage,
-    DWORD         dwFlags,
-    LPCPINFOEXA  lpCPInfoEx);
-
-WINBOOL
-STDCALL
-CheckNameLegalDOS8Dot3A(
-    LPCSTR lpName,
-    LPSTR lpOemName OPTIONAL,
-    DWORD OemNameSize OPTIONAL,
-    PWINBOOL pbNameContainsSpaces OPTIONAL,
-    PWINBOOL pbNameLegal
-    );
-
-WINBOOL
-STDCALL
-CreateHardLinkA(
-    LPCSTR lpFileName,
-    LPCSTR lpExistingFileName,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes
-    );
-
-HANDLE
-STDCALL
-CreateJobObjectA(
-    LPSECURITY_ATTRIBUTES lpJobAttributes,
-    LPCSTR lpName
-    );
-
-WINBOOL
-STDCALL
-DeleteVolumeMountPointA(
-    LPCSTR lpszVolumeMountPoint
-    );
-
-WINBOOL
-STDCALL
-DnsHostnameToComputerNameA (
-    LPCSTR Hostname,
-    LPSTR ComputerName,
-    LPDWORD nSize
-    );
-
-WINBOOL
-STDCALL
-FindActCtxSectionStringA(
-    DWORD dwFlags,
-    const GUID *lpExtensionGuid,
-    ULONG ulSectionId,
-    LPCSTR lpStringToFind,
-    PACTCTX_SECTION_KEYED_DATA ReturnedData
-    );
-
-HANDLE
-STDCALL
-FindFirstFileExA(
-    LPCSTR lpFileName,
-    FINDEX_INFO_LEVELS fInfoLevelId,
-    LPVOID lpFindFileData,
-    FINDEX_SEARCH_OPS fSearchOp,
-    LPVOID lpSearchFilter,
-    DWORD dwAdditionalFlags
-    );
-
-HANDLE
-STDCALL
-FindFirstVolumeA(
-    LPSTR lpszVolumeName,
-    DWORD cchBufferLength
-    );
-
-HANDLE
-STDCALL
-FindFirstVolumeMountPointA(
-    LPCSTR lpszRootPathName,
-    LPSTR lpszVolumeMountPoint,
-    DWORD cchBufferLength
-    );
-
-WINBOOL
-STDCALL
-FindNextVolumeA(
-    HANDLE hFindVolume,
-    LPSTR lpszVolumeName,
-    DWORD cchBufferLength
-    );
-
-WINBOOL
-STDCALL
-FindNextVolumeMountPointA(
-    HANDLE hFindVolumeMountPoint,
-    LPSTR lpszVolumeMountPoint,
-    DWORD cchBufferLength
-    );
-
-WINBOOL
-STDCALL
-GetComputerNameExA (
-    COMPUTER_NAME_FORMAT NameType,
-    LPSTR lpBuffer,
-    LPDWORD nSize
-    );
-
-DWORD
-STDCALL
-GetDllDirectoryA(
-    DWORD nBufferLength,
-    LPSTR lpBuffer
-    );
-
-DWORD
-STDCALL
-GetFirmwareEnvironmentVariableA(
-    LPCSTR lpName,
-    LPCSTR lpGuid,
-    PVOID   pBuffer,
-    DWORD    nSize
-    );
-
-DWORD
-STDCALL
-GetLongPathNameA(
-    LPCSTR lpszShortPath,
-    LPSTR  lpszLongPath,
-    DWORD    cchBuffer
-    );
-
-WINBOOL
-STDCALL
-GetModuleHandleExA(
-    DWORD        dwFlags,
-    LPCSTR     lpModuleName,
-    HMODULE*    phModule
-    );
-
-UINT
-STDCALL
-GetSystemWow64DirectoryA(
-    LPSTR lpBuffer,
-    UINT uSize
-    );
-
-WINBOOL
-STDCALL
-GetVolumeNameForVolumeMountPointA(
-    LPCSTR lpszVolumeMountPoint,
-    LPSTR lpszVolumeName,
-    DWORD cchBufferLength
-    );
-
-WINBOOL
-STDCALL
-GetVolumePathNameA(
-    LPCSTR lpszFileName,
-    LPSTR lpszVolumePathName,
-    DWORD cchBufferLength
-    );
-
-WINBOOL
-STDCALL
-GetVolumePathNamesForVolumeNameA(
-    LPCSTR lpszVolumeName,
-    LPSTR lpszVolumePathNames,
-    DWORD cchBufferLength,
-    PDWORD lpcchReturnLength
-    );
-
-HANDLE
-STDCALL
-OpenJobObjectA(
-    DWORD dwDesiredAccess,
-    WINBOOL bInheritHandle,
-    LPCSTR lpName
-    );
-
-WINBOOL
-STDCALL
-ReplaceFileA(
-    LPCSTR  lpReplacedFileName,
-    LPCSTR  lpReplacementFileName,
-    LPCSTR  lpBackupFileName,
-    DWORD   dwReplaceFlags,
-    LPVOID  lpExclude,
-    LPVOID  lpReserved
-    );
-
-WINBOOL
-STDCALL
-SetComputerNameExA (
-    COMPUTER_NAME_FORMAT NameType,
-    LPCSTR lpBuffer
-    );
-
-WINBOOL
-STDCALL
-SetDllDirectoryA(
-    LPCSTR lpPathName
-    );
-
-WINBOOL
-STDCALL
-SetFileShortNameA(
-    HANDLE hFile,
-    LPCSTR lpShortName
-    );
-
-WINBOOL
-STDCALL
-SetFirmwareEnvironmentVariableA(
-    LPCSTR lpName,
-    LPCSTR lpGuid,
-    PVOID    pValue,
-    DWORD    nSize
-    );
-
-WINBOOL
-STDCALL
-SetVolumeMountPointA(
-    LPCSTR lpszVolumeMountPoint,
-    LPCSTR lpszVolumeName
-    );
-
-WINBOOL
-STDCALL
-VerifyVersionInfoA(
-    LPOSVERSIONINFOEXA lpVersionInformation,
-    DWORD dwTypeMask,
-    DWORDLONG dwlConditionMask
-    );
-
-HDEVNOTIFY
-STDCALL
-RegisterDeviceNotificationA(
-    HANDLE hRecipient,
-    LPVOID NotificationFilter,
-    DWORD Flags
-    );
-
-UINT
-STDCALL
-GetRawInputDeviceInfoA(
-    HANDLE hDevice,
-    UINT uiCommand,
-    LPVOID pData,
-    PUINT pcbSize);
-
-LONG
-STDCALL
-BroadcastSystemMessageExA(
-    DWORD dwflags,
-    LPDWORD lpdwRecipients,
-    UINT uiMessage,
-    WPARAM wParam,
-    LPARAM lParam,
-    PBSMINFO pBSMInfo);
-
-HFONT 
-STDCALL
-CreateFontIndirectExA(const ENUMLOGFONTEXDVA *elfexd);
-
-DWORD 
-STDCALL
-GetGlyphIndicesA(
-       HDC hdc,
-       LPCSTR lpstr,
-       int c,
-       LPWORD pgi,
-       DWORD fl
-);
-
-WINBOOL 
-STDCALL
-RemoveFontResourceExA(
-       LPCSTR lpFileName,
-       DWORD fl,
-       PVOID pdv
-);
-
-UINT 
-STDCALL
-GetStringBitmapA(HDC hdc,LPSTR psz,WINBOOL unknown,UINT cj,BYTE *lpSB);
-
-WINBOOL 
-STDCALL
-GetAltTabInfoA(
-              HWND hwnd,
-              int iItem,
-              PALTTABINFO pati,
-              LPSTR pszItemText,
-              UINT cchItemText
-              );
-
-UINT 
-STDCALL
-PrivateExtractIconsA(
-                    LPCSTR szFileName,
-                    int nIconIndex,
-                    int cxIcon,
-                    int cyIcon,
-                    HICON *phicon,
-                    UINT *piconid,
-                    UINT nIcons,
-                    UINT flags
-                    );
-
-UINT
-STDCALL
-RealGetWindowClassA(
-                   HWND hwnd,
-                   LPSTR pszType,
-                   UINT cchType
-                   );
-
-LRESULT
-STDCALL
-MenuWindowProcA(
-               HWND hWnd,
-               UINT Msg,
-               WPARAM wParam,
-               LPARAM lParam
-               );
-
-WINBOOL
-STDCALL
-DrawCaptionTempA(
-                 HWND hwnd,
-                 HDC hdc,
-                 const RECT *rect,
-                 HFONT hFont,
-                 HICON hIcon,
-                 LPCSTR str,
-                 UINT uFlags
-                 );
-
-HHOOK
-STDCALL
-SetWindowsHookA(
-               int idHook,
-               HOOKPROC lpfn
-               );
-
-HRESULT
-STDCALL
-PrivateExtractIconExA(
-                     DWORD u,
-                     DWORD v,
-                     DWORD w,
-                     DWORD x,
-                     DWORD y
-                     );
-
-WINBOOL
-STDCALL
-GetBinaryTypeA(
-              LPCSTR lpApplicationName,
-              LPDWORD lpBinaryType
-              );
-
-DWORD
-STDCALL
-GetShortPathNameA(
-                 LPCSTR lpszLongPath,
-                 LPSTR  lpszShortPath,
-                 DWORD    cchBuffer
-                 );
-
-LPSTR
-STDCALL
-GetEnvironmentStringsA(
-                      VOID
-                      );
-
-WINBOOL
-STDCALL
-FreeEnvironmentStringsA(
-                       LPSTR
-                       );
-
-DWORD
-STDCALL
-FormatMessageA(
-              DWORD dwFlags,
-              LPCVOID lpSource,
-              DWORD dwMessageId,
-              DWORD dwLanguageId,
-              LPSTR lpBuffer,
-              DWORD nSize,
-              va_list *Arguments
-              );
-
-HANDLE
-STDCALL
-CreateMailslotA(
-               LPCSTR lpName,
-               DWORD nMaxMessageSize,
-               DWORD lReadTimeout,
-               LPSECURITY_ATTRIBUTES lpSecurityAttributes
-               );
-
-int
-STDCALL
-lstrcmpA(
-        LPCSTR lpString1,
-        LPCSTR lpString2
-        );
-
-int
-STDCALL
-lstrcmpiA(
-         LPCSTR lpString1,
-         LPCSTR lpString2
-         );
-
-LPSTR
-STDCALL
-lstrcpynA(
-         LPSTR lpString1,
-         LPCSTR lpString2,
-         int iMaxLength
-         );
-
-LPSTR
-STDCALL
-lstrcpyA(
-        LPSTR lpString1,
-        LPCSTR lpString2
-        );
-
-LPSTR
-STDCALL
-lstrcatA(
-        LPSTR lpString1,
-        LPCSTR lpString2
-        );
-
-int
-STDCALL
-lstrlenA(
-        LPCSTR lpString
-        );
-
-HANDLE
-STDCALL
-CreateMutexA(
-            LPSECURITY_ATTRIBUTES lpMutexAttributes,
-            WINBOOL bInitialOwner,
-            LPCSTR lpName
-            );
-
-HANDLE
-STDCALL
-OpenMutexA(
-          DWORD dwDesiredAccess,
-          WINBOOL bInheritHandle,
-          LPCSTR lpName
-          );
-
-HANDLE
-STDCALL
-CreateEventA(
-            LPSECURITY_ATTRIBUTES lpEventAttributes,
-            WINBOOL bManualReset,
-            WINBOOL bInitialState,
-            LPCSTR lpName
-            );
-
-HANDLE
-STDCALL
-OpenEventA(
-          DWORD dwDesiredAccess,
-          WINBOOL bInheritHandle,
-          LPCSTR lpName
-          );
-
-HANDLE
-STDCALL
-CreateSemaphoreA(
-                LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
-                LONG lInitialCount,
-                LONG lMaximumCount,
-                LPCSTR lpName
-                );
-
-HANDLE
-STDCALL
-OpenSemaphoreA(
-              DWORD dwDesiredAccess,
-              WINBOOL bInheritHandle,
-              LPCSTR lpName
-              );
-
-HANDLE
-STDCALL
-CreateFileMappingA(
-                  HANDLE hFile,
-                  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
-                  DWORD flProtect,
-                  DWORD dwMaximumSizeHigh,
-                  DWORD dwMaximumSizeLow,
-                  LPCSTR lpName
-                  );
-
-HANDLE
-STDCALL
-OpenFileMappingA(
-                DWORD dwDesiredAccess,
-                WINBOOL bInheritHandle,
-                LPCSTR lpName
-                );
-
-DWORD
-STDCALL
-GetLogicalDriveStringsA(
-                       DWORD nBufferLength,
-                       LPSTR lpBuffer
-                       );
-
-HINSTANCE
-STDCALL
-LoadLibraryA(
-            LPCSTR lpLibFileName
-            );
-
-HINSTANCE
-STDCALL
-LoadLibraryExA(
-              LPCSTR lpLibFileName,
-              HANDLE hFile,
-              DWORD dwFlags
-              );
-
-DWORD
-STDCALL
-GetModuleFileNameA(
-                  HINSTANCE hModule,
-                  LPSTR lpFilename,
-                  DWORD nSize
-                  );
-
-HMODULE
-STDCALL
-GetModuleHandleA(
-                LPCSTR lpModuleName
-                );
-
-VOID
-STDCALL
-FatalAppExitA(
-             UINT uAction,
-             LPCSTR lpMessageText
-             );
-
-LPSTR
-STDCALL
-GetCommandLineA(
-               VOID
-               );
-
-DWORD
-STDCALL
-GetEnvironmentVariableA(
-                       LPCSTR lpName,
-                       LPSTR lpBuffer,
-                       DWORD nSize
-                       );
-
-WINBOOL
-STDCALL
-SetEnvironmentVariableA(
-                       LPCSTR lpName,
-                       LPCSTR lpValue
-                       );
-
-DWORD
-STDCALL
-ExpandEnvironmentStringsA(
-                         LPCSTR lpSrc,
-                         LPSTR lpDst,
-                         DWORD nSize
-                         );
-
-VOID
-STDCALL
-OutputDebugStringA(
-                  LPCSTR lpOutputString
-                  );
-
-HRSRC
-STDCALL
-FindResourceA(
-             HINSTANCE hModule,
-             LPCSTR lpName,
-             LPCSTR lpType
-             );
-
-HRSRC
-STDCALL
-FindResourceExA(
-               HINSTANCE hModule,
-               LPCSTR lpType,
-               LPCSTR lpName,
-               WORD    wLanguage
-               );
-
-WINBOOL
-STDCALL
-EnumResourceTypesA(
-                  HINSTANCE hModule,
-                  ENUMRESTYPEPROCA lpEnumFunc,
-                  LONG lParam
-                  );
-
-WINBOOL
-STDCALL
-EnumResourceNamesA(
-                  HINSTANCE hModule,
-                  LPCSTR lpType,
-                  ENUMRESNAMEPROCA lpEnumFunc,
-                  LONG lParam
-                  );
-
-WINBOOL
-STDCALL
-EnumResourceLanguagesA(
-                      HINSTANCE hModule,
-                      LPCSTR lpType,
-                      LPCSTR lpName,
-                      ENUMRESLANGPROCA lpEnumFunc,
-                      LONG lParam
-                      );
-
-HANDLE
-STDCALL
-BeginUpdateResourceA(
-                    LPCSTR pFileName,
-                    WINBOOL bDeleteExistingResources
-                    );
-
-WINBOOL
-STDCALL
-UpdateResourceA(
-               HANDLE      hUpdate,
-               LPCSTR     lpType,
-               LPCSTR     lpName,
-               WORD        wLanguage,
-               LPVOID      lpData,
-               DWORD       cbData
-               );
-
-WINBOOL
-STDCALL
-EndUpdateResourceA(
-                  HANDLE      hUpdate,
-                  WINBOOL        fDiscard
-                  );
-
-ATOM
-STDCALL
-GlobalAddAtomA(
-              LPCSTR lpString
-              );
-
-ATOM
-STDCALL
-GlobalFindAtomA(
-               LPCSTR lpString
-               );
-
-UINT
-STDCALL
-GlobalGetAtomNameA(
-                  ATOM nAtom,
-                  LPSTR lpBuffer,
-                  int nSize
-                  );
-
-ATOM
-STDCALL
-AddAtomA(
-        LPCSTR lpString
-        );
-
-ATOM
-STDCALL
-FindAtomA(
-         LPCSTR lpString
-         );
-
-UINT
-STDCALL
-GetAtomNameA(
-            ATOM nAtom,
-            LPSTR lpBuffer,
-            int nSize
-            );
-
-UINT
-STDCALL
-GetProfileIntA(
-              LPCSTR lpAppName,
-              LPCSTR lpKeyName,
-              INT nDefault
-              );
-
-DWORD
-STDCALL
-GetProfileStringA(
-                 LPCSTR lpAppName,
-                 LPCSTR lpKeyName,
-                 LPCSTR lpDefault,
-                 LPSTR lpReturnedString,
-                 DWORD nSize
-                 );
-
-WINBOOL
-STDCALL
-WriteProfileStringA(
-    LPCSTR lpAppName,
-    LPCSTR lpKeyName,
-    LPCSTR lpString
-    );
-
-DWORD
-STDCALL
-GetProfileSectionA(
-    LPCSTR lpAppName,
-    LPSTR lpReturnedString,
-    DWORD nSize
-    );
-
-WINBOOL
-STDCALL
-WriteProfileSectionA(
-    LPCSTR lpAppName,
-    LPCSTR lpString
-    );
-
-UINT
-STDCALL
-GetPrivateProfileIntA(
-    LPCSTR lpAppName,
-    LPCSTR lpKeyName,
-    INT nDefault,
-    LPCSTR lpFileName
-    );
-
-DWORD
-STDCALL
-GetPrivateProfileStringA(
-    LPCSTR lpAppName,
-    LPCSTR lpKeyName,
-    LPCSTR lpDefault,
-    LPSTR lpReturnedString,
-    DWORD nSize,
-    LPCSTR lpFileName
-    );
-
-WINBOOL
-STDCALL
-WritePrivateProfileStringA(
-    LPCSTR lpAppName,
-    LPCSTR lpKeyName,
-    LPCSTR lpString,
-    LPCSTR lpFileName
-    );
-
-DWORD
-STDCALL
-GetPrivateProfileSectionA(
-    LPCSTR lpAppName,
-    LPSTR lpReturnedString,
-    DWORD nSize,
-    LPCSTR lpFileName
-    );
-
-WINBOOL
-STDCALL
-WritePrivateProfileSectionA(
-    LPCSTR lpAppName,
-    LPCSTR lpString,
-    LPCSTR lpFileName
-    );
-
-UINT
-STDCALL
-GetDriveTypeA(
-    LPCSTR lpRootPathName
-    );
-
-UINT
-STDCALL
-GetSystemDirectoryA(
-    LPSTR lpBuffer,
-    UINT uSize
-    );
-
-DWORD
-STDCALL
-GetTempPathA(
-    DWORD nBufferLength,
-    LPSTR lpBuffer
-    );
-
-UINT
-STDCALL
-GetTempFileNameA(
-    LPCSTR lpPathName,
-    LPCSTR lpPrefixString,
-    UINT uUnique,
-    LPSTR lpTempFileName
-    );
-
-UINT
-STDCALL
-GetWindowsDirectoryA(
-    LPSTR lpBuffer,
-    UINT uSize
-    );
-
-WINBOOL
-STDCALL
-SetCurrentDirectoryA(
-    LPCSTR lpPathName
-    );
-
-DWORD
-STDCALL
-GetCurrentDirectoryA(
-    DWORD nBufferLength,
-    LPSTR lpBuffer
-    );
-
-WINBOOL
-STDCALL
-GetDiskFreeSpaceA(
-    LPCSTR lpRootPathName,
-    LPDWORD lpSectorsPerCluster,
-    LPDWORD lpBytesPerSector,
-    LPDWORD lpNumberOfFreeClusters,
-    LPDWORD lpTotalNumberOfClusters
-    );
-
-WINBOOL
-STDCALL
-GetDiskFreeSpaceExA(
-    LPCSTR lpDirectoryName,
-    PULARGE_INTEGER lpFreeBytesAvailableToCaller,
-    PULARGE_INTEGER lpTotalNumberOfBytes,
-    PULARGE_INTEGER lpTotalNumberOfFreeBytes
-    );
-
-WINBOOL
-STDCALL
-CreateDirectoryA(
-    LPCSTR lpPathName,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes
-    );
-
-WINBOOL
-STDCALL
-CreateDirectoryExA(
-    LPCSTR lpTemplateDirectory,
-    LPCSTR lpNewDirectory,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes
-    );
-
-WINBOOL
-STDCALL
-RemoveDirectoryA(
-    LPCSTR lpPathName
-    );
-
-DWORD
-STDCALL
-GetFullPathNameA(
-    LPCSTR lpFileName,
-    DWORD nBufferLength,
-    LPSTR lpBuffer,
-    LPSTR *lpFilePart
-    );
-
-WINBOOL
-STDCALL
-DefineDosDeviceA(
-    DWORD dwFlags,
-    LPCSTR lpDeviceName,
-    LPCSTR lpTargetPath
-    );
-
-DWORD
-STDCALL
-QueryDosDeviceA(
-    LPCSTR lpDeviceName,
-    LPSTR lpTargetPath,
-    DWORD ucchMax
-    );
-
-HANDLE
-STDCALL
-CreateFileA(
-    LPCSTR lpFileName,
-    DWORD dwDesiredAccess,
-    DWORD dwShareMode,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
-    DWORD dwCreationDisposition,
-    DWORD dwFlagsAndAttributes,
-    HANDLE hTemplateFile
-    );
-
-WINBOOL
-STDCALL
-SetFileAttributesA(
-    LPCSTR lpFileName,
-    DWORD dwFileAttributes
-    );
-
-DWORD
-STDCALL
-GetFileAttributesA(
-    LPCSTR lpFileName
-    );
-
-BOOL 
-STDCALL
-GetFileAttributesExA(
-    LPCSTR lpFileName,
-    GET_FILEEX_INFO_LEVELS fInfoLevelId, 
-    LPVOID lpFileInformation
-    );    
-
-DWORD
-STDCALL
-GetCompressedFileSizeA(
-    LPCSTR lpFileName,
-    LPDWORD lpFileSizeHigh
-    );
-
-WINBOOL
-STDCALL
-DeleteFileA(
-    LPCSTR lpFileName
-    );
-
-DWORD
-STDCALL
-SearchPathA(
-           LPCSTR lpPath,
-    LPCSTR lpFileName,
-    LPCSTR lpExtension,
-    DWORD nBufferLength,
-    LPSTR lpBuffer,
-    LPSTR *lpFilePart
-    );
-
-WINBOOL
-STDCALL
-CopyFileA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    WINBOOL bFailIfExists
-    );
-
-WINBOOL
-STDCALL
-CopyFileExA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    LPPROGRESS_ROUTINE lpProgressRoutine,
-    LPVOID lpData,
-    LPBOOL pbCancel,
-    DWORD dwCopyFlags
-    );
-
-WINBOOL
-STDCALL
-MoveFileA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName
-    );
-
-WINBOOL
-STDCALL
-MoveFileExA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    DWORD dwFlags
-    );
-
-WINBOOL
-STDCALL
-MoveFileWithProgressA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    LPPROGRESS_ROUTINE lpProgressRoutine,
-    LPVOID lpData,
-    DWORD dwFlags
-    );
-
-HANDLE
-STDCALL
-CreateNamedPipeA(
-    LPCSTR lpName,
-    DWORD dwOpenMode,
-    DWORD dwPipeMode,
-    DWORD nMaxInstances,
-    DWORD nOutBufferSize,
-    DWORD nInBufferSize,
-    DWORD nDefaultTimeOut,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes
-    );
-
-WINBOOL
-STDCALL
-GetNamedPipeHandleStateA(
-    HANDLE hNamedPipe,
-    LPDWORD lpState,
-    LPDWORD lpCurInstances,
-    LPDWORD lpMaxCollectionCount,
-    LPDWORD lpCollectDataTimeout,
-    LPSTR lpUserName,
-    DWORD nMaxUserNameSize
-    );
-
-WINBOOL
-STDCALL
-CallNamedPipeA(
-    LPCSTR lpNamedPipeName,
-    LPVOID lpInBuffer,
-    DWORD nInBufferSize,
-    LPVOID lpOutBuffer,
-    DWORD nOutBufferSize,
-    LPDWORD lpBytesRead,
-    DWORD nTimeOut
-    );
-
-WINBOOL
-STDCALL
-WaitNamedPipeA(
-    LPCSTR lpNamedPipeName,
-    DWORD nTimeOut
-    );
-
-WINBOOL
-STDCALL
-SetVolumeLabelA(
-    LPCSTR lpRootPathName,
-    LPCSTR lpVolumeName
-    );
-
-WINBOOL
-STDCALL
-GetVolumeInformationA(
-    LPCSTR lpRootPathName,
-    LPSTR lpVolumeNameBuffer,
-    DWORD nVolumeNameSize,
-    LPDWORD lpVolumeSerialNumber,
-    LPDWORD lpMaximumComponentLength,
-    LPDWORD lpFileSystemFlags,
-    LPSTR lpFileSystemNameBuffer,
-    DWORD nFileSystemNameSize
-    );
-
-WINBOOL
-STDCALL
-ClearEventLogA (
-    HANDLE hEventLog,
-    LPCSTR lpBackupFileName
-    );
-
-WINBOOL
-STDCALL
-BackupEventLogA (
-    HANDLE hEventLog,
-    LPCSTR lpBackupFileName
-    );
-
-HANDLE
-STDCALL
-OpenEventLogA (
-    LPCSTR lpUNCServerName,
-    LPCSTR lpSourceName
-    );
-
-HANDLE
-STDCALL
-RegisterEventSourceA (
-    LPCSTR lpUNCServerName,
-    LPCSTR lpSourceName
-    );
-
-HANDLE
-STDCALL
-OpenBackupEventLogA (
-    LPCSTR lpUNCServerName,
-    LPCSTR lpFileName
-    );
-
-WINBOOL
-STDCALL
-ReadEventLogA (
-     HANDLE     hEventLog,
-     DWORD      dwReadFlags,
-     DWORD      dwRecordOffset,
-     LPVOID     lpBuffer,
-     DWORD      nNumberOfBytesToRead,
-     DWORD      *pnBytesRead,
-     DWORD      *pnMinNumberOfBytesNeeded
-    );
-
-WINBOOL
-STDCALL
-ReportEventA (
-     HANDLE     hEventLog,
-     WORD       wType,
-     WORD       wCategory,
-     DWORD      dwEventID,
-     PSID       lpUserSid,
-     WORD       wNumStrings,
-     DWORD      dwDataSize,
-     LPCSTR   *lpStrings,
-     LPVOID     lpRawData
-    );
-
-WINBOOL
-STDCALL
-AccessCheckAndAuditAlarmA (
-    LPCSTR SubsystemName,
-    LPVOID HandleId,
-    LPSTR ObjectTypeName,
-    LPSTR ObjectName,
-    PSECURITY_DESCRIPTOR SecurityDescriptor,
-    DWORD DesiredAccess,
-    PGENERIC_MAPPING GenericMapping,
-    WINBOOL ObjectCreation,
-    LPDWORD GrantedAccess,
-    LPBOOL AccessStatus,
-    LPBOOL pfGenerateOnClose
-    );
-
-WINBOOL
-STDCALL
-ObjectOpenAuditAlarmA (
-    LPCSTR SubsystemName,
-    LPVOID HandleId,
-    LPSTR ObjectTypeName,
-    LPSTR ObjectName,
-    PSECURITY_DESCRIPTOR pSecurityDescriptor,
-    HANDLE ClientToken,
-    DWORD DesiredAccess,
-    DWORD GrantedAccess,
-    PPRIVILEGE_SET Privileges,
-    WINBOOL ObjectCreation,
-    WINBOOL AccessGranted,
-    LPBOOL GenerateOnClose
-    );
-
-WINBOOL
-STDCALL
-ObjectPrivilegeAuditAlarmA (
-    LPCSTR SubsystemName,
-    LPVOID HandleId,
-    HANDLE ClientToken,
-    DWORD DesiredAccess,
-    PPRIVILEGE_SET Privileges,
-    WINBOOL AccessGranted
-    );
-
-WINBOOL
-STDCALL
-ObjectCloseAuditAlarmA (
-    LPCSTR SubsystemName,
-    LPVOID HandleId,
-    WINBOOL GenerateOnClose
-    );
-
-WINBOOL
-STDCALL
-PrivilegedServiceAuditAlarmA (
-    LPCSTR SubsystemName,
-    LPCSTR ServiceName,
-    HANDLE ClientToken,
-    PPRIVILEGE_SET Privileges,
-    WINBOOL AccessGranted
-    );
-
-WINBOOL
-STDCALL
-SetFileSecurityA (
-    LPCSTR lpFileName,
-    SECURITY_INFORMATION SecurityInformation,
-    PSECURITY_DESCRIPTOR pSecurityDescriptor
-    );
-
-WINBOOL
-STDCALL
-GetFileSecurityA (
-    LPCSTR lpFileName,
-    SECURITY_INFORMATION RequestedInformation,
-    PSECURITY_DESCRIPTOR pSecurityDescriptor,
-    DWORD nLength,
-    LPDWORD lpnLengthNeeded
-    );
-
-HANDLE
-STDCALL
-FindFirstChangeNotificationA(
-    LPCSTR lpPathName,
-    WINBOOL bWatchSubtree,
-    DWORD dwNotifyFilter
-    );
-
-WINBOOL
-STDCALL
-IsBadStringPtrA(
-    LPCSTR lpsz,
-    UINT ucchMax
-    );
-
-WINBOOL
-STDCALL
-LookupAccountSidA(
-    LPCSTR lpSystemName,
-    PSID Sid,
-    LPSTR Name,
-    LPDWORD cbName,
-    LPSTR ReferencedDomainName,
-    LPDWORD cbReferencedDomainName,
-    PSID_NAME_USE peUse
-    );
-
-WINBOOL
-STDCALL
-LookupAccountNameA(
-    LPCSTR lpSystemName,
-    LPCSTR lpAccountName,
-    PSID Sid,
-    LPDWORD cbSid,
-    LPSTR ReferencedDomainName,
-    LPDWORD cbReferencedDomainName,
-    PSID_NAME_USE peUse
-    );
-
-WINBOOL
-STDCALL
-LookupPrivilegeValueA(
-    LPCSTR lpSystemName,
-    LPCSTR lpName,
-    PLUID   lpLuid
-    );
-
-WINBOOL
-STDCALL
-LookupPrivilegeNameA(
-    LPCSTR lpSystemName,
-    PLUID   lpLuid,
-    LPSTR lpName,
-    LPDWORD cbName
-    );
-
-WINBOOL
-STDCALL
-LookupPrivilegeDisplayNameA(
-    LPCSTR lpSystemName,
-    LPCSTR lpName,
-    LPSTR lpDisplayName,
-    LPDWORD cbDisplayName,
-    LPDWORD lpLanguageId
-    );
-
-WINBOOL
-STDCALL
-BuildCommDCBA(
-    LPCSTR lpDef,
-    LPDCB lpDCB
-    );
-
-WINBOOL
-STDCALL
-BuildCommDCBAndTimeoutsA(
-    LPCSTR lpDef,
-    LPDCB lpDCB,
-    LPCOMMTIMEOUTS lpCommTimeouts
-    );
-
-WINBOOL
-STDCALL
-CommConfigDialogA(
-    LPCSTR lpszName,
-    HWND hWnd,
-    LPCOMMCONFIG lpCC
-    );
-
-WINBOOL
-STDCALL
-GetDefaultCommConfigA(
-    LPCSTR lpszName,
-    LPCOMMCONFIG lpCC,
-    LPDWORD lpdwSize
-    );
-
-WINBOOL
-STDCALL
-SetDefaultCommConfigA(
-    LPCSTR lpszName,
-    LPCOMMCONFIG lpCC,
-    DWORD dwSize
-    );
-
-WINBOOL
-STDCALL
-GetComputerNameA (
-    LPSTR lpBuffer,
-    LPDWORD nSize
-    );
-
-WINBOOL
-STDCALL
-SetComputerNameA (
-    LPCSTR lpComputerName
-    );
-
-WINBOOL
-STDCALL
-GetUserNameA (
-    LPSTR lpBuffer,
-    LPDWORD nSize
-    );
-
-int
-STDCALL
-wvsprintfA(
-    LPSTR,
-    LPCSTR,
-    va_list arglist);
-int
-CDECL
-wsprintfA(LPSTR, LPCSTR, ...);
-
-HKL
-STDCALL
-LoadKeyboardLayoutA(
-    LPCSTR pwszKLID,
-    UINT Flags);
-
-WINBOOL
-STDCALL
-GetKeyboardLayoutNameA(
-    LPSTR pwszKLID);
-
-HDESK
-STDCALL
-CreateDesktopA(
-    LPCSTR lpszDesktop,
-    LPCSTR lpszDevice,
-    LPDEVMODEA pDevmode,
-    DWORD dwFlags,
-    ACCESS_MASK dwDesiredAccess,
-    LPSECURITY_ATTRIBUTES lpsa);
-
-HDESK
-STDCALL
-OpenDesktopA(
-    LPSTR lpszDesktop,
-    DWORD dwFlags,
-    WINBOOL fInherit,
-    DWORD dwDesiredAccess);
-
-WINBOOL
-STDCALL
-EnumDesktopsA(
-    HWINSTA hwinsta,
-    DESKTOPENUMPROCA lpEnumFunc,
-    LPARAM lParam);
-
-HWINSTA
-STDCALL
-CreateWindowStationA(
-    LPSTR lpwinsta,
-    DWORD dwReserved,
-    DWORD dwDesiredAccess,
-    LPSECURITY_ATTRIBUTES lpsa);
-
-HANDLE STDCALL CreateWaitableTimerA( LPSECURITY_ATTRIBUTES Attributes,
-                                    BOOL ManualReset,
-                                    LPCSTR Name );
-  
-HWINSTA
-STDCALL
-OpenWindowStationA(
-    LPSTR lpszWinSta,
-    WINBOOL fInherit,
-    DWORD dwDesiredAccess);
-WINBOOL
-STDCALL
-EnumWindowStationsA(
-    ENUMWINDOWSTATIONPROCA lpEnumFunc,
-    LPARAM lParam);
-WINBOOL
-STDCALL
-GetUserObjectInformationA(
-    HANDLE hObj,
-    int nIndex,
-    PVOID pvInfo,
-    DWORD nLength,
-    LPDWORD lpnLengthNeeded);
-WINBOOL
-STDCALL
-SetUserObjectInformationA(
-    HANDLE hObj,
-    int nIndex,
-    PVOID pvInfo,
-    DWORD nLength);
-UINT
-STDCALL
-RegisterWindowMessageA(
-    LPCSTR lpString);
-WINBOOL
-STDCALL
-GetMessageA(
-    LPMSG lpMsg,
-    HWND hWnd ,
-    UINT wMsgFilterMin,
-    UINT wMsgFilterMax);
-LRESULT
-STDCALL
-DispatchMessageA(
-    CONST MSG *lpMsg);
-WINBOOL
-STDCALL
-PeekMessageA(
-    LPMSG lpMsg,
-    HWND hWnd ,
-    UINT wMsgFilterMin,
-    UINT wMsgFilterMax,
-    UINT wRemoveMsg);
-LRESULT
-STDCALL
-SendMessageA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-LRESULT
-STDCALL
-SendMessageTimeoutA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam,
-    UINT fuFlags,
-    UINT uTimeout,
-    PDWORD_PTR lpdwResult);
-WINBOOL
-STDCALL
-SendNotifyMessageA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-WINBOOL
-STDCALL
-SendMessageCallbackA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam,
-    SENDASYNCPROC lpResultCallBack,
-    ULONG_PTR dwData);
-WINBOOL
-STDCALL
-PostMessageA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-WINBOOL
-STDCALL
-PostThreadMessageA(
-    DWORD idThread,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-LRESULT
-STDCALL
-DefWindowProcA(
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-LRESULT
-STDCALL
-CallWindowProcA(
-    WNDPROC lpPrevWndFunc,
-    HWND hWnd,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-ATOM
-STDCALL
-RegisterClassA(
-    CONST WNDCLASSA *lpWndClass);
-WINBOOL
-STDCALL
-UnregisterClassA(
-    LPCSTR lpClassName,
-    HINSTANCE hInstance);
-WINBOOL
-STDCALL
-GetClassInfoA(
-    HINSTANCE hInstance ,
-    LPCSTR lpClassName,
-    LPWNDCLASSA lpWndClass);
-ATOM
-STDCALL
-RegisterClassExA(CONST WNDCLASSEXA *);
-WINBOOL
-STDCALL
-GetClassInfoExA(HINSTANCE, LPCSTR, LPWNDCLASSEXA);
-HWND
-STDCALL
-CreateWindowExA(
-    DWORD dwExStyle,
-    LPCSTR lpClassName,
-    LPCSTR lpWindowName,
-    DWORD dwStyle,
-    int X,
-    int Y,
-    int nWidth,
-    int nHeight,
-    HWND hWndParent ,
-    HMENU hMenu,
-    HINSTANCE hInstance,
-    LPVOID lpParam);
-HWND
-STDCALL
-CreateDialogParamA(
-    HINSTANCE hInstance,
-    LPCSTR lpTemplateName,
-    HWND hWndParent ,
-    DLGPROC lpDialogFunc,
-    LPARAM dwInitParam);
-HWND
-STDCALL
-CreateDialogIndirectParamA(
-    HINSTANCE hInstance,
-    LPCDLGTEMPLATE lpTemplate,
-    HWND hWndParent,
-    DLGPROC lpDialogFunc,
-    LPARAM dwInitParam);
-int
-STDCALL
-DialogBoxParamA(
-    HINSTANCE hInstance,
-    LPCSTR lpTemplateName,
-    HWND hWndParent ,
-    DLGPROC lpDialogFunc,
-    LPARAM dwInitParam);
-int
-STDCALL
-DialogBoxIndirectParamA(
-    HINSTANCE hInstance,
-    LPCDLGTEMPLATE hDialogTemplate,
-    HWND hWndParent ,
-    DLGPROC lpDialogFunc,
-    LPARAM dwInitParam);
-WINBOOL
-STDCALL
-SetDlgItemTextA(
-    HWND hDlg,
-    int nIDDlgItem,
-    LPCSTR lpString);
-UINT
-STDCALL
-GetDlgItemTextA(
-    HWND hDlg,
-    int nIDDlgItem,
-    LPSTR lpString,
-    int nMaxCount);
-
-WINBOOL
-STDCALL
-IsDialogMessageA(
-    HWND hDlg,
-    LPMSG lpMsg);
-
-LRESULT
-STDCALL
-SendDlgItemMessageA(
-    HWND hDlg,
-    int nIDDlgItem,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-LRESULT
-STDCALL
-DefDlgProcA(
-    HWND hDlg,
-    UINT Msg,
-    WPARAM wParam,
-    LPARAM lParam);
-WINBOOL
-STDCALL
-CallMsgFilterA(
-    LPMSG lpMsg,
-    int nCode);
-UINT
-STDCALL
-RegisterClipboardFormatA(
-    LPCSTR lpszFormat);
-int
-STDCALL
-GetClipboardFormatNameA(
-    UINT format,
-    LPSTR lpszFormatName,
-    int cchMaxCount);
-WINBOOL
-STDCALL
-CharToOemA(
-    LPCSTR lpszSrc,
-    LPSTR lpszDst);
-WINBOOL
-STDCALL
-OemToCharA(
-    LPCSTR lpszSrc,
-    LPSTR lpszDst);
-WINBOOL
-STDCALL
-CharToOemBuffA(
-    LPCSTR lpszSrc,
-    LPSTR lpszDst,
-    DWORD cchDstLength);
-WINBOOL
-STDCALL
-OemToCharBuffA(
-    LPCSTR lpszSrc,
-    LPSTR lpszDst,
-    DWORD cchDstLength);
-LPSTR
-STDCALL
-CharUpperA(
-    LPSTR lpsz);
-DWORD
-STDCALL
-CharUpperBuffA(
-    LPSTR lpsz,
-    DWORD cchLength);
-LPSTR
-STDCALL
-CharLowerA(
-    LPSTR lpsz);
-DWORD
-STDCALL
-CharLowerBuffA(
-    LPSTR lpsz,
-    DWORD cchLength);
-LPSTR
-STDCALL
-CharNextA(
-    LPCSTR lpsz);
-LPSTR
-STDCALL
-CharPrevA(
-    LPCSTR lpszStart,
-    LPCSTR lpszCurrent);
-WINBOOL
-STDCALL
-IsCharAlphaA(
-    CHAR ch);
-WINBOOL
-STDCALL
-IsCharAlphaNumericA(
-    CHAR ch);
-WINBOOL
-STDCALL
-IsCharUpperA(
-    CHAR ch);
-WINBOOL
-STDCALL
-IsCharLowerA(
-    CHAR ch);
-int
-STDCALL
-GetKeyNameTextA(
-    LONG lParam,
-    LPSTR lpString,
-    int nSize
-    );
-SHORT
-STDCALL
-VkKeyScanA(
-    CHAR ch);
-SHORT
-STDCALL VkKeyScanExA(
-    CHAR  ch,
-    HKL   dwhkl);
-UINT
-STDCALL
-MapVirtualKeyA(
-    UINT uCode,
-    UINT uMapType);
-UINT
-STDCALL
-MapVirtualKeyExA(
-    UINT uCode,
-    UINT uMapType,
-    HKL dwhkl);
-HACCEL
-STDCALL
-LoadAcceleratorsA(
-    HINSTANCE hInstance,
-    LPCSTR lpTableName);
-HACCEL
-STDCALL
-CreateAcceleratorTableA(
-    LPACCEL, int);
-int
-STDCALL
-CopyAcceleratorTableA(
-    HACCEL hAccelSrc,
-    LPACCEL lpAccelDst,
-    int cAccelEntries);
-int
-STDCALL
-TranslateAcceleratorA(
-    HWND hWnd,
-    HACCEL hAccTable,
-    LPMSG lpMsg);
-HMENU
-STDCALL
-LoadMenuA(
-    HINSTANCE hInstance,
-    LPCSTR lpMenuName);
-HMENU
-STDCALL
-LoadMenuIndirectA(
-    CONST MENUTEMPLATE *lpMenuTemplate);
-WINBOOL
-STDCALL
-ChangeMenuA(
-    HMENU hMenu,
-    UINT cmd,
-    LPCSTR lpszNewItem,
-    UINT cmdInsert,
-    UINT flags);
-int
-STDCALL
-GetMenuStringA(
-    HMENU hMenu,
-    UINT uIDItem,
-    LPSTR lpString,
-    int nMaxCount,
-    UINT uFlag);
-WINBOOL
-STDCALL
-InsertMenuA(
-    HMENU hMenu,
-    UINT uPosition,
-    UINT uFlags,
-    UINT uIDNewItem,
-    LPCSTR lpNewItem
-    );
-WINBOOL
-STDCALL
-AppendMenuA(
-    HMENU hMenu,
-    UINT uFlags,
-    UINT uIDNewItem,
-    LPCSTR lpNewItem
-    );
-WINBOOL
-STDCALL
-ModifyMenuA(
-    HMENU hMnu,
-    UINT uPosition,
-    UINT uFlags,
-    UINT uIDNewItem,
-    LPCSTR lpNewItem
-    );
-WINBOOL
-STDCALL
-InsertMenuItemA(
-    HMENU,
-    UINT,
-    WINBOOL,
-    LPCMENUITEMINFOA
-    );
-WINBOOL
-STDCALL
-GetMenuItemInfoA(
-    HMENU,
-    UINT,
-    WINBOOL,
-    LPMENUITEMINFOA
-    );
-WINBOOL
-STDCALL
-SetMenuItemInfoA(
-  HMENU hMenu,
-  UINT uItem,
-  WINBOOL fByPosition,
-  LPMENUITEMINFOA lpmii);
-int
-STDCALL
-DrawTextA(
-    HDC hDC,
-    LPCSTR lpString,
-    int nCount,
-    LPRECT lpRect,
-    UINT uFormat);
-int
-STDCALL
-DrawTextExA(HDC, LPSTR, int, LPRECT, UINT, LPDRAWTEXTPARAMS);
-WINBOOL
-STDCALL
-GrayStringA(
-    HDC hDC,
-    HBRUSH hBrush,
-    GRAYSTRINGPROC lpOutputFunc,
-    LPARAM lpData,
-    int nCount,
-    int X,
-    int Y,
-    int nWidth,
-    int nHeight);
-WINBOOL
-STDCALL
-DrawStateA(HDC, HBRUSH, DRAWSTATEPROC, LPARAM, WPARAM, int, int, int, int, UINT);
-
-LONG
-STDCALL
-TabbedTextOutA(
-    HDC hDC,
-    int X,
-    int Y,
-    LPCSTR lpString,
-    int nCount,
-    int nTabPositions,
-    LPINT lpnTabStopPositions,
-    int nTabOrigin);
-DWORD
-STDCALL
-GetTabbedTextExtentA(
-    HDC hDC,
-    LPCSTR lpString,
-    int nCount,
-    int nTabPositions,
-    LPINT lpnTabStopPositions);
-WINBOOL
-STDCALL
-SetPropA(
-    HWND hWnd,
-    LPCSTR lpString,
-    HANDLE hData);
-HANDLE
-STDCALL
-GetPropA(
-    HWND hWnd,
-    LPCSTR lpString);
-HANDLE
-STDCALL
-RemovePropA(
-    HWND hWnd,
-    LPCSTR lpString);
-int
-STDCALL
-EnumPropsExA(
-    HWND hWnd,
-    PROPENUMPROCEXA lpEnumFunc,
-    LPARAM lParam);
-int
-STDCALL
-EnumPropsA(
-    HWND hWnd,
-    PROPENUMPROCA lpEnumFunc);
-WINBOOL
-STDCALL
-SetWindowTextA(
-    HWND hWnd,
-    LPCSTR lpString);
-int
-STDCALL
-GetWindowTextA(
-    HWND hWnd,
-    LPSTR lpString,
-    int nMaxCount);
-int
-STDCALL
-GetWindowTextLengthA(
-    HWND hWnd);
-int
-STDCALL
-MessageBoxA(
-    HWND hWnd ,
-    LPCSTR lpText,
-    LPCSTR lpCaption,
-    UINT uType);
-int
-STDCALL
-MessageBoxExA(
-    HWND hWnd ,
-    LPCSTR lpText,
-    LPCSTR lpCaption,
-    UINT uType,
-    WORD wLanguageId);
-int
-STDCALL
-MessageBoxIndirectA(LPMSGBOXPARAMS);
-
-LONG
-STDCALL
-GetWindowLongA(
-    HWND hWnd,
-    int nIndex);
-LONG
-STDCALL
-SetWindowLongA(
-    HWND hWnd,
-    int nIndex,
-    LONG dwNewLong);
-DWORD
-STDCALL
-GetClassLongA(
-    HWND hWnd,
-    int nIndex);
-DWORD
-STDCALL
-SetClassLongA(
-    HWND hWnd,
-    int nIndex,
-    LONG dwNewLong);
-HWND
-STDCALL
-FindWindowA(
-    LPCSTR lpClassName ,
-    LPCSTR lpWindowName);
-HWND
-STDCALL
-FindWindowExA(HWND, HWND, LPCSTR, LPCSTR);
-
-int
-STDCALL
-GetClassNameA(
-    HWND hWnd,
-    LPSTR lpClassName,
-    int nMaxCount);
-HHOOK
-STDCALL
-SetWindowsHookExA(
-    int idHook,
-    HOOKPROC lpfn,
-    HINSTANCE hmod,
-    DWORD dwThreadId);
-HBITMAP
-STDCALL
-LoadBitmapA(
-    HINSTANCE hInstance,
-    LPCSTR lpBitmapName);
-HCURSOR
-STDCALL
-LoadCursorA(
-    HINSTANCE hInstance,
-    LPCSTR lpCursorName);
-HCURSOR
-STDCALL
-LoadCursorFromFileA(
-    LPCSTR    lpFileName);
-HICON
-STDCALL
-LoadIconA(
-    HINSTANCE hInstance,
-    LPCSTR lpIconName);
-HANDLE
-STDCALL
-LoadImageA(
-    HINSTANCE,
-    LPCSTR,
-    UINT,
-    int,
-    int,
-    UINT);
-int
-STDCALL
-LoadStringA(
-    HINSTANCE hInstance,
-    UINT uID,
-    LPSTR lpBuffer,
-    int nBufferMax);
-int
-STDCALL
-DlgDirListA(
-    HWND hDlg,
-    LPSTR lpPathSpec,
-    int nIDListBox,
-    int nIDStaticPath,
-    UINT uFileType);
-WINBOOL
-STDCALL
-DlgDirSelectExA(
-    HWND hDlg,
-    LPSTR lpString,
-    int nCount,
-    int nIDListBox);
-int
-STDCALL
-DlgDirListComboBoxA(
-    HWND hDlg,
-    LPSTR lpPathSpec,
-    int nIDComboBox,
-    int nIDStaticPath,
-    UINT uFiletype);
-WINBOOL
-STDCALL
-DlgDirSelectComboBoxExA(
-    HWND hDlg,
-    LPSTR lpString,
-    int nCount,
-    int nIDComboBox);
-LRESULT
-STDCALL
-DefFrameProcA(
-    HWND hWnd,
-    HWND hWndMDIClient ,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam);
-LRESULT
-STDCALL
-DefMDIChildProcA(
-    HWND hWnd,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam);
-HWND
-STDCALL
-CreateMDIWindowA(
-    LPCSTR lpClassName,
-    LPCSTR lpWindowName,
-    DWORD dwStyle,
-    int X,
-    int Y,
-    int nWidth,
-    int nHeight,
-    HWND hWndParent,
-    HINSTANCE hInstance,
-    LPARAM lParam
-    );
-WINBOOL
-STDCALL
-WinHelpA(
-    HWND hWndMain,
-    LPCSTR lpszHelp,
-    UINT uCommand,
-    DWORD dwData
-    );
-LONG
-STDCALL
-ChangeDisplaySettingsA(
-    LPDEVMODEA lpDevMode,
-    DWORD dwFlags);
-WINBOOL
-STDCALL
-EnumDisplaySettingsA(
-    LPCSTR lpszDeviceName,
-    DWORD iModeNum,
-    LPDEVMODEA lpDevMode);
-
-WINBOOL
-STDCALL
-SystemParametersInfoA(
-    UINT uiAction,
-    UINT uiParam,
-    PVOID pvParam,
-    UINT fWinIni);
-
-int
-STDCALL
-AddFontResourceA(LPCSTR);
-
-HMETAFILE
-STDCALL
-CopyMetaFileA(HMETAFILE, LPCSTR);
-
-HFONT
-STDCALL
-CreateFontIndirectA(CONST LOGFONTA *);
-
-HDC
-STDCALL
-CreateICA(LPCSTR, LPCSTR , LPCSTR , CONST DEVMODEA *);
-
-HDC
-STDCALL
-CreateMetaFileA(LPCSTR);
-
-WINBOOL
-STDCALL
-CreateScalableFontResourceA(DWORD, LPCSTR, LPCSTR, LPCSTR);
-
-int
-STDCALL
-DeviceCapabilitiesA(LPCSTR, LPCSTR, WORD,
-                                LPSTR, CONST DEVMODEA *);
-
-int
-STDCALL
-EnumFontFamiliesExA(HDC, LPLOGFONTA, FONTENUMEXPROCA, LPARAM,DWORD);
-
-int
-STDCALL
-EnumFontFamiliesA(HDC, LPCSTR, FONTENUMPROCA, LPARAM);
-
-int
-STDCALL
-EnumFontsA(HDC, LPCSTR,  FONTENUMPROCA, LPARAM);
-
-WINBOOL
-STDCALL
-GetCharWidthA(HDC, UINT, UINT, LPINT);
-
-WINBOOL
-STDCALL
-GetCharWidth32A(HDC, UINT, UINT, LPINT);
-
-WINBOOL
-STDCALL
-GetCharWidthFloatA(HDC, UINT, UINT, PFLOAT);
-
-WINBOOL
-STDCALL
-GetCharABCWidthsA(HDC, UINT, UINT, LPABC);
-
-WINBOOL
-STDCALL
-GetCharABCWidthsFloatA(HDC, UINT, UINT, LPABCFLOAT);
-DWORD
-STDCALL
-GetGlyphOutlineA(HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, LPVOID, CONST MAT2 *);
-
-HMETAFILE
-STDCALL
-GetMetaFileA(LPCSTR);
-
-UINT
-STDCALL
-GetOutlineTextMetricsA(HDC, UINT, LPOUTLINETEXTMETRICA);
-
-WINBOOL
-STDCALL
-GetTextExtentPointA(
-                    HDC,
-                    LPCSTR,
-                    int,
-                    LPSIZE
-                    );
-
-WINBOOL
-STDCALL
-GetTextExtentPoint32A(
-                    HDC,
-                    LPCSTR,
-                    int,
-                    LPSIZE
-                    );
-
-WINBOOL
-STDCALL
-GetTextExtentExPointA(
-                    HDC,
-                    LPCSTR,
-                    int,
-                    int,
-                    LPINT,
-                    LPINT,
-                    LPSIZE
-                    );
-
-DWORD
-STDCALL
-GetCharacterPlacementA(HDC, LPCSTR, int, int, LPGCP_RESULTSA, DWORD);
-
-HDC
-STDCALL
-ResetDCA(HDC, CONST DEVMODEA *);
-
-WINBOOL
-STDCALL
-RemoveFontResourceA(LPCSTR);
-
-HENHMETAFILE
-STDCALL
-CopyEnhMetaFileA(HENHMETAFILE, LPCSTR);
-
-HDC
-STDCALL
-CreateEnhMetaFileA(HDC, LPCSTR, CONST RECT *, LPCSTR);
-
-HENHMETAFILE
-STDCALL
-GetEnhMetaFileA(LPCSTR);
-
-UINT
-STDCALL
-GetEnhMetaFileDescriptionA(HENHMETAFILE, UINT, LPSTR );
-
-WINBOOL
-STDCALL
-GetTextMetricsA(HDC, LPTEXTMETRICA);
-
-int
-STDCALL
-StartDocA(HDC, CONST DOCINFOA *);
-
-int
-STDCALL
-GetObjectA(HGDIOBJ, int, LPVOID);
-
-WINBOOL
-STDCALL
-TextOutA(HDC, int, int, LPCSTR, int);
-
-WINBOOL
-STDCALL
-ExtTextOutA(HDC, int, int, UINT, CONST RECT *,LPCSTR, UINT, CONST INT *);
-
-WINBOOL
-STDCALL
-PolyTextOutA(HDC, CONST POLYTEXTA *, int); 
-
-int
-STDCALL
-GetTextFaceA(HDC, int, LPSTR);
-
-DWORD
-STDCALL
-GetKerningPairsA(HDC, DWORD, LPKERNINGPAIR);
-
-HCOLORSPACE
-STDCALL
-CreateColorSpaceA(LPLOGCOLORSPACEA);
-
-WINBOOL
-STDCALL
-GetLogColorSpaceA(HCOLORSPACE,LPLOGCOLORSPACEA,DWORD);
-
-WINBOOL
-STDCALL
-GetICMProfileA(HDC,DWORD,LPSTR);
-
-WINBOOL
-STDCALL
-SetICMProfileA(HDC,LPSTR);
-
-WINBOOL
-STDCALL
-UpdateICMRegKeyA(DWORD, DWORD, LPSTR, UINT);
-
-int
-STDCALL
-EnumICMProfilesA(HDC,ICMENUMPROCA,LPARAM);
-
-int
-STDCALL
-PropertySheetA(LPCPROPSHEETHEADERA lppsph);
-
-HIMAGELIST
-STDCALL
-ImageList_LoadImageA(HINSTANCE hi, LPCSTR lpbmp, int cx, int cGrow, COLORREF crMask, UINT uType, UINT uFlags);
-
-HWND
-STDCALL
-CreateStatusWindowA(LONG style, LPCSTR lpszText, HWND hwndParent, UINT wID);
-
-void
-STDCALL
-DrawStatusTextA(HDC hDC, LPRECT lprc, LPCSTR pszText, UINT uFlags);
-
-WINBOOL
-STDCALL
-GetOpenFileNameA(LPOPENFILENAMEA);
-
-WINBOOL
-STDCALL
-GetSaveFileNameA(LPOPENFILENAMEA);
-
-short
-STDCALL
-GetFileTitleA(LPCSTR, LPSTR, WORD);
-
-WINBOOL
-STDCALL
-ChooseColorA(LPCHOOSECOLORA);
-
-HWND
-STDCALL
-FindTextA(LPFINDREPLACEA);
-
-HWND
-STDCALL
-ReplaceTextA(LPFINDREPLACEA);
-
-WINBOOL
-STDCALL
-ChooseFontA(LPCHOOSEFONTA);
-
-WINBOOL
-STDCALL
-PrintDlgA(LPPRINTDLGA);
-
-WINBOOL
-STDCALL
-PageSetupDlgA( LPPAGESETUPDLGA );
-
-WINBOOL
-STDCALL
-CreateProcessA(
-    LPCSTR lpApplicationName,
-    LPSTR lpCommandLine,
-    LPSECURITY_ATTRIBUTES lpProcessAttributes,
-    LPSECURITY_ATTRIBUTES lpThreadAttributes,
-    WINBOOL bInheritHandles,
-    DWORD dwCreationFlags,
-    LPVOID lpEnvironment,
-    LPCSTR lpCurrentDirectory,
-    LPSTARTUPINFOA lpStartupInfo,
-    LPPROCESS_INFORMATION lpProcessInformation
-    );
-
-VOID
-STDCALL
-GetStartupInfoA(
-    LPSTARTUPINFOA lpStartupInfo
-    );
-
-WINBASEAPI
-HANDLE
-WINAPI
-FindFirstFileExA (
-       LPCSTR                  lpFileName,
-       FINDEX_INFO_LEVELS      fInfoLevelId,
-       LPVOID                  lpFindFileData,
-       FINDEX_SEARCH_OPS       fSearchOp,
-       LPVOID                  lpSearchFilter,
-       DWORD                   dwAdditionalFlags
-       );
-
-HANDLE
-STDCALL
-FindFirstFileA(
-    LPCSTR lpFileName,
-    LPWIN32_FIND_DATAA lpFindFileData
-    );
-
-WINBOOL
-STDCALL
-FindNextFileA(
-    HANDLE hFindFile,
-    LPWIN32_FIND_DATAA lpFindFileData
-    );
-
-WINBOOL
-STDCALL
-GetVersionExA(
-    LPOSVERSIONINFOA lpVersionInformation
-    );
-
-#define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\
-nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
-CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y,\
-nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
-
-#define CreateDialogA(hInstance, lpName, hWndParent, lpDialogFunc) \
-CreateDialogParamA(hInstance, lpName, hWndParent, lpDialogFunc, 0L)
-
-#define CreateDialogIndirectA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
-CreateDialogIndirectParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
-
-#define DialogBoxA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
-DialogBoxParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
-
-#define DialogBoxIndirectA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
-DialogBoxIndirectParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
-
-HDC
-STDCALL
-CreateDCA(LPCSTR, LPCSTR , LPCSTR , CONST DEVMODEA *);
-
-DWORD
-STDCALL
-VerInstallFileA(
-        DWORD uFlags,
-        LPSTR szSrcFileName,
-        LPSTR szDestFileName,
-        LPSTR szSrcDir,
-        LPSTR szDestDir,
-        LPSTR szCurDir,
-        LPSTR szTmpFile,
-        PUINT lpuTmpFileLen
-        );
-
-DWORD
-STDCALL
-GetFileVersionInfoSizeA(
-        LPSTR lptstrFilename,
-        LPDWORD lpdwHandle
-        );
-
-WINBOOL
-STDCALL
-GetFileVersionInfoA(
-        LPSTR lptstrFilename,
-        DWORD dwHandle,
-        DWORD dwLen,
-        LPVOID lpData
-        );
-
-DWORD
-STDCALL
-VerLanguageNameA(
-        DWORD wLang,
-        LPSTR szLang,
-        DWORD nSize
-        );
-
-WINBOOL
-STDCALL
-VerQueryValueA(
-        const LPVOID pBlock,
-        LPSTR lpSubBlock,
-        LPVOID * lplpBuffer,
-        PUINT puLen
-        );
-
-DWORD
-STDCALL
-VerFindFileA(
-        DWORD uFlags,
-        LPSTR szFileName,
-        LPSTR szWinDir,
-        LPSTR szAppDir,
-        LPSTR szCurDir,
-        PUINT lpuCurDirLen,
-        LPSTR szDestDir,
-        PUINT lpuDestDirLen
-        );
-
-LONG
-STDCALL
-RegConnectRegistryA (
-    LPCSTR lpMachineName,
-    HKEY hKey,
-    PHKEY phkResult
-    );
-
-LONG
-STDCALL
-RegCreateKeyA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    PHKEY phkResult
-    );
-
-LONG
-STDCALL
-RegCreateKeyExA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    DWORD Reserved,
-    LPSTR lpClass,
-    DWORD dwOptions,
-    REGSAM samDesired,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
-    PHKEY phkResult,
-    LPDWORD lpdwDisposition
-    );
-
-LONG
-STDCALL
-RegDeleteKeyA (
-    HKEY hKey,
-    LPCSTR lpSubKey
-    );
-
-LONG
-STDCALL
-RegDeleteValueA (
-    HKEY hKey,
-    LPCSTR lpValueName
-    );
-
-LONG
-STDCALL
-RegEnumKeyA (
-    HKEY hKey,
-    DWORD dwIndex,
-    LPSTR lpName,
-    DWORD cbName
-    );
-
-LONG
-STDCALL
-RegEnumKeyExA (
-    HKEY hKey,
-    DWORD dwIndex,
-    LPSTR lpName,
-    LPDWORD lpcbName,
-    LPDWORD lpReserved,
-    LPSTR lpClass,
-    LPDWORD lpcbClass,
-    PFILETIME lpftLastWriteTime
-    );
-
-LONG
-STDCALL
-RegEnumValueA (
-    HKEY hKey,
-    DWORD dwIndex,
-    LPSTR lpValueName,
-    LPDWORD lpcbValueName,
-    LPDWORD lpReserved,
-    LPDWORD lpType,
-    LPBYTE lpData,
-    LPDWORD lpcbData
-    );
-
-LONG
-STDCALL
-RegLoadKeyA (
-    HKEY    hKey,
-    LPCSTR  lpSubKey,
-    LPCSTR  lpFile
-    );
-
-LONG
-STDCALL
-RegOpenKeyA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    PHKEY phkResult
-    );
-
-LONG
-STDCALL
-RegOpenKeyExA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    DWORD ulOptions,
-    REGSAM samDesired,
-    PHKEY phkResult
-    );
-
-LONG
-STDCALL
-RegQueryInfoKeyA (
-    HKEY hKey,
-    LPSTR lpClass,
-    LPDWORD lpcbClass,
-    LPDWORD lpReserved,
-    LPDWORD lpcSubKeys,
-    LPDWORD lpcbMaxSubKeyLen,
-    LPDWORD lpcbMaxClassLen,
-    LPDWORD lpcValues,
-    LPDWORD lpcbMaxValueNameLen,
-    LPDWORD lpcbMaxValueLen,
-    LPDWORD lpcbSecurityDescriptor,
-    PFILETIME lpftLastWriteTime
-    );
-
-LONG
-STDCALL
-RegQueryValueA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    LPSTR lpValue,
-    PLONG   lpcbValue
-    );
-
-LONG
-STDCALL
-RegQueryMultipleValuesA (
-    HKEY hKey,
-    PVALENTA val_list,
-    DWORD num_vals,
-    LPSTR lpValueBuf,
-    LPDWORD ldwTotsize
-    );
-
-LONG
-STDCALL
-RegQueryValueExA (
-    HKEY hKey,
-    LPCSTR lpValueName,
-    LPDWORD lpReserved,
-    LPDWORD lpType,
-    LPBYTE lpData,
-    LPDWORD lpcbData
-    );
-
-LONG
-STDCALL
-RegReplaceKeyA (
-    HKEY     hKey,
-    LPCSTR  lpSubKey,
-    LPCSTR  lpNewFile,
-    LPCSTR  lpOldFile
-    );
-
-LONG
-STDCALL
-RegRestoreKeyA (
-    HKEY hKey,
-    LPCSTR lpFile,
-    DWORD   dwFlags
-    );
-
-LONG
-STDCALL
-RegSaveKeyA (
-    HKEY hKey,
-    LPCSTR lpFile,
-    LPSECURITY_ATTRIBUTES lpSecurityAttributes
-    );
-
-LONG
-STDCALL
-RegSetValueA (
-    HKEY hKey,
-    LPCSTR lpSubKey,
-    DWORD dwType,
-    LPCSTR lpData,
-    DWORD cbData
-    );
-
-LONG
-STDCALL
-RegSetValueExA (
-    HKEY hKey,
-    LPCSTR lpValueName,
-    DWORD Reserved,
-    DWORD dwType,
-    CONST BYTE* lpData,
-    DWORD cbData
-    );
-
-LONG
-STDCALL
-RegUnLoadKeyA (
-    HKEY    hKey,
-    LPCSTR lpSubKey
-    );
-
-WINBOOL
-STDCALL
-InitiateSystemShutdownA(
-    LPSTR lpMachineName,
-    LPSTR lpMessage,
-    DWORD dwTimeout,
-    WINBOOL bForceAppsClosed,
-    WINBOOL bRebootAfterShutdown
-    );
-
-WINBOOL
-STDCALL
-AbortSystemShutdownA(
-    LPCSTR lpMachineName
-    );
-
-int
-STDCALL
-CompareStringA(
-    LCID     Locale,
-    DWORD    dwCmpFlags,
-    LPCSTR lpString1,
-    int      cchCount1,
-    LPCSTR lpString2,
-    int      cchCount2);
-
-int
-STDCALL
-LCMapStringA(
-    LCID     Locale,
-    DWORD    dwMapFlags,
-    LPCSTR lpSrcStr,
-    int      cchSrc,
-    LPSTR  lpDestStr,
-    int      cchDest);
-
-int
-STDCALL
-GetLocaleInfoA(
-    LCID     Locale,
-    LCTYPE   LCType,
-    LPSTR  lpLCData,
-    int      cchData);
-
-WINBOOL
-STDCALL
-SetLocaleInfoA(
-    LCID     Locale,
-    LCTYPE   LCType,
-    LPCSTR lpLCData);
-
-int
-STDCALL
-GetTimeFormatA(
-    LCID     Locale,
-    DWORD    dwFlags,
-    CONST SYSTEMTIME *lpTime,
-    LPCSTR lpFormat,
-    LPSTR  lpTimeStr,
-    int      cchTime);
-
-int
-STDCALL
-GetDateFormatA(
-    LCID     Locale,
-    DWORD    dwFlags,
-    CONST SYSTEMTIME *lpDate,
-    LPCSTR lpFormat,
-    LPSTR  lpDateStr,
-    int      cchDate);
-
-int
-STDCALL
-GetNumberFormatA(
-    LCID     Locale,
-    DWORD    dwFlags,
-    LPCSTR lpValue,
-    CONST NUMBERFMTA *lpFormat,
-    LPSTR  lpNumberStr,
-    int      cchNumber);
-
-int
-STDCALL
-GetCurrencyFormatA(
-    LCID     Locale,
-    DWORD    dwFlags,
-    LPCSTR lpValue,
-    CONST CURRENCYFMTA *lpFormat,
-    LPSTR  lpCurrencyStr,
-    int      cchCurrency);
-
-WINBOOL
-STDCALL
-EnumCalendarInfoA(
-    CALINFO_ENUMPROCA lpCalInfoEnumProc,
-    LCID              Locale,
-    CALID             Calendar,
-    CALTYPE           CalType);
-
-WINBOOL
-STDCALL
-EnumTimeFormatsA(
-    TIMEFMT_ENUMPROCA lpTimeFmtEnumProc,
-    LCID              Locale,
-    DWORD             dwFlags);
-
-WINBOOL
-STDCALL
-EnumDateFormatsA(
-    DATEFMT_ENUMPROCA lpDateFmtEnumProc,
-    LCID              Locale,
-    DWORD             dwFlags);
-
-WINBOOL
-STDCALL
-GetStringTypeExA(
-    LCID     Locale,
-    DWORD    dwInfoType,
-    LPCSTR lpSrcStr,
-    int      cchSrc,
-    LPWORD   lpCharType);
-
-WINBOOL
-STDCALL
-GetStringTypeA(
-    LCID     Locale,
-    DWORD    dwInfoType,
-    LPCSTR   lpSrcStr,
-    int      cchSrc,
-    LPWORD   lpCharType);
-
-
-int
-STDCALL
-FoldStringA(
-    DWORD    dwMapFlags,
-    LPCSTR lpSrcStr,
-    int      cchSrc,
-    LPSTR  lpDestStr,
-    int      cchDest);
-
-WINBOOL
-STDCALL
-EnumSystemLocalesA(
-    LOCALE_ENUMPROCA lpLocaleEnumProc,
-    DWORD            dwFlags);
-
-WINBOOL
-STDCALL
-EnumSystemCodePagesA(
-    CODEPAGE_ENUMPROCA lpCodePageEnumProc,
-    DWORD              dwFlags);
-
-WINBOOL
-STDCALL
-PeekConsoleInputA(
-    HANDLE hConsoleInput,
-    PINPUT_RECORD lpBuffer,
-    DWORD nLength,
-    LPDWORD lpNumberOfEventsRead
-    );
-
-WINBOOL
-STDCALL
-ReadConsoleInputA(
-    HANDLE hConsoleInput,
-    PINPUT_RECORD lpBuffer,
-    DWORD nLength,
-    LPDWORD lpNumberOfEventsRead
-    );
-
-WINBOOL
-STDCALL
-WriteConsoleInputA(
-    HANDLE hConsoleInput,
-    CONST INPUT_RECORD *lpBuffer,
-    DWORD nLength,
-    LPDWORD lpNumberOfEventsWritten
-    );
-
-WINBOOL
-STDCALL
-ReadConsoleOutputA(
-    HANDLE hConsoleOutput,
-    PCHAR_INFO lpBuffer,
-    COORD dwBufferSize,
-    COORD dwBufferCoord,
-    PSMALL_RECT lpReadRegion
-    );
-
-WINBOOL
-STDCALL
-WriteConsoleOutputA(
-    HANDLE hConsoleOutput,
-    CONST CHAR_INFO *lpBuffer,
-    COORD dwBufferSize,
-    COORD dwBufferCoord,
-    PSMALL_RECT lpWriteRegion
-    );
-
-WINBOOL
-STDCALL
-ReadConsoleOutputCharacterA(
-    HANDLE hConsoleOutput,
-    LPSTR lpCharacter,
-    DWORD nLength,
-    COORD dwReadCoord,
-    LPDWORD lpNumberOfCharsRead
-    );
-
-WINBOOL
-STDCALL
-WriteConsoleOutputCharacterA(
-    HANDLE hConsoleOutput,
-    LPCSTR lpCharacter,
-    DWORD nLength,
-    COORD dwWriteCoord,
-    LPDWORD lpNumberOfCharsWritten
-    );
-
-WINBOOL
-STDCALL
-FillConsoleOutputCharacterA(
-    HANDLE hConsoleOutput,
-    CHAR  cCharacter,
-    DWORD  nLength,
-    COORD  dwWriteCoord,
-    LPDWORD lpNumberOfCharsWritten
-    );
-
-WINBOOL
-STDCALL
-ScrollConsoleScreenBufferA(
-    HANDLE hConsoleOutput,
-    CONST SMALL_RECT *lpScrollRectangle,
-    CONST SMALL_RECT *lpClipRectangle,
-    COORD dwDestinationOrigin,
-    CONST CHAR_INFO *lpFill
-    );
-
-DWORD
-STDCALL
-GetConsoleTitleA(
-    LPSTR lpConsoleTitle,
-    DWORD nSize
-    );
-
-WINBOOL
-STDCALL
-SetConsoleTitleA(
-    LPCSTR lpConsoleTitle
-    );
-
-WINBOOL
-STDCALL
-ReadConsoleA(
-    HANDLE hConsoleInput,
-    LPVOID lpBuffer,
-    DWORD nNumberOfCharsToRead,
-    LPDWORD lpNumberOfCharsRead,
-    LPVOID lpReserved
-    );
-
-WINBOOL
-STDCALL
-WriteConsoleA(
-    HANDLE hConsoleOutput,
-    CONST VOID *lpBuffer,
-    DWORD nNumberOfCharsToWrite,
-    LPDWORD lpNumberOfCharsWritten,
-    LPVOID lpReserved
-    );
-
-DWORD STDCALL
-WNetAddConnectionA(
-     LPCSTR   lpRemoteName,
-     LPCSTR   lpPassword,
-     LPCSTR   lpLocalName
-    );
-
-DWORD STDCALL
-WNetAddConnection2A(
-     LPNETRESOURCEA lpNetResource,
-     LPCSTR       lpPassword,
-     LPCSTR       lpUserName,
-     DWORD          dwFlags
-    );
-
-DWORD STDCALL
-WNetAddConnection3A(
-     HWND           hwndOwner,
-     LPNETRESOURCEA lpNetResource,
-     LPCSTR       lpPassword,
-     LPCSTR       lpUserName,
-     DWORD          dwFlags
-    );
-
-DWORD STDCALL
-WNetCancelConnectionA(
-     LPCSTR lpName,
-     WINBOOL     fForce
-    );
-
-DWORD STDCALL
-WNetCancelConnection2A(
-     LPCSTR lpName,
-     DWORD    dwFlags,
-     WINBOOL     fForce
-    );
-
-DWORD STDCALL
-WNetGetConnectionA(
-     LPCSTR lpLocalName,
-     LPSTR  lpRemoteName,
-     LPDWORD  lpnLength
-    );
-
-DWORD STDCALL
-WNetUseConnectionA(
-    HWND            hwndOwner,
-    LPNETRESOURCEA  lpNetResource,
-    LPCSTR        lpUserID,
-    LPCSTR        lpPassword,
-    DWORD           dwFlags,
-    LPSTR         lpAccessName,
-    LPDWORD         lpBufferSize,
-    LPDWORD         lpResult
-    );
-
-DWORD STDCALL
-WNetSetConnectionA(
-    LPCSTR    lpName,
-    DWORD       dwProperties,
-    LPVOID      pvValues
-    );
-
-DWORD STDCALL
-WNetConnectionDialog1A(
-    LPCONNECTDLGSTRUCTA lpConnDlgStruct
-    );
-
-DWORD STDCALL
-WNetDisconnectDialog1A(
-    LPDISCDLGSTRUCTA lpConnDlgStruct
-    );
-
-DWORD STDCALL
-WNetOpenEnumA(
-     DWORD          dwScope,
-     DWORD          dwType,
-     DWORD          dwUsage,
-     LPNETRESOURCEA lpNetResource,
-     LPHANDLE       lphEnum
-    );
-
-DWORD STDCALL
-WNetEnumResourceA(
-     HANDLE  hEnum,
-     LPDWORD lpcCount,
-     LPVOID  lpBuffer,
-     LPDWORD lpBufferSize
-    );
-
-DWORD STDCALL
-WNetGetUniversalNameA(
-     LPCSTR lpLocalPath,
-     DWORD    dwInfoLevel,
-     LPVOID   lpBuffer,
-     LPDWORD  lpBufferSize
-     );
-
-DWORD STDCALL
-WNetGetUserA(
-     LPCSTR  lpName,
-     LPSTR   lpUserName,
-     LPDWORD   lpnLength
-    );
-
-DWORD STDCALL
-WNetGetProviderNameA(
-    DWORD   dwNetType,
-    LPSTR lpProviderName,
-    LPDWORD lpBufferSize
-    );
-
-DWORD STDCALL
-WNetGetNetworkInformationA(
-    LPCSTR          lpProvider,
-    LPNETINFOSTRUCT   lpNetInfoStruct
-    );
-
-DWORD STDCALL
-WNetGetLastErrorA(
-     LPDWORD    lpError,
-     LPSTR    lpErrorBuf,
-     DWORD      nErrorBufSize,
-     LPSTR    lpNameBuf,
-     DWORD      nNameBufSize
-    );
-
-DWORD STDCALL
-MultinetGetConnectionPerformanceA(
-        LPNETRESOURCEA lpNetResource,
-        LPNETCONNECTINFOSTRUCT lpNetConnectInfoStruct
-        );
-
-WINBOOL
-STDCALL
-ChangeServiceConfigA(
-    SC_HANDLE    hService,
-    DWORD        dwServiceType,
-    DWORD        dwStartType,
-    DWORD        dwErrorControl,
-    LPCSTR     lpBinaryPathName,
-    LPCSTR     lpLoadOrderGroup,
-    LPDWORD      lpdwTagId,
-    LPCSTR     lpDependencies,
-    LPCSTR     lpServiceStartName,
-    LPCSTR     lpPassword,
-    LPCSTR     lpDisplayName
-    );
-
-SC_HANDLE
-STDCALL
-CreateServiceA(
-    SC_HANDLE    hSCManager,
-    LPCSTR     lpServiceName,
-    LPCSTR     lpDisplayName,
-    DWORD        dwDesiredAccess,
-    DWORD        dwServiceType,
-    DWORD        dwStartType,
-    DWORD        dwErrorControl,
-    LPCSTR     lpBinaryPathName,
-    LPCSTR     lpLoadOrderGroup,
-    LPDWORD      lpdwTagId,
-    LPCSTR     lpDependencies,
-    LPCSTR     lpServiceStartName,
-    LPCSTR     lpPassword
-    );
-
-WINBOOL
-STDCALL
-EnumDependentServicesA(
-    SC_HANDLE               hService,
-    DWORD                   dwServiceState,
-    LPENUM_SERVICE_STATUSA  lpServices,
-    DWORD                   cbBufSize,
-    LPDWORD                 pcbBytesNeeded,
-    LPDWORD                 lpServicesReturned
-    );
-
-WINBOOL
-STDCALL
-EnumServicesStatusA(
-    SC_HANDLE               hSCManager,
-    DWORD                   dwServiceType,
-    DWORD                   dwServiceState,
-    LPENUM_SERVICE_STATUSA  lpServices,
-    DWORD                   cbBufSize,
-    LPDWORD                 pcbBytesNeeded,
-    LPDWORD                 lpServicesReturned,
-    LPDWORD                 lpResumeHandle
-    );
-
-WINBOOL
-STDCALL
-GetServiceKeyNameA(
-    SC_HANDLE               hSCManager,
-    LPCSTR                lpDisplayName,
-    LPSTR                 lpServiceName,
-    LPDWORD                 lpcchBuffer
-    );
-
-WINBOOL
-STDCALL
-GetServiceDisplayNameA(
-    SC_HANDLE               hSCManager,
-    LPCSTR                lpServiceName,
-    LPSTR                 lpDisplayName,
-    LPDWORD                 lpcchBuffer
-    );
-
-SC_HANDLE
-STDCALL
-OpenSCManagerA(
-    LPCSTR lpMachineName,
-    LPCSTR lpDatabaseName,
-    DWORD   dwDesiredAccess
-    );
-
-SC_HANDLE
-STDCALL
-OpenServiceA(
-    SC_HANDLE   hSCManager,
-    LPCSTR    lpServiceName,
-    DWORD       dwDesiredAccess
-    );
-
-WINBOOL
-STDCALL
-QueryServiceConfigA(
-    SC_HANDLE               hService,
-    LPQUERY_SERVICE_CONFIGA lpServiceConfig,
-    DWORD                   cbBufSize,
-    LPDWORD                 pcbBytesNeeded
-    );
-
-WINBOOL
-STDCALL
-QueryServiceLockStatusA(
-    SC_HANDLE                       hSCManager,
-    LPQUERY_SERVICE_LOCK_STATUSA    lpLockStatus,
-    DWORD                           cbBufSize,
-    LPDWORD                         pcbBytesNeeded
-    );
-
-SERVICE_STATUS_HANDLE
-STDCALL
-RegisterServiceCtrlHandlerA(
-    LPCSTR             lpServiceName,
-    LPHANDLER_FUNCTION   lpHandlerProc
-    );
-
-WINBOOL
-STDCALL
-StartServiceCtrlDispatcherA(
-                            LPSERVICE_TABLE_ENTRYA   lpServiceStartTable
-                           );
-
-WINBOOL
-STDCALL
-StartServiceA(
-             SC_HANDLE            hService,
-             DWORD                dwNumServiceArgs,
-             LPCSTR             *lpServiceArgVectors
-             );
-
-/* Extensions to OpenGL */
-
-WINBOOL STDCALL
-wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD);
-
-WINBOOL STDCALL
-wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT,
-                   FLOAT, int, LPGLYPHMETRICSFLOAT);
-
-/* ------------------------------------- */
-/* From shellapi.h in old Cygnus headers */
-
-unsigned int WINAPI
-DragQueryFileA(HDROP, unsigned int, char *, unsigned int);
-
-HICON WINAPI
-ExtractAssociatedIconA (HINSTANCE, char *, WORD *);
-
-HICON WINAPI
-ExtractIconA (HINSTANCE, const char *, unsigned int);
-
-HINSTANCE WINAPI
-FindExecutableA (const char *, const char *, char *);
-
-int WINAPI
-ShellAboutA (HWND, const char *, const char *, HICON);
-
-HINSTANCE WINAPI
-ShellExecuteA (HWND, const char *, const char *, char *, const char *, int);
-
-/* end of stuff from shellapi.h in old Cygnus headers */
-/* -------------------------------------------------- */
-/* From ddeml.h in old Cygnus headers */
-
-HSZ WINAPI
-DdeCreateStringHandleA (DWORD, char *, int);
-
-UINT WINAPI
-DdeInitializeA (DWORD *, CALLB, DWORD, DWORD);
-
-DWORD WINAPI
-DdeQueryStringA (DWORD, HSZ, char *, DWORD, int);
-
-/* end of stuff from ddeml.h in old Cygnus headers */
-/* ----------------------------------------------- */
-
-DWORD WINAPI
-SHGetFileInfoA (LPCSTR, DWORD, SHFILEINFO FAR *, UINT, UINT);
-
-WINBOOL WINAPI
-SHGetPathFromIDListA (LPCITEMIDLIST, LPSTR);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _GNU_H_WINDOWS32_ASCIIFUNCTIONS */
diff --git a/reactos/include/coff.h b/reactos/include/coff.h
deleted file mode 100644 (file)
index 4ec6a8f..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
-#ifndef __dj_include_coff_h_
-#define __dj_include_coff_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*** coff information for Intel 386/486.  */
-
-/********************** FILE HEADER **********************/
-
-struct external_filehdr {
-       unsigned short f_magic;         /* magic number                 */
-       unsigned short f_nscns;         /* number of sections           */
-       unsigned long f_timdat; /* time & date stamp            */
-       unsigned long f_symptr; /* file pointer to symtab       */
-       unsigned long f_nsyms;          /* number of symtab entries     */
-       unsigned short f_opthdr;        /* sizeof(optional hdr)         */
-       unsigned short f_flags;         /* flags                        */
-};
-
-
-/* Bits for f_flags:
- *     F_RELFLG        relocation info stripped from file
- *     F_EXEC          file is executable (no unresolved external references)
- *     F_LNNO          line numbers stripped from file
- *     F_LSYMS         local symbols stripped from file
- *     F_AR32WR        file has byte ordering of an AR32WR machine (e.g. vax)
- */
-
-#define F_RELFLG       (0x0001)
-#define F_EXEC         (0x0002)
-#define F_LNNO         (0x0004)
-#define F_LSYMS                (0x0008)
-
-
-
-#define        I386MAGIC       0x14c
-#define I386AIXMAGIC   0x175
-#define I386BADMAG(x) (((x).f_magic!=I386MAGIC) && (x).f_magic!=I386AIXMAGIC)
-
-
-#define        FILHDR  struct external_filehdr
-#define        FILHSZ  sizeof(FILHDR)
-
-
-/********************** AOUT "OPTIONAL HEADER" **********************/
-
-
-typedef struct 
-{
-  unsigned short       magic;          /* type of file                         */
-  unsigned short       vstamp;         /* version stamp                        */
-  unsigned long        tsize;          /* text size in bytes, padded to FW bdry*/
-  unsigned long        dsize;          /* initialized data "  "                */
-  unsigned long        bsize;          /* uninitialized data "   "             */
-  unsigned long        entry;          /* entry pt.                            */
-  unsigned long        text_start;     /* base of text used for this file */
-  unsigned long        data_start;     /* base of data used for this file */
-}
-AOUTHDR;
-
-
-typedef struct gnu_aout {
-       unsigned long info;
-       unsigned long tsize;
-       unsigned long dsize;
-       unsigned long bsize;
-       unsigned long symsize;
-       unsigned long entry;
-       unsigned long txrel;
-       unsigned long dtrel;
-       } GNU_AOUT;
-
-#define AOUTSZ (sizeof(AOUTHDR))
-
-#define OMAGIC          0404    /* object files, eg as output */
-#define ZMAGIC          0413    /* demand load format, eg normal ld output */
-#define STMAGIC                0401    /* target shlib */
-#define SHMAGIC                0443    /* host   shlib */
-
-
-/********************** SECTION HEADER **********************/
-
-
-struct external_scnhdr {
-       char            s_name[8];      /* section name                 */
-       unsigned long           s_paddr;        /* physical address, aliased s_nlib */
-       unsigned long           s_vaddr;        /* virtual address              */
-       unsigned long           s_size;         /* section size                 */
-       unsigned long           s_scnptr;       /* file ptr to raw data for section */
-       unsigned long           s_relptr;       /* file ptr to relocation       */
-       unsigned long           s_lnnoptr;      /* file ptr to line numbers     */
-       unsigned short          s_nreloc;       /* number of relocation entries */
-       unsigned short          s_nlnno;        /* number of line number entries*/
-       unsigned long           s_flags;        /* flags                        */
-};
-
-#define        SCNHDR  struct external_scnhdr
-#define        SCNHSZ  sizeof(SCNHDR)
-
-/*
- * names of "special" sections
- */
-#define _TEXT  ".text"
-#define _DATA  ".data"
-#define _BSS   ".bss"
-#define _COMMENT ".comment"
-#define _LIB ".lib"
-
-/*
- * s_flags "type"
- */
-#define STYP_TEXT       (0x0020)       /* section contains text only */
-#define STYP_DATA       (0x0040)       /* section contains data only */
-#define STYP_BSS        (0x0080)       /* section contains bss only */
-
-#include <pshpack1.h>
-
-/********************** LINE NUMBERS **********************/
-
-/* 1 line number entry for every "breakpointable" source line in a section.
- * Line numbers are grouped on a per function basis; first entry in a function
- * grouping will have l_lnno = 0 and in place of physical address will be the
- * symbol table index of the function name.
- */
-struct external_lineno {
-       union {
-               unsigned long l_symndx; /* function name symbol index, iff l_lnno == 0 */
-               unsigned long l_paddr;          /* (physical) address of line number */
-       } l_addr;
-       unsigned short l_lnno;                                          /* line number */
-};
-
-
-#define        LINENO  struct external_lineno
-#define        LINESZ  sizeof(LINENO)
-
-
-/********************** SYMBOLS **********************/
-
-#define E_SYMNMLEN     8       /* # characters in a symbol name        */
-#define E_FILNMLEN     14      /* # characters in a file name          */
-#define E_DIMNUM       4       /* # array dimensions in auxiliary entry */
-
-struct external_syment 
-{
-  union {
-    char e_name[E_SYMNMLEN];
-    struct {
-      unsigned long e_zeroes;
-      unsigned long e_offset;
-    } e;
-  } e;
-  unsigned long e_value;
-  short e_scnum;
-  unsigned short e_type;
-  unsigned char e_sclass;
-  unsigned char e_numaux;
-};
-
-#define N_BTMASK       (0xf)
-#define N_TMASK                (0x30)
-#define N_BTSHFT       (4)
-#define N_TSHIFT       (2)
-  
-union external_auxent {
-       struct {
-               unsigned long x_tagndx;         /* str, un, or enum tag indx */
-               union {
-                       struct {
-                           unsigned short  x_lnno;                             /* declaration line number */
-                           unsigned short  x_size;                             /* str/union/array size */
-                       } x_lnsz;
-                       unsigned long x_fsize;          /* size of function */
-               } x_misc;
-               union {
-                       struct {                                        /* if ISFCN, tag, or .bb */
-                           unsigned long x_lnnoptr;    /* ptr to fcn line # */
-                           unsigned long x_endndx;     /* entry ndx past block end */
-                       } x_fcn;
-                       struct {                                        /* if ISARY, up to 4 dimen. */
-                           unsigned short x_dimen[E_DIMNUM];
-                       } x_ary;
-               } x_fcnary;
-               unsigned short x_tvndx;                                         /* tv index */
-       } x_sym;
-
-       union {
-               char x_fname[E_FILNMLEN];
-               struct {
-                       unsigned long x_zeroes;
-                       unsigned long x_offset;
-               } x_n;
-       } x_file;
-
-       struct {
-               unsigned long x_scnlen;                                         /* section length */
-               unsigned short x_nreloc;                                        /* # relocation entries */
-               unsigned short x_nlinno;                                        /* # line numbers */
-       } x_scn;
-
-        struct {
-               unsigned long x_tvfill;                                         /* tv fill value */
-               unsigned short x_tvlen;                                         /* length of .tv */
-               unsigned short x_tvran[2];                                      /* tv range */
-       } x_tv;         /* info about .tv section (in auxent of symbol .tv)) */
-
-
-};
-
-#define        SYMENT  struct external_syment
-#define        SYMESZ  sizeof(SYMENT)
-#define        AUXENT  union external_auxent
-#define        AUXESZ  sizeof(AUXENT)
-
-
-#      define _ETEXT   "etext"
-
-
-/* Relocatable symbols have number of the section in which they are defined,
-   or one of the following: */
-
-#define N_UNDEF        ((short)0)      /* undefined symbol */
-#define N_ABS  ((short)-1)     /* value of symbol is absolute */
-#define N_DEBUG        ((short)-2)     /* debugging symbol -- value is meaningless */
-#define N_TV   ((short)-3)     /* indicates symbol needs preload transfer vector */
-#define P_TV   ((short)-4)     /* indicates symbol needs postload transfer vector*/
-
-/*
- * Type of a symbol, in low N bits of the word
- */
-#define T_NULL         0
-#define T_VOID         1       /* function argument (only used by compiler) */
-#define T_CHAR         2       /* character            */
-#define T_SHORT                3       /* short integer        */
-#define T_INT          4       /* integer              */
-#define T_LONG         5       /* long integer         */
-#define T_FLOAT                6       /* floating point       */
-#define T_DOUBLE       7       /* double word          */
-#define T_STRUCT       8       /* structure            */
-#define T_UNION                9       /* union                */
-#define T_ENUM         10      /* enumeration          */
-#define T_MOE          11      /* member of enumeration*/
-#define T_UCHAR                12      /* unsigned character   */
-#define T_USHORT       13      /* unsigned short       */
-#define T_UINT         14      /* unsigned integer     */
-#define T_ULONG                15      /* unsigned long        */
-#define T_LNGDBL       16      /* long double          */
-
-/*
- * derived types, in n_type
-*/
-#define DT_NON         (0)     /* no derived type */
-#define DT_PTR         (1)     /* pointer */
-#define DT_FCN         (2)     /* function */
-#define DT_ARY         (3)     /* array */
-
-#define BTYPE(x)       ((x) & N_BTMASK)
-
-#define ISPTR(x)       (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
-#define ISFCN(x)       (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
-#define ISARY(x)       (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
-#define ISTAG(x)       ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
-#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
-
-/********************** STORAGE CLASSES **********************/
-
-/* This used to be defined as -1, but now n_sclass is unsigned.  */
-#define C_EFCN         0xff    /* physical end of function     */
-#define C_NULL         0
-#define C_AUTO         1       /* automatic variable           */
-#define C_EXT          2       /* external symbol              */
-#define C_STAT         3       /* static                       */
-#define C_REG          4       /* register variable            */
-#define C_EXTDEF       5       /* external definition          */
-#define C_LABEL                6       /* label                        */
-#define C_ULABEL       7       /* undefined label              */
-#define C_MOS          8       /* member of structure          */
-#define C_ARG          9       /* function argument            */
-#define C_STRTAG       10      /* structure tag                */
-#define C_MOU          11      /* member of union              */
-#define C_UNTAG                12      /* union tag                    */
-#define C_TPDEF                13      /* type definition              */
-#define C_USTATIC      14      /* undefined static             */
-#define C_ENTAG                15      /* enumeration tag              */
-#define C_MOE          16      /* member of enumeration        */
-#define C_REGPARM      17      /* register parameter           */
-#define C_FIELD                18      /* bit field                    */
-#define C_AUTOARG      19      /* auto argument                */
-#define C_LASTENT      20      /* dummy entry (end of block)   */
-#define C_BLOCK                100     /* ".bb" or ".eb"               */
-#define C_FCN          101     /* ".bf" or ".ef"               */
-#define C_EOS          102     /* end of structure             */
-#define C_FILE         103     /* file name                    */
-#define C_LINE         104     /* line # reformatted as symbol table entry */
-#define C_ALIAS                105     /* duplicate tag                */
-#define C_HIDDEN       106     /* ext symbol in dmert public lib */
-
-/********************** RELOCATION DIRECTIVES **********************/
-
-
-
-struct external_reloc {
-  unsigned long r_vaddr;
-  unsigned long r_symndx;
-  unsigned short r_type;
-};
-
-#include <poppack.h>
-
-
-#define RELOC struct external_reloc
-#define RELSZ sizeof(RELOC)
-
-#define RELOC_REL32    20      /* 32-bit PC-relative address */
-#define RELOC_ADDR32   6       /* 32-bit absolute address */
-
-#define DEFAULT_DATA_SECTION_ALIGNMENT 4
-#define DEFAULT_BSS_SECTION_ALIGNMENT 4
-#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
-/* For new sections we havn't heard of before */
-#define DEFAULT_SECTION_ALIGNMENT 4
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !__dj_include_coff_h_ */
index f619681..f7e536f 100644 (file)
 #ifndef __WINE_D3D_H
 #define __WINE_D3D_H
 
-#include <ddraw.h>
+#include <stdlib.h>
+#include <objbase.h>
 #include <d3dtypes.h> /* must precede d3dcaps.h */
 #include <d3dcaps.h>
 
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_IDirect3D,              0x3BBA0080,0x2421,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID(IID_IDirect3D2,             0x6aae1ec1,0x662a,0x11d0,0x88,0x9d,0x00,0xaa,0x00,0xbb,0xb7,0x6a);
+DEFINE_GUID(IID_IDirect3D3,             0xbb223240,0xe72b,0x11d0,0xa9,0xb4,0x00,0xaa,0x00,0xc0,0x99,0x3e);
+DEFINE_GUID(IID_IDirect3D7,             0xf5049e77,0x4861,0x11d2,0xa4,0x07,0x00,0xa0,0xc9,0x06,0x29,0xa8);
+
+DEFINE_GUID(IID_IDirect3DRampDevice,   0xF2086B20,0x259F,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID(IID_IDirect3DRGBDevice,    0xA4665C60,0x2673,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID(IID_IDirect3DHALDevice,    0x84E63dE0,0x46AA,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DMMXDevice,    0x881949a1,0xd6f3,0x11d0,0x89,0xab,0x00,0xa0,0xc9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DRefDevice,     0x50936643,0x13e9,0x11d1,0x89,0xaa,0x00,0xa0,0xc9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DTnLHalDevice,  0xf5049e78,0x4861,0x11d2,0xa4,0x07,0x00,0xa0,0xc9,0x06,0x29,0xa8);
+DEFINE_GUID(IID_IDirect3DNullDevice,    0x8767df22,0xbacc,0x11d1,0x89,0x69,0x00,0xa0,0xc9,0x06,0x29,0xa8);
+
+DEFINE_GUID(IID_IDirect3DDevice,       0x64108800,0x957d,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DDevice2,      0x93281501,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DDevice3,       0xb0ab3b60,0x33d7,0x11d1,0xa9,0x81,0x00,0xc0,0x4f,0xd7,0xb1,0x74);
+DEFINE_GUID(IID_IDirect3DDevice7,       0xf5049e79,0x4861,0x11d2,0xa4,0x07,0x00,0xa0,0xc9,0x06,0x29,0xa8);
+
+DEFINE_GUID(IID_IDirect3DTexture,      0x2CDCD9E0,0x25A0,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID(IID_IDirect3DTexture2,     0x93281502,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+
+DEFINE_GUID(IID_IDirect3DLight,                0x4417C142,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+
+DEFINE_GUID(IID_IDirect3DMaterial,     0x4417C144,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DMaterial2,    0x93281503,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DMaterial3,     0xca9c46f4,0xd3c5,0x11d1,0xb7,0x5a,0x00,0x60,0x08,0x52,0xb3,0x12);
+
+DEFINE_GUID(IID_IDirect3DExecuteBuffer,        0x4417C145,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+
+DEFINE_GUID(IID_IDirect3DViewport,     0x4417C146,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DViewport2,    0x93281500,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DViewport3,     0xb0ab3b61,0x33d7,0x11d1,0xa9,0x81,0x00,0xc0,0x4f,0xd7,0xb1,0x74);
+
+DEFINE_GUID(IID_IDirect3DVertexBuffer,  0x7a503555,0x4a83,0x11d1,0xa5,0xdb,0x00,0xa0,0xc9,0x03,0x67,0xf8);
+DEFINE_GUID(IID_IDirect3DVertexBuffer7, 0xf5049e7d,0x4861,0x11d2,0xa4,0x07,0x00,0xa0,0xc9,0x06,0x29,0xa8);
+
+
+typedef struct IDirect3D             *LPDIRECT3D;
+typedef struct IDirect3D2             *LPDIRECT3D2;
+typedef struct IDirect3D3             *LPDIRECT3D3;
+typedef struct IDirect3D7             *LPDIRECT3D7;
+
+typedef struct IDirect3DLight         *LPDIRECT3DLIGHT;
+
+typedef struct IDirect3DDevice        *LPDIRECT3DDEVICE;
+typedef struct IDirect3DDevice2       *LPDIRECT3DDEVICE2;
+typedef struct IDirect3DDevice3       *LPDIRECT3DDEVICE3;
+typedef struct IDirect3DDevice7       *LPDIRECT3DDEVICE7;
+
+typedef struct IDirect3DViewport      *LPDIRECT3DVIEWPORT;
+typedef struct IDirect3DViewport2     *LPDIRECT3DVIEWPORT2;
+typedef struct IDirect3DViewport3     *LPDIRECT3DVIEWPORT3;
+
+typedef struct IDirect3DMaterial      *LPDIRECT3DMATERIAL;
+typedef struct IDirect3DMaterial2     *LPDIRECT3DMATERIAL2;
+typedef struct IDirect3DMaterial3     *LPDIRECT3DMATERIAL3;
+
+typedef struct IDirect3DTexture       *LPDIRECT3DTEXTURE;
+typedef struct IDirect3DTexture2      *LPDIRECT3DTEXTURE2;
+
+typedef struct IDirect3DExecuteBuffer *LPDIRECT3DEXECUTEBUFFER;
+
+typedef struct IDirect3DVertexBuffer  *LPDIRECT3DVERTEXBUFFER;
+typedef struct IDirect3DVertexBuffer7 *LPDIRECT3DVERTEXBUFFER7;
+
 /* ********************************************************************
    Error Codes
    ******************************************************************** */
 #define D3DERR_VIEWPORTHASNODEVICE      MAKE_DDHRESULT(774)
 #define D3DERR_NOCURRENTVIEWPORT        MAKE_DDHRESULT(775)
 #define D3DERR_INVALIDVERTEXFORMAT     MAKE_DDHRESULT(2048)
+#define D3DERR_COLORKEYATTACHED         MAKE_DDHRESULT(2050)
 #define D3DERR_VERTEXBUFFEROPTIMIZED   MAKE_DDHRESULT(2060)
 #define D3DERR_VBUF_CREATE_FAILED      MAKE_DDHRESULT(2061)
 #define D3DERR_VERTEXBUFFERLOCKED      MAKE_DDHRESULT(2062)
    Types and structures
    ******************************************************************** */
 typedef DWORD D3DVIEWPORTHANDLE, *LPD3DVIEWPORTHANDLE;
+
+
+/*****************************************************************************
+ * IDirect3D interface
+ */
+#define INTERFACE IDirect3D
+DECLARE_INTERFACE_(IDirect3D,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D methods ***/
+    STDMETHOD(Initialize)(THIS_ REFIID riid) PURE;
+    STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, LPVOID lpUserArg) PURE;
+    STDMETHOD(CreateLight)(THIS_ LPDIRECT3DLIGHT *lplpDirect3DLight, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateMaterial)(THIS_ LPDIRECT3DMATERIAL *lplpDirect3DMaterial, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateViewport)(THIS_ LPDIRECT3DVIEWPORT *lplpD3DViewport, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(FindDevice)(THIS_ LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lplpD3DDevice) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3D_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3D methods ***/
+#define IDirect3D_Initialize(p,a)       (p)->lpVtbl->Initialize(p,a)
+#define IDirect3D_EnumDevices(p,a,b)    (p)->lpVtbl->EnumDevices(p,a,b)
+#define IDirect3D_CreateLight(p,a,b)    (p)->lpVtbl->CreateLight(p,a,b)
+#define IDirect3D_CreateMaterial(p,a,b) (p)->lpVtbl->CreateMaterial(p,a,b)
+#define IDirect3D_CreateViewport(p,a,b) (p)->lpVtbl->CreateViewport(p,a,b)
+#define IDirect3D_FindDevice(p,a,b)     (p)->lpVtbl->FindDevice(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D_AddRef(p)             (p)->AddRef()
+#define IDirect3D_Release(p)            (p)->Release()
+/*** IDirect3D methods ***/
+#define IDirect3D_Initialize(p,a)       (p)->Initialize(a)
+#define IDirect3D_EnumDevices(p,a,b)    (p)->EnumDevices(a,b)
+#define IDirect3D_CreateLight(p,a,b)    (p)->CreateLight(a,b)
+#define IDirect3D_CreateMaterial(p,a,b) (p)->CreateMaterial(a,b)
+#define IDirect3D_CreateViewport(p,a,b) (p)->CreateViewport(a,b)
+#define IDirect3D_FindDevice(p,a,b)     (p)->FindDevice(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3D2 interface
+ */
+#define INTERFACE IDirect3D2
+DECLARE_INTERFACE_(IDirect3D2,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D2 methods ***/
+    STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, LPVOID lpUserArg) PURE;
+    STDMETHOD(CreateLight)(THIS_ LPDIRECT3DLIGHT *lplpDirect3DLight, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateMaterial)(THIS_ LPDIRECT3DMATERIAL2 *lplpDirect3DMaterial2, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateViewport)(THIS_ LPDIRECT3DVIEWPORT2 *lplpD3DViewport2, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(FindDevice)(THIS_ LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lpD3DFDR) PURE;
+    STDMETHOD(CreateDevice)(THIS_ REFCLSID rclsid, LPDIRECTDRAWSURFACE lpDDS, LPDIRECT3DDEVICE2 *lplpD3DDevice2) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3D2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3D2 methods ***/
+#define IDirect3D2_EnumDevices(p,a,b)    (p)->lpVtbl->EnumDevices(p,a,b)
+#define IDirect3D2_CreateLight(p,a,b)    (p)->lpVtbl->CreateLight(p,a,b)
+#define IDirect3D2_CreateMaterial(p,a,b) (p)->lpVtbl->CreateMaterial(p,a,b)
+#define IDirect3D2_CreateViewport(p,a,b) (p)->lpVtbl->CreateViewport(p,a,b)
+#define IDirect3D2_FindDevice(p,a,b)     (p)->lpVtbl->FindDevice(p,a,b)
+#define IDirect3D2_CreateDevice(p,a,b,c) (p)->lpVtbl->CreateDevice(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D2_AddRef(p)             (p)->AddRef()
+#define IDirect3D2_Release(p)            (p)->Release()
+/*** IDirect3D2 methods ***/
+#define IDirect3D2_EnumDevices(p,a,b)    (p)->EnumDevices(a,b)
+#define IDirect3D2_CreateLight(p,a,b)    (p)->CreateLight(a,b)
+#define IDirect3D2_CreateMaterial(p,a,b) (p)->CreateMaterial(a,b)
+#define IDirect3D2_CreateViewport(p,a,b) (p)->CreateViewport(a,b)
+#define IDirect3D2_FindDevice(p,a,b)     (p)->FindDevice(a,b)
+#define IDirect3D2_CreateDevice(p,a,b,c) (p)->CreateDevice(a,b,c)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3D3 interface
+ */
+#define INTERFACE IDirect3D3
+DECLARE_INTERFACE_(IDirect3D3,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D3 methods ***/
+    STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, LPVOID lpUserArg) PURE;
+    STDMETHOD(CreateLight)(THIS_ LPDIRECT3DLIGHT *lplpDirect3DLight, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateMaterial)(THIS_ LPDIRECT3DMATERIAL3 *lplpDirect3DMaterial3, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateViewport)(THIS_ LPDIRECT3DVIEWPORT3 *lplpD3DViewport3, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(FindDevice)(THIS_ LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lpD3DFDR) PURE;
+    STDMETHOD(CreateDevice)(THIS_ REFCLSID rclsid,LPDIRECTDRAWSURFACE4 lpDDS, LPDIRECT3DDEVICE3 *lplpD3DDevice3,LPUNKNOWN lpUnk) PURE;
+    STDMETHOD(CreateVertexBuffer)(THIS_ LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,LPDIRECT3DVERTEXBUFFER *lplpD3DVertBuf,DWORD dwFlags,LPUNKNOWN lpUnk) PURE;
+    STDMETHOD(EnumZBufferFormats)(THIS_ REFCLSID riidDevice,LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,LPVOID lpContext) PURE;
+    STDMETHOD(EvictManagedTextures)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D3_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3D3_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3D3 methods ***/
+#define IDirect3D3_EnumDevices(p,a,b)            (p)->lpVtbl->EnumDevices(p,a,b)
+#define IDirect3D3_CreateLight(p,a,b)            (p)->lpVtbl->CreateLight(p,a,b)
+#define IDirect3D3_CreateMaterial(p,a,b)         (p)->lpVtbl->CreateMaterial(p,a,b)
+#define IDirect3D3_CreateViewport(p,a,b)         (p)->lpVtbl->CreateViewport(p,a,b)
+#define IDirect3D3_FindDevice(p,a,b)             (p)->lpVtbl->FindDevice(p,a,b)
+#define IDirect3D3_CreateDevice(p,a,b,c,d)       (p)->lpVtbl->CreateDevice(p,a,b,c,d)
+#define IDirect3D3_CreateVertexBuffer(p,a,b,c,d) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d)
+#define IDirect3D3_EnumZBufferFormats(p,a,b,c)   (p)->lpVtbl->EnumZBufferFormats(p,a,b,c)
+#define IDirect3D3_EvictManagedTextures(p)       (p)->lpVtbl->EvictManagedTextures(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D3_AddRef(p)             (p)->AddRef()
+#define IDirect3D3_Release(p)            (p)->Release()
+/*** IDirect3D3 methods ***/
+#define IDirect3D3_EnumDevices(p,a,b)            (p)->EnumDevices(a,b)
+#define IDirect3D3_CreateLight(p,a,b)            (p)->CreateLight(a,b)
+#define IDirect3D3_CreateMaterial(p,a,b)         (p)->CreateMaterial(a,b)
+#define IDirect3D3_CreateViewport(p,a,b)         (p)->CreateViewport(a,b)
+#define IDirect3D3_FindDevice(p,a,b)             (p)->FindDevice(a,b)
+#define IDirect3D3_CreateDevice(p,a,b,c,d)       (p)->CreateDevice(a,b,c,d)
+#define IDirect3D3_CreateVertexBuffer(p,a,b,c,d) (p)->CreateVertexBuffer(a,b,c,d)
+#define IDirect3D3_EnumZBufferFormats(p,a,b,c)   (p)->EnumZBufferFormats(a,b,c)
+#define IDirect3D3_EvictManagedTextures(p)       (p)->EvictManagedTextures()
+#endif
+
+/*****************************************************************************
+ * IDirect3D7 interface
+ */
+#define INTERFACE IDirect3D7
+DECLARE_INTERFACE_(IDirect3D7,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D7 methods ***/
+    STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, LPVOID lpUserArg) PURE;
+    STDMETHOD(CreateDevice)(THIS_ REFCLSID rclsid,LPDIRECTDRAWSURFACE7 lpDDS, LPDIRECT3DDEVICE7 *lplpD3DDevice) PURE;
+    STDMETHOD(CreateVertexBuffer)(THIS_ LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc,LPDIRECT3DVERTEXBUFFER7 *lplpD3DVertBuf,DWORD dwFlags) PURE;
+    STDMETHOD(EnumZBufferFormats)(THIS_ REFCLSID riidDevice,LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback,LPVOID lpContext) PURE;
+    STDMETHOD(EvictManagedTextures)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D7_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3D7_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3D3 methods ***/
+#define IDirect3D7_EnumDevices(p,a,b)            (p)->lpVtbl->EnumDevices(p,a,b)
+#define IDirect3D7_CreateDevice(p,a,b,c)         (p)->lpVtbl->CreateDevice(p,a,b,c)
+#define IDirect3D7_CreateVertexBuffer(p,a,b,c)   (p)->lpVtbl->CreateVertexBuffer(p,a,b,c)
+#define IDirect3D7_EnumZBufferFormats(p,a,b,c)   (p)->lpVtbl->EnumZBufferFormats(p,a,b,c)
+#define IDirect3D7_EvictManagedTextures(p)       (p)->lpVtbl->EvictManagedTextures(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D7_AddRef(p)             (p)->AddRef()
+#define IDirect3D7_Release(p)            (p)->Release()
+/*** IDirect3D3 methods ***/
+#define IDirect3D7_EnumDevices(p,a,b)            (p)->EnumDevices(a,b)
+#define IDirect3D7_CreateDevice(p,a,b,c)         (p)->CreateDevice(a,b,c)
+#define IDirect3D7_CreateVertexBuffer(p,a,b,c)   (p)->CreateVertexBuffer(a,b,c)
+#define IDirect3D7_EnumZBufferFormats(p,a,b,c)   (p)->EnumZBufferFormats(a,b,c)
+#define IDirect3D7_EvictManagedTextures(p)       (p)->EvictManagedTextures()
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DLight interface
+ */
+#define INTERFACE IDirect3DLight
+DECLARE_INTERFACE_(IDirect3DLight,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DLight methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D) PURE;
+    STDMETHOD(SetLight)(THIS_ LPD3DLIGHT lpLight) PURE;
+    STDMETHOD(GetLight)(THIS_ LPD3DLIGHT lpLight) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DLight_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DLight_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DLight_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DLight methods ***/
+#define IDirect3DLight_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirect3DLight_SetLight(p,a)   (p)->lpVtbl->SetLight(p,a)
+#define IDirect3DLight_GetLight(p,a)   (p)->lpVtbl->GetLight(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DLight_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DLight_AddRef(p)             (p)->AddRef()
+#define IDirect3DLight_Release(p)            (p)->Release()
+/*** IDirect3DLight methods ***/
+#define IDirect3DLight_Initialize(p,a) (p)->Initialize(a)
+#define IDirect3DLight_SetLight(p,a)   (p)->SetLight(a)
+#define IDirect3DLight_GetLight(p,a)   (p)->GetLight(a)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DMaterial interface
+ */
+#define INTERFACE IDirect3DMaterial
+DECLARE_INTERFACE_(IDirect3DMaterial,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DMaterial methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D) PURE;
+    STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetHandle)(THIS_ LPDIRECT3DDEVICE lpDirect3DDevice, LPD3DMATERIALHANDLE lpHandle) PURE;
+    STDMETHOD(Reserve)(THIS) PURE;
+    STDMETHOD(Unreserve)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DMaterial_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DMaterial_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DMaterial_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DMaterial methods ***/
+#define IDirect3DMaterial_Initialize(p,a)  (p)->lpVtbl->Initialize(p,a)
+#define IDirect3DMaterial_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DMaterial_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DMaterial_GetHandle(p,a,b) (p)->lpVtbl->GetHandle(p,a,b)
+#define IDirect3DMaterial_Reserve(p)       (p)->lpVtbl->Reserve(p)
+#define IDirect3DMaterial_Unreserve(p)     (p)->lpVtbl->Unreserve(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DMaterial_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DMaterial_AddRef(p)             (p)->AddRef()
+#define IDirect3DMaterial_Release(p)            (p)->Release()
+/*** IDirect3DMaterial methods ***/
+#define IDirect3DMaterial_Initialize(p,a)  (p)->Initialize(a)
+#define IDirect3DMaterial_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DMaterial_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DMaterial_GetHandle(p,a,b) (p)->GetHandle(a,b)
+#define IDirect3DMaterial_Reserve(p)       (p)->Reserve()
+#define IDirect3DMaterial_Unreserve(p)     (p)->Unreserve()
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DMaterial2 interface
+ */
+#define INTERFACE IDirect3DMaterial2
+DECLARE_INTERFACE_(IDirect3DMaterial2,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DMaterial2 methods ***/
+    STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetHandle)(THIS_ LPDIRECT3DDEVICE2 lpDirect3DDevice2, LPD3DMATERIALHANDLE lpHandle) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DMaterial2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DMaterial2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DMaterial2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DMaterial2 methods ***/
+#define IDirect3DMaterial2_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DMaterial2_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DMaterial2_GetHandle(p,a,b) (p)->lpVtbl->GetHandle(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DMaterial2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DMaterial2_AddRef(p)             (p)->AddRef()
+#define IDirect3DMaterial2_Release(p)            (p)->Release()
+/*** IDirect3DMaterial2 methods ***/
+#define IDirect3DMaterial2_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DMaterial2_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DMaterial2_GetHandle(p,a,b) (p)->GetHandle(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DMaterial3 interface
+ */
+#define INTERFACE IDirect3DMaterial3
+DECLARE_INTERFACE_(IDirect3DMaterial3,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DMaterial3 methods ***/
+    STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL lpMat) PURE;
+    STDMETHOD(GetHandle)(THIS_ LPDIRECT3DDEVICE3 lpDirect3DDevice3, LPD3DMATERIALHANDLE lpHandle) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DMaterial3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DMaterial3_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DMaterial3_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DMaterial3 methods ***/
+#define IDirect3DMaterial3_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DMaterial3_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DMaterial3_GetHandle(p,a,b) (p)->lpVtbl->GetHandle(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DMaterial3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DMaterial3_AddRef(p)             (p)->AddRef()
+#define IDirect3DMaterial3_Release(p)            (p)->Release()
+/*** IDirect3DMaterial3 methods ***/
+#define IDirect3DMaterial3_SetMaterial(p,a) (p)->SetMaterial(a)
+#define IDirect3DMaterial3_GetMaterial(p,a) (p)->GetMaterial(a)
+#define IDirect3DMaterial3_GetHandle(p,a,b) (p)->GetHandle(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DTexture interface
+ */
+#define INTERFACE IDirect3DTexture
+DECLARE_INTERFACE_(IDirect3DTexture,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DTexture methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3DDEVICE lpDirect3DDevice, LPDIRECTDRAWSURFACE lpDDSurface) PURE;
+    STDMETHOD(GetHandle)(THIS_ LPDIRECT3DDEVICE lpDirect3DDevice, LPD3DTEXTUREHANDLE  lpHandle) PURE;
+    STDMETHOD(PaletteChanged)(THIS_ DWORD dwStart, DWORD dwCount) PURE;
+    STDMETHOD(Load)(THIS_ LPDIRECT3DTEXTURE lpD3DTexture) PURE;
+    STDMETHOD(Unload)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture methods ***/
+#define IDirect3DTexture_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirect3DTexture_GetHandle(p,a,b,c) (p)->lpVtbl->GetHandle(p,a,b,c)
+#define IDirect3DTexture_PaletteChanged(p,a,b,c) (p)->lpVtbl->PaletteChanged(p,a,b,c)
+#define IDirect3DTexture_Load(p,a,b,c) (p)->lpVtbl->Load(p,a,b,c)
+#define IDirect3DTexture_Unload(p,a,b,c) (p)->lpVtbl->Unload(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DTexture_AddRef(p)             (p)->AddRef()
+#define IDirect3DTexture_Release(p)            (p)->Release()
+/*** IDirect3DTexture methods ***/
+#define IDirect3DTexture_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#define IDirect3DTexture_GetHandle(p,a,b,c) (p)->GetHandle(a,b,c)
+#define IDirect3DTexture_PaletteChanged(p,a,b,c) (p)->PaletteChanged(a,b,c)
+#define IDirect3DTexture_Load(p,a,b,c) (p)->Load(a,b,c)
+#define IDirect3DTexture_Unload(p,a,b,c) (p)->Unload(a,b,c)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DTexture2 interface
+ */
+#define INTERFACE IDirect3DTexture2
+DECLARE_INTERFACE_(IDirect3DTexture2,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DTexture2 methods ***/
+    STDMETHOD(GetHandle)(THIS_ LPDIRECT3DDEVICE2 lpDirect3DDevice2, LPD3DTEXTUREHANDLE lpHandle) PURE;
+    STDMETHOD(PaletteChanged)(THIS_ DWORD dwStart, DWORD dwCount) PURE;
+    STDMETHOD(Load)(THIS_ LPDIRECT3DTEXTURE2 lpD3DTexture2) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture2 methods ***/
+#define IDirect3DTexture2_GetHandle(p,a,b)      (p)->lpVtbl->GetHandle(p,a,b)
+#define IDirect3DTexture2_PaletteChanged(p,a,b) (p)->lpVtbl->PaletteChanged(p,a,b)
+#define IDirect3DTexture2_Load(p,a)             (p)->lpVtbl->Load(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DTexture2_AddRef(p)             (p)->AddRef()
+#define IDirect3DTexture2_Release(p)            (p)->Release()
+/*** IDirect3DTexture2 methods ***/
+#define IDirect3DTexture2_GetHandle(p,a,b)      (p)->GetHandle(a,b)
+#define IDirect3DTexture2_PaletteChanged(p,a,b) (p)->PaletteChanged(a,b)
+#define IDirect3DTexture2_Load(p,a)             (p)->Load(a)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DViewport interface
+ */
+#define INTERFACE IDirect3DViewport
+DECLARE_INTERFACE_(IDirect3DViewport,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DViewport methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D) PURE;
+    STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(TransformVertices)(THIS_ DWORD dwVertexCount, LPD3DTRANSFORMDATA lpData, DWORD dwFlags, LPDWORD lpOffScreen) PURE;
+    STDMETHOD(LightElements)(THIS_ DWORD dwElementCount, LPD3DLIGHTDATA lpData) PURE;
+    STDMETHOD(SetBackground)(THIS_ D3DMATERIALHANDLE hMat) PURE;
+    STDMETHOD(GetBackground)(THIS_ LPD3DMATERIALHANDLE lphMat, LPBOOL lpValid) PURE;
+    STDMETHOD(SetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface) PURE;
+    STDMETHOD(GetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE *lplpDDSurface, LPBOOL lpValid) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags) PURE;
+    STDMETHOD(AddLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(DeleteLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(NextLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight, LPDIRECT3DLIGHT *lplpDirect3DLight, DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DViewport_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DViewport_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DViewport_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DViewport methods ***/
+#define IDirect3DViewport_Initialize(p,a)              (p)->lpVtbl->Initialize(p,a)
+#define IDirect3DViewport_GetViewport(p,a)             (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DViewport_SetViewport(p,a)             (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DViewport_TransformVertices(p,a,b,c,d) (p)->lpVtbl->TransformVertices(p,a,b,c,d)
+#define IDirect3DViewport_LightElements(p,a,b)         (p)->lpVtbl->LightElements(p,a,b)
+#define IDirect3DViewport_SetBackground(p,a)           (p)->lpVtbl->SetBackground(p,a)
+#define IDirect3DViewport_GetBackground(p,a,b)         (p)->lpVtbl->GetBackground(p,a,b)
+#define IDirect3DViewport_SetBackgroundDepth(p,a)      (p)->lpVtbl->SetBackgroundDepth(p,a)
+#define IDirect3DViewport_GetBackgroundDepth(p,a,b)    (p)->lpVtbl->GetBackgroundDepth(p,a,b)
+#define IDirect3DViewport_Clear(p,a,b,c)               (p)->lpVtbl->Clear(p,a,b,c)
+#define IDirect3DViewport_AddLight(p,a)                (p)->lpVtbl->AddLight(p,a)
+#define IDirect3DViewport_DeleteLight(p,a)             (p)->lpVtbl->DeleteLight(p,a)
+#define IDirect3DViewport_NextLight(p,a,b,c)           (p)->lpVtbl->NextLight(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DViewport_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DViewport_AddRef(p)             (p)->AddRef()
+#define IDirect3DViewport_Release(p)            (p)->Release()
+/*** IDirect3DViewport methods ***/
+#define IDirect3DViewport_Initialize(p,a)              (p)->Initialize(a)
+#define IDirect3DViewport_GetViewport(p,a)             (p)->GetViewport(a)
+#define IDirect3DViewport_SetViewport(p,a)             (p)->SetViewport(a)
+#define IDirect3DViewport_TransformVertices(p,a,b,c,d) (p)->TransformVertices(a,b,c,d)
+#define IDirect3DViewport_LightElements(p,a,b)         (p)->LightElements(a,b)
+#define IDirect3DViewport_SetBackground(p,a)           (p)->SetBackground(a)
+#define IDirect3DViewport_GetBackground(p,a,b)         (p)->GetBackground(a,b)
+#define IDirect3DViewport_SetBackgroundDepth(p,a)      (p)->SetBackgroundDepth(a)
+#define IDirect3DViewport_GetBackgroundDepth(p,a,b)    (p)->GetBackgroundDepth(a,b)
+#define IDirect3DViewport_Clear(p,a,b,c)               (p)->Clear(a,b,c)
+#define IDirect3DViewport_AddLight(p,a)                (p)->AddLight(a)
+#define IDirect3DViewport_DeleteLight(p,a)             (p)->DeleteLight(a)
+#define IDirect3DViewport_NextLight(p,a,b,c)           (p)->NextLight(a,b,c)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DViewport2 interface
+ */
+#define INTERFACE IDirect3DViewport2
+DECLARE_INTERFACE_(IDirect3DViewport2,IDirect3DViewport)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DViewport methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D) PURE;
+    STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(TransformVertices)(THIS_ DWORD dwVertexCount, LPD3DTRANSFORMDATA lpData, DWORD dwFlags, LPDWORD lpOffScreen) PURE;
+    STDMETHOD(LightElements)(THIS_ DWORD dwElementCount, LPD3DLIGHTDATA lpData) PURE;
+    STDMETHOD(SetBackground)(THIS_ D3DMATERIALHANDLE hMat) PURE;
+    STDMETHOD(GetBackground)(THIS_ LPD3DMATERIALHANDLE lphMat, LPBOOL lpValid) PURE;
+    STDMETHOD(SetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface) PURE;
+    STDMETHOD(GetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE *lplpDDSurface, LPBOOL lpValid) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags) PURE;
+    STDMETHOD(AddLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(DeleteLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(NextLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight, LPDIRECT3DLIGHT *lplpDirect3DLight, DWORD dwFlags) PURE;
+    /*** IDirect3DViewport2 methods ***/
+    STDMETHOD(GetViewport2)(THIS_ LPD3DVIEWPORT2 lpData) PURE;
+    STDMETHOD(SetViewport2)(THIS_ LPD3DVIEWPORT2 lpData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DViewport2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DViewport2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DViewport2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3Viewport methods ***/
+#define IDirect3DViewport2_Initialize(p,a)              (p)->lpVtbl->Initialize(p,a)
+#define IDirect3DViewport2_GetViewport(p,a)             (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DViewport2_SetViewport(p,a)             (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DViewport2_TransformVertices(p,a,b,c,d) (p)->lpVtbl->TransformVertices(p,a,b,c,d)
+#define IDirect3DViewport2_LightElements(p,a,b)         (p)->lpVtbl->LightElements(p,a,b)
+#define IDirect3DViewport2_SetBackground(p,a)           (p)->lpVtbl->SetBackground(p,a)
+#define IDirect3DViewport2_GetBackground(p,a,b)         (p)->lpVtbl->GetBackground(p,a,b)
+#define IDirect3DViewport2_SetBackgroundDepth(p,a)      (p)->lpVtbl->SetBackgroundDepth(p,a)
+#define IDirect3DViewport2_GetBackgroundDepth(p,a,b)    (p)->lpVtbl->GetBackgroundDepth(p,a,b)
+#define IDirect3DViewport2_Clear(p,a,b,c)               (p)->lpVtbl->Clear(p,a,b,c)
+#define IDirect3DViewport2_AddLight(p,a)                (p)->lpVtbl->AddLight(p,a)
+#define IDirect3DViewport2_DeleteLight(p,a)             (p)->lpVtbl->DeleteLight(p,a)
+#define IDirect3DViewport2_NextLight(p,a,b,c)           (p)->lpVtbl->NextLight(p,a,b,c)
+/*** IDirect3DViewport2 methods ***/
+#define IDirect3DViewport2_GetViewport2(p,a) (p)->lpVtbl->GetViewport2(p,a)
+#define IDirect3DViewport2_SetViewport2(p,a) (p)->lpVtbl->SetViewport2(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DViewport2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DViewport2_AddRef(p)             (p)->AddRef()
+#define IDirect3DViewport2_Release(p)            (p)->Release()
+/*** IDirect3Viewport methods ***/
+#define IDirect3DViewport2_Initialize(p,a)              (p)->Initialize(a)
+#define IDirect3DViewport2_GetViewport(p,a)             (p)->GetViewport(a)
+#define IDirect3DViewport2_SetViewport(p,a)             (p)->SetViewport(a)
+#define IDirect3DViewport2_TransformVertices(p,a,b,c,d) (p)->TransformVertices(a,b,c,d)
+#define IDirect3DViewport2_LightElements(p,a,b)         (p)->LightElements(a,b)
+#define IDirect3DViewport2_SetBackground(p,a)           (p)->SetBackground(a)
+#define IDirect3DViewport2_GetBackground(p,a,b)         (p)->GetBackground(a,b)
+#define IDirect3DViewport2_SetBackgroundDepth(p,a)      (p)->SetBackgroundDepth(a)
+#define IDirect3DViewport2_GetBackgroundDepth(p,a,b)    (p)->GetBackgroundDepth(a,b)
+#define IDirect3DViewport2_Clear(p,a,b,c)               (p)->Clear(a,b,c)
+#define IDirect3DViewport2_AddLight(p,a)                (p)->AddLight(a)
+#define IDirect3DViewport2_DeleteLight(p,a)             (p)->DeleteLight(a)
+#define IDirect3DViewport2_NextLight(p,a,b,c)           (p)->NextLight(a,b,c)
+/*** IDirect3DViewport2 methods ***/
+#define IDirect3DViewport2_GetViewport2(p,a) (p)->GetViewport2(a)
+#define IDirect3DViewport2_SetViewport2(p,a) (p)->SetViewport2(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DViewport3 interface
+ */
+#define INTERFACE IDirect3DViewport3
+DECLARE_INTERFACE_(IDirect3DViewport3,IDirect3DViewport2)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DViewport methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D) PURE;
+    STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT lpData) PURE;
+    STDMETHOD(TransformVertices)(THIS_ DWORD dwVertexCount, LPD3DTRANSFORMDATA lpData, DWORD dwFlags, LPDWORD lpOffScreen) PURE;
+    STDMETHOD(LightElements)(THIS_ DWORD dwElementCount, LPD3DLIGHTDATA lpData) PURE;
+    STDMETHOD(SetBackground)(THIS_ D3DMATERIALHANDLE hMat) PURE;
+    STDMETHOD(GetBackground)(THIS_ LPD3DMATERIALHANDLE lphMat, LPBOOL lpValid) PURE;
+    STDMETHOD(SetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface) PURE;
+    STDMETHOD(GetBackgroundDepth)(THIS_ LPDIRECTDRAWSURFACE *lplpDDSurface, LPBOOL lpValid) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags) PURE;
+    STDMETHOD(AddLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(DeleteLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight) PURE;
+    STDMETHOD(NextLight)(THIS_ LPDIRECT3DLIGHT lpDirect3DLight, LPDIRECT3DLIGHT *lplpDirect3DLight, DWORD dwFlags) PURE;
+    /*** IDirect3DViewport2 methods ***/
+    STDMETHOD(GetViewport2)(THIS_ LPD3DVIEWPORT2 lpData) PURE;
+    STDMETHOD(SetViewport2)(THIS_ LPD3DVIEWPORT2 lpData) PURE;
+    /*** IDirect3DViewport3 methods ***/
+    STDMETHOD(SetBackgroundDepth2)(THIS_ LPDIRECTDRAWSURFACE4 lpDDS) PURE;
+    STDMETHOD(GetBackgroundDepth2)(THIS_ LPDIRECTDRAWSURFACE4 *lplpDDS,LPBOOL lpValid) PURE;
+    STDMETHOD(Clear2)(THIS_ DWORD dwCount,LPD3DRECT lpRects,DWORD dwFlags,DWORD dwColor,D3DVALUE dvZ,DWORD dwStencil) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DViewport3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DViewport3_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DViewport3_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3Viewport methods ***/
+#define IDirect3DViewport3_Initialize(p,a)              (p)->lpVtbl->Initialize(p,a)
+#define IDirect3DViewport3_GetViewport(p,a)             (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DViewport3_SetViewport(p,a)             (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DViewport3_TransformVertices(p,a,b,c,d) (p)->lpVtbl->TransformVertices(p,a,b,c,d)
+#define IDirect3DViewport3_LightElements(p,a,b)         (p)->lpVtbl->LightElements(p,a,b)
+#define IDirect3DViewport3_SetBackground(p,a)           (p)->lpVtbl->SetBackground(p,a)
+#define IDirect3DViewport3_GetBackground(p,a,b)         (p)->lpVtbl->GetBackground(p,a,b)
+#define IDirect3DViewport3_SetBackgroundDepth(p,a)      (p)->lpVtbl->SetBackgroundDepth(p,a)
+#define IDirect3DViewport3_GetBackgroundDepth(p,a,b)    (p)->lpVtbl->GetBackgroundDepth(p,a,b)
+#define IDirect3DViewport3_Clear(p,a,b,c)               (p)->lpVtbl->Clear(p,a,b,c)
+#define IDirect3DViewport3_AddLight(p,a)                (p)->lpVtbl->AddLight(p,a)
+#define IDirect3DViewport3_DeleteLight(p,a)             (p)->lpVtbl->DeleteLight(p,a)
+#define IDirect3DViewport3_NextLight(p,a,b,c)           (p)->lpVtbl->NextLight(p,a,b,c)
+/*** IDirect3DViewport2 methods ***/
+#define IDirect3DViewport3_GetViewport3(p,a) (p)->lpVtbl->GetViewport2(p,a)
+#define IDirect3DViewport3_SetViewport3(p,a) (p)->lpVtbl->SetViewport2(p,a)
+/*** IDirect3DViewport3 methods ***/
+#define IDirect3DViewport3_SetBackgroundDepth2(p,a)   (p)->lpVtbl->SetBackgroundDepth2(p,a)
+#define IDirect3DViewport3_GetBackgroundDepth2(p,a,b) (p)->lpVtbl->GetBackgroundDepth2(p,a,b)
+#define IDirect3DViewport3_Clear2(p,a,b,c,d,e,f)      (p)->lpVtbl->Clear2(p,a,b,c,d,e,f)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DViewport3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DViewport3_AddRef(p)             (p)->AddRef()
+#define IDirect3DViewport3_Release(p)            (p)->Release()
+/*** IDirect3Viewport methods ***/
+#define IDirect3DViewport3_Initialize(p,a)              (p)->Initialize(a)
+#define IDirect3DViewport3_GetViewport(p,a)             (p)->GetViewport(a)
+#define IDirect3DViewport3_SetViewport(p,a)             (p)->SetViewport(a)
+#define IDirect3DViewport3_TransformVertices(p,a,b,c,d) (p)->TransformVertices(a,b,c,d)
+#define IDirect3DViewport3_LightElements(p,a,b)         (p)->LightElements(a,b)
+#define IDirect3DViewport3_SetBackground(p,a)           (p)->SetBackground(a)
+#define IDirect3DViewport3_GetBackground(p,a,b)         (p)->GetBackground(a,b)
+#define IDirect3DViewport3_SetBackgroundDepth(p,a)      (p)->SetBackgroundDepth(a)
+#define IDirect3DViewport3_GetBackgroundDepth(p,a,b)    (p)->GetBackgroundDepth(a,b)
+#define IDirect3DViewport3_Clear(p,a,b,c)               (p)->Clear(a,b,c)
+#define IDirect3DViewport3_AddLight(p,a)                (p)->AddLight(a)
+#define IDirect3DViewport3_DeleteLight(p,a)             (p)->DeleteLight(a)
+#define IDirect3DViewport3_NextLight(p,a,b,c)           (p)->NextLight(a,b,c)
+/*** IDirect3DViewport2 methods ***/
+#define IDirect3DViewport3_GetViewport3(p,a) (p)->GetViewport2(a)
+#define IDirect3DViewport3_SetViewport3(p,a) (p)->SetViewport2(a)
+/*** IDirect3DViewport3 methods ***/
+#define IDirect3DViewport3_SetBackgroundDepth2(p,a)   (p)->SetBackgroundDepth2(a)
+#define IDirect3DViewport3_GetBackgroundDepth2(p,a,b) (p)->GetBackgroundDepth2(a,b)
+#define IDirect3DViewport3_Clear2(p,a,b,c,d,e,f)      (p)->Clear2(a,b,c,d,e,f)
+#endif
+
+
+
+/*****************************************************************************
+ * IDirect3DExecuteBuffer interface
+ */
+#define INTERFACE IDirect3DExecuteBuffer
+DECLARE_INTERFACE_(IDirect3DExecuteBuffer,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DExecuteBuffer methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3DDEVICE lpDirect3DDevice, LPD3DEXECUTEBUFFERDESC lpDesc) PURE;
+    STDMETHOD(Lock)(THIS_ LPD3DEXECUTEBUFFERDESC lpDesc) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(SetExecuteData)(THIS_ LPD3DEXECUTEDATA lpData) PURE;
+    STDMETHOD(GetExecuteData)(THIS_ LPD3DEXECUTEDATA lpData) PURE;
+    STDMETHOD(Validate)(THIS_ LPDWORD lpdwOffset, LPD3DVALIDATECALLBACK lpFunc, LPVOID lpUserArg, DWORD dwReserved) PURE;
+    STDMETHOD(Optimize)(THIS_ DWORD dwDummy) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DExecuteBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DExecuteBuffer_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DExecuteBuffer_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DExecuteBuffer methods ***/
+#define IDirect3DExecuteBuffer_Initialize(p,a,b)   (p)->lpVtbl->Initialize(p,a,b)
+#define IDirect3DExecuteBuffer_Lock(p,a)           (p)->lpVtbl->Lock(p,a)
+#define IDirect3DExecuteBuffer_Unlock(p)           (p)->lpVtbl->Unlock(p)
+#define IDirect3DExecuteBuffer_SetExecuteData(p,a) (p)->lpVtbl->SetExecuteData(p,a)
+#define IDirect3DExecuteBuffer_GetExecuteData(p,a) (p)->lpVtbl->GetExecuteData(p,a)
+#define IDirect3DExecuteBuffer_Validate(p,a,b,c,d) (p)->lpVtbl->Validate(p,a,b,c,d)
+#define IDirect3DExecuteBuffer_Optimize(p,a)       (p)->lpVtbl->Optimize(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DExecuteBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DExecuteBuffer_AddRef(p)             (p)->AddRef()
+#define IDirect3DExecuteBuffer_Release(p)            (p)->Release()
+/*** IDirect3DExecuteBuffer methods ***/
+#define IDirect3DExecuteBuffer_Initialize(p,a,b)   (p)->Initialize(a,b)
+#define IDirect3DExecuteBuffer_Lock(p,a)           (p)->Lock(a)
+#define IDirect3DExecuteBuffer_Unlock(p)           (p)->Unlock()
+#define IDirect3DExecuteBuffer_SetExecuteData(p,a) (p)->SetExecuteData(a)
+#define IDirect3DExecuteBuffer_GetExecuteData(p,a) (p)->GetExecuteData(a)
+#define IDirect3DExecuteBuffer_Validate(p,a,b,c,d) (p)->Validate(a,b,c,d)
+#define IDirect3DExecuteBuffer_Optimize(p,a)       (p)->Optimize(a)
 #endif
+
+
+/*****************************************************************************
+ * IDirect3DDevice interface
+ */
+#define INTERFACE IDirect3DDevice
+DECLARE_INTERFACE_(IDirect3DDevice,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice methods ***/
+    STDMETHOD(Initialize)(THIS_ LPDIRECT3D lpDirect3D, LPGUID lpGUID, LPD3DDEVICEDESC lpD3DDVDesc) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC lpD3DHWDevDesc, LPD3DDEVICEDESC lpD3DHELDevDesc) PURE;
+    STDMETHOD(SwapTextureHandles)(THIS_ LPDIRECT3DTEXTURE lpD3Dtex1, LPDIRECT3DTEXTURE lpD3DTex2) PURE;
+    STDMETHOD(CreateExecuteBuffer)(THIS_ LPD3DEXECUTEBUFFERDESC lpDesc, LPDIRECT3DEXECUTEBUFFER *lplpDirect3DExecuteBuffer, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(GetStats)(THIS_ LPD3DSTATS lpD3DStats) PURE;
+    STDMETHOD(Execute)(THIS_ LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags) PURE;
+    STDMETHOD(AddViewport)(THIS_ LPDIRECT3DVIEWPORT lpDirect3DViewport) PURE;
+    STDMETHOD(DeleteViewport)(THIS_ LPDIRECT3DVIEWPORT lpDirect3DViewport) PURE;
+    STDMETHOD(NextViewport)(THIS_ LPDIRECT3DVIEWPORT lpDirect3DViewport, LPDIRECT3DVIEWPORT *lplpDirect3DViewport, DWORD dwFlags) PURE;
+    STDMETHOD(Pick)(THIS_ LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, LPDIRECT3DVIEWPORT lpDirect3DViewport, DWORD dwFlags, LPD3DRECT lpRect) PURE;
+    STDMETHOD(GetPickRecords)(THIS_ LPDWORD lpCount, LPD3DPICKRECORD lpD3DPickRec) PURE;
+    STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, LPVOID lpArg) PURE;
+    STDMETHOD(CreateMatrix)(THIS_ LPD3DMATRIXHANDLE lpD3DMatHandle) PURE;
+    STDMETHOD(SetMatrix)(THIS_ D3DMATRIXHANDLE D3DMatHandle, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(GetMatrix)(THIS_ D3DMATRIXHANDLE D3DMatHandle, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(DeleteMatrix)(THIS_ D3DMATRIXHANDLE D3DMatHandle) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D *lplpDirect3D) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice methods ***/
+#define IDirect3DDevice_Initialize(p,a,b,c)          (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirect3DDevice_GetCaps(p,a,b)               (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirect3DDevice_SwapTextureHandles(p,a,b)    (p)->lpVtbl->SwapTextureHandles(p,a,b)
+#define IDirect3DDevice_CreateExecuteBuffer(p,a,b,c) (p)->lpVtbl->CreateExecuteBuffer(p,a,b,c)
+#define IDirect3DDevice_GetStats(p,a)                (p)->lpVtbl->GetStats(p,a)
+#define IDirect3DDevice_Execute(p,a,b,c)             (p)->lpVtbl->Execute(p,a,b,c)
+#define IDirect3DDevice_AddViewport(p,a)             (p)->lpVtbl->AddViewport(p,a)
+#define IDirect3DDevice_DeleteViewport(p,a)          (p)->lpVtbl->DeleteViewport(p,a)
+#define IDirect3DDevice_NextViewport(p,a,b,c)        (p)->lpVtbl->NextViewport(p,a,b,c)
+#define IDirect3DDevice_Pick(p,a,b,c,d)              (p)->lpVtbl->Pick(p,a,b,c,d)
+#define IDirect3DDevice_GetPickRecords(p,a,b)        (p)->lpVtbl->GetPickRecords(p,a,b)
+#define IDirect3DDevice_EnumTextureFormats(p,a,b)    (p)->lpVtbl->EnumTextureFormats(p,a,b)
+#define IDirect3DDevice_CreateMatrix(p,a)            (p)->lpVtbl->CreateMatrix(p,a)
+#define IDirect3DDevice_SetMatrix(p,a,b)             (p)->lpVtbl->SetMatrix(p,a,b)
+#define IDirect3DDevice_GetMatrix(p,a,b)             (p)->lpVtbl->GetMatrix(p,a,b)
+#define IDirect3DDevice_DeleteMatrix(p,a)            (p)->lpVtbl->DeleteMatrix(p,a)
+#define IDirect3DDevice_BeginScene(p)                (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice_EndScene(p)                  (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice_GetDirect3D(p,a)             (p)->lpVtbl->GetDirect3D(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice_AddRef(p)             (p)->AddRef()
+#define IDirect3DDevice_Release(p)            (p)->Release()
+/*** IDirect3DDevice methods ***/
+#define IDirect3DDevice_Initialize(p,a,b,c)          (p)->Initialize(a,b,c)
+#define IDirect3DDevice_GetCaps(p,a,b)               (p)->GetCaps(a,b)
+#define IDirect3DDevice_SwapTextureHandles(p,a,b)    (p)->SwapTextureHandles(a,b)
+#define IDirect3DDevice_CreateExecuteBuffer(p,a,b,c) (p)->CreateExecuteBuffer(a,b,c)
+#define IDirect3DDevice_GetStats(p,a)                (p)->GetStats(a)
+#define IDirect3DDevice_Execute(p,a,b,c)             (p)->Execute(a,b,c)
+#define IDirect3DDevice_AddViewport(p,a)             (p)->AddViewport(a)
+#define IDirect3DDevice_DeleteViewport(p,a)          (p)->DeleteViewport(a)
+#define IDirect3DDevice_NextViewport(p,a,b,c)        (p)->NextViewport(a,b,c)
+#define IDirect3DDevice_Pick(p,a,b,c,d)              (p)->Pick(a,b,c,d)
+#define IDirect3DDevice_GetPickRecords(p,a,b)        (p)->GetPickRecords(a,b)
+#define IDirect3DDevice_EnumTextureFormats(p,a,b)    (p)->EnumTextureFormats(a,b)
+#define IDirect3DDevice_CreateMatrix(p,a)            (p)->CreateMatrix(a)
+#define IDirect3DDevice_SetMatrix(p,a,b)             (p)->SetMatrix(a,b)
+#define IDirect3DDevice_GetMatrix(p,a,b)             (p)->GetMatrix(a,b)
+#define IDirect3DDevice_DeleteMatrix(p,a)            (p)->DeleteMatrix(a)
+#define IDirect3DDevice_BeginScene(p)                (p)->BeginScene()
+#define IDirect3DDevice_EndScene(p)                  (p)->EndScene()
+#define IDirect3DDevice_GetDirect3D(p,a)             (p)->GetDirect3D(a)
+#endif
+
+
+/*****************************************************************************
+ * IDirect3DDevice2 interface
+ */
+#define INTERFACE IDirect3DDevice2
+DECLARE_INTERFACE_(IDirect3DDevice2,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice2 methods ***/
+    STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC lpD3DHWDevDesc, LPD3DDEVICEDESC lpD3DHELDevDesc) PURE;
+    STDMETHOD(SwapTextureHandles)(THIS_ LPDIRECT3DTEXTURE2 lpD3DTex1, LPDIRECT3DTEXTURE2 lpD3DTex2) PURE;
+    STDMETHOD(GetStats)(THIS_ LPD3DSTATS lpD3DStats) PURE;
+    STDMETHOD(AddViewport)(THIS_ LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) PURE;
+    STDMETHOD(DeleteViewport)(THIS_ LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) PURE;
+    STDMETHOD(NextViewport)(THIS_ LPDIRECT3DVIEWPORT2 lpDirect3DViewport2, LPDIRECT3DVIEWPORT2 *lplpDirect3DViewport2, DWORD dwFlags) PURE;
+    STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, LPVOID lpArg) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D2 *lplpDirect3D2) PURE;
+    /*** DrawPrimitive API ***/
+    STDMETHOD(SetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) PURE;
+    STDMETHOD(GetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT2 *lplpDirect3DViewport2) PURE;
+    STDMETHOD(SetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE lpNewRenderTarget, DWORD dwFlags) PURE;
+    STDMETHOD(GetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE *lplpRenderTarget) PURE;
+    STDMETHOD(Begin)(THIS_ D3DPRIMITIVETYPE d3dpt,D3DVERTEXTYPE dwVertexTypeDesc,DWORD dwFlags) PURE;
+    STDMETHOD(BeginIndexed)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType, LPVOID lpvVertices, DWORD dwNumVertices, DWORD dwFlags) PURE;
+    STDMETHOD(Vertex)(THIS_ LPVOID lpVertexType) PURE;
+    STDMETHOD(Index)(THIS_ WORD wVertexIndex) PURE;
+    STDMETHOD(End)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState) PURE;
+    STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState) PURE;
+    STDMETHOD(GetLightState)(THIS_ D3DLIGHTSTATETYPE dwLightStateType, LPDWORD lpdwLightState) PURE;
+    STDMETHOD(SetLightState)(THIS_ D3DLIGHTSTATETYPE dwLightStateType, DWORD dwLightState) PURE;
+    STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, LPWORD dwIndices, DWORD dwIndexCount, DWORD dwFlags) PURE;
+    STDMETHOD(SetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+    STDMETHOD(GetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice2 methods ***/
+#define IDirect3DDevice2_GetCaps(p,a,b)                        (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirect3DDevice2_SwapTextureHandles(p,a,b)             (p)->lpVtbl->SwapTextureHandles(p,a,b)
+#define IDirect3DDevice2_GetStats(p,a)                         (p)->lpVtbl->GetStats(p,a)
+#define IDirect3DDevice2_AddViewport(p,a)                      (p)->lpVtbl->AddViewport(p,a)
+#define IDirect3DDevice2_DeleteViewport(p,a)                   (p)->lpVtbl->DeleteViewport(p,a)
+#define IDirect3DDevice2_NextViewport(p,a,b,c)                 (p)->lpVtbl->NextViewport(p,a,b,c)
+#define IDirect3DDevice2_EnumTextureFormats(p,a,b)             (p)->lpVtbl->EnumTextureFormats(p,a,b)
+#define IDirect3DDevice2_BeginScene(p)                         (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice2_EndScene(p)                           (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice2_GetDirect3D(p,a)                      (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice2_SetCurrentViewport(p,a)               (p)->lpVtbl->SetCurrentViewport(p,a)
+#define IDirect3DDevice2_GetCurrentViewport(p,a)               (p)->lpVtbl->GetCurrentViewport(p,a)
+#define IDirect3DDevice2_SetRenderTarget(p,a,b)                (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice2_GetRenderTarget(p,a)                  (p)->lpVtbl->GetRenderTarget(p,a)
+#define IDirect3DDevice2_Begin(p,a,b,c)                        (p)->lpVtbl->Begin(p,a,b,c)
+#define IDirect3DDevice2_BeginIndexed(p,a,b,c,d,e)             (p)->lpVtbl->BeginIndexed(p,a,b,c,d,e)
+#define IDirect3DDevice2_Vertex(p,a)                           (p)->lpVtbl->Vertex(p,a)
+#define IDirect3DDevice2_Index(p,a)                            (p)->lpVtbl->Index(p,a)
+#define IDirect3DDevice2_End(p,a)                              (p)->lpVtbl->End(p,a)
+#define IDirect3DDevice2_GetRenderState(p,a,b)                 (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice2_SetRenderState(p,a,b)                 (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice2_GetLightState(p,a,b)                  (p)->lpVtbl->GetLightState(p,a,b)
+#define IDirect3DDevice2_SetLightState(p,a,b)                  (p)->lpVtbl->SetLightState(p,a,b)
+#define IDirect3DDevice2_SetTransform(p,a,b)                   (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice2_GetTransform(p,a,b)                   (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice2_MultiplyTransform(p,a,b)              (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice2_DrawPrimitive(p,a,b,c,d,e)            (p)->lpVtbl->DrawPrimitive(p,a,b,c,d,e)
+#define IDirect3DDevice2_DrawIndexedPrimitive(p,a,b,c,d,e,f,g) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice2_SetClipStatus(p,a)                    (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice2_GetClipStatus(p,a)                    (p)->lpVtbl->GetClipStatus(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice2_AddRef(p)             (p)->AddRef()
+#define IDirect3DDevice2_Release(p)            (p)->Release()
+/*** IDirect3DDevice2 methods ***/
+#define IDirect3DDevice2_GetCaps(p,a,b)                        (p)->GetCaps(a,b)
+#define IDirect3DDevice2_SwapTextureHandles(p,a,b)             (p)->SwapTextureHandles(a,b)
+#define IDirect3DDevice2_GetStats(p,a)                         (p)->GetStats(a)
+#define IDirect3DDevice2_AddViewport(p,a)                      (p)->AddViewport(a)
+#define IDirect3DDevice2_DeleteViewport(p,a)                   (p)->DeleteViewport(a)
+#define IDirect3DDevice2_NextViewport(p,a,b,c)                 (p)->NextViewport(a,b,c)
+#define IDirect3DDevice2_EnumTextureFormats(p,a,b)             (p)->EnumTextureFormats(a,b)
+#define IDirect3DDevice2_BeginScene(p)                         (p)->BeginScene()
+#define IDirect3DDevice2_EndScene(p)                           (p)->EndScene()
+#define IDirect3DDevice2_GetDirect3D(p,a)                      (p)->GetDirect3D(a)
+#define IDirect3DDevice2_SetCurrentViewport(p,a)               (p)->SetCurrentViewport(a)
+#define IDirect3DDevice2_GetCurrentViewport(p,a)               (p)->GetCurrentViewport(a)
+#define IDirect3DDevice2_SetRenderTarget(p,a,b)                (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice2_GetRenderTarget(p,a)                  (p)->GetRenderTarget(a)
+#define IDirect3DDevice2_Begin(p,a,b,c)                        (p)->Begin(a,b,c)
+#define IDirect3DDevice2_BeginIndexed(p,a,b,c,d,e)             (p)->BeginIndexed(a,b,c,d,e)
+#define IDirect3DDevice2_Vertex(p,a)                           (p)->Vertex(a)
+#define IDirect3DDevice2_Index(p,a)                            (p)->Index(a)
+#define IDirect3DDevice2_End(p,a)                              (p)->End(a)
+#define IDirect3DDevice2_GetRenderState(p,a,b)                 (p)->GetRenderState(a,b)
+#define IDirect3DDevice2_SetRenderState(p,a,b)                 (p)->SetRenderState(a,b)
+#define IDirect3DDevice2_GetLightState(p,a,b)                  (p)->GetLightState(a,b)
+#define IDirect3DDevice2_SetLightState(p,a,b)                  (p)->SetLightState(a,b)
+#define IDirect3DDevice2_SetTransform(p,a,b)                   (p)->SetTransform(a,b)
+#define IDirect3DDevice2_GetTransform(p,a,b)                   (p)->GetTransform(a,b)
+#define IDirect3DDevice2_MultiplyTransform(p,a,b)              (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice2_DrawPrimitive(p,a,b,c,d,e)            (p)->DrawPrimitive(a,b,c,d,e)
+#define IDirect3DDevice2_DrawIndexedPrimitive(p,a,b,c,d,e,f,g) (p)->DrawIndexedPrimitive(a,b,c,d,e,f,g)
+#define IDirect3DDevice2_SetClipStatus(p,a)                    (p)->SetClipStatus(a)
+#define IDirect3DDevice2_GetClipStatus(p,a)                    (p)->GetClipStatus(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice3 interface
+ */
+#define INTERFACE IDirect3DDevice3
+DECLARE_INTERFACE_(IDirect3DDevice3,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice3 methods ***/
+    STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC lpD3DHWDevDesc, LPD3DDEVICEDESC lpD3DHELDevDesc) PURE;
+    STDMETHOD(GetStats)(THIS_ LPD3DSTATS lpD3DStats) PURE;
+    STDMETHOD(AddViewport)(THIS_ LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) PURE;
+    STDMETHOD(DeleteViewport)(THIS_ LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) PURE;
+    STDMETHOD(NextViewport)(THIS_ LPDIRECT3DVIEWPORT3 lpDirect3DViewport3, LPDIRECT3DVIEWPORT3 *lplpDirect3DViewport3, DWORD dwFlags) PURE;
+    STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, LPVOID lpArg) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D3 *lplpDirect3D3) PURE;
+    /*** DrawPrimitive API ***/
+    STDMETHOD(SetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) PURE;
+    STDMETHOD(GetCurrentViewport)(THIS_ LPDIRECT3DVIEWPORT3 *lplpDirect3DViewport3) PURE;
+    STDMETHOD(SetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE4 lpNewRenderTarget, DWORD dwFlags) PURE;
+    STDMETHOD(GetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE4 *lplpRenderTarget) PURE;
+    STDMETHOD(Begin)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexTypeDesc, DWORD dwFlags) PURE;
+    STDMETHOD(BeginIndexed)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD d3dvtVertexType, LPVOID lpvVertices, DWORD dwNumVertices, DWORD dwFlags) PURE;
+    STDMETHOD(Vertex)(THIS_ LPVOID lpVertexType) PURE;
+    STDMETHOD(Index)(THIS_ WORD wVertexIndex) PURE;
+    STDMETHOD(End)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState) PURE;
+    STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState) PURE;
+    STDMETHOD(GetLightState)(THIS_ D3DLIGHTSTATETYPE dwLightStateType, LPDWORD lpdwLightState) PURE;
+    STDMETHOD(SetLightState)(THIS_ D3DLIGHTSTATETYPE dwLightStateType, DWORD dwLightState) PURE;
+    STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, LPWORD dwIndices, DWORD dwIndexCount, DWORD dwFlags) PURE;
+    STDMETHOD(SetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+    STDMETHOD(GetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+    STDMETHOD(DrawPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,DWORD dwVertexCount,DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,DWORD dwVertexCount,LPWORD lpIndex,DWORD dwIndexCount,DWORD dwFlags) PURE;
+    STDMETHOD(DrawPrimitiveVB)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,DWORD dwStartVertex,DWORD dwNumVertices,DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitiveVB)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf,LPWORD lpwIndices,DWORD dwIndexCount,DWORD dwFlags) PURE;
+    STDMETHOD(ComputeSphereVisibility)(THIS_ LPD3DVECTOR lpCenters,LPD3DVALUE lpRadii,DWORD dwNumSpheres,DWORD dwFlags,LPDWORD lpdwReturnValues) PURE;
+    STDMETHOD(GetTexture)(THIS_ DWORD dwStage,LPDIRECT3DTEXTURE2 *lplpTexture2) PURE;
+    STDMETHOD(SetTexture)(THIS_ DWORD dwStage,LPDIRECT3DTEXTURE2 lpTexture2) PURE;
+    STDMETHOD(GetTextureStageState)(THIS_ DWORD dwStage,D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,LPDWORD lpdwState) PURE;
+    STDMETHOD(SetTextureStageState)(THIS_ DWORD dwStage,D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,DWORD dwState) PURE;
+    STDMETHOD(ValidateDevice)(THIS_ LPDWORD lpdwPasses) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice3_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice3_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice3 methods ***/
+#define IDirect3DDevice3_GetCaps(p,a,b)                        (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirect3DDevice3_GetStats(p,a)                         (p)->lpVtbl->GetStats(p,a)
+#define IDirect3DDevice3_AddViewport(p,a)                      (p)->lpVtbl->AddViewport(p,a)
+#define IDirect3DDevice3_DeleteViewport(p,a)                   (p)->lpVtbl->DeleteViewport(p,a)
+#define IDirect3DDevice3_NextViewport(p,a,b,c)                 (p)->lpVtbl->NextViewport(p,a,b,c)
+#define IDirect3DDevice3_EnumTextureFormats(p,a,b)             (p)->lpVtbl->EnumTextureFormats(p,a,b)
+#define IDirect3DDevice3_BeginScene(p)                         (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice3_EndScene(p)                           (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice3_GetDirect3D(p,a)                      (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice3_SetCurrentViewport(p,a)               (p)->lpVtbl->SetCurrentViewport(p,a)
+#define IDirect3DDevice3_GetCurrentViewport(p,a)               (p)->lpVtbl->GetCurrentViewport(p,a)
+#define IDirect3DDevice3_SetRenderTarget(p,a,b)                (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice3_GetRenderTarget(p,a)                  (p)->lpVtbl->GetRenderTarget(p,a)
+#define IDirect3DDevice3_Begin(p,a,b,c)                        (p)->lpVtbl->Begin(p,a,b,c)
+#define IDirect3DDevice3_BeginIndexed(p,a,b,c,d,e)             (p)->lpVtbl->BeginIndexed(p,a,b,c,d,e)
+#define IDirect3DDevice3_Vertex(p,a)                           (p)->lpVtbl->Vertex(p,a)
+#define IDirect3DDevice3_Index(p,a)                            (p)->lpVtbl->Index(p,a)
+#define IDirect3DDevice3_End(p,a)                              (p)->lpVtbl->End(p,a)
+#define IDirect3DDevice3_GetRenderState(p,a,b)                 (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice3_SetRenderState(p,a,b)                 (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice3_GetLightState(p,a,b)                  (p)->lpVtbl->GetLightState(p,a,b)
+#define IDirect3DDevice3_SetLightState(p,a,b)                  (p)->lpVtbl->SetLightState(p,a,b)
+#define IDirect3DDevice3_SetTransform(p,a,b)                   (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice3_GetTransform(p,a,b)                   (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice3_MultiplyTransform(p,a,b)              (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice3_DrawPrimitive(p,a,b,c,d,e)            (p)->lpVtbl->DrawPrimitive(p,a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitive(p,a,b,c,d,e,f,g) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice3_SetClipStatus(p,a)                    (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice3_GetClipStatus(p,a)                    (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice3_DrawPrimitiveStrided(p,a,b,c,d,e)     (p)->lpVtbl->DrawPrimitiveStrided(p,a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g) (p)->lpVtbl->DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice3_DrawPrimitiveVB(p,a,b,c,d,e)          (p)->lpVtbl->DrawPrimitiveVB(p,a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitiveVB(p,a,b,c,d,e)   (p)->lpVtbl->DrawIndexedPrimitiveVB(p,a,b,c,d,e)
+#define IDirect3DDevice3_ComputeSphereVisibility(p,a,b,c,d,e)  (p)->lpVtbl->ComputeSphereVisibility(p,a,b,c,d,e)
+#define IDirect3DDevice3_GetTexture(p,a,b)                     (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice3_SetTexture(p,a,b)                     (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice3_GetTextureStageState(p,a,b,c)         (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice3_SetTextureStageState(p,a,b,c)         (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice3_ValidateDevice(p,a)                   (p)->lpVtbl->ValidateDevice(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice3_AddRef(p)             (p)->AddRef()
+#define IDirect3DDevice3_Release(p)            (p)->Release()
+/*** IDirect3DDevice3 methods ***/
+#define IDirect3DDevice3_GetCaps(p,a,b)                        (p)->GetCaps(a,b)
+#define IDirect3DDevice3_GetStats(p,a)                         (p)->GetStats(a)
+#define IDirect3DDevice3_AddViewport(p,a)                      (p)->AddViewport(a)
+#define IDirect3DDevice3_DeleteViewport(p,a)                   (p)->DeleteViewport(a)
+#define IDirect3DDevice3_NextViewport(p,a,b,c)                 (p)->NextViewport(a,b,c)
+#define IDirect3DDevice3_EnumTextureFormats(p,a,b)             (p)->EnumTextureFormats(a,b)
+#define IDirect3DDevice3_BeginScene(p)                         (p)->BeginScene()
+#define IDirect3DDevice3_EndScene(p)                           (p)->EndScene()
+#define IDirect3DDevice3_GetDirect3D(p,a)                      (p)->GetDirect3D(a)
+#define IDirect3DDevice3_SetCurrentViewport(p,a)               (p)->SetCurrentViewport(a)
+#define IDirect3DDevice3_GetCurrentViewport(p,a)               (p)->GetCurrentViewport(a)
+#define IDirect3DDevice3_SetRenderTarget(p,a,b)                (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice3_GetRenderTarget(p,a)                  (p)->GetRenderTarget(a)
+#define IDirect3DDevice3_Begin(p,a,b,c)                        (p)->Begin(a,b,c)
+#define IDirect3DDevice3_BeginIndexed(p,a,b,c,d,e)             (p)->BeginIndexed(a,b,c,d,e)
+#define IDirect3DDevice3_Vertex(p,a)                           (p)->Vertex(a)
+#define IDirect3DDevice3_Index(p,a)                            (p)->Index(a)
+#define IDirect3DDevice3_End(p,a)                              (p)->End(a)
+#define IDirect3DDevice3_GetRenderState(p,a,b)                 (p)->GetRenderState(a,b)
+#define IDirect3DDevice3_SetRenderState(p,a,b)                 (p)->SetRenderState(a,b)
+#define IDirect3DDevice3_GetLightState(p,a,b)                  (p)->GetLightState(a,b)
+#define IDirect3DDevice3_SetLightState(p,a,b)                  (p)->SetLightState(a,b)
+#define IDirect3DDevice3_SetTransform(p,a,b)                   (p)->SetTransform(a,b)
+#define IDirect3DDevice3_GetTransform(p,a,b)                   (p)->GetTransform(a,b)
+#define IDirect3DDevice3_MultiplyTransform(p,a,b)              (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice3_DrawPrimitive(p,a,b,c,d,e)            (p)->DrawPrimitive(a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitive(p,a,b,c,d,e,f,g) (p)->DrawIndexedPrimitive(a,b,c,d,e,f,g)
+#define IDirect3DDevice3_SetClipStatus(p,a)                    (p)->SetClipStatus(a)
+#define IDirect3DDevice3_GetClipStatus(p,a)                    (p)->GetClipStatus(a)
+#define IDirect3DDevice3_DrawPrimitiveStrided(p,a,b,c,d,e)     (p)->DrawPrimitiveStrided(a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g) (p)->DrawIndexedPrimitiveStrided(a,b,c,d,e,f,g)
+#define IDirect3DDevice3_DrawPrimitiveVB(p,a,b,c,d,e)          (p)->DrawPrimitiveVB(a,b,c,d,e)
+#define IDirect3DDevice3_DrawIndexedPrimitiveVB(p,a,b,c,d,e)   (p)->DrawIndexedPrimitiveVB(a,b,c,d,e)
+#define IDirect3DDevice3_ComputeSphereVisibility(p,a,b,c,d,e)  (p)->ComputeSphereVisibility(a,b,c,d,e)
+#define IDirect3DDevice3_GetTexture(p,a,b)                     (p)->GetTexture(a,b)
+#define IDirect3DDevice3_SetTexture(p,a,b)                     (p)->SetTexture(a,b)
+#define IDirect3DDevice3_GetTextureStageState(p,a,b,c)         (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice3_SetTextureStageState(p,a,b,c)         (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice3_ValidateDevice(p,a)                   (p)->ValidateDevice(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice7 interface
+ */
+#define INTERFACE IDirect3DDevice7
+DECLARE_INTERFACE_(IDirect3DDevice7,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice7 methods ***/
+    STDMETHOD(GetCaps)(THIS_ LPD3DDEVICEDESC7 lpD3DHELDevDesc) PURE;
+    STDMETHOD(EnumTextureFormats)(THIS_ LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, LPVOID lpArg) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ LPDIRECT3D7 *lplpDirect3D3) PURE;
+    STDMETHOD(SetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7 lpNewRenderTarget,DWORD dwFlags) PURE;
+    STDMETHOD(GetRenderTarget)(THIS_ LPDIRECTDRAWSURFACE7 *lplpRenderTarget) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD dwCount,LPD3DRECT lpRects,DWORD dwFlags,D3DCOLOR dwColor,D3DVALUE dvZ,DWORD dwStencil) PURE;
+    STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType, LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(SetViewport)(THIS_ LPD3DVIEWPORT7 lpData) PURE;
+    STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE dtstTransformStateType,LPD3DMATRIX lpD3DMatrix) PURE;
+    STDMETHOD(GetViewport)(THIS_ LPD3DVIEWPORT7 lpData) PURE;
+    STDMETHOD(SetMaterial)(THIS_ LPD3DMATERIAL7 lpMat) PURE;
+    STDMETHOD(GetMaterial)(THIS_ LPD3DMATERIAL7 lpMat) PURE;
+    STDMETHOD(SetLight)(THIS_ DWORD dwLightIndex,LPD3DLIGHT7 lpLight) PURE;
+    STDMETHOD(GetLight)(THIS_ DWORD dwLightIndex,LPD3DLIGHT7 lpLight) PURE;
+    STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState) PURE;
+    STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState) PURE;
+    STDMETHOD(BeginStateBlock)(THIS) PURE;
+    STDMETHOD(EndStateBlock)(THIS_ LPDWORD lpdwBlockHandle) PURE;
+    STDMETHOD(PreLoad)(THIS_ LPDIRECTDRAWSURFACE7 lpddsTexture) PURE;
+    STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD d3dvtVertexType, LPVOID lpvVertices, DWORD dwVertexCount, LPWORD dwIndices, DWORD dwIndexCount, DWORD dwFlags) PURE;
+    STDMETHOD(SetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+    STDMETHOD(GetClipStatus)(THIS_ LPD3DCLIPSTATUS lpD3DClipStatus) PURE;
+    STDMETHOD(DrawPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,DWORD dwVertexCount,DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitiveStrided)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexType,LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData,DWORD dwVertexCount,LPWORD lpIndex,DWORD dwIndexCount,DWORD dwFlags) PURE;
+    STDMETHOD(DrawPrimitiveVB)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,DWORD dwStartVertex,DWORD dwNumVertices,DWORD dwFlags) PURE;
+    STDMETHOD(DrawIndexedPrimitiveVB)(THIS_ D3DPRIMITIVETYPE d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf,DWORD dwStartVertex,DWORD dwNumVertices,LPWORD lpwIndices,DWORD dwIndexCount,DWORD dwFlags) PURE;
+    STDMETHOD(ComputeSphereVisibility)(THIS_ LPD3DVECTOR lpCenters,LPD3DVALUE lpRadii,DWORD dwNumSpheres,DWORD dwFlags,LPDWORD lpdwReturnValues) PURE;
+    STDMETHOD(GetTexture)(THIS_ DWORD dwStage,LPDIRECTDRAWSURFACE7 *lpTexture) PURE;
+    STDMETHOD(SetTexture)(THIS_ DWORD dwStage,LPDIRECTDRAWSURFACE7 lpTexture) PURE;
+    STDMETHOD(GetTextureStageState)(THIS_ DWORD dwStage,D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,LPDWORD lpdwState) PURE;
+    STDMETHOD(SetTextureStageState)(THIS_ DWORD dwStage,D3DTEXTURESTAGESTATETYPE d3dTexStageStateType,DWORD dwState) PURE;
+    STDMETHOD(ValidateDevice)(THIS_ LPDWORD lpdwPasses) PURE;
+    STDMETHOD(ApplyStateBlock)(THIS_ DWORD dwBlockHandle) PURE;
+    STDMETHOD(CaptureStateBlock)(THIS_ DWORD dwBlockHandle) PURE;
+    STDMETHOD(DeleteStateBlock)(THIS_ DWORD dwBlockHandle) PURE;
+    STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE d3dsbType,LPDWORD lpdwBlockHandle) PURE;
+    STDMETHOD(Load)(THIS_ LPDIRECTDRAWSURFACE7 lpDestTex,LPPOINT lpDestPoint,LPDIRECTDRAWSURFACE7 lpSrcTex,LPRECT lprcSrcRect,DWORD dwFlags) PURE;
+    STDMETHOD(LightEnable)(THIS_ DWORD dwLightIndex,BOOL bEnable) PURE;
+    STDMETHOD(GetLightEnable)(THIS_ DWORD dwLightIndex,BOOL *pbEnable) PURE;
+    STDMETHOD(SetClipPlane)(THIS_ DWORD dwIndex,D3DVALUE *pPlaneEquation) PURE;
+    STDMETHOD(GetClipPlane)(THIS_ DWORD dwIndex,D3DVALUE *pPlaneEquation) PURE;
+    STDMETHOD(GetInfo)(THIS_ DWORD dwDevInfoID,LPVOID pDevInfoStruct,DWORD dwSize) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice7_QueryInterface(p,a,b)                        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice7_AddRef(p)                                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice7_Release(p)                                   (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice7 methods ***/
+#define IDirect3DDevice7_GetCaps(p,a)                                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirect3DDevice7_EnumTextureFormats(p,a,b)                    (p)->lpVtbl->EnumTextureFormats(p,a,b)
+#define IDirect3DDevice7_BeginScene(p)                                (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice7_EndScene(p)                                  (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice7_GetDirect3D(p,a)                             (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice7_SetRenderTarget(p,a,b)                       (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice7_GetRenderTarget(p,a)                         (p)->lpVtbl->GetRenderTarget(p,a)
+#define IDirect3DDevice7_Clear(p,a,b,c,d,e,f)                         (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice7_SetTransform(p,a,b)                          (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice7_GetTransform(p,a,b)                          (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice7_SetViewport(p,a)                             (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice7_MultiplyTransform(p,a,b)                     (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice7_GetViewport(p,a)                             (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice7_SetMaterial(p,a)                             (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice7_GetMaterial(p,a)                             (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice7_SetLight(p,a,b)                              (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice7_GetLight(p,a,b)                              (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice7_SetRenderState(p,a,b)                        (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice7_GetRenderState(p,a,b)                        (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice7_BeginStateBlock(p)                           (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice7_EndStateBlock(p,a)                           (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice7_PreLoad(p,a)                                 (p)->lpVtbl->PreLoad(p,a)
+#define IDirect3DDevice7_DrawPrimitive(p,a,b,c,d,e)                   (p)->lpVtbl->DrawPrimitive(p,a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitive(p,a,b,c,d,e,f,g)        (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice7_SetClipStatus(p,a)                           (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice7_GetClipStatus(p,a)                           (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice7_DrawPrimitiveStrided(p,a,b,c,d,e)            (p)->lpVtbl->DrawPrimitiveStrided(p,a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g) (p)->lpVtbl->DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice7_DrawPrimitiveVB(p,a,b,c,d,e)                 (p)->lpVtbl->DrawPrimitiveVB(p,a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitiveVB(p,a,b,c,d,e,f,g)      (p)->lpVtbl->DrawIndexedPrimitiveVB(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice7_ComputeSphereVisibility(p,a,b,c,d,e)         (p)->lpVtbl->ComputeSphereVisibility(p,a,b,c,d,e)
+#define IDirect3DDevice7_GetTexture(p,a,b)                            (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice7_SetTexture(p,a,b)                            (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice7_GetTextureStageState(p,a,b,c)                (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice7_SetTextureStageState(p,a,b,c)                (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice7_ValidateDevice(p,a)                          (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice7_ApplyStateBlock(p,a)                         (p)->lpVtbl->ApplyStateBlock(p,a)
+#define IDirect3DDevice7_CaptureStateBlock(p,a)                       (p)->lpVtbl->CaptureStateBlock(p,a)
+#define IDirect3DDevice7_DeleteStateBlock(p,a)                        (p)->lpVtbl->DeleteStateBlock(p,a)
+#define IDirect3DDevice7_CreateStateBlock(p,a,b)                      (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice7_Load(p,a,b,c,d,e)                            (p)->lpVtbl->Load(p,a,b,c,d,e)
+#define IDirect3DDevice7_LightEnable(p,a,b)                           (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice7_GetLightEnable(p,a,b)                        (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice7_SetClipPlane(p,a,b)                          (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice7_GetClipPlane(p,a,b)                          (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice7_GetInfo(p,a,b,c)                             (p)->lpVtbl->GetInfo(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice7_QueryInterface(p,a,b)                        (p)->QueryInterface(a,b)
+#define IDirect3DDevice7_AddRef(p)                                    (p)->AddRef()
+#define IDirect3DDevice7_Release(p)                                   (p)->Release()
+/*** IDirect3DDevice7 methods ***/
+#define IDirect3DDevice7_GetCaps(p,a)                                 (p)->GetCaps(a)
+#define IDirect3DDevice7_EnumTextureFormats(p,a,b)                    (p)->EnumTextureFormats(a,b)
+#define IDirect3DDevice7_BeginScene(p)                                (p)->BeginScene()
+#define IDirect3DDevice7_EndScene(p)                                  (p)->EndScene()
+#define IDirect3DDevice7_GetDirect3D(p,a)                             (p)->GetDirect3D(a)
+#define IDirect3DDevice7_SetRenderTarget(p,a,b)                       (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice7_GetRenderTarget(p,a)                         (p)->GetRenderTarget(a)
+#define IDirect3DDevice7_Clear(p,a,b,c,d,e,f)                         (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice7_SetTransform(p,a,b)                          (p)->SetTransform(a,b)
+#define IDirect3DDevice7_GetTransform(p,a,b)                          (p)->GetTransform(a,b)
+#define IDirect3DDevice7_SetViewport(p,a)                             (p)->SetViewport(a)
+#define IDirect3DDevice7_MultiplyTransform(p,a,b)                     (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice7_GetViewport(p,a)                             (p)->GetViewport(a)
+#define IDirect3DDevice7_SetMaterial(p,a)                             (p)->SetMaterial(a)
+#define IDirect3DDevice7_GetMaterial(p,a)                             (p)->GetMaterial(a)
+#define IDirect3DDevice7_SetLight(p,a,b)                              (p)->SetLight(a,b)
+#define IDirect3DDevice7_GetLight(p,a,b)                              (p)->GetLight(a,b)
+#define IDirect3DDevice7_SetRenderState(p,a,b)                        (p)->SetRenderState(a,b)
+#define IDirect3DDevice7_GetRenderState(p,a,b)                        (p)->GetRenderState(a,b)
+#define IDirect3DDevice7_BeginStateBlock(p)                           (p)->BeginStateBlock()
+#define IDirect3DDevice7_EndStateBlock(p,a)                           (p)->EndStateBlock(a)
+#define IDirect3DDevice7_PreLoad(p,a)                                 (p)->PreLoad(a)
+#define IDirect3DDevice7_DrawPrimitive(p,a,b,c,d,e)                   (p)->DrawPrimitive(a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitive(p,a,b,c,d,e,f,g)        (p)->DrawIndexedPrimitive(a,b,c,d,e,f,g)
+#define IDirect3DDevice7_SetClipStatus(p,a)                           (p)->SetClipStatus(a)
+#define IDirect3DDevice7_GetClipStatus(p,a)                           (p)->GetClipStatus(a)
+#define IDirect3DDevice7_DrawPrimitiveStrided(p,a,b,c,d,e)            (p)->DrawPrimitiveStrided(a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f,g) (p)->DrawIndexedPrimitiveStrided(a,b,c,d,e,f,g)
+#define IDirect3DDevice7_DrawPrimitiveVB(p,a,b,c,d,e)                 (p)->DrawPrimitiveVB(a,b,c,d,e)
+#define IDirect3DDevice7_DrawIndexedPrimitiveVB(p,a,b,c,d,e,f,g)      (p)->DrawIndexedPrimitiveVB(a,b,c,d,e,f,g)
+#define IDirect3DDevice7_ComputeSphereVisibility(p,a,b,c,d,e)         (p)->ComputeSphereVisibility(a,b,c,d,e)
+#define IDirect3DDevice7_GetTexture(p,a,b)                            (p)->GetTexture(a,b)
+#define IDirect3DDevice7_SetTexture(p,a,b)                            (p)->SetTexture(a,b)
+#define IDirect3DDevice7_GetTextureStageState(p,a,b,c)                (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice7_SetTextureStageState(p,a,b,c)                (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice7_ValidateDevice(p,a)                          (p)->ValidateDevice(a)
+#define IDirect3DDevice7_ApplyStateBlock(p,a)                         (p)->ApplyStateBlock(a)
+#define IDirect3DDevice7_CaptureStateBlock(p,a)                       (p)->CaptureStateBlock(a)
+#define IDirect3DDevice7_DeleteStateBlock(p,a)                        (p)->DeleteStateBlock(a)
+#define IDirect3DDevice7_CreateStateBlock(p,a,b)                      (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice7_Load(p,a,b,c,d,e)                            (p)->Load(a,b,c,d,e)
+#define IDirect3DDevice7_LightEnable(p,a,b)                           (p)->LightEnable(a,b)
+#define IDirect3DDevice7_GetLightEnable(p,a,b)                        (p)->GetLightEnable(a,b)
+#define IDirect3DDevice7_SetClipPlane(p,a,b)                          (p)->SetClipPlane(a,b)
+#define IDirect3DDevice7_GetClipPlane(p,a,b)                          (p)->GetClipPlane(a,b)
+#define IDirect3DDevice7_GetInfo(p,a,b,c)                             (p)->GetInfo(a,b,c)
+#endif
+
+
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer interface
+ */
+#define INTERFACE IDirect3DVertexBuffer
+DECLARE_INTERFACE_(IDirect3DVertexBuffer,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVertexBuffer methods ***/
+    STDMETHOD(Lock)(THIS_ DWORD dwFlags,LPVOID *lplpData,LPDWORD lpdwSize) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(ProcessVertices)(THIS_ DWORD dwVertexOp,DWORD dwDestIndex,DWORD dwCount,LPDIRECT3DVERTEXBUFFER lpSrcBuffer,DWORD dwSrcIndex,LPDIRECT3DDEVICE3 lpD3DDevice,DWORD dwFlags) PURE;
+    STDMETHOD(GetVertexBufferDesc)(THIS_ LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc) PURE;
+    STDMETHOD(Optimize)(THIS_ LPDIRECT3DDEVICE3  lpD3DDevice,DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer methods ***/
+#define IDirect3DVertexBuffer_Lock(p,a,b,c)                    (p)->lpVtbl->Lock(p,a,b,c)
+#define IDirect3DVertexBuffer_Unlock(p)                        (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer_ProcessVertices(p,a,b,c,d,e,f,g) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f,g)
+#define IDirect3DVertexBuffer_GetVertexBufferDesc(p,a)         (p)->lpVtbl->GetVertexBufferDesc(p,a)
+#define IDirect3DVertexBuffer_Optimize(p,a,b)                  (p)->lpVtbl->Optimize(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer_AddRef(p)             (p)->AddRef()
+#define IDirect3DVertexBuffer_Release(p)            (p)->Release()
+/*** IDirect3DVertexBuffer methods ***/
+#define IDirect3DVertexBuffer_Lock(p,a,b,c)                    (p)->Lock(a,b,c)
+#define IDirect3DVertexBuffer_Unlock(p)                        (p)->Unlock()
+#define IDirect3DVertexBuffer_ProcessVertices(p,a,b,c,d,e,f,g) (p)->ProcessVertices(a,b,c,d,e,f,g)
+#define IDirect3DVertexBuffer_GetVertexBufferDesc(p,a)         (p)->GetVertexBufferDesc(a)
+#define IDirect3DVertexBuffer_Optimize(p,a,b)                  (p)->Optimize(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer7 interface
+ */
+#define INTERFACE IDirect3DVertexBuffer7
+DECLARE_INTERFACE_(IDirect3DVertexBuffer7,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVertexBuffer7 methods ***/
+    STDMETHOD(Lock)(THIS_ DWORD dwFlags,LPVOID *lplpData,LPDWORD lpdwSize) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(ProcessVertices)(THIS_ DWORD dwVertexOp,DWORD dwDestIndex,DWORD dwCount,LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,DWORD dwSrcIndex,LPDIRECT3DDEVICE7 lpD3DDevice,DWORD dwFlags) PURE;
+    STDMETHOD(GetVertexBufferDesc)(THIS_ LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc) PURE;
+    STDMETHOD(Optimize)(THIS_ LPDIRECT3DDEVICE7  lpD3DDevice,DWORD dwFlags) PURE;
+    STDMETHOD(ProcessVerticesStrided)(THIS_ DWORD dwVertexOp,DWORD dwDestIndex,DWORD dwCount,LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,DWORD dwVertexTypeDesc,LPDIRECT3DDEVICE7 lpD3DDevice,DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer7_QueryInterface(p,a,b)                   (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer7_AddRef(p)                               (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer7_Release(p)                              (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer7 methods ***/
+#define IDirect3DVertexBuffer7_Lock(p,a,b,c)                           (p)->lpVtbl->Lock(p,a,b,c)
+#define IDirect3DVertexBuffer7_Unlock(p)                               (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer7_ProcessVertices(p,a,b,c,d,e,f,g)        (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f,g)
+#define IDirect3DVertexBuffer7_GetVertexBufferDesc(p,a)                (p)->lpVtbl->GetVertexBufferDesc(p,a)
+#define IDirect3DVertexBuffer7_Optimize(p,a,b)                         (p)->lpVtbl->Optimize(p,a,b)
+#define IDirect3DVertexBuffer7_ProcessVerticesStrided(p,a,b,c,d,e,f,g) (p)->lpVtbl->ProcessVerticesStrided(p,a,b,c,d,e,f,g)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer7_QueryInterface(p,a,b)                   (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer7_AddRef(p)                               (p)->AddRef()
+#define IDirect3DVertexBuffer7_Release(p)                              (p)->Release()
+/*** IDirect3DVertexBuffer7 methods ***/
+#define IDirect3DVertexBuffer7_Lock(p,a,b,c)                           (p)->Lock(a,b,c)
+#define IDirect3DVertexBuffer7_Unlock(p)                               (p)->Unlock()
+#define IDirect3DVertexBuffer7_ProcessVertices(p,a,b,c,d,e,f,g)        (p)->ProcessVertices(a,b,c,d,e,f,g)
+#define IDirect3DVertexBuffer7_GetVertexBufferDesc(p,a)                (p)->GetVertexBufferDesc(a)
+#define IDirect3DVertexBuffer7_Optimize(p,a,b)                         (p)->Optimize(a,b)
+#define IDirect3DVertexBuffer7_ProcessVerticesStrided(p,a,b,c,d,e,f,g) (p)->ProcessVerticesStrided(a,b,c,d,e,f,g)
+#endif
+
+#endif /* __WINE_D3D_H */
diff --git a/reactos/include/d3d8.h b/reactos/include/d3d8.h
new file mode 100644 (file)
index 0000000..6c83851
--- /dev/null
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (C) 2002 Jason Edmeades
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D8_H
+#define __WINE_D3D8_H
+
+#ifndef DIRECT3D_VERSION
+#define DIRECT3D_VERSION  0x0800
+#endif
+
+#include <objbase.h>
+
+#include <d3d8types.h>
+#include <d3d8caps.h>
+
+/*****************************************************************************
+ * Behavior Flags for IDirect3D8::CreateDevice
+ */
+#define D3DCREATE_FPU_PRESERVE                  0x00000002L
+#define D3DCREATE_MULTITHREADED                 0x00000004L
+#define D3DCREATE_PUREDEVICE                    0x00000010L
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING     0x00000020L
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING     0x00000040L
+#define D3DCREATE_MIXED_VERTEXPROCESSING        0x00000080L
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define D3DADAPTER_DEFAULT           0
+#define D3DENUM_NO_WHQL_LEVEL        2
+
+#define _FACD3D  0x876
+#define MAKE_D3DHRESULT( code )  MAKE_HRESULT( 1, _FACD3D, code )
+
+/*
+ * Direct3D Errors
+ */
+#define D3D_OK                                  S_OK
+#define D3DERR_WRONGTEXTUREFORMAT               MAKE_D3DHRESULT(2072)
+#define D3DERR_UNSUPPORTEDCOLOROPERATION        MAKE_D3DHRESULT(2073)
+#define D3DERR_UNSUPPORTEDCOLORARG              MAKE_D3DHRESULT(2074)
+#define D3DERR_UNSUPPORTEDALPHAOPERATION        MAKE_D3DHRESULT(2075)
+#define D3DERR_UNSUPPORTEDALPHAARG              MAKE_D3DHRESULT(2076)
+#define D3DERR_TOOMANYOPERATIONS                MAKE_D3DHRESULT(2077)
+#define D3DERR_CONFLICTINGTEXTUREFILTER         MAKE_D3DHRESULT(2078)
+#define D3DERR_UNSUPPORTEDFACTORVALUE           MAKE_D3DHRESULT(2079)
+#define D3DERR_CONFLICTINGRENDERSTATE           MAKE_D3DHRESULT(2081)
+#define D3DERR_UNSUPPORTEDTEXTUREFILTER         MAKE_D3DHRESULT(2082)
+#define D3DERR_CONFLICTINGTEXTUREPALETTE        MAKE_D3DHRESULT(2086)
+#define D3DERR_DRIVERINTERNALERROR              MAKE_D3DHRESULT(2087)
+
+#define D3DERR_NOTFOUND                         MAKE_D3DHRESULT(2150)
+#define D3DERR_MOREDATA                         MAKE_D3DHRESULT(2151)
+#define D3DERR_DEVICELOST                       MAKE_D3DHRESULT(2152)
+#define D3DERR_DEVICENOTRESET                   MAKE_D3DHRESULT(2153)
+#define D3DERR_NOTAVAILABLE                     MAKE_D3DHRESULT(2154)
+#define D3DERR_OUTOFVIDEOMEMORY                 MAKE_D3DHRESULT(380)
+#define D3DERR_INVALIDDEVICE                    MAKE_D3DHRESULT(2155)
+#define D3DERR_INVALIDCALL                      MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINVALIDCALL                MAKE_D3DHRESULT(2157)
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_IDirect3D8,              0x1DD9E8DA,0x1C77,0x4D40,0xB0,0xCF,0x98,0xFE,0xFD,0xFF,0x95,0x12);
+typedef struct IDirect3D8                IDirect3D8, *LPDIRECT3D8;
+
+DEFINE_GUID(IID_IDirect3DDevice8,        0x7385E5DF,0x8FE8,0x41D5,0x86,0xB6,0xD7,0xB4,0x85,0x47,0xB6,0xCF);
+typedef struct IDirect3DDevice8          IDirect3DDevice8, *LPDIRECT3DDEVICE8;
+
+DEFINE_GUID(IID_IDirect3DResource8,      0x1B36BB7B,0x09B7,0x410A,0xB4,0x45,0x7D,0x14,0x30,0xD7,0xB3,0x3F);
+typedef struct IDirect3DResource8        IDirect3DResource8, *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8;
+
+DEFINE_GUID(IID_IDirect3DVertexBuffer8,  0x8AEEEAC7,0x05F9,0x44D4,0xB5,0x91,0x00,0x0B,0x0D,0xF1,0xCB,0x95);
+typedef struct IDirect3DVertexBuffer8    IDirect3DVertexBuffer8, *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8;
+
+DEFINE_GUID(IID_IDirect3DVolume8,        0xBD7349F5,0x14F1,0x42E4,0x9C,0x79,0x97,0x23,0x80,0xDB,0x40,0xC0);
+typedef struct IDirect3DVolume8          IDirect3DVolume8, *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8;
+
+DEFINE_GUID(IID_IDirect3DSwapChain8,     0x928C088B,0x76B9,0x4C6B,0xA5,0x36,0xA5,0x90,0x85,0x38,0x76,0xCD);
+typedef struct IDirect3DSwapChain8       IDirect3DSwapChain8, *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8;
+
+DEFINE_GUID(IID_IDirect3DSurface8,       0xB96EEBCA,0xB326,0x4EA5,0x88,0x2F,0x2F,0xF5,0xBA,0xE0,0x21,0xDD);
+typedef struct IDirect3DSurface8         IDirect3DSurface8, *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8;
+
+DEFINE_GUID(IID_IDirect3DIndexBuffer8,   0x0E689C9A,0x053D,0x44A0,0x9D,0x92,0xDB,0x0E,0x3D,0x75,0x0F,0x86);
+typedef struct IDirect3DIndexBuffer8     IDirect3DIndexBuffer8, *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8;
+
+DEFINE_GUID(IID_IDirect3DBaseTexture8,   0xB4211CFA,0x51B9,0x4A9F,0xAB,0x78,0xDB,0x99,0xB2,0xBB,0x67,0x8E);
+typedef struct IDirect3DBaseTexture8     IDirect3DBaseTexture8, *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DTexture8,       0xE4CDD575,0x2866,0x4F01,0xB1,0x2E,0x7E,0xEC,0xE1,0xEC,0x93,0x58);
+typedef struct IDirect3DTexture8         IDirect3DTexture8, *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DCubeTexture8,   0x3EE5B968,0x2ACA,0x4C34,0x8B,0xB5,0x7E,0x0C,0x3D,0x19,0xB7,0x50);
+typedef struct IDirect3DCubeTexture8     IDirect3DCubeTexture8, *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8;
+
+DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4B8AAAFA,0x140F,0x42BA,0x91,0x31,0x59,0x7E,0xAF,0xAA,0x2E,0xAD);
+typedef struct IDirect3DVolumeTexture8   IDirect3DVolumeTexture8, *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8;
+
+/*****************************************************************************
+ * IDirect3D8 interface
+ */
+#define INTERFACE IDirect3D8
+DECLARE_INTERFACE_(IDirect3D8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D8 methods ***/
+    STDMETHOD(RegisterSoftwareDevice)(THIS_ void * pInitializeFunction) PURE;
+    STDMETHOD_(UINT,GetAdapterCount             )(THIS) PURE;
+    STDMETHOD(GetAdapterIdentifier)(THIS_ UINT  Adapter, DWORD  Flags, D3DADAPTER_IDENTIFIER8 * pIdentifier) PURE;
+    STDMETHOD_(UINT,GetAdapterModeCount)(THIS_ UINT  Adapter) PURE;
+    STDMETHOD(EnumAdapterModes)(THIS_ UINT  Adapter, UINT  Mode, D3DDISPLAYMODE * pMode) PURE;
+    STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT  Adapter, D3DDISPLAYMODE * pMode) PURE;
+    STDMETHOD(CheckDeviceType)(THIS_ UINT  Adapter, D3DDEVTYPE  CheckType, D3DFORMAT  DisplayFormat, D3DFORMAT  BackBufferFormat, BOOL  Windowed) PURE;
+    STDMETHOD(CheckDeviceFormat)(THIS_ UINT  Adapter, D3DDEVTYPE  DeviceType, D3DFORMAT  AdapterFormat, DWORD  Usage, D3DRESOURCETYPE  RType, D3DFORMAT  CheckFormat) PURE;
+    STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT  Adapter, D3DDEVTYPE  DeviceType, D3DFORMAT  SurfaceFormat, BOOL  Windowed, D3DMULTISAMPLE_TYPE  MultiSampleType) PURE;
+    STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT  Adapter, D3DDEVTYPE  DeviceType, D3DFORMAT  AdapterFormat, D3DFORMAT  RenderTargetFormat, D3DFORMAT  DepthStencilFormat) PURE;
+    STDMETHOD(GetDeviceCaps)(THIS_ UINT  Adapter, D3DDEVTYPE  DeviceType, D3DCAPS8 * pCaps) PURE;
+    STDMETHOD_(HMONITOR,GetAdapterMonitor)(THIS_ UINT  Adapter) PURE;
+    STDMETHOD(CreateDevice)(THIS_ UINT  Adapter, D3DDEVTYPE  DeviceType,HWND  hFocusWindow, DWORD  BehaviorFlags, D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DDevice8 ** ppReturnedDeviceInterface) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D8_QueryInterface(p,a,b)                    (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D8_AddRef(p)                                (p)->lpVtbl->AddRef(p)
+#define IDirect3D8_Release(p)                               (p)->lpVtbl->Release(p)
+/*** IDirect3D8 methods ***/
+#define IDirect3D8_RegisterSoftwareDevice(p,a)              (p)->lpVtbl->RegisterSoftwareDevice(p,a)
+#define IDirect3D8_GetAdapterCount(p)                       (p)->lpVtbl->GetAdapterCount(p)
+#define IDirect3D8_GetAdapterIdentifier(p,a,b,c)            (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c)
+#define IDirect3D8_GetAdapterModeCount(p,a)                 (p)->lpVtbl->GetAdapterModeCount(p,a)
+#define IDirect3D8_EnumAdapterModes(p,a,b,c)                (p)->lpVtbl->EnumAdapterModes(p,a,b,c)
+#define IDirect3D8_GetAdapterDisplayMode(p,a,b)             (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
+#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e)             (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e)
+#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f)         (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f)
+#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e)  (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e)
+#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e)      (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e)
+#define IDirect3D8_GetDeviceCaps(p,a,b,c)                   (p)->lpVtbl->GetDeviceCaps(p,a,b,c)
+#define IDirect3D8_GetAdapterMonitor(p,a)                   (p)->lpVtbl->GetAdapterMonitor(p,a)
+#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f)              (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D8_QueryInterface(p,a,b)                    (p)->QueryInterface(a,b)
+#define IDirect3D8_AddRef(p)                                (p)->AddRef()
+#define IDirect3D8_Release(p)                               (p)->Release()
+/*** IDirect3D8 methods ***/
+#define IDirect3D8_RegisterSoftwareDevice(p,a)              (p)->RegisterSoftwareDevice(a)
+#define IDirect3D8_GetAdapterCount(p)                       (p)->GetAdapterCount()
+#define IDirect3D8_GetAdapterIdentifier(p,a,b,c)            (p)->GetAdapterIdentifier(a,b,c)
+#define IDirect3D8_GetAdapterModeCount(p,a)                 (p)->GetAdapterModeCount(a)
+#define IDirect3D8_EnumAdapterModes(p,a,b,c)                (p)->EnumAdapterModes(a,b,c)
+#define IDirect3D8_GetAdapterDisplayMode(p,a,b)             (p)->GetAdapterDisplayMode(a,b)
+#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e)             (p)->CheckDeviceType(a,b,c,d,e)
+#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f)         (p)->CheckDeviceFormat(a,b,c,d,e,f)
+#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e)  (p)->CheckDeviceMultiSampleType(a,b,c,d,e)
+#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e)      (p)->CheckDepthStencilMatch(a,b,c,d,e)
+#define IDirect3D8_GetDeviceCaps(p,a,b,c)                   (p)->GetDeviceCaps(a,b,c)
+#define IDirect3D8_GetAdapterMonitor(p,a)                   (p)->GetAdapterMonitor(a)
+#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f)              (p)->CreateDevice(a,b,c,d,e,f)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice8 interface
+ */
+#define INTERFACE IDirect3DDevice8
+DECLARE_INTERFACE_(IDirect3DDevice8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice8 methods ***/
+    STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+    STDMETHOD_(UINT,GetAvailableTextureMem)(THIS) PURE;
+    STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD  Bytes) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ IDirect3D8 ** ppD3D8) PURE;
+    STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8 * pCaps) PURE;
+    STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE * pMode) PURE;
+    STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS  * pParameters) PURE;
+    STDMETHOD(SetCursorProperties)(THIS_ UINT  XHotSpot, UINT  YHotSpot, IDirect3DSurface8 * pCursorBitmap) PURE;
+    STDMETHOD_(void,SetCursorPosition)(THIS_ UINT  XScreenSpace, UINT  YScreenSpace,DWORD  Flags) PURE;
+    STDMETHOD_(BOOL,ShowCursor)(THIS_ BOOL  bShow) PURE;
+    STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS * pPresentationParameters, IDirect3DSwapChain8 ** pSwapChain) PURE;
+    STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS * pPresentationParameters) PURE;
+    STDMETHOD(Present)(THIS_ CONST RECT * pSourceRect,CONST RECT * pDestRect,HWND  hDestWindowOverride,CONST RGNDATA * pDirtyRegion) PURE;
+    STDMETHOD(GetBackBuffer)(THIS_ UINT  BackBuffer,D3DBACKBUFFER_TYPE  Type,IDirect3DSurface8 ** ppBackBuffer) PURE;
+    STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS * pRasterStatus) PURE;
+    STDMETHOD_(void,SetGammaRamp)(THIS_ DWORD  Flags,CONST D3DGAMMARAMP * pRamp) PURE;
+    STDMETHOD_(void,GetGammaRamp)(THIS_ D3DGAMMARAMP * pRamp) PURE;
+    STDMETHOD(CreateTexture)(THIS_ UINT  Width,UINT  Height,UINT  Levels,DWORD  Usage,D3DFORMAT  Format,D3DPOOL  Pool,IDirect3DTexture8 ** ppTexture) PURE;
+    STDMETHOD(CreateVolumeTexture)(THIS_ UINT  Width,UINT  Height,UINT  Depth,UINT  Levels,DWORD  Usage,D3DFORMAT  Format,D3DPOOL  Pool,IDirect3DVolumeTexture8 ** ppVolumeTexture) PURE;
+    STDMETHOD(CreateCubeTexture)(THIS_ UINT  EdgeLength,UINT  Levels,DWORD  Usage,D3DFORMAT  Format,D3DPOOL  Pool,IDirect3DCubeTexture8 ** ppCubeTexture) PURE;
+    STDMETHOD(CreateVertexBuffer)(THIS_ UINT  Length,DWORD  Usage,DWORD  FVF,D3DPOOL  Pool,IDirect3DVertexBuffer8 ** ppVertexBuffer) PURE;
+    STDMETHOD(CreateIndexBuffer)(THIS_ UINT  Length,DWORD  Usage,D3DFORMAT  Format,D3DPOOL  Pool,IDirect3DIndexBuffer8 ** ppIndexBuffer) PURE;
+    STDMETHOD(CreateRenderTarget)(THIS_ UINT  Width,UINT  Height,D3DFORMAT  Format,D3DMULTISAMPLE_TYPE  MultiSample,BOOL  Lockable,IDirect3DSurface8 ** ppSurface) PURE;
+    STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT  Width,UINT  Height,D3DFORMAT  Format,D3DMULTISAMPLE_TYPE  MultiSample,IDirect3DSurface8 ** ppSurface) PURE;
+    STDMETHOD(CreateImageSurface)(THIS_ UINT  Width,UINT  Height,D3DFORMAT  Format,IDirect3DSurface8 ** ppSurface) PURE;
+    STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8 * pSourceSurface,CONST RECT * pSourceRectsArray,UINT  cRects,IDirect3DSurface8 * pDestinationSurface,CONST POINT * pDestPointsArray) PURE;
+    STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8 * pSourceTexture,IDirect3DBaseTexture8 * pDestinationTexture) PURE;
+    STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8 * pDestSurface) PURE;
+    STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8 * pRenderTarget,IDirect3DSurface8 * pNewZStencil) PURE;
+    STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8 ** ppRenderTarget) PURE;
+    STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8 ** ppZStencilSurface) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD  Count,CONST D3DRECT * pRects,DWORD  Flags,D3DCOLOR  Color,float  Z,DWORD  Stencil) PURE;
+    STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE  State,CONST D3DMATRIX * pMatrix) PURE;
+    STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE  State,D3DMATRIX * pMatrix) PURE;
+    STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE  State, CONST D3DMATRIX * pMatrix) PURE;
+    STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8 * pViewport) PURE;
+    STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8 * pViewport) PURE;
+    STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8 * pMaterial) PURE;
+    STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8 *pMaterial) PURE;
+    STDMETHOD(SetLight)(THIS_ DWORD  Index,CONST D3DLIGHT8 * pLight) PURE;
+    STDMETHOD(GetLight)(THIS_ DWORD  Index,D3DLIGHT8 * pLight) PURE;
+    STDMETHOD(LightEnable)(THIS_ DWORD  Index,BOOL  Enable) PURE;
+    STDMETHOD(GetLightEnable)(THIS_ DWORD  Index,BOOL * pEnable) PURE;
+    STDMETHOD(SetClipPlane)(THIS_ DWORD  Index,CONST float * pPlane) PURE;
+    STDMETHOD(GetClipPlane)(THIS_ DWORD  Index,float * pPlane) PURE;
+    STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE  State,DWORD  Value) PURE;
+    STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE  State,DWORD * pValue) PURE;
+    STDMETHOD(BeginStateBlock)(THIS) PURE;
+    STDMETHOD(EndStateBlock)(THIS_ DWORD * pToken) PURE;
+    STDMETHOD(ApplyStateBlock)(THIS_ DWORD  Token) PURE;
+    STDMETHOD(CaptureStateBlock)(THIS_ DWORD  Token) PURE;
+    STDMETHOD(DeleteStateBlock)(THIS_ DWORD  Token) PURE;
+    STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE  Type,DWORD * pToken) PURE;
+    STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8 * pClipStatus) PURE;
+    STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8 * pClipStatus) PURE;
+    STDMETHOD(GetTexture)(THIS_ DWORD  Stage,IDirect3DBaseTexture8 ** ppTexture) PURE;
+    STDMETHOD(SetTexture)(THIS_ DWORD  Stage,IDirect3DBaseTexture8 * pTexture) PURE;
+    STDMETHOD(GetTextureStageState)(THIS_ DWORD  Stage,D3DTEXTURESTAGESTATETYPE  Type,DWORD * pValue) PURE;
+    STDMETHOD(SetTextureStageState)(THIS_ DWORD  Stage,D3DTEXTURESTAGESTATETYPE  Type,DWORD  Value) PURE;
+    STDMETHOD(ValidateDevice)(THIS_ DWORD * pNumPasses) PURE;
+    STDMETHOD(GetInfo)(THIS_ DWORD  DevInfoID,void * pDevInfoStruct,DWORD  DevInfoStructSize) PURE;
+    STDMETHOD(SetPaletteEntries)(THIS_ UINT  PaletteNumber,CONST PALETTEENTRY * pEntries) PURE;
+    STDMETHOD(GetPaletteEntries)(THIS_ UINT  PaletteNumber,PALETTEENTRY * pEntries) PURE;
+    STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT  PaletteNumber) PURE;
+    STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT  * PaletteNumber) PURE;
+    STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE  PrimitiveType,UINT  StartVertex,UINT  PrimitiveCount) PURE;
+    STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE  PrimitiveType,UINT  minIndex,UINT  NumVertices,UINT  startIndex,UINT  primCount) PURE;
+    STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE  PrimitiveType,UINT  PrimitiveCount,CONST void * pVertexStreamZeroData,UINT  VertexStreamZeroStride) PURE;
+    STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE  PrimitiveType,UINT  MinVertexIndex,UINT  NumVertexIndices,UINT  PrimitiveCount,CONST void * pIndexData,D3DFORMAT  IndexDataFormat,CONST void * pVertexStreamZeroData,UINT  VertexStreamZeroStride) PURE;
+    STDMETHOD(ProcessVertices)(THIS_ UINT  SrcStartIndex,UINT  DestIndex,UINT  VertexCount,IDirect3DVertexBuffer8 * pDestBuffer,DWORD  Flags) PURE;
+    STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD * pDeclaration,CONST DWORD * pFunction,DWORD * pHandle,DWORD  Usage) PURE;
+    STDMETHOD(SetVertexShader)(THIS_ DWORD  Handle) PURE;
+    STDMETHOD(GetVertexShader)(THIS_ DWORD * pHandle) PURE;
+    STDMETHOD(DeleteVertexShader)(THIS_ DWORD  Handle) PURE;
+    STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD  Register,CONST void * pConstantData,DWORD  ConstantCount) PURE;
+    STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD  Register,void * pConstantData,DWORD  ConstantCount) PURE;
+    STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD  Handle,void * pData,DWORD * pSizeOfData) PURE;
+    STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD  Handle,void * pData,DWORD * pSizeOfData) PURE;
+    STDMETHOD(SetStreamSource)(THIS_ UINT  StreamNumber,IDirect3DVertexBuffer8 * pStreamData,UINT  Stride) PURE;
+    STDMETHOD(GetStreamSource)(THIS_ UINT  StreamNumber,IDirect3DVertexBuffer8 ** ppStreamData,UINT * pStride) PURE;
+    STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8 * pIndexData,UINT  BaseVertexIndex) PURE;
+    STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8 ** ppIndexData,UINT * pBaseVertexIndex) PURE;
+    STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD * pFunction,DWORD * pHandle) PURE;
+    STDMETHOD(SetPixelShader)(THIS_ DWORD  Handle) PURE;
+    STDMETHOD(GetPixelShader)(THIS_ DWORD * pHandle) PURE;
+    STDMETHOD(DeletePixelShader)(THIS_ DWORD  Handle) PURE;
+    STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD  Register,CONST void * pConstantData,DWORD  ConstantCount) PURE;
+    STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD  Register,void * pConstantData,DWORD  ConstantCount) PURE;
+    STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD  Handle,void * pData,DWORD * pSizeOfData) PURE;
+    STDMETHOD(DrawRectPatch)(THIS_ UINT  Handle,CONST float * pNumSegs,CONST D3DRECTPATCH_INFO * pRectPatchInfo) PURE;
+    STDMETHOD(DrawTriPatch)(THIS_ UINT  Handle,CONST float * pNumSegs,CONST D3DTRIPATCH_INFO * pTriPatchInfo) PURE;
+    STDMETHOD(DeletePatch)(THIS_ UINT  Handle) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice8_QueryInterface(p,a,b)                     (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice8_AddRef(p)                                 (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice8_Release(p)                                (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice8 methods ***/
+#define IDirect3DDevice8_TestCooperativeLevel(p)                   (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirect3DDevice8_GetAvailableTextureMem(p)                 (p)->lpVtbl->GetAvailableTextureMem(p)
+#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a)          (p)->lpVtbl->ResourceManagerDiscardBytes(p,a)
+#define IDirect3DDevice8_GetDirect3D(p,a)                          (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice8_GetDeviceCaps(p,a)                        (p)->lpVtbl->GetDeviceCaps(p,a)
+#define IDirect3DDevice8_GetDisplayMode(p,a)                       (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirect3DDevice8_GetCreationParameters(p,a)                (p)->lpVtbl->GetCreationParameters(p,a)
+#define IDirect3DDevice8_SetCursorProperties(p,a,b,c)              (p)->lpVtbl->SetCursorProperties(p,a,b,c)
+#define IDirect3DDevice8_SetCursorPosition(p,a,b,c)                (p)->lpVtbl->SetCursorPosition(p,a,b,c)
+#define IDirect3DDevice8_ShowCursor(p,a)                           (p)->lpVtbl->ShowCursor(p,a)
+#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b)          (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b)
+#define IDirect3DDevice8_Reset(p,a)                                (p)->lpVtbl->Reset(p,a)
+#define IDirect3DDevice8_Present(p,a,b,c,d)                        (p)->lpVtbl->Present(p,a,b,c,d)
+#define IDirect3DDevice8_GetBackBuffer(p,a,b,c)                    (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#define IDirect3DDevice8_GetRasterStatus(p,a)                      (p)->lpVtbl->GetRasterStatus(p,a)
+#define IDirect3DDevice8_SetGammaRamp(p,a,b)                       (p)->lpVtbl->SetGammaRamp(p,a,b)
+#define IDirect3DDevice8_GetGammaRamp(p,a)                         (p)->lpVtbl->GetGammaRamp(p,a)
+#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g)            (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h)    (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f)          (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e)           (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e)            (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f)         (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e)    (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d)             (p)->lpVtbl->CreateImageSurface(p,a,b,c,d)
+#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e)                    (p)->lpVtbl->CopyRects(p,a,b,c,d,e)
+#define IDirect3DDevice8_UpdateTexture(p,a,b)                      (p)->lpVtbl->UpdateTexture(p,a,b)
+#define IDirect3DDevice8_GetFrontBuffer(p,a)                       (p)->lpVtbl->GetFrontBuffer(p,a)
+#define IDirect3DDevice8_SetRenderTarget(p,a,b)                    (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice8_GetRenderTarget(p,a)                      (p)->lpVtbl->GetRenderTarget(p,a)
+#define IDirect3DDevice8_GetDepthStencilSurface(p,a)               (p)->lpVtbl->GetDepthStencilSurface(p,a)
+#define IDirect3DDevice8_BeginScene(p)                             (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice8_EndScene(p)                               (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f)                      (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice8_SetTransform(p,a,b)                       (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice8_GetTransform(p,a,b)                       (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice8_MultiplyTransform(p,a,b)                  (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice8_SetViewport(p,a)                          (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice8_GetViewport(p,a)                          (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice8_SetMaterial(p,a)                          (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice8_GetMaterial(p,a)                          (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice8_SetLight(p,a,b)                           (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice8_GetLight(p,a,b)                           (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice8_LightEnable(p,a,b)                        (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice8_GetLightEnable(p,a,b)                     (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice8_SetClipPlane(p,a,b)                       (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice8_GetClipPlane(p,a,b)                       (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice8_SetRenderState(p,a,b)                     (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice8_GetRenderState(p,a,b)                     (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice8_BeginStateBlock(p)                        (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice8_EndStateBlock(p,a)                        (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice8_ApplyStateBlock(p,a)                      (p)->lpVtbl->ApplyStateBlock(p,a)
+#define IDirect3DDevice8_CaptureStateBlock(p,a)                    (p)->lpVtbl->CaptureStateBlock(p,a)
+#define IDirect3DDevice8_DeleteStateBlock(p,a)                     (p)->lpVtbl->DeleteStateBlock(p,a)
+#define IDirect3DDevice8_CreateStateBlock(p,a,b)                   (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice8_SetClipStatus(p,a)                        (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice8_GetClipStatus(p,a)                        (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice8_GetTexture(p,a,b)                         (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice8_SetTexture(p,a,b)                         (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice8_GetTextureStageState(p,a,b,c)             (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice8_SetTextureStageState(p,a,b,c)             (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice8_ValidateDevice(p,a)                       (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice8_GetInfo(p,a,b,c)                          (p)->lpVtbl->GetInfo(p,a,b,c)
+#define IDirect3DDevice8_SetPaletteEntries(p,a,b)                  (p)->lpVtbl->SetPaletteEntries(p,a,b)
+#define IDirect3DDevice8_GetPaletteEntries(p,a,b)                  (p)->lpVtbl->GetPaletteEntries(p,a,b)
+#define IDirect3DDevice8_SetCurrentTexturePalette(p,a)             (p)->lpVtbl->SetCurrentTexturePalette(p,a)
+#define IDirect3DDevice8_GetCurrentTexturePalette(p,a)             (p)->lpVtbl->GetCurrentTexturePalette(p,a)
+#define IDirect3DDevice8_DrawPrimitive(p,a,b,c)                    (p)->lpVtbl->DrawPrimitive(p,a,b,c)
+#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e)         (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e)
+#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d)                (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
+#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e)              (p)->lpVtbl->processVertices(p,a,b,c,d,e)
+#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d)             (p)->lpVtbl->CreateVertexShader(p,a,b,c,d)
+#define IDirect3DDevice8_SetVertexShader(p,a)                      (p)->lpVtbl->SetVertexShader(p,a)
+#define IDirect3DDevice8_GetVertexShader(p,a)                      (p)->lpVtbl->GetVertexShader(p,a)
+#define IDirect3DDevice8_DeleteVertexShader(p,a)                   (p)->lpVtbl->DeleteVertexShader(p,a)
+#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c)          (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c)          (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c)       (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c)
+#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c)          (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c)
+#define IDirect3DDevice8_SetStreamSource(p,a,b,c)                  (p)->lpVtbl->SetStreamSource(p,a,b,c)
+#define IDirect3DDevice8_GetStreamSource(p,a,b,c)                  (p)->lpVtbl->GetStreamSource(p,a,b,c)
+#define IDirect3DDevice8_SetIndices(p,a,b)                         (p)->lpVtbl->SetIndices(p,a,b)
+#define IDirect3DDevice8_GetIndices(p,a,b)                         (p)->lpVtbl->GetIndices(p,a,b)
+#define IDirect3DDevice8_CreatePixelShader(p,a,b)                  (p)->lpVtbl->CreatePixelShader(p,a,b)
+#define IDirect3DDevice8_SetPixelShader(p,a)                       (p)->lpVtbl->SetPixelShader(p,a)
+#define IDirect3DDevice8_GetPixelShader(p,a)                       (p)->lpVtbl->GetPixelShader(p,a)
+#define IDirect3DDevice8_DeletePixelShader(p,a)                    (p)->lpVtbl->DeletePixelShader(p,a)
+#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c)           (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c)           (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c)
+#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c)           (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c)
+#define IDirect3DDevice8_DrawRectPatch(p,a,b,c)                    (p)->lpVtbl->DrawRectPatch(p,a,b,c)
+#define IDirect3DDevice8_DrawTriPatch(p,a,b,c)                     (p)->lpVtbl->DrawTriPatch(p,a,b,c)
+#define IDirect3DDevice8_DeletePatch(p,a)                          (p)->lpVtbl->DeletePatch(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice8_QueryInterface(p,a,b)                     (p)->QueryInterface(a,b)
+#define IDirect3DDevice8_AddRef(p)                                 (p)->AddRef()
+#define IDirect3DDevice8_Release(p)                                (p)->Release()
+/*** IDirect3DDevice8 methods ***/
+#define IDirect3DDevice8_TestCooperativeLevel(p)                   (p)->TestCooperativeLevel()
+#define IDirect3DDevice8_GetAvailableTextureMem(p)                 (p)->GetAvailableTextureMem()
+#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a)          (p)->ResourceManagerDiscardBytes(a)
+#define IDirect3DDevice8_GetDirect3D(p,a)                          (p)->GetDirect3D(a)
+#define IDirect3DDevice8_GetDeviceCaps(p,a)                        (p)->GetDeviceCaps(a)
+#define IDirect3DDevice8_GetDisplayMode(p,a)                       (p)->GetDisplayMode(a)
+#define IDirect3DDevice8_GetCreationParameters(p,a)                (p)->GetCreationParameters(a)
+#define IDirect3DDevice8_SetCursorProperties(p,a,b,c)              (p)->SetCursorProperties(a,b,c)
+#define IDirect3DDevice8_SetCursorPosition(p,a,b,c)                (p)->SetCursorPosition(a,b,c)
+#define IDirect3DDevice8_ShowCursor(p,a)                           (p)->ShowCursor(a)
+#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b)          (p)->CreateAdditionalSwapChain(a,b)
+#define IDirect3DDevice8_Reset(p,a)                                (p)->Reset(a)
+#define IDirect3DDevice8_Present(p,a,b,c,d)                        (p)->Present(a,b,c,d)
+#define IDirect3DDevice8_GetBackBuffer(p,a,b,c)                    (p)->GetBackBuffer(a,b,c)
+#define IDirect3DDevice8_GetRasterStatus(p,a)                      (p)->GetRasterStatus(a)
+#define IDirect3DDevice8_SetGammaRamp(p,a,b)                       (p)->SetGammaRamp(a,b)
+#define IDirect3DDevice8_GetGammaRamp(p,a)                         (p)->GetGammaRamp(a)
+#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g)            (p)->CreateTexture(a,b,c,d,e,f,g)
+#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h)    (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f)          (p)->CreateCubeTexture(a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e)           (p)->CreateVertexBuffer(a,b,c,d,e)
+#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e)            (p)->CreateIndexBuffer(a,b,c,d,e)
+#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f)         (p)->CreateRenderTarget(a,b,c,d,e,f)
+#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e)    (p)->CreateDepthStencilSurface(a,b,c,d,e)
+#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d)             (p)->CreateImageSurface(a,b,c,d)
+#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e)                    (p)->CopyRects(a,b,c,d,e)
+#define IDirect3DDevice8_UpdateTexture(p,a,b)                      (p)->UpdateTexture(a,b)
+#define IDirect3DDevice8_GetFrontBuffer(p,a)                       (p)->GetFrontBuffer(a)
+#define IDirect3DDevice8_SetRenderTarget(p,a,b)                    (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice8_GetRenderTarget(p,a)                      (p)->GetRenderTarget(a)
+#define IDirect3DDevice8_GetDepthStencilSurface(p,a)               (p)->GetDepthStencilSurface(a)
+#define IDirect3DDevice8_BeginScene(p)                             (p)->BeginScene()
+#define IDirect3DDevice8_EndScene(p)                               (p)->EndScene()
+#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f)                      (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice8_SetTransform(p,a,b)                       (p)->SetTransform(a,b)
+#define IDirect3DDevice8_GetTransform(p,a,b)                       (p)->GetTransform(a,b)
+#define IDirect3DDevice8_MultiplyTransform(p,a,b)                  (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice8_SetViewport(p,a)                          (p)->SetViewport(a)
+#define IDirect3DDevice8_GetViewport(p,a)                          (p)->GetViewport(a)
+#define IDirect3DDevice8_SetMaterial(p,a)                          (p)->SetMaterial(a)
+#define IDirect3DDevice8_GetMaterial(p,a)                          (p)->GetMaterial(a)
+#define IDirect3DDevice8_SetLight(p,a,b)                           (p)->SetLight(a,b)
+#define IDirect3DDevice8_GetLight(p,a,b)                           (p)->GetLight(a,b)
+#define IDirect3DDevice8_LightEnable(p,a,b)                        (p)->LightEnable(a,b)
+#define IDirect3DDevice8_GetLightEnable(p,a,b)                     (p)->GetLightEnable(a,b)
+#define IDirect3DDevice8_SetClipPlane(p,a,b)                       (p)->SetClipPlane(a,b)
+#define IDirect3DDevice8_GetClipPlane(p,a,b)                       (p)->GetClipPlane(a,b)
+#define IDirect3DDevice8_SetRenderState(p,a,b)                     (p)->SetRenderState(a,b)
+#define IDirect3DDevice8_GetRenderState(p,a,b)                     (p)->GetRenderState(a,b)
+#define IDirect3DDevice8_BeginStateBlock(p)                        (p)->BeginStateBlock()
+#define IDirect3DDevice8_EndStateBlock(p,a)                        (p)->EndStateBlock(a)
+#define IDirect3DDevice8_ApplyStateBlock(p,a)                      (p)->ApplyStateBlock(a)
+#define IDirect3DDevice8_CaptureStateBlock(p,a)                    (p)->CaptureStateBlock(a)
+#define IDirect3DDevice8_DeleteStateBlock(p,a)                     (p)->DeleteStateBlock(a)
+#define IDirect3DDevice8_CreateStateBlock(p,a,b)                   (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice8_SetClipStatus(p,a)                        (p)->SetClipStatus(a)
+#define IDirect3DDevice8_GetClipStatus(p,a)                        (p)->GetClipStatus(a)
+#define IDirect3DDevice8_GetTexture(p,a,b)                         (p)->GetTexture(a,b)
+#define IDirect3DDevice8_SetTexture(p,a,b)                         (p)->SetTexture(a,b)
+#define IDirect3DDevice8_GetTextureStageState(p,a,b,c)             (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice8_SetTextureStageState(p,a,b,c)             (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice8_ValidateDevice(p,a)                       (p)->ValidateDevice(a)
+#define IDirect3DDevice8_GetInfo(p,a,b,c)                          (p)->GetInfo(a,b,c)
+#define IDirect3DDevice8_SetPaletteEntries(p,a,b)                  (p)->SetPaletteEntries(a,b)
+#define IDirect3DDevice8_GetPaletteEntries(p,a,b)                  (p)->GetPaletteEntries(a,b)
+#define IDirect3DDevice8_SetCurrentTexturePalette(p,a)             (p)->SetCurrentTexturePalette(a)
+#define IDirect3DDevice8_GetCurrentTexturePalette(p,a)             (p)->GetCurrentTexturePalette(a)
+#define IDirect3DDevice8_DrawPrimitive(p,a,b,c)                    (p)->DrawPrimitive(a,b,c)
+#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e)         (p)->DrawIndexedPrimitive(a,b,c,d,e)
+#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d)                (p)->DrawPrimitiveUP(a,b,c,d)
+#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e)              (p)->processVertices(a,b,c,d,e)
+#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d)             (p)->CreateVertexShader(a,b,c,d)
+#define IDirect3DDevice8_SetVertexShader(p,a)                      (p)->SetVertexShader(a)
+#define IDirect3DDevice8_GetVertexShader(p,a)                      (p)->GetVertexShader(a)
+#define IDirect3DDevice8_DeleteVertexShader(p,a)                   (p)->DeleteVertexShader(a)
+#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c)          (p)->SetVertexShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c)          (p)->GetVertexShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c)       (p)->GetVertexShaderDeclaration(a,b,c)
+#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c)          (p)->GetVertexShaderFunction(a,b,c)
+#define IDirect3DDevice8_SetStreamSource(p,a,b,c)                  (p)->SetStreamSource(a,b,c)
+#define IDirect3DDevice8_GetStreamSource(p,a,b,c)                  (p)->GetStreamSource(a,b,c)
+#define IDirect3DDevice8_SetIndices(p,a,b)                         (p)->SetIndices(a,b)
+#define IDirect3DDevice8_GetIndices(p,a,b)                         (p)->GetIndices(a,b)
+#define IDirect3DDevice8_CreatePixelShader(p,a,b)                  (p)->CreatePixelShader(a,b)
+#define IDirect3DDevice8_SetPixelShader(p,a)                       (p)->SetPixelShader(a)
+#define IDirect3DDevice8_GetPixelShader(p,a)                       (p)->GetPixelShader(a)
+#define IDirect3DDevice8_DeletePixelShader(p,a)                    (p)->DeletePixelShader(a)
+#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c)           (p)->SetPixelShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c)           (p)->GetPixelShaderConstant(a,b,c)
+#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c)           (p)->GetPixelShaderFunction(a,b,c)
+#define IDirect3DDevice8_DrawRectPatch(p,a,b,c)                    (p)->DrawRectPatch(a,b,c)
+#define IDirect3DDevice8_DrawTriPatch(p,a,b,c)                     (p)->DrawTriPatch(a,b,c)
+#define IDirect3DDevice8_DeletePatch(p,a)                          (p)->DeletePatch(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolume8 interface
+ */
+#define INTERFACE IDirect3DVolume8
+DECLARE_INTERFACE_(IDirect3DVolume8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVolume8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid,CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID   refguid,void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD(GetContainer)(THIS_ REFIID  riid, void ** ppContainer) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC * pDesc) PURE;
+    STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX * pBox, DWORD  Flags) PURE;
+    STDMETHOD(UnlockBox)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolume8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolume8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolume8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DVolume8 methods ***/
+#define IDirect3DVolume8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolume8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolume8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolume8_GetContainer(p,a,b)          (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DVolume8_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DVolume8_LockBox(p,a,b,c)             (p)->lpVtbl->LockBox(p,a,b,c)
+#define IDirect3DVolume8_UnlockBox(p)                 (p)->lpVtbl->UnlockBox(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolume8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DVolume8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DVolume8_Release(p)                   (p)->Release()
+/*** IDirect3DVolume8 methods ***/
+#define IDirect3DVolume8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolume8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolume8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DVolume8_GetContainer(p,a,b)          (p)->GetContainer(a,b)
+#define IDirect3DVolume8_GetDesc(p,a)                 (p)->GetDesc(a)
+#define IDirect3DVolume8_LockBox(p,a,b,c)             (p)->LockBox(a,b,c)
+#define IDirect3DVolume8_UnlockBox(p)                 (p)->UnlockBox()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSwapChain8 interface
+ */
+#define INTERFACE IDirect3DSwapChain8
+DECLARE_INTERFACE_(IDirect3DSwapChain8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DSwapChain8 methods ***/
+    STDMETHOD(Present)(THIS_ CONST RECT * pSourceRect, CONST RECT * pDestRect, HWND  hDestWindowOverride,CONST RGNDATA * pDirtyRegion) PURE;
+    STDMETHOD(GetBackBuffer)(THIS_ UINT  BackBuffer, D3DBACKBUFFER_TYPE  Type,IDirect3DSurface8 ** ppBackBuffer) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSwapChain8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DSwapChain8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DSwapChain8 methods ***/
+#define IDirect3DSwapChain8_Present(p,a,b,c)             (p)->lpVtbl->Present(p,a,b,c)
+#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c,d)     (p)->lpVtbl->GetBackBuffer(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DSwapChain8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DSwapChain8_Release(p)                   (p)->Release()
+/*** IDirect3DSwapChain8 methods ***/
+#define IDirect3DSwapChain8_Present(p,a,b,c)             (p)->Present(a,b,c)
+#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c,d)     (p)->GetBackBuffer(a,b,c,d)
+#endif
+
+/*****************************************************************************
+ * IDirect3DSurface8 interface
+ */
+#define INTERFACE IDirect3DSurface8
+DECLARE_INTERFACE_(IDirect3DSurface8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DSurface8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid,CONST void * pData,DWORD  SizeOfData,DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid,void * pData,DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD(GetContainer)(THIS_ REFIID  riid, void ** ppContainer) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC * pDesc) PURE;
+    STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT * pLockedRect, CONST RECT * pRect,DWORD  Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSurface8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSurface8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DSurface8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DSurface8 methods ***/
+#define IDirect3DSurface8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DSurface8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DSurface8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DSurface8_GetContainer(p,a,b)          (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DSurface8_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DSurface8_LockRect(p,a,b,c)            (p)->lpVtbl->LockRect(p,a,b,c)
+#define IDirect3DSurface8_UnlockRect(p)                (p)->lpVtbl->UnlockRect(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSurface8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DSurface8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DSurface8_Release(p)                   (p)->Release()
+/*** IDirect3DSurface8 methods ***/
+#define IDirect3DSurface8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DSurface8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DSurface8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DSurface8_GetContainer(p,a,b)          (p)->GetContainer(a,b)
+#define IDirect3DSurface8_GetDesc(p,a)                 (p)->GetDesc(a)
+#define IDirect3DSurface8_LockRect(p,a,b,c)            (p)->LockRect(a,b,c)
+#define IDirect3DSurface8_UnlockRect(p)                (p)->UnlockRect()
+#endif
+
+/*****************************************************************************
+ * IDirect3DResource8 interface
+ */
+#define INTERFACE IDirect3DResource8
+DECLARE_INTERFACE_(IDirect3DResource8,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DResource8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DResource8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DResource8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DResource8 methods ***/
+#define IDirect3DResource8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DResource8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DResource8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DResource8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DResource8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DResource8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DResource8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DResource8_GetType(p)                   (p)->lpVtbl->GetType(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DResource8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DResource8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DResource8_Release(p)                   (p)->Release()
+/*** IDirect3DResource8 methods ***/
+#define IDirect3DResource8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DResource8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DResource8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DResource8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DResource8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DResource8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DResource8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DResource8_GetType(p)                   (p)->GetType()
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer8 interface
+ */
+#define INTERFACE IDirect3DVertexBuffer8
+DECLARE_INTERFACE_(IDirect3DVertexBuffer8,IDirect3DResource8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DVertexBuffer8 methods ***/
+    STDMETHOD(Lock)(THIS_ UINT  OffsetToLock, UINT  SizeToLock, BYTE ** ppbData, DWORD  Flags) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC  * pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DVertexBuffer8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVertexBuffer8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVertexBuffer8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVertexBuffer8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVertexBuffer8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVertexBuffer8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DVertexBuffer8 methods ***/
+#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DVertexBuffer8_Unlock(p)                    (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer8_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DVertexBuffer8_Release(p)                   (p)->Release()
+/*** IDirect3DVertexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DVertexBuffer8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DVertexBuffer8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DVertexBuffer8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DVertexBuffer8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DVertexBuffer8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DVertexBuffer8_GetType(p)                   (p)->GetType()
+/*** IDirect3DVertexBuffer8 methods ***/
+#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirect3DVertexBuffer8_Unlock(p)                    (p)->Unlock()
+#define IDirect3DVertexBuffer8_GetDesc(p,a)                 (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DIndexBuffer8 interface
+ */
+#define INTERFACE IDirect3DIndexBuffer8
+DECLARE_INTERFACE_(IDirect3DIndexBuffer8,IDirect3DResource8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DIndexBuffer8 methods ***/
+    STDMETHOD(Lock)(THIS_ UINT  OffsetToLock, UINT  SizeToLock, BYTE ** ppbData, DWORD  Flags) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC * pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DIndexBuffer8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DIndexBuffer8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DIndexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DIndexBuffer8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DIndexBuffer8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DIndexBuffer8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DIndexBuffer8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DIndexBuffer8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DIndexBuffer8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DIndexBuffer8 methods ***/
+#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DIndexBuffer8_Unlock(p)                    (p)->lpVtbl->Unlock(p)
+#define IDirect3DIndexBuffer8_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DIndexBuffer8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DIndexBuffer8_Release(p)                   (p)->Release()
+/*** IDirect3DIndexBuffer8 methods: IDirect3DResource8 ***/
+#define IDirect3DIndexBuffer8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DIndexBuffer8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DIndexBuffer8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DIndexBuffer8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DIndexBuffer8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DIndexBuffer8_GetType(p)                   (p)->GetType()
+/*** IDirect3DIndexBuffer8 methods ***/
+#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirect3DIndexBuffer8_Unlock(p)                    (p)->Unlock()
+#define IDirect3DIndexBuffer8_GetDesc(p,a)                 (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DBaseTexture8 interface
+ */
+#define INTERFACE IDirect3DBaseTexture8
+DECLARE_INTERFACE_(IDirect3DBaseTexture8,IDirect3DResource8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture8 methods ***/
+    STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD  LODNew) PURE;
+    STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DBaseTexture8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DBaseTexture8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DBaseTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DBaseTexture8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DBaseTexture8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DBaseTexture8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DBaseTexture8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DBaseTexture8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DBaseTexture8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DBaseTexture8 methods ***/
+#define IDirect3DBaseTexture8_SetLOD(p,a)                  (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DBaseTexture8_GetLOD(p)                    (p)->lpVtbl->GetLOD(p)
+#define IDirect3DBaseTexture8_GetLevelCount(p)             (p)->lpVtbl->GetLevelCount(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DBaseTexture8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DBaseTexture8_Release(p)                   (p)->Release()
+/*** IDirect3DBaseTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DBaseTexture8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DBaseTexture8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DBaseTexture8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DBaseTexture8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DBaseTexture8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DBaseTexture8_GetType(p)                   (p)->GetType()
+/*** IDirect3DBaseTexture8 methods ***/
+#define IDirect3DBaseTexture8_SetLOD(p,a)                  (p)->SetLOD(a)
+#define IDirect3DBaseTexture8_GetLOD(p)                    (p)->GetLOD()
+#define IDirect3DBaseTexture8_GetLevelCount(p)             (p)->GetLevelCount()
+#endif
+
+/*****************************************************************************
+ * IDirect3DCubeTexture8 interface
+ */
+#define INTERFACE IDirect3DCubeTexture8
+DECLARE_INTERFACE_(IDirect3DCubeTexture8,IDirect3DBaseTexture8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture8 methods ***/
+    STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD  LODNew) PURE;
+    STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+    /*** IDirect3DCubeTexture8 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT  Level,D3DSURFACE_DESC * pDesc) PURE;
+    STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES  FaceType,UINT  Level,IDirect3DSurface8 ** ppCubeMapSurface) PURE;
+    STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES  FaceType,UINT  Level,D3DLOCKED_RECT * pLockedRect,CONST RECT * pRect,DWORD  Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES  FaceType,UINT  Level) PURE;
+    STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES  FaceType,CONST RECT * pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DCubeTexture8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DCubeTexture8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DCubeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DCubeTexture8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DCubeTexture8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DCubeTexture8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DCubeTexture8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DCubeTexture8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DCubeTexture8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DCubeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DCubeTexture8_SetLOD(p,a)                  (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DCubeTexture8_GetLOD(p)                    (p)->lpVtbl->GetLOD(p)
+#define IDirect3DCubeTexture8_GetLevelCount(p)             (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DCubeTexture8 methods ***/
+#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b)          (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c)   (p)->lpVtbl->GetCubeMapSurface(p,a,b,c)
+#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e)        (p)->lpVtbl->LockRect(p,a,b,c,d,e)
+#define IDirect3DCubeTexture8_UnlockRect(p,a,b)            (p)->lpVtbl->UnlockRect(p,a,b)
+#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b)          (p)->lpVtbl->AddDirtyRect(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DCubeTexture8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DCubeTexture8_Release(p)                   (p)->Release()
+/*** IDirect3DCubeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DCubeTexture8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DCubeTexture8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DCubeTexture8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DCubeTexture8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DCubeTexture8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DCubeTexture8_GetType(p)                   (p)->GetType()
+/*** IDirect3DCubeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DCubeTexture8_SetLOD(p,a)                  (p)->SetLOD(a)
+#define IDirect3DCubeTexture8_GetLOD(p)                    (p)->GetLOD()
+#define IDirect3DCubeTexture8_GetLevelCount(p)             (p)->GetLevelCount()
+/*** IDirect3DCubeTexture8 methods ***/
+#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b)          (p)->GetLevelDesc(a,b)
+#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c)   (p)->GetCubeMapSurface(a,b,c)
+#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e)        (p)->LockRect(a,b,c,d,e)
+#define IDirect3DCubeTexture8_UnlockRect(p,a,b)            (p)->UnlockRect(a,b)
+#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b)          (p)->AddDirtyRect(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DTexture8 interface
+ */
+#define INTERFACE IDirect3DTexture8
+DECLARE_INTERFACE_(IDirect3DTexture8,IDirect3DBaseTexture8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture8 methods ***/
+    STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD  LODNew) PURE;
+    STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+    /*** IDirect3DTexture8 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT  Level,D3DSURFACE_DESC * pDesc) PURE;
+    STDMETHOD(GetSurfaceLevel)(THIS_ UINT  Level,IDirect3DSurface8 ** ppSurfaceLevel) PURE;
+    STDMETHOD(LockRect)(THIS_ UINT  Level,D3DLOCKED_RECT * pLockedRect,CONST RECT * pRect,DWORD  Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS_ UINT  Level) PURE;
+    STDMETHOD(AddDirtyRect)(THIS_ CONST RECT * pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DTexture8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DTexture8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DTexture8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DTexture8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DTexture8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DTexture8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DTexture8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DTexture8_SetLOD(p,a)                  (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DTexture8_GetLOD(p)                    (p)->lpVtbl->GetLOD(p)
+#define IDirect3DTexture8_GetLevelCount(p)             (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DTexture8 methods ***/
+#define IDirect3DTexture8_GetLevelDesc(p,a,b)          (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DTexture8_GetSurfaceLevel(p,a,b)       (p)->lpVtbl->GetSurfaceLevel(p,a,b)
+#define IDirect3DTexture8_LockRect(p,a,b,c,d)          (p)->lpVtbl->LockRect(p,a,b,c,d)
+#define IDirect3DTexture8_UnlockRect(p,a)              (p)->lpVtbl->UnlockRect(p,a)
+#define IDirect3DTexture8_AddDirtyRect(p,a)            (p)->lpVtbl->AddDirtyRect(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DTexture8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DTexture8_Release(p)                   (p)->Release()
+/*** IDirect3DTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DTexture8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DTexture8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DTexture8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DTexture8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DTexture8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DTexture8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DTexture8_GetType(p)                   (p)->GetType()
+/*** IDirect3DTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DTexture8_SetLOD(p,a)                  (p)->SetLOD(a)
+#define IDirect3DTexture8_GetLOD(p)                    (p)->GetLOD()
+#define IDirect3DTexture8_GetLevelCount(p)             (p)->GetLevelCount()
+/*** IDirect3DTexture8 methods ***/
+#define IDirect3DTexture8_GetLevelDesc(p,a,b)          (p)->GetLevelDesc(a,b)
+#define IDirect3DTexture8_GetSurfaceLevel(p,a,b)       (p)->GetSurfaceLevel(a,b)
+#define IDirect3DTexture8_LockRect(p,a,b,c,d)          (p)->LockRect(a,b,c,d)
+#define IDirect3DTexture8_UnlockRect(p,a)              (p)->UnlockRect(a)
+#define IDirect3DTexture8_AddDirtyRect(p,a)            (p)->AddDirtyRect(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolumeTexture8 interface
+ */
+#define INTERFACE IDirect3DVolumeTexture8
+DECLARE_INTERFACE_(IDirect3DVolumeTexture8,IDirect3DBaseTexture8)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource8 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8 ** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID  refguid, CONST void * pData, DWORD  SizeOfData, DWORD  Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID  refguid, void * pData, DWORD * pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID  refguid) PURE;
+    STDMETHOD_(DWORD,SetPriority)(THIS_ DWORD  PriorityNew) PURE;
+    STDMETHOD_(DWORD,GetPriority)(THIS) PURE;
+    STDMETHOD_(void,PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE,GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture8 methods ***/
+    STDMETHOD_(DWORD,SetLOD)(THIS_ DWORD  LODNew) PURE;
+    STDMETHOD_(DWORD,GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD,GetLevelCount)(THIS) PURE;
+    /*** IDirect3DVolumeTexture8 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT  Level,D3DVOLUME_DESC * pDesc) PURE;
+    STDMETHOD(GetVolumeLevel)(THIS_ UINT  Level,IDirect3DVolume8 ** ppVolumeLevel) PURE;
+    STDMETHOD(LockBox)(THIS_ UINT  Level,D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX * pBox,DWORD  Flags) PURE;
+    STDMETHOD(UnlockBox)(THIS_ UINT  Level) PURE;
+    STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX * pDirtyBox) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture8_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolumeTexture8_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolumeTexture8_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DVolumeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DVolumeTexture8_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolumeTexture8_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolumeTexture8_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVolumeTexture8_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVolumeTexture8_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVolumeTexture8_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DVolumeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DVolumeTexture8_SetLOD(p,a)                  (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DVolumeTexture8_GetLOD(p)                    (p)->lpVtbl->GetLOD(p)
+#define IDirect3DVolumeTexture8_GetLevelCount(p)             (p)->lpVtbl->GetLevelCount(p)
+/*** IDirect3DVolumeTexture8 methods ***/
+#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b)          (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b)        (p)->lpVtbl->GetVolumeLevel(p,a,b)
+#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d)           (p)->lpVtbl->LockBox(p,a,b,c,d)
+#define IDirect3DVolumeTexture8_UnlockBox(p,a)               (p)->lpVtbl->UnlockBox(p,a)
+#define IDirect3DVolumeTexture8_AddDirtyBox(p,a)             (p)->lpVtbl->AddDirtyBox(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture8_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DVolumeTexture8_AddRef(p)                    (p)->AddRef()
+#define IDirect3DVolumeTexture8_Release(p)                   (p)->Release()
+/*** IDirect3DVolumeTexture8 methods: IDirect3DResource8 ***/
+#define IDirect3DVolumeTexture8_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolumeTexture8_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DVolumeTexture8_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DVolumeTexture8_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DVolumeTexture8_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DVolumeTexture8_GetType(p)                   (p)->GetType()
+/*** IDirect3DVolumeTexture8 methods: IDirect3DBaseTexture8 ***/
+#define IDirect3DVolumeTexture8_SetLOD(p,a)                  (p)->SetLOD(a)
+#define IDirect3DVolumeTexture8_GetLOD(p)                    (p)->GetLOD()
+#define IDirect3DVolumeTexture8_GetLevelCount(p)             (p)->GetLevelCount()
+/*** IDirect3DVolumeTexture8 methods ***/
+#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b)          (p)->GetLevelDesc(a,b)
+#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b)        (p)->GetVolumeLevel(a,b)
+#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d)           (p)->LockBox(a,b,c,d)
+#define IDirect3DVolumeTexture8_UnlockBox(p,a)               (p)->UnlockBox(a)
+#define IDirect3DVolumeTexture8_AddDirtyBox(p,a)             (p)->AddDirtyBox(a)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  /* defined(__cplusplus) */
+
+/* Define the main entrypoint as well */
+IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* __WINE_D3D8_H */
diff --git a/reactos/include/d3d8caps.h b/reactos/include/d3d8caps.h
new file mode 100644 (file)
index 0000000..bbee824
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2002 Jason Edmeades
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D8CAPS_H
+#define __WINE_D3D8CAPS_H
+
+/*
+ * Definitions
+ */
+
+#define D3DCAPS_READ_SCANLINE 0x20000
+
+#define D3DCURSORCAPS_COLOR   1
+#define D3DCURSORCAPS_LOWRES  2
+
+#define D3DDEVCAPS_EXECUTESYSTEMMEMORY     0x0000010
+#define D3DDEVCAPS_EXECUTEVIDEOMEMORY      0x0000020
+#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY    0x0000040
+#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY     0x0000080
+#define D3DDEVCAPS_TEXTURESYSTEMMEMORY     0x0000100
+#define D3DDEVCAPS_TEXTUREVIDEOMEMORY      0x0000200
+#define D3DDEVCAPS_DRAWPRIMTLVERTEX        0x0000400
+#define D3DDEVCAPS_CANRENDERAFTERFLIP      0x0000800
+#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM   0x0001000
+#define D3DDEVCAPS_DRAWPRIMITIVES2         0x0002000
+#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x0004000
+#define D3DDEVCAPS_DRAWPRIMITIVES2EX       0x0008000
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT     0x0010000
+#define D3DDEVCAPS_CANBLTSYSTONONLOCAL     0x0020000
+#define D3DDEVCAPS_HWRASTERIZATION         0x0080000
+#define D3DDEVCAPS_PUREDEVICE              0x0100000
+#define D3DDEVCAPS_QUINTICRTPATCHES        0x0200000
+#define D3DDEVCAPS_RTPATCHES               0x0400000
+#define D3DDEVCAPS_RTPATCHHANDLEZERO       0x0800000
+#define D3DDEVCAPS_NPATCHES                0x1000000
+
+#define D3DFVFCAPS_TEXCOORDCOUNTMASK  0x00FFFF
+#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x080000
+#define D3DFVFCAPS_PSIZE              0x100000
+
+#define D3DLINECAPS_TEXTURE           0x01
+#define D3DLINECAPS_ZTEST             0x02
+#define D3DLINECAPS_BLEND             0x04
+#define D3DLINECAPS_ALPHACMP          0x08
+#define D3DLINECAPS_FOG               0x10
+
+#define D3DPBLENDCAPS_ZERO            0x0001
+#define D3DPBLENDCAPS_ONE             0x0002
+#define D3DPBLENDCAPS_SRCCOLOR        0x0004
+#define D3DPBLENDCAPS_INVSRCCOLOR     0x0008
+#define D3DPBLENDCAPS_SRCALPHA        0x0010
+#define D3DPBLENDCAPS_INVSRCALPHA     0x0020
+#define D3DPBLENDCAPS_DESTALPHA       0x0040
+#define D3DPBLENDCAPS_INVDESTALPHA    0x0080
+#define D3DPBLENDCAPS_DESTCOLOR       0x0100
+#define D3DPBLENDCAPS_INVDESTCOLOR    0x0200
+#define D3DPBLENDCAPS_SRCALPHASAT     0x0400
+#define D3DPBLENDCAPS_BOTHSRCALPHA    0x0800
+#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x1000
+
+#define D3DPCMPCAPS_NEVER        0x01
+#define D3DPCMPCAPS_LESS         0x02
+#define D3DPCMPCAPS_EQUAL        0x04
+#define D3DPCMPCAPS_LESSEQUAL    0x08
+#define D3DPCMPCAPS_GREATER      0x10
+#define D3DPCMPCAPS_NOTEQUAL     0x20
+#define D3DPCMPCAPS_GREATEREQUAL 0x40
+#define D3DPCMPCAPS_ALWAYS       0x80
+
+#define D3DPMISCCAPS_MASKZ                 0x0002
+#define D3DPMISCCAPS_LINEPATTERNREP        0x0004
+#define D3DPMISCCAPS_CULLNONE              0x0010
+#define D3DPMISCCAPS_CULLCW                0x0020
+#define D3DPMISCCAPS_CULLCCW               0x0040
+#define D3DPMISCCAPS_COLORWRITEENABLE      0x0080
+#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x0100
+#define D3DPMISCCAPS_CLIPTLVERTS           0x0200
+#define D3DPMISCCAPS_TSSARGTEMP            0x0400
+#define D3DPMISCCAPS_BLENDOP               0x0800
+
+#define D3DPRASTERCAPS_DITHER                     0x00000001
+#define D3DPRASTERCAPS_PAT                        0x00000008
+#define D3DPRASTERCAPS_ZTEST                      0x00000010
+#define D3DPRASTERCAPS_FOGVERTEX                  0x00000080
+#define D3DPRASTERCAPS_FOGTABLE                   0x00000100
+#define D3DPRASTERCAPS_ANTIALIASEDGES             0x00001000
+#define D3DPRASTERCAPS_MIPMAPLODBIAS              0x00002000
+#define D3DPRASTERCAPS_ZBIAS                      0x00004000
+#define D3DPRASTERCAPS_ZBUFFERLESSHSR             0x00008000
+#define D3DPRASTERCAPS_FOGRANGE                   0x00010000
+#define D3DPRASTERCAPS_ANISOTROPY                 0x00020000
+#define D3DPRASTERCAPS_WBUFFER                    0x00040000
+#define D3DPRASTERCAPS_WFOG                       0x00100000
+#define D3DPRASTERCAPS_ZFOG                       0x00200000
+#define D3DPRASTERCAPS_COLORPERSPECTIVE           0x00400000
+#define D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE      0x00800000
+
+#define D3DPRESENT_INTERVAL_DEFAULT               0x00000000
+#define D3DPRESENT_INTERVAL_ONE                   0x00000001
+#define D3DPRESENT_INTERVAL_TWO                   0x00000002
+#define D3DPRESENT_INTERVAL_THREE                 0x00000004
+#define D3DPRESENT_INTERVAL_FOUR                  0x00000008
+#define D3DPRESENT_INTERVAL_IMMEDIATE             0x80000000
+
+#define D3DPSHADECAPS_COLORGOURAUDRGB             0x00008
+#define D3DPSHADECAPS_SPECULARGOURAUDRGB          0x00200
+#define D3DPSHADECAPS_ALPHAGOURAUDBLEND           0x04000
+#define D3DPSHADECAPS_FOGGOURAUD                  0x80000
+
+#define D3DPTADDRESSCAPS_WRAP                     0x01
+#define D3DPTADDRESSCAPS_MIRROR                   0x02
+#define D3DPTADDRESSCAPS_CLAMP                    0x04
+#define D3DPTADDRESSCAPS_BORDER                   0x08
+#define D3DPTADDRESSCAPS_INDEPENDENTUV            0x10
+#define D3DPTADDRESSCAPS_MIRRORONCE               0x20
+
+#define D3DPTEXTURECAPS_PERSPECTIVE              0x00001
+#define D3DPTEXTURECAPS_POW2                     0x00002
+#define D3DPTEXTURECAPS_ALPHA                    0x00004
+#define D3DPTEXTURECAPS_SQUAREONLY               0x00020
+#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00040
+#define D3DPTEXTURECAPS_ALPHAPALETTE             0x00080
+#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL       0x00100
+#define D3DPTEXTURECAPS_PROJECTED                0x00400
+#define D3DPTEXTURECAPS_CUBEMAP                  0x00800
+#define D3DPTEXTURECAPS_VOLUMEMAP                0x02000
+#define D3DPTEXTURECAPS_MIPMAP                   0x04000
+#define D3DPTEXTURECAPS_MIPVOLUMEMAP             0x08000
+#define D3DPTEXTURECAPS_MIPCUBEMAP               0x10000
+#define D3DPTEXTURECAPS_CUBEMAP_POW2             0x20000
+#define D3DPTEXTURECAPS_VOLUMEMAP_POW2           0x40000
+
+#define D3DPTFILTERCAPS_MINFPOINT                0x00000100
+#define D3DPTFILTERCAPS_MINFLINEAR               0x00000200
+#define D3DPTFILTERCAPS_MINFANISOTROPIC          0x00000400
+#define D3DPTFILTERCAPS_MIPFPOINT                0x00010000
+#define D3DPTFILTERCAPS_MIPFLINEAR               0x00020000
+#define D3DPTFILTERCAPS_MAGFPOINT                0x01000000
+#define D3DPTFILTERCAPS_MAGFLINEAR               0x02000000
+#define D3DPTFILTERCAPS_MAGFANISOTROPIC          0x04000000
+#define D3DPTFILTERCAPS_MAGFAFLATCUBIC           0x08000000
+#define D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC        0x10000000
+
+#define D3DSTENCILCAPS_KEEP                      0x01
+#define D3DSTENCILCAPS_ZERO                      0x02
+#define D3DSTENCILCAPS_REPLACE                   0x04
+#define D3DSTENCILCAPS_INCRSAT                   0x08
+#define D3DSTENCILCAPS_DECRSAT                   0x10
+#define D3DSTENCILCAPS_INVERT                    0x20
+#define D3DSTENCILCAPS_INCR                      0x40
+#define D3DSTENCILCAPS_DECR                      0x80
+
+#define D3DTEXOPCAPS_DISABLE                     0x0000001
+#define D3DTEXOPCAPS_SELECTARG1                  0x0000002
+#define D3DTEXOPCAPS_SELECTARG2                  0x0000004
+#define D3DTEXOPCAPS_MODULATE                    0x0000008
+#define D3DTEXOPCAPS_MODULATE2X                  0x0000010
+#define D3DTEXOPCAPS_MODULATE4X                  0x0000020
+#define D3DTEXOPCAPS_ADD                         0x0000040
+#define D3DTEXOPCAPS_ADDSIGNED                   0x0000080
+#define D3DTEXOPCAPS_ADDSIGNED2X                 0x0000100
+#define D3DTEXOPCAPS_SUBTRACT                    0x0000200
+#define D3DTEXOPCAPS_ADDSMOOTH                   0x0000400
+#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA           0x0000800
+#define D3DTEXOPCAPS_BLENDTEXTUREALPHA           0x0001000
+#define D3DTEXOPCAPS_BLENDFACTORALPHA            0x0002000
+#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM         0x0004000
+#define D3DTEXOPCAPS_BLENDCURRENTALPHA           0x0008000
+#define D3DTEXOPCAPS_PREMODULATE                 0x0010000
+#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR      0x0020000
+#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA      0x0040000
+#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR   0x0080000
+#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA   0x0100000
+#define D3DTEXOPCAPS_BUMPENVMAP                  0x0200000
+#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE         0x0400000
+#define D3DTEXOPCAPS_DOTPRODUCT3                 0x0800000
+#define D3DTEXOPCAPS_MULTIPLYADD                 0x1000000
+#define D3DTEXOPCAPS_LERP                        0x2000000
+
+#define D3DVTXPCAPS_TEXGEN                       0x01
+#define D3DVTXPCAPS_MATERIALSOURCE7              0x02
+#define D3DVTXPCAPS_DIRECTIONALLIGHTS            0x08
+#define D3DVTXPCAPS_POSITIONALLIGHTS             0x10
+#define D3DVTXPCAPS_LOCALVIEWER                  0x20
+#define D3DVTXPCAPS_TWEENING                     0x40
+
+#define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD  0x00000020
+#define D3DCAPS3_RESERVED                          0x8000001f
+
+#define D3DCAPS2_CANCALIBRATEGAMMA                 0x0100000
+#define D3DCAPS2_CANRENDERWINDOWED                 0x0080000
+#define D3DCAPS2_CANMANAGERESOURCE                 0x10000000
+#define D3DCAPS2_DYNAMICTEXTURES                   0x20000000
+#define D3DCAPS2_FULLSCREENGAMMA                   0x0020000
+#define D3DCAPS2_NO2DDURING3DSCENE                 0x0000002
+#define D3DCAPS2_RESERVED                          0x2000000
+
+/*
+ * The d3dcaps8 structure
+ */
+typedef struct _D3DCAPS8 {
+    D3DDEVTYPE          DeviceType;
+    UINT                AdapterOrdinal;
+
+    DWORD               Caps;
+    DWORD               Caps2;
+    DWORD               Caps3;
+    DWORD               PresentationIntervals;
+
+    DWORD               CursorCaps;
+
+    DWORD               DevCaps;
+
+    DWORD               PrimitiveMiscCaps;
+    DWORD               RasterCaps;
+    DWORD               ZCmpCaps;
+    DWORD               SrcBlendCaps;
+    DWORD               DestBlendCaps;
+    DWORD               AlphaCmpCaps;
+    DWORD               ShadeCaps;
+    DWORD               TextureCaps;
+    DWORD               TextureFilterCaps;
+    DWORD               CubeTextureFilterCaps;
+    DWORD               VolumeTextureFilterCaps;
+    DWORD               TextureAddressCaps;
+    DWORD               VolumeTextureAddressCaps;
+
+    DWORD               LineCaps;
+
+    DWORD               MaxTextureWidth, MaxTextureHeight;
+    DWORD               MaxVolumeExtent;
+
+    DWORD               MaxTextureRepeat;
+    DWORD               MaxTextureAspectRatio;
+    DWORD               MaxAnisotropy;
+    float               MaxVertexW;
+
+    float               GuardBandLeft;
+    float               GuardBandTop;
+    float               GuardBandRight;
+    float               GuardBandBottom;
+
+    float               ExtentsAdjust;
+    DWORD               StencilCaps;
+
+    DWORD               FVFCaps;
+    DWORD               TextureOpCaps;
+    DWORD               MaxTextureBlendStages;
+    DWORD               MaxSimultaneousTextures;
+
+    DWORD               VertexProcessingCaps;
+    DWORD               MaxActiveLights;
+    DWORD               MaxUserClipPlanes;
+    DWORD               MaxVertexBlendMatrices;
+    DWORD               MaxVertexBlendMatrixIndex;
+
+    float               MaxPointSize;
+
+    DWORD               MaxPrimitiveCount;
+    DWORD               MaxVertexIndex;
+    DWORD               MaxStreams;
+    DWORD               MaxStreamStride;
+
+    DWORD               VertexShaderVersion;
+    DWORD               MaxVertexShaderConst;
+
+    DWORD               PixelShaderVersion;
+    float               MaxPixelShaderValue;
+} D3DCAPS8;
+
+#endif  /* __WINE_D3D8CAPS_H */
diff --git a/reactos/include/d3d8types.h b/reactos/include/d3d8types.h
new file mode 100644 (file)
index 0000000..5253cfa
--- /dev/null
@@ -0,0 +1,1210 @@
+/*
+ * Copyright (C) 2002 Jason Edmeades
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D8TYPES_H
+#define __WINE_D3D8TYPES_H
+
+
+/*****************************************************************************
+ * Direct 3D v8 #defines
+ */
+
+#define D3DCLEAR_TARGET   1
+#define D3DCLEAR_ZBUFFER  2
+#define D3DCLEAR_STENCIL  4
+
+#define D3DCLIPPLANE0 (1 << 0)
+#define D3DCLIPPLANE1 (1 << 1)
+#define D3DCLIPPLANE2 (1 << 2)
+#define D3DCLIPPLANE3 (1 << 3)
+#define D3DCLIPPLANE4 (1 << 4)
+#define D3DCLIPPLANE5 (1 << 5)
+
+#define D3DCOLOR_ARGB(a,r,g,b)        ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
+#define D3DCOLOR_COLORVALUE(r,g,b,a)  D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f))
+#define D3DCOLOR_RGBA(r,g,b,a)        D3DCOLOR_ARGB(a,r,g,b)
+#define D3DCOLOR_XRGB(r,g,b)          D3DCOLOR_ARGB(0xff,r,g,b)
+
+#define D3DCOLORWRITEENABLED_RED     1
+#define D3DCOLORWRITEENABLED_GREEN   2
+#define D3DCOLORWRITEENABLED_BLUE    4
+#define D3DCOLORWRITEENABLED_ALPHA   8
+
+#define D3DCS_LEFT                 0x001
+#define D3DCS_RIGHT                0x002
+#define D3DCS_TOP                  0x004
+#define D3DCS_BOTTOM               0x008
+#define D3DCS_FRONT                0x010
+#define D3DCS_BACK                 0x020
+#define D3DCS_PLANE0               0x040
+#define D3DCS_PLANE1               0x080
+#define D3DCS_PLANE2               0x100
+#define D3DCS_PLANE3               0x200
+#define D3DCS_PLANE4               0x400
+#define D3DCS_PLANE5               0x800
+#define D3DCS_ALL                  0xFFF
+
+#define D3DFVF_TEXTUREFORMAT1 3
+#define D3DFVF_TEXTUREFORMAT2 0
+#define D3DFVF_TEXTUREFORMAT3 1
+#define D3DFVF_TEXTUREFORMAT4 2
+#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16))
+#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2)
+#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16))
+#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16))
+
+#define D3DLOCK_READONLY           0x0010
+#define D3DLOCK_NOSYSLOCK          0x0800
+#define D3DLOCK_NOOVERWRITE        0x1000
+#define D3DLOCK_DISCARD            0x2000
+#define D3DLOCK_NO_DIRTY_UPDATE    0x8000
+
+#define D3DMAXUSERCLIPPLANES       32
+
+#define D3DRENDERSTATE_WRAPBIAS    0x80
+
+#define D3DTSS_TCI_PASSTHRU                       0x00000
+#define D3DTSS_TCI_CAMERASPACENORMAL              0x10000
+#define D3DTSS_TCI_CAMERASPACEPOSITION            0x20000
+#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR    0x30000
+
+
+#define D3DTS_WORLD  D3DTS_WORLDMATRIX(0)
+#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1)
+#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2)
+#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3)
+#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)
+
+#define D3DUSAGE_RENDERTARGET       0x01
+#define D3DUSAGE_DEPTHSTENCIL       0x02
+#define D3DUSAGE_WRITEONLY          0x08
+#define D3DUSAGE_SOFTWAREPROCESSING 0x10
+#define D3DUSAGE_DONOTCLIP          0x20
+#define D3DUSAGE_POINTS             0x40
+#define D3DUSAGE_RTPATCHES          0x80
+#define D3DUSAGE_NPATCHES           0x100
+#define D3DUSAGE_DYNAMIC            0x200
+
+#define D3DWRAP_U        1
+#define D3DWRAP_V        2
+#define D3DWRAP_W        4
+#define D3DWRAPCOORD_0   1
+#define D3DWRAPCOORD_1   2
+#define D3DWRAPCOORD_2   4
+#define D3DWRAPCOORD_3   8
+
+#define MAX_DEVICE_IDENTIFIER_STRING        512
+
+#define D3DFVF_RESERVED0           0x0001
+#define D3DFVF_POSITION_MASK       0x000E
+#define D3DFVF_XYZ                 0x0002
+#define D3DFVF_XYZRHW              0x0004
+#define D3DFVF_XYZB1               0x0006
+#define D3DFVF_XYZB2               0x0008
+#define D3DFVF_XYZB3               0x000a
+#define D3DFVF_XYZB4               0x000c
+#define D3DFVF_XYZB5               0x000e
+#define D3DFVF_NORMAL              0x0010
+#define D3DFVF_PSIZE               0x0020
+#define D3DFVF_DIFFUSE             0x0040
+#define D3DFVF_SPECULAR            0x0080
+#define D3DFVF_TEXCOUNT_MASK       0x0f00
+#define D3DFVF_TEXCOUNT_SHIFT           8
+#define D3DFVF_TEX0                0x0000
+#define D3DFVF_TEX1                0x0100
+#define D3DFVF_TEX2                0x0200
+#define D3DFVF_TEX3                0x0300
+#define D3DFVF_TEX4                0x0400
+#define D3DFVF_TEX5                0x0500
+#define D3DFVF_TEX6                0x0600
+#define D3DFVF_TEX7                0x0700
+#define D3DFVF_TEX8                0x0800
+#define D3DFVF_LASTBETA_UBYTE4     0x1000
+#define D3DFVF_RESERVED2           0xE000
+
+#define D3DTA_SELECTMASK        0x0000000f
+#define D3DTA_DIFFUSE           0x00000000
+#define D3DTA_CURRENT           0x00000001
+#define D3DTA_TEXTURE           0x00000002
+#define D3DTA_TFACTOR           0x00000003
+#define D3DTA_SPECULAR          0x00000004
+#define D3DTA_COMPLEMENT        0x00000010
+#define D3DTA_ALPHAREPLICATE    0x00000020
+#define D3DTA_TEMP              0x00000005
+
+#define D3DCOLORWRITEENABLE_RED   (1L<<0)   
+#define D3DCOLORWRITEENABLE_GREEN (1L<<1)
+#define D3DCOLORWRITEENABLE_BLUE  (1L<<2)
+#define D3DCOLORWRITEENABLE_ALPHA (1L<<3)
+
+
+
+#define MAKEFOURCC(ch0, ch1, ch2, ch3)  \
+    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |  \
+    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+
+
+/**************************** 
+ * Vertex Shaders Declaration
+ */
+
+typedef enum _D3DVSD_TOKENTYPE {
+  D3DVSD_TOKEN_NOP         = 0,
+  D3DVSD_TOKEN_STREAM      = 1,
+  D3DVSD_TOKEN_STREAMDATA  = 2,
+  D3DVSD_TOKEN_TESSELLATOR = 3,
+  D3DVSD_TOKEN_CONSTMEM    = 4,
+  D3DVSD_TOKEN_EXT         = 5,
+  /* RESERVED              = 6 */
+  D3DVSD_TOKEN_END         = 7,
+  D3DVSD_FORCE_DWORD       = 0x7FFFFFFF
+} D3DVSD_TOKENTYPE;
+
+/** input registers for vertes shaders functions */
+/*
+#define D3DVSDE_POSITION      0
+#define D3DVSDE_BLENDWEIGHT   1
+#define D3DVSDE_BLENDINDICES  2
+#define D3DVSDE_NORMAL        3
+#define D3DVSDE_PSIZE         4
+#define D3DVSDE_DIFFUSE       5
+#define D3DVSDE_SPECULAR      6
+#define D3DVSDE_TEXCOORD0     7
+#define D3DVSDE_TEXCOORD1     8
+#define D3DVSDE_TEXCOORD2     9
+#define D3DVSDE_TEXCOORD3    10
+#define D3DVSDE_TEXCOORD4    11
+#define D3DVSDE_TEXCOORD5    12
+#define D3DVSDE_TEXCOORD6    13
+#define D3DVSDE_TEXCOORD7    14
+#define D3DVSDE_POSITION2    15
+#define D3DVSDE_NORMAL2      16
+*/
+/** Address of the vertex register. 0 - 16 */
+typedef enum _D3DVSDE_REGISTER {
+  D3DVSDE_POSITION     =  0,
+  D3DVSDE_BLENDWEIGHT  =  1,
+  D3DVSDE_BLENDINDICES =  2,
+  D3DVSDE_NORMAL       =  3,
+  D3DVSDE_PSIZE        =  4,
+  D3DVSDE_DIFFUSE      =  5,
+  D3DVSDE_SPECULAR     =  6,
+  D3DVSDE_TEXCOORD0    =  7,
+  D3DVSDE_TEXCOORD1    =  8,
+  D3DVSDE_TEXCOORD2    =  9,
+  D3DVSDE_TEXCOORD3    = 10,
+  D3DVSDE_TEXCOORD4    = 11,
+  D3DVSDE_TEXCOORD5    = 12,
+  D3DVSDE_TEXCOORD6    = 13,
+  D3DVSDE_TEXCOORD7    = 14,
+  D3DVSDE_POSITION2    = 15,
+  D3DVSDE_NORMAL2      = 16
+} D3DVSDE_REGISTER;
+
+/** bit-field declaration for VertexRegister Type */
+/*
+#define D3DVSDT_FLOAT1      0x00
+#define D3DVSDT_FLOAT2      0x01
+#define D3DVSDT_FLOAT3      0x02
+#define D3DVSDT_FLOAT4      0x03
+#define D3DVSDT_D3DCOLOR    0x04
+#define D3DVSDT_UBYTE4      0x05
+#define D3DVSDT_SHORT2      0x06
+#define D3DVSDT_SHORT4      0x07
+*/
+typedef enum _D3DVSDT_TYPE {
+  D3DVSDT_FLOAT1   = 0x00,
+  D3DVSDT_FLOAT2   = 0x01,
+  D3DVSDT_FLOAT3   = 0x02,
+  D3DVSDT_FLOAT4   = 0x03,
+  D3DVSDT_D3DCOLOR = 0x04,
+  D3DVSDT_UBYTE4   = 0x05,
+  D3DVSDT_SHORT2   = 0x06,
+  D3DVSDT_SHORT4   = 0x07
+} D3DVSDT_TYPE;
+
+
+#define D3DVSD_CONSTADDRESSSHIFT  0
+#define D3DVSD_EXTINFOSHIFT       0
+#define D3DVSD_STREAMNUMBERSHIFT  0
+#define D3DVSD_VERTEXREGSHIFT     0
+#define D3DVSD_CONSTRSSHIFT      16
+#define D3DVSD_DATATYPESHIFT     16
+#define D3DVSD_SKIPCOUNTSHIFT    16
+#define D3DVSD_VERTEXREGINSHIFT  20
+#define D3DVSD_EXTCOUNTSHIFT     24
+#define D3DVSD_CONSTCOUNTSHIFT   25
+#define D3DVSD_DATALOADTYPESHIFT 28
+#define D3DVSD_STREAMTESSSHIFT   28
+#define D3DVSD_TOKENTYPESHIFT    29
+
+#define D3DVSD_CONSTADDRESSMASK  (0x7F     << D3DVSD_CONSTADDRESSSHIFT)
+#define D3DVSD_EXTINFOMASK       (0xFFFFFF << D3DVSD_EXTINFOSHIFT)
+#define D3DVSD_STREAMNUMBERMASK  (0xF      << D3DVSD_STREAMNUMBERSHIFT)
+#define D3DVSD_VERTEXREGMASK     (0x1F     << D3DVSD_VERTEXREGSHIFT)
+#define D3DVSD_CONSTRSMASK       (0x1FFF   << D3DVSD_CONSTRSSHIFT)
+#define D3DVSD_DATATYPEMASK      (0xF      << D3DVSD_DATATYPESHIFT)
+#define D3DVSD_SKIPCOUNTMASK     (0xF      << D3DVSD_SKIPCOUNTSHIFT)
+#define D3DVSD_EXTCOUNTMASK      (0x1F     << D3DVSD_EXTCOUNTSHIFT)
+#define D3DVSD_VERTEXREGINMASK   (0xF      << D3DVSD_VERTEXREGINSHIFT)
+#define D3DVSD_CONSTCOUNTMASK    (0xF      << D3DVSD_CONSTCOUNTSHIFT)
+#define D3DVSD_DATALOADTYPEMASK  (0x1      << D3DVSD_DATALOADTYPESHIFT)
+#define D3DVSD_STREAMTESSMASK    (0x1      << D3DVSD_STREAMTESSSHIFT)
+#define D3DVSD_TOKENTYPEMASK     (0x7      << D3DVSD_TOKENTYPESHIFT)
+
+
+#define D3DVSD_MAKETOKENTYPE(TokenType) \
+  ((TokenType << D3DVSD_TOKENTYPESHIFT) & D3DVSD_TOKENTYPEMASK)
+
+#define D3DVSD_CONST(ConstantAddress, Count) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_CONSTMEM) | ((Count) << D3DVSD_CONSTCOUNTSHIFT) | (ConstantAddress))
+
+#define D3DVSD_END() 0xFFFFFFFF
+
+#define D3DVSD_NOP() 0x00000000
+
+#define D3DVSD_REG(VertexRegister, Type) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | ((Type) << D3DVSD_DATATYPESHIFT) | (VertexRegister))
+
+#define D3DVSD_SKIP(Count) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | 0x10000000 | ((Count) << D3DVSD_SKIPCOUNTSHIFT))
+
+#define D3DVSD_STREAM(StreamNumber) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (StreamNumber))
+
+#define D3DVSD_STREAM_TESS() \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (D3DVSD_STREAMTESSMASK))
+
+#define D3DVSD_TESSNORMAL(RegisterIn, RegisterOut) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | ((RegisterIn) << D3DVSD_VERTEXREGINSHIFT) | ((0x02) << D3DVSD_DATATYPESHIFT) | (RegisterOut))
+
+#define D3DVSD_TESSUV(Register) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | 0x10000000 | ((0x01) << D3DVSD_DATATYPESHIFT) | (Register))
+
+
+/********************************
+ * Pixel/Vertex Shaders Functions
+ */
+
+/** Maximum number of supported texture coordinates sets operation */
+#define D3DDP_MAXTEXCOORD   8
+
+/** opcode token mask */
+#define D3DSI_OPCODE_MASK 0x0000FFFF
+
+/** opcodes types for PS and VS */
+typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE {
+  D3DSIO_NOP          =  0,
+  D3DSIO_MOV          =  1,
+  D3DSIO_ADD          =  2,
+  D3DSIO_SUB          =  3,
+  D3DSIO_MAD          =  4,
+  D3DSIO_MUL          =  5,
+  D3DSIO_RCP          =  6,
+  D3DSIO_RSQ          =  7,
+  D3DSIO_DP3          =  8,
+  D3DSIO_DP4          =  9,
+  D3DSIO_MIN          = 10,
+  D3DSIO_MAX          = 11,
+  D3DSIO_SLT          = 12,
+  D3DSIO_SGE          = 13,
+  D3DSIO_EXP          = 14,
+  D3DSIO_LOG          = 15,
+  D3DSIO_LIT          = 16,
+  D3DSIO_DST          = 17,
+  D3DSIO_LRP          = 18,
+  D3DSIO_FRC          = 19,
+  D3DSIO_M4x4         = 20,
+  D3DSIO_M4x3         = 21,
+  D3DSIO_M3x4         = 22,
+  D3DSIO_M3x3         = 23,
+  D3DSIO_M3x2         = 24,
+
+  D3DSIO_TEXCOORD     = 64,
+  D3DSIO_TEXKILL      = 65,
+  D3DSIO_TEX          = 66,
+  D3DSIO_TEXBEM       = 67,
+  D3DSIO_TEXBEML      = 68,
+  D3DSIO_TEXREG2AR    = 69,
+  D3DSIO_TEXREG2GB    = 70,
+  D3DSIO_TEXM3x2PAD   = 71,
+  D3DSIO_TEXM3x2TEX   = 72,
+  D3DSIO_TEXM3x3PAD   = 73,
+  D3DSIO_TEXM3x3TEX   = 74,
+  D3DSIO_TEXM3x3DIFF  = 75,
+  D3DSIO_TEXM3x3SPEC  = 76,
+  D3DSIO_TEXM3x3VSPEC = 77,
+  D3DSIO_EXPP         = 78,
+  D3DSIO_LOGP         = 79,
+  D3DSIO_CND          = 80,
+  D3DSIO_DEF          = 81,
+  D3DSIO_TEXREG2RGB   = 82,
+  D3DSIO_TEXDP3TEX    = 83,
+  D3DSIO_TEXM3x2DEPTH = 84,
+  D3DSIO_TEXDP3       = 85,
+  D3DSIO_TEXM3x3      = 86,
+  D3DSIO_TEXDEPTH     = 87,
+  D3DSIO_CMP          = 88,
+  D3DSIO_BEM          = 89,
+
+  D3DSIO_PHASE        = 0xFFFD,
+  D3DSIO_COMMENT      = 0xFFFE,
+  D3DSIO_END          = 0XFFFF,
+
+  D3DSIO_FORCE_DWORD  = 0X7FFFFFFF /** for 32-bit alignment */
+} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+/** for parallelism */
+#define D3DSI_COISSUE 0x40000000
+
+/** destination parameter modifiers (.xyzw) */
+#define D3DSP_WRITEMASK_0       0x00010000 /* .x r */
+#define D3DSP_WRITEMASK_1       0x00020000 /* .y g */
+#define D3DSP_WRITEMASK_2       0x00040000 /* .z b */
+#define D3DSP_WRITEMASK_3       0x00080000 /* .w a */
+#define D3DSP_WRITEMASK_ALL     0x000F0000 /* all */
+
+#define D3DSP_DSTMOD_SHIFT      20
+#define D3DSP_DSTMOD_MASK       (0xF << D3DSP_DSTMOD_SHIFT)
+
+typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE {
+  D3DSPDM_NONE         = 0 << D3DSP_DSTMOD_SHIFT,
+  D3DSPDM_SATURATE     = 1 << D3DSP_DSTMOD_SHIFT,
+  D3DSPDM_FORCE_DWORD  = 0X7FFFFFFF
+} D3DSHADER_PARAM_DSTMOD_TYPE;
+
+/** destination param */
+#define D3DSP_DSTSHIFT_SHIFT     24
+#define D3DSP_DSTSHIFT_MASK      (0xF << D3DSP_DSTSHIFT_SHIFT)
+
+/** destination/source reg type */
+#define D3DSP_REGTYPE_SHIFT      28
+#define D3DSP_REGTYPE_MASK       (0x7 << D3DSP_REGTYPE_SHIFT)
+
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE {
+  D3DSPR_TEMP         = 0 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_INPUT        = 1 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_CONST        = 2 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_ADDR         = 3 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_TEXTURE      = 3 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_RASTOUT      = 4 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_ATTROUT      = 5 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_TEXCRDOUT    = 6 << D3DSP_REGTYPE_SHIFT,
+  D3DSPR_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSHADER_PARAM_REGISTER_TYPE;
+
+typedef enum _D3DVS_RASTOUT_OFFSETS {
+  D3DSRO_POSITION     = 0,
+  D3DSRO_FOG          = 1,
+  D3DSRO_POINT_SIZE   = 2,
+  D3DSRO_FORCE_DWORD  = 0x7FFFFFFF
+} D3DVS_RASTOUT_OFFSETS;
+
+#define D3DVS_ADDRESSMODE_SHIFT  13
+#define D3DVS_ADDRESSMODE_MASK   (0x1 << D3DVS_ADDRESSMODE_SHIFT)
+
+typedef enum _D3DVS_ADDRESSMODE_TYPE {
+  D3DVS_ADDRMODE_ABSOLUTE     = 0 << D3DVS_ADDRESSMODE_SHIFT,
+  D3DVS_ADDRMODE_RELATIVE     = 1 << D3DVS_ADDRESSMODE_SHIFT,
+  D3DVS_ADDRMODE_FORCE_DWORD  = 0x7FFFFFFF
+} D3DVS_ADDRESSMODE_TYPE;
+
+#define D3DVS_SWIZZLE_SHIFT      16
+#define D3DVS_SWIZZLE_MASK       (0xFF << D3DVS_SWIZZLE_SHIFT)
+
+#define D3DSP_SWIZZLE_SHIFT      16
+#define D3DSP_SWIZZLE_MASK       (0xFF << D3DSP_SWIZZLE_SHIFT)
+
+#define D3DVS_X_X       (0 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Y       (1 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Z       (2 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_W       (3 << D3DVS_SWIZZLE_SHIFT)
+
+#define D3DVS_Y_X       (0 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_W       (3 << (D3DVS_SWIZZLE_SHIFT + 2))
+
+#define D3DVS_Z_X       (0 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_W       (3 << (D3DVS_SWIZZLE_SHIFT + 4))
+
+#define D3DVS_W_X       (0 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_W       (3 << (D3DVS_SWIZZLE_SHIFT + 6))
+
+#define D3DVS_NOSWIZZLE (D3DVS_X_X | D3DVS_Y_Y | D3DVS_Z_Z | D3DVS_W_W)
+
+#define D3DSP_NOSWIZZLE \
+    ((0 << (D3DSP_SWIZZLE_SHIFT + 0)) | (1 << (D3DSP_SWIZZLE_SHIFT + 2)) | (2 << (D3DSP_SWIZZLE_SHIFT + 4)) | (3 << (D3DSP_SWIZZLE_SHIFT + 6)))
+
+#define D3DSP_SRCMOD_SHIFT      24
+#define D3DSP_SRCMOD_MASK       (0xF << D3DSP_SRCMOD_SHIFT)
+
+typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE {
+  D3DSPSM_NONE         =  0 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_NEG          =  1 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_BIAS         =  2 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_BIASNEG      =  3 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_SIGN         =  4 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_SIGNNEG      =  5 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_COMP         =  6 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_X2           =  7 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_X2NEG        =  8 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_DZ           =  9 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_DW           = 10 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSHADER_PARAM_SRCMOD_TYPE;
+
+#define D3DPS_VERSION(major, minor) (0xFFFF0000 | ((major) << 8) | (minor))
+#define D3DVS_VERSION(major, minor) (0xFFFE0000 | ((major) << 8) | (minor))
+#define D3DSHADER_VERSION_MAJOR(version) (((version) >> 8) & 0xFF)
+#define D3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
+
+#define D3DSI_COMMENTSIZE_SHIFT 16
+#define D3DSI_COMMENTSIZE_MASK (0x7FFF << D3DSI_COMMENTSIZE_SHIFT)
+
+#define D3DSHADER_COMMENT(commentSize) \
+  ((((commentSize) << D3DSI_COMMENTSIZE_SHIFT) & D3DSI_COMMENTSIZE_MASK) | D3DSIO_COMMENT)
+
+#define D3DPS_END() 0x0000FFFF
+#define D3DVS_END() 0x0000FFFF
+
+
+/*****************************************************************************
+ * Direct 3D v8 enumerated types
+ */
+typedef enum _D3DBACKBUFFER_TYPE {
+    D3DBACKBUFFER_TYPE_MONO         = 0,
+    D3DBACKBUFFER_TYPE_LEFT         = 1,
+    D3DBACKBUFFER_TYPE_RIGHT        = 2,
+
+    D3DBACKBUFFER_TYPE_FORCE_DWORD  = 0x7fffffff
+} D3DBACKBUFFER_TYPE;
+
+typedef enum _D3DBASISTYPE{
+   D3DBASIS_BEZIER        = 0,
+   D3DBASIS_BSPLINE       = 1,
+   D3DBASIS_INTERPOLATE   = 2,
+
+   D3DBASIS_FORCE_DWORD   = 0x7fffffff
+} D3DBASISTYPE;
+
+typedef enum _D3DBLEND {
+    D3DBLEND_ZERO               =  1,
+    D3DBLEND_ONE                =  2,
+    D3DBLEND_SRCCOLOR           =  3,
+    D3DBLEND_INVSRCCOLOR        =  4,
+    D3DBLEND_SRCALPHA           =  5,
+    D3DBLEND_INVSRCALPHA        =  6,
+    D3DBLEND_DESTALPHA          =  7,
+    D3DBLEND_INVDESTALPHA       =  8,
+    D3DBLEND_DESTCOLOR          =  9,
+    D3DBLEND_INVDESTCOLOR       = 10,
+    D3DBLEND_SRCALPHASAT        = 11,
+    D3DBLEND_BOTHSRCALPHA       = 12,
+    D3DBLEND_BOTHINVSRCALPHA    = 13,
+
+    D3DBLEND_FORCE_DWORD        = 0x7fffffff
+} D3DBLEND;
+
+typedef enum _D3DBLENDOP {
+    D3DBLENDOP_ADD              = 1,
+    D3DBLENDOP_SUBTRACT         = 2,
+    D3DBLENDOP_REVSUBTRACT      = 3,
+    D3DBLENDOP_MIN              = 4,
+    D3DBLENDOP_MAX              = 5,
+
+    D3DBLENDOP_FORCE_DWORD      = 0x7fffffff
+} D3DBLENDOP;
+
+typedef enum _D3DCMPFUNC {
+    D3DCMP_NEVER                = 1,
+    D3DCMP_LESS                 = 2,
+    D3DCMP_EQUAL                = 3,
+    D3DCMP_LESSEQUAL            = 4,
+    D3DCMP_GREATER              = 5,
+    D3DCMP_NOTEQUAL             = 6,
+    D3DCMP_GREATEREQUAL         = 7,
+    D3DCMP_ALWAYS               = 8,
+
+    D3DCMP_FORCE_DWORD          = 0x7fffffff
+} D3DCMPFUNC;
+
+typedef enum _D3DCUBEMAP_FACES {
+    D3DCUBEMAP_FACE_POSITIVE_X     = 0,
+    D3DCUBEMAP_FACE_NEGATIVE_X     = 1,
+    D3DCUBEMAP_FACE_POSITIVE_Y     = 2,
+    D3DCUBEMAP_FACE_NEGATIVE_Y     = 3,
+    D3DCUBEMAP_FACE_POSITIVE_Z     = 4,
+    D3DCUBEMAP_FACE_NEGATIVE_Z     = 5,
+
+    D3DCUBEMAP_FACE_FORCE_DWORD    = 0xffffffff
+} D3DCUBEMAP_FACES;
+
+typedef enum _D3DCULL {
+    D3DCULL_NONE                = 1,
+    D3DCULL_CW                  = 2,
+    D3DCULL_CCW                 = 3,
+
+    D3DCULL_FORCE_DWORD         = 0x7fffffff
+} D3DCULL;
+
+typedef enum _D3DDEBUGMONITORTOKENS {
+    D3DDMT_ENABLE          = 0,
+    D3DDMT_DISABLE         = 1,
+
+    D3DDMT_FORCE_DWORD     = 0x7fffffff
+} D3DDEBUGMONITORTOKENS;
+
+typedef enum _D3DDEVTYPE {
+    D3DDEVTYPE_HAL         = 1,
+    D3DDEVTYPE_REF         = 2,
+    D3DDEVTYPE_SW          = 3,
+
+    D3DDEVTYPE_FORCE_DWORD = 0xffffffff
+} D3DDEVTYPE;
+
+typedef enum _D3DFILLMODE {
+    D3DFILL_POINT               = 1,
+    D3DFILL_WIREFRAME           = 2,
+    D3DFILL_SOLID               = 3,
+
+    D3DFILL_FORCE_DWORD         = 0x7fffffff
+} D3DFILLMODE;
+
+typedef enum _D3DFOGMODE {
+    D3DFOG_NONE                 = 0,
+    D3DFOG_EXP                  = 1,
+    D3DFOG_EXP2                 = 2,
+    D3DFOG_LINEAR               = 3,
+
+    D3DFOG_FORCE_DWORD          = 0x7fffffff
+} D3DFOGMODE;
+
+typedef enum _D3DFORMAT {
+    D3DFMT_UNKNOWN              =   0,
+
+    D3DFMT_R8G8B8               =  20,
+    D3DFMT_A8R8G8B8             =  21,
+    D3DFMT_X8R8G8B8             =  22,
+    D3DFMT_R5G6B5               =  23,
+    D3DFMT_X1R5G5B5             =  24,
+    D3DFMT_A1R5G5B5             =  25,
+    D3DFMT_A4R4G4B4             =  26,
+    D3DFMT_R3G3B2               =  27,
+    D3DFMT_A8                   =  28,
+    D3DFMT_A8R3G3B2             =  29,
+    D3DFMT_X4R4G4B4             =  30,
+
+    D3DFMT_A8P8                 =  40,
+    D3DFMT_P8                   =  41,
+
+    D3DFMT_L8                   =  50,
+    D3DFMT_A8L8                 =  51,
+    D3DFMT_A4L4                 =  52,
+
+    D3DFMT_V8U8                 =  60,
+    D3DFMT_L6V5U5               =  61,
+    D3DFMT_X8L8V8U8             =  62,
+    D3DFMT_Q8W8V8U8             =  63,
+    D3DFMT_V16U16               =  64,
+    D3DFMT_W11V11U10            =  65,
+
+    D3DFMT_UYVY                 =  MAKEFOURCC('U', 'Y', 'V', 'Y'),
+    D3DFMT_YUY2                 =  MAKEFOURCC('Y', 'U', 'Y', '2'),
+    D3DFMT_DXT1                 =  MAKEFOURCC('D', 'X', 'T', '1'),
+    D3DFMT_DXT2                 =  MAKEFOURCC('D', 'X', 'T', '2'),
+    D3DFMT_DXT3                 =  MAKEFOURCC('D', 'X', 'T', '3'),
+    D3DFMT_DXT4                 =  MAKEFOURCC('D', 'X', 'T', '4'),
+    D3DFMT_DXT5                 =  MAKEFOURCC('D', 'X', 'T', '5'),
+
+    D3DFMT_D16_LOCKABLE         =  70,
+    D3DFMT_D32                  =  71,
+    D3DFMT_D15S1                =  73,
+    D3DFMT_D24S8                =  75,
+    D3DFMT_D16                  =  80,
+    D3DFMT_D24X8                =  77,
+    D3DFMT_D24X4S4              =  79,
+
+    D3DFMT_VERTEXDATA           = 100,
+    D3DFMT_INDEX16              = 101,
+    D3DFMT_INDEX32              = 102,
+
+    D3DFMT_FORCE_DWORD          = 0xFFFFFFFF
+} D3DFORMAT;
+
+typedef enum _D3DLIGHTTYPE {
+    D3DLIGHT_POINT          = 1,
+    D3DLIGHT_SPOT           = 2,
+    D3DLIGHT_DIRECTIONAL    = 3,
+
+    D3DLIGHT_FORCE_DWORD    = 0x7fffffff
+} D3DLIGHTTYPE;
+
+typedef enum _D3DMATERIALCOLORSOURCE {
+    D3DMCS_MATERIAL         = 0,
+    D3DMCS_COLOR1           = 1,
+    D3DMCS_COLOR2           = 2,
+
+    D3DMCS_FORCE_DWORD      = 0x7fffffff
+} D3DMATERIALCOLORSOURCE;
+
+typedef enum _D3DMULTISAMPLE_TYPE {
+    D3DMULTISAMPLE_NONE            =  0,
+    D3DMULTISAMPLE_2_SAMPLES       =  2,
+    D3DMULTISAMPLE_3_SAMPLES       =  3,
+    D3DMULTISAMPLE_4_SAMPLES       =  4,
+    D3DMULTISAMPLE_5_SAMPLES       =  5,
+    D3DMULTISAMPLE_6_SAMPLES       =  6,
+    D3DMULTISAMPLE_7_SAMPLES       =  7,
+    D3DMULTISAMPLE_8_SAMPLES       =  8,
+    D3DMULTISAMPLE_9_SAMPLES       =  9,
+    D3DMULTISAMPLE_10_SAMPLES      = 10,
+    D3DMULTISAMPLE_11_SAMPLES      = 11,
+    D3DMULTISAMPLE_12_SAMPLES      = 12,
+    D3DMULTISAMPLE_13_SAMPLES      = 13,
+    D3DMULTISAMPLE_14_SAMPLES      = 14,
+    D3DMULTISAMPLE_15_SAMPLES      = 15,
+    D3DMULTISAMPLE_16_SAMPLES      = 16,
+
+    D3DMULTISAMPLE_FORCE_DWORD     = 0xffffffff
+} D3DMULTISAMPLE_TYPE;
+
+typedef enum _D3DORDERTYPE {
+   D3DORDER_LINEAR      = 1,
+   D3DORDER_QUADRATIC   = 2,
+   D3DORDER_CUBIC       = 3,
+   D3DORDER_QUINTIC     = 5,
+
+   D3DORDER_FORCE_DWORD = 0x7fffffff
+} D3DORDERTYPE;
+
+typedef enum _D3DPATCHEDGESTYLE {
+   D3DPATCHEDGE_DISCRETE    = 0,
+   D3DPATCHEDGE_CONTINUOUS  = 1,
+
+   D3DPATCHEDGE_FORCE_DWORD = 0x7fffffff,
+} D3DPATCHEDGESTYLE;
+
+typedef enum _D3DPOOL {
+    D3DPOOL_DEFAULT                 = 0,
+    D3DPOOL_MANAGED                 = 1,
+    D3DPOOL_SYSTEMMEM               = 2,
+    D3DPOOL_SCRATCH                 = 3,
+
+    D3DPOOL_FORCE_DWORD             = 0x7fffffff
+} D3DPOOL;
+
+typedef enum _D3DPRIMITIVETYPE {
+    D3DPT_POINTLIST             = 1,
+    D3DPT_LINELIST              = 2,
+    D3DPT_LINESTRIP             = 3,
+    D3DPT_TRIANGLELIST          = 4,
+    D3DPT_TRIANGLESTRIP         = 5,
+    D3DPT_TRIANGLEFAN           = 6,
+
+    D3DPT_FORCE_DWORD           = 0x7fffffff
+} D3DPRIMITIVETYPE;
+
+typedef enum _D3DRENDERSTATETYPE {
+    D3DRS_ZENABLE                   =   7,
+    D3DRS_FILLMODE                  =   8,
+    D3DRS_SHADEMODE                 =   9,
+    D3DRS_LINEPATTERN               =  10,
+    D3DRS_ZWRITEENABLE              =  14,
+    D3DRS_ALPHATESTENABLE           =  15,
+    D3DRS_LASTPIXEL                 =  16,
+    D3DRS_SRCBLEND                  =  19,
+    D3DRS_DESTBLEND                 =  20,
+    D3DRS_CULLMODE                  =  22,
+    D3DRS_ZFUNC                     =  23,
+    D3DRS_ALPHAREF                  =  24,
+    D3DRS_ALPHAFUNC                 =  25,
+    D3DRS_DITHERENABLE              =  26,
+    D3DRS_ALPHABLENDENABLE          =  27,
+    D3DRS_FOGENABLE                 =  28,
+    D3DRS_SPECULARENABLE            =  29,
+    D3DRS_ZVISIBLE                  =  30,
+    D3DRS_FOGCOLOR                  =  34,
+    D3DRS_FOGTABLEMODE              =  35,
+    D3DRS_FOGSTART                  =  36,
+    D3DRS_FOGEND                    =  37,
+    D3DRS_FOGDENSITY                =  38,
+    D3DRS_EDGEANTIALIAS             =  40,
+    D3DRS_ZBIAS                     =  47,
+    D3DRS_RANGEFOGENABLE            =  48,
+    D3DRS_STENCILENABLE             =  52,
+    D3DRS_STENCILFAIL               =  53,
+    D3DRS_STENCILZFAIL              =  54,
+    D3DRS_STENCILPASS               =  55,
+    D3DRS_STENCILFUNC               =  56,
+    D3DRS_STENCILREF                =  57,
+    D3DRS_STENCILMASK               =  58,
+    D3DRS_STENCILWRITEMASK          =  59,
+    D3DRS_TEXTUREFACTOR             =  60,
+    D3DRS_WRAP0                     = 128,
+    D3DRS_WRAP1                     = 129,
+    D3DRS_WRAP2                     = 130,
+    D3DRS_WRAP3                     = 131,
+    D3DRS_WRAP4                     = 132,
+    D3DRS_WRAP5                     = 133,
+    D3DRS_WRAP6                     = 134,
+    D3DRS_WRAP7                     = 135,
+    D3DRS_CLIPPING                  = 136,
+    D3DRS_LIGHTING                  = 137,
+    D3DRS_AMBIENT                   = 139,
+    D3DRS_FOGVERTEXMODE             = 140,
+    D3DRS_COLORVERTEX               = 141,
+    D3DRS_LOCALVIEWER               = 142,
+    D3DRS_NORMALIZENORMALS          = 143,
+    D3DRS_DIFFUSEMATERIALSOURCE     = 145,
+    D3DRS_SPECULARMATERIALSOURCE    = 146,
+    D3DRS_AMBIENTMATERIALSOURCE     = 147,
+    D3DRS_EMISSIVEMATERIALSOURCE    = 148,
+    D3DRS_VERTEXBLEND               = 151,
+    D3DRS_CLIPPLANEENABLE           = 152,
+    D3DRS_SOFTWAREVERTEXPROCESSING  = 153,
+    D3DRS_POINTSIZE                 = 154,
+    D3DRS_POINTSIZE_MIN             = 155,
+    D3DRS_POINTSPRITEENABLE         = 156,
+    D3DRS_POINTSCALEENABLE          = 157,
+    D3DRS_POINTSCALE_A              = 158,
+    D3DRS_POINTSCALE_B              = 159,
+    D3DRS_POINTSCALE_C              = 160,
+    D3DRS_MULTISAMPLEANTIALIAS      = 161,
+    D3DRS_MULTISAMPLEMASK           = 162,
+    D3DRS_PATCHEDGESTYLE            = 163,
+    D3DRS_PATCHSEGMENTS             = 164,
+    D3DRS_DEBUGMONITORTOKEN         = 165,
+    D3DRS_POINTSIZE_MAX             = 166,
+    D3DRS_INDEXEDVERTEXBLENDENABLE  = 167,
+    D3DRS_COLORWRITEENABLE          = 168,
+    D3DRS_TWEENFACTOR               = 170,
+    D3DRS_BLENDOP                   = 171,
+    D3DRS_POSITIONORDER             = 172,
+    D3DRS_NORMALORDER               = 173,
+
+    D3DRS_FORCE_DWORD               = 0x7fffffff
+} D3DRENDERSTATETYPE;
+
+typedef enum _D3DRESOURCETYPE {
+    D3DRTYPE_SURFACE                =  1,
+    D3DRTYPE_VOLUME                 =  2,
+    D3DRTYPE_TEXTURE                =  3,
+    D3DRTYPE_VOLUMETEXTURE          =  4,
+    D3DRTYPE_CUBETEXTURE            =  5,
+    D3DRTYPE_VERTEXBUFFER           =  6,
+    D3DRTYPE_INDEXBUFFER            =  7,
+
+    D3DRTYPE_FORCE_DWORD            = 0x7fffffff
+} D3DRESOURCETYPE;
+
+typedef enum _D3DSHADEMODE {
+    D3DSHADE_FLAT               = 1,
+    D3DSHADE_GOURAUD            = 2,
+    D3DSHADE_PHONG              = 3,
+
+    D3DSHADE_FORCE_DWORD        = 0x7fffffff
+} D3DSHADEMODE;
+
+typedef enum _D3DSTATEBLOCKTYPE {
+    D3DSBT_ALL           = 1,
+    D3DSBT_PIXELSTATE    = 2,
+    D3DSBT_VERTEXSTATE   = 3,
+
+    D3DSBT_FORCE_DWORD   = 0xffffffff
+} D3DSTATEBLOCKTYPE;
+
+typedef enum _D3DSTENCILOP {
+    D3DSTENCILOP_KEEP           = 1,
+    D3DSTENCILOP_ZERO           = 2,
+    D3DSTENCILOP_REPLACE        = 3,
+    D3DSTENCILOP_INCRSAT        = 4,
+    D3DSTENCILOP_DECRSAT        = 5,
+    D3DSTENCILOP_INVERT         = 6,
+    D3DSTENCILOP_INCR           = 7,
+    D3DSTENCILOP_DECR           = 8,
+
+    D3DSTENCILOP_FORCE_DWORD    = 0x7fffffff
+} D3DSTENCILOP;
+
+typedef enum _D3DSWAPEFFECT {
+    D3DSWAPEFFECT_DISCARD         = 1,
+    D3DSWAPEFFECT_FLIP            = 2,
+    D3DSWAPEFFECT_COPY            = 3,
+    D3DSWAPEFFECT_COPY_VSYNC      = 4,
+
+    D3DSWAPEFFECT_FORCE_DWORD     = 0xFFFFFFFF
+} D3DSWAPEFFECT;
+
+typedef enum _D3DTEXTUREADDRESS {
+    D3DTADDRESS_WRAP            = 1,
+    D3DTADDRESS_MIRROR          = 2,
+    D3DTADDRESS_CLAMP           = 3,
+    D3DTADDRESS_BORDER          = 4,
+    D3DTADDRESS_MIRRORONCE      = 5,
+
+    D3DTADDRESS_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTUREADDRESS;
+
+typedef enum _D3DTEXTUREFILTERTYPE {
+    D3DTEXF_NONE            = 0,
+    D3DTEXF_POINT           = 1,
+    D3DTEXF_LINEAR          = 2,
+    D3DTEXF_ANISOTROPIC     = 3,
+    D3DTEXF_FLATCUBIC       = 4,
+    D3DTEXF_GAUSSIANCUBIC   = 5,
+
+    D3DTEXF_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTUREFILTERTYPE;
+
+typedef enum _D3DTEXTUREOP {
+    D3DTOP_DISABLE                   =  1,
+    D3DTOP_SELECTARG1                =  2,
+    D3DTOP_SELECTARG2                =  3,
+    D3DTOP_MODULATE                  =  4,
+    D3DTOP_MODULATE2X                =  5,
+    D3DTOP_MODULATE4X                =  6,
+    D3DTOP_ADD                       =  7,
+    D3DTOP_ADDSIGNED                 =  8,
+    D3DTOP_ADDSIGNED2X               =  9,
+    D3DTOP_SUBTRACT                  = 10,
+    D3DTOP_ADDSMOOTH                 = 11,
+    D3DTOP_BLENDDIFFUSEALPHA         = 12,
+    D3DTOP_BLENDTEXTUREALPHA         = 13,
+    D3DTOP_BLENDFACTORALPHA          = 14,
+    D3DTOP_BLENDTEXTUREALPHAPM       = 15,
+    D3DTOP_BLENDCURRENTALPHA         = 16,
+    D3DTOP_PREMODULATE               = 17,
+    D3DTOP_MODULATEALPHA_ADDCOLOR    = 18,
+    D3DTOP_MODULATECOLOR_ADDALPHA    = 19,
+    D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
+    D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
+    D3DTOP_BUMPENVMAP                = 22,
+    D3DTOP_BUMPENVMAPLUMINANCE       = 23,
+    D3DTOP_DOTPRODUCT3               = 24,
+    D3DTOP_MULTIPLYADD               = 25,
+    D3DTOP_LERP                      = 26,
+
+    D3DTOP_FORCE_DWORD               = 0x7fffffff,
+} D3DTEXTUREOP;
+
+typedef enum _D3DTEXTURESTAGESTATETYPE {
+    D3DTSS_COLOROP               =  1,
+    D3DTSS_COLORARG1             =  2,
+    D3DTSS_COLORARG2             =  3,
+    D3DTSS_ALPHAOP               =  4,
+    D3DTSS_ALPHAARG1             =  5,
+    D3DTSS_ALPHAARG2             =  6,
+    D3DTSS_BUMPENVMAT00          =  7,
+    D3DTSS_BUMPENVMAT01          =  8,
+    D3DTSS_BUMPENVMAT10          =  9,
+    D3DTSS_BUMPENVMAT11          = 10,
+    D3DTSS_TEXCOORDINDEX         = 11,
+    D3DTSS_ADDRESSU              = 13,
+    D3DTSS_ADDRESSV              = 14,
+    D3DTSS_BORDERCOLOR           = 15,
+    D3DTSS_MAGFILTER             = 16,
+    D3DTSS_MINFILTER             = 17,
+    D3DTSS_MIPFILTER             = 18,
+    D3DTSS_MIPMAPLODBIAS         = 19,
+    D3DTSS_MAXMIPLEVEL           = 20,
+    D3DTSS_MAXANISOTROPY         = 21,
+    D3DTSS_BUMPENVLSCALE         = 22,
+    D3DTSS_BUMPENVLOFFSET        = 23,
+    D3DTSS_TEXTURETRANSFORMFLAGS = 24,
+    D3DTSS_ADDRESSW              = 25,
+    D3DTSS_COLORARG0             = 26,
+    D3DTSS_ALPHAARG0             = 27,
+    D3DTSS_RESULTARG             = 28,
+
+    D3DTSS_FORCE_DWORD           = 0x7fffffff
+} D3DTEXTURESTAGESTATETYPE;
+
+typedef enum _D3DTEXTURETRANSFORMFLAGS {
+    D3DTTFF_DISABLE         =   0,
+    D3DTTFF_COUNT1          =   1,
+    D3DTTFF_COUNT2          =   2,
+    D3DTTFF_COUNT3          =   3,
+    D3DTTFF_COUNT4          =   4,
+    D3DTTFF_PROJECTED       = 256,
+
+    D3DTTFF_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTURETRANSFORMFLAGS;
+
+typedef enum _D3DTRANSFORMSTATETYPE {
+    D3DTS_VIEW            =  2,
+    D3DTS_PROJECTION      =  3,
+    D3DTS_TEXTURE0        = 16,
+    D3DTS_TEXTURE1        = 17,
+    D3DTS_TEXTURE2        = 18,
+    D3DTS_TEXTURE3        = 19,
+    D3DTS_TEXTURE4        = 20,
+    D3DTS_TEXTURE5        = 21,
+    D3DTS_TEXTURE6        = 22,
+    D3DTS_TEXTURE7        = 23,
+
+    D3DTS_FORCE_DWORD     = 0x7fffffff
+} D3DTRANSFORMSTATETYPE;
+
+typedef enum _D3DVERTEXBLENDFLAGS {
+    D3DVBF_DISABLE  =   0,
+    D3DVBF_1WEIGHTS =   1,
+    D3DVBF_2WEIGHTS =   2,
+    D3DVBF_3WEIGHTS =   3,
+    D3DVBF_TWEENING = 255,
+    D3DVBF_0WEIGHTS = 256
+} D3DVERTEXBLENDFLAGS;
+
+typedef enum _D3DZBUFFERTYPE {
+    D3DZB_FALSE                 = 0,
+    D3DZB_TRUE                  = 1,
+    D3DZB_USEW                  = 2,
+
+    D3DZB_FORCE_DWORD           = 0x7fffffff
+} D3DZBUFFERTYPE;
+
+
+/*****************************************************************************
+ * Direct 3D v8 typedefs
+ */
+typedef DWORD D3DCOLOR;
+
+/*****************************************************************************
+ * Direct 3D v8 structures
+ */
+typedef struct _D3DADAPTER_IDENTIFIER8 {
+    char            Driver[MAX_DEVICE_IDENTIFIER_STRING];
+    char            Description[MAX_DEVICE_IDENTIFIER_STRING];
+
+    LARGE_INTEGER   DriverVersion;
+    DWORD           VendorId;
+    DWORD           DeviceId;
+    DWORD           SubSysId;
+    DWORD           Revision;
+
+    GUID            DeviceIdentifier;
+
+    DWORD           WHQLLevel;
+} D3DADAPTER_IDENTIFIER8;
+
+typedef struct _D3DBOX {
+    UINT                Left;
+    UINT                Top;
+    UINT                Right;
+    UINT                Bottom;
+    UINT                Front;
+    UINT                Back;
+} D3DBOX;
+
+typedef struct _D3DCLIPSTATUS8 {
+   DWORD ClipUnion;
+   DWORD ClipIntersection;
+} D3DCLIPSTATUS8;
+
+typedef struct _D3DCOLORVALUE {
+    float r;
+    float g;
+    float b;
+    float a;
+} D3DCOLORVALUE;
+
+typedef struct _D3DDEVICE_CREATION_PARAMETERS {
+    UINT          AdapterOrdinal;
+    D3DDEVTYPE    DeviceType;
+    HWND          hFocusWindow;
+    DWORD         BehaviorFlags;
+} D3DDEVICE_CREATION_PARAMETERS;
+
+typedef struct _D3DDISPLAYMODE {
+    UINT            Width;
+    UINT            Height;
+    UINT            RefreshRate;
+    D3DFORMAT       Format;
+} D3DDISPLAYMODE;
+
+typedef struct _D3DGAMMARAMP {
+    WORD                red  [256];
+    WORD                green[256];
+    WORD                blue [256];
+} D3DGAMMARAMP;
+
+typedef struct _D3DINDEXBUFFER_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+} D3DINDEXBUFFER_DESC;
+
+typedef struct _D3DVECTOR {
+    float x;
+    float y;
+    float z;
+} D3DVECTOR;
+
+typedef struct _D3DLIGHT8 {
+    D3DLIGHTTYPE    Type;
+    D3DCOLORVALUE   Diffuse;
+    D3DCOLORVALUE   Specular;
+    D3DCOLORVALUE   Ambient;
+    D3DVECTOR       Position;
+    D3DVECTOR       Direction;
+    float           Range;
+    float           Falloff;
+    float           Attenuation0;
+    float           Attenuation1;
+    float           Attenuation2;
+    float           Theta;
+    float           Phi;
+} D3DLIGHT8;
+
+typedef struct _D3DLINEPATTERN {
+    WORD    wRepeatFactor;
+    WORD    wLinePattern;
+} D3DLINEPATTERN;
+
+typedef struct _D3DLOCKED_BOX {
+    INT                 RowPitch;
+    INT                 SlicePitch;
+    void*               pBits;
+} D3DLOCKED_BOX;
+
+typedef struct _D3DLOCKED_RECT {
+    INT                 Pitch;
+    void*               pBits;
+} D3DLOCKED_RECT;
+
+typedef struct _D3DMATERIAL8 {
+    D3DCOLORVALUE   Diffuse;
+    D3DCOLORVALUE   Ambient;
+    D3DCOLORVALUE   Specular;
+    D3DCOLORVALUE   Emissive;
+    float           Power;
+} D3DMATERIAL8;
+
+typedef struct _D3DMATRIX {
+    union {
+        struct {
+            float        _11, _12, _13, _14;
+            float        _21, _22, _23, _24;
+            float        _31, _32, _33, _34;
+            float        _41, _42, _43, _44;
+        } DUMMYSTRUCTNAME;
+        float m[4][4];
+    } DUMMYUNIONNAME;
+} D3DMATRIX;
+
+typedef struct _D3DPRESENT_PARAMETERS_ {
+    UINT                    BackBufferWidth;
+    UINT                    BackBufferHeight;
+    D3DFORMAT               BackBufferFormat;
+    UINT                    BackBufferCount;
+
+    D3DMULTISAMPLE_TYPE     MultiSampleType;
+
+    D3DSWAPEFFECT           SwapEffect;
+    HWND                    hDeviceWindow;
+    BOOL                    Windowed;
+    BOOL                    EnableAutoDepthStencil;
+    D3DFORMAT               AutoDepthStencilFormat;
+    DWORD                   Flags;
+
+    UINT                    FullScreen_RefreshRateInHz;
+    UINT                    FullScreen_PresentationInterval;
+
+} D3DPRESENT_PARAMETERS;
+
+typedef struct _D3DRANGE {
+    UINT                Offset;
+    UINT                Size;
+} D3DRANGE;
+
+typedef struct _D3DRASTER_STATUS {
+    BOOL            InVBlank;
+    UINT            ScanLine;
+} D3DRASTER_STATUS;
+
+typedef struct _D3DRECT {
+    LONG x1;
+    LONG y1;
+    LONG x2;
+    LONG y2;
+} D3DRECT;
+
+typedef struct _D3DRECTPATCH_INFO {
+    UINT                StartVertexOffsetWidth;
+    UINT                StartVertexOffsetHeight;
+    UINT                Width;
+    UINT                Height;
+    UINT                Stride;
+    D3DBASISTYPE        Basis;
+    D3DORDERTYPE        Order;
+} D3DRECTPATCH_INFO;
+
+typedef struct _D3DSURFACE_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+    D3DMULTISAMPLE_TYPE MultiSampleType;
+    UINT                Width;
+    UINT                Height;
+} D3DSURFACE_DESC;
+
+typedef struct _D3DTRIPATCH_INFO {
+    UINT                StartVertexOffset;
+    UINT                NumVertices;
+    D3DBASISTYPE        Basis;
+    D3DORDERTYPE        Order;
+} D3DTRIPATCH_INFO;
+
+typedef struct _D3DVERTEXBUFFER_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+    DWORD               FVF;
+} D3DVERTEXBUFFER_DESC;
+
+typedef struct _D3DVIEWPORT8 {
+    DWORD       X;
+    DWORD       Y;
+    DWORD       Width;
+    DWORD       Height;
+    float       MinZ;
+    float       MaxZ;
+} D3DVIEWPORT8;
+
+typedef struct _D3DVOLUME_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+    UINT                Width;
+    UINT                Height;
+    UINT                Depth;
+} D3DVOLUME_DESC;
+
+#endif  /* __WINE_D3D8TYPES_H */
diff --git a/reactos/include/d3d9.h b/reactos/include/d3d9.h
new file mode 100644 (file)
index 0000000..10b26c1
--- /dev/null
@@ -0,0 +1,1486 @@
+/*
+ * Copyright (C) 2002-2003 Jason Edmeades
+ *                         Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D9_H
+#define __WINE_D3D9_H
+
+#ifndef DIRECT3D_VERSION
+#define DIRECT3D_VERSION  0x0900
+#endif
+
+#include <objbase.h>
+
+#include <d3d9types.h>
+#include <d3d9caps.h>
+
+/*****************************************************************************
+ * Behavior Flags for IDirect3D8::CreateDevice
+ */
+#define D3DCREATE_FPU_PRESERVE                  0x00000002L
+#define D3DCREATE_MULTITHREADED                 0x00000004L
+#define D3DCREATE_PUREDEVICE                    0x00000010L
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING     0x00000020L
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING     0x00000040L
+#define D3DCREATE_MIXED_VERTEXPROCESSING        0x00000080L
+#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT     0x00000100L
+#define D3DCREATE_ADAPTERGROUP_DEVICE           0x00000200L
+
+/*****************************************************************************
+ * Flags for SetPrivateData
+ */
+#define D3DSPD_IUNKNOWN                         0x00000001L
+
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define D3DADAPTER_DEFAULT                      0
+#define D3DENUM_NO_WHQL_LEVEL                   0x00000002L
+#define D3DPRESENT_BACK_BUFFERS_MAX             3L
+#define D3DSGR_NO_CALIBRATION                   0x00000000L
+#define D3DSGR_CALIBRATE                        0x00000001L
+
+#define _FACD3D  0x876
+#define MAKE_D3DHRESULT( code )                 MAKE_HRESULT( 1, _FACD3D, code )
+#define MAKE_D3DSTATUS( code )                  MAKE_HRESULT( 0, _FACD3D, code )
+
+/*****************************************************************************
+ * Direct3D Errors
+ */
+#define D3D_OK                                  S_OK
+#define D3DERR_WRONGTEXTUREFORMAT               MAKE_D3DHRESULT(2072)
+#define D3DERR_UNSUPPORTEDCOLOROPERATION        MAKE_D3DHRESULT(2073)
+#define D3DERR_UNSUPPORTEDCOLORARG              MAKE_D3DHRESULT(2074)
+#define D3DERR_UNSUPPORTEDALPHAOPERATION        MAKE_D3DHRESULT(2075)
+#define D3DERR_UNSUPPORTEDALPHAARG              MAKE_D3DHRESULT(2076)
+#define D3DERR_TOOMANYOPERATIONS                MAKE_D3DHRESULT(2077)
+#define D3DERR_CONFLICTINGTEXTUREFILTER         MAKE_D3DHRESULT(2078)
+#define D3DERR_UNSUPPORTEDFACTORVALUE           MAKE_D3DHRESULT(2079)
+#define D3DERR_CONFLICTINGRENDERSTATE           MAKE_D3DHRESULT(2081)
+#define D3DERR_UNSUPPORTEDTEXTUREFILTER         MAKE_D3DHRESULT(2082)
+#define D3DERR_CONFLICTINGTEXTUREPALETTE        MAKE_D3DHRESULT(2086)
+#define D3DERR_DRIVERINTERNALERROR              MAKE_D3DHRESULT(2087)
+#define D3DERR_NOTFOUND                         MAKE_D3DHRESULT(2150)
+#define D3DERR_MOREDATA                         MAKE_D3DHRESULT(2151)
+#define D3DERR_DEVICELOST                       MAKE_D3DHRESULT(2152)
+#define D3DERR_DEVICENOTRESET                   MAKE_D3DHRESULT(2153)
+#define D3DERR_NOTAVAILABLE                     MAKE_D3DHRESULT(2154)
+#define D3DERR_OUTOFVIDEOMEMORY                 MAKE_D3DHRESULT(380)
+#define D3DERR_INVALIDDEVICE                    MAKE_D3DHRESULT(2155)
+#define D3DERR_INVALIDCALL                      MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINVALIDCALL                MAKE_D3DHRESULT(2157)
+#define D3DERR_WASSTILLDRAWING                  MAKE_D3DHRESULT(540)
+#define D3DOK_NOAUTOGEN                         MAKE_D3DSTATUS(2159)
+
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_IDirect3D9,                   0x81BDCBCA, 0x64D4, 0x426D, 0xAE, 0x8D, 0xAD, 0x1, 0x47, 0xF4, 0x27, 0x5C);
+typedef struct IDirect3D9                     IDirect3D9, *LPDIRECT3D9, *PDIRECT3D9;
+
+DEFINE_GUID(IID_IDirect3DDevice9,             0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb);
+typedef struct IDirect3DDevice9               IDirect3DDevice9, *LPDIRECT3DDEVICE9;
+
+DEFINE_GUID(IID_IDirect3DResource9,           0x5eec05d, 0x8f7d, 0x4362, 0xb9, 0x99, 0xd1, 0xba, 0xf3, 0x57, 0xc7, 0x4);
+typedef struct IDirect3DResource9             IDirect3DResource9, *LPDIRECT3DRESOURCE9, *PDIRECT3DRESOURCE9;
+
+DEFINE_GUID(IID_IDirect3DVertexBuffer9,       0xb64bb1b5, 0xfd70, 0x4df6, 0xbf, 0x91, 0x19, 0xd0, 0xa1, 0x24, 0x55, 0xe3);
+typedef struct IDirect3DVertexBuffer9         IDirect3DVertexBuffer9, *LPDIRECT3DVERTEXBUFFER9, *PDIRECT3DVERTEXBUFFER9;
+
+DEFINE_GUID(IID_IDirect3DVolume9,             0x24f416e6, 0x1f67, 0x4aa7, 0xb8, 0x8e, 0xd3, 0x3f, 0x6f, 0x31, 0x28, 0xa1);
+typedef struct IDirect3DVolume9               IDirect3DVolume9, *LPDIRECT3DVOLUME9, *PDIRECT3DVOLUME9;
+
+DEFINE_GUID(IID_IDirect3DSwapChain9,          0x794950f2, 0xadfc, 0x458a, 0x90, 0x5e, 0x10, 0xa1, 0xb, 0xb, 0x50, 0x3b);
+typedef struct IDirect3DSwapChain9            IDirect3DSwapChain9, *LPDIRECT3DSWAPCHAIN9, *PDIRECT3DSWAPCHAIN9;
+
+DEFINE_GUID(IID_IDirect3DSurface9,            0xcfbaf3a, 0x9ff6, 0x429a, 0x99, 0xb3, 0xa2, 0x79, 0x6a, 0xf8, 0xb8, 0x9b);
+typedef struct IDirect3DSurface9              IDirect3DSurface9, *LPDIRECT3DSURFACE9, *PDIRECT3DSURFACE9;
+
+DEFINE_GUID(IID_IDirect3DIndexBuffer9,        0x7c9dd65e, 0xd3f7, 0x4529, 0xac, 0xee, 0x78, 0x58, 0x30, 0xac, 0xde, 0x35);
+typedef struct IDirect3DIndexBuffer9          IDirect3DIndexBuffer9, *LPDIRECT3DINDEXBUFFER9, *PDIRECT3DINDEXBUFFER9;
+
+DEFINE_GUID(IID_IDirect3DBaseTexture9,        0x580ca87e, 0x1d3c, 0x4d54, 0x99, 0x1d, 0xb7, 0xd3, 0xe3, 0xc2, 0x98, 0xce);
+typedef struct IDirect3DBaseTexture9          IDirect3DBaseTexture9, *LPDIRECT3DBASETEXTURE9, *PDIRECT3DBASETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DTexture9,            0x85c31227, 0x3de5, 0x4f00, 0x9b, 0x3a, 0xf1, 0x1a, 0xc3, 0x8c, 0x18, 0xb5);
+typedef struct IDirect3DTexture9              IDirect3DTexture9, *LPDIRECT3DTEXTURE9, *PDIRECT3DTEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DCubeTexture9,        0xfff32f81, 0xd953, 0x473a, 0x92, 0x23, 0x93, 0xd6, 0x52, 0xab, 0xa9, 0x3f);
+typedef struct IDirect3DCubeTexture9          IDirect3DCubeTexture9, *LPDIRECT3DCUBETEXTURE9, *PDIRECT3DCUBETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DVolumeTexture9,      0x2518526c, 0xe789, 0x4111, 0xa7, 0xb9, 0x47, 0xef, 0x32, 0x8d, 0x13, 0xe6);
+typedef struct IDirect3DVolumeTexture9        IDirect3DVolumeTexture9, *LPDIRECT3DVOLUMETEXTURE9, *PDIRECT3DVOLUMETEXTURE9;
+
+DEFINE_GUID(IID_IDirect3DVertexDeclaration9,  0xdd13c59c, 0x36fa, 0x4098, 0xa8, 0xfb, 0xc7, 0xed, 0x39, 0xdc, 0x85, 0x46);
+typedef struct IDirect3DVertexDeclaration9    IDirect3DVertexDeclaration9, *LPDIRECT3DVERTEXDECLARATION9;
+
+DEFINE_GUID(IID_IDirect3DVertexShader9,       0xefc5557e, 0x6265, 0x4613, 0x8a, 0x94, 0x43, 0x85, 0x78, 0x89, 0xeb, 0x36);
+typedef struct IDirect3DVertexShader9         IDirect3DVertexShader9, *LPDIRECT3DVERTEXSHADER9;
+
+DEFINE_GUID(IID_IDirect3DPixelShader9,        0x6d3bdbdc, 0x5b02, 0x4415, 0xb8, 0x52, 0xce, 0x5e, 0x8b, 0xcc, 0xb2, 0x89);
+typedef struct IDirect3DPixelShader9          IDirect3DPixelShader9, *LPDIRECT3DPIXELSHADER9;
+
+DEFINE_GUID(IID_IDirect3DStateBlock9,         0xb07c4fe5, 0x310d, 0x4ba8, 0xa2, 0x3c, 0x4f, 0xf, 0x20, 0x6f, 0x21, 0x8b);
+typedef struct IDirect3DStateBlock9           IDirect3DStateBlock9, *LPDIRECT3DSTATEBLOCK9;
+
+DEFINE_GUID(IID_IDirect3DQuery9,              0xd9771460, 0xa695, 0x4f26, 0xbb, 0xd3, 0x27, 0xb8, 0x40, 0xb5, 0x41, 0xcc);
+typedef struct IDirect3DQuery9                IDirect3DQuery9, *LPDIRECT3DQUERY9, *PDIRECT3DQUERY9;
+
+/*****************************************************************************
+ * IDirect3D9 interface
+ */
+#define INTERFACE IDirect3D9
+DECLARE_INTERFACE_(IDirect3D9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3D9 methods ***/
+    STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
+    STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
+    STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
+    STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter, D3DFORMAT Format) PURE;
+    STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE* pMode) PURE;
+    STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter, D3DDISPLAYMODE* pMode) PURE;
+    STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter, D3DDEVTYPE DevType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) PURE;
+    STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) PURE;
+    STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) PURE;
+    STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) PURE;
+    STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) PURE;
+    STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) PURE;
+    STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
+    STDMETHOD(CreateDevice)(THIS_ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3D9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3D9_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3D9_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3D9 methods ***/
+#define IDirect3D9_RegisterSoftwareDevice(p,a)                (p)->lpVtbl->RegisterSoftwareDevice(p,a)
+#define IDirect3D9_GetAdapterCount(p)                         (p)->lpVtbl->GetAdapterCount(p)
+#define IDirect3D9_GetAdapterIdentifier(p,a,b,c)              (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c)
+#define IDirect3D9_GetAdapterModeCount(p,a,b)                 (p)->lpVtbl->GetAdapterModeCount(p,a,b)
+#define IDirect3D9_EnumAdapterModes(p,a,b,c,d)                (p)->lpVtbl->EnumAdapterModes(p,a,b,c,d)
+#define IDirect3D9_GetAdapterDisplayMode(p,a,b)               (p)->lpVtbl->GetAdapterDisplayMode(p,a,b)
+#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e)               (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f)           (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f)
+#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f)  (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e,f)
+#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e)        (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d)     (p)->lpVtbl->CheckDeviceFormatConversion(p,a,b,c,d)
+#define IDirect3D9_GetDeviceCaps(p,a,b,c)                     (p)->lpVtbl->GetDeviceCaps(p,a,b,c)
+#define IDirect3D9_GetAdapterMonitor(p,a)                     (p)->lpVtbl->GetAdapterMonitor(p,a)
+#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f)                (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f)
+#else
+/*** IUnknown methods ***/
+#define IDirect3D9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3D9_AddRef(p)             (p)->AddRef()
+#define IDirect3D9_Release(p)            (p)->Release()
+/*** IDirect3D9 methods ***/
+#define IDirect3D9_RegisterSoftwareDevice(p,a)                (p)->RegisterSoftwareDevice(a)
+#define IDirect3D9_GetAdapterCount(p)                         (p)->GetAdapterCount()
+#define IDirect3D9_GetAdapterIdentifier(p,a,b,c)              (p)->GetAdapterIdentifier(a,b,c)
+#define IDirect3D9_GetAdapterModeCount(p,a,b)                 (p)->GetAdapterModeCount(a,b)
+#define IDirect3D9_EnumAdapterModes(p,a,b,c,d)                (p)->EnumAdapterModes(a,b,c,d)
+#define IDirect3D9_GetAdapterDisplayMode(p,a,b)               (p)->GetAdapterDisplayMode(a,b)
+#define IDirect3D9_CheckDeviceType(p,a,b,c,d,e)               (p)->CheckDeviceType(a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormat(p,a,b,c,d,e,f)           (p)->CheckDeviceFormat(a,b,c,d,e,f)
+#define IDirect3D9_CheckDeviceMultiSampleType(p,a,b,c,d,e,f)  (p)->CheckDeviceMultiSampleType(a,b,c,d,e,f)
+#define IDirect3D9_CheckDepthStencilMatch(p,a,b,c,d,e)        (p)->CheckDepthStencilMatch(a,b,c,d,e)
+#define IDirect3D9_CheckDeviceFormatConversion(p,a,b,c,d)     (p)->CheckDeviceFormatConversion(a,b,c,d)
+#define IDirect3D9_GetDeviceCaps(p,a,b,c)                     (p)->GetDeviceCaps(a,b,c)
+#define IDirect3D9_GetAdapterMonitor(p,a)                     (p)->GetAdapterMonitor(a)
+#define IDirect3D9_CreateDevice(p,a,b,c,d,e,f)                (p)->CreateDevice(a,b,c,d,e,f)
+#endif
+
+/*****************************************************************************
+ * IDirect3DDevice9 interface
+ */
+#define INTERFACE IDirect3DDevice9
+DECLARE_INTERFACE_(IDirect3DDevice9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DDevice9 methods ***/
+    STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+    STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
+    STDMETHOD(EvictManagedResources)(THIS) PURE;
+    STDMETHOD(GetDirect3D)(THIS_ IDirect3D9** ppD3D9) PURE;
+    STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS9* pCaps) PURE;
+    STDMETHOD(GetDisplayMode)(THIS_ UINT iSwapChain, D3DDISPLAYMODE* pMode) PURE;
+    STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE;
+    STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) PURE;
+    STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y, DWORD Flags) PURE;
+    STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE;
+    STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** pSwapChain) PURE;
+    STDMETHOD(GetSwapChain)(THIS_ UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) PURE;
+    STDMETHOD_(UINT, GetNumberOfSwapChains)(THIS) PURE;
+    STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
+    STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) PURE;
+    STDMETHOD(GetBackBuffer)(THIS_ UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) PURE;
+    STDMETHOD(GetRasterStatus)(THIS_ UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) PURE;
+    STDMETHOD(SetDialogBoxMode)(THIS_ BOOL bEnableDialogs) PURE;
+    STDMETHOD_(void, SetGammaRamp)(THIS_ UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp) PURE;
+    STDMETHOD_(void, GetGammaRamp)(THIS_ UINT iSwapChain, D3DGAMMARAMP* pRamp) PURE;
+    STDMETHOD(CreateTexture)(THIS_ UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateRenderTarget)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(UpdateSurface)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) PURE;
+    STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) PURE;
+    STDMETHOD(GetRenderTargetData)(THIS_ IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) PURE;
+    STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain, IDirect3DSurface9* pDestSurface) PURE;
+    STDMETHOD(StretchRect)(THIS_ IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) PURE;
+    STDMETHOD(ColorFill)(THIS_ IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) PURE;
+    STDMETHOD(CreateOffscreenPlainSurface)(THIS_ UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle) PURE;
+    STDMETHOD(SetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) PURE;
+    STDMETHOD(GetRenderTarget)(THIS_ DWORD RenderTargetIndex, IDirect3DSurface9** ppRenderTarget) PURE;
+    STDMETHOD(SetDepthStencilSurface)(THIS_ IDirect3DSurface9* pNewZStencil) PURE;
+    STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface9** ppZStencilSurface) PURE;
+    STDMETHOD(BeginScene)(THIS) PURE;
+    STDMETHOD(EndScene)(THIS) PURE;
+    STDMETHOD(Clear)(THIS_ DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) PURE;
+    STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) PURE;
+    STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) PURE;
+    STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE, CONST D3DMATRIX*) PURE;
+    STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT9* pViewport) PURE;
+    STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT9* pViewport) PURE;
+    STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL9* pMaterial) PURE;
+    STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL9* pMaterial) PURE;
+    STDMETHOD(SetLight)(THIS_ DWORD Index, CONST D3DLIGHT9*) PURE;
+    STDMETHOD(GetLight)(THIS_ DWORD Index, D3DLIGHT9*) PURE;
+    STDMETHOD(LightEnable)(THIS_ DWORD Index, BOOL Enable) PURE;
+    STDMETHOD(GetLightEnable)(THIS_ DWORD Index, BOOL* pEnable) PURE;
+    STDMETHOD(SetClipPlane)(THIS_ DWORD Index, CONST float* pPlane) PURE;
+    STDMETHOD(GetClipPlane)(THIS_ DWORD Index, float* pPlane) PURE;
+    STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD Value) PURE;
+    STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State, DWORD* pValue) PURE;
+    STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type, IDirect3DStateBlock9** ppSB) PURE;
+    STDMETHOD(BeginStateBlock)(THIS) PURE;
+    STDMETHOD(EndStateBlock)(THIS_ IDirect3DStateBlock9** ppSB) PURE;
+    STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS9* pClipStatus) PURE;
+    STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS9* pClipStatus) PURE;
+    STDMETHOD(GetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9** ppTexture) PURE;
+    STDMETHOD(SetTexture)(THIS_ DWORD Stage, IDirect3DBaseTexture9* pTexture) PURE;
+    STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) PURE;
+    STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) PURE;
+    STDMETHOD(GetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) PURE;
+    STDMETHOD(SetSamplerState)(THIS_ DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) PURE;
+    STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE;
+    STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber, CONST PALETTEENTRY* pEntries) PURE;
+    STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE;
+    STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE;
+    STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE;
+    STDMETHOD(SetScissorRect)(THIS_ CONST RECT* pRect) PURE;
+    STDMETHOD(GetScissorRect)(THIS_ RECT* pRect) PURE;
+    STDMETHOD(SetSoftwareVertexProcessing)(THIS_ BOOL bSoftware) PURE;
+    STDMETHOD_(BOOL, GetSoftwareVertexProcessing)(THIS) PURE;
+    STDMETHOD(SetNPatchMode)(THIS_ float nSegments) PURE;
+    STDMETHOD_(float, GetNPatchMode)(THIS) PURE;
+    STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) PURE;
+    STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) PURE;
+    STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+    STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE;
+    STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) PURE;
+    STDMETHOD(CreateVertexDeclaration)(THIS_ CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl) PURE;
+    STDMETHOD(SetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9* pDecl) PURE;
+    STDMETHOD(GetVertexDeclaration)(THIS_ IDirect3DVertexDeclaration9** ppDecl) PURE;
+    STDMETHOD(SetFVF)(THIS_ DWORD FVF) PURE;
+    STDMETHOD(GetFVF)(THIS_ DWORD* pFVF) PURE;
+    STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader) PURE;
+    STDMETHOD(SetVertexShader)(THIS_ IDirect3DVertexShader9* pShader) PURE;
+    STDMETHOD(GetVertexShader)(THIS_ IDirect3DVertexShader9** ppShader) PURE;
+    STDMETHOD(SetVertexShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+    STDMETHOD(GetVertexShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+    STDMETHOD(SetVertexShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+    STDMETHOD(GetVertexShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+    STDMETHOD(SetVertexShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT  BoolCount) PURE;
+    STDMETHOD(GetVertexShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+    STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) PURE;
+    STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* OffsetInBytes, UINT* pStride) PURE;
+    STDMETHOD(SetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT Divider) PURE;
+    STDMETHOD(GetStreamSourceFreq)(THIS_ UINT StreamNumber, UINT* Divider) PURE;
+    STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer9* pIndexData) PURE;
+    STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer9** ppIndexData) PURE;
+    STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, IDirect3DPixelShader9** ppShader) PURE;
+    STDMETHOD(SetPixelShader)(THIS_ IDirect3DPixelShader9* pShader) PURE;
+    STDMETHOD(GetPixelShader)(THIS_ IDirect3DPixelShader9** ppShader) PURE;
+    STDMETHOD(SetPixelShaderConstantF)(THIS_ UINT StartRegister, CONST float* pConstantData, UINT Vector4fCount) PURE;
+    STDMETHOD(GetPixelShaderConstantF)(THIS_ UINT StartRegister, float* pConstantData, UINT Vector4fCount) PURE;
+    STDMETHOD(SetPixelShaderConstantI)(THIS_ UINT StartRegister, CONST int* pConstantData, UINT Vector4iCount) PURE;
+    STDMETHOD(GetPixelShaderConstantI)(THIS_ UINT StartRegister, int* pConstantData, UINT Vector4iCount) PURE;
+    STDMETHOD(SetPixelShaderConstantB)(THIS_ UINT StartRegister, CONST BOOL* pConstantData, UINT  BoolCount) PURE;
+    STDMETHOD(GetPixelShaderConstantB)(THIS_ UINT StartRegister, BOOL* pConstantData, UINT BoolCount) PURE;
+    STDMETHOD(DrawRectPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE;
+    STDMETHOD(DrawTriPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE;
+    STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE;
+    STDMETHOD(CreateQuery)(THIS_ D3DQUERYTYPE Type, IDirect3DQuery9** ppQuery) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DDevice9_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirect3DDevice9_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9_TestCooperativeLevel(p)                       (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirect3DDevice9_GetAvailableTextureMem(p)                     (p)->lpVtbl->GetAvailableTextureMem(p)
+#define IDirect3DDevice9_EvictManagedResources(p)                      (p)->lpVtbl->EvictManagedResources(p)
+#define IDirect3DDevice9_GetDirect3D(p,a)                              (p)->lpVtbl->GetDirect3D(p,a)
+#define IDirect3DDevice9_GetDeviceCaps(p,a)                            (p)->lpVtbl->GetDeviceCaps(p,a)
+#define IDirect3DDevice9_GetDisplayMode(p,a,b)                         (p)->lpVtbl->GetDisplayMode(p,a,b)
+#define IDirect3DDevice9_GetCreationParameters(p,a)                    (p)->lpVtbl->GetCreationParameters(p,a)
+#define IDirect3DDevice9_SetCursorProperties(p,a,b,c)                  (p)->lpVtbl->SetCursorProperties(p,a,b,c)
+#define IDirect3DDevice9_SetCursorPosition(p,a,b,c)                    (p)->lpVtbl->SetCursorPosition(p,a,b,c)
+#define IDirect3DDevice9_ShowCursor(p,a)                               (p)->lpVtbl->ShowCursor(p,a)
+#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b)              (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b)
+#define IDirect3DDevice9_GetSwapChain(p,a,b)                           (p)->lpVtbl->GetSwapChain(p,a,b)
+#define IDirect3DDevice9_GetNumberOfSwapChains(p)                      (p)->lpVtbl->GetNumberOfSwapChains(p)
+#define IDirect3DDevice9_Reset(p,a)                                    (p)->lpVtbl->Reset(p,a)
+#define IDirect3DDevice9_Present(p,a,b,c,d)                            (p)->lpVtbl->Present(p,a,b,c,d)
+#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d)                      (p)->lpVtbl->GetBackBuffer(p,a,b,c,d)
+#define IDirect3DDevice9_GetRasterStatus(p,a,b)                        (p)->lpVtbl->GetRasterStatus(p,a,b)
+#define IDirect3DDevice9_SetDialogBoxMode(p,a)                         (p)->lpVtbl->SetDialogBoxMode(p,a)
+#define IDirect3DDevice9_SetGammaRamp(p,a,b,c)                         (p)->lpVtbl->SetGammaRamp(p,a,b,c)
+#define IDirect3DDevice9_GetGammaRamp(p,a,b)                           (p)->lpVtbl->GetGammaRamp(p,a,b)
+#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h)              (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i)      (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g)            (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f,g)
+#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f)             (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f)              (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h)         (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h)  (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d)                      (p)->lpVtbl->UpdateSurface(p,a,b,c,d)
+#define IDirect3DDevice9_UpdateTexture(p,a,b)                          (p)->lpVtbl->UpdateTexture(p,a,b)
+#define IDirect3DDevice9_GetRenderTargetData(p,a,b)                    (p)->lpVtbl->GetRenderTargetData(p,a,b)
+#define IDirect3DDevice9_GetFrontBufferData(p,a,b)                     (p)->lpVtbl->GetFrontBufferData(p,a,b)
+#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e)                      (p)->lpVtbl->StretchRect(p,a,b,c,d,e)
+#define IDirect3DDevice9_ColorFill(p,a,b,c)                            (p)->lpVtbl->ColorFill(p,a,b,c)
+#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f)    (p)->lpVtbl->CreateOffscreenPlainSurface(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_SetRenderTarget(p,a,b)                        (p)->lpVtbl->SetRenderTarget(p,a,b)
+#define IDirect3DDevice9_GetRenderTarget(p,a,b)                        (p)->lpVtbl->GetRenderTarget(p,a,b)
+#define IDirect3DDevice9_SetDepthStencilSurface(p,a)                   (p)->lpVtbl->SetDepthStencilSurface(p,a)
+#define IDirect3DDevice9_GetDepthStencilSurface(p,a)                   (p)->lpVtbl->GetDepthStencilSurface(p,a)
+#define IDirect3DDevice9_BeginScene(p)                                 (p)->lpVtbl->BeginScene(p)
+#define IDirect3DDevice9_EndScene(p)                                   (p)->lpVtbl->EndScene(p)
+#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f)                          (p)->lpVtbl->Clear(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_SetTransform(p,a,b)                           (p)->lpVtbl->SetTransform(p,a,b)
+#define IDirect3DDevice9_GetTransform(p,a,b)                           (p)->lpVtbl->GetTransform(p,a,b)
+#define IDirect3DDevice9_MultiplyTransform(p,a,b)                      (p)->lpVtbl->MultiplyTransform(p,a,b)
+#define IDirect3DDevice9_SetViewport(p,a)                              (p)->lpVtbl->SetViewport(p,a)
+#define IDirect3DDevice9_GetViewport(p,a)                              (p)->lpVtbl->GetViewport(p,a)
+#define IDirect3DDevice9_SetMaterial(p,a)                              (p)->lpVtbl->SetMaterial(p,a)
+#define IDirect3DDevice9_GetMaterial(p,a)                              (p)->lpVtbl->GetMaterial(p,a)
+#define IDirect3DDevice9_SetLight(p,a,b)                               (p)->lpVtbl->SetLight(p,a,b)
+#define IDirect3DDevice9_GetLight(p,a,b)                               (p)->lpVtbl->GetLight(p,a,b)
+#define IDirect3DDevice9_LightEnable(p,a,b)                            (p)->lpVtbl->LightEnable(p,a,b)
+#define IDirect3DDevice9_GetLightEnable(p,a,b)                         (p)->lpVtbl->GetLightEnable(p,a,b)
+#define IDirect3DDevice9_SetClipPlane(p,a,b)                           (p)->lpVtbl->SetClipPlane(p,a,b)
+#define IDirect3DDevice9_GetClipPlane(p,a,b)                           (p)->lpVtbl->GetClipPlane(p,a,b)
+#define IDirect3DDevice9_SetRenderState(p,a,b)                         (p)->lpVtbl->SetRenderState(p,a,b)
+#define IDirect3DDevice9_GetRenderState(p,a,b)                         (p)->lpVtbl->GetRenderState(p,a,b)
+#define IDirect3DDevice9_CreateStateBlock(p,a,b)                       (p)->lpVtbl->CreateStateBlock(p,a,b)
+#define IDirect3DDevice9_BeginStateBlock(p)                            (p)->lpVtbl->BeginStateBlock(p)
+#define IDirect3DDevice9_EndStateBlock(p,a)                            (p)->lpVtbl->EndStateBlock(p,a)
+#define IDirect3DDevice9_SetClipStatus(p,a)                            (p)->lpVtbl->SetClipStatus(p,a)
+#define IDirect3DDevice9_GetClipStatus(p,a)                            (p)->lpVtbl->GetClipStatus(p,a)
+#define IDirect3DDevice9_GetTexture(p,a,b)                             (p)->lpVtbl->GetTexture(p,a,b)
+#define IDirect3DDevice9_SetTexture(p,a,b)                             (p)->lpVtbl->SetTexture(p,a,b)
+#define IDirect3DDevice9_GetTextureStageState(p,a,b,c)                 (p)->lpVtbl->GetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9_SetTextureStageState(p,a,b,c)                 (p)->lpVtbl->SetTextureStageState(p,a,b,c)
+#define IDirect3DDevice9_GetSamplerState(p,a,b,c)                      (p)->lpVtbl->GetSamplerState(p,a,b,c)
+#define IDirect3DDevice9_SetSamplerState(p,a,b,c)                      (p)->lpVtbl->SetSamplerState(p,a,b,c)
+#define IDirect3DDevice9_ValidateDevice(p,a)                           (p)->lpVtbl->ValidateDevice(p,a)
+#define IDirect3DDevice9_SetPaletteEntries(p,a,b)                      (p)->lpVtbl->SetPaletteEntries(p,a,b)
+#define IDirect3DDevice9_GetPaletteEntries(p,a,b)                      (p)->lpVtbl->GetPaletteEntries(p,a,b)
+#define IDirect3DDevice9_SetCurrentTexturePalette(p,a)                 (p)->lpVtbl->SetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9_GetCurrentTexturePalette(p,a)                 (p)->lpVtbl->GetCurrentTexturePalette(p,a)
+#define IDirect3DDevice9_SetScissorRect(p,a)                           (p)->lpVtbl->SetScissorRect(p,a)
+#define IDirect3DDevice9_GetScissorRect(p,a)                           (p)->lpVtbl->GetScissorRect(p,a)
+#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a)              (p)->lpVtbl->SetSoftwareVertexProcessing(p,a)
+#define IDirect3DDevice9_GetSoftwareVertexProcessing(p)                (p)->lpVtbl->GetSoftwareVertexProcessing(p)
+#define IDirect3DDevice9_SetNPatchMode(p,a)                            (p)->lpVtbl->SetNPatchMode(p,a)
+#define IDirect3DDevice9_GetNPatchMode(p)                              (p)->lpVtbl->GetNPatchMode(p)
+#define IDirect3DDevice9_DrawPrimitive(p,a,b,c)                        (p)->lpVtbl->DrawPrimitive(p,a,b,c)
+#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f)           (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d)                    (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
+#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)     (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f)                (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b)                (p)->lpVtbl->CreateVertexDeclaration(p,a,b)
+#define IDirect3DDevice9_SetVertexDeclaration(p,a)                     (p)->lpVtbl->SetVertexDeclaration(p,a)
+#define IDirect3DDevice9_GetVertexDeclaration(p,a)                     (p)->lpVtbl->GetVertexDeclaration(p,a)
+#define IDirect3DDevice9_SetFVF(p,a)                                   (p)->lpVtbl->SetFVF(p,a)
+#define IDirect3DDevice9_GetFVF(p,a)                                   (p)->lpVtbl->GetFVF(p,a)
+#define IDirect3DDevice9_CreateVertexShader(p,a,b)                     (p)->lpVtbl->CreateVertexShader(p,a,b)
+#define IDirect3DDevice9_SetVertexShader(p,a)                          (p)->lpVtbl->SetVertexShader(p,a)
+#define IDirect3DDevice9_GetVertexShader(p,a)                          (p)->lpVtbl->GetVertexShader(p,a)
+#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c)             (p)->lpVtbl->SetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c)             (p)->lpVtbl->GetVertexShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c)             (p)->lpVtbl->SetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c)             (p)->lpVtbl->GetVertexShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c)             (p)->lpVtbl->SetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c)             (p)->lpVtbl->GetVertexShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d)                    (p)->lpVtbl->SetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d)                    (p)->lpVtbl->GetStreamSource(p,a,b,c,d)
+#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b)                    (p)->lpVtbl->SetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b)                    (p)->lpVtbl->GetStreamSourceFreq(p,a,b)
+#define IDirect3DDevice9_SetIndices(p,a)                               (p)->lpVtbl->SetIndices(p,a)
+#define IDirect3DDevice9_GetIndices(p,a)                               (p)->lpVtbl->GetIndices(p,a)
+#define IDirect3DDevice9_CreatePixelShader(p,a,b)                      (p)->lpVtbl->CreatePixelShader(p,a,b)
+#define IDirect3DDevice9_SetPixelShader(p,a)                           (p)->lpVtbl->SetPixelShader(p,a)
+#define IDirect3DDevice9_GetPixelShader(p,a)                           (p)->lpVtbl->GetPixelShader(p,a)
+#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c)              (p)->lpVtbl->SetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c)              (p)->lpVtbl->GetPixelShaderConstantF(p,a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c)              (p)->lpVtbl->SetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c)              (p)->lpVtbl->GetPixelShaderConstantI(p,a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c)              (p)->lpVtbl->SetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c)              (p)->lpVtbl->GetPixelShaderConstantB(p,a,b,c)
+#define IDirect3DDevice9_DrawRectPatch(p,a,b,c)                        (p)->lpVtbl->DrawRectPatch(p,a,b,c)
+#define IDirect3DDevice9_DrawTriPatch(p,a,b,c)                         (p)->lpVtbl->DrawTriPatch(p,a,b,c)
+#define IDirect3DDevice9_DeletePatch(p,a)                              (p)->lpVtbl->DeletePatch(p,a)
+#define IDirect3DDevice9_CreateQuery(p,a,b)                            (p)->lpVtbl->CreateQuery(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DDevice9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DDevice9_AddRef(p)             (p)->AddRef()
+#define IDirect3DDevice9_Release(p)            (p)->Release()
+/*** IDirect3DDevice9 methods ***/
+#define IDirect3DDevice9_TestCooperativeLevel(p)                       (p)->TestCooperativeLevel()
+#define IDirect3DDevice9_GetAvailableTextureMem(p)                     (p)->GetAvailableTextureMem()
+#define IDirect3DDevice9_EvictManagedResources(p)                      (p)->EvictManagedResources()
+#define IDirect3DDevice9_GetDirect3D(p,a)                              (p)->GetDirect3D(a)
+#define IDirect3DDevice9_GetDeviceCaps(p,a)                            (p)->GetDeviceCaps(a)
+#define IDirect3DDevice9_GetDisplayMode(p,a,b)                         (p)->GetDisplayMode(a,b)
+#define IDirect3DDevice9_GetCreationParameters(p,a)                    (p)->GetCreationParameters(a)
+#define IDirect3DDevice9_SetCursorProperties(p,a,b,c)                  (p)->SetCursorProperties(a,b,c)
+#define IDirect3DDevice9_SetCursorPosition(p,a,b,c)                    (p)->SetCursorPosition(a,b,c)
+#define IDirect3DDevice9_ShowCursor(p,a)                               (p)->ShowCursor(a)
+#define IDirect3DDevice9_CreateAdditionalSwapChain(p,a,b)              (p)->CreateAdditionalSwapChain(a,b)
+#define IDirect3DDevice9_GetSwapChain(p,a,b)                           (p)->GetSwapChain(a,b)
+#define IDirect3DDevice9_GetNumberOfSwapChains(p)                      (p)->GetNumberOfSwapChains()
+#define IDirect3DDevice9_Reset(p,a)                                    (p)->Reset(a)
+#define IDirect3DDevice9_Present(p,a,b,c,d)                            (p)->Present(a,b,c,d)
+#define IDirect3DDevice9_GetBackBuffer(p,a,b,c,d)                      (p)->GetBackBuffer(a,b,c,d)
+#define IDirect3DDevice9_GetRasterStatus(p,a,b)                        (p)->GetRasterStatus(a,b)
+#define IDirect3DDevice9_SetDialogBoxMode(p,a)                         (p)->SetDialogBoxMode(a)
+#define IDirect3DDevice9_SetGammaRamp(p,a,b,c)                         (p)->SetGammaRamp(a,b,c)
+#define IDirect3DDevice9_GetGammaRamp(p,a,b)                           (p)->GetGammaRamp(a,b)
+#define IDirect3DDevice9_CreateTexture(p,a,b,c,d,e,f,g,h)              (p)->CreateTexture(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateVolumeTexture(p,a,b,c,d,e,f,g,h,i)      (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h,i)
+#define IDirect3DDevice9_CreateCubeTexture(p,a,b,c,d,e,f,g)            (p)->CreateCubeTexture(a,b,c,d,e,f,g)
+#define IDirect3DDevice9_CreateVertexBuffer(p,a,b,c,d,e,f)             (p)->CreateVertexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateIndexBuffer(p,a,b,c,d,e,f)              (p)->CreateIndexBuffer(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateRenderTarget(p,a,b,c,d,e,f,g,h)         (p)->CreateRenderTarget(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_CreateDepthStencilSurface(p,a,b,c,d,e,f,g,h)  (p)->CreateDepthStencilSurface(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_UpdateSurface(p,a,b,c,d)                      (p)->UpdateSurface(a,b,c,d)
+#define IDirect3DDevice9_UpdateTexture(p,a,b)                          (p)->UpdateTexture(a,b)
+#define IDirect3DDevice9_GetRenderTargetData(p,a,b)                    (p)->GetRenderTargetData(a,b)
+#define IDirect3DDevice9_GetFrontBufferData(p,a,b)                     (p)->GetFrontBufferData(a,b)
+#define IDirect3DDevice9_StretchRect(p,a,b,c,d,e)                      (p)->StretchRect(a,b,c,d,e)
+#define IDirect3DDevice9_ColorFill(p,a,b,c)                            (p)->ColorFill(a,b,c)
+#define IDirect3DDevice9_CreateOffscreenPlainSurface(p,a,b,c,d,e,f)    (p)->CreateOffscreenPlainSurface(a,b,c,d,e,f)
+#define IDirect3DDevice9_SetRenderTarget(p,a,b)                        (p)->SetRenderTarget(a,b)
+#define IDirect3DDevice9_GetRenderTarget(p,a,b)                        (p)->GetRenderTarget(a,b)
+#define IDirect3DDevice9_SetDepthStencilSurface(p,a)                   (p)->SetDepthStencilSurface(a)
+#define IDirect3DDevice9_GetDepthStencilSurface(p,a)                   (p)->GetDepthStencilSurface(a)
+#define IDirect3DDevice9_BeginScene(p)                                 (p)->BeginScene()
+#define IDirect3DDevice9_EndScene(p)                                   (p)->EndScene()
+#define IDirect3DDevice9_Clear(p,a,b,c,d,e,f)                          (p)->Clear(a,b,c,d,e,f)
+#define IDirect3DDevice9_SetTransform(p,a,b)                           (p)->SetTransform(a,b)
+#define IDirect3DDevice9_GetTransform(p,a,b)                           (p)->GetTransform(a,b)
+#define IDirect3DDevice9_MultiplyTransform(p,a,b)                      (p)->MultiplyTransform(a,b)
+#define IDirect3DDevice9_SetViewport(p,a)                              (p)->SetViewport(a)
+#define IDirect3DDevice9_GetViewport(p,a)                              (p)->GetViewport(a)
+#define IDirect3DDevice9_SetMaterial(p,a)                              (p)->SetMaterial(a)
+#define IDirect3DDevice9_GetMaterial(p,a)                              (p)->GetMaterial(a)
+#define IDirect3DDevice9_SetLight(p,a,b)                               (p)->SetLight(a,b)
+#define IDirect3DDevice9_GetLight(p,a,b)                               (p)->GetLight(a,b)
+#define IDirect3DDevice9_LightEnable(p,a,b)                            (p)->LightEnable(a,b)
+#define IDirect3DDevice9_GetLightEnable(p,a,b)                         (p)->GetLightEnable(a,b)
+#define IDirect3DDevice9_SetClipPlane(p,a,b)                           (p)->SetClipPlane(a,b)
+#define IDirect3DDevice9_GetClipPlane(p,a,b)                           (p)->GetClipPlane(a,b)
+#define IDirect3DDevice9_SetRenderState(p,a,b)                         (p)->SetRenderState(a,b)
+#define IDirect3DDevice9_GetRenderState(p,a,b)                         (p)->GetRenderState(a,b)
+#define IDirect3DDevice9_CreateStateBlock(p,a,b)                       (p)->CreateStateBlock(a,b)
+#define IDirect3DDevice9_BeginStateBlock(p)                            (p)->BeginStateBlock()
+#define IDirect3DDevice9_EndStateBlock(p,a)                            (p)->EndStateBlock(a)
+#define IDirect3DDevice9_SetClipStatus(p,a)                            (p)->SetClipStatus(a)
+#define IDirect3DDevice9_GetClipStatus(p,a)                            (p)->GetClipStatus(a)
+#define IDirect3DDevice9_GetTexture(p,a,b)                             (p)->GetTexture(a,b)
+#define IDirect3DDevice9_SetTexture(p,a,b)                             (p)->SetTexture(a,b)
+#define IDirect3DDevice9_GetTextureStageState(p,a,b,c)                 (p)->GetTextureStageState(a,b,c)
+#define IDirect3DDevice9_SetTextureStageState(p,a,b,c)                 (p)->SetTextureStageState(a,b,c)
+#define IDirect3DDevice9_GetSamplerState(p,a,b,c)                      (p)->GetSamplerState(a,b,c)
+#define IDirect3DDevice9_SetSamplerState(p,a,b,c)                      (p)->SetSamplerState(a,b,c)
+#define IDirect3DDevice9_ValidateDevice(p,a)                           (p)->ValidateDevice(a)
+#define IDirect3DDevice9_SetPaletteEntries(p,a,b)                      (p)->SetPaletteEntries(a,b)
+#define IDirect3DDevice9_GetPaletteEntries(p,a,b)                      (p)->GetPaletteEntries(a,b)
+#define IDirect3DDevice9_SetCurrentTexturePalette(p,a)                 (p)->SetCurrentTexturePalette(a)
+#define IDirect3DDevice9_GetCurrentTexturePalette(p,a)                 (p)->GetCurrentTexturePalette(a)
+#define IDirect3DDevice9_SetScissorRect(p,a)                           (p)->SetScissorRect(a)
+#define IDirect3DDevice9_GetScissorRect(p,a)                           (p)->GetScissorRect(a)
+#define IDirect3DDevice9_SetSoftwareVertexProcessing(p,a)              (p)->SetSoftwareVertexProcessing(a)
+#define IDirect3DDevice9_GetSoftwareVertexProcessing(p)                (p)->GetSoftwareVertexProcessing()
+#define IDirect3DDevice9_SetNPatchMode(p,a)                            (p)->SetNPatchMode(a)
+#define IDirect3DDevice9_GetNPatchMode(p)                              (p)->GetNPatchMode()
+#define IDirect3DDevice9_DrawPrimitive(p,a,b,c)                        (p)->DrawPrimitive(a,b,c)
+#define IDirect3DDevice9_DrawIndexedPrimitive(p,a,b,c,d,e,f)           (p)->DrawIndexedPrimitive(a,b,c,d,e,f)
+#define IDirect3DDevice9_DrawPrimitiveUP(p,a,b,c,d)                    (p)->DrawPrimitiveUP(a,b,c,d)
+#define IDirect3DDevice9_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)     (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h)
+#define IDirect3DDevice9_ProcessVertices(p,a,b,c,d,e,f)                (p)->ProcessVertices(a,b,c,d,e,f)
+#define IDirect3DDevice9_CreateVertexDeclaration(p,a,b)                (p)->CreateVertexDeclaration(a,b)
+#define IDirect3DDevice9_SetVertexDeclaration(p,a)                     (p)->SetVertexDeclaration(a)
+#define IDirect3DDevice9_GetVertexDeclaration(p,a)                     (p)->GetVertexDeclaration(a)
+#define IDirect3DDevice9_SetFVF(p,a)                                   (p)->SetFVF(a)
+#define IDirect3DDevice9_GetFVF(p,a)                                   (p)->GetFVF(a)
+#define IDirect3DDevice9_CreateVertexShader(p,a,b)                     (p)->CreateVertexShader(a,b)
+#define IDirect3DDevice9_SetVertexShader(p,a)                          (p)->SetVertexShader(a)
+#define IDirect3DDevice9_GetVertexShader(p,a)                          (p)->GetVertexShader(a)
+#define IDirect3DDevice9_SetVertexShaderConstantF(p,a,b,c)             (p)->SetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantF(p,a,b,c)             (p)->GetVertexShaderConstantF(a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantI(p,a,b,c)             (p)->SetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantI(p,a,b,c)             (p)->GetVertexShaderConstantI(a,b,c)
+#define IDirect3DDevice9_SetVertexShaderConstantB(p,a,b,c)             (p)->SetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9_GetVertexShaderConstantB(p,a,b,c)             (p)->GetVertexShaderConstantB(a,b,c)
+#define IDirect3DDevice9_SetStreamSource(p,a,b,c,d)                    (p)->SetStreamSource(a,b,c,d)
+#define IDirect3DDevice9_GetStreamSource(p,a,b,c,d)                    (p)->GetStreamSource(a,b,c,d)
+#define IDirect3DDevice9_SetStreamSourceFreq(p,a,b)                    (p)->SetStreamSourceFreq(a,b)
+#define IDirect3DDevice9_GetStreamSourceFreq(p,a,b)                    (p)->GetStreamSourceFreq(a,b)
+#define IDirect3DDevice9_SetIndices(p,a)                               (p)->SetIndices(a)
+#define IDirect3DDevice9_GetIndices(p,a)                               (p)->GetIndices(a)
+#define IDirect3DDevice9_CreatePixelShader(p,a,b)                      (p)->CreatePixelShader(a,b)
+#define IDirect3DDevice9_SetPixelShader(p,a)                           (p)->SetPixelShader(a)
+#define IDirect3DDevice9_GetPixelShader(p,a)                           (p)->GetPixelShader(a)
+#define IDirect3DDevice9_SetPixelShaderConstantF(p,a,b,c)              (p)->SetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantF(p,a,b,c)              (p)->GetPixelShaderConstantF(a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantI(p,a,b,c)              (p)->SetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantI(p,a,b,c)              (p)->GetPixelShaderConstantI(a,b,c)
+#define IDirect3DDevice9_SetPixelShaderConstantB(p,a,b,c)              (p)->SetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9_GetPixelShaderConstantB(p,a,b,c)              (p)->GetPixelShaderConstantB(a,b,c)
+#define IDirect3DDevice9_DrawRectPatch(p,a,b,c)                        (p)->DrawRectPatch(a,b,c)
+#define IDirect3DDevice9_DrawTriPatch(p,a,b,c)                         (p)->DrawTriPatch(a,b,c)
+#define IDirect3DDevice9_DeletePatch(p,a)                              (p)->DeletePatch(a)
+#define IDirect3DDevice9_CreateQuery(p,a,b)                            (p)->CreateQuery(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolume9 interface
+ */
+#define INTERFACE IDirect3DVolume9
+DECLARE_INTERFACE_(IDirect3DVolume9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVolume9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD(GetContainer)(THIS_ REFIID riid, void** ppContainer) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC* pDesc) PURE;
+    STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
+    STDMETHOD(UnlockBox)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolume9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolume9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolume9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DVolume9 methods ***/
+#define IDirect3DVolume9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolume9_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolume9_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolume9_GetContainer(p,a,b)          (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DVolume9_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DVolume9_LockBox(p,a,b,c)             (p)->lpVtbl->LockBox(p,a,b,c)
+#define IDirect3DVolume9_UnlockBox(p)                 (p)->lpVtbl->UnlockBox(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolume9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DVolume9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DVolume9_Release(p)                   (p)->Release()
+/*** IDirect3DVolume9 methods ***/
+#define IDirect3DVolume9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DVolume9_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolume9_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolume9_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DVolume9_GetContainer(p,a,b)          (p)->GetContainer(a,b)
+#define IDirect3DVolume9_GetDesc(p,a)                 (p)->GetDesc(a)
+#define IDirect3DVolume9_LockBox(p,a,b,c)             (p)->LockBox(a,b,c)
+#define IDirect3DVolume9_UnlockBox(p)                 (p)->UnlockBox()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSwapChain9 interface
+ */
+#define INTERFACE IDirect3DSwapChain9
+DECLARE_INTERFACE_(IDirect3DSwapChain9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DSwapChain9 methods ***/
+    STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion, DWORD dwFlags) PURE;
+    STDMETHOD(GetFrontBufferData)(THIS_ IDirect3DSurface9* pDestSurface) PURE;
+    STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer) PURE;
+    STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE;
+    STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE;
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(GetPresentParameters)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSwapChain9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DSwapChain9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DSwapChain9 methods ***/
+#define IDirect3DSwapChain9_Present(p,a,b,c,d,e)         (p)->lpVtbl->Present(p,a,b,c,d,e)
+#define IDirect3DSwapChain9_GetFrontBufferData(p,a)      (p)->lpVtbl->GetFrontBufferData(p,a)
+#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c)       (p)->lpVtbl->GetBackBuffer(p,a,b,c)
+#define IDirect3DSwapChain9_GetRasterStatus(p,a)         (p)->lpVtbl->GetRasterStatus(p,a)
+#define IDirect3DSwapChain9_GetDisplayMode(p,a)          (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirect3DSwapChain9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSwapChain9_GetPresentParameters(p,a)    (p)->lpVtbl->GetPresentParameters(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSwapChain9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DSwapChain9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DSwapChain9_Release(p)                   (p)->Release()
+/*** IDirect3DSwapChain9 methods ***/
+#define IDirect3DSwapChain9_Present(p,a,b,c,d,e)         (p)->Present(a,b,c,d,e)
+#define IDirect3DSwapChain9_GetFrontBufferData(p,a)      (p)->GetFrontBufferData(a)
+#define IDirect3DSwapChain9_GetBackBuffer(p,a,b,c)       (p)->GetBackBuffer(a,b,c)
+#define IDirect3DSwapChain9_GetRasterStatus(p,a)         (p)->GetRasterStatus(a)
+#define IDirect3DSwapChain9_GetDisplayMode(p,a)          (p)->GetDisplayMode(a)
+#define IDirect3DSwapChain9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DSwapChain9_GetPresentParameters(p,a)    (p)->GetPresentParameters(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DResource9 interface
+ */
+#define INTERFACE IDirect3DResource9
+DECLARE_INTERFACE_(IDirect3DResource9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DResource9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DResource9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DResource9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DResource9 methods ***/
+#define IDirect3DResource9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DResource9_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DResource9_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DResource9_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DResource9_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DResource9_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DResource9_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DResource9_GetType(p)                   (p)->lpVtbl->GetType(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DResource9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DResource9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DResource9_Release(p)                   (p)->Release()
+/*** IDirect3DResource9 methods ***/
+#define IDirect3DResource9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DResource9_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DResource9_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DResource9_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DResource9_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DResource9_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DResource9_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DResource9_GetType(p)                   (p)->GetType()
+#endif
+
+/*****************************************************************************
+ * IDirect3DSurface9 interface
+ */
+#define INTERFACE IDirect3DSurface9
+DECLARE_INTERFACE_(IDirect3DSurface9,IDirect3DResource9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DSurface9 methods ***/
+    STDMETHOD(GetContainer)(THIS_ REFIID riid, void** ppContainer) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC* pDesc) PURE;
+    STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC* phdc) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC hdc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DSurface9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DSurface9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DSurface9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DSurface9 methods: IDirect3DResource9 ***/
+#define IDirect3DSurface9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DSurface9_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DSurface9_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DSurface9_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DSurface9_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DSurface9_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DSurface9_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DSurface9 methods ***/
+#define IDirect3DSurface9_GetContainer(p,a,b)          (p)->lpVtbl->GetContainer(p,a,b)
+#define IDirect3DSurface9_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#define IDirect3DSurface9_LockRect(p,a,b,c)            (p)->lpVtbl->LockRect(p,a,b,c)
+#define IDirect3DSurface9_UnlockRect(p)                (p)->lpVtbl->UnlockRect(p)
+#define IDirect3DSurface9_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirect3DSurface9_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DSurface9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DSurface9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DSurface9_Release(p)                   (p)->Release()
+/*** IDirect3DSurface9 methods: IDirect3DResource9 ***/
+#define IDirect3DSurface9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DSurface9_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DSurface9_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DSurface9_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DSurface9_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DSurface9_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DSurface9_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DSurface9_GetType(p)                   (p)->GetType()
+/*** IDirect3DSurface9 methods ***/
+#define IDirect3DSurface9_GetContainer(p,a,b)          (p)->GetContainer(a,b)
+#define IDirect3DSurface9_GetDesc(p,a)                 (p)->GetDesc(a)
+#define IDirect3DSurface9_LockRect(p,a,b,c)            (p)->LockRect(a,b,c)
+#define IDirect3DSurface9_UnlockRect(p)                (p)->UnlockRect()
+#define IDirect3DSurface9_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirect3DSurface9_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexBuffer9 interface
+ */
+#define INTERFACE IDirect3DVertexBuffer9
+DECLARE_INTERFACE_(IDirect3DVertexBuffer9,IDirect3DResource9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DVertexBuffer9 methods ***/
+    STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC* pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexBuffer9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexBuffer9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DVertexBuffer9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVertexBuffer9_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVertexBuffer9_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVertexBuffer9_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVertexBuffer9_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVertexBuffer9_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DVertexBuffer9 methods ***/
+#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DVertexBuffer9_Unlock(p)                    (p)->lpVtbl->Unlock(p)
+#define IDirect3DVertexBuffer9_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexBuffer9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DVertexBuffer9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DVertexBuffer9_Release(p)                   (p)->Release()
+/*** IDirect3DVertexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DVertexBuffer9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DVertexBuffer9_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVertexBuffer9_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DVertexBuffer9_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DVertexBuffer9_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DVertexBuffer9_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DVertexBuffer9_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DVertexBuffer9_GetType(p)                   (p)->GetType()
+/*** IDirect3DVertexBuffer9 methods ***/
+#define IDirect3DVertexBuffer9_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirect3DVertexBuffer9_Unlock(p)                    (p)->Unlock()
+#define IDirect3DVertexBuffer9_GetDesc(p,a)                 (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DIndexBuffer9 interface
+ */
+#define INTERFACE IDirect3DIndexBuffer9
+DECLARE_INTERFACE_(IDirect3DIndexBuffer9,IDirect3DResource9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DIndexBuffer9 methods ***/
+    STDMETHOD(Lock)(THIS_ UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags) PURE;
+    STDMETHOD(Unlock)(THIS) PURE;
+    STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC* pDesc) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer9_QueryInterface(p,a,b)        (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DIndexBuffer9_AddRef(p)                    (p)->lpVtbl->AddRef(p)
+#define IDirect3DIndexBuffer9_Release(p)                   (p)->lpVtbl->Release(p)
+/*** IDirect3DIndexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DIndexBuffer9_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d)    (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c)      (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DIndexBuffer9_FreePrivateData(p,a)         (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DIndexBuffer9_SetPriority(p,a)             (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DIndexBuffer9_GetPriority(p)               (p)->lpVtbl->GetPriority(p)
+#define IDirect3DIndexBuffer9_PreLoad(p)                   (p)->lpVtbl->PreLoad(p)
+#define IDirect3DIndexBuffer9_GetType(p)                   (p)->lpVtbl->GetType(p)
+/*** IDirect3DIndexBuffer9 methods ***/
+#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirect3DIndexBuffer9_Unlock(p)                    (p)->lpVtbl->Unlock(p)
+#define IDirect3DIndexBuffer9_GetDesc(p,a)                 (p)->lpVtbl->GetDesc(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DIndexBuffer9_QueryInterface(p,a,b)        (p)->QueryInterface(a,b)
+#define IDirect3DIndexBuffer9_AddRef(p)                    (p)->AddRef()
+#define IDirect3DIndexBuffer9_Release(p)                   (p)->Release()
+/*** IDirect3DIndexBuffer9 methods: IDirect3DResource9 ***/
+#define IDirect3DIndexBuffer9_GetDevice(p,a)               (p)->GetDevice(a)
+#define IDirect3DIndexBuffer9_SetPrivateData(p,a,b,c,d)    (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DIndexBuffer9_GetPrivateData(p,a,b,c)      (p)->GetPrivateData(a,b,c)
+#define IDirect3DIndexBuffer9_FreePrivateData(p,a)         (p)->FreePrivateData(a)
+#define IDirect3DIndexBuffer9_SetPriority(p,a)             (p)->SetPriority(a)
+#define IDirect3DIndexBuffer9_GetPriority(p)               (p)->GetPriority()
+#define IDirect3DIndexBuffer9_PreLoad(p)                   (p)->PreLoad()
+#define IDirect3DIndexBuffer9_GetType(p)                   (p)->GetType()
+/*** IDirect3DIndexBuffer9 methods ***/
+#define IDirect3DIndexBuffer9_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirect3DIndexBuffer9_Unlock(p)                    (p)->Unlock()
+#define IDirect3DIndexBuffer9_GetDesc(p,a)                 (p)->GetDesc(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DBaseTexture9 interface
+ */
+#define INTERFACE IDirect3DBaseTexture9
+DECLARE_INTERFACE_(IDirect3DBaseTexture9,IDirect3DResource9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture9 methods ***/
+    STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+    STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+    STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+    STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+    STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture9_QueryInterface(p,a,b)  (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DBaseTexture9_AddRef(p)              (p)->lpVtbl->AddRef(p)
+#define IDirect3DBaseTexture9_Release(p)             (p)->lpVtbl->Release(p)
+/*** IDirect3DBaseTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DBaseTexture9_GetDevice(p,a)             (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d)  (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c)    (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DBaseTexture9_FreePrivateData(p,a)       (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DBaseTexture9_SetPriority(p,a)           (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DBaseTexture9_GetPriority(p)             (p)->lpVtbl->GetPriority(p)
+#define IDirect3DBaseTexture9_PreLoad(p)                 (p)->lpVtbl->PreLoad(p)
+#define IDirect3DBaseTexture9_GetType(p)                 (p)->lpVtbl->GetType(p)
+/*** IDirect3DBaseTexture9 methods ***/
+#define IDirect3DBaseTexture9_SetLOD(p,a)                (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DBaseTexture9_GetLOD(p)                  (p)->lpVtbl->GetLOD(p)
+#define IDirect3DBaseTexture9_GetLevelCount(p)           (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a)  (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DBaseTexture9_GetAutoGenFilterType(p)    (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DBaseTexture9_GenerateMipSubLevels(p)    (p)->lpVtbl->GenerateMipSubLevels(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DBaseTexture9_QueryInterface(p,a,b)  (p)->QueryInterface(a,b)
+#define IDirect3DBaseTexture9_AddRef(p)              (p)->AddRef()
+#define IDirect3DBaseTexture9_Release(p)             (p)->Release()
+/*** IDirect3DBaseTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DBaseTexture9_GetDevice(p,a)             (p)->GetDevice(a)
+#define IDirect3DBaseTexture9_SetPrivateData(p,a,b,c,d)  (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DBaseTexture9_GetPrivateData(p,a,b,c)    (p)->GetPrivateData(a,b,c)
+#define IDirect3DBaseTexture9_FreePrivateData(p,a)       (p)->FreePrivateData(a)
+#define IDirect3DBaseTexture9_SetPriority(p,a)           (p)->SetPriority(a)
+#define IDirect3DBaseTexture9_GetPriority(p)             (p)->GetPriority()
+#define IDirect3DBaseTexture9_PreLoad(p)                 (p)->PreLoad()
+#define IDirect3DBaseTexture9_GetType(p)                 (p)->GetType()
+/*** IDirect3DBaseTexture9 methods ***/
+#define IDirect3DBaseTexture9_SetLOD(p,a)                (p)->SetLOD(a)
+#define IDirect3DBaseTexture9_GetLOD(p)                  (p)->GetLOD()
+#define IDirect3DBaseTexture9_GetLevelCount(p)           (p)->GetLevelCount()
+#define IDirect3DBaseTexture9_SetAutoGenFilterType(p,a)  (p)->SetAutoGenFilterType(a)
+#define IDirect3DBaseTexture9_GetAutoGenFilterType(p)    (p)->GetAutoGenFilterType()
+#define IDirect3DBaseTexture9_GenerateMipSubLevels(p)    (p)->GenerateMipSubLevels()
+#endif
+
+/*****************************************************************************
+ * IDirect3DCubeTexture9 interface
+ */
+#define INTERFACE IDirect3DCubeTexture9
+DECLARE_INTERFACE_(IDirect3DCubeTexture9,IDirect3DBaseTexture9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture9 methods ***/
+    STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+    STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+    STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+    STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+    STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+    /*** IDirect3DCubeTexture9 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC* pDesc) PURE;
+    STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, IDirect3DSurface9** ppCubeMapSurface) PURE;
+    STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level) PURE;
+    STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType, CONST RECT* pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture9_QueryInterface(p,a,b)       (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DCubeTexture9_AddRef(p)                   (p)->lpVtbl->AddRef(p)
+#define IDirect3DCubeTexture9_Release(p)                  (p)->lpVtbl->Release(p)
+/*** IDirect3DCubeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DCubeTexture9_GetDevice(p,a)              (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d)   (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c)     (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DCubeTexture9_FreePrivateData(p,a)        (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DCubeTexture9_SetPriority(p,a)            (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DCubeTexture9_GetPriority(p)              (p)->lpVtbl->GetPriority(p)
+#define IDirect3DCubeTexture9_PreLoad(p)                  (p)->lpVtbl->PreLoad(p)
+#define IDirect3DCubeTexture9_GetType(p)                  (p)->lpVtbl->GetType(p)
+/*** IDirect3DCubeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DCubeTexture9_SetLOD(p,a)                 (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DCubeTexture9_GetLOD(p)                   (p)->lpVtbl->GetLOD(p)
+#define IDirect3DCubeTexture9_GetLevelCount(p)            (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a)   (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DCubeTexture9_GetAutoGenFilterType(p)     (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DCubeTexture9_GenerateMipSubLevels(p)     (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DCubeTexture9 methods ***/
+#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b)         (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c)  (p)->lpVtbl->GetCubeMapSurface(p,a,b,c)
+#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e)       (p)->lpVtbl->LockRect(p,a,b,c,d,e)
+#define IDirect3DCubeTexture9_UnlockRect(p,a,b)           (p)->lpVtbl->UnlockRect(p,a,b)
+#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b)         (p)->lpVtbl->AddDirtyRect(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DCubeTexture9_QueryInterface(p,a,b)       (p)->QueryInterface(a,b)
+#define IDirect3DCubeTexture9_AddRef(p)                   (p)->AddRef()
+#define IDirect3DCubeTexture9_Release(p)                  (p)->Release()
+/*** IDirect3DCubeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DCubeTexture9_GetDevice(p,a)              (p)->GetDevice(a)
+#define IDirect3DCubeTexture9_SetPrivateData(p,a,b,c,d)   (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DCubeTexture9_GetPrivateData(p,a,b,c)     (p)->GetPrivateData(a,b,c)
+#define IDirect3DCubeTexture9_FreePrivateData(p,a)        (p)->FreePrivateData(a)
+#define IDirect3DCubeTexture9_SetPriority(p,a)            (p)->SetPriority(a)
+#define IDirect3DCubeTexture9_GetPriority(p)              (p)->GetPriority()
+#define IDirect3DCubeTexture9_PreLoad(p)                  (p)->PreLoad()
+#define IDirect3DCubeTexture9_GetType(p)                  (p)->GetType()
+/*** IDirect3DCubeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DCubeTexture9_SetLOD(p,a)                 (p)->SetLOD(a)
+#define IDirect3DCubeTexture9_GetLOD(p)                   (p)->GetLOD()
+#define IDirect3DCubeTexture9_GetLevelCount(p)            (p)->GetLevelCount()
+#define IDirect3DCubeTexture9_SetAutoGenFilterType(p,a)   (p)->SetAutoGenFilterType(a)
+#define IDirect3DCubeTexture9_GetAutoGenFilterType(p)     (p)->GetAutoGenFilterType()
+#define IDirect3DCubeTexture9_GenerateMipSubLevels(p)     (p)->GenerateMipSubLevels()
+/*** IDirect3DCubeTexture9 methods ***/
+#define IDirect3DCubeTexture9_GetLevelDesc(p,a,b)         (p)->GetLevelDesc(a,b)
+#define IDirect3DCubeTexture9_GetCubeMapSurface(p,a,b,c)  (p)->GetCubeMapSurface(a,b,c)
+#define IDirect3DCubeTexture9_LockRect(p,a,b,c,d,e)       (p)->LockRect(a,b,c,d,e)
+#define IDirect3DCubeTexture9_UnlockRect(p,a,b)           (p)->UnlockRect(a,b)
+#define IDirect3DCubeTexture9_AddDirtyRect(p,a,b)         (p)->AddDirtyRect(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DTexture9 interface
+ */
+#define INTERFACE IDirect3DTexture9
+DECLARE_INTERFACE_(IDirect3DTexture9,IDirect3DBaseTexture9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture9 methods ***/
+    STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+    STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+    STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+    STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+    STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+    /*** IDirect3DTexture9 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT Level, D3DSURFACE_DESC* pDesc) PURE;
+    STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level, IDirect3DSurface9** ppSurfaceLevel) PURE;
+    STDMETHOD(LockRect)(THIS_ UINT Level, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) PURE;
+    STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE;
+    STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DTexture9_QueryInterface(p,a,b)      (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DTexture9_AddRef(p)                  (p)->lpVtbl->AddRef(p)
+#define IDirect3DTexture9_Release(p)                 (p)->lpVtbl->Release(p)
+/*** IDirect3DTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DTexture9_GetDevice(p,a)             (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d)  (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DTexture9_GetPrivateData(p,a,b,c)    (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DTexture9_FreePrivateData(p,a)       (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DTexture9_SetPriority(p,a)           (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DTexture9_GetPriority(p)             (p)->lpVtbl->GetPriority(p)
+#define IDirect3DTexture9_PreLoad(p)                 (p)->lpVtbl->PreLoad(p)
+#define IDirect3DTexture9_GetType(p)                 (p)->lpVtbl->GetType(p)
+/*** IDirect3DTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DTexture9_SetLOD(p,a)                (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DTexture9_GetLOD(p)                  (p)->lpVtbl->GetLOD(p)
+#define IDirect3DTexture9_GetLevelCount(p)           (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DTexture9_SetAutoGenFilterType(p,a)  (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DTexture9_GetAutoGenFilterType(p)    (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DTexture9_GenerateMipSubLevels(p)    (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DTexture9 methods ***/
+#define IDirect3DTexture9_GetLevelDesc(p,a,b)        (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DTexture9_GetSurfaceLevel(p,a,b)     (p)->lpVtbl->GetSurfaceLevel(p,a,b)
+#define IDirect3DTexture9_LockRect(p,a,b,c,d)        (p)->lpVtbl->LockRect(p,a,b,c,d)
+#define IDirect3DTexture9_UnlockRect(p,a)            (p)->lpVtbl->UnlockRect(p,a)
+#define IDirect3DTexture9_AddDirtyRect(p,a)          (p)->lpVtbl->AddDirtyRect(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DTexture9_QueryInterface(p,a,b)      (p)->QueryInterface(a,b)
+#define IDirect3DTexture9_AddRef(p)                  (p)->AddRef()
+#define IDirect3DTexture9_Release(p)                 (p)->Release()
+/*** IDirect3DTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DTexture9_GetDevice(p,a)             (p)->GetDevice(a)
+#define IDirect3DTexture9_SetPrivateData(p,a,b,c,d)  (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DTexture9_GetPrivateData(p,a,b,c)    (p)->GetPrivateData(a,b,c)
+#define IDirect3DTexture9_FreePrivateData(p,a)       (p)->FreePrivateData(a)
+#define IDirect3DTexture9_SetPriority(p,a)           (p)->SetPriority(a)
+#define IDirect3DTexture9_GetPriority(p)             (p)->GetPriority()
+#define IDirect3DTexture9_PreLoad(p)                 (p)->PreLoad()
+#define IDirect3DTexture9_GetType(p)                 (p)->GetType()
+/*** IDirect3DTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DTexture9_SetLOD(p,a)                (p)->SetLOD(a)
+#define IDirect3DTexture9_GetLOD(p)                  (p)->GetLOD()
+#define IDirect3DTexture9_GetLevelCount(p)           (p)->GetLevelCount()
+#define IDirect3DTexture9_SetAutoGenFilterType(p,a)  (p)->SetAutoGenFilterType(a)
+#define IDirect3DTexture9_GetAutoGenFilterType(p)    (p)->GetAutoGenFilterType()
+#define IDirect3DTexture9_GenerateMipSubLevels(p)    (p)->GenerateMipSubLevels()
+/*** IDirect3DTexture9 methods ***/
+#define IDirect3DTexture9_GetLevelDesc(p,a,b)        (p)->GetLevelDesc(a,b)
+#define IDirect3DTexture9_GetSurfaceLevel(p,a,b)     (p)->GetSurfaceLevel(a,b)
+#define IDirect3DTexture9_LockRect(p,a,b,c,d)        (p)->LockRect(a,b,c,d)
+#define IDirect3DTexture9_UnlockRect(p,a)            (p)->UnlockRect(a)
+#define IDirect3DTexture9_AddDirtyRect(p,a)          (p)->AddDirtyRect(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVolumeTexture9 interface
+ */
+#define INTERFACE IDirect3DVolumeTexture9
+DECLARE_INTERFACE_(IDirect3DVolumeTexture9,IDirect3DBaseTexture9)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DResource9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid, void* pData, DWORD* pSizeOfData) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
+    STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
+    STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
+    STDMETHOD_(void, PreLoad)(THIS) PURE;
+    STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
+    /*** IDirect3DBaseTexture9 methods ***/
+    STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE;
+    STDMETHOD_(DWORD, GetLOD)(THIS) PURE;
+    STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE;
+    STDMETHOD(SetAutoGenFilterType)(THIS_ D3DTEXTUREFILTERTYPE FilterType) PURE;
+    STDMETHOD_(D3DTEXTUREFILTERTYPE, GetAutoGenFilterType)(THIS) PURE;
+    STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE;
+    /*** IDirect3DVolumeTexture9 methods ***/
+    STDMETHOD(GetLevelDesc)(THIS_ UINT Level, D3DVOLUME_DESC *pDesc) PURE;
+    STDMETHOD(GetVolumeLevel)(THIS_ UINT Level, IDirect3DVolume9** ppVolumeLevel) PURE;
+    STDMETHOD(LockBox)(THIS_ UINT Level, D3DLOCKED_BOX* pLockedVolume, CONST D3DBOX* pBox, DWORD Flags) PURE;
+    STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE;
+    STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVolumeTexture9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DVolumeTexture9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DVolumeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirect3DVolumeTexture9_GetPriority(p) (p)->lpVtbl->GetPriority(p)
+#define IDirect3DVolumeTexture9_PreLoad(p) (p)->lpVtbl->PreLoad(p)
+#define IDirect3DVolumeTexture9_GetType(p) (p)->lpVtbl->GetType(p)
+/*** IDirect3DVolumeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirect3DVolumeTexture9_GetLOD(p) (p)->lpVtbl->GetLOD(p)
+#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p)
+#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->lpVtbl->SetAutoGenFilterType(p,a)
+#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->lpVtbl->GetAutoGenFilterType(p)
+#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p)
+/*** IDirect3DVolumeTexture9 methods ***/
+#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b)
+#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b)
+#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d)
+#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a)
+#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVolumeTexture9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DVolumeTexture9_AddRef(p) (p)->AddRef()
+#define IDirect3DVolumeTexture9_Release(p) (p)->Release()
+/*** IDirect3DVolumeTexture9 methods: IDirect3DResource9 ***/
+#define IDirect3DVolumeTexture9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DVolumeTexture9_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirect3DVolumeTexture9_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirect3DVolumeTexture9_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirect3DVolumeTexture9_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirect3DVolumeTexture9_GetPriority(p) (p)->GetPriority()
+#define IDirect3DVolumeTexture9_PreLoad(p) (p)->PreLoad()
+#define IDirect3DVolumeTexture9_GetType(p) (p)->GetType()
+/*** IDirect3DVolumeTexture9 methods: IDirect3DBaseTexture9 ***/
+#define IDirect3DVolumeTexture9_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirect3DVolumeTexture9_GetLOD(p) (p)->GetLOD()
+#define IDirect3DVolumeTexture9_GetLevelCount(p) (p)->GetLevelCount()
+#define IDirect3DVolumeTexture9_SetAutoGenFilterType(p,a) (p)->SetAutoGenFilterType(a)
+#define IDirect3DVolumeTexture9_GetAutoGenFilterType(p) (p)->GetAutoGenFilterType()
+#define IDirect3DVolumeTexture9_GenerateMipSubLevels(p) (p)->GenerateMipSubLevels()
+/*** IDirect3DVolumeTexture9 methods ***/
+#define IDirect3DVolumeTexture9_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b)
+#define IDirect3DVolumeTexture9_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b)
+#define IDirect3DVolumeTexture9_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d)
+#define IDirect3DVolumeTexture9_UnlockBox(p,a) (p)->UnlockBox(a)
+#define IDirect3DVolumeTexture9_AddDirtyBox(p,a) (p)->AddDirtyBox(a)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexDeclaration9 interface
+ */
+#define INTERFACE IDirect3DVertexDeclaration9
+DECLARE_INTERFACE_(IDirect3DVertexDeclaration9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVertexDeclaration9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9*, UINT* pNumElements) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b)  (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexDeclaration9_AddRef(p)              (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexDeclaration9_Release(p)             (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexDeclaration9_GetDevice(p,a)         (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b)  (p)->lpVtbl->GetDeclaration(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexDeclaration9_QueryInterface(p,a,b)  (p)->QueryInterface(a,b)
+#define IDirect3DVertexDeclaration9_AddRef(p)              (p)->AddRef()
+#define IDirect3DVertexDeclaration9_Release(p)             (p)->Release()
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexDeclaration9_GetDevice(p,a)         (p)->GetDevice(a)
+#define IDirect3DVertexDeclaration9_GetDeclaration(p,a,b)  (p)->GetDeclaration(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DVertexShader9 interface
+ */
+#define INTERFACE IDirect3DVertexShader9
+DECLARE_INTERFACE_(IDirect3DVertexShader9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DVertexShader9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DVertexShader9_QueryInterface(p,a,b)  (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DVertexShader9_AddRef(p)              (p)->lpVtbl->AddRef(p)
+#define IDirect3DVertexShader9_Release(p)             (p)->lpVtbl->Release(p)
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexShader9_GetDevice(p,a)         (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DVertexShader9_GetFunction(p,a,b)     (p)->lpVtbl->GetFunction(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DVertexShader9_QueryInterface(p,a,b)  (p)->QueryInterface(a,b)
+#define IDirect3DVertexShader9_AddRef(p)              (p)->AddRef()
+#define IDirect3DVertexShader9_Release(p)             (p)->Release()
+/*** IDirect3DVertexShader9 methods ***/
+#define IDirect3DVertexShader9_GetDevice(p,a)         (p)->GetDevice(a)
+#define IDirect3DVertexShader9_GetFunction(p,a,b)     (p)->GetFunction(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DPixelShader9 interface
+ */
+#define INTERFACE IDirect3DPixelShader9
+DECLARE_INTERFACE_(IDirect3DPixelShader9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DPixelShader9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(GetFunction)(THIS_ void*, UINT* pSizeOfData) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DPixelShader9_QueryInterface(p,a,b)  (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DPixelShader9_AddRef(p)              (p)->lpVtbl->AddRef(p)
+#define IDirect3DPixelShader9_Release(p)             (p)->lpVtbl->Release(p)
+/*** IDirect3DPixelShader9 methods ***/
+#define IDirect3DPixelShader9_GetDevice(p,a)         (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DPixelShader9_GetFunction(p,a,b)     (p)->lpVtbl->GetFunction(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DPixelShader9_QueryInterface(p,a,b)  (p)->QueryInterface(a,b)
+#define IDirect3DPixelShader9_AddRef(p)              (p)->AddRef()
+#define IDirect3DPixelShader9_Release(p)             (p)->Release()
+/*** IDirect3DPixelShader9 methods ***/
+#define IDirect3DPixelShader9_GetDevice(p,a)         (p)->GetDevice(a)
+#define IDirect3DPixelShader9_GetFunction(p,a,b)     (p)->GetFunction(a,b)
+#endif
+
+/*****************************************************************************
+ * IDirect3DStateBlock9 interface
+ */
+#define INTERFACE IDirect3DStateBlock9
+DECLARE_INTERFACE_(IDirect3DStateBlock9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DStateBlock9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD(Capture)(THIS) PURE;
+    STDMETHOD(Apply)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DStateBlock9_QueryInterface(p,a,b)  (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DStateBlock9_AddRef(p)              (p)->lpVtbl->AddRef(p)
+#define IDirect3DStateBlock9_Release(p)             (p)->lpVtbl->Release(p)
+/*** IDirect3DStateBlock9 methods ***/
+#define IDirect3DStateBlock9_GetDevice(p,a)         (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DStateBlock9_Capture(p)             (p)->lpVtbl->Capture(p)
+#define IDirect3DStateBlock9_Apply(p)               (p)->lpVtbl->Apply(p)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DStateBlock9_QueryInterface(p,a,b)  (p)->QueryInterface(a,b)
+#define IDirect3DStateBlock9_AddRef(p)              (p)->AddRef()
+#define IDirect3DStateBlock9_Release(p)             (p)->Release()
+/*** IDirect3DStateBlock9 methods ***/
+#define IDirect3DStateBlock9_GetDevice(p,a)         (p)->GetDevice(a)
+#define IDirect3DStateBlock9_Capture(p)             (p)->Capture()
+#define IDirect3DStateBlock9_Apply(p)               (p)->Apply()
+#endif
+
+/*****************************************************************************
+ * IDirect3DQuery9 interface
+ */
+#define INTERFACE IDirect3DQuery9
+DECLARE_INTERFACE_(IDirect3DQuery9,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirect3DQuery9 methods ***/
+    STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
+    STDMETHOD_(D3DQUERYTYPE, GetType)(THIS) PURE;
+    STDMETHOD_(DWORD, GetDataSize)(THIS) PURE;
+    STDMETHOD(Issue)(THIS_ DWORD dwIssueFlags) PURE;
+    STDMETHOD(GetData)(THIS_ void* pData, DWORD dwSize, DWORD dwGetDataFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirect3DQuery9_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirect3DQuery9_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirect3DQuery9 ***/
+#define IDirect3DQuery9_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
+#define IDirect3DQuery9_GetType(p) (p)->lpVtbl->GetType(p)
+#define IDirect3DQuery9_GetDataSize(p) (p)->lpVtbl->GetDataSize(p)
+#define IDirect3DQuery9_Issue(p,a) (p)->lpVtbl->Issue(p,a)
+#define IDirect3DQuery9_GetData(p,a,b,c) (p)->lpVtbl->GetData(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirect3DQuery9_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirect3DQuery9_AddRef(p) (p)->AddRef()
+#define IDirect3DQuery9_Release(p) (p)->Release()
+/*** IDirect3DQuery9 ***/
+#define IDirect3DQuery9_GetDevice(p,a) (p)->GetDevice(a)
+#define IDirect3DQuery9_GetType(p) (p)->GetType()
+#define IDirect3DQuery9_GetDataSize(p) (p)->GetDataSize()
+#define IDirect3DQuery9_Issue(p,a) (p)->Issue(a)
+#define IDirect3DQuery9_GetData(p,a,b,c) (p)->GetData(a,b,c)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif  /* defined(__cplusplus) */
+
+/* Define the main entrypoint as well */
+IDirect3D9* WINAPI Direct3DCreate9(UINT SDKVersion);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+
+#endif /* __WINE_D3D9_H */
diff --git a/reactos/include/d3d9caps.h b/reactos/include/d3d9caps.h
new file mode 100644 (file)
index 0000000..0731de5
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2002-2003 Jason Edmeades
+ *                         Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D9CAPS_H
+#define __WINE_D3D9CAPS_H
+
+/*
+ * Definitions
+ */
+#define D3DCAPS_READ_SCANLINE 0x20000
+
+#define D3DCURSORCAPS_COLOR   1
+#define D3DCURSORCAPS_LOWRES  2
+
+
+#define D3DDEVCAPS2_STREAMOFFSET                        0x00000001L
+#define D3DDEVCAPS2_DMAPNPATCH                          0x00000002L
+#define D3DDEVCAPS2_ADAPTIVETESSRTPATCH                 0x00000004L
+#define D3DDEVCAPS2_ADAPTIVETESSNPATCH                  0x00000008L
+#define D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES       0x00000010L
+#define D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH                0x00000020L
+#define D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET  0x00000040L
+
+#define D3DDEVCAPS_EXECUTESYSTEMMEMORY     0x0000010
+#define D3DDEVCAPS_EXECUTEVIDEOMEMORY      0x0000020
+#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY    0x0000040
+#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY     0x0000080
+#define D3DDEVCAPS_TEXTURESYSTEMMEMORY     0x0000100
+#define D3DDEVCAPS_TEXTUREVIDEOMEMORY      0x0000200
+#define D3DDEVCAPS_DRAWPRIMTLVERTEX        0x0000400
+#define D3DDEVCAPS_CANRENDERAFTERFLIP      0x0000800
+#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM   0x0001000
+#define D3DDEVCAPS_DRAWPRIMITIVES2         0x0002000
+#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x0004000
+#define D3DDEVCAPS_DRAWPRIMITIVES2EX       0x0008000
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT     0x0010000
+#define D3DDEVCAPS_CANBLTSYSTONONLOCAL     0x0020000
+#define D3DDEVCAPS_HWRASTERIZATION         0x0080000
+#define D3DDEVCAPS_PUREDEVICE              0x0100000
+#define D3DDEVCAPS_QUINTICRTPATCHES        0x0200000
+#define D3DDEVCAPS_RTPATCHES               0x0400000
+#define D3DDEVCAPS_RTPATCHHANDLEZERO       0x0800000
+#define D3DDEVCAPS_NPATCHES                0x1000000
+
+#define D3DFVFCAPS_TEXCOORDCOUNTMASK  0x00FFFF
+#define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x080000
+#define D3DFVFCAPS_PSIZE              0x100000
+
+#define D3DLINECAPS_TEXTURE           0x01
+#define D3DLINECAPS_ZTEST             0x02
+#define D3DLINECAPS_BLEND             0x04
+#define D3DLINECAPS_ALPHACMP          0x08
+#define D3DLINECAPS_FOG               0x10
+
+#define D3DPBLENDCAPS_ZERO            0x00000001
+#define D3DPBLENDCAPS_ONE             0x00000002
+#define D3DPBLENDCAPS_SRCCOLOR        0x00000004
+#define D3DPBLENDCAPS_INVSRCCOLOR     0x00000008
+#define D3DPBLENDCAPS_SRCALPHA        0x00000010
+#define D3DPBLENDCAPS_INVSRCALPHA     0x00000020
+#define D3DPBLENDCAPS_DESTALPHA       0x00000040
+#define D3DPBLENDCAPS_INVDESTALPHA    0x00000080
+#define D3DPBLENDCAPS_DESTCOLOR       0x00000100
+#define D3DPBLENDCAPS_INVDESTCOLOR    0x00000200
+#define D3DPBLENDCAPS_SRCALPHASAT     0x00000400
+#define D3DPBLENDCAPS_BOTHSRCALPHA    0x00000800
+#define D3DPBLENDCAPS_BOTHINVSRCALPHA 0x00001000
+#define D3DPBLENDCAPS_BLENDFACTOR     0x00002000
+
+#define D3DPCMPCAPS_NEVER        0x01
+#define D3DPCMPCAPS_LESS         0x02
+#define D3DPCMPCAPS_EQUAL        0x04
+#define D3DPCMPCAPS_LESSEQUAL    0x08
+#define D3DPCMPCAPS_GREATER      0x10
+#define D3DPCMPCAPS_NOTEQUAL     0x20
+#define D3DPCMPCAPS_GREATEREQUAL 0x40
+#define D3DPCMPCAPS_ALWAYS       0x80
+
+#define D3DPMISCCAPS_MASKZ                      0x00000002L
+#define D3DPMISCCAPS_LINEPATTERNREP             0x00000004L
+#define D3DPMISCCAPS_CULLNONE                   0x00000010L
+#define D3DPMISCCAPS_CULLCW                     0x00000020L
+#define D3DPMISCCAPS_CULLCCW                    0x00000040L
+#define D3DPMISCCAPS_COLORWRITEENABLE           0x00000080L
+#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS      0x00000100L
+#define D3DPMISCCAPS_CLIPTLVERTS                0x00000200L
+#define D3DPMISCCAPS_TSSARGTEMP                 0x00000400L
+#define D3DPMISCCAPS_BLENDOP                    0x00000800L
+#define D3DPMISCCAPS_NULLREFERENCE              0x00001000L
+#define D3DPMISCCAPS_INDEPENDENTWRITEMASKS      0x00004000L
+#define D3DPMISCCAPS_PERSTAGECONSTANT           0x00008000L
+#define D3DPMISCCAPS_FOGANDSPECULARALPHA        0x00010000L
+#define D3DPMISCCAPS_SEPARATEALPHABLEND         0x00020000L
+#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS    0x00040000L
+#define D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING 0x00080000L
+#define D3DPMISCCAPS_FOGVERTEXCLAMPED           0x00100000L
+
+
+#define D3DPRASTERCAPS_DITHER                     0x00000001L
+#define D3DPRASTERCAPS_PAT                        0x00000008L
+#define D3DPRASTERCAPS_ZTEST                      0x00000010L
+#define D3DPRASTERCAPS_FOGVERTEX                  0x00000080L
+#define D3DPRASTERCAPS_FOGTABLE                   0x00000100L
+#define D3DPRASTERCAPS_ANTIALIASEDGES             0x00001000L
+#define D3DPRASTERCAPS_MIPMAPLODBIAS              0x00002000L
+#define D3DPRASTERCAPS_ZBIAS                      0x00004000L
+#define D3DPRASTERCAPS_ZBUFFERLESSHSR             0x00008000L
+#define D3DPRASTERCAPS_FOGRANGE                   0x00010000L
+#define D3DPRASTERCAPS_ANISOTROPY                 0x00020000L
+#define D3DPRASTERCAPS_WBUFFER                    0x00040000L
+#define D3DPRASTERCAPS_WFOG                       0x00100000L
+#define D3DPRASTERCAPS_ZFOG                       0x00200000L
+#define D3DPRASTERCAPS_COLORPERSPECTIVE           0x00400000L
+#define D3DPRASTERCAPS_SCISSORTEST                0x01000000L
+#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS        0x02000000L
+#define D3DPRASTERCAPS_DEPTHBIAS                  0x04000000L 
+#define D3DPRASTERCAPS_MULTISAMPLE_TOGGLE         0x08000000L
+
+#define D3DPRESENT_INTERVAL_DEFAULT               0x00000000
+#define D3DPRESENT_INTERVAL_ONE                   0x00000001
+#define D3DPRESENT_INTERVAL_TWO                   0x00000002
+#define D3DPRESENT_INTERVAL_THREE                 0x00000004
+#define D3DPRESENT_INTERVAL_FOUR                  0x00000008
+#define D3DPRESENT_INTERVAL_IMMEDIATE             0x80000000
+
+#define D3DPSHADECAPS_COLORGOURAUDRGB             0x00008
+#define D3DPSHADECAPS_SPECULARGOURAUDRGB          0x00200
+#define D3DPSHADECAPS_ALPHAGOURAUDBLEND           0x04000
+#define D3DPSHADECAPS_FOGGOURAUD                  0x80000
+
+#define D3DPTADDRESSCAPS_WRAP                     0x01
+#define D3DPTADDRESSCAPS_MIRROR                   0x02
+#define D3DPTADDRESSCAPS_CLAMP                    0x04
+#define D3DPTADDRESSCAPS_BORDER                   0x08
+#define D3DPTADDRESSCAPS_INDEPENDENTUV            0x10
+#define D3DPTADDRESSCAPS_MIRRORONCE               0x20
+
+#define D3DPTEXTURECAPS_PERSPECTIVE              0x00000001L
+#define D3DPTEXTURECAPS_POW2                     0x00000002L
+#define D3DPTEXTURECAPS_ALPHA                    0x00000004L
+#define D3DPTEXTURECAPS_SQUAREONLY               0x00000020L
+#define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040L
+#define D3DPTEXTURECAPS_ALPHAPALETTE             0x00000080L
+#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL       0x00000100L
+#define D3DPTEXTURECAPS_PROJECTED                0x00000400L
+#define D3DPTEXTURECAPS_CUBEMAP                  0x00000800L
+#define D3DPTEXTURECAPS_VOLUMEMAP                0x00002000L
+#define D3DPTEXTURECAPS_MIPMAP                   0x00004000L
+#define D3DPTEXTURECAPS_MIPVOLUMEMAP             0x00008000L
+#define D3DPTEXTURECAPS_MIPCUBEMAP               0x00010000L
+#define D3DPTEXTURECAPS_CUBEMAP_POW2             0x00020000L
+#define D3DPTEXTURECAPS_VOLUMEMAP_POW2           0x00040000L
+#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV       0x00200000L
+
+#define D3DPTFILTERCAPS_MINFPOINT                0x00000100
+#define D3DPTFILTERCAPS_MINFLINEAR               0x00000200
+#define D3DPTFILTERCAPS_MINFANISOTROPIC          0x00000400
+#define D3DPTFILTERCAPS_MIPFPOINT                0x00010000
+#define D3DPTFILTERCAPS_MIPFLINEAR               0x00020000
+#define D3DPTFILTERCAPS_MAGFPOINT                0x01000000
+#define D3DPTFILTERCAPS_MAGFLINEAR               0x02000000
+#define D3DPTFILTERCAPS_MAGFANISOTROPIC          0x04000000
+#define D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD        0x08000000
+#define D3DPTFILTERCAPS_MAGFGAUSSIANQUAD         0x10000000
+
+#define D3DSTENCILCAPS_KEEP                      0x01
+#define D3DSTENCILCAPS_ZERO                      0x02
+#define D3DSTENCILCAPS_REPLACE                   0x04
+#define D3DSTENCILCAPS_INCRSAT                   0x08
+#define D3DSTENCILCAPS_DECRSAT                   0x10
+#define D3DSTENCILCAPS_INVERT                    0x20
+#define D3DSTENCILCAPS_INCR                      0x40
+#define D3DSTENCILCAPS_DECR                      0x80
+
+#define D3DTEXOPCAPS_DISABLE                     0x0000001
+#define D3DTEXOPCAPS_SELECTARG1                  0x0000002
+#define D3DTEXOPCAPS_SELECTARG2                  0x0000004
+#define D3DTEXOPCAPS_MODULATE                    0x0000008
+#define D3DTEXOPCAPS_MODULATE2X                  0x0000010
+#define D3DTEXOPCAPS_MODULATE4X                  0x0000020
+#define D3DTEXOPCAPS_ADD                         0x0000040
+#define D3DTEXOPCAPS_ADDSIGNED                   0x0000080
+#define D3DTEXOPCAPS_ADDSIGNED2X                 0x0000100
+#define D3DTEXOPCAPS_SUBTRACT                    0x0000200
+#define D3DTEXOPCAPS_ADDSMOOTH                   0x0000400
+#define D3DTEXOPCAPS_BLENDDIFFUSEALPHA           0x0000800
+#define D3DTEXOPCAPS_BLENDTEXTUREALPHA           0x0001000
+#define D3DTEXOPCAPS_BLENDFACTORALPHA            0x0002000
+#define D3DTEXOPCAPS_BLENDTEXTUREALPHAPM         0x0004000
+#define D3DTEXOPCAPS_BLENDCURRENTALPHA           0x0008000
+#define D3DTEXOPCAPS_PREMODULATE                 0x0010000
+#define D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR      0x0020000
+#define D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA      0x0040000
+#define D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR   0x0080000
+#define D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA   0x0100000
+#define D3DTEXOPCAPS_BUMPENVMAP                  0x0200000
+#define D3DTEXOPCAPS_BUMPENVMAPLUMINANCE         0x0400000
+#define D3DTEXOPCAPS_DOTPRODUCT3                 0x0800000
+#define D3DTEXOPCAPS_MULTIPLYADD                 0x1000000
+#define D3DTEXOPCAPS_LERP                        0x2000000
+
+#define D3DVTXPCAPS_TEXGEN                         0x00000001L
+#define D3DVTXPCAPS_MATERIALSOURCE7                0x00000002L
+#define D3DVTXPCAPS_DIRECTIONALLIGHTS              0x00000008L
+#define D3DVTXPCAPS_POSITIONALLIGHTS               0x00000010L
+#define D3DVTXPCAPS_LOCALVIEWER                    0x00000020L
+#define D3DVTXPCAPS_TWEENING                       0x00000040L
+#define D3DVTXPCAPS_TEXGEN_SPHEREMAP               0x00000100L
+#define D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER       0x00000200L
+
+#define D3DDTCAPS_UBYTE4                           0x00000001L
+#define D3DDTCAPS_UBYTE4N                          0x00000002L
+#define D3DDTCAPS_SHORT2N                          0x00000004L
+#define D3DDTCAPS_SHORT4N                          0x00000008L
+#define D3DDTCAPS_USHORT2N                         0x00000010L
+#define D3DDTCAPS_USHORT4N                         0x00000020L
+#define D3DDTCAPS_UDEC3                            0x00000040L
+#define D3DDTCAPS_DEC3N                            0x00000080L
+#define D3DDTCAPS_FLOAT16_2                        0x00000100L
+#define D3DDTCAPS_FLOAT16_4                        0x00000200L
+
+#define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD  0x00000020L
+#define D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION       0x00000080L
+#define D3DCAPS3_COPY_TO_VIDMEM                    0x00000100L 
+#define D3DCAPS3_COPY_TO_SYSTEMMEM                 0x00000200L
+#define D3DCAPS3_RESERVED                          0x8000001FL
+
+#define D3DCAPS2_NO2DDURING3DSCENE                 0x00000002L
+#define D3DCAPS2_FULLSCREENGAMMA                   0x00020000L
+#define D3DCAPS2_CANRENDERWINDOWED                 0x00080000L
+#define D3DCAPS2_CANCALIBRATEGAMMA                 0x00100000L
+#define D3DCAPS2_RESERVED                          0x02000000L
+#define D3DCAPS2_CANMANAGERESOURCE                 0x10000000L
+#define D3DCAPS2_DYNAMICTEXTURES                   0x20000000L
+#define D3DCAPS2_CANAUTOGENMIPMAP                  0x40000000L
+
+
+#define D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH  24
+#define D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH  0
+#define D3DVS20_MAX_NUMTEMPS                 32
+#define D3DVS20_MIN_NUMTEMPS                 12
+#define D3DVS20_MAX_STATICFLOWCONTROLDEPTH   4
+#define D3DVS20_MIN_STATICFLOWCONTROLDEPTH   1
+
+#define D3DVS20CAPS_PREDICATION              (1 << 0)
+
+#define D3DPS20CAPS_ARBITRARYSWIZZLE         (1 << 0)
+#define D3DPS20CAPS_GRADIENTINSTRUCTIONS     (1 << 1)
+#define D3DPS20CAPS_PREDICATION              (1 << 2)
+#define D3DPS20CAPS_NODEPENDENTREADLIMIT     (1 << 3)
+#define D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT    (1 << 4)
+
+#define D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH  24
+#define D3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH  0
+#define D3DPS20_MAX_NUMTEMPS                 32
+#define D3DPS20_MIN_NUMTEMPS                 12
+#define D3DPS20_MAX_STATICFLOWCONTROLDEPTH   4
+#define D3DPS20_MIN_STATICFLOWCONTROLDEPTH   0
+#define D3DPS20_MAX_NUMINSTRUCTIONSLOTS      512
+#define D3DPS20_MIN_NUMINSTRUCTIONSLOTS      96
+
+#define D3DMIN30SHADERINSTRUCTIONS          512
+#define D3DMAX30SHADERINSTRUCTIONS          32768
+
+
+typedef struct _D3DVSHADERCAPS2_0 {
+  DWORD  Caps;
+  INT    DynamicFlowControlDepth;
+  INT    NumTemps;
+  INT    StaticFlowControlDepth;
+} D3DVSHADERCAPS2_0;
+
+typedef struct _D3DPSHADERCAPS2_0 {
+  DWORD  Caps;
+  INT    DynamicFlowControlDepth;
+  INT    NumTemps;
+  INT    StaticFlowControlDepth;
+  INT    NumInstructionSlots;
+} D3DPSHADERCAPS2_0;
+
+/*
+ * The d3dcaps9 structure
+ */
+typedef struct _D3DCAPS9 {
+  D3DDEVTYPE          DeviceType;
+  UINT                AdapterOrdinal;
+  
+  DWORD               Caps;
+  DWORD               Caps2;
+  DWORD               Caps3;
+  DWORD               PresentationIntervals;
+  
+  DWORD               CursorCaps;
+  
+  DWORD               DevCaps;
+  
+  DWORD               PrimitiveMiscCaps;
+  DWORD               RasterCaps;
+  DWORD               ZCmpCaps;
+  DWORD               SrcBlendCaps;
+  DWORD               DestBlendCaps;
+  DWORD               AlphaCmpCaps;
+  DWORD               ShadeCaps;
+  DWORD               TextureCaps;
+  DWORD               TextureFilterCaps;
+  DWORD               CubeTextureFilterCaps;
+  DWORD               VolumeTextureFilterCaps;
+  DWORD               TextureAddressCaps;
+  DWORD               VolumeTextureAddressCaps;
+  
+  DWORD               LineCaps;
+  
+  DWORD               MaxTextureWidth, MaxTextureHeight;
+  DWORD               MaxVolumeExtent;
+  
+  DWORD               MaxTextureRepeat;
+  DWORD               MaxTextureAspectRatio;
+  DWORD               MaxAnisotropy;
+  float               MaxVertexW;
+  
+  float               GuardBandLeft;
+  float               GuardBandTop;
+  float               GuardBandRight;
+  float               GuardBandBottom;
+  
+  float               ExtentsAdjust;
+  DWORD               StencilCaps;
+  
+  DWORD               FVFCaps;
+  DWORD               TextureOpCaps;
+  DWORD               MaxTextureBlendStages;
+  DWORD               MaxSimultaneousTextures;
+  
+  DWORD               VertexProcessingCaps;
+  DWORD               MaxActiveLights;
+  DWORD               MaxUserClipPlanes;
+  DWORD               MaxVertexBlendMatrices;
+  DWORD               MaxVertexBlendMatrixIndex;
+  
+  float               MaxPointSize;
+  
+  DWORD               MaxPrimitiveCount;
+  DWORD               MaxVertexIndex;
+  DWORD               MaxStreams;
+  DWORD               MaxStreamStride;
+  
+  DWORD               VertexShaderVersion;
+  DWORD               MaxVertexShaderConst;
+  
+  DWORD               PixelShaderVersion;
+  float               MaxPixelShaderValue;
+
+  /* DX 9 */
+  DWORD               DevCaps2;
+
+  float               MaxNpatchTessellationLevel;
+  DWORD               Reserved5;
+
+  UINT                MasterAdapterOrdinal;   
+  UINT                AdapterOrdinalInGroup;  
+  UINT                NumberOfAdaptersInGroup;
+  DWORD               DeclTypes;              
+  DWORD               NumSimultaneousRTs;     
+  DWORD               StretchRectFilterCaps;  
+  D3DVSHADERCAPS2_0   VS20Caps;
+  D3DPSHADERCAPS2_0   PS20Caps;
+  DWORD               VertexTextureFilterCaps;
+  DWORD               MaxVShaderInstructionsExecuted;
+  DWORD               MaxPShaderInstructionsExecuted;
+  DWORD               MaxVertexShader30InstructionSlots; 
+  DWORD               MaxPixelShader30InstructionSlots;
+
+} D3DCAPS9;
+
+#endif
diff --git a/reactos/include/d3d9types.h b/reactos/include/d3d9types.h
new file mode 100644 (file)
index 0000000..ccd7a63
--- /dev/null
@@ -0,0 +1,1518 @@
+/*
+ * Copyright (C) 2002-2003 Jason Edmeades 
+ * Copyright (C) 2002-2003 Raphael Junqueira
+ * Copyright (C) 2005 Oliver Stieber
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3D9TYPES_H
+#define __WINE_D3D9TYPES_H
+
+/*****************************************************************************
+ * Direct 3D v9 #defines
+ */
+#define D3DCLEAR_TARGET   0x00000001L
+#define D3DCLEAR_ZBUFFER  0x00000002L
+#define D3DCLEAR_STENCIL  0x00000004L
+
+#define D3DCLIPPLANE0 (1 << 0)
+#define D3DCLIPPLANE1 (1 << 1)
+#define D3DCLIPPLANE2 (1 << 2)
+#define D3DCLIPPLANE3 (1 << 3)
+#define D3DCLIPPLANE4 (1 << 4)
+#define D3DCLIPPLANE5 (1 << 5)
+
+#define D3DCOLOR_ARGB(a,r,g,b)       ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
+#define D3DCOLOR_COLORVALUE(r,g,b,a) D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f))
+#define D3DCOLOR_RGBA(r,g,b,a)       D3DCOLOR_ARGB(a,r,g,b)
+#define D3DCOLOR_XRGB(r,g,b)         D3DCOLOR_ARGB(0xff,r,g,b)
+#define D3DCOLOR_XYUV(y,u,v)         D3DCOLOR_ARGB(0xFF,y,u,v)
+#define D3DCOLOR_AYUV(a,y,u,v)       D3DCOLOR_ARGB(a,y,u,v)
+
+#define D3DCOLORWRITEENABLED_RED     1
+#define D3DCOLORWRITEENABLED_GREEN   2
+#define D3DCOLORWRITEENABLED_BLUE    4
+#define D3DCOLORWRITEENABLED_ALPHA   8
+
+#define D3DCS_LEFT                   0x001L
+#define D3DCS_RIGHT                  0x002L
+#define D3DCS_TOP                    0x004L
+#define D3DCS_BOTTOM                 0x008L
+#define D3DCS_FRONT                  0x010L
+#define D3DCS_BACK                   0x020L
+#define D3DCS_PLANE0                 0x040L
+#define D3DCS_PLANE1                 0x080L
+#define D3DCS_PLANE2                 0x100L
+#define D3DCS_PLANE3                 0x200L
+#define D3DCS_PLANE4                 0x400L
+#define D3DCS_PLANE5                 0x800L
+#define D3DCS_ALL                    0xFFFL
+
+#define D3DFVF_TEXTUREFORMAT1 3
+#define D3DFVF_TEXTUREFORMAT2 0
+#define D3DFVF_TEXTUREFORMAT3 1
+#define D3DFVF_TEXTUREFORMAT4 2
+#define D3DFVF_TEXCOORDSIZE1(CoordIndex) (D3DFVF_TEXTUREFORMAT1 << (CoordIndex*2 + 16))
+#define D3DFVF_TEXCOORDSIZE2(CoordIndex) (D3DFVF_TEXTUREFORMAT2)
+#define D3DFVF_TEXCOORDSIZE3(CoordIndex) (D3DFVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16))
+#define D3DFVF_TEXCOORDSIZE4(CoordIndex) (D3DFVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16))
+
+#define D3DLOCK_READONLY           0x0010
+#define D3DLOCK_NOSYSLOCK          0x0800
+#define D3DLOCK_NOOVERWRITE        0x1000
+#define D3DLOCK_DISCARD            0x2000
+#define D3DLOCK_DONOTWAIT          0x4000
+#define D3DLOCK_NO_DIRTY_UPDATE    0x8000
+
+#define D3DMAXUSERCLIPPLANES       32
+#define D3DCLIPPLANE0              (1 << 0)
+#define D3DCLIPPLANE1              (1 << 1)
+#define D3DCLIPPLANE2              (1 << 2)
+#define D3DCLIPPLANE3              (1 << 3)
+#define D3DCLIPPLANE4              (1 << 4)
+#define D3DCLIPPLANE5              (1 << 5)
+
+
+#define D3DRENDERSTATE_WRAPBIAS    128UL
+
+/* MSDN has this in d3d9caps.h, but it should be here */
+#define D3DTSS_TCI_PASSTHRU                       0x00000
+#define D3DTSS_TCI_CAMERASPACENORMAL              0x10000
+#define D3DTSS_TCI_CAMERASPACEPOSITION            0x20000
+#define D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR    0x30000
+#define D3DTSS_TCI_SPHEREMAP                      0x40000
+
+
+#define D3DTS_WORLD  D3DTS_WORLDMATRIX(0)
+#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1)
+#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2)
+#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3)
+#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)
+
+#define D3DUSAGE_RENDERTARGET       0x00000001L
+#define D3DUSAGE_DEPTHSTENCIL       0x00000002L
+#define D3DUSAGE_WRITEONLY          0x00000008L
+#define D3DUSAGE_SOFTWAREPROCESSING 0x00000010L
+#define D3DUSAGE_DONOTCLIP          0x00000020L
+#define D3DUSAGE_POINTS             0x00000040L
+#define D3DUSAGE_RTPATCHES          0x00000080L
+#define D3DUSAGE_NPATCHES           0x00000100L
+#define D3DUSAGE_DYNAMIC            0x00000200L
+#define D3DUSAGE_AUTOGENMIPMAP      0x00000400L 
+#define D3DUSAGE_DMAP               0x00004000L
+
+#define D3DUSAGE_QUERY_FILTER                   0x00020000L
+#define D3DUSAGE_QUERY_LEGACYBUMPMAP            0x00008000L
+#define D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING 0x00080000L
+#define D3DUSAGE_QUERY_SRGBREAD                 0x00010000L
+#define D3DUSAGE_QUERY_SRGBWRITE                0x00040000L
+#define D3DUSAGE_QUERY_VERTEXTEXTURE            0x00100000L
+
+
+#define D3DWRAP_U        1
+#define D3DWRAP_V        2
+#define D3DWRAP_W        4
+#define D3DWRAPCOORD_0   1
+#define D3DWRAPCOORD_1   2
+#define D3DWRAPCOORD_2   4
+#define D3DWRAPCOORD_3   8
+
+#define MAX_DEVICE_IDENTIFIER_STRING        512
+
+#define D3DFVF_RESERVED0           0x0001
+#define D3DFVF_POSITION_MASK       0x4000E
+#define D3DFVF_XYZ                 0x0002
+#define D3DFVF_XYZRHW              0x0004
+#define D3DFVF_XYZB1               0x0006
+#define D3DFVF_XYZB2               0x0008
+#define D3DFVF_XYZB3               0x000a
+#define D3DFVF_XYZB4               0x000c
+#define D3DFVF_XYZB5               0x000e
+#define D3DFVF_XYZW                0x4002
+#define D3DFVF_NORMAL              0x0010
+#define D3DFVF_PSIZE               0x0020
+#define D3DFVF_DIFFUSE             0x0040
+#define D3DFVF_SPECULAR            0x0080
+#define D3DFVF_TEXCOUNT_MASK       0x0f00
+#define D3DFVF_TEXCOUNT_SHIFT           8
+#define D3DFVF_TEX0                0x0000
+#define D3DFVF_TEX1                0x0100
+#define D3DFVF_TEX2                0x0200
+#define D3DFVF_TEX3                0x0300
+#define D3DFVF_TEX4                0x0400
+#define D3DFVF_TEX5                0x0500
+#define D3DFVF_TEX6                0x0600
+#define D3DFVF_TEX7                0x0700
+#define D3DFVF_TEX8                0x0800
+#define D3DFVF_LASTBETA_UBYTE4     0x1000
+#define D3DFVF_LASTBETA_D3DCOLOR   0x8000
+#define D3DFVF_RESERVED2           0x6000
+
+#define D3DTA_SELECTMASK        0x0000000f
+#define D3DTA_DIFFUSE           0x00000000
+#define D3DTA_CURRENT           0x00000001
+#define D3DTA_TEXTURE           0x00000002
+#define D3DTA_TFACTOR           0x00000003
+#define D3DTA_SPECULAR          0x00000004
+#define D3DTA_TEMP              0x00000005
+#define D3DTA_CONSTANT          0x00000006
+#define D3DTA_COMPLEMENT        0x00000010
+#define D3DTA_ALPHAREPLICATE    0x00000020
+
+#define D3DCOLORWRITEENABLE_RED   (1L<<0)   
+#define D3DCOLORWRITEENABLE_GREEN (1L<<1)
+#define D3DCOLORWRITEENABLE_BLUE  (1L<<2)
+#define D3DCOLORWRITEENABLE_ALPHA (1L<<3)
+
+#define D3DPV_DONOTCOPYDATA         (1 << 0)
+
+#define D3DSTREAMSOURCE_INDEXEDDATA  (1 << 30)
+#define D3DSTREAMSOURCE_INSTANCEDATA (2 << 30)
+
+#define D3D_MAX_SIMULTANEOUS_RENDERTARGETS 4
+
+#define MAXD3DDECLLENGTH         64 /* +end marker */
+#define MAXD3DDECLMETHOD         D3DDECLMETHOD_LOOKUPPRESAMPLED
+#define MAXD3DDECLTYPE           D3DDECLTYPE_UNUSED
+#define MAXD3DDECLUSAGE          D3DDECLUSAGE_SAMPLE
+#define MAXD3DDECLUSAGEINDEX     15
+
+#define D3DDMAPSAMPLER 256
+#define D3DVERTEXTEXTURESAMPLER0 (D3DDMAPSAMPLER+1)
+#define D3DVERTEXTEXTURESAMPLER1 (D3DDMAPSAMPLER+2)
+#define D3DVERTEXTEXTURESAMPLER2 (D3DDMAPSAMPLER+3)
+#define D3DVERTEXTEXTURESAMPLER3 (D3DDMAPSAMPLER+4)
+
+#define MAKEFOURCC(ch0, ch1, ch2, ch3)  \
+    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |  \
+    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+
+/* Constants used by D3DPRESENT_PARAMETERS. when creating a device or swapchain */
+
+#define D3DPRESENTFLAG_LOCKABLE_BACKBUFFER  0x00000001 /* Create a lockable backbuffer */
+#define D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL 0x00000002 /* Discard Z buffer */
+#define D3DPRESENTFLAG_DEVICECLIP           0x00000004 /* Clip the window blited into the client area 2k + xp only */
+#define D3DPRESENTFLAG_VIDEO                0x00000010 /* backbuffer 'may' contain video data */
+
+
+
+/**************************** 
+ * Vertex Shaders Declaration
+ */
+
+typedef enum _D3DDECLUSAGE {
+  D3DDECLUSAGE_POSITION     = 0,
+  D3DDECLUSAGE_BLENDWEIGHT  = 1,
+  D3DDECLUSAGE_BLENDINDICES = 2,
+  D3DDECLUSAGE_NORMAL       = 3,      
+  D3DDECLUSAGE_PSIZE        = 4,       
+  D3DDECLUSAGE_TEXCOORD     = 5,    
+  D3DDECLUSAGE_TANGENT      = 6,     
+  D3DDECLUSAGE_BINORMAL     = 7,    
+  D3DDECLUSAGE_TESSFACTOR   = 8,  
+  D3DDECLUSAGE_POSITIONT    = 9,   
+  D3DDECLUSAGE_COLOR        = 10,       
+  D3DDECLUSAGE_FOG          = 11,        
+  D3DDECLUSAGE_DEPTH        = 12,      
+  D3DDECLUSAGE_SAMPLE       = 13     
+} D3DDECLUSAGE;
+
+/* MSDN is quite confussing at this point...
+http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/reference/d3d/constants/OTHER_D3D.asp
+says D3DMAX, and D3DMAXDECLUSAGE = D3DDECLUSAGE_DEPTH
+http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/directx9_c_summer_03/directx/graphics/reference/d3d/constants/other_d3d.asp
+says MAXD3D, and D3DDECLUSAGE_SAMPLE
+
+So both are defined
+*/
+
+#define D3DMAXDECLUSAGE         D3DDECLUSAGE_SAMPLE
+#define D3DMAXDECLUSAGEINDEX    15
+#define D3DMAXDECLLENGTH        18
+#define D3DMAXDECLUSAGE_DX8     D3DDECLUSAGE_TEXCOORD
+
+typedef enum _D3DDECLMETHOD {
+  D3DDECLMETHOD_DEFAULT          = 0,
+  D3DDECLMETHOD_PARTIALU         = 1,
+  D3DDECLMETHOD_PARTIALV         = 2,
+  D3DDECLMETHOD_CROSSUV          = 3,
+  D3DDECLMETHOD_UV               = 4,
+  D3DDECLMETHOD_LOOKUP           = 5,
+  D3DDECLMETHOD_LOOKUPPRESAMPLED = 6
+} D3DDECLMETHOD;
+
+
+#define D3DMAXDECLMETHOD        D3DDECLMETHOD_LOOKUPPRESAMPLED
+
+typedef enum _D3DDECLTYPE {
+  D3DDECLTYPE_FLOAT1    =  0,
+  D3DDECLTYPE_FLOAT2    =  1,
+  D3DDECLTYPE_FLOAT3    =  2,
+  D3DDECLTYPE_FLOAT4    =  3,
+  D3DDECLTYPE_D3DCOLOR  =  4,
+  D3DDECLTYPE_UBYTE4    =  5,
+  D3DDECLTYPE_SHORT2    =  6,
+  D3DDECLTYPE_SHORT4    =  7,
+  /* VS 2.0 */
+  D3DDECLTYPE_UBYTE4N   =  8,
+  D3DDECLTYPE_SHORT2N   =  9,
+  D3DDECLTYPE_SHORT4N   = 10,
+  D3DDECLTYPE_USHORT2N  = 11,
+  D3DDECLTYPE_USHORT4N  = 12,
+  D3DDECLTYPE_UDEC3     = 13,
+  D3DDECLTYPE_DEC3N     = 14,
+  D3DDECLTYPE_FLOAT16_2 = 15,
+  D3DDECLTYPE_FLOAT16_4 = 16,
+  D3DDECLTYPE_UNUSED    = 17,
+} D3DDECLTYPE;
+
+#define D3DMAXDECLTYPE          D3DDECLTYPE_UNUSED
+
+typedef struct _D3DVERTEXELEMENT9 {
+  WORD    Stream;
+  WORD    Offset;
+  BYTE    Type;
+  BYTE    Method;
+  BYTE    Usage;
+  BYTE    UsageIndex;
+} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;
+
+
+typedef enum _D3DQUERYTYPE {
+    D3DQUERYTYPE_VCACHE = 4,
+    D3DQUERYTYPE_RESOURCEMANAGER = 5,
+    D3DQUERYTYPE_VERTEXSTATS = 6,
+    D3DQUERYTYPE_EVENT = 8,
+    D3DQUERYTYPE_OCCLUSION = 9,
+    D3DQUERYTYPE_TIMESTAMP = 10,
+    D3DQUERYTYPE_TIMESTAMPDISJOINT = 11,
+    D3DQUERYTYPE_TIMESTAMPFREQ = 12,
+    D3DQUERYTYPE_PIPELINETIMINGS = 13,
+    D3DQUERYTYPE_INTERFACETIMINGS = 14,
+    D3DQUERYTYPE_VERTEXTIMINGS = 15,
+    D3DQUERYTYPE_PIXELTIMINGS = 16,
+    D3DQUERYTYPE_BANDWIDTHTIMINGS = 17,
+    D3DQUERYTYPE_CACHEUTILIZATION = 18
+} D3DQUERYTYPE;
+
+#define D3DISSUE_BEGIN   (1 << 1)
+#define D3DISSUE_END     (1 << 0)
+#define D3DGETDATA_FLUSH (1 << 0)
+
+
+#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
+#define D3DDP_MAXTEXCOORD   8
+
+
+#define D3DVSD_MAKETOKENTYPE(TokenType) \
+  ((TokenType << D3DVSD_TOKENTYPESHIFT) & D3DVSD_TOKENTYPEMASK)
+
+#define D3DVSD_CONST(ConstantAddress, Count) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_CONSTMEM) | ((Count) << D3DVSD_CONSTCOUNTSHIFT) | (ConstantAddress))
+
+#define D3DVSD_END() 0xFFFFFFFF
+
+#define D3DVSD_NOP() 0x00000000
+
+#define D3DVSD_REG(VertexRegister, Type) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | ((Type) << D3DVSD_DATATYPESHIFT) | (VertexRegister))
+
+#define D3DVSD_SKIP(Count) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAMDATA) | 0x10000000 | ((Count) << D3DVSD_SKIPCOUNTSHIFT))
+
+#define D3DVSD_STREAM(StreamNumber) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (StreamNumber))
+
+#define D3DVSD_STREAM_TESS() \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_STREAM) | (D3DVSD_STREAMTESSMASK))
+
+#define D3DVSD_TESSNORMAL(RegisterIn, RegisterOut) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | ((RegisterIn) << D3DVSD_VERTEXREGINSHIFT) | ((0x02) << D3DVSD_DATATYPESHIFT) | (RegisterOut))
+
+#define D3DVSD_TESSUV(Register) \
+  (D3DVSD_MAKETOKENTYPE(D3DVSD_TOKEN_TESSELLATOR) | 0x10000000 | ((0x01) << D3DVSD_DATATYPESHIFT) | (Register))
+
+
+/********************************
+ * Pixel/Vertex Shaders Functions
+ */
+
+/** Maximum number of supported texture coordinates sets operation */
+#define D3DDP_MAXTEXCOORD   8
+
+/** opcode token mask */
+#define D3DSI_OPCODE_MASK       0x0000FFFF
+#define D3DSI_INSTLENGTH_MASK   0x0F000000
+#define D3DSI_INSTLENGTH_SHIFT  24
+
+/** opcodes types for PS and VS */
+typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE {
+  D3DSIO_NOP          =  0,
+  D3DSIO_MOV          =  1,
+  D3DSIO_ADD          =  2,
+  D3DSIO_SUB          =  3,
+  D3DSIO_MAD          =  4,
+  D3DSIO_MUL          =  5,
+  D3DSIO_RCP          =  6,
+  D3DSIO_RSQ          =  7,
+  D3DSIO_DP3          =  8,
+  D3DSIO_DP4          =  9,
+  D3DSIO_MIN          = 10,
+  D3DSIO_MAX          = 11,
+  D3DSIO_SLT          = 12,
+  D3DSIO_SGE          = 13,
+  D3DSIO_EXP          = 14,
+  D3DSIO_LOG          = 15,
+  D3DSIO_LIT          = 16,
+  D3DSIO_DST          = 17,
+  D3DSIO_LRP          = 18,
+  D3DSIO_FRC          = 19,
+  D3DSIO_M4x4         = 20,
+  D3DSIO_M4x3         = 21,
+  D3DSIO_M3x4         = 22,
+  D3DSIO_M3x3         = 23,
+  D3DSIO_M3x2         = 24,
+  D3DSIO_CALL         = 25,
+  D3DSIO_CALLNZ       = 26,
+  D3DSIO_LOOP         = 27,
+  D3DSIO_RET          = 28,
+  D3DSIO_ENDLOOP      = 29,
+  D3DSIO_LABEL        = 30,
+  D3DSIO_DCL          = 31,
+  D3DSIO_POW          = 32,
+  D3DSIO_CRS          = 33,
+  D3DSIO_SGN          = 34,
+  D3DSIO_ABS          = 35,
+  D3DSIO_NRM          = 36,
+  D3DSIO_SINCOS       = 37,
+  D3DSIO_REP          = 38,
+  D3DSIO_ENDREP       = 39,
+  D3DSIO_IF           = 40,
+  D3DSIO_IFC          = 41,
+  D3DSIO_ELSE         = 42,
+  D3DSIO_ENDIF        = 43,
+  D3DSIO_BREAK        = 44,
+  D3DSIO_BREAKC       = 45,
+  D3DSIO_MOVA         = 46,
+  D3DSIO_DEFB         = 47,
+  D3DSIO_DEFI         = 48,
+
+  D3DSIO_TEXCOORD     = 64,
+  D3DSIO_TEXKILL      = 65,
+  D3DSIO_TEX          = 66,
+  D3DSIO_TEXBEM       = 67,
+  D3DSIO_TEXBEML      = 68,
+  D3DSIO_TEXREG2AR    = 69,
+  D3DSIO_TEXREG2GB    = 70,
+  D3DSIO_TEXM3x2PAD   = 71,
+  D3DSIO_TEXM3x2TEX   = 72,
+  D3DSIO_TEXM3x3PAD   = 73,
+  D3DSIO_TEXM3x3TEX   = 74,
+  D3DSIO_TEXM3x3DIFF  = 75,
+  D3DSIO_TEXM3x3SPEC  = 76,
+  D3DSIO_TEXM3x3VSPEC = 77,
+  D3DSIO_EXPP         = 78,
+  D3DSIO_LOGP         = 79,
+  D3DSIO_CND          = 80,
+  D3DSIO_DEF          = 81,
+  D3DSIO_TEXREG2RGB   = 82,
+  D3DSIO_TEXDP3TEX    = 83,
+  D3DSIO_TEXM3x2DEPTH = 84,
+  D3DSIO_TEXDP3       = 85,
+  D3DSIO_TEXM3x3      = 86,
+  D3DSIO_TEXDEPTH     = 87,
+  D3DSIO_CMP          = 88,
+  D3DSIO_BEM          = 89,
+  D3DSIO_DP2ADD       = 90,
+  D3DSIO_DSX          = 91,
+  D3DSIO_DSY          = 92,
+  D3DSIO_TEXLDD       = 93,
+  D3DSIO_SETP         = 94,
+  D3DSIO_TEXLDL       = 95,
+  D3DSIO_BREAKP       = 96,
+  
+  D3DSIO_PHASE        = 0xFFFD,
+  D3DSIO_COMMENT      = 0xFFFE,
+  D3DSIO_END          = 0XFFFF,
+
+  D3DSIO_FORCE_DWORD  = 0X7FFFFFFF /** for 32-bit alignment */
+} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+#define D3DSINCOSCONST1   -1.5500992e-006f, -2.1701389e-005f,  0.0026041667f, 0.00026041668f
+#define D3DSINCOSCONST2   -0.020833334f,    -0.12500000f,      1.0f,          0.50000000f
+
+#define D3DSHADER_INSTRUCTION_PREDICATED    (1 << 28)
+
+/** for parallelism */
+#define D3DSI_COISSUE 0x40000000
+
+#define D3DSP_DCL_USAGE_SHIFT 0
+#define D3DSP_DCL_USAGE_MASK  0x0000000f
+
+#define D3DSP_DCL_USAGEINDEX_SHIFT 16
+#define D3DSP_DCL_USAGEINDEX_MASK  0x000f0000
+
+#define D3DSP_TEXTURETYPE_SHIFT 27
+#define D3DSP_TEXTURETYPE_MASK  0x78000000
+
+typedef enum _D3DSAMPLER_TEXTURE_TYPE {
+  D3DSTT_UNKNOWN      = 0 << D3DSP_TEXTURETYPE_SHIFT,
+  D3DSTT_2D           = 2 << D3DSP_TEXTURETYPE_SHIFT,
+  D3DSTT_CUBE         = 3 << D3DSP_TEXTURETYPE_SHIFT,
+  D3DSTT_VOLUME       = 4 << D3DSP_TEXTURETYPE_SHIFT,
+
+  D3DSTT_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSAMPLER_TEXTURE_TYPE;
+
+#define D3DSP_REGNUM_MASK       0x000007FF
+
+/** destination parameter modifiers (.xyzw) */
+#define D3DSP_WRITEMASK_0       0x00010000 /* .x r */
+#define D3DSP_WRITEMASK_1       0x00020000 /* .y g */
+#define D3DSP_WRITEMASK_2       0x00040000 /* .z b */
+#define D3DSP_WRITEMASK_3       0x00080000 /* .w a */
+#define D3DSP_WRITEMASK_ALL     0x000F0000 /* all */
+
+#define D3DSP_DSTMOD_SHIFT      20
+#define D3DSP_DSTMOD_MASK       (0xF << D3DSP_DSTMOD_SHIFT)
+
+typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE {
+  D3DSPDM_NONE             = 0 << D3DSP_DSTMOD_SHIFT,
+  D3DSPDM_SATURATE         = 1 << D3DSP_DSTMOD_SHIFT,
+  D3DSPDM_PARTIALPRECISION = 2 << D3DSP_DSTMOD_SHIFT,
+  D3DSPDM_MSAMPCENTROID    = 4 << D3DSP_DSTMOD_SHIFT,
+
+  D3DSPDM_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSHADER_PARAM_DSTMOD_TYPE;
+
+/** destination param */
+#define D3DSP_DSTSHIFT_SHIFT     24
+#define D3DSP_DSTSHIFT_MASK      (0xF << D3DSP_DSTSHIFT_SHIFT)
+
+/** destination/source reg type */
+#define D3DSP_REGTYPE_SHIFT      28
+#define D3DSP_REGTYPE_SHIFT2     8
+#define D3DSP_REGTYPE_MASK       (0x7 << D3DSP_REGTYPE_SHIFT)
+#define D3DSP_REGTYPE_MASK2      0x00001800
+
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE {
+  D3DSPR_TEMP         =  0, 
+  D3DSPR_INPUT        =  1,
+  D3DSPR_CONST        =  2,
+  D3DSPR_ADDR         =  3,
+  D3DSPR_TEXTURE      =  3,
+  D3DSPR_RASTOUT      =  4,
+  D3DSPR_ATTROUT      =  5,
+  D3DSPR_TEXCRDOUT    =  6,
+  D3DSPR_OUTPUT       =  6,
+  D3DSPR_CONSTINT     =  7,
+  D3DSPR_COLOROUT     =  8,
+  D3DSPR_DEPTHOUT     =  9,
+  D3DSPR_SAMPLER      = 10,
+  D3DSPR_CONST2       = 11,
+  D3DSPR_CONST3       = 12,
+  D3DSPR_CONST4       = 13,
+  D3DSPR_CONSTBOOL    = 14,
+  D3DSPR_LOOP         = 15,
+  D3DSPR_TEMPFLOAT16  = 16,
+  D3DSPR_MISCTYPE     = 17,
+  D3DSPR_LABEL        = 18,
+  D3DSPR_PREDICATE    = 19,
+
+  D3DSPR_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSHADER_PARAM_REGISTER_TYPE;
+
+typedef enum _D3DSHADER_MISCTYPE_OFFSETS {
+    D3DSMO_POSITION  = 0,
+    D3DSMO_FACE      = 1
+} D3DSHADER_MISCTYPE_OFFSETS;
+
+typedef enum _D3DVS_RASTOUT_OFFSETS {
+  D3DSRO_POSITION     = 0,
+  D3DSRO_FOG          = 1,
+  D3DSRO_POINT_SIZE   = 2,
+
+  D3DSRO_FORCE_DWORD  = 0x7FFFFFFF
+} D3DVS_RASTOUT_OFFSETS;
+
+#define D3DVS_ADDRESSMODE_SHIFT  13
+#define D3DVS_ADDRESSMODE_MASK   (0x1 << D3DVS_ADDRESSMODE_SHIFT)
+
+typedef enum _D3DVS_ADDRESSMODE_TYPE {
+  D3DVS_ADDRMODE_ABSOLUTE     = 0 << D3DVS_ADDRESSMODE_SHIFT,
+  D3DVS_ADDRMODE_RELATIVE     = 1 << D3DVS_ADDRESSMODE_SHIFT,
+
+  D3DVS_ADDRMODE_FORCE_DWORD  = 0x7FFFFFFF
+} D3DVS_ADDRESSMODE_TYPE;
+
+#define D3DSHADER_ADDRESSMODE_SHIFT 13
+#define D3DSHADER_ADDRESSMODE_MASK  (1 << D3DSHADER_ADDRESSMODE_SHIFT)
+
+typedef enum _D3DSHADER_ADDRESSMODE_TYPE {
+  D3DSHADER_ADDRMODE_ABSOLUTE    = 0 << D3DSHADER_ADDRESSMODE_SHIFT,
+  D3DSHADER_ADDRMODE_RELATIVE    = 1 << D3DSHADER_ADDRESSMODE_SHIFT,
+
+  D3DSHADER_ADDRMODE_FORCE_DWORD = 0x7FFFFFFF
+} D3DSHADER_ADDRESSMODE_TYPE;
+
+
+#define D3DVS_SWIZZLE_SHIFT      16
+#define D3DVS_SWIZZLE_MASK       (0xFF << D3DVS_SWIZZLE_SHIFT)
+
+#define D3DSP_SWIZZLE_SHIFT      16
+#define D3DSP_SWIZZLE_MASK       (0xFF << D3DSP_SWIZZLE_SHIFT)
+
+#define D3DVS_X_X       (0 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Y       (1 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Z       (2 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_W       (3 << D3DVS_SWIZZLE_SHIFT)
+
+#define D3DVS_Y_X       (0 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_W       (3 << (D3DVS_SWIZZLE_SHIFT + 2))
+
+#define D3DVS_Z_X       (0 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_W       (3 << (D3DVS_SWIZZLE_SHIFT + 4))
+
+#define D3DVS_W_X       (0 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Y       (1 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Z       (2 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_W       (3 << (D3DVS_SWIZZLE_SHIFT + 6))
+
+#define D3DVS_NOSWIZZLE (D3DVS_X_X | D3DVS_Y_Y | D3DVS_Z_Z | D3DVS_W_W)
+
+#define D3DSP_NOSWIZZLE \
+    ((0 << (D3DSP_SWIZZLE_SHIFT + 0)) | (1 << (D3DSP_SWIZZLE_SHIFT + 2)) | (2 << (D3DSP_SWIZZLE_SHIFT + 4)) | (3 << (D3DSP_SWIZZLE_SHIFT + 6)))
+
+#define D3DSP_SRCMOD_SHIFT      24
+#define D3DSP_SRCMOD_MASK       (0xF << D3DSP_SRCMOD_SHIFT)
+
+typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE {
+  D3DSPSM_NONE         =  0 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_NEG          =  1 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_BIAS         =  2 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_BIASNEG      =  3 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_SIGN         =  4 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_SIGNNEG      =  5 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_COMP         =  6 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_X2           =  7 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_X2NEG        =  8 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_DZ           =  9 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_DW           = 10 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_ABS          = 11 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_ABSNEG       = 12 << D3DSP_SRCMOD_SHIFT,
+  D3DSPSM_NOT          = 13 << D3DSP_SRCMOD_SHIFT,
+
+  D3DSPSM_FORCE_DWORD  = 0x7FFFFFFF
+} D3DSHADER_PARAM_SRCMOD_TYPE;
+
+#define D3DPS_VERSION(major, minor) (0xFFFF0000 | ((major) << 8) | (minor))
+#define D3DVS_VERSION(major, minor) (0xFFFE0000 | ((major) << 8) | (minor))
+#define D3DSHADER_VERSION_MAJOR(version) (((version) >> 8) & 0xFF)
+#define D3DSHADER_VERSION_MINOR(version) (((version) >> 0) & 0xFF)
+
+#define D3DSI_COMMENTSIZE_SHIFT 16
+#define D3DSI_COMMENTSIZE_MASK (0x7FFF << D3DSI_COMMENTSIZE_SHIFT)
+
+#define D3DSHADER_COMMENT(commentSize) \
+  ((((commentSize) << D3DSI_COMMENTSIZE_SHIFT) & D3DSI_COMMENTSIZE_MASK) | D3DSIO_COMMENT)
+
+#define D3DPS_END() 0x0000FFFF
+#define D3DVS_END() 0x0000FFFF
+
+
+/*****************************************************************************
+ * Direct 3D v8 enumerated types
+ */
+typedef enum _D3DBACKBUFFER_TYPE {
+    D3DBACKBUFFER_TYPE_MONO         = 0,
+    D3DBACKBUFFER_TYPE_LEFT         = 1,
+    D3DBACKBUFFER_TYPE_RIGHT        = 2,
+
+    D3DBACKBUFFER_TYPE_FORCE_DWORD  = 0x7fffffff
+} D3DBACKBUFFER_TYPE;
+
+#define D3DPRESENT_BACK_BUFFER_MAX 3L
+
+typedef enum _D3DBASISTYPE {
+   D3DBASIS_BEZIER        = 0,
+   D3DBASIS_BSPLINE       = 1,
+   D3DBASIS_INTERPOLATE   = 2,
+
+   D3DBASIS_FORCE_DWORD   = 0x7fffffff
+} D3DBASISTYPE;
+
+typedef enum _D3DBLEND {
+    D3DBLEND_ZERO               =  1,
+    D3DBLEND_ONE                =  2,
+    D3DBLEND_SRCCOLOR           =  3,
+    D3DBLEND_INVSRCCOLOR        =  4,
+    D3DBLEND_SRCALPHA           =  5,
+    D3DBLEND_INVSRCALPHA        =  6,
+    D3DBLEND_DESTALPHA          =  7,
+    D3DBLEND_INVDESTALPHA       =  8,
+    D3DBLEND_DESTCOLOR          =  9,
+    D3DBLEND_INVDESTCOLOR       = 10,
+    D3DBLEND_SRCALPHASAT        = 11,
+    D3DBLEND_BOTHSRCALPHA       = 12,
+    D3DBLEND_BOTHINVSRCALPHA    = 13,
+    D3DBLEND_BLENDFACTOR        = 14,
+    D3DBLEND_INVBLENDFACTOR     = 15,
+    D3DBLEND_FORCE_DWORD        = 0x7fffffff
+} D3DBLEND;
+
+typedef enum _D3DBLENDOP {
+    D3DBLENDOP_ADD              = 1,
+    D3DBLENDOP_SUBTRACT         = 2,
+    D3DBLENDOP_REVSUBTRACT      = 3,
+    D3DBLENDOP_MIN              = 4,
+    D3DBLENDOP_MAX              = 5,
+
+    D3DBLENDOP_FORCE_DWORD      = 0x7fffffff
+} D3DBLENDOP;
+
+typedef enum _D3DCMPFUNC {
+    D3DCMP_NEVER                = 1,
+    D3DCMP_LESS                 = 2,
+    D3DCMP_EQUAL                = 3,
+    D3DCMP_LESSEQUAL            = 4,
+    D3DCMP_GREATER              = 5,
+    D3DCMP_NOTEQUAL             = 6,
+    D3DCMP_GREATEREQUAL         = 7,
+    D3DCMP_ALWAYS               = 8,
+
+    D3DCMP_FORCE_DWORD          = 0x7fffffff
+} D3DCMPFUNC;
+
+typedef enum _D3DCUBEMAP_FACES {
+    D3DCUBEMAP_FACE_POSITIVE_X     = 0,
+    D3DCUBEMAP_FACE_NEGATIVE_X     = 1,
+    D3DCUBEMAP_FACE_POSITIVE_Y     = 2,
+    D3DCUBEMAP_FACE_NEGATIVE_Y     = 3,
+    D3DCUBEMAP_FACE_POSITIVE_Z     = 4,
+    D3DCUBEMAP_FACE_NEGATIVE_Z     = 5,
+
+    D3DCUBEMAP_FACE_FORCE_DWORD    = 0xffffffff
+} D3DCUBEMAP_FACES;
+
+typedef enum _D3DCULL {
+    D3DCULL_NONE                = 1,
+    D3DCULL_CW                  = 2,
+    D3DCULL_CCW                 = 3,
+
+    D3DCULL_FORCE_DWORD         = 0x7fffffff
+} D3DCULL;
+
+typedef enum _D3DDEBUGMONITORTOKENS {
+    D3DDMT_ENABLE          = 0,
+    D3DDMT_DISABLE         = 1,
+
+    D3DDMT_FORCE_DWORD     = 0x7fffffff
+} D3DDEBUGMONITORTOKENS;
+
+typedef enum _D3DDEGREETYPE {
+    D3DDEGREE_LINEAR      = 1,
+    D3DDEGREE_QUADRATIC   = 2,
+    D3DDEGREE_CUBIC       = 3,
+    D3DDEGREE_QUINTIC     = 5,
+    
+    D3DDEGREE_FORCE_DWORD   = 0x7fffffff
+} D3DDEGREETYPE;
+
+typedef enum _D3DDEVTYPE {
+    D3DDEVTYPE_HAL         = 1,
+    D3DDEVTYPE_REF         = 2,
+    D3DDEVTYPE_SW          = 3,
+
+    D3DDEVTYPE_FORCE_DWORD = 0xffffffff
+} D3DDEVTYPE;
+
+typedef enum _D3DFILLMODE {
+    D3DFILL_POINT               = 1,
+    D3DFILL_WIREFRAME           = 2,
+    D3DFILL_SOLID               = 3,
+
+    D3DFILL_FORCE_DWORD         = 0x7fffffff
+} D3DFILLMODE;
+
+typedef enum _D3DFOGMODE {
+    D3DFOG_NONE                 = 0,
+    D3DFOG_EXP                  = 1,
+    D3DFOG_EXP2                 = 2,
+    D3DFOG_LINEAR               = 3,
+
+    D3DFOG_FORCE_DWORD          = 0x7fffffff
+} D3DFOGMODE;
+
+typedef enum _D3DFORMAT {
+    D3DFMT_UNKNOWN              =   0,
+
+    D3DFMT_R8G8B8               =  20,
+    D3DFMT_A8R8G8B8             =  21,
+    D3DFMT_X8R8G8B8             =  22,
+    D3DFMT_R5G6B5               =  23,
+    D3DFMT_X1R5G5B5             =  24,
+    D3DFMT_A1R5G5B5             =  25,
+    D3DFMT_A4R4G4B4             =  26,
+    D3DFMT_R3G3B2               =  27,
+    D3DFMT_A8                   =  28,
+    D3DFMT_A8R3G3B2             =  29,
+    D3DFMT_X4R4G4B4             =  30,
+    D3DFMT_A2B10G10R10          =  31,
+    D3DFMT_A8B8G8R8             =  32,
+    D3DFMT_X8B8G8R8             =  33,
+    D3DFMT_G16R16               =  34,
+    D3DFMT_A2R10G10B10          =  35,
+    D3DFMT_A16B16G16R16         =  36,
+  
+
+    D3DFMT_A8P8                 =  40,
+    D3DFMT_P8                   =  41,
+
+    D3DFMT_L8                   =  50,
+    D3DFMT_A8L8                 =  51,
+    D3DFMT_A4L4                 =  52,
+
+    D3DFMT_V8U8                 =  60,
+    D3DFMT_L6V5U5               =  61,
+    D3DFMT_X8L8V8U8             =  62,
+    D3DFMT_Q8W8V8U8             =  63,
+    D3DFMT_V16U16               =  64,
+    D3DFMT_W11V11U10            =  65,
+    D3DFMT_A2W10V10U10          =  67,
+
+    D3DFMT_UYVY                 =  MAKEFOURCC('U', 'Y', 'V', 'Y'),
+    D3DFMT_YUY2                 =  MAKEFOURCC('Y', 'U', 'Y', '2'),
+    D3DFMT_DXT1                 =  MAKEFOURCC('D', 'X', 'T', '1'),
+    D3DFMT_DXT2                 =  MAKEFOURCC('D', 'X', 'T', '2'),
+    D3DFMT_DXT3                 =  MAKEFOURCC('D', 'X', 'T', '3'),
+    D3DFMT_DXT4                 =  MAKEFOURCC('D', 'X', 'T', '4'),
+    D3DFMT_DXT5                 =  MAKEFOURCC('D', 'X', 'T', '5'),
+    D3DFMT_MULTI2_ARGB          =  MAKEFOURCC('M', 'E', 'T', '1'),
+    D3DFMT_G8R8_G8B8            =  MAKEFOURCC('G', 'R', 'G', 'B'),
+    D3DFMT_R8G8_B8G8            =  MAKEFOURCC('R', 'G', 'B', 'G'),
+
+    D3DFMT_D16_LOCKABLE         =  70,
+    D3DFMT_D32                  =  71,
+    D3DFMT_D15S1                =  73,
+    D3DFMT_D24X8                =  77,
+    D3DFMT_D24X4S4              =  79,
+    D3DFMT_D16                  =  80,
+    D3DFMT_D32F_LOCKABLE        =  82,
+    D3DFMT_D24FS8               =  83,
+
+    D3DFMT_VERTEXDATA           = 100,
+    D3DFMT_INDEX16              = 101,
+    D3DFMT_INDEX32              = 102,
+    D3DFMT_Q16W16V16U16         = 110,
+    /* Flaoting point formats */
+    D3DFMT_R16F                 = 111,
+    D3DFMT_G16R16F              = 112,
+    D3DFMT_A16B16G16R16F        = 113,
+    
+    /* IEEE formats */
+    D3DFMT_R32F                 = 114,
+    D3DFMT_G32R32F              = 115,
+    D3DFMT_A32B32G32R32F        = 116,
+    
+    D3DFMT_CxV8U8               = 117,
+
+
+    D3DFMT_FORCE_DWORD          = 0xFFFFFFFF
+} D3DFORMAT;
+
+typedef enum _D3DLIGHTTYPE {
+    D3DLIGHT_POINT          = 1,
+    D3DLIGHT_SPOT           = 2,
+    D3DLIGHT_DIRECTIONAL    = 3,
+
+    D3DLIGHT_FORCE_DWORD    = 0x7fffffff
+} D3DLIGHTTYPE;
+
+typedef enum _D3DMATERIALCOLORSOURCE {
+    D3DMCS_MATERIAL         = 0,
+    D3DMCS_COLOR1           = 1,
+    D3DMCS_COLOR2           = 2,
+
+    D3DMCS_FORCE_DWORD      = 0x7fffffff
+} D3DMATERIALCOLORSOURCE;
+
+typedef enum _D3DMULTISAMPLE_TYPE {
+    D3DMULTISAMPLE_NONE            =  0,
+    D3DMULTISAMPLE_NONMASKABLE     =  1,
+    D3DMULTISAMPLE_2_SAMPLES       =  2,
+    D3DMULTISAMPLE_3_SAMPLES       =  3,
+    D3DMULTISAMPLE_4_SAMPLES       =  4,
+    D3DMULTISAMPLE_5_SAMPLES       =  5,
+    D3DMULTISAMPLE_6_SAMPLES       =  6,
+    D3DMULTISAMPLE_7_SAMPLES       =  7,
+    D3DMULTISAMPLE_8_SAMPLES       =  8,
+    D3DMULTISAMPLE_9_SAMPLES       =  9,
+    D3DMULTISAMPLE_10_SAMPLES      = 10,
+    D3DMULTISAMPLE_11_SAMPLES      = 11,
+    D3DMULTISAMPLE_12_SAMPLES      = 12,
+    D3DMULTISAMPLE_13_SAMPLES      = 13,
+    D3DMULTISAMPLE_14_SAMPLES      = 14,
+    D3DMULTISAMPLE_15_SAMPLES      = 15,
+    D3DMULTISAMPLE_16_SAMPLES      = 16,
+
+    D3DMULTISAMPLE_FORCE_DWORD     = 0xffffffff
+} D3DMULTISAMPLE_TYPE;
+
+#if 0
+typedef enum _D3DORDERTYPE {
+   D3DORDER_LINEAR      = 1,
+   D3DORDER_QUADRATIC   = 2,
+   D3DORDER_CUBIC       = 3,
+   D3DORDER_QUINTIC     = 5,
+
+   D3DORDER_FORCE_DWORD = 0x7fffffff
+} D3DORDERTYPE;
+#endif
+typedef enum _D3DPATCHEDGESTYLE {
+   D3DPATCHEDGE_DISCRETE    = 0,
+   D3DPATCHEDGE_CONTINUOUS  = 1,
+
+   D3DPATCHEDGE_FORCE_DWORD = 0x7fffffff,
+} D3DPATCHEDGESTYLE;
+
+typedef enum _D3DPOOL {
+    D3DPOOL_DEFAULT                 = 0,
+    D3DPOOL_MANAGED                 = 1,
+    D3DPOOL_SYSTEMMEM               = 2,
+    D3DPOOL_SCRATCH                 = 3,
+
+    D3DPOOL_FORCE_DWORD             = 0x7fffffff
+} D3DPOOL;
+
+typedef enum _D3DPRIMITIVETYPE {
+    D3DPT_POINTLIST             = 1,
+    D3DPT_LINELIST              = 2,
+    D3DPT_LINESTRIP             = 3,
+    D3DPT_TRIANGLELIST          = 4,
+    D3DPT_TRIANGLESTRIP         = 5,
+    D3DPT_TRIANGLEFAN           = 6,
+
+    D3DPT_FORCE_DWORD           = 0x7fffffff
+} D3DPRIMITIVETYPE;
+
+typedef enum _D3DRENDERSTATETYPE {
+    D3DRS_ZENABLE                   =   7,
+    D3DRS_FILLMODE                  =   8,
+    D3DRS_SHADEMODE                 =   9,
+    D3DRS_ZWRITEENABLE              =  14,
+    D3DRS_ALPHATESTENABLE           =  15,
+    D3DRS_LASTPIXEL                 =  16,
+    D3DRS_SRCBLEND                  =  19,
+    D3DRS_DESTBLEND                 =  20,
+    D3DRS_CULLMODE                  =  22,
+    D3DRS_ZFUNC                     =  23,
+    D3DRS_ALPHAREF                  =  24,
+    D3DRS_ALPHAFUNC                 =  25,
+    D3DRS_DITHERENABLE              =  26,
+    D3DRS_ALPHABLENDENABLE          =  27,
+    D3DRS_FOGENABLE                 =  28,
+    D3DRS_SPECULARENABLE            =  29,
+    D3DRS_FOGCOLOR                  =  34,
+    D3DRS_FOGTABLEMODE              =  35,
+    D3DRS_FOGSTART                  =  36,
+    D3DRS_FOGEND                    =  37,
+    D3DRS_FOGDENSITY                =  38,
+    D3DRS_RANGEFOGENABLE            =  48,
+    D3DRS_STENCILENABLE             =  52,
+    D3DRS_STENCILFAIL               =  53,
+    D3DRS_STENCILZFAIL              =  54,
+    D3DRS_STENCILPASS               =  55,
+    D3DRS_STENCILFUNC               =  56,
+    D3DRS_STENCILREF                =  57,
+    D3DRS_STENCILMASK               =  58,
+    D3DRS_STENCILWRITEMASK          =  59,
+    D3DRS_TEXTUREFACTOR             =  60,
+    D3DRS_WRAP0                     = 128,
+    D3DRS_WRAP1                     = 129,
+    D3DRS_WRAP2                     = 130,
+    D3DRS_WRAP3                     = 131,
+    D3DRS_WRAP4                     = 132,
+    D3DRS_WRAP5                     = 133,
+    D3DRS_WRAP6                     = 134,
+    D3DRS_WRAP7                     = 135,
+    D3DRS_CLIPPING                  = 136,
+    D3DRS_LIGHTING                  = 137,
+    D3DRS_AMBIENT                   = 139,
+    D3DRS_FOGVERTEXMODE             = 140,
+    D3DRS_COLORVERTEX               = 141,
+    D3DRS_LOCALVIEWER               = 142,
+    D3DRS_NORMALIZENORMALS          = 143,
+    D3DRS_DIFFUSEMATERIALSOURCE     = 145,
+    D3DRS_SPECULARMATERIALSOURCE    = 146,
+    D3DRS_AMBIENTMATERIALSOURCE     = 147,
+    D3DRS_EMISSIVEMATERIALSOURCE    = 148,
+    D3DRS_VERTEXBLEND               = 151,
+    D3DRS_CLIPPLANEENABLE           = 152,
+    D3DRS_POINTSIZE                 = 154,
+    D3DRS_POINTSIZE_MIN             = 155,
+    D3DRS_POINTSPRITEENABLE         = 156,
+    D3DRS_POINTSCALEENABLE          = 157,
+    D3DRS_POINTSCALE_A              = 158,
+    D3DRS_POINTSCALE_B              = 159,
+    D3DRS_POINTSCALE_C              = 160,
+    D3DRS_MULTISAMPLEANTIALIAS      = 161,
+    D3DRS_MULTISAMPLEMASK           = 162,
+    D3DRS_PATCHEDGESTYLE            = 163,
+    D3DRS_DEBUGMONITORTOKEN         = 165,
+    D3DRS_POINTSIZE_MAX             = 166,
+    D3DRS_INDEXEDVERTEXBLENDENABLE  = 167,
+    D3DRS_COLORWRITEENABLE          = 168,
+    D3DRS_TWEENFACTOR               = 170,
+    D3DRS_BLENDOP                   = 171,
+    D3DRS_POSITIONDEGREE            = 172,
+    D3DRS_NORMALDEGREE              = 173,
+    D3DRS_SCISSORTESTENABLE         = 174,
+    D3DRS_SLOPESCALEDEPTHBIAS       = 175,
+    D3DRS_ANTIALIASEDLINEENABLE     = 176,
+    D3DRS_MINTESSELLATIONLEVEL      = 178,
+    D3DRS_MAXTESSELLATIONLEVEL      = 179,
+    D3DRS_ADAPTIVETESS_X            = 180,
+    D3DRS_ADAPTIVETESS_Y            = 181,
+    D3DRS_ADAPTIVETESS_Z            = 182,
+    D3DRS_ADAPTIVETESS_W            = 183,
+    D3DRS_ENABLEADAPTIVETESSELLATION= 184,
+    D3DRS_TWOSIDEDSTENCILMODE       = 185,
+    D3DRS_CCW_STENCILFAIL           = 186,
+    D3DRS_CCW_STENCILZFAIL          = 187,
+    D3DRS_CCW_STENCILPASS           = 188,
+    D3DRS_CCW_STENCILFUNC           = 189,
+    D3DRS_COLORWRITEENABLE1         = 190,
+    D3DRS_COLORWRITEENABLE2         = 191,
+    D3DRS_COLORWRITEENABLE3         = 192,
+    D3DRS_BLENDFACTOR               = 193,
+    D3DRS_SRGBWRITEENABLE           = 194,
+    D3DRS_DEPTHBIAS                 = 195,
+    D3DRS_WRAP8                     = 198,
+    D3DRS_WRAP9                     = 199,
+    D3DRS_WRAP10                    = 200,
+    D3DRS_WRAP11                    = 201,
+    D3DRS_WRAP12                    = 202,
+    D3DRS_WRAP13                    = 203,
+    D3DRS_WRAP14                    = 204,
+    D3DRS_WRAP15                    = 205,
+    D3DRS_SEPARATEALPHABLENDENABLE  = 206,
+    D3DRS_SRCBLENDALPHA             = 207,
+    D3DRS_DESTBLENDALPHA            = 208,
+    D3DRS_BLENDOPALPHA              = 209,
+
+    D3DRS_FORCE_DWORD               = 0x7fffffff
+} D3DRENDERSTATETYPE;
+
+typedef enum _D3DRESOURCETYPE {
+    D3DRTYPE_SURFACE                =  1,
+    D3DRTYPE_VOLUME                 =  2,
+    D3DRTYPE_TEXTURE                =  3,
+    D3DRTYPE_VOLUMETEXTURE          =  4,
+    D3DRTYPE_CUBETEXTURE            =  5,
+    D3DRTYPE_VERTEXBUFFER           =  6,
+    D3DRTYPE_INDEXBUFFER            =  7,
+
+    D3DRTYPE_FORCE_DWORD            = 0x7fffffff
+} D3DRESOURCETYPE;
+
+#define D3DRTYPECOUNT (D3DRTYPE_INDEXBUFFER+1)
+
+typedef enum _D3DSHADEMODE {
+    D3DSHADE_FLAT               = 1,
+    D3DSHADE_GOURAUD            = 2,
+    D3DSHADE_PHONG              = 3,
+
+    D3DSHADE_FORCE_DWORD        = 0x7fffffff
+} D3DSHADEMODE;
+
+typedef enum _D3DSTATEBLOCKTYPE {
+    D3DSBT_ALL           = 1,
+    D3DSBT_PIXELSTATE    = 2,
+    D3DSBT_VERTEXSTATE   = 3,
+
+    D3DSBT_FORCE_DWORD   = 0xffffffff
+} D3DSTATEBLOCKTYPE;
+
+typedef enum _D3DSTENCILOP {
+    D3DSTENCILOP_KEEP           = 1,
+    D3DSTENCILOP_ZERO           = 2,
+    D3DSTENCILOP_REPLACE        = 3,
+    D3DSTENCILOP_INCRSAT        = 4,
+    D3DSTENCILOP_DECRSAT        = 5,
+    D3DSTENCILOP_INVERT         = 6,
+    D3DSTENCILOP_INCR           = 7,
+    D3DSTENCILOP_DECR           = 8,
+
+    D3DSTENCILOP_FORCE_DWORD    = 0x7fffffff
+} D3DSTENCILOP;
+
+typedef enum _D3DSWAPEFFECT {
+    D3DSWAPEFFECT_DISCARD         = 1,
+    D3DSWAPEFFECT_FLIP            = 2,
+    D3DSWAPEFFECT_COPY            = 3,
+    D3DSWAPEFFECT_FORCE_DWORD     = 0xFFFFFFFF
+} D3DSWAPEFFECT;
+
+typedef enum _D3DTEXTUREADDRESS {
+    D3DTADDRESS_WRAP            = 1,
+    D3DTADDRESS_MIRROR          = 2,
+    D3DTADDRESS_CLAMP           = 3,
+    D3DTADDRESS_BORDER          = 4,
+    D3DTADDRESS_MIRRORONCE      = 5,
+
+    D3DTADDRESS_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTUREADDRESS;
+
+typedef enum _D3DTEXTUREFILTERTYPE {
+    D3DTEXF_NONE            = 0,
+    D3DTEXF_POINT           = 1,
+    D3DTEXF_LINEAR          = 2,
+    D3DTEXF_ANISOTROPIC     = 3,
+    D3DTEXF_FLATCUBIC       = 4,
+    D3DTEXF_GAUSSIANCUBIC   = 5,
+    D3DTEXF_PYRAMIDALQUAD   = 6,
+    D3DTEXF_GAUSSIANQUAD    = 7,
+    D3DTEXF_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTUREFILTERTYPE;
+
+typedef enum _D3DTEXTUREOP {
+    D3DTOP_DISABLE                   =  1,
+    D3DTOP_SELECTARG1                =  2,
+    D3DTOP_SELECTARG2                =  3,
+    D3DTOP_MODULATE                  =  4,
+    D3DTOP_MODULATE2X                =  5,
+    D3DTOP_MODULATE4X                =  6,
+    D3DTOP_ADD                       =  7,
+    D3DTOP_ADDSIGNED                 =  8,
+    D3DTOP_ADDSIGNED2X               =  9,
+    D3DTOP_SUBTRACT                  = 10,
+    D3DTOP_ADDSMOOTH                 = 11,
+    D3DTOP_BLENDDIFFUSEALPHA         = 12,
+    D3DTOP_BLENDTEXTUREALPHA         = 13,
+    D3DTOP_BLENDFACTORALPHA          = 14,
+    D3DTOP_BLENDTEXTUREALPHAPM       = 15,
+    D3DTOP_BLENDCURRENTALPHA         = 16,
+    D3DTOP_PREMODULATE               = 17,
+    D3DTOP_MODULATEALPHA_ADDCOLOR    = 18,
+    D3DTOP_MODULATECOLOR_ADDALPHA    = 19,
+    D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
+    D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
+    D3DTOP_BUMPENVMAP                = 22,
+    D3DTOP_BUMPENVMAPLUMINANCE       = 23,
+    D3DTOP_DOTPRODUCT3               = 24,
+    D3DTOP_MULTIPLYADD               = 25,
+    D3DTOP_LERP                      = 26,
+
+    D3DTOP_FORCE_DWORD               = 0x7fffffff,
+} D3DTEXTUREOP;
+
+typedef enum _D3DTEXTURESTAGESTATETYPE {
+    D3DTSS_COLOROP               =  1,
+    D3DTSS_COLORARG1             =  2,
+    D3DTSS_COLORARG2             =  3,
+    D3DTSS_ALPHAOP               =  4,
+    D3DTSS_ALPHAARG1             =  5,
+    D3DTSS_ALPHAARG2             =  6,
+    D3DTSS_BUMPENVMAT00          =  7,
+    D3DTSS_BUMPENVMAT01          =  8,
+    D3DTSS_BUMPENVMAT10          =  9,
+    D3DTSS_BUMPENVMAT11          = 10,
+    D3DTSS_TEXCOORDINDEX         = 11,
+#if 1 /* TODO: remove once samplerstates are implemented.  */
+    D3DTSS_ADDRESSU              = 13,
+    D3DTSS_ADDRESSV              = 14,
+    D3DTSS_BORDERCOLOR           = 15,
+    D3DTSS_MAGFILTER             = 16,
+    D3DTSS_MINFILTER             = 17,
+    D3DTSS_MIPFILTER             = 18,
+    D3DTSS_MIPMAPLODBIAS         = 19,
+    D3DTSS_MAXMIPLEVEL           = 20,
+    D3DTSS_MAXANISOTROPY         = 21,
+#endif
+    D3DTSS_BUMPENVLSCALE         = 22,
+    D3DTSS_BUMPENVLOFFSET        = 23,
+    D3DTSS_TEXTURETRANSFORMFLAGS = 24,
+    D3DTSS_ADDRESSW              = 25,
+    D3DTSS_COLORARG0             = 26,
+    D3DTSS_ALPHAARG0             = 27,
+    D3DTSS_RESULTARG             = 28,
+    D3DTSS_CONSTANT              = 32,
+
+    D3DTSS_FORCE_DWORD           = 0x7fffffff
+} D3DTEXTURESTAGESTATETYPE;
+
+typedef enum _D3DTEXTURETRANSFORMFLAGS {
+    D3DTTFF_DISABLE         =   0,
+    D3DTTFF_COUNT1          =   1,
+    D3DTTFF_COUNT2          =   2,
+    D3DTTFF_COUNT3          =   3,
+    D3DTTFF_COUNT4          =   4,
+    D3DTTFF_PROJECTED       = 256,
+
+    D3DTTFF_FORCE_DWORD     = 0x7fffffff
+} D3DTEXTURETRANSFORMFLAGS;
+
+typedef enum _D3DTRANSFORMSTATETYPE {
+    D3DTS_VIEW            =  2,
+    D3DTS_PROJECTION      =  3,
+    D3DTS_TEXTURE0        = 16,
+    D3DTS_TEXTURE1        = 17,
+    D3DTS_TEXTURE2        = 18,
+    D3DTS_TEXTURE3        = 19,
+    D3DTS_TEXTURE4        = 20,
+    D3DTS_TEXTURE5        = 21,
+    D3DTS_TEXTURE6        = 22,
+    D3DTS_TEXTURE7        = 23,
+
+    D3DTS_FORCE_DWORD     = 0x7fffffff
+} D3DTRANSFORMSTATETYPE;
+
+typedef enum _D3DVERTEXBLENDFLAGS {
+    D3DVBF_DISABLE  =   0,
+    D3DVBF_1WEIGHTS =   1,
+    D3DVBF_2WEIGHTS =   2,
+    D3DVBF_3WEIGHTS =   3,
+    D3DVBF_TWEENING = 255,
+    D3DVBF_0WEIGHTS = 256
+} D3DVERTEXBLENDFLAGS;
+
+typedef enum _D3DZBUFFERTYPE {
+    D3DZB_FALSE                 = 0,
+    D3DZB_TRUE                  = 1,
+    D3DZB_USEW                  = 2,
+
+    D3DZB_FORCE_DWORD           = 0x7fffffff
+} D3DZBUFFERTYPE;
+
+typedef enum _D3DSAMPLERSTATETYPE {
+    D3DSAMP_ADDRESSU       = 1,
+    D3DSAMP_ADDRESSV       = 2,
+    D3DSAMP_ADDRESSW       = 3,
+    D3DSAMP_BORDERCOLOR    = 4,
+    D3DSAMP_MAGFILTER      = 5,
+    D3DSAMP_MINFILTER      = 6,
+    D3DSAMP_MIPFILTER      = 7,
+    D3DSAMP_MIPMAPLODBIAS  = 8,
+    D3DSAMP_MAXMIPLEVEL    = 9,
+    D3DSAMP_MAXANISOTROPY  = 10,
+    D3DSAMP_SRGBTEXTURE    = 11,
+    D3DSAMP_ELEMENTINDEX   = 12,
+    D3DSAMP_DMAPOFFSET     = 13,
+                                
+    D3DSAMP_FORCE_DWORD   = 0x7fffffff,
+} D3DSAMPLERSTATETYPE;
+
+
+/*****************************************************************************
+ * Direct 3D v9 typedefs
+ */
+typedef DWORD D3DCOLOR;
+
+/*****************************************************************************
+ * Direct 3D v9 structures
+ */
+typedef struct _D3DADAPTER_IDENTIFIER9 {
+    char            Driver[MAX_DEVICE_IDENTIFIER_STRING];
+    char            Description[MAX_DEVICE_IDENTIFIER_STRING];
+    char            DeviceName[32];
+    LARGE_INTEGER   DriverVersion; 
+
+    DWORD           VendorId;
+    DWORD           DeviceId;
+    DWORD           SubSysId;
+    DWORD           Revision;
+
+    GUID            DeviceIdentifier;
+
+    DWORD           WHQLLevel;
+} D3DADAPTER_IDENTIFIER9;
+
+typedef struct _D3DBOX {
+    UINT                Left;
+    UINT                Top;
+    UINT                Right;
+    UINT                Bottom;
+    UINT                Front;
+    UINT                Back;
+} D3DBOX;
+
+typedef struct _D3DCLIPSTATUS9 {
+   DWORD ClipUnion;
+   DWORD ClipIntersection;
+} D3DCLIPSTATUS9;
+
+typedef struct _D3DCOLORVALUE {
+    float r;
+    float g;
+    float b;
+    float a;
+} D3DCOLORVALUE;
+
+typedef struct _D3DDEVICE_CREATION_PARAMETERS {
+    UINT          AdapterOrdinal;
+    D3DDEVTYPE    DeviceType;
+    HWND          hFocusWindow;
+    DWORD         BehaviorFlags;
+} D3DDEVICE_CREATION_PARAMETERS;
+
+typedef struct _D3DDEVINFO_D3D9BANDWIDTHTIMINGS {
+    float         MaxBandwidthUtilized;
+    float         FrontEndUploadMemoryUtilizedPercent;
+    float         VertexRateUtilizedPercent;
+    float         TriangleSetupRateUtilizedPercent;
+    float         FillRateUtilizedPercent;
+} D3DDEVINFO_D3D9BANDWIDTHTIMINGS;
+
+typedef struct _D3DDEVINFO_D3D9CACHEUTILIZATION {
+    float         TextureCacheHitRate;
+    float         PostTransformVertexCacheHitRate;
+} D3DDEVINFO_D3D9CACHEUTILIZATION;
+
+typedef struct _D3DDEVINFO_D3D9INTERFACETIMINGS {
+    float         WaitingForGPUToUseApplicationResourceTimePercent;
+    float         WaitingForGPUToAcceptMoreCommandsTimePercent;
+    float         WaitingForGPUToStayWithinLatencyTimePercent;
+    float         WaitingForGPUExclusiveResourceTimePercent;
+    float         WaitingForGPUOtherTimePercent;
+} D3DDEVINFO_D3D9INTERFACETIMINGS;
+
+typedef struct _D3DDEVINFO_D3D9PIPELINETIMINGS {
+    float         VertexProcessingTimePercent;
+    float         PixelProcessingTimePercent;
+    float         OtherGPUProcessingTimePercent;
+    float         GPUIdleTimePercent;
+} D3DDEVINFO_D3D9PIPELINETIMINGS;
+
+typedef struct _D3DDEVINFO_D3D9STAGETIMINGS {
+    float         MemoryProcessingPercent;
+    float         ComputationProcessingPercent;
+} D3DDEVINFO_D3D9STAGETIMINGS;
+
+
+/* Vertex cache optimization hints. */
+typedef struct D3DDEVINFO_VCACHE {
+    /* Must be a 4 char code FOURCC (e.g. CACH) */
+    DWORD         Pattern; 
+    /* 0 to get the longest  strips, 1 vertex cache */
+    DWORD         OptMethod; 
+     /* Cache size to use (only valid if OptMethod==1) */
+    DWORD         CacheSize;
+    /* internal for deciding when to restart strips, non user modifyable (only valid if OptMethod==1) */
+    DWORD         MagicNumber; 
+} D3DDEVINFO_VCACHE;
+
+typedef struct D3DRESOURCESTATS {
+    BOOL                bThrashing;
+    DWORD               ApproxBytesDownloaded;
+    DWORD               NumEvicts;
+    DWORD               NumVidCreates;
+    DWORD               LastPri;
+    DWORD               NumUsed;
+    DWORD               NumUsedInVidMem;
+    DWORD               WorkingSet;
+    DWORD               WorkingSetBytes;
+    DWORD               TotalManaged;
+    DWORD               TotalBytes;
+} D3DRESOURCESTATS;
+
+typedef struct _D3DDEVINFO_D3DRESOURCEMANAGER {
+    D3DRESOURCESTATS stats[D3DRTYPECOUNT];
+} D3DDEVINFO_D3DRESOURCEMANAGER;
+
+typedef struct _D3DDEVINFO_D3DVERTEXSTATS {
+    DWORD NumRenderedTriangles;
+    DWORD NumExtraClippingTriangles;
+} D3DDEVINFO_D3DVERTEXSTATS;
+
+typedef struct _D3DDISPLAYMODE {
+    UINT            Width;
+    UINT            Height;
+    UINT            RefreshRate;
+    D3DFORMAT       Format;
+} D3DDISPLAYMODE;
+
+typedef struct _D3DGAMMARAMP {
+    WORD                red  [256];
+    WORD                green[256];
+    WORD                blue [256];
+} D3DGAMMARAMP;
+
+typedef struct _D3DINDEXBUFFER_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+} D3DINDEXBUFFER_DESC;
+
+typedef struct _D3DVECTOR {
+    float x;
+    float y;
+    float z;
+} D3DVECTOR;
+
+typedef struct _D3DLIGHT9 {
+    D3DLIGHTTYPE    Type;
+    D3DCOLORVALUE   Diffuse;
+    D3DCOLORVALUE   Specular;
+    D3DCOLORVALUE   Ambient;
+    D3DVECTOR       Position;
+    D3DVECTOR       Direction;
+    float           Range;
+    float           Falloff;
+    float           Attenuation0;
+    float           Attenuation1;
+    float           Attenuation2;
+    float           Theta;
+    float           Phi;
+} D3DLIGHT9;
+
+typedef struct _D3DLINEPATTERN {
+    WORD    wRepeatFactor;
+    WORD    wLinePattern;
+} D3DLINEPATTERN;
+
+typedef struct _D3DLOCKED_BOX {
+    INT                 RowPitch;
+    INT                 SlicePitch;
+    void*               pBits;
+} D3DLOCKED_BOX;
+
+typedef struct _D3DLOCKED_RECT {
+    INT                 Pitch;
+    void*               pBits;
+} D3DLOCKED_RECT;
+
+typedef struct _D3DMATERIAL9 {
+    D3DCOLORVALUE   Diffuse;
+    D3DCOLORVALUE   Ambient;
+    D3DCOLORVALUE   Specular;
+    D3DCOLORVALUE   Emissive;
+    float           Power;
+} D3DMATERIAL9;
+
+typedef struct _D3DMATRIX {
+    union {
+        struct {
+            float        _11, _12, _13, _14;
+            float        _21, _22, _23, _24;
+            float        _31, _32, _33, _34;
+            float        _41, _42, _43, _44;
+        } DUMMYSTRUCTNAME;
+        float m[4][4];
+    } DUMMYUNIONNAME;
+} D3DMATRIX;
+
+typedef struct _D3DPRESENT_PARAMETERS_ {
+    UINT                    BackBufferWidth;
+    UINT                    BackBufferHeight;
+    D3DFORMAT               BackBufferFormat;
+    UINT                    BackBufferCount;
+
+    D3DMULTISAMPLE_TYPE     MultiSampleType;
+    DWORD                   MultiSampleQuality;
+
+    D3DSWAPEFFECT           SwapEffect;
+    HWND                    hDeviceWindow;
+    BOOL                    Windowed;
+    BOOL                    EnableAutoDepthStencil;
+    D3DFORMAT               AutoDepthStencilFormat;
+    DWORD                   Flags;
+
+    UINT                    FullScreen_RefreshRateInHz;
+    UINT                    PresentationInterval;
+
+} D3DPRESENT_PARAMETERS;
+
+typedef struct _D3DRANGE {
+    UINT                Offset;
+    UINT                Size;
+} D3DRANGE;
+
+typedef struct _D3DRASTER_STATUS {
+    BOOL            InVBlank;
+    UINT            ScanLine;
+} D3DRASTER_STATUS;
+
+typedef struct _D3DRECT {
+    LONG x1;
+    LONG y1;
+    LONG x2;
+    LONG y2;
+} D3DRECT;
+
+typedef struct _D3DRECTPATCH_INFO {
+    UINT                StartVertexOffsetWidth;
+    UINT                StartVertexOffsetHeight;
+    UINT                Width;
+    UINT                Height;
+    UINT                Stride;
+    D3DBASISTYPE        Basis;
+    D3DDEGREETYPE       Degree;
+} D3DRECTPATCH_INFO;
+
+typedef struct _D3DSURFACE_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    D3DMULTISAMPLE_TYPE MultiSampleType;
+    DWORD               MultiSampleQuality;
+    UINT                Width;
+    UINT                Height;
+} D3DSURFACE_DESC;
+
+typedef struct _D3DTRIPATCH_INFO {
+    UINT                StartVertexOffset;
+    UINT                NumVertices;
+    D3DBASISTYPE        Basis;
+    D3DDEGREETYPE       Degree;
+} D3DTRIPATCH_INFO;
+
+typedef struct _D3DVERTEXBUFFER_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+    DWORD               FVF;
+} D3DVERTEXBUFFER_DESC;
+
+typedef struct _D3DVIEWPORT9 {
+    DWORD       X;
+    DWORD       Y;
+    DWORD       Width;
+    DWORD       Height;
+    float       MinZ;
+    float       MaxZ;
+} D3DVIEWPORT9;
+
+typedef struct _D3DVOLUME_DESC {
+    D3DFORMAT           Format;
+    D3DRESOURCETYPE     Type;
+    DWORD               Usage;
+    D3DPOOL             Pool;
+    UINT                Size;
+    UINT                Width;
+    UINT                Height;
+    UINT                Depth;
+} D3DVOLUME_DESC;
+
+#endif /* __WINE_D3D9TYPES_H */
diff --git a/reactos/include/d3drm.h b/reactos/include/d3drm.h
new file mode 100644 (file)
index 0000000..142efdf
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2005 Peter Berg Larsen
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __D3DRM_H__
+#define __D3DRM_H__
+
+#include <ddraw.h>
+/* #include <d3drmobj.h> */
+
+#endif /* __D3DRM_H__ */
index f933550..6670e71 100644 (file)
 #ifndef __WINE_D3DTYPES_H
 #define __WINE_D3DTYPES_H
 
+/* #include <windows.h> FIXME: Need to include for compatibility. Inclusion caused compile fail */
+
 #include <float.h>
 #include <ddraw.h>
 
 #define D3DVALP(val, prec)      ((float)(val))
 #define D3DVAL(val)             ((float)(val))
-typedef float D3DVALUE,*LPD3DVALUE;
 #define D3DDivide(a, b)         (float)((double) (a) / (double) (b))
 #define D3DMultiply(a, b)       ((a) * (b))
 
@@ -75,53 +76,16 @@ typedef HRESULT (CALLBACK *LPD3DVALIDATECALLBACK)(LPVOID lpUserArg, DWORD dwOffs
 typedef HRESULT (CALLBACK *LPD3DENUMTEXTUREFORMATSCALLBACK)(LPDDSURFACEDESC lpDdsd, LPVOID lpContext);
 typedef HRESULT (CALLBACK *LPD3DENUMPIXELFORMATSCALLBACK)(LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext);
 
+#ifndef DX_SHARED_DEFINES
+
+typedef float D3DVALUE,*LPD3DVALUE;
+
 #ifndef D3DCOLOR_DEFINED
 typedef DWORD D3DCOLOR, *LPD3DCOLOR;
 #define D3DCOLOR_DEFINED
 #endif
 
-typedef DWORD D3DMATERIALHANDLE, *LPD3DMATERIALHANDLE;
-typedef DWORD D3DTEXTUREHANDLE,  *LPD3DTEXTUREHANDLE;
-typedef DWORD D3DMATRIXHANDLE,   *LPD3DMATRIXHANDLE;
-
-typedef struct _D3DCOLORVALUE {
-        union {
-                D3DVALUE r;
-                D3DVALUE dvR;
-        } DUMMYUNIONNAME1;
-        union {
-                D3DVALUE g;
-                D3DVALUE dvG;
-        } DUMMYUNIONNAME2;
-        union {
-                D3DVALUE b;
-                D3DVALUE dvB;
-        } DUMMYUNIONNAME3;
-        union {
-                D3DVALUE a;
-                D3DVALUE dvA;
-        } DUMMYUNIONNAME4;
-} D3DCOLORVALUE,*LPD3DCOLORVALUE;
-
-typedef struct _D3DRECT {
-  union {
-    LONG x1;
-    LONG lX1;
-  } DUMMYUNIONNAME1;
-  union {
-    LONG y1;
-    LONG lY1;
-  } DUMMYUNIONNAME2;
-  union {
-    LONG x2;
-    LONG lX2;
-  } DUMMYUNIONNAME3;
-  union {
-    LONG y2;
-    LONG lY2;
-  } DUMMYUNIONNAME4;
-} D3DRECT, *LPD3DRECT;
-
+#ifndef D3DVECTOR_DEFINED
 typedef struct _D3DVECTOR {
   union {
         D3DVALUE        x;
@@ -173,6 +137,53 @@ public:
   friend _D3DVECTOR CrossProduct(const _D3DVECTOR& v1, const _D3DVECTOR& v2);
 #endif
 } D3DVECTOR,*LPD3DVECTOR;
+#define D3DVECTOR_DEFINED
+#endif
+
+#define DX_SHARED_DEFINES
+#endif /* DX_SHARED_DEFINES */
+
+typedef DWORD D3DMATERIALHANDLE, *LPD3DMATERIALHANDLE;
+typedef DWORD D3DTEXTUREHANDLE,  *LPD3DTEXTUREHANDLE;
+typedef DWORD D3DMATRIXHANDLE,   *LPD3DMATRIXHANDLE;
+
+typedef struct _D3DCOLORVALUE {
+        union {
+                D3DVALUE r;
+                D3DVALUE dvR;
+        } DUMMYUNIONNAME1;
+        union {
+                D3DVALUE g;
+                D3DVALUE dvG;
+        } DUMMYUNIONNAME2;
+        union {
+                D3DVALUE b;
+                D3DVALUE dvB;
+        } DUMMYUNIONNAME3;
+        union {
+                D3DVALUE a;
+                D3DVALUE dvA;
+        } DUMMYUNIONNAME4;
+} D3DCOLORVALUE,*LPD3DCOLORVALUE;
+
+typedef struct _D3DRECT {
+  union {
+    LONG x1;
+    LONG lX1;
+  } DUMMYUNIONNAME1;
+  union {
+    LONG y1;
+    LONG lY1;
+  } DUMMYUNIONNAME2;
+  union {
+    LONG x2;
+    LONG lX2;
+  } DUMMYUNIONNAME3;
+  union {
+    LONG y2;
+    LONG lY2;
+  } DUMMYUNIONNAME4;
+} D3DRECT, *LPD3DRECT;
 
 typedef struct _D3DHVERTEX {
     DWORD         dwFlags;
@@ -330,7 +341,7 @@ typedef struct _D3DMATRIX {
 } D3DMATRIX, *LPD3DMATRIX;
 
 #if defined(__cplusplus) && defined(D3D_OVERLOADS)
-#include "d3dvec.inl"
+#include <d3dvec.inl>
 #endif
 
 typedef struct _D3DVIEWPORT {
diff --git a/reactos/include/d3dvec.inl b/reactos/include/d3dvec.inl
new file mode 100644 (file)
index 0000000..9b4c53f
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2000 Ove Kaaven
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3DVEC_INL
+#define __WINE_D3DVEC_INL
+
+/*** constructors ***/
+
+inline _D3DVECTOR::_D3DVECTOR(D3DVALUE f)
+{
+  x = y = z = f;
+}
+
+inline _D3DVECTOR::_D3DVECTOR(D3DVALUE _x, D3DVALUE _y, D3DVALUE _z)
+{
+  x = _x; y = _y; z = _z;
+}
+
+/*** assignment operators ***/
+
+inline _D3DVECTOR& _D3DVECTOR::operator += (const _D3DVECTOR& v)
+{
+  x += v.x; y += v.y; z += v.z;
+  return *this;
+}
+
+inline _D3DVECTOR& _D3DVECTOR::operator -= (const _D3DVECTOR& v)
+{
+  x -= v.x; y -= v.y; z -= v.z;
+  return *this;
+}
+
+inline _D3DVECTOR& _D3DVECTOR::operator *= (const _D3DVECTOR& v)
+{
+  x *= v.x; y *= v.y; z *= v.z;
+  return *this;
+}
+
+inline _D3DVECTOR& _D3DVECTOR::operator /= (const _D3DVECTOR& v)
+{
+  x /= v.x; y /= v.y; z /= v.z;
+  return *this;
+}
+
+inline _D3DVECTOR& _D3DVECTOR::operator *= (D3DVALUE s)
+{
+  x *= s; y *= s; z *= s;
+  return *this;
+}
+
+inline _D3DVECTOR& _D3DVECTOR::operator /= (D3DVALUE s)
+{
+  x /= s; y /= s; z /= s;
+  return *this;
+}
+
+/*** unary operators ***/
+
+inline _D3DVECTOR operator + (const _D3DVECTOR& v)
+{
+  return v;
+}
+
+inline _D3DVECTOR operator - (const _D3DVECTOR& v)
+{
+  return _D3DVECTOR(-v.x, -v.y, -v.z);
+}
+
+/*** binary operators ***/
+
+inline _D3DVECTOR operator + (const _D3DVECTOR& v1, const _D3DVECTOR& v2)
+{
+  return _D3DVECTOR(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z);
+}
+
+inline _D3DVECTOR operator - (const _D3DVECTOR& v1, const _D3DVECTOR& v2)
+{
+  return _D3DVECTOR(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z);
+}
+
+inline _D3DVECTOR operator * (const _D3DVECTOR& v, D3DVALUE s)
+{
+  return _D3DVECTOR(v.x*s, v.y*s, v.z*s);
+}
+
+inline _D3DVECTOR operator * (D3DVALUE s, const _D3DVECTOR& v)
+{
+  return _D3DVECTOR(v.x*s, v.y*s, v.z*s);
+}
+
+inline _D3DVECTOR operator / (const _D3DVECTOR& v, D3DVALUE s)
+{
+  return _D3DVECTOR(v.x/s, v.y/s, v.z/s);
+}
+
+inline D3DVALUE SquareMagnitude(const _D3DVECTOR& v)
+{
+  return v.x*v.x + v.y*v.y + v.z*v.z; /* DotProduct(v, v) */
+}
+
+inline D3DVALUE Magnitude(const _D3DVECTOR& v)
+{
+  return sqrt(SquareMagnitude(v));
+}
+
+inline _D3DVECTOR Normalize(const _D3DVECTOR& v)
+{
+  return v / Magnitude(v);
+}
+
+inline D3DVALUE DotProduct(const _D3DVECTOR& v1, const _D3DVECTOR& v2)
+{
+  return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+}
+
+inline _D3DVECTOR CrossProduct(const _D3DVECTOR& v1, const _D3DVECTOR& v2)
+{
+  _D3DVECTOR res;
+  /* this is a left-handed cross product, right? */
+  res.x = v1.y * v2.z - v1.z * v2.y;
+  res.y = v1.z * v2.x - v1.x * v2.z;
+  res.z = v1.x * v2.y - v1.y * v2.x;
+  return res;
+}
+
+#endif
diff --git a/reactos/include/d3dx8core.h b/reactos/include/d3dx8core.h
new file mode 100644 (file)
index 0000000..4d795c2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2002 Raphael Junqueira
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_D3DX8CORE_H
+#define __WINE_D3DX8CORE_H
+
+#include <objbase.h>
+
+#include <d3d8.h>
+#include <d3d8types.h>
+#include <d3d8caps.h>
+
+/*****************************************************************************
+ * #defines and error codes
+ */
+#define D3DXASM_DEBUG           1
+#define D3DXASM_SKIPVALIDATION  2
+
+#define _FACD3D  0x876
+#define MAKE_D3DXHRESULT( code )  MAKE_HRESULT( 1, _FACD3D, code )
+
+/*
+ * Direct3D Errors
+ */
+#define D3DXERR_CANNOTATTRSORT                  MAKE_D3DXHRESULT(2158)
+#define D3DXERR_CANNOTMODIFYINDEXBUFFER         MAKE_D3DXHRESULT(2159)
+#define D3DXERR_INVALIDMESH                     MAKE_D3DXHRESULT(2160)
+#define D3DXERR_SKINNINGNOTSUPPORTED            MAKE_D3DXHRESULT(2161)
+#define D3DXERR_TOOMANYINFLUENCES               MAKE_D3DXHRESULT(2162)
+#define D3DXERR_INVALIDDATA                     MAKE_D3DXHRESULT(2163)
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+DEFINE_GUID(IID_ID3DXBuffer,             0x1,0x1,0x4,0xB0,0xCF,0x98,0xFE,0xFD,0xFF,0x95,0x12);/* FIXME */
+typedef struct ID3DXBuffer              ID3DXBuffer, *LPD3DXBUFFER;
+DEFINE_GUID(IID_ID3DXFont,               0x1,0x1,0x4,0xB0,0xCF,0x98,0xFE,0xFD,0xFF,0x95,0x13);/* FIXME */
+typedef struct ID3DXFont                ID3DXFont, *LPD3DXFONT;
+
+/*****************************************************************************
+ * ID3DXBuffer interface
+ */
+#define INTERFACE ID3DXBuffer
+DECLARE_INTERFACE_(ID3DXBuffer,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** ID3DXBuffer methods ***/
+    STDMETHOD_(LPVOID,GetBufferPointer)(THIS) PURE;
+    STDMETHOD_(DWORD,GetBufferSize)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define ID3DXBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define ID3DXBuffer_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define ID3DXBuffer_Release(p)            (p)->lpVtbl->Release(p)
+/*** ID3DXBuffer methods ***/
+#define ID3DXBuffer_GetBufferPointer(p)   (p)->lpVtbl->GetBufferPointer(p)
+#define ID3DXBuffer_GetBufferSize(p)      (p)->lpVtbl->GetBufferSize(p)
+#endif
+
+/*****************************************************************************
+ * ID3DXFont interface
+ */
+#define INTERFACE ID3DXFont
+DECLARE_INTERFACE_(ID3DXFont,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** ID3DXFont methods ***/
+    STDMETHOD(Begin)(THIS) PURE;
+    STDMETHOD(DrawTextA)(THIS) PURE;
+    STDMETHOD(End)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define ID3DXFont_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define ID3DXFont_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define ID3DXFont_Release(p)            (p)->lpVtbl->Release(p)
+/*** ID3DXFont methods ***/
+#define ID3DXFont_Begin(p)              (p)->lpVtbl->Begin(p)
+#define ID3DXFont_DrawTextA(p,a,b,c,d,e)(p)->lpVtbl->DrawText(p,a,b,c,d,e)
+#define ID3DXFont_End(p)                (p)->lpVtbl->End(p)
+#endif
+
+/*************************************************************************************
+ * Define entrypoints 
+ */
+HRESULT WINAPI D3DXCreateBuffer(DWORD NumBytes, LPD3DXBUFFER* ppBuffer);
+HRESULT WINAPI D3DXCreateFont(LPDIRECT3DDEVICE8 pDevice, HFONT hFont, LPD3DXFONT* ppFont);
+UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF);
+HRESULT WINAPI D3DXAssembleShader(LPCVOID pSrcData, UINT SrcDataLen, DWORD Flags, 
+                          LPD3DXBUFFER* ppConstants, 
+                          LPD3DXBUFFER* ppCompiledShader,
+                          LPD3DXBUFFER* ppCompilationErrors);
+HRESULT WINAPI D3DXAssembleShaderFromFileA(LPSTR pSrcFile, DWORD Flags,
+                                   LPD3DXBUFFER* ppConstants,
+                                   LPD3DXBUFFER* ppCompiledShader,
+                                   LPD3DXBUFFER* ppCompilationErrors);
+HRESULT WINAPI D3DXAssembleShaderFromFileW(LPSTR pSrcFile, DWORD Flags,
+                                   LPD3DXBUFFER* ppConstants,
+                                   LPD3DXBUFFER* ppCompiledShader,
+                                   LPD3DXBUFFER* ppCompilationErrors);
+
+#endif /* __WINE_D3DX8CORE_H */
index a98cc95..71f5667 100644 (file)
@@ -10,7 +10,10 @@ typedef enum _KEY_INFORMATION_CLASS
 {
   KeyBasicInformation,
   KeyNodeInformation,
-  KeyFullInformation
+  KeyFullInformation,
+  KeyNameInformation,
+  KeyCachedInformation,
+  KeyFlagsInformation
 } KEY_INFORMATION_CLASS;
 
 typedef struct _KEY_BASIC_INFORMATION
index 56cc075..3b173ee 100644 (file)
@@ -77,6 +77,27 @@ enum
 #define HIGH_LEVEL     31              // Highest interrupt level
 #define SYNCH_LEVEL    (IPI_LEVEL-1)   // synchronization level
 
+#define WINSTA_ACCESSCLIPBOARD (0x4L)
+#define WINSTA_ACCESSGLOBALATOMS       (0x20L)
+#define WINSTA_CREATEDESKTOP   (0x8L)
+#define WINSTA_ENUMDESKTOPS    (0x1L)
+#define WINSTA_ENUMERATE       (0x100L)
+#define WINSTA_EXITWINDOWS     (0x40L)
+#define WINSTA_READATTRIBUTES  (0x2L)
+#define WINSTA_READSCREEN      (0x200L)
+#define WINSTA_WRITEATTRIBUTES (0x10L)
+
+#define DF_ALLOWOTHERACCOUNTHOOK       (0x1L)
+#define DESKTOP_CREATEMENU     (0x4L)
+#define DESKTOP_CREATEWINDOW   (0x2L)
+#define DESKTOP_ENUMERATE      (0x40L)
+#define DESKTOP_HOOKCONTROL    (0x8L)
+#define DESKTOP_JOURNALPLAYBACK        (0x20L)
+#define DESKTOP_JOURNALRECORD  (0x10L)
+#define DESKTOP_READOBJECTS    (0x1L)
+#define DESKTOP_SWITCHDESKTOP  (0x100L)
+#define DESKTOP_WRITEOBJECTS   (0x80L)
+
 #endif /* __ASM__ */
 
 /* Values returned by KeGetPreviousMode() */
index 4db6f6d..29cfd89 100644 (file)
@@ -30,6 +30,22 @@ typedef enum _WORK_QUEUE_TYPE {
     MaximumWorkQueue
 } WORK_QUEUE_TYPE;
 
+typedef struct _EX_QUEUE_WORKER_INFO {
+    UCHAR QueueDisabled:1;
+    UCHAR MakeThreadsAsNecessary:1;
+    UCHAR WaitMode:1;
+    ULONG WorkerCount:29;
+} EX_QUEUE_WORKER_INFO, *PEX_QUEUE_WORKER_INFO;
+
+typedef struct _EX_WORK_QUEUE {
+    KQUEUE WorkerQueue;
+    ULONG DynamicThreadCount;
+    ULONG WorkItemsProcessed;
+    ULONG WorkItemsProcessedLastPass;
+    ULONG QueueDepthLastPass;
+    EX_QUEUE_WORKER_INFO Info;    
+} EX_WORK_QUEUE, *PEX_WORK_QUEUE;
+
 typedef ULONG_PTR ERESOURCE_THREAD, *PERESOURCE_THREAD;
 
 typedef struct _OWNER_ENTRY
index bca0769..379cfc8 100644 (file)
@@ -886,6 +886,8 @@ struct _FAST_IO_DISPATCH_TABLE
 #endif
 
 #define IO_TYPE_DRIVER 4L
+#define IO_TYPE_FILE 0x0F5L
+
 #define DRVO_UNLOAD_INVOKED 0x1L
 #define DRVO_LEGACY_DRIVER  0x2L
 #define DRVO_BUILTIN_DRIVER 0x4L
index e28a5ba..2559e46 100644 (file)
@@ -42,6 +42,15 @@ VOID STDCALL KeAcquireSpinLock (PKSPIN_LOCK  SpinLock,
 
 #ifndef __USE_W32API
 
+static __inline
+VOID
+KeMemoryBarrier(
+  VOID)
+{
+  volatile LONG Barrier;
+  __asm__ __volatile__ ("xchg %%eax, %0" : : "m" (Barrier) : "%eax");
+}
+
 VOID STDCALL KeAcquireSpinLockAtDpcLevel (IN PKSPIN_LOCK       SpinLock);
 
 #define KefAcquireSpinLockAtDpcLevel KeAcquireSpinLockAtDpcLevel
@@ -720,7 +729,7 @@ KeCapturePersistentThreadState(
 BOOLEAN
 STDCALL
 KeRemoveSystemServiceTable(
-    IN PUCHAR Number
+    IN ULONG TableIndex
 );
 
 NTSTATUS
index ce77b02..b938fc6 100644 (file)
@@ -36,23 +36,34 @@ typedef VOID STDCALL_FUNC
 
 struct _DISPATCHER_HEADER;
 
-typedef enum _KERNEL_OBJECTS {
-       KNotificationEvent = 0,
-       KSynchronizationEvent = 1,
-       KMutant = 2,
-       KProcess = 3,
-       KQueue = 4,
-       KSemaphore = 5,
-       KThread = 6,
-       KNotificationTimer = 8,
-       KSynchronizationTimer = 9,
-       KApc = 18,
-       KDpc = 19,
-       KDeviceQueue = 20,
-       KEventPair = 21,
-       KInterrupt = 22,
-       KProfile = 23
-} KERNEL_OBJECTS;
+typedef enum _KOBJECTS {
+   EventNotificationObject = 0,
+   EventSynchronizationObject = 1,
+   MutantObject = 2,
+   ProcessObject = 3,
+   QueueObject = 4,
+   SemaphoreObject = 5,
+   ThreadObject = 6,
+   GateObject = 7,
+   TimerNotificationObject = 8,
+   TimerSynchronizationObject = 9,
+   Spare2Object = 10,
+   Spare3Object = 11,
+   Spare4Object = 12,
+   Spare5Object = 13,
+   Spare6Object = 14,
+   Spare7Object = 15,
+   Spare8Object = 16,
+   Spare9Object = 17,
+   ApcObject = 18,
+   DpcObject = 19,
+   DeviceQueueObject = 20,
+   EventPairObject = 21,
+   InterruptObject = 22,
+   ProfileObject = 23,
+   ThreadedDpcObject = 24,
+   MaximumKernelObject = 25
+} KOBJECTS;
 
 #include <pshpack1.h>
 
index 64b896f..14e3fc2 100644 (file)
@@ -14,12 +14,12 @@ LdrFindResource_U(IN  PVOID BaseAddress,
                   IN  ULONG Level,
                   OUT PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry);
 
-/*NTSTATUS STDCALL 
+NTSTATUS STDCALL 
 LdrFindResourceDirectory_U(    IN PVOID                                                BaseAddress,
-                                                       IN PLDR_RESOURCE_INFO                   ResourceInfo,
+                     IN PLDR_RESOURCE_INFO  ResourceInfo,
                                                        IN  ULONG                                               Level,
                                                        OUT PIMAGE_RESOURCE_DIRECTORY   *ResourceDirectory);
-*/
+
 NTSTATUS STDCALL
 LdrEnumResources(IN PVOID                                              BaseAddress,
                                 IN PLDR_RESOURCE_INFO                  ResourceInfo,
index bbf635a..6c6ff59 100644 (file)
@@ -279,6 +279,19 @@ MmGetPhysicalMemoryRanges (
        (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) ? \
                ((Mdl)->MappedSystemVa):(MmMapLockedPages((Mdl),KernelMode)))
 
+/*
+ * PVOID
+ * MmGetSystemAddressForMdlSafe(
+ *   IN PMDL  Mdl,
+ *   IN MM_PAGE_PRIORITY  Priority)
+ */
+#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \
+  ((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \
+    | MDL_SOURCE_IS_NONPAGED_POOL)) ? \
+    (_Mdl)->MappedSystemVa : \
+    (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \
+      KernelMode, MmCached, NULL, FALSE, _Priority)
+
 PVOID
 STDCALL
 MmGetSystemRoutineAddress (
@@ -425,6 +438,13 @@ MmMapLockedPages (
        PMDL            MemoryDescriptorList,
        KPROCESSOR_MODE AccessMode
        );
+PVOID STDCALL
+MmMapLockedPagesSpecifyCache ( IN PMDL Mdl,
+                               IN KPROCESSOR_MODE AccessMode,
+                               IN MEMORY_CACHING_TYPE CacheType,
+                               IN PVOID BaseAddress,
+                               IN ULONG BugCheckOnFailure,
+                               IN MM_PAGE_PRIORITY Priority);   
 VOID
 STDCALL
 MmMapMemoryDumpMdl (
index cca162f..574af3e 100644 (file)
@@ -360,7 +360,7 @@ STDCALL PsSetThreadWin32Thread(
 VOID STDCALL
 STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
                          PW32_THREAD_CALLBACK W32ThreadCallback,
-                         PVOID Param3,
+                         PW32_OBJECT_CALLBACK W32ObjectCallback,
                          PVOID Param4,
                          ULONG W32ThreadSize,
                          ULONG W32ProcessSize);
index a1ce54d..7b31e08 100644 (file)
@@ -66,6 +66,40 @@ typedef NTSTATUS STDCALL_FUNC
 typedef NTSTATUS STDCALL_FUNC
 (*PW32_THREAD_CALLBACK)(struct _ETHREAD *Thread,
                        BOOLEAN Create);
+            
+/* 
+ * Callbacks used for Win32 objects... this define won't be needed after the Object Manager
+ * rewrite -- Alex
+ */
+typedef NTSTATUS STDCALL_FUNC
+(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody,
+                         PVOID Parent,
+                         PWSTR RemainingPath,
+                         struct _OBJECT_ATTRIBUTES* ObjectAttributes);
+
+typedef NTSTATUS STDCALL_FUNC
+(*OBJECT_PARSE_ROUTINE)(PVOID Object,
+                        PVOID *NextObject,
+                        PUNICODE_STRING FullPath,
+                        PWSTR *Path,
+                        ULONG Attributes);
+                        
+typedef VOID STDCALL_FUNC
+(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject);
+
+typedef PVOID STDCALL_FUNC
+(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject,
+                       PWSTR Name,
+                       ULONG Attributes);
+                       
+typedef struct _W32_OBJECT_CALLBACK {
+    OBJECT_CREATE_ROUTINE WinStaCreate;
+    OBJECT_PARSE_ROUTINE WinStaParse;
+    OBJECT_DELETE_ROUTINE WinStaDelete;
+    OBJECT_FIND_ROUTINE WinStaFind;
+    OBJECT_CREATE_ROUTINE DesktopCreate;
+    OBJECT_DELETE_ROUTINE DesktopDelete;    
+} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK;
 
 typedef struct _STACK_INFORMATION
 {
index f9890b4..10bdff2 100644 (file)
@@ -98,37 +98,36 @@ typedef struct _SEP_AUDIT_POLICY {
 } SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY;
  
 typedef struct _TOKEN {
-  TOKEN_SOURCE         TokenSource;               /* 0x00 */
-  LUID                         TokenId;                   /* 0x10 */
-  LUID                         AuthenticationId;          /* 0x18 */
-  LUID              ParentTokenId;             /* 0x20 */
-  LARGE_INTEGER                ExpirationTime;            /* 0x28 */
-  struct _ERESOURCE *TokenLock;                /* 0x30 */
-  ULONG             Padding;                   /* 0x34 */
-  SEP_AUDIT_POLICY  AuditPolicy;               /* 0x38 */
-  LUID                         ModifiedId;                /* 0x40 */
-  ULONG             SessionId;                 /* 0x48 */
-  ULONG                                UserAndGroupCount;         /* 0x4C */
-  ULONG             RestrictedSidCount;        /* 0x50 */
-  ULONG                                PrivilegeCount;            /* 0x54 */
-  ULONG                                VariableLength;            /* 0x58 */
-  ULONG                                DynamicCharged;            /* 0x5C */
-  ULONG                                DynamicAvailable;          /* 0x60 */
-  ULONG                                DefaultOwnerIndex;         /* 0x64 */
-  PSID_AND_ATTRIBUTES UserAndGroups;           /* 0x68 */
-  PSID_AND_ATTRIBUTES RestrictedSids;          /* 0x6C */
-  PSID                         PrimaryGroup;              /* 0x70 */
-  PLUID_AND_ATTRIBUTES Privileges;             /* 0x74 */
-  PULONG            DynamicPart;               /* 0x78 */
-  PACL                         DefaultDacl;               /* 0x7C */
-  TOKEN_TYPE           TokenType;                 /* 0x80 */
-  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;  /* 0x84 */
-  ULONG                                TokenFlags;                /* 0x88 */
-  ULONG                            TokenInUse;                /* 0x8C */
-  PVOID                                ProxyData;                 /* 0x90 */
-  PVOID                                AuditData;                 /* 0x94 */
-  LUID              OriginatingLogonSession;   /* 0x98 */
-  UCHAR                                VariablePart[1];           /* 0xA0 */
+  TOKEN_SOURCE TokenSource;                         /* 0x00 */
+  LUID TokenId;                                     /* 0x10 */
+  LUID AuthenticationId;                            /* 0x18 */
+  LUID ParentTokenId;                               /* 0x20 */
+  LARGE_INTEGER ExpirationTime;                     /* 0x28 */
+  struct _ERESOURCE *TokenLock;                     /* 0x30 */
+  SEP_AUDIT_POLICY  AuditPolicy;                    /* 0x38 */
+  LUID ModifiedId;                                  /* 0x40 */
+  ULONG SessionId;                                  /* 0x48 */
+  ULONG UserAndGroupCount;                          /* 0x4C */
+  ULONG RestrictedSidCount;                         /* 0x50 */
+  ULONG PrivilegeCount;                             /* 0x54 */
+  ULONG VariableLength;                             /* 0x58 */
+  ULONG DynamicCharged;                             /* 0x5C */
+  ULONG DynamicAvailable;                           /* 0x60 */
+  ULONG DefaultOwnerIndex;                          /* 0x64 */
+  PSID_AND_ATTRIBUTES UserAndGroups;                /* 0x68 */
+  PSID_AND_ATTRIBUTES RestrictedSids;               /* 0x6C */
+  PSID PrimaryGroup;                                /* 0x70 */
+  PLUID_AND_ATTRIBUTES Privileges;                  /* 0x74 */
+  PULONG DynamicPart;                               /* 0x78 */
+  PACL DefaultDacl;                                 /* 0x7C */
+  TOKEN_TYPE TokenType;                             /* 0x80 */
+  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;  /* 0x84 */
+  ULONG TokenFlags;                                 /* 0x88 */
+  BOOLEAN TokenInUse;                               /* 0x8C */
+  PVOID ProxyData;                                  /* 0x90 */
+  PVOID AuditData;                                  /* 0x94 */
+  LUID OriginatingLogonSession;                     /* 0x98 */
+  ULONG VariablePart;                               /* 0xA0 */
 } TOKEN, *PTOKEN;
 
 typedef PVOID PACCESS_TOKEN;
index 2f68e62..77fd562 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#ifndef __WINE_WINDEF_H
+#define __WINE_WINDEF_H
+
+/* Macros to map Winelib names to the correct implementation name */
+
+#if defined(__WINESRC__) || defined(__REACTOS__)
+# define WINELIB_NAME_AW(func) \
+    func##_must_be_suffixed_with_W_or_A_in_this_context \
+    func##_must_be_suffixed_with_W_or_A_in_this_context
+#else  /* __WINESRC__  || __REACTOS__*/
+# ifdef UNICODE
+#  define WINELIB_NAME_AW(func) func##W
+# else
+#  define WINELIB_NAME_AW(func) func##A
+# endif  /* UNICODE */
+#endif  /* __WINESRC__ */
+
+#if defined(__WINESRC__) || defined(__REACTOS__)
+# define DECL_WINELIB_TYPE_AW(type)  /* nothing */
+#else   /* __WINESRC__ */
+# define DECL_WINELIB_TYPE_AW(type)  typedef WINELIB_NAME_AW(type) type;
+#endif  /* __WINESRC__ */
+
+#endif /* __WINE_WINDEF_H */
 
 #ifndef __WINE_DDRAW_H
 #define __WINE_DDRAW_H
 
-#include <windows.h> /* LARGE_INTEGER ... */
+#include <objbase.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* defined(__cplusplus) */
 
+#ifndef        DIRECTDRAW_VERSION
+#define        DIRECTDRAW_VERSION      0x0700
+#endif /* DIRECTDRAW_VERSION */
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+#ifndef __DDRAW_GUID_DEFINED__
+DEFINE_GUID( CLSID_DirectDraw,         0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 );
+DEFINE_GUID( CLSID_DirectDraw7,         0x3C305196,0x50DB,0x11D3,0x9C,0xFE,0x00,0xC0,0x4F,0xD9,0x30,0xC5 );
+DEFINE_GUID( CLSID_DirectDrawClipper,  0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 );
+DEFINE_GUID( IID_IDirectDraw,          0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDraw2,         0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );
+DEFINE_GUID( IID_IDirectDraw4,          0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );
+DEFINE_GUID( IID_IDirectDraw7,          0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b );
+DEFINE_GUID( IID_IDirectDrawSurface,   0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawSurface2,  0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 );
+DEFINE_GUID( IID_IDirectDrawSurface3,  0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB );
+DEFINE_GUID( IID_IDirectDrawSurface4,   0x0B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B );
+DEFINE_GUID( IID_IDirectDrawSurface7,   0x06675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b );
+DEFINE_GUID( IID_IDirectDrawPalette,   0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawClipper,   0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 );
+DEFINE_GUID( IID_IDirectDrawGammaControl,0x69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E );
+#endif
+
+typedef struct IDirectDraw *LPDIRECTDRAW;
+typedef struct IDirectDraw2 *LPDIRECTDRAW2;
+typedef struct IDirectDraw4 *LPDIRECTDRAW4;
+typedef struct IDirectDraw7 *LPDIRECTDRAW7;
+typedef struct IDirectDrawClipper *LPDIRECTDRAWCLIPPER;
+typedef struct IDirectDrawPalette *LPDIRECTDRAWPALETTE;
+typedef struct IDirectDrawSurface *LPDIRECTDRAWSURFACE;
+typedef struct IDirectDrawSurface2 *LPDIRECTDRAWSURFACE2;
+typedef struct IDirectDrawSurface3 *LPDIRECTDRAWSURFACE3;
+typedef struct IDirectDrawSurface4 *LPDIRECTDRAWSURFACE4;
+typedef struct IDirectDrawSurface7 *LPDIRECTDRAWSURFACE7;
+typedef struct IDirectDrawColorControl *LPDIRECTDRAWCOLORCONTROL;
+typedef struct IDirectDrawGammaControl *LPDIRECTDRAWGAMMACONTROL;
+
+
 #define DDENUMRET_CANCEL       0
 #define DDENUMRET_OK           1
 
 #define DD_OK                  0
 
+
 #define _FACDD         0x876
 #define MAKE_DDHRESULT( code )  MAKE_HRESULT( 1, _FACDD, code )
 
@@ -328,10 +394,9 @@ typedef struct _DDSCAPSEX {
        DWORD   dwCaps3; /* reserved capabilities */
        DWORD   dwCaps4; /* more reserved capabilities */
 } DDSCAPSEX,*LPDDSCAPSEX;
-
 #define        DD_ROP_SPACE    (256/32)        /* space required to store ROP array */
 
-typedef struct DDCAPS_DX7              /* DirectX 7 version of caps struct */
+typedef struct _DDCAPS_DX7             /* DirectX 7 version of caps struct */
 {
     DWORD      dwSize;                 /* size of the DDDRIVERCAPS structure */
     DWORD      dwCaps;                 /* driver specific capabilities */
@@ -392,7 +457,196 @@ typedef struct DDCAPS_DX7         /* DirectX 7 version of caps struct */
     DDSCAPS2    ddsCaps;               /* surface capabilities */
 } DDCAPS_DX7,*LPDDCAPS_DX7;
 
+typedef struct _DDCAPS_DX6             /* DirectX 6 version of caps struct */
+{
+    DWORD      dwSize;                 /* size of the DDDRIVERCAPS structure */
+    DWORD      dwCaps;                 /* driver specific capabilities */
+    DWORD      dwCaps2;                /* more driver specific capabilites */
+    DWORD      dwCKeyCaps;             /* color key capabilities of the surface */
+    DWORD      dwFXCaps;               /* driver specific stretching and effects capabilites */
+    DWORD      dwFXAlphaCaps;          /* alpha driver specific capabilities */
+    DWORD      dwPalCaps;              /* palette capabilities */
+    DWORD      dwSVCaps;               /* stereo vision capabilities */
+    DWORD      dwAlphaBltConstBitDepths;       /* DDBD_2,4,8 */
+    DWORD      dwAlphaBltPixelBitDepths;       /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaBltSurfaceBitDepths;     /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlayConstBitDepths;   /* DDBD_2,4,8 */
+    DWORD      dwAlphaOverlayPixelBitDepths;   /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+    DWORD      dwZBufferBitDepths;             /* DDBD_8,16,24,32 */
+    DWORD      dwVidMemTotal;          /* total amount of video memory */
+    DWORD      dwVidMemFree;           /* amount of free video memory */
+    DWORD      dwMaxVisibleOverlays;   /* maximum number of visible overlays */
+    DWORD      dwCurrVisibleOverlays;  /* current number of visible overlays */
+    DWORD      dwNumFourCCCodes;       /* number of four cc codes */
+    DWORD      dwAlignBoundarySrc;     /* source rectangle alignment */
+    DWORD      dwAlignSizeSrc;         /* source rectangle byte size */
+    DWORD      dwAlignBoundaryDest;    /* dest rectangle alignment */
+    DWORD      dwAlignSizeDest;        /* dest rectangle byte size */
+    DWORD      dwAlignStrideAlign;     /* stride alignment */
+    DWORD      dwRops[DD_ROP_SPACE];   /* ROPS supported */
+    DDSCAPS    ddsOldCaps;             /* old DDSCAPS - superseded for DirectX6+ */
+    DWORD      dwMinOverlayStretch;    /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxOverlayStretch;    /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinLiveVideoStretch;  /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxLiveVideoStretch;  /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinHwCodecStretch;    /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxHwCodecStretch;    /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwReserved1;
+    DWORD      dwReserved2;
+    DWORD      dwReserved3;
+    DWORD      dwSVBCaps;              /* driver specific capabilities for System->Vmem blts */
+    DWORD      dwSVBCKeyCaps;          /* driver color key capabilities for System->Vmem blts */
+    DWORD      dwSVBFXCaps;            /* driver FX capabilities for System->Vmem blts */
+    DWORD      dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+    DWORD      dwVSBCaps;              /* driver specific capabilities for Vmem->System blts */
+    DWORD      dwVSBCKeyCaps;          /* driver color key capabilities for Vmem->System blts */
+    DWORD      dwVSBFXCaps;            /* driver FX capabilities for Vmem->System blts */
+    DWORD      dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+    DWORD      dwSSBCaps;              /* driver specific capabilities for System->System blts */
+    DWORD      dwSSBCKeyCaps;          /* driver color key capabilities for System->System blts */
+    DWORD      dwSSBFXCaps;            /* driver FX capabilities for System->System blts */
+    DWORD      dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+    DWORD       dwMaxVideoPorts;        /* maximum number of usable video ports */
+    DWORD      dwCurrVideoPorts;       /* current number of video ports used */
+    DWORD      dwSVBCaps2;             /* more driver specific capabilities for System->Vmem blts */
+    DWORD      dwNLVBCaps;             /* driver specific capabilities for non-local->local vidmem blts */
+    DWORD      dwNLVBCaps2;            /* more driver specific capabilities non-local->local vidmem blts */
+    DWORD      dwNLVBCKeyCaps;         /* driver color key capabilities for non-local->local vidmem blts */
+    DWORD      dwNLVBFXCaps;           /* driver FX capabilities for non-local->local blts */
+    DWORD      dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */
+    /* and one new member for DirectX 6 */
+    DDSCAPS2    ddsCaps;               /* surface capabilities */
+} DDCAPS_DX6,*LPDDCAPS_DX6;
+
+typedef struct _DDCAPS_DX5             /* DirectX5 version of caps struct */
+{
+    DWORD      dwSize;                 /* size of the DDDRIVERCAPS structure */
+    DWORD      dwCaps;                 /* driver specific capabilities */
+    DWORD      dwCaps2;                /* more driver specific capabilites */
+    DWORD      dwCKeyCaps;             /* color key capabilities of the surface */
+    DWORD      dwFXCaps;               /* driver specific stretching and effects capabilites */
+    DWORD      dwFXAlphaCaps;          /* alpha driver specific capabilities */
+    DWORD      dwPalCaps;              /* palette capabilities */
+    DWORD      dwSVCaps;               /* stereo vision capabilities */
+    DWORD      dwAlphaBltConstBitDepths;       /* DDBD_2,4,8 */
+    DWORD      dwAlphaBltPixelBitDepths;       /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaBltSurfaceBitDepths;     /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlayConstBitDepths;   /* DDBD_2,4,8 */
+    DWORD      dwAlphaOverlayPixelBitDepths;   /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+    DWORD      dwZBufferBitDepths;             /* DDBD_8,16,24,32 */
+    DWORD      dwVidMemTotal;          /* total amount of video memory */
+    DWORD      dwVidMemFree;           /* amount of free video memory */
+    DWORD      dwMaxVisibleOverlays;   /* maximum number of visible overlays */
+    DWORD      dwCurrVisibleOverlays;  /* current number of visible overlays */
+    DWORD      dwNumFourCCCodes;       /* number of four cc codes */
+    DWORD      dwAlignBoundarySrc;     /* source rectangle alignment */
+    DWORD      dwAlignSizeSrc;         /* source rectangle byte size */
+    DWORD      dwAlignBoundaryDest;    /* dest rectangle alignment */
+    DWORD      dwAlignSizeDest;        /* dest rectangle byte size */
+    DWORD      dwAlignStrideAlign;     /* stride alignment */
+    DWORD      dwRops[DD_ROP_SPACE];   /* ROPS supported */
+    DDSCAPS    ddsCaps;                /* DDSCAPS structure has all the general capabilities */
+    DWORD      dwMinOverlayStretch;    /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxOverlayStretch;    /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinLiveVideoStretch;  /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxLiveVideoStretch;  /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinHwCodecStretch;    /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxHwCodecStretch;    /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwReserved1;
+    DWORD      dwReserved2;
+    DWORD      dwReserved3;
+    DWORD      dwSVBCaps;              /* driver specific capabilities for System->Vmem blts */
+    DWORD      dwSVBCKeyCaps;          /* driver color key capabilities for System->Vmem blts */
+    DWORD      dwSVBFXCaps;            /* driver FX capabilities for System->Vmem blts */
+    DWORD      dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+    DWORD      dwVSBCaps;              /* driver specific capabilities for Vmem->System blts */
+    DWORD      dwVSBCKeyCaps;          /* driver color key capabilities for Vmem->System blts */
+    DWORD      dwVSBFXCaps;            /* driver FX capabilities for Vmem->System blts */
+    DWORD      dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+    DWORD      dwSSBCaps;              /* driver specific capabilities for System->System blts */
+    DWORD      dwSSBCKeyCaps;          /* driver color key capabilities for System->System blts */
+    DWORD      dwSSBFXCaps;            /* driver FX capabilities for System->System blts */
+    DWORD      dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+    /* the following are the new DirectX 5 members */
+    DWORD       dwMaxVideoPorts;        /* maximum number of usable video ports */
+    DWORD      dwCurrVideoPorts;       /* current number of video ports used */
+    DWORD      dwSVBCaps2;             /* more driver specific capabilities for System->Vmem blts */
+    DWORD      dwNLVBCaps;             /* driver specific capabilities for non-local->local vidmem blts */
+    DWORD      dwNLVBCaps2;            /* more driver specific capabilities non-local->local vidmem blts */
+    DWORD      dwNLVBCKeyCaps;         /* driver color key capabilities for non-local->local vidmem blts */
+    DWORD      dwNLVBFXCaps;           /* driver FX capabilities for non-local->local blts */
+    DWORD      dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */
+} DDCAPS_DX5,*LPDDCAPS_DX5;
+
+typedef struct _DDCAPS_DX3             /* DirectX3 version of caps struct */
+{
+    DWORD      dwSize;                 /* size of the DDDRIVERCAPS structure */
+    DWORD      dwCaps;                 /* driver specific capabilities */
+    DWORD      dwCaps2;                /* more driver specific capabilites */
+    DWORD      dwCKeyCaps;             /* color key capabilities of the surface */
+    DWORD      dwFXCaps;               /* driver specific stretching and effects capabilites */
+    DWORD      dwFXAlphaCaps;          /* alpha driver specific capabilities */
+    DWORD      dwPalCaps;              /* palette capabilities */
+    DWORD      dwSVCaps;               /* stereo vision capabilities */
+    DWORD      dwAlphaBltConstBitDepths;       /* DDBD_2,4,8 */
+    DWORD      dwAlphaBltPixelBitDepths;       /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaBltSurfaceBitDepths;     /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlayConstBitDepths;   /* DDBD_2,4,8 */
+    DWORD      dwAlphaOverlayPixelBitDepths;   /* DDBD_1,2,4,8 */
+    DWORD      dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+    DWORD      dwZBufferBitDepths;             /* DDBD_8,16,24,32 */
+    DWORD      dwVidMemTotal;          /* total amount of video memory */
+    DWORD      dwVidMemFree;           /* amount of free video memory */
+    DWORD      dwMaxVisibleOverlays;   /* maximum number of visible overlays */
+    DWORD      dwCurrVisibleOverlays;  /* current number of visible overlays */
+    DWORD      dwNumFourCCCodes;       /* number of four cc codes */
+    DWORD      dwAlignBoundarySrc;     /* source rectangle alignment */
+    DWORD      dwAlignSizeSrc;         /* source rectangle byte size */
+    DWORD      dwAlignBoundaryDest;    /* dest rectangle alignment */
+    DWORD      dwAlignSizeDest;        /* dest rectangle byte size */
+    DWORD      dwAlignStrideAlign;     /* stride alignment */
+    DWORD      dwRops[DD_ROP_SPACE];   /* ROPS supported */
+    DDSCAPS    ddsCaps;                /* DDSCAPS structure has all the general capabilities */
+    DWORD      dwMinOverlayStretch;    /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxOverlayStretch;    /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinLiveVideoStretch;  /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxLiveVideoStretch;  /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMinHwCodecStretch;    /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwMaxHwCodecStretch;    /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+    DWORD      dwReserved1;
+    DWORD      dwReserved2;
+    DWORD      dwReserved3;
+    DWORD      dwSVBCaps;              /* driver specific capabilities for System->Vmem blts */
+    DWORD      dwSVBCKeyCaps;          /* driver color key capabilities for System->Vmem blts */
+    DWORD      dwSVBFXCaps;            /* driver FX capabilities for System->Vmem blts */
+    DWORD      dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+    DWORD      dwVSBCaps;              /* driver specific capabilities for Vmem->System blts */
+    DWORD      dwVSBCKeyCaps;          /* driver color key capabilities for Vmem->System blts */
+    DWORD      dwVSBFXCaps;            /* driver FX capabilities for Vmem->System blts */
+    DWORD      dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+    DWORD      dwSSBCaps;              /* driver specific capabilities for System->System blts */
+    DWORD      dwSSBCKeyCaps;          /* driver color key capabilities for System->System blts */
+    DWORD      dwSSBFXCaps;            /* driver FX capabilities for System->System blts */
+    DWORD      dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+    DWORD      dwReserved4;
+    DWORD      dwReserved5;
+    DWORD      dwReserved6;
+} DDCAPS_DX3,*LPDDCAPS_DX3;
+
+/* set caps struct according to DIRECTDRAW_VERSION */
+
+#if DIRECTDRAW_VERSION <= 0x300
+typedef DDCAPS_DX3 DDCAPS;
+#elif DIRECTDRAW_VERSION <= 0x500
+typedef DDCAPS_DX5 DDCAPS;
+#elif DIRECTDRAW_VERSION <= 0x600
+typedef DDCAPS_DX6 DDCAPS;
+#else
 typedef DDCAPS_DX7 DDCAPS;
+#endif
+
 typedef DDCAPS *LPDDCAPS;
 
 /* DDCAPS.dwCaps */
@@ -815,6 +1069,28 @@ typedef struct {
        WORD    blue[256];
 } DDGAMMARAMP,*LPDDGAMMARAMP;
 
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID);
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKW)(GUID *, LPWSTR, LPWSTR, LPVOID);
+DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK)
+
+typedef HRESULT (CALLBACK *LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMMODESCALLBACK2)(LPDDSURFACEDESC2, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK2)(LPDIRECTDRAWSURFACE4, LPDDSURFACEDESC2, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK7)(LPDIRECTDRAWSURFACE7, LPDDSURFACEDESC2, LPVOID);
+
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKEXA)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR);
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKEXW)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR);
+DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACKEX)
+
+HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags);
+#define DirectDrawEnumerateEx WINELIB_NAME_AW(DirectDrawEnumerateEx)
+
+typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEXA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEXW)( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags);
+DECL_WINELIB_TYPE_AW(LPDIRECTDRAWENUMERATEEX)
+
 /* flags for DirectDrawEnumerateEx */
 #define DDENUM_ATTACHEDSECONDARYDEVICES        0x00000001
 #define DDENUM_DETACHEDSECONDARYDEVICES        0x00000002
@@ -824,28 +1100,6 @@ typedef struct {
 #define DDCREATE_HARDWAREONLY  1L
 #define DDCREATE_EMULATIONONLY 2L
 
-/* dwDDFX */
-/* arithmetic stretching along y axis */
-#define DDBLTFX_ARITHSTRETCHY                  0x00000001
-/* mirror on y axis */
-#define DDBLTFX_MIRRORLEFTRIGHT                        0x00000002
-/* mirror on x axis */
-#define DDBLTFX_MIRRORUPDOWN                   0x00000004
-/* do not tear */
-#define DDBLTFX_NOTEARING                      0x00000008
-/* 180 degrees clockwise rotation */
-#define DDBLTFX_ROTATE180                      0x00000010
-/* 270 degrees clockwise rotation */
-#define DDBLTFX_ROTATE270                      0x00000020
-/* 90 degrees clockwise rotation */
-#define DDBLTFX_ROTATE90                       0x00000040
-/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */
-#define DDBLTFX_ZBUFFERRANGE                   0x00000080
-/* add dwZBufferBaseDest to every source z value before compare */
-#define DDBLTFX_ZBUFFERBASEDEST                        0x00000100
-
-typedef DWORD IDirectDrawSurface; /* FIXME: implement proper definition */
-typedef IDirectDrawSurface *LPDIRECTDRAWSURFACE;
 typedef struct _DDBLTFX
 {
     DWORD       dwSize;                         /* size of structure */
@@ -894,6 +1148,27 @@ typedef struct _DDBLTFX
     DDCOLORKEY  ddckDestColorkey;               /* DestColorkey override */
     DDCOLORKEY  ddckSrcColorkey;                /* SrcColorkey override */
 } DDBLTFX,*LPDDBLTFX;
+
+/* dwDDFX */
+/* arithmetic stretching along y axis */
+#define DDBLTFX_ARITHSTRETCHY                  0x00000001
+/* mirror on y axis */
+#define DDBLTFX_MIRRORLEFTRIGHT                        0x00000002
+/* mirror on x axis */
+#define DDBLTFX_MIRRORUPDOWN                   0x00000004
+/* do not tear */
+#define DDBLTFX_NOTEARING                      0x00000008
+/* 180 degrees clockwise rotation */
+#define DDBLTFX_ROTATE180                      0x00000010
+/* 270 degrees clockwise rotation */
+#define DDBLTFX_ROTATE270                      0x00000020
+/* 90 degrees clockwise rotation */
+#define DDBLTFX_ROTATE90                       0x00000040
+/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */
+#define DDBLTFX_ZBUFFERRANGE                   0x00000080
+/* add dwZBufferBaseDest to every source z value before compare */
+#define DDBLTFX_ZBUFFERBASEDEST                        0x00000100
+
 typedef struct _DDOVERLAYFX
 {
     DWORD       dwSize;                         /* size of structure */
@@ -929,6 +1204,8 @@ typedef struct _DDBLTBATCH
 
 #define MAX_DDDEVICEID_STRING          512
 
+#define DDGDI_GETHOSTIDENTIFIER 1
+
 typedef struct tagDDDEVICEIDENTIFIER {
   char    szDriver[MAX_DDDEVICEID_STRING];
   char    szDescription[MAX_DDDEVICEID_STRING];
@@ -952,8 +1229,1367 @@ typedef struct tagDDDEVICEIDENTIFIER2 {
   DWORD   dwWHQLLevel;                         /* Windows Hardware Quality Lab certification level */
 } DDDEVICEIDENTIFIER2, * LPDDDEVICEIDENTIFIER2;
 
+/*****************************************************************************
+ * IDirectDrawPalette interface
+ */
+#define INTERFACE IDirectDrawPalette
+DECLARE_INTERFACE_(IDirectDrawPalette,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawPalette methods ***/
+    STDMETHOD(GetCaps)(THIS_ LPDWORD lpdwCaps) PURE;
+    STDMETHOD(GetEntries)(THIS_ DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) PURE;
+    STDMETHOD(SetEntries)(THIS_ DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawPalette_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawPalette_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawPalette_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawPalette methods ***/
+#define IDirectDrawPalette_GetCaps(p,a)          (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawPalette_GetEntries(p,a,b,c,d) (p)->lpVtbl->GetEntries(p,a,b,c,d)
+#define IDirectDrawPalette_Initialize(p,a,b,c)   (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirectDrawPalette_SetEntries(p,a,b,c,d) (p)->lpVtbl->SetEntries(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawPalette_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawPalette_AddRef(p)             (p)->AddRef()
+#define IDirectDrawPalette_Release(p)            (p)->Release()
+/*** IDirectDrawPalette methods ***/
+#define IDirectDrawPalette_GetCaps(p,a)          (p)->GetCaps(a)
+#define IDirectDrawPalette_GetEntries(p,a,b,c,d) (p)->GetEntries(a,b,c,d)
+#define IDirectDrawPalette_Initialize(p,a,b,c)   (p)->Initialize(a,b,c)
+#define IDirectDrawPalette_SetEntries(p,a,b,c,d) (p)->SetEntries(a,b,c,d)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawClipper interface
+ */
+#define INTERFACE IDirectDrawClipper
+DECLARE_INTERFACE_(IDirectDrawClipper,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawClipper methods ***/
+    STDMETHOD(GetClipList)(THIS_ LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) PURE;
+    STDMETHOD(GetHWnd)(THIS_ HWND *lphWnd) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags) PURE;
+    STDMETHOD(IsClipListChanged)(THIS_ BOOL *lpbChanged) PURE;
+    STDMETHOD(SetClipList)(THIS_ LPRGNDATA lpClipList, DWORD dwFlags) PURE;
+    STDMETHOD(SetHWnd)(THIS_ DWORD dwFlags, HWND hWnd) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawClipper_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawClipper_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawClipper_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawClipper methods ***/
+#define IDirectDrawClipper_GetClipList(p,a,b,c)   (p)->lpVtbl->GetClipList(p,a,b,c)
+#define IDirectDrawClipper_GetHWnd(p,a)           (p)->lpVtbl->GetHWnd(p,a)
+#define IDirectDrawClipper_Initialize(p,a,b)      (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawClipper_IsClipListChanged(p,a) (p)->lpVtbl->IsClipListChanged(p,a)
+#define IDirectDrawClipper_SetClipList(p,a,b)     (p)->lpVtbl->SetClipList(p,a,b)
+#define IDirectDrawClipper_SetHWnd(p,a,b)         (p)->lpVtbl->SetHWnd(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawClipper_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawClipper_AddRef(p)             (p)->AddRef()
+#define IDirectDrawClipper_Release(p)            (p)->Release()
+/*** IDirectDrawClipper methods ***/
+#define IDirectDrawClipper_GetClipList(p,a,b,c)   (p)->GetClipList(a,b,c)
+#define IDirectDrawClipper_GetHWnd(p,a)           (p)->GetHWnd(a)
+#define IDirectDrawClipper_Initialize(p,a,b)      (p)->Initialize(a,b)
+#define IDirectDrawClipper_IsClipListChanged(p,a) (p)->IsClipListChanged(a)
+#define IDirectDrawClipper_SetClipList(p,a,b)     (p)->SetClipList(a,b)
+#define IDirectDrawClipper_SetHWnd(p,a,b)         (p)->SetHWnd(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw interface
+ */
+#define INTERFACE IDirectDraw
+DECLARE_INTERFACE_(IDirectDraw,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDraw methods ***/
+    STDMETHOD(Compact)(THIS) PURE;
+    STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+    STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface) PURE;
+    STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE;
+    STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+    STDMETHOD(FlipToGDISurface)(THIS) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+    STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+    STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+    STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE *lplpGDIDDSurface) PURE;
+    STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+    STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+    STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+    STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+    STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+    STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) PURE;
+    STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDraw_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw_Compact(p)                  (p)->lpVtbl->Compact(p)
+#define IDirectDraw_CreateClipper(p,a,b,c)      (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw_CreatePalette(p,a,b,c,d)    (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw_CreateSurface(p,a,b,c)      (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw_DuplicateSurface(p,a,b)     (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw_EnumSurfaces(p,a,b,c,d)     (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw_FlipToGDISurface(p)         (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw_GetCaps(p,a,b)              (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw_GetDisplayMode(p,a)         (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw_GetFourCCCodes(p,a,b)       (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw_GetGDISurface(p,a)          (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw_GetMonitorFrequency(p,a)    (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw_GetScanLine(p,a)            (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw_Initialize(p,a)             (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw_RestoreDisplayMode(p)       (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw_SetCooperativeLevel(p,a,b)  (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw_SetDisplayMode(p,a,b,c)     (p)->lpVtbl->SetDisplayMode(p,a,b,c)
+#define IDirectDraw_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw_AddRef(p)             (p)->AddRef()
+#define IDirectDraw_Release(p)            (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw_Compact(p)                  (p)->Compact()
+#define IDirectDraw_CreateClipper(p,a,b,c)      (p)->CreateClipper(a,b,c)
+#define IDirectDraw_CreatePalette(p,a,b,c,d)    (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw_CreateSurface(p,a,b,c)      (p)->CreateSurface(a,b,c)
+#define IDirectDraw_DuplicateSurface(p,a,b)     (p)->DuplicateSurface(a,b)
+#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw_EnumSurfaces(p,a,b,c,d)     (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw_FlipToGDISurface(p)         (p)->FlipToGDISurface()
+#define IDirectDraw_GetCaps(p,a,b)              (p)->GetCaps(a,b)
+#define IDirectDraw_GetDisplayMode(p,a)         (p)->GetDisplayMode(a)
+#define IDirectDraw_GetFourCCCodes(p,a,b)       (p)->GetFourCCCodes(a,b)
+#define IDirectDraw_GetGDISurface(p,a)          (p)->GetGDISurface(a)
+#define IDirectDraw_GetMonitorFrequency(p,a)    (p)->GetMonitorFrequency(a)
+#define IDirectDraw_GetScanLine(p,a)            (p)->GetScanLine(a)
+#define IDirectDraw_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw_Initialize(p,a)             (p)->Initialize(a)
+#define IDirectDraw_RestoreDisplayMode(p)       (p)->RestoreDisplayMode()
+#define IDirectDraw_SetCooperativeLevel(p,a,b)  (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw_SetDisplayMode(p,a,b,c)     (p)->SetDisplayMode(a,b,c)
+#define IDirectDraw_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+#endif
+
+
+/* flags for Lock() */
+#define DDLOCK_SURFACEMEMORYPTR        0x00000000
+#define DDLOCK_WAIT            0x00000001
+#define DDLOCK_EVENT           0x00000002
+#define DDLOCK_READONLY                0x00000010
+#define DDLOCK_WRITEONLY       0x00000020
+#define DDLOCK_NOSYSLOCK       0x00000800
+#define DDLOCK_NOOVERWRITE      0x00001000
+#define DDLOCK_DISCARDCONTENTS  0x00002000
+
+
+/*****************************************************************************
+ * IDirectDraw2 interface
+ */
+/* Note: IDirectDraw2 cannot derive from IDirectDraw because the number of
+ * arguments of SetDisplayMode has changed !
+ */
+#define INTERFACE IDirectDraw2
+DECLARE_INTERFACE_(IDirectDraw2,IUnknown)
+{
+          /*** IUnknown methods ***/
+/*00*/    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/    STDMETHOD_(ULONG,Release)(THIS) PURE;
+          /*** IDirectDraw2 methods ***/
+/*0c*/    STDMETHOD(Compact)(THIS) PURE;
+/*10*/    STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/    STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/    STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/    STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface) PURE;
+/*20*/    STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE;
+/*24*/    STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+/*28*/    STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/    STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/    STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*34*/    STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/    STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE *lplpGDIDDSurface) PURE;
+/*3c*/    STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/    STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/    STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/    STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/    STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/    STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/    STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/    STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+          /* added in v2 */
+/*5c*/    STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDraw2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw2_Compact(p)                  (p)->lpVtbl->Compact(p)
+#define IDirectDraw2_CreateClipper(p,a,b,c)      (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw2_CreatePalette(p,a,b,c,d)    (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw2_CreateSurface(p,a,b,c)      (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw2_DuplicateSurface(p,a,b)     (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw2_EnumSurfaces(p,a,b,c,d)     (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw2_FlipToGDISurface(p)         (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw2_GetCaps(p,a,b)              (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw2_GetDisplayMode(p,a)         (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw2_GetFourCCCodes(p,a,b)       (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw2_GetGDISurface(p,a)          (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw2_GetMonitorFrequency(p,a)    (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw2_GetScanLine(p,a)            (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw2_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw2_Initialize(p,a)             (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw2_RestoreDisplayMode(p)       (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw2_SetCooperativeLevel(p,a,b)  (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw2_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw2_AddRef(p)             (p)->AddRef()
+#define IDirectDraw2_Release(p)            (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw2_Compact(p)                  (p)->Compact()
+#define IDirectDraw2_CreateClipper(p,a,b,c)      (p)->CreateClipper(a,b,c)
+#define IDirectDraw2_CreatePalette(p,a,b,c,d)    (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw2_CreateSurface(p,a,b,c)      (p)->CreateSurface(a,b,c)
+#define IDirectDraw2_DuplicateSurface(p,a,b)     (p)->DuplicateSurface(a,b)
+#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw2_EnumSurfaces(p,a,b,c,d)     (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw2_FlipToGDISurface(p)         (p)->FlipToGDISurface()
+#define IDirectDraw2_GetCaps(p,a,b)              (p)->GetCaps(a,b)
+#define IDirectDraw2_GetDisplayMode(p,a)         (p)->GetDisplayMode(a)
+#define IDirectDraw2_GetFourCCCodes(p,a,b)       (p)->GetFourCCCodes(a,b)
+#define IDirectDraw2_GetGDISurface(p,a)          (p)->GetGDISurface(a)
+#define IDirectDraw2_GetMonitorFrequency(p,a)    (p)->GetMonitorFrequency(a)
+#define IDirectDraw2_GetScanLine(p,a)            (p)->GetScanLine(a)
+#define IDirectDraw2_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw2_Initialize(p,a)             (p)->Initialize(a)
+#define IDirectDraw2_RestoreDisplayMode(p)       (p)->RestoreDisplayMode()
+#define IDirectDraw2_SetCooperativeLevel(p,a,b)  (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw2_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw4 interface
+ */
+#define INTERFACE IDirectDraw4
+DECLARE_INTERFACE_(IDirectDraw4,IUnknown)
+{
+          /*** IUnknown methods ***/
+/*00*/    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/    STDMETHOD_(ULONG,Release)(THIS) PURE;
+          /*** IDirectDraw4 methods ***/
+/*0c*/    STDMETHOD(Compact)(THIS) PURE;
+/*10*/    STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/    STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/    STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4 *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/    STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurface, LPDIRECTDRAWSURFACE4 *lplpDupDDSurface) PURE;
+/*20*/    STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE;
+/*24*/    STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK2 lpEnumSurfacesCallback) PURE;
+/*28*/    STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/    STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/    STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+/*34*/    STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/    STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE4 *lplpGDIDDSurface) PURE;
+/*3c*/    STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/    STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/    STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/    STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/    STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/    STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/    STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/    STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+          /* added in v2 */
+/*5c*/    STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+          /* added in v4 */
+/*60*/    STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE4 *pSurf) PURE;
+/*64*/    STDMETHOD(RestoreAllSurfaces)(THIS) PURE;
+/*68*/    STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+/*6c*/    STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw4_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw4_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDraw4_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw4_Compact(p)                  (p)->lpVtbl->Compact(p)
+#define IDirectDraw4_CreateClipper(p,a,b,c)      (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw4_CreatePalette(p,a,b,c,d)    (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw4_CreateSurface(p,a,b,c)      (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw4_DuplicateSurface(p,a,b)     (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw4_EnumSurfaces(p,a,b,c,d)     (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw4_FlipToGDISurface(p)         (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw4_GetCaps(p,a,b)              (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw4_GetDisplayMode(p,a)         (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw4_GetFourCCCodes(p,a,b)       (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw4_GetGDISurface(p,a)          (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw4_GetMonitorFrequency(p,a)    (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw4_GetScanLine(p,a)            (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw4_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw4_Initialize(p,a)             (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw4_RestoreDisplayMode(p)       (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw4_SetCooperativeLevel(p,a,b)  (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw4_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+/*** IDirectDraw4 methods ***/
+#define IDirectDraw4_GetSurfaceFromDC(p,a,b)    (p)->lpVtbl->GetSurfaceFromDC(p,a,b)
+#define IDirectDraw4_RestoreAllSurfaces(pc)     (p)->lpVtbl->RestoreAllSurfaces(p)
+#define IDirectDraw4_TestCooperativeLevel(p)    (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirectDraw4_GetDeviceIdentifier(p,a,b) (p)->lpVtbl->GetDeviceIdentifier(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw4_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw4_AddRef(p)             (p)->AddRef()
+#define IDirectDraw4_Release(p)            (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw4_Compact(p)                  (p)->Compact()
+#define IDirectDraw4_CreateClipper(p,a,b,c)      (p)->CreateClipper(a,b,c)
+#define IDirectDraw4_CreatePalette(p,a,b,c,d)    (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw4_CreateSurface(p,a,b,c)      (p)->CreateSurface(a,b,c)
+#define IDirectDraw4_DuplicateSurface(p,a,b)     (p)->DuplicateSurface(a,b)
+#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw4_EnumSurfaces(p,a,b,c,d)     (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw4_FlipToGDISurface(p)         (p)->FlipToGDISurface()
+#define IDirectDraw4_GetCaps(p,a,b)              (p)->GetCaps(a,b)
+#define IDirectDraw4_GetDisplayMode(p,a)         (p)->GetDisplayMode(a)
+#define IDirectDraw4_GetFourCCCodes(p,a,b)       (p)->GetFourCCCodes(a,b)
+#define IDirectDraw4_GetGDISurface(p,a)          (p)->GetGDISurface(a)
+#define IDirectDraw4_GetMonitorFrequency(p,a)    (p)->GetMonitorFrequency(a)
+#define IDirectDraw4_GetScanLine(p,a)            (p)->GetScanLine(a)
+#define IDirectDraw4_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw4_Initialize(p,a)             (p)->Initialize(a)
+#define IDirectDraw4_RestoreDisplayMode(p)       (p)->RestoreDisplayMode()
+#define IDirectDraw4_SetCooperativeLevel(p,a,b)  (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw4_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+/*** IDirectDraw4 methods ***/
+#define IDirectDraw4_GetSurfaceFromDC(p,a,b)    (p)->GetSurfaceFromDC(a,b)
+#define IDirectDraw4_RestoreAllSurfaces(pc)     (p)->RestoreAllSurfaces()
+#define IDirectDraw4_TestCooperativeLevel(p)    (p)->TestCooperativeLevel()
+#define IDirectDraw4_GetDeviceIdentifier(p,a,b) (p)->GetDeviceIdentifier(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw7 interface
+ */
+/* Note: IDirectDraw7 cannot derive from IDirectDraw4; it is even documented
+ * as not interchangeable with earlier DirectDraw interfaces.
+ */
+#define INTERFACE IDirectDraw7
+DECLARE_INTERFACE_(IDirectDraw7,IUnknown)
+{
+          /*** IUnknown methods ***/
+/*00*/    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/    STDMETHOD_(ULONG,Release)(THIS) PURE;
+          /*** IDirectDraw7 methods ***/
+/*0c*/    STDMETHOD(Compact)(THIS) PURE;
+/*10*/    STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/    STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/    STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7 *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/    STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurface, LPDIRECTDRAWSURFACE7 *lplpDupDDSurface) PURE;
+/*20*/    STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE;
+/*24*/    STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE;
+/*28*/    STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/    STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/    STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+/*34*/    STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/    STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE7 *lplpGDIDDSurface) PURE;
+/*3c*/    STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/    STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/    STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/    STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/    STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/    STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/    STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/    STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+          /* added in v2 */
+/*5c*/    STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+          /* added in v4 */
+/*60*/    STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE7 *pSurf) PURE;
+/*64*/    STDMETHOD(RestoreAllSurfaces)(THIS) PURE;
+/*68*/    STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+/*6c*/    STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags) PURE;
+          /* added in v7 */
+/*70*/    STDMETHOD(StartModeTest)(THIS_ LPSIZE pModes, DWORD dwNumModes, DWORD dwFlags) PURE;
+/*74*/    STDMETHOD(EvaluateMode)(THIS_ DWORD dwFlags, DWORD  *pTimeout) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw7_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDraw7_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw7_Compact(p)                  (p)->lpVtbl->Compact(p)
+#define IDirectDraw7_CreateClipper(p,a,b,c)      (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw7_CreatePalette(p,a,b,c,d)    (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw7_CreateSurface(p,a,b,c)      (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw7_DuplicateSurface(p,a,b)     (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw7_EnumSurfaces(p,a,b,c,d)     (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw7_FlipToGDISurface(p)         (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw7_GetCaps(p,a,b)              (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw7_GetDisplayMode(p,a)         (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw7_GetFourCCCodes(p,a,b)       (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw7_GetGDISurface(p,a)          (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw7_GetMonitorFrequency(p,a)    (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw7_GetScanLine(p,a)            (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw7_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw7_Initialize(p,a)             (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw7_RestoreDisplayMode(p)       (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw7_SetCooperativeLevel(p,a,b)  (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw7_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** added in IDirectDraw2 ***/
+#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+/*** added in IDirectDraw4 ***/
+#define IDirectDraw7_GetSurfaceFromDC(p,a,b)    (p)->lpVtbl->GetSurfaceFromDC(p,a,b)
+#define IDirectDraw7_RestoreAllSurfaces(p)     (p)->lpVtbl->RestoreAllSurfaces(p)
+#define IDirectDraw7_TestCooperativeLevel(p)    (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirectDraw7_GetDeviceIdentifier(p,a,b) (p)->lpVtbl->GetDeviceIdentifier(p,a,b)
+/*** added in IDirectDraw 7 ***/
+#define IDirectDraw7_StartModeTest(p,a,b,c)     (p)->lpVtbl->StartModeTest(p,a,b,c)
+#define IDirectDraw7_EvaluateMode(p,a,b)        (p)->lpVtbl->EvaluateMode(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw7_AddRef(p)             (p)->AddRef()
+#define IDirectDraw7_Release(p)            (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw7_Compact(p)                  (p)->Compact()
+#define IDirectDraw7_CreateClipper(p,a,b,c)      (p)->CreateClipper(a,b,c)
+#define IDirectDraw7_CreatePalette(p,a,b,c,d)    (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw7_CreateSurface(p,a,b,c)      (p)->CreateSurface(a,b,c)
+#define IDirectDraw7_DuplicateSurface(p,a,b)     (p)->DuplicateSurface(a,b)
+#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw7_EnumSurfaces(p,a,b,c,d)     (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw7_FlipToGDISurface(p)         (p)->FlipToGDISurface()
+#define IDirectDraw7_GetCaps(p,a,b)              (p)->GetCaps(a,b)
+#define IDirectDraw7_GetDisplayMode(p,a)         (p)->GetDisplayMode(a)
+#define IDirectDraw7_GetFourCCCodes(p,a,b)       (p)->GetFourCCCodes(a,b)
+#define IDirectDraw7_GetGDISurface(p,a)          (p)->GetGDISurface(a)
+#define IDirectDraw7_GetMonitorFrequency(p,a)    (p)->GetMonitorFrequency(a)
+#define IDirectDraw7_GetScanLine(p,a)            (p)->GetScanLine(a)
+#define IDirectDraw7_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw7_Initialize(p,a)             (p)->Initialize(a)
+#define IDirectDraw7_RestoreDisplayMode(p)       (p)->RestoreDisplayMode()
+#define IDirectDraw7_SetCooperativeLevel(p,a,b)  (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw7_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** added in IDirectDraw2 ***/
+#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+/*** added in IDirectDraw4 ***/
+#define IDirectDraw7_GetSurfaceFromDC(p,a,b)    (p)->GetSurfaceFromDC(a,b)
+#define IDirectDraw7_RestoreAllSurfaces(p)     (p)->RestoreAllSurfaces()
+#define IDirectDraw7_TestCooperativeLevel(p)    (p)->TestCooperativeLevel()
+#define IDirectDraw7_GetDeviceIdentifier(p,a,b) (p)->GetDeviceIdentifier(a,b)
+/*** added in IDirectDraw 7 ***/
+#define IDirectDraw7_StartModeTest(p,a,b,c)     (p)->StartModeTest(a,b,c)
+#define IDirectDraw7_EvaluateMode(p,a,b)        (p)->EvaluateMode(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface interface
+ */
+#define INTERFACE IDirectDrawSurface
+DECLARE_INTERFACE_(IDirectDrawSurface,IUnknown)
+{
+          /*** IUnknown methods ***/
+/*00*/    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/    STDMETHOD_(ULONG,Release)(THIS) PURE;
+          /*** IDirectDrawSurface methods ***/
+/*0c*/    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE;
+/*10*/    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+/*14*/    STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+/*18*/    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+/*1c*/    STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+/*20*/    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE;
+/*24*/    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+/*28*/    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+/*2c*/    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+/*30*/    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE *lplpDDAttachedSurface) PURE;
+/*34*/    STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+/*38*/    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+/*3c*/    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+/*40*/    STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+/*44*/    STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+/*48*/    STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+/*4c*/    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+/*50*/    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+/*54*/    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+/*58*/    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*5c*/    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*60*/    STDMETHOD(IsLost)(THIS) PURE;
+/*64*/    STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+/*68*/    STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+/*6c*/    STDMETHOD(Restore)(THIS) PURE;
+/*70*/    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+/*74*/    STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+/*78*/    STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+/*7c*/    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+/*80*/    STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+/*84*/    STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+/*88*/    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+/*8c*/    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods ***/
+#define IDirectDrawSurface_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface_GetCaps(p,a)                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface_IsLost(p)                    (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface_Restore(p)                   (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface_Unlock(p,a)                  (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface_AddRef(p)             (p)->AddRef()
+#define IDirectDrawSurface_Release(p)            (p)->Release()
+/*** IDirectDrawSurface methods ***/
+#define IDirectDrawSurface_AddAttachedSurface(p,a)      (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface_AddOverlayDirtyRect(p,a)     (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface_Blt(p,a,b,c,d,e)             (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface_BltBatch(p,a,b,c)            (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface_BltFast(p,a,b,c,d,e)         (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b)  (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c)  (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface_Flip(p,a,b)                  (p)->Flip(a,b)
+#define IDirectDrawSurface_GetAttachedSurface(p,a,b)    (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface_GetBltStatus(p,a)            (p)->GetBltStatus(a)
+#define IDirectDrawSurface_GetCaps(p,a)                 (p)->GetCaps(a)
+#define IDirectDrawSurface_GetClipper(p,a)              (p)->GetClipper(a)
+#define IDirectDrawSurface_GetColorKey(p,a,b)           (p)->GetColorKey(a,b)
+#define IDirectDrawSurface_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirectDrawSurface_GetFlipStatus(p,a)           (p)->GetFlipStatus(a)
+#define IDirectDrawSurface_GetOverlayPosition(p,a,b)    (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface_GetPalette(p,a)              (p)->GetPalette(a)
+#define IDirectDrawSurface_GetPixelFormat(p,a)          (p)->GetPixelFormat(a)
+#define IDirectDrawSurface_GetSurfaceDesc(p,a)          (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface_Initialize(p,a,b)            (p)->Initialize(a,b)
+#define IDirectDrawSurface_IsLost(p)                    (p)->IsLost()
+#define IDirectDrawSurface_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#define IDirectDrawSurface_Restore(p)                   (p)->Restore()
+#define IDirectDrawSurface_SetClipper(p,a)              (p)->SetClipper(a)
+#define IDirectDrawSurface_SetColorKey(p,a,b)           (p)->SetColorKey(a,b)
+#define IDirectDrawSurface_SetOverlayPosition(p,a,b)    (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface_SetPalette(p,a)              (p)->SetPalette(a)
+#define IDirectDrawSurface_Unlock(p,a)                  (p)->Unlock(a)
+#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e)   (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface_UpdateOverlayDisplay(p,a)    (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b)   (p)->UpdateOverlayZOrder(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface2 interface
+ */
+/* Cannot inherit from IDirectDrawSurface because the LPDIRECTDRAWSURFACE parameters
+ * have been converted to LPDIRECTDRAWSURFACE2.
+ */
+#define INTERFACE IDirectDrawSurface2
+DECLARE_INTERFACE_(IDirectDrawSurface2,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawSurface2 methods ***/
+    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE;
+    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+    STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+    STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE;
+    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2 *lplpDDAttachedSurface) PURE;
+    STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+    STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+    STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+    STDMETHOD(IsLost)(THIS) PURE;
+    STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+    STDMETHOD(Restore)(THIS) PURE;
+    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+    STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+    STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+    STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE2 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSReference) PURE;
+    /* added in v2 */
+    STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+    STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface2_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface2_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface2_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface2_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface2_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface2_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface2_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface2_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface2_GetCaps(p,a)                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface2_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface2_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface2_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface2_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface2_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface2_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface2_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface2_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface2_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface2_IsLost(p)                    (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface2_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface2_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface2_Restore(p)                   (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface2_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface2_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface2_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface2_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface2_Unlock(p,a)                  (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface2_PageLock(p,a)       (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface2_PageUnlock(p,a)     (p)->lpVtbl->PageUnlock(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface2_AddRef(p)             (p)->AddRef()
+#define IDirectDrawSurface2_Release(p)            (p)->Release()
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface2_AddAttachedSurface(p,a)      (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a)     (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface2_Blt(p,a,b,c,d,e)             (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface2_BltBatch(p,a,b,c)            (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e)         (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b)  (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c)  (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface2_Flip(p,a,b)                  (p)->Flip(a,b)
+#define IDirectDrawSurface2_GetAttachedSurface(p,a,b)    (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface2_GetBltStatus(p,a)            (p)->GetBltStatus(a)
+#define IDirectDrawSurface2_GetCaps(p,a)                 (p)->GetCaps(a)
+#define IDirectDrawSurface2_GetClipper(p,a)              (p)->GetClipper(a)
+#define IDirectDrawSurface2_GetColorKey(p,a,b)           (p)->GetColorKey(a,b)
+#define IDirectDrawSurface2_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirectDrawSurface2_GetFlipStatus(p,a)           (p)->GetFlipStatus(a)
+#define IDirectDrawSurface2_GetOverlayPosition(p,a,b)    (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface2_GetPalette(p,a)              (p)->GetPalette(a)
+#define IDirectDrawSurface2_GetPixelFormat(p,a)          (p)->GetPixelFormat(a)
+#define IDirectDrawSurface2_GetSurfaceDesc(p,a)          (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface2_Initialize(p,a,b)            (p)->Initialize(a,b)
+#define IDirectDrawSurface2_IsLost(p)                    (p)->IsLost()
+#define IDirectDrawSurface2_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface2_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#define IDirectDrawSurface2_Restore(p)                   (p)->Restore()
+#define IDirectDrawSurface2_SetClipper(p,a)              (p)->SetClipper(a)
+#define IDirectDrawSurface2_SetColorKey(p,a,b)           (p)->SetColorKey(a,b)
+#define IDirectDrawSurface2_SetOverlayPosition(p,a,b)    (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface2_SetPalette(p,a)              (p)->SetPalette(a)
+#define IDirectDrawSurface2_Unlock(p,a)                  (p)->Unlock(a)
+#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e)   (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a)    (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b)   (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface2_PageLock(p,a)       (p)->PageLock(a)
+#define IDirectDrawSurface2_PageUnlock(p,a)     (p)->PageUnlock(a)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface3 interface
+ */
+/* Cannot inherit from IDirectDrawSurface2 because the LPDIRECTDRAWSURFACE2 parameters
+ * have been converted to LPDIRECTDRAWSURFACE3.
+ */
+#define INTERFACE IDirectDrawSurface3
+DECLARE_INTERFACE_(IDirectDrawSurface3,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawSurface3 methods ***/
+    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE;
+    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+    STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+    STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE;
+    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3 *lplpDDAttachedSurface) PURE;
+    STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+    STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+    STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+    STDMETHOD(IsLost)(THIS) PURE;
+    STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+    STDMETHOD(Restore)(THIS) PURE;
+    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+    STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+    STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+    STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE3 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSReference) PURE;
+    /* added in v2 */
+    STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+    STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+    /* added in v3 */
+    STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface3_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface3_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface3_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface3_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface3_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface3_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface3_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface3_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface3_GetCaps(p,a)                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface3_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface3_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface3_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface3_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface3_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface3_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface3_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface3_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface3_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface3_IsLost(p)                    (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface3_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface3_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface3_Restore(p)                   (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface3_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface3_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface3_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface3_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface3_Unlock(p,a)                  (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface3_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface3_PageLock(p,a)       (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface3_PageUnlock(p,a)     (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface3_AddRef(p)             (p)->AddRef()
+#define IDirectDrawSurface3_Release(p)            (p)->Release()
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface3_AddAttachedSurface(p,a)      (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a)     (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface3_Blt(p,a,b,c,d,e)             (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface3_BltBatch(p,a,b,c)            (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e)         (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b)  (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c)  (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface3_Flip(p,a,b)                  (p)->Flip(a,b)
+#define IDirectDrawSurface3_GetAttachedSurface(p,a,b)    (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface3_GetBltStatus(p,a)            (p)->GetBltStatus(a)
+#define IDirectDrawSurface3_GetCaps(p,a)                 (p)->GetCaps(a)
+#define IDirectDrawSurface3_GetClipper(p,a)              (p)->GetClipper(a)
+#define IDirectDrawSurface3_GetColorKey(p,a,b)           (p)->GetColorKey(a,b)
+#define IDirectDrawSurface3_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirectDrawSurface3_GetFlipStatus(p,a)           (p)->GetFlipStatus(a)
+#define IDirectDrawSurface3_GetOverlayPosition(p,a,b)    (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface3_GetPalette(p,a)              (p)->GetPalette(a)
+#define IDirectDrawSurface3_GetPixelFormat(p,a)          (p)->GetPixelFormat(a)
+#define IDirectDrawSurface3_GetSurfaceDesc(p,a)          (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface3_Initialize(p,a,b)            (p)->Initialize(a,b)
+#define IDirectDrawSurface3_IsLost(p)                    (p)->IsLost()
+#define IDirectDrawSurface3_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface3_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#define IDirectDrawSurface3_Restore(p)                   (p)->Restore()
+#define IDirectDrawSurface3_SetClipper(p,a)              (p)->SetClipper(a)
+#define IDirectDrawSurface3_SetColorKey(p,a,b)           (p)->SetColorKey(a,b)
+#define IDirectDrawSurface3_SetOverlayPosition(p,a,b)    (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface3_SetPalette(p,a)              (p)->SetPalette(a)
+#define IDirectDrawSurface3_Unlock(p,a)                  (p)->Unlock(a)
+#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e)   (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a)    (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b)   (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface3_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface3_PageLock(p,a)       (p)->PageLock(a)
+#define IDirectDrawSurface3_PageUnlock(p,a)     (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface4 interface
+ */
+/* Cannot inherit from IDirectDrawSurface2 because DDSCAPS changed to DDSCAPS2.
+ */
+#define INTERFACE IDirectDrawSurface4
+DECLARE_INTERFACE_(IDirectDrawSurface4,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawSurface4 methods ***/
+    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE;
+    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+    STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+    STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE;
+    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4 *lplpDDAttachedSurface) PURE;
+    STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE;
+    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+    STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+    STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+    STDMETHOD(IsLost)(THIS) PURE;
+    STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+    STDMETHOD(Restore)(THIS) PURE;
+    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+    STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+    STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE;
+    STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSReference) PURE;
+    /* added in v2 */
+    STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+    STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+    /* added in v3 */
+    STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE;
+    /* added in v4 */
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID tag, LPVOID pData, DWORD cbSize, DWORD dwFlags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID tag, LPVOID pBuffer, LPDWORD pcbBufferSize) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID tag) PURE;
+    STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD pValue) PURE;
+    STDMETHOD(ChangeUniquenessValue)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface4_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface4_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface4_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface4_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface4_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface4_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface4_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface4_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface4_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface4_GetCaps(p,a)                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface4_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface4_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface4_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface4_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface4_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface4_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface4_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface4_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface4_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface4_IsLost(p)                    (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface4_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface4_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface4_Restore(p)                   (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface4_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface4_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface4_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface4_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface4_Unlock(p,a)                  (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface4_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface4_PageLock(p,a)       (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface4_PageUnlock(p,a)     (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirectDrawSurface4_GetPrivateData(p,a,b,c)   (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirectDrawSurface4_FreePrivateData(p,a)      (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirectDrawSurface4_GetUniquenessValue(p,a)   (p)->lpVtbl->GetUniquenessValue(p,a)
+#define IDirectDrawSurface4_ChangeUniquenessValue(p)  (p)->lpVtbl->ChangeUniquenessValue(p)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface4_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface4_AddRef(p)             (p)->AddRef()
+#define IDirectDrawSurface4_Release(p)            (p)->Release()
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface4_AddAttachedSurface(p,a)      (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a)     (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface4_Blt(p,a,b,c,d,e)             (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface4_BltBatch(p,a,b,c)            (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e)         (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b)  (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c)  (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface4_Flip(p,a,b)                  (p)->Flip(a,b)
+#define IDirectDrawSurface4_GetAttachedSurface(p,a,b)    (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface4_GetBltStatus(p,a)            (p)->GetBltStatus(a)
+#define IDirectDrawSurface4_GetCaps(p,a)                 (p)->GetCaps(a)
+#define IDirectDrawSurface4_GetClipper(p,a)              (p)->GetClipper(a)
+#define IDirectDrawSurface4_GetColorKey(p,a,b)           (p)->GetColorKey(a,b)
+#define IDirectDrawSurface4_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirectDrawSurface4_GetFlipStatus(p,a)           (p)->GetFlipStatus(a)
+#define IDirectDrawSurface4_GetOverlayPosition(p,a,b)    (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface4_GetPalette(p,a)              (p)->GetPalette(a)
+#define IDirectDrawSurface4_GetPixelFormat(p,a)          (p)->GetPixelFormat(a)
+#define IDirectDrawSurface4_GetSurfaceDesc(p,a)          (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface4_Initialize(p,a,b)            (p)->Initialize(a,b)
+#define IDirectDrawSurface4_IsLost(p)                    (p)->IsLost()
+#define IDirectDrawSurface4_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface4_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#define IDirectDrawSurface4_Restore(p)                   (p)->Restore()
+#define IDirectDrawSurface4_SetClipper(p,a)              (p)->SetClipper(a)
+#define IDirectDrawSurface4_SetColorKey(p,a,b)           (p)->SetColorKey(a,b)
+#define IDirectDrawSurface4_SetOverlayPosition(p,a,b)    (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface4_SetPalette(p,a)              (p)->SetPalette(a)
+#define IDirectDrawSurface4_Unlock(p,a)                  (p)->Unlock(a)
+#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e)   (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a)    (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b)   (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface4_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface4_PageLock(p,a)       (p)->PageLock(a)
+#define IDirectDrawSurface4_PageUnlock(p,a)     (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirectDrawSurface4_GetPrivateData(p,a,b,c)   (p)->GetPrivateData(a,b,c)
+#define IDirectDrawSurface4_FreePrivateData(p,a)      (p)->FreePrivateData(a)
+#define IDirectDrawSurface4_GetUniquenessValue(p,a)   (p)->GetUniquenessValue(a)
+#define IDirectDrawSurface4_ChangeUniquenessValue(p)  (p)->ChangeUniquenessValue()
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface7 interface
+ */
+#define INTERFACE IDirectDrawSurface7
+DECLARE_INTERFACE_(IDirectDrawSurface7,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawSurface7 methods ***/
+    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE;
+    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+    STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+    STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE;
+    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE;
+    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpfnCallback) PURE;
+    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE7 *lplpDDAttachedSurface) PURE;
+    STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE;
+    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+    STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+    STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+    STDMETHOD(IsLost)(THIS) PURE;
+    STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+    STDMETHOD(Restore)(THIS) PURE;
+    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+    STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+    STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+    STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE;
+    STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSReference) PURE;
+    /* added in v2 */
+    STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+    STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+    STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+    /* added in v3 */
+    STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE;
+    /* added in v4 */
+    STDMETHOD(SetPrivateData)(THIS_ REFGUID tag, LPVOID pData, DWORD cbSize, DWORD dwFlags) PURE;
+    STDMETHOD(GetPrivateData)(THIS_ REFGUID tag, LPVOID pBuffer, LPDWORD pcbBufferSize) PURE;
+    STDMETHOD(FreePrivateData)(THIS_ REFGUID tag) PURE;
+    STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD pValue) PURE;
+    STDMETHOD(ChangeUniquenessValue)(THIS) PURE;
+    /* added in v7 */
+    STDMETHOD(SetPriority)(THIS_ DWORD prio) PURE;
+    STDMETHOD(GetPriority)(THIS_ LPDWORD prio) PURE;
+    STDMETHOD(SetLOD)(THIS_ DWORD lod) PURE;
+    STDMETHOD(GetLOD)(THIS_ LPDWORD lod) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface7_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface7_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface7_AddAttachedSurface(p,a)      (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a)     (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface7_Blt(p,a,b,c,d,e)             (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface7_BltBatch(p,a,b,c)            (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e)         (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b)  (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c)  (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface7_Flip(p,a,b)                  (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface7_GetAttachedSurface(p,a,b)    (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface7_GetBltStatus(p,a)            (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface7_GetCaps(p,a)                 (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface7_GetClipper(p,a)              (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface7_GetColorKey(p,a,b)           (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface7_GetDC(p,a)                   (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface7_GetFlipStatus(p,a)           (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface7_GetOverlayPosition(p,a,b)    (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface7_GetPalette(p,a)              (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface7_GetPixelFormat(p,a)          (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface7_GetSurfaceDesc(p,a)          (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface7_Initialize(p,a,b)            (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface7_IsLost(p)                    (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface7_Lock(p,a,b,c,d)              (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface7_ReleaseDC(p,a)               (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface7_Restore(p)                   (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface7_SetClipper(p,a)              (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface7_SetColorKey(p,a,b)           (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface7_SetOverlayPosition(p,a,b)    (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface7_SetPalette(p,a)              (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface7_Unlock(p,a)                  (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e)   (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a)    (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b)   (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface7_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface7_PageLock(p,a)       (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface7_PageUnlock(p,a)     (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirectDrawSurface7_GetPrivateData(p,a,b,c)   (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirectDrawSurface7_FreePrivateData(p,a)      (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirectDrawSurface7_GetUniquenessValue(p,a)   (p)->lpVtbl->GetUniquenessValue(p,a)
+#define IDirectDrawSurface7_ChangeUniquenessValue(p)  (p)->lpVtbl->ChangeUniquenessValue(p)
+/*** IDirectDrawSurface7 methods ***/
+#define IDirectDrawSurface7_SetPriority(p,a)          (p)->lpVtbl->SetPriority(p,a)
+#define IDirectDrawSurface7_GetPriority(p,a)          (p)->lpVtbl->GetPriority(p,a)
+#define IDirectDrawSurface7_SetLOD(p,a)               (p)->lpVtbl->SetLOD(p,a)
+#define IDirectDrawSurface7_GetLOD(p,a)               (p)->lpVtbl->GetLOD(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface7_AddRef(p)             (p)->AddRef()
+#define IDirectDrawSurface7_Release(p)            (p)->Release()
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface7_AddAttachedSurface(p,a)      (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a)     (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface7_Blt(p,a,b,c,d,e)             (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface7_BltBatch(p,a,b,c)            (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e)         (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b)  (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c)  (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface7_Flip(p,a,b)                  (p)->Flip(a,b)
+#define IDirectDrawSurface7_GetAttachedSurface(p,a,b)    (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface7_GetBltStatus(p,a)            (p)->GetBltStatus(a)
+#define IDirectDrawSurface7_GetCaps(p,a)                 (p)->GetCaps(a)
+#define IDirectDrawSurface7_GetClipper(p,a)              (p)->GetClipper(a)
+#define IDirectDrawSurface7_GetColorKey(p,a,b)           (p)->GetColorKey(a,b)
+#define IDirectDrawSurface7_GetDC(p,a)                   (p)->GetDC(a)
+#define IDirectDrawSurface7_GetFlipStatus(p,a)           (p)->GetFlipStatus(a)
+#define IDirectDrawSurface7_GetOverlayPosition(p,a,b)    (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface7_GetPalette(p,a)              (p)->GetPalette(a)
+#define IDirectDrawSurface7_GetPixelFormat(p,a)          (p)->GetPixelFormat(a)
+#define IDirectDrawSurface7_GetSurfaceDesc(p,a)          (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface7_Initialize(p,a,b)            (p)->Initialize(a,b)
+#define IDirectDrawSurface7_IsLost(p)                    (p)->IsLost()
+#define IDirectDrawSurface7_Lock(p,a,b,c,d)              (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface7_ReleaseDC(p,a)               (p)->ReleaseDC(a)
+#define IDirectDrawSurface7_Restore(p)                   (p)->Restore()
+#define IDirectDrawSurface7_SetClipper(p,a)              (p)->SetClipper(a)
+#define IDirectDrawSurface7_SetColorKey(p,a,b)           (p)->SetColorKey(a,b)
+#define IDirectDrawSurface7_SetOverlayPosition(p,a,b)    (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface7_SetPalette(p,a)              (p)->SetPalette(a)
+#define IDirectDrawSurface7_Unlock(p,a)                  (p)->Unlock(a)
+#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e)   (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a)    (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b)   (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface7_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface7_PageLock(p,a)       (p)->PageLock(a)
+#define IDirectDrawSurface7_PageUnlock(p,a)     (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirectDrawSurface7_GetPrivateData(p,a,b,c)   (p)->GetPrivateData(a,b,c)
+#define IDirectDrawSurface7_FreePrivateData(p,a)      (p)->FreePrivateData(a)
+#define IDirectDrawSurface7_GetUniquenessValue(p,a)   (p)->GetUniquenessValue(a)
+#define IDirectDrawSurface7_ChangeUniquenessValue(p)  (p)->ChangeUniquenessValue()
+/*** IDirectDrawSurface7 methods ***/
+#define IDirectDrawSurface7_SetPriority(p,a)          (p)->SetPriority(a)
+#define IDirectDrawSurface7_GetPriority(p,a)          (p)->GetPriority(a)
+#define IDirectDrawSurface7_SetLOD(p,a)               (p)->SetLOD(a)
+#define IDirectDrawSurface7_GetLOD(p,a)               (p)->GetLOD(a)
+#endif
+
+/*****************************************************************************
+ * IDirectDrawColorControl interface
+ */
+#define INTERFACE IDirectDrawColorControl
+DECLARE_INTERFACE_(IDirectDrawColorControl,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawColorControl methods ***/
+    STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE;
+    STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawColorControl_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawColorControl_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawColorControl_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawColorControl methods ***/
+#define IDirectDrawColorControl_GetColorControls(p,a) (p)->lpVtbl->GetColorControls(p,a)
+#define IDirectDrawColorControl_SetColorControls(p,a) (p)->lpVtbl->SetColorControls(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawColorControl_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawColorControl_AddRef(p)             (p)->AddRef()
+#define IDirectDrawColorControl_Release(p)            (p)->Release()
+/*** IDirectDrawColorControl methods ***/
+#define IDirectDrawColorControl_GetColorControls(p,a) (p)->GetColorControls(a)
+#define IDirectDrawColorControl_SetColorControls(p,a) (p)->SetColorControls(a)
+#endif
+
+/*****************************************************************************
+ * IDirectDrawGammaControl interface
+ */
+#define INTERFACE IDirectDrawGammaControl
+DECLARE_INTERFACE_(IDirectDrawGammaControl,IUnknown)
+{
+    /*** IUnknown methods ***/
+    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+    /*** IDirectDrawGammaControl methods ***/
+    STDMETHOD(GetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE;
+    STDMETHOD(SetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawGammaControl_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawGammaControl_AddRef(p)             (p)->lpVtbl->AddRef(p)
+#define IDirectDrawGammaControl_Release(p)            (p)->lpVtbl->Release(p)
+/*** IDirectDrawGammaControl methods ***/
+#define IDirectDrawGammaControl_GetGammaRamp(p,a,b)   (p)->lpVtbl->GetGammaRamp(p,a,b)
+#define IDirectDrawGammaControl_SetGammaRamp(p,a,b)   (p)->lpVtbl->SetGammaRamp(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawGammaControl_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawGammaControl_AddRef(p)             (p)->AddRef()
+#define IDirectDrawGammaControl_Release(p)            (p)->Release()
+/*** IDirectDrawGammaControl methods ***/
+#define IDirectDrawGammaControl_GetGammaRamp(p,a,b)   (p)->GetGammaRamp(a,b)
+#define IDirectDrawGammaControl_SetGammaRamp(p,a,b)   (p)->SetGammaRamp(a,b)
+#endif
+
+
+HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN);
+HRESULT WINAPI DirectDrawCreateEx(LPGUID,LPVOID*,REFIID,LPUNKNOWN);
+HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA,LPVOID);
+HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW,LPVOID);
+#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate)
+HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,LPUNKNOWN);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
 
 #endif /* __WINE_DDRAW_H */
+
index 8bc7090..7663a9a 100644 (file)
@@ -269,6 +269,7 @@ typedef struct _DDNONLOCALVIDMEMCAPS {
 
 
 
+
 #define DDSCAPS_EXECUTEBUFFER  DDSCAPS_RESERVED2
 #define DDSCAPS2_VERTEXBUFFER  DDSCAPS2_RESERVED1
 #define DDSCAPS2_COMMANDBUFFER DDSCAPS2_RESERVED2
diff --git a/reactos/include/directory.xml b/reactos/include/directory.xml
new file mode 100644 (file)
index 0000000..10b4d1f
--- /dev/null
@@ -0,0 +1,3 @@
+<directory name="idl">
+       <xi:include href="idl/idl.xml" />
+</directory>
diff --git a/reactos/include/errors.h b/reactos/include/errors.h
deleted file mode 100644 (file)
index 78d7c25..0000000
+++ /dev/null
@@ -1,1189 +0,0 @@
-/* 
-   Errors.h
-
-   Windows32 API error codes
-
-   Copyright (C) 1996 Free Software Foundation, Inc.
-
-   Author: Scott Christley <scottc@net-community.com>
-
-   This file is part of the Windows32 API Library.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 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
-   Library General Public License for more details.
-
-   If you are interested in a warranty or support for this source code,
-   contact Scott Christley <scottc@net-community.com> for more information.
-   
-   You should have received a copy of the GNU Library General Public
-   License along with this library; see the file COPYING.LIB.
-   If not, write to the Free Software Foundation, 
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/ 
-
-#ifndef _GNU_H_WINDOWS32_ERROR
-#define _GNU_H_WINDOWS32_ERROR
-
-#ifdef __USE_W32API
-
-#include_next <windows.h>
-
-#else /* !__USE_W32API */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/*
- *     Return Code macros
- */
-#define        SUCCEEDED(Status)       ((HRESULT)(Status) >= 0)
-#define        FAILED(Status)          ((HRESULT)(Status)<0)
-
-/*
- *     Success Codes
- */
-#define S_OK                                           0x00000000L
-#define S_FALSE                                                0x00000001L
-
-/* Numerical order */
-
-#define LZERROR_UNKNOWNALG             (-8)
-#define LZERROR_BADVALUE               (-7)
-#define LZERROR_GLOBLOCK               (-6)
-#define LZERROR_GLOBALLOC              (-5)
-#define LZERROR_WRITE                  (-4)
-#define LZERROR_READ                   (-3)
-#define LZERROR_BADOUTHANDLE           (-2)
-#define LZERROR_BADINHANDLE            (-1)
-#define NO_ERROR                         0L
-
-#if 0
-#include "../reactos/errcodes.h"
-#else
-#define ERROR_SUCCESS                    0L
-#define ERROR_INVALID_FUNCTION           1L
-#define ERROR_FILE_NOT_FOUND             2L
-#define ERROR_PATH_NOT_FOUND             3L
-#define ERROR_TOO_MANY_OPEN_FILES        4L
-#define ERROR_ACCESS_DENIED              5L
-#define ERROR_INVALID_HANDLE             6L
-#define ERROR_ARENA_TRASHED              7L
-#define ERROR_NOT_ENOUGH_MEMORY          8L
-#define ERROR_INVALID_BLOCK              9L
-#define ERROR_BAD_ENVIRONMENT            10L
-#define ERROR_BAD_FORMAT                 11L
-#define ERROR_INVALID_ACCESS             12L
-#define ERROR_INVALID_DATA               13L
-#define ERROR_OUTOFMEMORY                14L
-#define ERROR_INVALID_DRIVE              15L
-#define ERROR_CURRENT_DIRECTORY          16L
-#define ERROR_NOT_SAME_DEVICE            17L
-#define ERROR_NO_MORE_FILES              18L
-#define ERROR_WRITE_PROTECT              19L
-#define ERROR_BAD_UNIT                   20L
-#define ERROR_NOT_READY                  21L
-#define ERROR_BAD_COMMAND                22L
-#define ERROR_CRC                        23L
-#define ERROR_BAD_LENGTH                 24L
-#define ERROR_SEEK                       25L
-#define ERROR_NOT_DOS_DISK               26L
-#define ERROR_SECTOR_NOT_FOUND           27L
-#define ERROR_OUT_OF_PAPER               28L
-#define ERROR_WRITE_FAULT                29L
-#define ERROR_READ_FAULT                 30L
-#define ERROR_GEN_FAILURE                31L
-#define ERROR_SHARING_VIOLATION          32L
-#define ERROR_LOCK_VIOLATION             33L
-#define ERROR_WRONG_DISK                 34L
-#define ERROR_SHARING_BUFFER_EXCEEDED    36L
-#define ERROR_HANDLE_EOF                 38L
-#define ERROR_HANDLE_DISK_FULL           39L
-#define ERROR_NOT_SUPPORTED              50L
-#define ERROR_REM_NOT_LIST               51L
-#define ERROR_DUP_NAME                   52L
-#define ERROR_BAD_NETPATH                53L
-#define ERROR_NETWORK_BUSY               54L
-#define ERROR_DEV_NOT_EXIST              55L
-#define ERROR_TOO_MANY_CMDS              56L
-#define ERROR_ADAP_HDW_ERR               57L
-#define ERROR_BAD_NET_RESP               58L
-#define ERROR_UNEXP_NET_ERR              59L
-#define ERROR_BAD_REM_ADAP               60L
-#define ERROR_PRINTQ_FULL                61L
-#define ERROR_NO_SPOOL_SPACE             62L
-#define ERROR_PRINT_CANCELLED            63L
-#define ERROR_NETNAME_DELETED            64L
-#define ERROR_NETWORK_ACCESS_DENIED      65L
-#define ERROR_BAD_DEV_TYPE               66L
-#define ERROR_BAD_NET_NAME               67L
-#define ERROR_TOO_MANY_NAMES             68L
-#define ERROR_TOO_MANY_SESS              69L
-#define ERROR_SHARING_PAUSED             70L
-#define ERROR_REQ_NOT_ACCEP              71L
-#define ERROR_REDIR_PAUSED               72L
-#define ERROR_FILE_EXISTS                80L
-#define ERROR_CANNOT_MAKE                82L
-#define ERROR_FAIL_I24                   83L
-#define ERROR_OUT_OF_STRUCTURES          84L
-#define ERROR_ALREADY_ASSIGNED           85L
-#define ERROR_INVALID_PASSWORD           86L
-#define ERROR_INVALID_PARAMETER          87L
-#define ERROR_NET_WRITE_FAULT            88L
-#define ERROR_NO_PROC_SLOTS              89L
-#define ERROR_TOO_MANY_SEMAPHORES        100L
-#define ERROR_EXCL_SEM_ALREADY_OWNED     101L
-#define ERROR_SEM_IS_SET                 102L
-#define ERROR_TOO_MANY_SEM_REQUESTS      103L
-#define ERROR_INVALID_AT_INTERRUPT_TIME  104L
-#define ERROR_SEM_OWNER_DIED             105L
-#define ERROR_SEM_USER_LIMIT             106L
-#define ERROR_DISK_CHANGE                107L
-#define ERROR_DRIVE_LOCKED               108L
-#define ERROR_BROKEN_PIPE                109L
-#define ERROR_OPEN_FAILED                110L
-#define ERROR_BUFFER_OVERFLOW            111L
-#define ERROR_DISK_FULL                  112L
-#define ERROR_NO_MORE_SEARCH_HANDLES     113L
-#define ERROR_INVALID_TARGET_HANDLE      114L
-#define ERROR_INVALID_CATEGORY           117L
-#define ERROR_INVALID_VERIFY_SWITCH      118L
-#define ERROR_BAD_DRIVER_LEVEL           119L
-#define ERROR_CALL_NOT_IMPLEMENTED       120L
-#define ERROR_SEM_TIMEOUT                121L
-#define ERROR_INSUFFICIENT_BUFFER        122L
-#define ERROR_INVALID_NAME               123L
-#define ERROR_INVALID_LEVEL              124L
-#define ERROR_NO_VOLUME_LABEL            125L
-#define ERROR_MOD_NOT_FOUND              126L
-#define ERROR_PROC_NOT_FOUND             127L
-#define ERROR_WAIT_NO_CHILDREN           128L
-#define ERROR_CHILD_NOT_COMPLETE         129L
-#define ERROR_DIRECT_ACCESS_HANDLE       130L
-#define ERROR_NEGATIVE_SEEK              131L
-#define ERROR_SEEK_ON_DEVICE             132L
-#define ERROR_IS_JOIN_TARGET             133L
-#define ERROR_IS_JOINED                  134L
-#define ERROR_IS_SUBSTED                 135L
-#define ERROR_NOT_JOINED                 136L
-#define ERROR_NOT_SUBSTED                137L
-#define ERROR_JOIN_TO_JOIN               138L
-#define ERROR_SUBST_TO_SUBST             139L
-#define ERROR_JOIN_TO_SUBST              140L
-#define ERROR_SUBST_TO_JOIN              141L
-#define ERROR_BUSY_DRIVE                 142L
-#define ERROR_SAME_DRIVE                 143L
-#define ERROR_DIR_NOT_ROOT               144L
-#define ERROR_DIR_NOT_EMPTY              145L
-#define ERROR_IS_SUBST_PATH              146L
-#define ERROR_IS_JOIN_PATH               147L
-#define ERROR_PATH_BUSY                  148L
-#define ERROR_IS_SUBST_TARGET            149L
-#define ERROR_SYSTEM_TRACE               150L
-#define ERROR_INVALID_EVENT_COUNT        151L
-#define ERROR_TOO_MANY_MUXWAITERS        152L
-#define ERROR_INVALID_LIST_FORMAT        153L
-#define ERROR_LABEL_TOO_LONG             154L
-#define ERROR_TOO_MANY_TCBS              155L
-#define ERROR_SIGNAL_REFUSED             156L
-#define ERROR_DISCARDED                  157L
-#define ERROR_NOT_LOCKED                 158L
-#define ERROR_BAD_THREADID_ADDR          159L
-#define ERROR_BAD_ARGUMENTS              160L
-#define ERROR_BAD_PATHNAME               161L
-#define ERROR_SIGNAL_PENDING             162L
-#define ERROR_MAX_THRDS_REACHED          164L
-#define ERROR_LOCK_FAILED                167L
-#define ERROR_BUSY                       170L
-#define ERROR_CANCEL_VIOLATION           173L
-#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174L
-#define ERROR_INVALID_SEGMENT_NUMBER     180L
-#define ERROR_INVALID_ORDINAL            182L
-#define ERROR_ALREADY_EXISTS             183L
-#define ERROR_INVALID_FLAG_NUMBER        186L
-#define ERROR_SEM_NOT_FOUND              187L
-#define ERROR_INVALID_STARTING_CODESEG   188L
-#define ERROR_INVALID_STACKSEG           189L
-#define ERROR_INVALID_MODULETYPE         190L
-#define ERROR_INVALID_EXE_SIGNATURE      191L
-#define ERROR_EXE_MARKED_INVALID         192L
-#define ERROR_BAD_EXE_FORMAT             193L
-#define ERROR_ITERATED_DATA_EXCEEDS_64k  194L
-#define ERROR_INVALID_MINALLOCSIZE       195L
-#define ERROR_DYNLINK_FROM_INVALID_RING  196L
-#define ERROR_IOPL_NOT_ENABLED           197L
-#define ERROR_INVALID_SEGDPL             198L
-#define ERROR_AUTODATASEG_EXCEEDS_64k    199L
-#define ERROR_RING2SEG_MUST_BE_MOVABLE   200L
-#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM   201L
-#define ERROR_INFLOOP_IN_RELOC_CHAIN     202L
-#define ERROR_ENVVAR_NOT_FOUND           203L
-#define ERROR_NO_SIGNAL_SENT             205L
-#define ERROR_FILENAME_EXCED_RANGE       206L
-#define ERROR_RING2_STACK_IN_USE         207L
-#define ERROR_META_EXPANSION_TOO_LONG    208L
-#define ERROR_INVALID_SIGNAL_NUMBER      209L
-#define ERROR_THREAD_1_INACTIVE          210L
-#define ERROR_LOCKED                     212L
-#define ERROR_TOO_MANY_MODULES           214L
-#define ERROR_NESTING_NOT_ALLOWED        215L
-#define ERROR_CANNOT_SHRINK              216L
-#define ERROR_ZOMBIE_PROCESS             217L
-#define ERROR_STACK_IN_HIGH_MEMORY       218L
-#define ERROR_INVALID_EXITROUTINE_RING   219L
-#define ERROR_GETBUF_FAILED              220L
-#define ERROR_FLUSHBUF_FAILED            221L
-#define ERROR_TRANSFER_TOO_LONG          222L
-#define ERROR_FORCENOSWAP_FAILED         223L
-#define ERROR_SMG_NO_TARGET_WINDOW       224L
-#define ERROR_NO_CHILDREN                228L
-#define ERROR_INVALID_SCREEN_GROUP       229L
-#define ERROR_BAD_PIPE                   230L
-#define ERROR_PIPE_BUSY                  231L
-#define ERROR_NO_DATA                    232L
-#define ERROR_PIPE_NOT_CONNECTED         233L
-#define ERROR_MORE_DATA                  234L
-#define ERROR_VC_DISCONNECTED            240L
-#define ERROR_INVALID_EA_NAME            254L
-#define ERROR_EA_LIST_INCONSISTENT       255L
-#define ERROR_NO_MORE_ITEMS              259L
-#define ERROR_CANNOT_COPY                266L
-#define ERROR_DIRECTORY                  267L
-#define ERROR_EAS_DIDNT_FIT              275L
-#define ERROR_EA_FILE_CORRUPT            276L
-#define ERROR_EA_TABLE_FULL              277L
-#define ERROR_INVALID_EA_HANDLE          278L
-#define ERROR_EAS_NOT_SUPPORTED          282L
-#define ERROR_NOT_OWNER                  288L
-#define ERROR_TOO_MANY_POSTS             298L
-#define ERROR_PARTIAL_COPY               299L
-#define ERROR_MR_MID_NOT_FOUND           317L
-#define ERROR_INVALID_ADDRESS            487L
-#define ERROR_ARITHMETIC_OVERFLOW        534L
-#define ERROR_PIPE_CONNECTED             535L
-#define ERROR_PIPE_LISTENING             536L
-#define ERROR_EA_ACCESS_DENIED           994L
-#define ERROR_OPERATION_ABORTED          995L
-#define ERROR_IO_INCOMPLETE              996L
-#define ERROR_IO_PENDING                 997L
-#define ERROR_NOACCESS                   998L
-#define ERROR_SWAPERROR                  999L
-#define ERROR_STACK_OVERFLOW             1001L
-#define ERROR_INVALID_MESSAGE            1002L
-#define ERROR_CAN_NOT_COMPLETE           1003L
-#define ERROR_INVALID_FLAGS              1004L
-#define ERROR_UNRECOGNIZED_VOLUME        1005L
-#define ERROR_FILE_INVALID               1006L
-#define ERROR_FULLSCREEN_MODE            1007L
-#define ERROR_NO_TOKEN                   1008L
-#define ERROR_BADDB                      1009L
-#define ERROR_BADKEY                     1010L
-#define ERROR_CANTOPEN                   1011L
-#define ERROR_CANTREAD                   1012L
-#define ERROR_CANTWRITE                  1013L
-#define ERROR_REGISTRY_RECOVERED         1014L
-#define ERROR_REGISTRY_CORRUPT           1015L
-#define ERROR_REGISTRY_IO_FAILED         1016L
-#define ERROR_NOT_REGISTRY_FILE          1017L
-#define ERROR_KEY_DELETED                1018L
-#define ERROR_NO_LOG_SPACE               1019L
-#define ERROR_KEY_HAS_CHILDREN           1020L
-#define ERROR_CHILD_MUST_BE_VOLATILE     1021L
-#define ERROR_NOTIFY_ENUM_DIR            1022L
-#define ERROR_DEPENDENT_SERVICES_RUNNING 1051L
-#define ERROR_INVALID_SERVICE_CONTROL    1052L
-#define ERROR_SERVICE_REQUEST_TIMEOUT    1053L
-#define ERROR_SERVICE_NO_THREAD          1054L
-#define ERROR_SERVICE_DATABASE_LOCKED    1055L
-#define ERROR_SERVICE_ALREADY_RUNNING    1056L
-#define ERROR_INVALID_SERVICE_ACCOUNT    1057L
-#define ERROR_SERVICE_DISABLED           1058L
-#define ERROR_CIRCULAR_DEPENDENCY        1059L
-#define ERROR_SERVICE_DOES_NOT_EXIST     1060L
-#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061L
-#define ERROR_SERVICE_NOT_ACTIVE         1062L
-#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063L
-#define ERROR_EXCEPTION_IN_SERVICE       1064L
-#define ERROR_DATABASE_DOES_NOT_EXIST    1065L
-#define ERROR_SERVICE_SPECIFIC_ERROR     1066L
-#define ERROR_PROCESS_ABORTED            1067L
-#define ERROR_SERVICE_DEPENDENCY_FAIL    1068L
-#define ERROR_SERVICE_LOGON_FAILED       1069L
-#define ERROR_SERVICE_START_HANG         1070L
-#define ERROR_INVALID_SERVICE_LOCK       1071L
-#define ERROR_SERVICE_MARKED_FOR_DELETE  1072L
-#define ERROR_SERVICE_EXISTS             1073L
-#define ERROR_ALREADY_RUNNING_LKG        1074L
-#define ERROR_SERVICE_DEPENDENCY_DELETED 1075L
-#define ERROR_BOOT_ALREADY_ACCEPTED      1076L
-#define ERROR_SERVICE_NEVER_STARTED      1077L
-#define ERROR_DUPLICATE_SERVICE_NAME     1078L
-#define ERROR_END_OF_MEDIA               1100L
-#define ERROR_FILEMARK_DETECTED          1101L
-#define ERROR_BEGINNING_OF_MEDIA         1102L
-#define ERROR_SETMARK_DETECTED           1103L
-#define ERROR_NO_DATA_DETECTED           1104L
-#define ERROR_PARTITION_FAILURE          1105L
-#define ERROR_INVALID_BLOCK_LENGTH       1106L
-#define ERROR_DEVICE_NOT_PARTITIONED     1107L
-#define ERROR_UNABLE_TO_LOCK_MEDIA       1108L
-#define ERROR_UNABLE_TO_UNLOAD_MEDIA     1109L
-#define ERROR_MEDIA_CHANGED              1110L
-#define ERROR_BUS_RESET                  1111L
-#define ERROR_NO_MEDIA_IN_DRIVE          1112L
-#define ERROR_NO_UNICODE_TRANSLATION     1113L
-#define ERROR_DLL_INIT_FAILED            1114L
-#define ERROR_SHUTDOWN_IN_PROGRESS       1115L
-#define ERROR_NO_SHUTDOWN_IN_PROGRESS    1116L
-#define ERROR_IO_DEVICE                  1117L
-#define ERROR_SERIAL_NO_DEVICE           1118L
-#define ERROR_IRQ_BUSY                   1119L
-#define ERROR_MORE_WRITES                1120L
-#define ERROR_COUNTER_TIMEOUT            1121L
-#define ERROR_FLOPPY_ID_MARK_NOT_FOUND   1122L
-#define ERROR_FLOPPY_WRONG_CYLINDER      1123L
-#define ERROR_FLOPPY_UNKNOWN_ERROR       1124L
-#define ERROR_FLOPPY_BAD_REGISTERS       1125L
-#define ERROR_DISK_RECALIBRATE_FAILED    1126L
-#define ERROR_DISK_OPERATION_FAILED      1127L
-#define ERROR_DISK_RESET_FAILED          1128L
-#define ERROR_EOM_OVERFLOW               1129L
-#define ERROR_NOT_ENOUGH_SERVER_MEMORY   1130L
-#define ERROR_POSSIBLE_DEADLOCK          1131L
-#define ERROR_MAPPED_ALIGNMENT           1132L
-#define ERROR_SET_POWER_STATE_VETOED     1140L
-#define ERROR_SET_POWER_STATE_FAILED     1141L
-#define ERROR_TOO_MANY_LINKS             1142L
-#define ERROR_OLD_WIN_VERSION            1150L
-#define ERROR_APP_WRONG_OS               1151L
-#define ERROR_SINGLE_INSTANCE_APP        1152L
-#define ERROR_RMODE_APP                  1153L
-#define ERROR_INVALID_DLL                1154L
-#define ERROR_NO_ASSOCIATION             1155L
-#define ERROR_DDE_FAIL                   1156L
-#define ERROR_DLL_NOT_FOUND              1157L
-#define ERROR_BAD_DEVICE                 1200L
-#define ERROR_CONNECTION_UNAVAIL         1201L
-#define ERROR_DEVICE_ALREADY_REMEMBERED  1202L
-#define ERROR_NO_NET_OR_BAD_PATH         1203L
-#define ERROR_BAD_PROVIDER               1204L
-#define ERROR_CANNOT_OPEN_PROFILE        1205L
-#define ERROR_BAD_PROFILE                1206L
-#define ERROR_NOT_CONTAINER              1207L
-#define ERROR_EXTENDED_ERROR             1208L
-#define ERROR_INVALID_GROUPNAME          1209L
-#define ERROR_INVALID_COMPUTERNAME       1210L
-#define ERROR_INVALID_EVENTNAME          1211L
-#define ERROR_INVALID_DOMAINNAME         1212L
-#define ERROR_INVALID_SERVICENAME        1213L
-#define ERROR_INVALID_NETNAME            1214L
-#define ERROR_INVALID_SHARENAME          1215L
-#define ERROR_INVALID_PASSWORDNAME       1216L
-#define ERROR_INVALID_MESSAGENAME        1217L
-#define ERROR_INVALID_MESSAGEDEST        1218L
-#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219L
-#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220L
-#define ERROR_DUP_DOMAINNAME             1221L
-#define ERROR_NO_NETWORK                 1222L
-#define ERROR_CANCELLED                  1223L
-#define ERROR_USER_MAPPED_FILE           1224L
-#define ERROR_CONNECTION_REFUSED         1225L
-#define ERROR_GRACEFUL_DISCONNECT        1226L
-#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227L
-#define ERROR_ADDRESS_NOT_ASSOCIATED     1228L
-#define ERROR_CONNECTION_INVALID         1229L
-#define ERROR_CONNECTION_ACTIVE          1230L
-#define ERROR_NETWORK_UNREACHABLE        1231L
-#define ERROR_HOST_UNREACHABLE           1232L
-#define ERROR_PROTOCOL_UNREACHABLE       1233L
-#define ERROR_PORT_UNREACHABLE           1234L
-#define ERROR_REQUEST_ABORTED            1235L
-#define ERROR_CONNECTION_ABORTED         1236L
-#define ERROR_RETRY                      1237L
-#define ERROR_CONNECTION_COUNT_LIMIT     1238L
-#define ERROR_LOGIN_TIME_RESTRICTION     1239L
-#define ERROR_LOGIN_WKSTA_RESTRICTION    1240L
-#define ERROR_INCORRECT_ADDRESS          1241L
-#define ERROR_ALREADY_REGISTERED         1242L
-#define ERROR_SERVICE_NOT_FOUND          1243L
-#define ERROR_NOT_AUTHENTICATED          1244L
-#define ERROR_NOT_LOGGED_ON              1245L
-#define ERROR_CONTINUE                   1246L
-#define ERROR_ALREADY_INITIALIZED        1247L
-#define ERROR_NO_MORE_DEVICES            1248L
-#define ERROR_NOT_ALL_ASSIGNED           1300L
-#define ERROR_SOME_NOT_MAPPED            1301L
-#define ERROR_NO_QUOTAS_FOR_ACCOUNT      1302L
-#define ERROR_LOCAL_USER_SESSION_KEY     1303L
-#define ERROR_NULL_LM_PASSWORD           1304L
-#define ERROR_UNKNOWN_REVISION           1305L
-#define ERROR_REVISION_MISMATCH          1306L
-#define ERROR_INVALID_OWNER              1307L
-#define ERROR_INVALID_PRIMARY_GROUP      1308L
-#define ERROR_NO_IMPERSONATION_TOKEN     1309L
-#define ERROR_CANT_DISABLE_MANDATORY     1310L
-#define ERROR_NO_LOGON_SERVERS           1311L
-#define ERROR_NO_SUCH_LOGON_SESSION      1312L
-#define ERROR_NO_SUCH_PRIVILEGE          1313L
-#define ERROR_PRIVILEGE_NOT_HELD         1314L
-#define ERROR_INVALID_ACCOUNT_NAME       1315L
-#define ERROR_USER_EXISTS                1316L
-#define ERROR_NO_SUCH_USER               1317L
-#define ERROR_GROUP_EXISTS               1318L
-#define ERROR_NO_SUCH_GROUP              1319L
-#define ERROR_MEMBER_IN_GROUP            1320L
-#define ERROR_MEMBER_NOT_IN_GROUP        1321L
-#define ERROR_LAST_ADMIN                 1322L
-#define ERROR_WRONG_PASSWORD             1323L
-#define ERROR_ILL_FORMED_PASSWORD        1324L
-#define ERROR_PASSWORD_RESTRICTION       1325L
-#define ERROR_LOGON_FAILURE              1326L
-#define ERROR_ACCOUNT_RESTRICTION        1327L
-#define ERROR_INVALID_LOGON_HOURS        1328L
-#define ERROR_INVALID_WORKSTATION        1329L
-#define ERROR_PASSWORD_EXPIRED           1330L
-#define ERROR_ACCOUNT_DISABLED           1331L
-#define ERROR_NONE_MAPPED                1332L
-#define ERROR_TOO_MANY_LUIDS_REQUESTED   1333L
-#define ERROR_LUIDS_EXHAUSTED            1334L
-#define ERROR_INVALID_SUB_AUTHORITY      1335L
-#define ERROR_INVALID_ACL                1336L
-#define ERROR_INVALID_SID                1337L
-#define ERROR_INVALID_SECURITY_DESCR     1338L
-#define ERROR_BAD_INHERITANCE_ACL        1340L
-#define ERROR_SERVER_DISABLED            1341L
-#define ERROR_SERVER_NOT_DISABLED        1342L
-#define ERROR_INVALID_ID_AUTHORITY       1343L
-#define ERROR_ALLOTTED_SPACE_EXCEEDED    1344L
-#define ERROR_INVALID_GROUP_ATTRIBUTES   1345L
-#define ERROR_BAD_IMPERSONATION_LEVEL    1346L
-#define ERROR_CANT_OPEN_ANONYMOUS        1347L
-#define ERROR_BAD_VALIDATION_CLASS       1348L
-#define ERROR_BAD_TOKEN_TYPE             1349L
-#define ERROR_NO_SECURITY_ON_OBJECT      1350L
-#define ERROR_CANT_ACCESS_DOMAIN_INFO    1351L
-#define ERROR_INVALID_SERVER_STATE       1352L
-#define ERROR_INVALID_DOMAIN_STATE       1353L
-#define ERROR_INVALID_DOMAIN_ROLE        1354L
-#define ERROR_NO_SUCH_DOMAIN             1355L
-#define ERROR_DOMAIN_EXISTS              1356L
-#define ERROR_DOMAIN_LIMIT_EXCEEDED      1357L
-#define ERROR_INTERNAL_DB_CORRUPTION     1358L
-#define ERROR_INTERNAL_ERROR             1359L
-#define ERROR_GENERIC_NOT_MAPPED         1360L
-#define ERROR_BAD_DESCRIPTOR_FORMAT      1361L
-#define ERROR_NOT_LOGON_PROCESS          1362L
-#define ERROR_LOGON_SESSION_EXISTS       1363L
-#define ERROR_NO_SUCH_PACKAGE            1364L
-#define ERROR_BAD_LOGON_SESSION_STATE    1365L
-#define ERROR_LOGON_SESSION_COLLISION    1366L
-#define ERROR_INVALID_LOGON_TYPE         1367L
-#define ERROR_CANNOT_IMPERSONATE         1368L
-#define ERROR_RXACT_INVALID_STATE        1369L
-#define ERROR_RXACT_COMMIT_FAILURE       1370L
-#define ERROR_SPECIAL_ACCOUNT            1371L
-#define ERROR_SPECIAL_GROUP              1372L
-#define ERROR_SPECIAL_USER               1373L
-#define ERROR_MEMBERS_PRIMARY_GROUP      1374L
-#define ERROR_TOKEN_ALREADY_IN_USE       1375L
-#define ERROR_NO_SUCH_ALIAS              1376L
-#define ERROR_MEMBER_NOT_IN_ALIAS        1377L
-#define ERROR_MEMBER_IN_ALIAS            1378L
-#define ERROR_ALIAS_EXISTS               1379L
-#define ERROR_LOGON_NOT_GRANTED          1380L
-#define ERROR_TOO_MANY_SECRETS           1381L
-#define ERROR_SECRET_TOO_LONG            1382L
-#define ERROR_INTERNAL_DB_ERROR          1383L
-#define ERROR_TOO_MANY_CONTEXT_IDS       1384L
-#define ERROR_LOGON_TYPE_NOT_GRANTED     1385L
-#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386L
-#define ERROR_NO_SUCH_MEMBER             1387L
-#define ERROR_INVALID_MEMBER             1388L
-#define ERROR_TOO_MANY_SIDS              1389L
-#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390L
-#define ERROR_NO_INHERITANCE             1391L
-#define ERROR_FILE_CORRUPT               1392L
-#define ERROR_DISK_CORRUPT               1393L
-#define ERROR_NO_USER_SESSION_KEY        1394L
-#define ERROR_LICENSE_QUOTA_EXCEEDED     1395L
-#define ERROR_INVALID_WINDOW_HANDLE      1400L
-#define ERROR_INVALID_MENU_HANDLE        1401L
-#define ERROR_INVALID_CURSOR_HANDLE      1402L
-#define ERROR_INVALID_ACCEL_HANDLE       1403L
-#define ERROR_INVALID_HOOK_HANDLE        1404L
-#define ERROR_INVALID_DWP_HANDLE         1405L
-#define ERROR_TLW_WITH_WSCHILD           1406L
-#define ERROR_CANNOT_FIND_WND_CLASS      1407L
-#define ERROR_WINDOW_OF_OTHER_THREAD     1408L
-#define ERROR_HOTKEY_ALREADY_REGISTERED  1409L
-#define ERROR_CLASS_ALREADY_EXISTS       1410L
-#define ERROR_CLASS_DOES_NOT_EXIST       1411L
-#define ERROR_CLASS_HAS_WINDOWS          1412L
-#define ERROR_INVALID_INDEX              1413L
-#define ERROR_INVALID_ICON_HANDLE        1414L
-#define ERROR_PRIVATE_DIALOG_INDEX       1415L
-#define ERROR_LISTBOX_ID_NOT_FOUND       1416L
-#define ERROR_NO_WILDCARD_CHARACTERS     1417L
-#define ERROR_CLIPBOARD_NOT_OPEN         1418L
-#define ERROR_HOTKEY_NOT_REGISTERED      1419L
-#define ERROR_WINDOW_NOT_DIALOG          1420L
-#define ERROR_CONTROL_ID_NOT_FOUND       1421L
-#define ERROR_INVALID_COMBOBOX_MESSAGE   1422L
-#define ERROR_WINDOW_NOT_COMBOBOX        1423L
-#define ERROR_INVALID_EDIT_HEIGHT        1424L
-#define ERROR_DC_NOT_FOUND               1425L
-#define ERROR_INVALID_HOOK_FILTER        1426L
-#define ERROR_INVALID_FILTER_PROC        1427L
-#define ERROR_HOOK_NEEDS_HMOD            1428L
-#define ERROR_GLOBAL_ONLY_HOOK           1429L
-#define ERROR_JOURNAL_HOOK_SET           1430L
-#define ERROR_HOOK_NOT_INSTALLED         1431L
-#define ERROR_INVALID_LB_MESSAGE         1432L
-#define ERROR_SETCOUNT_ON_BAD_LB         1433L
-#define ERROR_LB_WITHOUT_TABSTOPS        1434L
-#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435L
-#define ERROR_CHILD_WINDOW_MENU          1436L
-#define ERROR_NO_SYSTEM_MENU             1437L
-#define ERROR_INVALID_MSGBOX_STYLE       1438L
-#define ERROR_INVALID_SPI_VALUE          1439L
-#define ERROR_SCREEN_ALREADY_LOCKED      1440L
-#define ERROR_HWNDS_HAVE_DIFF_PARENT     1441L
-#define ERROR_NOT_CHILD_WINDOW           1442L
-#define ERROR_INVALID_GW_COMMAND         1443L
-#define ERROR_INVALID_THREAD_ID          1444L
-#define ERROR_NON_MDICHILD_WINDOW        1445L
-#define ERROR_POPUP_ALREADY_ACTIVE       1446L
-#define ERROR_NO_SCROLLBARS              1447L
-#define ERROR_INVALID_SCROLLBAR_RANGE    1448L
-#define ERROR_INVALID_SHOWWIN_COMMAND    1449L
-#define ERROR_NO_SYSTEM_RESOURCES        1450L
-#define ERROR_NONPAGED_SYSTEM_RESOURCES  1451L
-#define ERROR_PAGED_SYSTEM_RESOURCES     1452L
-#define ERROR_WORKING_SET_QUOTA          1453L
-#define ERROR_PAGEFILE_QUOTA             1454L
-#define ERROR_COMMITMENT_LIMIT           1455L
-#define ERROR_MENU_ITEM_NOT_FOUND        1456L
-#define ERROR_TIMEOUT                    1460L
-#define ERROR_INVALID_MONITOR_HANDLE     1461L
-#define ERROR_EVENTLOG_FILE_CORRUPT      1500L
-#define ERROR_EVENTLOG_CANT_START        1501L
-#define ERROR_LOG_FILE_FULL              1502L
-#define ERROR_EVENTLOG_FILE_CHANGED      1503L
-#define RPC_S_INVALID_STRING_BINDING     1700L
-#define RPC_S_WRONG_KIND_OF_BINDING      1701L
-#define RPC_S_INVALID_BINDING            1702L
-#define RPC_S_PROTSEQ_NOT_SUPPORTED      1703L
-#define RPC_S_INVALID_RPC_PROTSEQ        1704L
-#define RPC_S_INVALID_STRING_UUID        1705L
-#define RPC_S_INVALID_ENDPOINT_FORMAT    1706L
-#define RPC_S_INVALID_NET_ADDR           1707L
-#define RPC_S_NO_ENDPOINT_FOUND          1708L
-#define RPC_S_INVALID_TIMEOUT            1709L
-#define RPC_S_OBJECT_NOT_FOUND           1710L
-#define RPC_S_ALREADY_REGISTERED         1711L
-#define RPC_S_TYPE_ALREADY_REGISTERED    1712L
-#define RPC_S_ALREADY_LISTENING          1713L
-#define RPC_S_NO_PROTSEQS_REGISTERED     1714L
-#define RPC_S_NOT_LISTENING              1715L
-#define RPC_S_UNKNOWN_MGR_TYPE           1716L
-#define RPC_S_UNKNOWN_IF                 1717L
-#define RPC_S_NO_BINDINGS                1718L
-#define RPC_S_NO_PROTSEQS                1719L
-#define RPC_S_CANT_CREATE_ENDPOINT       1720L
-#define RPC_S_OUT_OF_RESOURCES           1721L
-#define RPC_S_SERVER_UNAVAILABLE         1722L
-#define RPC_S_SERVER_TOO_BUSY            1723L
-#define RPC_S_INVALID_NETWORK_OPTIONS    1724L
-#define RPC_S_NO_CALL_ACTIVE             1725L
-#define RPC_S_CALL_FAILED                1726L
-#define RPC_S_CALL_FAILED_DNE            1727L
-#define RPC_S_PROTOCOL_ERROR             1728L
-#define RPC_S_UNSUPPORTED_TRANS_SYN      1730L
-#define RPC_S_UNSUPPORTED_TYPE           1732L
-#define RPC_S_INVALID_TAG                1733L
-#define RPC_S_INVALID_BOUND              1734L
-#define RPC_S_NO_ENTRY_NAME              1735L
-#define RPC_S_INVALID_NAME_SYNTAX        1736L
-#define RPC_S_UNSUPPORTED_NAME_SYNTAX    1737L
-#define RPC_S_UUID_NO_ADDRESS            1739L
-#define RPC_S_DUPLICATE_ENDPOINT         1740L
-#define RPC_S_UNKNOWN_AUTHN_TYPE         1741L
-#define RPC_S_MAX_CALLS_TOO_SMALL        1742L
-#define RPC_S_STRING_TOO_LONG            1743L
-#define RPC_S_PROTSEQ_NOT_FOUND          1744L
-#define RPC_S_PROCNUM_OUT_OF_RANGE       1745L
-#define RPC_S_BINDING_HAS_NO_AUTH        1746L
-#define RPC_S_UNKNOWN_AUTHN_SERVICE      1747L
-#define RPC_S_UNKNOWN_AUTHN_LEVEL        1748L
-#define RPC_S_INVALID_AUTH_IDENTITY      1749L
-#define RPC_S_UNKNOWN_AUTHZ_SERVICE      1750L
-#define EPT_S_INVALID_ENTRY              1751L
-#define EPT_S_CANT_PERFORM_OP            1752L
-#define EPT_S_NOT_REGISTERED             1753L
-#define RPC_S_NOTHING_TO_EXPORT          1754L
-#define RPC_S_INCOMPLETE_NAME            1755L
-#define RPC_S_INVALID_VERS_OPTION        1756L
-#define RPC_S_NO_MORE_MEMBERS            1757L
-#define RPC_S_NOT_ALL_OBJS_UNEXPORTED    1758L
-#define RPC_S_INTERFACE_NOT_FOUND        1759L
-#define RPC_S_ENTRY_ALREADY_EXISTS       1760L
-#define RPC_S_ENTRY_NOT_FOUND            1761L
-#define RPC_S_NAME_SERVICE_UNAVAILABLE   1762L
-#define RPC_S_INVALID_NAF_ID             1763L
-#define RPC_S_CANNOT_SUPPORT             1764L
-#define RPC_S_NO_CONTEXT_AVAILABLE       1765L
-#define RPC_S_INTERNAL_ERROR             1766L
-#define RPC_S_ZERO_DIVIDE                1767L
-#define RPC_S_ADDRESS_ERROR              1768L
-#define RPC_S_FP_DIV_ZERO                1769L
-#define RPC_S_FP_UNDERFLOW               1770L
-#define RPC_S_FP_OVERFLOW                1771L
-#define RPC_X_NO_MORE_ENTRIES            1772L
-#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL    1773L
-#define RPC_X_SS_CHAR_TRANS_SHORT_FILE   1774L
-#define RPC_X_SS_IN_NULL_CONTEXT         1775L
-#define RPC_X_SS_CONTEXT_DAMAGED         1777L
-#define RPC_X_SS_HANDLES_MISMATCH        1778L
-#define RPC_X_SS_CANNOT_GET_CALL_HANDLE  1779L
-#define RPC_X_NULL_REF_POINTER           1780L
-#define RPC_X_ENUM_VALUE_OUT_OF_RANGE    1781L
-#define RPC_X_BYTE_COUNT_TOO_SMALL       1782L
-#define RPC_X_BAD_STUB_DATA              1783L
-#define ERROR_INVALID_USER_BUFFER        1784L
-#define ERROR_UNRECOGNIZED_MEDIA         1785L
-#define ERROR_NO_TRUST_LSA_SECRET        1786L
-#define ERROR_NO_TRUST_SAM_ACCOUNT       1787L
-#define ERROR_TRUSTED_DOMAIN_FAILURE     1788L
-#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789L
-#define ERROR_TRUST_FAILURE              1790L
-#define RPC_S_CALL_IN_PROGRESS           1791L
-#define ERROR_NETLOGON_NOT_STARTED       1792L
-#define ERROR_ACCOUNT_EXPIRED            1793L
-#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794L
-#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795L
-#define ERROR_UNKNOWN_PORT               1796L
-#define ERROR_UNKNOWN_PRINTER_DRIVER     1797L
-#define ERROR_UNKNOWN_PRINTPROCESSOR     1798L
-#define ERROR_INVALID_SEPARATOR_FILE     1799L
-#define ERROR_INVALID_PRIORITY           1800L
-#define ERROR_INVALID_PRINTER_NAME       1801L
-#define ERROR_PRINTER_ALREADY_EXISTS     1802L
-#define ERROR_INVALID_PRINTER_COMMAND    1803L
-#define ERROR_INVALID_DATATYPE           1804L
-#define ERROR_INVALID_ENVIRONMENT        1805L
-#define RPC_S_NO_MORE_BINDINGS           1806L
-#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807L
-#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808L
-#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809L
-#define ERROR_DOMAIN_TRUST_INCONSISTENT  1810L
-#define ERROR_SERVER_HAS_OPEN_HANDLES    1811L
-#define ERROR_RESOURCE_DATA_NOT_FOUND    1812L
-#define ERROR_RESOURCE_TYPE_NOT_FOUND    1813L
-#define ERROR_RESOURCE_NAME_NOT_FOUND    1814L
-#define ERROR_RESOURCE_LANG_NOT_FOUND    1815L
-#define ERROR_NOT_ENOUGH_QUOTA           1816L
-#define RPC_S_NO_INTERFACES              1817L
-#define RPC_S_CALL_CANCELLED             1818L
-#define RPC_S_BINDING_INCOMPLETE         1819L
-#define RPC_S_COMM_FAILURE               1820L
-#define RPC_S_UNSUPPORTED_AUTHN_LEVEL    1821L
-#define RPC_S_NO_PRINC_NAME              1822L
-#define RPC_S_NOT_RPC_ERROR              1823L
-#define RPC_S_UUID_LOCAL_ONLY            1824L
-#define RPC_S_SEC_PKG_ERROR              1825L
-#define RPC_S_NOT_CANCELLED              1826L
-#define RPC_X_INVALID_ES_ACTION          1827L
-#define RPC_X_WRONG_ES_VERSION           1828L
-#define RPC_X_WRONG_STUB_VERSION         1829L
-#define RPC_X_INVALID_PIPE_OBJECT        1830L
-#define RPC_X_WRONG_PIPE_ORDER           1831L
-#define RPC_X_WRONG_PIPE_VERSION         1832L
-#define RPC_S_GROUP_MEMBER_NOT_FOUND     1898L
-#define EPT_S_CANT_CREATE                1899L
-#define RPC_S_INVALID_OBJECT             1900L
-#define ERROR_INVALID_TIME               1901L
-#define ERROR_INVALID_FORM_NAME          1902L
-#define ERROR_INVALID_FORM_SIZE          1903L
-#define ERROR_ALREADY_WAITING            1904L
-#define ERROR_PRINTER_DELETED            1905L
-#define ERROR_INVALID_PRINTER_STATE      1906L
-#define ERROR_PASSWORD_MUST_CHANGE       1907L
-#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908L
-#define ERROR_ACCOUNT_LOCKED_OUT         1909L
-#define OR_INVALID_OXID                  1910L
-#define OR_INVALID_OID                   1911L
-#define OR_INVALID_SET                   1912L
-#define RPC_S_SEND_INCOMPLETE            1913L
-#define ERROR_INVALID_PIXEL_FORMAT       2000L
-#define ERROR_BAD_DRIVER                 2001L
-#define ERROR_INVALID_WINDOW_STYLE       2002L
-#define ERROR_METAFILE_NOT_SUPPORTED     2003L
-#define ERROR_TRANSFORM_NOT_SUPPORTED    2004L
-#define ERROR_CLIPPING_NOT_SUPPORTED     2005L
-#define ERROR_BAD_USERNAME               2202L
-#define ERROR_NOT_CONNECTED              2250L
-#define ERROR_OPEN_FILES                 2401L
-#define ERROR_ACTIVE_CONNECTIONS         2402L
-#define ERROR_DEVICE_IN_USE              2404L
-#define ERROR_UNKNOWN_PRINT_MONITOR      3000L
-#define ERROR_PRINTER_DRIVER_IN_USE      3001L
-#define ERROR_SPOOL_FILE_NOT_FOUND       3002L
-#define ERROR_SPL_NO_STARTDOC            3003L
-#define ERROR_SPL_NO_ADDJOB              3004L
-#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005L
-#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006L
-#define ERROR_WINS_INTERNAL              4000L
-#define ERROR_CAN_NOT_DEL_LOCAL_WINS     4001L
-#define ERROR_STATIC_INIT                4002L
-#define ERROR_INC_BACKUP                 4003L
-#define ERROR_FULL_BACKUP                4004L
-#define ERROR_REC_NON_EXISTENT           4005L
-#define ERROR_RPL_NOT_ALLOWED            4006L
-#define ERROR_NO_BROWSER_SERVERS_FOUND   6118L
-#endif
-
-
-/* HRESULT values for OLE, SHELL and other Interface stuff */
-/* the codes 4000-40ff are reserved for OLE */
-#define NOERROR                                            0L
-
-#define E_PENDING                                          0x8000000AL
-
-
-#define E_NOTIMPL                                          0x80004001L
-#define E_NOINTERFACE                                      0x80004002L
-#define E_POINTER                                          0x80004003L
-#define E_ABORT                                            0x80004004L
-#define E_FAIL                                             0x80004005L
-/* FIXME: E_UNSPEC is not a standard value but it is used by 
- * FileMoniker, IOleLink and DoDragDrop as a return value.
- */
-#define E_UNSPEC                                           E_FAIL
-
-
-#define CO_E_INIT_TLS                                      0x80004006L
-#define CO_E_INIT_SHARED_ALLOCATOR                         0x80004007L
-#define CO_E_INIT_MEMORY_ALLOCATOR                         0x80004008L
-#define CO_E_INIT_CLASS_CACHE                              0x80004009L
-#define CO_E_INIT_RPC_CHANNEL                              0x8000400AL
-#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL                  0x8000400BL
-#define CO_E_INIT_TLS_CHANNEL_CONTROL                      0x8000400CL
-#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR                0x8000400DL
-#define CO_E_INIT_SCM_MUTEX_EXISTS                         0x8000400EL
-#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS                  0x8000400FL
-#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE                     0x80004010L
-#define CO_E_INIT_SCM_EXEC_FAILURE                         0x80004011L
-#define CO_E_INIT_ONLY_SINGLE_THREADED                     0x80004012L
-
-#define E_UNEXPECTED                                       0x8000FFFFL
-
-#define RPC_E_CALL_REJECTED                                0x80010001L
-#define RPC_E_CALL_CANCELED                                0x80010002L
-#define RPC_E_CANTPOST_INSENDCALL                          0x80010003L
-#define RPC_E_CANTCALLOUT_INASYNCCALL                      0x80010004L
-#define RPC_E_CANTCALLOUT_INEXTERNALCALL                   0x80010005L
-#define RPC_E_CONNECTION_TERMINATED                        0x80010006L
-#define RPC_E_SERVER_DIED                                  0x80010007L
-#define RPC_E_CLIENT_DIED                                  0x80010008L
-#define RPC_E_INVALID_DATAPACKET                           0x80010009L
-#define RPC_E_CANTTRANSMIT_CALL                            0x8001000AL
-#define RPC_E_CLIENT_CANTMARSHAL_DATA                      0x8001000BL
-#define RPC_E_CLIENT_CANTUNMARSHAL_DATA                    0x8001000CL
-#define RPC_E_SERVER_CANTMARSHAL_DATA                      0x8001000DL
-#define RPC_E_SERVER_CANTUNMARSHAL_DATA                    0x8001000EL
-#define RPC_E_INVALID_DATA                                 0x8001000FL
-#define RPC_E_INVALID_PARAMETER                            0x80010010L
-#define RPC_E_CANTCALLOUT_AGAIN                            0x80010011L
-#define RPC_E_SERVER_DIED_DNE                              0x80010012L
-#define RPC_E_SYS_CALL_FAILED                              0x80010100L
-#define RPC_E_OUT_OF_RESOURCES                             0x80010101L
-#define RPC_E_ATTEMPTED_MULTITHREAD                        0x80010102L
-#define RPC_E_NOT_REGISTERED                               0x80010103L
-#define RPC_E_FAULT                                        0x80010104L
-#define RPC_E_SERVERFAULT                                  0x80010105L
-#define RPC_E_CHANGED_MODE                                 0x80010106L
-#define RPC_E_INVALIDMETHOD                                0x80010107L
-#define RPC_E_DISCONNECTED                                 0x80010108L
-#define RPC_E_RETRY                                        0x80010109L
-#define RPC_E_SERVERCALL_RETRYLATER                        0x8001010AL
-#define RPC_E_SERVERCALL_REJECTED                          0x8001010BL
-#define RPC_E_INVALID_CALLDATA                             0x8001010CL
-#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL                  0x8001010DL
-#define RPC_E_WRONG_THREAD                                 0x8001010EL
-#define RPC_E_THREAD_NOT_INIT                              0x8001010FL
-#define RPC_E_VERSION_MISMATCH                             0x80010110L
-#define RPC_E_INVALID_HEADER                               0x80010111L
-#define RPC_E_INVALID_EXTENSION                            0x80010112L
-#define RPC_E_INVALID_IPID                                 0x80010113L
-#define RPC_E_INVALID_OBJECT                               0x80010114L
-#define RPC_S_CALLPENDING                                  0x80010115L
-#define RPC_S_WAITONTIMER                                  0x80010116L
-#define RPC_E_CALL_COMPLETE                                0x80010117L
-#define RPC_E_UNSECURE_CALL                                0x80010118L
-#define RPC_E_TOO_LATE                                     0x80010119L
-#define RPC_E_NO_GOOD_SECURITY_PACKAGES                    0x8001011AL
-#define RPC_E_ACCESS_DENIED                                0x8001011BL
-#define RPC_E_REMOTE_DISABLED                              0x8001011CL
-#define RPC_E_INVALID_OBJREF                               0x8001011DL
-#define RPC_E_NO_CONTEXT                                   0x8001011EL
-#define RPC_E_TIMEOUT                                      0x8001011FL
-#define RPC_E_NO_SYNC                                      0x80010120L
-#define RPC_E_UNEXPECTED                                   0x8001FFFFL
-
-#define DISP_E_UNKNOWNINTERFACE                            0x80020001L
-#define DISP_E_MEMBERNOTFOUND                              0x80020003L
-#define DISP_E_PARAMNOTFOUND                               0x80020004L
-#define DISP_E_TYPEMISMATCH                                0x80020005L
-#define DISP_E_UNKNOWNNAME                                 0x80020006L
-#define DISP_E_NONAMEDARGS                                 0x80020007L
-#define DISP_E_BADVARTYPE                                  0x80020008L
-#define DISP_E_EXCEPTION                                   0x80020009L
-#define DISP_E_OVERFLOW                                    0x8002000AL
-#define DISP_E_BADINDEX                                    0x8002000BL
-#define DISP_E_UNKNOWNLCID                                 0x8002000CL
-#define DISP_E_ARRAYISLOCKED                               0x8002000DL
-#define DISP_E_BADPARAMCOUNT                               0x8002000EL
-#define DISP_E_PARAMNOTOPTIONAL                            0x8002000FL
-#define DISP_E_BADCALLEE                                   0x80020010L
-#define DISP_E_NOTACOLLECTION                              0x80020011L
-#define DISP_E_DIVBYZERO                                   0x80020012L
-
-#define TYPE_E_BUFFERTOOSMALL                              0x80028016L
-#define TYPE_E_FIELDNOTFOUND                               0x80028017L
-#define TYPE_E_INVDATAREAD                                 0x80028018L
-#define TYPE_E_UNSUPFORMAT                                 0x80028019L
-#define TYPE_E_REGISTRYACCESS                              0x8002801CL
-#define TYPE_E_LIBNOTREGISTERED                            0x8002801DL
-#define TYPE_E_UNDEFINEDTYPE                               0x80028027L
-#define TYPE_E_QUALIFIEDNAMEDISALLOWED                     0x80028028L
-#define TYPE_E_INVALIDSTATE                                0x80028029L
-#define TYPE_E_WRONGTYPEKIND                               0x8002802AL
-#define TYPE_E_ELEMENTNOTFOUND                             0x8002802BL
-#define TYPE_E_AMBIGUOUSNAME                               0x8002802CL
-#define TYPE_E_NAMECONFLICT                                0x8002802DL
-#define TYPE_E_UNKNOWNLCID                                 0x8002802EL
-#define TYPE_E_DLLFUNCTIONNOTFOUND                         0x8002802FL
-#define TYPE_E_BADMODULEKIND                               0x800288BDL
-#define TYPE_E_SIZETOOBIG                                  0x800288C5L
-#define TYPE_E_DUPLICATEID                                 0x800288C6L
-#define TYPE_E_INVALIDID                                   0x800288CFL
-#define TYPE_E_TYPEMISMATCH                                0x80028CA0L
-#define TYPE_E_OUTOFBOUNDS                                 0x80028CA1L
-#define TYPE_E_IOERROR                                     0x80028CA2L
-#define TYPE_E_CANTCREATETMPFILE                           0x80028CA3L
-#define TYPE_E_CANTLOADLIBRARY                             0x80029C4AL
-#define TYPE_E_INCONSISTENTPROPFUNCS                       0x80029C83L
-#define TYPE_E_CIRCULARTYPE                                0x80029C84L
-
-#define STG_S_CONVERTED                                    0x00030200L
-#define STG_S_BLOCK                                        0x00030201L
-#define STG_S_RETRYNOW                                     0x00030202L
-#define STG_S_MONITORING                                   0x00030203L
-#define STG_S_MULTIPLEOPENS                                0x00030204L
-#define STG_S_CONSOLIDATIONFAILED                          0x00030205L
-#define STG_S_CANNOTCONSOLIDATE                            0x00030206L
-
-#define STG_E_INVALIDFUNCTION                              0x80030001L
-#define STG_E_FILENOTFOUND                                 0x80030002L
-#define STG_E_PATHNOTFOUND                                 0x80030003L
-#define STG_E_TOOMANYOPENFILES                             0x80030004L
-#define STG_E_ACCESSDENIED                                 0x80030005L
-#define STG_E_INVALIDHANDLE                                0x80030006L
-#define STG_E_INSUFFICIENTMEMORY                           0x80030008L
-#define STG_E_INVALIDPOINTER                               0x80030009L
-#define STG_E_NOMOREFILES                                  0x80030012L
-#define STG_E_DISKISWRITEPROTECTED                         0x80030013L
-#define STG_E_SEEKERROR                                    0x80030019L
-#define STG_E_WRITEFAULT                                   0x8003001DL
-#define STG_E_READFAULT                                    0x8003001EL
-#define STG_E_SHAREVIOLATION                               0x80030020L
-#define STG_E_LOCKVIOLATION                                0x80030021L
-#define STG_E_FILEALREADYEXISTS                            0x80030050L
-#define STG_E_INVALIDPARAMETER                             0x80030057L
-#define STG_E_MEDIUMFULL                                   0x80030070L
-#define STG_E_ABNORMALAPIEXIT                              0x800300FAL
-#define STG_E_INVALIDHEADER                                0x800300FBL
-#define STG_E_INVALIDNAME                                  0x800300FCL
-#define STG_E_UNKNOWN                                      0x800300FDL
-#define STG_E_UNIMPLEMENTEDFUNCTION                        0x800300FEL
-#define STG_E_INVALIDFLAG                                  0x800300FFL
-#define STG_E_INUSE                                        0x80030100L
-#define STG_E_NOTCURRENT                                   0x80030101L
-#define STG_E_REVERTED                                     0x80030102L
-#define STG_E_CANTSAVE                                     0x80030103L
-#define STG_E_OLDFORMAT                                    0x80030104L
-#define STG_E_OLDDLL                                       0x80030105L
-#define STG_E_SHAREREQUIRED                                0x80030106L
-#define STG_E_NOTFILEBASEDSTORAGE                          0x80030107L
-#define STG_E_EXTANTMARSHALLINGS                           0x80030108L
-
-#define OLE_S_FIRST                                        0x00040000L
-#define OLE_S_USEREG                                       0x00040000L
-#define OLE_S_STATIC                                       0x00040001L
-#define OLE_S_MAC_CLIPFORMAT                               0x00040002L
-#define OLE_S_LAST                                         0x000400FFL
-
-#define OLE_E_FIRST                                        0x80040000L
-#define OLE_E_OLEVERB                                      0x80040000L
-#define OLE_E_ADVF                                         0x80040001L
-#define OLE_E_ENUM_NOMORE                                  0x80040002L
-#define OLE_E_ADVISENOTSUPPORTED                           0x80040003L
-#define OLE_E_NOCONNECTION                                 0x80040004L
-#define OLE_E_NOTRUNNING                                   0x80040005L
-#define OLE_E_NOCACHE                                      0x80040006L
-#define OLE_E_BLANK                                        0x80040007L
-#define OLE_E_CLASSDIFF                                    0x80040008L
-#define OLE_E_CANT_GETMONIKER                              0x80040009L
-#define OLE_E_CANT_BINDTOSOURCE                            0x8004000AL
-#define OLE_E_STATIC                                       0x8004000BL
-#define OLE_E_PROMPTSAVECANCELLED                          0x8004000CL
-#define OLE_E_INVALIDRECT                                  0x8004000DL
-#define OLE_E_WRONGCOMPOBJ                                 0x8004000EL
-#define OLE_E_INVALIDHWND                                  0x8004000FL
-#define OLE_E_NOT_INPLACEACTIVE                            0x80040010L
-#define OLE_E_CANTCONVERT                                  0x80040011L
-#define OLE_E_NOSTORAGE                                    0x80040012L
-#define DV_E_FORMATETC                                     0x80040064L
-#define DV_E_DVTARGETDEVICE                                0x80040065L
-#define DV_E_STGMEDIUM                                     0x80040066L
-#define DV_E_STATDATA                                      0x80040067L
-#define DV_E_LINDEX                                        0x80040068L
-#define DV_E_TYMED                                         0x80040069L
-#define DV_E_CLIPFORMAT                                    0x8004006AL
-#define DV_E_DVASPECT                                      0x8004006BL
-#define DV_E_DVTARGETDEVICE_SIZE                           0x8004006CL
-#define DV_E_NOIVIEWOBJECT                                 0x8004006DL
-#define OLE_E_LAST                                         0x800400FFL
-
-#define DRAGDROP_S_FIRST                                   0x00040100L
-#define DRAGDROP_S_DROP                                    0x00040100L
-#define DRAGDROP_S_CANCEL                                  0x00040101L
-#define DRAGDROP_S_USEDEFAULTCURSORS                       0x00040102L
-#define DRAGDROP_S_LAST                                    0x0004010FL
-
-#define DRAGDROP_E_FIRST                                   0x80040100L
-#define DRAGDROP_E_NOTREGISTERED                           0x80040100L
-#define DRAGDROP_E_ALREADYREGISTERED                       0x80040101L
-#define DRAGDROP_E_INVALIDHWND                             0x80040102L
-#define DRAGDROP_E_LAST                                    0x8004010FL
-
-
-#define CLASSFACTORY_S_FIRST                               0x00040110L
-#define CLASSFACTORY_S_LAST                                0x0004011FL
-
-#define CLASSFACTORY_E_FIRST                               0x80040110L
-#define CLASS_E_NOAGGREGATION                              0x80040110L
-#define CLASS_E_CLASSNOTAVAILABLE                          0x80040111L
-#define CLASS_E_NOTLICENSED                                0x80040112L
-#define CLASSFACTORY_E_LAST                                0x8004011FL
-
-#define MARSHAL_S_FIRST                                    0x00040120L
-#define MARSHAL_S_LAST                                     0x0004012FL
-
-#define MARSHAL_E_FIRST                                    0x80040120L
-#define MARSHAL_E_LAST                                     0x8004012FL
-
-#define DATA_S_FIRST                                       0x00040130L
-#define DATA_S_SAMEFORMATETC                               0x00040130L
-#define DATA_S_LAST                                        0x0004013FL
-
-#define DATA_E_FIRST                                       0x80040130L
-#define DATA_E_LAST                                        0x8004013FL
-
-#define VIEW_S_FIRST                                       0x00040140L
-#define VIEW_S_ALREADY_FROZEN                              0x00040140L
-#define VIEW_S_LAST                                        0x0004014FL
-
-#define VIEW_E_FIRST                                       0x80040140L
-#define VIEW_E_DRAW                                        0x80040140L
-#define VIEW_E_LAST                                        0x8004014FL
-
-#define REGDB_S_FIRST                                      0x00040150L
-#define REGDB_S_LAST                                       0x0004015FL
-
-#define REGDB_E_FIRST                                      0x80040150L
-#define REGDB_E_READREGDB                                  0x80040150L
-#define REGDB_E_WRITEREGDB                                 0x80040151L
-#define REGDB_E_KEYMISSING                                 0x80040152L
-#define REGDB_E_INVALIDVALUE                               0x80040153L
-#define REGDB_E_CLASSNOTREG                                0x80040154L
-#define REGDB_E_IIDNOTREG                                  0x80040155L
-#define REGDB_E_LAST                                       0x8004015FL
-
-#define CACHE_S_FIRST                                      0x00040170L
-#define CACHE_S_FORMATETC_NOTSUPPORTED                     0x00040170L
-#define CACHE_S_SAMECACHE                                  0x00040171L
-#define CACHE_S_SOMECACHES_NOTUPDATED                      0x00040172L
-#define CACHE_S_LAST                                       0x0004017FL
-
-#define CACHE_E_FIRST                                      0x80040170L
-#define CACHE_E_NOCACHE_UPDATED                            0x80040170L
-#define CACHE_E_LAST                                       0x8004017FL
-
-#define OLEOBJ_S_FIRST                                     0x00040180L
-#define OLEOBJ_S_INVALIDVERB                               0x00040180L
-#define OLEOBJ_S_CANNOT_DOVERB_NOW                         0x00040181L
-#define OLEOBJ_S_INVALIDHWND                               0x00040182L
-#define OLEOBJ_S_LAST                                      0x0004018FL
-
-#define OLEOBJ_E_FIRST                                     0x80040180L
-#define OLEOBJ_E_NOVERBS                                   0x80040180L
-#define OLEOBJ_E_INVALIDVERB                               0x80040181L
-#define OLEOBJ_E_LAST                                      0x8004018FL
-
-#define CLIENTSITE_S_FIRST                                 0x00040190L
-#define CLIENTSITE_S_LAST                                  0x0004019FL
-
-#define CLIENTSITE_E_FIRST                                 0x80040190L
-#define CLIENTSITE_E_LAST                                  0x8004019FL
-
-#define INPLACE_S_FIRST                                    0x000401A0L
-#define INPLACE_S_TRUNCATED                                0x000401A0L
-#define INPLACE_S_LAST                                     0x000401AFL
-
-#define INPLACE_E_FIRST                                    0x800401A0L
-#define INPLACE_E_NOTUNDOABLE                              0x800401A0L
-#define INPLACE_E_NOTOOLSPACE                              0x800401A1L
-#define INPLACE_E_LAST                                     0x800401AFL
-
-#define ENUM_S_FIRST                                       0x000401B0L
-#define ENUM_S_LAST                                        0x000401BFL
-
-#define ENUM_E_FIRST                                       0x800401B0L
-#define ENUM_E_LAST                                        0x800401BFL
-
-#define CONVERT10_S_FIRST                                  0x000401C0L
-#define CONVERT10_S_NO_PRESENTATION                        0x000401C0L
-#define CONVERT10_S_LAST                                   0x000401CFL
-
-#define CONVERT10_E_FIRST                                  0x800401C0L
-#define CONVERT10_E_OLESTREAM_GET                          0x800401C0L
-#define CONVERT10_E_OLESTREAM_PUT                          0x800401C1L
-#define CONVERT10_E_OLESTREAM_FMT                          0x800401C2L
-#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB                0x800401C3L
-#define CONVERT10_E_STG_FMT                                0x800401C4L
-#define CONVERT10_E_STG_NO_STD_STREAM                      0x800401C5L
-#define CONVERT10_E_STG_DIB_TO_BITMAP                      0x800401C6L
-#define CONVERT10_E_LAST                                   0x800401CFL
-
-#define CLIPBRD_S_FIRST                                    0x000401D0L
-#define CLIPBRD_S_LAST                                     0x000401DFL
-
-#define CLIPBRD_E_FIRST                                    0x800401D0L
-#define CLIPBRD_E_LAST                                     0x800401DFL
-#define CLIPBRD_E_CANT_OPEN                                0x800401D0L
-#define CLIPBRD_E_CANT_EMPTY                               0x800401D1L
-#define CLIPBRD_E_CANT_SET                                 0x800401D2L
-#define CLIPBRD_E_BAD_DATA                                 0x800401D3L
-#define CLIPBRD_E_CANT_CLOSE                               0x800401D4L
-
-#define MK_S_FIRST                                         0x000401E0L
-#define MK_S_REDUCED_TO_SELF                               0x000401E2L
-#define MK_S_ME                                            0x000401E4L
-#define MK_S_HIM                                           0x000401E5L
-#define MK_S_US                                            0x000401E6L
-#define MK_S_MONIKERALREADYREGISTERED                      0x000401E7L
-#define MK_S_LAST                                          0x000401EFL
-
-#define MK_E_FIRST                                         0x800401E0L
-#define MK_E_CONNECTMANUALLY                               0x800401E0L
-#define MK_E_EXCEEDEDDEADLINE                              0x800401E1L
-#define MK_E_NEEDGENERIC                                   0x800401E2L
-#define MK_E_UNAVAILABLE                                   0x800401E3L
-#define MK_E_SYNTAX                                        0x800401E4L
-#define MK_E_NOOBJECT                                      0x800401E5L
-#define MK_E_INVALIDEXTENSION                              0x800401E6L
-#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED             0x800401E7L
-#define MK_E_NOTBINDABLE                                   0x800401E8L
-#define MK_E_NOTBOUND                                      0x800401E9L
-#define MK_E_CANTOPENFILE                                  0x800401EAL
-#define MK_E_MUSTBOTHERUSER                                0x800401EBL
-#define MK_E_NOINVERSE                                     0x800401ECL
-#define MK_E_NOSTORAGE                                     0x800401EDL
-#define MK_E_NOPREFIX                                      0x800401EEL
-#define MK_E_ENUMERATION_FAILED                            0x800401EFL
-#define MK_E_LAST                                          0x800401EFL
-
-#define CO_S_FIRST                                         0x000401F0L
-#define CO_S_LAST                                          0x000401FFL
-
-#define CO_E_FIRST                                         0x800401F0L
-#define CO_E_NOTINITIALIZED                                0x800401F0L
-#define CO_E_ALREADYINITIALIZED                            0x800401F1L
-#define CO_E_CANTDETERMINECLASS                            0x800401F2L
-#define CO_E_CLASSSTRING                                   0x800401F3L
-#define CO_E_IIDSTRING                                     0x800401F4L
-#define CO_E_APPNOTFOUND                                   0x800401F5L
-#define CO_E_APPSINGLEUSE                                  0x800401F6L
-#define CO_E_ERRORINAPP                                    0x800401F7L
-#define CO_E_DLLNOTFOUND                                   0x800401F8L
-#define CO_E_ERRORINDLL                                    0x800401F9L
-#define CO_E_WRONGOSFORAPP                                 0x800401FAL
-#define CO_E_OBJNOTREG                                     0x800401FBL
-#define CO_E_OBJISREG                                      0x800401FCL
-#define CO_E_OBJNOTCONNECTED                               0x800401FDL
-#define CO_E_APPDIDNTREG                                   0x800401FEL
-#define CO_E_RELEASED                                      0x800401FFL
-#define CO_E_LAST                                          0x800401FFL
-#define CO_E_FAILEDTOIMPERSONATE                           0x80040200L
-#define CO_E_FAILEDTOGETSECCTX                             0x80040201L
-#define CO_E_FAILEDTOOPENTHREADTOKEN                       0x80040202L
-#define CO_E_FAILEDTOGETTOKENINFO                          0x80040203L
-#define CO_E_TRUSTEEDOESNTMATCHCLIENT                      0x80040204L
-#define CO_E_FAILEDTOQUERYCLIENTBLANKET                    0x80040205L
-#define CO_E_FAILEDTOSETDACL                               0x80040206L
-#define CO_E_ACCESSCHECKFAILED                             0x80040207L
-#define CO_E_NETACCESSAPIFAILED                            0x80040208L
-#define CO_E_WRONGTRUSTEENAMESYNTAX                        0x80040209L
-#define CO_E_INVALIDSID                                    0x8004020AL
-#define CO_E_CONVERSIONFAILED                              0x8004020BL
-#define CO_E_NOMATCHINGSIDFOUND                            0x8004020CL
-#define CO_E_LOOKUPACCSIDFAILED                            0x8004020DL
-#define CO_E_NOMATCHINGNAMEFOUND                           0x8004020EL
-#define CO_E_LOOKUPACCNAMEFAILED                           0x8004020FL
-#define CO_E_SETSERLHNDLFAILED                             0x80040210L
-#define CO_E_FAILEDTOGETWINDIR                             0x80040211L
-#define CO_E_PATHTOOLONG                                   0x80040212L
-#define CO_E_FAILEDTOGENUUID                               0x80040213L
-#define CO_E_FAILEDTOCREATEFILE                            0x80040214L
-#define CO_E_FAILEDTOCLOSEHANDLE                           0x80040215L
-#define CO_E_EXCEEDSYSACLLIMIT                             0x80040216L
-#define CO_E_ACESINWRONGORDER                              0x80040217L
-#define CO_E_INCOMPATIBLESTREAMVERSION                     0x80040218L
-#define CO_E_FAILEDTOOPENPROCESSTOKEN                      0x80040219L
-#define CO_E_DECODEFAILED                                  0x8004021AL
-#define CO_E_ACNOTINITIALIZED                              0x8004021BL
-
-#define E_ACCESSDENIED                                     0x80070005L
-#define E_HANDLE                                           0x80070006L
-#define E_OUTOFMEMORY                                      0x8007000EL
-#define E_INVALIDARG                                       0x80070057L
-
-#define CO_S_NOTALLINTERFACES                              0x00080012L
-
-#define CO_E_CLASS_CREATE_FAILED                           0x80080001L
-#define CO_E_SCM_ERROR                                     0x80080002L
-#define CO_E_SCM_RPC_FAILURE                               0x80080003L
-#define CO_E_BAD_PATH                                      0x80080004L
-#define CO_E_SERVER_EXEC_FAILURE                           0x80080005L
-#define CO_E_OBJSRV_RPC_FAILURE                            0x80080006L
-#define MK_E_NO_NORMALIZED                                 0x80080007L
-#define CO_E_SERVER_STOPPING                               0x80080008L
-#define MEM_E_INVALID_ROOT                                 0x80080009L
-#define MEM_E_INVALID_LINK                                 0x80080010L
-#define MEM_E_INVALID_SIZE                                 0x80080011L
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* !__USE_W32API */
-
-#endif /* _GNU_H_WINDOWS32_ERROR */
index 52a153c..2b30af5 100644 (file)
@@ -57,9 +57,9 @@ typedef PPROGRESS_ROUTINE LPPROGRESS_ROUTINE;
 #include <unicode.h>
 #endif /* !UNICODE_ONLY */
 
-#ifndef ANSI_ONLY
-#include <ascii.h>
-#endif /* !ANSI_ONLY */
+//#ifndef ANSI_ONLY
+//#include <ascii.h>
+//#endif /* !ANSI_ONLY */
 
 /* Define the approprate declaration based upon UNICODE or ASCII */
 
diff --git a/reactos/include/idl/idl.xml b/reactos/include/idl/idl.xml
new file mode 100644 (file)
index 0000000..57f5d45
--- /dev/null
@@ -0,0 +1,12 @@
+<module name="pnp_server" type="rpcserver">
+       <include base="ReactOS">.</include>
+       <include base="ReactOS">w32api/include</include>
+       <define name="_X86_" />
+       <file>pnp.idl</file>
+</module>
+<module name="pnp_client" type="rpcclient">
+       <include base="ReactOS">.</include>
+       <include base="ReactOS">w32api/include</include>
+       <define name="_X86_" />
+       <file>pnp.idl</file>
+</module>
diff --git a/reactos/include/idl/pnp.idl b/reactos/include/idl/pnp.idl
new file mode 100644 (file)
index 0000000..57481d1
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+ * Plug and Play Manager interface definition\r
+ */\r
+\r
+#define WORD unsigned short\r
+\r
+[\r
+  uuid (809F4e40-A03D-11CE-8F69-08003E30051B),\r
+  version(1.0),\r
+  pointer_default(unique),\r
+  explicit_handle\r
+]\r
+interface pnp\r
+{\r
+//  unsigned long PNP_GetRootDeviceInstance(handle_t BindingHandle,\r
+//                                       [out, string, size_is(Length)] wchar_t *DeviceInstance,\r
+//                                       [in] unsigned long Length);\r
+  WORD PNP_GetVersion(handle_t BindingHandle);\r
+}\r
diff --git a/reactos/include/messages.h b/reactos/include/messages.h
deleted file mode 100644 (file)
index 821693c..0000000
+++ /dev/null
@@ -1,1144 +0,0 @@
-/* 
-   Messages.h
-
-   Windows32 API message definitions
-
-   Copyright (C) 1996 Free Software Foundation, Inc.
-
-   Author: Scott Christley <scottc@net-community.com>
-
-   This file is part of the Windows32 API Library.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 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
-   Library General Public License for more details.
-
-   If you are interested in a warranty or support for this source code,
-   contact Scott Christley <scottc@net-community.com> for more information.
-   
-   You should have received a copy of the GNU Library General Public
-   License along with this library; see the file COPYING.LIB.
-   If not, write to the Free Software Foundation, 
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-/* WARNING:  This file is automatically generated. */
-
-#ifndef _GNU_H_WINDOWS32_MESSAGES
-#define _GNU_H_WINDOWS32_MESSAGES
-
-#ifdef __USE_W32API
-
-#include <winuser.h>
-
-#else /* __USE_W32API */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-/* Application bar */
-
-/* Application bar notifications */
-
-/* Animation Control */
-#define ACM_OPENW      (1127)
-#define ACM_OPENA      (1124)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define ACM_OPEN ACM_OPENW
-#else
-#define ACM_OPEN ACM_OPENA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define ACM_PLAY       (1125)
-#define ACM_STOP       (1126)
-#define ACN_START      (1)
-#define ACN_STOP       (2)
-
-/* Buttons */
-#define BM_CLICK       (245)
-#define BM_GETCHECK    (240)
-#define BM_GETIMAGE    (246)
-#define BM_GETSTATE    (242)
-#define BM_SETCHECK    (241)
-#define BM_SETIMAGE    (247)
-#define BM_SETSTATE    (243)
-#define BM_SETSTYLE    (244)
-#define BN_CLICKED     (0)
-#define BN_DBLCLK      (5)
-#define BN_DISABLE     (4)
-#define BN_DOUBLECLICKED       (5)
-#define BN_HILITE      (2)
-#define BN_KILLFOCUS   (7)
-#define BN_PAINT       (1)
-#define BN_PUSHED      (2)
-#define BN_SETFOCUS    (6)
-#define BN_UNHILITE    (3)
-#define BN_UNPUSHED    (3)
-
-/* Combo Box */
-#define CB_ADDSTRING   (323)
-#define CB_DELETESTRING        (324)
-#define CB_DIR (325)
-#define CB_FINDSTRING  (332)
-#define CB_FINDSTRINGEXACT     (344)
-#define CB_GETCOUNT    (326)
-#define CB_GETCURSEL   (327)
-#define CB_GETDROPPEDCONTROLRECT       (338)
-#define CB_GETDROPPEDSTATE     (343)
-#define CB_GETDROPPEDWIDTH     (351)
-#define CB_GETEDITSEL  (320)
-#define CB_GETEXTENDEDUI       (342)
-#define CB_GETHORIZONTALEXTENT (349)
-#define CB_GETITEMDATA (336)
-#define CB_GETITEMHEIGHT       (340)
-#define CB_GETLBTEXT   (328)
-#define CB_GETLBTEXTLEN        (329)
-#define CB_GETLOCALE   (346)
-#define CB_GETTOPINDEX (347)
-#define CB_INITSTORAGE (353)
-#define CB_INSERTSTRING        (330)
-#define CB_LIMITTEXT   (321)
-#define CB_RESETCONTENT        (331)
-#define CB_SELECTSTRING        (333)
-#define CB_SETCURSEL   (334)
-#define CB_SETDROPPEDWIDTH     (352)
-#define CB_SETEDITSEL  (322)
-#define CB_SETEXTENDEDUI       (341)
-#define CB_SETHORIZONTALEXTENT (350)
-#define CB_SETITEMDATA (337)
-#define CB_SETITEMHEIGHT       (339)
-#define CB_SETLOCALE   (345)
-#define CB_SETTOPINDEX (348)
-#define CB_SHOWDROPDOWN        (335)
-
-/* Combo Box notifications */
-#define CBN_CLOSEUP    (8)
-#define CBN_DBLCLK     (2)
-#define CBN_DROPDOWN   (7)
-#define CBN_EDITCHANGE (5)
-#define CBN_EDITUPDATE (6)
-#define CBN_ERRSPACE   (-1)
-#define CBN_KILLFOCUS  (4)
-#define CBN_SELCHANGE  (1)
-#define CBN_SELENDCANCEL       (10)
-#define CBN_SELENDOK   (9)
-#define CBN_SETFOCUS   (3)
-
-/* Control Panel */
-
-/* Device messages */
-
-/* Drag list box */
-#define DL_BEGINDRAG   (1157)
-#define DL_CANCELDRAG  (1160)
-#define DL_DRAGGING    (1158)
-#define DL_DROPPED     (1159)
-
-/* Default push button */
-#define DM_GETDEFID    (1024)
-#define DM_REPOSITION  (1026)
-#define DM_SETDEFID    (1025)
-
-/* RTF control */
-#define EM_CANPASTE    (1074)
-#define EM_CANUNDO     (198)
-#define EM_CHARFROMPOS (215)
-#define EM_DISPLAYBAND (1075)
-#define EM_EMPTYUNDOBUFFER     (205)
-#define EM_EXGETSEL    (1076)
-#define EM_EXLIMITTEXT (1077)
-#define EM_EXLINEFROMCHAR      (1078)
-#define EM_EXSETSEL    (1079)
-#define EM_FINDTEXT    (1080)
-#define EM_FINDTEXTEX  (1103)
-#define EM_FINDWORDBREAK       (1100)
-#define EM_FMTLINES    (200)
-#define EM_FORMATRANGE (1081)
-#define EM_GETCHARFORMAT       (1082)
-#define EM_GETEVENTMASK        (1083)
-#define EM_GETFIRSTVISIBLELINE (206)
-#define EM_GETHANDLE   (189)
-#define EM_GETLIMITTEXT        (213)
-#define EM_GETLINE     (196)
-#define EM_GETLINECOUNT        (186)
-#define EM_GETMARGINS  (212)
-#define EM_GETMODIFY   (184)
-#define EM_GETIMECOLOR (1129)
-#define EM_GETIMEOPTIONS       (1131)
-#define EM_GETOPTIONS  (1102)
-#define EM_GETOLEINTERFACE     (1084)
-#define EM_GETPARAFORMAT       (1085)
-#define EM_GETPASSWORDCHAR     (210)
-#define EM_GETPUNCTUATION      (1125)
-#define EM_GETRECT     (178)
-#define EM_GETSEL      (176)
-#define EM_GETSELTEXT  (1086)
-#define EM_GETTEXTRANGE        (1099)
-#define EM_GETTHUMB    (190)
-#define EM_GETWORDBREAKPROC    (209)
-#define EM_GETWORDBREAKPROCEX  (1104)
-#define EM_GETWORDWRAPMODE     (1127)
-#define EM_HIDESELECTION       (1087)
-#define EM_LIMITTEXT   (197)
-#define EM_LINEFROMCHAR        (201)
-#define EM_LINEINDEX   (187)
-#define EM_LINELENGTH  (193)
-#define EM_LINESCROLL  (182)
-#define EM_PASTESPECIAL        (1088)
-#define EM_POSFROMCHAR (214)
-#define EM_REPLACESEL  (194)
-#define EM_REQUESTRESIZE       (1089)
-#define EM_SCROLL      (181)
-#define EM_SCROLLCARET (183)
-#define EM_SELECTIONTYPE       (1090)
-#define EM_SETBKGNDCOLOR       (1091)
-#define EM_SETCHARFORMAT       (1092)
-#define EM_SETEVENTMASK        (1093)
-#define EM_SETHANDLE   (188)
-#define EM_SETIMECOLOR (1128)
-#define EM_SETIMEOPTIONS       (1130)
-#define EM_SETLIMITTEXT        (197)
-#define EM_SETMARGINS  (211)
-#define EM_SETMODIFY   (185)
-#define EM_SETOLECALLBACK      (1094)
-#define EM_SETOPTIONS  (1101)
-#define EM_SETPARAFORMAT       (1095)
-#define EM_SETPASSWORDCHAR     (204)
-#define EM_SETPUNCTUATION      (1124)
-#define EM_SETREADONLY (207)
-#define EM_SETRECT     (179)
-#define EM_SETRECTNP   (180)
-#define EM_SETSEL      (177)
-#define EM_SETTABSTOPS (203)
-#define EM_SETTARGETDEVICE     (1096)
-#define EM_SETWORDBREAKPROC    (208)
-#define EM_SETWORDBREAKPROCEX  (1105)
-#define EM_SETWORDWRAPMODE     (1126)
-#define EM_STREAMIN    (1097)
-#define EM_STREAMOUT   (1098)
-#define EM_UNDO        (199)
-
-/* Edit control */
-#define EN_CHANGE      (768)
-#define EN_CORRECTTEXT (1797)
-#define EN_DROPFILES   (1795)
-#define EN_ERRSPACE    (1280)
-#define EN_HSCROLL     (1537)
-#define EN_IMECHANGE   (1799)
-#define EN_KILLFOCUS   (512)
-#define EN_MAXTEXT     (1281)
-#define EN_MSGFILTER   (1792)
-#define EN_OLEOPFAILED (1801)
-#define EN_PROTECTED   (1796)
-#define EN_REQUESTRESIZE       (1793)
-#define EN_SAVECLIPBOARD       (1800)
-#define EN_SELCHANGE   (1794)
-#define EN_SETFOCUS    (256)
-#define EN_STOPNOUNDO  (1798)
-#define EN_UPDATE      (1024)
-#define EN_VSCROLL     (1538)
-
-/* File Manager extensions */
-
-/* File Manager extensions DLL events */
-
-/* Header control */
-#define HDM_DELETEITEM (4610)
-#define HDM_GETITEMW   (4619)
-#define HDM_INSERTITEMW        (4618)
-#define HDM_SETITEMW   (4620)
-#define HDM_GETITEMA   (4611)
-#define HDM_INSERTITEMA        (4609)
-#define HDM_SETITEMA   (4612)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define HDM_GETITEM HDM_GETITEMW
-#define HDM_INSERTITEM HDM_INSERTITEMW
-#define HDM_SETITEM HDM_SETITEMW
-#else
-#define HDM_GETITEM HDM_GETITEMA
-#define HDM_INSERTITEM HDM_INSERTITEMA
-#define HDM_SETITEM HDM_SETITEMA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define HDM_GETITEMCOUNT       (4608)
-#define HDM_HITTEST    (4614)
-#define HDM_LAYOUT     (4613)
-
-/* Header control notifications */
-#define HDN_BEGINTRACKW        (-326)
-#define HDN_DIVIDERDBLCLICKW   (-325)
-#define HDN_ENDTRACKW  (-327)
-#define HDN_ITEMCHANGEDW       (-321)
-#define HDN_ITEMCHANGINGW      (-320)
-#define HDN_ITEMCLICKW (-322)
-#define HDN_ITEMDBLCLICKW      (-323)
-#define HDN_TRACKW     (-328)
-#define HDN_BEGINTRACKA        (-306)
-#define HDN_DIVIDERDBLCLICKA   (-305)
-#define HDN_ENDTRACKA  (-307)
-#define HDN_ITEMCHANGEDA       (-301)
-#define HDN_ITEMCHANGINGA      (-300)
-#define HDN_ITEMCLICKA (-302)
-#define HDN_ITEMDBLCLICKA      (-303)
-#define HDN_TRACKA     (-308)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define HDN_BEGINTRACK HDN_BEGINTRACKW
-#define HDN_DIVIDERDBLCLICK HDN_DIVIDERDBLCLICKW
-#define HDN_ENDTRACK HDN_ENDTRACKW
-#define HDN_ITEMCHANGED HDN_ITEMCHANGEDW
-#define HDN_ITEMCHANGING HDN_ITEMCHANGINGW
-#define HDN_ITEMCLICK HDN_ITEMCLICKW
-#define HDN_ITEMDBLCLICK HDN_ITEMDBLCLICKW
-#define HDN_TRACK HDN_TRACKW
-#else
-#define HDN_BEGINTRACK HDN_BEGINTRACKA
-#define HDN_DIVIDERDBLCLICK HDN_DIVIDERDBLCLICKA
-#define HDN_ENDTRACK HDN_ENDTRACKA
-#define HDN_ITEMCHANGED HDN_ITEMCHANGEDA
-#define HDN_ITEMCHANGING HDN_ITEMCHANGINGA
-#define HDN_ITEMCLICK HDN_ITEMCLICKA
-#define HDN_ITEMDBLCLICK HDN_ITEMDBLCLICKA
-#define HDN_TRACK HDN_TRACKA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-
-/* Hot key control */
-#define HKM_GETHOTKEY  (1026)
-#define HKM_SETHOTKEY  (1025)
-#define HKM_SETRULES   (1027)
-
-/* List box */
-#define LB_ADDFILE     (406)
-#define LB_ADDSTRING   (384)
-#define LB_DELETESTRING        (386)
-#define LB_DIR (397)
-#define LB_FINDSTRING  (399)
-#define LB_FINDSTRINGEXACT     (418)
-#define LB_GETANCHORINDEX      (413)
-#define LB_GETCARETINDEX       (415)
-#define LB_GETCOUNT    (395)
-#define LB_GETCURSEL   (392)
-#define LB_GETHORIZONTALEXTENT (403)
-#define LB_GETITEMDATA (409)
-#define LB_GETITEMHEIGHT       (417)
-#define LB_GETITEMRECT (408)
-#define LB_GETLOCALE   (422)
-#define LB_GETSEL      (391)
-#define LB_GETSELCOUNT (400)
-#define LB_GETSELITEMS (401)
-#define LB_GETTEXT     (393)
-#define LB_GETTEXTLEN  (394)
-#define LB_GETTOPINDEX (398)
-#define LB_INITSTORAGE (424)
-#define LB_INSERTSTRING        (385)
-#define LB_ITEMFROMPOINT       (425)
-#define LB_RESETCONTENT        (388)
-#define LB_SELECTSTRING        (396)
-#define LB_SELITEMRANGE        (411)
-#define LB_SELITEMRANGEEX      (387)
-#define LB_SETANCHORINDEX      (412)
-#define LB_SETCARETINDEX       (414)
-#define LB_SETCOLUMNWIDTH      (405)
-#define LB_SETCOUNT    (423)
-#define LB_SETCURSEL   (390)
-#define LB_SETHORIZONTALEXTENT (404)
-#define LB_SETITEMDATA (410)
-#define LB_SETITEMHEIGHT       (416)
-#define LB_SETLOCALE   (421)
-#define LB_SETSEL      (389)
-#define LB_SETTABSTOPS (402)
-#define LB_SETTOPINDEX (407)
-
-/* List box notifications */
-#define LBN_DBLCLK     (2)
-#define LBN_ERRSPACE   (-2)
-#define LBN_KILLFOCUS  (5)
-#define LBN_SELCANCEL  (3)
-#define LBN_SELCHANGE  (1)
-#define LBN_SETFOCUS   (4)
-
-/* List view control */
-#define LVM_ARRANGE    (4118)
-#define LVM_CREATEDRAGIMAGE    (4129)
-#define LVM_DELETEALLITEMS     (4105)
-#define LVM_DELETECOLUMN       (4124)
-#define LVM_DELETEITEM (4104)
-#define LVM_ENSUREVISIBLE      (4115)
-#define LVM_GETBKCOLOR (4096)
-#define LVM_GETCALLBACKMASK    (4106)
-#define LVM_GETCOLUMNWIDTH     (4125)
-#define LVM_GETCOUNTPERPAGE    (4136)
-#define LVM_GETEDITCONTROL     (4120)
-#define LVM_GETIMAGELIST       (4098)
-#define LVM_EDITLABELW (4214)
-#define LVM_FINDITEMW  (4179)
-#define LVM_GETCOLUMNW (4191)
-#define LVM_GETISEARCHSTRINGW  (4213)
-#define LVM_GETITEMW   (4171)
-#define LVM_GETITEMTEXTW       (4211)
-#define LVM_GETSTRINGWIDTHW    (4183)
-#define LVM_INSERTCOLUMNW      (4193)
-#define LVM_INSERTITEMW        (4173)
-#define LVM_SETCOLUMNW (4192)
-#define LVM_SETITEMW   (4172)
-#define LVM_SETITEMTEXTW       (4212)
-#define LVM_EDITLABELA (4119)
-#define LVM_FINDITEMA  (4109)
-#define LVM_GETCOLUMNA (4121)
-#define LVM_GETISEARCHSTRINGA  (4148)
-#define LVM_GETITEMA   (4101)
-#define LVM_GETITEMTEXTA       (4141)
-#define LVM_GETSTRINGWIDTHA    (4113)
-#define LVM_INSERTCOLUMNA      (4123)
-#define LVM_INSERTITEMA        (4103)
-#define LVM_SETCOLUMNA (4122)
-#define LVM_SETITEMA   (4102)
-#define LVM_SETITEMTEXTA       (4142)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define LVM_EDITLABEL LVM_EDITLABELW
-#define LVM_FINDITEM LVM_FINDITEMW
-#define LVM_GETCOLUMN LVM_GETCOLUMNW
-#define LVM_GETISEARCHSTRING LVM_GETISEARCHSTRINGW
-#define LVM_GETITEM LVM_GETITEMW
-#define LVM_GETITEMTEXT LVM_GETITEMTEXTW
-#define LVM_GETSTRINGWIDTH LVM_GETSTRINGWIDTHW
-#define LVM_INSERTCOLUMN LVM_INSERTCOLUMNW
-#define LVM_INSERTITEM LVM_INSERTITEMW
-#define LVM_SETCOLUMN LVM_SETCOLUMNW
-#define LVM_SETITEM LVM_SETITEMW
-#define LVM_SETITEMTEXT LVM_SETITEMTEXTW
-#else
-#define LVM_EDITLABEL LVM_EDITLABELA
-#define LVM_FINDITEM LVM_FINDITEMA
-#define LVM_GETCOLUMN LVM_GETCOLUMNA
-#define LVM_GETISEARCHSTRING LVM_GETISEARCHSTRINGA
-#define LVM_GETITEM LVM_GETITEMA
-#define LVM_GETITEMTEXT LVM_GETITEMTEXTA
-#define LVM_GETSTRINGWIDTH LVM_GETSTRINGWIDTHA
-#define LVM_INSERTCOLUMN LVM_INSERTCOLUMNA
-#define LVM_INSERTITEM LVM_INSERTITEMA
-#define LVM_SETCOLUMN LVM_SETCOLUMNA
-#define LVM_SETITEM LVM_SETITEMA
-#define LVM_SETITEMTEXT LVM_SETITEMTEXTA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define LVM_GETITEMCOUNT       (4100)
-#define LVM_GETITEMPOSITION    (4112)
-#define LVM_GETITEMRECT        (4110)
-#define LVM_GETITEMSPACING     (4147)
-#define LVM_GETITEMSTATE       (4140)
-#define LVM_GETNEXTITEM        (4108)
-#define LVM_GETORIGIN  (4137)
-#define LVM_GETSELECTEDCOUNT   (4146)
-#define LVM_GETTEXTBKCOLOR     (4133)
-#define LVM_GETTEXTCOLOR       (4131)
-#define LVM_GETTOPINDEX        (4135)
-#define LVM_GETVIEWRECT        (4130)
-#define LVM_HITTEST    (4114)
-#define LVM_REDRAWITEMS        (4117)
-#define LVM_SCROLL     (4116)
-#define LVM_SETBKCOLOR (4097)
-#define LVM_SETCALLBACKMASK    (4107)
-#define LVM_SETCOLUMNWIDTH     (4126)
-#define LVM_SETIMAGELIST       (4099)
-#define LVM_SETITEMCOUNT       (4143)
-#define LVM_SETITEMPOSITION    (4111)
-#define LVM_SETITEMPOSITION32  (4145)
-#define LVM_SETITEMSTATE       (4139)
-#define LVM_SETTEXTBKCOLOR     (4134)
-#define LVM_SETTEXTCOLOR       (4132)
-#define LVM_SORTITEMS  (4144)
-#define LVM_UPDATE     (4138)
-
-/* List view control notifications */
-#define LVN_BEGINDRAG  (-109)
-#define LVN_BEGINRDRAG (-111)
-#define LVN_COLUMNCLICK        (-108)
-#define LVN_DELETEALLITEMS     (-104)
-#define LVN_DELETEITEM (-103)
-#define LVN_BEGINLABELEDITW    (-175)
-#define LVN_ENDLABELEDITW      (-176)
-#define LVN_GETDISPINFOW       (-177)
-#define LVN_SETDISPINFOW       (-178)
-#define LVN_BEGINLABELEDITA    (-105)
-#define LVN_ENDLABELEDITA      (-106)
-#define LVN_GETDISPINFOA       (-150)
-#define LVN_SETDISPINFOA       (-151)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define LVN_BEGINLABELEDIT LVN_BEGINLABELEDITW
-#define LVN_ENDLABELEDIT LVN_ENDLABELEDITW
-#define LVN_GETDISPINFO LVN_GETDISPINFOW
-#define LVN_SETDISPINFO LVN_SETDISPINFOW
-#else
-#define LVN_BEGINLABELEDIT LVN_BEGINLABELEDITA
-#define LVN_ENDLABELEDIT LVN_ENDLABELEDITA
-#define LVN_GETDISPINFO LVN_GETDISPINFOA
-#define LVN_SETDISPINFO LVN_SETDISPINFOA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define LVN_INSERTITEM (-102)
-#define LVN_ITEMCHANGED        (-101)
-#define LVN_ITEMCHANGING       (-100)
-#define LVN_KEYDOWN    (-155)
-
-/* Control notification */
-#define NM_CLICK       (-2)
-#define NM_DBLCLK      (-3)
-#define NM_KILLFOCUS   (-8)
-#define NM_OUTOFMEMORY (-1)
-#define NM_RCLICK      (-5)
-#define NM_RDBLCLK     (-6)
-#define NM_RETURN      (-4)
-#define NM_SETFOCUS    (-7)
-
-/* Power status */
-
-/* Progress bar control */
-#define PBM_DELTAPOS   (1027)
-#define PBM_SETPOS     (1026)
-#define PBM_SETRANGE   (1025)
-#define PBM_SETSTEP    (1028)
-#define PBM_STEPIT     (1029)
-
-/* Property sheets */
-#define PSM_ADDPAGE    (1127)
-#define PSM_APPLY      (1134)
-#define PSM_CANCELTOCLOSE      (1131)
-#define PSM_CHANGED    (1128)
-#define PSM_GETTABCONTROL      (1140)
-#define PSM_GETCURRENTPAGEHWND (1142)
-#define PSM_ISDIALOGMESSAGE    (1141)
-#define PSM_PRESSBUTTON        (1137)
-#define PSM_QUERYSIBLINGS      (1132)
-#define PSM_REBOOTSYSTEM       (1130)
-#define PSM_REMOVEPAGE (1126)
-#define PSM_RESTARTWINDOWS     (1129)
-#define PSM_SETCURSEL  (1125)
-#define PSM_SETCURSELID        (1138)
-#define PSM_SETFINISHTEXTW     (1145)
-#define PSM_SETTITLEW  (1144)
-#define PSM_SETFINISHTEXTA     (1139)
-#define PSM_SETTITLEA  (1135)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define PSM_SETFINISHTEXT PSM_SETFINISHTEXTW
-#define PSM_SETTITLE PSM_SETTITLEW
-#else
-#define PSM_SETFINISHTEXT PSM_SETFINISHTEXTA
-#define PSM_SETTITLE PSM_SETTITLEA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define PSM_SETWIZBUTTONS      (1136)
-#define PSM_UNCHANGED  (1133)
-
-/* Property sheet notifications */
-#define PSN_APPLY      (-202)
-#define PSN_HELP       (-205)
-#define PSN_KILLACTIVE (-201)
-#define PSN_QUERYCANCEL        (-209)
-#define PSN_RESET      (-203)
-#define PSN_SETACTIVE  (-200)
-#define PSN_WIZBACK    (-206)
-#define PSN_WIZFINISH  (-208)
-#define PSN_WIZNEXT    (-207)
-
-/* Status window */
-#define SB_GETBORDERS  (1031)
-#define SB_GETPARTS    (1030)
-#define SB_GETRECT     (1034)
-#define SB_GETTEXTW    (1037)
-#define SB_GETTEXTLENGTHW      (1036)
-#define SB_SETTEXTW    (1035)
-#define SB_GETTEXTA    (1026)
-#define SB_GETTEXTLENGTHA      (1027)
-#define SB_SETTEXTA    (1025)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define SB_GETTEXT SB_GETTEXTW
-#define SB_GETTEXTLENGTH SB_GETTEXTLENGTHW
-#define SB_SETTEXT SB_SETTEXTW
-#else
-#define SB_GETTEXT SB_GETTEXTA
-#define SB_GETTEXTLENGTH SB_GETTEXTLENGTHA
-#define SB_SETTEXT SB_SETTEXTA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define SB_SETMINHEIGHT        (1032)
-#define SB_SETPARTS    (1028)
-#define SB_SIMPLE      (1033)
-
-/* Scroll bar control */
-#define SBM_ENABLE_ARROWS      (228)
-#define SBM_GETPOS     (225)
-#define SBM_GETRANGE   (227)
-#define SBM_GETSCROLLINFO      (234)
-#define SBM_SETPOS     (224)
-#define SBM_SETRANGE   (226)
-#define SBM_SETRANGEREDRAW     (230)
-#define SBM_SETSCROLLINFO      (233)
-
-/* Static control */
-#define STM_GETICON    (369)
-#define STM_GETIMAGE   (371)
-#define STM_SETICON    (368)
-#define STM_SETIMAGE   (370)
-
-/* Static control notifications */
-#define STN_CLICKED    (0)
-#define STN_DBLCLK     (1)
-#define STN_DISABLE    (3)
-#define STN_ENABLE     (2)
-
-/* Toolbar control */
-#define TB_ADDBITMAP   (1043)
-#define TB_ADDBUTTONS  (1044)
-#define TB_AUTOSIZE    (1057)
-#define TB_BUTTONCOUNT (1048)
-#define TB_BUTTONSTRUCTSIZE    (1054)
-#define TB_CHANGEBITMAP        (1067)
-#define TB_CHECKBUTTON (1026)
-#define TB_COMMANDTOINDEX      (1049)
-#define TB_CUSTOMIZE   (1051)
-#define TB_DELETEBUTTON        (1046)
-#define TB_ENABLEBUTTON        (1025)
-#define TB_GETBITMAP   (1068)
-#define TB_GETBITMAPFLAGS      (1065)
-#define TB_GETBUTTON   (1047)
-#define TB_ADDSTRINGW  (1101)
-#define TB_GETBUTTONTEXTW      (1099)
-#define TB_SAVERESTOREW        (1100)
-#define TB_ADDSTRINGA  (1052)
-#define TB_GETBUTTONTEXTA      (1069)
-#define TB_SAVERESTOREA        (1050)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TB_ADDSTRING TB_ADDSTRINGW
-#define TB_GETBUTTONTEXT TB_GETBUTTONTEXTW
-#define TB_SAVERESTORE TB_SAVERESTOREW
-#else
-#define TB_ADDSTRING TB_ADDSTRINGA
-#define TB_GETBUTTONTEXT TB_GETBUTTONTEXTA
-#define TB_SAVERESTORE TB_SAVERESTOREA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TB_GETITEMRECT (1053)
-#define TB_GETROWS     (1064)
-#define TB_GETSTATE    (1042)
-#define TB_GETTOOLTIPS (1059)
-#define TB_HIDEBUTTON  (1028)
-#define TB_INDETERMINATE       (1029)
-#define TB_INSERTBUTTON        (1045)
-#define TB_ISBUTTONCHECKED     (1034)
-#define TB_ISBUTTONENABLED     (1033)
-#define TB_ISBUTTONHIDDEN      (1036)
-#define TB_ISBUTTONINDETERMINATE       (1037)
-#define TB_ISBUTTONPRESSED     (1035)
-#define TB_PRESSBUTTON (1027)
-#define TB_SETBITMAPSIZE       (1056)
-#define TB_SETBUTTONSIZE       (1055)
-#define TB_SETCMDID    (1066)
-#define TB_SETPARENT   (1061)
-#define TB_SETROWS     (1063)
-#define TB_SETSTATE    (1041)
-#define TB_SETTOOLTIPS (1060)
-
-/* Track bar control */
-#define TBM_CLEARSEL   (1043)
-#define TBM_CLEARTICS  (1033)
-#define TBM_GETCHANNELRECT     (1050)
-#define TBM_GETLINESIZE        (1048)
-#define TBM_GETNUMTICS (1040)
-#define TBM_GETPAGESIZE        (1046)
-#define TBM_GETPOS     (1024)
-#define TBM_GETPTICS   (1038)
-#define TBM_GETRANGEMAX        (1026)
-#define TBM_GETRANGEMIN        (1025)
-#define TBM_GETSELEND  (1042)
-#define TBM_GETSELSTART        (1041)
-#define TBM_GETTHUMBLENGTH     (1052)
-#define TBM_GETTHUMBRECT       (1049)
-#define TBM_GETTIC     (1027)
-#define TBM_GETTICPOS  (1039)
-#define TBM_SETLINESIZE        (1047)
-#define TBM_SETPAGESIZE        (1045)
-#define TBM_SETPOS     (1029)
-#define TBM_SETRANGE   (1030)
-#define TBM_SETRANGEMAX        (1032)
-#define TBM_SETRANGEMIN        (1031)
-#define TBM_SETSEL     (1034)
-#define TBM_SETSELEND  (1036)
-#define TBM_SETSELSTART        (1035)
-#define TBM_SETTHUMBLENGTH     (1051)
-#define TBM_SETTIC     (1028)
-#define TBM_SETTICFREQ (1044)
-
-/* Tool bar control notifications */
-#define TBN_BEGINADJUST        (-703)
-#define TBN_BEGINDRAG  (-701)
-#define TBN_CUSTHELP   (-709)
-#define TBN_ENDADJUST  (-704)
-#define TBN_ENDDRAG    (-702)
-#define TBN_GETBUTTONINFOW     (-720)
-#define TBN_GETBUTTONINFOA     (-700)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TBN_GETBUTTONINFO TBN_GETBUTTONINFOW
-#else
-#define TBN_GETBUTTONINFO TBN_GETBUTTONINFOA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TBN_QUERYDELETE        (-707)
-#define TBN_QUERYINSERT        (-706)
-#define TBN_RESET      (-705)
-#define TBN_TOOLBARCHANGE      (-708)
-
-/* Tab control */
-#define TCM_ADJUSTRECT (4904)
-#define TCM_DELETEALLITEMS     (4873)
-#define TCM_DELETEITEM (4872)
-#define TCM_GETCURFOCUS        (4911)
-#define TCM_GETCURSEL  (4875)
-#define TCM_GETIMAGELIST       (4866)
-#define TCM_GETITEMW   (4924)
-#define TCM_INSERTITEMW        (4926)
-#define TCM_SETITEMW   (4925)
-#define TCM_GETITEMA   (4869)
-#define TCM_INSERTITEMA        (4871)
-#define TCM_SETITEMA   (4870)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TCM_GETITEM TCM_GETITEM
-#define TCM_INSERTITEM TCM_INSERTITEMW
-#define TCM_SETITEM TCM_SETITEMW
-#else
-#define TCM_GETITEM TCM_GETITEMA
-#define TCM_INSERTITEM TCM_INSERTITEMA
-#define TCM_SETITEM TCM_SETITEMA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TCM_GETITEMCOUNT       (4868)
-#define TCM_GETITEMRECT        (4874)
-#define TCM_GETROWCOUNT        (4908)
-#define TCM_GETTOOLTIPS        (4909)
-#define TCM_HITTEST    (4877)
-#define TCM_REMOVEIMAGE        (4906)
-#define TCM_SETCURFOCUS        (4912)
-#define TCM_SETCURSEL  (4876)
-#define TCM_SETIMAGELIST       (4867)
-#define TCM_SETITEMEXTRA       (4878)
-#define TCM_SETITEMSIZE        (4905)
-#define TCM_SETPADDING (4907)
-#define TCM_SETTOOLTIPS        (4910)
-
-/* Tab control notifications */
-#define TCN_KEYDOWN    (-550)
-#define TCN_SELCHANGE  (-551)
-#define TCN_SELCHANGING        (-552)
-
-/* Tool tip control */
-#define TTM_ACTIVATE   (1025)
-#define TTM_ADDTOOLW   (1074)
-#define TTM_DELTOOLW   (1075)
-#define TTM_ENUMTOOLSW (1082)
-#define TTM_GETCURRENTTOOLW    (1083)
-#define TTM_GETTEXTW   (1080)
-#define TTM_GETTOOLINFOW       (1077)
-#define TTM_HITTESTW   (1079)
-#define TTM_NEWTOOLRECTW       (1076)
-#define TTM_SETTOOLINFOW       (1078)
-#define TTM_UPDATETIPTEXTW     (1081)
-#define TTM_ADDTOOLA   (1028)
-#define TTM_DELTOOLA   (1029)
-#define TTM_ENUMTOOLSA (1038)
-#define TTM_GETCURRENTTOOLA    (1039)
-#define TTM_GETTEXTA   (1035)
-#define TTM_GETTOOLINFOA       (1032)
-#define TTM_HITTESTA   (1034)
-#define TTM_NEWTOOLRECTA       (1030)
-#define TTM_SETTOOLINFOA       (1033)
-#define TTM_UPDATETIPTEXTA     (1036)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TTM_ADDTOOL TTM_ADDTOOLW
-#define TTM_DELTOOL TTM_DELTOOLW
-#define TTM_ENUMTOOLS TTM_ENUMTOOLSW
-#define TTM_GETCURRENTTOOL TTM_GETCURRENTTOOLW
-#define TTM_GETTEXT TTM_GETTEXTW
-#define TTM_GETTOOLINFO TTM_GETTOOLINFOW
-#define TTM_HITTEST TTM_HITTESTW
-#define TTM_NEWTOOLRECT TTM_NEWTOOLRECTW
-#define TTM_SETTOOLINFO TTM_SETTOOLINFOW
-#define TTM_UPDATETIPTEXT TTM_UPDATETIPTEXTW
-#else
-#define TTM_ADDTOOL TTM_ADDTOOLA
-#define TTM_DELTOOL TTM_DELTOOLA
-#define TTM_ENUMTOOLS TTM_ENUMTOOLSA
-#define TTM_GETCURRENTTOOL TTM_GETCURRENTTOOLA
-#define TTM_GETTEXT TTM_GETTEXTA
-#define TTM_GETTOOLINFO TTM_GETTOOLINFOA
-#define TTM_HITTEST TTM_HITTESTA
-#define TTM_NEWTOOLRECT TTM_NEWTOOLRECTA
-#define TTM_SETTOOLINFO TTM_SETTOOLINFOA
-#define TTM_UPDATETIPTEXT TTM_UPDATETIPTEXTA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TTM_GETTOOLCOUNT       (1037)
-#define TTM_RELAYEVENT (1031)
-#define TTM_SETDELAYTIME       (1027)
-#define TTM_WINDOWFROMPOINT    (1040)
-
-/* Tool tip control notification */
-#define TTN_NEEDTEXTW  (-530)
-#define TTN_NEEDTEXTA  (-520)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TTN_NEEDTEXT TTN_NEEDTEXTW
-#else
-#define TTN_NEEDTEXT TTN_NEEDTEXTA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TTN_POP        (-522)
-#define TTN_SHOW       (-521)
-
-/* Tree view control */
-#define TVM_CREATEDRAGIMAGE    (4370)
-#define TVM_DELETEITEM (4353)
-#define TVM_ENDEDITLABELNOW    (4374)
-#define TVM_ENSUREVISIBLE      (4372)
-#define TVM_EXPAND     (4354)
-#define TVM_GETCOUNT   (4357)
-#define TVM_GETEDITCONTROL     (4367)
-#define TVM_GETIMAGELIST       (4360)
-#define TVM_GETINDENT  (4358)
-#define TVM_GETITEMRECT        (4356)
-#define TVM_GETNEXTITEM        (4362)
-#define TVM_GETVISIBLECOUNT    (4368)
-#define TVM_HITTEST    (4369)
-#define TVM_EDITLABELW (4417)
-#define TVM_GETISEARCHSTRINGW  (4416)
-#define TVM_GETITEMW   (4414)
-#define TVM_INSERTITEMW        (4402)
-#define TVM_SETITEMW   (4415)
-#define TVM_EDITLABELA (4366)
-#define TVM_GETISEARCHSTRINGA  (4375)
-#define TVM_GETITEMA   (4364)
-#define TVM_INSERTITEMA        (4352)
-#define TVM_SETITEMA   (4365)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TVM_EDITLABEL TVM_EDITLABELW
-#define TVM_GETISEARCHSTRING TVM_GETISEARCHSTRINGW
-#define TVM_GETITEM TVM_GETITEMW
-#define TVM_INSERTITEM TVM_INSERTITEMW
-#define TVM_SETITEM TVM_SETITEMW
-#else
-#define TVM_EDITLABEL TVM_EDITLABELA
-#define TVM_GETISEARCHSTRING TVM_GETISEARCHSTRINGA
-#define TVM_GETITEM TVM_GETITEMA
-#define TVM_INSERTITEM TVM_INSERTITEMA
-#define TVM_SETITEM TVM_SETITEMA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-#define TVM_SELECTITEM (4363)
-#define TVM_SETIMAGELIST       (4361)
-#define TVM_SETINDENT  (4359)
-#define TVM_SORTCHILDREN       (4371)
-#define TVM_SORTCHILDRENCB     (4373)
-
-/* Tree view control notification */
-#define TVN_KEYDOWN    (-412)
-#define TVN_BEGINDRAGW (-456)
-#define TVN_BEGINLABELEDITW    (-459)
-#define TVN_BEGINRDRAGW        (-457)
-#define TVN_DELETEITEMW        (-458)
-#define TVN_ENDLABELEDITW      (-460)
-#define TVN_GETDISPINFOW       (-452)
-#define TVN_ITEMEXPANDEDW      (-455)
-#define TVN_ITEMEXPANDINGW     (-454)
-#define TVN_SELCHANGEDW        (-451)
-#define TVN_SELCHANGINGW       (-450)
-#define TVN_SETDISPINFOW       (-453)
-#define TVN_BEGINDRAGA (-407)
-#define TVN_BEGINLABELEDITA    (-410)
-#define TVN_BEGINRDRAGA        (-408)
-#define TVN_DELETEITEMA        (-409)
-#define TVN_ENDLABELEDITA      (-411)
-#define TVN_GETDISPINFOA       (-403)
-#define TVN_ITEMEXPANDEDA      (-406)
-#define TVN_ITEMEXPANDINGA     (-405)
-#define TVN_SELCHANGEDA        (-402)
-#define TVN_SELCHANGINGA       (-401)
-#define TVN_SETDISPINFOA       (-404)
-#ifndef _DISABLE_TIDENTS
-#ifdef UNICODE
-#define TVN_BEGINDRAG TVN_BEGINDRAGW
-#define TVN_BEGINLABELEDIT TVN_BEGINLABELEDITW
-#define TVN_BEGINRDRAG TVN_BEGINRDRAGW
-#define TVN_DELETEITEM TVN_DELETEITEMW
-#define TVN_ENDLABELEDIT TVN_ENDLABELEDITW
-#define TVN_GETDISPINFO TVN_GETDISPINFOW
-#define TVN_ITEMEXPANDED TVN_ITEMEXPANDEDW
-#define TVN_ITEMEXPANDING TVN_ITEMEXPANDINGW
-#define TVN_SELCHANGED TVN_SELCHANGEDW
-#define TVN_SELCHANGING TVN_SELCHANGINGW
-#define TVN_SETDISPINFO TVN_SETDISPINFOW
-#else
-#define TVN_BEGINDRAG TVN_BEGINDRAGA
-#define TVN_BEGINLABELEDIT TVN_BEGINLABELEDITA
-#define TVN_BEGINRDRAG TVN_BEGINRDRAGA
-#define TVN_DELETEITEM TVN_DELETEITEMA
-#define TVN_ENDLABELEDIT TVN_ENDLABELEDITA
-#define TVN_GETDISPINFO TVN_GETDISPINFOA
-#define TVN_ITEMEXPANDED TVN_ITEMEXPANDEDA
-#define TVN_ITEMEXPANDING TVN_ITEMEXPANDINGA
-#define TVN_SELCHANGED TVN_SELCHANGEDA
-#define TVN_SELCHANGING TVN_SELCHANGINGA
-#define TVN_SETDISPINFO TVN_SETDISPINFOA
-#endif /* UNICODE */
-#endif /* _DISABLE_TIDENTS */
-
-/* Up/down control */
-#define UDM_GETACCEL   (1132)
-#define UDM_GETBASE    (1134)
-#define UDM_GETBUDDY   (1130)
-#define UDM_GETPOS     (1128)
-#define UDM_GETRANGE   (1126)
-#define UDM_SETACCEL   (1131)
-#define UDM_SETBASE    (1133)
-#define UDM_SETBUDDY   (1129)
-#define UDM_SETPOS     (1127)
-#define UDM_SETRANGE   (1125)
-
-/* Up/down control notification */
-#define UDN_DELTAPOS   (-722)
-
-/* Window messages */
-
-#define WM_ACTIVATE    (6)
-#define WM_ACTIVATEAPP (28)
-#define WM_ASKCBFORMATNAME     (780)
-#define WM_CANCELJOURNAL       (75)
-#define WM_CANCELMODE  (31)
-#define WM_CAPTURECHANGED      (533)
-#define WM_CHANGECBCHAIN       (781)
-#define WM_CHAR        (258)
-#define WM_CHARTOITEM  (47)
-#define WM_CHILDACTIVATE       (34)
-#define WM_CHOOSEFONT_GETLOGFONT       (1025)
-#define WM_CHOOSEFONT_SETLOGFONT       (1125)
-#define WM_CHOOSEFONT_SETFLAGS (1126)
-#define WM_CLEAR       (771)
-#define WM_CLOSE       (16)
-#define WM_COMMAND     (273)
-#define WM_COMPACTING  (65)
-#define WM_COMPAREITEM (57)
-#define WM_CONTEXTMENU (123)
-#define WM_COPY        (769)
-#define WM_COPYDATA    (74)
-#define WM_CREATE      (1)
-#define WM_CTLCOLORBTN (309)
-#define WM_CTLCOLORDLG (310)
-#define WM_CTLCOLOREDIT        (307)
-#define WM_CTLCOLORLISTBOX     (308)
-#define WM_CTLCOLORMSGBOX      (306)
-#define WM_CTLCOLORSCROLLBAR   (311)
-#define WM_CTLCOLORSTATIC      (312)
-#define WM_CUT (768)
-#define WM_DEADCHAR    (259)
-#define WM_DELETEITEM  (45)
-#define WM_DESTROY     (2)
-#define WM_DESTROYCLIPBOARD    (775)
-#define WM_DEVICECHANGE        (537)
-#define WM_DEVMODECHANGE       (27)
-#define WM_DISPLAYCHANGE       (126)
-#define WM_DRAWCLIPBOARD       (776)
-#define WM_DRAWITEM    (43)
-#define WM_DROPFILES   (563)
-#define WM_DROPOBJECT   (544)
-#define WM_ENABLE      (10)
-#define WM_ENDSESSION  (22)
-#define WM_ENTERIDLE   (289)
-#define WM_ENTERMENULOOP       (529)
-#define WM_ENTERSIZEMOVE       (561)
-#define WM_ERASEBKGND  (20)
-#define WM_EXITMENULOOP        (530)
-#define WM_EXITSIZEMOVE        (562)
-#define WM_FONTCHANGE  (29)
-#define WM_GETDLGCODE  (135)
-#define WM_GETFONT     (49)
-#define WM_GETHOTKEY   (51)
-#define WM_GETICON     (127)
-#define WM_GETMINMAXINFO       (36)
-#define WM_GETTEXT     (13)
-#define WM_GETTEXTLENGTH       (14)
-#define WM_HELP        (83)
-#define WM_HOTKEY      (786)
-#define WM_HSCROLL     (276)
-#define WM_HSCROLLCLIPBOARD    (782)
-#define WM_ICONERASEBKGND      (39)
-#define WM_IME_CHAR    (646)
-#define WM_IME_COMPOSITION     (271)
-#define WM_IME_COMPOSITIONFULL (644)
-#define WM_IME_CONTROL (643)
-#define WM_IME_ENDCOMPOSITION  (270)
-#define WM_IME_KEYDOWN (656)
-#define WM_IME_KEYUP   (657)
-#define WM_IME_NOTIFY  (642)
-#define WM_IME_SELECT  (645)
-#define WM_IME_SETCONTEXT      (641)
-#define WM_IME_STARTCOMPOSITION        (269)
-#define WM_INITDIALOG  (272)
-#define WM_INITMENU    (278)
-#define WM_INITMENUPOPUP       (279)
-#define WM_INPUTLANGCHANGE     (81)
-#define WM_INPUTLANGCHANGEREQUEST      (80)
-#define WM_KEYDOWN     (256)
-#define WM_KEYUP       (257)
-#define WM_KILLFOCUS   (8)
-#define WM_SETVISIBLE   (9)
-#define WM_LBUTTONDBLCLK       (515)
-#define WM_LBUTTONDOWN (513)
-#define WM_LBUTTONUP   (514)
-#define WM_MBUTTONDBLCLK       (521)
-#define WM_MBUTTONDOWN (519)
-#define WM_MBUTTONUP   (520)
-#define WM_MDIACTIVATE (546)
-#define WM_MDICASCADE  (551)
-#define WM_MDICREATE   (544)
-#define WM_MDIDESTROY  (545)
-#define WM_MDIGETACTIVE        (553)
-#define WM_MDIICONARRANGE      (552)
-#define WM_MDIMAXIMIZE (549)
-#define WM_MDINEXT     (548)
-#define WM_MDIREFRESHMENU      (564)
-#define WM_MDIRESTORE  (547)
-#define WM_MDISETMENU  (560)
-#define WM_MDITILE     (550)
-#define WM_MEASUREITEM (44)
-#define WM_MENUCHAR    (288)
-#define WM_MENUSELECT  (287)
-#define WM_MOUSEACTIVATE       (33)
-#define WM_MOUSEMOVE   (512)
-#define WM_MOUSEWHEEL   (522)
-#define WM_MOVE        (3)
-#define WM_MOVING      (534)
-#define WM_NCACTIVATE  (134)
-#define WM_NCCALCSIZE  (131)
-#define WM_NCCREATE    (129)
-#define WM_NCDESTROY   (130)
-#define WM_NCHITTEST   (132)
-#define WM_NCLBUTTONDBLCLK     (163)
-#define WM_NCLBUTTONDOWN       (161)
-#define WM_NCLBUTTONUP (162)
-#define WM_NCMBUTTONDBLCLK     (169)
-#define WM_NCMBUTTONDOWN       (167)
-#define WM_NCMBUTTONUP (168)
-#define WM_NCMOUSEMOVE (160)
-#define WM_NCPAINT     (133)
-#define WM_NCRBUTTONDBLCLK     (166)
-#define WM_NCRBUTTONDOWN       (164)
-#define WM_NCRBUTTONUP (165)
-#define WM_NCXBUTTONDOWN       (171)
-#define WM_NCXBUTTONUP (172)
-#define WM_NCXBUTTONDBLCLK     (173)
-#define WM_NEXTDLGCTL  (40)
-#define WM_NEXTMENU    (531)
-#define WM_NOTIFY      (78)
-#define WM_NOTIFYFORMAT        (85)
-#define WM_NULL         (0)
-#define WM_PAINT       (15)
-#define WM_PAINTCLIPBOARD      (777)
-#define WM_PAINTICON   (38)
-#define WM_PALETTECHANGED      (785)
-#define WM_PALETTEISCHANGING   (784)
-#define WM_PARENTNOTIFY        (528)
-#define WM_PASTE       (770)
-#define WM_PENWINFIRST  (896)
-#define WM_PENWINLAST  (911)
-#define WM_POWER       (72)
-#define WM_POWERBROADCAST      (536)
-#define WM_PRINT       (791)
-#define WM_PRINTCLIENT (792)
-#define WM_PSD_ENVSTAMPRECT    (1029)
-#define WM_PSD_FULLPAGERECT    (1025)
-#define WM_PSD_GREEKTEXTRECT   (1028)
-#define WM_PSD_MARGINRECT      (1027)
-#define WM_PSD_MINMARGINRECT   (1026)
-#define WM_PSD_PAGESETUPDLG    (1024)
-#define WM_PSD_YAFULLPAGERECT  (1030)
-#define WM_QUERYDRAGICON       (55)
-#define WM_QUERYDROPOBJECT      (555)
-#define WM_QUERYENDSESSION     (17)
-#define WM_QUERYNEWPALETTE     (783)
-#define WM_QUERYOPEN   (19)
-#define WM_QUEUESYNC   (35)
-#define WM_QUIT        (18)
-#define WM_RBUTTONDBLCLK       (518)
-#define WM_RBUTTONDOWN (516)
-#define WM_RBUTTONUP   (517)
-#define WM_RENDERALLFORMATS    (774)
-#define WM_RENDERFORMAT        (773)
-#define WM_SETCURSOR   (32)
-#define WM_SETFOCUS    (7)
-#define WM_SETFONT     (48)
-#define WM_SETHOTKEY   (50)
-#define WM_SETICON     (128)
-#define WM_SETREDRAW   (11)
-#define WM_SETTEXT     (12)
-#define WM_SETTINGCHANGE       (26)
-#define WM_SHOWWINDOW  (24)
-#define WM_SIZE        (5)
-#define WM_SIZECLIPBOARD       (779)
-#define WM_SIZING      (532)
-#define WM_SPOOLERSTATUS       (42)
-#define WM_STYLECHANGED        (125)
-#define WM_STYLECHANGING       (124)
-#define WM_SYNCPAINT    (136)
-#define WM_SYSCHAR     (262)
-#define WM_SYSCOLORCHANGE      (21)
-#define WM_SYSCOMMAND  (274)
-#define WM_SYSDEADCHAR (263)
-#define WM_SYSKEYDOWN  (260)
-#define WM_SYSKEYUP    (261)
-#define WM_TCARD       (82)
-#define WM_TIMECHANGE  (30)
-#define WM_TIMER       (275)
-#define WM_SYSTIMER    (280)
-#define WM_UNDO        (772)
-#define WM_USER        (1024)
-#define WM_USERCHANGED (84)
-#define WM_VKEYTOITEM  (46)
-#define WM_VSCROLL     (277)
-#define WM_VSCROLLCLIPBOARD    (778)
-#define WM_WINDOWPOSCHANGED    (71)
-#define WM_WINDOWPOSCHANGING   (70)
-#define WM_WININICHANGE        (26)
-#define WM_XBUTTONDOWN  (523)
-#define WM_XBUTTONUP    (524)
-#define WM_XBUTTONDBLCLK    (525)
-
-/* Window message ranges */
-#define WM_KEYFIRST    (256)
-#define WM_KEYLAST     (264)
-#define WM_MOUSEFIRST  (512)
-#define WM_MOUSELAST   (525)
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __USE_W32API */
-
-#endif /* _GNU_H_WINDOWS32_MESSAGES */
index cb73f55..c996714 100644 (file)
@@ -770,6 +770,13 @@ NTSTATUS
 STDCALL
 RtlDeleteTimerQueue(HANDLE TimerQueue);
 
+PVOID
+STDCALL
+RtlEncodePointer(IN PVOID Pointer);
+
+PVOID
+STDCALL
+RtlDecodePointer(IN PVOID Pointer);
 
 #ifndef __NTDRIVER__
 
index 9094b06..c54a8e6 100755 (executable)
@@ -87,12 +87,38 @@ typedef struct _OBJECT_ATTRIBUTES
    PVOID SecurityQualityOfService;
 } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
 
+typedef struct _HANDLE_TABLE_ENTRY_INFO {
+    ULONG AuditMask;
+} HANDLE_TABLE_ENTRY_INFO, *PHANDLE_TABLE_ENTRY_INFO;
+
+typedef struct _HANDLE_TABLE_ENTRY {
+    union {
+        PVOID Object;
+        ULONG_PTR ObAttributes;
+        PHANDLE_TABLE_ENTRY_INFO InfoTable;
+        ULONG_PTR Value;
+    } u1;
+    union {
+        ULONG GrantedAccess;
+        USHORT GrantedAccessIndex;
+        LONG NextFreeTableEntry;
+    } u2;
+} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
+
 #endif /* __USE_W32API */
 
 typedef struct _HANDLE_TABLE
 {
-   LIST_ENTRY ListHead;
-   KSPIN_LOCK ListLock;
+    ULONG Flags;
+    LONG HandleCount;
+    PHANDLE_TABLE_ENTRY **Table;
+    PEPROCESS QuotaProcess;
+    HANDLE UniqueProcessId;
+    LONG FirstFreeTableEntry;
+    LONG NextIndexNeedingPool;
+    ERESOURCE HandleTableLock;
+    LIST_ENTRY HandleTableList;
+    KEVENT HandleContentionEvent;
 } HANDLE_TABLE;
 
 #ifndef __USE_W32API
index 6623ea5..81034ee 100755 (executable)
@@ -377,6 +377,21 @@ RemoveTailList(
   
 #define RtlEqualMemory(Destination,Source,Length)   (!memcmp((Destination), (Source), (Length)))
 
+NTSTATUS
+STDCALL
+RtlCreateUserThread (
+   IN HANDLE         ProcessHandle,
+   IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+   IN BOOLEAN        CreateSuspended,
+   IN LONG        StackZeroBits,
+   IN OUT   PULONG         StackReserve,
+   IN OUT   PULONG         StackCommit,
+   IN PTHREAD_START_ROUTINE   StartAddress,
+   IN PVOID       Parameter,
+   IN OUT   PHANDLE        ThreadHandle,
+   IN OUT   PCLIENT_ID     ClientId
+   );      
+
 NTSTATUS
 STDCALL
 RtlAppendUnicodeToString (
index e4b76e9..b9dad2a 100644 (file)
@@ -153,13 +153,14 @@ typedef struct _SECURITY_DESCRIPTOR_CONTEXT
 #define TOKEN_ADJUST_PRIVILEGES                (0x0020L)
 #define TOKEN_ADJUST_GROUPS            (0x0040L)
 #define TOKEN_ADJUST_DEFAULT           (0x0080L)
+#define TOKEN_ADJUST_SESSIONID         (0x0100L)
 
-#define TOKEN_ALL_ACCESS               (0xf00ffL)
+#define TOKEN_ALL_ACCESS               (0xf01ffL)
 #define TOKEN_READ                     (0x20008L)
 #define TOKEN_WRITE                    (0x200e0L)
 #define TOKEN_EXECUTE                  (0x20000L)
 
-typedef BOOL SECURITY_CONTEXT_TRACKING_MODE;
+typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
 
 #define SECURITY_STATIC_TRACKING       (0)
 #define SECURITY_DYNAMIC_TRACKING      (1)
@@ -192,12 +193,13 @@ typedef enum _TOKEN_INFORMATION_CLASS
   TokenOrigin
 } TOKEN_INFORMATION_CLASS;
 
-typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
-
-#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0)
-#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1)
-#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2)
-#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3)
+typedef enum _SECURITY_IMPERSONATION_LEVEL
+{
+  SecurityAnonymous,
+  SecurityIdentification,
+  SecurityImpersonation,
+  SecurityDelegation
+} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
 
 typedef ULONG ACCESS_MASK, *PACCESS_MASK;
 typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
@@ -339,6 +341,20 @@ typedef struct _TOKEN_GROUPS
   SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
 } TOKEN_GROUPS, *PTOKEN_GROUPS, *LPTOKEN_GROUPS;
 
+typedef struct _TOKEN_GROUPS_AND_PRIVILEGES
+{
+  ULONG SidCount;
+  ULONG SidLength;
+  PSID_AND_ATTRIBUTES Sids;
+  ULONG RestrictedSidCount;
+  ULONG RestrictedSidLength;
+  PSID_AND_ATTRIBUTES RestrictedSids;
+  ULONG PrivilegeCount;
+  ULONG PrivilegeLength;
+  PLUID_AND_ATTRIBUTES Privileges;
+  LUID AuthenticationId;
+} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES;
+
 typedef struct _TOKEN_PRIVILEGES
 {
   DWORD PrivilegeCount;
index 0ee104f..c74fc21 100644 (file)
@@ -492,6 +492,7 @@ typedef struct _ADDRESS_RANGE
 #define MB_FLAGS_BOOT_LOADER_NAME (0x200)
 #define MB_FLAGS_APM_TABLE        (0x400)
 #define MB_FLAGS_GRAPHICS_TABLE   (0x800)
+#define MB_FLAGS_ACPI_TABLE       (0x1000)
 
 typedef struct _LOADER_MODULE
 {
index 1483c57..3a88cd6 100755 (executable)
@@ -58,6 +58,7 @@ typedef enum _KPROFILE_SOURCE
   ProfileTime
 } KPROFILE_SOURCE;
 
+
 // file disposition values
 
 #define FILE_SUPERSEDE                  0x0000
@@ -489,6 +490,19 @@ struct _SYSTEM_CACHE_INFORMATION
 
 } SYSTEM_CACHE_INFORMATION;
 
+// SystemInterruptInformation (23)
+typedef
+struct _SYSTEM_INTERRUPT_INFORMATION
+{
+       ULONG   ContextSwitches;
+       ULONG   DpcCount;
+       ULONG   DpcRate;
+       ULONG   TimeIncrement;
+       ULONG   DpcBypassCount;
+       ULONG   ApcBypassCount;
+
+} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;
+
 // SystemDpcInformation (24)
 typedef
 struct _SYSTEM_DPC_INFORMATION
@@ -1219,9 +1233,17 @@ extern IMPORTED ULONG NtBuildNumber;
 #define ProcessSessionInformation              24
 #define ProcessForegroundInformation           25
 #define ProcessWow64Information                        26
-/* ReactOS private. */
 #define ProcessImageFileName                   27
-#define MaxProcessInfoClass                    28
+#define ProcessLUIDDeviceMapsEnabled            28
+#define ProcessBreakOnTermination               29
+#define ProcessDebugObjectHandle                30
+#define ProcessDebugFlags                       31
+#define ProcessHandleTracing                    32
+#define ProcessUnknown33                        33
+#define ProcessUnknown34                        34
+#define ProcessUnknown35                        35
+#define ProcessCookie                           36
+#define MaxProcessInfoClass                     36
 
 /*
  * thread query / set information class
@@ -1263,9 +1285,9 @@ typedef enum _MUTANT_INFORMATION_CLASS
 
 typedef struct _MUTANT_BASIC_INFORMATION
 {
-  LONG Count;
-  BOOLEAN Owned;
-  BOOLEAN Abandoned;
+  LONG CurrentCount;
+  BOOLEAN OwnedByCaller;
+  BOOLEAN AbandonedState;
 } MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
 
 
@@ -1379,17 +1401,17 @@ struct _SYSTEM_DEVICE_INFORMATION
 // SystemProcessorPerformanceInformation (8)
 // (one per processor in the system)
 typedef
-struct _SYSTEM_PROCESSORTIME_INFO
-{
-       TIME    TotalProcessorRunTime;
-       TIME    TotalProcessorTime;
-       TIME    TotalProcessorUserTime;
-       TIME    TotalDPCTime;
-       TIME    TotalInterruptTime;
-       ULONG   TotalInterrupts;
-       ULONG   Unused;
+struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
+{
+       LARGE_INTEGER   IdleTime;
+       LARGE_INTEGER   KernelTime;
+       LARGE_INTEGER   UserTime;
+       LARGE_INTEGER   DpcTime;
+       LARGE_INTEGER   InterruptTime;
+       ULONG   InterruptCount;
+       ULONG   Reserved;
 
-} SYSTEM_PROCESSORTIME_INFO, *PSYSTEM_PROCESSORTIME_INFO;
+} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
 
 // SystemFlagsInformation (9)
 typedef
index d903d8f..c083557 100644 (file)
@@ -590,6 +590,7 @@ typedef struct _IMAGE_RESOURCE_DIRECTORY {
 #define IMAGE_SUBSYSTEM_OS2_CUI                5
 #define IMAGE_SUBSYSTEM_POSIX_GUI      6
 #define IMAGE_SUBSYSTEM_POSIX_CUI      7
+#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8
 #define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION        10
 #define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER        11
index 9535555..9bebfab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2004 KJK::Hyperion
+ Copyright (c) 2004/2005 KJK::Hyperion
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
@@ -67,7 +67,6 @@
 static _SEH_LOCALS_TYPENAME(_SEHDummyLocals) { int Dummy_; } _SEHLocals;
 static void __inline _SEHDummyLocalsUser(void) { (void)_SEHLocals; }
 
-/* TODO: <pseh/native.h> to wrap native SEH implementations */
 #include <pseh/framebased.h>
 
 #endif
index 3dcbb36..9760c94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2004 KJK::Hyperion
+ Copyright (c) 2004/2005 KJK::Hyperion
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
index 51823e0..d039b2f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2004 KJK::Hyperion
+ Copyright (c) 2004/2005 KJK::Hyperion
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
 
 /*
  Fall back to non-optimal, non-native NLG implementation for environments
- without their own (e.g., currently, kernel-mode ReactOS/Windows)
+ without their own (e.g., currently, kernel-mode ReactOS/Windows). THIS IS NOT
+ RECOMMENDED AND IT WILL BE DROPPED IN A FUTURE VERSION BECAUSE IT MAY CAUSE
+ SEVERE STACK CORRUPTION. REIMPLEMENT OR PORT YOUR COMPILER'S NATIVE NLG
+ IMPLEMENTATION INSTEAD.
 */
 #ifdef _SEH_NO_NATIVE_NLG
 # include <pseh/setjmp.h>
@@ -222,6 +225,97 @@ static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler
 
 #define _SEH_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0)
 
+/* New syntax */
+#define _SEH2_STATE_INIT_EXCEPT  (1)
+#define _SEH2_STATE_INIT_FINALLY (_SEH2_STATE_INIT_EXCEPT + 1)
+#define _SEH2_STATE_BODY         (_SEH2_STATE_INIT_FINALLY + 1)
+#define _SEH2_STATE_HANDLER      (_SEH2_STATE_BODY + 1)
+#define _SEH2_STATE_DONE         (_SEH2_STATE_HANDLER + 1)
+
+#define _SEH2_LEAVE { _SEH2State = _SEH2_STATE_DONE; break; }
+
+#define _SEH2_TRY \
+{                                                                              \
+ int _SEH2State;                                                               \
+ _SEHFilter_t _SEH2Filter;                                                     \
+ _SEHFinally_t _SEH2Finally;                                                   \
+                                                                               \
+ _SEHFrame_t * _SEHFrame;                                                      \
+ volatile _SEHPortableFrame_t * _SEHPortableFrame;                             \
+                                                                               \
+ for(_SEH2State = 0; _SEH2State < _SEH2_STATE_DONE; ++ _SEH2State)             \
+ {                                                                             \
+  switch(_SEH2State)                                                           \
+  {                                                                            \
+   case _SEH2_STATE_BODY:                                                      \
+   {                                                                           \
+    _SEH_DECLARE_HANDLERS(_SEH2Filter, _SEH2Finally);                          \
+                                                                               \
+    _SEHFrame = _alloca(sizeof(_SEHFrame_t));                                  \
+    _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers;                        \
+    _SEHFrame->SEH_Locals = &_SEHLocals;                                       \
+                                                                               \
+    _SEHPortableFrame = &_SEHFrame->SEH_Header;                                \
+    (void)_SEHPortableFrame;                                                   \
+                                                                               \
+    if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf))                                      \
+     break;                                                                    \
+                                                                               \
+    _SEHEnter(&_SEHFrame->SEH_Header);
+
+#define _SEH2_EXCEPT(FILTER_) \
+    _SEHLeave(&_SEHFrame->SEH_Header);                                         \
+    _SEH2State = _SEH2_STATE_DONE;                                             \
+                                                                               \
+    break;                                                                     \
+   }                                                                           \
+                                                                               \
+   case _SEH2_STATE_INIT_EXCEPT:                                               \
+   {                                                                           \
+    _SEH2Filter = (FILTER_);                                                   \
+    break;                                                                     \
+   }                                                                           \
+                                                                               \
+   case _SEH2_STATE_HANDLER:                                                   \
+   {                                                                           \
+    _SEHLeave(&_SEHFrame->SEH_Header);
+
+#define _SEH2_FINALLY(FINALLY_) \
+    break;                                                                     \
+   }                                                                           \
+                                                                               \
+   case _SEH2_STATE_INIT_FINALLY:                                              \
+   {                                                                           \
+    _SEH2Finally = (FINALLY_);
+
+#define _SEH2_END \
+    break;                                                                     \
+   }                                                                           \
+                                                                               \
+   default:                                                                    \
+   {                                                                           \
+    switch(state)                                                              \
+    {                                                                          \
+     case _SEH2_STATE_INIT_EXCEPT: _SEH2Filter = NULL; break;                  \
+     case _SEH2_STATE_INIT_FINALLY: _SEH2Finally = NULL; break;                \
+     case _SEH2_STATE_HANDLER: _SEHLeave(&_SEHFrame->SEH_Header); break;       \
+    }                                                                          \
+                                                                               \
+    break;                                                                     \
+   }                                                                           \
+  }                                                                            \
+ }                                                                             \
+                                                                               \
+ if(_SEHHandlers.SH_Finally)                                                   \
+  _SEHHandlers.SH_Finally(&_SEHFrame->SEH_Header);                             \
+}
+
+#define _SEH2_HANDLE _SEH2_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
+
+#define _SEH2_GetExceptionCode     _SEH_GetExceptionCode
+#define _SEH2_GetExceptionPointers _SEH_GetExceptionPointers
+#define _SEH2_AbnormalTermination  _SEH_AbnormalTermination
+
 #endif
 
 /* EOF */
index 4c5f916..dfad5db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2004 KJK::Hyperion
+ Copyright (c) 2004/2005 KJK::Hyperion
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
diff --git a/reactos/include/pseh/native.h b/reactos/include/pseh/native.h
new file mode 100644 (file)
index 0000000..931f5b8
--- /dev/null
@@ -0,0 +1,242 @@
+/*\r
+ Copyright (c) 2004/2005 KJK::Hyperion\r
\r
+ Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ this software and associated documentation files (the "Software"), to deal in\r
+ the Software without restriction, including without limitation the rights to\r
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r
+ of the Software, and to permit persons to whom the Software is furnished to do\r
+ so, subject to the following conditions:\r
\r
+ The above copyright notice and this permission notice shall be included in all\r
+ copies or substantial portions of the Software.\r
\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ SOFTWARE.\r
+*/\r
+\r
+#ifndef KJK_PSEH_NATIVE_H_\r
+#define KJK_PSEH_NATIVE_H_\r
+\r
+#include <excpt.h>\r
+#include <pseh/excpt.h>\r
+\r
+/*\r
+ Note: just define __inline to an empty symbol if your C compiler doesn't\r
+ support it\r
+*/\r
+#ifdef __cplusplus\r
+# ifndef __inline\r
+#  define __inline inline\r
+# endif\r
+#endif\r
+\r
+typedef long (__stdcall * _SEHFilter_t)\r
+(\r
+ long,\r
+ struct _EXCEPTION_POINTERS *,\r
+ void *\r
+);\r
+\r
+typedef void (__stdcall * _SEHFinally_t)\r
+(\r
+ int,\r
+ void *\r
+);\r
+\r
+static __inline long _SEHCallFilter\r
+(\r
+ _SEHFilter_t _SEHFilter,\r
+ long _SEHExceptionCode,\r
+ struct _EXCEPTION_POINTERS * _SEHExceptionPointers,\r
+ void * _SEHPVLocals\r
+)\r
+{\r
+ if(_SEHFilter == _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))\r
+  return _SEH_EXECUTE_HANDLER;\r
+ else if(_SEHFilter == _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH))\r
+  return _SEH_CONTINUE_SEARCH;\r
+ else if(_SEHFilter == _SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION))\r
+  return _SEH_CONTINUE_EXECUTION;\r
+ else if(_SEHFilter)\r
+  return _SEHFilter(_SEHExceptionCode, _SEHExceptionPointers, _SEHPVLocals);\r
+ else\r
+  return _SEH_CONTINUE_SEARCH;\r
+}\r
+\r
+static __inline void _SEHCallFinally\r
+(\r
+ _SEHFinally_t _SEHFinally,\r
+ int _SEHAbnormalTermination,\r
+ void * _SEHPVLocals\r
+)\r
+{\r
+ if(_SEHFinally)\r
+  (_SEHFinally)(_SEHAbnormalTermination, _SEHPVLocals);\r
+}\r
+\r
+/* SHARED LOCALS */\r
+/* Access the locals for the current frame */\r
+#define _SEH_ACCESS_LOCALS(LOCALS_) \\r
+ _SEH_LOCALS_TYPENAME(LOCALS_) * _SEHPLocals; \\r
+ _SEHPLocals = _SEH_PVOID_CAST(_SEH_LOCALS_TYPENAME(LOCALS_) *, _SEHPVLocals);\r
+\r
+/* Access local variable VAR_ */\r
+#define _SEH_VAR(VAR_) _SEHPLocals->VAR_\r
+\r
+/* FILTER FUNCTIONS */\r
+/* Declares a filter function's prototype */\r
+#define _SEH_FILTER(NAME_) \\r
+ long __stdcall NAME_ \\r
+ ( \\r
+  long _SEHExceptionCode, \\r
+  struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \\r
+  void * _SEHPVLocals \\r
+ )\r
+\r
+/* Declares a static filter */\r
+#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))\r
+\r
+/* Declares a PSEH filter wrapping a regular filter function */\r
+#define _SEH_WRAP_FILTER(WRAPPER_, NAME_) \\r
+ static __inline _SEH_FILTER(WRAPPER_) \\r
+ { \\r
+  return (NAME_)(_SEHExceptionPointers); \\r
+ }\r
+\r
+/* FINALLY FUNCTIONS */\r
+/* Declares a finally function's prototype */\r
+#define _SEH_FINALLY(NAME_) \\r
+ void __stdcall NAME_ \\r
+ ( \\r
+  int _SEHAbnormalTermination, \\r
+  void * _SEHPVLocals \\r
+ )\r
+\r
+/* Declares a PSEH finally function wrapping a regular function */\r
+#define _SEH_WRAP_FINALLY(WRAPPER_, NAME_) \\r
+ _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())\r
+\r
+#define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \\r
+ static __inline _SEH_FINALLY(WRAPPER_) \\r
+ { \\r
+  NAME_ ARGS_; \\r
+ }\r
+\r
+#define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \\r
+ static __inline _SEH_FINALLY(WRAPPER_) \\r
+ { \\r
+  _SEH_ACCESS_LOCALS(LOCALS_); \\r
+  NAME_ ARGS_; \\r
+ }\r
+\r
+/* SAFE BLOCKS */\r
+#define _SEH_TRY_FINALLY(FINALLY_) \\r
+ _SEH_TRY_FILTER_FINALLY \\r
+ ( \\r
+  _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH), \\r
+  (FINALLY_) \\r
+ )\r
+\r
+#define _SEH_END_FINALLY _SEH_HANDLE _SEH_END\r
+\r
+#define _SEH_TRY_FILTER(FILTER_) \\r
+ _SEH_TRY_FILTER_FINALLY((FILTER_), NULL)\r
+\r
+#define _SEH_TRY_HANDLE_FINALLY(FINALLY_) \\r
+ _SEH_TRY_FILTER_FINALLY \\r
+ ( \\r
+  _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER), \\r
+  (FINALLY_) \\r
+ )\r
+\r
+#define _SEH_TRY \\r
+ _SEH_TRY_HANDLE_FINALLY(NULL)\r
+\r
+#define _SEH_CALL_FILTER(FILTER_) \\r
+ _SEHCallFilter                                                                \\r
+ (                                                                             \\r
+  (FILTER_),                                                                   \\r
+  GetExceptionCode(),                                                          \\r
+  GetExceptionPointers(),                                                      \\r
+  _SEHPVLocals                                                                 \\r
+ )\r
+\r
+#define _SEH_CALL_FINALLY(FINALLY_) \\r
+ _SEHCallFinally((FINALLY_), (AbnormalTermination() != 0), _SEHPVLocals)\r
+\r
+#define _SEH_TRY_FILTER_FINALLY(FILTER_, FINALLY_) \\r
+ __try                                                                         \\r
+ {                                                                             \\r
+  _SEHFinally_t _SEHFinally = (FINALLY_);                                      \\r
+  _SEHFilter_t _SEHFilter = (FILTER_);                                         \\r
+  void * _SEHPVLocals = &_SEHLocals;                                           \\r
+  (void)_SEHPVLocals;                                                          \\r
+                                                                               \\r
+  __try                                                                        \\r
+  {\r
+\r
+#define _SEH_HANDLE \\r
+  }                                                                            \\r
+  __except(_SEH_CALL_FILTER(_SEHFilter))                                       \\r
+  {                                                                            \\r
+   struct _EXCEPTION_POINTERS * _SEHExceptionPointers = GetExceptionPointers();\\r
+   long _SEHExceptionCode = GetExceptionCode();                                \\r
+\r
+#define _SEH_END \\r
+  }                                                                            \\r
+ }                                                                             \\r
+ __finally                                                                     \\r
+ {                                                                             \\r
+  _SEH_CALL_FINALLY(_SEHFinally);                                              \\r
+ }\r
+\r
+#define _SEH_LEAVE __leave\r
+\r
+#define _SEH_GetExceptionCode() (_SEHExceptionCode)\r
+#define _SEH_GetExceptionPointers() (_SEHExceptionPointers)\r
+#define _SEH_AbnormalTermination() (_SEHAbnormalTermination)\r
+\r
+/* New syntax */\r
+\r
+#define _SEH2_TRY \\r
+ {                                                                             \\r
+  void * _SEHPVLocals = &_SEHLocals;                                           \\r
+  (void)_SEHPVLocals;                                                          \\r
+                                                                               \\r
+  __try                                                                        \\r
+  {\r
+\r
+#define _SEH2_EXCEPT(FILTER_) \\r
+  }                                                                            \\r
+  __except(_SEH_CALL_FILTER(FILTER_))                                          \\r
+  {                                                                            \\r
+   struct _EXCEPTION_POINTERS * _SEHExceptionPointers = GetExceptionPointers();\\r
+   long _SEHExceptionCode = GetExceptionCode();                                \\r
+\r
+#define _SEH2_FINALLY(FINALLY_) \\r
+  }                                                                            \\r
+  __finally                                                                    \\r
+  {                                                                            \\r
+   _SEH_CALL_FINALLY(FINALLY_)\r
+\r
+#define _SEH2_END \\r
+  }                                                                            \\r
+ }\r
+\r
+#define _SEH2_HANDLE _SEH2_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))\r
+\r
+#define _SEH2_LEAVE _SEH_LEAVE\r
+\r
+#define _SEH2_GetExceptionCode     _SEH_GetExceptionCode\r
+#define _SEH2_GetExceptionPointers _SEH_GetExceptionPointers\r
+#define _SEH2_AbnormalTermination  _SEH_AbnormalTermination\r
+\r
+#endif\r
+\r
+/* EOF */\r
index 6acf58b..b4f2cd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2004 KJK::Hyperion
+ Copyright (c) 2004/2005 KJK::Hyperion
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of
  this software and associated documentation files (the "Software"), to deal in
index 01bc9a1..aca5158 100644 (file)
@@ -3,21 +3,31 @@
 
 /* $Id$ */
 
-/* smdll/connect.c */
+/* smlib/connect.c */
 NTSTATUS STDCALL
 SmConnectApiPort (IN      PUNICODE_STRING  pSbApiPortName  OPTIONAL,
                  IN      HANDLE           hSbApiPort      OPTIONAL,
                  IN      DWORD            dwSubsystem     OPTIONAL, /* pe.h */
                  IN OUT  PHANDLE          phSmApiPort);
-/* smdll/compses.c */
+/* smlib/compses.c */
 NTSTATUS STDCALL
 SmCompleteSession (IN     HANDLE  hSmApiPort,
                   IN     HANDLE  hSbApiPort,
                   IN     HANDLE  hApiPort);
-/* smdll/execpgm.c */
+/* smlib/execpgm.c */
 NTSTATUS STDCALL
 SmExecuteProgram (IN     HANDLE           hSmApiPort,
                  IN     PUNICODE_STRING  Pgm
                  );
+/* smdll/query.c */
+typedef enum {
+       SM_BASE_INFORMATION
+} SM_INFORMATION_CLASS, *PSM_INFORMATION_CLASS;
+
+NTSTATUS STDCALL
+SmQuery (IN      HANDLE                SmApiPort,
+        IN      SM_INFORMATION_CLASS  SmInformationClass,
+        IN OUT  PVOID                 Data,
+        IN OUT  PULONG                DataLength);
 
 #endif /* ndef INCLUDE_SM_HELPER_H */
diff --git a/reactos/include/sockets.h b/reactos/include/sockets.h
deleted file mode 100644 (file)
index 13f86a3..0000000
+++ /dev/null
@@ -1,958 +0,0 @@
-/* 
-   Sockets.h
-
-   Windows Sockets specification version 1.1
-
-   Copyright (C) 1996 Free Software Foundation, Inc.
-   Thanks to Linux header files for supplying many needed definitions
-
-   Author:  Scott Christley <scottc@net-community.com>
-   Date: 1996
-   
-   This file is part of the Windows32 API Library.
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 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
-   Library General Public License for more details.
-
-   If you are interested in a warranty or support for this source code,
-   contact Scott Christley <scottc@net-community.com> for more information.
-   
-   You should have received a copy of the GNU Library General Public
-   License along with this library; see the file COPYING.LIB.
-   If not, write to the Free Software Foundation, 
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/ 
-
-/*-
- * Portions Copyright (c) 1980, 1983, 1988, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#ifndef _GNU_H_WINDOWS32_SOCKETS
-#define _GNU_H_WINDOWS32_SOCKETS
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* BSD */
-#ifndef _SYS_TYPES_H
-typedef unsigned char   u_char;
-typedef unsigned short  u_short;
-typedef unsigned int    u_int;
-typedef unsigned long   u_long;
-#endif
-
-/*
-  Default maximium number of sockets.
-  Define this before including Sockets.h to increase; this does not
-  mean that the underlying Windows Sockets implementation has to
-  support that many!
-  */
-#ifndef FD_SETSIZE
-#define FD_SETSIZE      64
-#endif /* !FD_SETSIZE */
-
-/*
-  These macros are critical to the usage of Windows Sockets.
-  According to the documentation, a SOCKET is no longer represented
-  by a "small non-negative integer"; so all programs MUST use these
-  macros for setting, initializing, clearing and checking the
-  fd_set structures.
-  */
-
-typedef u_int           SOCKET;
-
-/* fd_set may have been defined by the newlib <sys/types.h>.  */
-#ifdef fd_set
-#undef fd_set
-#endif
-typedef struct fd_set {
-        u_int   fd_count;
-        SOCKET  fd_array[FD_SETSIZE];
-} fd_set;
-
-/* Internal function, not documented except in winsock.h */
-extern int PASCAL __WSAFDIsSet(SOCKET, fd_set*);
-
-#ifdef FD_CLR
-#undef FD_CLR
-#endif
-#define FD_CLR(fd, set) do { \
-    u_int __i; \
-    for (__i = 0; __i < ((fd_set*)(set))->fd_count ; __i++) { \
-        if (((fd_set*)(set))->fd_array[__i] == fd) { \
-            while (__i < ((fd_set*)(set))->fd_count-1) { \
-                ((fd_set*)(set))->fd_array[__i] = \
-                    ((fd_set*)(set))->fd_array[__i+1]; \
-                __i++; \
-            } \
-            ((fd_set*)(set))->fd_count--; \
-            break; \
-        } \
-    } \
-} while(0)
-
-#ifdef FD_SET
-#undef FD_SET
-#endif
-#define FD_SET(fd, set) do { \
-    if (((fd_set*)(set))->fd_count < FD_SETSIZE) \
-        ((fd_set*)(set))->fd_array[((fd_set*)(set))->fd_count++]=(fd);\
-} while(0)
-
-#ifdef FD_ZERO
-#undef FD_ZERO
-#endif
-#define FD_ZERO(set) (((fd_set*)(set))->fd_count=0)
-
-#ifdef FD_ISSET
-#undef FD_ISSET
-#endif
-#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set*)(set))
-
-/*
-  time structures
-  */
-struct timeval {
-  long tv_sec;     /* seconds */
-  long tv_usec;    /* microseconds */
-};
-struct timezone {
-  int tz_minuteswest; /* minutes west of Greenwich */
-  int tz_dsttime;     /* type of dst correction */
-};
-
-/*
- Operations on timevals.
-
- NB: timercmp does not work for >= or <=.
- */
-#define        timerisset(tvp)         ((tvp)->tv_sec || (tvp)->tv_usec)
-#define        timercmp(tvp, uvp, cmp) \
-    (((tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) \
-    || (tvp)->tv_sec cmp (uvp)->tv_sec)
-#define        timerclear(tvp)         ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
-/*
-  ioctl command encoding.
-  Some of this is different than what Linux has
-  */
-#define IOCPARM_MASK    0x7f
-#define IOC_VOID        0x20000000
-#define IOC_OUT         0x40000000
-#define IOC_IN          0x80000000
-#define IOC_INOUT       (IOC_IN | IOC_OUT)
-
-/* _IO(magic, subcode) */
-#define _IO(c,d)        (IOC_VOID | ((c)<<8) | (d))
-/* _IOXX(magic, subcode, arg_t) */
-#define _IOW(c,d,t)     (IOC_IN | (((long)sizeof(t) & IOCPARM_MASK)<<16) | \
-                        ((c)<<8) | (d))
-#define _IOR(c,d,t)     (IOC_OUT | (((long)sizeof(t) & IOCPARM_MASK)<<16) | \
-                        ((c)<<8) | (d))
-
-/*
-  This stuff is hard-coded on Linux
-  But winsock.h uses the macros defined above
-  */
-#define FIONREAD    _IOR('f', 127, u_long)
-#define FIONBIO     _IOW('f', 126, u_long)
-#define FIOASYNC    _IOW('f', 125, u_long)
-
-#define SIOCSHIWAT  _IOW('s',  0, u_long)
-#define SIOCGHIWAT  _IOR('s',  1, u_long)
-#define SIOCSLOWAT  _IOW('s',  2, u_long)
-#define SIOCGLOWAT  _IOR('s',  3, u_long)
-#define SIOCATMARK  _IOR('s',  7, u_long)
-
-/*
- Structures returned by network data base library, taken from the
- BSD file netdb.h.  All addresses are supplied in host order, and
- returned in network order (suitable for use in system calls).
-
- Slight modifications for differences between Linux and winsock.h
- */
-
-struct  hostent {
-  char    *h_name;                /* official name of host */
-  char    **h_aliases;            /* alias list */
-  short   h_addrtype;             /* host address type */
-  short   h_length;               /* length of address */
-  char    **h_addr_list;          /* list of addresses */
-#define h_addr  h_addr_list[0]    /* address, for backward compat */
-};
-
-/*
- * Assumption here is that a network number
- * fits in an unsigned long -- someday that won't be true!
- */
-struct  netent {
-  char    *n_name;      /* official name of net */
-  char    **n_aliases;  /* alias list */
-  short   n_addrtype;   /* net address type */
-  u_long  n_net;        /* network # */
-};
-
-struct  servent {
-  char    *s_name;      /* official service name */
-  char    **s_aliases;  /* alias list */
-  short   s_port;       /* port # */
-  char    *s_proto;     /* protocol to use */
-};
-
-struct  protoent {
-  char    *p_name;      /* official protocol name */
-  char    **p_aliases;  /* alias list */
-  short   p_proto;      /* protocol # */
-};
-
-/*
-  Standard well-known IP protocols.
-  For some reason there are differences between Linx and winsock.h
-  */
-enum {
-  IPPROTO_IP = 0,
-  IPPROTO_ICMP = 1,
-  IPPROTO_GGP = 2,               /* huh? */
-  IPPROTO_IPIP = 4,
-  IPPROTO_TCP = 6,               /* Transmission Control Protocol */
-  IPPROTO_EGP = 8,
-  IPPROTO_PUP = 12,
-  IPPROTO_UDP = 17,              /* User Datagram Protocol */
-  IPPROTO_IDP = 22,
-  IPPROTO_ND = 77,               /* This one was in winsock.h */
-
-  IPPROTO_RAW = 255,             /* raw IP packets */
-  IPPROTO_MAX
-};
-
-/* Standard well-known ports */
-enum {
-  IPPORT_ECHO = 7,
-  IPPORT_DISCARD = 9,
-  IPPORT_SYSTAT = 11,
-  IPPORT_DAYTIME = 13,
-  IPPORT_NETSTAT = 15,
-  IPPORT_FTP = 21,
-  IPPORT_TELNET = 23,
-  IPPORT_SMTP = 25,
-  IPPORT_TIMESERVER = 37,
-  IPPORT_NAMESERVER = 42,
-  IPPORT_WHOIS = 43,
-  IPPORT_MTP = 57,
-
-  IPPORT_TFTP = 69,
-  IPPORT_RJE = 77,
-  IPPORT_FINGER = 79,
-  IPPORT_TTYLINK = 87,
-  IPPORT_SUPDUP = 95,
-
-  IPPORT_EXECSERVER = 512,
-  IPPORT_LOGINSERVER = 513,
-  IPPORT_CMDSERVER = 514,
-  IPPORT_EFSSERVER = 520,
-
-  /* UDP ports. */
-  IPPORT_BIFFUDP = 512,
-  IPPORT_WHOSERVER = 513,
-  IPPORT_ROUTESERVER = 520,
-
-  /* Ports less than this value are reservered for privileged processes. */
-  IPPORT_RESERVED = 1024,
-
-  /* Ports greater than this value are reserved for 
-     (non-privileged) processes */
-  IPPORT_USERRESERVED = 5000
-};
-
-/* Link numbers. */
-#define IMPLINK_IP              155
-#define IMPLINK_LOWEXPER        156
-#define IMPLINK_HIGHEXPER       158
-
-/* Linux uses a simple unsigned long int, but winsock.h ... */
-struct in_addr {
-        union {
-                struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
-                struct { u_short s_w1,s_w2; } S_un_w;
-                u_long S_addr;
-        } S_un;
-#define s_addr  S_un.S_addr
-#define s_host  S_un.S_un_b.s_b2
-#define s_net   S_un.S_un_b.s_b1
-#define s_imp   S_un.S_un_w.s_w2
-#define s_impno S_un.S_un_b.s_b4
-#define s_lh    S_un.S_un_b.s_b3
-};
-
-/*
- Definitions of bits in internet address integers.
- On subnets, host and network parts are found according
- to the subnet mask, not these masks.
- */
-#define IN_CLASSA(i)            (((long)(i) & 0x80000000) == 0)
-#define IN_CLASSA_NET           0xff000000
-#define IN_CLASSA_NSHIFT        24
-#define IN_CLASSA_HOST          0x00ffffff
-#define IN_CLASSA_MAX           128
-
-#define IN_CLASSB(i)            (((long)(i) & 0xc0000000) == 0x80000000)
-#define IN_CLASSB_NET           0xffff0000
-#define IN_CLASSB_NSHIFT        16
-#define IN_CLASSB_HOST          0x0000ffff
-#define IN_CLASSB_MAX           65536
-
-#define IN_CLASSC(i)            (((long)(i) & 0xe0000000) == 0xc0000000)
-#define IN_CLASSC_NET           0xffffff00
-#define IN_CLASSC_NSHIFT        8
-#define IN_CLASSC_HOST          0x000000ff
-
-#define INADDR_ANY              (u_long)0x00000000
-#define INADDR_LOOPBACK         0x7f000001
-#define INADDR_BROADCAST        (u_long)0xffffffff    
-#define INADDR_NONE             0xffffffff
-
-/*
- Structure describing an Internet (IP) socket address.
- */
-struct sockaddr_in {
-  short   sin_family;
-  u_short sin_port;
-  struct  in_addr sin_addr;
-  char    sin_zero[8];
-};
-
-/*
-  EVERYTHING FROM THIS POINT IS MAINLY SPECIFIC TO Win32
-
-  Structure which holds the detail for the underlying Window Sockets
-  implementation.  Set when WSAStartup() is called.
-  */
-#define WSADESCRIPTION_LEN      256
-#define WSASYS_STATUS_LEN       128
-
-typedef struct WSAData {
-  WORD wVersion;
-  WORD wHighVersion;
-  char szDescription[WSADESCRIPTION_LEN+1];
-  char szSystemStatus[WSASYS_STATUS_LEN+1];
-  unsigned short iMaxSockets;
-  unsigned short iMaxUdpDg;
-  char *lpVendorInfo;
-} WSADATA, *LPWSADATA;
-
-#define IP_OPTIONS          1
-#define IP_MULTICAST_IF     2
-#define IP_MULTICAST_TTL    3
-#define IP_MULTICAST_LOOP   4
-#define IP_ADD_MEMBERSHIP   5
-#define IP_DROP_MEMBERSHIP  6
-
-#define IP_DEFAULT_MULTICAST_TTL   1
-#define IP_DEFAULT_MULTICAST_LOOP  1
-#define IP_MAX_MEMBERSHIPS         20
-
-struct ip_mreq {
-  struct in_addr imr_multiaddr;
-  struct in_addr imr_interface;
-};
-
-/*
- * Definitions related to sockets: types, address families, options,
- * taken from the BSD file sys/socket.h.
- */
-
-/*
- * This is used instead of -1, since the
- * SOCKET type is unsigned.
- */
-#define INVALID_SOCKET  (SOCKET)(~0)
-#define SOCKET_ERROR            (-1)
-
-/* Socket types. */
-#define SOCK_STREAM     1
-#define SOCK_DGRAM      2
-#define SOCK_RAW        3
-#define SOCK_RDM        4 
-#define SOCK_SEQPACKET  5
-
-/* For setsockoptions(2) */
-#define SO_DEBUG        0x0001
-#define SO_ACCEPTCONN   0x0002
-#define SO_REUSEADDR    0x0004
-#define SO_KEEPALIVE    0x0008
-#define SO_DONTROUTE    0x0010
-#define SO_BROADCAST    0x0020
-#define SO_USELOOPBACK  0x0040
-#define SO_LINGER       0x0080
-#define SO_OOBINLINE    0x0100
-
-#define SO_DONTLINGER   (u_int)(~SO_LINGER)
-
-/*
- * Additional options.
- */
-#define SO_SNDBUF       0x1001          /* send buffer size */
-#define SO_RCVBUF       0x1002          /* receive buffer size */
-#define SO_SNDLOWAT     0x1003          /* send low-water mark */
-#define SO_RCVLOWAT     0x1004          /* receive low-water mark */
-#define SO_SNDTIMEO     0x1005          /* send timeout */
-#define SO_RCVTIMEO     0x1006          /* receive timeout */
-#define SO_ERROR        0x1007          /* get error status and clear */
-#define SO_TYPE         0x1008          /* get socket type */
-
-/*
- * Options for connect and disconnect data and options.  Used only by
- * non-TCP/IP transports such as DECNet, OSI TP4, etc.
- */
-#define SO_CONNDATA     0x7000
-#define SO_CONNOPT      0x7001
-#define SO_DISCDATA     0x7002
-#define SO_DISCOPT      0x7003
-#define SO_CONNDATALEN  0x7004
-#define SO_CONNOPTLEN   0x7005
-#define SO_DISCDATALEN  0x7006
-#define SO_DISCOPTLEN   0x7007
-
-/*
- * Option for opening sockets for synchronous access.
- */
-#define SO_OPENTYPE     0x7008
-
-#define SO_SYNCHRONOUS_ALERT    0x10
-#define SO_SYNCHRONOUS_NONALERT 0x20
-
-/*
- * Other NT-specific options.
- */
-#define SO_MAXDG        0x7009
-#define SO_MAXPATHDG    0x700A
-
-/*
- * TCP options.
- */
-#define TCP_NODELAY     0x0001
-#define TCP_BSDURGENT   0x7000
-
-/*
- * Address families.
- */
-#define AF_UNSPEC       0               /* unspecified */
-#define AF_UNIX         1               /* local to host (pipes, portals) */
-#define AF_INET         2               /* internetwork: UDP, TCP, etc. */
-#define AF_IMPLINK      3               /* arpanet imp addresses */
-#define AF_PUP          4               /* pup protocols: e.g. BSP */
-#define AF_CHAOS        5               /* mit CHAOS protocols */
-#define AF_IPX          6               /* IPX and SPX */
-#define AF_NS           6               /* XEROX NS protocols */
-#define AF_ISO          7               /* ISO protocols */
-#define AF_OSI          AF_ISO          /* OSI is ISO */
-#define AF_ECMA         8               /* european computer manufacturers */
-#define AF_DATAKIT      9               /* datakit protocols */
-#define AF_CCITT        10              /* CCITT protocols, X.25 etc */
-#define AF_SNA          11              /* IBM SNA */
-#define AF_DECnet       12              /* DECnet */
-#define AF_DLI          13              /* Direct data link interface */
-#define AF_LAT          14              /* LAT */
-#define AF_HYLINK       15              /* NSC Hyperchannel */
-#define AF_APPLETALK    16              /* AppleTalk */
-#define AF_NETBIOS      17              /* NetBios-style addresses */
-
-#define AF_MAX          18
-
-/*
- * Structure used by kernel to store most
- * addresses.
- */
-struct sockaddr {
-  u_short sa_family;
-  char    sa_data[14];
-};
-
-/*
- * Structure used by kernel to pass protocol
- * information in raw sockets.
- */
-struct sockproto {
-  u_short sp_family;
-  u_short sp_protocol;
-};
-
-/*
- * Protocol families, same as address families for now.
- */
-#define PF_UNSPEC       AF_UNSPEC
-#define PF_UNIX         AF_UNIX
-#define PF_INET         AF_INET
-#define PF_IMPLINK      AF_IMPLINK
-#define PF_PUP          AF_PUP
-#define PF_CHAOS        AF_CHAOS
-#define PF_NS           AF_NS
-#define PF_IPX          AF_IPX
-#define PF_ISO          AF_ISO
-#define PF_OSI          AF_OSI
-#define PF_ECMA         AF_ECMA
-#define PF_DATAKIT      AF_DATAKIT
-#define PF_CCITT        AF_CCITT
-#define PF_SNA          AF_SNA
-#define PF_DECnet       AF_DECnet
-#define PF_DLI          AF_DLI
-#define PF_LAT          AF_LAT
-#define PF_HYLINK       AF_HYLINK
-#define PF_APPLETALK    AF_APPLETALK
-
-#define PF_MAX          AF_MAX
-
-/*
- * Structure used for manipulating linger option.
- */
-struct  linger {
-  u_short l_onoff;
-  u_short l_linger;
-};
-
-/*
- * Level number for (get/set)sockopt() to apply to socket itself.
- */
-#define SOL_SOCKET      0xffff          /* options for socket level */
-
-/*
- * Maximum queue length specifiable by listen.
- */
-#define SOMAXCONN       5
-
-#define MSG_OOB         0x1             /* process out-of-band data */
-#define MSG_PEEK        0x2             /* peek at incoming message */
-#define MSG_DONTROUTE   0x4             /* send without using routing tables */
-
-#define MSG_MAXIOVLEN   16
-
-#define        MSG_PARTIAL     0x8000          /* partial send or recv for message xport */
-
-/*
- * Define constant based on rfc883, used by gethostbyxxxx() calls.
- */
-#define MAXGETHOSTSTRUCT        1024
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN          MAXGETHOSTSTRUCT
-#endif
-
-/*
- * Define flags to be used with the WSAAsyncSelect() call.
- */
-#define FD_READ         0x01
-#define FD_WRITE        0x02
-#define FD_OOB          0x04
-#define FD_ACCEPT       0x08
-#define FD_CONNECT      0x10
-#define FD_CLOSE        0x20
-
-/*
- * All Windows Sockets error constants are biased by WSABASEERR from
- * the "normal"
- */
-#define WSABASEERR              10000
-/*
- * Windows Sockets definitions of regular Microsoft C error constants
- */
-#define WSAEINTR                (WSABASEERR+4)
-#define WSAEBADF                (WSABASEERR+9)
-#define WSAEACCES               (WSABASEERR+13)
-#define WSAEFAULT               (WSABASEERR+14)
-#define WSAEINVAL               (WSABASEERR+22)
-#define WSAEMFILE               (WSABASEERR+24)
-
-/*
- * Windows Sockets definitions of regular Berkeley error constants
- */
-#define WSAEWOULDBLOCK          (WSABASEERR+35)
-#define WSAEINPROGRESS          (WSABASEERR+36)
-#define WSAEALREADY             (WSABASEERR+37)
-#define WSAENOTSOCK             (WSABASEERR+38)
-#define WSAEDESTADDRREQ         (WSABASEERR+39)
-#define WSAEMSGSIZE             (WSABASEERR+40)
-#define WSAEPROTOTYPE           (WSABASEERR+41)
-#define WSAENOPROTOOPT          (WSABASEERR+42)
-#define WSAEPROTONOSUPPORT      (WSABASEERR+43)
-#define WSAESOCKTNOSUPPORT      (WSABASEERR+44)
-#define WSAEOPNOTSUPP           (WSABASEERR+45)
-#define WSAEPFNOSUPPORT         (WSABASEERR+46)
-#define WSAEAFNOSUPPORT         (WSABASEERR+47)
-#define WSAEADDRINUSE           (WSABASEERR+48)
-#define WSAEADDRNOTAVAIL        (WSABASEERR+49)
-#define WSAENETDOWN             (WSABASEERR+50)
-#define WSAENETUNREACH          (WSABASEERR+51)
-#define WSAENETRESET            (WSABASEERR+52)
-#define WSAECONNABORTED         (WSABASEERR+53)
-#define WSAECONNRESET           (WSABASEERR+54)
-#define WSAENOBUFS              (WSABASEERR+55)
-#define WSAEISCONN              (WSABASEERR+56)
-#define WSAENOTCONN             (WSABASEERR+57)
-#define WSAESHUTDOWN            (WSABASEERR+58)
-#define WSAETOOMANYREFS         (WSABASEERR+59)
-#define WSAETIMEDOUT            (WSABASEERR+60)
-#define WSAECONNREFUSED         (WSABASEERR+61)
-#define WSAELOOP                (WSABASEERR+62)
-#define WSAENAMETOOLONG         (WSABASEERR+63)
-#define WSAEHOSTDOWN            (WSABASEERR+64)
-#define WSAEHOSTUNREACH         (WSABASEERR+65)
-#define WSAENOTEMPTY            (WSABASEERR+66)
-#define WSAEPROCLIM             (WSABASEERR+67)
-#define WSAEUSERS               (WSABASEERR+68)
-#define WSAEDQUOT               (WSABASEERR+69)
-#define WSAESTALE               (WSABASEERR+70)
-#define WSAEREMOTE              (WSABASEERR+71)
-
-#define WSAEDISCON              (WSABASEERR+101)
-
-/*
- * Extended Windows Sockets error constant definitions
- */
-#define WSASYSNOTREADY          (WSABASEERR+91)
-#define WSAVERNOTSUPPORTED      (WSABASEERR+92)
-#define WSANOTINITIALISED       (WSABASEERR+93)
-
-/*
- * Error return codes from gethostbyname() and gethostbyaddr()
- * (when using the resolver). Note that these errors are
- * retrieved via WSAGetLastError() and must therefore follow
- * the rules for avoiding clashes with error numbers from
- * specific implementations or language run-time systems.
- * For this reason the codes are based at WSABASEERR+1001.
- * Note also that [WSA]NO_ADDRESS is defined only for
- * compatibility purposes.
- */
-
-#define h_errno         WSAGetLastError()
-
-/* Authoritative Answer: Host not found */
-#define WSAHOST_NOT_FOUND       (WSABASEERR+1001)
-#define HOST_NOT_FOUND          WSAHOST_NOT_FOUND
-
-/* Non-Authoritative: Host not found, or SERVERFAIL */
-#define WSATRY_AGAIN            (WSABASEERR+1002)
-#define TRY_AGAIN               WSATRY_AGAIN
-
-/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
-#define WSANO_RECOVERY          (WSABASEERR+1003)
-#define NO_RECOVERY             WSANO_RECOVERY
-
-/* Valid name, no data record of requested type */
-#define WSANO_DATA              (WSABASEERR+1004)
-#define NO_DATA                 WSANO_DATA
-
-/* no address, look for MX record */
-#define WSANO_ADDRESS           WSANO_DATA
-#define NO_ADDRESS              WSANO_ADDRESS
-
-/*
- * Windows Sockets errors redefined as regular Berkeley error constants.
- * These are commented out in Windows NT to avoid conflicts with errno.h.
- * Use the WSA constants instead.
- */
-#if 0
-#define EWOULDBLOCK             WSAEWOULDBLOCK
-#define EINPROGRESS             WSAEINPROGRESS
-#define EALREADY                WSAEALREADY
-#define ENOTSOCK                WSAENOTSOCK
-#define EDESTADDRREQ            WSAEDESTADDRREQ
-#define EMSGSIZE                WSAEMSGSIZE
-#define EPROTOTYPE              WSAEPROTOTYPE
-#define ENOPROTOOPT             WSAENOPROTOOPT
-#define EPROTONOSUPPORT         WSAEPROTONOSUPPORT
-#define ESOCKTNOSUPPORT         WSAESOCKTNOSUPPORT
-#define EOPNOTSUPP              WSAEOPNOTSUPP
-#define EPFNOSUPPORT            WSAEPFNOSUPPORT
-#define EAFNOSUPPORT            WSAEAFNOSUPPORT
-#define EADDRINUSE              WSAEADDRINUSE
-#define EADDRNOTAVAIL           WSAEADDRNOTAVAIL
-#define ENETDOWN                WSAENETDOWN
-#define ENETUNREACH             WSAENETUNREACH
-#define ENETRESET               WSAENETRESET
-#define ECONNABORTED            WSAECONNABORTED
-#define ECONNRESET              WSAECONNRESET
-#define ENOBUFS                 WSAENOBUFS
-#define EISCONN                 WSAEISCONN
-#define ENOTCONN                WSAENOTCONN
-#define ESHUTDOWN               WSAESHUTDOWN
-#define ETOOMANYREFS            WSAETOOMANYREFS
-#define ETIMEDOUT               WSAETIMEDOUT
-#define ECONNREFUSED            WSAECONNREFUSED
-#define ELOOP                   WSAELOOP
-#define ENAMETOOLONG            WSAENAMETOOLONG
-#define EHOSTDOWN               WSAEHOSTDOWN
-#define EHOSTUNREACH            WSAEHOSTUNREACH
-#define ENOTEMPTY               WSAENOTEMPTY
-#define EPROCLIM                WSAEPROCLIM
-#define EUSERS                  WSAEUSERS
-#define EDQUOT                  WSAEDQUOT
-#define ESTALE                  WSAESTALE
-#define EREMOTE                 WSAEREMOTE
-#endif
-
-/* Socket function prototypes */
-
-SOCKET PASCAL accept (SOCKET s, struct sockaddr *addr,
-                          int *addrlen);
-
-int PASCAL bind (SOCKET s, const struct sockaddr *addr, int namelen);
-
-int PASCAL closesocket (SOCKET s);
-
-int PASCAL connect (SOCKET s, const struct sockaddr *name, int namelen);
-
-int PASCAL ioctlsocket (SOCKET s, long cmd, u_long *argp);
-
-int PASCAL getpeername (SOCKET s, struct sockaddr *name,
-                            int * namelen);
-
-int PASCAL getsockname (SOCKET s, struct sockaddr *name,
-                            int * namelen);
-
-int PASCAL getsockopt (SOCKET s, int level, int optname,
-                           char * optval, int *optlen);
-
-u_long PASCAL htonl (u_long hostlong);
-
-u_short PASCAL htons (u_short hostshort);
-
-unsigned long PASCAL inet_addr (const char * cp);
-
-char * PASCAL inet_ntoa (struct in_addr in);
-
-int PASCAL listen (SOCKET s, int backlog);
-
-u_long PASCAL ntohl (u_long netlong);
-
-/* For some reason WSOCK.LIB has ntohs defined as a 4 byte paramter?! */
-#ifdef _WIN32
-u_short PASCAL ntohs (u_long netshort);
-#else
-u_short PASCAL ntohs (u_short netshort);
-#endif /* _WIN32 */
-
-int PASCAL recv (SOCKET s, char * buf, int len, int flags);
-
-int PASCAL recvfrom (SOCKET s, char * buf, int len, int flags,
-                         struct sockaddr *from, int * fromlen);
-
-int PASCAL select (int nfds, fd_set *readfds, fd_set *writefds,
-                       fd_set *exceptfds, const struct timeval *timeout);
-
-int PASCAL send (SOCKET s, const char * buf, int len, int flags);
-
-int PASCAL sendto (SOCKET s, const char * buf, int len, int flags,
-                       const struct sockaddr *to, int tolen);
-
-int PASCAL setsockopt (SOCKET s, int level, int optname,
-                           const char * optval, int optlen);
-
-int PASCAL shutdown (SOCKET s, int how);
-
-SOCKET PASCAL socket (int af, int type, int protocol);
-
-/* Database function prototypes */
-
-struct hostent * PASCAL gethostbyaddr(const char * addr,
-                                              int len, int type);
-
-struct hostent * PASCAL gethostbyname(const char * name);
-
-int PASCAL gethostname (char * name, int namelen);
-
-struct servent * PASCAL getservbyport(int port, const char * proto);
-
-struct servent * PASCAL getservbyname(const char * name,
-                                              const char * proto);
-
-struct protoent * PASCAL getprotobynumber(int proto);
-
-struct protoent * PASCAL getprotobyname(const char * name);
-
-/* Microsoft Windows Extension function prototypes */
-
-int PASCAL WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
-
-int PASCAL WSACleanup(void);
-
-void PASCAL WSASetLastError(int iError);
-
-int PASCAL WSAGetLastError(void);
-
-WINBOOL PASCAL WSAIsBlocking(void);
-
-int PASCAL WSAUnhookBlockingHook(void);
-
-FARPROC PASCAL WSASetBlockingHook(FARPROC lpBlockFunc);
-
-int PASCAL WSACancelBlockingCall(void);
-
-HANDLE PASCAL WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
-                                        const char * name, 
-                                        const char * proto,
-                                        char * buf, int buflen);
-
-HANDLE PASCAL WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
-                                        const char * proto, char * buf,
-                                        int buflen);
-
-HANDLE PASCAL WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
-                                         const char * name, char * buf,
-                                         int buflen);
-
-HANDLE PASCAL WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
-                                           int number, char * buf,
-                                           int buflen);
-
-HANDLE PASCAL WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
-                                        const char * name, char * buf,
-                                        int buflen);
-
-HANDLE PASCAL WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
-                                        const char * addr, int len, int type,
-                                        char * buf, int buflen);
-
-int PASCAL WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
-
-int PASCAL WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
-                               long lEvent);
-
-int PASCAL WSARecvEx (SOCKET s, char * buf, int len, int *flags);
-
-/* Microsoft Windows Extended data types */
-typedef struct sockaddr SOCKADDR;
-typedef struct sockaddr *PSOCKADDR;
-typedef struct sockaddr *LPSOCKADDR;
-
-typedef struct sockaddr_in SOCKADDR_IN;
-typedef struct sockaddr_in *PSOCKADDR_IN;
-typedef struct sockaddr_in *LPSOCKADDR_IN;
-
-typedef struct linger LINGER;
-typedef struct linger *PLINGER;
-typedef struct linger *LPLINGER;
-
-typedef struct in_addr IN_ADDR;
-typedef struct in_addr *PIN_ADDR;
-typedef struct in_addr *LPIN_ADDR;
-
-typedef struct fd_set FD_SET;
-typedef struct fd_set *PFD_SET;
-typedef struct fd_set *LPFD_SET;
-
-typedef struct hostent HOSTENT;
-typedef struct hostent *PHOSTENT;
-typedef struct hostent *LPHOSTENT;
-
-typedef struct servent SERVENT;
-typedef struct servent *PSERVENT;
-typedef struct servent *LPSERVENT;
-
-typedef struct protoent PROTOENT;
-typedef struct protoent *PPROTOENT;
-typedef struct protoent *LPPROTOENT;
-
-typedef struct timeval TIMEVAL;
-typedef struct timeval *PTIMEVAL;
-typedef struct timeval *LPTIMEVAL;
-
-/*
- * Windows message parameter composition and decomposition
- * macros.
- *
- * WSAMAKEASYNCREPLY is intended for use by the Windows Sockets implementation
- * when constructing the response to a WSAAsyncGetXByY() routine.
- */
-#define WSAMAKEASYNCREPLY(buflen,error)     MAKELONG(buflen,error)
-/*
- * WSAMAKESELECTREPLY is intended for use by the Windows Sockets implementation
- * when constructing the response to WSAAsyncSelect().
- */
-#define WSAMAKESELECTREPLY(event,error)     MAKELONG(event,error)
-/*
- * WSAGETASYNCBUFLEN is intended for use by the Windows Sockets application
- * to extract the buffer length from the lParam in the response
- * to a WSAGetXByY().
- */
-#define WSAGETASYNCBUFLEN(lParam)           LOWORD(lParam)
-/*
- * WSAGETASYNCERROR is intended for use by the Windows Sockets application
- * to extract the error code from the lParam in the response
- * to a WSAGetXByY().
- */
-#define WSAGETASYNCERROR(lParam)            HIWORD(lParam)
-/*
- * WSAGETSELECTEVENT is intended for use by the Windows Sockets application
- * to extract the event code from the lParam in the response
- * to a WSAAsyncSelect().
- */
-#define WSAGETSELECTEVENT(lParam)           LOWORD(lParam)
-/*
- * WSAGETSELECTERROR is intended for use by the Windows Sockets application
- * to extract the error code from the lParam in the response
- * to a WSAAsyncSelect().
- */
-#define WSAGETSELECTERROR(lParam)           HIWORD(lParam)
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _GNU_H_WINDOWS32_SOCKETS */
index b1e113d..49d5b79 100644 (file)
 #define IOCTL_TCP_SET_INFORMATION_EX \
     _TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
 
+#define IOCTL_SET_IP_ADDRESS \
+    _TCP_CTL_CODE(14, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define IOCTL_DELETE_IP_ADDRESS \
+    _TCP_CTL_CODE(16, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
 #endif/*_TCPIOCTL_H*/
index a438eba..4382f46 100644 (file)
@@ -18,7 +18,7 @@ typedef struct _BITMAPOBJ
 
   /* For device-independent bitmaps: */
   DIBSECTION *dib;
-  RGBQUAD *ColorMap;
+  HPALETTE hDIBPalette;
 } BITMAPOBJ, *PBITMAPOBJ;
 
 #define BITMAPOBJ_IS_APIBITMAP         0x1
index 3f39a5f..9d44112 100644 (file)
@@ -86,14 +86,11 @@ NtGdiCreateBrushIndirect(
    CONST LOGBRUSH *LogBrush);
 
 HBRUSH STDCALL
-NtGdiCreateDIBPatternBrush(
-   HGLOBAL hDIBPacked,
-   UINT ColorSpec);
-
-HBRUSH STDCALL
-NtGdiCreateDIBPatternBrushPt(
-   CONST VOID *PackedDIB,
-   UINT Usage);
+NtGdiCreateDIBBrush(
+   CONST BITMAPINFO *BitmapInfoAndData,
+   UINT ColorSpec,
+   UINT BitmapInfoSize,
+   CONST VOID *PackedDIB);
 
 HBRUSH STDCALL
 NtGdiCreateHatchBrush(
index d85424d..4f276dc 100644 (file)
@@ -79,7 +79,6 @@ typedef struct _DC
   HDC  hSelf;
   HDC  hNext;
   DHPDEV  PDev;
-  DEVMODEW  DMW;
   HSURF  FillPatternSurfaces[HS_DDI_MAX];
   PGDIINFO  GDIInfo;
   PDEVINFO  DevInfo;
@@ -104,6 +103,7 @@ typedef struct _DC
   XLATEOBJ *XlatePen;
 
   INT  saveLevel;
+  BOOL IsIC;
 
   WIN_DC_INFO  w;
 } DC, *PDC;
@@ -136,6 +136,8 @@ typedef struct
   DEVINFO DevInfo;
   DRIVER_FUNCTIONS DriverFunctions;
   PFILE_OBJECT VideoFileObject;
+  BOOLEAN PreparedDriver;
+  ULONG DisplayNumber;
 
   GDIPOINTER Pointer;
 
index 1592fd5..68b4e1d 100644 (file)
@@ -103,6 +103,11 @@ NtUserBuildPropList(
   DWORD BufferSize,
   DWORD *Count);
 
+enum {
+       HWND_ROUTINE_REGISTERSHELLHOOKWINDOW,
+       HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW
+};
+
 DWORD
 STDCALL
 NtUserCallHwnd(
index 2f15da1..1c6beff 100644 (file)
@@ -7,6 +7,7 @@ typedef struct
 {
    LOGFONTW   logfont;
    FONTOBJ    *Font;
+   BOOLEAN Initialized; /* Don't reinitialize for each DC */
 } TEXTOBJ, *PTEXTOBJ;
 
 /*  Internal interface  */
index 4fab007..7809f4e 100644 (file)
 /* Base definitions */
 #include <base.h>
 
-/* WIN32 messages */
-#ifndef WIN32_LEAN_AND_MEAN
-#include <messages.h>
-#endif
-
 /* WIN32 definitions */
 #include <defines.h>
 
 #endif /* ! defined (RC_INVOKED) */
 
 /* WIN32 error codes */
-#ifndef WIN32_LEAN_AND_MEAN
-#include <errors.h>
-#endif
+//#ifndef WIN32_LEAN_AND_MEAN
+//#include <errors.h>
+//#endif
 
 #ifndef RC_INVOKED
 
-/* Windows sockets specification version 1.1 */
-#ifdef Win32_Winsock
-#ifndef WIN32_LEAN_AND_MEAN
-#include <sockets.h>
-#endif
-#endif
-
 /* There is a conflict with BOOL between Objective-C and Win32,
    so the Windows32 API Library defines and uses WINBOOL.
    However, if we are not using Objective-C then define the normal
index 2c3792e..e29063a 100644 (file)
 #ifndef _CFGMGR32_H_
 #define _CFGMGR32_H_
 
+/* cfgmgr32 doesn't use the normal convention, it adds an underscore before A/W */
+#ifdef __WINESRC__
+# define DECL_WINELIB_CFGMGR32_TYPE_AW(type)  /* nothing */
+#else   /* __WINESRC__ */
+# define DECL_WINELIB_CFGMGR32_TYPE_AW(type)  typedef WINELIB_NAME_AW(type##_) type;
+#endif  /* __WINESRC__ */
+
 typedef DWORD CONFIGRET;
 typedef HANDLE HMACHINE;
 typedef HMACHINE *PHMACHINE;
+typedef DWORD DEVINST;
+typedef DEVINST *PDEVINST;
+
+typedef CHAR  *DEVINSTID_A;
+typedef WCHAR *DEVINSTID_W;
+DECL_WINELIB_CFGMGR32_TYPE_AW(DEVINSTID)
 
-#define CR_SUCCESS       0x00000000
-#define CR_INVALID_DATA  0x0000001F
-#define CR_ACCESS_DENIED 0x00000033
+
+#define CR_SUCCESS             0x00000000
+#define CR_OUT_OF_MEMORY       0x00000002
+#define CR_INVALID_DATA        0x0000001F
+#define CR_INVALID_MACHINENAME 0x0000002F
+#define CR_ACCESS_DENIED       0x00000033
 
 
 CONFIGRET WINAPI CM_Connect_MachineA( PCSTR, PHMACHINE );
@@ -34,6 +50,8 @@ CONFIGRET WINAPI CM_Connect_MachineW( PCWSTR, PHMACHINE );
 
 CONFIGRET WINAPI CM_Disconnect_Machine( HMACHINE );
 
+CONFIGRET WINAPI CM_Get_Child( PDEVINST, DEVINST, ULONG );
+CONFIGRET WINAPI CM_Get_Child_Ex( PDEVINST, DEVINST, ULONG, HMACHINE );
 CONFIGRET WINAPI CM_Get_Device_ID_ListA( PCSTR, PCHAR, ULONG, ULONG );
 CONFIGRET WINAPI CM_Get_Device_ID_ListW( PCWSTR, PWCHAR, ULONG, ULONG );
 #define     CM_Get_Device_ID_List WINELIB_NAME_AW(CM_Get_Device_ID_List)
@@ -46,5 +64,18 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW( PULONG, PCWSTR, ULONG );
 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA( PULONG, PCSTR, ULONG, HMACHINE );
 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW( PULONG, PCWSTR, ULONG, HMACHINE );
 #define     CM_Get_Device_ID_List_Size_Ex WINELIB_NAME_AW(CM_Get_Device_ID_List_Size_Ex)
+CONFIGRET WINAPI CM_Get_Parent( PDEVINST, DEVINST, ULONG );
+CONFIGRET WINAPI CM_Get_Parent_Ex( PDEVINST, DEVINST, ULONG, HMACHINE );
+CONFIGRET WINAPI CM_Get_Sibling( PDEVINST, DEVINST, ULONG );
+CONFIGRET WINAPI CM_Get_Sibling_Ex( PDEVINST, DEVINST, ULONG, HMACHINE );
+WORD WINAPI CM_Get_Version( VOID );
+WORD WINAPI CM_Get_Version_Ex( HMACHINE );
+
+CONFIGRET WINAPI CM_Locate_DevNodeA(PDEVINST, DEVINSTID_A, ULONG);
+CONFIGRET WINAPI CM_Locate_DevNodeW(PDEVINST, DEVINSTID_W, ULONG);
+#define     CM_Locate_DevNode WINELIB_NAME_AW(CM_Locate_DevNode)
+CONFIGRET WINAPI CM_Locate_DevNode_ExA(PDEVINST, DEVINSTID_A, ULONG, HMACHINE);
+CONFIGRET WINAPI CM_Locate_DevNode_ExW(PDEVINST, DEVINSTID_W, ULONG, HMACHINE);
+#define     CM_Locate_DevNode_Ex WINELIB_NAME_AW(CM_Locate_DevNode_Ex)
 
 #endif /* _CFGMGR32_H_ */
index fccd779..b7f8ff6 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id $
- *
+/*
  * Compatibility header
  *
  * This header is wrapper to allow compilation of Wine DLLs under ReactOS
@@ -59,6 +58,18 @@ typedef LPFINDINFOW LPLVFINDINFOW;
 #define HDM_SETBITMAPMARGIN     (HDM_FIRST+20)
 #define HDM_GETBITMAPMARGIN     (HDM_FIRST+21)
 
-#define FLATSB_CLASSA         "flatsb_class32"
+#define SB_SETBORDERS          (WM_USER+5)
+
+#define FLATSB_CLASSA           "flatsb_class32"
+#define DRAGLISTMSGSTRINGA      "commctrl_DragListMsg"
+#if defined(__GNUC__)
+# define DRAGLISTMSGSTRINGW (const WCHAR []){ 'c','o','m','m','c','t','r','l', \
+  '_','D','r','a','g','L','i','s','t','M','s','g',0 }
+#elif defined(_MSC_VER)
+# define DRAGLISTMSGSTRINGW     L"commctrl_DragListMsg"
+#else
+static const WCHAR DRAGLISTMSGSTRINGW[] = { 'c','o','m','m','c','t','r','l', \
+  '_','D','r','a','g','L','i','s','t','M','s','g',0 };
+#endif
 
 #endif /* __WINE_COMMCTRL_H */
diff --git a/reactos/include/wine/cpl.h b/reactos/include/wine/cpl.h
deleted file mode 100644 (file)
index 845bc41..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __WINE_CPL_H
-#define __WINE_CPL_H
-
-#include_next <cpl.h>
-
-#define CPL_STARTWPARMSA 9
-
-#endif  /* __WINE_CPL_H */
index b2cf55c..45d4f20 100644 (file)
@@ -89,6 +89,20 @@ enum msidbFeatureAttributes
     msidbFeatureAttributesNoUnsupportedAdvertise = 0x00000020
 };
 
+enum msidbComponentAttributes
+{
+    msidbComponentAttributesLocalOnly = 0x00000000,
+    msidbComponentAttributesSourceOnly = 0x00000001,
+    msidbComponentAttributesOptional = 0x00000002,
+    msidbComponentAttributesRegistryKeyPath = 0x00000004,
+    msidbComponentAttributesSharedDllRefCount = 0x00000008,
+    msidbComponentAttributesPermanent = 0x00000010,
+    msidbComponentAttributesODBCDataSource = 0x00000020,
+    msidbComponentAttributesTransitive = 0x00000040,
+    msidbComponentAttributesNeverOverwrite = 0x00000080,
+    msidbComponentAttributes64bit = 0x00000100
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/reactos/include/wine/richole.h b/reactos/include/wine/richole.h
new file mode 100644 (file)
index 0000000..4a4f3df
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Compatibility header
+ *
+ * This header is wrapper to allow compilation of Wine DLLs under ReactOS
+ * build system. It contains definitions commonly refered to as Wineisms
+ * and definitions that are missing in w32api.
+ */
+
+#include <richedit.h>
+
+#include_next <richole.h>
+
+#ifndef WINE_RICHOLE_H_INCLUDED
+#define WINE_RICHOLE_H_INCLUDED
+
+#ifdef COBJMACROS
+/*** IUnknown methods ***/
+#define IRichEditOle_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IRichEditOle_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IRichEditOle_Release(p) (p)->lpVtbl->Release(p)
+/*** IRichEditOle methods ***/
+#define IRichEditOle_GetClientSite(p,a) (p)->lpVtbl->GetClientSite(p,a)
+#define IRichEditOle_GetObjectCount(p) (p)->lpVtbl->GetObjectCount(p)
+#define IRichEditOle_GetLinkCount(p) (p)->lpVtbl->GetLinkCount(p)
+#define IRichEditOle_GetObject(p,a,b,c) (p)->lpVtbl->GetObject(p,a,b,c)
+#define IRichEditOle_InsertObject(p,a) (p)->lpVtbl->InsertObject(p,a)
+#define IRichEditOle_ConvertObject(p,a,b,c) (p)->lpVtbl->ConvertObject(p,a,b,c)
+#define IRichEditOle_ActivateAs(p,a,b) (p)->lpVtbl->ActivateAs(p,a,b)
+#define IRichEditOle_SetHostNames(p,a,b) (p)->lpVtbl->SetHostNames(p,a,b)
+#define IRichEditOle_SetLinkAvailable(p,a,b) (p)->lpVtbl->SetLinkAvailable(p,a,b)
+#define IRichEditOle_SetDvaspect(p,a,b) (p)->lpVtbl->SetDvaspect(p,a,b)
+#define IRichEditOle_HandsOffStorage(p,a) (p)->lpVtbl->HandsOffStorage(p,a)
+#define IRichEditOle_SaveCompleted(p,a,b) (p)->lpVtbl->SaveCompleted(p,a,b)
+#define IRichEditOle_InPlaceDeactivate(p) (p)->lpVtbl->InPlaceDeactivate(p)
+#define IRichEditOle_ContextSensitiveHelp(p,a) (p)->lpVtbl->ContextSensitiveHelp(p,a)
+#define IRichEditOle_GetClipboardData(p,a,b,c) (p)->lpVtbl->GetClipboardData(p,a,b,c)
+#define IRichEditOle_ImportDataObject(p,a,b,c) (p)->lpVtbl->ImportDataObject(p,a,b,c)
+#endif
+
+#endif /* WINE_RICHOLE_H_INCLUDED */
index cee5f4c..e5596da 100644 (file)
@@ -666,6 +666,8 @@ DECL_WINELIB_SETUPAPI_TYPE_AW(PFILEPATHS)
 
 
 LONG     WINAPI AddTagToGroupOrderList(PCWSTR lpGroupName, DWORD dwUnknown2, DWORD dwUnknown3);
+DWORD    WINAPI CaptureAndConvertAnsiArg(PCSTR lpSrc, PWSTR *lpDst);
+DWORD    WINAPI CaptureStringArg(PCWSTR lpSrc, PWSTR *lpDst);
 BOOL     WINAPI DelayedMove(PCWSTR lpExistingFileName, PCWSTR lpNewFileName);
 BOOL     WINAPI DoesUserHavePrivilege(PCWSTR lpPrivilegeName);
 PWSTR    WINAPI DuplicateString(PCWSTR lpSrc);
index 57ba1a4..f230b81 100644 (file)
@@ -10,4 +10,5 @@
 IDB_USRGRPIMAGES BITMAP "res/usrgrp.bmp"
 
 #include "aclui_En.rc"
-
+#include "aclui_De.rc"
+#include "aclui_Sv.rc"
diff --git a/reactos/lib/aclui/aclui_De.rc b/reactos/lib/aclui/aclui_De.rc
new file mode 100644 (file)
index 0000000..67e8dec
--- /dev/null
@@ -0,0 +1,23 @@
+#include <reactos/resource.h>
+#include <defines.h>
+#include "resource.h"
+
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
+
+IDD_SECPAGE DIALOGEX 0, 0, 227, 215
+STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "Sicherheit"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "&Gruppen oder Benutzernamen:", -1, 7, 7, 105, 8
+  CONTROL "", IDC_ACELIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 7, 17, 213, 66, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE
+  PUSHBUTTON "&Hinzufügen...", IDC_ACELIST_ADD, 116, 87, 50, 14
+  PUSHBUTTON "&Entfernen", IDC_ACELIST_REMOVE, 170, 87, 50, 14
+  LTEXT "Erlauben", -1, 135, 107, 32, 8, SS_CENTER
+  LTEXT "Verbieten", -1, 176, 107, 32, 8, SS_CENTER
+END
+
+STRINGTABLE DISCARDABLE
+{
+  IDS_PSP_TITLE "Berechtigungen für %1"
+}
diff --git a/reactos/lib/aclui/aclui_Sv.rc b/reactos/lib/aclui/aclui_Sv.rc
new file mode 100644 (file)
index 0000000..aae36d8
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright 2005 Andreas Bjerkeholt\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <reactos/resource.h>\r
+#include <defines.h>\r
+#include "resource.h"\r
+\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+IDD_SECPAGE DIALOGEX 0, 0, 227, 215\r
+STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Säkerhet"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "&Grupp eller användarnamn:", -1, 7, 7, 105, 8\r
+  CONTROL "", IDC_ACELIST, "SysListView32", LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 7, 17, 213, 66, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE\r
+  PUSHBUTTON "&Lägg till...", IDC_ACELIST_ADD, 116, 87, 50, 14\r
+  PUSHBUTTON "&Ta bort", IDC_ACELIST_REMOVE, 170, 87, 50, 14\r
+  LTEXT "Tillåt", -1, 135, 107, 32, 8, SS_CENTER\r
+  LTEXT "Neka", -1, 176, 107, 32, 8, SS_CENTER\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+  IDS_PSP_TITLE "Behörigheter för %1"\r
+}\r
+\r
index 784440f..4e34e94 100644 (file)
@@ -1,6 +1,7 @@
 <module name="adns" type="staticlibrary">\r
        <include base="adns">src</include>\r
        <include base="adns">adns_win32</include>\r
+       <define name="__USE_W32API" />\r
        <define name="ADNS_JGAA_WIN32" />\r
        <directory name="adns_win32">\r
                <file>adns_unix_calls.c</file>\r
index dfbbbb4..6f70591 100644 (file)
@@ -14,13 +14,25 @@ AbortSystemShutdownW@4
 AccessCheck@32
 AccessCheckAndAuditAlarmA@44
 AccessCheckAndAuditAlarmW@44
+;AccessCheckByType
+;AccessCheckByTypeAndAuditAlarmA@64
+;AccessCheckByTypeAndAuditAlarmW@64
+;AccessCheckByTypeResultList@44
+;AccessCheckByTypeResultListAndAuditAlarmA@64
+;AccessCheckByTypeResultListAndAuditAlarmByHandleA@68
+;AccessCheckByTypeResultListAndAuditAlarmByHandleW@68
+;AccessCheckByTypeResultListAndAuditAlarmW@64
 AddAccessAllowedAce@16
 AddAccessAllowedAceEx@20
+;AddAccessAllowedObjectAce@28
 AddAccessDeniedAce@16
 AddAccessDeniedAceEx@20
+;AddAccessDeniedObjectAce@28
 AddAce@20
 AddAuditAccessAce@24
 AddAuditAccessAceEx@28
+;AddAuditAccessObjectAce@36
+;AddUsersToEncryptedFile@8
 AdjustTokenGroups@24
 AdjustTokenPrivileges@24
 AllocateAndInitializeSid@44
@@ -29,8 +41,6 @@ AreAllAccessesGranted@8
 AreAnyAccessesGranted@8
 BackupEventLogA@8
 BackupEventLogW@8
-;BuildAccessRequestA
-;BuildAccessRequestW
 BuildExplicitAccessWithNameA@20
 BuildExplicitAccessWithNameW@20
 BuildImpersonateExplicitAccessWithNameA@24
@@ -41,24 +51,94 @@ BuildImpersonateTrusteeW@8
 ;BuildSecurityDescriptorW@36
 BuildTrusteeWithNameA@8
 BuildTrusteeWithNameW@8
+;BuildTrusteeWithObjectsAndNameA@24
+;BuildTrusteeWithObjectsAndNameW@24
+;BuildTrusteeWithObjectsAndSidA@20
+;BuildTrusteeWithObjectsAndSidW@20
 BuildTrusteeWithSidA@8
 BuildTrusteeWithSidW@8
+;CancelOverlappedAccess@4
+;ChangeServiceConfig2A@12
+;ChangeServiceConfig2W@12
 ChangeServiceConfigA@44
 ChangeServiceConfigW@44
 CheckTokenMembership@12
 ClearEventLogA@8
 ClearEventLogW@8
+;CloseCodeAuthzLevel@4
+;CloseEncryptedFileRaw
 CloseEventLog@4
 CloseServiceHandle@4
+;CloseTrace@8
+;CommandLineFromMsiDescriptor@12
+;ComputeAccessTokenFromCodeAuthzLevel@20
 ControlService@12
+;ControlTraceA@12
+;ControlTraceW@12
+;ConvertAccessToSecurityDescriptorA@20
+;ConvertAccessToSecurityDescriptorW@20
+;ConvertSDToStringSDRootDomainA@24
+;ConvertSDToStringSDRootDomainW@24
+;ConvertSecurityDescriptorToAccessA@28
+;ConvertSecurityDescriptorToAccessNamedA=ConvertSecurityDescriptorToAccessA@28
+;ConvertSecurityDescriptorToAccessNamedW=ConvertSecurityDescriptorToAccessW@28
+;ConvertSecurityDescriptorToAccessW@28
+;ConvertSecurityDescriptorToStringSecurityDescriptorA@20
+;ConvertSecurityDescriptorToStringSecurityDescriptorW@20
 ConvertSidToStringSidA@8
 ConvertSidToStringSidW@8
+;ConvertStringSDToSDDomainA@24
+;ConvertStringSDToSDDomainW@24
+;ConvertStringSDToSDRootDomainA@20
+;ConvertStringSDToSDRootDomainW@20
+;ConvertStringSecurityDescriptorToSecurityDescriptorA@20
+;ConvertStringSecurityDescriptorToSecurityDescriptorW@20
+;ConvertStringSidToSidA@8
+;ConvertStringSidToSidW@8
+;ConvertToAutoInheritPrivateObjectSecurity@24
 CopySid@12
+;CreateCodeAuthzLevel@20
 ;CreatePrivateObjectSecurity@24
+;CreatePrivateObjectSecurityEx@32
+;CreatePrivateObjectSecurityWithMultipleInheritance@36
 CreateProcessAsUserA@44
+;CreateProcessAsUserSecure
 CreateProcessAsUserW@44
+;CreateProcessWithLogonW
+;CreateRestrictedToken@36
 CreateServiceA@52
 CreateServiceW@52
+;CreateTraceInstanceId@8
+;CreateWellKnownSid@16
+;CredDeleteA@12
+;CredDeleteW@12
+;CredEnumerateA@16
+;CredEnumerateW@16
+;CredFree@4
+;CredGetSessionTypes@8
+;CredGetTargetInfoA@12
+;CredGetTargetInfoW@12
+;CredIsMarshaledCredentialA@4
+;CredIsMarshaledCredentialW@4
+;CredMarshalCredentialA@12
+;CredMarshalCredentialW@12
+;CredProfileLoaded
+;CredReadA
+;CredReadDomainCredentialsA
+;CredReadDomainCredentialsW
+;CredReadW
+;CredRenameA
+;CredRenameW
+;CredUnmarshalCredentialA
+;CredUnmarshalCredentialW
+;CredWriteA
+;CredWriteDomainCredentialsA
+;CredWriteDomainCredentialsW
+;CredWriteW
+;CredpConvertCredential
+;CredpConvertTargetInfo
+;CredpDecodeCredential
+;CredpEncodeCredential
 CryptAcquireContextA@20
 CryptAcquireContextW@20
 CryptContextAddRef@12
@@ -67,10 +147,18 @@ CryptDecrypt@24
 CryptDeriveKey@20
 CryptDestroyHash@4
 CryptDestroyKey@4
+;CryptDuplicateHash@16
+;CryptDuplicateKey@16
 CryptEncrypt@28
+;CryptEnumProviderTypesA@24
+;CryptEnumProviderTypesW@24
+;CryptEnumProvidersA@24
+;CryptEnumProvidersW@24
 CryptExportKey@24
 CryptGenKey@16
 CryptGenRandom@12
+;CryptGetDefaultProviderA@20
+;CryptGetDefaultProviderW@20
 CryptGetHashParam@20
 CryptGetKeyParam@20
 CryptGetProvParam@20
@@ -83,17 +171,20 @@ CryptSetHashParam@16
 CryptSetKeyParam@16
 CryptSetProvParam@16
 CryptSetProviderA@8
+;CryptSetProviderExA@16
+;CryptSetProviderExW@16
 CryptSetProviderW@8
 CryptSignHashA@24
 ;CryptSignHashW@24
 CryptVerifySignatureA@24
-;CryptVerifySignatureW@24
+CryptVerifySignatureW@24
+;DecryptFileA@8
+;DecryptFileW@8
 DeleteAce@8
 DeleteService@4
-;DenyAccessRightsA
-;DenyAccessRightsW
 DeregisterEventSource@4
 ;DestroyPrivateObjectSecurity@4
+;DuplicateEncryptionInfoFile
 DuplicateToken@12
 DuplicateTokenEx@24
 ;ElfBackupEventLogFileA@8
@@ -115,48 +206,67 @@ DuplicateTokenEx@24
 ;ElfRegisterEventSourceW@12
 ;ElfReportEventA@48
 ;ElfReportEventW@48
+;EnableTrace
+;EncryptFileA
+;EncryptFileW
+;EncryptedFileKeyInfo
+;EncryptionDisable
 EnumDependentServicesA@24
 EnumDependentServicesW@24
 EnumServiceGroupW@36
 EnumServicesStatusA@32
+;EnumServicesStatusExA
+;EnumServicesStatusExW
 EnumServicesStatusW@32
+;EnumerateTraceGuids
+;EqualDomainSid
 EqualPrefixSid@8
 EqualSid@8
+;FileEncryptionStatusA
+;FileEncryptionStatusW
 FindFirstFreeAce@8
+;FlushTraceA
+;FlushTraceW
+;FreeEncryptedFileKeyInfo
+;FreeEncryptionCertificateHashList
 FreeInheritedFromArray@12
 FreeSid@4
+;GetAccessPermissionsForObjectA
+;GetAccessPermissionsForObjectW
 GetAce@12
 GetAclInformation@16
 ;GetAuditedPermissionsFromAclA@16
 ;GetAuditedPermissionsFromAclW@16
-;GetAuditedPermissionsFromSDA
-;GetAuditedPermissionsFromSDW
 GetCurrentHwProfileA@4
 GetCurrentHwProfileW@4
-;GetEffectiveAccessRightsA
-;GetEffectiveAccessRightsW
 ;GetEffectiveRightsFromAclA@12
 ;GetEffectiveRightsFromAclW@12
-;GetEffectiveRightsFromSDA@12
-;GetEffectiveRightsFromSDW@12
-;GetExplicitAccessRightsA
-;GetExplicitAccessRightsW
+;GetEventLogInformation
 ;GetExplicitEntriesFromAclA@12
 ;GetExplicitEntriesFromAclW@12
 GetFileSecurityA@20
 GetFileSecurityW@20
+;GetInformationCodeAuthzLevelW
+;GetInformationCodeAuthzPolicyW
 GetInheritanceSourceA@40
 GetInheritanceSourceW@40
 GetKernelObjectSecurity@20
 GetLengthSid@4
+;GetLocalManagedApplicationData
+;GetLocalManagedApplications
+;GetManagedApplicationCategories
+;GetManagedApplications
 GetMultipleTrusteeA@4
 GetMultipleTrusteeOperationA@4
 GetMultipleTrusteeOperationW@4
 GetMultipleTrusteeW@4
 GetNamedSecurityInfoA@32
+;GetNamedSecurityInfoExA
+;GetNamedSecurityInfoExW
 GetNamedSecurityInfoW@32
 GetNumberOfEventLogRecords@8
 GetOldestEventLogRecord@8
+;GetOverlappedAccessResults
 ;GetPrivateObjectSecurity@20
 GetSecurityDescriptorControl@12
 GetSecurityDescriptorDacl@16
@@ -177,6 +287,9 @@ GetSidLengthRequired@4
 GetSidSubAuthority@8
 GetSidSubAuthorityCount@4
 GetTokenInformation@20
+;GetTraceEnableFlags
+;GetTraceEnableLevel
+;GetTraceLoggerHandle
 GetTrusteeFormA@4
 GetTrusteeFormW@4
 GetTrusteeNameA@4
@@ -185,11 +298,15 @@ GetTrusteeTypeA@4
 GetTrusteeTypeW@4
 GetUserNameA@8
 GetUserNameW@8
-;GrantAccessRightsA@16
-;GrantAccessRightsW@16
+;GetWindowsAccountDomainSid
 ;I_ScGetCurrentGroupStateW@12
+;I_ScIsSecurityProcess
+;I_ScPnPGetServiceName
+;I_ScSendTSMessage
 ;I_ScSetServiceBitsA@20
 ;I_ScSetServiceBitsW@20
+;IdentifyCodeAuthzLevelW
+;ImpersonateAnonymousToken
 ImpersonateLoggedOnUser@4
 ImpersonateNamedPipeClient@4
 ImpersonateSelf@4
@@ -197,15 +314,21 @@ InitializeAcl@12
 InitializeSecurityDescriptor@8
 InitializeSid@12
 InitiateSystemShutdownA@20
+;InitiateSystemShutdownExA@24
+;InitiateSystemShutdownExW@24
 InitiateSystemShutdownW@20
-;IsAccessPermittedA@20
-;IsAccessPermittedW@20
+;InstallApplication
 IsTextUnicode@12=NTDLL.RtlIsTextUnicode
+;IsTokenRestricted
+;IsTokenUntrusted
 IsValidAcl@4
 IsValidSecurityDescriptor@4
 IsValidSid@4
+;IsWellKnownSid
 LockServiceDatabase@4
 LogonUserA@24
+;LogonUserExA
+;LogonUserExW
 LogonUserW@24
 LookupAccountNameA@28
 LookupAccountNameW@28
@@ -226,6 +349,7 @@ LsaClose@4
 ;LsaCreateAccount@16
 ;LsaCreateSecret@16
 ;LsaCreateTrustedDomain@16
+;LsaCreateTrustedDomainEx
 ;LsaDelete@4
 ;LsaDeleteTrustedDomain@8
 ;LsaEnumerateAccountRights@16
@@ -234,13 +358,18 @@ LsaClose@4
 ;LsaEnumeratePrivileges@20
 ;LsaEnumeratePrivilegesOfAccount@8
 ;LsaEnumerateTrustedDomains@20
+;LsaEnumerateTrustedDomainsEx
 LsaFreeMemory@4
 ;LsaGetQuotasForAccount@8
+;LsaGetRemoteUserName
 ;LsaGetSystemAccessAccount@8
 LsaGetUserName@8
 ;LsaICLookupNames@32
+;LsaICLookupNamesWithCreds
 ;LsaICLookupSids@32
+;LsaICLookupSidsWithCreds
 ;LsaLookupNames@20
+;LsaLookupNames2
 ;LsaLookupPrivilegeDisplayName@16
 ;LsaLookupPrivilegeName@12
 ;LsaLookupPrivilegeValue@12
@@ -248,34 +377,44 @@ LsaGetUserName@8
 LsaNtStatusToWinError@4
 ;LsaOpenAccount@16
 LsaOpenPolicy@16
+;LsaOpenPolicySce
 ;LsaOpenSecret@16
 ;LsaOpenTrustedDomain@16
-;LsaQueryInfoTrustedDomain
+;LsaOpenTrustedDomainByName
+;LsaQueryDomainInformationPolicy
+;LsaQueryForestTrustInformation
+LsaQueryInfoTrustedDomain@12
 LsaQueryInformationPolicy@12
 ;LsaQuerySecret@20
 ;LsaQuerySecurityObject@12
 ;LsaQueryTrustedDomainInfo@16
+;LsaQueryTrustedDomainInfoByName
 ;LsaRemoveAccountRights@20
 ;LsaRemovePrivilegesFromAccount@12
 LsaRetrievePrivateData@12
 ;LsaSetInformationPolicy@12
+;LsaSetForestTrustInformation
+;LsaSetInformationPolicy
 ;LsaSetInformationTrustedDomain@12
 ;LsaSetQuotasForAccount@8
 ;LsaSetSecret@12
 ;LsaSetSecurityObject@12
 ;LsaSetSystemAccessAccount@8
+;LsaSetTrustedDomainInfoByName
 ;LsaSetTrustedDomainInformation@16
 LsaStorePrivateData@12
-MakeAbsoluteSD@44
-MakeSelfRelativeSD@12
-MapGenericMask@8
 MD4Final@4
 MD4Init@4
 MD4Update@12
 MD5Final@4
 MD5Init@4
 MD5Update@12
-;NTAccessMaskToProvAccessRights@12
+;MSChapSrvChangePassword
+;MSChapSrvChangePassword2
+MakeAbsoluteSD@44
+;MakeAbsoluteSD2
+MakeSelfRelativeSD@12
+MapGenericMask@8
 ;NotifyBootConfigStatus@4
 NotifyChangeEventLog@8
 ObjectCloseAuditAlarmA@12
@@ -288,6 +427,8 @@ ObjectPrivilegeAuditAlarmA@24
 ObjectPrivilegeAuditAlarmW@24
 OpenBackupEventLogA@8
 OpenBackupEventLogW@8
+;OpenEncryptedFileRawA
+;OpenEncryptedFileRawW
 OpenEventLogA@8
 OpenEventLogW@8
 OpenProcessToken@12
@@ -296,10 +437,19 @@ OpenSCManagerW@12
 OpenServiceA@12
 OpenServiceW@12
 OpenThreadToken@16
+;OpenTraceA
+;OpenTraceW
 PrivilegeCheck@12
 PrivilegedServiceAuditAlarmA@20
 PrivilegedServiceAuditAlarmW@20
-;ProvAccessRightsToNTAccessMask
+;ProcessIdleTasks
+;ProcessTrace
+;ProvAccessRightsToNTAccessMask ; ?
+;QueryAllTracesA
+;QueryAllTracesW
+;QueryRecoveryAgentsOnEncryptedFile
+;QueryServiceConfig2A
+;QueryServiceConfig2W
 QueryServiceConfigA@16
 QueryServiceConfigW@16
 QueryServiceLockStatusA@16
@@ -307,7 +457,11 @@ QueryServiceLockStatusW@16
 QueryServiceObjectSecurity@20
 QueryServiceStatus@8
 QueryServiceStatusEx@20
+;QueryTraceA
+;QueryTraceW
+;QueryUsersOnEncryptedFile
 ;QueryWindows31FilesMigration@4
+;ReadEncryptedFileRaw
 ReadEventLogA@28
 ReadEventLogW@28
 RegCloseKey@4
@@ -321,6 +475,7 @@ RegDeleteKeyA@8
 RegDeleteKeyW@8
 RegDeleteValueA@8
 RegDeleteValueW@8
+;RegDisablePredefinedCache
 RegEnumKeyA@16
 RegEnumKeyExA@32
 RegEnumKeyExW@32
@@ -332,10 +487,13 @@ RegGetKeySecurity@16
 RegLoadKeyA@12
 RegLoadKeyW@12
 RegNotifyChangeKeyValue@20
+;RegOpenCurrentUser
 RegOpenKeyA@12
 RegOpenKeyExA@20
 RegOpenKeyExW@20
 RegOpenKeyW@12
+;RegOpenUserClassesRoot
+;RegOverridePredefKey
 RegQueryInfoKeyA@48
 RegQueryInfoKeyW@48
 RegQueryMultipleValuesA@20
@@ -349,6 +507,8 @@ RegReplaceKeyW@16
 RegRestoreKeyA@12
 RegRestoreKeyW@12
 RegSaveKeyA@12
+;RegSaveKeyExA
+;RegSaveKeyExW
 RegSaveKeyW@12
 RegSetKeySecurity@12
 RegSetValueA@20
@@ -359,28 +519,52 @@ RegUnLoadKeyA@8
 RegUnLoadKeyW@8
 RegisterEventSourceA@8
 RegisterEventSourceW@8
+;RegisterIdleTask
 RegisterServiceCtrlHandlerA@8
-RegisterServiceCtrlHandlerW@8
 RegisterServiceCtrlHandlerExA@12
 RegisterServiceCtrlHandlerExW@12
-;ReplaceAllAccessRightsA
-;ReplaceAllAccessRightsW
+RegisterServiceCtrlHandlerW@8
+;RegisterTraceGuidsA
+;RegisterTraceGuidsW
+;RemoveTraceCallback
+;RemoveUsersFromEncryptedFile
 ReportEventA@36
 ReportEventW@36
 RevertToSelf@0
-;RevokeExplicitAccessRightsA@16
-;RevokeExplicitAccessRightsW@16
-;SetAccessRightsA@16
-;SetAccessRightsW@16
+;SaferCloseLevel
+;SaferComputeTokenFromLevel
+;SaferCreateLevel
+;SaferGetLevelInformation
+;SaferGetPolicyInformation
+;SaferIdentifyLevel
+;SaferRecordEventLogEntry
+;SaferSetLevelInformation
+;SaferSetPolicyInformation
+;SaferiChangeRegistryScope
+;SaferiCompareTokenLevels
+;SaferiIsExecutableFileType
+;SaferiPopulateDefaultsInRegistry
+;SaferiRecordEventLogEntry
+;SaferiReplaceProcessThreadTokens
+;SaferiSearchMatchingHashRules
 SetAclInformation@16
+;SetEntriesInAccessListA
+;SetEntriesInAccessListW
 ;SetEntriesInAclA@16
 ;SetEntriesInAclW@16
+;SetEntriesInAuditListA
+;SetEntriesInAuditListW
 SetFileSecurityA@12
 SetFileSecurityW@12
+;SetInformationCodeAuthzLevelW
+;SetInformationCodeAuthzPolicyW
 SetKernelObjectSecurity@12
 SetNamedSecurityInfoA@28
+;SetNamedSecurityInfoExA
+;SetNamedSecurityInfoExW
 SetNamedSecurityInfoW@28
 ;SetPrivateObjectSecurity@20
+;SetPrivateObjectSecurityEx
 SetSecurityDescriptorControl@12
 SetSecurityDescriptorDacl@16
 SetSecurityDescriptorGroup@12
@@ -388,15 +572,23 @@ SetSecurityDescriptorOwner@12
 SetSecurityDescriptorRMControl@8
 SetSecurityDescriptorSacl@16
 SetSecurityInfo@28
+;SetSecurityInfoExA
+;SetSecurityInfoExW
 SetServiceBits@16
 SetServiceObjectSecurity@12
 SetServiceStatus@8
 SetThreadToken@8
 SetTokenInformation@16
+;SetTraceCallback
+;SetUserFileEncryptionKey
 StartServiceA@12
 StartServiceCtrlDispatcherA@4
 StartServiceCtrlDispatcherW@4
 StartServiceW@12
+;StartTraceA
+;StartTraceW
+;StopTraceA
+;StopTraceW
 ;SynchronizeWindows31FilesAndWindowsNTRegistry@16
 SystemFunction001@12
 SystemFunction002@12
@@ -433,5 +625,60 @@ SystemFunction032@8
 SystemFunction033@8
 SystemFunction034@8
 SystemFunction035@8
+SystemFunction036@8
+SystemFunction040@12
+SystemFunction041@12
+;TraceEvent
+;TraceEventInstance
+;TraceMessage
+;TraceMessageVa
+;TreeResetNamedSecurityInfoA
+;TreeResetNamedSecurityInfoW
+;TrusteeAccessToObjectA
+;TrusteeAccessToObjectW
+;UninstallApplication
 UnlockServiceDatabase@4
+;UnregisterIdleTask
+;UnregisterTraceGuids
+;UpdateTraceA
+;UpdateTraceW
+;WdmWmiServiceMain
+;WmiCloseBlock
+;WmiCloseTraceWithCursor
+;WmiConvertTimestamp
+;WmiDevInstToInstanceNameA
+;WmiDevInstToInstanceNameW
+;WmiEnumerateGuids
+;WmiExecuteMethodA
+;WmiExecuteMethodW
+;WmiFileHandleToInstanceNameA
+;WmiFileHandleToInstanceNameW
+;WmiFreeBuffer
+;WmiGetFirstTraceOffset
+;WmiGetNextEvent
+;WmiGetTraceHeader
+;WmiMofEnumerateResourcesA
+;WmiMofEnumerateResourcesW
+;WmiNotificationRegistrationA
+;WmiNotificationRegistrationW
+;WmiOpenBlock
+;WmiOpenTraceWithCursor
+;WmiParseTraceEvent
+;WmiQueryAllDataA
+;WmiQueryAllDataMultipleA
+;WmiQueryAllDataMultipleW
+;WmiQueryAllDataW
+;WmiQueryGuidInformation
+;WmiQuerySingleInstanceA
+;WmiQuerySingleInstanceMultipleA
+;WmiQuerySingleInstanceMultipleW
+;WmiQuerySingleInstanceW
+;WmiReceiveNotificationsA
+;WmiReceiveNotificationsW
+;WmiSetSingleInstanceA
+;WmiSetSingleInstanceW
+;WmiSetSingleItemA
+;WmiSetSingleItemW
+;Wow64Win32ApiEntry
+;WriteEncryptedFileRaw
 ; EOF
index ca505fc..f369bee 100644 (file)
@@ -1887,6 +1887,17 @@ BOOL WINAPI CryptVerifySignatureA (HCRYPTHASH hHash, BYTE *pbSignature, DWORD dw
                key->hPrivate, NULL, dwFlags);
 }
 
+BOOL WINAPI
+CryptVerifySignatureW (HCRYPTHASH hHash,
+                       BYTE *pbSignature,
+                       DWORD dwSigLen,
+                       HCRYPTKEY hPubKey,
+                       LPCWSTR sDescription,
+                       DWORD dwFlags)
+{
+       OutputDebugStringA ("ADVAPI32!CryptVerifySignatureW not implemented!");
+       return FALSE;
+}
 
 /*
    These functions have nearly identical prototypes to CryptProtectMemory and CryptUnprotectMemory,
index f4c7361..b2e6742 100644 (file)
@@ -452,4 +452,16 @@ SystemFunction035(INT a, INT b)
        return 35;
 }
 
+/**********************************************************************
+ *
+ * @unimplemented
+ */
+INT
+STDCALL
+SystemFunction036(INT a, INT b)
+{
+       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+       return 36;
+}
+
 /* EOF */
index 9c6a668..8f22f56 100644 (file)
@@ -222,7 +222,7 @@ OpenUsersKey (PHANDLE KeyHandle)
                              NULL,
                              NULL);
   return NtOpenKey (KeyHandle,
-                   KEY_ALL_ACCESS,
+                   MAXIMUM_ALLOWED,
                    &Attributes);
 }
 
index bc915a6..5d424e2 100644 (file)
@@ -507,4 +507,19 @@ LsaGetUserName(
   return STATUS_NOT_IMPLEMENTED;
 }
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+LsaQueryInfoTrustedDomain (DWORD Unknonw0,
+                          DWORD Unknonw1,
+                          DWORD Unknonw2)
+{
+  DPRINT1("LsaQueryInfoTrustedDomain not implemented\n");
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+
 /* EOF */
diff --git a/reactos/lib/advapi32/winetests/crypt.c b/reactos/lib/advapi32/winetests/crypt.c
new file mode 100644 (file)
index 0000000..3e0f4a7
--- /dev/null
@@ -0,0 +1,575 @@
+/*\r
+ * Unit tests for crypt functions\r
+ *\r
+ * Copyright (c) 2004 Michael Jung\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wincrypt.h"\r
+#include "winerror.h"\r
+#include "winreg.h"\r
+\r
+#include "wine/test.h"\r
+\r
+static const char szRsaBaseProv[] = MS_DEF_PROV_A;\r
+static const char szNonExistentProv[] = "Wine Nonexistent Cryptographic Provider v11.2";\r
+static const char szKeySet[] = "wine_test_keyset";\r
+static const char szBadKeySet[] = "wine_test_bad_keyset";\r
+#define NON_DEF_PROV_TYPE 999\r
+\r
+static HMODULE hadvapi32;\r
+static BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*,LPCSTR,LPCSTR,DWORD,DWORD);\r
+static BOOL (WINAPI *pCryptEnumProviderTypesA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);\r
+static BOOL (WINAPI *pCryptEnumProvidersA)(DWORD, DWORD*, DWORD, DWORD*, LPSTR, DWORD*);\r
+static BOOL (WINAPI *pCryptGetDefaultProviderA)(DWORD, DWORD*, DWORD, LPSTR, DWORD*);\r
+static BOOL (WINAPI *pCryptReleaseContext)(HCRYPTPROV, DWORD);\r
+static BOOL (WINAPI *pCryptSetProviderExA)(LPCSTR, DWORD, DWORD*, DWORD);\r
+\r
+static void init_function_pointers(void)\r
+{\r
+    hadvapi32 = GetModuleHandleA("advapi32.dll");\r
+\r
+    if(hadvapi32)\r
+    {\r
+       pCryptAcquireContextA = (void*)GetProcAddress(hadvapi32, "CryptAcquireContextA");\r
+       pCryptEnumProviderTypesA = (void*)GetProcAddress(hadvapi32, "CryptEnumProviderTypesA");\r
+       pCryptEnumProvidersA = (void*)GetProcAddress(hadvapi32, "CryptEnumProvidersA");\r
+       pCryptGetDefaultProviderA = (void*)GetProcAddress(hadvapi32, "CryptGetDefaultProviderA");\r
+       pCryptReleaseContext = (void*)GetProcAddress(hadvapi32, "CryptReleaseContext");\r
+       pCryptSetProviderExA = (void*)GetProcAddress(hadvapi32, "CryptSetProviderExA");\r
+    }\r
+}\r
+\r
+\r
+static void init_environment(void)\r
+{\r
+       HCRYPTPROV hProv;\r
+       \r
+       /* Ensure that container "wine_test_keyset" does exist */\r
+       if (!pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))\r
+       {\r
+               pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_NEWKEYSET);\r
+       }\r
+       pCryptReleaseContext(hProv, 0);\r
+\r
+       /* Ensure that container "wine_test_keyset" does exist in default PROV_RSA_FULL type provider */\r
+       if (!pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))\r
+       {\r
+               pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET);\r
+       }\r
+       pCryptReleaseContext(hProv, 0);\r
+\r
+       /* Ensure that container "wine_test_bad_keyset" does not exist. */\r
+       if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))\r
+       {\r
+               pCryptReleaseContext(hProv, 0);\r
+               pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);\r
+       }\r
+}\r
+\r
+static void clean_up_environment(void)\r
+{\r
+       HCRYPTPROV hProv;\r
+\r
+       /* Remove container "wine_test_keyset" */\r
+       if (pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))\r
+       {\r
+               pCryptReleaseContext(hProv, 0);\r
+               pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);\r
+       }\r
+\r
+       /* Remove container "wine_test_keyset" from default PROV_RSA_FULL type provider */\r
+       if (pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, 0))\r
+       {\r
+               pCryptReleaseContext(hProv, 0);\r
+               pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);\r
+       }\r
+}\r
+\r
+static void test_acquire_context(void)\r
+{\r
+       BOOL result;\r
+       HCRYPTPROV hProv;\r
+\r
+       /* Provoke all kinds of error conditions (which are easy to provoke). \r
+        * The order of the error tests seems to match Windows XP's rsaenh.dll CSP,\r
+        * but since this is likely to change between CSP versions, we don't check\r
+        * this. Please don't change the order of tests. */\r
+       result = pCryptAcquireContextA(&hProv, NULL, NULL, 0, 0);\r
+       ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%ld\n", GetLastError());\r
+       \r
+       result = pCryptAcquireContextA(&hProv, NULL, NULL, 1000, 0);\r
+       ok(!result && GetLastError()==NTE_BAD_PROV_TYPE, "%ld\n", GetLastError());\r
+\r
+       result = pCryptAcquireContextA(&hProv, NULL, NULL, NON_DEF_PROV_TYPE, 0);\r
+       ok(!result && GetLastError()==NTE_PROV_TYPE_NOT_DEF, "%ld\n", GetLastError());\r
+       \r
+       result = pCryptAcquireContextA(&hProv, szKeySet, szNonExistentProv, PROV_RSA_FULL, 0);\r
+       ok(!result && GetLastError()==NTE_KEYSET_NOT_DEF, "%ld\n", GetLastError());\r
+\r
+       result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, NON_DEF_PROV_TYPE, 0);\r
+       ok(!result && GetLastError()==NTE_PROV_TYPE_NO_MATCH, "%ld\n", GetLastError());\r
+       \r
+       /* This test fails under Win2k SP4:\r
+          result = TRUE, GetLastError() == ERROR_INVALID_PARAMETER\r
+       SetLastError(0xdeadbeef);\r
+       result = pCryptAcquireContextA(NULL, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);\r
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%d/%ld\n", result, GetLastError());\r
+       */\r
+       \r
+       /* Last not least, try to really acquire a context. */\r
+       hProv = 0;\r
+       SetLastError(0xdeadbeef);\r
+       result = pCryptAcquireContextA(&hProv, szKeySet, szRsaBaseProv, PROV_RSA_FULL, 0);\r
+       ok(result && (GetLastError() == ERROR_ENVVAR_NOT_FOUND || GetLastError() == ERROR_SUCCESS  || GetLastError() == ERROR_RING2_STACK_IN_USE), "%d/%ld\n", result, GetLastError());\r
+\r
+       if (hProv) \r
+               pCryptReleaseContext(hProv, 0);\r
+\r
+       /* Try again, witch an empty ("\0") szProvider parameter */\r
+       hProv = 0;\r
+       SetLastError(0xdeadbeef);\r
+       result = pCryptAcquireContextA(&hProv, szKeySet, "", PROV_RSA_FULL, 0);\r
+       ok(result && (GetLastError() == ERROR_ENVVAR_NOT_FOUND || GetLastError() == ERROR_SUCCESS  || GetLastError() == ERROR_RING2_STACK_IN_USE), "%d/%ld\n", result, GetLastError());\r
+\r
+       if (hProv) \r
+               pCryptReleaseContext(hProv, 0);\r
+}\r
+\r
+static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, \r
+                           DWORD *pcbProvName, DWORD *pdwProvCount)\r
+{\r
+       HKEY hKey;\r
+       HKEY subkey;\r
+       DWORD size = sizeof(DWORD);\r
+       \r
+       if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))\r
+               return FALSE;\r
+       \r
+       RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, \r
+                                NULL, NULL, NULL, NULL, NULL, NULL);\r
+       (*pcbProvName)++;\r
+       \r
+       if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))\r
+               return FALSE;\r
+       \r
+       RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);\r
+       (*pcbProvName)++;\r
+\r
+       RegOpenKey(hKey, *pszProvName, &subkey);\r
+       RegQueryValueEx(subkey, "Type", NULL, NULL, (BYTE*)pdwProvType, &size);\r
+       \r
+       RegCloseKey(subkey);\r
+       RegCloseKey(hKey);\r
+       \r
+       return TRUE;\r
+}\r
+\r
+static void test_enum_providers(void)\r
+{\r
+       /* expected results */\r
+       CHAR *pszProvName = NULL;\r
+       DWORD cbName;\r
+       DWORD dwType;\r
+       DWORD provCount;\r
+       DWORD dwIndex = 0;\r
+       \r
+       /* actual results */\r
+       CHAR *provider = NULL;\r
+       DWORD providerLen;\r
+       DWORD type;\r
+       DWORD count;\r
+       BOOL result;\r
+       DWORD notNull = 5;\r
+       DWORD notZeroFlags = 5;\r
+       \r
+       if(!pCryptEnumProvidersA)\r
+       {\r
+           trace("skipping CryptEnumProviders tests\n");\r
+           return;\r
+       }\r
+       \r
+       if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))\r
+               return;\r
+       \r
+       /* check pdwReserved flag for NULL */\r
+       result = pCryptEnumProvidersA(dwIndex, &notNull, 0, &type, NULL, &providerLen);\r
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%ld\n", GetLastError());\r
+       \r
+       /* check dwFlags == 0 */\r
+       result = pCryptEnumProvidersA(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);\r
+       ok(!result && GetLastError()==NTE_BAD_FLAGS, "%ld\n", GetLastError());\r
+       \r
+       /* alloc provider to half the size required\r
+        * cbName holds the size required */\r
+       providerLen = cbName / 2;\r
+       if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))\r
+               return;\r
+\r
+       result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);\r
+       ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %ld\n",\r
+               ERROR_MORE_DATA, GetLastError());\r
+\r
+       LocalFree(provider);\r
+\r
+       /* loop through the providers to get the number of providers \r
+        * after loop ends, count should be provCount + 1 so subtract 1\r
+        * to get actual number of providers */\r
+       count = 0;\r
+       while(pCryptEnumProvidersA(count++, NULL, 0, &type, NULL, &providerLen))\r
+               ;\r
+       count--;\r
+       ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);\r
+       \r
+       /* loop past the actual number of providers to get the error\r
+        * ERROR_NO_MORE_ITEMS */\r
+       for (count = 0; count < provCount + 1; count++)\r
+               result = pCryptEnumProvidersA(count, NULL, 0, &type, NULL, &providerLen);\r
+       ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %ld\n", \r
+                       ERROR_NO_MORE_ITEMS, GetLastError());\r
+       \r
+       /* check expected versus actual values returned */\r
+       result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, NULL, &providerLen);\r
+       ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);\r
+       if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))\r
+               return;\r
+               \r
+       result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);\r
+       ok(result && type==dwType, "expected %ld, got %ld\n", \r
+               dwType, type);\r
+       ok(result && !strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);\r
+       ok(result && cbName==providerLen, "expected %ld, got %ld\n", \r
+               cbName, providerLen);\r
+\r
+       LocalFree(provider);\r
+}\r
+\r
+static BOOL FindProvTypesRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszTypeName, \r
+                                DWORD *pcbTypeName, DWORD *pdwTypeCount)\r
+{\r
+       HKEY hKey;\r
+       HKEY hSubKey;\r
+       PSTR ch;\r
+       \r
+       if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))\r
+               return FALSE;\r
+       \r
+       if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,\r
+                       NULL, NULL, NULL, NULL, NULL))\r
+           return FALSE;\r
+       (*pcbTypeName)++;\r
+       \r
+       if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))\r
+               return FALSE;\r
+       \r
+       if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))\r
+           return FALSE;\r
+       (*pcbTypeName)++;\r
+       ch = *pszTypeName + strlen(*pszTypeName);\r
+       /* Convert "Type 000" to 0, etc/ */\r
+       *pdwProvType = *(--ch) - '0';\r
+       *pdwProvType += (*(--ch) - '0') * 10;\r
+       *pdwProvType += (*(--ch) - '0') * 100;\r
+       \r
+       if (RegOpenKey(hKey, *pszTypeName, &hSubKey))\r
+           return FALSE;\r
+       \r
+       if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))\r
+            return FALSE;\r
+\r
+       if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))\r
+               return FALSE;\r
+       \r
+       if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, *pszTypeName, pcbTypeName))\r
+           return FALSE;\r
+       \r
+       RegCloseKey(hSubKey);\r
+       RegCloseKey(hKey);\r
+       \r
+       return TRUE;\r
+}\r
+\r
+static void test_enum_provider_types()\r
+{\r
+       /* expected values */\r
+       DWORD dwProvType;\r
+       LPSTR pszTypeName = NULL;\r
+       DWORD cbTypeName;\r
+       DWORD dwTypeCount;\r
+       \r
+       /* actual values */\r
+       DWORD index = 0;\r
+       DWORD provType;\r
+       LPSTR typeName = NULL;\r
+       DWORD typeNameSize;\r
+       DWORD typeCount;\r
+       DWORD result;\r
+       DWORD notNull = 5;\r
+       DWORD notZeroFlags = 5;\r
+       \r
+       if(!pCryptEnumProviderTypesA)\r
+       {\r
+           trace("skipping CryptEnumProviderTypes tests\n");\r
+           return;\r
+       }\r
+       \r
+       if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName, &dwTypeCount))\r
+       {\r
+           trace("could not find provider types in registry, skipping the test\n");\r
+           return;\r
+       }\r
+       \r
+       /* check pdwReserved for NULL */\r
+       result = pCryptEnumProviderTypesA(index, &notNull, 0, &provType, typeName, &typeNameSize);\r
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %ld\n", \r
+               ERROR_INVALID_PARAMETER, GetLastError());\r
+       \r
+       /* check dwFlags == zero */\r
+       result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName, &typeNameSize);\r
+       ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %ld\n",\r
+               ERROR_INVALID_PARAMETER, GetLastError());\r
+       \r
+       /* alloc provider type to half the size required\r
+        * cbTypeName holds the size required */\r
+       typeNameSize = cbTypeName / 2;\r
+       if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))\r
+               return;\r
+\r
+       /* This test fails under Win2k SP4:\r
+          result = TRUE, GetLastError() == 0xdeadbeef\r
+       SetLastError(0xdeadbeef);\r
+       result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);\r
+       ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA, got %d/%08lx\n",\r
+               result, GetLastError());\r
+       */\r
+       \r
+       LocalFree(typeName);\r
+       \r
+       /* loop through the provider types to get the number of provider types \r
+        * after loop ends, count should be dwTypeCount + 1 so subtract 1\r
+        * to get actual number of provider types */\r
+       typeCount = 0;\r
+       while(pCryptEnumProviderTypesA(typeCount++, NULL, 0, &provType, NULL, &typeNameSize))\r
+               ;\r
+       typeCount--;\r
+       ok(typeCount==dwTypeCount, "expected %ld, got %ld\n", dwTypeCount, typeCount);\r
+       \r
+       /* loop past the actual number of provider types to get the error\r
+        * ERROR_NO_MORE_ITEMS */\r
+       for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)\r
+               result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL, &typeNameSize);\r
+       ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got %ld\n", \r
+                       ERROR_NO_MORE_ITEMS, GetLastError());\r
+       \r
+\r
+       /* check expected versus actual values returned */\r
+       result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL, &typeNameSize);\r
+       ok(result && typeNameSize==cbTypeName, "expected %ld, got %ld\n", cbTypeName, typeNameSize);\r
+       if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))\r
+               return;\r
+               \r
+       typeNameSize = 0xdeadbeef;\r
+       result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName, &typeNameSize);\r
+       ok(result, "expected TRUE, got %ld\n", result);\r
+       ok(provType==dwProvType, "expected %ld, got %ld\n", dwProvType, provType);\r
+       if (pszTypeName)\r
+           ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName, typeName);\r
+       ok(typeNameSize==cbTypeName, "expected %ld, got %ld\n", cbTypeName, typeNameSize);\r
+       \r
+       LocalFree(typeName);\r
+}\r
+\r
+static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName, DWORD *pcbProvName)\r
+{\r
+       HKEY hKey;\r
+       PSTR keyname;\r
+       PSTR ptr;\r
+       DWORD user = dwFlags & CRYPT_USER_DEFAULT;\r
+       \r
+       LPSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";\r
+       LPSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX";\r
+       \r
+       keyname = LocalAlloc(LMEM_ZEROINIT, (user ? strlen(USERSTR) : strlen(MACHINESTR)) + 1);\r
+       if (keyname)\r
+       {\r
+               user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR);\r
+               ptr = keyname + strlen(keyname);\r
+               *(--ptr) = (dwProvType % 10) + '0';\r
+               *(--ptr) = ((dwProvType / 10) % 10) + '0';\r
+               *(--ptr) = (dwProvType / 100) + '0';\r
+       } else\r
+               return FALSE;\r
+       \r
+       if (RegOpenKey((dwFlags & CRYPT_USER_DEFAULT) ?  HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE ,keyname, &hKey))\r
+       {\r
+               LocalFree(keyname);\r
+               return FALSE;\r
+       }\r
+       LocalFree(keyname);\r
+       \r
+       if (RegQueryValueEx(hKey, "Name", NULL, NULL, *pszProvName, pcbProvName))\r
+       {\r
+               if (GetLastError() != ERROR_MORE_DATA)\r
+                       SetLastError(NTE_PROV_TYPE_ENTRY_BAD);\r
+               return FALSE;\r
+       }\r
+       \r
+       if (!(*pszProvName = LocalAlloc(LMEM_ZEROINIT, *pcbProvName)))\r
+               return FALSE;\r
+       \r
+       if (RegQueryValueEx(hKey, "Name", NULL, NULL, *pszProvName, pcbProvName))\r
+       {\r
+               if (GetLastError() != ERROR_MORE_DATA)\r
+                       SetLastError(NTE_PROV_TYPE_ENTRY_BAD);\r
+               return FALSE;\r
+       }\r
+       \r
+       RegCloseKey(hKey);\r
+       \r
+       return TRUE;\r
+}\r
+\r
+static void test_get_default_provider()\r
+{\r
+       /* expected results */\r
+       DWORD dwProvType = PROV_RSA_FULL;\r
+       DWORD dwFlags = CRYPT_MACHINE_DEFAULT;\r
+       LPSTR pszProvName = NULL;\r
+       DWORD cbProvName;\r
+       \r
+       /* actual results */\r
+       DWORD provType = PROV_RSA_FULL;\r
+       DWORD flags = CRYPT_MACHINE_DEFAULT;\r
+       LPSTR provName = NULL;\r
+       DWORD provNameSize;\r
+       DWORD result;\r
+       DWORD notNull = 5;\r
+       \r
+       if(!pCryptGetDefaultProviderA)\r
+       {\r
+           trace("skipping CryptGetDefaultProvider tests\n");\r
+           return;\r
+       }\r
+       \r
+       FindDfltProvRegVals(dwProvType, dwFlags, &pszProvName, &cbProvName);\r
+       \r
+       /* check pdwReserved for NULL */\r
+       result = pCryptGetDefaultProviderA(provType, &notNull, flags, provName, &provNameSize);\r
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %ld\n",\r
+               ERROR_INVALID_PARAMETER, GetLastError());\r
+       \r
+       /* check for invalid flag */\r
+       flags = 0xdeadbeef;\r
+       result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);\r
+       ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %ld, got %ld\n",\r
+               NTE_BAD_FLAGS, GetLastError());\r
+       flags = CRYPT_MACHINE_DEFAULT;\r
+       \r
+       /* check for invalid prov type */\r
+       provType = 0xdeadbeef;\r
+       result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);\r
+       ok(!result && (GetLastError() == NTE_BAD_PROV_TYPE ||\r
+                      GetLastError() == ERROR_INVALID_PARAMETER),\r
+               "expected NTE_BAD_PROV_TYPE or ERROR_INVALID_PARAMETER, got %ld/%ld\n",\r
+               result, GetLastError());\r
+       provType = PROV_RSA_FULL;\r
+       \r
+       SetLastError(0);\r
+       \r
+       /* alloc provName to half the size required\r
+        * cbProvName holds the size required */\r
+       provNameSize = cbProvName / 2;\r
+       if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))\r
+               return;\r
+       \r
+       result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);\r
+       ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %i, got %ld\n",\r
+               ERROR_MORE_DATA, GetLastError());\r
+               \r
+       LocalFree(provName);\r
+       \r
+       /* check expected versus actual values returned */\r
+       result = pCryptGetDefaultProviderA(provType, NULL, flags, NULL, &provNameSize);\r
+       ok(result && provNameSize==cbProvName, "expected %ld, got %ld\n", cbProvName, provNameSize);\r
+       provNameSize = cbProvName;\r
+       \r
+       if (!(provName = LocalAlloc(LMEM_ZEROINIT, provNameSize)))\r
+               return;\r
+       \r
+       result = pCryptGetDefaultProviderA(provType, NULL, flags, provName, &provNameSize);\r
+       ok(result && !strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName, provName);\r
+       ok(result && provNameSize==cbProvName, "expected %ld, got %ld\n", cbProvName, provNameSize);\r
+\r
+       LocalFree(provName);\r
+}\r
+\r
+static void test_set_provider_ex()\r
+{\r
+       DWORD result;\r
+       DWORD notNull = 5;\r
+       \r
+       /* results */\r
+       LPSTR pszProvName = NULL;\r
+       DWORD cbProvName;\r
+       \r
+       if(!pCryptGetDefaultProviderA || !pCryptSetProviderExA)\r
+       {\r
+           trace("skipping CryptSetProviderEx tests\n");\r
+           return;\r
+       }\r
+\r
+       /* check pdwReserved for NULL */\r
+       result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, &notNull, CRYPT_MACHINE_DEFAULT);\r
+       ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got %ld\n",\r
+               ERROR_INVALID_PARAMETER, GetLastError());\r
+\r
+       /* remove the default provider and then set it to MS_DEF_PROV/PROV_RSA_FULL */\r
+       result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT | CRYPT_DELETE_DEFAULT);\r
+       ok(result, "%ld\n", GetLastError());\r
+\r
+       result = pCryptSetProviderExA(MS_DEF_PROV, PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT);\r
+       ok(result, "%ld\n", GetLastError());\r
+       \r
+       /* call CryptGetDefaultProvider to see if they match */\r
+       result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, NULL, &cbProvName);\r
+       if (!(pszProvName = LocalAlloc(LMEM_ZEROINIT, cbProvName)))\r
+               return;\r
+\r
+       result = pCryptGetDefaultProviderA(PROV_RSA_FULL, NULL, CRYPT_MACHINE_DEFAULT, pszProvName, &cbProvName);\r
+       ok(result && !strcmp(MS_DEF_PROV, pszProvName), "expected %s, got %s\n", MS_DEF_PROV, pszProvName);\r
+       ok(result && cbProvName==(strlen(MS_DEF_PROV) + 1), "expected %i, got %ld\n", (strlen(MS_DEF_PROV) + 1), cbProvName);\r
+\r
+       LocalFree(pszProvName);\r
+}\r
+\r
+START_TEST(crypt)\r
+{\r
+       init_function_pointers();\r
+       if(pCryptAcquireContextA && pCryptReleaseContext) {\r
+       init_environment();\r
+       test_acquire_context();\r
+       clean_up_environment();\r
+       }\r
+       \r
+       test_enum_providers();\r
+       test_enum_provider_types();\r
+       test_get_default_provider();\r
+       test_set_provider_ex();\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/crypt_lmhash.c b/reactos/lib/advapi32/winetests/crypt_lmhash.c
new file mode 100644 (file)
index 0000000..d887953
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Unit tests for SystemFunction006 (LMHash?)\r
+ *\r
+ * Copyright 2004 Hans Leidekker\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdio.h>\r
+\r
+#include "wine/test.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+\r
+typedef VOID (WINAPI *fnSystemFunction006)( PCSTR passwd, PSTR lmhash );\r
+fnSystemFunction006 pSystemFunction006;\r
+\r
+static void test_SystemFunction006()\r
+{\r
+    static unsigned char lmhash[16 + 1];\r
+\r
+    unsigned char passwd[] = { 's','e','c','r','e','t', 0, 0, 0, 0, 0, 0, 0, 0 };\r
+    unsigned char expect[] = \r
+        { 0x85, 0xf5, 0x28, 0x9f, 0x09, 0xdc, 0xa7, 0xeb,\r
+          0xaa, 0xd3, 0xb4, 0x35, 0xb5, 0x14, 0x04, 0xee };\r
+\r
+    pSystemFunction006( passwd, lmhash );\r
+\r
+    ok( !memcmp( lmhash, expect, sizeof(expect) ),\r
+        "lmhash: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",\r
+        lmhash[0], lmhash[1], lmhash[2], lmhash[3], lmhash[4], lmhash[5],\r
+        lmhash[6], lmhash[7], lmhash[8], lmhash[9], lmhash[10], lmhash[11],\r
+        lmhash[12], lmhash[13], lmhash[14], lmhash[15] );\r
+}\r
+\r
+START_TEST(crypt_lmhash)\r
+{\r
+    HMODULE module;\r
+\r
+    if (!(module = LoadLibrary("advapi32.dll"))) return;\r
+\r
+    pSystemFunction006 = (fnSystemFunction006)GetProcAddress( module, "SystemFunction006" );\r
+\r
+    if (!pSystemFunction006) goto out;\r
+\r
+    if (pSystemFunction006) \r
+        test_SystemFunction006();\r
+\r
+out:\r
+    FreeLibrary( module );\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/crypt_md4.c b/reactos/lib/advapi32/winetests/crypt_md4.c
new file mode 100644 (file)
index 0000000..391a2b7
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Unit tests for MD4 functions\r
+ *\r
+ * Copyright 2004 Hans Leidekker\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdio.h>\r
+\r
+#include "wine/test.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winerror.h"\r
+\r
+typedef struct\r
+{\r
+    unsigned int buf[4];\r
+    unsigned int i[2];\r
+    unsigned char in[64];\r
+    unsigned char digest[16];\r
+} MD4_CTX;\r
+\r
+typedef VOID (WINAPI *fnMD4Init)( MD4_CTX *ctx );\r
+typedef VOID (WINAPI *fnMD4Update)( MD4_CTX *ctx, const unsigned char *src, const int len );\r
+typedef VOID (WINAPI *fnMD4Final)( MD4_CTX *ctx );\r
+\r
+fnMD4Init pMD4Init;\r
+fnMD4Update pMD4Update;\r
+fnMD4Final pMD4Final;\r
+\r
+#define ctxcmp( a, b ) memcmp( (char*)a, (char*)b, FIELD_OFFSET( MD4_CTX, in ) )\r
+\r
+void test_md4_ctx()\r
+{\r
+    static unsigned char message[] =\r
+        "In our Life there's If"\r
+        "In our beliefs there's Lie"\r
+        "In our business there is Sin"\r
+        "In our bodies, there is Die";\r
+\r
+    int size = strlen( message );\r
+    HMODULE module;\r
+\r
+    MD4_CTX ctx;\r
+    MD4_CTX ctx_initialized = \r
+    {\r
+        { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 },\r
+        { 0, 0 }\r
+    };\r
+\r
+    MD4_CTX ctx_update1 =\r
+    {\r
+        { 0x5e592ef7, 0xbdcb1567, 0x2b626d17, 0x7d1198bd },\r
+        { 0x00000338, 0 }\r
+    };\r
+\r
+    MD4_CTX ctx_update2 =\r
+    {\r
+        { 0x05dcfd65, 0xb3711c0d, 0x9e3369c2, 0x903ead11 },\r
+        { 0x00000670, 0 }\r
+    };\r
+\r
+    unsigned char expect[16] =\r
+        { 0x5f, 0xd3, 0x9b, 0x29, 0x47, 0x53, 0x47, 0xaf,\r
+          0xa5, 0xba, 0x0c, 0x05, 0xff, 0xc0, 0xc7, 0xda };\r
+\r
+    if (!(module = LoadLibrary( "advapi32.dll" ))) return;\r
+\r
+    pMD4Init = (fnMD4Init)GetProcAddress( module, "MD4Init" );\r
+    pMD4Update = (fnMD4Update)GetProcAddress( module, "MD4Update" );\r
+    pMD4Final = (fnMD4Final)GetProcAddress( module, "MD4Final" );\r
+\r
+    if (!pMD4Init || !pMD4Update || !pMD4Final) goto out;\r
+\r
+    memset( &ctx, 0, sizeof(ctx) );\r
+    pMD4Init( &ctx );\r
+    ok( !ctxcmp( &ctx, &ctx_initialized ), "invalid initialization\n" );\r
+\r
+    pMD4Update( &ctx, message, size );\r
+    ok( !ctxcmp( &ctx, &ctx_update1 ), "update doesn't work correctly\n" );\r
+\r
+    pMD4Update( &ctx, message, size );\r
+    ok( !ctxcmp( &ctx, &ctx_update2 ), "update doesn't work correctly\n" );\r
+\r
+    pMD4Final( &ctx );\r
+    ok( ctxcmp( &ctx, &ctx_initialized ), "context has changed\n" );\r
+    ok( !memcmp( ctx.digest, expect, sizeof(expect) ), "incorrect result\n" );\r
+\r
+out:\r
+    FreeLibrary( module );\r
+}\r
+\r
+START_TEST(crypt_md4)\r
+{\r
+    test_md4_ctx();\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/crypt_md5.c b/reactos/lib/advapi32/winetests/crypt_md5.c
new file mode 100644 (file)
index 0000000..68afd60
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Unit tests for MD5 functions\r
+ *\r
+ * Copyright 2004 Hans Leidekker\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdio.h>\r
+\r
+#include "wine/test.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winerror.h"\r
+\r
+typedef struct\r
+{\r
+    unsigned int i[2];\r
+    unsigned int buf[4];\r
+    unsigned char in[64];\r
+    unsigned char digest[16];\r
+} MD5_CTX;\r
+\r
+typedef VOID (WINAPI *fnMD5Init)( MD5_CTX *ctx );\r
+typedef VOID (WINAPI *fnMD5Update)( MD5_CTX *ctx, const unsigned char *src, const int len );\r
+typedef VOID (WINAPI *fnMD5Final)( MD5_CTX *ctx );\r
+\r
+fnMD5Init pMD5Init;\r
+fnMD5Update pMD5Update;\r
+fnMD5Final pMD5Final;\r
+\r
+#define ctxcmp( a, b ) memcmp( (char*)a, (char*)b, FIELD_OFFSET( MD5_CTX, in ) )\r
+\r
+void test_md5_ctx()\r
+{\r
+    static unsigned char message[] =\r
+        "In our Life there's If"\r
+        "In our beliefs there's Lie"\r
+        "In our business there is Sin"\r
+        "In our bodies, there is Die";\r
+\r
+    int size = strlen( message );\r
+    HMODULE module;\r
+\r
+    MD5_CTX ctx;\r
+    MD5_CTX ctx_initialized = \r
+    {\r
+        { 0, 0 },\r
+        { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }\r
+    };\r
+\r
+    MD5_CTX ctx_update1 =\r
+    {\r
+        { 0x00000338, 0 },\r
+        { 0x068cb64d, 0xb7a05790, 0x426979ee, 0xed67e221 }\r
+    };\r
+\r
+    MD5_CTX ctx_update2 =\r
+    {\r
+        { 0x00000670, 0 },\r
+        { 0x2f7afe58, 0xcc3e9315, 0x709c465c, 0xbf6414c8 }\r
+    };\r
+\r
+    unsigned char expect[16] =\r
+        { 0x43, 0x03, 0xdd, 0x8c, 0x60, 0xd9, 0x3a, 0x22,\r
+          0x0b, 0x28, 0xd0, 0xb2, 0x65, 0x93, 0xd0, 0x36 };\r
+\r
+    if (!(module = LoadLibrary( "advapi32.dll" ))) return;\r
+\r
+    pMD5Init = (fnMD5Init)GetProcAddress( module, "MD5Init" );\r
+    pMD5Update = (fnMD5Update)GetProcAddress( module, "MD5Update" );\r
+    pMD5Final = (fnMD5Final)GetProcAddress( module, "MD5Final" );\r
+\r
+    if (!pMD5Init || !pMD5Update || !pMD5Final) goto out;\r
+\r
+    memset( &ctx, 0, sizeof(ctx) );\r
+    pMD5Init( &ctx );\r
+    ok( !ctxcmp( &ctx, &ctx_initialized ), "invalid initialization\n" );\r
+\r
+    pMD5Update( &ctx, message, size );\r
+    ok( !ctxcmp( &ctx, &ctx_update1 ), "update doesn't work correctly\n" );\r
+\r
+    pMD5Update( &ctx, message, size );\r
+    ok( !ctxcmp( &ctx, &ctx_update2 ), "update doesn't work correctly\n" );\r
+\r
+    pMD5Final( &ctx );\r
+    ok( ctxcmp( &ctx, &ctx_initialized ), "context has changed\n" );\r
+    ok( !memcmp( ctx.digest, expect, sizeof(expect) ), "incorrect result\n" );\r
+\r
+out:\r
+    FreeLibrary( module );\r
+}\r
+\r
+START_TEST(crypt_md5)\r
+{\r
+    test_md5_ctx();\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/crypt_sha.c b/reactos/lib/advapi32/winetests/crypt_sha.c
new file mode 100644 (file)
index 0000000..a364235
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+ * Unit tests for SHA functions\r
+ *\r
+ * Copyright (c) 2004 Filip Navara\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winerror.h"\r
+\r
+#include "wine/test.h"\r
+\r
+typedef struct {\r
+   ULONG Unknown[6];\r
+   ULONG State[5];\r
+   ULONG Count[2];\r
+   UCHAR Buffer[64];\r
+} SHA_CTX, *PSHA_CTX;\r
+\r
+#define ctxcmp(a,b) memcmp((char*)a, (char*)b, FIELD_OFFSET(SHA_CTX, Buffer))\r
+\r
+static void test_sha_ctx(void)\r
+{\r
+   FARPROC pA_SHAInit, pA_SHAUpdate, pA_SHAFinal;\r
+   static const char test_buffer[] = "In our Life there's If"\r
+                       "In our beliefs there's Lie"\r
+                       "In our business there is Sin"\r
+                       "In our bodies, there is Die";\r
+   ULONG test_buffer_size = strlen(test_buffer);\r
+   HMODULE hmod;\r
+   SHA_CTX ctx;\r
+   SHA_CTX ctx_initialized = {{0, 0, 0, 0, 0}, {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0}, {0, 0}};\r
+   SHA_CTX ctx_update1 = {{0, 0, 0, 0, 0}, {0xdbe5eba8, 0x6b4335ca, 0xf7c94abe, 0xc9f34e31, 0x311023f0}, {0, 0x67}};\r
+   SHA_CTX ctx_update2 = {{0, 0, 0, 0, 0}, {0x5ecc818d, 0x52498169, 0xf6758559, 0xd035a164, 0x871dd125}, {0, 0xce}};\r
+   ULONG result[5];\r
+   ULONG result_correct[5] = {0xe014f93, 0xe09791ec, 0x6dcf96c8, 0x8e9385fc, 0x1611c1bb};\r
+\r
+   hmod = LoadLibrary("advapi32.dll");\r
+   pA_SHAInit = GetProcAddress(hmod, "A_SHAInit");\r
+   pA_SHAUpdate = GetProcAddress(hmod, "A_SHAUpdate");\r
+   pA_SHAFinal = GetProcAddress(hmod, "A_SHAFinal");\r
+\r
+   if (!pA_SHAInit || !pA_SHAUpdate || !pA_SHAFinal) return;\r
+\r
+   RtlZeroMemory(&ctx, sizeof(ctx));\r
+   pA_SHAInit(&ctx);\r
+   ok(!ctxcmp(&ctx, &ctx_initialized), "invalid initialization\n");\r
+\r
+   pA_SHAUpdate(&ctx, test_buffer, test_buffer_size);\r
+   ok(!ctxcmp(&ctx, &ctx_update1), "update doesn't work correctly\n");\r
+\r
+   pA_SHAUpdate(&ctx, test_buffer, test_buffer_size);\r
+   ok(!ctxcmp(&ctx, &ctx_update2), "update doesn't work correctly\n");\r
+\r
+   pA_SHAFinal(&ctx, result);\r
+   ok(!ctxcmp(&ctx, &ctx_initialized), "context hasn't been reinitialized\n");\r
+   ok(!memcmp(result, result_correct, sizeof(result)), "incorrect result\n");\r
+\r
+   FreeLibrary(hmod);\r
+}\r
+\r
+START_TEST(crypt_sha)\r
+{\r
+    test_sha_ctx();\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/makefile b/reactos/lib/advapi32/winetests/makefile
new file mode 100644 (file)
index 0000000..dd825b1
--- /dev/null
@@ -0,0 +1,33 @@
+# $Id: Makefile 12745 2005-01-03 02:37:10Z sedwards $\r
+\r
+PATH_TO_TOP = ../../..\r
+\r
+TARGET_NORC = yes\r
+\r
+TARGET_TYPE = program\r
+\r
+TARGET_APPTYPE = console\r
+\r
+# require os code to explicitly request A/W version of structs/functions\r
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \\r
+       -D_WIN32_WINNT=0x0501 -D__REACTOS__\r
+\r
+TARGET_NAME = advapi32_test\r
+\r
+TARGET_SDKLIBS = advapi32.a ntdll.a wine.a\r
+\r
+TARGET_OBJECTS = \\r
+       testlist.o \\r
+       crypt.o \\r
+       crypt_lmhash.o \\r
+       crypt_md4.o \\r
+       crypt_md5.o \\r
+       crypt_sha.o \\r
+       registry.o \\r
+       security.o\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+# EOF
\ No newline at end of file
diff --git a/reactos/lib/advapi32/winetests/registry.c b/reactos/lib/advapi32/winetests/registry.c
new file mode 100644 (file)
index 0000000..0416a3e
--- /dev/null
@@ -0,0 +1,358 @@
+/*\r
+ * Unit tests for registry functions\r
+ *\r
+ * Copyright (c) 2002 Alexandre Julliard\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <assert.h>\r
+#include <stdarg.h>\r
+#include "wine/test.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winerror.h"\r
+\r
+static HKEY hkey_main;\r
+\r
+static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";\r
+static const char * sTestpath2 = "%FOO%\\subdir1";\r
+\r
+/* delete key and all its subkeys */\r
+static DWORD delete_key( HKEY hkey )\r
+{\r
+    char name[MAX_PATH];\r
+    DWORD ret;\r
+\r
+    while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name))))\r
+    {\r
+        HKEY tmp;\r
+        if (!(ret = RegOpenKeyExA( hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp )))\r
+        {\r
+            ret = delete_key( tmp );\r
+            RegCloseKey( tmp );\r
+        }\r
+        if (ret) break;\r
+    }\r
+    if (ret != ERROR_NO_MORE_ITEMS) return ret;\r
+    RegDeleteKeyA( hkey, NULL );\r
+    return 0;\r
+}\r
+\r
+static void setup_main_key(void)\r
+{\r
+    if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )) delete_key( hkey_main );\r
+\r
+    assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main ));\r
+}\r
+\r
+static void create_test_entries(void)\r
+{\r
+    SetEnvironmentVariableA("LONGSYSTEMVAR", "bar");\r
+    SetEnvironmentVariableA("FOO", "ImARatherLongButIndeedNeededString");\r
+\r
+    ok(!RegSetValueExA(hkey_main,"Test1",0,REG_EXPAND_SZ, sTestpath1, strlen(sTestpath1)+1), \r
+        "RegSetValueExA failed\n");\r
+    ok(!RegSetValueExA(hkey_main,"Test2",0,REG_SZ, sTestpath1, strlen(sTestpath1)+1), \r
+        "RegSetValueExA failed\n");\r
+    ok(!RegSetValueExA(hkey_main,"Test3",0,REG_EXPAND_SZ, sTestpath2, strlen(sTestpath2)+1), \r
+        "RegSetValueExA failed\n");\r
+}\r
+        \r
+static void test_enum_value(void)\r
+{\r
+    DWORD res;\r
+    char value[20], data[20];\r
+    WCHAR valueW[20], dataW[20];\r
+    DWORD val_count, data_count, type;\r
+    static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};\r
+    static const WCHAR testW[] = {'T','e','s','t',0};\r
+    static const WCHAR xxxW[] = {'x','x','x','x','x','x','x','x',0};\r
+\r
+    /* check NULL data with zero length */\r
+    res = RegSetValueExA( hkey_main, "Test", 0, REG_SZ, NULL, 0 );\r
+    if (GetVersion() & 0x80000000)\r
+        ok( res == ERROR_INVALID_PARAMETER, "RegSetValueExA returned %ld\n", res );\r
+    else\r
+        ok( !res, "RegSetValueExA returned %ld\n", res );\r
+    res = RegSetValueExA( hkey_main, "Test", 0, REG_EXPAND_SZ, NULL, 0 );\r
+    ok( !res, "RegSetValueExA returned %ld\n", res );\r
+    res = RegSetValueExA( hkey_main, "Test", 0, REG_BINARY, NULL, 0 );\r
+    ok( !res, "RegSetValueExA returned %ld\n", res );\r
+\r
+    res = RegSetValueExA( hkey_main, "Test", 0, REG_SZ, (BYTE *)"foobar", 7 );\r
+    ok( res == 0, "RegSetValueExA failed error %ld\n", res );\r
+\r
+    /* overflow both name and data */\r
+    val_count = 2;\r
+    data_count = 2;\r
+    type = 1234;\r
+    strcpy( value, "xxxxxxxxxx" );\r
+    strcpy( data, "xxxxxxxxxx" );\r
+    res = RegEnumValueA( hkey_main, 0, value, &val_count, NULL, &type, data, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 2, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );\r
+    ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data );\r
+\r
+    /* overflow name */\r
+    val_count = 3;\r
+    data_count = 20;\r
+    type = 1234;\r
+    strcpy( value, "xxxxxxxxxx" );\r
+    strcpy( data, "xxxxxxxxxx" );\r
+    res = RegEnumValueA( hkey_main, 0, value, &val_count, NULL, &type, data, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    /* Win9x returns 2 as specified by MSDN but NT returns 3... */\r
+    ok( val_count == 2 || val_count == 3, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+#if 0\r
+    /* v5.1.2600.0 (XP Home) does not touch value or data in this case */\r
+    ok( !strcmp( value, "Te" ), "value set to '%s' instead of 'Te'\n", value );\r
+    ok( !strcmp( data, "foobar" ), "data set to '%s' instead of 'foobar'\n", data );\r
+#endif\r
+\r
+    /* overflow empty name */\r
+    val_count = 0;\r
+    data_count = 20;\r
+    type = 1234;\r
+    strcpy( value, "xxxxxxxxxx" );\r
+    strcpy( data, "xxxxxxxxxx" );\r
+    res = RegEnumValueA( hkey_main, 0, value, &val_count, NULL, &type, data, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 0, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );\r
+#if 0\r
+    /* v5.1.2600.0 (XP Home) does not touch data in this case */\r
+    ok( !strcmp( data, "foobar" ), "data set to '%s' instead of 'foobar'\n", data );\r
+#endif\r
+\r
+    /* overflow data */\r
+    val_count = 20;\r
+    data_count = 2;\r
+    type = 1234;\r
+    strcpy( value, "xxxxxxxxxx" );\r
+    strcpy( data, "xxxxxxxxxx" );\r
+    res = RegEnumValueA( hkey_main, 0, value, &val_count, NULL, &type, data, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 20, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !strcmp( value, "xxxxxxxxxx" ), "value set to '%s'\n", value );\r
+    ok( !strcmp( data, "xxxxxxxxxx" ), "data set to '%s'\n", data );\r
+\r
+    /* no overflow */\r
+    val_count = 20;\r
+    data_count = 20;\r
+    type = 1234;\r
+    strcpy( value, "xxxxxxxxxx" );\r
+    strcpy( data, "xxxxxxxxxx" );\r
+    res = RegEnumValueA( hkey_main, 0, value, &val_count, NULL, &type, data, &data_count );\r
+    ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res );\r
+    ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count );\r
+    ok( data_count == 7, "data_count set to %ld instead of 7\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !strcmp( value, "Test" ), "value is '%s' instead of Test\n", value );\r
+    ok( !strcmp( data, "foobar" ), "data is '%s' instead of foobar\n", data );\r
+\r
+    /* Unicode tests */\r
+\r
+    SetLastError(0);\r
+    res = RegSetValueExW( hkey_main, testW, 0, REG_SZ, (const BYTE *)foobarW, 7*sizeof(WCHAR) );\r
+    if (res==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)\r
+        goto CLEANUP;\r
+    ok( res == 0, "RegSetValueExW failed error %ld\n", res );\r
+\r
+    /* overflow both name and data */\r
+    val_count = 2;\r
+    data_count = 2;\r
+    type = 1234;\r
+    memcpy( valueW, xxxW, sizeof(xxxW) );\r
+    memcpy( dataW, xxxW, sizeof(xxxW) );\r
+    res = RegEnumValueW( hkey_main, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 2, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" );\r
+    ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );\r
+\r
+    /* overflow name */\r
+    val_count = 3;\r
+    data_count = 20;\r
+    type = 1234;\r
+    memcpy( valueW, xxxW, sizeof(xxxW) );\r
+    memcpy( dataW, xxxW, sizeof(xxxW) );\r
+    res = RegEnumValueW( hkey_main, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 3, "val_count set to %ld\n", val_count );\r
+    ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !memcmp( valueW, xxxW, sizeof(xxxW) ), "value modified\n" );\r
+    ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );\r
+\r
+    /* overflow data */\r
+    val_count = 20;\r
+    data_count = 2;\r
+    type = 1234;\r
+    memcpy( valueW, xxxW, sizeof(xxxW) );\r
+    memcpy( dataW, xxxW, sizeof(xxxW) );\r
+    res = RegEnumValueW( hkey_main, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );\r
+    ok( res == ERROR_MORE_DATA, "expected ERROR_MORE_DATA, got %ld\n", res );\r
+    ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count );\r
+    ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" );\r
+    ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data modified\n" );\r
+\r
+    /* no overflow */\r
+    val_count = 20;\r
+    data_count = 20;\r
+    type = 1234;\r
+    memcpy( valueW, xxxW, sizeof(xxxW) );\r
+    memcpy( dataW, xxxW, sizeof(xxxW) );\r
+    res = RegEnumValueW( hkey_main, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count );\r
+    ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", res );\r
+    ok( val_count == 4, "val_count set to %ld instead of 4\n", val_count );\r
+    ok( data_count == 7*sizeof(WCHAR), "data_count set to %ld instead of 7*sizeof(WCHAR)\n", data_count );\r
+    ok( type == REG_SZ, "type %ld is not REG_SZ\n", type );\r
+    ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" );\r
+    ok( !memcmp( dataW, foobarW, sizeof(foobarW) ), "data is not 'foobar'\n" );\r
+\r
+CLEANUP:\r
+    /* cleanup */\r
+    RegDeleteValueA( hkey_main, "Test" );\r
+}\r
+\r
+static void test_query_value_ex()\r
+{\r
+    DWORD ret;\r
+    DWORD size;\r
+    DWORD type;\r
+    \r
+    ret = RegQueryValueExA(hkey_main, "Test2", NULL, &type, NULL, &size);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(size == strlen(sTestpath1) + 1, "(%ld,%ld)\n", (DWORD)strlen(sTestpath1) + 1, size);\r
+    ok(type == REG_SZ, "type %ld is not REG_SZ\n", type);\r
+}\r
+\r
+static void test_reg_open_key()\r
+{\r
+    DWORD ret = 0;\r
+    HKEY hkResult = NULL;\r
+    HKEY hkPreserve = NULL;\r
+\r
+    /* successful open */\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(hkResult != NULL, "expected hkResult != NULL\n");\r
+    hkPreserve = hkResult;\r
+\r
+    /* open same key twice */\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkResult);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(hkResult != hkPreserve && hkResult != NULL, \r
+               "expected hkResult != hkPreserve and hkResult != NULL\n");\r
+    RegCloseKey(hkResult);\r
+\r
+    /* open nonexistent key\r
+     * check that hkResult is set to NULL\r
+     */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult);\r
+    ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret);\r
+    ok(hkResult == NULL, "expected hkResult == NULL\n");\r
+\r
+    /* open the same nonexistent key again to make sure the key wasn't created */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Nonexistent", &hkResult);\r
+    ok(ret == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %ld\n", ret);\r
+    ok(hkResult == NULL, "expected hkResult == NULL\n");\r
+\r
+    /* send in NULL lpSubKey\r
+     * check that hkResult receives the value of hKey\r
+     */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, NULL, &hkResult);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n");\r
+\r
+    /* send empty-string in lpSubKey */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "", &hkResult);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(hkResult == HKEY_CURRENT_USER, "expected hkResult == HKEY_CURRENT_USER\n");\r
+\r
+    /* send in NULL lpSubKey and NULL hKey\r
+     * hkResult is set to NULL\r
+     */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(NULL, NULL, &hkResult);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+    ok(hkResult == NULL, "expected hkResult == NULL\n");\r
+\r
+    /* only send NULL hKey\r
+     * the value of hkResult remains unchanged\r
+     */\r
+    hkResult = hkPreserve;\r
+    ret = RegOpenKeyA(NULL, "Software\\Wine\\Test", &hkResult);\r
+    ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", ret);\r
+    ok(hkResult == hkPreserve, "expected hkResult == hkPreserve\n");\r
+    RegCloseKey(hkResult);\r
+\r
+    /* send in NULL hkResult */\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", NULL);\r
+    ok(ret == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", ret);\r
+}\r
+\r
+static void test_reg_close_key()\r
+{\r
+    DWORD ret = 0;\r
+    HKEY hkHandle;\r
+\r
+    /* successfully close key\r
+     * hkHandle remains changed after call to RegCloseKey\r
+     */\r
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkHandle);\r
+    ret = RegCloseKey(hkHandle);\r
+    ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret);\r
+\r
+    /* try to close the key twice */\r
+    ret = RegCloseKey(hkHandle);\r
+    ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", ret);\r
+\r
+    /* try to close a NULL handle */\r
+    ret = RegCloseKey(NULL);\r
+    ok(ret == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", ret);\r
+}\r
+\r
+START_TEST(registry)\r
+{\r
+    setup_main_key();\r
+    create_test_entries();\r
+    test_enum_value();\r
+    test_query_value_ex();\r
+    test_reg_open_key();\r
+    test_reg_close_key();\r
+\r
+    /* cleanup */\r
+    delete_key( hkey_main );\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/security.c b/reactos/lib/advapi32/winetests/security.c
new file mode 100644 (file)
index 0000000..ad8a4e1
--- /dev/null
@@ -0,0 +1,408 @@
+/*\r
+ * Unit tests for security functions\r
+ *\r
+ * Copyright (c) 2004 Mike McCormack\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdio.h>\r
+\r
+#include "wine/test.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winerror.h"\r
+#include "aclapi.h"\r
+#include "winnt.h"\r
+\r
+typedef BOOL (WINAPI *fnBuildTrusteeWithSidA)( TRUSTEE *trustee, PSID psid );\r
+typedef BOOL (WINAPI *fnBuildTrusteeWithNameA)( TRUSTEE *trustee, LPSTR str );\r
+typedef BOOL (WINAPI *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str );\r
+typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );\r
+\r
+static HMODULE hmod;\r
+\r
+fnBuildTrusteeWithSidA   pBuildTrusteeWithSidA;\r
+fnBuildTrusteeWithNameA  pBuildTrusteeWithNameA;\r
+fnConvertSidToStringSidA pConvertSidToStringSidA;\r
+fnConvertStringSidToSidA pConvertStringSidToSidA;\r
+\r
+struct sidRef\r
+{\r
+    SID_IDENTIFIER_AUTHORITY auth;\r
+    const char *refStr;\r
+};\r
+\r
+static void init(void)\r
+{\r
+    hmod = GetModuleHandle("advapi32.dll");\r
+}\r
+\r
+void test_sid()\r
+{\r
+    struct sidRef refs[] = {\r
+     { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },\r
+     { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1"  },\r
+     { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1"     },\r
+     { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1"       },\r
+     { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1"         },\r
+     { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1"        },\r
+    };\r
+    const char noSubAuthStr[] = "S-1-5";\r
+    unsigned int i;\r
+    PSID psid = NULL;\r
+    BOOL r;\r
+    LPSTR str = NULL;\r
+\r
+    pConvertSidToStringSidA = (fnConvertSidToStringSidA)\r
+                    GetProcAddress( hmod, "ConvertSidToStringSidA" );\r
+    if( !pConvertSidToStringSidA )\r
+        return;\r
+    pConvertStringSidToSidA = (fnConvertStringSidToSidA)\r
+                    GetProcAddress( hmod, "ConvertStringSidToSidA" );\r
+    if( !pConvertStringSidToSidA )\r
+        return;\r
+\r
+    r = pConvertStringSidToSidA( NULL, NULL );\r
+    ok( !r, "expected failure with NULL parameters\n" );\r
+    if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )\r
+        return;\r
+    ok( GetLastError() == ERROR_INVALID_PARAMETER,\r
+     "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",\r
+     GetLastError() );\r
+\r
+    r = pConvertStringSidToSidA( refs[0].refStr, NULL );\r
+    ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,\r
+     "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",\r
+     GetLastError() );\r
+\r
+    r = pConvertStringSidToSidA( NULL, &str );\r
+    ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,\r
+     "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",\r
+     GetLastError() );\r
+\r
+    r = pConvertStringSidToSidA( noSubAuthStr, &psid );\r
+    ok( !r,\r
+     "expected failure with no sub authorities\n" );\r
+    ok( GetLastError() == ERROR_INVALID_SID,\r
+     "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",\r
+     GetLastError() );\r
+\r
+    for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )\r
+    {\r
+        PISID pisid;\r
+\r
+        r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,\r
+         &psid );\r
+        ok( r, "failed to allocate sid\n" );\r
+        r = pConvertSidToStringSidA( psid, &str );\r
+        ok( r, "failed to convert sid\n" );\r
+        ok( !strcmp( str, refs[i].refStr ),\r
+         "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );\r
+        if( str )\r
+            LocalFree( str );\r
+        if( psid )\r
+            FreeSid( psid );\r
+\r
+        r = pConvertStringSidToSidA( refs[i].refStr, &psid );\r
+        ok( r, "failed to parse sid string\n" );\r
+        pisid = (PISID)psid;\r
+        ok( pisid &&\r
+         !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,\r
+         sizeof(refs[i].auth) ),\r
+         "string sid %s didn't parse to expected value\n"\r
+         "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",\r
+         refs[i].refStr,\r
+         MAKEWORD( pisid->IdentifierAuthority.Value[1],\r
+         pisid->IdentifierAuthority.Value[0] ),\r
+         MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],\r
+         pisid->IdentifierAuthority.Value[4] ),\r
+         MAKEWORD( pisid->IdentifierAuthority.Value[3],\r
+         pisid->IdentifierAuthority.Value[2] ) ),\r
+         MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),\r
+         MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),\r
+         MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );\r
+        if( psid )\r
+            LocalFree( psid );\r
+    }\r
+}\r
+\r
+void test_trustee()\r
+{\r
+    TRUSTEE trustee;\r
+    PSID psid;\r
+    LPSTR str = "2jjj";\r
+\r
+    SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };\r
+\r
+    pBuildTrusteeWithSidA = (fnBuildTrusteeWithSidA)\r
+                    GetProcAddress( hmod, "BuildTrusteeWithSidA" );\r
+    pBuildTrusteeWithNameA = (fnBuildTrusteeWithNameA)\r
+                    GetProcAddress( hmod, "BuildTrusteeWithNameA" );\r
+    if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA)\r
+        return;\r
+\r
+    if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )\r
+    {\r
+        trace( "failed to init SID\n" );\r
+       return;\r
+    }\r
+\r
+    memset( &trustee, 0xff, sizeof trustee );\r
+    pBuildTrusteeWithSidA( &trustee, psid );\r
+\r
+    ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");\r
+    ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, \r
+        "MultipleTrusteeOperation wrong\n");\r
+    ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");\r
+    ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");\r
+    ok( trustee.ptstrName == (LPSTR) psid, "ptstrName wrong\n" );\r
+    FreeSid( psid );\r
+\r
+    /* test BuildTrusteeWithNameA */\r
+    memset( &trustee, 0xff, sizeof trustee );\r
+    pBuildTrusteeWithNameA( &trustee, str );\r
+\r
+    ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");\r
+    ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, \r
+        "MultipleTrusteeOperation wrong\n");\r
+    ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");\r
+    ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");\r
+    ok( trustee.ptstrName == str, "ptstrName wrong\n" );\r
+}\r
\r
+/* If the first isn't defined, assume none is */\r
+#ifndef SE_MIN_WELL_KNOWN_PRIVILEGE\r
+#define SE_MIN_WELL_KNOWN_PRIVILEGE       2L\r
+#define SE_CREATE_TOKEN_PRIVILEGE         2L\r
+#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE   3L\r
+#define SE_LOCK_MEMORY_PRIVILEGE          4L\r
+#define SE_INCREASE_QUOTA_PRIVILEGE       5L\r
+#define SE_MACHINE_ACCOUNT_PRIVILEGE      6L\r
+#define SE_TCB_PRIVILEGE                  7L\r
+#define SE_SECURITY_PRIVILEGE             8L\r
+#define SE_TAKE_OWNERSHIP_PRIVILEGE       9L\r
+#define SE_LOAD_DRIVER_PRIVILEGE         10L\r
+#define SE_SYSTEM_PROFILE_PRIVILEGE      11L\r
+#define SE_SYSTEMTIME_PRIVILEGE          12L\r
+#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L\r
+#define SE_INC_BASE_PRIORITY_PRIVILEGE   14L\r
+#define SE_CREATE_PAGEFILE_PRIVILEGE     15L\r
+#define SE_CREATE_PERMANENT_PRIVILEGE    16L\r
+#define SE_BACKUP_PRIVILEGE              17L\r
+#define SE_RESTORE_PRIVILEGE             18L\r
+#define SE_SHUTDOWN_PRIVILEGE            19L\r
+#define SE_DEBUG_PRIVILEGE               20L\r
+#define SE_AUDIT_PRIVILEGE               21L\r
+#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE  22L\r
+#define SE_CHANGE_NOTIFY_PRIVILLEGE      23L\r
+#define SE_REMOTE_SHUTDOWN_PRIVILEGE     24L\r
+#define SE_UNDOCK_PRIVILEGE              25L\r
+#define SE_SYNC_AGENT_PRIVILEGE          26L\r
+#define SE_ENABLE_DELEGATION_PRIVILEGE   27L\r
+#define SE_MANAGE_VOLUME_PRIVILEGE       28L\r
+#define SE_IMPERSONATE_PRIVILEGE         29L\r
+#define SE_CREATE_GLOBAL_PRIVILEGE       30L\r
+#define SE_MAX_WELL_KNOWN_PRIVILEGE      SE_CREATE_GLOBAL_PRIVILEGE\r
+#endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */\r
+\r
+static void test_allocateLuid(void)\r
+{\r
+    BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);\r
+    LUID luid1, luid2;\r
+    BOOL ret;\r
+\r
+    pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");\r
+    if (!pAllocateLocallyUniqueId) return;\r
+\r
+    ret = pAllocateLocallyUniqueId(&luid1);\r
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)\r
+        return;\r
+\r
+    ok(ret,\r
+     "AllocateLocallyUniqueId failed: %ld\n", GetLastError());\r
+    ret = pAllocateLocallyUniqueId(&luid2);\r
+    ok( ret,\r
+     "AllocateLocallyUniqueId failed: %ld\n", GetLastError());\r
+    ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,\r
+     "AllocateLocallyUniqueId returned a well-known LUID\n");\r
+    ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,\r
+     "AllocateLocallyUniqueId returned non-unique LUIDs\n");\r
+    ret = pAllocateLocallyUniqueId(NULL);\r
+    ok( !ret && GetLastError() == ERROR_NOACCESS,\r
+     "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",\r
+     GetLastError());\r
+}\r
+\r
+static void test_lookupPrivilegeName(void)\r
+{\r
+    BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);\r
+    char buf[MAX_PATH]; /* arbitrary, seems long enough */\r
+    DWORD cchName = sizeof(buf);\r
+    LUID luid = { 0, 0 };\r
+    LONG i;\r
+    BOOL ret;\r
+\r
+    /* check whether it's available first */\r
+    pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");\r
+    if (!pLookupPrivilegeNameA) return;\r
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;\r
+    ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);\r
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)\r
+        return;\r
+\r
+    /* check with a short buffer */\r
+    cchName = 0;\r
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;\r
+    ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);\r
+    ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,\r
+     "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",\r
+     GetLastError());\r
+    ok(cchName == strlen("SeCreateTokenPrivilege") + 1,\r
+     "LookupPrivilegeNameA returned an incorrect required length for\n"\r
+     "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,\r
+     strlen("SeCreateTokenPrivilege") + 1);\r
+    /* check a known value and its returned length on success */\r
+    cchName = sizeof(buf);\r
+    ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&\r
+     cchName == strlen("SeCreateTokenPrivilege"),\r
+     "LookupPrivilegeNameA returned an incorrect output length for\n"\r
+     "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,\r
+     (int)strlen("SeCreateTokenPrivilege"));\r
+    /* check known values */\r
+    for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)\r
+    {\r
+        luid.LowPart = i;\r
+        cchName = sizeof(buf);\r
+        ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);\r
+        ok( ret && GetLastError() != ERROR_NO_SUCH_PRIVILEGE,\r
+         "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());\r
+    }\r
+    /* check a bogus LUID */\r
+    luid.LowPart = 0xdeadbeef;\r
+    cchName = sizeof(buf);\r
+    ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);\r
+    ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,\r
+     "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",\r
+     GetLastError());\r
+    /* check on a bogus system */\r
+    luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;\r
+    cchName = sizeof(buf);\r
+    ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);\r
+    ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,\r
+     "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",\r
+     GetLastError());\r
+}\r
+\r
+struct NameToLUID\r
+{\r
+    const char *name;\r
+    DWORD lowPart;\r
+};\r
+\r
+static void test_lookupPrivilegeValue(void)\r
+{\r
+    static const struct NameToLUID privs[] = {\r
+     { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },\r
+     { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },\r
+     { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },\r
+     { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },\r
+     { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },\r
+     { "SeTcbPrivilege", SE_TCB_PRIVILEGE },\r
+     { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },\r
+     { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },\r
+     { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },\r
+     { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },\r
+     { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },\r
+     { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },\r
+     { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },\r
+     { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },\r
+     { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },\r
+     { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },\r
+     { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },\r
+     { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },\r
+     { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },\r
+     { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },\r
+     { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },\r
+     { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },\r
+     { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },\r
+     { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },\r
+     { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },\r
+     { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },\r
+     { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },\r
+     { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },\r
+     { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },\r
+    };\r
+    BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);\r
+    int i;\r
+    LUID luid;\r
+    BOOL ret;\r
+\r
+    /* check whether it's available first */\r
+    pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");\r
+    if (!pLookupPrivilegeValueA) return;\r
+    ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);\r
+    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)\r
+        return;\r
+\r
+    /* check a bogus system name */\r
+    ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);\r
+    ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,\r
+     "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",\r
+     GetLastError());\r
+    /* check a NULL string */\r
+    ret = pLookupPrivilegeValueA(NULL, 0, &luid);\r
+    ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,\r
+     "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",\r
+     GetLastError());\r
+    /* check a bogus privilege name */\r
+    ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);\r
+    ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,\r
+     "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",\r
+     GetLastError());\r
+    /* check case insensitive */\r
+    ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);\r
+    ok( ret,\r
+     "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",\r
+     GetLastError());\r
+    for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)\r
+    {\r
+        /* Not all privileges are implemented on all Windows versions, so\r
+         * don't worry if the call fails\r
+         */\r
+        if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))\r
+        {\r
+            ok(luid.LowPart == privs[i].lowPart,\r
+             "LookupPrivilegeValueA returned an invalid LUID for %s\n",\r
+             privs[i].name);\r
+        }\r
+    }\r
+}\r
+\r
+static void test_luid(void)\r
+{\r
+    test_allocateLuid();\r
+    test_lookupPrivilegeName();\r
+    test_lookupPrivilegeValue();\r
+}\r
+\r
+START_TEST(security)\r
+{\r
+    init();\r
+    if (!hmod) return;\r
+    test_sid();\r
+    test_trustee();\r
+    test_luid();\r
+}\r
diff --git a/reactos/lib/advapi32/winetests/testlist.c b/reactos/lib/advapi32/winetests/testlist.c
new file mode 100644 (file)
index 0000000..cbf5d79
--- /dev/null
@@ -0,0 +1,37 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+/* stdarg.h is needed for Winelib */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+
+extern void func_crypt(void);
+extern void func_crypt_lmhash(void);
+extern void func_crypt_md4(void);
+extern void func_crypt_md5(void);
+extern void func_crypt_sha(void);
+extern void func_registry(void);
+extern void func_security(void);
+
+struct test
+{
+    const char *name;
+    void (*func)(void);
+};
+
+static const struct test winetest_testlist[] =
+{
+    { "crypt", func_crypt },
+    { "crypt_lmhash", func_crypt_lmhash },
+    { "crypt_md4", func_crypt_md4 },
+    { "crypt_md5", func_crypt_md5 },
+    { "crypt_sha", func_crypt_sha },
+    { "registry", func_registry },
+    { "security", func_security },
+    { 0, 0 }
+};
+
+#define WINETEST_WANT_MAIN
+#include "wine/test.h"
index 90eca7d..9ea8766 100644 (file)
 402 stdcall -noname FindMRUStringW(long wstr ptr)\r
 403 stdcall -noname EnumMRUListW(long long ptr long)\r
 404 stdcall -noname CreateMRUListLazyW(ptr long long long)\r
-410 stdcall SetWindowSubclass(long ptr long long)\r
-411 stdcall GetWindowSubclass(long ptr long ptr)\r
-412 stdcall RemoveWindowSubclass(long ptr long)\r
-413 stdcall DefSubclassProc(long long long long)\r
+410 stdcall -noname SetWindowSubclass(long ptr long long)\r
+411 stdcall -noname GetWindowSubclass(long ptr long ptr)\r
+412 stdcall -noname RemoveWindowSubclass(long ptr long)\r
+413 stdcall -noname DefSubclassProc(long long long long)\r
 414 stdcall -noname MirrorIcon(ptr ptr)\r
 415 stdcall DrawTextWrap(long wstr long ptr long) user32.DrawTextW\r
 416 stdcall DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW\r
index 837a9e9..feb479b 100644 (file)
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140\r
 STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE\r
diff --git a/reactos/lib/comctl32/comctl_Sv.rc b/reactos/lib/comctl32/comctl_Sv.rc
new file mode 100644 (file)
index 0000000..cea2d6b
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ * Copyright 2005 Andreas Bjerkeholt\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_SWEDISH, SUBLANG_SWEDISH\r
+\r
+IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140\r
+STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE\r
+CAPTION "Egenskaper för "\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  DEFPUSHBUTTON "OK",     IDOK,4,122,50,14, WS_TABSTOP | WS_GROUP\r
+  PUSHBUTTON    "Avbryt", IDCANCEL,58,122,50,14\r
+  PUSHBUTTON    "&Verkställ", IDC_APPLY_BUTTON,112,122,50,14,WS_DISABLED\r
+  PUSHBUTTON    "Hjälp",   IDHELP,166,122,50,14,WS_TABSTOP|WS_GROUP\r
+  CONTROL       "Tab",    IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS|WS_GROUP|WS_TABSTOP|TCS_MULTILINE,4,4,212,114\r
+END\r
+\r
+\r
+IDD_WIZARD DIALOG DISCARDABLE 0, 0, 290, 159\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE\r
+CAPTION "Guide"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  DEFPUSHBUTTON "Slutför",  IDC_FINISH_BUTTON,121,138,50,14\r
+  DEFPUSHBUTTON "&Nästa >", IDC_NEXT_BUTTON,121,138,50,14\r
+  PUSHBUTTON    "< &Föregående", IDC_BACK_BUTTON,71,138,50,14\r
+  PUSHBUTTON    "Avbryt",  IDCANCEL,178,138,50,14\r
+  PUSHBUTTON    "Hjälp",    IDHELP,235,138,50,14,WS_GROUP\r
+  LTEXT         "",        IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN\r
+  CONTROL       "Tab",     IDC_TABCONTROL,"SysTabControl32",WS_CLIPSIBLINGS | WS_DISABLED,7,7,258,5\r
+  LTEXT                "",        IDC_SUNKEN_LINEHEADER,0,35,290,1,SS_LEFT | SS_SUNKEN | WS_CHILD | WS_VISIBLE\r
+END\r
+\r
+\r
+IDD_TBCUSTOMIZE DIALOG DISCARDABLE 10, 20, 357, 125\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Anpassa verktygsfältet"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  DEFPUSHBUTTON "&Stäng",     IDCANCEL,308,6,44,14\r
+  PUSHBUTTON    "&Återställ",     IDC_RESET_BTN,308,23,44,14\r
+  PUSHBUTTON    "&Hjälp",      IDC_HELP_BTN,308,40,44,14\r
+  PUSHBUTTON    "Flytta &upp",   IDC_MOVEUP_BTN,308,74,44,14\r
+  PUSHBUTTON    "Flytta &ned", IDC_MOVEDN_BTN,308,91,44,14\r
+  LTEXT         "T&illgängliga knappar:", -1,4,5,84,10\r
+  LISTBOX       IDC_AVAILBTN_LBOX,4,17,120,100, LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP\r
+  PUSHBUTTON    "&Lägg till ->",    IDOK, 131, 42, 44, 14\r
+  PUSHBUTTON    "<- &Ta bort", IDC_REMOVE_BTN,131,62,44,14\r
+  LTEXT         "Knappar i v&erktygsfältet:", -1,182,5,85,10\r
+  LISTBOX       IDC_TOOLBARBTN_LBOX, 182,17,120,100,LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDS_CLOSE    "Stäng"\r
+}\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDM_TODAY    "Idag:"\r
+    IDM_GOTODAY  "Gå till idag"\r
+}\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDS_SEPARATOR "Separator"\r
+}\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    HKY_NONE "Ingen"\r
+}\r
index bc1deea..4a9d619 100644 (file)
 \r
 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);\r
 \r
-/* for compiler compatibility we only accept literal ASCII strings */\r
-#undef TEXT\r
-#define TEXT(string) string\r
-\r
 #define DRAGLIST_SUBCLASSID     0\r
 #define DRAGLIST_SCROLLPERIOD 200\r
 #define DRAGLIST_TIMERID      666\r
@@ -95,7 +91,7 @@ static LRESULT DragList_Notify(HWND hwndLB, UINT uNotification)
 }\r
 \r
 /* cleans up after dragging */\r
-static inline void DragList_EndDrag(HWND hwnd, DRAGLISTDATA * data)\r
+static void DragList_EndDrag(HWND hwnd, DRAGLISTDATA * data)\r
 {\r
     KillTimer(hwnd, DRAGLIST_TIMERID);\r
     ReleaseCapture();\r
@@ -207,12 +203,12 @@ DragList_SubclassWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
  */\r
 BOOL WINAPI MakeDragList (HWND hwndLB)\r
 {\r
-    DRAGLISTDATA * data = Alloc(sizeof(DRAGLISTDATA));\r
+    DRAGLISTDATA *data = Alloc(sizeof(DRAGLISTDATA));\r
 \r
     TRACE("(%p)\n", hwndLB);\r
 \r
     if (!uDragListMessage)\r
-        uDragListMessage = RegisterWindowMessageA(DRAGLISTMSGSTRING);\r
+        uDragListMessage = RegisterWindowMessageW(DRAGLISTMSGSTRINGW);\r
 \r
     return SetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR)data);\r
 }\r
@@ -301,14 +297,14 @@ INT WINAPI LBItemFromPt (HWND hwndLB, POINT pt, BOOL bAutoScroll)
 \r
     ScreenToClient (hwndLB, &pt);\r
     GetClientRect (hwndLB, &rcClient);\r
-    nIndex = (INT)SendMessageA (hwndLB, LB_GETTOPINDEX, 0, 0);\r
+    nIndex = (INT)SendMessageW (hwndLB, LB_GETTOPINDEX, 0, 0);\r
 \r
     if (PtInRect (&rcClient, pt))\r
     {\r
         /* point is inside -- get the item index */\r
         while (TRUE)\r
         {\r
-            if (SendMessageA (hwndLB, LB_GETITEMRECT, nIndex, (LPARAM)&rcClient) == LB_ERR)\r
+            if (SendMessageW (hwndLB, LB_GETITEMRECT, nIndex, (LPARAM)&rcClient) == LB_ERR)\r
                 return -1;\r
 \r
             if (PtInRect (&rcClient, pt))\r
@@ -338,7 +334,7 @@ INT WINAPI LBItemFromPt (HWND hwndLB, POINT pt, BOOL bAutoScroll)
 \r
         dwLastScrollTime = dwScrollTime;\r
 \r
-        SendMessageA (hwndLB, LB_SETTOPINDEX, (WPARAM)nIndex, 0);\r
+        SendMessageW (hwndLB, LB_SETTOPINDEX, (WPARAM)nIndex, 0);\r
     }\r
 \r
     return -1;\r
index 03b8084..601a0c8 100644 (file)
@@ -324,9 +324,19 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
            } \r
            else\r
                tx = 0;\r
-           ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, r.left + tx + 2*infoPtr->iMargin,\r
-                            r.top + (r.bottom-r.top-infoPtr->himl->cy)/2, infoPtr->himl->cx, r.bottom-r.top, \r
-                            CLR_DEFAULT, CLR_DEFAULT, 0);\r
+\r
+           if (tx < (r.right-r.left - infoPtr->himl->cx - GetSystemMetrics(SM_CXEDGE)))\r
+               ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, r.left + tx + 2*infoPtr->iMargin,\r
+                                r.top + (r.bottom-r.top-infoPtr->himl->cy)/2, infoPtr->himl->cx, r.bottom-r.top, \r
+                                CLR_DEFAULT, CLR_DEFAULT, 0);\r
+           else {\r
+               INT x = max(r.right - infoPtr->iMargin - infoPtr->himl->cx, r.left);\r
+               INT cx = min(infoPtr->himl->cx, r.right-r.left - GetSystemMetrics(SM_CXEDGE));\r
+               ImageList_DrawEx(infoPtr->himl, phdi->iImage, hdc, x ,\r
+                                r.top + (r.bottom-r.top-infoPtr->himl->cy)/2, cx, r.bottom-r.top, \r
+                                CLR_DEFAULT, CLR_DEFAULT, 0);  \r
+               r.right -= infoPtr->himl->cx - infoPtr->iMargin;\r
+           }\r
        }       \r
 \r
         if (((phdi->fmt & HDF_STRING)\r
@@ -1203,10 +1213,8 @@ HEADER_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
       {\r
        lpItem->iOrder = phdi->iOrder;\r
       }\r
-    else\r
-      lpItem->iOrder = nItem;\r
 \r
-       HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGEDA, nItem, phdi->mask);\r
+    HEADER_SendHeaderNotify (hwnd, HDN_ITEMCHANGEDA, nItem, phdi->mask);\r
 \r
     HEADER_SetItemBounds (hwnd);\r
 \r
@@ -1270,10 +1278,8 @@ HEADER_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
       {\r
        lpItem->iOrder = phdi->iOrder;\r
       }\r
-    else\r
-      lpItem->iOrder = nItem;\r
 \r
-       HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask);\r
+    HEADER_SendHeaderNotify(hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask);\r
 \r
     HEADER_SetItemBounds (hwnd);\r
 \r
index 37f7def..db098b2 100644 (file)
@@ -1577,84 +1577,28 @@ ImageList_GetImageRect (HIMAGELIST himl, INT i, LPRECT lpRect)
  *\r
  * Creates an image list from a bitmap, icon or cursor.\r
  *\r
- * PARAMS\r
- *     hi      [I] instance handle\r
- *     lpbmp   [I] name or id of the image\r
- *     cx      [I] width of each image\r
- *     cGrow   [I] number of images to expand\r
- *     clrMask [I] mask color\r
- *     uType   [I] type of image to load\r
- *     uFlags  [I] loading flags\r
- *\r
- * RETURNS\r
- *     Success: handle to the loaded image list\r
- *     Failure: NULL\r
- *\r
  * SEE\r
- *     LoadImage ()\r
+ *     ImageList_LoadImageW ()\r
  */\r
 \r
 HIMAGELIST WINAPI\r
 ImageList_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow,\r
                        COLORREF clrMask, UINT uType, UINT uFlags)\r
 {\r
-    HIMAGELIST himl = NULL;\r
-    HANDLE   handle;\r
-    INT      nImageCount;\r
-\r
-    handle = LoadImageA (hi, lpbmp, uType, 0, 0, uFlags);\r
-    if (!handle) {\r
-        ERR("Error loading image!\n");\r
-        return NULL;\r
-    }\r
-\r
-    if (uType == IMAGE_BITMAP) {\r
-        BITMAP bmp;\r
-        GetObjectA (handle, sizeof(BITMAP), &bmp);\r
-\r
-        /* To match windows behavior, if cx is set to zero and\r
-         the flag DI_DEFAULTSIZE is specified, cx becomes the\r
-         system metric value for icons. If the flag is not specified\r
-         the function sets the size to the height of the bitmap */\r
-        if (cx == 0)\r
-        {\r
-            if (uFlags & DI_DEFAULTSIZE)\r
-                cx = GetSystemMetrics (SM_CXICON);\r
-            else\r
-                cx = bmp.bmHeight;\r
-        }\r
-\r
-        nImageCount = bmp.bmWidth / cx;\r
-\r
-        himl = ImageList_Create (cx, bmp.bmHeight, ILC_MASK | ILC_COLOR,\r
-                                 nImageCount, cGrow);\r
-        if (!himl) {\r
-            DeleteObject (handle);\r
-            return NULL;\r
-        }\r
-        ImageList_AddMasked (himl, (HBITMAP)handle, clrMask);\r
-    }\r
-    else if ((uType == IMAGE_ICON) || (uType == IMAGE_CURSOR)) {\r
-        ICONINFO ii;\r
-        BITMAP bmp;\r
+    HIMAGELIST himl;\r
+    LPWSTR lpbmpW;\r
+    DWORD len;\r
 \r
-        GetIconInfo (handle, &ii);\r
-        GetObjectA (ii.hbmColor, sizeof(BITMAP), (LPVOID)&bmp);\r
-        himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,\r
-                                 ILC_MASK | ILC_COLOR, 1, cGrow);\r
-        if (!himl) {\r
-            DeleteObject (ii.hbmColor);\r
-            DeleteObject (ii.hbmMask);\r
-            DeleteObject (handle);\r
-            return NULL;\r
-        }\r
-        ImageList_Add (himl, ii.hbmColor, ii.hbmMask);\r
-        DeleteObject (ii.hbmColor);\r
-        DeleteObject (ii.hbmMask);\r
-    }\r
+    if (!HIWORD(lpbmp))\r
+        return ImageList_LoadImageW(hi, (LPCWSTR)lpbmp, cx, cGrow, clrMask,\r
+                                    uType, uFlags);\r
 \r
-    DeleteObject (handle);\r
+    len = MultiByteToWideChar(CP_ACP, 0, lpbmp, -1, NULL, 0);\r
+    lpbmpW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));\r
+    MultiByteToWideChar(CP_ACP, 0, lpbmp, -1, lpbmpW, len);\r
 \r
+    himl = ImageList_LoadImageW(hi, lpbmpW, cx, cGrow, clrMask, uType, uFlags);\r
+    HeapFree(GetProcessHeap(), 0, lpbmpW);\r
     return himl;\r
 }\r
 \r
@@ -1683,7 +1627,7 @@ ImageList_LoadImageA (HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow,
 \r
 HIMAGELIST WINAPI\r
 ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,\r
-                       COLORREF clrMask, UINT uType,   UINT uFlags)\r
+                      COLORREF clrMask, UINT uType, UINT uFlags)\r
 {\r
     HIMAGELIST himl = NULL;\r
     HANDLE   handle;\r
@@ -1726,7 +1670,7 @@ ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
         BITMAP bmp;\r
 \r
         GetIconInfo (handle, &ii);\r
-        GetObjectW (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);\r
+        GetObjectW (ii.hbmColor, sizeof(BITMAP), (LPVOID)&bmp);\r
         himl = ImageList_Create (bmp.bmWidth, bmp.bmHeight,\r
                                  ILC_MASK | ILC_COLOR, 1, cGrow);\r
         if (!himl) {\r
index 23875cf..e35c4f5 100644 (file)
@@ -6276,7 +6276,7 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW_INFO *infoPtr, COLORREF clrBk)
        if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);\r
        infoPtr->clrBk = clrBk;\r
        if (clrBk == CLR_NONE)\r
-           infoPtr->hBkBrush = (HBRUSH)GetClassLongW(infoPtr->hwndSelf, GCL_HBRBACKGROUND);\r
+           infoPtr->hBkBrush = (HBRUSH)GetClassLongPtrW(infoPtr->hwndSelf, GCLP_HBRBACKGROUND);\r
        else\r
            infoPtr->hBkBrush = CreateSolidBrush(clrBk);\r
        LISTVIEW_InvalidateList(infoPtr);\r
@@ -8253,6 +8253,7 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE
 \r
                lpColumnInfo->rcHeader.right += dx;\r
                LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx);\r
+               LISTVIEW_UpdateItemSize(infoPtr);\r
                if (uView == LVS_REPORT && is_redrawing(infoPtr))\r
                {\r
                    /* this trick works for left aligned columns only */\r
index b01295b..1b0f4a7 100644 (file)
@@ -134,7 +134,7 @@ typedef struct
 \r
     SIZE    offChild;       /* x,y offset if child is not FIXEDSIZE */\r
     UINT    uMinHeight;\r
-    INT     iRow;           /* row this band assigned to */\r
+    INT     iRow;           /* zero-based index of the row this band assigned to */\r
     UINT    fStatus;        /* status flags, reset only by _Validate */\r
     UINT    fDraw;          /* drawing flags, reset only by _Layout */\r
     UINT    uCDret;         /* last return from NM_CUSTOMDRAW */\r
@@ -360,8 +360,14 @@ static VOID
 REBAR_DumpBandInfo( LPREBARBANDINFOA pB)\r
 {\r
     if( !TRACE_ON(rebar) ) return;\r
-    TRACE("band info: ID=%u, size=%u, child=%p, clrF=0x%06lx, clrB=0x%06lx\n",\r
-         pB->wID, pB->cbSize, pB->hwndChild, pB->clrFore, pB->clrBack);\r
+    TRACE("band info: ");\r
+    if (pB->fMask & RBBIM_ID);\r
+        TRACE("ID=%u, ", pB->wID);\r
+    TRACE("size=%u, child=%p", pB->cbSize, pB->hwndChild);\r
+    if (pB->fMask & RBBIM_COLORS)\r
+        TRACE(", clrF=0x%06lx, clrB=0x%06lx", pB->clrFore, pB->clrBack);\r
+    TRACE("\n");\r
+\r
     TRACE("band info: mask=0x%08x (%s)\n", pB->fMask, REBAR_FmtMask(pB->fMask));\r
     if (pB->fMask & RBBIM_STYLE)\r
        TRACE("band info: style=0x%08x (%s)\n", pB->fStyle, REBAR_FmtStyle(pB->fStyle));\r
@@ -403,8 +409,14 @@ REBAR_DumpBand (REBAR_INFO *iP)
          (iP->NtfUnicode)?"TRUE":"FALSE", (iP->DoRedraw)?"TRUE":"FALSE");\r
     for (i = 0; i < iP->uNumBands; i++) {\r
        pB = &iP->bands[i];\r
-       TRACE("band # %u: ID=%u, child=%p, row=%u, clrF=0x%06lx, clrB=0x%06lx\n",\r
-             i, pB->wID, pB->hwndChild, pB->iRow, pB->clrFore, pB->clrBack);\r
+       TRACE("band # %u:", i);\r
+       if (pB->fMask & RBBIM_ID);\r
+           TRACE(" ID=%u", pB->wID);\r
+       if (pB->fMask & RBBIM_CHILD)\r
+           TRACE(" child=%p", pB->hwndChild);\r
+       if (pB->fMask & RBBIM_COLORS)\r
+           TRACE(" clrF=0x%06lx clrB=0x%06lx", pB->clrFore, pB->clrBack);\r
+       TRACE("\n");\r
        TRACE("band # %u: mask=0x%08x (%s)\n", i, pB->fMask, REBAR_FmtMask(pB->fMask));\r
        if (pB->fMask & RBBIM_STYLE)\r
            TRACE("band # %u: style=0x%08x (%s)\n",\r
@@ -1419,7 +1431,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
          clientcx, clientcy, adjcx, adjcy);\r
     x = initx;\r
     y = inity;\r
-    row = 1;\r
+    row = 0;\r
     cx = 0;\r
     mcy = 0;\r
     rowstart = 0;\r
@@ -1560,7 +1572,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
     }\r
 \r
     if (infoPtr->uNumBands)\r
-        infoPtr->uNumRows = row;\r
+        infoPtr->uNumRows = row + 1;\r
 \r
     /* ******* End Phase 1 - all bands on row at minimum size ******* */\r
 \r
@@ -1583,7 +1595,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
 \r
        /* now adjust all rectangles by using the height found above */\r
        xy = 0;\r
-       row = 1;\r
+       row = 0;\r
        for (i=0; i<infoPtr->uNumBands; i++) {\r
            lpBand = &infoPtr->bands[i];\r
            if (HIDDENBAND(lpBand)) continue;\r
@@ -1759,6 +1771,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
             if( !(lpBand->fDraw&DRAW_LAST_IN_ROW) )\r
                 continue;\r
 \r
+            /* FIXME: this next line is wrong, but fixing it to be inverted causes IE's sidebars to be the wrong size */\r
            if (lpBand->fMask & RBBS_VARIABLEHEIGHT) continue;\r
            if (((INT)lpBand->cyMaxChild < 1) ||\r
                ((INT)lpBand->cyIntegral < 1)) {\r
@@ -1943,7 +1956,7 @@ REBAR_ValidateBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
     infoPtr->fStatus |= BAND_NEEDS_LAYOUT;\r
 \r
     /* Header is where the image, text and gripper exist  */\r
-    /* in the band and preceed the child window.          */\r
+    /* in the band and precede the child window.          */\r
 \r
     /* count number of non-FIXEDSIZE and non-Hidden bands */\r
     nonfixed = 0;\r
index a3adf4c..7261b99 100644 (file)
@@ -1206,5 +1206,6 @@ IDI_TT_ERROR_SM ICON LOADONCALL DISCARDABLE idi_tt_error_sm.ico
 #include "comctl_Pt.rc"\r
 #include "comctl_Ru.rc"\r
 #include "comctl_Si.rc"\r
+#include "comctl_Sv.rc"\r
 #include "comctl_Th.rc"\r
 #include "comctl_Uk.rc"\r
index d5b94c4..bd4898c 100644 (file)
@@ -79,6 +79,9 @@ typedef struct
     BOOL              NtfUnicode;      /* notify format */\r
     STATUSWINDOWPART  part0;           /* simple window */\r
     STATUSWINDOWPART* parts;\r
+    INT               horizontalBorder;\r
+    INT               verticalBorder;\r
+    INT               horizontalGap;\r
 } STATUS_INFO;\r
 \r
 /*\r
@@ -159,28 +162,24 @@ STATUSBAR_DrawPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, int i
 \r
     DrawEdge(hdc, &r, border, BF_RECT|BF_ADJUST);\r
 \r
-    if (part->style & SBT_OWNERDRAW)\r
-       {\r
-           DRAWITEMSTRUCT dis;\r
-\r
-           dis.CtlID = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);\r
-           dis.itemID = itemID;\r
-           dis.hwndItem = infoPtr->Self;\r
-           dis.hDC = hdc;\r
-           dis.rcItem = r;\r
-           dis.itemData = (INT)part->text;\r
-           SendMessageW (infoPtr->Notify, WM_DRAWITEM, (WPARAM)dis.CtlID, (LPARAM)&dis);\r
-    }\r
-    else\r
-       {\r
-           if (part->hIcon)\r
-               {\r
-               INT cy = r.bottom - r.top;\r
-\r
-               r.left += 2;\r
-               DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);\r
-               r.left += cy;\r
-               }\r
+    if (part->style & SBT_OWNERDRAW) {\r
+       DRAWITEMSTRUCT dis;\r
+\r
+       dis.CtlID = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);\r
+       dis.itemID = itemID;\r
+       dis.hwndItem = infoPtr->Self;\r
+       dis.hDC = hdc;\r
+       dis.rcItem = r;\r
+       dis.itemData = (INT)part->text;\r
+       SendMessageW (infoPtr->Notify, WM_DRAWITEM, (WPARAM)dis.CtlID, (LPARAM)&dis);\r
+    } else {\r
+       if (part->hIcon) {\r
+          INT cy = r.bottom - r.top;\r
+\r
+           r.left += 2;\r
+           DrawIconEx (hdc, r.left, r.top, part->hIcon, cy, cy, 0, 0, DI_NORMAL);\r
+           r.left += cy;\r
+       }\r
         DrawStatusTextW (hdc, &r, part->text, SBT_NOBORDERS);\r
     }\r
 }\r
@@ -213,12 +212,11 @@ STATUSBAR_RefreshPart (STATUS_INFO *infoPtr, HDC hdc, STATUSWINDOWPART *part, in
     if (infoPtr->clrBk != CLR_DEFAULT)\r
            DeleteObject (hbrBk);\r
 \r
-    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP)\r
-       {\r
-           RECT rect;\r
+    if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & SBARS_SIZEGRIP) {\r
+        RECT rect;\r
 \r
-           GetClientRect (infoPtr->Self, &rect);\r
-           STATUSBAR_DrawSizeGrip (hdc, &rect);\r
+       GetClientRect (infoPtr->Self, &rect);\r
+       STATUSBAR_DrawSizeGrip (hdc, &rect);\r
     }\r
 }\r
 \r
@@ -240,19 +238,19 @@ STATUSBAR_Refresh (STATUS_INFO *infoPtr, HDC hdc)
     GetClientRect (infoPtr->Self, &rect);\r
 \r
     if (infoPtr->clrBk != CLR_DEFAULT)\r
-           hbrBk = CreateSolidBrush (infoPtr->clrBk);\r
+       hbrBk = CreateSolidBrush (infoPtr->clrBk);\r
     else\r
-           hbrBk = GetSysColorBrush (COLOR_3DFACE);\r
+       hbrBk = GetSysColorBrush (COLOR_3DFACE);\r
     FillRect(hdc, &rect, hbrBk);\r
 \r
     hOldFont = SelectObject (hdc, infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont);\r
 \r
     if (infoPtr->simple) {\r
-           STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->part0, 0);\r
+       STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->part0, 0);\r
     } else {\r
-           for (i = 0; i < infoPtr->numParts; i++) {\r
-                   STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->parts[i], i);\r
-           }\r
+       for (i = 0; i < infoPtr->numParts; i++) {\r
+           STATUSBAR_RefreshPart (infoPtr, hdc, &infoPtr->parts[i], i);\r
+       }\r
     }\r
 \r
     SelectObject (hdc, hOldFont);\r
@@ -278,7 +276,8 @@ STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr)
     GetClientRect (infoPtr->Self, &rect);\r
     TRACE("client wnd size is %ld,%ld - %ld,%ld\n", rect.left, rect.top, rect.right, rect.bottom);\r
 \r
-    rect.top += VERT_BORDER;\r
+    rect.left += infoPtr->horizontalBorder;\r
+    rect.top += infoPtr->verticalBorder;\r
 \r
     /* set bounds for simple rectangle */\r
     infoPtr->part0.bound = rect;\r
@@ -292,7 +291,7 @@ STATUSBAR_SetPartBounds (STATUS_INFO *infoPtr)
        if (i == 0)\r
            r->left = 0;\r
        else\r
-           r->left = infoPtr->parts[i-1].bound.right + HORZ_GAP;\r
+           r->left = infoPtr->parts[i-1].bound.right + infoPtr->horizontalGap;\r
        if (part->x == -1)\r
            r->right = rect.right;\r
        else\r
@@ -331,12 +330,25 @@ STATUSBAR_Relay2Tip (STATUS_INFO *infoPtr, UINT uMsg,
 \r
 \r
 static BOOL\r
-STATUSBAR_GetBorders (INT out[])\r
+STATUSBAR_GetBorders (STATUS_INFO *infoPtr, INT out[])\r
+{\r
+    TRACE("\n");\r
+    out[0] = infoPtr->horizontalBorder;\r
+    out[1] = infoPtr->verticalBorder;\r
+    out[2] = infoPtr->horizontalGap;\r
+\r
+    return TRUE;\r
+}\r
+\r
+\r
+static BOOL\r
+STATUSBAR_SetBorders (STATUS_INFO *infoPtr, INT in[])\r
 {\r
     TRACE("\n");\r
-    out[0] = HORZ_BORDER; /* horizontal border width */\r
-    out[1] = VERT_BORDER; /* vertical border width */\r
-    out[2] = HORZ_GAP; /* width of border between rectangles */\r
+    infoPtr->horizontalBorder = in[0];\r
+    infoPtr->verticalBorder = in[1];\r
+    infoPtr->horizontalGap = in[2];\r
+    InvalidateRect(infoPtr->Self, NULL, FALSE);\r
 \r
     return TRUE;\r
 }\r
@@ -560,13 +572,13 @@ STATUSBAR_SetMinHeight (STATUS_INFO *infoPtr, INT height)
        RECT parent_rect;\r
 \r
        GetClientRect (infoPtr->Notify, &parent_rect);\r
-       infoPtr->height = height + VERT_BORDER;\r
+       infoPtr->height = height + infoPtr->verticalBorder;\r
        width = parent_rect.right - parent_rect.left;\r
        x = parent_rect.left;\r
        y = parent_rect.bottom - infoPtr->height;\r
        MoveWindow (infoPtr->Self, parent_rect.left,\r
-                     parent_rect.bottom - infoPtr->height,\r
-                     width, infoPtr->height, TRUE);\r
+                   parent_rect.bottom - infoPtr->height,\r
+                   width, infoPtr->height, TRUE);\r
        STATUSBAR_SetPartBounds (infoPtr);\r
     }\r
 \r
@@ -728,8 +740,7 @@ STATUSBAR_SetTipTextA (STATUS_INFO *infoPtr, INT id, LPSTR text)
        ti.uId = id;\r
        ti.hinst = 0;\r
        ti.lpszText = text;\r
-       SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,\r
-                       0, (LPARAM)&ti);\r
+       SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA, 0, (LPARAM)&ti);\r
     }\r
 \r
     return 0;\r
@@ -747,8 +758,7 @@ STATUSBAR_SetTipTextW (STATUS_INFO *infoPtr, INT id, LPWSTR text)
        ti.uId = id;\r
        ti.hinst = 0;\r
        ti.lpszText = text;\r
-       SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW,\r
-                       0, (LPARAM)&ti);\r
+       SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);\r
     }\r
 \r
     return 0;\r
@@ -838,6 +848,9 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
     infoPtr->simple = FALSE;\r
     infoPtr->clrBk = CLR_DEFAULT;\r
     infoPtr->hFont = 0;\r
+    infoPtr->horizontalBorder = HORZ_BORDER;\r
+    infoPtr->verticalBorder = VERT_BORDER;\r
+    infoPtr->horizontalGap = HORZ_GAP;\r
 \r
     i = SendMessageW(infoPtr->Notify, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);\r
     infoPtr->NtfUnicode = (i == NFR_UNICODE);\r
@@ -929,7 +942,7 @@ STATUSBAR_WMCreate (HWND hwnd, LPCREATESTRUCTA lpCreate)
     if (!(dwStyle & CCS_NORESIZE)) { /* don't resize wnd if it doesn't want it ! */\r
         GetClientRect (infoPtr->Notify, &rect);\r
         width = rect.right - rect.left;\r
-        infoPtr->height = textHeight + 4 + VERT_BORDER;\r
+        infoPtr->height = textHeight + 4 + infoPtr->verticalBorder;\r
         SetWindowPos(hwnd, 0, lpCreate->x, lpCreate->y - 1,\r
                        width, infoPtr->height, SWP_NOZORDER);\r
         STATUSBAR_SetPartBounds (infoPtr);\r
@@ -1069,8 +1082,7 @@ STATUSBAR_WMSize (STATUS_INFO *infoPtr, WORD flags)
     /* Need to resize width to match parent */\r
     TRACE("flags %04x\n", flags);\r
 \r
-    if (flags != SIZE_RESTORED && flags != SIZE_MAXIMIZED)\r
-    {\r
+    if (flags != SIZE_RESTORED && flags != SIZE_MAXIMIZED) {\r
        WARN("flags MUST be SIZE_RESTORED or SIZE_MAXIMIZED\n");\r
        return FALSE;\r
     }\r
@@ -1129,7 +1141,7 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 \r
     switch (msg) {\r
        case SB_GETBORDERS:\r
-           return STATUSBAR_GetBorders ((INT *)lParam);\r
+           return STATUSBAR_GetBorders (infoPtr, (INT *)lParam);\r
 \r
        case SB_GETICON:\r
            return (LRESULT)STATUSBAR_GetIcon (infoPtr, nPart);\r
@@ -1162,6 +1174,9 @@ StatusWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        case SB_ISSIMPLE:\r
            return infoPtr->simple;\r
 \r
+       case SB_SETBORDERS:\r
+           return STATUSBAR_SetBorders (infoPtr, (INT *)lParam);\r
+\r
        case SB_SETBKCOLOR:\r
            return STATUSBAR_SetBkColor (infoPtr, (COLORREF)lParam);\r
 \r
index e5f28ab..b9aa285 100644 (file)
@@ -421,7 +421,7 @@ INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
 /**************************************************************************\r
  * StrRChrA [COMCTL32.351]\r
  *\r
- * Find the last occurence of a character in string.\r
+ * Find the last occurrence of a character in string.\r
  *\r
  * PARAMS\r
  *  lpszStr [I] String to search in\r
@@ -572,7 +572,7 @@ LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
 /*************************************************************************\r
  * StrRStrIA   [COMCTL32.372]\r
  *\r
- * Find the last occurence of a substring within a string.\r
+ * Find the last occurrence of a substring within a string.\r
  *\r
  * PARAMS\r
  *  lpszStr    [I] String to search in\r
@@ -580,7 +580,7 @@ LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
  *  lpszSearch [I] String to look for\r
  *\r
  * RETURNS\r
- *  The last occurence lpszSearch within lpszStr, or NULL if not found.\r
+ *  The last occurrence lpszSearch within lpszStr, or NULL if not found.\r
  */\r
 LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)\r
 {\r
@@ -709,7 +709,7 @@ int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
 /**************************************************************************\r
  * StrRChrIA   [COMCTL32.368]\r
  *\r
- * Find the last occurence of a character in string, ignoring case.\r
+ * Find the last occurrence of a character in string, ignoring case.\r
  *\r
  * PARAMS\r
  *  lpszStr [I] String to search in\r
index 3567c96..34402f3 100644 (file)
@@ -513,7 +513,7 @@ static VOID SYSLINK_RepaintLink (SYSLINK_INFO *infoPtr, PDOC_ITEM DocItem)
 \r
 /***********************************************************************\r
  * SYSLINK_GetLinkItemByIndex\r
- * Retreives a document link by it's index\r
+ * Retrieves a document link by its index\r
  */\r
 static PDOC_ITEM SYSLINK_GetLinkItemByIndex (SYSLINK_INFO *infoPtr, int iLink)\r
 {\r
@@ -532,7 +532,7 @@ static PDOC_ITEM SYSLINK_GetLinkItemByIndex (SYSLINK_INFO *infoPtr, int iLink)
 \r
 /***********************************************************************\r
  * SYSLINK_GetFocusLink\r
- * Retreives the link that has the LIS_FOCUSED bit\r
+ * Retrieves the link that has the LIS_FOCUSED bit\r
  */\r
 static PDOC_ITEM SYSLINK_GetFocusLink (SYSLINK_INFO *infoPtr, int *LinkId)\r
 {\r
index a4b843c..8fb27e8 100644 (file)
@@ -59,7 +59,7 @@ typedef struct
                      * leftmost item (the leftmost item, 0, would have a\r
                      * "left" member of 0 in this rectangle)\r
                      *\r
-                     * additionally the top member hold the row number\r
+                     * additionally the top member holds the row number\r
                      * and bottom is unused and should be 0 */\r
   BYTE   extra[1];  /* Space for caller supplied info, variable size */\r
 } TAB_ITEM;\r
@@ -69,6 +69,7 @@ typedef struct
 \r
 typedef struct\r
 {\r
+  HWND       hwnd;            /* Tab control window */\r
   HWND       hwndNotify;      /* notification window (parent) */\r
   UINT       uNumItem;        /* number of tab items */\r
   UINT       uNumRows;       /* number of tab rows */\r
@@ -126,20 +127,17 @@ typedef struct
 /******************************************************************************\r
  * Prototypes\r
  */\r
-static void TAB_Refresh (HWND hwnd, HDC hdc);\r
-static void TAB_InvalidateTabArea(HWND hwnd, TAB_INFO* infoPtr);\r
-static void TAB_EnsureSelectionVisible(HWND hwnd, TAB_INFO* infoPtr);\r
-static void TAB_DrawItem(HWND hwnd, HDC hdc, INT iItem);\r
-static void TAB_DrawItemInterior(HWND hwnd, HDC hdc, INT iItem, RECT* drawRect);\r
+static void TAB_InvalidateTabArea(TAB_INFO *);\r
+static void TAB_EnsureSelectionVisible(TAB_INFO *);\r
+static void TAB_DrawItemInterior(TAB_INFO *, HDC, INT, RECT*);\r
 \r
 static BOOL\r
-TAB_SendSimpleNotify (HWND hwnd, UINT code)\r
+TAB_SendSimpleNotify (const TAB_INFO *infoPtr, UINT code)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
     NMHDR nmhdr;\r
 \r
-    nmhdr.hwndFrom = hwnd;\r
-    nmhdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);\r
+    nmhdr.hwndFrom = infoPtr->hwnd;\r
+    nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);\r
     nmhdr.code = code;\r
 \r
     return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,\r
@@ -203,11 +201,8 @@ TAB_DumpItemInternal(TAB_INFO *infoPtr, UINT iItem)
 \r
 /* RETURNS\r
  *   the index of the selected tab, or -1 if no tab is selected. */\r
-static LRESULT\r
-TAB_GetCurSel (HWND hwnd)\r
+static inline LRESULT TAB_GetCurSel (const TAB_INFO *infoPtr)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
     return infoPtr->iSelected;\r
 }\r
 \r
@@ -217,10 +212,9 @@ TAB_GetCurSel (HWND hwnd)
  *   we have not to return negative value\r
  * TODO\r
  *   test for windows */\r
-static LRESULT\r
-TAB_GetCurFocus (HWND hwnd)\r
+static inline LRESULT\r
+TAB_GetCurFocus (const TAB_INFO *infoPtr)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
     if (infoPtr->uFocus<0)\r
     {\r
         FIXME("we have not to return negative value");\r
@@ -229,79 +223,66 @@ TAB_GetCurFocus (HWND hwnd)
     return infoPtr->uFocus;\r
 }\r
 \r
-static LRESULT\r
-TAB_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_GetToolTips (const TAB_INFO *infoPtr)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
     if (infoPtr == NULL) return 0;\r
     return (LRESULT)infoPtr->hwndToolTip;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetCurSel (HWND hwnd,WPARAM wParam)\r
+static inline LRESULT TAB_SetCurSel (TAB_INFO *infoPtr, INT iItem)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  INT iItem = (INT)wParam;\r
-  INT prevItem;\r
+  INT prevItem = -1;\r
 \r
-  prevItem = -1;\r
-  if ((iItem >= 0) && (iItem < infoPtr->uNumItem)) {\r
-    prevItem=infoPtr->iSelected;\r
+  if (iItem >= 0 && iItem < infoPtr->uNumItem) {\r
+      prevItem=infoPtr->iSelected;\r
       infoPtr->iSelected=iItem;\r
-      TAB_EnsureSelectionVisible(hwnd, infoPtr);\r
-      TAB_InvalidateTabArea(hwnd, infoPtr);\r
+      TAB_EnsureSelectionVisible(infoPtr);\r
+      TAB_InvalidateTabArea(infoPtr);\r
   }\r
   return prevItem;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetCurFocus (HWND hwnd,WPARAM wParam)\r
+static LRESULT TAB_SetCurFocus (TAB_INFO *infoPtr, INT iItem)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  INT iItem=(INT) wParam;\r
-\r
-  if ((iItem < 0) || (iItem >= infoPtr->uNumItem)) return 0;\r
+  if (iItem < 0 || iItem >= infoPtr->uNumItem) return 0;\r
 \r
-  if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS) {\r
+  if (GetWindowLongA(infoPtr->hwnd, GWL_STYLE) & TCS_BUTTONS) {\r
     FIXME("Should set input focus\n");\r
   } else {\r
     int oldFocus = infoPtr->uFocus;\r
     if (infoPtr->iSelected != iItem || oldFocus == -1 ) {\r
       infoPtr->uFocus = iItem;\r
       if (oldFocus != -1) {\r
-        if (!TAB_SendSimpleNotify(hwnd, TCN_SELCHANGING))  {\r
+        if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))  {\r
           infoPtr->iSelected = iItem;\r
-          TAB_SendSimpleNotify(hwnd, TCN_SELCHANGE);\r
+          TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);\r
         }\r
         else\r
           infoPtr->iSelected = iItem;\r
-        TAB_EnsureSelectionVisible(hwnd, infoPtr);\r
-        TAB_InvalidateTabArea(hwnd, infoPtr);\r
+        TAB_EnsureSelectionVisible(infoPtr);\r
+        TAB_InvalidateTabArea(infoPtr);\r
       }\r
     }\r
   }\r
   return 0;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_SetToolTips (TAB_INFO *infoPtr, HWND hwndToolTip)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
-    if (infoPtr == NULL) return 0;\r
-    infoPtr->hwndToolTip = (HWND)wParam;\r
+    if (infoPtr)\r
+        infoPtr->hwndToolTip = hwndToolTip;\r
     return 0;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_SetPadding (TAB_INFO *infoPtr, LPARAM lParam)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-    \r
-    if (infoPtr == NULL) return 0;\r
-    infoPtr->uHItemPadding_s=LOWORD(lParam);\r
-    infoPtr->uVItemPadding_s=HIWORD(lParam);\r
+    if (infoPtr)\r
+    {\r
+        infoPtr->uHItemPadding_s=LOWORD(lParam);\r
+        infoPtr->uVItemPadding_s=HIWORD(lParam);\r
+    }\r
     return 0;\r
 }\r
 \r
@@ -315,14 +296,13 @@ TAB_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam)
  * if it is completely outside the client area.\r
  */\r
 static BOOL TAB_InternalGetItemRect(\r
-  HWND        hwnd,\r
-  TAB_INFO*   infoPtr,\r
+  const TAB_INFO* infoPtr,\r
   INT         itemIndex,\r
   RECT*       itemRect,\r
   RECT*       selectedRect)\r
 {\r
   RECT tmpItemRect,clientRect;\r
-  LONG        lStyle  = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
 \r
   /* Perform a sanity check and a trivial visibility check. */\r
   if ( (infoPtr->uNumItem <= 0) ||\r
@@ -341,7 +321,7 @@ static BOOL TAB_InternalGetItemRect(
   *itemRect = TAB_GetItem(infoPtr,itemIndex)->rect;\r
 \r
   /* calculate the times bottom and top based on the row */\r
-  GetClientRect(hwnd, &clientRect);\r
+  GetClientRect(infoPtr->hwnd, &clientRect);\r
 \r
   if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))\r
   {\r
@@ -440,10 +420,10 @@ static BOOL TAB_InternalGetItemRect(
   return TRUE;\r
 }\r
 \r
-static BOOL TAB_GetItemRect(HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline BOOL\r
+TAB_GetItemRect(TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)\r
 {\r
-  return TAB_InternalGetItemRect(hwnd, TAB_GetInfoPtr(hwnd), (INT)wParam,\r
-                                 (LPRECT)lParam, (LPRECT)NULL);\r
+  return TAB_InternalGetItemRect(infoPtr, (INT)wParam, (LPRECT)lParam, (LPRECT)NULL);\r
 }\r
 \r
 /******************************************************************************\r
@@ -451,11 +431,8 @@ static BOOL TAB_GetItemRect(HWND hwnd, WPARAM wParam, LPARAM lParam)
  *\r
  * This method is called to handle keyboard input\r
  */\r
-static LRESULT TAB_KeyUp(\r
-  HWND   hwnd,\r
-  WPARAM keyCode)\r
+static LRESULT TAB_KeyUp(TAB_INFO* infoPtr, WPARAM keyCode)\r
 {\r
-  TAB_INFO* infoPtr = TAB_GetInfoPtr(hwnd);\r
   int       newItem = -1;\r
 \r
   switch (keyCode)\r
@@ -471,18 +448,18 @@ static LRESULT TAB_KeyUp(
   /*\r
    * If we changed to a valid item, change the selection\r
    */\r
-  if ((newItem >= 0) &&\r
-       (newItem < infoPtr->uNumItem) &&\r
-       (infoPtr->uFocus != newItem))\r
+  if (newItem >= 0 &&\r
+      newItem < infoPtr->uNumItem &&\r
+      infoPtr->uFocus != newItem)\r
   {\r
-    if (!TAB_SendSimpleNotify(hwnd, TCN_SELCHANGING))\r
+    if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))\r
     {\r
       infoPtr->iSelected = newItem;\r
       infoPtr->uFocus    = newItem;\r
-      TAB_SendSimpleNotify(hwnd, TCN_SELCHANGE);\r
+      TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);\r
 \r
-      TAB_EnsureSelectionVisible(hwnd, infoPtr);\r
-      TAB_InvalidateTabArea(hwnd, infoPtr);\r
+      TAB_EnsureSelectionVisible(infoPtr);\r
+      TAB_InvalidateTabArea(infoPtr);\r
     }\r
   }\r
 \r
@@ -495,21 +472,15 @@ static LRESULT TAB_KeyUp(
  * This method is called whenever the focus goes in or out of this control\r
  * it is used to update the visual state of the control.\r
  */\r
-static LRESULT TAB_FocusChanging(\r
-  HWND   hwnd,\r
-  UINT   uMsg,\r
-  WPARAM wParam,\r
-  LPARAM lParam)\r
+static VOID TAB_FocusChanging(const TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   RECT      selectedRect;\r
   BOOL      isVisible;\r
 \r
   /*\r
    * Get the rectangle for the item.\r
    */\r
-  isVisible = TAB_InternalGetItemRect(hwnd,\r
-                                     infoPtr,\r
+  isVisible = TAB_InternalGetItemRect(infoPtr,\r
                                      infoPtr->uFocus,\r
                                      NULL,\r
                                      &selectedRect);\r
@@ -523,17 +494,11 @@ static LRESULT TAB_FocusChanging(
       TRACE("invalidate (%ld,%ld)-(%ld,%ld)\n",\r
            selectedRect.left,selectedRect.top,\r
            selectedRect.right,selectedRect.bottom);\r
-    InvalidateRect(hwnd, &selectedRect, TRUE);\r
+    InvalidateRect(infoPtr->hwnd, &selectedRect, TRUE);\r
   }\r
-\r
-  /*\r
-   * Don't otherwise disturb normal behavior.\r
-   */\r
-  return DefWindowProcW (hwnd, uMsg, wParam, lParam);\r
 }\r
 \r
 static INT TAB_InternalHitTest (\r
-  HWND      hwnd,\r
   TAB_INFO* infoPtr,\r
   POINT     pt,\r
   UINT*     flags)\r
@@ -544,7 +509,7 @@ static INT TAB_InternalHitTest (
 \r
   for (iCount = 0; iCount < infoPtr->uNumItem; iCount++)\r
   {\r
-    TAB_InternalGetItemRect(hwnd, infoPtr, iCount, &rect, NULL);\r
+    TAB_InternalGetItemRect(infoPtr, iCount, &rect, NULL);\r
 \r
     if (PtInRect(&rect, pt))\r
     {\r
@@ -557,13 +522,10 @@ static INT TAB_InternalHitTest (
   return -1;\r
 }\r
 \r
-static LRESULT\r
-TAB_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_HitTest (TAB_INFO *infoPtr, LPTCHITTESTINFO lptest)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  LPTCHITTESTINFO lptest = (LPTCHITTESTINFO) lParam;\r
-\r
-  return TAB_InternalHitTest (hwnd, infoPtr, lptest->pt, &lptest->flags);\r
+  return TAB_InternalHitTest (infoPtr, lptest->pt, &lptest->flags);\r
 }\r
 \r
 /******************************************************************************\r
@@ -578,77 +540,75 @@ TAB_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
  * FIXME: WM_NCHITTEST handling correct ? Fix it if you know that Windows\r
  * doesn't do it that way. Maybe depends on tab control styles ?\r
  */\r
-static LRESULT\r
-TAB_NCHitTest (HWND hwnd, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_NCHitTest (TAB_INFO *infoPtr, LPARAM lParam)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   POINT pt;\r
   UINT dummyflag;\r
 \r
   pt.x = LOWORD(lParam);\r
   pt.y = HIWORD(lParam);\r
-  ScreenToClient(hwnd, &pt);\r
+  ScreenToClient(infoPtr->hwnd, &pt);\r
 \r
-  if (TAB_InternalHitTest(hwnd, infoPtr, pt, &dummyflag) == -1)\r
+  if (TAB_InternalHitTest(infoPtr, pt, &dummyflag) == -1)\r
     return HTTRANSPARENT;\r
   else\r
     return HTCLIENT;\r
 }\r
 \r
 static LRESULT\r
-TAB_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   POINT pt;\r
   INT newItem, dummy;\r
 \r
   if (infoPtr->hwndToolTip)\r
-    TAB_RelayEvent (infoPtr->hwndToolTip, hwnd,\r
+    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,\r
                    WM_LBUTTONDOWN, wParam, lParam);\r
 \r
-  if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_FOCUSONBUTTONDOWN ) {\r
-    SetFocus (hwnd);\r
+  if (GetWindowLongA(infoPtr->hwnd, GWL_STYLE) & TCS_FOCUSONBUTTONDOWN ) {\r
+    SetFocus (infoPtr->hwnd);\r
   }\r
 \r
   if (infoPtr->hwndToolTip)\r
-    TAB_RelayEvent (infoPtr->hwndToolTip, hwnd,\r
+    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,\r
                    WM_LBUTTONDOWN, wParam, lParam);\r
 \r
   pt.x = (INT)LOWORD(lParam);\r
   pt.y = (INT)HIWORD(lParam);\r
 \r
-  newItem = TAB_InternalHitTest (hwnd, infoPtr, pt, &dummy);\r
+  newItem = TAB_InternalHitTest (infoPtr, pt, &dummy);\r
 \r
   TRACE("On Tab, item %d\n", newItem);\r
 \r
-  if ((newItem != -1) && (infoPtr->iSelected != newItem))\r
+  if (newItem != -1 && infoPtr->iSelected != newItem)\r
   {\r
-    if (!TAB_SendSimpleNotify(hwnd, TCN_SELCHANGING))\r
+    if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))\r
     {\r
       infoPtr->iSelected = newItem;\r
       infoPtr->uFocus    = newItem;\r
-      TAB_SendSimpleNotify(hwnd, TCN_SELCHANGE);\r
+      TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);\r
 \r
-      TAB_EnsureSelectionVisible(hwnd, infoPtr);\r
+      TAB_EnsureSelectionVisible(infoPtr);\r
 \r
-      TAB_InvalidateTabArea(hwnd, infoPtr);\r
+      TAB_InvalidateTabArea(infoPtr);\r
     }\r
   }\r
   return 0;\r
 }\r
 \r
-static LRESULT\r
-TAB_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_LButtonUp (const TAB_INFO *infoPtr)\r
 {\r
-  TAB_SendSimpleNotify(hwnd, NM_CLICK);\r
+  TAB_SendSimpleNotify(infoPtr, NM_CLICK);\r
 \r
   return 0;\r
 }\r
 \r
-static LRESULT\r
-TAB_RButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT\r
+TAB_RButtonDown (const TAB_INFO *infoPtr)\r
 {\r
-  TAB_SendSimpleNotify(hwnd, NM_RCLICK);\r
+  TAB_SendSimpleNotify(infoPtr, NM_RCLICK);\r
   return 0;\r
 }\r
 \r
@@ -661,20 +621,20 @@ TAB_RButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
  * only calls TAB_DrawItemInterior for the single specified item.\r
  */\r
 static void\r
-TAB_DrawLoneItemInterior(HWND hwnd, TAB_INFO* infoPtr, int iItem)\r
+TAB_DrawLoneItemInterior(TAB_INFO* infoPtr, int iItem)\r
 {\r
-  HDC hdc = GetDC(hwnd);\r
+  HDC hdc = GetDC(infoPtr->hwnd);\r
   RECT r, rC;\r
 \r
   /* Clip UpDown control to not draw over it */\r
   if (infoPtr->needsScrolling)\r
   {\r
-    GetWindowRect(hwnd, &rC);\r
+    GetWindowRect(infoPtr->hwnd, &rC);\r
     GetWindowRect(infoPtr->hwndUpDown, &r);\r
     ExcludeClipRect(hdc, r.left - rC.left, r.top - rC.top, r.right - rC.left, r.bottom - rC.top);\r
   }\r
-  TAB_DrawItemInterior(hwnd, hdc, iItem, NULL);\r
-  ReleaseDC(hwnd, hdc);\r
+  TAB_DrawItemInterior(infoPtr, hdc, iItem, NULL);\r
+  ReleaseDC(infoPtr->hwnd, hdc);\r
 }\r
 \r
 /******************************************************************************\r
@@ -716,7 +676,7 @@ TAB_HotTrackTimerProc
       /* Redraw iHotTracked to look normal */\r
       INT iRedraw = infoPtr->iHotTracked;\r
       infoPtr->iHotTracked = -1;\r
-      TAB_DrawLoneItemInterior(hwnd, infoPtr, iRedraw);\r
+      TAB_DrawLoneItemInterior(infoPtr, iRedraw);\r
 \r
       /* Kill this timer */\r
       KillTimer(hwnd, TAB_HOTTRACK_TIMER);\r
@@ -743,14 +703,12 @@ TAB_HotTrackTimerProc
 static void\r
 TAB_RecalcHotTrack\r
   (\r
-  HWND            hwnd,\r
+  TAB_INFO*       infoPtr,\r
   const LPARAM*   pos,\r
   int*            out_redrawLeave,\r
   int*            out_redrawEnter\r
   )\r
 {\r
-  TAB_INFO* infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
   int item = -1;\r
 \r
 \r
@@ -759,7 +717,7 @@ TAB_RecalcHotTrack
   if (out_redrawEnter != NULL)\r
     *out_redrawEnter = -1;\r
 \r
-  if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_HOTTRACK)\r
+  if (GetWindowLongA(infoPtr->hwnd, GWL_STYLE) & TCS_HOTTRACK)\r
   {\r
     POINT pt;\r
     UINT  flags;\r
@@ -767,7 +725,7 @@ TAB_RecalcHotTrack
     if (pos == NULL)\r
     {\r
       GetCursorPos(&pt);\r
-      ScreenToClient(hwnd, &pt);\r
+      ScreenToClient(infoPtr->hwnd, &pt);\r
     }\r
     else\r
     {\r
@@ -775,7 +733,7 @@ TAB_RecalcHotTrack
       pt.y = HIWORD(*pos);\r
     }\r
 \r
-    item = TAB_InternalHitTest(hwnd, infoPtr, pt, &flags);\r
+    item = TAB_InternalHitTest(infoPtr, pt, &flags);\r
   }\r
 \r
   if (item != infoPtr->iHotTracked)\r
@@ -789,7 +747,7 @@ TAB_RecalcHotTrack
       if (item < 0)\r
       {\r
         /* Kill timer which forces recheck of mouse pos */\r
-        KillTimer(hwnd, TAB_HOTTRACK_TIMER);\r
+        KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);\r
       }\r
     }\r
     else\r
@@ -797,7 +755,7 @@ TAB_RecalcHotTrack
       /* Start timer so we recheck mouse pos */\r
       UINT timerID = SetTimer\r
         (\r
-        hwnd,\r
+        infoPtr->hwnd,\r
         TAB_HOTTRACK_TIMER,\r
         TAB_HOTTRACK_TIMER_INTERVAL,\r
         TAB_HotTrackTimerProc\r
@@ -824,25 +782,23 @@ TAB_RecalcHotTrack
  * Handles the mouse-move event.  Updates tooltips.  Updates hot-tracking.\r
  */\r
 static LRESULT\r
-TAB_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+TAB_MouseMove (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)\r
 {\r
   int redrawLeave;\r
   int redrawEnter;\r
 \r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
   if (infoPtr->hwndToolTip)\r
-    TAB_RelayEvent (infoPtr->hwndToolTip, hwnd,\r
+    TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,\r
                    WM_LBUTTONDOWN, wParam, lParam);\r
 \r
   /* Determine which tab to highlight.  Redraw tabs which change highlight\r
   ** status. */\r
-  TAB_RecalcHotTrack(hwnd, &lParam, &redrawLeave, &redrawEnter);\r
+  TAB_RecalcHotTrack(infoPtr, &lParam, &redrawLeave, &redrawEnter);\r
 \r
   if (redrawLeave != -1)\r
-    TAB_DrawLoneItemInterior(hwnd, infoPtr, redrawLeave);\r
+    TAB_DrawLoneItemInterior(infoPtr, redrawLeave);\r
   if (redrawEnter != -1)\r
-    TAB_DrawLoneItemInterior(hwnd, infoPtr, redrawEnter);\r
+    TAB_DrawLoneItemInterior(infoPtr, redrawEnter);\r
 \r
   return 0;\r
 }\r
@@ -854,15 +810,14 @@ TAB_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
  * the window rectangle given the requested display rectangle.\r
  */\r
 static LRESULT TAB_AdjustRect(\r
-  HWND   hwnd,\r
+  TAB_INFO *infoPtr,\r
   WPARAM fLarger,\r
   LPRECT prc)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-    DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);\r
+    DWORD lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
     LONG *iRightBottom, *iLeftTop;\r
 \r
-    TRACE ("hwnd=%p fLarger=%d (%ld,%ld)-(%ld,%ld)\n", hwnd, fLarger, prc->left, prc->top, prc->right, prc->bottom);\r
+    TRACE ("hwnd=%p fLarger=%d (%ld,%ld)-(%ld,%ld)\n", infoPtr->hwnd, fLarger, prc->left, prc->top, prc->right, prc->bottom);\r
 \r
     if(lStyle & TCS_VERTICAL)\r
     {\r
@@ -916,13 +871,11 @@ static LRESULT TAB_AdjustRect(
  * perform the scrolling operation on the tab control.\r
  */\r
 static LRESULT TAB_OnHScroll(\r
-  HWND    hwnd,\r
+  TAB_INFO *infoPtr,\r
   int     nScrollCode,\r
   int     nPos,\r
   HWND    hwndScroll)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
   if(nScrollCode == SB_THUMBPOSITION && nPos != infoPtr->leftmostVisible)\r
   {\r
      if(nPos < infoPtr->leftmostVisible)\r
@@ -930,8 +883,8 @@ static LRESULT TAB_OnHScroll(
      else\r
         infoPtr->leftmostVisible++;\r
 \r
-     TAB_RecalcHotTrack(hwnd, NULL, NULL, NULL);\r
-     TAB_InvalidateTabArea(hwnd, infoPtr);\r
+     TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);\r
+     TAB_InvalidateTabArea(infoPtr);\r
      SendMessageW(infoPtr->hwndUpDown, UDM_SETPOS, 0,\r
                    MAKELONG(infoPtr->leftmostVisible, 0));\r
    }\r
@@ -1061,10 +1014,9 @@ static void TAB_SetupScrolling(
  * it checks if all the tabs fit in the client area of the window. If they\r
  * don't, a scrolling control is added.\r
  */\r
-static void TAB_SetItemBounds (HWND hwnd)\r
+static void TAB_SetItemBounds (TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO*   infoPtr = TAB_GetInfoPtr(hwnd);\r
-  LONG        lStyle  = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG        lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
   TEXTMETRICA fontMetrics;\r
   UINT        curItem;\r
   INT         curItemLeftPos;\r
@@ -1082,7 +1034,7 @@ static void TAB_SetItemBounds (HWND hwnd)
    * We need to get text information so we need a DC and we need to select\r
    * a font.\r
    */\r
-  hdc = GetDC(hwnd);\r
+  hdc = GetDC(infoPtr->hwnd);\r
 \r
   hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);\r
   hOldFont = SelectObject (hdc, hFont);\r
@@ -1091,7 +1043,7 @@ static void TAB_SetItemBounds (HWND hwnd)
    * We will base the rectangle calculations on the client rectangle\r
    * of the control.\r
    */\r
-  GetClientRect(hwnd, &clientRect);\r
+  GetClientRect(infoPtr->hwnd, &clientRect);\r
 \r
   /* if TCS_VERTICAL then swap the height and width so this code places the\r
      tabs along the top of the rectangle and we can just rotate them after\r
@@ -1242,7 +1194,7 @@ static void TAB_SetItemBounds (HWND hwnd)
     infoPtr->needsScrolling = FALSE;\r
     infoPtr->leftmostVisible = 0;\r
   }\r
-  TAB_SetupScrolling(hwnd, infoPtr, &clientRect);\r
+  TAB_SetupScrolling(infoPtr->hwnd, infoPtr, &clientRect);\r
 \r
   /* Set the number of rows */\r
   infoPtr->uNumRows = curItemRowCount;\r
@@ -1404,26 +1356,25 @@ static void TAB_SetItemBounds (HWND hwnd)
     }\r
   }\r
 \r
-  TAB_EnsureSelectionVisible(hwnd,infoPtr);\r
-  TAB_RecalcHotTrack(hwnd, NULL, NULL, NULL);\r
+  TAB_EnsureSelectionVisible(infoPtr);\r
+  TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);\r
 \r
   /* Cleanup */\r
   SelectObject (hdc, hOldFont);\r
-  ReleaseDC (hwnd, hdc);\r
+  ReleaseDC (infoPtr->hwnd, hdc);\r
 }\r
 \r
 \r
 static void\r
 TAB_EraseTabInterior\r
     (\r
-    HWND       hwnd,\r
+    TAB_INFO*   infoPtr,\r
     HDC         hdc,\r
     INT         iItem,\r
     RECT*       drawRect\r
     )\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-    LONG     lStyle  = GetWindowLongA(hwnd, GWL_STYLE);\r
+    LONG     lStyle  = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
     HBRUSH   hbr = CreateSolidBrush (comctl32_color.clrBtnFace);\r
     BOOL     deleteBrush = TRUE;\r
     RECT     rTemp = *drawRect;\r
@@ -1484,14 +1435,13 @@ TAB_EraseTabInterior
 static void\r
 TAB_DrawItemInterior\r
   (\r
-  HWND        hwnd,\r
+  TAB_INFO*   infoPtr,\r
   HDC         hdc,\r
   INT         iItem,\r
   RECT*       drawRect\r
   )\r
 {\r
-  TAB_INFO* infoPtr = TAB_GetInfoPtr(hwnd);\r
-  LONG      lStyle  = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG      lStyle  = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
 \r
   RECT localRect;\r
 \r
@@ -1509,7 +1459,7 @@ TAB_DrawItemInterior
     /*\r
      * Get the rectangle for the item.\r
      */\r
-    isVisible = TAB_InternalGetItemRect(hwnd, infoPtr, iItem, &itemRect, &selectedRect);\r
+    isVisible = TAB_InternalGetItemRect(infoPtr, iItem, &itemRect, &selectedRect);\r
     if (!isVisible)\r
       return;\r
 \r
@@ -1600,11 +1550,11 @@ TAB_DrawItemInterior
          drawRect->left, drawRect->top, drawRect->right, drawRect->bottom);\r
 \r
   /* Clear interior */\r
-  TAB_EraseTabInterior (hwnd, hdc, iItem, drawRect);\r
+  TAB_EraseTabInterior (infoPtr, hdc, iItem, drawRect);\r
 \r
   /* Draw the focus rectangle */\r
   if (!(lStyle & TCS_FOCUSNEVER) &&\r
-      (GetFocus() == hwnd) &&\r
+      (GetFocus() == infoPtr->hwnd) &&\r
       (iItem == infoPtr->uFocus) )\r
   {\r
     RECT rFocus = *drawRect;\r
@@ -1638,7 +1588,7 @@ TAB_DrawItemInterior
   /*\r
    * if owner draw, tell the owner to draw\r
    */\r
-  if ((lStyle & TCS_OWNERDRAWFIXED) && GetParent(hwnd))\r
+  if ((lStyle & TCS_OWNERDRAWFIXED) && GetParent(infoPtr->hwnd))\r
   {\r
     DRAWITEMSTRUCT dis;\r
     UINT id;\r
@@ -1654,7 +1604,7 @@ TAB_DrawItemInterior
     /*\r
      * get the control id\r
      */\r
-    id = (UINT)GetWindowLongPtrW( hwnd, GWLP_ID );\r
+    id = (UINT)GetWindowLongPtrW( infoPtr->hwnd, GWLP_ID );\r
 \r
     /*\r
      * put together the DRAWITEMSTRUCT\r
@@ -1668,7 +1618,7 @@ TAB_DrawItemInterior
       dis.itemState |= ODS_SELECTED;\r
     if (infoPtr->uFocus == iItem) \r
       dis.itemState |= ODS_FOCUS;\r
-    dis.hwndItem = hwnd;               /* */\r
+    dis.hwndItem = infoPtr->hwnd;\r
     dis.hDC      = hdc;\r
     CopyRect(&dis.rcItem,drawRect);\r
     dis.itemData = (ULONG_PTR)TAB_GetItem(infoPtr, iItem)->extra;\r
@@ -1891,12 +1841,11 @@ TAB_DrawItemInterior
  * This method is used to draw a single tab into the tab control.\r
  */\r
 static void TAB_DrawItem(\r
-  HWND hwnd,\r
+  TAB_INFO *infoPtr,\r
   HDC  hdc,\r
   INT  iItem)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  LONG      lStyle  = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG      lStyle  = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
   RECT      itemRect;\r
   RECT      selectedRect;\r
   BOOL      isVisible;\r
@@ -1908,8 +1857,7 @@ static void TAB_DrawItem(
   /*\r
    * Get the rectangle for the item.\r
    */\r
-  isVisible = TAB_InternalGetItemRect(hwnd,\r
-                                     infoPtr,\r
+  isVisible = TAB_InternalGetItemRect(infoPtr,\r
                                      iItem,\r
                                      &itemRect,\r
                                      &selectedRect);\r
@@ -1921,7 +1869,7 @@ static void TAB_DrawItem(
     /* Clip UpDown control to not draw over it */\r
     if (infoPtr->needsScrolling)\r
     {\r
-      GetWindowRect(hwnd, &rC);\r
+      GetWindowRect(infoPtr->hwnd, &rC);\r
       GetWindowRect(infoPtr->hwndUpDown, &rUD);\r
       ExcludeClipRect(hdc, rUD.left - rC.left, rUD.top - rC.top, rUD.right - rC.left, rUD.bottom - rC.top);\r
     }\r
@@ -1965,7 +1913,7 @@ static void TAB_DrawItem(
        * state. */\r
       if (iItem == infoPtr->iSelected) {\r
        RECT rect;\r
-       GetClientRect (hwnd, &rect);\r
+       GetClientRect (infoPtr->hwnd, &rect);\r
        clRight = rect.right;\r
        clBottom = rect.bottom;\r
         r = selectedRect;\r
@@ -2188,7 +2136,7 @@ static void TAB_DrawItem(
     TAB_DumpItemInternal(infoPtr, iItem);\r
 \r
     /* This modifies r to be the text rectangle. */\r
-    TAB_DrawItemInterior(hwnd, hdc, iItem, &r);\r
+    TAB_DrawItemInterior(infoPtr, hdc, iItem, &r);\r
   }\r
 }\r
 \r
@@ -2198,13 +2146,12 @@ static void TAB_DrawItem(
  * This method is used to draw the raised border around the tab control\r
  * "content" area.\r
  */\r
-static void TAB_DrawBorder (HWND hwnd, HDC hdc)\r
+static void TAB_DrawBorder (TAB_INFO *infoPtr, HDC hdc)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   RECT rect;\r
-  DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);\r
+  DWORD lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
 \r
-  GetClientRect (hwnd, &rect);\r
+  GetClientRect (infoPtr->hwnd, &rect);\r
 \r
   /*\r
    * Adjust for the style\r
@@ -2233,9 +2180,8 @@ static void TAB_DrawBorder (HWND hwnd, HDC hdc)
  *\r
  * This method repaints the tab control..\r
  */\r
-static void TAB_Refresh (HWND hwnd, HDC hdc)\r
+static void TAB_Refresh (TAB_INFO *infoPtr, HDC hdc)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   HFONT hOldFont;\r
   INT i;\r
 \r
@@ -2244,10 +2190,10 @@ static void TAB_Refresh (HWND hwnd, HDC hdc)
 \r
   hOldFont = SelectObject (hdc, infoPtr->hFont);\r
 \r
-  if (GetWindowLongA(hwnd, GWL_STYLE) & TCS_BUTTONS)\r
+  if (GetWindowLongA(infoPtr->hwnd, GWL_STYLE) & TCS_BUTTONS)\r
   {\r
     for (i = 0; i < infoPtr->uNumItem; i++)\r
-      TAB_DrawItem (hwnd, hdc, i);\r
+      TAB_DrawItem (infoPtr, hdc, i);\r
   }\r
   else\r
   {\r
@@ -2255,39 +2201,33 @@ static void TAB_Refresh (HWND hwnd, HDC hdc)
     for (i = 0; i < infoPtr->uNumItem; i++)\r
     {\r
       if (i != infoPtr->iSelected)\r
-       TAB_DrawItem (hwnd, hdc, i);\r
+       TAB_DrawItem (infoPtr, hdc, i);\r
     }\r
 \r
     /* Now, draw the border, draw it before the selected item\r
      * since the selected item overwrites part of the border. */\r
-    TAB_DrawBorder (hwnd, hdc);\r
+    TAB_DrawBorder (infoPtr, hdc);\r
 \r
     /* Then, draw the selected item */\r
-    TAB_DrawItem (hwnd, hdc, infoPtr->iSelected);\r
+    TAB_DrawItem (infoPtr, hdc, infoPtr->iSelected);\r
 \r
     /* If we haven't set the current focus yet, set it now.\r
      * Only happens when we first paint the tab controls */\r
     if (infoPtr->uFocus == -1)\r
-      TAB_SetCurFocus(hwnd, infoPtr->iSelected);\r
+      TAB_SetCurFocus(infoPtr, infoPtr->iSelected);\r
   }\r
 \r
   SelectObject (hdc, hOldFont);\r
 }\r
 \r
-static DWORD\r
-TAB_GetRowCount (HWND hwnd )\r
+static inline DWORD TAB_GetRowCount (const TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
   return infoPtr->uNumRows;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetRedraw (HWND hwnd, WPARAM wParam)\r
+static inline LRESULT TAB_SetRedraw (TAB_INFO *infoPtr, BOOL doRedraw)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
-  infoPtr->DoRedraw=(BOOL) wParam;\r
+  infoPtr->DoRedraw = doRedraw;\r
   return 0;\r
 }\r
 \r
@@ -2298,11 +2238,10 @@ TAB_SetRedraw (HWND hwnd, WPARAM wParam)
  * visible by scrolling until it is.\r
  */\r
 static void TAB_EnsureSelectionVisible(\r
-  HWND      hwnd,\r
   TAB_INFO* infoPtr)\r
 {\r
   INT iSelected = infoPtr->iSelected;\r
-  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
   INT iOrigLeftmostVisible = infoPtr->leftmostVisible;\r
 \r
   /* set the items row to the bottommost row or topmost row depending on\r
@@ -2356,7 +2295,7 @@ static void TAB_EnsureSelectionVisible(
              }\r
           }\r
         }\r
-        TAB_RecalcHotTrack(hwnd, NULL, NULL, NULL);\r
+        TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);\r
       }\r
   }\r
 \r
@@ -2379,7 +2318,7 @@ static void TAB_EnsureSelectionVisible(
      UINT i;\r
 \r
      /* Calculate the part of the client area that is visible */\r
-     GetClientRect(hwnd, &r);\r
+     GetClientRect(infoPtr->hwnd, &r);\r
      width = r.right;\r
 \r
      GetClientRect(infoPtr->hwndUpDown, &r);\r
@@ -2405,7 +2344,7 @@ static void TAB_EnsureSelectionVisible(
   }\r
 \r
   if (infoPtr->leftmostVisible != iOrigLeftmostVisible)\r
-    TAB_RecalcHotTrack(hwnd, NULL, NULL, NULL);\r
+    TAB_RecalcHotTrack(infoPtr, NULL, NULL, NULL);\r
 \r
   SendMessageW(infoPtr->hwndUpDown, UDM_SETPOS, 0,\r
                MAKELONG(infoPtr->leftmostVisible, 0));\r
@@ -2418,24 +2357,22 @@ static void TAB_EnsureSelectionVisible(
  * tabs. It is called when the state of the control changes and needs\r
  * to be redisplayed\r
  */\r
-static void TAB_InvalidateTabArea(\r
-  HWND      hwnd,\r
-  TAB_INFO* infoPtr)\r
+static void TAB_InvalidateTabArea(TAB_INFO* infoPtr)\r
 {\r
   RECT clientRect, rInvalidate, rAdjClient;\r
-  DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);\r
+  DWORD lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
   INT lastRow = infoPtr->uNumRows - 1;\r
   RECT rect;\r
 \r
   if (lastRow < 0) return;\r
 \r
-  GetClientRect(hwnd, &clientRect);\r
+  GetClientRect(infoPtr->hwnd, &clientRect);\r
   rInvalidate = clientRect;\r
   rAdjClient = clientRect;\r
 \r
-  TAB_AdjustRect(hwnd, 0, &rAdjClient);\r
+  TAB_AdjustRect(infoPtr, 0, &rAdjClient);\r
 \r
-  TAB_InternalGetItemRect(hwnd, infoPtr, infoPtr->uNumItem-1 , &rect, NULL);\r
+  TAB_InternalGetItemRect(infoPtr, infoPtr->uNumItem-1 , &rect, NULL);\r
   if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))\r
   {\r
     rInvalidate.left = rAdjClient.right;\r
@@ -2475,44 +2412,42 @@ static void TAB_InvalidateTabArea(
        rInvalidate.left,  rInvalidate.top,\r
        rInvalidate.right, rInvalidate.bottom);\r
  \r
-  InvalidateRect(hwnd, &rInvalidate, TRUE);\r
+  InvalidateRect(infoPtr->hwnd, &rInvalidate, TRUE);\r
 }\r
 \r
-static LRESULT\r
-TAB_Paint (HWND hwnd, WPARAM wParam)\r
+static inline LRESULT TAB_Paint (TAB_INFO *infoPtr, HDC hdcPaint)\r
 {\r
   HDC hdc;\r
   PAINTSTRUCT ps;\r
 \r
-  if (wParam == 0)\r
+  if (hdcPaint)\r
+    hdc = hdcPaint;\r
+  else\r
   {\r
-    hdc = BeginPaint (hwnd, &ps);\r
+    hdc = BeginPaint (infoPtr->hwnd, &ps);\r
     TRACE("erase %d, rect=(%ld,%ld)-(%ld,%ld)\n",\r
          ps.fErase,\r
          ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right,ps.rcPaint.bottom);\r
-  } else {\r
-    hdc = (HDC)wParam;\r
   }\r
-    \r
-  TAB_Refresh (hwnd, hdc);\r
 \r
-  if(!wParam)\r
-    EndPaint (hwnd, &ps);\r
+  TAB_Refresh (infoPtr, hdc);\r
+\r
+  if (!hdcPaint)\r
+    EndPaint (infoPtr->hwnd, &ps);\r
 \r
   return 0;\r
 }\r
 \r
 static LRESULT\r
-TAB_InsertItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)\r
+TAB_InsertItemAW (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnicode)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   TAB_ITEM *item;\r
   TCITEMA *pti;\r
   INT iItem;\r
   RECT rect;\r
 \r
-  GetClientRect (hwnd, &rect);\r
-  TRACE("Rect: %p T %li, L %li, B %li, R %li\n", hwnd,\r
+  GetClientRect (infoPtr->hwnd, &rect);\r
+  TRACE("Rect: %p T %li, L %li, B %li, R %li\n", infoPtr->hwnd,\r
         rect.top, rect.left, rect.bottom, rect.right);\r
 \r
   pti = (TCITEMA *)lParam;\r
@@ -2582,23 +2517,22 @@ TAB_InsertItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
   else\r
     memset(item->extra, 0, infoPtr->cbInfo);\r
   \r
-  TAB_SetItemBounds(hwnd);\r
+  TAB_SetItemBounds(infoPtr);\r
   if (infoPtr->uNumItem > 1)\r
-    TAB_InvalidateTabArea(hwnd, infoPtr);\r
+    TAB_InvalidateTabArea(infoPtr);\r
   else\r
-    InvalidateRect(hwnd, NULL, TRUE);\r
+    InvalidateRect(infoPtr->hwnd, NULL, TRUE);\r
 \r
   TRACE("[%p]: added item %d %s\n",\r
-        hwnd, iItem, debugstr_w(item->pszText));\r
+        infoPtr->hwnd, iItem, debugstr_w(item->pszText));\r
 \r
   return iItem;\r
 }\r
 \r
 static LRESULT\r
-TAB_SetItemSize (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+TAB_SetItemSize (TAB_INFO *infoPtr, LPARAM lParam)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  LONG lStyle = GetWindowLongA(hwnd, GWL_STYLE);\r
+  LONG lStyle = GetWindowLongA(infoPtr->hwnd, GWL_STYLE);\r
   LONG lResult = 0;\r
   BOOL bNeedPaint = FALSE;\r
 \r
@@ -2624,60 +2558,56 @@ TAB_SetItemSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
 \r
   if (bNeedPaint)\r
   {\r
-    TAB_SetItemBounds(hwnd);\r
-    RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);\r
+    TAB_SetItemBounds(infoPtr);\r
+    RedrawWindow(infoPtr->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);\r
   }\r
-    \r
+\r
   return lResult;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetMinTabWidth (HWND hwnd, LPARAM lParam)\r
+static inline LRESULT TAB_SetMinTabWidth (TAB_INFO *infoPtr, INT cx)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  INT cx = (INT)lParam;\r
-  INT oldcx;\r
+  INT oldcx = 0;\r
+\r
+  TRACE("(%p,%d)\n", infoPtr, cx);\r
 \r
   if (infoPtr) {\r
     oldcx = infoPtr->tabMinWidth;\r
     infoPtr->tabMinWidth = (cx==-1)?DEFAULT_TAB_WIDTH:cx;\r
-  } else\r
-    return 0;\r
+  }\r
 \r
   return oldcx;\r
 }\r
 \r
-static LRESULT \r
-TAB_HighlightItem (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT \r
+TAB_HighlightItem (TAB_INFO *infoPtr, INT iItem, BOOL fHighlight)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  INT iItem = (INT)wParam;\r
-  BOOL fHighlight = (BOOL)LOWORD(lParam);\r
+  LPDWORD lpState;\r
 \r
-  if ((infoPtr) && (iItem>=0) && (iItem<infoPtr->uNumItem)) {\r
-    if (fHighlight)\r
-      TAB_GetItem(infoPtr, iItem)->dwState |= TCIS_HIGHLIGHTED;\r
-    else\r
-      TAB_GetItem(infoPtr, iItem)->dwState &= ~TCIS_HIGHLIGHTED;\r
-  } else\r
+  TRACE("(%p,%d,%s)\n", infoPtr, iItem, fHighlight ? "true" : "false");\r
+\r
+  if (!infoPtr || iItem < 0 || iItem >= infoPtr->uNumItem)\r
     return FALSE;\r
+  \r
+  lpState = &TAB_GetItem(infoPtr, iItem)->dwState;\r
+\r
+  if (fHighlight)\r
+    *lpState |= TCIS_HIGHLIGHTED;\r
+  else\r
+    *lpState &= ~TCIS_HIGHLIGHTED;\r
 \r
   return TRUE;\r
 }\r
 \r
 static LRESULT\r
-TAB_SetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)\r
+TAB_SetItemAW (TAB_INFO *infoPtr, INT iItem, LPTCITEMA tabItem, BOOL bUnicode)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  TCITEMA *tabItem;\r
   TAB_ITEM *wineItem;\r
-  INT    iItem;\r
 \r
-  iItem = (INT)wParam;\r
-  tabItem = (LPTCITEMA)lParam;\r
+  TRACE("(%p,%d,%p,%s)\n", infoPtr, iItem, tabItem, bUnicode ? "true" : "false");\r
 \r
-  TRACE("%d %p\n", iItem, tabItem);\r
-  if ((iItem<0) || (iItem>=infoPtr->uNumItem)) return FALSE;\r
+  if (iItem < 0 || iItem >= infoPtr->uNumItem)\r
+    return FALSE;\r
 \r
   if (bUnicode)\r
     TAB_DumpItemExternalW((TCITEMW *)tabItem, iItem);\r
@@ -2712,33 +2642,26 @@ TAB_SetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
   }\r
 \r
   /* Update and repaint tabs */\r
-  TAB_SetItemBounds(hwnd);\r
-  TAB_InvalidateTabArea(hwnd,infoPtr);\r
+  TAB_SetItemBounds(infoPtr);\r
+  TAB_InvalidateTabArea(infoPtr);\r
 \r
   return TRUE;\r
 }\r
 \r
-static LRESULT\r
-TAB_GetItemCount (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_GetItemCount (const TAB_INFO *infoPtr)\r
 {\r
-   TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
    return infoPtr->uNumItem;\r
 }\r
 \r
 \r
 static LRESULT\r
-TAB_GetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)\r
+TAB_GetItemAW (TAB_INFO *infoPtr, INT iItem, LPTCITEMA tabItem, BOOL bUnicode)\r
 {\r
-   TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-   TCITEMA *tabItem;\r
-   TAB_ITEM *wineItem;\r
-   INT    iItem;\r
+  TAB_ITEM *wineItem;\r
 \r
-  iItem = (INT)wParam;\r
-  tabItem = (LPTCITEMA)lParam;\r
-  TRACE("\n");\r
-  if ((iItem<0) || (iItem>=infoPtr->uNumItem))\r
+  TRACE("(%p,%d,%p,%s)\n", infoPtr, iItem, tabItem, bUnicode ? "true" : "false");\r
+\r
+  if (iItem < 0 || iItem >= infoPtr->uNumItem)\r
     return FALSE;\r
 \r
   wineItem = TAB_GetItem(infoPtr, iItem);\r
@@ -2772,19 +2695,18 @@ TAB_GetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
 }\r
 \r
 \r
-static LRESULT\r
-TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-    INT iItem = (INT) wParam;\r
     BOOL bResult = FALSE;\r
 \r
+    TRACE("(%p, %d)\n", infoPtr, iItem);\r
+\r
     if ((iItem >= 0) && (iItem < infoPtr->uNumItem))\r
     {\r
         TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);\r
         LPBYTE oldItems = (LPBYTE)infoPtr->items;\r
        \r
-       TAB_InvalidateTabArea(hwnd, infoPtr);\r
+       TAB_InvalidateTabArea(infoPtr);\r
 \r
        if ((item->mask & TCIF_TEXT) && item->pszText)\r
             Free(item->pszText);\r
@@ -2796,7 +2718,7 @@ TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
             infoPtr->items = NULL;\r
             if (infoPtr->iHotTracked >= 0)\r
             {\r
-                KillTimer(hwnd, TAB_HOTTRACK_TIMER);\r
+                KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);\r
                 infoPtr->iHotTracked = -1;\r
             }\r
         }\r
@@ -2831,7 +2753,7 @@ TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
            infoPtr->iSelected = -1;\r
 \r
        /* Reposition and repaint tabs */\r
-       TAB_SetItemBounds(hwnd);\r
+       TAB_SetItemBounds(infoPtr);\r
 \r
        bResult = TRUE;\r
     }\r
@@ -2839,86 +2761,64 @@ TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
     return bResult;\r
 }\r
 \r
-static LRESULT\r
-TAB_DeleteAllItems (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
\r
+    TRACE("(%p)\n", infoPtr);\r
     while (infoPtr->uNumItem)\r
-      TAB_DeleteItem (hwnd, 0, 0);\r
+      TAB_DeleteItem (infoPtr, 0);\r
     return TRUE;\r
 }\r
 \r
 \r
-static LRESULT\r
-TAB_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_GetFont (const TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
-  TRACE("\n");\r
+  TRACE("(%p) returning %p\n", infoPtr, infoPtr->hFont);\r
   return (LRESULT)infoPtr->hFont;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
-\r
+static inline LRESULT TAB_SetFont (TAB_INFO *infoPtr, HFONT hNewFont)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
-  TRACE("%x %lx\n",wParam, lParam);\r
+  TRACE("(%p,%p)\n", infoPtr, hNewFont);\r
 \r
-  infoPtr->hFont = (HFONT)wParam;\r
+  infoPtr->hFont = hNewFont;\r
 \r
-  TAB_SetItemBounds(hwnd);\r
+  TAB_SetItemBounds(infoPtr);\r
 \r
-  TAB_InvalidateTabArea(hwnd, infoPtr);\r
+  TAB_InvalidateTabArea(infoPtr);\r
 \r
   return 0;\r
 }\r
 \r
 \r
-static LRESULT\r
-TAB_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_GetImageList (const TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-\r
   TRACE("\n");\r
   return (LRESULT)infoPtr->himl;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static inline LRESULT TAB_SetImageList (TAB_INFO *infoPtr, HIMAGELIST himlNew)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-    HIMAGELIST himlPrev;\r
-\r
+    HIMAGELIST himlPrev = infoPtr->himl;\r
     TRACE("\n");\r
-    himlPrev = infoPtr->himl;\r
-    infoPtr->himl= (HIMAGELIST)lParam;\r
+    infoPtr->himl = himlNew;\r
     return (LRESULT)himlPrev;\r
 }\r
 \r
-static LRESULT\r
-TAB_GetUnicodeFormat (HWND hwnd)\r
+static inline LRESULT TAB_GetUnicodeFormat (const TAB_INFO *infoPtr)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr (hwnd);\r
     return infoPtr->bUnicode;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetUnicodeFormat (HWND hwnd, WPARAM wParam)\r
+static inline LRESULT TAB_SetUnicodeFormat (TAB_INFO *infoPtr, BOOL bUnicode)\r
 {\r
-    TAB_INFO *infoPtr = TAB_GetInfoPtr (hwnd);\r
     BOOL bTemp = infoPtr->bUnicode;\r
 \r
-    infoPtr->bUnicode = (BOOL)wParam;\r
+    infoPtr->bUnicode = bUnicode;\r
 \r
     return bTemp;\r
 }\r
 \r
-static LRESULT\r
-TAB_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
-\r
+static inline LRESULT TAB_Size (TAB_INFO *infoPtr)\r
 {\r
 /* I'm not really sure what the following code was meant to do.\r
    This is what it is doing:\r
@@ -2945,17 +2845,16 @@ TAB_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
   } */\r
 \r
   /* Recompute the size/position of the tabs. */\r
-  TAB_SetItemBounds (hwnd);\r
+  TAB_SetItemBounds (infoPtr);\r
 \r
   /* Force a repaint of the control. */\r
-  InvalidateRect(hwnd, NULL, TRUE);\r
+  InvalidateRect(infoPtr->hwnd, NULL, TRUE);\r
 \r
   return 0;\r
 }\r
 \r
 \r
-static LRESULT\r
-TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+static LRESULT TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
 {\r
   TAB_INFO *infoPtr;\r
   TEXTMETRICA fontMetrics;\r
@@ -2967,6 +2866,7 @@ TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
 \r
   SetWindowLongA(hwnd, 0, (DWORD)infoPtr);\r
 \r
+  infoPtr->hwnd            = hwnd;\r
   infoPtr->hwndNotify      = ((LPCREATESTRUCTW)lParam)->hwndParent;\r
   infoPtr->uNumItem        = 0;\r
   infoPtr->uNumRows        = 0;\r
@@ -3050,9 +2950,8 @@ TAB_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
 }\r
 \r
 static LRESULT\r
-TAB_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
+TAB_Destroy (TAB_INFO *infoPtr)\r
 {\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
   UINT iItem;\r
 \r
   if (!infoPtr)\r
@@ -3073,19 +2972,16 @@ TAB_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
     DestroyWindow(infoPtr->hwndUpDown);\r
 \r
   if (infoPtr->iHotTracked >= 0)\r
-    KillTimer(hwnd, TAB_HOTTRACK_TIMER);\r
+    KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);\r
 \r
   Free (infoPtr);\r
-  SetWindowLongA(hwnd, 0, 0);\r
+  SetWindowLongA(infoPtr->hwnd, 0, 0);\r
   return 0;\r
 }\r
 \r
-static LRESULT\r
-TAB_SetItemExtra (HWND hwnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
-  INT cbInfo = wParam;\r
-   \r
+static inline LRESULT\r
+TAB_SetItemExtra (TAB_INFO *infoPtr, INT cbInfo)\r
+{   \r
   if (!infoPtr || cbInfo <= 0)\r
     return FALSE;\r
 \r
@@ -3105,92 +3001,92 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);\r
 \r
     TRACE("hwnd=%p msg=%x wParam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);\r
-    if (!TAB_GetInfoPtr(hwnd) && (uMsg != WM_CREATE))\r
+    if (!infoPtr && (uMsg != WM_CREATE))\r
       return DefWindowProcW (hwnd, uMsg, wParam, lParam);\r
 \r
     switch (uMsg)\r
     {\r
     case TCM_GETIMAGELIST:\r
-      return TAB_GetImageList (hwnd, wParam, lParam);\r
+      return TAB_GetImageList (infoPtr);\r
 \r
     case TCM_SETIMAGELIST:\r
-      return TAB_SetImageList (hwnd, wParam, lParam);\r
+      return TAB_SetImageList (infoPtr, (HIMAGELIST)lParam);\r
 \r
     case TCM_GETITEMCOUNT:\r
-      return TAB_GetItemCount (hwnd, wParam, lParam);\r
+      return TAB_GetItemCount (infoPtr);\r
 \r
     case TCM_GETITEMA:\r
     case TCM_GETITEMW:\r
-      return TAB_GetItemAW (hwnd, wParam, lParam, uMsg == TCM_GETITEMW);\r
+      return TAB_GetItemAW (infoPtr, (INT)wParam, (LPTCITEMA)lParam, uMsg == TCM_GETITEMW);\r
 \r
     case TCM_SETITEMA:\r
     case TCM_SETITEMW:\r
-      return TAB_SetItemAW (hwnd, wParam, lParam, uMsg == TCM_SETITEMW);\r
+      return TAB_SetItemAW (infoPtr, (INT)wParam, (LPTCITEMA)lParam, uMsg == TCM_SETITEMW);\r
 \r
     case TCM_DELETEITEM:\r
-      return TAB_DeleteItem (hwnd, wParam, lParam);\r
+      return TAB_DeleteItem (infoPtr, (INT)wParam);\r
 \r
     case TCM_DELETEALLITEMS:\r
-     return TAB_DeleteAllItems (hwnd, wParam, lParam);\r
+     return TAB_DeleteAllItems (infoPtr);\r
 \r
     case TCM_GETITEMRECT:\r
-     return TAB_GetItemRect (hwnd, wParam, lParam);\r
+     return TAB_GetItemRect (infoPtr, wParam, lParam);\r
 \r
     case TCM_GETCURSEL:\r
-      return TAB_GetCurSel (hwnd);\r
+      return TAB_GetCurSel (infoPtr);\r
 \r
     case TCM_HITTEST:\r
-      return TAB_HitTest (hwnd, wParam, lParam);\r
+      return TAB_HitTest (infoPtr, (LPTCHITTESTINFO)lParam);\r
 \r
     case TCM_SETCURSEL:\r
-      return TAB_SetCurSel (hwnd, wParam);\r
+      return TAB_SetCurSel (infoPtr, (INT)wParam);\r
 \r
     case TCM_INSERTITEMA:\r
     case TCM_INSERTITEMW:\r
-      return TAB_InsertItemAW (hwnd, wParam, lParam, uMsg == TCM_INSERTITEMW);\r
+      return TAB_InsertItemAW (infoPtr, wParam, lParam, uMsg == TCM_INSERTITEMW);\r
 \r
     case TCM_SETITEMEXTRA:\r
-      return TAB_SetItemExtra (hwnd, wParam, lParam);\r
+      return TAB_SetItemExtra (infoPtr, (int)wParam);\r
 \r
     case TCM_ADJUSTRECT:\r
-      return TAB_AdjustRect (hwnd, (BOOL)wParam, (LPRECT)lParam);\r
+      return TAB_AdjustRect (infoPtr, (BOOL)wParam, (LPRECT)lParam);\r
 \r
     case TCM_SETITEMSIZE:\r
-      return TAB_SetItemSize (hwnd, wParam, lParam);\r
+      return TAB_SetItemSize (infoPtr, lParam);\r
 \r
     case TCM_REMOVEIMAGE:\r
       FIXME("Unimplemented msg TCM_REMOVEIMAGE\n");\r
       return 0;\r
 \r
     case TCM_SETPADDING:\r
-      return TAB_SetPadding (hwnd, wParam, lParam);\r
+      return TAB_SetPadding (infoPtr, lParam);\r
 \r
     case TCM_GETROWCOUNT:\r
-      return TAB_GetRowCount(hwnd);\r
+      return TAB_GetRowCount(infoPtr);\r
 \r
     case TCM_GETUNICODEFORMAT:\r
-      return TAB_GetUnicodeFormat (hwnd);\r
+      return TAB_GetUnicodeFormat (infoPtr);\r
 \r
     case TCM_SETUNICODEFORMAT:\r
-      return TAB_SetUnicodeFormat (hwnd, wParam);\r
+      return TAB_SetUnicodeFormat (infoPtr, (BOOL)wParam);\r
 \r
     case TCM_HIGHLIGHTITEM:\r
-      return TAB_HighlightItem (hwnd, wParam, lParam);\r
+      return TAB_HighlightItem (infoPtr, (INT)wParam, (BOOL)LOWORD(lParam));\r
 \r
     case TCM_GETTOOLTIPS:\r
-      return TAB_GetToolTips (hwnd, wParam, lParam);\r
+      return TAB_GetToolTips (infoPtr);\r
 \r
     case TCM_SETTOOLTIPS:\r
-      return TAB_SetToolTips (hwnd, wParam, lParam);\r
+      return TAB_SetToolTips (infoPtr, (HWND)wParam);\r
 \r
     case TCM_GETCURFOCUS:\r
-      return TAB_GetCurFocus (hwnd);\r
+      return TAB_GetCurFocus (infoPtr);\r
 \r
     case TCM_SETCURFOCUS:\r
-      return TAB_SetCurFocus (hwnd, wParam);\r
+      return TAB_SetCurFocus (infoPtr, (INT)wParam);\r
 \r
     case TCM_SETMINTABWIDTH:\r
-      return TAB_SetMinTabWidth(hwnd, lParam);\r
+      return TAB_SetMinTabWidth(infoPtr, (INT)lParam);\r
 \r
     case TCM_DESELECTALL:\r
       FIXME("Unimplemented msg TCM_DESELECTALL\n");\r
@@ -3205,49 +3101,49 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
       return 0;\r
 \r
     case WM_GETFONT:\r
-      return TAB_GetFont (hwnd, wParam, lParam);\r
+      return TAB_GetFont (infoPtr);\r
 \r
     case WM_SETFONT:\r
-      return TAB_SetFont (hwnd, wParam, lParam);\r
+      return TAB_SetFont (infoPtr, (HFONT)wParam);\r
 \r
     case WM_CREATE:\r
       return TAB_Create (hwnd, wParam, lParam);\r
 \r
     case WM_NCDESTROY:\r
-      return TAB_Destroy (hwnd, wParam, lParam);\r
+      return TAB_Destroy (infoPtr);\r
 \r
     case WM_GETDLGCODE:\r
       return DLGC_WANTARROWS | DLGC_WANTCHARS;\r
 \r
     case WM_LBUTTONDOWN:\r
-      return TAB_LButtonDown (hwnd, wParam, lParam);\r
+      return TAB_LButtonDown (infoPtr, wParam, lParam);\r
 \r
     case WM_LBUTTONUP:\r
-      return TAB_LButtonUp (hwnd, wParam, lParam);\r
+      return TAB_LButtonUp (infoPtr);\r
 \r
     case WM_NOTIFY:\r
       return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);\r
 \r
     case WM_RBUTTONDOWN:\r
-      return TAB_RButtonDown (hwnd, wParam, lParam);\r
+      return TAB_RButtonDown (infoPtr);\r
 \r
     case WM_MOUSEMOVE:\r
-      return TAB_MouseMove (hwnd, wParam, lParam);\r
+      return TAB_MouseMove (infoPtr, wParam, lParam);\r
 \r
     case WM_PAINT:\r
-      return TAB_Paint (hwnd, wParam);\r
+      return TAB_Paint (infoPtr, (HDC)wParam);\r
 \r
     case WM_SIZE:\r
-      return TAB_Size (hwnd, wParam, lParam);\r
+      return TAB_Size (infoPtr);\r
 \r
     case WM_SETREDRAW:\r
-      return TAB_SetRedraw (hwnd, wParam);\r
+      return TAB_SetRedraw (infoPtr, (BOOL)wParam);\r
 \r
     case WM_HSCROLL:\r
-      return TAB_OnHScroll(hwnd, (int)LOWORD(wParam), (int)HIWORD(wParam), (HWND)lParam);\r
+      return TAB_OnHScroll(infoPtr, (int)LOWORD(wParam), (int)HIWORD(wParam), (HWND)lParam);\r
 \r
     case WM_STYLECHANGED:\r
-      TAB_SetItemBounds (hwnd);\r
+      TAB_SetItemBounds (infoPtr);\r
       InvalidateRect(hwnd, NULL, TRUE);\r
       return 0;\r
 \r
@@ -3257,19 +3153,21 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
     case WM_KILLFOCUS:\r
     case WM_SETFOCUS:\r
-      return TAB_FocusChanging(hwnd, uMsg, wParam, lParam);\r
+      TAB_FocusChanging(infoPtr);\r
+      break;   /* Don't disturb normal focus behavior */\r
 \r
     case WM_KEYUP:\r
-      return TAB_KeyUp(hwnd, wParam);\r
+      return TAB_KeyUp(infoPtr, wParam);\r
     case WM_NCHITTEST:\r
-      return TAB_NCHitTest(hwnd, lParam);\r
+      return TAB_NCHitTest(infoPtr, lParam);\r
 \r
     default:\r
-      if ((uMsg >= WM_USER) && (uMsg < WM_APP))\r
+      if (uMsg >= WM_USER && uMsg < WM_APP)\r
        WARN("unknown msg %04x wp=%08x lp=%08lx\n",\r
             uMsg, wParam, lParam);\r
-      return DefWindowProcW(hwnd, uMsg, wParam, lParam);\r
+      break;\r
     }\r
+    return DefWindowProcW(hwnd, uMsg, wParam, lParam);\r
 }\r
 \r
 \r
index b7320f1..0c4a5cc 100644 (file)
@@ -2386,7 +2386,9 @@ TREEVIEW_DrawItem(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *wineItem)
 \r
     /* The custom draw handler can query the text rectangle,\r
      * so get ready. */\r
-    TREEVIEW_ComputeTextWidth(infoPtr, wineItem, hdc);\r
+    /* should already be known, set to 0 when changed */\r
+    if (!wineItem->textWidth)\r
+        TREEVIEW_ComputeTextWidth(infoPtr, wineItem, hdc);\r
 \r
     cditem = 0;\r
 \r
@@ -3084,6 +3086,9 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
 {\r
     UINT action = TVE_COLLAPSE | (bRemoveChildren ? TVE_COLLAPSERESET : 0);\r
     BOOL bSetSelection, bSetFirstVisible;\r
+    RECT scrollRect;\r
+    LONG scrollDist = 0;\r
+    TREEVIEW_ITEM *nextItem = NULL, *tmpItem;\r
 \r
     TRACE("TVE_COLLAPSE %p %s\n", wineItem, TREEVIEW_ItemName(wineItem));\r
 \r
@@ -3107,6 +3112,20 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
     bSetFirstVisible = (infoPtr->firstVisible != NULL\r
                         && TREEVIEW_IsChildOf(wineItem, infoPtr->firstVisible));\r
 \r
+    tmpItem = wineItem;\r
+    while (tmpItem)\r
+    {\r
+        if (tmpItem->nextSibling)\r
+        {\r
+            nextItem = tmpItem->nextSibling;\r
+            break;\r
+        }\r
+        tmpItem = tmpItem->parent;\r
+    }\r
+\r
+    if (nextItem)\r
+        scrollDist = nextItem->rect.top;\r
+\r
     if (bRemoveChildren)\r
     {\r
         INT old_cChildren = wineItem->cChildren;\r
@@ -3131,8 +3150,8 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
 \r
     TREEVIEW_RecalculateVisibleOrder(infoPtr, wineItem);\r
 \r
-    TREEVIEW_SetFirstVisible(infoPtr, bSetFirstVisible ? wineItem\r
-                            : infoPtr->firstVisible, TRUE);\r
+    if (nextItem)\r
+        scrollDist = -(scrollDist - nextItem->rect.top);\r
 \r
     if (bSetSelection)\r
     {\r
@@ -3141,12 +3160,29 @@ TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
            infoPtr->selectedItem->state &= ~TVIS_SELECTED;\r
        wineItem->state |= TVIS_SELECTED;\r
        infoPtr->selectedItem = wineItem;\r
-\r
-       TREEVIEW_EnsureVisible(infoPtr, wineItem, FALSE);\r
     }\r
 \r
     TREEVIEW_UpdateScrollBars(infoPtr);\r
-    TREEVIEW_Invalidate(infoPtr, NULL);\r
+\r
+    scrollRect.left = 0;\r
+    scrollRect.right = infoPtr->clientWidth;\r
+    scrollRect.bottom = infoPtr->clientHeight;\r
+\r
+    if (nextItem)\r
+    {\r
+        scrollRect.top = nextItem->rect.top;\r
+\r
+        ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,\r
+                       NULL, NULL, SW_ERASE | SW_INVALIDATE);\r
+        TREEVIEW_Invalidate(infoPtr, wineItem);\r
+    } else {\r
+        scrollRect.top = wineItem->rect.top;\r
+        InvalidateRect(infoPtr->hwnd, &scrollRect, TRUE);\r
+    }\r
+\r
+    TREEVIEW_SetFirstVisible(infoPtr,\r
+                             bSetFirstVisible ? wineItem : infoPtr->firstVisible,\r
+                             TRUE);\r
 \r
     return TRUE;\r
 }\r
@@ -3155,11 +3191,30 @@ static BOOL
 TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,\r
                BOOL bExpandPartial, BOOL bUser)\r
 {\r
+    LONG scrollDist;\r
+    LONG orgNextTop = 0;\r
+    RECT scrollRect;\r
+    TREEVIEW_ITEM *nextItem, *tmpItem;\r
+\r
     TRACE("\n");\r
 \r
     if (wineItem->state & TVIS_EXPANDED)\r
        return TRUE;\r
 \r
+    tmpItem = wineItem; nextItem = NULL;\r
+    while (tmpItem)\r
+    {\r
+        if (tmpItem->nextSibling)\r
+        {\r
+            nextItem = tmpItem->nextSibling;\r
+            break;\r
+        }\r
+        tmpItem = tmpItem->parent;\r
+    }\r
+\r
+    if (nextItem)\r
+        orgNextTop = nextItem->rect.top;\r
+\r
     TRACE("TVE_EXPAND %p %s\n", wineItem, TREEVIEW_ItemName(wineItem));\r
 \r
     if (bUser || ((wineItem->cChildren != 0) &&\r
@@ -3194,6 +3249,22 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
     TREEVIEW_UpdateSubTree(infoPtr, wineItem);\r
     TREEVIEW_UpdateScrollBars(infoPtr);\r
 \r
+    scrollRect.left = 0;\r
+    scrollRect.bottom = infoPtr->treeHeight;\r
+    scrollRect.right = infoPtr->clientWidth;\r
+    if (nextItem)\r
+    {\r
+        scrollDist = nextItem->rect.top - orgNextTop;\r
+        scrollRect.top = orgNextTop;\r
+\r
+        ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,\r
+                       NULL, NULL, SW_ERASE | SW_INVALIDATE);\r
+        TREEVIEW_Invalidate (infoPtr, wineItem);\r
+    } else {\r
+        scrollRect.top = wineItem->rect.top;\r
+        InvalidateRect(infoPtr->hwnd, &scrollRect, FALSE);\r
+    }\r
+\r
     /* Scroll up so that as many children as possible are visible.\r
      * This fails when expanding causes an HScroll bar to appear, but we\r
      * don't know that yet, so the last item is obscured. */\r
@@ -3226,8 +3297,6 @@ TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
        }\r
     }\r
 \r
-    TREEVIEW_Invalidate(infoPtr, NULL);\r
-\r
     return TRUE;\r
 }\r
 \r
@@ -4735,7 +4804,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
     infoPtr->uIndent = MINIMUM_INDENT;\r
     infoPtr->selectedItem = 0;\r
     infoPtr->focusedItem = 0;\r
-    /* hotItem? */\r
+    infoPtr->hotItem = 0;\r
     infoPtr->firstVisible = 0;\r
     infoPtr->maxVisibleOrder = 0;\r
     infoPtr->dropItem = 0;\r
@@ -5435,7 +5504,10 @@ TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
        return TREEVIEW_MouseLeave(infoPtr);\r
 \r
     case WM_MOUSEMOVE:\r
-       return TREEVIEW_MouseMove(infoPtr, wParam, lParam);\r
+        if (infoPtr->dwStyle & TVS_TRACKSELECT)\r
+            return TREEVIEW_MouseMove(infoPtr, wParam, lParam);\r
+        else\r
+            return 0;\r
 \r
     case WM_NOTIFY:\r
        return TREEVIEW_Notify(infoPtr, wParam, lParam);\r
diff --git a/reactos/lib/comctl32/winetests/dpa.c b/reactos/lib/comctl32/winetests/dpa.c
new file mode 100644 (file)
index 0000000..4e0209f
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Unit tests for DPA functions
+ *
+ * Copyright 2003 Uwe Bonnes
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "commctrl.h"
+
+#include "wine/test.h"
+
+static HDPA (WINAPI *pDPA_Create)(int);
+static BOOL (WINAPI *pDPA_Grow)(const HDPA hdpa, INT nGrow);
+static BOOL (WINAPI *pDPA_Destroy)(const HDPA hdpa);
+static BOOL (WINAPI *pDPA_SetPtr)(const HDPA hdpa, INT i, LPVOID p);
+
+static INT CALLBACK dpa_strcmp(LPVOID pvstr1, LPVOID pvstr2, LPARAM flags)
+{
+  LPCSTR str1 = (LPCSTR)pvstr1;
+  LPCSTR str2 = (LPCSTR)pvstr2;
+
+  return lstrcmpA (str1, str2);
+}
+
+void DPA_test()
+{
+  HDPA dpa_ret;
+  INT  int_ret;
+  CHAR test_str0[]="test0";
+
+  if (!pDPA_Create)
+      return;
+
+  dpa_ret = pDPA_Create(0);
+  ok((dpa_ret !=0), "DPA_Create failed\n");
+  int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED);
+  ok((int_ret == -1), "DPA_Search found invalid item\n");
+  int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTBEFORE);
+  ok((int_ret == 0), "DPA_Search proposed bad item\n");
+  int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTAFTER);
+  ok((int_ret == 0), "DPA_Search proposed bad item\n");
+  int_ret = pDPA_Grow(dpa_ret,0);
+  ok(int_ret != 0, "DPA_Grow failed\n");
+  int_ret = pDPA_SetPtr(dpa_ret, 0, (void*)0xdeadbeef);
+  ok(int_ret != 0, "DPA_SetPtr failed\n");
+  int_ret = pDPA_Destroy(dpa_ret);
+  ok(int_ret != 0, "DPA_Destory failed\n");
+}
+
+START_TEST(dpa)
+{
+    HMODULE hdll;
+
+    hdll=GetModuleHandleA("comctl32.dll");
+    pDPA_Create=(void*)GetProcAddress(hdll,(LPCSTR)328);
+    pDPA_Destroy=(void*)GetProcAddress(hdll,(LPCSTR)329);
+    pDPA_Grow=(void*)GetProcAddress(hdll,(LPCSTR)330);
+    pDPA_SetPtr=(void*)GetProcAddress(hdll,(LPCSTR)335);
+
+    DPA_test();
+}
diff --git a/reactos/lib/comctl32/winetests/imagelist.c b/reactos/lib/comctl32/winetests/imagelist.c
new file mode 100644 (file)
index 0000000..359d370
--- /dev/null
@@ -0,0 +1,560 @@
+/* Unit test suite for imagelist control.
+ *
+ * Copyright 2004 Michael Stefaniuc
+ * Copyright 2002 Mike McCormack 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+
+#include "wine/test.h"
+
+#undef VISIBLE
+
+#ifdef VISIBLE
+#define WAIT Sleep (1000)
+#define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
+#else
+#define WAIT
+#define REDRAW(hwnd)
+#endif
+
+
+static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*) = NULL;
+
+static HDC desktopDC;
+static HINSTANCE hinst;
+
+/* These macros build cursor/bitmap data in 4x4 pixel blocks */
+#define B(x,y) ((x?0xf0:0)|(y?0xf:0))
+#define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
+#define ROW32(a,b,c,d,e,f,g,h) ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h), \
+  ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
+#define ROW2(a,b,c,d,e,f,g,h,i,j,k,l) ROW1(a,b,c,d,e,f,g,h),B(i,j),B(k,l)
+#define ROW48(a,b,c,d,e,f,g,h,i,j,k,l) ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
+  ROW2(a,b,c,d,e,f,g,h,i,j,k,l), ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
+  ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
+
+static const BYTE empty_bits[48*48/8];
+
+static const BYTE icon_bits[32*32/8] =
+{
+  ROW32(0,0,0,0,0,0,0,0),
+  ROW32(0,0,1,1,1,1,0,0),
+  ROW32(0,1,1,1,1,1,1,0),
+  ROW32(0,1,1,0,0,1,1,0),
+  ROW32(0,1,1,0,0,1,1,0),
+  ROW32(0,1,1,1,1,1,1,0),
+  ROW32(0,0,1,1,1,1,0,0),
+  ROW32(0,0,0,0,0,0,0,0)
+};
+
+static const BYTE bitmap_bits[48*48/8] =
+{
+  ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
+  ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
+  ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
+  ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
+  ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
+  ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
+  ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
+  ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
+  ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
+  ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
+  ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
+  ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
+};
+
+static HIMAGELIST createImageList(int cx, int cy)
+{
+    /* Create an ImageList and put an image into it */
+    HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
+    HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
+    ImageList_Add(himl, hbm, NULL);
+    return himl;
+}
+
+static HWND create_a_window(void)
+{
+    char className[] = "bmwnd";
+    char winName[]   = "Test Bitmap";
+    HWND hWnd;
+    static int registered = 0;
+
+    if (!registered)
+    {
+        WNDCLASSA cls;
+
+        cls.style         = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
+        cls.lpfnWndProc   = DefWindowProcA;
+        cls.cbClsExtra    = 0;
+        cls.cbWndExtra    = 0;
+        cls.hInstance     = 0;
+        cls.hIcon         = LoadIconA (0, (LPSTR)IDI_APPLICATION);
+        cls.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROW);
+        cls.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+        cls.lpszMenuName  = 0;
+        cls.lpszClassName = className;
+
+        RegisterClassA (&cls);
+        registered = 1;
+    }
+
+    /* Setup window */
+    hWnd = CreateWindowA (className, winName,
+       WS_OVERLAPPEDWINDOW ,
+       CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
+       0, hinst, 0);
+
+#ifdef VISIBLE
+    ShowWindow (hWnd, SW_SHOW);
+#endif
+    REDRAW(hWnd);
+    WAIT;
+
+    return hWnd;
+}
+
+static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
+                      LPCSTR loc, BOOL clear)
+{
+    HDC hdc = NULL;
+#ifdef VISIBLE
+    if (!himl) return NULL;
+
+    SetWindowText(hwnd, loc);
+    hdc = GetDC(hwnd);
+    ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
+
+    REDRAW(hwnd);
+    WAIT;
+
+    if (clear)
+    {
+        BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
+        ReleaseDC(hwnd, hdc);
+        hdc = NULL;
+    }
+#endif /* VISIBLE */
+    return hdc;
+}
+
+/* Useful for checking differences */
+#if 0
+static void dump_bits(const BYTE *p, const BYTE *q, int size)
+{
+  int i, j;
+
+  size /= 8;
+
+  for (i = 0; i < size * 2; i++)
+  {
+      printf("|");
+      for (j = 0; j < size; j++)
+          printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
+      printf(" -- ");
+      for (j = 0; j < size; j++)
+          printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
+      printf("|\n");
+      p += size * 4;
+      q += size * 4;
+  }
+  printf("\n");
+}
+#endif
+
+static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
+                       const BYTE *checkbits, LPCSTR loc)
+{
+#ifdef VISIBLE
+    BYTE bits[100*100/8];
+    COLORREF c;
+    HDC hdc;
+    int x, y, i = -1;
+
+    if (!himl) return;
+
+    memset(bits, 0, sizeof(bits));
+    hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
+
+    c = GetPixel(hdc, 0, 0);
+
+    for (y = 0; y < size; y ++)
+    {
+        for (x = 0; x < size; x++)
+        {
+            if (!(x & 0x7)) i++;
+            if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
+        }
+    }
+
+    BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
+    ReleaseDC(hwnd, hdc);
+
+    ok (memcmp(bits, checkbits, (size * size)/8) == 0,
+        "%s: bits different\n", loc);
+    if (memcmp(bits, checkbits, (size * size)/8))
+        dump_bits(bits, checkbits, size);
+#endif /* VISIBLE */
+}
+
+static void testHotspot (void)
+{
+    struct hotspot {
+        int dx;
+        int dy;
+    };
+
+#define SIZEX1 47
+#define SIZEY1 31
+#define SIZEX2 11
+#define SIZEY2 17
+#define HOTSPOTS_MAX 4       /* Number of entries in hotspots */
+    static const struct hotspot hotspots[HOTSPOTS_MAX] = {
+        { 10, 7 },
+        { SIZEX1, SIZEY1 },
+        { -9, -8 },
+        { -7, 35 }
+    };
+    int i, j, ret;
+    HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
+    HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
+    HWND hwnd = create_a_window();
+
+
+    for (i = 0; i < HOTSPOTS_MAX; i++) {
+        for (j = 0; j < HOTSPOTS_MAX; j++) {
+            int dx1 = hotspots[i].dx;
+            int dy1 = hotspots[i].dy;
+            int dx2 = hotspots[j].dx;
+            int dy2 = hotspots[j].dy;
+            int correctx, correcty, newx, newy;
+            char loc[256];
+            HIMAGELIST himlNew;
+            POINT ppt;
+
+            ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
+            ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
+            sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
+            show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
+
+            /* check merging the dragged image with a second image */
+            ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
+            ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
+                    dx1, dy1, dx2, dy2);
+            sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
+            show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
+
+            /* check new hotspot, it should be the same like the old one */
+            himlNew = ImageList_GetDragImage(NULL, &ppt);
+            ok(ppt.x == dx1 && ppt.y == dy1,
+                    "Expected drag hotspot [%d,%d] got [%ld,%ld]\n",
+                    dx1, dy1, ppt.x, ppt.y);
+            /* check size of new dragged image */
+            ImageList_GetIconSize(himlNew, &newx, &newy);
+            correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
+            correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
+            ok(newx == correctx && newy == correcty,
+                    "Expected drag image size [%d,%d] got [%d,%d]\n",
+                    correctx, correcty, newx, newy);
+            sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
+            show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
+            ImageList_EndDrag();
+        }
+    }
+#undef SIZEX1
+#undef SIZEY1
+#undef SIZEX2
+#undef SIZEY2
+#undef HOTSPOTS_MAX
+    DestroyWindow(hwnd);
+}
+
+static BOOL DoTest1(void)
+{
+    HIMAGELIST himl ;
+
+    HICON hicon1 ;
+    HICON hicon2 ;
+    HICON hicon3 ;
+
+    /* create an imagelist to play with */
+    himl = ImageList_Create(84,84,0x10,0,3);
+    ok(himl!=0,"failed to create imagelist\n");
+
+    /* load the icons to add to the image list */
+    hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon1 != 0, "no hicon1\n");
+    hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon2 != 0, "no hicon2\n");
+    hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon3 != 0, "no hicon3\n");
+
+    /* remove when nothing exists */
+    ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
+    /* removing everything from an empty imagelist should succeed */
+    ok(ImageList_RemoveAll(himl),"removed nonexistent icon\n");
+
+    /* add three */
+    ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
+    ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
+    ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
+
+    /* remove an index out of range */
+    ok(!ImageList_Remove(himl,4711),"removed nonexistent icon\n");
+
+    /* remove three */
+    ok(ImageList_Remove(himl,0),"can't remove 0\n");
+    ok(ImageList_Remove(himl,0),"can't remove 0\n");
+    ok(ImageList_Remove(himl,0),"can't remove 0\n");
+
+    /* remove one extra */
+    ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
+
+    /* destroy it */
+    ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
+
+    /* icons should be deleted by the imagelist */
+    ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
+    ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
+    ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
+
+    return TRUE;
+}
+
+static BOOL DoTest2(void)
+{
+    HIMAGELIST himl ;
+
+    HICON hicon1 ;
+    HICON hicon2 ;
+    HICON hicon3 ;
+
+    /* create an imagelist to play with */
+    himl = ImageList_Create(84,84,0x10,0,3);
+    ok(himl!=0,"failed to create imagelist\n");
+
+    /* load the icons to add to the image list */
+    hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon1 != 0, "no hicon1\n");
+    hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon2 != 0, "no hicon2\n");
+    hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon3 != 0, "no hicon3\n");
+
+    /* add three */
+    ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
+    ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
+    ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
+
+    /* destroy it */
+    ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
+
+    /* icons should be deleted by the imagelist */
+    ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
+    ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
+    ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
+
+    return TRUE;
+}
+
+static BOOL DoTest3(void)
+{
+    HIMAGELIST himl;
+
+    HBITMAP hbm1;
+    HBITMAP hbm2;
+    HBITMAP hbm3;
+
+    IMAGELISTDRAWPARAMS imldp;
+    HDC hdc;
+    HWND hwndfortest;
+
+    if (!pImageList_DrawIndirect)
+    {
+        HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
+        pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
+        if (!pImageList_DrawIndirect)
+        {
+            trace("ImageList_DrawIndirect not available, skipping test\n");
+            return TRUE;
+        }
+    }
+
+    hwndfortest = create_a_window();
+    hdc = GetDC(hwndfortest);
+    ok(hdc!=NULL, "couldn't get DC\n");
+
+    /* create an imagelist to play with */
+    himl = ImageList_Create(48,48,0x10,0,3);
+    ok(himl!=0,"failed to create imagelist\n");
+
+    /* load the icons to add to the image list */
+    hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
+    ok(hbm1 != 0, "no bitmap 1\n");
+    hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
+    ok(hbm2 != 0, "no bitmap 2\n");
+    hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
+    ok(hbm3 != 0, "no bitmap 3\n");
+
+    /* add three */
+    ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
+    ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
+
+    ok(ImageList_SetImageCount(himl,3),"Setimage count failed\n");
+    /*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
+    ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
+
+    memset(&imldp, 0, sizeof (imldp));
+    ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
+    imldp.cbSize = sizeof (imldp);
+    ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
+    imldp.hdcDst = hdc;
+    ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
+    imldp.himl = himl;
+    if (!pImageList_DrawIndirect(&imldp))
+    {
+      /* Earlier versions of native comctl32 use a smaller structure */
+      imldp.cbSize -= 3 * sizeof(DWORD);
+      ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n");
+    }
+    REDRAW(hwndfortest);
+    WAIT;
+
+    imldp.fStyle = SRCCOPY;
+    imldp.rgbBk = CLR_DEFAULT;
+    imldp.rgbFg = CLR_DEFAULT;
+    imldp.y = 100;
+    imldp.x = 100;
+    ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
+    imldp.i ++;
+    ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
+    imldp.i ++;
+    ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
+    imldp.i ++;
+    ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
+
+    /* remove three */
+    ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
+    ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
+    ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
+
+    /* destroy it */
+    ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
+
+    /* bitmaps should not be deleted by the imagelist */
+    ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
+    ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
+    ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
+
+    ReleaseDC(hwndfortest, hdc);
+    DestroyWindow(hwndfortest);
+
+    return TRUE;
+}
+
+static void testMerge()
+{
+    HIMAGELIST himl1, himl2, hmerge;
+    HICON hicon1;
+    HWND hwnd = create_a_window();
+
+    himl1 = ImageList_Create(32,32,0,0,3);
+    ok(himl1 != NULL,"failed to create himl1\n");
+
+    himl2 = ImageList_Create(32,32,0,0,3);
+    ok(himl2 != NULL,"failed to create himl2\n");
+
+    hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
+    ok(hicon1 != NULL, "failed to create hicon1\n");
+
+    if (!himl1 || !himl2 || !hicon1)
+        return;
+
+    ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
+    check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
+
+    /* If himl1 has no images, merge still succeeds */
+    hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
+    ok(hmerge != NULL, "merge himl1,-1 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
+    ok(hmerge != NULL,"merge himl1,0 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    /* Same happens if himl2 is empty */
+    ImageList_Destroy(himl2);
+    himl2 = ImageList_Create(32,32,0,0,3);
+    ok(himl2 != NULL,"failed to recreate himl2\n");
+    if (!himl2)
+        return;
+
+    hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
+    ok(hmerge != NULL, "merge himl2,-1 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
+    ok(hmerge != NULL, "merge himl2,0 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    /* Now try merging an image with itself */
+    ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
+
+    hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
+    ok(hmerge != NULL, "merge himl2 with itself failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    /* Try merging 2 different image lists */
+    ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
+
+    hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
+    ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
+    ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
+    check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
+    if (hmerge) ImageList_Destroy(hmerge);
+
+    ImageList_Destroy(himl1);
+    ImageList_Destroy(himl2);
+    DeleteObject(hicon1);
+    DestroyWindow(hwnd);
+}
+
+START_TEST(imagelist)
+{
+    desktopDC=GetDC(NULL);
+    hinst = GetModuleHandleA(NULL);
+
+    InitCommonControls();
+
+    testHotspot();
+    DoTest1();
+    DoTest2();
+    DoTest3();
+    testMerge();
+}
diff --git a/reactos/lib/comctl32/winetests/makefile b/reactos/lib/comctl32/winetests/makefile
new file mode 100644 (file)
index 0000000..12a68aa
--- /dev/null
@@ -0,0 +1,31 @@
+# $Id: Makefile 12745 2005-01-03 02:37:10Z sedwards $\r
+\r
+PATH_TO_TOP = ../../..\r
+\r
+TARGET_NORC = yes\r
+\r
+TARGET_TYPE = program\r
+\r
+TARGET_APPTYPE = console\r
+\r
+# require os code to explicitly request A/W version of structs/functions\r
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \\r
+       -D_WIN32_WINNT=0x0501 -D__REACTOS__\r
+\r
+TARGET_NAME = comctl32_test\r
+\r
+TARGET_SDKLIBS = shlwapi.a gdi32.a comctl32.a ntdll.a wine.a\r
+\r
+TARGET_OBJECTS = \\r
+       testlist.o \\r
+       dpa.o \\r
+       imagelist.o \\r
+       mru.o \\r
+       subclass.o \\r
+       tab.o\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+# EOF
\ No newline at end of file
diff --git a/reactos/lib/comctl32/winetests/mru.c b/reactos/lib/comctl32/winetests/mru.c
new file mode 100644 (file)
index 0000000..da9e989
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * comctl32 MRU unit tests
+ *
+ * Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "winreg.h"
+#include "commctrl.h"
+#include "shlwapi.h"
+
+#include "wine/test.h"
+
+/* Keys for testing MRU functions */
+#define REG_TEST_BASEKEYA    "Software\\Wine"
+#define REG_TEST_BASESUBKEYA "Test"
+#define REG_TEST_KEYA    REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
+#define REG_TEST_SUBKEYA "MRUTest"
+#define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
+
+/* Undocumented MRU structures & functions */
+typedef struct tagCREATEMRULISTA
+{
+    DWORD   cbSize;
+    DWORD   nMaxItems;
+    DWORD   dwFlags;
+    HKEY    hKey;
+    LPCSTR  lpszSubKey;
+    PROC    lpfnCompare;
+} CREATEMRULISTA, *LPCREATEMRULISTA;
+
+#define MRUF_STRING_LIST  0
+#define MRUF_BINARY_LIST  1
+#define MRUF_DELAYED_SAVE 2
+
+#define LIST_SIZE 3 /* Max entries for each mru */
+
+static CREATEMRULISTA mruA =
+{
+    sizeof(CREATEMRULISTA),
+    LIST_SIZE,
+    0,
+    NULL,
+    REG_TEST_SUBKEYA,
+    NULL
+};
+
+static HMODULE hComctl32;
+static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA);
+static void   (WINAPI *pFreeMRUList)(HANDLE);
+static INT    (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
+/*
+static INT    (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
+static INT    (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
+*/
+
+static BOOL create_reg_entries(void)
+{
+    HKEY hKey = NULL;
+
+    ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
+       "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
+    if (!hKey) return FALSE;
+    RegCloseKey(hKey);
+    return TRUE;
+}
+
+static void delete_reg_entries(void)
+{
+    HKEY hKey;
+
+    if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_BASEKEYA, 0, KEY_ALL_ACCESS,
+                      &hKey))
+        return;
+    SHDeleteKeyA(hKey, REG_TEST_BASESUBKEYA);
+    RegCloseKey(hKey);
+}
+
+static void check_reg_entries(const char *mrulist, const char**items)
+{
+    char buff[128];
+    HKEY hKey = NULL;
+    DWORD type, size, ret;
+    size_t i;
+
+    ok(!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
+       "Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
+    if (!hKey) return;
+
+    type = REG_SZ;
+    size = sizeof(buff);
+    buff[0] = '\0';
+    ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
+
+    ok(!ret && buff[0], "Checking MRU: got %ld from RegQueryValueExW\n", ret);
+    if(ret || !buff[0]) return;
+
+    ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
+       mrulist, buff);
+    if(strcmp(buff, mrulist)) return;
+
+    for (i = 0; i < strlen(mrulist); i++)
+    {
+        char name[2];
+        name[0] = mrulist[i];
+        name[1] = '\0';
+        type = REG_SZ;
+        size = sizeof(buff);
+        buff[0] = '\0';
+        ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
+        ok(!ret && buff[0],
+           "Checking MRU item %d ('%c'): got %ld from RegQueryValueExW\n",
+           i, mrulist[i], ret);
+        if(ret || !buff[0]) return;
+        ok(!strcmp(buff, items[mrulist[i]-'a']),
+           "Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
+           i, mrulist[i], buff, items[mrulist[i] - 'a']);
+    }
+}
+
+static INT CALLBACK cmp_mru_strA(LPCVOID data1, LPCVOID data2)
+{
+    return lstrcmpiA(data1, data2);
+}
+
+static HANDLE create_mruA(HKEY hKey, DWORD flags, PROC cmp)
+{
+    mruA.dwFlags = flags;
+    mruA.lpfnCompare = cmp;
+    mruA.hKey = hKey;
+
+    SetLastError(0);
+    return pCreateMRUListA(&mruA);
+}
+
+static void test_MRUListA(void)
+{
+    const char *checks[LIST_SIZE+1];
+    HANDLE hMRU;
+    HKEY hKey;
+    INT iRet;
+
+    pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
+    pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
+    pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
+    if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA)
+        return;
+
+#if 0 /* Create (NULL) - crashes native */
+    hMRU = pCreateMRUListA(NULL);
+#endif
+
+    /* Create (size too small) */
+    mruA.cbSize = sizeof(mruA) - 2;
+    hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
+    ok (!hMRU && !GetLastError(),
+        "CreateMRUListA(too small) expected NULL,0 got %p,%ld\n",
+        hMRU, GetLastError());
+    mruA.cbSize = sizeof(mruA);
+
+    /* Create (size too big) */
+    mruA.cbSize = sizeof(mruA) + 2;
+    hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
+    ok (!hMRU && !GetLastError(),
+        "CreateMRUListA(too big) expected NULL,0 got %p,%ld\n",
+        hMRU, GetLastError());
+    mruA.cbSize = sizeof(mruA);
+
+    /* Create (NULL hKey) */
+    hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
+    ok (!hMRU && !GetLastError(),
+        "CreateMRUListA(NULL key) expected NULL,0 got %p,%ld\n",
+        hMRU, GetLastError());
+
+    /* Create (NULL name) */
+    mruA.lpszSubKey = NULL;
+    hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
+    ok (!hMRU && !GetLastError(),
+        "CreateMRUListA(NULL name) expected NULL,0 got %p,%ld\n",
+        hMRU, GetLastError());
+    mruA.lpszSubKey = REG_TEST_SUBKEYA;
+
+    /* Create a string MRU */
+    ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
+       "Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
+    if (!hKey)
+        return;
+    hMRU = create_mruA(hKey, MRUF_STRING_LIST, cmp_mru_strA);
+    ok(hMRU && !GetLastError(),
+       "CreateMRUListA(string) expected non-NULL,0 got %p,%ld\n",
+       hMRU, GetLastError());
+
+    if (hMRU)
+    {
+        checks[0] = "Test 1";
+        checks[1] = "Test 2";
+        checks[2] = "Test 3";
+        checks[3] = "Test 4";
+
+        /* Add (NULL list) */
+        SetLastError(0);
+        iRet = pAddMRUStringA(NULL, checks[0]);
+        ok(iRet == -1 && !GetLastError(),
+           "AddMRUStringA(NULL list) expected -1,0 got %d,%ld\n",
+           iRet, GetLastError());
+
+        /* Add (NULL string) */
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, NULL);
+        ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
+           "AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%ld\n",
+           iRet, GetLastError());
+
+        /* Add 3 strings. Check the registry is correct after each add */
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, checks[0]);
+        ok(iRet == 0 && !GetLastError(),
+           "AddMRUStringA(1) expected 0,0 got %d,%ld\n",
+           iRet, GetLastError());
+        check_reg_entries("a", checks);
+
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, checks[1]);
+        ok(iRet == 1 && !GetLastError(),
+           "AddMRUStringA(2) expected 1,0 got %d,%ld\n",
+           iRet, GetLastError());
+        check_reg_entries("ba", checks);
+
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, checks[2]);
+        ok(iRet == 2 && !GetLastError(),
+           "AddMRUStringA(2) expected 2,0 got %d,%ld\n",
+           iRet, GetLastError());
+        check_reg_entries("cba", checks);
+
+        /* Add a duplicate of the 2nd string - it should move to the front,
+         * but keep the same index in the registry.
+         */
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, checks[1]);
+        ok(iRet == 1 && !GetLastError(),
+           "AddMRUStringA(re-add 1) expected 1,0 got %d,%ld\n",
+           iRet, GetLastError());
+        check_reg_entries("bca", checks);
+
+        /* Add a new string - replaces the oldest string + moves to the front */
+        SetLastError(0);
+        iRet = pAddMRUStringA(hMRU, checks[3]);
+        ok(iRet == 0 && !GetLastError(),
+           "AddMRUStringA(add new) expected 0,0 got %d,%ld\n",
+           iRet, GetLastError());
+        checks[0] = checks[3];
+        check_reg_entries("abc", checks);
+
+        /* Finished with this MRU */
+        pFreeMRUList(hMRU);
+    }
+
+    /* Free (NULL list) - Doesn't crash */
+    pFreeMRUList(NULL);
+}
+
+START_TEST(mru)
+{
+    hComctl32 = GetModuleHandleA("comctl32.dll");
+    if (!hComctl32)
+        return;
+
+    delete_reg_entries();
+    if (!create_reg_entries())
+        return;
+
+    test_MRUListA();
+
+    delete_reg_entries();
+}
diff --git a/reactos/lib/comctl32/winetests/subclass.c b/reactos/lib/comctl32/winetests/subclass.c
new file mode 100644 (file)
index 0000000..268eed9
--- /dev/null
@@ -0,0 +1,298 @@
+/* Unit tests for subclassed windows.
+ *
+ * Copyright 2004 Kevin Koltzau
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+
+#define _WIN32_WINNT 0x0501 /* For SetWindowSubclass/etc */
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "commctrl.h"
+
+#include "wine/test.h"
+
+static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
+static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
+static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
+
+#define SEND_NEST   0x01
+#define DELETE_SELF 0x02
+#define DELETE_PREV 0x04
+
+struct message {
+    int procnum;           /* WndProc id message is expected from */
+    WPARAM wParam;         /* expected value of wParam */
+};
+
+static int sequence_cnt, sequence_size;
+static struct message* sequence;
+
+static const struct message Sub_BasicTest[] = {
+    { 2, 1 },
+    { 1, 1 },
+    { 2, 2 },
+    { 1, 2 },
+    { 0 }
+};
+
+static const struct message Sub_DeletedTest[] = {
+    { 2, 1 },
+    { 1, 1 },
+    { 0 }
+};
+
+static const struct message Sub_AfterDeletedTest[] = {
+    { 1, 1 },
+    { 0 }
+};
+
+static const struct message Sub_OldAfterNewTest[] = {
+    { 3, 1 },
+    { 2, 1 },
+    { 1, 1 },
+    { 3, 2 },
+    { 2, 2 },
+    { 1, 2 },
+    { 0 }
+};
+
+static const struct message Sub_MixTest[] = {
+    { 3, 1 },
+    { 4, 1 },
+    { 2, 1 },
+    { 1, 1 },
+    { 0 }
+};
+
+static const struct message Sub_MixAndNestTest[] = {
+    { 3, 1 },
+    { 4, 1 },
+    { 3, 2 },
+    { 4, 2 },
+    { 2, 2 },
+    { 1, 2 },
+    { 2, 1 },
+    { 1, 1 },
+    { 0 }
+};
+
+static const struct message Sub_MixNestDelTest[] = {
+    { 3, 1 },
+    { 4, 1 },
+    { 3, 2 },
+    { 2, 2 },
+    { 1, 2 },
+    { 2, 1 },
+    { 1, 1 },
+    { 0 }
+};
+
+static const struct message Sub_MixDelPrevTest[] = {
+    { 3, 1 },
+    { 5, 1 },
+    { 2, 1 },
+    { 1, 1 },
+    { 0 }
+};
+
+static void add_message(const struct message *msg)
+{
+    if (!sequence)
+    {
+        sequence_size = 10;
+        sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
+    }
+    if (sequence_cnt == sequence_size)
+    {
+        sequence_size *= 2;
+        sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
+    }
+    assert(sequence);
+
+    sequence[sequence_cnt].wParam  = msg->wParam;
+    sequence[sequence_cnt].procnum = msg->procnum;
+
+    sequence_cnt++;
+}
+
+static void flush_sequence()
+{
+    HeapFree(GetProcessHeap(), 0, sequence);
+    sequence = 0;
+    sequence_cnt = sequence_size = 0;
+}
+
+static void ok_sequence(const struct message *expected, const char *context)
+{
+    static const struct message end_of_sequence = { 0, 0 };
+    const struct message *actual;
+
+    add_message(&end_of_sequence);
+
+    actual = sequence;
+
+    while(expected->procnum && actual->procnum)
+    {
+        ok(expected->procnum == actual->procnum,
+            "%s: the procnum %d was expected, but got procnum %d instead\n",
+            context, expected->procnum, actual->procnum);
+        ok(expected->wParam == actual->wParam,
+            "%s: in procnum %d expecting wParam 0x%x got 0x%x\n",
+            context, expected->procnum, expected->wParam, actual->wParam);
+        expected++;
+        actual++;
+    }
+    ok(!expected->procnum, "Received fewer messages than expected\n");
+    ok(!actual->procnum, "Received more messages than expected\n");
+    flush_sequence();
+}
+
+static LRESULT WINAPI WndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct message msg;
+    
+    if(message == WM_USER) {
+        msg.wParam = wParam;
+        msg.procnum = 1;
+        add_message(&msg);
+    }
+    return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+
+static WNDPROC origProc3;
+static LRESULT WINAPI WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct message msg;
+    
+    if(message == WM_USER) {
+        msg.wParam = wParam;
+        msg.procnum = 3;
+        add_message(&msg);
+    }
+    return CallWindowProc(origProc3, hwnd, message, wParam, lParam);
+}
+
+static LRESULT WINAPI WndProcSub(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uldSubclass, DWORD_PTR dwRefData)
+{
+    struct message msg;
+    
+    if(message == WM_USER) {
+        msg.wParam = wParam;
+        msg.procnum = uldSubclass;
+        add_message(&msg);
+        
+        if(lParam) {
+            if(dwRefData & DELETE_SELF) {
+                pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass);
+                pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass);
+            }
+            if(dwRefData & DELETE_PREV)
+                pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass-1);
+            if(dwRefData & SEND_NEST)
+                SendMessage(hwnd, WM_USER, wParam+1, 0);
+        }
+    }
+    return pDefSubclassProc(hwnd, message, wParam, lParam);
+}
+
+static void test_subclass()
+{
+    HWND hwnd = CreateWindowExA(0, "TestSubclass", "Test subclass", WS_OVERLAPPEDWINDOW,
+                           100, 100, 200, 200, 0, 0, 0, NULL);
+    assert(hwnd);
+
+    pSetWindowSubclass(hwnd, WndProcSub, 2, 0);
+    SendMessage(hwnd, WM_USER, 1, 0);
+    SendMessage(hwnd, WM_USER, 2, 0);
+    ok_sequence(Sub_BasicTest, "Basic");
+
+    pSetWindowSubclass(hwnd, WndProcSub, 2, DELETE_SELF);
+    SendMessage(hwnd, WM_USER, 1, 1);
+    ok_sequence(Sub_DeletedTest, "Deleted");
+
+    SendMessage(hwnd, WM_USER, 1, 0);
+    ok_sequence(Sub_AfterDeletedTest, "After Deleted");
+
+    pSetWindowSubclass(hwnd, WndProcSub, 2, 0);
+    origProc3 = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WndProc3);
+    SendMessage(hwnd, WM_USER, 1, 0);
+    SendMessage(hwnd, WM_USER, 2, 0);
+    ok_sequence(Sub_OldAfterNewTest, "Old after New");
+
+    pSetWindowSubclass(hwnd, WndProcSub, 4, 0);
+    SendMessage(hwnd, WM_USER, 1, 0);
+    ok_sequence(Sub_MixTest, "Mix");
+
+    /* Now the fun starts */
+    pSetWindowSubclass(hwnd, WndProcSub, 4, SEND_NEST);
+    SendMessage(hwnd, WM_USER, 1, 1);
+    ok_sequence(Sub_MixAndNestTest, "Mix and nest");
+
+    pSetWindowSubclass(hwnd, WndProcSub, 4, SEND_NEST | DELETE_SELF);
+    SendMessage(hwnd, WM_USER, 1, 1);
+    ok_sequence(Sub_MixNestDelTest, "Mix, nest, del");
+
+    pSetWindowSubclass(hwnd, WndProcSub, 4, 0);
+    pSetWindowSubclass(hwnd, WndProcSub, 5, DELETE_PREV);
+    SendMessage(hwnd, WM_USER, 1, 1);
+    ok_sequence(Sub_MixDelPrevTest, "Mix and del prev");
+
+    DestroyWindow(hwnd);
+}
+
+static BOOL RegisterWindowClasses(void)
+{
+    WNDCLASSA cls;
+
+    cls.style = 0;
+    cls.lpfnWndProc = WndProc1;
+    cls.cbClsExtra = 0;
+    cls.cbWndExtra = 0;
+    cls.hInstance = GetModuleHandleA(0);
+    cls.hIcon = 0;
+    cls.hCursor = NULL;
+    cls.hbrBackground = NULL;
+    cls.lpszMenuName = NULL;
+    cls.lpszClassName = "TestSubclass";
+    if(!RegisterClassA(&cls)) return FALSE;
+    
+    return TRUE;
+}
+
+START_TEST(subclass)
+{
+    HMODULE hdll;
+    
+    hdll = GetModuleHandleA("comctl32.dll");
+    assert(hdll);
+    pSetWindowSubclass = (void*)GetProcAddress(hdll, "SetWindowSubclass");
+    pRemoveWindowSubclass = (void*)GetProcAddress(hdll, "RemoveWindowSubclass");
+    pDefSubclassProc = (void*)GetProcAddress(hdll, "DefSubclassProc");
+    
+    if(!pSetWindowSubclass || !pRemoveWindowSubclass || !pDefSubclassProc)
+        return;
+
+    if(!RegisterWindowClasses()) assert(0);
+
+    test_subclass();
+}
diff --git a/reactos/lib/comctl32/winetests/tab.c b/reactos/lib/comctl32/winetests/tab.c
new file mode 100644 (file)
index 0000000..23234d3
--- /dev/null
@@ -0,0 +1,197 @@
+/* Unit test suite for tab control.
+ *
+ * Copyright 2003 Vitaliy Margolen
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include <windows.h>
+#include <commctrl.h>
+
+#include "wine/test.h"
+
+#undef VISIBLE
+
+#define TAB_DEFAULT_WIDTH 96
+#define TAB_PADDING_X 2
+#define TAB_PADDING_Y 2
+
+#ifdef VISIBLE
+#define WAIT Sleep (1000)
+#define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
+#define trace_tab(str) trace(str)
+#else
+#define WAIT
+#define REDRAW(hwnd)
+#define trace_tab(str)
+#endif
+
+HWND
+create_tabcontrol (DWORD style)
+{
+    HWND handle;
+    TCITEM tcNewTab;
+
+    handle = CreateWindow (
+       WC_TABCONTROLA,
+       "TestTab",
+       WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
+        10, 10, 300, 100,
+        NULL, NULL, NULL, 0);
+
+    assert (handle);
+    
+    SetWindowLong(handle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style);
+
+    tcNewTab.mask = TCIF_TEXT | TCIF_IMAGE;
+    tcNewTab.pszText = "Tab 1";
+    tcNewTab.iImage = 0;
+    SendMessage (handle, TCM_INSERTITEM, 0, (LPARAM) &tcNewTab);
+    tcNewTab.pszText = "Wide Tab 2";
+    tcNewTab.iImage = 1;
+    SendMessage (handle, TCM_INSERTITEM, 1, (LPARAM) &tcNewTab);
+    tcNewTab.pszText = "T 3";
+    tcNewTab.iImage = 2;
+    SendMessage (handle, TCM_INSERTITEM, 2, (LPARAM) &tcNewTab);
+
+#ifdef VISIBLE
+    ShowWindow (handle, SW_SHOW);
+#endif
+    REDRAW(handle);
+    WAIT;
+
+    return handle;
+}
+
+void CheckSize(HWND hwnd, INT width, INT height)
+{
+    RECT rTab, r1;
+
+    r1.left=r1.top=r1.right=r1.bottom=0;
+    SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);
+    SendMessage (hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) &r1);
+    /* trace ("Got (%ld,%ld)-(%ld,%ld)\n", rTab.left, rTab.top, rTab.right, rTab.bottom); */
+    trace (" (%ld,%ld)-(%ld,%ld)\n", r1.left, r1.top, r1.right, r1.bottom);
+    if ((width  >= 0) && (height < 0))
+       ok (width  == rTab.right  - rTab.left, "Expected [%d] got [%ld]\n",  width,  rTab.right  - rTab.left);
+    else if ((height >= 0) && (width  < 0))
+       ok (height == rTab.bottom - rTab.top,  "Expected [%d] got [%ld]\n",  height, rTab.bottom - rTab.top);
+    else
+       ok ((width  == rTab.right  - rTab.left) &&
+           (height == rTab.bottom - rTab.top ),
+           "Expected [%d,%d] got [%ld,%ld]\n", width, height, rTab.right - rTab.left, rTab.bottom - rTab.top);
+}
+
+void TabCheckSetSize(HWND hwnd, INT SetWidth, INT SetHeight, INT ExpWidth, INT ExpHeight)
+{
+    SendMessage (hwnd, TCM_SETITEMSIZE, 0,
+       (LPARAM) MAKELPARAM((SetWidth >= 0) ? SetWidth:0, (SetHeight >= 0) ? SetHeight:0));
+    REDRAW(hwnd);
+    CheckSize(hwnd, ExpWidth, ExpHeight);
+    WAIT;
+}
+
+START_TEST(tab)
+{
+    HWND hwTab;
+    HIMAGELIST himl = ImageList_Create(21, 21, ILC_COLOR, 3, 4);
+
+    InitCommonControls();
+
+
+    hwTab = create_tabcontrol(TCS_FIXEDWIDTH);
+
+    trace_tab ("Testing TCS_FIXEDWIDTH tabs no icon...\n");
+    trace_tab ("  default width...\n");
+    CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
+    trace_tab ("  set size...\n");
+    TabCheckSetSize(hwTab, 50, 20, 50, 20);
+    WAIT;
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 0, 1);
+    WAIT;
+
+    SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
+
+    trace_tab ("Testing TCS_FIXEDWIDTH tabs with icon...\n");
+    trace_tab ("  set size > icon...\n");
+    TabCheckSetSize(hwTab, 50, 30, 50, 30);
+    trace_tab ("  set size < icon...\n");
+    TabCheckSetSize(hwTab, 20, 20, 25, 20);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+
+    DestroyWindow (hwTab);
+
+    trace_tab ("Testing TCS_FIXEDWIDTH buttons no icon...\n");
+    hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS);
+
+    trace_tab ("  default width...\n");
+    CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
+    trace_tab ("  set size 1...\n");
+    TabCheckSetSize(hwTab, 20, 20, 20, 20);
+    trace_tab ("  set size 2...\n");
+    TabCheckSetSize(hwTab, 10, 50, 10, 50);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 0, 1);
+
+    SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
+
+    trace_tab ("Testing TCS_FIXEDWIDTH buttons with icon...\n");
+    trace_tab ("  set size > icon...\n");
+    TabCheckSetSize(hwTab, 50, 30, 50, 30);
+    trace_tab ("  set size < icon...\n");
+    TabCheckSetSize(hwTab, 20, 20, 25, 20);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+    trace_tab (" Add padding...\n");
+    SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+
+    DestroyWindow (hwTab);
+
+    hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM);
+    trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs no icon...\n");
+
+    trace_tab ("  default width...\n");
+    CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
+    trace_tab ("  set size 1...\n");
+    TabCheckSetSize(hwTab, 20, 20, 20, 20);
+    trace_tab ("  set size 2...\n");
+    TabCheckSetSize(hwTab, 10, 50, 10, 50);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 0, 1);
+
+    SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
+    
+    trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs with icon...\n");
+    trace_tab ("  set size > icon...\n");
+    TabCheckSetSize(hwTab, 50, 30, 50, 30);
+    trace_tab ("  set size < icon...\n");
+    TabCheckSetSize(hwTab, 20, 20, 25, 20);
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+    trace_tab (" Add padding...\n");
+    SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
+    trace_tab ("  min size...\n");
+    TabCheckSetSize(hwTab, 0, 1, 25, 1);
+
+    DestroyWindow (hwTab);
+
+
+    ImageList_Destroy(himl);
+}
diff --git a/reactos/lib/comctl32/winetests/testlist.c b/reactos/lib/comctl32/winetests/testlist.c
new file mode 100644 (file)
index 0000000..8a3d396
--- /dev/null
@@ -0,0 +1,33 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+/* stdarg.h is needed for Winelib */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+
+extern void func_dpa(void);
+extern void func_imagelist(void);
+extern void func_mru(void);
+extern void func_subclass(void);
+extern void func_tab(void);
+
+struct test
+{
+    const char *name;
+    void (*func)(void);
+};
+
+static const struct test winetest_testlist[] =
+{
+    { "dpa", func_dpa },
+    { "imagelist", func_imagelist },
+    { "mru", func_mru },
+    { "subclass", func_subclass },
+    { "tab", func_tab },
+    { 0, 0 }
+};
+
+#define WINETEST_WANT_MAIN
+#include "wine/test.h"
index eaf0eb5..1790aef 100644 (file)
@@ -131,8 +131,8 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
  *     COMDLG32_AllocMem                       (internal)\r
  * Get memory for internal datastructure plus stringspace etc.\r
  *     RETURNS\r
- *             Pointer to a heap block: Succes\r
- *             NULL: Failure\r
+ *             Success: Pointer to a heap block\r
+ *             Failure: null\r
  */\r
 LPVOID COMDLG32_AllocMem(\r
        int size        /* [in] Block size to allocate */\r
index a18ad98..4f8820c 100644 (file)
@@ -470,33 +470,6 @@ STRINGTABLE DISCARDABLE
     IDS_OPEN_FILE   "Open File"\r
 }\r
 \r
-/* Translators do not need to translate this text, unless the language uses a\r
- * different character set or if the distribution of characters looks wrong.\r
- * It is rendered illegibly small and is used to make a mock-up of a document.\r
- */\r
-STRINGTABLE DISCARDABLE\r
-{\r
-    IDS_FAKEDOCTEXT\r
-        "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \\r
-        Nulla a tortor. Etiam aliquet libero venenatis nunc. \n \\r
-        \n \\r
-        Sed augue ante, fermentum sit amet, imperdiet et, gravida eu, enim. \\r
-        Donec nibh quam, sodales in, commodo vel, facilisis id, neque. \n \\r
-        \n \\r
-        Nunc eleifend bibendum nibh. Phasellus in lorem. Ut vel odio quis \\r
-        libero adipiscing consequat. Donec consectetuer laoreet mauris. \n \\r
-        \n \\r
-        Maecenas tempor, ligula sed congue nonummy, arcu dolor ornare erat, \\r
-        egestas iaculis magna purus sed turpis. \n \\r
-        \n \\r
-        Morbi ultricies est non ipsum. Cum sociis natoque penatibus et magnis \\r
-        dis parturient montes, nascetur ridiculus mus. \n \\r
-        \n \\r
-        Duis sit amet nibh quis purus sollicitudin blandit. Curabitur justo. \\r
-        Phasellus varius, erat eu luctus pharetra, odio elit fringilla leo, \\r
-        non vulputate turpis elit id neque. Vestibulum sit amet tellus sed \\r
-        tortor fermentum consectetuer."\r
-}\r
 \r
 /****************************************************************/\r
 /* English neutral resources\r
index fe46629..1489a02 100644 (file)
@@ -21,7 +21,7 @@
  * WARNING: DO NOT CHANGE THE SIZE OF THE STANDARD DIALOG TEMPLATES.\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
index af0258b..446be3f 100644 (file)
@@ -458,3 +458,13 @@ STRINGTABLE DISCARDABLE /* Nomes de cores */
     IDS_COLOR_AQUA      "Azul-piscina"\r
     IDS_COLOR_WHITE     "Branco"\r
 }\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDS_FONT_SIZE   "Selecione o tamanho da fonte entre %d e %d pontos."\r
+    IDS_SAVE_BUTTON "&Salvar"\r
+    IDS_SAVE_IN     "Salvar &em:"\r
+    IDS_SAVE        "Salvar"\r
+    IDS_SAVE_AS     "Salvar como"\r
+    IDS_OPEN_FILE   "Abrir Arquivo"\r
+}\r
index a4a23a7..f03e4db 100644 (file)
@@ -32,6 +32,35 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 \r
 #include "wine/wine_common_ver.rc"\r
 \r
+/* Translators do not need to translate this text, unless the language uses a\r
+ * different character set or if the distribution of characters looks wrong.\r
+ * It is rendered illegibly small and is used to make a mock-up of a document.\r
+ */\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDS_FAKEDOCTEXT\r
+        "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \\r
+        Nulla a tortor. Etiam aliquet libero venenatis nunc. \n \\r
+        \n \\r
+        Sed augue ante, fermentum sit amet, imperdiet et, gravida eu, enim. \\r
+        Donec nibh quam, sodales in, commodo vel, facilisis id, neque. \n \\r
+        \n \\r
+        Nunc eleifend bibendum nibh. Phasellus in lorem. Ut vel odio quis \\r
+        libero adipiscing consequat. Donec consectetuer laoreet mauris. \n \\r
+        \n \\r
+        Maecenas tempor, ligula sed congue nonummy, arcu dolor ornare erat, \\r
+        egestas iaculis magna purus sed turpis. \n \\r
+        \n \\r
+        Morbi ultricies est non ipsum. Cum sociis natoque penatibus et magnis \\r
+        dis parturient montes, nascetur ridiculus mus. \n \\r
+        \n \\r
+        Duis sit amet nibh quis purus sollicitudin blandit. Curabitur justo. \\r
+        Phasellus varius, erat eu luctus pharetra, odio elit fringilla leo, \\r
+        non vulputate turpis elit id neque. Vestibulum sit amet tellus sed \\r
+        tortor fermentum consectetuer."\r
+}\r
+\r
+\r
 /* BINRES pd32_collate.ico */\r
 PD32_COLLATE ICON DISCARDABLE LOADONCALL pd32_collate.ico\r
 /* {\r
index 9898f0d..a9ff14f 100644 (file)
@@ -461,7 +461,7 @@ void CC_PaintTriangle( HWND hDlg, int y)
  int oben;\r
  RECT rect;\r
  HWND hwnd = GetDlgItem(hDlg, 0x2be);\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA( hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW( hDlg, DWLP_USER);\r
 \r
  if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6)))   /* if full size */\r
  {\r
@@ -480,7 +480,7 @@ void CC_PaintTriangle( HWND hDlg, int y)
    points[2].y = points[0].y - w;\r
    points[2].x = points[1].x = points[0].x + w;\r
 \r
-   FillRect(hDC, &lpp->old3angle, (HBRUSH)GetClassLongA( hwnd, GCL_HBRBACKGROUND));\r
+   FillRect(hDC, &lpp->old3angle, (HBRUSH)GetClassLongPtrW( hwnd, GCLP_HBRBACKGROUND));\r
    lpp->old3angle.left  = points[0].x;\r
    lpp->old3angle.right = points[1].x + 1;\r
    lpp->old3angle.top   = points[2].y - 1;\r
@@ -499,7 +499,7 @@ void CC_PaintCross( HWND hDlg, int x, int y)
  HDC hDC;\r
  int w = GetDialogBaseUnits();\r
  HWND hwnd = GetDlgItem(hDlg, 0x2c6);\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA( hDlg, DWL_USER );\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW( hDlg, DWLP_USER );\r
  RECT rect;\r
  POINT point, p;\r
  HPEN hPen;\r
@@ -544,11 +544,11 @@ static void CC_PrepareColorGraph( HWND hDlg )
 {\r
  int sdif, hdif, xdif, ydif, r, g, b, hue, sat;\r
  HWND hwnd = GetDlgItem(hDlg, 0x2c6);\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
  HBRUSH hbrush;\r
  HDC hdc ;\r
  RECT rect, client;\r
- HCURSOR hcursor = SetCursor( LoadCursorA(0, (LPSTR)IDC_WAIT) );\r
+ HCURSOR hcursor = SetCursor( LoadCursorW(0, (LPCWSTR)IDC_WAIT) );\r
 \r
  GetClientRect(hwnd, &client);\r
  hdc = GetDC(hwnd);\r
@@ -587,7 +587,7 @@ static void CC_PrepareColorGraph( HWND hDlg )
 static void CC_PaintColorGraph( HWND hDlg )\r
 {\r
  HWND hwnd = GetDlgItem( hDlg, 0x2c6 );\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
  HDC  hDC;\r
  RECT rect;\r
  if (IsWindowVisible(hwnd))   /* if full size */\r
@@ -647,7 +647,7 @@ static void CC_PaintLumBar( HWND hDlg, int hue, int sat )
 void CC_EditSetRGB( HWND hDlg, COLORREF cr )\r
 {\r
  char buffer[10];\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
  int r = GetRValue(cr);\r
  int g = GetGValue(cr);\r
  int b = GetBValue(cr);\r
@@ -670,7 +670,7 @@ void CC_EditSetRGB( HWND hDlg, COLORREF cr )
 void CC_EditSetHSL( HWND hDlg, int h, int s, int l )\r
 {\r
  char buffer[10];\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
  lpp->updating = TRUE;\r
  if (IsWindowVisible( GetDlgItem(hDlg, 0x2c6) ))   /* if full size */\r
  {\r
@@ -692,7 +692,7 @@ void CC_EditSetHSL( HWND hDlg, int h, int s, int l )
 void CC_SwitchToFullSize( HWND hDlg, COLORREF result, LPRECT lprect )\r
 {\r
  int i;\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
 \r
  EnableWindow( GetDlgItem(hDlg, 0x2cf), FALSE);\r
  CC_PrepareColorGraph(hDlg);\r
@@ -728,7 +728,7 @@ static void CC_PaintPredefColorArray( HWND hDlg, int rows, int cols)
  HDC  hdc;\r
  HBRUSH hBrush;\r
  int dx, dy, i, j, k;\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
 \r
  GetClientRect(hwnd, &rect);\r
  dx = rect.right / cols;\r
@@ -737,7 +737,7 @@ static void CC_PaintPredefColorArray( HWND hDlg, int rows, int cols)
 \r
  hdc = GetDC(hwnd);\r
  GetClientRect(hwnd, &rect);\r
- FillRect(hdc, &rect, (HBRUSH)GetClassLongA(hwnd, GCL_HBRBACKGROUND));\r
+ FillRect(hdc, &rect, (HBRUSH)GetClassLongPtrW(hwnd, GCLP_HBRBACKGROUND));\r
  for ( j = 0; j < rows; j++ )\r
  {\r
   for ( i = 0; i < cols; i++ )\r
@@ -770,7 +770,7 @@ void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, COLORREF* lpcr )
  HDC  hdc;\r
  HBRUSH hBrush;\r
  int dx, dy, i, j, k;\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
 \r
  GetClientRect(hwnd, &rect);\r
 \r
@@ -781,7 +781,7 @@ void CC_PaintUserColorArray( HWND hDlg, int rows, int cols, COLORREF* lpcr )
  hdc = GetDC(hwnd);\r
  if (hdc)\r
  {\r
-  FillRect(hdc, &rect, (HBRUSH)GetClassLongA(hwnd, GCL_HBRBACKGROUND) );\r
+  FillRect(hdc, &rect, (HBRUSH)GetClassLongPtrW(hwnd, GCLP_HBRBACKGROUND) );\r
   for (j = 0; j < rows; j++)\r
   {\r
    for (i = 0; i < cols; i++)\r
@@ -842,7 +842,7 @@ LONG CC_WMInitDialog( HWND hDlg, WPARAM wParam, LPARAM lParam )
        return FALSE;\r
    }\r
 \r
-   SetWindowLongA(hDlg, DWL_USER, (LONG)lpp);\r
+   SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)lpp);\r
 \r
    if (!(lpp->lpcc->Flags & CC_SHOWHELP))\r
       ShowWindow( GetDlgItem(hDlg,0x40e), SW_HIDE);\r
@@ -936,7 +936,7 @@ LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode,
     UINT cokmsg;\r
     HDC hdc;\r
     COLORREF *cr;\r
-    LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+    LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
     TRACE("CC_WMCommand wParam=%x lParam=%lx\n", wParam, lParam);\r
     switch (wParam)\r
     {\r
@@ -1058,7 +1058,7 @@ LRESULT CC_WMCommand( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode,
 LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam )\r
 {\r
     PAINTSTRUCT ps;\r
-    LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+    LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
 \r
     BeginPaint(hDlg, &ps);\r
     /* we have to paint dialog children except text and buttons */\r
@@ -1079,7 +1079,7 @@ LRESULT CC_WMPaint( HWND hDlg, WPARAM wParam, LPARAM lParam )
  */\r
 LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam )\r
 {\r
-   LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+   LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
    if (lpp->capturedGraph)\r
    {\r
        lpp->capturedGraph = 0;\r
@@ -1095,7 +1095,7 @@ LRESULT CC_WMLButtonUp( HWND hDlg, WPARAM wParam, LPARAM lParam )
  */\r
 LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam )\r
 {\r
-   LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+   LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
    int r, g, b;\r
 \r
    if (lpp->capturedGraph)\r
@@ -1133,7 +1133,7 @@ LRESULT CC_WMMouseMove( HWND hDlg, LPARAM lParam )
  */\r
 LRESULT CC_WMLButtonDown( HWND hDlg, WPARAM wParam, LPARAM lParam )\r
 {\r
-   LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+   LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
    int r, g, b, i;\r
    i = 0;\r
 \r
@@ -1192,7 +1192,7 @@ static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message,
 {\r
 \r
  int res;\r
- LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+ LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
  if (message != WM_INITDIALOG)\r
  {\r
   if (!lpp)\r
@@ -1217,7 +1217,7 @@ static INT_PTR CALLBACK ColorDlgProc( HWND hDlg, UINT message,
                        DeleteDC(lpp->hdcMem);\r
                        DeleteObject(lpp->hbmMem);\r
                         HeapFree(GetProcessHeap(), 0, lpp);\r
-                       SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */\r
+                       SetWindowLongPtrW(hDlg, DWLP_USER, 0); /* we don't need it anymore */\r
                        break;\r
          case WM_COMMAND:\r
                        if (CC_WMCommand( hDlg, wParam, lParam, HIWORD(wParam), (HWND) lParam))\r
index eb8d30c..fb6f172 100644 (file)
@@ -102,7 +102,7 @@ LONG CC_WMInitDialog16( HWND hDlg, WPARAM wParam, LPARAM lParam )
    ch32->lpfnHook = (LPCCHOOKPROC) ch16->lpfnHook; /* only used as flag */\r
    ch32->Flags = ch16->Flags;\r
 \r
-   SetWindowLongA(hDlg, DWL_USER, (LONG)lpp);\r
+   SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)lpp);\r
 \r
    if (!(lpp->lpcc->Flags & CC_SHOWHELP))\r
       ShowWindow( GetDlgItem(hDlg,0x40e), SW_HIDE);\r
@@ -196,7 +196,7 @@ LRESULT CC_WMCommand16( HWND hDlg, WPARAM wParam, LPARAM lParam, WORD notifyCode
     UINT cokmsg;\r
     HDC hdc;\r
     COLORREF *cr;\r
-    LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+    LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
     TRACE("CC_WMCommand wParam=%x lParam=%lx\n", wParam, lParam);\r
     switch (wParam)\r
     {\r
@@ -334,7 +334,7 @@ BOOL16 CALLBACK ColorDlgProc16( HWND16 hDlg16, UINT16 message,
     BOOL16 res;\r
     HWND hDlg = HWND_32(hDlg16);\r
 \r
-    LCCPRIV lpp = (LCCPRIV)GetWindowLongA(hDlg, DWL_USER);\r
+    LCCPRIV lpp = (LCCPRIV)GetWindowLongPtrW(hDlg, DWLP_USER);\r
     if (message != WM_INITDIALOG)\r
     {\r
         if (!lpp)\r
@@ -360,7 +360,7 @@ BOOL16 CALLBACK ColorDlgProc16( HWND16 hDlg16, UINT16 message,
                        DeleteObject(lpp->hbmMem);\r
                         HeapFree(GetProcessHeap(), 0, lpp->lpcc);\r
                         HeapFree(GetProcessHeap(), 0, lpp);\r
-                       SetWindowLongA(hDlg, DWL_USER, 0L); /* we don't need it anymore */\r
+                       SetWindowLongPtrW(hDlg, DWLP_USER, 0); /* we don't need it anymore */\r
                        break;\r
          case WM_COMMAND:\r
                        if (CC_WMCommand16(hDlg, wParam, lParam,\r
index 86b6635..926bf9c 100644 (file)
@@ -1528,7 +1528,7 @@ static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
 \r
   TRACE("\n");\r
 \r
-  SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)fodInfos->Shell.FOIShellBrowser);\r
+  SetWindowLongPtrW(hwnd,DWLP_MSGRESULT,(LONG_PTR)fodInfos->Shell.FOIShellBrowser);\r
 \r
   return TRUE;\r
 }\r
@@ -1551,7 +1551,7 @@ static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
         TRACE("---\n");\r
         /* First send CDN_FILEOK as MSDN doc says */\r
         SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);\r
-        if (GetWindowLongW(fodInfos->DlgInfos.hwndCustomDlg, DWL_MSGRESULT))\r
+        if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))\r
         {\r
             TRACE("canceled\n");\r
             return FALSE;\r
@@ -1560,7 +1560,7 @@ static BOOL FILEDLG95_SendFileOK( HWND hwnd, FileOpenDlgInfos *fodInfos )
         /* fodInfos->ofnInfos points to an ASCII or UNICODE structure as appropriate */\r
         SendMessageW(fodInfos->DlgInfos.hwndCustomDlg,\r
                      fodInfos->HookMsg.fileokstring, 0, (LPARAM)fodInfos->ofnInfos);\r
-        if (GetWindowLongW(fodInfos->DlgInfos.hwndCustomDlg, DWL_MSGRESULT))\r
+        if (GetWindowLongPtrW(fodInfos->DlgInfos.hwndCustomDlg, DWLP_MSGRESULT))\r
         {\r
             TRACE("canceled\n");\r
             return FALSE;\r
index a5cceb9..b59c841 100644 (file)
@@ -230,7 +230,7 @@ HWND16 WINAPI ReplaceText16( SEGPTR find )
 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, LPARAM lParam, LPDWORD lpFlags,\r
                                     LPSTR lpstrFindWhat, BOOL fUnicode)\r
 {\r
-    SetWindowLongA(hWnd, DWL_USER, lParam);\r
+    SetWindowLongPtrW(hWnd, DWLP_USER, lParam);\r
     *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);\r
     /*\r
      * FIXME : If the initial FindWhat string is empty, we should disable the\r
@@ -295,14 +295,14 @@ static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam,
                else *lpFlags &= ~FR_MATCHCASE;\r
             *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);\r
            *lpFlags |= FR_FINDNEXT;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            return TRUE;\r
        case IDCANCEL:\r
             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);\r
            *lpFlags |= FR_DIALOGTERM;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            DestroyWindow(hWnd);\r
            return TRUE;\r
        case pshHelp:\r
@@ -328,7 +328,7 @@ BOOL16 CALLBACK FindTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
            return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags),\r
                MapSL(lpfr->lpstrFindWhat), FALSE);\r
        case WM_COMMAND:\r
-           lpfr=MapSL(GetWindowLongA(hWnd, DWL_USER));\r
+           lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER));\r
            return FINDDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner),\r
                &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),\r
                lpfr->wFindWhatLen, FALSE);\r
@@ -344,7 +344,7 @@ static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, LPARAM lParam,
                    LPDWORD lpFlags, LPSTR lpstrFindWhat,\r
                    LPSTR lpstrReplaceWith, BOOL fUnicode)\r
 {\r
-    SetWindowLongA(hWnd, DWL_USER, lParam);\r
+    SetWindowLongPtrW(hWnd, DWLP_USER, lParam);\r
     *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);\r
     /*\r
      * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /\r
@@ -410,14 +410,14 @@ static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM16 wParam,
                else *lpFlags &= ~FR_MATCHCASE;\r
             *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);\r
            *lpFlags |= FR_FINDNEXT;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            return TRUE;\r
        case IDCANCEL:\r
             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);\r
            *lpFlags |= FR_DIALOGTERM;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            DestroyWindow(hWnd);\r
            return TRUE;\r
        case psh1:\r
@@ -438,8 +438,8 @@ static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM16 wParam,
                else *lpFlags &= ~FR_MATCHCASE;\r
             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);\r
            *lpFlags |= FR_REPLACE;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            return TRUE;\r
        case psh2:\r
            if (fUnicode)\r
@@ -459,8 +459,8 @@ static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM16 wParam,
                else *lpFlags &= ~FR_MATCHCASE;\r
             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);\r
            *lpFlags |= FR_REPLACEALL;\r
-           SendMessageA(hwndOwner, uFindReplaceMessage, 0,\r
-                          GetWindowLongA(hWnd, DWL_USER) );\r
+           SendMessageW( hwndOwner, uFindReplaceMessage, 0,\r
+                          GetWindowLongPtrW(hWnd, DWLP_USER) );\r
            return TRUE;\r
        case pshHelp:\r
            /* FIXME : should lpfr structure be passed as an argument ??? */\r
@@ -486,7 +486,7 @@ BOOL16 CALLBACK ReplaceTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam
                    MapSL(lpfr->lpstrFindWhat),\r
                    MapSL(lpfr->lpstrReplaceWith), FALSE);\r
        case WM_COMMAND:\r
-           lpfr=MapSL(GetWindowLongA(hWnd, DWL_USER));\r
+           lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER));\r
            return REPLACEDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner),\r
                    &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),\r
                    lpfr->wFindWhatLen, MapSL(lpfr->lpstrReplaceWith),\r
index 37acc27..8237f1e 100644 (file)
@@ -590,7 +590,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
     HCURSOR hcursor=SetCursor(LoadCursorW(0,(LPWSTR)IDC_WAIT));\r
     static const WCHAR strColorName[] = {'[','c','o','l','o','r',' ','n','a','m','e',']',0};\r
 \r
-    SetPropW(hDlg, strWineFontData, (HANDLE)lParam);\r
+    SetPropW(hDlg, strWineFontData, (HANDLE)lpcf);\r
     lpxx=lpcf->lpLogFont;\r
     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);\r
 \r
@@ -697,7 +697,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam,
         SendMessageW(hDlg, WM_COMMAND, MAKEWPARAM(cmb1, CBN_SELCHANGE),\r
                 (LPARAM)GetDlgItem(hDlg,cmb1));\r
     }\r
-    if (lpcf->Flags & CF_USESTYLE && lpcf->lpszStyle)\r
+    if ((lpcf->Flags & CF_USESTYLE) && lpcf->lpszStyle)\r
     {\r
         j=SendDlgItemMessageW(hDlg,cmb2,CB_FINDSTRING,-1,(LONG)lpcf->lpszStyle);\r
         if (j!=CB_ERR)\r
@@ -1041,7 +1041,7 @@ LRESULT CFn_WMDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam, LPCHOOSEFONTW lpc
     WideCharToMultiByte(CP_ACP, 0, lpcfw->lpLogFont->lfFaceName,\r
                         LF_FACESIZE, lpcfa->lpLogFont->lfFaceName, LF_FACESIZE, 0, 0);\r
 \r
-    if(lpcfw->lpszStyle)  {\r
+    if((lpcfw->Flags & CF_USESTYLE) && lpcfw->lpszStyle) {\r
         len = WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, NULL, -1, 0, 0);\r
         WideCharToMultiByte(CP_ACP, 0, lpcfw->lpszStyle, -1, lpcfa->lpszStyle, len, 0, 0);\r
         HeapFree(GetProcessHeap(), 0, lpcfw->lpszStyle);\r
@@ -1135,13 +1135,13 @@ INT_PTR CALLBACK FormatCharDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
         MultiByteToWideChar(CP_ACP, 0, lpcfa->lpLogFont->lfFaceName,\r
                             LF_FACESIZE, lpcfw->lpLogFont->lfFaceName, LF_FACESIZE);\r
 \r
-        if(lpcfa->lpszStyle)  {\r
+        if((lpcfa->Flags & CF_USESTYLE) && lpcfa->lpszStyle)  {\r
             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, NULL, 0);\r
             lpcfw->lpszStyle = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));\r
             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpszStyle, -1, lpcfw->lpszStyle, len);\r
         }\r
 \r
-        if(lpcfa->lpTemplateName)  {\r
+        if((lpcfa->Flags & CF_ENABLETEMPLATE) && lpcfa->lpTemplateName) {\r
             len = MultiByteToWideChar(CP_ACP, 0, lpcfa->lpTemplateName, -1, NULL, 0);\r
             lpcfw->lpTemplateName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));\r
             MultiByteToWideChar(CP_ACP, 0, lpcfa->lpTemplateName,\r
index 5a04ccd..9bfcb77 100644 (file)
@@ -122,7 +122,7 @@ INT16 WINAPI FontFamilyEnumProc16( SEGPTR logfont, SEGPTR metrics,
 {\r
   HWND hwnd=HWND_32(LOWORD(lParam));\r
   HWND hDlg=GetParent(hwnd);\r
-  LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);\r
+  LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongPtrW(hDlg, DWLP_USER);\r
   LOGFONT16 *lplf = MapSL( logfont );\r
   TEXTMETRIC16 *lpmtrx16 = MapSL(metrics);\r
   ENUMLOGFONTEXW elf32w;\r
@@ -142,7 +142,7 @@ INT16 WINAPI FontStyleEnumProc16( SEGPTR logfont, SEGPTR metrics,
   HWND hcmb2=HWND_32(LOWORD(lParam));\r
   HWND hcmb3=HWND_32(HIWORD(lParam));\r
   HWND hDlg=GetParent(hcmb3);\r
-  LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);\r
+  LPCHOOSEFONT16 lpcf=(LPCHOOSEFONT16)GetWindowLongPtrW(hDlg, DWLP_USER);\r
   LOGFONT16 *lplf = MapSL(logfont);\r
   TEXTMETRIC16 *lpmtrx16 = MapSL(metrics);\r
   ENUMLOGFONTEXW elf32w;\r
@@ -300,7 +300,7 @@ BOOL16 CALLBACK FormatCharDlgProc16(HWND16 hDlg16, UINT16 message,
   BOOL16 res=0;\r
   if (message!=WM_INITDIALOG)\r
   {\r
-   lpcf=(LPCHOOSEFONT16)GetWindowLongA(hDlg, DWL_USER);\r
+   lpcf=(LPCHOOSEFONT16)GetWindowLongPtrW(hDlg, DWLP_USER);\r
    if (!lpcf && message != WM_MEASUREITEM)\r
       return FALSE;\r
    if (CFn_HookCallChk(lpcf))\r
diff --git a/reactos/lib/commctrl/Makefile b/reactos/lib/commctrl/Makefile
deleted file mode 100644 (file)
index ee15267..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-PATH_TO_TOP = ../..
-
-TARGET_TYPE = dynlink
-
-TARGET_NAME = commctrl
-
-TARGET_BASE=$(TARGET_BASE_LIB_COMMCTRL)
-
-# require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall -Werror
-
-TARGET_SDKLIBS = ntdll.a kernel32.a
-
-TARGET_OBJECTS = commctrl_main.o
-
-include $(PATH_TO_TOP)/rules.mak
-
-include $(TOOLS_PATH)/helper.mk
diff --git a/reactos/lib/commctrl/commctrl.def b/reactos/lib/commctrl/commctrl.def
deleted file mode 100644 (file)
index 306c3e5..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-LIBRARY commctrl.dll
-EXPORTS
-;Header_Init@@YAHPAUHINSTANCE__@@@Z
-;ListView_Init@@YAHPAUHINSTANCE__@@@Z
-;TV_Init@@YAHPAUHINSTANCE__@@@Z
-;_CenterWindow @35
-;_CommandBands_AddAdornments   @39
-;_CommandBands_AddBands        @37
-;_CommandBands_Create  @36
-;_CommandBands_GetCommandBar   @38
-;_CommandBands_GetRestoreInformation   @41
-;_CommandBands_Show    @40
-_CommandBar_AddAdornments@0    @10
-;_CommandBar_AddBitmap @5
-;_CommandBar_AlignAdornments   @44
-_CommandBar_Create@0   @3
-;_CommandBar_DrawMenuBar       @43
-;_CommandBar_GetItemWindow     @11
-;_CommandBar_GetMenu   @9
-;_CommandBar_Height    @12
-;_CommandBar_InsertComboBox    @6
-;_CommandBar_InsertControl     @7
-_CommandBar_InsertMenubar@0    @8
-;_CommandBar_InsertMenubarEx   @42
-_CommandBar_Show@0     @4
-;_CreatePropertySheetPageW     @19
-;_CreateStatusWindowW  @17
-;_CreateToolbar        @15
-;_CreateToolbarEx      @16
-;_CreateUpDownControl  @14
-;_DPA_Destroy  @31
-;_DPA_GetPtr   @32
-;_DSA_Create   @23
-;_DSA_DeleteAllItems   @30
-;_DSA_DeleteItem       @29
-;_DSA_Destroy  @24
-;_DSA_DestroyCallback  @57
-;_DSA_GetItem  @25
-;_DSA_GetItemPtr       @26
-;_DSA_InsertItem       @27
-;_DSA_SetItem  @28
-;_DestroyPropertySheetPage     @20
-;_DrawStatusTextW      @21
-;InitCapEdit
-;_InitCommonControls   @1
-;_InitCommonControlsEx @2
-;InitDateClasses
-;InitProgressClass
-;InitReBarClass
-;InitStatusClass
-;InitToolTipsClass
-;InitToolbarClass
-;InitTrackBar
-;InitUpDownClass
-;_InvertRect   @22
-;_IsCommandBarMessage  @13
-;_PropertySheetW       @18
-;_StrToIntW    @34
-;_Str_SetPtrW  @33
-;Tab_Init
diff --git a/reactos/lib/commctrl/commctrl.rc b/reactos/lib/commctrl/commctrl.rc
deleted file mode 100644 (file)
index 5387ace..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* $Id$ */
-
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS WinCE Compatiblity Layer\0"
-#define REACTOS_STR_INTERNAL_NAME      "commctrl\0"
-#define REACTOS_STR_ORIGINAL_FILENAME  "commctrl.dll\0"
-#include <reactos/version.rc>
diff --git a/reactos/lib/commctrl/commctrl_main.c b/reactos/lib/commctrl/commctrl_main.c
deleted file mode 100644 (file)
index eb2710b..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ReactOS-CE Common Controls
- *
- * Copyright 2004 Steven Edwards
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * TODO:
- * ATM this is just a dummy forwarding dll for the WinCE API to Win32 API
- * When you exit a simple WinCE app on Windows or on ReactOS it causes
- * a program error or unhandled exception probl'y because we dont handle
- * threading and process attaching/detaching like we should here.
- *
- * There will be some parts of the WinCE API that cant just be forwarded to
- * the Win32 API as paramater names or types may differ. In that case you will
- * need to copy the Win32 implementation and make the needed changes.
- */
-
-#include <debug.h>
-#include "windows.h"
-
-BOOL STDCALL
-DllMain(HANDLE hDll,
-       DWORD dwReason,
-       LPVOID lpReserved)
-{
-   return TRUE;
-}
-
-BOOL STDCALL 
-_CommandBar_Create()
-{
-DPRINT1("CommandBar_Create called\n");
-   return TRUE;
-}
-
-BOOL STDCALL 
-_CommandBar_Show()
-{
-DPRINT1("CommandBar_Show called\n");
-   return TRUE;
-}
-
-BOOL STDCALL
-_CommandBar_InsertMenubar()
-{
-DPRINT1("CommandBar_InsertMenubar called\n");
-   return TRUE;
-}
-
-BOOL STDCALL 
-_CommandBar_AddAdornments()
-{
-DPRINT1("CommandBar_AddAdornments called\n");
-   return TRUE;
-}
diff --git a/reactos/lib/coredll/Makefile b/reactos/lib/coredll/Makefile
deleted file mode 100644 (file)
index b6c109e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-PATH_TO_TOP = ../..
-
-TARGET_TYPE = dynlink
-
-TARGET_NAME = coredll
-
-TARGET_BASE=$(TARGET_BASE_LIB_COREDLL)
-
-# require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall -Werror
-
-TARGET_SDKLIBS = ntdll.a kernel32.a
-
-TARGET_OBJECTS = coredll_main.o
-
-include $(PATH_TO_TOP)/rules.mak
-
-include $(TOOLS_PATH)/helper.mk
diff --git a/reactos/lib/coredll/coredll.def b/reactos/lib/coredll/coredll.def
deleted file mode 100644 (file)
index a806ea2..0000000
+++ /dev/null
@@ -1,1405 +0,0 @@
-LIBRARY COREDLL.dll
-EXPORTS
-;??0exception@std@@QAE@ABV01@@Z        @1572
-;??0exception@std@@QAE@PBD@Z   @1571
-;??0exception@std@@QAE@XZ      @1570
-;??0type_info@@AAE@ABV0@@Z     @1568
-;??1exception@std@@UAE@XZ      @1574
-;??1type_info@@UAE@XZ  @1562
-;??2@YAPAXI@Z  @1095
-;??2@YAPAXIABUnothrow_t@std@@@Z        @1646
-;??3@YAXPAX@Z  @1094
-;??3@YAXPAXABUnothrow_t@std@@@Z        @1662
-;??4exception@std@@QAEAAV01@ABV01@@Z   @1573
-;??4type_info@@AAEAAV0@ABV0@@Z @1569
-;??8type_info@@QBEHABV0@@Z     @1563
-;??9type_info@@QBEHABV0@@Z     @1564
-;??_7exception@std@@6B@        @1579
-;??_7type_info@@6B@    @1580
-;??_L@YGXPAXIHP6EX0@Z1@Z       @1576
-;??_M@YGXPAXIHP6EX0@Z@Z        @1578
-;??_N@YGXPAXIHP6EX0@Z1@Z       @1577
-;??_U@YAPAXI@Z @1456
-;??_U@YAPAXIABUnothrow_t@std@@@Z       @1661
-;??_V@YAXPAX@Z @1457
-;??_V@YAXPAXABUnothrow_t@std@@@Z       @1663
-;?DefaultImcGet@@YAKXZ @1218
-;?DefaultImeWndGet@@YAPAUHWND__@@XZ    @1219
-;?ImmGetUIClassName@@YAPAGXZ   @1223
-;?ImmProcessKey@@YAKPAUHWND__@@IJKI@Z  @1220
-;?ImmSetActiveContext@@YAHPAUHWND__@@KH@Z      @806
-;?ImmTranslateMessage@@YAHPAUHWND__@@IIJHIIPAH@Z       @1221
-;?_Nomemory@std@@YAXXZ @1660
-;?_Xlen@std@@YAXXZ     @1658
-;?_Xran@std@@YAXXZ     @1659
-;?__set_inconsistency@@YAP6AXXZP6AXXZ@Z        @1555
-;?_inconsistency@@YAXXZ        @1558
-;?_query_new_handler@@YAP6AHI@ZXZ      @1618
-;?_query_new_mode@@YAHXZ       @1649
-;?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z @1650
-;?_set_new_mode@@YAHH@Z        @1648
-;?before@type_info@@QBEHABV1@@Z        @1565
-;?name@type_info@@QBEPBDXZ     @1566
-;?nothrow@std@@3Unothrow_t@1@B @1647
-;?raw_name@type_info@@QBEPBDXZ @1567
-;?set_new_handler@@YAP6AXXZP6AXXZ@Z    @1619
-;?set_terminate@std@@YAP6AXXZP6AXXZ@Z  @1552
-;?set_unexpected@std@@YAP6AXXZP6AXXZ@Z @1553
-;?terminate@std@@YAXXZ @1556
-;?unexpected@std@@YAXXZ        @1557
-;?what@exception@std@@UBEPBDXZ @1575
-;_AAFS_CloseAllFileHandles     @655
-;_AFS_CreateDirectoryW @644
-;_AFS_CreateFileW      @648
-;_AFS_DeleteFileW      @649
-;_AFS_FindFirstChangeNotificationW     @1685
-;_AFS_FindFirstFileW   @651
-;_AFS_GetDiskFreeSpace @656
-;_AFS_GetFileAttributesW       @646
-;_AFS_MoveFileW        @650
-;_AFS_NotifyMountedFS  @657
-;_AFS_PrestoChangoFileName     @654
-;_AFS_RegisterFileSystemFunction       @652
-;_AFS_RemoveDirectoryW @645
-;_AFS_SetFileAttributesW       @647
-;_AFS_Unmount  @643
-;_AbortDoc     @955
-;_AccessibilitySoundSentryEvent        @1540
-;_ActivateDevice       @1179
-;_ActivateDeviceEx     @1494
-;_ActivateService      @1508
-;_AddEventAccess       @558
-;_AddFontResourceW     @893
-;_AddTrackedItem       @578
-;_AdjustWindowRectEx   @887
-;_AdvertiseInterface   @1687
-;_AllKeys      @1453
-;_AllocPhysMem @1486
-;_AppendMenuW  @842
-;_AttachDebugger       @157
-;_AudioUpdateFromRegistry      @376
-;_BatteryDrvrGetLevels @297
-;_BatteryDrvrSupportsChangeNotification        @298
-;_BatteryGetLifeTimeInfo       @713
-;_BatteryNotifyOfTimeChange    @714
-;_BeginDeferWindowPos  @1157
-_BeginPaint=user32.BeginPaint  @260
-;_BinaryCompress       @593
-;_BinaryDecompress     @594
-;_BitBlt       @903
-;_BringWindowToTop     @275
-;_CacheSync    @577
-;_CallNextHookEx       @1204
-;_CallWindowProcW      @285
-;_CechangeDatabaseLCID @340
-;_CeclearUserNotification      @474
-;_CecreateDatabase     @315
-;_CecreateDatabaseEx   @1190
-;_CecreateDatabaseEx2  @1468
-;_CeDeleteDatabase     @318
-;_CeDeleteDatabaseEx   @1193
-;_CeDeleteRecord       @320
-;_CeEnumDBVolumes      @1165
-;_CeEventHasOccurred   @479
-;_CeFindFirstDatabase  @313
-;_CeFindFirstDatabaseEx        @1196
-;_CeFindNextDatabase   @314
-;_CeFindNextDatabaseEx @1189
-;_CeFlushDBVol @1217
-;_CeFreeNotification   @1226
-;_CeGenRandom  @1601
-;_CeGetCallerTrust     @1395
-;_CeGetCurrentTrust    @1357
-;_CeGetDBInformationByHandle   @1473
-;_CeGetRandomSeed      @1443
-;_CeGetThreadPriority  @622
-;_CeGetThreadQuantum   @1245
-;_CeGetUserNotification        @1354
-;_CeGetUserNotificationHandles @1353
-;_CeGetUserNotificationPreferences     @478
-;_CeHandleAppNotifications     @477
-;_CeLogData    @1451
-;_CeLogGetZones        @1681
-;_CeLogReSync  @1467
-;_CeLogSetZones        @1452
-;_CeMapArgumentArray   @1446
-;_CeModuleJit  @53
-;_CeMountDBVol @1164
-;_CeOidGetInfo @312
-;_CeOidGetInfoEx       @1195
-;_CeOidGetInfoEx2      @1472
-;_CeOpenDatabase       @317
-;_CeOpenDatabaseEx     @1192
-;_CeOpenDatabaseEx2    @1469
-;_CeReadRecordProps    @321
-;_CeReadRecordPropsEx  @1194
-;_CeRegisterFileSystemNotification     @331
-;_CeRemoveFontResource @894
-;_CeResyncFilesys      @1425
-;_CeRunAppAtEvent      @476
-;_CeRunAppAtTime       @475
-;_CeSeekDatabase       @319
-;_CeSeekDatabaseEx     @1470
-;_CeSetDatabaseInfo    @316
-;_CeSetDatabaseInfoEx  @1191
-;_CeSetDatabaseInfoEx2 @1471
-;_CeSetExtendedPdata   @1455
-;_CeSetThreadPriority  @621
-;_CeSetThreadQuantum   @1244
-;_CeSetUserNotification        @473
-;_CeSetUserNotificationEx      @1352
-;_CeUnmountDBVol       @1197
-;_CeWriteRecordProps   @322
-;_ChangeDisplaySettingsEx      @1611
-;_CharLowerBuffW       @222
-;_CharLowerW   @221
-;_CharNextW    @226
-;_CharPrevW    @225
-;_CharUpperBuffW       @223
-;_CharUpperW   @224
-;_CheckMenuItem        @848
-;_CheckMenuRadioItem   @849
-;_CheckPassword        @182
-;_CheckRadioButton     @684
-;_ChildWindowFromPoint @253
-;_ClearCommBreak       @107
-;_ClearCommError       @108
-;_ClientToScreen       @254
-;_ClipCursor   @731
-;_CloseAllDeviceHandles        @244
-;_CloseAllFileHandles  @242
-;_CloseAllServiceHandles       @1511
-;_CloseClipboard       @669
-;_CloseEnhMetaFile     @956
-;_CloseHandle  @553
-;_CloseMsgQueue        @1533
-;_CloseProcOE  @589
-;_ComThreadBaseFunc    @1240
-;_CombineRgn   @968
-;_CompactAllHeaps      @54
-;_CompareFileTime      @18
-;_CompareStringW       @198
-;_ConnectDebugger      @633
-;_ContinueDebugEvent   @504
-;_ConvertDefaultLocale @210
-;_ConvertThreadToFiber @1480
-;_CopyFileW    @164
-;_CopyRect     @96
-;_CountClipboardFormats        @674
-;_CreateAPIHandle      @636
-;_CreateAPISet @559
-;_CreateAcceleratorTableW      @92
-;_CreateBitmap @901
-;_CreateBitmapFromPointer      @946
-;_CreateCaret  @658
-;_CreateCompatibleBitmap       @902
-;_CreateCompatibleDC   @910
-;_CreateCrit   @616
-;_CreateCursor @722
-;_CreateDCW    @909
-;_CreateDIBPatternBrushPt      @929
-;_CreateDIBSection     @90
-;_CreateDeviceHandle   @245
-;_CreateDialogIndirectParamW   @688
-;_CreateDirectoryW     @160
-;_CreateEnhMetaFileW   @957
-;_CreateEventW @495
-;_CreateFiber  @1483
-;_CreateFileForMapping @552
-;_CreateFileForMappingW        @1167
-;_CreateFileMappingW   @548
-;_CreateFileW  @168
-;_CreateFontIndirectW  @895
-;_CreateIconIndirect   @723
-;_CreateLocaleView     @1466
-;_CreateMenu   @851
-;_CreateMsgQueue       @1529
-;_CreateMutexW @555
-;_CreatePalette        @947
-;_CreatePatternBrush   @925
-;_CreatePen    @926
-;_CreatePenIndirect    @930
-;_CreatePopupMenu      @852
-;_CreateProcessW       @493
-;_CreateRectRgn        @980
-;_CreateRectRgnIndirect        @969
-;_CreateSemaphoreW     @1238
-;_CreateServiceHandle  @1512
-;_CreateSolidBrush     @931
-;_CreateStaticMapping  @1539
-;_CreateThread @492
-_CreateWindowExW=user32.CreateWindowExW        @246
-;_CryptAcquireContextW @126
-;_CryptContextAddRef   @154
-;_CryptCreateHash      @137
-;_CryptDecrypt @136
-;_CryptDeriveKey       @129
-;_CryptDestroyHash     @140
-;_CryptDestroyKey      @130
-;_CryptDuplicateHash   @156
-;_CryptDuplicateKey    @155
-;_CryptEncrypt @135
-;_CryptEnumProviderTypesW      @152
-;_CryptEnumProvidersW  @153
-;_CryptExportKey       @133
-;_CryptGenKey  @128
-;_CryptGenRandom       @143
-;_CryptGetDefaultProviderW     @151
-;_CryptGetHashParam    @146
-;_CryptGetKeyParam     @132
-;_CryptGetProvParam    @148
-;_CryptGetUserKey      @144
-;_CryptHashData        @139
-;_CryptHashSessionKey  @138
-;_CryptImportKey       @134
-;_CryptProtectData     @1599
-;_CryptReleaseContext  @127
-;_CryptSetHashParam    @147
-;_CryptSetKeyParam     @131
-;_CryptSetProvParam    @149
-;_CryptSetProviderExW  @150
-;_CryptSetProviderW    @145
-;_CryptSignHashW       @141
-;_CryptUnprotectData   @1600
-;_CryptVerifySignatureW        @142
-;_DBCanonicalize       @233
-;_DDKReg_GetIsrInfo    @1669
-;_DDKReg_GetPciInfo    @1670
-;_DDKReg_GetWindowInfo @1668
-;_DeactivateDevice     @1180
-;_DebugActiveProcess   @505
-;_DebugNotify  @642
-;_DefDlgProcW  @689
-_DefWindowProcW=user32.DefWindowProcW  @264
-;_DeferWindowPos       @1158
-;_DeleteAndRenameFile  @183
-;_DeleteCriticalSection        @3
-;_DeleteDC     @911
-;_DeleteEnhMetaFile    @958
-;_DeleteFiber  @1484
-;_DeleteFileW  @165
-;_DeleteMenu   @850
-;_DeleteObject @912
-;_DeleteTrackedItem    @579
-;_DeregisterAFS        @335
-;_DeregisterAFSName    @339
-;_DeregisterDevice     @236
-;_DeregisterService    @1510
-;_DestroyAcceleratorTable      @93
-;_DestroyCaret @659
-;_DestroyCursor        @724
-;_DestroyIcon  @725
-;_DestroyMenu  @844
-_DestroyWindow=user32.DestroyWindow    @265
-;_DeviceIoControl      @179
-;_DevicePowerNotify    @1588
-_DialogBoxIndirectParamW=user32.DialogBoxIndirectParamW        @690
-;_DisableCaretSystemWide       @666
-;_DisableThreadLibraryCalls    @1232
-_DispatchMessageW=user32.DispatchMessageW      @859
-;_DrawEdge     @932
-;_DrawFocusRect        @933
-;_DrawFrameControl     @987
-;_DrawIconEx   @726
-;_DrawMenuBar  @856
-_DrawTextW=user32.DrawTextW    @945
-;_DumpFileSystemHeap   @341
-;_DumpKCallProfile     @510
-;_DuplicateHandle      @1535
-;_Ellipse      @934
-;_EmptyClipboard       @677
-;_EnableCaretSystemWide        @667
-;_EnableEUDC   @986
-;_EnableHardwareKeyboard       @825
-;_EnableMenuItem       @847
-;_EnableWindow @287
-;_EndDeferWindowPos    @1159
-_EndDialog=user32.EndDialog    @691
-;_EndDoc       @959
-;_EndPage      @960
-_EndPaint=user32.EndPaint      @261
-;_EnterCriticalSection @4
-;_EnumCalendarInfoW    @206
-;_EnumClipboardFormats @675
-;_EnumDateFormatsW     @208
-;_EnumDevices  @124
-;_EnumDisplayMonitors  @1526
-;_EnumFontFamiliesW    @965
-;_EnumFontsW   @966
-;_EnumPnpIds   @123
-;_EnumPropsEx  @1500
-;_EnumServices @1517
-;_EnumSystemCodePagesW @220
-;_EnumSystemLocalesW   @219
-;_EnumTimeFormatsW     @207
-;_EnumWindows  @291
-;_EqualRect    @97
-;_EqualRgn     @91
-;_EscapeCommFunction   @109
-;_EventModify  @494
-;_ExcludeClipRect      @970
-;_ExitThread   @6
-;_ExtCreateRegion      @1617
-;_ExtEscape    @1182
-;_ExtTextOutW  @896
-;_ExtractIconExW       @727
-;_ExtractResource      @573
-;_FileSystemPowerFunction      @241
-;_FileTimeToLocalFileTime      @21
-;_FileTimeToSystemTime @20
-;_FillRect     @935
-;_FillRgn      @927
-;_FilterTrackedItem    @585
-;_FindClose    @180
-;_FindCloseChangeNotification  @1684
-;_FindFirstChangeNotificationW @1682
-;_FindFirstFileExW     @1235
-;_FindFirstFileW       @167
-;_FindNextChangeNotification   @1683
-;_FindNextFileW        @181
-;_FindResource @531
-_FindResourceW=kernel32.FindResourceW  @532
-;_FindWindowW  @286
-;_FlushFileBuffers     @175
-;_FlushInstructionCache        @508
-;_FlushViewOfFile      @551
-;_FlushViewOfFileMaybe @1215
-;_FoldStringW  @218
-;_ForcePageout @540
-;_FormatMessageW       @234
-;_FreeIntChainHandler  @1476
-;_FreeLibrary  @529
-;_FreeLibraryAndExitThread     @1216
-;_FreePhysMem  @1487
-;_GetACP       @186
-;_GetAPIAddress        @32
-;_GetActiveWindow      @706
-;_GetAssociatedMenu    @300
-;_GetAsyncKeyState     @826
-;_GetAsyncShiftFlags   @834
-;_GetBkColor   @913
-;_GetBkMode    @914
-;_GetCPInfo    @188
-;_GetCRTFlags  @1228
-;_GetCRTStorageEx      @1227
-;_GetCallerProcess     @607
-;_GetCallerProcessIndex        @641
-;_GetCapture   @707
-;_GetCaretBlinkTime    @665
-;_GetCaretPos  @663
-;_GetCharWidth32       @1664
-;_GetClassInfoW        @878
-;_GetClassLong @881
-;_GetClassLongW        @879
-;_GetClassNameW        @283
-_GetClientRect=user32.GetClientRect    @249
-;_GetClipBox   @971
-;_GetClipCursor        @732
-;_GetClipRgn   @972
-;_GetClipboardData     @672
-;_GetClipboardDataAlloc        @681
-;_GetClipboardFormatNameW      @676
-;_GetClipboardOwner    @670
-;_GetCommMask  @110
-;_GetCommModemStatus   @111
-;_GetCommProperties    @112
-;_GetCommState @113
-;_GetCommTimeouts      @114
-;_GetCommandLineW      @1231
-;_GetCurrencyFormatW   @205
-;_GetCurrentFT @29
-;_GetCurrentFiber      @1481
-;_GetCurrentObject     @915
-;_GetCurrentPermissions        @612
-;_GetCurrentPositionEx @1653
-;_GetCursor    @733
-;_GetCursorPos @734
-;_GetDC        @262
-;_GetDCEx      @1185
-;_GetDIBColorTable     @1665
-;_GetDateFormatW       @203
-;_GetDesktopWindow     @1397
-;_GetDeviceByIndex     @1236
-;_GetDeviceCaps        @916
-;_GetDeviceKeys        @125
-;_GetDevicePower       @1679
-;_GetDialogBaseUnits   @694
-;_GetDiskFreeSpaceExW  @184
-;_GetDlgCtrlID @693
-;_GetDlgItem   @692
-;_GetDlgItemInt        @695
-;_GetDlgItemTextW      @687
-;_GetDoubleClickTime   @888
-;_GetEventData @1527
-;_GetExitCodeProcess   @519
-;_GetExitCodeThread    @518
-;_GetFSHeapInfo        @603
-;_GetFiberData @1482
-;_GetFileAttributesExW @1237
-;_GetFileAttributesW   @166
-;_GetFileInformationByHandle   @174
-;_GetFileSize  @172
-;_GetFileTime  @176
-;_GetFileVersionInfoSizeW      @1461
-;_GetFileVersionInfoW  @1460
-;_GetFocus     @705
-;_GetForegroundInfo    @1224
-;_GetForegroundKeyboardTarget  @1225
-;_GetForegroundWindow  @701
-;_GetHeapSnapshot      @52
-;_GetIdleTime  @608
-;_GetKPhys     @581
-;_GetKeyState  @860
-;_GetKeyboardLayout    @1229
-;_GetKeyboardLayoutNameW       @1160
-;_GetKeyboardStatus    @827
-;_GetKeyboardTarget    @711
-;_GetLastError @516
-;_GetLocalTime @23
-;_GetLocaleInfoW       @200
-;_GetMenuItemInfoW     @854
-;_GetMessagePos        @862
-;_GetMessageQueueReadyTimeStamp        @1477
-;_GetMessageSource     @872
-_GetMessageW=user32.GetMessageW        @861
-;_GetMessageWNoWait    @863
-;_GetModuleFileNameW   @537
-;_GetModuleHandleW     @1177
-;_GetMonitorInfo       @1525
-;_GetMouseMovePoints   @820
-;_GetMsgQueueInfo      @1532
-;_GetNearestColor      @952
-;_GetNearestPaletteIndex       @948
-;_GetNextDlgGroupItem  @697
-;_GetNextDlgTabItem    @696
-;_GetNumberFormatW     @204
-;_GetOEMCP     @187
-;_GetObjectType        @917
-;_GetObjectW   @918
-;_GetOpenClipboardWindow       @680
-;_GetOpenFileNameW     @488
-;_GetOwnerProcess      @606
-;_GetPaletteEntries    @949
-_GetParent=user32.GetParent    @269
-;_GetPasswordActive    @239
-;_GetPasswordStatus    @1538
-;_GetPixel     @936
-;_GetPriorityClipboardFormat   @679
-;_GetPrivateCallbacks  @1400
-;_GetProcAddrBits      @602
-;_GetProcAddressA      @1230
-;_GetProcAddressW      @530
-;_GetProcFromPtr       @600
-;_GetProcName  @624
-;_GetProcessHeap       @50
-;_GetProcessIndexFromID        @640
-;_GetProcessVersion    @536
-;_GetProp      @1498
-;_GetQueueStatus       @1420
-;_GetRealTime  @570
-;_GetRegionData        @973
-;_GetRgnBox    @974
-;_GetRomFileBytes      @576
-;_GetRomFileInfo       @575
-;_GetSaveFileNameW     @489
-;_GetScrollInfo        @282
-;_GetServiceByIndex    @1513
-;_GetServiceHandle     @1518
-;_GetStdioPathW        @1149
-_GetStockObject=gdi32.GetStockObject   @919
-;_GetStoreInformation  @323
-;_GetStringTypeExW     @217
-;_GetStringTypeW       @216
-;_GetSubMenu   @855
-;_GetSysColor  @889
-;_GetSysColorBrush     @937
-;_GetSystemDefaultLCID @213
-;_GetSystemDefaultLangID       @211
-;_GetSystemInfo        @542
-;_GetSystemMemoryDivision      @336
-;_GetSystemMetrics     @885
-;_GetSystemPaletteEntries      @950
-;_GetSystemPowerState  @1581
-;_GetSystemPowerStatusEx       @715
-;_GetSystemPowerStatusEx2      @1358
-;_GetSystemTime        @25
-;_GetTempFileNameW     @1234
-;_GetTempPathW @162
-;_GetTextAlign @1655
-;_GetTextColor @920
-;_GetTextExtentExPointW        @897
-;_GetTextFaceW @967
-;_GetTextMetricsW      @898
-;_GetThreadContext     @1148
-;_GetThreadPriority    @515
-;_GetThreadTimes       @1186
-;_GetTickCount @535
-;_GetTimeFormatW       @202
-;_GetTimeZoneInformation       @27
-;_GetUpdateRect        @274
-;_GetUpdateRgn @273
-;_GetUserDefaultLCID   @215
-;_GetUserDefaultLangID @212
-;_GetUserDirectory     @1686
-;_GetUserNameExW       @1503
-;_GetVersionEx @17
-;_GetVersionExW        @717
-;_GetWindow    @251
-;_GetWindowDC  @270
-;_GetWindowLongW       @259
-_GetWindowRect=user32.GetWindowRect    @248
-;_GetWindowRgn @1399
-;_GetWindowTextLengthW @276
-;_GetWindowTextW       @257
-;_GetWindowTextWDirect @1454
-;_GetWindowThreadProcessId     @292
-;_GiveKPhys    @582
-;_GlobalAddAtomW       @1519
-;_GlobalDeleteAtom     @1520
-;_GlobalFindAtomW      @1521
-;_GlobalMemoryStatus   @88
-;_GwesPowerOffSystem   @296
-;_HeapAlloc    @46
-;_HeapCreate   @44
-;_HeapDestroy  @45
-;_HeapFree     @49
-;_HeapReAlloc  @47
-;_HeapSize     @48
-;_HeapValidate @51
-;_HideCaret    @660
-;_ImageList_Add        @738
-;_ImageList_AddMasked  @739
-;_ImageList_BeginDrag  @740
-;_ImageList_Copy       @767
-;_ImageList_CopyDitherImage    @741
-;_ImageList_Create     @742
-;_ImageList_Destroy    @743
-;_ImageList_DragEnter  @744
-;_ImageList_DragLeave  @745
-;_ImageList_DragMove   @746
-;_ImageList_DragShowNolock     @747
-;_ImageList_Draw       @748
-;_ImageList_DrawEx     @749
-;_ImageList_DrawIndirect       @750
-;_ImageList_Duplicate  @768
-;_ImageList_EndDrag    @751
-;_ImageList_GetBkColor @752
-;_ImageList_GetDragImage       @753
-;_ImageList_GetIcon    @754
-;_ImageList_GetIconSize        @755
-;_ImageList_GetImageCount      @756
-;_ImageList_GetImageInfo       @757
-;_ImageList_LoadImage  @758
-;_ImageList_Merge      @759
-;_ImageList_Remove     @760
-;_ImageList_Replace    @761
-;_ImageList_ReplaceIcon        @762
-;_ImageList_SetBkColor @763
-;_ImageList_SetDragCursorImage @764
-;_ImageList_SetIconSize        @765
-;_ImageList_SetImageCount      @769
-;_ImageList_SetOverlayImage    @766
-;_ImmAssociateContext  @770
-;_ImmAssociateContextEx        @1205
-;_ImmConfigureIMEW     @771
-;_ImmCreateContext     @1198
-;_ImmCreateIMCC        @772
-;_ImmDestroyContext    @1199
-;_ImmDestroyIMCC       @773
-;_ImmDisableIME        @1206
-;_ImmEnableIME @1541
-;_ImmEnumRegisterWordW @774
-;_ImmEscapeW   @775
-;_ImmGenerateMessage   @776
-;_ImmGetCandidateListCountW    @778
-;_ImmGetCandidateListW @777
-;_ImmGetCandidateWindow        @779
-;_ImmGetCompositionFontW       @780
-;_ImmGetCompositionStringW     @781
-;_ImmGetCompositionWindow      @782
-;_ImmGetContext        @783
-;_ImmGetConversionListW        @784
-;_ImmGetConversionStatus       @785
-;_ImmGetDefaultIMEWnd  @786
-;_ImmGetDescriptionW   @787
-;_ImmGetGuideLineW     @788
-;_ImmGetHotKey @813
-;_ImmGetIMCCLockCount  @789
-;_ImmGetIMCCSize       @790
-;_ImmGetIMCLockCount   @791
-;_ImmGetIMEFileNameW   @1207
-;_ImmGetImeMenuItemsW  @1211
-;_ImmGetOpenStatus     @792
-;_ImmGetProperty       @793
-;_ImmGetRegisterWordStyleW     @794
-;_ImmGetStatusWindowPos        @1200
-;_ImmGetVirtualKey     @1210
-;_ImmIsIME     @1209
-;_ImmIsUIMessageW      @796
-;_ImmLockIMC   @797
-;_ImmLockIMCC  @798
-;_ImmNotifyIME @800
-;_ImmReSizeIMCC        @801
-;_ImmRegisterWordW     @802
-;_ImmReleaseContext    @803
-;_ImmRequestMessageW   @1242
-;_ImmSIPanelState      @804
-;_ImmSetCandidateWindow        @807
-;_ImmSetCompositionFontW       @808
-;_ImmSetCompositionStringW     @809
-;_ImmSetCompositionWindow      @810
-;_ImmSetConversionStatus       @811
-;_ImmSetHotKey @812
-;_ImmSetImeWndIMC      @1222
-;_ImmSetOpenStatus     @814
-;_ImmSetStatusWindowPos        @815
-;_ImmSimulateHotKey    @816
-;_ImmUnlockIMC @817
-;_ImmUnlockIMCC        @818
-;_ImmUnregisterWordW   @819
-;_InSendMessage        @1419
-;_InflateRect  @98
-;_InitLocale   @8
-;_InitializeCriticalSection    @2
-;_InputDebugCharW      @595
-;_InsertMenuW  @841
-;_InterruptDisable     @629
-;_InterruptDone        @628
-;_InterruptInitialize  @627
-;_IntersectClipRect    @975
-;_IntersectRect        @99
-;_InvalidateRect       @250
-;_InvalidateRgn        @1615
-;_IsAPIReady   @30
-;_IsBadCodePtr @521
-;_IsBadPtr     @601
-;_IsBadReadPtr @522
-;_IsBadWritePtr        @523
-;_IsChild      @277
-;_IsClipboardFormatAvailable   @678
-;_IsDBCSLeadByte       @191
-;_IsDBCSLeadByteEx     @192
-;_IsDialogMessageW     @698
-;_IsEncryptionPermitted        @613
-;_IsExiting    @159
-;_IsPrimaryThread      @610
-;_IsProcessDying       @1213
-;_IsRectEmpty  @100
-;_IsSystemFile @1680
-;_IsValidCodePage      @185
-;_IsValidLocale        @209
-;_IsWindow     @271
-;_IsWindowEnabled      @288
-;_IsWindowVisible      @886
-;_KernExtractIcons     @574
-;_KernelIoControl      @557
-;_KernelLibIoControl   @1489
-;_KeybdGetDeviceInfo   @828
-;_KeybdInitStates      @829
-;_KeybdVKeyToUnicode   @830
-;_KillAllOtherThreads  @605
-;_KillTimer    @876
-;_LCMapStringW @199
-;_LeaveCritSec @597
-;_LeaveCriticalSection @5
-;_LineTo       @1652
-_LoadAcceleratorsW=user32.LoadAcceleratorsW    @94
-;_LoadAnimatedCursor   @1493
-;_LoadBitmapW  @873
-;_LoadCursorW  @683
-;_LoadDriver   @626
-;_LoadFSD      @237
-;_LoadFSDEx    @1421
-_LoadIconW=user32.LoadIconW    @728
-;_LoadImageW   @730
-;_LoadIntChainHandler  @1475
-;_LoadKernelLibrary    @1671
-;_LoadLibraryExW       @1241
-;_LoadLibraryW @528
-;_LoadMenuW    @846
-_LoadResource=kernel32.LoadResource    @533
-_LoadStringW=user32.LoadStringW        @874
-;_LocalAlloc   @33
-;_LocalAllocInProcess  @41
-;_LocalFileTimeToFileTime      @22
-_LocalFree=kernel32.LocalFree  @36
-;_LocalFreeInProcess   @42
-;_LocalReAlloc @34
-;_LocalSize    @35
-;_LocalSizeInProcess   @43
-;_LockPages    @1161
-;_MainThreadBaseFunc   @14
-;_MapCallerPtr @1602
-;_MapDialogRect        @699
-;_MapPtrToProcWithSize @1603
-;_MapPtrToProcess      @598
-;_MapPtrUnsecure       @599
-;_MapViewOfFile        @549
-;_MapVirtualKeyW       @831
-;_MapWindowPoints      @284
-;_MaskBlt      @904
-;_MessageBeep  @857
-_MessageBoxW=user32.MessageBoxW        @858
-;_MonitorFromPoint     @1522
-;_MonitorFromRect      @1523
-;_MonitorFromWindow    @1524
-;_MoveFileW    @163
-;_MoveToEx     @1651
-;_MoveWindow   @272
-;_MsgWaitForMultipleObjectsEx  @871
-;_MultiByteToWideChar  @196
-;_NKDbgPrintfW @545
-;_NKTerminateThread    @623
-;_NKvDbgPrintfW        @568
-;_NLedGetDeviceInfo    @839
-;_NLedSetDevice        @840
-;_NotifyForceCleanboot @513
-;_NotifyWinUserSystem  @716
-;_OffsetRect   @101
-;_OffsetRgn    @976
-;_OpenClipboard        @668
-;_OpenDeviceKey        @1396
-;_OpenEventW   @1496
-;_OpenMsgQueue @1536
-;_OpenProcess  @509
-;_OtherThreadsRunning  @604
-;_OutputDebugStringW   @541
-;_PPSHRestart  @638
-;_PSLNotify    @7
-;_PatBlt       @938
-;_PeekMessageW @864
-;_PegClearUserNotification     @468
-;_PegCreateDatabase    @304
-;_PegDeleteDatabase    @307
-;_PegDeleteRecord      @309
-;_PegFindFirstDatabase @302
-;_PegFindNextDatabase  @303
-;_PegGetUserNotificationPreferences    @472
-;_PegHandleAppNotifications    @471
-;_PegOidGetInfo        @301
-;_PegOpenDatabase      @306
-;_PegReadRecordProps   @310
-;_PegRemoveFontResource        @899
-;_PegRunAppAtEvent     @470
-;_PegRunAppAtTime      @469
-;_PegSeekDatabase      @308
-;_PegSetDatabaseInfo   @305
-;_PegSetUserNotification       @467
-;_PegWriteRecordProps  @311
-;_PerformCallBack4     @1448
-;_PlayEnhMetaFile      @961
-;_PlaySoundW   @378
-;_Polygon      @939
-;_Polyline     @940
-;_PostKeybdMessage     @832
-;_PostMessageW @865
-_PostQuitMessage=user32.PostQuitMessage        @866
-;_PostThreadMessageW   @290
-;_PowerOffSystem       @617
-;_PrintTrackedItem     @580
-;_ProcessDetachAllDLLs @572
-;_ProfileStart @82
-;_ProfileStop  @83
-;_ProfileSyscall       @569
-;_PtInRect     @102
-;_PtInRegion   @977
-;_PurgeComm    @115
-;_QASetWindowsJournalHook      @821
-;_QAUnhookWindowsJournalHook   @822
-;_QueryAPISetID        @490
-;_QueryInstructionSet  @1677
-;_QueryPerformanceCounter      @538
-;_QueryPerformanceFrequency    @539
-;_RaiseException       @543
-;_Random       @80
-;_ReadFile     @170
-;_ReadFileWithSeek     @243
-;_ReadMsgQueue @1530
-;_ReadProcessMemory    @506
-;_ReadRegistryFromOEM  @1153
-;_RealizePalette       @953
-;_RectInRegion @978
-;_RectVisible  @981
-;_Rectangle    @941
-;_RectangleAnimation   @294
-;_RedrawWindow @1672
-;_RefreshKernelAlarm   @587
-;_RegCloseKey  @455
-;_RegCopyFile  @465
-;_RegCreateKeyExW      @456
-;_RegDeleteKeyW        @457
-;_RegDeleteValueW      @458
-;_RegEnumKeyExW        @460
-;_RegEnumValueW        @459
-;_RegFlushKey  @1152
-;_RegOpenKeyExW        @461
-;_RegOpenProcessKey    @1542
-;_RegQueryInfoKeyW     @462
-;_RegQueryValueExW     @463
-;_RegReplaceKey        @1479
-;_RegRestoreFile       @466
-;_RegSaveKey   @1478
-;_RegSetValueExW       @464
-;_RegisterAFSEx        @1490
-;_RegisterAFSName      @338
-;_RegisterAPISet       @635
-_RegisterClassW=user32.RegisterClassW  @95
-;_RegisterClassWStub   @883
-;_RegisterClipboardFormatW     @673
-;_RegisterDbgZones     @546
-;_RegisterDesktop      @1507
-;_RegisterDevice       @235
-;_RegisterHotKey       @835
-;_RegisterPowerRelationship    @1609
-;_RegisterSIPanel      @293
-;_RegisterService      @1509
-;_RegisterTaskBar      @892
-;_RegisterTaskBarEx    @1506
-;_RegisterTrackedItem  @584
-;_RegisterWindowMessageW       @891
-;_ReleaseCapture       @709
-;_ReleaseDC    @263
-;_ReleaseMutex @556
-;_ReleasePowerRelationship     @1610
-;_ReleasePowerRequirement      @1584
-;_ReleaseSemaphore     @1239
-;_RemoteHeapAlloc      @1604
-;_RemoteHeapFree       @1606
-;_RemoteHeapReAlloc    @1605
-;_RemoteHeapSize       @1607
-;_RemoteLocalAlloc     @37
-;_RemoteLocalFree      @40
-;_RemoteLocalReAlloc   @38
-;_RemoteLocalSize      @39
-;_RemoveDirectoryW     @161
-;_RemoveFontResourceW  @900
-;_RemoveMenu   @843
-;_RemoveProp   @1499
-;_RequestDeviceNotifications   @1504
-;_RequestPowerNotifications    @1585
-;_ResourceCreateList   @1612
-;_ResourceRelease      @1614
-;_ResourceRequest      @1613
-;_RestoreDC    @907
-;_ResumeThread @500
-;_RoundRect    @942
-;_SHAddToRecentDocs    @483
-;_SHCreateExplorerInstance     @1163
-;_SHCreateShortcut     @484
-;_SHCreateShortcutEx   @1488
-;_SHGetFileInfo        @482
-;_SHGetShortcutTarget  @485
-;_SHGetSpecialFolderPath       @295
-;_SHLoadDIBitmap       @487
-;_SHShowOutOfMemory    @486
-;_SaveDC       @908
-;_ScreenToClient       @255
-;_ScrollDC     @985
-;_ScrollWindowEx       @289
-;_SelectClipRgn        @979
-;_SelectObject @921
-;_SelectPalette        @954
-;_SendDlgItemMessageW  @685
-;_SendInput    @823
-;_SendMessageTimeout   @1495
-;_SendMessageW @868
-;_SendNotifyMessageW   @869
-;_ServiceAddPort       @1515
-;_ServiceIoControl     @1514
-;_ServiceUnbindPorts   @1516
-;_SetACP       @189
-;_SetAbortProc @962
-;_SetActiveWindow      @703
-;_SetAssociatedMenu    @299
-;_SetBkColor   @922
-;_SetBkMode    @923
-;_SetBrushOrgEx        @943
-;_SetCapture   @708
-;_SetCaretBlinkTime    @664
-;_SetCaretPos  @662
-;_SetClassLong @882
-;_SetClassLongW        @880
-;_SetCleanRebootFlag   @615
-;_SetClipboardData     @671
-;_SetCommBreak @116
-;_SetCommMask  @117
-;_SetCommState @118
-;_SetCommTimeouts      @119
-;_SetCurrentUser       @1501
-;_SetCursor    @682
-;_SetCursorPos @736
-;_SetDIBColorTable     @1666
-;_SetDaylightTime      @547
-;_SetDbgZone   @618
-;_SetDevicePower       @1678
-;_SetDlgItemInt        @700
-;_SetDlgItemTextW      @686
-;_SetEndOfFile @178
-;_SetEventData @1528
-;_SetExceptionHandler  @583
-;_SetFileAttributesW   @169
-;_SetFilePointer       @173
-;_SetFileTime  @177
-;_SetFocus     @704
-;_SetForegroundWindow  @702
-;_SetGwesOOMEvent      @590
-;_SetGwesPowerHandler  @632
-;_SetHandleOwner       @625
-;_SetHardwareWatch     @634
-;_SetInterruptEvent    @158
-;_SetKMode     @630
-;_SetKernelAlarm       @586
-;_SetKeyboardTarget    @710
-;_SetLastError @517
-;_SetLocalTime @24
-;_SetLocaleInfoW       @201
-;_SetLowestScheduledPriority   @609
-;_SetMenuItemInfoW     @853
-;_SetOEMCP     @190
-;_SetOOMEvent  @1462
-;_SetObjectOwner       @984
-;_SetPaletteEntries    @951
-;_SetParent    @268
-;_SetPassword  @238
-;_SetPasswordActive    @240
-;_SetPasswordStatus    @1537
-;_SetPixel     @944
-;_SetPowerOffHandler   @631
-;_SetPowerRequirement  @1583
-;_SetProcPermissions   @611
-;_SetProp      @1497
-;_SetROP2      @928
-;_SetRealTime  @571
-;_SetRect      @103
-;_SetRectEmpty @104
-;_SetRectRgn   @982
-;_SetScrollInfo        @279
-;_SetScrollPos @280
-;_SetScrollRange       @281
-;_SetStdioPathW  @1150
-;_SetSysColors   @890
-;_SetSystemDefaultLCID   @214
-;_SetSystemMemoryDivision        @337
-;_SetSystemPowerState    @1582
-;_SetSystemTime  @26
-;_SetTextAlign   @1654
-;_SetTextColor   @924
-;_SetThreadContext       @502
-;_SetThreadPriority      @514
-;_SetTimeZoneBias        @614
-;_SetTimeZoneInformation @28
-;_SetTimer       @875
-;_SetUserData    @1502
-;_SetViewportOrgEx       @983
-;_SetWDevicePowerHandler @1178
-;_SetWindowLongW @258
-_SetWindowPos=user32.SetWindowPos   @247
-;_SetWindowRgn   @1398
-;_SetWindowTextW @256
-;_SetWindowsHookExW      @1202
-;_SetupComm      @120
-;_ShellExecuteEx @480
-;_ShellModalEnd  @712
-;_Shell_NotifyIcon       @481
-;_ShowCaret      @661
-;_ShowCursor     @737
-_ShowWindow=user32.ShowWindow     @266
-;_SignalStarted  @639
-;_SizeofResource @534
-;_Sleep  @496
-;_SleepTillTick  @1534
-;_StartDocW      @963
-;_StartPage      @964
-;_StopDeviceNotifications        @1505
-;_StopPowerNotifications @1586
-;_StretchBlt     @905
-;_StretchDIBits  @1667
-;_StringCompress @591
-;_StringDecompress       @592
-;_SubtractRect   @105
-;_SuspendThread  @499
-;_SwitchToFiber  @1485
-;_SystemIdleTimerReset   @837
-;_SystemMemoryLow        @720
-;_SystemParametersInfoW  @89
-;_SystemStarted  @1
-;_SystemTimeToFileTime   @19
-;_THCreateSnapshot       @511
-;_THGrow @512
-;_TakeCritSec    @596
-;_TerminateProcess       @544
-;_TerminateThread        @491
-;_ThreadAttachAllDLLs    @561
-;_ThreadBaseFunc @13
-;_ThreadDetachAllDLLs    @562
-;_ThreadExceptionExit    @1474
-;_TlsCall        @520
-;_TlsGetValue    @15
-;_TlsSetValue    @16
-;_TouchCalibrate @877
-;_TrackPopupMenuEx       @845
-_TranslateAcceleratorW=user32.TranslateAcceleratorW  @838
-;_TranslateCharsetInfo   @1166
-_TranslateMessage=user32.TranslateMessage       @870
-;_TransmitCommChar       @121
-;_TransparentImage       @906
-;_TryEnterCriticalSection        @1233
-;_TurnOffProfiling       @620
-;_TurnOnProfiling        @619
-;_U_rclose       @567
-;_U_rlseek       @566
-;_U_ropen        @563
-;_U_rread        @564
-;_U_rwrite       @565
-;_UnhookWindowsHookEx    @1203
-;_UnionRect      @106
-;_UnlockPages    @1162
-;_UnmapViewOfFile        @550
-;_UnregisterClassW       @884
-;_UnregisterFunc1        @1156
-;_UnregisterHotKey       @836
-;_UpdateNLSInfo  @1447
-_UpdateWindow=user32.UpdateWindow   @267
-;_ValidateRect   @278
-;_ValidateRgn    @1616
-;_VerQueryValueW @1459
-;_VerifyAPIHandle        @637
-;_VirtualAlloc   @524
-;_VirtualCopy    @560
-;_VirtualFree    @525
-;_VirtualProtect @526
-;_VirtualQuery   @527
-;_WNetAddConnection3W    @444
-;_WNetCancelConnection2W @445
-;_WNetCloseEnum  @453
-;_WNetConnectionDialog1W @446
-;_WNetDisconnectDialog   @447
-;_WNetDisconnectDialog1W @448
-;_WNetEnumResourceW      @454
-;_WNetGetConnectionW     @449
-;_WNetGetUniversalNameW  @450
-;_WNetGetUserW   @451
-;_WNetOpenEnumW  @452
-;_WaitCommEvent  @122
-;_WaitForDebugEvent      @503
-;_WaitForMultipleObjects @498
-;_WaitForSingleObject    @497
-;_WideCharToMultiByte    @197
-;_WindowFromPoint        @252
-;_WriteDebugLED  @1155
-;_WriteFile      @171
-;_WriteFileWithSeek      @718
-;_WriteMsgQueue  @1531
-;_WriteProcessMemory     @507
-;_WriteRegistryToOEM     @1154
-;__CIacos        @2020
-;__CIasin        @2019
-;__CIatan        @2021
-;__CIatan2       @2022
-;__CIcos @2017
-;__CIcosh        @2024
-;__CIexp @2015
-;__CIfmod        @2026
-;__CIlog @2013
-;__CIlog10       @2014
-;__CIpow @2012
-;__CIsin @2016
-;__CIsinh        @2023
-;__CIsqrt        @2011
-;__CItan @2018
-;__CItanh        @2025
-;__CxxThrowException@8   @1551
-;__EH_prolog     @1620
-;__HUGE  @1181
-;__InitStdioLib  @1151
-__XcptFilter=msvcrt._XcptFilter    @1645
-;___CxxFrameHandler      @1550
-;___RTCastToVoid @1559
-;___RTDynamicCast        @1561
-;___RTtypeid     @1560
-___abnormal_termination=msvcrt._abnormal_termination @86
-;___strgtold12   @1089
-;__alldiv        @2001
-;__allmul        @2002
-;__alloca_probe  @2010
-;__allrem        @2003
-;__allshl        @2005
-;__allshr        @2004
-;__atodbl        @996
-;__atoflt        @997
-;__atoi64        @1418
-;__aulldiv       @2006
-;__aullrem       @2008
-;__aullshr       @2007
-;__cabs  @998
-;__chgsign       @1000
-;__chkstk        @2009
-;__clearfp       @1001
-;__controlfp     @1002
-;__copysign      @1003
-;__ecvt  @1008
-__except_handler3=msvcrt._except_handler3       @84
-;__fcloseall     @1119
-;__fcvt  @1011
-;__fileno        @1124
-;__finite        @1012
-;__fload @2027
-;__fltused       @1093
-;__flushall      @1123
-;__fpclass       @1015
-;__fpieee_flt    @1016
-;__fpreset       @1017
-;__frnd  @1020
-;__fsqrt @1021
-;__ftol  @2028
-;__gcvt  @1022
-;__getstdfilex   @1100
-;__getws @1138
-;__hypot @1023
-;__inp   @2029
-;__inpd  @2031
-;__inpw  @2030
-;__isctype       @1417
-;__isnan @1024
-;__itoa  @1025
-;__itow  @1026
-;__j0    @1027
-;__j1    @1028
-;__jn    @1029
-;__ld12tod       @1087
-;__ld12tof       @1088
-;__local_unwind2 @85
-;__logb  @1035
-;__lrotl @1037
-;__lrotr @1038
-;__ltoa  @1039
-;__ltow  @1040
-;__memccpy       @1042
-;__memicmp       @1045
-;__msize @1049
-;__nextafter     @1050
-;__outp  @2032
-;__outpd @2034
-;__outpw @2033
-;__purecall      @1092
-;__putws @1139
-;__rotl  @1055
-;__rotr  @1056
-;__scalb @1057
-;__setjmp3       @2000
-;__setmode       @1187
-;__snprintf      @729
-;__snwprintf     @1096
-;__statusfp      @1062
-;__strdup        @1409
-;__stricmp       @1410
-;__strlwr        @1415
-;__strnicmp      @1411
-;__strnset       @1412
-;__strrev        @1413
-;__strset        @1414
-;__strupr        @1416
-;__swab  @1074
-;__ultoa @1079
-;__ultow @1080
-;__vsnprintf     @1147
-;__vsnwprintf    @1132
-;__wcsdup        @74
-;__wcsicmp       @230
-;__wcslwr        @231
-;__wcsnicmp      @229
-;__wcsnset       @67
-;__wcsrev        @70
-;__wcsset        @71
-;__wcsupr        @232
-;__wfdopen       @1117
-;__wfopen        @1145
-;__wfreopen      @1201
-;__wtol  @78
-;__wtoll @79
-;__y0    @1084
-;__y1    @1085
-;__yn    @1086
-;_abs    @988
-;_acos   @989
-;_asin   @990
-;_atan   @991
-;_atan2  @992
-;_atof   @995
-;_atoi   @993
-;_atol   @994
-;_calloc @1346
-;_ceil   @999
-;_clearerr       @1127
-;_cos    @1004
-;_cosh   @1005
-;_difftime       @1006
-;_div    @1007
-;_exp    @1009
-;_fabs   @1010
-;_fclose @1118
-;_feof   @1125
-;_ferror @1126
-;_fflush @1122
-;_fgetc  @1108
-;_fgetpos        @1128
-;_fgets  @1109
-;_fgetwc @1140
-;_fgetws @1143
-;_floor  @1013
-;_fmod   @1014
-;_fopen  @1113
-;_fprintf        @1115
-;_fputc  @1110
-;_fputs  @1111
-;_fputwc @1141
-;_fputws @1144
-;_fread  @1120
-;_free   @1018
-;_frexp  @1019
-;_fscanf @1114
-;_fseek  @1130
-;_fsetpos        @1129
-;_ftell  @1131
-;_fwprintf       @867
-;_fwrite @1121
-;_fwscanf        @735
-;_getchar        @1104
-;_gets   @1106
-;_getwchar       @1136
-;_iswctype       @193
-;_keybd_event    @833
-;_labs   @1030
-;_ldexp  @1031
-;_ldiv   @1032
-;_log    @1033
-;_log10  @1034
-;_longjmp        @1036
-;_lstrcmpW       @227
-;_lstrcmpiW      @228
-;_malloc @1041
-;_mbstowcs       @76
-;_memchr @31
-;_memcmp @1043
-;_memcpy @1044
-;_memmove        @1046
-;_memset @1047
-;_mixerClose     @1598
-;_mixerGetControlDetails @1589
-;_mixerGetDevCaps        @1591
-;_mixerGetID     @1590
-;_mixerGetLineControls   @1592
-;_mixerGetLineInfo       @1593
-;_mixerGetNumDevs        @1594
-;_mixerMessage   @1596
-;_mixerOpen      @1595
-;_mixerSetControlDetails @1597
-;_modf   @1048
-;_mouse_event    @824
-;_pow    @1051
-;_printf @1102
-;_putchar        @1105
-;_puts   @1107
-;_putwchar       @1137
-;_qsort  @1052
-;_rand   @1053
-;_realloc        @1054
-;_scanf  @1101
-;_setvbuf        @1608
-;_sin    @1058
-;_sinh   @1059
-;_sndPlaySoundW  @377
-;_sprintf        @719
-;_sqrt   @1060
-;_srand  @1061
-;_sscanf @653
-;_strcat @1063
-;_strchr @1064
-;_strcmp @1065
-;_strcpy @1066
-;_strcspn        @1067
-;_strlen @1068
-;_strncat        @1069
-;_strncmp        @1070
-;_strncpy        @1071
-;_strpbrk      @1406
-;_strrchr      @1407
-;_strspn       @1408
-;_strstr       @1072
-;_strtod       @1403
-;_strtok       @1073
-;_strtol       @1404
-;_strtoul      @1405
-;_swprintf     @1097
-;_swscanf      @1098
-;_tan  @1075
-;_tanh @1076
-;_tolower      @1090
-;_toupper      @1091
-;_towlower     @194
-;_towupper     @195
-;_ungetc       @1112
-;_ungetwc      @1142
-;_vfprintf     @1116
-;_vfwprintf    @721
-;_vprintf      @1103
-;_vsprintf     @1146
-;_vswprintf    @1099
-;_vwprintf     @1135
-;_waveInAddBuffer      @406
-;_waveInClose  @403
-;_waveInGetDevCaps     @401
-;_waveInGetErrorText   @402
-;_waveInGetID  @411
-;_waveInGetNumDevs     @400
-;_waveInGetPosition    @410
-;_waveInMessage        @412
-;_waveInOpen   @413
-;_waveInPrepareHeader  @404
-;_waveInReset  @409
-;_waveInStart  @407
-;_waveInStop   @408
-;_waveInUnprepareHeader        @405
-;_waveOutBreakLoop     @391
-;_waveOutClose @384
-;_waveOutGetDevCaps    @380
-;_waveOutGetErrorText  @383
-;_waveOutGetID @397
-;_waveOutGetNumDevs    @379
-;_waveOutGetPitch      @393
-;_waveOutGetPlaybackRate       @395
-;_waveOutGetPosition   @392
-;_waveOutGetVolume     @381
-;_waveOutMessage       @398
-;_waveOutOpen  @399
-;_waveOutPause @388
-;_waveOutPrepareHeader @385
-;_waveOutReset @390
-;_waveOutRestart       @389
-;_waveOutSetPitch      @394
-;_waveOutSetPlaybackRate       @396
-;_waveOutSetVolume     @382
-;_waveOutUnprepareHeader       @386
-;_waveOutWrite @387
-;_wcscat       @58
-;_wcschr       @59
-;_wcscmp       @60
-;_wcscpy       @61
-;_wcscspn      @62
-_wcslen=msvcrt.wcslen  @63
-;_wcsncat      @64
-;_wcsncmp      @65
-;_wcsncpy      @66
-;_wcspbrk      @68
-;_wcsrchr      @69
-;_wcsspn       @72
-;_wcsstr       @73
-;_wcstod       @1081
-;_wcstok       @77
-;_wcstol       @1082
-;_wcstombs     @75
-;_wcstoul      @1083
-;_wprintf      @1134
-;_wscanf       @1133
-;_wsprintfW    @56
-;_wvsprintfW   @57
diff --git a/reactos/lib/coredll/coredll.rc b/reactos/lib/coredll/coredll.rc
deleted file mode 100644 (file)
index a5b65e7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* $Id$ */
-
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS WinCE Compatiblity Layer\0"
-#define REACTOS_STR_INTERNAL_NAME      "coredll\0"
-#define REACTOS_STR_ORIGINAL_FILENAME  "coredll.dll\0"
-#include <reactos/version.rc>
diff --git a/reactos/lib/cpl/appwiz/De.rc b/reactos/lib/cpl/appwiz/De.rc
new file mode 100644 (file)
index 0000000..a5ddd33
--- /dev/null
@@ -0,0 +1,32 @@
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+\r
+IDD_PROPPAGEINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Programme ändern/entfernen"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,18,16,16\r
+  LTEXT "Um ein neues Programm zu installieren, klicken Sie auf Installieren",-1,36,18,PROPSHEETWIDTH-48,8\r
+  PUSHBUTTON "&Installieren...", IDC_INSTALL, PROPSHEETWIDTH-(72), 36, 60, 14\r
+  LTEXT "", -1, PROPSHEETPADDING, 63, PROPSHEETWIDTH-12, 1, NOT WS_GROUP | SS_SUNKEN\r
+  \r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,76,16,16\r
+  LTEXT "Die folgende Software kann automatisch entfernt werden. Um ein Programm zu entfernen oder die installierten Programmpakete zu ändern, wählen Sie das Programm in der Liste und klicken auf Ändern/Entfernen.",-1,36,72,PROPSHEETWIDTH-48,32\r
+  LISTBOX IDC_SOFTWARELIST, PROPSHEETPADDING, 105, PROPSHEETWIDTH-12, 88, LBS_STANDARD | WS_TABSTOP\r
+  PUSHBUTTON "Ändern/Entfe&rnen", IDC_ADDREMOVE, PROPSHEETWIDTH-(82), 198, 70, 14\r
+END\r
+\r
+IDD_PROPPAGEROSSETUP DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Reactos Setup"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+\r
+END\r
+\r
+\r
+STRINGTABLE \r
+BEGIN\r
+  IDS_CPLSYSTEMNAME "Add/Remove Programs"\r
+  IDS_CPLSYSTEMDESCRIPTION "Sets up programs and creates shortcuts."\r
+END\r
diff --git a/reactos/lib/cpl/appwiz/Dk.rc b/reactos/lib/cpl/appwiz/Dk.rc
new file mode 100644 (file)
index 0000000..b718717
--- /dev/null
@@ -0,0 +1,50 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_PROPPAGEINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Installer/Afinstallere"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,18,16,16
+  LTEXT "For at installere et nyt Program/Spil, Klik på Installere",-1,36,18,PROPSHEETWIDTH-48,8
+  PUSHBUTTON "&Installere...", IDC_INSTALL, PROPSHEETWIDTH-(72), 36, 60, 14
+  LTEXT "", -1, PROPSHEETPADDING, 63, PROPSHEETWIDTH-12, 1, NOT WS_GROUP | SS_SUNKEN
+  
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,76,16,16
+  LTEXT "Følgende Software kan automatisk blive Fjernet. For at fjerne programmer eller ændre hvilken typer komponeter der skal være installeret, vælg fra listen og klik på Tilføj/Fjern.",-1,36,72,PROPSHEETWIDTH-48,32
+  LISTBOX IDC_SOFTWARELIST, PROPSHEETPADDING, 105, PROPSHEETWIDTH-12, 88, LBS_STANDARD | WS_TABSTOP
+  PUSHBUTTON "Tilføj/&Fjern", IDC_ADDREMOVE, PROPSHEETWIDTH-72, 198, 60, 14
+END
+
+IDD_PROPPAGEROSSETUP DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Reactos Installation"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+
+END
+
+IDD_FIRSTPAGE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Opret Weblink"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Tekst 1", -1, 115, 15, 160, 24
+  LTEXT "Tekst 2", -1, 115, 35, 160, 17
+END
+
+IDD_SUBMIT_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Opret Weblink"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Tekst 1",-1,10,0,225,40
+  LTEXT "Tekst 2",-1,10,40,120,20
+  LTEXT "Tekst 3",-1,10,55,120,20
+END
+
+STRINGTABLE 
+BEGIN
+  IDS_CPLSYSTEMNAME "Tilføjer/Fjerner Programmer"
+  IDS_CPLSYSTEMDESCRIPTION "Installere programmer og opretter genveje."
+END
diff --git a/reactos/lib/cpl/appwiz/En.rc b/reactos/lib/cpl/appwiz/En.rc
new file mode 100644 (file)
index 0000000..937b1b5
--- /dev/null
@@ -0,0 +1,50 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+\r
+IDD_PROPPAGEINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Install/Uninstall"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,18,16,16\r
+  LTEXT "To install a new program, click Install",-1,36,18,PROPSHEETWIDTH-48,8\r
+  PUSHBUTTON "&Install...", IDC_INSTALL, PROPSHEETWIDTH-(72), 36, 60, 14\r
+  LTEXT "", -1, PROPSHEETPADDING, 63, PROPSHEETWIDTH-12, 1, NOT WS_GROUP | SS_SUNKEN\r
+  \r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,76,16,16\r
+  LTEXT "The following Software can be automatically removed. To remove a program or to modify its installed components, select it from the list and click Add/Remove.",-1,36,72,PROPSHEETWIDTH-48,32\r
+  LISTBOX IDC_SOFTWARELIST, PROPSHEETPADDING, 105, PROPSHEETWIDTH-12, 88, LBS_STANDARD | WS_TABSTOP\r
+  PUSHBUTTON "Add/&Remove", IDC_ADDREMOVE, PROPSHEETWIDTH-72, 198, 60, 14\r
+END\r
+\r
+IDD_PROPPAGEROSSETUP DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Reactos Setup"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+\r
+END\r
+\r
+IDD_FIRSTPAGE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Create link"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "Text1", -1, 115, 15, 160, 24\r
+  LTEXT "Text2", -1, 115, 35, 160, 17\r
+END\r
+\r
+IDD_SUBMIT_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Create link"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "Text1",-1,10,0,225,40\r
+  LTEXT "Text2",-1,10,40,120,20\r
+  LTEXT "Text3",-1,10,55,120,20\r
+END\r
+\r
+STRINGTABLE \r
+BEGIN\r
+  IDS_CPLSYSTEMNAME "Add/Remove Programs"\r
+  IDS_CPLSYSTEMDESCRIPTION "Sets up programs and creates shortcuts."\r
+END\r
diff --git a/reactos/lib/cpl/appwiz/Ru.rc b/reactos/lib/cpl/appwiz/Ru.rc
new file mode 100644 (file)
index 0000000..f301183
--- /dev/null
@@ -0,0 +1,50 @@
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT\r
+\r
+IDD_PROPPAGEINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Óñòàíîâèòü/Óäàëèòü"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,18,16,16\r
+  LTEXT "×òîáû óñòàíîâèòü íîâóþ ïðîãðàììó, íàæìèòå ""Óñòàíîâêà"".",-1,36,18,PROPSHEETWIDTH-48,16\r
+  PUSHBUTTON "&Óñòàíîâêà...", IDC_INSTALL, PROPSHEETWIDTH-72, 36, 60, 14\r
+  LTEXT "", -1, PROPSHEETPADDING, 63, PROPSHEETWIDTH-12, 1, NOT WS_GROUP | SS_SUNKEN\r
+  \r
+  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,76,16,16\r
+  LTEXT "×òîáû óñòàíîâèòü ïðîãðàììó èëè èçìåíèòü å¸ óñòàíîâëåííûå êîìïîíåíòû, âûäåëèòå å¸ â ñïèñêå è íàæìèòå ""Çàìåíèòü/Óäàëèòü"".",-1,36,72,PROPSHEETWIDTH-48,32\r
+  LISTBOX IDC_SOFTWARELIST, PROPSHEETPADDING, 105, PROPSHEETWIDTH-12, 88, LBS_STANDARD | WS_TABSTOP\r
+  PUSHBUTTON "&Çàìåíèòü/Óäàëèòü", IDC_ADDREMOVE, PROPSHEETWIDTH-98, 198, 85, 14\r
+END\r
+\r
+IDD_PROPPAGEROSSETUP DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Óñòàíîâêà êîìïîíåíòîâ ReactOS"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+\r
+END\r
+\r
+IDD_FIRSTPAGE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Create link"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "Text1", -1, 115, 15, 160, 24\r
+  LTEXT "Text2", -1, 115, 35, 160, 17\r
+END\r
+\r
+IDD_SUBMIT_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Create link"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "Text1",-1,10,0,225,40\r
+  LTEXT "Text2",-1,10,40,120,20\r
+  LTEXT "Text3",-1,10,55,120,20\r
+END\r
+\r
+STRINGTABLE \r
+BEGIN\r
+  IDS_CPLSYSTEMNAME "Óñòàíîâêà è óäàëåíèå ïðîãðàìì"\r
+  IDS_CPLSYSTEMDESCRIPTION "Óñòàíîâêà èëè óäàëåíèå ïðîãðàìì è êîìïîíåíòîâ ReactOS"\r
+END\r
index 6cfcf31..07cdf9e 100644 (file)
@@ -19,33 +19,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
 IDI_CPLSYSTEM ICON "resources/applet.ico"
 
-IDD_PROPPAGEINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Install/Uninstall"
-FONT 8, "MS Shell Dlg", 0, 0, 0x0
-BEGIN
-  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,18,16,16
-  LTEXT "To install a new program, click Install",-1,36,18,PROPSHEETWIDTH-48,8
-  PUSHBUTTON "&Install...", IDC_INSTALL, PROPSHEETWIDTH-(72), 36, 60, 14
-  LTEXT "", -1, PROPSHEETPADDING, 63, PROPSHEETWIDTH-12, 1, NOT WS_GROUP | SS_SUNKEN
-  
-  ICON            IDI_CPLSYSTEM,-1,PROPSHEETPADDING,76,16,16
-  LTEXT "The following Software can be automatically removed. To remove a program or to modify its installed components, select it from the list and click Add/Remove.",-1,36,72,PROPSHEETWIDTH-48,32
-  LISTBOX IDC_SOFTWARELIST, PROPSHEETPADDING, 105, PROPSHEETWIDTH-12, 88, LBS_STANDARD | WS_TABSTOP
-  PUSHBUTTON "Add/&Remove", IDC_ADDREMOVE, PROPSHEETWIDTH-72, 198, 60, 14
-END
+/*
+ * Everything specific to any language goes in one of the specific
+ * files. Note that you can and may override resources which also have
+ * a neutral version. This is to get localized bitmaps for example.
+ */
 
-IDD_PROPPAGEROSSETUP DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Reactos Setup"
-FONT 8, "MS Shell Dlg", 0, 0, 0x0
-BEGIN
+#include "En.rc"
+#include "De.rc"
+#include "Dk.rc"
+#include "Ru.rc"
 
-END
-
-
-STRINGTABLE 
-BEGIN
-  IDS_CPLSYSTEMNAME "Add/Remove Programs"
-  IDS_CPLSYSTEMDESCRIPTION "Sets up programs and creates shortcuts."
-END
index 3eae16d..883bd95 100644 (file)
Binary files a/reactos/lib/cpl/appwiz/resources/applet.ico and b/reactos/lib/cpl/appwiz/resources/applet.ico differ
diff --git a/reactos/lib/cpl/control/De.rc b/reactos/lib/cpl/control/De.rc
new file mode 100644 (file)
index 0000000..0b4611c
--- /dev/null
@@ -0,0 +1,28 @@
+// German language resource file (frik85, 2005-03-08)\r
+\r
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDM_MAINMENU MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "&Datei"\r
+    BEGIN\r
+        MENUITEM "&Beenden",                     IDM_CLOSE\r
+    END\r
+    POPUP "&Ansicht"\r
+    BEGIN\r
+        MENUITEM "Große Symbole",                IDM_LARGEICONS\r
+        MENUITEM "Kleine Symbole",               IDM_SMALLICONS\r
+        MENUITEM "Liste",                        IDM_LIST\r
+        MENUITEM "Details",                      IDM_DETAILS\r
+    END\r
+    POPUP "&?"\r
+    BEGIN\r
+        MENUITEM "Inf&o",                        IDM_ABOUT\r
+    END\r
+END\r
+\r
diff --git a/reactos/lib/cpl/control/Dk.rc b/reactos/lib/cpl/control/Dk.rc
new file mode 100644 (file)
index 0000000..808c955
--- /dev/null
@@ -0,0 +1,26 @@
+// Danish language resource file (Thomas Larsen, 2005-03-11)
+
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+IDM_MAINMENU MENU DISCARDABLE 
+BEGIN
+    POPUP "&Fil"
+    BEGIN
+        MENUITEM "&Luk",                        IDM_CLOSE
+    END
+    POPUP "&Vis"
+    BEGIN
+        MENUITEM "Store Ikoner",                IDM_LARGEICONS
+        MENUITEM "Små Ikoner",                  IDM_SMALLICONS
+        MENUITEM "Liste",                       IDM_LIST
+        MENUITEM "Detaljer",                    IDM_DETAILS
+    END
+    POPUP "Hjælp"
+    BEGIN
+        MENUITEM "Om",                       IDM_ABOUT
+    END
+END
diff --git a/reactos/lib/cpl/control/En.rc b/reactos/lib/cpl/control/En.rc
new file mode 100644 (file)
index 0000000..89ff27a
--- /dev/null
@@ -0,0 +1,28 @@
+// English language resource file (frik85, 2005-03-08)\r
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDM_MAINMENU MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "&File"\r
+    BEGIN\r
+        MENUITEM "&Close",                      IDM_CLOSE\r
+    END\r
+    POPUP "&View"\r
+    BEGIN\r
+        MENUITEM "Large Icons",                 IDM_LARGEICONS\r
+        MENUITEM "Small Icons",                 IDM_SMALLICONS\r
+        MENUITEM "List",                        IDM_LIST\r
+        MENUITEM "Details",                     IDM_DETAILS\r
+    END\r
+    POPUP "Help"\r
+    BEGIN\r
+        MENUITEM "About",                       IDM_ABOUT\r
+    END\r
+END\r
+\r
diff --git a/reactos/lib/cpl/control/Ru.rc b/reactos/lib/cpl/control/Ru.rc
new file mode 100644 (file)
index 0000000..c77a10a
--- /dev/null
@@ -0,0 +1,27 @@
+// Russian language resource file (unC0Rr, 2005-03-11)\r
+\r
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDM_MAINMENU MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "&Ôàéë"\r
+    BEGIN\r
+        MENUITEM "&Âûõîä",                       IDM_CLOSE\r
+    END\r
+    POPUP "&Âèä"\r
+    BEGIN\r
+        MENUITEM "Ïë&èòêà",                      IDM_LARGEICONS\r
+        MENUITEM "&Çíà÷êè",                      IDM_SMALLICONS\r
+        MENUITEM "Ñïèñ&îê",                      IDM_LIST\r
+        MENUITEM "&Òàáëèöà",                     IDM_DETAILS\r
+    END\r
+    POPUP "&Ñïðàâêà"\r
+    BEGIN\r
+        MENUITEM "&Πïðîãðàììå",                 IDM_ABOUT\r
+    END\r
+END\r
index afed276..2cb7fd2 100644 (file)
 #include <../../../include/reactos/version.rc>
 #endif
 
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Menu
-//
-
-IDM_MAINMENU MENU DISCARDABLE 
-BEGIN
-    POPUP "&File"
-    BEGIN
-        MENUITEM "&Close",                      IDM_CLOSE
-    END
-    POPUP "&View"
-    BEGIN
-        MENUITEM "Large Icons",                 IDM_LARGEICONS
-        MENUITEM "Small Icons",                 IDM_SMALLICONS
-        MENUITEM "List",                        IDM_LIST
-        MENUITEM "Details",                     IDM_DETAILS
-    END
-    POPUP "Help"
-    BEGIN
-        MENUITEM "About",                       IDM_ABOUT
-    END
-END
-
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -54,3 +27,15 @@ END
 // remains consistent on all systems.
 IDI_MAINICON            ICON    DISCARDABLE     "resources/config.ico"
 /////////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Everything specific to any language goes in one of the specific
+ * files. Note that you can and may override resources which also have
+ * a neutral version. This is to get localized bitmaps for example.
+ */
+
+#include "En.rc"
+#include "De.rc"
+#include "Dk.rc"
+#include "Ru.rc"
index 1ad7b88..463795b 100644 (file)
@@ -1,4 +1,4 @@
-LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL\r
 \r
 IDD_BACKGROUND DIALOGEX DISCARDABLE 0, 0, 246, 228\r
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION\r
@@ -9,13 +9,13 @@ BEGIN
                     150,105,WS_EX_STATICEDGE\r
     CONTROL         "",IDC_BACKGROUND_LIST,"SysListView32",LVS_REPORT |\r
                     LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_SHAREIMAGELISTS |\r
-                    WS_BORDER | WS_TABSTOP,7,139,173,71\r
-    LTEXT           "Wähle ein Bild um es als Desktop Hintergrund zu nutzen:",\r
+                    WS_BORDER | WS_TABSTOP,7,139,170,71\r
+    LTEXT           "Hintergrundbild:",\r
                     IDC_STATIC,8,127,180,8\r
-    PUSHBUTTON      "&Durchsuchen...",IDC_BROWSE_BUTTON,187,175,50,14\r
-    PUSHBUTTON      "&Farbe...",IDC_COLOR_BUTTON,187,195,50,14\r
-    LTEXT           "Ausrichtung:",IDC_STATIC,187,138,36,8\r
-    COMBOBOX        IDC_PLACEMENT_COMBO,187,148,50,90,CBS_DROPDOWNLIST |\r
+    PUSHBUTTON      "&Durchsuchen...",IDC_BROWSE_BUTTON,181,175,60,14\r
+    PUSHBUTTON      "&Farbe...",IDC_COLOR_BUTTON,181,195,60,14\r
+    LTEXT           "Ausrichtung:",IDC_STATIC,181,138,45,8\r
+    COMBOBOX        IDC_PLACEMENT_COMBO,181,148,60,90,CBS_DROPDOWNLIST |\r
                     CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
 END\r
 \r
@@ -42,8 +42,20 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Einstellungen"\r
 FONT 8, "MS Shell Dlg"\r
 BEGIN\r
-    LTEXT           "This space is intentionally left blank",IDC_STATIC,66,\r
-                    110,112,8\r
+    LTEXT           "&Anzeige:",1820,3,140,30,8\r
+    LTEXT           "<kein>",IDC_SETTINGS_DEVICE,9,149,224,8\r
+    GROUPBOX        "Bi&ldschirmauflösung",1818,3,160,115,43\r
+    CONTROL         "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,\r
+                    32,170,60,17\r
+    LTEXT           "Niedrig",1815,9,170,25,8,NOT WS_GROUP\r
+    LTEXT           "Hoch",1816,93,170,21,8,NOT WS_GROUP\r
+    LTEXT           "",IDC_SETTINGS_RESOLUTION_TEXT,10,190,100,10,NOT WS_GROUP | SS_CENTER\r
+    GROUPBOX        "&Farbqualität",1817,125,160,115,43\r
+    COMBOBOX        IDC_SETTINGS_BPP,131,170,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    CONTROL         "",1813,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,\r
+                    131,188,103,9\r
+    PUSHBUTTON      "&Erweitert",IDC_SETTINGS_ADVANCED,306,205,56,14\r
 END\r
 \r
 STRINGTABLE\r
@@ -56,3 +68,13 @@ BEGIN
     IDS_STRETCH "Gestreckt"\r
     IDS_TILE "Nebeneinander"\r
 END\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_COLOR_4BIT "16 Farben"\r
+    IDS_COLOR_8BIT "256 Farben"\r
+    IDS_COLOR_16BIT "High Color (16 Bit)"\r
+    IDS_COLOR_32BIT "True Color (24 Bit)"\r
+    IDS_COLOR_32BIT "True Color (32 Bit)"\r
+    IDS_PIXEL "%lux%lu Pixel"\r
+END\r
index 88614bf..518db78 100644 (file)
@@ -1,4 +1,4 @@
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 IDD_BACKGROUND DIALOGEX DISCARDABLE 0, 0, 246, 228
 STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
@@ -42,8 +42,20 @@ STYLE DS_SHELLFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Settings"
 FONT 8, "MS Shell Dlg"
 BEGIN
-    LTEXT           "This space is intentionally left blank",IDC_STATIC,66,
-                    110,112,8
+    LTEXT           "&Display:",1820,3,140,30,8
+    LTEXT           "<none>",IDC_SETTINGS_DEVICE,9,149,224,8
+    GROUPBOX        "&Screen area",1818,3,160,115,43
+    CONTROL         "",IDC_SETTINGS_RESOLUTION,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,
+                    30,170,58,17
+    LTEXT           "Less",1815,9,170,15,8,NOT WS_GROUP
+    LTEXT           "More",1816,93,170,21,8,NOT WS_GROUP
+    LTEXT           "",IDC_SETTINGS_RESOLUTION_TEXT,10,190,100,10,NOT WS_GROUP | SS_CENTER
+    GROUPBOX        "&Colors",1817,125,160,115,43
+    COMBOBOX        IDC_SETTINGS_BPP,131,170,103,80,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | 
+                    WS_VSCROLL | WS_TABSTOP
+    CONTROL         "",1813,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,
+                    131,188,103,9
+    PUSHBUTTON      "Ad&vanced...",IDC_SETTINGS_ADVANCED,306,205,56,14
 END
 
 STRINGTABLE 
@@ -57,3 +69,12 @@ BEGIN
     IDS_TILE "Tile"
 END
 
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_COLOR_4BIT "16 Colors"
+    IDS_COLOR_8BIT "256 Colors"
+    IDS_COLOR_16BIT "High Color (16 Bit)"
+    IDS_COLOR_32BIT "True Color (24 Bit)"
+    IDS_COLOR_32BIT "True Color (32 Bit)"
+    IDS_PIXEL "%lux%lu Pixel"
+END
index c1fc9bc..01bf3b6 100644 (file)
 #define IDS_STRETCH                 2004
 #define IDS_TILE                    2005
 
+#define IDC_SETTINGS_DEVICE           201
+#define IDC_SETTINGS_BPP             202
+#define IDC_SETTINGS_RESOLUTION      203
+#define IDC_SETTINGS_RESOLUTION_TEXT 204
+#define IDC_SETTINGS_ADVANCED        205
+
+/* Settings Page */
+
+#define IDS_PIXEL                              2301
+
+#define IDS_COLOR_4BIT                 2904
+#define IDS_COLOR_8BIT                 2908
+#define IDS_COLOR_16BIT                        2916
+#define IDS_COLOR_32BIT                        2932  
+
 #endif /* __CPL_DESK_RESOURCE_H__ */
 
index 7c2b0d2..0b05977 100644 (file)
  * PURPOSE:         Settings property page
  * 
  * PROGRAMMERS:     Trevor McCort (lycan359@gmail.com)
+ *                  Hervé Poussineau (poussine@freesurf.fr)
  */
 
 #include <windows.h>
 #include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <cpl.h>
 
 #include "resource.h"
+#include "desk.h"
 
-INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg,
-                                  UINT uMsg,
-                                  WPARAM wParam,
-                                  LPARAM lParam)
-{
-    switch(uMsg)
-    {
-        case WM_INITDIALOG:
-            {
-            } break;
-        
-        case WM_COMMAND:
-            {
-            } break;
-    }
-    
-    return FALSE;
+/* As slider control can't contain user data, we have to keep an
+ * array of RESOLUTION_INFO to have our own associated data.
+ */
+typedef struct _RESOLUTION_INFO
+{
+       DWORD dmPelsWidth;
+       DWORD dmPelsHeight;
+} RESOLUTION_INFO, *PRESOLUTION_INFO;
+
+typedef struct _SETTINGS_ENTRY
+{
+       struct _SETTINGS_ENTRY *Blink;
+       struct _SETTINGS_ENTRY *Flink;
+       DWORD dmBitsPerPel;
+       DWORD dmPelsWidth;
+       DWORD dmPelsHeight;
+} SETTINGS_ENTRY, *PSETTINGS_ENTRY;
+
+typedef struct _DISPLAY_DEVICE_ENTRY
+{
+       struct _DISPLAY_DEVICE_ENTRY *Flink;
+       LPTSTR DeviceDescription;
+       LPTSTR DeviceName;
+       PSETTINGS_ENTRY Settings; /* sorted by increasing dmPelsHeight, BPP */
+       DWORD SettingsCount;
+       PRESOLUTION_INFO Resolutions;
+       DWORD ResolutionsCount;
+       PSETTINGS_ENTRY CurrentSettings; /* Points into Settings list */
+       SETTINGS_ENTRY InitialSettings;
+} DISPLAY_DEVICE_ENTRY, *PDISPLAY_DEVICE_ENTRY;
+
+static PDISPLAY_DEVICE_ENTRY DisplayDeviceList = NULL;
+static PDISPLAY_DEVICE_ENTRY CurrentDisplayDevice = NULL;
+
+static VOID
+UpdateDisplay(IN HWND hwndDlg)
+{
+       TCHAR Buffer[64];
+       TCHAR Pixel[64];
+       DWORD index;
+       
+       LoadString(hApplet, IDS_PIXEL, Pixel, sizeof(Pixel) / sizeof(TCHAR));
+       _stprintf(Buffer, Pixel, CurrentDisplayDevice->CurrentSettings->dmPelsWidth, CurrentDisplayDevice->CurrentSettings->dmPelsHeight, Pixel);
+       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT, WM_SETTEXT, 0, (LPARAM)Buffer);
+       
+       for (index = 0; index < CurrentDisplayDevice->ResolutionsCount; index++)
+               if (CurrentDisplayDevice->Resolutions[index].dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth &&
+                   CurrentDisplayDevice->Resolutions[index].dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight)
+               {
+                       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETPOS, TRUE, index);
+                       break;
+               }
+       if (LoadString(hApplet, (2900 + CurrentDisplayDevice->CurrentSettings->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR))) 
+               SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SELECTSTRING, -1, (LPARAM)Buffer);
 }
 
+static PSETTINGS_ENTRY
+GetPossibleSettings(IN LPTSTR DeviceName, OUT DWORD* pSettingsCount, OUT PSETTINGS_ENTRY* CurrentSettings)
+{
+       DEVMODE devmode;
+       DWORD NbSettings = 0;
+       DWORD iMode = 0;
+       DWORD dwFlags = 0;
+       PSETTINGS_ENTRY Settings = NULL;
+       HDC hDC;
+       PSETTINGS_ENTRY Current;
+       DWORD bpp, xres, yres;
+       
+       /* Get current settings */
+       *CurrentSettings = NULL;
+       hDC = CreateIC(NULL, DeviceName, NULL, NULL);
+       bpp = GetDeviceCaps(hDC, PLANES);
+       bpp *= GetDeviceCaps(hDC, BITSPIXEL);
+       xres = GetDeviceCaps(hDC, HORZRES);
+       yres = GetDeviceCaps(hDC, VERTRES);
+       DeleteDC(hDC);
+       
+       /* List all settings */
+       devmode.dmSize = (WORD)sizeof(DEVMODE);
+       devmode.dmDriverExtra = 0;
+       while (EnumDisplaySettingsEx(DeviceName, iMode, &devmode, dwFlags))
+       {
+       
+               if (devmode.dmPelsWidth < 640 ||
+                       devmode.dmPelsHeight < 480)
+               {
+                       iMode++;
+                       continue;
+               }
+
+               Current = HeapAlloc(GetProcessHeap(), 0, sizeof(SETTINGS_ENTRY));
+               if (Current != NULL)
+               {
+                       /* Sort resolutions by increasing height, and BPP */
+                       PSETTINGS_ENTRY Previous = NULL;
+                       PSETTINGS_ENTRY Next = Settings;
+                       Current->dmPelsWidth = devmode.dmPelsWidth;
+                       Current->dmPelsHeight = devmode.dmPelsHeight;
+                       Current->dmBitsPerPel = devmode.dmBitsPerPel;
+                       while (Next != NULL && (
+                              Next->dmPelsHeight < Current->dmPelsHeight ||
+                              (Next->dmPelsHeight == Current->dmPelsHeight && Next->dmBitsPerPel < Current->dmBitsPerPel)))
+                       {
+                               Previous = Next;
+                               Next = Next->Flink;
+                       }
+                       Current->Blink = Previous;
+                       Current->Flink = Next;
+                       if (Previous == NULL)
+                               Settings = Current;
+                       else
+                               Previous->Flink = Current;
+                       if (Next != NULL)
+                               Next->Blink = Current;
+                       if (devmode.dmPelsWidth == xres && devmode.dmPelsHeight == yres && devmode.dmBitsPerPel == bpp)
+                       {
+                               *CurrentSettings = Current;
+                       }
+                       NbSettings++;
+               }
+               iMode++;
+       }
+       
+       *pSettingsCount = NbSettings;
+       return Settings;
+}
+
+static VOID
+AddDisplayDevice(IN LPTSTR Description, IN LPTSTR DeviceName)
+{
+       PDISPLAY_DEVICE_ENTRY newEntry = NULL;
+       LPTSTR description = NULL;
+       LPTSTR name = NULL;
+       DWORD descriptionSize;
+       DWORD nameSize;
+       PSETTINGS_ENTRY Current;
+       DWORD ResolutionsCount = 1;
+       DWORD i;
+       
+       newEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(DISPLAY_DEVICE_ENTRY));
+       if (!newEntry) goto ByeBye;
+       
+       newEntry->Settings = GetPossibleSettings(DeviceName, &newEntry->SettingsCount, &newEntry->CurrentSettings);
+       if (!newEntry->Settings) goto ByeBye;
+       
+       newEntry->InitialSettings.dmPelsWidth = newEntry->CurrentSettings->dmPelsWidth;
+       newEntry->InitialSettings.dmPelsHeight = newEntry->CurrentSettings->dmPelsHeight;
+       newEntry->InitialSettings.dmBitsPerPel = newEntry->CurrentSettings->dmBitsPerPel;
+       
+       /* Count different resolutions */
+       for (Current = newEntry->Settings; Current != NULL; Current = Current->Flink)
+               if (Current->Flink != NULL &&
+                  ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) || (Current->dmPelsHeight != Current->Flink->dmPelsHeight)))
+                       ResolutionsCount++;
+       newEntry->Resolutions = HeapAlloc(GetProcessHeap(), 0, ResolutionsCount * sizeof(RESOLUTION_INFO));
+       if (!newEntry->Resolutions) goto ByeBye;
+       newEntry->ResolutionsCount = ResolutionsCount;
+       /* Fill resolutions infos */
+       for (Current = newEntry->Settings, i = 0; Current != NULL; Current = Current->Flink)
+               if (Current->Flink == NULL || (Current->Flink != NULL &&
+                   ((Current->dmPelsWidth != Current->Flink->dmPelsWidth) || (Current->dmPelsHeight != Current->Flink->dmPelsHeight))))
+               {
+                       newEntry->Resolutions[i].dmPelsWidth = Current->dmPelsWidth;
+                       newEntry->Resolutions[i].dmPelsHeight = Current->dmPelsHeight;
+                       i++;
+               }
+       
+       descriptionSize = (_tcslen(Description) + 1) * sizeof(TCHAR);
+       description = HeapAlloc(GetProcessHeap(), 0, descriptionSize);
+       if (!description) goto ByeBye;
+       
+       nameSize = (_tcslen(DeviceName) + 1) * sizeof(TCHAR);
+       name = HeapAlloc(GetProcessHeap(), 0, nameSize);
+       if (!name) goto ByeBye;
+       
+       memcpy(description, Description, descriptionSize);
+       memcpy(name, DeviceName, nameSize);
+       newEntry->DeviceDescription = description;
+       newEntry->DeviceName = name;
+       newEntry->Flink = DisplayDeviceList;
+       DisplayDeviceList = newEntry;
+       return;
+       
+ByeBye:
+       if (newEntry != NULL)
+       {
+               if (newEntry->Settings != NULL)
+               {
+                       Current = newEntry->Settings;
+                       while (Current != NULL)
+                       {
+                               PSETTINGS_ENTRY Next = Current->Flink;
+                               HeapFree(GetProcessHeap(), 0, Current);
+                               Current = Next;
+                       }
+               }
+               if (newEntry->Resolutions != NULL)
+                       HeapFree(GetProcessHeap(), 0, newEntry->Resolutions);
+               HeapFree(GetProcessHeap(), 0, newEntry);
+       }
+       if (description != NULL)
+               HeapFree(GetProcessHeap(), 0, description);
+       if (name != NULL)
+               HeapFree(GetProcessHeap(), 0, name);
+}
+
+static VOID
+OnDisplayDeviceChanged(IN HWND hwndDlg, IN PDISPLAY_DEVICE_ENTRY pDeviceEntry)
+{
+       PSETTINGS_ENTRY Current;
+       DWORD index;
+       
+       CurrentDisplayDevice = pDeviceEntry; /* Update global variable */
+       
+       /* Fill color depths combo box */
+       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_RESETCONTENT, 0, 0);
+       for (Current = pDeviceEntry->Settings; Current != NULL; Current = Current->Flink)
+       {
+               TCHAR Buffer[64];
+               if (LoadString(hApplet, (2900 + Current->dmBitsPerPel), Buffer, sizeof(Buffer) / sizeof(TCHAR)))
+               {
+                       index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
+                       if (index == CB_ERR)
+                       {
+                               index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_ADDSTRING, 0, (LPARAM)Buffer);
+                               SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_SETITEMDATA, index, Current->dmBitsPerPel);
+                       }
+               }
+       }
+       
+       /* Fill resolutions slider */
+       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_CLEARTICS, TRUE, 0);
+       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(0, pDeviceEntry->ResolutionsCount - 1));
+       
+       UpdateDisplay(hwndDlg);
+}
+
+static VOID
+OnInitDialog(IN HWND hwndDlg)
+{
+       DWORD Result = 0;
+       DWORD iDevNum = 0;
+       DISPLAY_DEVICE displayDevice;
+       
+       /* Get video cards list */
+       displayDevice.cb = (DWORD)sizeof(DISPLAY_DEVICE);
+       while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0))
+       {
+               if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0)
+               {
+                       AddDisplayDevice(displayDevice.DeviceString, displayDevice.DeviceName);
+                       Result++;
+               }
+               iDevNum++;
+       }
+       if (Result == 0)
+       {
+               /* No adapter found */
+               EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_BPP), FALSE);
+               EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION), FALSE);
+               EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_RESOLUTION_TEXT), FALSE);
+               EnableWindow(GetDlgItem(hwndDlg, IDC_SETTINGS_ADVANCED), FALSE);
+       }
+       else if (Result == 1)
+       {
+               /* Single video adapter */
+               SendDlgItemMessage(hwndDlg, IDC_SETTINGS_DEVICE, WM_SETTEXT, 0, (LPARAM)DisplayDeviceList->DeviceDescription);
+               OnDisplayDeviceChanged(hwndDlg, DisplayDeviceList);
+       }
+       else
+       {
+               /* FIXME: multi video adapter */
+               /* FIXME: choose selected adapter being the primary one */
+       }
+}
+
+static VOID
+OnBPPChanged(IN HWND hwndDlg)
+{
+       /* if new BPP is not compatible with resolution:
+        * 1) try to find the nearest smaller matching resolution
+        * 2) otherwise, get the nearest bigger resolution
+        */
+       PSETTINGS_ENTRY Current;
+       DWORD dmNewBitsPerPel;
+       DWORD index;
+       TCHAR Buffer[64];
+       
+       SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, WM_GETTEXT, (WPARAM)(sizeof(Buffer) / sizeof(TCHAR)), (LPARAM)Buffer);
+       index = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)Buffer);
+       dmNewBitsPerPel = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_BPP, CB_GETITEMDATA, index, 0);
+       
+       /* find if new parameters are valid */
+       Current = CurrentDisplayDevice->CurrentSettings;
+       if (dmNewBitsPerPel == Current->dmBitsPerPel)
+       {
+               /* no change */
+               return;
+       }
+       
+       PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+       
+       if (dmNewBitsPerPel < Current->dmBitsPerPel)
+       {
+               Current = Current->Blink;
+               while (Current != NULL)
+               {
+                       if (Current->dmBitsPerPel == dmNewBitsPerPel
+                        && Current->dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight
+                        && Current->dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
+                       {
+                               CurrentDisplayDevice->CurrentSettings = Current;
+                               UpdateDisplay(hwndDlg);
+                               return;
+                       }
+                       Current = Current->Blink;
+               }
+       }
+       else
+       {
+               Current = Current->Flink;
+               while (Current != NULL)
+               {
+                       if (Current->dmBitsPerPel == dmNewBitsPerPel
+                        && Current->dmPelsHeight == CurrentDisplayDevice->CurrentSettings->dmPelsHeight
+                        && Current->dmPelsWidth == CurrentDisplayDevice->CurrentSettings->dmPelsWidth)
+                       {
+                               CurrentDisplayDevice->CurrentSettings = Current;
+                               UpdateDisplay(hwndDlg);
+                               return;
+                       }
+                       Current = Current->Flink;
+               }
+       }
+       
+       /* search smaller resolution compatible with current color depth */
+       Current = CurrentDisplayDevice->CurrentSettings->Blink;
+       while (Current != NULL)
+       {
+               if (Current->dmBitsPerPel == dmNewBitsPerPel)
+               {
+                       CurrentDisplayDevice->CurrentSettings = Current;
+                       UpdateDisplay(hwndDlg);
+                       return;
+               }
+               Current = Current->Blink;
+       }
+       
+       /* search bigger resolution compatible with current color depth */
+       Current = CurrentDisplayDevice->CurrentSettings->Flink;
+       while (Current != NULL)
+       {
+               if (Current->dmBitsPerPel == dmNewBitsPerPel)
+               {
+                       CurrentDisplayDevice->CurrentSettings = Current;
+                       UpdateDisplay(hwndDlg);
+                       return;
+               }
+               Current = Current->Flink;
+       }
+       
+       /* we shouldn't go there */
+}
+
+static VOID
+OnResolutionChanged(IN HWND hwndDlg, IN DWORD NewPosition)
+{
+       /* if new resolution is not compatible with color depth:
+        * 1) try to find the nearest bigger matching color depth
+        * 2) otherwise, get the nearest smaller color depth
+        */
+       PSETTINGS_ENTRY Current;
+       DWORD dmNewPelsHeight = CurrentDisplayDevice->Resolutions[NewPosition].dmPelsHeight;
+       DWORD dmNewPelsWidth = CurrentDisplayDevice->Resolutions[NewPosition].dmPelsWidth;
+       
+       /* find if new parameters are valid */
+       Current = CurrentDisplayDevice->CurrentSettings;
+       if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
+       {
+               /* no change */
+               return;
+       }
+       
+       PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+       
+       if (dmNewPelsHeight < Current->dmPelsHeight)
+       {
+               Current = Current->Blink;
+               while (Current != NULL)
+               {
+                       if (Current->dmPelsHeight == dmNewPelsHeight
+                        && Current->dmPelsWidth == dmNewPelsWidth
+                        && Current->dmBitsPerPel == CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
+                       {
+                               CurrentDisplayDevice->CurrentSettings = Current;
+                               UpdateDisplay(hwndDlg);
+                               return;
+                       }
+                       Current = Current->Blink;
+               }
+       }
+       else
+       {
+               Current = Current->Flink;
+               while (Current != NULL)
+               {
+                       if (Current->dmPelsHeight == dmNewPelsHeight
+                        && Current->dmPelsWidth == dmNewPelsWidth
+                        && Current->dmBitsPerPel == CurrentDisplayDevice->CurrentSettings->dmBitsPerPel)
+                       {
+                               CurrentDisplayDevice->CurrentSettings = Current;
+                               UpdateDisplay(hwndDlg);
+                               return;
+                       }
+                       Current = Current->Flink;
+               }
+       }
+       
+       /* search bigger color depth compatible with current resolution */
+       Current = CurrentDisplayDevice->CurrentSettings->Flink;
+       while (Current != NULL)
+       {
+               if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
+               {
+                       CurrentDisplayDevice->CurrentSettings = Current;
+                       UpdateDisplay(hwndDlg);
+                       return;
+               }
+               Current = Current->Flink;
+       }
+       
+       /* search smaller color depth compatible with current resolution */
+       Current = CurrentDisplayDevice->CurrentSettings->Blink;
+       while (Current != NULL)
+       {
+               if (dmNewPelsHeight == Current->dmPelsHeight && dmNewPelsWidth == Current->dmPelsWidth)
+               {
+                       CurrentDisplayDevice->CurrentSettings = Current;
+                       UpdateDisplay(hwndDlg);
+                       return;
+               }
+               Current = Current->Blink;
+       }
+       
+       /* we shouldn't go there */
+}
+
+static VOID
+OnAdvancedButton()
+{
+       MessageBox(NULL, TEXT("That button doesn't do anything yet"), TEXT("Whoops"), MB_OK);
+}
+
+/* Property page dialog callback */
+INT_PTR CALLBACK
+SettingsPageProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
+{
+       switch(uMsg)
+       {
+               case WM_INITDIALOG:
+                       OnInitDialog(hwndDlg);
+                       break;
+               case WM_COMMAND:
+               {
+                       DWORD controlId = LOWORD(wParam);
+                       DWORD command   = HIWORD(wParam);
+               
+                       if (controlId == IDC_SETTINGS_ADVANCED && command == BN_CLICKED)
+                               OnAdvancedButton();
+                       else if (controlId == IDC_SETTINGS_BPP && command == CBN_SELCHANGE)
+                               OnBPPChanged(hwndDlg);
+                       break;
+               }
+               case WM_HSCROLL:
+               {
+                       switch (LOWORD(wParam))
+                       {
+                               case TB_LINEUP:
+                               case TB_LINEDOWN:
+                               case TB_PAGEUP:
+                               case TB_PAGEDOWN:
+                               case TB_TOP:
+                               case TB_BOTTOM:
+                               case TB_ENDTRACK:
+                               {
+                                       DWORD newPosition = SendDlgItemMessage(hwndDlg, IDC_SETTINGS_RESOLUTION, TBM_GETPOS, 0, 0);
+                                       OnResolutionChanged(hwndDlg, newPosition);
+                               }
+                       }
+                       break;
+               }
+               case WM_NOTIFY:
+               {
+                       LPNMHDR lpnm = (LPNMHDR)lParam;
+                       if (lpnm->code == PSN_APPLY)
+                       {
+                               if (CurrentDisplayDevice->CurrentSettings->dmPelsWidth != CurrentDisplayDevice->InitialSettings.dmPelsWidth
+                                || CurrentDisplayDevice->CurrentSettings->dmPelsHeight != CurrentDisplayDevice->InitialSettings.dmPelsHeight
+                                || CurrentDisplayDevice->CurrentSettings->dmBitsPerPel != CurrentDisplayDevice->InitialSettings.dmBitsPerPel)
+                               {
+                                       /* FIXME: Need to test changes */
+                                       /* Apply new settings */
+                                       LONG rc;
+                                       DEVMODE devmode;
+                                       RtlZeroMemory(&devmode, sizeof(DEVMODE));
+                                       devmode.dmSize = (WORD)sizeof(DEVMODE);
+                                       devmode.dmPelsWidth = CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
+                                       devmode.dmPelsHeight = CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
+                                       devmode.dmBitsPerPel = CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
+                                       devmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
+                                       rc = ChangeDisplaySettingsEx(
+                                               CurrentDisplayDevice->DeviceName,
+                                               &devmode,
+                                               NULL,
+                                               CDS_UPDATEREGISTRY,
+                                               NULL);
+                                       switch (rc)
+                                       {
+                                               case DISP_CHANGE_SUCCESSFUL:
+                                                       CurrentDisplayDevice->InitialSettings.dmPelsWidth = CurrentDisplayDevice->CurrentSettings->dmPelsWidth;
+                                                       CurrentDisplayDevice->InitialSettings.dmPelsHeight = CurrentDisplayDevice->CurrentSettings->dmPelsHeight;
+                                                       CurrentDisplayDevice->InitialSettings.dmBitsPerPel = CurrentDisplayDevice->CurrentSettings->dmBitsPerPel;
+                                                       break;
+                                               case DISP_CHANGE_FAILED:
+                                                       MessageBox(NULL, TEXT("Failed to apply new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
+                                                       break;
+                                               case DISP_CHANGE_RESTART:
+                                                       MessageBox(NULL, TEXT("You need to restart your computer to apply changes."), TEXT("Display settings"), MB_OK | MB_ICONINFORMATION);
+                                                       break;
+                                               default:
+                                                       MessageBox(NULL, TEXT("Unknown error when applying new settings..."), TEXT("Display settings"), MB_OK | MB_ICONSTOP);
+                                                       break;
+                                       }
+                               }
+                       }
+                       break;
+               }
+               case WM_DESTROY:
+               {
+                       PDISPLAY_DEVICE_ENTRY Current = DisplayDeviceList;
+                       while (Current != NULL)
+                       {
+                               PDISPLAY_DEVICE_ENTRY Next = Current->Flink;
+                               PSETTINGS_ENTRY CurrentSettings = Current->Settings;
+                               while (CurrentSettings != NULL)
+                               {
+                                       PSETTINGS_ENTRY NextSettings = CurrentSettings->Flink;
+                                       HeapFree(GetProcessHeap(), 0, CurrentSettings);
+                                       CurrentSettings = NextSettings;
+                               }
+                               HeapFree(GetProcessHeap(), 0, Current);
+                               Current = Next;
+                       }
+               }
+       }
+       return FALSE;
+}
diff --git a/reactos/lib/cpl/intl/de.rc b/reactos/lib/cpl/intl/de.rc
new file mode 100644 (file)
index 0000000..5168f02
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id: intl.rc 12852 2005-01-06 13:58:04Z mf $ */\r
+\r
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+\r
+IDD_GENERALPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Allgemein"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 1",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_NUMBERSPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Zahlen"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 2",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_CURRENCYPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Währung"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 3",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_TIMEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Uhrzeit"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 4",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_DATEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Datum"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 5",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_LOCALEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Regionale Einstellungen"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  GROUPBOX "Standardsprache", -1, 8, 11, 228, 74 \r
+  ICON IDC_FLAGS, IDC_ICON1, 12, 26, 21, 20, SS_ICON\r
+  LTEXT "Wählen Sie eine Sprache und Region aus welche Sie benutzen wollen:", -1, 38, 25, 193, 22\r
+  COMBOBOX IDC_LANGUAGELIST, 39, 49, 191, 83, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
+\r
+\r
+STRINGTABLE\r
+BEGIN\r
+  IDS_CPLNAME "Regionale Einstellungen"\r
+  IDS_CPLDESCRIPTION "Wählen Sie Anzeigeeinstellungen für Sprache, Zahlen, Währung, Uhrzeit und Datum aus."\r
+END\r
diff --git a/reactos/lib/cpl/intl/en.rc b/reactos/lib/cpl/intl/en.rc
new file mode 100644 (file)
index 0000000..fd579b6
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id: intl.rc 12852 2005-01-06 13:58:04Z mf $ */\r
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
+\r
+IDD_GENERALPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "General"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 1",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_NUMBERSPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Numbers"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 2",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_CURRENCYPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Currency"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 3",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_TIMEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Time"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 4",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_DATEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Date"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  LTEXT "Property Page 5",-1,73,74,90,8\r
+END\r
+\r
+\r
+IDD_LOCALEPAGE DIALOGEX 0, 0, 246, 228\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Input Locale"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+  GROUPBOX "Primary language", -1, 8, 11, 228, 74 \r
+  ICON IDC_FLAGS, IDC_ICON1, 12, 26, 21, 20, SS_ICON\r
+  LTEXT "Select the primary language and region you want to use:", -1, 38, 25, 193, 22\r
+  COMBOBOX IDC_LANGUAGELIST, 39, 49, 191, 83, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
+\r
+\r
+STRINGTABLE\r
+BEGIN\r
+  IDS_CPLNAME "Regional Options"\r
+  IDS_CPLDESCRIPTION "Select languages and format numbers, currencies, times and date."\r
+END\r
index abd1173..6fe063b 100644 (file)
 
 
 IDC_CPLICON ICON "resources/applet.ico"
+IDC_FLAGS ICON "resources/flags.ico"
 
 
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
-IDD_GENERALPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 1",-1,73,74,90,8
-END
+/*
+ * Everything specific to any language goes in one of the specific
+ * files. Note that you can and may override resources which also have
+ * a neutral version. This is to get localized bitmaps for example.
+ */
 
+#include "en.rc"
+#include "de.rc"
 
-IDD_NUMBERSPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Numbers"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 2",-1,73,74,90,8
-END
-
-
-IDD_CURRENCYPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Currency"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 3",-1,73,74,90,8
-END
-
-
-IDD_TIMEPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Time"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 4",-1,73,74,90,8
-END
-
-
-IDD_DATEPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Date"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 5",-1,73,74,90,8
-END
-
-
-IDD_LOCALEPAGE DIALOGEX 0, 0, 246, 228
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Input Locale"
-FONT 8, "MS Shell Dlg"
-BEGIN
-  LTEXT "Property Page 6",-1,73,74,90,8
-END
-
-
-STRINGTABLE
-BEGIN
-  IDS_CPLNAME "Regional Options"
-  IDS_CPLDESCRIPTION "Select languages and format numbers, currencies, times and date."
-END
index a37b9ea..86eecea 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ReactOS
- *  Copyright (C) 2004 ReactOS Team
+ *  Copyright (C) 2004, 2005 ReactOS Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
  * FILE:            lib/cpl/intl/locale.c
  * PURPOSE:         Locale property page
  * PROGRAMMER:      Eric Kohl
+ *                  Klemens Friedl
  */
 
 #include <windows.h>
 #include "resource.h"
 
 
+// FIXME:
+//        * change registry function (-> "HKCR\MIME\Database\Rfc1766")
+
+
+
+typedef struct _TZ_INFO
+{
+  LONG Bias;
+  LONG StandardBias;
+  LONG DaylightBias;
+  SYSTEMTIME StandardDate;
+  SYSTEMTIME DaylightDate;
+} TZ_INFO, *PTZ_INFO;
+
+typedef struct _TIMEZONE_ENTRY
+{
+  struct _TIMEZONE_ENTRY *Prev;
+  struct _TIMEZONE_ENTRY *Next;
+  WCHAR Description[64];   /* 'Display' */
+  WCHAR StandardName[32];  /* 'Std' */
+  WCHAR DaylightName[32];  /* 'Dlt' */
+  TZ_INFO TimezoneInfo;    /* 'TZI' */
+  ULONG Index;             /* 'Index' */
+} TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
+
+
+
+PTIMEZONE_ENTRY TimeZoneListHead = NULL;
+PTIMEZONE_ENTRY TimeZoneListTail = NULL;
+
+
+
+
+static PTIMEZONE_ENTRY
+GetLargerTimeZoneEntry(DWORD Index)
+{
+  PTIMEZONE_ENTRY Entry;
+
+  Entry = TimeZoneListHead;
+  while (Entry != NULL)
+    {
+      if (Entry->Index >= Index)
+       return Entry;
+
+      Entry = Entry->Next;
+    }
+
+  return NULL;
+}
+
+
+static VOID
+CreateTimeZoneList(VOID)
+{
+
+  WCHAR szKeyName[256];
+  DWORD dwIndex;
+  DWORD dwNameSize;
+  DWORD dwValueSize;
+  LONG lError;
+  HKEY hZonesKey;
+  HKEY hZoneKey;
+
+  PTIMEZONE_ENTRY Entry;
+  PTIMEZONE_ENTRY Current;
+
+
+
+  if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                   L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
+                   0,
+                   KEY_ALL_ACCESS,
+                   &hZonesKey))
+    return;
+
+  dwIndex = 0;
+  while (TRUE)
+    {
+      dwNameSize = 256;
+      lError = RegEnumKeyExW(hZonesKey,
+                            dwIndex,
+                            szKeyName,
+                            &dwNameSize,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+      if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
+       break;
+
+
+      if (RegOpenKeyExW(hZonesKey,
+                       szKeyName,
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hZoneKey))
+       break;
+
+
+      Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
+      if (Entry == NULL)
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      dwValueSize = 64 * sizeof(WCHAR);
+      if (RegQueryValueExW(hZonesKey,
+                          L"Display",
+                          NULL,
+                          NULL,
+                          (LPBYTE)&Entry->Description,
+                          &dwValueSize))
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      dwValueSize = 32 * sizeof(WCHAR);
+      if (RegQueryValueExW(hZonesKey,
+                          L"Std",
+                          NULL,
+                          NULL,
+                          (LPBYTE)&Entry->StandardName,
+                          &dwValueSize))
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      dwValueSize = 32 * sizeof(WCHAR);
+      if (RegQueryValueExW(hZonesKey,
+                          L"Dlt",
+                          NULL,
+                          NULL,
+                          (LPBYTE)&Entry->DaylightName,
+                          &dwValueSize))
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      dwValueSize = sizeof(DWORD);
+      if (RegQueryValueExW(hZonesKey,
+                          L"Index",
+                          NULL,
+                          NULL,
+                          (LPBYTE)&Entry->Index,
+                          &dwValueSize))
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      dwValueSize = sizeof(TZ_INFO);
+      if (RegQueryValueExW(hZonesKey,
+                          L"TZI",
+                          NULL,
+                          NULL,
+                          (LPBYTE)&Entry->TimezoneInfo,
+                          &dwValueSize))
+       {
+         RegCloseKey(hZonesKey);
+         break;
+       }
+
+      RegCloseKey(hZoneKey);
+
+      if (TimeZoneListHead == NULL &&
+         TimeZoneListTail == NULL)
+       {
+         Entry->Prev = NULL;
+         Entry->Next = NULL;
+         TimeZoneListHead = Entry;
+         TimeZoneListTail = Entry;
+       }
+      else
+       {
+         Current = GetLargerTimeZoneEntry(Entry->Index);
+         if (Current != NULL)
+           {
+             if (Current == TimeZoneListHead)
+               {
+                 /* Prepend to head */
+                 Entry->Prev = NULL;
+                 Entry->Next = TimeZoneListHead;
+                 TimeZoneListHead->Prev = Entry;
+                 TimeZoneListHead = Entry;
+               }
+             else
+               {
+                 /* Insert before current */
+                 Entry->Prev = Current->Prev;
+                 Entry->Next = Current;
+                 Current->Prev->Next = Entry;
+                 Current->Prev = Entry;
+               }
+           }
+         else
+           {
+             /* Append to tail */
+             Entry->Prev = TimeZoneListTail;
+             Entry->Next = NULL;
+             TimeZoneListTail->Next = Entry;
+             TimeZoneListTail = Entry;
+           }
+       }
+
+      dwIndex++;
+    }
+
+  RegCloseKey(hZonesKey);
+
+}
+
+
+static VOID
+ShowTimeZoneList(HWND hwnd)
+{
+  TIME_ZONE_INFORMATION TimeZoneInfo;
+  PTIMEZONE_ENTRY Entry;
+  DWORD dwIndex;
+  DWORD i;
+
+  GetTimeZoneInformation(&TimeZoneInfo);
+
+  dwIndex = 0;
+  i = 0;
+  Entry = TimeZoneListHead;
+  while (Entry != NULL)
+    {
+      SendMessageW(hwnd,
+                  CB_ADDSTRING,
+                  0,
+                  (LPARAM)Entry->Description);
+
+      if (!wcscmp(Entry->StandardName, TimeZoneInfo.StandardName))
+       dwIndex = i;
+
+      i++;
+      Entry = Entry->Next;
+    }
+
+  SendMessageW(hwnd,
+              CB_SETCURSEL,
+              (WPARAM)dwIndex,
+              0);
+}
+
+
+
+
 /* Property page dialog callback */
 INT_PTR CALLBACK
 LocalePageProc(HWND hwndDlg,
@@ -42,9 +295,14 @@ LocalePageProc(HWND hwndDlg,
   switch(uMsg)
   {
     case WM_INITDIALOG:
+
+      CreateTimeZoneList();
+      ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
+
       break;
   }
   return FALSE;
 }
 
+
 /* EOF */
index fb4aaf3..e54eac9 100644 (file)
@@ -3,6 +3,8 @@
 
 
 #define IDC_CPLICON            1
+#define IDC_FLAGS               2
+#define IDC_ICON1               3
 
 #define IDD_GENERALPAGE                100
 #define IDD_NUMBERSPAGE                101
 #define IDD_TIMEPAGE           103
 #define IDD_DATEPAGE           104
 #define IDD_LOCALEPAGE         105
+#define IDC_LANGUAGELIST        106
 
 #define IDS_CPLNAME            1000
 #define IDS_CPLDESCRIPTION     1001
 
+
 #endif /* __CPL_RESOURCE_H */
 
 /* EOF */
diff --git a/reactos/lib/cpl/intl/resources/flags.ico b/reactos/lib/cpl/intl/resources/flags.ico
new file mode 100644 (file)
index 0000000..750f2d0
Binary files /dev/null and b/reactos/lib/cpl/intl/resources/flags.ico differ
diff --git a/reactos/lib/cpl/liccpa/Makefile b/reactos/lib/cpl/liccpa/Makefile
new file mode 100644 (file)
index 0000000..6c27204
--- /dev/null
@@ -0,0 +1,49 @@
+# $Id: Makefile 12852 2005-01-06 13:58:04Z mf $\r
+\r
+PATH_TO_TOP = ../../..\r
+\r
+TARGET_TYPE = dynlink\r
+\r
+TARGET_EXTENSION = .cpl\r
+\r
+TARGET_NAME = liccpa\r
+\r
+TARGET_INSTALLDIR = system32\r
+\r
+TARGET_BASE = 0x75970000\r
+\r
+TARGET_CFLAGS = \\r
+ -D_WIN32_IE=0x0600 \\r
+ -D_WIN32_WINNT=0x0501 \\r
+ -D__USE_W32API \\r
+ -I./include \\r
+ -DUNICODE \\r
+ -D_UNICODE \\r
+ -D__REACTOS__ \\r
+ -Wall \\r
+ -fno-builtin\r
+\r
+TARGET_LFLAGS = -nostartfiles\r
+\r
+TARGET_SDKLIBS = kernel32.a user32.a comctl32.a\r
+\r
+TARGET_GCCLIBS = gcc\r
+\r
+TARGET_PCH = \r
+\r
+TARGET_CLEAN = \r
+\r
+TARGET_OBJECTS = liccpa.o\r
+\r
+DEP_OBJECTS = $(TARGET_OBJECTS)\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+include $(TOOLS_PATH)/depend.mk\r
+\r
+%/TAGS:\r
+       etags -o $(@D)/TAGS $(@D)/\*.c\r
+\r
+etags: ./TAGS\r
diff --git a/reactos/lib/cpl/liccpa/liccpa.c b/reactos/lib/cpl/liccpa/liccpa.c
new file mode 100644 (file)
index 0000000..7e82e3e
--- /dev/null
@@ -0,0 +1,127 @@
+/* $Id: appearance.c 13406 2005-02-04 20:39:10Z weiden $\r
+ *\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS License Manager\r
+ * FILE:            lib/cpl/liccpa\r
+ * PURPOSE:         License Manager GUI\r
+ * \r
+ * PROGRAMMERS:     Steven Edwards (steven_ed4153@yahoo.com)\r
+ *\r
+ * NOTES:\r
+ * This application does almost nothing and its really good at it.\r
+ */\r
+\r
+#include <windows.h>\r
+#include <commctrl.h>\r
+#include <cpl.h>\r
+\r
+#include "resource.h"\r
+#include "liccpa.h"\r
+\r
+HINSTANCE hApplet = 0;\r
+\r
+INT_PTR CALLBACK\r
+DlgMainProc(\r
+  HWND hwndDlg,\r
+  UINT uMsg,\r
+  WPARAM wParam,\r
+  LPARAM lParam\r
+)\r
+{\r
+  TCHAR szString[256];\r
+\r
+  switch(uMsg)\r
+  {\r
+    case WM_INITDIALOG:\r
+      break;\r
+\r
+    case WM_COMMAND:\r
+    {\r
+      switch(HIWORD(wParam))\r
+      {\r
+        case LBN_DBLCLK:\r
+        {\r
+          switch(LOWORD(wParam))\r
+          {\r
+          }\r
+          break;\r
+        }\r
+        default:\r
+        {\r
+          switch(LOWORD(wParam))\r
+          {\r
+            case IDC_OK:\r
+            {\r
+              break;\r
+            }\r
+            case IDC_CANCEL:\r
+            {\r
+              EndDialog(hwndDlg, IDC_CANCEL);\r
+              break;\r
+            }\r
+          }\r
+          break;\r
+        }\r
+      }\r
+      break;\r
+    }\r
+    case WM_CLOSE:\r
+    {\r
+      EndDialog(hwndDlg, IDC_CANCEL);\r
+      return TRUE;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+LONG CALLBACK\r
+CPlApplet(\r
+       HWND hwndCPl,\r
+       UINT uMsg,\r
+       LPARAM lParam1,\r
+       LPARAM lParam2)\r
+{\r
+  switch(uMsg)\r
+  {\r
+    case CPL_INIT:\r
+    {\r
+      return TRUE;\r
+    }\r
+    case CPL_GETCOUNT:\r
+    {\r
+      return 1;\r
+    }\r
+    case CPL_INQUIRE:\r
+    {\r
+      CPLINFO *CPlInfo = (CPLINFO*)lParam2;\r
+      CPlInfo->lData = 0;\r
+      CPlInfo->idIcon = IDC_CPLICON_1;\r
+      CPlInfo->idName = IDS_CPLNAME_1;\r
+      CPlInfo->idInfo = IDS_CPLDESCRIPTION_1;\r
+      break;\r
+    }\r
+    case CPL_DBLCLK:\r
+    {\r
+      DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_PROPPAGE1), hwndCPl, DlgMainProc, WM_INITDIALOG);\r
+      break;\r
+    }\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+BOOL STDCALL\r
+DllMain(\r
+       HINSTANCE hinstDLL,\r
+       DWORD     dwReason,\r
+       LPVOID    lpvReserved)\r
+{\r
+  switch(dwReason)\r
+  {\r
+    case DLL_PROCESS_ATTACH:\r
+    case DLL_THREAD_ATTACH:\r
+      hApplet = hinstDLL;\r
+      break;\r
+  }\r
+  return TRUE;\r
+}\r
diff --git a/reactos/lib/cpl/liccpa/liccpa.def b/reactos/lib/cpl/liccpa/liccpa.def
new file mode 100644 (file)
index 0000000..06bb13f
--- /dev/null
@@ -0,0 +1,6 @@
+LIBRARY liccpa.cpl\r
+\r
+EXPORTS\r
+CPlApplet@16\r
+\r
+; EOF\r
diff --git a/reactos/lib/cpl/liccpa/liccpa.h b/reactos/lib/cpl/liccpa/liccpa.h
new file mode 100644 (file)
index 0000000..b98d0a9
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __CPL_SAMPLE_H\r
+#define __CPL_SAMPLE_H\r
+\r
+typedef struct\r
+{\r
+  int idIcon;\r
+  int idName;\r
+  int idDescription;\r
+  APPLET_PROC AppletProc;\r
+} APPLET, *PAPPLET;\r
+\r
+extern HINSTANCE hApplet;\r
+\r
+#endif /* __CPL_SAMPLE_H */\r
+\r
+/* EOF */\r
diff --git a/reactos/lib/cpl/liccpa/liccpa.rc b/reactos/lib/cpl/liccpa/liccpa.rc
new file mode 100644 (file)
index 0000000..102db14
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id: cplsample.rc 12852 2005-01-06 13:58:04Z mf $ */\r
+\r
+#include <defines.h>\r
+#include "resource.h"\r
+\r
+#define REACTOS_VERSION_DLL\r
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS Sample Control Panel\0"\r
+#define REACTOS_STR_INTERNAL_NAME      "cplsample\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME  "cplsample.cpl\0"\r
+#include <reactos/version.rc>\r
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
+\r
+IDC_CPLICON_1 ICON "resources/cpl_icon1.ico"\r
+\r
+IDD_PROPPAGE1 DIALOG DISCARDABLE  20, 40, 315, 104\r
+STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU\r
+CAPTION "Chose Licensing Mode"\r
+FONT 8, "Helv"\r
+BEGIN\r
+       CONTROL "Client Licensing Mode",                         100, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 4, 4, 239, 94\r
+       CONTROL "Per Device or Per User",                        102, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 13, 79, 107, 12\r
+       CONTROL "Per Server. Number of concurrent connections:", 103, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 13, 38, 163, 9\r
+       CONTROL "Product:",                                      105, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 13, 20, 31, 8\r
+       CONTROL "",                                              106, "COMBOBOX", CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP, 49, 20, 171, 12\r
+       CONTROL "OK",                                            107, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 263, 7, 46, 14\r
+       CONTROL "Cancel",                                        108, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 263, 27, 46, 14\r
+       CONTROL "Help",                                          109, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 263, 48, 46, 14\r
+       CONTROL "Replication...",                                110, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 263, 68, 46, 14\r
+       CONTROL "Add Licenses",                                  111, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 30, 56, 65, 15\r
+       CONTROL "Remove Licenses",                               112, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 112, 56, 61, 16\r
+       CONTROL "",                                              114, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 187, 39, 32, 12\r
+END\r
+\r
+STRINGTABLE \r
+BEGIN\r
+  IDS_CPLNAME_1 "License Manager"\r
+  IDS_CPLDESCRIPTION_1 "License Manager"\r
+  IDS_REACTOS "ReactOS - FreeSoftware"\r
+END\r
diff --git a/reactos/lib/cpl/liccpa/resource.h b/reactos/lib/cpl/liccpa/resource.h
new file mode 100644 (file)
index 0000000..ee937b1
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __CPL_RESOURCE_H\r
+#define __CPL_RESOURCE_H\r
+\r
+/* ids */\r
+\r
+#define IDC_CPLICON_1  1\r
+#define IDD_PROPPAGE1  100\r
+#define IDS_CPLNAME_1  1001\r
+#define IDS_CPLDESCRIPTION_1   2001\r
+#define IDS_REACTOS    2002\r
+\r
+#define IDC_LICENSE     106\r
+#define IDC_OK         107\r
+#define IDC_CANCEL     108\r
+\r
+#endif /* __CPL_RESOURCE_H */\r
+\r
+/* EOF */\r
diff --git a/reactos/lib/cpl/liccpa/resources/cpl_icon1.ico b/reactos/lib/cpl/liccpa/resources/cpl_icon1.ico
new file mode 100644 (file)
index 0000000..3eae16d
Binary files /dev/null and b/reactos/lib/cpl/liccpa/resources/cpl_icon1.ico differ
diff --git a/reactos/lib/cpl/ncpa/de.rc b/reactos/lib/cpl/ncpa/de.rc
new file mode 100644 (file)
index 0000000..b9ee2fd
--- /dev/null
@@ -0,0 +1,87 @@
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
+
+IDD_PROPPAGENETWORK DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Netzwerk Einstellungen"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    LTEXT           "Netzwerkkarten",-1,9,9,217,8
+    LISTBOX         IDC_NETCARDLIST,9,21,229,73,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "&Hinzufügen",IDC_ADD,9,100,60,14
+    PUSHBUTTON      "&Entfernen",IDC_REMOVE,72,100,60,14
+    PUSHBUTTON      "&Eigenschaften",IDC_PROPERTIES,179,100,60,14
+END
+
+IDD_NETPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Allgemein"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Verbindung herstellen über:", -1, 9,9,217,8
+ EDITTEXT IDC_NETCARDNAME, 9, 21, 230, 12, WS_DISABLED | WS_BORDER | WS_TABSTOP
+ PUSHBUTTON "&Konfigurieren", IDC_CONFIGURE, 189, 38, 50, 14
+ LTEXT "Diese &Verbindung verwendet folgende Elemente:", -1, 9, 59, 217, 8
+ LISTBOX IDC_COMPONENTSLIST, 9, 71, 230, 67, LBS_STANDARD
+ PUSHBUTTON "&Installieren", IDC_INSTALL, 9, 130, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Deinstallieren", IDC_UNINSTALL, 90, 130, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Eigenschaften", IDC_PROPERTIES, 174, 130, 65, 14
+ 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_DISABLED | WS_TABSTOP
+END
+
+
+IDD_CARDPROPERTIES DIALOG DISCARDABLE  0, 0, 200,180
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Allgemein"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Allgemein", -1, 9, 8, 182, 58, BS_GROUPBOX
+ LTEXT "Status:", -1, 19, 20, 60, 8
+ LTEXT "Dauer:", -1, 19, 34, 60, 8
+ LTEXT "Übertragungsrate:", -1, 19, 48, 60, 8
+ GROUPBOX "Aktivität", -1, 9, 74, 182, 70, BS_GROUPBOX
+ RTEXT "Gesendet", -1, 26, 90, 60, 8
+ ICON IDI_HORIZONTAL, -1, 90, 85, 18, 20
+ ICON IDI_NETSTAT, -1, 110, 85, 18, 20
+ ICON IDI_HORIZONTAL, -1, 130, 85, 18, 20
+ LTEXT "Empfangen", -1, 149, 90, 37, 8
+ LTEXT "Paketes:", -1, 17, 115, 32, 8
+ RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
+ ICON IDI_VERTICAL, -1, 110, 108, 18, 20
+ RTEXT "000.000.000", IDC_RECEIVED, 139, 115, 44, 8
+ PUSHBUTTON "E&igenschaften", IDC_PROPERTIES, 10, 150, 50, 14
+ PUSHBUTTON "&Deaktivieren", IDC_ENDISABLE, 66, 150, 50, 14
+END
+
+IDD_TCPIPPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "IP-Einstellungen können automatisch zugewiesen werden, wenn das Netzwerk diese Funktion unterstützt. Wenden Sie sich andernfalls an den Netzwerkadministrator, um die geeigneten IP-Einstellungen zu beziehen.", -1, 9, 9, 228, 27
+ CONTROL "I&P-Adresse automatisch beziehen", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12
+ GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX
+ CONTROL "Folgende IP-&Adresse verwenden:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12
+ LTEXT "&IP-Addresse:", -1, 14, 75, 135, 8
+ CONTROL "",IDC_IPADDR,"SysIPAddress32",0,150,75-2,80,12
+ LTEXT "S&ubnetzmaske:", -1, 14, 90, 135, 8
+ CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",0,150,90-2,80,12
+ LTEXT "&Standardgateway:", -1, 14, 105, 135, 8
+ CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",0,150,105-2,80,12
+ CONTROL "D&NS-Serveradresse automatisch beziehen", IDC_AUTODNS, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 139, 210, 12
+ GROUPBOX "", -1, 9, 157, 228, 47, BS_GROUPBOX
+ CONTROL "Folgende DNS-Serveradressen &verwenden:", IDC_FIXEDDNS, "BUTTON", BS_AUTORADIOBUTTON, 14, 155, 142, 12
+ LTEXT "&Bevorzugter DNS-Server:", -1, 14, 171, 135, 8
+ CONTROL "",IDC_DNS1,"SysIPAddress32",0,150,171-2,80,12
+ LTEXT "A&lternativer DNS-Server:", -1, 14, 186, 135, 8
+ CONTROL "",IDC_DNS2,"SysIPAddress32",0,150,186-2,80,12
+ PUSHBUTTON "&Erweitert...", IDC_ADVANCED, 186, 209, 50, 14, WS_DISABLED | WS_TABSTOP
+}
+
+
+STRINGTABLE
+BEGIN
+  IDS_CPLSYSTEMNAME "Netzwerk Einstellungen"
+  IDS_CPLSYSTEMDESCRIPTION "Bearbeite Netzwerkeinstellungen."
+END
diff --git a/reactos/lib/cpl/ncpa/dk.rc b/reactos/lib/cpl/ncpa/dk.rc
new file mode 100644 (file)
index 0000000..30f1340
--- /dev/null
@@ -0,0 +1,87 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_PROPPAGENETWORK DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Netværks Indstillinger"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    LTEXT           "Dine Netwærks Adaptere:",-1,9,9,217,8
+    LISTBOX         IDC_NETCARDLIST,9,21,229,73,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "&Tilføj",IDC_ADD,9,100,60,14
+    PUSHBUTTON      "&Fjern",IDC_REMOVE,72,100,60,14
+    PUSHBUTTON      "&Egenskaber",IDC_PROPERTIES,179,100,60,14
+END
+
+IDD_NETPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Generelt"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Forbind til Netværket/Internettet med:", -1, 9,9,217,8
+ EDITTEXT IDC_NETCARDNAME, 9, 21, 230, 12, WS_DISABLED | WS_BORDER | WS_TABSTOP
+ PUSHBUTTON "&Konfigure", IDC_CONFIGURE, 189, 38, 50, 14
+ LTEXT "Komponeter mærkeret med et flueben er brugt af den forbindelse:", -1, 9, 59, 217, 8
+ LISTBOX IDC_COMPONENTSLIST, 9, 71, 230, 67, LBS_STANDARD
+ PUSHBUTTON "&Installere", IDC_INSTALL, 9, 133, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Afinstallere", IDC_UNINSTALL, 90, 133, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Egenskaber", IDC_PROPERTIES, 174, 133, 65, 14
+ GROUPBOX "Beskrivelse", -1, 9, 153, 230, 46, BS_GROUPBOX
+ LTEXT "Komponent Beskrivelse Her...", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP
+ CHECKBOX "Vis Ikon i System Tray ved forbindelse.", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP
+END
+
+
+IDD_CARDPROPERTIES DIALOG DISCARDABLE  0, 0, 200,180
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Generelt"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Aktiv Forbindelse", -1, 9, 8, 182, 58, BS_GROUPBOX
+ LTEXT "Status:", -1, 19, 20, 60, 8
+ LTEXT "Tids Periode:", -1, 19, 34, 60, 8
+ 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_HORIZONTAL, -1, 90, 85, 18, 20
+ ICON IDI_NETSTAT, -1, 110, 85, 18, 20
+ ICON IDI_HORIZONTAL, -1, 130, 85, 18, 20
+ LTEXT " Modtaget", -1, 149, 90, 37, 8
+ LTEXT "Netværks pakker:", -1, 73, 115, 44, 8
+ RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
+ ICON IDI_VERTICAL, -1, 117, 108, 21, 20
+ RTEXT "000.000.000", IDC_RECEIVED, 134, 115, 44, 8
+ PUSHBUTTON "&Egenskaber", IDC_PROPERTIES, 10, 150, 50, 14
+ PUSHBUTTON "&Deaktiver", IDC_ENDISABLE, 66, 150, 50, 14
+END
+
+IDD_TCPIPPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Du kan få din IP opsætning indstillet automatisk, hvis dit Netværkskort understøtter denne mulighed. Ellers, er du nød til at spørge din 'Netværks Administrator' omkring din IP opsætning.", -1, 9, 9, 228, 27
+ CONTROL "Tildel Automatisk en IP Adresse", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12
+ GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX
+ CONTROL "&Brug følge IP Adresse:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12
+ LTEXT "IP Adresse:", -1, 14, 75, 135, 8
+ CONTROL "",IDC_IPADDR,"SysIPAddress32",0,150,75-2,80,12
+ LTEXT "Subnet maske:", -1, 14, 90, 135, 8
+ CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",0,150,90-2,80,12
+ LTEXT "Standard gateway:", -1, 14, 105, 135, 8
+ CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",0,150,105-2,80,12
+ CONTROL "Tildel automatisk en DNS server adresse.", IDC_AUTODNS, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 139, 210, 12
+ GROUPBOX "", -1, 9, 157, 228, 47, BS_GROUPBOX
+ CONTROL "&Brug følgende DNS Server Adresse:", IDC_FIXEDDNS, "BUTTON", BS_AUTORADIOBUTTON, 14, 155, 142, 12
+ LTEXT "Fortrukket DNS server:", -1, 14, 171, 135, 8
+ CONTROL "",IDC_DNS1,"SysIPAddress32",0,150,171-2,80,12
+ LTEXT "Alternativ DNS server:", -1, 14, 186, 135, 8
+ CONTROL "",IDC_DNS2,"SysIPAddress32",0,150,186-2,80,12
+ PUSHBUTTON "&Avanceret", IDC_ADVANCED, 186, 209, 50, 14, WS_DISABLED | WS_TABSTOP
+}
+
+
+STRINGTABLE 
+BEGIN
+  IDS_CPLSYSTEMNAME "Netværks Indstillinger"
+  IDS_CPLSYSTEMDESCRIPTION "Tilpas dine Netværks Indstillinger."
+END
diff --git a/reactos/lib/cpl/ncpa/en.rc b/reactos/lib/cpl/ncpa/en.rc
new file mode 100644 (file)
index 0000000..30115f5
--- /dev/null
@@ -0,0 +1,87 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+IDD_PROPPAGENETWORK DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Network Properties"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    LTEXT           "Network Adapters",-1,9,9,217,8
+    LISTBOX         IDC_NETCARDLIST,9,21,229,73,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "&Add",IDC_ADD,9,100,60,14
+    PUSHBUTTON      "&Remove",IDC_REMOVE,72,100,60,14
+    PUSHBUTTON      "&Properties",IDC_PROPERTIES,179,100,60,14
+END
+
+IDD_NETPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Connect Using:", -1, 9,9,217,8
+ EDITTEXT IDC_NETCARDNAME, 9, 21, 230, 12, WS_DISABLED | WS_BORDER | WS_TABSTOP
+ PUSHBUTTON "&Configure", IDC_CONFIGURE, 189, 38, 50, 14
+ LTEXT "Components checked are used by this connection:", -1, 9, 59, 217, 8
+ LISTBOX IDC_COMPONENTSLIST, 9, 71, 230, 67, LBS_STANDARD
+ PUSHBUTTON "&Install", IDC_INSTALL, 9, 130, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Uninstall", IDC_UNINSTALL, 90, 130, 65, 14, WS_DISABLED | WS_TABSTOP
+ PUSHBUTTON "&Properties", IDC_PROPERTIES, 174, 130, 65, 14
+ GROUPBOX "Description", -1, 9, 153, 230, 46, BS_GROUPBOX
+ LTEXT "Component Description goes here...", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP
+ CHECKBOX "Show Icon in taskbar when connected", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP
+END
+
+
+IDD_CARDPROPERTIES DIALOG DISCARDABLE  0, 0, 200,180
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Connection", -1, 9, 8, 182, 58, BS_GROUPBOX
+ LTEXT "Status:", -1, 19, 20, 60, 8
+ LTEXT "Duration:", -1, 19, 34, 60, 8
+ 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_HORIZONTAL, -1, 90, 85, 18, 20
+ ICON IDI_NETSTAT, -1, 110, 85, 18, 20
+ ICON IDI_HORIZONTAL, -1, 130, 85, 18, 20
+ LTEXT "Received", -1, 149, 90, 37, 8
+ LTEXT "Packets:", -1, 17, 115, 32, 8
+ RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
+ ICON IDI_VERTICAL, -1, 110, 108, 18, 20
+ RTEXT "000.000.000", IDC_RECEIVED, 139, 115, 44, 8
+ PUSHBUTTON "&Properties", IDC_PROPERTIES, 10, 150, 50, 14
+ PUSHBUTTON "&Disable", IDC_ENDISABLE, 66, 150, 50, 14
+END
+
+IDD_TCPIPPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
+STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "General"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "You can get IP settings assigned automatically if your network supports this capability. Otherwise, you need to ask your network administrator for the appropriate IP settings.", -1, 9, 9, 228, 27
+ CONTROL "Obtain the IP address automatically", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12
+ GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX
+ CONTROL "&Use the following IP address:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12
+ LTEXT "IP address:", -1, 14, 75, 135, 8
+ CONTROL "",IDC_IPADDR,"SysIPAddress32",0,150,75-2,80,12
+ LTEXT "Subnet mask:", -1, 14, 90, 135, 8
+ CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",0,150,90-2,80,12
+ LTEXT "Default gateway:", -1, 14, 105, 135, 8
+ CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",0,150,105-2,80,12
+ CONTROL "Obtain the DNS server address automatically", IDC_AUTODNS, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 139, 210, 12
+ GROUPBOX "", -1, 9, 157, 228, 47, BS_GROUPBOX
+ CONTROL "&Use the following DNS server addresses", IDC_FIXEDDNS, "BUTTON", BS_AUTORADIOBUTTON, 14, 155, 142, 12
+ LTEXT "Preferred DNS server:", -1, 14, 171, 135, 8
+ CONTROL "",IDC_DNS1,"SysIPAddress32",0,150,171-2,80,12
+ LTEXT "Alternate DNS server:", -1, 14, 186, 135, 8
+ CONTROL "",IDC_DNS2,"SysIPAddress32",0,150,186-2,80,12
+ PUSHBUTTON "&Advanced", IDC_ADVANCED, 186, 209, 50, 14, WS_DISABLED | WS_TABSTOP
+}
+
+
+STRINGTABLE 
+BEGIN
+  IDS_CPLSYSTEMNAME "Network Properties"
+  IDS_CPLSYSTEMDESCRIPTION "Customizes network settings."
+END
index 4d6165a..28c8de5 100644 (file)
 #include <reactos/version.rc>
 #endif
 
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
-
 IDI_CPLSYSTEM ICON "resources/applet.ico"
 IDI_HORIZONTAL ICON "resources/HORIZ.ICO"
 IDI_VERTICAL ICON "resources/VERTIC.ICO"
 IDI_NETSTAT ICON "resources/NETCONN.ICO"
 
-IDD_PROPPAGENETWORK DIALOG DISCARDABLE  0, 0, 246, 228
-STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION ""
-FONT 8, "MS Shell Dlg"
-BEGIN
-    LTEXT           "Network Adapters",-1,9,9,217,8
-    LISTBOX         IDC_NETCARDLIST,9,21,229,73,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "&Add",IDC_ADD,9,100,60,14
-    PUSHBUTTON      "&Remove",IDC_REMOVE,72,100,60,14
-    PUSHBUTTON      "&Properties",IDC_PROPERTIES,179,100,60,14
-END
-
-IDD_NETPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
-STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "Connect Using:", -1, 9,9,217,8
- EDITTEXT IDC_NETCARDNAME, 9, 21, 230, 12, WS_DISABLED | WS_BORDER | WS_TABSTOP
- PUSHBUTTON "&Configure", IDC_CONFIGURE, 189, 38, 50, 14
- LTEXT "Components checked are used by this connection:", -1, 9, 59, 217, 8
- LISTBOX IDC_COMPONENTSLIST, 9, 71, 230, 67, LBS_STANDARD
- PUSHBUTTON "&Install", IDC_INSTALL, 9, 130, 65, 14, WS_DISABLED | WS_TABSTOP
- PUSHBUTTON "&Uninstall", IDC_UNINSTALL, 90, 130, 65, 14, WS_DISABLED | WS_TABSTOP
- PUSHBUTTON "&Properties", IDC_PROPERTIES, 174, 130, 65, 14
- GROUPBOX "Description", -1, 9, 153, 230, 46, BS_GROUPBOX
- LTEXT "Component Description goes here...", IDC_DESCRIPTION, 15, 165, 217, 28, WS_GROUP
- CHECKBOX "Show Icon in taskbar when connected", IDC_SHOWTASKBAR, 9, 206, 230, 12, BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP
-END
-
-
-IDD_CARDPROPERTIES DIALOG DISCARDABLE  0, 0, 200,180
-STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
-FONT 8, "MS Shell Dlg"
-BEGIN
- GROUPBOX "Connection", -1, 9, 8, 182, 58, BS_GROUPBOX
- LTEXT "Status:", -1, 19, 20, 60, 8
- LTEXT "Duration:", -1, 19, 34, 60, 8
- 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_HORIZONTAL, -1, 90, 85, 18, 20
- ICON IDI_NETSTAT, -1, 110, 85, 18, 20
- ICON IDI_HORIZONTAL, -1, 130, 85, 18, 20
- LTEXT "Received", -1, 149, 90, 37, 8
- LTEXT "Packets:", -1, 17, 115, 32, 8
- RTEXT "000.000.000", IDC_SEND, 63, 115, 44, 8
- ICON IDI_VERTICAL, -1, 110, 108, 18, 20
- RTEXT "000.000.000", IDC_RECEIVED, 139, 115, 44, 8
- PUSHBUTTON "&Properties", IDC_PROPERTIES, 10, 150, 50, 14
- PUSHBUTTON "&Disable", IDC_ENDISABLE, 66, 150, 50, 14
-END
-
-IDD_TCPIPPROPERTIES DIALOG DISCARDABLE  0, 0, 246, 228
-STYLE DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "General"
-FONT 8, "MS Shell Dlg"
-BEGIN
- LTEXT "You can get IP settings assigned automatically if your network supports this capability. Otherwise, you need to ask your network administrator for the appropriate IP settings.", -1, 9, 9, 228, 27
- CONTROL "Obtain the IP address automatically", IDC_USEDHCP, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 43, 210, 12
- GROUPBOX "", -1, 9, 61, 228, 70, BS_GROUPBOX
- CONTROL "&Use the following IP address:", IDC_NODHCP, "BUTTON", BS_AUTORADIOBUTTON, 14, 59, 105, 12
- LTEXT "IP address:", -1, 14, 75, 135, 8
- CONTROL "",IDC_IPADDR,"SysIPAddress32",0,150,75-2,80,12
- LTEXT "Subnet mask:", -1, 14, 90, 135, 8
- CONTROL "",IDC_SUBNETMASK,"SysIPAddress32",0,150,90-2,80,12
- LTEXT "Default gateway:", -1, 14, 105, 135, 8
- CONTROL "",IDC_DEFGATEWAY,"SysIPAddress32",0,150,105-2,80,12
- CONTROL "Obtain the DNS server address automatically", IDC_AUTODNS, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 14, 139, 210, 12
- GROUPBOX "", -1, 9, 157, 228, 47, BS_GROUPBOX
- CONTROL "&Use the following DNS server addresses", IDC_FIXEDDNS, "BUTTON", BS_AUTORADIOBUTTON, 14, 155, 142, 12
- LTEXT "Preferred DNS server:", -1, 14, 171, 135, 8
- CONTROL "",IDC_DNS1,"SysIPAddress32",0,150,171-2,80,12
- LTEXT "Alternate DNS server:", -1, 14, 186, 135, 8
- CONTROL "",IDC_DNS2,"SysIPAddress32",0,150,186-2,80,12
- PUSHBUTTON "&Advanced", IDC_ADVANCED, 186, 209, 50, 14, WS_DISABLED | WS_TABSTOP
-}
-
-
-STRINGTABLE 
-BEGIN
-  IDS_CPLSYSTEMNAME "Network Properties"
-  IDS_CPLSYSTEMDESCRIPTION "Customizes network settings."
-END
+#include "en.rc"
+#include "de.rc"
+#include "dk.rc"
index 74fa3a5..17bacde 100644 (file)
@@ -1,9 +1,5 @@
 LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
 
-IDI_CPLSYSTEM ICON "resources/applet.ico"
-IDI_DEVMGR ICON "resources/devmgr.ico"
-RC_LICENSE RTDATA "resources/gpl.txt"
-
 IDD_PROPPAGEGENERAL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Allgemein"
@@ -29,10 +25,10 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
   ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1)-5, ICONSIZE, ICONSIZE, SS_ICON
   LTEXT "Windows benutzt folgende Informationen im Sie im Netzwerk zu erkennen.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
-  LTEXT "Vollständiger Computername:",-1,PROPSHEETPADDING,LABELLINE(4)-4,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-4
-  LTEXT "",IDC_COMPUTERNAME,120,LABELLINE(4)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-5
-  LTEXT "Arbeitsgruppe:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
-  LTEXT "",IDC_WORKGROUPDOMAIN_NAME,120,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
+  LTEXT "Vollständiger Computername:",-1,PROPSHEETPADDING,LABELLINE(4)-4,17*PROPSHEETPADDING,LABELLINE(4)-4
+  LTEXT "(Default)",IDC_COMPUTERNAME,17*PROPSHEETPADDING,LABELLINE(4)-5,60,LABELLINE(4)-5
+  LTEXT "Arbeitsgruppe:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,17*PROPSHEETPADDING,LABELLINE(6)-6
+  LTEXT "(leer)",IDC_WORKGROUPDOMAIN_NAME,17*PROPSHEETPADDING,LABELLINE(6)-6,60,LABELLINE(6)-6
   LTEXT "Klicken Sie auf Netzwerkkennung um sich einer Domaine anzuschließen und einen lokalen Benutzer zu erstellen",-1,PROPSHEETPADDING,LABELLINE(7)+5,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(8)+5
   PUSHBUTTON "&Netzwerkkennung...",IDC_NETWORK_ID,175,LABELLINE(7)+5,70,LABELLINE(1)+4
   LTEXT "Klicken Sie auf Eigenschaften, um den Computer umzubennen oder einer Domäne anzuschließen.",-1,PROPSHEETPADDING,LABELLINE(11)+2,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(12)+2
@@ -72,8 +68,8 @@ BEGIN
   CONTROL "",IDC_USERPROFILE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|WS_BORDER|WS_TABSTOP,PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(11),WS_EX_CLIENTEDGE
   
   PUSHBUTTON "Löschen",IDC_USERPROFILE_DELETE,PROPSHEETPADDING,LABELLINE(20),60,LABELLINE(1)+2
-  PUSHBUTTON "Typ ändern...",IDC_USERPROFILE_CHANGE,95,LABELLINE(20),60,LABELLINE(1)+2
-  PUSHBUTTON "Kopieren zu...",IDC_USERPROFILE_COPY,180,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Typ ändern...",IDC_USERPROFILE_CHANGE,(PROPSHEETWIDTH/2)-30,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Kopieren zu...",IDC_USERPROFILE_COPY,PROPSHEETWIDTH-PROPSHEETPADDING-60,LABELLINE(20),60,LABELLINE(1)+2
 END
 
 IDD_PROPPAGEADVANCED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
@@ -87,7 +83,7 @@ BEGIN
   PUSHBUTTON "&Systemleistungseinstellungen...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(5)+2,(18*PROPSHEETPADDING),14
   GROUPBOX "Umgebungsvariablen",-1,PROPSHEETPADDING,LABELLINE(8)+2,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
   ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-5, ICONSIZE, ICONSIZE, SS_ICON
-  LTEXT "Über Umgebungvariablen wird festgelegt, wo bestimmte Informationen zu finden sind.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(11)
+  LTEXT "Über Umgebungvariablen wird festgelegt, wo bestimmte Informationen zu finden sind.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
   PUSHBUTTON "&Umgebungsvariablen..",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(12)+2,(18*PROPSHEETPADDING),14
   GROUPBOX "&Start und Wiederherstellung",-1,PROPSHEETPADDING,LABELLINE(15)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
   ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(17)-5, ICONSIZE, ICONSIZE, SS_ICON
diff --git a/reactos/lib/cpl/sysdm/dk.rc b/reactos/lib/cpl/sysdm/dk.rc
new file mode 100644 (file)
index 0000000..191bde4
--- /dev/null
@@ -0,0 +1,137 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_PROPPAGEGENERAL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Generelt"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Operativsystem:",-1,SYSTEM_COLUMN,LABELLINE(2),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT REACTOS_STR_PRODUCT_NAME,-1,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(3),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Version: " REACTOS_STR_PRODUCT_VERSION,-1,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(4),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  
+  LTEXT "Computer:",-1,SYSTEM_COLUMN,LABELLINE(6),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Processor Forhandler:",IDC_PROCESSORMANUFACTURER,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(7),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Processor Navn:",IDC_PROCESSOR,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Processor Hastighed:",IDC_PROCESSORSPEED,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(9),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Hukommelse:",IDC_SYSTEMMEMORY,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(10),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  
+  EDITTEXT IDC_LICENSEMEMO,PROPSHEETPADDING,LABELLINE(13),PROPSHEETWIDTH-(2*PROPSHEETPADDING),PROPSHEETHEIGHT-LABELLINE(13)-PROPSHEETPADDING,ES_LEFT|WS_TABSTOP|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_GROUP|ES_MULTILINE|ES_READONLY
+END
+
+IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Netværks Identifikation"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Reactos bruger følgende informationer til at identificere din computer på netværket.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  LTEXT "Dit Fulde Computer Navn:",-1,PROPSHEETPADDING,LABELLINE(4)-4,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-4
+  LTEXT "",IDC_COMPUTERNAME,120,LABELLINE(4)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-5
+  LTEXT "Arbejdsgruppe:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
+  LTEXT "",IDC_WORKGROUPDOMAIN_NAME,120,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
+  LTEXT "For at bruge Netværks Identfications Guiden til at melde in et et domæne eller oprette en lokal bruger, Klik på Netværks ID.",-1,PROPSHEETPADDING,LABELLINE(7)+5,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(8)+5
+  PUSHBUTTON "&Netværks ID...",IDC_NETWORK_ID,175,LABELLINE(7)+5,70,LABELLINE(1)+4
+  LTEXT "For at omdøbe denne computer eller for at melde ind i et Domæne, Klik på Egenskaber.",-1,PROPSHEETPADDING,LABELLINE(11)+2,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(12)+2
+  PUSHBUTTON "&Egenskaber...",IDC_NETWORK_PROPERTY,175,LABELLINE(11)+2,70,LABELLINE(1)+4
+END
+
+IDD_PROPPAGEHARDWARE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Hardware"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN  
+  GROUPBOX "Hardware Guide",-1,PROPSHEETPADDING,LABELLINE(1),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  LTEXT "Hardware Guiden hjælper dig med at Installer, Afinstaller, Reparerer, Afmontere, Fjerne, og konfigurer din hardware.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON
+  PUSHBUTTON "&Hardware Guide...",IDC_HARDWARE_WIZARD,PROPSHEETWIDTH-(17*PROPSHEETPADDING),LABELLINE(5)+2,(15*PROPSHEETPADDING),14
+
+  GROUPBOX "Enhedshåntering",-1,PROPSHEETPADDING,LABELLINE(8)+5,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(7)+2
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-3,ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Enhedshåntering viser alle dine hardware enheder installeret på din computer. Brug Enhedshåntering til at skifte indstillinger for alle Hardware Enheder.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-3,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  
+  PUSHBUTTON "&Enhedshåntering...",IDC_HARDWARE_DEVICE_MANAGER,PROPSHEETWIDTH-(17*PROPSHEETPADDING),LABELLINE(13)+2,(15*PROPSHEETPADDING),14
+
+  GROUPBOX "Hardware Profiler",-1,PROPSHEETPADDING,LABELLINE(16)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(18)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Hardware Profiler Giver dig en mulighed for at sætte og gemme forskellinge hardware indstillinger.",0,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(18)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "Hard&ware Profiler...",IDC_HARDWARE_PROFILE,PROPSHEETWIDTH-(17*PROPSHEETPADDING),LABELLINE(20)+2,(15*PROPSHEETPADDING),14
+END
+
+IDD_PROPPAGEUSERPROFILE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Bruger Profiler"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1), ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Bruger Profiler indeholde skrivebords indstillinger og andre informationer relateret til dit login. En Anden bruger profil bliver oprette på alle computere du logger på, eller du kan vælge en Roaming profil some er den samme på alle computer du logger på.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)
+  LTEXT "Bruger Profiler gemt på denne computer:",-1,PROPSHEETPADDING,LABELLINE(6),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(1)
+  CONTROL "",IDC_USERPROFILE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|WS_BORDER|WS_TABSTOP,PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(11),WS_EX_CLIENTEDGE
+  
+  PUSHBUTTON "&Slet",IDC_USERPROFILE_DELETE,PROPSHEETPADDING,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Skift &Type...",IDC_USERPROFILE_CHANGE,95,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "&Kopiere Til...",IDC_USERPROFILE_COPY,180,LABELLINE(20),60,LABELLINE(1)+2
+END
+
+IDD_PROPPAGEADVANCED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Avanceret"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  GROUPBOX "Hukommelses Indstillinger",-1,PROPSHEETPADDING,LABELLINE(1),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Hukommelses indstillingerne styrer programmers brug af hukommelse, hvilket påvirker hastigheden af din computer.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "&Hukommelses indstillinger...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(5)+2,(18*PROPSHEETPADDING),14
+  GROUPBOX "Miljø Variabler",-1,PROPSHEETPADDING,LABELLINE(8)+2,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Miljø Variabler fortæller din computer hvor den kan finde forskellige typer af informationer.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(11)
+  PUSHBUTTON "&Miljø Variabler...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(12)+2,(18*PROPSHEETPADDING),14
+  GROUPBOX "&Opstart og Gendannelse",-1,PROPSHEETPADDING,LABELLINE(15)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(17)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Opstart og Gendannelse fortæller din computer hvordan den skal starte og hvad den skal gøre hvis en kritisk fejl opstår som får din computer til at stoppe.",0,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(17)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "&Opstart og Gendannelse...",IDC_STAREC,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(19)+2,(18*PROPSHEETPADDING),14
+END
+
+IDD_ENVIRONMENT_VARIABLES DIALOGEX 6, 18, 252, 245
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Miljø Variabler"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  GROUPBOX "Brugere Variabler",-1,7,12,238,100
+  LTEXT "&Variabler:",-1,14,24,224,8
+  CONTROL "",IDC_USER_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,35,224,48,WS_EX_CLIENTEDGE
+  PUSHBUTTON "&Ny...",IDC_USER_VARIABLE_NEW,80,90,50,14
+  PUSHBUTTON "&Redigere...",IDC_USER_VARIABLE_EDIT,134,90,50,14
+  PUSHBUTTON "&Slet",IDC_USER_VARIABLE_DELETE,188,90,50,14
+
+  GROUPBOX "System Variabler",-1,7,116,238,100
+  LTEXT "V&ariabler:",-1,14,128,224,8
+  CONTROL "",IDC_SYSTEM_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,139,224,48,WS_EX_CLIENTEDGE
+  PUSHBUTTON "N&y...",IDC_SYSTEM_VARIABLE_NEW,80,194,50,14
+  PUSHBUTTON "R&edigere...",IDC_SYSTEM_VARIABLE_EDIT,134,194,50,14
+  PUSHBUTTON "S&let",IDC_SYSTEM_VARIABLE_DELETE,188,194,50,14
+
+  DEFPUSHBUTTON "OK",IDOK,141,224,50,14,WS_GROUP
+  PUSHBUTTON "Fortryd",IDCANCEL,195,224,50,14
+END
+
+
+IDD_EDIT_VARIABLE DIALOGEX 10, 15, 227, 71
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Redigere Variable"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT           "&Navn:",-1,7,14,50,8
+  EDITTEXT        IDC_VARIABLE_NAME,75,12,145,12,ES_AUTOHSCROLL
+  LTEXT           "&Indhold:",-1,7,32,50,8
+  EDITTEXT        IDC_VARIABLE_VALUE,75,30,145,12,ES_AUTOHSCROLL
+  
+  DEFPUSHBUTTON "OK",IDOK,116,50,50,14,WS_GROUP
+  PUSHBUTTON "Fortryd",IDCANCEL,170,50,50,14
+END
+
+
+STRINGTABLE 
+BEGIN
+  IDS_CPLSYSTEMNAME "System Indstillinger"
+  IDS_CPLSYSTEMDESCRIPTION "Se mere information omkring din computer, og skift diverse system og hardware indstillinger."
+END
index 2289a9f..eee2c6b 100644 (file)
@@ -1,7 +1,5 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 
-IDI_CPLSYSTEM ICON "resources/applet.ico"
-IDI_DEVMGR ICON "resources/devmgr.ico"
 RC_LICENSE RTDATA "resources/gpl.txt"
 
 IDD_PROPPAGEGENERAL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
@@ -29,10 +27,10 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x0
 BEGIN
   ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1)-5, ICONSIZE, ICONSIZE, SS_ICON
   LTEXT "Windows uses the following information to identify your computer on the network.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
-  LTEXT "Full computer name:",-1,PROPSHEETPADDING,LABELLINE(4)-4,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-4
-  LTEXT "",IDC_COMPUTERNAME,120,LABELLINE(4)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(4)-5
-  LTEXT "Workgroup:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
-  LTEXT "",IDC_WORKGROUPDOMAIN_NAME,120,LABELLINE(6)-6,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(6)-6
+  LTEXT "Full computer name:",-1,PROPSHEETPADDING,LABELLINE(4)-4,17*PROPSHEETPADDING,LABELLINE(4)-4
+  LTEXT "(Default)",IDC_COMPUTERNAME,17*PROPSHEETPADDING,LABELLINE(4)-5,60,LABELLINE(4)-5
+  LTEXT "Workgroup:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,17*PROPSHEETPADDING,LABELLINE(6)-6
+  LTEXT "(empty)",IDC_WORKGROUPDOMAIN_NAME,17*PROPSHEETPADDING,LABELLINE(6)-6,60,LABELLINE(6)-6
   LTEXT "To use the Network Identfication Wizard to join a domain and create a local user, click Network ID.",-1,PROPSHEETPADDING,LABELLINE(7)+5,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(8)+5
   PUSHBUTTON "&Network ID...",IDC_NETWORK_ID,175,LABELLINE(7)+5,70,LABELLINE(1)+4
   LTEXT "To rename this computer or join a domain, click Properties.",-1,PROPSHEETPADDING,LABELLINE(11)+2,PROPSHEETWIDTH-(12*PROPSHEETPADDING)-ICONSIZE,LABELLINE(12)+2
@@ -72,8 +70,8 @@ BEGIN
   CONTROL "",IDC_USERPROFILE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|WS_BORDER|WS_TABSTOP,PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(11),WS_EX_CLIENTEDGE
   
   PUSHBUTTON "Delete",IDC_USERPROFILE_DELETE,PROPSHEETPADDING,LABELLINE(20),60,LABELLINE(1)+2
-  PUSHBUTTON "Change Type...",IDC_USERPROFILE_CHANGE,95,LABELLINE(20),60,LABELLINE(1)+2
-  PUSHBUTTON "Copy To...",IDC_USERPROFILE_COPY,180,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Change Type...",IDC_USERPROFILE_CHANGE,(PROPSHEETWIDTH/2)-30,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Copy To...",IDC_USERPROFILE_COPY,PROPSHEETWIDTH-PROPSHEETPADDING-60,LABELLINE(20),60,LABELLINE(1)+2
 END
 
 IDD_PROPPAGEADVANCED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
@@ -87,7 +85,7 @@ BEGIN
   PUSHBUTTON "&Performance Options...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(5)+2,(18*PROPSHEETPADDING),14
   GROUPBOX "Environment Variables",-1,PROPSHEETPADDING,LABELLINE(8)+2,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
   ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-5, ICONSIZE, ICONSIZE, SS_ICON
-  LTEXT "Environment variables tell your computer where to find certain types of information.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(11)
+  LTEXT "Environment variables tell your computer where to find certain types of information.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
   PUSHBUTTON "&Environment Variables...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(12)+2,(18*PROPSHEETPADDING),14
   GROUPBOX "&Startup and Recovery",-1,PROPSHEETPADDING,LABELLINE(15)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
   ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(17)-5, ICONSIZE, ICONSIZE, SS_ICON
diff --git a/reactos/lib/cpl/sysdm/fr.rc b/reactos/lib/cpl/sysdm/fr.rc
new file mode 100644 (file)
index 0000000..b0efcb8
--- /dev/null
@@ -0,0 +1,141 @@
+LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
+
+IDI_CPLSYSTEM ICON "resources/applet.ico"
+IDI_DEVMGR ICON "resources/devmgr.ico"
+RC_LICENSE RTDATA "resources/gpl.txt"
+
+IDD_PROPPAGEGENERAL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Général"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Système d'exploitation",-1,SYSTEM_COLUMN,LABELLINE(2),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT REACTOS_STR_PRODUCT_NAME,-1,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(3),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "Version " REACTOS_STR_PRODUCT_VERSION,-1,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(4),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  
+  LTEXT "Ordinateur",-1,SYSTEM_COLUMN,LABELLINE(6),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "",IDC_PROCESSORMANUFACTURER,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(7),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "",IDC_PROCESSOR,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "",IDC_PROCESSORSPEED,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(9),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  LTEXT "",IDC_SYSTEMMEMORY,SYSTEM_COLUMN+PROPSHEETPADDING,LABELLINE(10),PROPSHEETWIDTH-SYSTEM_COLUMN-PROPSHEETPADDING,8
+  
+  EDITTEXT IDC_LICENSEMEMO,PROPSHEETPADDING,LABELLINE(13),PROPSHEETWIDTH-(2*PROPSHEETPADDING),PROPSHEETHEIGHT-LABELLINE(13)-PROPSHEETPADDING,ES_LEFT|WS_TABSTOP|WS_BORDER|WS_VSCROLL|WS_HSCROLL|WS_GROUP|ES_MULTILINE|ES_READONLY
+END
+
+IDD_PROPPAGECOMPUTER DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Identification réseau"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "ReactOS utilise les informations suivantes pour identifier votre ordinateur sur le réseau.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  LTEXT "Nom complet de l'ordinateur:",-1,PROPSHEETPADDING,LABELLINE(4)-4,17*PROPSHEETPADDING,LABELLINE(4)-4
+  LTEXT "(Défaut)",IDC_COMPUTERNAME,17*PROPSHEETPADDING,LABELLINE(4)-5,60,LABELLINE(4)-5
+  LTEXT "Domaine:",IDC_WORKGROUPDOMAIN,PROPSHEETPADDING,LABELLINE(6)-6,17*PROPSHEETPADDING,LABELLINE(6)-6
+  LTEXT "(vide)",IDC_WORKGROUPDOMAIN_NAME,17*PROPSHEETPADDING,LABELLINE(6)-6,60,LABELLINE(6)-6
+  LTEXT "Pour utiliser l'Assistant Réseau, afin de rejoindre un domaine ou créer un utilisateur local, cliquez sur Identification Réseau.",-1,PROPSHEETPADDING,LABELLINE(7)+5,PROPSHEETWIDTH-(13*PROPSHEETPADDING)-ICONSIZE,LABELLINE(8)+5
+  PUSHBUTTON "&Identification &réseau...",IDC_NETWORK_ID,170,LABELLINE(7)+5,80,LABELLINE(1)+4
+  LTEXT "Pour changer le nom de cet ordinateur ou rejoindre un domaine, cliquez sur Propriétés.",-1,PROPSHEETPADDING,LABELLINE(11)+2,PROPSHEETWIDTH-(13*PROPSHEETPADDING)-ICONSIZE,LABELLINE(12)+2
+  PUSHBUTTON "&Propriétés...",IDC_NETWORK_PROPERTY,170,LABELLINE(11)+2,80,LABELLINE(1)+4
+END
+
+IDD_PROPPAGEHARDWARE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Matériel"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN  
+  GROUPBOX "Assistant matériel",-1,PROPSHEETPADDING,LABELLINE(1),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  LTEXT "L'Assistant matériel vous aide à installer, désinstaller, réparer, débrancher, enlever et configurer votre matériel.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON
+  PUSHBUTTON "Assistant &matériel...",IDC_HARDWARE_WIZARD,PROPSHEETWIDTH-(21*PROPSHEETPADDING),LABELLINE(5)+2,(19*PROPSHEETPADDING),14
+
+  GROUPBOX "Gestionnaire de périphériques",-1,PROPSHEETPADDING,LABELLINE(8)+5,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(7)+2
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-3,ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Le Gestionnaire de périphériques liste tous les périphériques installés sur votre ordinateur. Utilisez le Gestionnaire de périphériques pour modifier les propriétés de tout périphérique.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-3,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  
+  PUSHBUTTON "&Gestionnaire de périphériques...",IDC_HARDWARE_DEVICE_MANAGER,PROPSHEETWIDTH-(21*PROPSHEETPADDING),LABELLINE(13)+2,(19*PROPSHEETPADDING),14
+
+  GROUPBOX "Profils matériels",-1,PROPSHEETPADDING,LABELLINE(16)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(18)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Les Profils matériels vous donnent un moyen de metttre en place et conserver différentes configurations matérielles.",0,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(18)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "Profils &matériels...",IDC_HARDWARE_PROFILE,PROPSHEETWIDTH-(21*PROPSHEETPADDING),LABELLINE(20)+2,(19*PROPSHEETPADDING),14
+END
+
+IDD_PROPPAGEUSERPROFILE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Profils utilisateurs"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  ICON IDI_DEVMGR, IDC_ICON1, PROPSHEETPADDING,LABELLINE(1), ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Les Profils utilisateurs contiennent les réglages bureau et d'autres informations associées à votre compte utilisateur. Un profil différent peut être créé sur chaque ordinateur que vous utilisez, ou vous pouvez choisir un profil nomade qui sera identique sur chaque ordinateur que vous utiliserez.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(1),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(5)
+  LTEXT "Profils sauvés sur cet ordinateur:",-1,PROPSHEETPADDING,LABELLINE(6),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(1)
+  CONTROL "",IDC_USERPROFILE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|WS_BORDER|WS_TABSTOP,PROPSHEETPADDING,LABELLINE(8),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(11),WS_EX_CLIENTEDGE
+  
+  PUSHBUTTON "Effacer",IDC_USERPROFILE_DELETE,PROPSHEETPADDING,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Modifier le type...",IDC_USERPROFILE_CHANGE,(PROPSHEETWIDTH/2)-30,LABELLINE(20),60,LABELLINE(1)+2
+  PUSHBUTTON "Copier vers...",IDC_USERPROFILE_COPY,PROPSHEETWIDTH-PROPSHEETPADDING-60,LABELLINE(20),60,LABELLINE(1)+2
+END
+
+IDD_PROPPAGEADVANCED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Avancé"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  GROUPBOX "Performances",-1,PROPSHEETPADDING,LABELLINE(1),PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(2), ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Les options de performance controlent comment les applications utilisent la mémoire, ce qui affecte la vitesse de votre ordinateur.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(2),PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "&Options Performances...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(5)+2,(18*PROPSHEETPADDING),14
+  GROUPBOX "Variables d'environnement",-1,PROPSHEETPADDING,LABELLINE(8)+2,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(10)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Les Variables d'environnement indiquent à votre ordinateur où trouver certains types d'informations.",-1,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(10)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "Variables d'&environnement...",IDC_ENVVAR,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(12)+2,(18*PROPSHEETPADDING),14
+  GROUPBOX "&Démarrage et récupération",-1,PROPSHEETPADDING,LABELLINE(15)+3,PROPSHEETWIDTH-(2*PROPSHEETPADDING),LABELLINE(6)+PROPSHEETPADDING
+  ICON IDI_DEVMGR, IDC_ICON1, (2*PROPSHEETPADDING),LABELLINE(17)-5, ICONSIZE, ICONSIZE, SS_ICON
+  LTEXT "Les options de d&émarrage et de récupération disent à votre ordinateur comment démarrer et quoi faire en cas d'arrêt dû à une erreur système.",0,(4*PROPSHEETPADDING)+ICONSIZE,LABELLINE(17)-5,PROPSHEETWIDTH-(6*PROPSHEETPADDING)-ICONSIZE,LABELLINE(3)
+  PUSHBUTTON "&Démarrage et récupération...",IDC_STAREC,PROPSHEETWIDTH-(20*PROPSHEETPADDING),LABELLINE(19)+2,(18*PROPSHEETPADDING),14
+END
+
+IDD_ENVIRONMENT_VARIABLES DIALOGEX 6, 18, 252, 245
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Variables d'environnement"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  GROUPBOX "Variables utilisateur",-1,7,12,238,100
+  LTEXT "&Variables:",-1,14,24,224,8
+  CONTROL "",IDC_USER_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,35,224,48,WS_EX_CLIENTEDGE
+  PUSHBUTTON "&Nouveau...",IDC_USER_VARIABLE_NEW,80,90,50,14
+  PUSHBUTTON "&Modifier...",IDC_USER_VARIABLE_EDIT,134,90,50,14
+  PUSHBUTTON "&Effacer",IDC_USER_VARIABLE_DELETE,188,90,50,14
+
+  GROUPBOX "Variables système",-1,7,116,238,100
+  LTEXT "V&ariables:",-1,14,128,224,8
+  CONTROL "",IDC_SYSTEM_VARIABLE_LIST,"SysListView32",LVS_REPORT|LVS_SINGLESEL|LVS_SHOWSELALWAYS|LVS_SORTASCENDING|LVS_NOSORTHEADER|WS_VSCROLL|WS_HSCROLL|WS_TABSTOP,14,139,224,48,WS_EX_CLIENTEDGE
+  PUSHBUTTON "&Nouveau......",IDC_SYSTEM_VARIABLE_NEW,80,194,50,14
+  PUSHBUTTON "&Modifier...",IDC_SYSTEM_VARIABLE_EDIT,134,194,50,14
+  PUSHBUTTON "&Effacer",IDC_SYSTEM_VARIABLE_DELETE,188,194,50,14
+
+  DEFPUSHBUTTON "OK",IDOK,141,224,50,14,WS_GROUP
+  PUSHBUTTON "Annuler",IDCANCEL,195,224,50,14
+END
+
+
+IDD_EDIT_VARIABLE DIALOGEX 10, 15, 240, 71
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Modifier la variable"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT           "&Nom de la variable:",-1,7,14,65,8
+  EDITTEXT        IDC_VARIABLE_NAME,85,12,145,12,ES_AUTOHSCROLL
+  LTEXT           "&Valeur de la variable:",-1,7,32,70,8
+  EDITTEXT        IDC_VARIABLE_VALUE,85,30,145,12,ES_AUTOHSCROLL
+  
+  DEFPUSHBUTTON "OK",IDOK,116,50,50,14,WS_GROUP
+  PUSHBUTTON "Annuler",IDCANCEL,170,50,50,14
+END
+
+
+STRINGTABLE 
+BEGIN
+  IDS_CPLSYSTEMNAME "Système"
+  IDS_CPLSYSTEMDESCRIPTION "Afficher les informations sur votre odrinateur et changer les paramètres du système et du matériel."
+END
index 2a9aeef..70e50a6 100644 (file)
@@ -14,7 +14,10 @@ LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
 #define REACTOS_STR_ORIGINAL_FILENAME  "sysdm.cpl\0"
 #include <reactos/version.rc>
 
+IDI_CPLSYSTEM ICON "resources/applet.ico"
+IDI_DEVMGR ICON "resources/devmgr.ico"
 
 #include "en.rc"
 #include "de.rc"
-
+#include "dk.rc"
+#include "fr.rc"
index b616d68..518bdec 100644 (file)
@@ -1,4 +1,4 @@
-<module name="sysdm" type="win32dll" extension=".cpl" baseaddress="${BASEADDRESS_SYSDM}" installbase="system32" installname="sysdm.cpl">\r
+<module name="sysdm" type="win32dll" extension=".cpl" baseaddress="${BASEADDRESS_SYSDM}" installbase="system32" installname="sysdm.cpl" usewrc="false">\r
        <importlibrary definition="sysdm.def" />\r
        <include base="sysdm">.</include>\r
        <define name="UNICODE" />\r
diff --git a/reactos/lib/cpl/timedate/Dk.rc b/reactos/lib/cpl/timedate/Dk.rc
new file mode 100644 (file)
index 0000000..416c324
--- /dev/null
@@ -0,0 +1,43 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_DATETIMEPAGE DIALOGEX 0, 0, 252, 149
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Dato && Tid"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    GROUPBOX "&Dato", -1, 4, 2, 126, 133
+    CONTROL "", IDC_DATEPICKER, "SysDateTimePick32",
+            DTS_SHORTDATEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+            10, 17, 115, 12
+    CONTROL "", IDC_MONTHCALENDAR, "SysMonthCal32",
+            WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
+            9, 34, 115, 97
+    GROUPBOX "&Klokken",
+             -1, 132, 2, 113, 133
+    CONTROL "", IDC_TIMEPICKER, "SysDateTimePick32",
+            DTS_TIMEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+            144, 17, 90, 12
+    LTEXT "Nuværende Tidszone:", IDC_TIMEZONE, 4, 138, 241, 8
+END
+
+
+IDD_TIMEZONEPAGE DIALOGEX 0, 0, 252, 146
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Tidszone"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    COMBOBOX IDC_TIMEZONELIST, 5, 4, 241, 136,
+             CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP
+    AUTOCHECKBOX "Justere uret automatisk efter &Sommertid/Vintertid.",
+                 IDC_AUTODAYLIGHT, 5, 136, 241, 10, WS_VISIBLE | WS_GROUP | WS_TABSTOP
+END
+
+
+STRINGTABLE
+BEGIN
+    IDS_CPLNAME "Dato/Tid"
+    IDS_CPLDESCRIPTION "Skifter Dato, Tid og Tidszone informationer."
+    IDS_TIMEZONETEXT "Nuværende tidszone: %s"
+    IDS_TIMEZONEINVALID "Ugyldig"
+    IDS_TIMEZONEUNKNOWN "Ukendt"
+END
diff --git a/reactos/lib/cpl/timedate/Ru.rc b/reactos/lib/cpl/timedate/Ru.rc
new file mode 100644 (file)
index 0000000..09f7e09
--- /dev/null
@@ -0,0 +1,42 @@
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT\r
+\r
+IDD_DATETIMEPAGE DIALOGEX 0, 0, 252, 146\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Äàòà è âðåìÿ"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+    GROUPBOX "&Äàòà", -1, 4, 2, 122, 125\r
+    CONTROL "", IDC_DATEPICKER, "SysDateTimePick32",\r
+            DTS_SHORTDATEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            11, 17, 108, 12\r
+    CONTROL "", IDC_MONTHCALENDAR, "SysMonthCal32",\r
+            WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            11, 37, 108, 80\r
+    GROUPBOX "&Âðåìÿ", -1, 132, 2, 113, 125\r
+    CONTROL "", IDC_TIMEPICKER, "SysDateTimePick32",\r
+            DTS_TIMEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            144, 17, 90, 12\r
+    LTEXT "", IDC_TIMEZONE, 4, 136, 241, 8\r
+END\r
+\r
+\r
+IDD_TIMEZONEPAGE DIALOGEX 0, 0, 252, 146\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "×àñîâîé ïîÿñ"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+    COMBOBOX IDC_TIMEZONELIST, 5, 4, 241, 136,\r
+             CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP\r
+    AUTOCHECKBOX "Àâòîìàòè&÷åñêèé ïåðåõîä íà ëåòíåå âðåìÿ è îáðàòíî",\r
+                 IDC_AUTODAYLIGHT, 5, 136, 241, 10, WS_VISIBLE | WS_GROUP | WS_TABSTOP\r
+END\r
+\r
+\r
+STRINGTABLE\r
+BEGIN\r
+    IDS_CPLNAME "Äàòà è âðåìÿ"\r
+    IDS_CPLDESCRIPTION "Óñòàíîâêà äàòû, âðåìåíè è ÷àñîâîãî ïîÿñà äëÿ ýòîãî êîìïüþòåðà"\r
+    IDS_TIMEZONETEXT "Òåêóùèé ÷àñîâîé ïîÿñ: %s"\r
+    IDS_TIMEZONEINVALID "Íåäåéñòâèòåëüíàÿ"\r
+    IDS_TIMEZONEUNKNOWN "Íåèçâåñòíàÿ"\r
+END\r
diff --git a/reactos/lib/cpl/timedate/Sv.rc b/reactos/lib/cpl/timedate/Sv.rc
new file mode 100644 (file)
index 0000000..d245db4
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Swedish resources by Andreas Bjerkeholt\r
+ *\r
+ */\r
+\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+IDD_DATETIMEPAGE DIALOGEX 0, 0, 252, 146\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Datum && Tid"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+    GROUPBOX "&Datum", -1, 4, 2, 122, 125\r
+    CONTROL "", IDC_DATEPICKER, "SysDateTimePick32",\r
+            DTS_SHORTDATEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            11, 17, 108, 12\r
+    CONTROL "", IDC_MONTHCALENDAR, "SysMonthCal32",\r
+            WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            11, 37, 108, 80\r
+    GROUPBOX "&Tid", -1, 132, 2, 113, 125\r
+    CONTROL "", IDC_TIMEPICKER, "SysDateTimePick32",\r
+            DTS_TIMEFORMAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,\r
+            144, 17, 90, 12\r
+    LTEXT "", IDC_TIMEZONE, 4, 136, 241, 8\r
+END\r
+\r
+\r
+IDD_TIMEZONEPAGE DIALOGEX 0, 0, 252, 146\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Tidszon"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+    COMBOBOX IDC_TIMEZONELIST, 5, 4, 241, 136,\r
+             CBS_DROPDOWNLIST | WS_VSCROLL | WS_VISIBLE | WS_TABSTOP\r
+    AUTOCHECKBOX "&Justera klockan automatiskt för sommar- och vintertid",\r
+                 IDC_AUTODAYLIGHT, 5, 136, 241, 10, WS_VISIBLE | WS_GROUP | WS_TABSTOP\r
+END\r
+\r
+\r
+STRINGTABLE\r
+BEGIN\r
+    IDS_CPLNAME "Datum/Tid"\r
+    IDS_CPLDESCRIPTION "Ändrar information om datum, tid och tidszon."\r
+    IDS_TIMEZONETEXT "Aktuell tidszon: %s"\r
+    IDS_TIMEZONEINVALID "Felaktig"\r
+    IDS_TIMEZONEUNKNOWN "Okänd"\r
+END\r
index cc27842..657708a 100644 (file)
@@ -19,5 +19,8 @@ IDC_CPLICON ICON "resources/applet.ico"
 
 #include "En.rc"
 #include "De.rc"
+#include "Dk.rc"
 #include "Es.rc"
 #include "Fr.rc"
+#include "Ru.rc"
+#include "Sv.rc"
index f751c30..4823522 100644 (file)
@@ -1,16 +1,8 @@
 #include "precomp.h"
+#include <math.h>
 #include <ntos/except.h>
 
 
-struct _exception {
-    int type;
-    char* name;
-    double arg1;
-    double arg2;
-    double retval;
-} ;
-
-
 int _matherr(struct _exception* e)
 {
     return 0;
index 523c02c..d7c8a10 100644 (file)
@@ -1,7 +1,3 @@
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
-
 #include <float.h>
 #include <internal/tls.h>
 
index 040c479..b451e29 100644 (file)
@@ -17,6 +17,9 @@
 #include <fcntl.h>
 #include <stdarg.h>
 
+#include <windef.h>
+#include <winbase.h>
+#include <winnt.h>
 
 #ifndef _IORMONCL
 #define _IORMONCL 004000  /* remove on close, for temp files */
@@ -50,9 +53,6 @@ void free_fd(int _fd);
 void sigabort_handler(int sig);
 char split_oflags(int oflags);
 
-
-#include <windows.h>
-
 unsigned create_io_inherit_block(STARTUPINFOA* si);
 void UnixTimeToFileTime(time_t unix_time, FILETIME* filetime, DWORD remainder);
 time_t FileTimeToUnixTime(const FILETIME* filetime, DWORD *remainder);
index 1bb029c..690aa39 100644 (file)
@@ -3,7 +3,12 @@
 #ifndef __CRT_INTERNAL_TLS_H
 #define __CRT_INTERNAL_TLS_H
 
-#include <windows.h>
+#include <stdarg.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include <winnt.h>
+
 #include <msvcrt/crttypes.h>
 #include <stddef.h>
 
index d54ae83..189ef81 100644 (file)
@@ -1,5 +1,4 @@
-#include <io.h>
-#include <sys/stat.h>
+#include <internal/file.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -7,13 +6,10 @@
 /*
  * @implemented
  */
-int _isatty( int fd )
+int _isatty(int fd)
 {
-  struct _stat buf;
-  DPRINT("_isatty(fd %d)\n", fd);
-  if (_fstat (fd, &buf) < 0)
+  HANDLE hFile = fdinfo(fd)->hFile;
+  if (hFile == INVALID_HANDLE_VALUE)
     return 0;
-  if (S_ISCHR (buf.st_mode))
-    return 1;
-  return 0;
+  return GetFileType(hFile) == FILE_TYPE_CHAR ? 1 : 0;
 }
index 83b7532..d36c3cb 100644 (file)
@@ -608,14 +608,20 @@ BOOL __fileno_init(void)
 
    if (fdinfo(0)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(0)->fdflags & FOPEN)) {
       fdinfo(0)->hFile = GetStdHandle(STD_INPUT_HANDLE);
+      if (fdinfo(0)->hFile == NULL)
+         fdinfo(0)->hFile = INVALID_HANDLE_VALUE;
       fdinfo(0)->fdflags = FOPEN|FTEXT;
    }
    if (fdinfo(1)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(1)->fdflags & FOPEN)) {
       fdinfo(1)->hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+      if (fdinfo(1)->hFile == NULL)
+         fdinfo(1)->hFile = INVALID_HANDLE_VALUE;
       fdinfo(1)->fdflags = FOPEN|FTEXT;
    }
    if (fdinfo(2)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(2)->fdflags & FOPEN)) {
       fdinfo(2)->hFile = GetStdHandle(STD_ERROR_HANDLE);
+      if (fdinfo(2)->hFile == NULL)
+         fdinfo(2)->hFile = INVALID_HANDLE_VALUE;
       fdinfo(2)->fdflags = FOPEN|FTEXT;
    }
 
index 1bbbd3b..9d9f0e1 100644 (file)
@@ -25,6 +25,8 @@
  */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 
+#include "precomp.h"
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
index 738eb19..9030e5d 100644 (file)
@@ -1,5 +1,7 @@
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 
+#include "precomp.h"
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
index 571dacb..fc94ac6 100644 (file)
@@ -9,6 +9,8 @@
  */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 
+#include "precomp.h"
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
index 70e6568..f695154 100644 (file)
@@ -3,20 +3,11 @@
 #include <stdio.h>
 #include <malloc.h>
 #include <internal/file.h>
-
-#ifdef __USE_W32API
 #include <ntdef.h>
-#endif
-
-
 
 extern int __mb_cur_max;
-
-
-
 int __vfprintf(FILE*, const char*, va_list);
 
-
 /*
  * @implemented
  */
index 262b2d1..92040f3 100644 (file)
@@ -1,14 +1,13 @@
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
 
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
+#include "precomp.h"
 
 #include <stdarg.h>
 #include <stdio.h>
 #include <malloc.h>
 #include <internal/file.h>
 
+#include <ntdef.h>
 
 int _isnanl(double x);
 int _isinfl(double x);
index 7b2ba8d..74e7068 100644 (file)
@@ -1,9 +1,6 @@
 /* $Id$
  *
  */
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif 
 
 #include <errno.h>
 #include <internal/tls.h>
index 2be3bad..e6c4f44 100644 (file)
@@ -1,7 +1,4 @@
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
 
 #include <stdlib.h>
 #include <search.h>
index 79a04b5..ddcfe47 100644 (file)
@@ -1,7 +1,4 @@
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
 
 #include <stdlib.h>
 #include <internal/tls.h>
index 188b10d..f5f8b61 100644 (file)
@@ -1,7 +1,3 @@
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
-
 #include <internal/tls.h>
 #include <assert.h>
 
index 4bd36f3..aca32a6 100644 (file)
@@ -1,7 +1,4 @@
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#ifdef __USE_W32API
-#undef __USE_W32API
-#endif
 
 #include <string.h>
 #include <internal/tls.h>
index 5fe005b..6bffbdd 100644 (file)
@@ -98,257 +98,257 @@ _FUNCTION_ {
     if (nch == _EOF_) return _EOF_RET;\r
 \r
     while (*format) {\r
-       /* a whitespace character in the format string causes scanf to read,\r
-        * but not store, all consecutive white-space characters in the input\r
-        * up to the next non-white-space character.  One white space character\r
-        * in the input matches any number (including zero) and combination of\r
-        * white-space characters in the input. */\r
-       if (_ISSPACE_(*format)) {\r
+   /* a whitespace character in the format string causes scanf to read,\r
+    * but not store, all consecutive white-space characters in the input\r
+    * up to the next non-white-space character.  One white space character\r
+    * in the input matches any number (including zero) and combination of\r
+    * white-space characters in the input. */\r
+   if (_ISSPACE_(*format)) {\r
             /* skip whitespace */\r
             while ((nch!=_EOF_) && _ISSPACE_(nch))\r
                 nch = _GETC_(file);\r
         }\r
-       /* a format specification causes scanf to read and convert characters\r
-        * in the input into values of a specified type.  The value is assigned\r
-        * to an argument in the argument list.  Format specifications have\r
-        * the form %[*][width][{h | l | I64 | L}]type */\r
+   /* a format specification causes scanf to read and convert characters\r
+    * in the input into values of a specified type.  The value is assigned\r
+    * to an argument in the argument list.  Format specifications have\r
+    * the form %[*][width][{h | l | I64 | L}]type */\r
         else if (*format == '%') {\r
             int st = 0; int suppress = 0; int width = 0;\r
-           int base, number_signed;\r
-           int h_prefix = 0;\r
-           int l_prefix = 0;\r
-           int L_prefix = 0;\r
-           int w_prefix = 0;\r
-           int prefix_finished = 0;\r
-           int I64_prefix = 0;\r
+       int base, number_signed;\r
+       int h_prefix = 0;\r
+       int l_prefix = 0;\r
+       int L_prefix = 0;\r
+       int w_prefix = 0;\r
+       int prefix_finished = 0;\r
+       int I64_prefix = 0;\r
             format++;\r
-           /* look for leading asterisk, which means 'suppress assignment of\r
-            * this field'. */\r
-           if (*format=='*') {\r
-               format++;\r
-               suppress=1;\r
-           }\r
-           /* look for width specification */\r
-           while (_ISDIGIT_(*format)) {\r
-               width*=10;\r
-               width+=*format++ - '0';\r
-           }\r
-           if (width==0) width=-1; /* no width spec seen */\r
-           /* read prefix (if any) */\r
-           while (!prefix_finished) {\r
-               switch(*format) {\r
-               case 'h': h_prefix = 1; break;\r
-               case 'l': l_prefix = 1; break;\r
-               case 'w': w_prefix = 1; break;\r
-               case 'L': L_prefix = 1; break;\r
-               case 'I':\r
-                   if (*(format + 1) == '6' &&\r
-                       *(format + 2) == '4') {\r
-                       I64_prefix = 1;\r
-                       format += 2;\r
-                   }\r
-                   break;\r
-               default:\r
-                   prefix_finished = 1;\r
-               }\r
-               if (!prefix_finished) format++;\r
-           }\r
-           /* read type */\r
+       /* look for leading asterisk, which means 'suppress assignment of\r
+        * this field'. */\r
+       if (*format=='*') {\r
+      format++;\r
+      suppress=1;\r
+       }\r
+       /* look for width specification */\r
+       while (_ISDIGIT_(*format)) {\r
+      width*=10;\r
+      width+=*format++ - '0';\r
+       }\r
+       if (width==0) width=-1; /* no width spec seen */\r
+       /* read prefix (if any) */\r
+       while (!prefix_finished) {\r
+      switch(*format) {\r
+      case 'h': h_prefix = 1; break;\r
+      case 'l': l_prefix = 1; break;\r
+      case 'w': w_prefix = 1; break;\r
+      case 'L': L_prefix = 1; break;\r
+      case 'I':\r
+          if (*(format + 1) == '6' &&\r
+         *(format + 2) == '4') {\r
+         I64_prefix = 1;\r
+         format += 2;\r
+          }\r
+          break;\r
+      default:\r
+          prefix_finished = 1;\r
+      }\r
+      if (!prefix_finished) format++;\r
+       }\r
+       /* read type */\r
             switch(*format) {\r
-           case 'x':\r
-           case 'X': /* hexadecimal integer. */\r
-               base = 16; number_signed = 0;\r
-               goto number;\r
-           case 'o': /* octal integer */\r
-               base = 8; number_signed = 0;\r
-               goto number;\r
-           case 'u': /* unsigned decimal integer */\r
-               base = 10; number_signed = 0;\r
-               goto number;\r
-           case 'd': /* signed decimal integer */\r
-               base = 10; number_signed = 1;\r
-               goto number;\r
-           case 'i': /* generic integer */\r
-               base = 10; number_signed = 1;\r
-           number: {\r
-                   /* read an integer */\r
-                   ULONGLONG cur = 0;\r
-                   int negative = 0;\r
-                   int seendigit=0;\r
+       case 'x':\r
+       case 'X': /* hexadecimal integer. */\r
+      base = 16; number_signed = 0;\r
+      goto number;\r
+       case 'o': /* octal integer */\r
+      base = 8; number_signed = 0;\r
+      goto number;\r
+       case 'u': /* unsigned decimal integer */\r
+      base = 10; number_signed = 0;\r
+      goto number;\r
+       case 'd': /* signed decimal integer */\r
+      base = 10; number_signed = 1;\r
+      goto number;\r
+       case 'i': /* generic integer */\r
+      base = 10; number_signed = 1;\r
+       number: {\r
+          /* read an integer */\r
+          ULONGLONG cur = 0;\r
+          int negative = 0;\r
+          int seendigit=0;\r
                     /* skip initial whitespace */\r
                     while ((nch!=_EOF_) && _ISSPACE_(nch))\r
                         nch = _GETC_(file);\r
                     /* get sign */\r
                     if (number_signed && (nch == '-' ||\r
-                                         nch == '+')) {\r
-                       negative = (nch=='-');\r
+                 nch == '+')) {\r
+         negative = (nch=='-');\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
+         if (width>0) width--;\r
                     }\r
-                   /* look for leading indication of base */\r
-                   if (width!=0 && nch == '0') {\r
+          /* look for leading indication of base */\r
+          if (width!=0 && nch == '0') {\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                       seendigit=1;\r
-                       if (width!=0 && (nch=='x' || nch=='X')) {\r
-                           if (base==0)\r
-                               base=16;\r
-                           if (base==16) {\r
-                               nch = _GETC_(file);\r
-                               if (width>0) width--;\r
-                               seendigit=0;\r
-                           }\r
-                       } else if (base==0)\r
-                           base = 8;\r
-                   }\r
-                   /* throw away leading zeros */\r
-                   while (width!=0 && nch=='0') {\r
+         if (width>0) width--;\r
+         seendigit=1;\r
+         if (width!=0 && (nch=='x' || nch=='X')) {\r
+             if (base==0)\r
+            base=16;\r
+             if (base==16) {\r
+            nch = _GETC_(file);\r
+            if (width>0) width--;\r
+            seendigit=0;\r
+             }\r
+         } else if (base==0)\r
+             base = 8;\r
+          }\r
+          /* throw away leading zeros */\r
+          while (width!=0 && nch=='0') {\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                       seendigit=1;\r
-                   }\r
-                   if (width!=0 && _CHAR2DIGIT_(nch, base)!=-1) {\r
-                       cur = _CHAR2DIGIT_(nch, base);\r
-                       nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                       seendigit=1;\r
-                   }\r
+         if (width>0) width--;\r
+         seendigit=1;\r
+          }\r
+          if (width!=0 && _CHAR2DIGIT_(nch, base)!=-1) {\r
+         cur = _CHAR2DIGIT_(nch, base);\r
+         nch = _GETC_(file);\r
+         if (width>0) width--;\r
+         seendigit=1;\r
+          }\r
                     /* read until no more digits */\r
                     while (width!=0 && (nch!=_EOF_) && _CHAR2DIGIT_(nch, base)!=-1) {\r
                         cur = cur*base + _CHAR2DIGIT_(nch, base);\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                       seendigit=1;\r
+         if (width>0) width--;\r
+         seendigit=1;\r
                     }\r
-                   /* okay, done! */\r
-                   if (!seendigit) break; /* not a valid number */\r
+          /* okay, done! */\r
+          if (!seendigit) break; /* not a valid number */\r
                     st = 1;\r
                     if (!suppress) {\r
 #define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur\r
-                       if (number_signed) {\r
-                           if (I64_prefix) _SET_NUMBER_(LONGLONG);\r
-                           else if (l_prefix) _SET_NUMBER_(long int);\r
-                           else if (h_prefix) _SET_NUMBER_(short int);\r
-                           else _SET_NUMBER_(int);\r
-                       } else {\r
-                           if (negative) {\r
-                               WARN("Dropping sign in reading a negative number into an unsigned value");\r
-                               negative = 0;\r
-                           }\r
-                           if (I64_prefix) _SET_NUMBER_(ULONGLONG);\r
-                           else if (l_prefix) _SET_NUMBER_(unsigned long int);\r
-                           else if (h_prefix)\r
-                               _SET_NUMBER_(unsigned short int);\r
-                           else _SET_NUMBER_(unsigned int);\r
-                       }\r
-                   }\r
+         if (number_signed) {\r
+             if (I64_prefix) _SET_NUMBER_(LONGLONG);\r
+             else if (l_prefix) _SET_NUMBER_(long int);\r
+             else if (h_prefix) _SET_NUMBER_(short int);\r
+             else _SET_NUMBER_(int);\r
+         } else {\r
+             if (negative) {\r
+            WARN("Dropping sign in reading a negative number into an unsigned value");\r
+            negative = 0;\r
+             }\r
+             if (I64_prefix) _SET_NUMBER_(ULONGLONG);\r
+             else if (l_prefix) _SET_NUMBER_(unsigned long int);\r
+             else if (h_prefix)\r
+            _SET_NUMBER_(unsigned short int);\r
+             else _SET_NUMBER_(unsigned int);\r
+         }\r
+          }\r
                 }\r
                 break;\r
-           case 'e':\r
-           case 'E':\r
-           case 'f':\r
-           case 'g':\r
+       case 'e':\r
+       case 'E':\r
+       case 'f':\r
+       case 'g':\r
             case 'G': { /* read a float */\r
                     long double cur = 0;\r
-                   int negative = 0;\r
+          int negative = 0;\r
                     /* skip initial whitespace */\r
                     while ((nch!=_EOF_) && _ISSPACE_(nch))\r
                         nch = _GETC_(file);\r
-                   /* get sign. */\r
+          /* get sign. */\r
                     if (nch == '-' || nch == '+') {\r
-                       negative = (nch=='-');\r
-                       if (width>0) width--;\r
-                       if (width==0) break;\r
+         negative = (nch=='-');\r
+         if (width>0) width--;\r
+         if (width==0) break;\r
                         nch = _GETC_(file);\r
                     }\r
-                   /* get first digit. */\r
-                   if ('.' != nch) {\r
-                     if (!_ISDIGIT_(nch)) break;\r
-                     cur = (nch - '0');\r
-                     nch = _GETC_(file);\r
-                     if (width>0) width--;\r
-                     /* read until no more digits */\r
-                     while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {\r
+          /* get first digit. */\r
+          if ('.' != nch) {\r
+            if (!_ISDIGIT_(nch)) break;\r
+            cur = (nch - '0');\r
+            nch = _GETC_(file);\r
+            if (width>0) width--;\r
+            /* read until no more digits */\r
+            while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {\r
                         cur = cur*10 + (nch - '0');\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                     }\r
-                   } else {\r
-                     cur = 0; /* MaxPayneDemo Fix: .8 -> 0.8 */\r
-                   }\r
-                   /* handle decimals */\r
+         if (width>0) width--;\r
+            }\r
+          } else {\r
+            cur = 0; /* MaxPayneDemo Fix: .8 -> 0.8 */\r
+          }\r
+          /* handle decimals */\r
                     if (width!=0 && nch == '.') {\r
                         float dec = 1;\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
+         if (width>0) width--;\r
                         while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {\r
                             dec /= 10;\r
                             cur += dec * (nch - '0');\r
                             nch = _GETC_(file);\r
-                           if (width>0) width--;\r
+             if (width>0) width--;\r
                         }\r
                     }\r
-                   /* handle exponent */\r
-                   if (width!=0 && (nch == 'e' || nch == 'E')) {\r
-                       int exponent = 0, negexp = 0;\r
-                       float expcnt;\r
+          /* handle exponent */\r
+          if (width!=0 && (nch == 'e' || nch == 'E')) {\r
+         int exponent = 0, negexp = 0;\r
+         float expcnt;\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
-                       /* possible sign on the exponent */\r
-                       if (width!=0 && (nch=='+' || nch=='-')) {\r
-                           negexp = (nch=='-');\r
+         if (width>0) width--;\r
+         /* possible sign on the exponent */\r
+         if (width!=0 && (nch=='+' || nch=='-')) {\r
+             negexp = (nch=='-');\r
                             nch = _GETC_(file);\r
-                           if (width>0) width--;\r
-                       }\r
-                       /* exponent digits */\r
-                       while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {\r
-                           exponent *= 10;\r
-                           exponent += (nch - '0');\r
+             if (width>0) width--;\r
+         }\r
+         /* exponent digits */\r
+         while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {\r
+             exponent *= 10;\r
+             exponent += (nch - '0');\r
                             nch = _GETC_(file);\r
-                           if (width>0) width--;\r
+             if (width>0) width--;\r
                         }\r
-                       /* update 'cur' with this exponent. */\r
-                       expcnt =  negexp ? .1 : 10;\r
-                       while (exponent!=0) {\r
-                           if (exponent&1)\r
-                               cur*=expcnt;\r
-                           exponent/=2;\r
-                           expcnt=expcnt*expcnt;\r
-                       }\r
-                   }\r
+         /* update 'cur' with this exponent. */\r
+         expcnt =  negexp ? .1 : 10;\r
+         while (exponent!=0) {\r
+             if (exponent&1)\r
+            cur*=expcnt;\r
+             exponent/=2;\r
+             expcnt=expcnt*expcnt;\r
+         }\r
+          }\r
                     st = 1;\r
                     if (!suppress) {\r
-                       if (L_prefix) _SET_NUMBER_(long double);\r
-                       else if (l_prefix) _SET_NUMBER_(double);\r
-                       else _SET_NUMBER_(float);\r
-                   }\r
+         if (L_prefix) _SET_NUMBER_(long double);\r
+         else if (l_prefix) _SET_NUMBER_(double);\r
+         else _SET_NUMBER_(float);\r
+          }\r
                 }\r
                 break;\r
-               /* According to\r
-                * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_scanf_type_field_characters.asp\r
-                * 's' reads a character string in a call to fscanf\r
-                * and 'S' a wide character string and vice versa in a\r
-                * call to fwscanf. The 'h', 'w' and 'l' prefixes override\r
-                * this behaviour. 'h' forces reading char * but 'l' and 'w'\r
-                * force reading WCHAR. */\r
-           case 's':\r
-                   if (w_prefix || l_prefix) goto widecharstring;\r
-                   else if (h_prefix) goto charstring;\r
+      /* According to\r
+       * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_scanf_type_field_characters.asp\r
+       * 's' reads a character string in a call to fscanf\r
+       * and 'S' a wide character string and vice versa in a\r
+       * call to fwscanf. The 'h', 'w' and 'l' prefixes override\r
+       * this behaviour. 'h' forces reading char * but 'l' and 'w'\r
+       * force reading WCHAR. */\r
+       case 's':\r
+          if (w_prefix || l_prefix) goto widecharstring;\r
+          else if (h_prefix) goto charstring;\r
 #ifdef WIDE_SCANF\r
-                   else goto widecharstring;\r
+          else goto widecharstring;\r
 #else /* WIDE_SCANF */\r
-                   else goto charstring;\r
+          else goto charstring;\r
 #endif /* WIDE_SCANF */\r
-           case 'S':\r
-                   if (w_prefix || l_prefix) goto widecharstring;\r
-                   else if (h_prefix) goto charstring;\r
+       case 'S':\r
+          if (w_prefix || l_prefix) goto widecharstring;\r
+          else if (h_prefix) goto charstring;\r
 #ifdef WIDE_SCANF\r
-                   else goto charstring;\r
+          else goto charstring;\r
 #else /* WIDE_SCANF */\r
-                   else goto widecharstring;\r
+          else goto widecharstring;\r
 #endif /* WIDE_SCANF */\r
-           charstring: { /* read a word into a char */\r
-                   char*str = suppress ? NULL : va_arg(ap, char*);\r
+       charstring: { /* read a word into a char */\r
+          char*str = suppress ? NULL : va_arg(ap, char*);\r
                     char*sptr = str;\r
                     /* skip initial whitespace */\r
                     while ((nch!=_EOF_) && _ISSPACE_(nch))\r
@@ -356,15 +356,15 @@ _FUNCTION_ {
                     /* read until whitespace */\r
                     while (width!=0 && (nch!=_EOF_) && !_ISSPACE_(nch)) {\r
                         if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch);\r
-                       st++;\r
+         st++;\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
+         if (width>0) width--;\r
                     }\r
                     /* terminate */\r
                     if (!suppress) *sptr = 0;\r
                 }\r
                 break;\r
-           widecharstring: { /* read a word into a wchar_t* */\r
+       widecharstring: { /* read a word into a wchar_t* */\r
                    wchar_t*str =\r
                        suppress ? NULL : va_arg(ap, wchar_t*);\r
                     wchar_t*sptr = str;\r
@@ -374,33 +374,33 @@ _FUNCTION_ {
                     /* read until whitespace */\r
                     while (width!=0 && (nch!=_EOF_) && !_ISSPACE_(nch)) {\r
                         if (!suppress) *sptr++ = _WIDE2SUPPORTED_(nch);\r
-                       st++;\r
+         st++;\r
                         nch = _GETC_(file);\r
-                       if (width>0) width--;\r
+         if (width>0) width--;\r
                     }\r
                     /* terminate */\r
                     if (!suppress) *sptr = 0;\r
                 }\r
                 break;\r
             /* 'c' and 'C work analogously to 's' and 'S' as described\r
-            * above */\r
-           case 'c':\r
-                   if (w_prefix || l_prefix) goto widecharacter;\r
-                   else if (h_prefix) goto character;\r
+        * above */\r
+       case 'c':\r
+          if (w_prefix || l_prefix) goto widecharacter;\r
+          else if (h_prefix) goto character;\r
 #ifdef WIDE_SCANF\r
-                   else goto widecharacter;\r
+          else goto widecharacter;\r
 #else /* WIDE_SCANF */\r
-                   else goto character;\r
+          else goto character;\r
 #endif /* WIDE_SCANF */\r
-           case 'C':\r
-                   if (w_prefix || l_prefix) goto widecharacter;\r
-                   else if (h_prefix) goto character;\r
+       case 'C':\r
+          if (w_prefix || l_prefix) goto widecharacter;\r
+          else if (h_prefix) goto character;\r
 #ifdef WIDE_SCANF\r
-                   else goto character;\r
+          else goto character;\r
 #else /* WIDE_SCANF */\r
-                   else goto widecharacter;\r
+          else goto widecharacter;\r
 #endif /* WIDE_SCANF */\r
-         character: { /* read single character into char */\r
+     character: { /* read single character into char */\r
                     if (nch!=_EOF_) {\r
                         if (!suppress) {\r
                             char*c = va_arg(ap, char*);\r
@@ -410,8 +410,8 @@ _FUNCTION_ {
                         nch = _GETC_(file);\r
                     }\r
                 }\r
-               break;\r
-         widecharacter: { /* read single character into a wchar_t */\r
+      break;\r
+     widecharacter: { /* read single character into a wchar_t */\r
                     if (nch!=_EOF_) {\r
                         if (!suppress) {\r
                             wchar_t*c = va_arg(ap, wchar_t*);\r
@@ -420,80 +420,103 @@ _FUNCTION_ {
                         nch = _GETC_(file);\r
                         st = 1;\r
                     }\r
-               }\r
-               break;\r
-           case 'n': {\r
-                   if (!suppress) {\r
-                       int*n = va_arg(ap, int*);\r
-                       *n = consumed - (nch!=_EOF_);\r
-                   }\r
-               }\r
-               break;\r
-           case '[': {\r
+           }\r
+      break;\r
+       case 'n': {\r
+          if (!suppress) {\r
+         int*n = va_arg(ap, int*);\r
+\r
+         /* \r
+         *n = consumed - (nch!=_EOF_);\r
+         \r
+         FIXME: The above is the Wine version and it doesnt work in ros\r
+         when %n is at end of input string (return one too many).\r
+         But does it fail in Wine too?? If so wine also needs fixin.\r
+         -Gunnar\r
+         */\r
+\r
+         *n = consumed - 1;\r
+          }\r
+          /* This is an odd one: according to the standard,\r
+           * "Execution of a %n directive does not increment the\r
+           * assignment count returned at the completion of\r
+           * execution" even if it wasn't suppressed with the\r
+           * '*' flag.  The Corrigendum to the standard seems\r
+           * to contradict this (comment out the assignment to\r
+           * suppress below if you want to implement these\r
+           * alternate semantics) but the windows program I'm\r
+           * looking at expects the behavior I've coded here\r
+           * (which happens to be what glibc does as well).\r
+           */\r
+          suppress = 1;\r
+          st = 1;\r
+           }\r
+      break;\r
+       case '[': {\r
                     _CHAR_ *str = suppress ? NULL : va_arg(ap, _CHAR_*);\r
                     _CHAR_ *sptr = str;\r
-                   RTL_BITMAP bitMask;\r
+          RTL_BITMAP bitMask;\r
                     ULONG *Mask;\r
-                   int invert = 0; /* Set if we are NOT to find the chars */\r
+          int invert = 0; /* Set if we are NOT to find the chars */\r
 \r
-                   /* Init our bitmap */\r
+          /* Init our bitmap */\r
           Mask = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, _BITMAPSIZE_/8);\r
-                   RtlInitializeBitMap(&bitMask, Mask, _BITMAPSIZE_);\r
+          RtlInitializeBitMap(&bitMask, Mask, _BITMAPSIZE_);\r
 \r
-                   /* Read the format */\r
-                   format++;\r
-                   if(*format == '^') {\r
-                       invert = 1;\r
-                       format++;\r
-                   }\r
-                   if(*format == ']') {\r
-                       RtlSetBits(&bitMask, ']', 1);\r
-                       format++;\r
-                   }\r
+          /* Read the format */\r
+          format++;\r
+          if(*format == '^') {\r
+         invert = 1;\r
+         format++;\r
+          }\r
+          if(*format == ']') {\r
+         RtlSetBits(&bitMask, ']', 1);\r
+         format++;\r
+          }\r
                     while(*format && (*format != ']')) {\r
-                       /* According to:\r
-                        * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_scanf_width_specification.asp\r
-                        * "Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]." */\r
-                       if((*format == '-') && (*(format + 1) != ']')) {\r
-                           if ((*(format - 1)) < *(format + 1))\r
-                               RtlSetBits(&bitMask, *(format - 1) +1 , *(format + 1) - *(format - 1));\r
-                           else\r
-                               RtlSetBits(&bitMask, *(format + 1)    , *(format - 1) - *(format + 1));                       \r
-                           format++;\r
-                       } else\r
-                           RtlSetBits(&bitMask, *format, 1);\r
-                       format++;\r
-                   }\r
+         /* According to:\r
+          * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_scanf_width_specification.asp\r
+          * "Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]." */\r
+         if((*format == '-') && (*(format + 1) != ']')) {\r
+             if ((*(format - 1)) < *(format + 1))\r
+            RtlSetBits(&bitMask, *(format - 1) +1 , *(format + 1) - *(format - 1));\r
+             else\r
+            RtlSetBits(&bitMask, *(format + 1)    , *(format - 1) - *(format + 1));             \r
+             format++;\r
+         } else\r
+             RtlSetBits(&bitMask, *format, 1);\r
+         format++;\r
+          }\r
                     /* read until char is not suitable */\r
                     while ((width != 0) && (nch != _EOF_)) {\r
-                       if(!invert) {\r
-                           if(RtlAreBitsSet(&bitMask, nch, 1)) {\r
-                               if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch);\r
-                           } else\r
-                               break;\r
-                       } else {\r
-                           if(RtlAreBitsClear(&bitMask, nch, 1)) {\r
-                               if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch);\r
-                           } else\r
-                               break;\r
-                       }\r
+         if(!invert) {\r
+             if(RtlAreBitsSet(&bitMask, nch, 1)) {\r
+            if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch);\r
+             } else\r
+            break;\r
+         } else {\r
+             if(RtlAreBitsClear(&bitMask, nch, 1)) {\r
+            if (!suppress) *sptr++ = _CHAR2SUPPORTED_(nch);\r
+             } else\r
+            break;\r
+         }\r
                         st++;\r
                         nch = _GETC_(file);\r
                         if (width>0) width--;\r
                     }\r
                     /* terminate */\r
                     if (!suppress) *sptr = 0;\r
-                   HeapFree(GetProcessHeap(), 0, Mask);\r
+          HeapFree(GetProcessHeap(), 0, Mask);\r
                 }\r
                 break;\r
             default:\r
-               /* From spec: "if a percent sign is followed by a character\r
-                * that has no meaning as a format-control character, that\r
-                * character and the following characters are treated as\r
-                * an ordinary sequence of characters, that is, a sequence\r
-                * of characters that must match the input.  For example,\r
-                * to specify that a percent-sign character is to be input,\r
-                * use %%." */\r
+      /* From spec: "if a percent sign is followed by a character\r
+       * that has no meaning as a format-control character, that\r
+       * character and the following characters are treated as\r
+       * an ordinary sequence of characters, that is, a sequence\r
+       * of characters that must match the input.  For example,\r
+       * to specify that a percent-sign character is to be input,\r
+       * use %%." */\r
                 while ((nch!=_EOF_) && _ISSPACE_(nch))\r
                     nch = _GETC_(file);\r
                 if (nch==*format) {\r
@@ -506,18 +529,18 @@ _FUNCTION_ {
             if (st && !suppress) rd++;\r
             else if (!st) break;\r
         }\r
-       /* a non-white-space character causes scanf to read, but not store,\r
-        * a matching non-white-space character. */\r
+   /* a non-white-space character causes scanf to read, but not store,\r
+    * a matching non-white-space character. */\r
         else {\r
             /* check for character match */\r
             if (nch == *format) {\r
-               nch = _GETC_(file);\r
+      nch = _GETC_(file);\r
             } else break;\r
         }\r
         format++;\r
     }\r
     if (nch!=_EOF_) {\r
-       _UNGETC_(nch, file);\r
+   _UNGETC_(nch, file);\r
     }\r
     TRACE("returning %d\n", rd);\r
     return rd;\r
index 2a5f42b..5594448 100644 (file)
@@ -2215,6 +2215,7 @@ static BOOL codeview_process_info(const struct process* pcs,
         pdb_lookup.filename = pdb->name;
         pdb_lookup.kind = PDB_JG;
         pdb_lookup.u.jg.timestamp = pdb->timestamp;
+        pdb_lookup.u.jg.toc = NULL;
         ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
         break;
     }
@@ -2227,6 +2228,7 @@ static BOOL codeview_process_info(const struct process* pcs,
         pdb_lookup.filename = rsds->name;
         pdb_lookup.kind = PDB_DS;
         pdb_lookup.u.ds.guid = rsds->guid;
+        pdb_lookup.u.ds.toc = NULL;
         ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
         break;
     }
index 553c5f7..86507a5 100644 (file)
@@ -7,15 +7,20 @@ TARGET_NORC = yes
 TARGET_NAME = ddraw
 
 # -fno-builtin
-TARGET_CFLAGS = -D__USE_W32API
+TARGET_CFLAGS = -D__USE_W32API -I$(PATH_TO_TOP)/include/wine
 
 # require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall -Werror
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -Wall 
+
+TARGET_SDKLIBS = ntdll.a gdi32.a dxguid.a ole32.a user32.a d3d8thk.a
 
-TARGET_SDKLIBS = ntdll.a gdi32.a
 
 TARGET_OBJECTS = \
-       ddraw.o
+      regsvr.o \
+      ddraw.o \
+      ddraw_hal.o 
+     
+
 
 DEP_OBJECTS = $(TARGET_OBJECTS)
 
index dbd4c8c..ffe0129 100644 (file)
  */
 
 #include <windows.h>
-//#include <ddraw.h>
-
- #define DD_OK 0
-HRESULT STDCALL DirectDrawCreate(
-  GUID FAR* lpGUID, 
-  DWORD FAR* lplpDD, 
-  IUnknown FAR* pUnkOuter
-)
-{
-    return DD_OK;
+#include "ddraw.h"
+#include "rosddraw.h"
+               
+HRESULT WINAPI DirectDrawCreate(LPGUID lpGUID, LPDIRECTDRAW* lplpDD, LPUNKNOWN pUnkOuter) 
+{      
+    if (pUnkOuter!=NULL) return DDERR_INVALIDPARAMS;
+       return DDRAW_Create(lpGUID, (LPVOID*) lplpDD, pUnkOuter, &IID_IDirectDraw, FALSE);
 }
 
-HRESULT STDCALL DirectDrawCreateEx(
-  GUID FAR* lpGUID, 
-  DWORD FAR* lplpDD, 
-  DWORD Unknown3,
-  IUnknown FAR* pUnkOuter
-)
+                
+HRESULT WINAPI DirectDrawCreateEx(LPGUID lpGUID, LPVOID* lplpDD, REFIID iid, LPUNKNOWN pUnkOuter)
 {
-    return DD_OK;
+       if (pUnkOuter!=NULL) return DDERR_INVALIDPARAMS;
+       if (!IsEqualGUID(iid, &IID_IDirectDraw7)) return DDERR_INVALIDPARAMS;
+
+    return DDRAW_Create(lpGUID, lplpDD, pUnkOuter, iid, TRUE);
 }
 
 HRESULT WINAPI DirectDrawEnumerateA(
-  DWORD *lpCallback, 
+  LPDDENUMCALLBACKA lpCallback, 
   LPVOID lpContext
 )
 {
@@ -43,7 +38,7 @@ HRESULT WINAPI DirectDrawEnumerateA(
 
 
 HRESULT WINAPI DirectDrawEnumerateW(
-  DWORD *lpCallback, 
+  LPDDENUMCALLBACKW lpCallback, 
   LPVOID lpContext
 )
 {
@@ -51,7 +46,7 @@ HRESULT WINAPI DirectDrawEnumerateW(
 }
 
 HRESULT WINAPI DirectDrawEnumerateExA(
-  DWORD lpCallback, 
+  LPDDENUMCALLBACKEXA lpCallback, 
   LPVOID lpContext, 
   DWORD dwFlags
 )
@@ -60,23 +55,53 @@ HRESULT WINAPI DirectDrawEnumerateExA(
 }
 
 HRESULT WINAPI DirectDrawEnumerateExW(
-  DWORD lpCallback, 
+  LPDDENUMCALLBACKEXW lpCallback, 
   LPVOID lpContext, 
   DWORD dwFlags
 )
 {
     return DD_OK;
 }
-
 HRESULT WINAPI DirectDrawCreateClipper(
   DWORD dwFlags, 
-  DWORD FAR* lplpDDClipper, 
-  IUnknown FAR* pUnkOuter
+  LPDIRECTDRAWCLIPPER* lplpDDClipper, 
+  LPUNKNOWN pUnkOuter
 )
 {
     return DD_OK;
 }
 
+HRESULT DDRAW_Create(
+       LPGUID lpGUID, LPVOID *lplpDD, LPUNKNOWN pUnkOuter, REFIID iid, BOOL ex) 
+{                    
+       
+        HRESULT hr;
+
+     
+    /* TODO 1: 
+          check the GUID are right 
+          add scanner that DirectDrawCreate / DirectDrawCreateEx select right driver.
+          now we will assume it is the current display driver 
+       */
+
+        /* TODO 2: 
+          do not only use hardware mode.
+       */
+
+       hr = HAL_DirectDraw_Create(lpGUID, lplpDD, pUnkOuter, iid,  ex);
+
+       /* old code 
+        //HDC desktop;         
+       
+       desktop = GetWindowDC(GetDesktopWindow());
+       lplpDD = OsThunkDdCreateDirectDrawObject(desktop);   
+       if (lplpDD == NULL) return DDERR_NODIRECTDRAWHW;
+       */
+               
+       return hr;
+}
+
 BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD fwdReason, LPVOID lpvReserved)
 {
     switch(fwdReason)
diff --git a/reactos/lib/ddraw/ddraw_hal.c b/reactos/lib/ddraw/ddraw_hal.c
new file mode 100644 (file)
index 0000000..b1dec34
--- /dev/null
@@ -0,0 +1,360 @@
+/*     DirectDraw HAL driver\r
+ *\r
+ * Copyright 2001 TransGaming Technologies Inc.\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+\r
+\r
+#include <windows.h>\r
+#include "ddraw.h"\r
+#include "rosddraw.h"\r
+#include "ddraw_private.h"\r
+\r
+static IDirectDraw7Vtbl HAL_DirectDraw_VTable;\r
+\r
+\r
+HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)\r
+{    \r
+    //This->local.lpGbl = &dd_gbl;\r
+\r
+    This->final_release = HAL_DirectDraw_final_release;\r
+    This->set_exclusive_mode = HAL_DirectDrawSet_exclusive_mode;\r
+   // This->create_palette = HAL_DirectDrawPalette_Create;\r
+\r
+    This->create_primary    = HAL_DirectDraw_create_primary;\r
+    This->create_backbuffer = HAL_DirectDraw_create_backbuffer;\r
+    This->create_texture    = HAL_DirectDraw_create_texture;    \r
+\r
+   // ICOM_INIT_INTERFACE(This, IDirectDraw7, HAL_DirectDraw_VTable);\r
+    return S_OK;\r
+}\r
+\r
+void HAL_DirectDraw_final_release(IDirectDrawImpl *This)\r
+{\r
\r
+}\r
+\r
+HRESULT HAL_DirectDrawSet_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl)\r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+\r
+HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD, LPDIRECTDRAWSURFACE7* ppSurf,\r
+                                     IUnknown* pUnkOuter)\r
+\r
+{\r
+       return DDERR_UNSUPPORTED;\r
+  }\r
+\r
+HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,\r
+                                        const DDSURFACEDESC2* pDDSD,\r
+                                        LPDIRECTDRAWSURFACE7* ppSurf,\r
+                                        IUnknown* pUnkOuter,\r
+                                        IDirectDrawSurfaceImpl* primary)\r
+{\r
+       return DDERR_UNSUPPORTED;\r
+  }\r
+\r
+HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,\r
+                                     const DDSURFACEDESC2* pDDSD,\r
+                                     LPDIRECTDRAWSURFACE7* ppSurf,\r
+                                     LPUNKNOWN pOuter,\r
+                                     DWORD dwMipMapLevel)\r
+{\r
+       return DDERR_UNSUPPORTED;\r
+  }\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* basic funtion for the com object */\r
+HRESULT WINAPI HAL_DirectDraw_QueryInterface(LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj) \r
+{\r
+       return DDERR_UNSUPPORTED;\r
+  }\r
+\r
+ULONG WINAPI HAL_DirectDraw_AddRef(LPDIRECTDRAW7 iface) \r
+{\r
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;\r
+    ULONG ref = InterlockedIncrement(&This->ref);\r
+\r
+    //TRACE("(%p)->() incrementing from %lu.\n", This, ref -1);\r
+\r
+    return ref;\r
+}\r
+\r
+ULONG WINAPI HAL_DirectDraw_Release(LPDIRECTDRAW7 iface) \r
+{\r
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;\r
+    ULONG ref = InterlockedDecrement(&This->ref);\r
+    \r
+    if (ref == 0)\r
+    {\r
+       if (This->final_release != NULL)\r
+           This->final_release(This);\r
+\r
+       /* We free the private. This is an artifact of the fact that I don't\r
+        * have the destructors set up correctly. */\r
+       if (This->private != (This+1))\r
+           HeapFree(GetProcessHeap(), 0, This->private);\r
+\r
+       HeapFree(GetProcessHeap(), 0, This);\r
+    }\r
+\r
+    return ref;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_Compact(LPDIRECTDRAW7 iface) \r
+{\r
\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags, \r
+                                                                                        LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)\r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+HRESULT WINAPI HAL_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,\r
+                             LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown)\r
+{\r
+       return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,\r
+                             LPDIRECTDRAWSURFACE7 *ppSurf,IUnknown *pUnkOuter) \r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,\r
+                                LPDIRECTDRAWSURFACE7* dst) \r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,\r
+                                LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback) \r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,\r
+                            LPDDSURFACEDESC2 lpDDSD2, LPVOID context,\r
+                            LPDDENUMSURFACESCALLBACK7 callback) \r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface) \r
+{\r
+return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,\r
+                       LPDDCAPS pHELCaps) \r
+{\r
+return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD) \r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)\r
+{\r
+  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, \r
+                                                                                        LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)\r
+{\r
+  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)\r
+{  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)\r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)\r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid)\r
+{\r
+ return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)\r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,\r
+                                                                                                  DWORD cooplevel)\r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,\r
+                             DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)\r
+{\r
+  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+\r
+HRESULT WINAPI HAL_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,\r
+                                                                                                  HANDLE h)\r
+{\r
+  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,\r
+                                  LPDWORD total, LPDWORD free)                                                                                    \r
+\r
+{\r
+  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+                                                                                                  \r
+HRESULT WINAPI HAL_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,\r
+                                                                                               LPDIRECTDRAWSURFACE7 *lpDDS)\r
+{  \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)\r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) \r
+{\r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,\r
+                                  LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)\r
+{    \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,\r
+                             DWORD dwNumModes, DWORD dwFlags)\r
+{    \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+HRESULT WINAPI HAL_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)\r
+{    \r
+    return DDERR_UNSUPPORTED;\r
+}\r
+\r
+/* End com interface */\r
+\r
+\r
+\r
+\r
+HRESULT WINAPI HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,\r
+                             IUnknown* pUnkOuter, BOOL ex)\r
+{\r
+   \r
+      HRESULT hr;\r
+    IDirectDrawImpl* This;\r
+       HDC desktop;\r
+\r
+       /*\r
+    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,\r
+                    sizeof(IDirectDrawImpl)\r
+                    + sizeof(HAL_DirectDrawImpl));\r
+        */\r
+       This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,\r
+                    sizeof(IDirectDrawImpl));\r
+\r
+    if (This == NULL) return E_OUTOFMEMORY;\r
+\r
+    /* Note that this relation does *not* hold true if the DD object was\r
+     * CoCreateInstanced then Initialized. */\r
+    //This->private = (HAL_DirectDrawImpl *)(This+1);\r
+\r
+    /* Initialize the DDCAPS structure */\r
+    This->caps.dwSize = sizeof(This->caps);\r
+\r
+    hr = HAL_DirectDraw_Construct(This, ex);\r
+    if (FAILED(hr))\r
+       HeapFree(GetProcessHeap(), 0, This);\r
+    else *pIface = ICOM_INTERFACE(This, IDirectDraw7);\r
+\r
+       /* create a scaner that check which driver we should get the HDC from */\r
+       /* for now we always asume it is the active dirver that should be use. */\r
+       \r
+       desktop = GetWindowDC(GetDesktopWindow());\r
+       *pIface = OsThunkDdCreateDirectDrawObject(desktop);   \r
+       if (pIface == NULL) hr == DDERR_NODIRECTDRAWHW;  \r
+\r
+    return hr;\r
+}\r
+\r
+static IDirectDraw7Vtbl HAL_DirectDraw_VTable =\r
+{\r
+    HAL_DirectDraw_QueryInterface,\r
+    HAL_DirectDraw_AddRef,\r
+    HAL_DirectDraw_Release,\r
+    HAL_DirectDraw_Compact,\r
+    HAL_DirectDraw_CreateClipper,\r
+    HAL_DirectDraw_CreatePalette,\r
+    HAL_DirectDraw_CreateSurface,\r
+    HAL_DirectDraw_DuplicateSurface,\r
+    HAL_DirectDraw_EnumDisplayModes,\r
+    HAL_DirectDraw_EnumSurfaces,\r
+    HAL_DirectDraw_FlipToGDISurface,\r
+    HAL_DirectDraw_GetCaps,\r
+    HAL_DirectDraw_GetDisplayMode,\r
+    HAL_DirectDraw_GetFourCCCodes,\r
+    HAL_DirectDraw_GetGDISurface,\r
+    HAL_DirectDraw_GetMonitorFrequency,\r
+    HAL_DirectDraw_GetScanLine,\r
+    HAL_DirectDraw_GetVerticalBlankStatus,\r
+    HAL_DirectDraw_Initialize,\r
+    HAL_DirectDraw_RestoreDisplayMode,\r
+    HAL_DirectDraw_SetCooperativeLevel,\r
+    HAL_DirectDraw_SetDisplayMode,\r
+    HAL_DirectDraw_WaitForVerticalBlank,\r
+    HAL_DirectDraw_GetAvailableVidMem,\r
+    HAL_DirectDraw_GetSurfaceFromDC,\r
+    HAL_DirectDraw_RestoreAllSurfaces,\r
+    HAL_DirectDraw_TestCooperativeLevel,\r
+    HAL_DirectDraw_GetDeviceIdentifier,\r
+    HAL_DirectDraw_StartModeTest,\r
+    HAL_DirectDraw_EvaluateMode\r
+};\r
diff --git a/reactos/lib/ddraw/ddraw_private.h b/reactos/lib/ddraw/ddraw_private.h
new file mode 100644 (file)
index 0000000..98558e9
--- /dev/null
@@ -0,0 +1,482 @@
+/*\r
+ * Copyright 2000-2001 TransGaming Technologies Inc.\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+#ifndef _DDCOMIMPL_H_\r
+#define _DDCOMIMPL_H_\r
+\r
+#include <stddef.h>\r
+\r
+/* Generates the name for a vtable pointer for a given interface. */\r
+/* The canonical name for a single interface is "lpVtbl". */\r
+#define ICOM_VFIELD_MULTI_NAME2(iface) ITF_##iface\r
+#define ICOM_VFIELD_MULTI_NAME(iface) ICOM_VFIELD_MULTI_NAME2(iface)\r
+\r
+/* Declares a vtable pointer field in an implementation. */\r
+#define ICOM_VFIELD_MULTI(iface) \\r
+       iface ICOM_VFIELD_MULTI_NAME(iface)\r
+\r
+/* Returns the offset of a vtable pointer within an implementation object. */\r
+#define ICOM_VFIELD_OFFSET(impltype, iface) \\r
+       offsetof(impltype, ICOM_VFIELD_MULTI_NAME(iface))\r
+\r
+/* Given an interface pointer, returns the implementation pointer. */\r
+#define ICOM_OBJECT(impltype, ifacename, ifaceptr)             \\r
+       (impltype*)((ifaceptr) == NULL ? NULL                   \\r
+                 : (char*)(ifaceptr) - ICOM_VFIELD_OFFSET(impltype,ifacename))\r
+\r
+#define ICOM_THIS_FROM(impltype, ifacename, ifaceptr) \\r
+       impltype* This = ICOM_OBJECT(impltype, ifacename, ifaceptr)\r
+\r
+/* Given an object and interface name, returns a pointer to that interface. */\r
+#define ICOM_INTERFACE(implobj, iface) \\r
+       (&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))\r
+\r
+#define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \\r
+       do { \\r
+         (implobj)->ICOM_VFIELD_MULTI_NAME(ifacename).lpVtbl = &(vtblname); \\r
+       } while (0)\r
+\r
+#define COM_INTERFACE_CAST(impltype, ifnamefrom, ifnameto, ifaceptr)   \\r
+       ICOM_INTERFACE(ICOM_OBJECT(impltype, ifnamefrom, ifaceptr), ifnameto)\r
+\r
+#endif /* _DDCOMIMPL_H_ */\r
+\r
+#ifndef __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H\r
+#define __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H\r
+\r
+/* MAY NOT CONTAIN X11 or DGA specific includes/defines/structs! */\r
+\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wtypes.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "ddraw.h"\r
+#include "d3d.h"\r
+#include "ddrawi.h"\r
+\r
+/* XXX Put this somewhere proper. */\r
+#define DD_STRUCT_INIT(x)                      \\r
+       do {                                    \\r
+               memset((x), 0, sizeof(*(x)));   \\r
+               (x)->dwSize = sizeof(*x);       \\r
+       } while (0)\r
+\r
+#define DD_STRUCT_COPY_BYSIZE(to,from)                 \\r
+       do {                                            \\r
+               DWORD __size = (to)->dwSize;            \\r
+               DWORD __copysize = __size;              \\r
+               DWORD __resetsize = __size;             \\r
+               if (__resetsize > sizeof(*to))          \\r
+                   __resetsize = sizeof(*to);          \\r
+               memset(to,0,__resetsize);               \\r
+               if ((from)->dwSize < __size)            \\r
+                   __copysize = (from)->dwSize;        \\r
+               memcpy(to,from,__copysize);             \\r
+               (to)->dwSize = __size;/*restore size*/  \\r
+       } while (0)\r
+\r
+#define MAKE_FOURCC(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 24))\r
+\r
+/*****************************************************************************\r
+ * IDirectDraw implementation structure\r
+ */\r
+\r
+typedef struct IDirectDrawImpl IDirectDrawImpl;\r
+typedef struct IDirectDrawPaletteImpl IDirectDrawPaletteImpl;\r
+typedef struct IDirectDrawClipperImpl IDirectDrawClipperImpl;\r
+typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl;\r
+typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl;\r
+\r
+typedef void (*pixel_convert_func)(void *src, void *dst, DWORD width,\r
+                                  DWORD height, LONG pitch,\r
+                                  IDirectDrawPaletteImpl *palette);\r
+\r
+typedef void (*palette_convert_func)(LPPALETTEENTRY palent,\r
+                                    void *screen_palette, DWORD start,\r
+                                    DWORD count);\r
+\r
+struct IDirectDrawImpl\r
+{\r
+    ICOM_VFIELD_MULTI(IDirectDraw7);\r
+    ICOM_VFIELD_MULTI(IDirectDraw4);\r
+    ICOM_VFIELD_MULTI(IDirectDraw2);\r
+    ICOM_VFIELD_MULTI(IDirectDraw);\r
+    ICOM_VFIELD_MULTI(IDirect3D7);\r
+    ICOM_VFIELD_MULTI(IDirect3D3);\r
+    ICOM_VFIELD_MULTI(IDirect3D2);\r
+    ICOM_VFIELD_MULTI(IDirect3D);\r
+\r
+    DWORD ref;\r
+\r
+    /* TRUE if created via DirectDrawCreateEx or CoCreateInstance,\r
+     * FALSE if created via DirectDrawCreate. */\r
+    BOOL ex;\r
+\r
+    /* Linked list of surfaces, joined by next_ddraw in IDirectSurfaceImpl. */\r
+    IDirectDrawSurfaceImpl* surfaces;\r
+    /* Linked list of palettes, joined by next_ddraw. */\r
+    IDirectDrawPaletteImpl* palettes;\r
+    /* Linked list of clippers, joined by next_ddraw. */\r
+    IDirectDrawClipperImpl* clippers;\r
+\r
+    IDirectDrawSurfaceImpl* primary_surface;\r
+\r
+    DDRAWI_DIRECTDRAW_LCL local;\r
+    DDCAPS caps;\r
+\r
+    HWND window;\r
+    DWORD cooperative_level;\r
+    WNDPROC original_wndproc;\r
+\r
+    DWORD width, height;\r
+    LONG pitch;\r
+    DDPIXELFORMAT pixelformat;\r
+    DWORD cur_scanline;\r
+\r
+    /* Should each of these go into some structure? */\r
+    DWORD orig_width, orig_height;\r
+    LONG orig_pitch;\r
+    DDPIXELFORMAT orig_pixelformat;\r
+\r
+    /* Called when the refcount goes to 0. */\r
+    void (*final_release)(IDirectDrawImpl *This);\r
+\r
+    HRESULT (*set_exclusive_mode)(IDirectDrawImpl *This, DWORD dwExcl);\r
+\r
+    HRESULT (*create_palette)(IDirectDrawImpl* This, DWORD dwFlags,\r
+                             LPDIRECTDRAWPALETTE* ppPalette,\r
+                             LPUNKNOWN pUnkOuter);\r
+\r
+    /* Surface creation functions. For all of these, pOuter == NULL. */\r
+\r
+    /* Do not create any backbuffers or the flipping chain. */\r
+    HRESULT (*create_primary)(IDirectDrawImpl* This,\r
+                             const DDSURFACEDESC2* pDDSD,\r
+                             LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);\r
+\r
+    /* Primary may be NULL if we are creating an unattached backbuffer. */\r
+    HRESULT (*create_backbuffer)(IDirectDrawImpl* This,\r
+                                const DDSURFACEDESC2* pDDSD,\r
+                                LPDIRECTDRAWSURFACE7* ppSurf,\r
+                                LPUNKNOWN pOuter,\r
+                                IDirectDrawSurfaceImpl* primary);\r
+\r
+    /* shiny happy offscreenplain surfaces */\r
+    HRESULT (*create_offscreen)(IDirectDrawImpl* This,\r
+                               const DDSURFACEDESC2* pDDSD,\r
+                               LPDIRECTDRAWSURFACE7* ppSurf,\r
+                               LPUNKNOWN pOuter);\r
+\r
+    /* dwMipMapLevel is specified as per OpenGL. (i.e. 0 is base) */\r
+    HRESULT (*create_texture)(IDirectDrawImpl* This,\r
+                             const DDSURFACEDESC2* pDDSD,\r
+                             LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,\r
+                     DWORD dwMipMapLevel);\r
+\r
+     HRESULT (*create_zbuffer)(IDirectDrawImpl* This,\r
+                             const DDSURFACEDESC2* pDDSD,\r
+                             LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter);\r
+\r
+    LPVOID     private;\r
+\r
+    /* Everything below here is still questionable. */\r
+\r
+    DDPIXELFORMAT screen_pixelformat;\r
+\r
+    int           pixmap_depth;\r
+    // pixel_convert_func pixel_convert;\r
+    // palette_convert_func palette_convert;\r
+\r
+    /* Use to fool some too strict games */\r
+    INT32 (*allocate_memory)(IDirectDrawImpl *This, DWORD mem);\r
+    void (*free_memory)(IDirectDrawImpl *This, DWORD mem);\r
+    DWORD total_vidmem, available_vidmem;\r
+    \r
+    /* IDirect3D fields */\r
+    LPVOID d3d_private;\r
+\r
+    /* Used as a callback function to create a texture */\r
+    HRESULT (*d3d_create_texture)(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main);\r
+\r
+    /* Used as a callback for Devices to tell to the D3D object it's been created */\r
+     HRESULT (*d3d_added_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device);\r
+     HRESULT (*d3d_removed_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device);\r
+\r
+    /* This is needed for delayed texture creation and Z buffer blits */\r
+    IDirect3DDeviceImpl *current_device;\r
+\r
+    /* This is for the fake mainWindow */\r
+    ATOM       winclass;\r
+    PAINTSTRUCT        ps;\r
+    BOOL       paintable;\r
+};\r
+\r
+/*****************************************************************************\r
+ * IDirectDrawPalette implementation structure\r
+ */\r
+struct IDirectDrawPaletteImpl\r
+{\r
+    /* IUnknown fields */\r
+    ICOM_VFIELD_MULTI(IDirectDrawPalette);\r
+    DWORD ref;\r
+\r
+    DDRAWI_DDRAWPALETTE_LCL local;\r
+    DDRAWI_DDRAWPALETTE_GBL global;\r
+\r
+    /* IDirectDrawPalette fields */\r
+    HPALETTE           hpal;\r
+    WORD               palVersion, palNumEntries; /* LOGPALETTE */\r
+    PALETTEENTRY       palents[256];\r
+    /* This is to store the palette in 'screen format' */\r
+    int                        screen_palents[256];\r
+\r
+    VOID (*final_release)(IDirectDrawPaletteImpl* This);\r
+\r
+    IDirectDrawImpl* ddraw_owner;\r
+    IDirectDrawPaletteImpl* prev_ddraw;\r
+    IDirectDrawPaletteImpl* next_ddraw;\r
+\r
+    LPVOID             private;\r
+};\r
+\r
+/*****************************************************************************\r
+ * IDirectDrawClipper implementation structure\r
+ */\r
+struct IDirectDrawClipperImpl\r
+{\r
+    /* IUnknown fields */\r
+    ICOM_VFIELD_MULTI(IDirectDrawClipper);\r
+    DWORD ref;\r
+\r
+    /* IDirectDrawClipper fields */\r
+    HWND hWnd;\r
+\r
+    IDirectDrawImpl* ddraw_owner;\r
+    IDirectDrawClipperImpl* prev_ddraw;\r
+    IDirectDrawClipperImpl* next_ddraw;\r
+};\r
+\r
+/*****************************************************************************\r
+ * IDirectDrawSurface implementation structure\r
+ */\r
+\r
+struct IDirectDrawSurfaceImpl\r
+{\r
+    /* IUnknown fields */\r
+    ICOM_VFIELD_MULTI(IDirectDrawSurface7);\r
+    ICOM_VFIELD_MULTI(IDirectDrawSurface3);\r
+    ICOM_VFIELD_MULTI(IDirectDrawGammaControl);\r
+    ICOM_VFIELD_MULTI(IDirect3DTexture2);\r
+    ICOM_VFIELD_MULTI(IDirect3DTexture);\r
+    DWORD ref;\r
+\r
+    struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */\r
+\r
+    struct IDirectDrawSurfaceImpl* next_ddraw; /* ddraw surface chain */\r
+    struct IDirectDrawSurfaceImpl* prev_ddraw;\r
+    struct IDirectDrawSurfaceImpl* next_attached; /* attached surface chain */\r
+    struct IDirectDrawSurfaceImpl* prev_attached;\r
+\r
+    IDirectDrawImpl* ddraw_owner;\r
+    IDirectDrawSurfaceImpl* surface_owner;\r
+\r
+    IDirectDrawPaletteImpl* palette; /* strong ref */\r
+    IDirectDrawClipperImpl* clipper; /* strong ref */\r
+\r
+    DDRAWI_DDRAWSURFACE_LCL local;\r
+    DDRAWI_DDRAWSURFACE_MORE more;\r
+    /* FIXME: since Flip should swap the GBL structures, they should\r
+     * probably not be embedded into the IDirectDrawSurfaceImpl structure... */\r
+    LPDDRAWI_DDRAWSURFACE_GBL_MORE gmore;\r
+    DDRAWI_DDRAWSURFACE_GBL global;\r
+    DDRAWI_DDRAWSURFACE_GBL_MORE global_more;\r
+\r
+    DDSURFACEDESC2 surface_desc;\r
+\r
+    HDC hDC;\r
+    RECT lastlockrect;\r
+    DWORD lastlocktype;\r
+    BOOL dc_in_use;\r
+    BOOL locked;\r
+\r
+    HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src,\r
+                                LPDIRECTDRAWSURFACE7* dst);\r
+    void (*final_release)(IDirectDrawSurfaceImpl *This);\r
+    HRESULT (*late_allocate)(IDirectDrawSurfaceImpl *This);\r
+    BOOL (*attach)(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *to);\r
+    BOOL (*detach)(IDirectDrawSurfaceImpl *This);\r
+    void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);\r
+    void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);\r
+    void (*lose_surface)(IDirectDrawSurfaceImpl* This);\r
+    BOOL (*flip_data)(IDirectDrawSurfaceImpl* front,\r
+                     IDirectDrawSurfaceImpl* back,\r
+                     DWORD dwFlags);\r
+    void (*flip_update)(IDirectDrawSurfaceImpl* front, DWORD dwFlags);\r
+    HRESULT (*get_dc)(IDirectDrawSurfaceImpl* This, HDC* phDC);\r
+    HRESULT (*release_dc)(IDirectDrawSurfaceImpl* This, HDC hDC);\r
+    void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal);\r
+    void (*update_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal,\r
+                          DWORD dwStart, DWORD dwCount, LPPALETTEENTRY palent);\r
+    HWND (*get_display_window)(IDirectDrawSurfaceImpl *This);\r
+    HRESULT (*get_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp);\r
+    HRESULT (*set_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp);\r
+\r
+    struct PrivateData* private_data;\r
+\r
+    DWORD max_lod;\r
+    DWORD priority;\r
+\r
+    BOOL lost;\r
+\r
+    DWORD uniqueness_value;\r
+\r
+    LPVOID private;\r
+\r
+    /* Everything below here is dodgy. */\r
+    /* For Direct3D use */\r
+    LPVOID aux_ctx, aux_data;\r
+    void (*aux_release)(LPVOID ctx, LPVOID data);\r
+    BOOL (*aux_flip)(LPVOID ctx, LPVOID data);\r
+    void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect);\r
+    HRESULT (*aux_blt)(struct IDirectDrawSurfaceImpl *This, LPRECT rdst, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD dwFlags, LPDDBLTFX lpbltfx);\r
+    HRESULT (*aux_bltfast)(struct IDirectDrawSurfaceImpl *This, DWORD dstx, DWORD dsty, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD trans);\r
+    HRESULT (*aux_setcolorkey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey );\r
+    /* This is to get the D3DDevice object associated to this surface */\r
+    struct IDirect3DDeviceImpl *d3ddevice;\r
+    /* This is for texture */\r
+    IDirectDrawSurfaceImpl *mip_main;\r
+    int mipmap_level;\r
+    LPVOID tex_private;\r
+    void (*lock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);\r
+    void (*unlock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);\r
+    BOOLEAN (*get_dirty_status)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);\r
+};\r
+\r
+/*****************************************************************************\r
+ * Driver initialisation functions.\r
+ */\r
+BOOL DDRAW_HAL_Init(HINSTANCE, DWORD, LPVOID);\r
+BOOL DDRAW_User_Init(HINSTANCE, DWORD, LPVOID);\r
+\r
+typedef struct {\r
+    const DDDEVICEIDENTIFIER2* info;\r
+    int        preference;     /* how good we are. dga might get 100, xlib 50*/\r
+    HRESULT (*create)(const GUID*, LPDIRECTDRAW7*, LPUNKNOWN, BOOL ex);\r
+\r
+    /* For IDirectDraw7::Initialize. */\r
+    HRESULT (*init)(IDirectDrawImpl *, const GUID*);\r
+} ddraw_driver;\r
+\r
+void DDRAW_register_driver(const ddraw_driver*);\r
+\r
+const ddraw_driver* DDRAW_FindDriver(const GUID* guid);\r
+\r
+/******************************************************************************\r
+ * Random utilities\r
+ */\r
+\r
+/* Get DDSCAPS of surface (shortcutmacro) */\r
+#define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)\r
+/* Get the number of bytes per pixel for a given surface */\r
+#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.u1.dwRGBBitCount+7)/8))\r
+#define GET_BPP(desc) PFGET_BPP(desc.u4.ddpfPixelFormat)\r
+\r
+LONG DDRAW_width_bpp_to_pitch(DWORD width, DWORD bpp);\r
+\r
+typedef struct {\r
+    unsigned short     bpp,depth;\r
+    unsigned int       rmask,gmask,bmask;\r
+} ConvertMode;\r
+\r
+typedef struct {\r
+    void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);\r
+    void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);\r
+} ConvertFuncs;\r
+\r
+typedef struct {\r
+    ConvertMode screen, dest;\r
+    ConvertFuncs funcs;\r
+} Convert;\r
+\r
+extern Convert ModeEmulations[8];\r
+extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw);\r
+extern BOOL opengl_initialized;\r
+extern BOOL s3tc_initialized;\r
+\r
+typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT1)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);\r
+typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT3)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);\r
+typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT5)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel);\r
+\r
+extern FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1;\r
+extern FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3;\r
+extern FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5;\r
+\r
+/******************************************************************************\r
+ * Structure conversion (for thunks)\r
+ */\r
+void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut);\r
+void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn,\r
+                                            DDDEVICEIDENTIFIER* pOut);\r
+\r
+/******************************************************************************\r
+ * Debugging / Flags output functions\r
+ */\r
+extern void DDRAW_dump_DDBLTFX(DWORD flagmask);\r
+extern void DDRAW_dump_DDBLTFAST(DWORD flagmask);\r
+extern void DDRAW_dump_DDBLT(DWORD flagmask);\r
+extern void DDRAW_dump_DDSCAPS(const DDSCAPS *in);\r
+extern void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in);\r
+extern void DDRAW_dump_pixelformat_flag(DWORD flagmask);\r
+extern void DDRAW_dump_paletteformat(DWORD dwFlags);\r
+extern void DDRAW_dump_pixelformat(const DDPIXELFORMAT *in);\r
+extern void DDRAW_dump_colorkeyflag(DWORD ck);\r
+extern void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd);\r
+extern void DDRAW_dump_cooperativelevel(DWORD cooplevel);\r
+extern void DDRAW_dump_lockflag(DWORD lockflag);\r
+extern void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *in);\r
+extern void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps);\r
+extern void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale) ;\r
+\r
+/* Used for generic dumping */\r
+typedef struct\r
+{\r
+    DWORD val;\r
+    const char* name;\r
+} flag_info;\r
+\r
+#define FE(x) { x, #x }\r
+\r
+typedef struct\r
+{\r
+    DWORD val;\r
+    const char* name;\r
+    void (*func)(const void *);\r
+    ptrdiff_t offset;\r
+} member_info;\r
+\r
+#define DDRAW_dump_flags(flags,names,num_names) DDRAW_dump_flags_(flags, names, num_names, 1)\r
+#define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) }\r
+\r
+extern void DDRAW_dump_flags_(DWORD flags, const flag_info* names, size_t num_names, int newline);\r
+extern void DDRAW_dump_members(DWORD flags, const void* data, const member_info* mems, size_t num_mems);\r
\r
+\r
+#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */\r
diff --git a/reactos/lib/ddraw/ddraw_user.c b/reactos/lib/ddraw/ddraw_user.c
new file mode 100644 (file)
index 0000000..a956854
--- /dev/null
@@ -0,0 +1,330 @@
+/*     DirectDraw HAL driver
+ *
+ * Copyright 2001 TransGaming Technologies Inc.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+
+#include <windows.h>\r
+#include "ddraw.h"\r
+#include "rosddraw.h"
+#include "ddraw_private.h"
+
+static IDirectDraw7Vtbl MAIN_DirectDraw_VTable;
+
+
+HRESULT MAIN_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex)
+{    
+    //This->local.lpGbl = &dd_gbl;
+
+    This->final_release = MAIN_DirectDraw_final_release;
+    This->set_exclusive_mode = MAIN_DirectDrawSet_exclusive_mode;
+   // This->create_palette = MAIN_DirectDrawPalette_Create;
+
+    This->create_primary    = MAIN_DirectDraw_create_primary;
+    This->create_backbuffer = MAIN_DirectDraw_create_backbuffer;
+    This->create_texture    = MAIN_DirectDraw_create_texture;
+
+    ICOM_INIT_INTERFACE(This, IDirectDraw7, MAIN_DirectDraw_VTable);
+    return S_OK;
+}
+
+void MAIN_DirectDraw_final_release(IDirectDrawImpl *This)
+{
+}
+
+HRESULT MAIN_DirectDrawSet_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl)
+{
+ return DDERR_UNSUPPORTED;
+}
+
+
+HRESULT MAIN_DirectDraw_create_primary(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD, LPDIRECTDRAWSURFACE7* ppSurf,
+                                     IUnknown* pUnkOuter)
+
+{
+       return DDERR_UNSUPPORTED;
+  }
+
+HRESULT MAIN_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
+                                        const DDSURFACEDESC2* pDDSD,
+                                        LPDIRECTDRAWSURFACE7* ppSurf,
+                                        IUnknown* pUnkOuter,
+                                        IDirectDrawSurfaceImpl* primary)
+{
+       return DDERR_UNSUPPORTED;
+  }
+
+HRESULT MAIN_DirectDraw_create_texture(IDirectDrawImpl* This,
+                                     const DDSURFACEDESC2* pDDSD,
+                                     LPDIRECTDRAWSURFACE7* ppSurf,
+                                     LPUNKNOWN pOuter,
+                                     DWORD dwMipMapLevel)
+{
+       return DDERR_UNSUPPORTED;
+  }
+
+
+
+
+
+
+/* basic funtion for the com object */
+HRESULT WINAPI MAIN_DirectDraw_QueryInterface(LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj) 
+{
+       return DDERR_UNSUPPORTED;
+  }
+
+ULONG WINAPI MAIN_DirectDraw_AddRef(LPDIRECTDRAW7 iface) 
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    //TRACE("(%p)->() incrementing from %lu.\n", This, ref -1);
+
+    return ref;
+}
+
+ULONG WINAPI MAIN_DirectDraw_Release(LPDIRECTDRAW7 iface) 
+{
+    IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+    
+    if (ref == 0)
+    {
+       if (This->final_release != NULL)
+           This->final_release(This);
+
+       /* We free the private. This is an artifact of the fact that I don't
+        * have the destructors set up correctly. */
+       if (This->private != (This+1))
+           HeapFree(GetProcessHeap(), 0, This->private);
+
+       HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_Compact(LPDIRECTDRAW7 iface) 
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags, 
+                                                                                        LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
+{
+    return DDERR_UNSUPPORTED;
+}
+HRESULT WINAPI MAIN_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                             LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown)
+{
+       return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
+                             LPDIRECTDRAWSURFACE7 *ppSurf,IUnknown *pUnkOuter) 
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
+                                LPDIRECTDRAWSURFACE7* dst) 
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                                LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback) 
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                            LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
+                            LPDDENUMSURFACESCALLBACK7 callback) 
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface) 
+{
+return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
+                       LPDDCAPS pHELCaps) 
+{
+return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD) 
+{
+    return DDERR_UNSUPPORTED;
+}
+
+
+HRESULT WINAPI MAIN_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
+{
+  
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, 
+                                                                                        LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
+{
+  
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
+{  
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid)
+{
+ return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
+                                                                                                  DWORD cooplevel)
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+                             DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
+{
+  
+    return DDERR_UNSUPPORTED;
+}
+
+
+HRESULT WINAPI MAIN_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                                                                                                  HANDLE h)
+{
+  
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
+                                  LPDWORD total, LPDWORD free)                                                                                    
+
+{
+  
+    return DDERR_UNSUPPORTED;
+}
+                                                                                                  
+HRESULT WINAPI MAIN_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
+                                                                                               LPDIRECTDRAWSURFACE7 *lpDDS)
+{  
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) 
+{
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
+                                  LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
+{    
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
+                             DWORD dwNumModes, DWORD dwFlags)
+{    
+    return DDERR_UNSUPPORTED;
+}
+
+HRESULT WINAPI MAIN_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
+{    
+    return DDERR_UNSUPPORTED;
+}
+
+/* End com interface */
+
+
+
+
+HRESULT WINAPI MAIN_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+                             IUnknown* pUnkOuter, BOOL ex)
+{
+   
+    IDirectDrawImpl* This;    
+       *pIface = ICOM_INTERFACE(This, IDirectDraw7);
+
+    return DD_OK;
+}
+
+static IDirectDraw7Vtbl MAIN_DirectDraw_VTable =
+{
+    MAIN_DirectDraw_QueryInterface,
+    MAIN_DirectDraw_AddRef,
+    MAIN_DirectDraw_Release,
+    MAIN_DirectDraw_Compact,
+    MAIN_DirectDraw_CreateClipper,
+    MAIN_DirectDraw_CreatePalette,
+    MAIN_DirectDraw_CreateSurface,
+    MAIN_DirectDraw_DuplicateSurface,
+    MAIN_DirectDraw_EnumDisplayModes,
+    MAIN_DirectDraw_EnumSurfaces,
+    MAIN_DirectDraw_FlipToGDISurface,
+    MAIN_DirectDraw_GetCaps,
+    MAIN_DirectDraw_GetDisplayMode,
+    MAIN_DirectDraw_GetFourCCCodes,
+    MAIN_DirectDraw_GetGDISurface,
+    MAIN_DirectDraw_GetMonitorFrequency,
+    MAIN_DirectDraw_GetScanLine,
+    MAIN_DirectDraw_GetVerticalBlankStatus,
+    MAIN_DirectDraw_Initialize,
+    MAIN_DirectDraw_RestoreDisplayMode,
+    MAIN_DirectDraw_SetCooperativeLevel,
+    MAIN_DirectDraw_SetDisplayMode,
+    MAIN_DirectDraw_WaitForVerticalBlank,
+    MAIN_DirectDraw_GetAvailableVidMem,
+    MAIN_DirectDraw_GetSurfaceFromDC,
+    MAIN_DirectDraw_RestoreAllSurfaces,
+    MAIN_DirectDraw_TestCooperativeLevel,
+    MAIN_DirectDraw_GetDeviceIdentifier,
+    MAIN_DirectDraw_StartModeTest,
+    MAIN_DirectDraw_EvaluateMode
+};
diff --git a/reactos/lib/ddraw/regsvr.c b/reactos/lib/ddraw/regsvr.c
new file mode 100644 (file)
index 0000000..13b2316
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ *     self-registerable dll functions for ddraw.dll
+ *
+ * Copyright (C) 2003 John K. Hohm
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * this file are from wine ddraw with some modification
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "ddraw.h"
+
+
+//#include "wine/debug.h"
+
+//WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ *             interface for self-registering
+ */
+struct regsvr_interface
+{
+    IID const *iid;            /* NULL for end of list */
+    LPCSTR name;               /* can be NULL to omit */
+    IID const *base_iid;       /* can be NULL to omit */
+    int num_methods;           /* can be <0 to omit */
+    CLSID const *ps_clsid;     /* can be NULL to omit */
+    CLSID const *ps_clsid32;   /* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+struct regsvr_coclass
+{
+    CLSID const *clsid;                /* NULL for end of list */
+    LPCSTR name;               /* can be NULL to omit */
+    LPCSTR ips;                        /* can be NULL to omit */
+    LPCSTR ips32;              /* can be NULL to omit */
+    LPCSTR ips32_tmodel;       /* can be NULL to omit */
+    LPCSTR clsid_str;          /* can be NULL to omit */
+    LPCSTR progid;             /* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ *             static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+    'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+    'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+    'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+    'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+    'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+    'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+    'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const ips_keyname[13] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    0 };
+static WCHAR const ips32_keyname[15] = {
+    'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+    '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+    'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ *             static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+                                  WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+                                  char const *value);
+static LONG recursive_delete_key(HKEY key);
+static LONG recursive_delete_keyA(HKEY base, char const *name);
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
+
+/***********************************************************************
+ *             register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+       WCHAR buf[39];
+       HKEY iid_key;
+
+       StringFromGUID2(list->iid, buf, 39);
+       res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+                             KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+       if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+       if (list->name) {
+           res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)(list->name),
+                                strlen(list->name) + 1);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->base_iid) {
+           register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (0 <= list->num_methods) {
+           static WCHAR const fmt[3] = { '%', 'd', 0 };
+           HKEY key;
+
+           res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+                                 KEY_READ | KEY_WRITE, NULL, &key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+           wsprintfW(buf, fmt, list->num_methods);
+           res = RegSetValueExW(key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)buf,
+                                (lstrlenW(buf) + 1) * sizeof(WCHAR));
+           RegCloseKey(key);
+
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->ps_clsid) {
+           register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+       if (list->ps_clsid32) {
+           register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+           if (res != ERROR_SUCCESS) goto error_close_iid_key;
+       }
+
+    error_close_iid_key:
+       RegCloseKey(iid_key);
+    }
+
+error_close_interface_key:
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY interface_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+                       KEY_READ | KEY_WRITE, &interface_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->iid; ++list) {
+       WCHAR buf[39];
+
+       StringFromGUID2(list->iid, buf, 39);
+       res = recursive_delete_keyW(interface_key, buf);
+    }
+
+    RegCloseKey(interface_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+       WCHAR buf[39];
+       HKEY clsid_key;
+
+       StringFromGUID2(list->clsid, buf, 39);
+       res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+                             KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+       if (list->name) {
+           res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)(list->name),
+                                strlen(list->name) + 1);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->ips) {
+           res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->ips32) {
+           HKEY ips32_key;
+
+           res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+                                 KEY_READ | KEY_WRITE, NULL,
+                                 &ips32_key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+                                (CONST BYTE*)list->ips32,
+                                lstrlenA(list->ips32) + 1);
+           if (res == ERROR_SUCCESS && list->ips32_tmodel)
+               res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+                                    (CONST BYTE*)list->ips32_tmodel,
+                                    strlen(list->ips32_tmodel) + 1);
+           RegCloseKey(ips32_key);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->clsid_str) {
+           res = register_key_defvalueA(clsid_key, clsid_keyname,
+                                        list->clsid_str);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+       if (list->progid) {
+           HKEY progid_key;
+
+           res = register_key_defvalueA(clsid_key, progid_keyname,
+                                        list->progid);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0,
+                                 NULL, 0, KEY_READ | KEY_WRITE, NULL,
+                                 &progid_key, NULL);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+           res = register_key_defvalueW(progid_key, clsid_keyname, buf);
+           RegCloseKey(progid_key);
+           if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+       }
+
+    error_close_clsid_key:
+       RegCloseKey(clsid_key);
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
+{
+    LONG res = ERROR_SUCCESS;
+    HKEY coclass_key;
+
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+                       KEY_READ | KEY_WRITE, &coclass_key);
+    if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+    if (res != ERROR_SUCCESS) goto error_return;
+
+    for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+       WCHAR buf[39];
+
+       StringFromGUID2(list->clsid, buf, 39);
+       res = recursive_delete_keyW(coclass_key, buf);
+       if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+       if (list->progid) {
+           res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
+           if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+       }
+    }
+
+error_close_coclass_key:
+    RegCloseKey(coclass_key);
+error_return:
+    return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ *             regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
+{
+    WCHAR buf[39];
+
+    StringFromGUID2(guid, buf, 39);
+    return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ *             regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+    HKEY base,
+    WCHAR const *name,
+    WCHAR const *value)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+                        (lstrlenW(value) + 1) * sizeof(WCHAR));
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+    HKEY base,
+    WCHAR const *name,
+    char const *value)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegCreateKeyExW(base, name, 0, NULL, 0,
+                         KEY_READ | KEY_WRITE, NULL, &key, NULL);
+    if (res != ERROR_SUCCESS) return res;
+    res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+                        lstrlenA(value) + 1);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key)
+{
+    LONG res;
+    WCHAR subkey_name[MAX_PATH];
+    DWORD cName;
+    HKEY subkey;
+
+    for (;;) {
+       cName = sizeof(subkey_name) / sizeof(WCHAR);
+       res = RegEnumKeyExW(key, 0, subkey_name, &cName,
+                           NULL, NULL, NULL, NULL);
+       if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+           res = ERROR_SUCCESS; /* presumably we're done enumerating */
+           break;
+       }
+       res = RegOpenKeyExW(key, subkey_name, 0,
+                           KEY_READ | KEY_WRITE, &subkey);
+       if (res == ERROR_FILE_NOT_FOUND) continue;
+       if (res != ERROR_SUCCESS) break;
+
+       res = recursive_delete_key(subkey);
+       RegCloseKey(subkey);
+       if (res != ERROR_SUCCESS) break;
+    }
+
+    if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+    return res;
+}
+
+/***********************************************************************
+ *             recursive_delete_keyA
+ */
+static LONG recursive_delete_keyA(HKEY base, char const *name)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
+    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+    if (res != ERROR_SUCCESS) return res;
+    res = recursive_delete_key(key);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             recursive_delete_keyW
+ */
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
+{
+    LONG res;
+    HKEY key;
+
+    res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
+    if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+    if (res != ERROR_SUCCESS) return res;
+    res = recursive_delete_key(key);
+    RegCloseKey(key);
+    return res;
+}
+
+/***********************************************************************
+ *             coclass list
+ */
+
+static struct regsvr_coclass const coclass_list[] = {
+    {   &CLSID_DirectDraw,
+       "DirectDraw Object",
+       NULL,
+       "ddraw.dll",
+       "Both"
+    },
+    {   &CLSID_DirectDrawClipper,
+       "DirectDraw Clipper Object",
+       NULL,
+       "ddraw.dll",
+       "Both"
+    },
+    { NULL }                   /* list terminator */
+};
+
+/***********************************************************************
+ *             interface list
+ */
+
+static struct regsvr_interface const interface_list[] = {
+    { NULL }                   /* list terminator */
+};
+
+/***********************************************************************
+ *             DllRegisterServer (DDRAW.@)
+ */
+HRESULT WINAPI DDRAW_DllRegisterServer()
+{
+    HRESULT hr;
+
+    //TRACE("\n");
+
+    hr = register_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+       hr = register_interfaces(interface_list);
+    return hr;
+}
+
+/***********************************************************************
+ *             DllUnregisterServer (DDRAW.@)
+ */
+HRESULT WINAPI DDRAW_DllUnregisterServer()
+{
+    HRESULT hr;
+
+    //TRACE("\n");
+
+    hr = unregister_coclasses(coclass_list);
+    if (SUCCEEDED(hr))
+       hr = unregister_interfaces(interface_list);
+    return hr;
+}
diff --git a/reactos/lib/ddraw/rosddraw.h b/reactos/lib/ddraw/rosddraw.h
new file mode 100644 (file)
index 0000000..670affe
--- /dev/null
@@ -0,0 +1,125 @@
+/* \r
+ *\r
+ * COPYRIGHT:            See COPYING in the top level directory\r
+ * PROJECT:              ReactOS kernel\r
+ * FILE:                 lib/ddraw/ddraw.c\r
+ * PURPOSE:              ddraw lib\r
+ * PROGRAMMER:           Magnus Olsen\r
+ * UPDATE HISTORY:\r
+ */\r
+#include "ddraw_private.h"\r
+\r
+\r
+\r
+HANDLE STDCALL OsThunkDdCreateDirectDrawObject(HDC hdc);\r
+\r
+\r
+void HAL_DirectDraw_final_release(IDirectDrawImpl *This);\r
+HRESULT HAL_DirectDrawSet_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl);\r
+\r
+\r
+\r
\r
+\r
+HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD, LPDIRECTDRAWSURFACE7* ppSurf,
+                                     IUnknown* pUnkOuter);\r
+\r
+HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This,
+                                        const DDSURFACEDESC2* pDDSD,
+                                        LPDIRECTDRAWSURFACE7* ppSurf,
+                                        IUnknown* pUnkOuter,
+                                        IDirectDrawSurfaceImpl* primary);\r
+\r
+HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This,
+                                     const DDSURFACEDESC2* pDDSD,
+                                     LPDIRECTDRAWSURFACE7* ppSurf,
+                                     LPUNKNOWN pOuter,
+                                     DWORD dwMipMapLevel);\r
+\r
+HRESULT DDRAW_Create(LPGUID lpGUID, LPVOID *lplpDD, LPUNKNOWN pUnkOuter, REFIID iid, BOOL ex); \r
+\r
+\r
+HRESULT WINAPI HAL7_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags, 
+                                                                                        LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter);\r
+\r
+HRESULT WINAPI HAL7_DirectDraw_QueryInterface(LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj) ;
+
+ULONG WINAPI HAL7_DirectDraw_AddRef(LPDIRECTDRAW7 iface) ;
+
+ULONG WINAPI HAL7_DirectDraw_Release(LPDIRECTDRAW7 iface) ;
+
+HRESULT WINAPI HAL7_DirectDraw_Compact(LPDIRECTDRAW7 iface) ;
+
+HRESULT WINAPI HAL7_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                             LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown) ;
+
+HRESULT WINAPI HAL7_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
+                             LPDIRECTDRAWSURFACE7 *ppSurf,IUnknown *pUnkOuter) ;
+
+HRESULT WINAPI HAL7_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
+                                LPDIRECTDRAWSURFACE7* dst) ;
+
+HRESULT WINAPI HAL7_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                                LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback) ;
+
+HRESULT WINAPI HAL7_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                            LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
+                            LPDDENUMSURFACESCALLBACK7 callback) ;
+
+HRESULT WINAPI HAL7_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface) ;
+
+HRESULT WINAPI HAL7_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
+                       LPDDCAPS pHELCaps) ;
+
+
+HRESULT WINAPI HAL7_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD) ;
+
+
+HRESULT WINAPI HAL7_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes);
+
+HRESULT WINAPI HAL7_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, 
+                                                                                        LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface);
+
+
+HRESULT WINAPI HAL7_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq);
+
+HRESULT WINAPI HAL7_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine);
+
+HRESULT WINAPI HAL7_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status);
+
+HRESULT WINAPI HAL7_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid);
+
+HRESULT WINAPI HAL7_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface);
+
+
+HRESULT WINAPI HAL7_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd,
+                                                                                                  DWORD cooplevel);
+
+HRESULT WINAPI HAL7_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth,
+                             DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags);
+
+HRESULT WINAPI HAL7_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
+                                                                                                  HANDLE h);
+
+HRESULT WINAPI HAL7_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
+                                  LPDWORD total, LPDWORD free);
+
+HRESULT WINAPI HAL7_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
+                                                                                               LPDIRECTDRAWSURFACE7 *lpDDS);
+
+
+HRESULT WINAPI HAL7_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface);
+
+HRESULT WINAPI HAL7_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) ;
+
+HRESULT WINAPI HAL7_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
+                                  LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags);
+
+HRESULT WINAPI HAL7_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
+                             DWORD dwNumModes, DWORD dwFlags);
+
+HRESULT WINAPI HAL7_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b);
+
+
+HRESULT WINAPI HAL7_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface,
+                             IUnknown* pUnkOuter, BOOL ex);\r
index 673cc38..e59c0a6 100644 (file)
@@ -978,7 +978,7 @@ static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
 {\r
   JoystickImpl *This = (JoystickImpl *)iface;\r
 \r
-  TRACE("(this=%p,%s,%p): stub!\n",\r
+  TRACE("(this=%p,%s,%p)\n",\r
        iface, debugstr_guid(rguid), pdiph);\r
 \r
   if (TRACE_ON(dinput))\r
index 41630d0..1893b65 100644 (file)
@@ -426,6 +426,36 @@ static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
        return DI_OK;\r
 }\r
 \r
+static HRESULT WINAPI SysKeyboardAImpl_GetProperty(\r
+       LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPDIPROPHEADER ph\r
+)\r
+{\r
+       SysKeyboardImpl *This = (SysKeyboardImpl *)iface;\r
+\r
+       TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);\r
+       TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",\r
+            ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);\r
+       if (!HIWORD(rguid)) {\r
+               switch ((DWORD)rguid) {\r
+               case (DWORD) DIPROP_BUFFERSIZE: {\r
+                       LPDIPROPDWORD   pd = (LPDIPROPDWORD)ph;\r
+\r
+                       TRACE("(buffersize=%ld)\n",pd->dwData);\r
+\r
+                        if (This->acquired)\r
+                           return DIERR_INVALIDPARAM;\r
+\r
+                        pd->dwData = This->buffersize;\r
+\r
+                       break;\r
+               }\r
+               default:\r
+                       WARN("Unknown type %ld\n",(DWORD)rguid);\r
+                       break;\r
+               }\r
+       }\r
+       return DI_OK;\r
+}\r
 \r
 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(\r
        LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr\r
@@ -441,7 +471,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
     if (len != 256)\r
       return DIERR_INVALIDPARAM;\r
 \r
-    MsgWaitForMultipleObjectsEx(0, NULL, 0, 0, 0);\r
+    MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);\r
 \r
     if (TRACE_ON(dinput)) {\r
        int i;\r
@@ -480,7 +510,7 @@ static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
         if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))\r
           return DIERR_INVALIDPARAM;\r
 \r
-        MsgWaitForMultipleObjectsEx(0, NULL, 0, 0, 0);\r
+        MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, 0);\r
 \r
         EnterCriticalSection(&(This->crit));\r
 \r
@@ -792,7 +822,7 @@ static IDirectInputDevice8AVtbl SysKeyboardAvt =
        SysKeyboardAImpl_Release,\r
        SysKeyboardAImpl_GetCapabilities,\r
        SysKeyboardAImpl_EnumObjects,\r
-       IDirectInputDevice2AImpl_GetProperty,\r
+       SysKeyboardAImpl_GetProperty,\r
        SysKeyboardAImpl_SetProperty,\r
        SysKeyboardAImpl_Acquire,\r
        SysKeyboardAImpl_Unacquire,\r
@@ -834,7 +864,7 @@ static IDirectInputDevice8WVtbl SysKeyboardWvt =
        XCAST(Release)SysKeyboardAImpl_Release,\r
        XCAST(GetCapabilities)SysKeyboardAImpl_GetCapabilities,\r
        SysKeyboardWImpl_EnumObjects,\r
-       XCAST(GetProperty)IDirectInputDevice2AImpl_GetProperty,\r
+       XCAST(GetProperty)SysKeyboardAImpl_GetProperty,\r
        XCAST(SetProperty)SysKeyboardAImpl_SetProperty,\r
        XCAST(Acquire)SysKeyboardAImpl_Acquire,\r
        XCAST(Unacquire)SysKeyboardAImpl_Unacquire,\r
index 5069661..6594708 100644 (file)
@@ -733,7 +733,7 @@ void getmousesvalue(LPDIRECTINPUTDEVICE8A iface)
 \r
     \r
        \r
-\r
\r
        if (poll_mouse==1) filp=0;\r
        if (filp==2) filp=0;\r
        if (filp==0) {\r
@@ -849,6 +849,7 @@ getmousesvalue(iface);
   *     GetDeviceState : gets buffered input data.\r
   */\r
 \r
+\r
 static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,\r
                                                  DWORD dodsize,\r
                                                  LPDIDEVICEOBJECTDATA dod,\r
@@ -861,62 +862,160 @@ static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
 #ifdef __REACTOS__\r
 static int last_event=0;\r
 const int size = sizeof(DIDEVICEOBJECTDATA) * 1;\r
-static count=0;\r
+int count=0;\r
+DWORD count_ent=0;\r
 static DWORD time=0;\r
+static POINT save_point;\r
+static int save_b[5];\r
+static int b[5];\r
+static POINT point;\r
+int calc;\r
+int count_button;\r
+int add = 0;\r
 #endif\r
 \r
     \r
     TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);\r
     \r
 #ifdef __REACTOS__\r
-getmousesvalue(iface);\r
+\r
+if (flags != DIGDD_PEEK) \r
+{\r
+b[0] = ((GetKeyState(VK_LBUTTON) & 0x80) ? 0xFF : 0x00);       \r
+b[1] = ((GetKeyState(VK_RBUTTON) & 0x80) ? 0xFF : 0x00);       \r
+b[2] = ((GetKeyState(VK_MBUTTON) & 0x80) ? 0xFF : 0x00);       \r
+b[3] = ((GetKeyState(VK_XBUTTON1) & 0x80) ? 0xFF : 0x00);      \r
+b[4] = ((GetKeyState(VK_XBUTTON2) & 0x80) ? 0xFF : 0x00);      \r
+GetCursorPos( &point );        \r
+}\r
+\r
 #endif\r
 \r
+    \r
+  \r
+       \r
+       \r
+    \r
+\r
+  if (This->acquired == 0) {\r
+       WARN(" application tries to get data from an unacquired device !\n");\r
+       return DIERR_NOTACQUIRED;\r
+\r
        // windows does not get any data if \r
        // we do not call manual to mouse Acquire\r
        // this is only need if some apps calling on getdevice data direcly\r
        // in windows GetdeviceData does always update first the data\r
        // then return it.\r
-       SysMouseAImpl_Acquire(iface);\r
+       }\r
+       \r
+    \r
 \r
+   \r
 \r
-    if (This->acquired == 0) {\r
-       WARN(" application tries to get data from an unacquired device !\n");\r
-       return DIERR_NOTACQUIRED;\r
-    }\r
-    \r
 #ifdef __REACTOS__     \r
-  FIXME("This is broken in Tribes, need right implant of the buffer!!!!!!!!\n"); \r
 \r
-  *entries = 5;\r
-  if (GetTickCount()-time <50) return DI_OK;\r
+\r
+  if (*entries == 0) return DIERR_INVALIDPARAM;\r
+\r
+  if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) {\r
+           ERR("Wrong structure size !\n");     \r
+           return DIERR_INVALIDPARAM;\r
+       }\r
+       if (This->data_queue==NULL) {\r
+       WARN("No buffer have been set up !\n");   \r
+       return DIERR_NOTINITIALIZED;\r
+       }             \r
+    \r
+/* this code are not need it but if we want 100% compatible\r
+  with ms we should keep it. but the mouse will be choppy \r
+  in Unreal 2004 Demo\r
+\r
+  if (GetTickCount()-time <50) {\r
+         *entries=0;\r
+         return DI_OK;\r
+      }\r
   time = GetTickCount();\r
-   \r
-  dod[0].dwOfs =   DIMOFS_X;\r
-  dod[0].dwData =   This->m_state.lX;\r
-  dod[0].dwTimeStamp =  0;\r
-  dod[0].dwSequence = last_event++;\r
-   \r
-  dod[1].dwOfs =   DIMOFS_Y;\r
-  dod[1].dwData =   This->m_state.lY;\r
-  dod[1].dwTimeStamp =  0;\r
-  dod[1].dwSequence = last_event++;\r
-  \r
-  dod[2].dwOfs =   DIMOFS_BUTTON0;\r
-  dod[2].dwData =   This->m_state.rgbButtons[0];\r
-  dod[2].dwTimeStamp =  0;\r
-  dod[2].dwSequence = last_event++;\r
-  \r
-  dod[3].dwOfs =   DIMOFS_BUTTON1;\r
-  dod[3].dwData =   This->m_state.rgbButtons[1];\r
-  dod[3].dwTimeStamp =  0;\r
-  dod[3].dwSequence = last_event++;\r
-  \r
-  dod[4].dwOfs =   DIMOFS_BUTTON2;\r
-  dod[4].dwData =   This->m_state.rgbButtons[2];\r
-  dod[4].dwTimeStamp =  50;\r
-  dod[4].dwSequence = last_event++;\r
+*/  \r
+       if (GetTickCount()-time <50)\r
+          {\r
+           add=0;\r
+          }\r
+       else \r
+       {\r
+        add=1;\r
+        time = GetTickCount();\r
+       }\r
+\r
+\r
+  for (count=0;count<*entries;count++) {\r
+         \r
+        \r
+         if (save_point.x != point.x) {\r
+             dod[count_ent].dwOfs =   DIMOFS_X;         \r
+\r
+                    dod[count_ent].dwData =  point.x - save_point.x;                                    \r
+             dod[count_ent].dwTimeStamp =  GetTickCount();\r
+             dod[count_ent].dwSequence = last_event+=add;  \r
+                    count_ent++;\r
+             save_point.x = point.x;\r
+                    }\r
+\r
+          else  if (save_point.y != point.y) {\r
+              dod[count_ent].dwOfs =   DIMOFS_Y;               \r
+                     dod[count_ent].dwData =  point.y - save_point.y;  \r
+\r
+              dod[count_ent].dwTimeStamp =  GetTickCount();\r
+              dod[count_ent].dwSequence =  last_event+=add;  \r
+                     count_ent++;\r
+                     save_point.y = point.y;                           \r
+                 }           \r
+\r
+        else if (save_b[0] != b[0]) {           \r
+               dod[count_ent].dwOfs =   DIMOFS_BUTTON0;\r
+                       \r
+        dod[count_ent].dwData =   b[0];\r
+        dod[count_ent].dwTimeStamp =  GetTickCount();\r
+        dod[count_ent].dwSequence =  last_event+=add;  \r
+               count_ent++;\r
+               save_b[0] = b[0];\r
+           }\r
+\r
+        else if (save_b[1] != b[1]) {           \r
+               dod[count_ent].dwOfs =   DIMOFS_BUTTON1;\r
+                       \r
+        dod[count_ent].dwData =   b[1];\r
+        dod[count_ent].dwTimeStamp =  GetTickCount();\r
+        dod[count_ent].dwSequence =  last_event+=add;  \r
+               count_ent++;\r
+               save_b[1] = b[1];\r
+           }\r
+\r
+        else if (save_b[2] != b[2]) {           \r
+               dod[count_ent].dwOfs =   DIMOFS_BUTTON2;\r
+                       \r
+        dod[count_ent].dwData =   b[2];\r
+        dod[count_ent].dwTimeStamp =  GetTickCount();\r
+        dod[count_ent].dwSequence =  last_event+=add;  \r
+               count_ent++;\r
+               save_b[2] = b[2];\r
+           }\r
+\r
+     else if (save_b[3] != b[3]) {              \r
+               dod[count_ent].dwOfs =   DIMOFS_BUTTON3;\r
+                       \r
+        dod[count_ent].dwData =   b[3];\r
+        dod[count_ent].dwTimeStamp =  GetTickCount();\r
+        dod[count_ent].dwSequence =  last_event+=add;  \r
+               count_ent++;\r
+               save_b[3] = b[3];\r
+           }\r
+        \r
+\r
+  }  // end for\r
+\r
 \r
+SetCursorPos(point.x, point.y);\r
+*entries = count_ent;\r
 #endif\r
 \r
 #ifndef __REACTOS__\r
@@ -1016,6 +1115,7 @@ static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
            case (DWORD) DIPROP_AXISMODE: {\r
                LPCDIPROPDWORD    pd = (LPCDIPROPDWORD)ph;\r
                This->absolute = !(pd->dwData);\r
+        \r
                TRACE("Using %s coordinates mode now\n", This->absolute ? "absolute" : "relative");\r
                break;\r
            }\r
@@ -1037,7 +1137,7 @@ static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
 {\r
     SysMouseImpl *This = (SysMouseImpl *)iface;\r
     \r
-    TRACE("(this=%p,%s,%p): stub!\n",\r
+    TRACE("(this=%p,%s,%p)\n",\r
          iface, debugstr_guid(rguid), pdiph);\r
     \r
     if (TRACE_ON(dinput))\r
index 05c33d1..7fe706b 100644 (file)
 <directory name="richedit">\r
        <xi:include href="richedit/riched32.xml" />\r
 </directory>\r
+<directory name="riched20">\r
+       <xi:include href="riched20/riched20.xml" />\r
+</directory>\r
 <directory name="rosrtl">\r
        <xi:include href="rosrtl/rosrtl.xml" />\r
 </directory>\r
 <directory name="smdll">\r
        <xi:include href="smdll/smdll.xml" />\r
 </directory>\r
+<directory name="smlib">\r
+       <xi:include href="smlib/smlib.xml" />\r
+</directory>\r
 <directory name="string">\r
        <xi:include href="string/string.xml" />\r
 </directory>\r
index f26eccb..cc54d56 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <windows.h>
-#include <WinError.h>
+#include <winerror.h>
 #include <windns.h>
 #include <internal/windns.h>
 
index 3dfa8a0..a66b2a8 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <windows.h>
-#include <WinError.h>
+#include <winerror.h>
 #include <windns.h>
 #define NTOS_MODE_USER
 #include <ntos.h>
index 1228376..e4bfe9d 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <windows.h>
-#include <WinError.h>
+#include <winerror.h>
 #include <windns.h>
 #include <internal/windns.h>
 #define NTOS_MODE_USER
index 7c74494..dd24e8a 100644 (file)
@@ -1,5 +1,5 @@
 #include <windows.h>
-#include <WinError.h>
+#include <winerror.h>
 #include <windns.h>
 #include <internal/windns.h>
 #define NTOS_MODE_USER
index 0806af1..2def104 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include <windows.h>
-#include <WinError.h>
+#include <winerror.h>
 #include <windns.h>
 #include <internal/windns.h>
 #include <string.h>
index fcfe4c5..101660b 100644 (file)
@@ -1,6 +1,6 @@
 #include <windows.h>
 /*#include <windns.h>*/
-#include <WinError.h>
+#include <winerror.h>
 #define NTOS_MODE_USER
 #include <ntos.h>
 #include <debug.h>
index 4e773d5..141e9a7 100644 (file)
@@ -7,7 +7,7 @@ TARGET_TYPE = library
 TARGET_NAME = epsapi
 
 # require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -Werror -Wall
+TARGET_CFLAGS += -D__USE_W32API -D_DISABLE_TIDENTS -Werror -Wall
 
 TARGET_OBJECTS = \
  enum/drivers.o \
index 1a05e5e..a361375 100755 (executable)
@@ -57,7 +57,7 @@ VfatFormat (PUNICODE_STRING DriveRoot,
     NULL);
 
   Status = NtOpenFile(&FileHandle,
-    FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
+    FILE_GENERIC_READ | FILE_GENERIC_WRITE,
     &ObjectAttributes,
     &Iosb,
     FILE_SHARE_READ,
index 38e4a77..9e514b6 100644 (file)
@@ -55,7 +55,7 @@ VfatxFormat (PUNICODE_STRING DriveRoot,
     NULL);\r
 \r
   Status = NtOpenFile(&FileHandle,\r
-    FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,\r
+    FILE_GENERIC_READ | FILE_GENERIC_WRITE,\r
     &ObjectAttributes,\r
     &Iosb,\r
     FILE_SHARE_READ,\r
@@ -162,7 +162,7 @@ VfatxFormat (PUNICODE_STRING DriveRoot,
       Callback (DONE, 0, (PVOID)&Context.Success);\r
     }\r
 \r
-  DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);\r
+  DPRINT("VfatxFormat() done. Status 0x%.08x\n", Status);\r
 \r
   return Status;\r
 }\r
index fcf7a82..b1db991 100644 (file)
@@ -49,7 +49,7 @@ CopyMetaFileA@8
 CopyMetaFileW@8
 CreateBitmap@20=NtGdiCreateBitmap@20
 CreateBitmapIndirect@4=NtGdiCreateBitmapIndirect@4
-CreateBrushIndirect@4=NtGdiCreateBrushIndirect@4
+CreateBrushIndirect@4
 CreateColorSpaceA@4
 CreateColorSpaceW@4
 CreateCompatibleBitmap@12=NtGdiCreateCompatibleBitmap@12
@@ -57,8 +57,8 @@ CreateCompatibleDC@4=NtGdiCreateCompatableDC@4
 CreateDCA@16
 CreateDCW@16
 CreateDIBPatternBrush@8
-CreateDIBPatternBrushPt@8=NtGdiCreateDIBPatternBrushPt@8
-CreateDIBSection@24=NtGdiCreateDIBSection@24
+CreateDIBPatternBrushPt@8
+CreateDIBSection@24
 CreateDIBitmap@24=NtGdiCreateDIBitmap@24
 CreateDiscardableBitmap@12=NtGdiCreateDiscardableBitmap@12
 CreateEllipticRgn@16=NtGdiCreateEllipticRgn@16
index b157624..7008492 100644 (file)
                <file>wingl.c</file>\r
        </directory>\r
        <directory name="objects">\r
-               <file>bitblt.c</file>\r
+               <file>bitmap.c</file>\r
+               <file>brush.c</file>\r
                <file>dc.c</file>\r
                <file>font.c</file>\r
                <file>linedda.c</file>\r
                <file>metafile.c</file>\r
                <file>region.c</file>\r
                <file>text.c</file>\r
+               <file>utils.c</file>\r
        </directory>\r
        <file>gdi32.rc</file>\r
 </module>\r
index 141f82c..2965b2d 100644 (file)
@@ -1,4 +1,6 @@
+#include <wine/windef.h>
 #include <windows.h>
+#include <ddraw.h>
 #include <ddentry.h>
 #include <string.h>
 #include <win32k/kapi.h>
@@ -51,7 +53,13 @@ BOOL FASTCALL NewTextMetricW2A(NEWTEXTMETRICA *tma, NEWTEXTMETRICW *tmw);
 BOOL FASTCALL NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw);
 
 /* == GDI HANDLES =========================================================== */
+
 BOOL GdiIsHandleValid(HGDIOBJ hGdiObj);
 BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, PVOID *UserData);
 
+/* == BITMAP UTILITY FUNCTIONS ============================================== */
+
+BOOL STDCALL CalculateColorTableSize(CONST BITMAPINFOHEADER *BitmapInfoHeader, UINT *ColorSpec, UINT *ColorTableSize);
+LPBITMAPINFO STDCALL ConvertBitmapInfo(CONST BITMAPINFO *BitmapInfo, UINT ColorSpec, UINT *BitmapInfoSize, BOOL FollowedByData);
+
 /* EOF */
index 686e958..5d9751c 100644 (file)
@@ -39,7 +39,9 @@ MISC_OBJECTS = \
  misc/win32k.o
 
 OBJECTS_OBJECTS = \
- objects/bitblt.o \
+ objects/bitmap.o \
+ objects/utils.o \
+ objects/brush.o \
  objects/dc.o \
  objects/font.o \
  objects/linedda.o \
index 9689b85..af2b41d 100644 (file)
@@ -84,21 +84,6 @@ CloseMetaFile(
        return 0;
 }
 
-/*
- * @unimplemented
- */
-HBRUSH
-STDCALL
-CreateDIBPatternBrush(
-       HGLOBAL                 a0,
-       UINT                    a1
-       )
-{
-       UNIMPLEMENTED;
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 0;
-}
-
 
 /*
  * @unimplemented
diff --git a/reactos/lib/gdi32/objects/bitblt.c b/reactos/lib/gdi32/objects/bitblt.c
deleted file mode 100644 (file)
index 0ddf1cf..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/gdi32/object/bitblt.c
- * PURPOSE:         
- * PROGRAMMER:
- */
-
-#include "precomp.h"
-
-#include <debug.h>
-
-
-/*
- * @implemented
- */
-BOOL
-STDCALL
-StretchBlt(
-           HDC hdcDest,      // handle to destination DC
-           int nXOriginDest, // x-coord of destination upper-left corner
-           int nYOriginDest, // y-coord of destination upper-left corner
-           int nWidthDest,   // width of destination rectangle
-           int nHeightDest,  // height of destination rectangle
-           HDC hdcSrc,       // handle to source DC
-           int nXOriginSrc,  // x-coord of source upper-left corner
-           int nYOriginSrc,  // y-coord of source upper-left corner
-           int nWidthSrc,    // width of source rectangle
-           int nHeightSrc,   // height of source rectangle
-           DWORD dwRop       // raster operation code
-       )
-{
-  if ((nWidthDest != nWidthSrc) || (nHeightDest != nHeightSrc))
-  {
-    return NtGdiStretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
-                           hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, dwRop);
-  }
-  
-  return NtGdiBitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcSrc,
-                     nXOriginSrc, nYOriginSrc, dwRop);
-}
diff --git a/reactos/lib/gdi32/objects/bitmap.c b/reactos/lib/gdi32/objects/bitmap.c
new file mode 100644 (file)
index 0000000..40d37a8
--- /dev/null
@@ -0,0 +1,59 @@
+#include "precomp.h"\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+HBITMAP STDCALL\r
+CreateDIBSection(\r
+   HDC hDC,\r
+   CONST BITMAPINFO *BitmapInfo,\r
+   UINT Usage,\r
+   VOID **Bits,\r
+   HANDLE hSection,\r
+   DWORD dwOffset)\r
+{\r
+   PBITMAPINFO pConvertedInfo;\r
+   UINT ConvertedInfoSize;\r
+   HBITMAP hBitmap = NULL;\r
+\r
+   pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage,\r
+                                      &ConvertedInfoSize, FALSE);\r
+   if (pConvertedInfo)\r
+   {\r
+      hBitmap = NtGdiCreateDIBSection(hDC, pConvertedInfo, Usage, Bits,\r
+                                      hSection, dwOffset);\r
+      if (BitmapInfo != pConvertedInfo)\r
+         RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);\r
+   }\r
+\r
+   return hBitmap;\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+BOOL STDCALL\r
+StretchBlt(\r
+   HDC hdcDest,      /* handle to destination DC */\r
+   int nXOriginDest, /* x-coord of destination upper-left corner */\r
+   int nYOriginDest, /* y-coord of destination upper-left corner */\r
+   int nWidthDest,   /* width of destination rectangle */\r
+   int nHeightDest,  /* height of destination rectangle */\r
+   HDC hdcSrc,       /* handle to source DC */\r
+   int nXOriginSrc,  /* x-coord of source upper-left corner */\r
+   int nYOriginSrc,  /* y-coord of source upper-left corner */\r
+   int nWidthSrc,    /* width of source rectangle */\r
+   int nHeightSrc,   /* height of source rectangle */\r
+   DWORD dwRop)      /* raster operation code */\r
+       \r
+{\r
+   if ((nWidthDest != nWidthSrc) || (nHeightDest != nHeightSrc))\r
+   {\r
+      return NtGdiStretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest,\r
+                             nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc,\r
+                             nWidthSrc, nHeightSrc, dwRop);\r
+   }\r
+  \r
+   return NtGdiBitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest,\r
+                      nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, dwRop);\r
+}\r
diff --git a/reactos/lib/gdi32/objects/brush.c b/reactos/lib/gdi32/objects/brush.c
new file mode 100644 (file)
index 0000000..6978962
--- /dev/null
@@ -0,0 +1,127 @@
+#include "precomp.h"\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+BOOL\r
+STDCALL\r
+FixBrushOrgEx(\r
+   HDC hDC,\r
+   INT nXOrg,\r
+   INT nYOrg,\r
+   LPPOINT lpPoint)\r
+{\r
+   return FALSE;\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+HBRUSH STDCALL\r
+CreateDIBPatternBrush(\r
+   HGLOBAL hglbDIBPacked,\r
+   UINT fuColorSpec)\r
+{\r
+   PVOID lpPackedDIB;\r
+   HBRUSH hBrush = NULL;\r
+   PBITMAPINFO pConvertedInfo;\r
+   UINT ConvertedInfoSize;\r
+\r
+   lpPackedDIB = GlobalLock(hglbDIBPacked); \r
+   if (lpPackedDIB == NULL)\r
+      return 0;\r
+\r
+   pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,\r
+                                      &ConvertedInfoSize, TRUE);\r
+   if (pConvertedInfo)\r
+   {\r
+      hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,\r
+                                   ConvertedInfoSize, lpPackedDIB);\r
+      if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)\r
+         RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);\r
+   }\r
+   \r
+   GlobalUnlock(hglbDIBPacked);\r
+\r
+   return hBrush;\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+HBRUSH STDCALL\r
+CreateDIBPatternBrushPt(\r
+   CONST VOID *lpPackedDIB,\r
+   UINT fuColorSpec)\r
+{\r
+   HBRUSH hBrush = NULL;\r
+   PBITMAPINFO pConvertedInfo;\r
+   UINT ConvertedInfoSize;\r
+\r
+   if (lpPackedDIB == NULL)\r
+      return 0;\r
+\r
+   pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,\r
+                                      &ConvertedInfoSize, TRUE);\r
+   if (pConvertedInfo)\r
+   {\r
+      hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,\r
+                                   ConvertedInfoSize, lpPackedDIB);\r
+      if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)\r
+         RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);\r
+   }\r
+\r
+   return hBrush;\r
+}\r
+\r
+/*\r
+ * @implemented\r
+ */\r
+HBRUSH STDCALL\r
+CreateBrushIndirect(\r
+   CONST LOGBRUSH *LogBrush)\r
+{\r
+   HBRUSH hBrush;\r
+\r
+   switch (LogBrush->lbStyle)\r
+   {\r
+      case BS_DIBPATTERN8X8:\r
+      case BS_DIBPATTERN:\r
+         hBrush = CreateDIBPatternBrush((HGLOBAL)LogBrush->lbHatch,\r
+                                        LogBrush->lbColor);\r
+         break;\r
+\r
+      case BS_DIBPATTERNPT:\r
+         hBrush = CreateDIBPatternBrushPt((PVOID)LogBrush->lbHatch,\r
+                                          LogBrush->lbColor);\r
+         break;\r
+\r
+      case BS_PATTERN:\r
+      case BS_PATTERN8X8:\r
+         hBrush = NtGdiCreatePatternBrush((HBITMAP)LogBrush->lbHatch);\r
+         break;\r
+\r
+      case BS_SOLID:\r
+         hBrush = NtGdiCreateSolidBrush(LogBrush->lbColor);\r
+         break;\r
+\r
+      case BS_HATCHED:\r
+         hBrush = NtGdiCreateHatchBrush(LogBrush->lbHatch, LogBrush->lbColor);\r
+         break;\r
+         \r
+      case BS_NULL:\r
+         hBrush = NtGdiGetStockObject(NULL_BRUSH);\r
+         break;\r
+\r
+      default:\r
+         SetLastError(ERROR_INVALID_PARAMETER);\r
+         hBrush = NULL;\r
+         break;\r
+   }\r
+\r
+   return hBrush;\r
+}\r
+\r
index 476aa3a..c3f9cba 100644 (file)
@@ -287,26 +287,6 @@ GetObjectW(HGDIOBJ Handle, int Size, LPVOID Buffer)
 }
 
 
-/*
- * @implemented
- */
-BOOL
-STDCALL
-FixBrushOrgEx(
-       HDC     hdc,
-       int     nXOrg,
-       int     nYOrg,
-       LPPOINT lppt
-       )
-{
-  #if 0
-  /* FIXME - Check if we're emulating win95, if so, forward to SetBrushOrgEx() */
-  return SetBrushOrgEx(hdc, nXOrg, nYOrg, lppt);
-  #endif
-  
-  return FALSE;
-}
-
 /*
  * @implemented
  */
diff --git a/reactos/lib/gdi32/objects/utils.c b/reactos/lib/gdi32/objects/utils.c
new file mode 100644 (file)
index 0000000..dadf1da
--- /dev/null
@@ -0,0 +1,333 @@
+#include "precomp.h"\r
+\r
+/**\r
+ * @name CalculateColorTableSize\r
+ *\r
+ * Internal routine to calculate the number of color table entries.\r
+ *\r
+ * @param BitmapInfoHeader\r
+ *        Input bitmap information header, can be any version of\r
+ *        BITMAPINFOHEADER or BITMAPCOREHEADER.\r
+ *\r
+ * @param ColorSpec\r
+ *        Pointer to variable which specifiing the color mode (DIB_RGB_COLORS\r
+ *        or DIB_RGB_COLORS). On successful return this value is normalized\r
+ *        according to the bitmap info.\r
+ *\r
+ * @param ColorTableSize\r
+ *        On successful return this variable is filled with number of\r
+ *        entries in color table for the image with specified parameters.\r
+ *\r
+ * @return\r
+ *    TRUE if the input values together form a valid image, FALSE otherwise.\r
+ */\r
+\r
+BOOL STDCALL\r
+CalculateColorTableSize(\r
+   CONST BITMAPINFOHEADER *BitmapInfoHeader,\r
+   UINT *ColorSpec,\r
+   UINT *ColorTableSize)\r
+{\r
+   WORD BitCount;\r
+   DWORD ClrUsed;\r
+   DWORD Compression;\r
+\r
+   /*\r
+    * At first get some basic parameters from the passed BitmapInfoHeader\r
+    * structure. It can have one of the following formats: \r
+    * - BITMAPCOREHEADER (the oldest one with totally different layout\r
+    *                     from the others)\r
+    * - BITMAPINFOHEADER (the standard and most common header)\r
+    * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)\r
+    * - BITMAPV5HEADER (extension of BITMAPV4HEADER)\r
+    */\r
+\r
+   if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))\r
+   {\r
+      BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;\r
+      ClrUsed = 0;\r
+      Compression = BI_RGB;\r
+   }\r
+   else\r
+   {\r
+      BitCount = BitmapInfoHeader->biBitCount;\r
+      ClrUsed = BitmapInfoHeader->biClrUsed;\r
+      Compression = BitmapInfoHeader->biCompression;\r
+   }\r
+\r
+   switch (Compression)\r
+   {\r
+      case BI_BITFIELDS:\r
+         if (*ColorSpec == DIB_PAL_COLORS)\r
+            *ColorSpec = DIB_RGB_COLORS;\r
+\r
+         if (BitCount != 16 && BitCount != 32)\r
+            return FALSE;\r
+\r
+         /*\r
+          * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in\r
+          * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).\r
+          * For BITMAPINFOHEADER the color masks are stored in the palette.\r
+          */\r
+\r
+         if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))\r
+            *ColorTableSize = 0;\r
+         else\r
+            *ColorTableSize = 3;\r
+         \r
+         return TRUE;\r
+\r
+      case BI_RGB:\r
+         switch (BitCount)\r
+         {\r
+            case 1:\r
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;\r
+               return TRUE;\r
+\r
+            case 4:\r
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;\r
+               return TRUE;\r
+\r
+            case 8:\r
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;\r
+               return TRUE;\r
+\r
+            default:\r
+               if (*ColorSpec == DIB_PAL_COLORS)\r
+                  *ColorSpec = DIB_RGB_COLORS;\r
+               if (BitCount != 16 && BitCount != 24 && BitCount != 32)\r
+                  return FALSE;\r
+               *ColorTableSize = ClrUsed;\r
+               return TRUE;\r
+         }\r
+         \r
+      case BI_RLE4:\r
+         if (BitCount == 4)\r
+         {\r
+            *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;\r
+            return TRUE;\r
+         }\r
+         return FALSE;\r
+\r
+      case BI_RLE8:\r
+         if (BitCount == 8)\r
+         {\r
+            *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;\r
+            return TRUE;\r
+         }\r
+         return FALSE;\r
+\r
+      case BI_JPEG:\r
+      case BI_PNG:\r
+         *ColorTableSize = ClrUsed;\r
+         return TRUE;\r
+\r
+      default:\r
+         return FALSE;      \r
+   }\r
+}\r
+\r
+/**\r
+ * @name ConvertBitmapInfo\r
+ *\r
+ * Internal routine to convert a user-passed BITMAPINFO structure into\r
+ * unified BITMAPINFO structure.\r
+ *\r
+ * @param BitmapInfo\r
+ *        Input bitmap info, can be any version of BITMAPINFO or\r
+ *        BITMAPCOREINFO.\r
+ * @param ColorSpec\r
+ *        Specifies whether the bmiColors member of the BITMAPINFO structure\r
+ *        contains a valid color table and, if so, whether the entries in\r
+ *        this color table contain explicit red, green, blue (DIB_RGB_COLORS)\r
+ *        values or palette indexes (DIB_PAL_COLORS).\r
+ * @param BitmapInfoSize\r
+ *        On successful return contains the size of the returned BITMAPINFO\r
+ *        structure. If FollowedByData is TRUE the size includes the number\r
+ *        of bytes occupied by the image data.\r
+ * @param FollowedByData\r
+ *        Specifies if the BITMAPINFO header is immediately followed\r
+ *        by the actual bitmap data (eg. as passed to CreateDIBPatternBrush).\r
+ *\r
+ * @return\r
+ *    Either the original BitmapInfo or newly allocated structure is\r
+ *    returned. For the later case the caller is responsible for freeing the\r
+ *    memory using RtlFreeHeap with the current process heap.\r
+ *\r
+ * @example\r
+ *    PBITMAPINFO NewBitmapInfo;\r
+ *    UINT NewBitmapInfoSize;\r
+ *\r
+ *    NewBitmapInfo = ConvertBitmapInfo(OldBitmapInfo, DIB_RGB_COLORS,\r
+ *                                      &NewBitmapInfoSize, FALSE);\r
+ *    if (NewBitmapInfo)\r
+ *    {\r
+ *       <do something with the bitmap info>\r
+ *       if (NewBitmapInfo != OldBitmapInfo)\r
+ *          RtlFreeHeap(RtlGetProcessHeap(), 0, NewBitmapInfo);\r
+ *    }\r
+ */\r
+\r
+LPBITMAPINFO STDCALL\r
+ConvertBitmapInfo(\r
+   CONST BITMAPINFO *BitmapInfo,\r
+   UINT ColorSpec,\r
+   UINT *BitmapInfoSize,\r
+   BOOL FollowedByData)\r
+{\r
+   LPBITMAPINFO NewBitmapInfo = (LPBITMAPINFO)BitmapInfo;\r
+   LPBITMAPCOREINFO CoreBitmapInfo = (LPBITMAPCOREINFO)BitmapInfo;\r
+   DWORD Size = 0;\r
+   ULONG DataSize = 0;\r
+   UINT PaletteEntryCount = 0;\r
+\r
+   /*\r
+    * At first check if the passed BitmapInfo structure has valid size. It\r
+    * can have one of these headers: BITMAPCOREHEADER, BITMAPINFOHEADER,\r
+    * BITMAPV4HEADER or BITMAPV5HEADER (see CalculateColorTableSize for\r
+    * description).\r
+    */\r
+\r
+   if (BitmapInfo->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&\r
+       (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER) ||\r
+        BitmapInfo->bmiHeader.biSize > sizeof(BITMAPV5HEADER)))\r
+   {\r
+      return NULL;\r
+   }\r
+\r
+   /*\r
+    * Now calculate the color table size. Also if the bitmap info contains\r
+    * invalid color information it's rejected here.\r
+    */\r
+\r
+   if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, &ColorSpec,\r
+                                &PaletteEntryCount))\r
+   {\r
+      return NULL;\r
+   }\r
+\r
+   /*\r
+    * Calculate the size of image data if applicable. We must be careful\r
+    * to do proper aligning on line ends.\r
+    */\r
+\r
+   if (FollowedByData)\r
+   {\r
+      if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))\r
+      {\r
+         DataSize =\r
+            CoreBitmapInfo->bmciHeader.bcHeight *\r
+            CoreBitmapInfo->bmciHeader.bcWidth *               \r
+            CoreBitmapInfo->bmciHeader.bcBitCount;\r
+         DataSize = ((DataSize + 31) & ~31) / 8;\r
+         DataSize *= CoreBitmapInfo->bmciHeader.bcPlanes;\r
+      }\r
+      else\r
+      {\r
+         if (BitmapInfo->bmiHeader.biCompression == BI_RGB ||\r
+             BitmapInfo->bmiHeader.biCompression == BI_BITFIELDS)\r
+         {\r
+            DataSize =\r
+               abs(BitmapInfo->bmiHeader.biHeight) *\r
+               BitmapInfo->bmiHeader.biWidth *\r
+               BitmapInfo->bmiHeader.biBitCount;\r
+            DataSize = ((DataSize + 31) & ~31) / 8;\r
+            DataSize *= BitmapInfo->bmiHeader.biPlanes;\r
+         }\r
+         else\r
+         {\r
+            DataSize = BitmapInfo->bmiHeader.biSizeImage;\r
+         }\r
+      }\r
+   }\r
+\r
+   /*\r
+    * If BitmapInfo was originally BITMAPCOREINFO then we need to convert\r
+    * it to the standard BITMAPINFO layout.\r
+    */\r
+\r
+   if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))\r
+   {\r
+      Size = sizeof(BITMAPINFOHEADER);\r
+      if (ColorSpec == DIB_RGB_COLORS)\r
+         Size += PaletteEntryCount * sizeof(RGBQUAD);\r
+      else\r
+         Size += PaletteEntryCount * sizeof(USHORT);\r
+      Size += DataSize;\r
+\r
+      NewBitmapInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);\r
+      if (NewBitmapInfo == NULL)\r
+      {\r
+         return NULL;\r
+      }\r
+\r
+      NewBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\r
+      NewBitmapInfo->bmiHeader.biWidth = CoreBitmapInfo->bmciHeader.bcWidth;\r
+      NewBitmapInfo->bmiHeader.biHeight = CoreBitmapInfo->bmciHeader.bcHeight;\r
+      NewBitmapInfo->bmiHeader.biPlanes = CoreBitmapInfo->bmciHeader.bcPlanes;\r
+      NewBitmapInfo->bmiHeader.biBitCount = CoreBitmapInfo->bmciHeader.bcBitCount;\r
+      NewBitmapInfo->bmiHeader.biCompression = BI_RGB;\r
+      NewBitmapInfo->bmiHeader.biSizeImage = 0;\r
+      NewBitmapInfo->bmiHeader.biXPelsPerMeter = 0;\r
+      NewBitmapInfo->bmiHeader.biYPelsPerMeter = 0;\r
+      NewBitmapInfo->bmiHeader.biClrUsed = 0;\r
+      NewBitmapInfo->bmiHeader.biClrImportant = 0;\r
+\r
+      if (PaletteEntryCount != 0)\r
+      {\r
+         if (ColorSpec == DIB_RGB_COLORS)\r
+         {\r
+            ULONG Index;\r
+\r
+            for (Index = 0; Index < PaletteEntryCount; Index++)\r
+            {\r
+               NewBitmapInfo->bmiColors[Index].rgbRed =\r
+                  CoreBitmapInfo->bmciColors[Index].rgbtRed;\r
+               NewBitmapInfo->bmiColors[Index].rgbGreen =\r
+                  CoreBitmapInfo->bmciColors[Index].rgbtGreen;\r
+               NewBitmapInfo->bmiColors[Index].rgbBlue =\r
+                  CoreBitmapInfo->bmciColors[Index].rgbtBlue;\r
+               NewBitmapInfo->bmiColors[Index].rgbReserved = 0;\r
+            }\r
+         }\r
+         else\r
+         {\r
+            RtlCopyMemory(NewBitmapInfo->bmiColors,\r
+                          CoreBitmapInfo->bmciColors,\r
+                          PaletteEntryCount * sizeof(USHORT));\r
+         }\r
+      }\r
+\r
+      if (FollowedByData)\r
+      {\r
+         ULONG_PTR NewDataPtr, OldDataPtr;\r
+\r
+         if (ColorSpec == DIB_RGB_COLORS)\r
+         {\r
+            NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors +\r
+                         PaletteEntryCount);\r
+            OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors +\r
+                         PaletteEntryCount);\r
+         }\r
+         else\r
+         {\r
+            NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors) +\r
+                         PaletteEntryCount * sizeof(USHORT);\r
+            OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors) +\r
+                         PaletteEntryCount * sizeof(USHORT);\r
+         }\r
+\r
+         RtlCopyMemory((PVOID)NewDataPtr, (PVOID)OldDataPtr, DataSize);\r
+      }\r
+   }\r
+\r
+   Size = NewBitmapInfo->bmiHeader.biSize;\r
+   if (ColorSpec == DIB_RGB_COLORS)\r
+      Size += PaletteEntryCount * sizeof(RGBQUAD);\r
+   else\r
+      Size += PaletteEntryCount * sizeof(USHORT);\r
+   Size += DataSize;\r
+   *BitmapInfoSize = Size;\r
+\r
+   return NewBitmapInfo;\r
+}\r
index 7486b94..6bd5c84 100644 (file)
@@ -754,6 +754,8 @@ DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
                     sizeof(info.if_info) );
         }
         
+        DPRINT1("entry->bDescr = %s\n", entry->bDescr);
+
         closeTcpFile( tcpFile );
     }
 
@@ -795,3 +797,72 @@ char *toIPAddressString(unsigned int addr, char string[16])
   }
   return string;
 }
+
+NTSTATUS addIPAddress( IPAddr Address, IPMask Mask, DWORD IfIndex, 
+                       PULONG NteContext, PULONG NteInstance ) 
+{
+  HANDLE tcpFile;
+  NTSTATUS status = openTcpFile( &tcpFile );
+  IP_SET_DATA Data;
+  IO_STATUS_BLOCK Iosb;
+
+  DPRINT("Called.\n");
+  
+  if( !NT_SUCCESS(status) ) return status;
+
+  Data.NteContext = IfIndex;
+  Data.NewAddress = Address;
+  Data.NewNetmask = Mask;
+
+  status = NtDeviceIoControlFile( tcpFile, 
+                                  NULL,
+                                  NULL,
+                                  NULL, 
+                                  &Iosb,
+                                  IOCTL_SET_IP_ADDRESS,
+                                  &Data,
+                                  sizeof(Data),
+                                  &Data,
+                                  sizeof(Data) );
+
+  closeTcpFile( tcpFile );
+  
+  if( NT_SUCCESS(status) ) {
+      *NteContext = Iosb.Information;
+      *NteInstance = Data.NewAddress;
+  }
+
+  switch( status ) {
+  case STATUS_SUCCESS: return ERROR_SUCCESS;
+  case STATUS_DEVICE_DOES_NOT_EXIST: return ERROR_DEV_NOT_EXIST;
+  default: return status;
+  }
+}
+
+NTSTATUS deleteIpAddress( ULONG NteContext ) 
+{
+  HANDLE tcpFile;
+  NTSTATUS status = openTcpFile( &tcpFile );
+  USHORT TheNteContext = NteContext;
+  IO_STATUS_BLOCK Iosb;
+
+  DPRINT("Called.\n");
+  
+  if( !NT_SUCCESS(status) ) return status;
+
+  status = NtDeviceIoControlFile( tcpFile, 
+                                  NULL,
+                                  NULL,
+                                  NULL, 
+                                  &Iosb,
+                                  IOCTL_DELETE_IP_ADDRESS,
+                                  &NteContext,
+                                  sizeof(USHORT),
+                                  NULL,
+                                  0 );
+
+  closeTcpFile( tcpFile );
+
+  if( NT_SUCCESS(status) ) return ERROR_SUCCESS;
+  else return ERROR_GEN_FAILURE;
+}
index 7cb9295..3baddf6 100644 (file)
@@ -82,11 +82,9 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  *  DWORD
  *
  */
-DWORD WINAPI AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance)
+DWORD WINAPI AddIPAddress(IPAddr Address, IPMask Netmask, DWORD IfIndex, PULONG NteContext, PULONG NteInstance)
 {
-  FIXME(":stub\n");
-  /* marking Win2K+ functions not supported */
-  return ERROR_NOT_SUPPORTED;
+    return addIPAddress( Address, Netmask, IfIndex, NteContext, NteInstance );
 }
 
 
@@ -404,9 +402,7 @@ DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex)
 DWORD WINAPI DeleteIPAddress(ULONG NTEContext)
 {
   TRACE("NTEContext %ld\n", NTEContext);
-  FIXME(":stub\n");
-  /* marking Win2K+ functions not supported */
-  return ERROR_NOT_SUPPORTED;
+  return deleteIpAddress( NTEContext );
 }
 
 
index 92b9be8..1d52a9f 100644 (file)
@@ -82,6 +82,12 @@ typedef struct _IFInfo {
     IPAddrEntry        ip_addr;
 } IFInfo;
 
+typedef struct _IP_SET_DATA {
+    ULONG NteContext;
+    ULONG NewAddress;
+    ULONG NewNetmask;
+} IP_SET_DATA, *PIP_SET_DATA;
+
 typedef enum _IPHLPAddrType {
     IPAAddr, IPABcast, IPAMask, IFMtu, IFStatus
 } IPHLPAddrType;
index 517b40a..3394047 100644 (file)
@@ -456,7 +456,8 @@ VOID WINAPI OutputDebugStringA(LPCSTR _OutputString)
    if(hDBMonDataReady) CloseHandle(hDBMonDataReady);
 
    /* leave the critical section */
-   ReleaseMutex(hDBMonMutex);
+   if(hDBMonDataReady != NULL)
+    ReleaseMutex(hDBMonMutex);
 #if 0
   }
  }
index a02b159..e7364cc 100644 (file)
@@ -83,13 +83,19 @@ SetUnhandledExceptionFilter(
  * The address can point to anywhere within the module.
  */
 static const char*
-_module_name_from_addr(const void* addr, char* psz, size_t nChars)
+_module_name_from_addr(const void* addr, void **module_start_addr, 
+                       char* psz, size_t nChars)
 {
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery(addr, &mbi, sizeof(mbi)) != sizeof(mbi) ||
        !GetModuleFileNameA((HMODULE)mbi.AllocationBase, psz, nChars))
    {
       psz[0] = '\0';
+      *module_start_addr = 0;
+   }
+   else
+   {
+      *module_start_addr = (void *)mbi.AllocationBase;
    }
    return psz;
 }
@@ -152,26 +158,30 @@ UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
    {
 #ifdef _X86_
       PULONG Frame;
+      PVOID StartAddr;
       CHAR szMod[128] = "";
 #endif
 
       /* Print a stack trace. */
-      DPRINT1("Unhandled exception\n");
-      DPRINT1("Address:\n");
-      DPRINT1("   %8x   %s\n",
+      DbgPrint("Unhandled exception\n");
+      DbgPrint("Address:\n");
+      DbgPrint("   %8x   %s\n",
          ExceptionInfo->ExceptionRecord->ExceptionAddress,
-         _module_name_from_addr(ExceptionInfo->ExceptionRecord->ExceptionAddress, szMod, sizeof(szMod)));
+         _module_name_from_addr(ExceptionInfo->ExceptionRecord->ExceptionAddress, &StartAddr, szMod, sizeof(szMod)));
       _dump_context ( ExceptionInfo->ContextRecord );
 #ifdef _X86_
-      DPRINT1("Frames:\n");
+      DbgPrint("Frames:\n");
       Frame = (PULONG)ExceptionInfo->ContextRecord->Ebp;
       while (Frame[1] != 0 && Frame[1] != 0xdeadbeef)
       {
          if (IsBadReadPtr((PVOID)Frame[1], 4)) {
-           DPRINT1("   %8x   %s\n", Frame[1], "<invalid address>");
+           DbgPrint("   %8x%9s   %s\n", Frame[1], "<invalid address>"," ");
          } else {
-           _module_name_from_addr((const void*)Frame[1], szMod, sizeof(szMod));
-           DPRINT1("   %8x   %s\n", Frame[1], szMod);
+           _module_name_from_addr((const void*)Frame[1], &StartAddr, 
+                                  szMod, sizeof(szMod));
+           DbgPrint("   %8x+%-8x   %s\n", 
+                   (PVOID)StartAddr, 
+                   (ULONG_PTR)Frame[1] - (ULONG_PTR)StartAddr, szMod);
          }
          if (IsBadReadPtr((PVOID)Frame[0], sizeof(*Frame) * 2)) {
            break;
index 31d8ddc..48a5bde 100644 (file)
@@ -304,10 +304,7 @@ GetBinaryTypeA (
     LPDWORD lpBinaryType
     )
 {
-  ANSI_STRING FileNameA;
-  UNICODE_STRING FileName;
-  NTSTATUS Status;
-  BOOL Ret;
+  PWCHAR ApplicationNameW;
   
   if(!lpApplicationName || !lpBinaryType)
   {
@@ -315,22 +312,10 @@ GetBinaryTypeA (
     return FALSE;
   }
   
-  RtlInitAnsiString(&FileNameA, (LPSTR)lpApplicationName);
+  if (!(ApplicationNameW = FilenameA2W(lpApplicationName, FALSE)))
+     return FALSE;
   
-  if(bIsFileApiAnsi)
-    Status = RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
-  else
-    Status = RtlOemStringToUnicodeString(&FileName, &FileNameA, TRUE);
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastErrorByStatus(Status);
-    return FALSE;
-  }
-  
-  Ret = GetBinaryTypeW(FileName.Buffer, lpBinaryType);
-  
-  RtlFreeUnicodeString(&FileName);
-  return Ret;
+  return GetBinaryTypeW(ApplicationNameW, lpBinaryType);
 }
 
 /* EOF */
index 9512418..2d9b450 100644 (file)
@@ -42,34 +42,14 @@ FindFirstChangeNotificationA (
        DWORD   dwNotifyFilter
        )
 {
-       UNICODE_STRING PathNameU;
-       ANSI_STRING PathName;
-       HANDLE hNotify;
+       PWCHAR PathNameW;
 
-       RtlInitAnsiString (&PathName,
-                          (LPSTR)lpPathName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-   {
-               RtlAnsiStringToUnicodeString (&PathNameU,
-                                             &PathName,
-                                             TRUE);
-   }
-       else
-   {
-               RtlOemStringToUnicodeString (&PathNameU,
-                                            &PathName,
-                                            TRUE);
-   }
+   if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+      return INVALID_HANDLE_VALUE;
 
-   hNotify = FindFirstChangeNotificationW (PathNameU.Buffer,
+   return FindFirstChangeNotificationW (PathNameW ,
                                                bWatchSubtree,
                                                dwNotifyFilter);
-
-   RtlFreeUnicodeString(&PathNameU);
-
-   return hNotify;
 }
 
 
@@ -90,13 +70,6 @@ FindFirstChangeNotificationW (
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE hDir;
 
-   /*
-   RtlDosPathNameToNtPathName takes a fully qualified file name "C:\Projects\LoadLibrary\Debug\TestDll.dll" 
-   and returns something like "\??\C:\Projects\LoadLibrary\Debug\TestDll.dll."
-   If the file name cannot be interpreted, then the routine returns STATUS_OBJECT_PATH_SYNTAX_BAD and 
-   ends execution.
-   */
-
    if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
                                           &NtPathU,
                                           NULL,
@@ -106,9 +79,11 @@ FindFirstChangeNotificationW (
       return INVALID_HANDLE_VALUE;
    }
 
+
+
    InitializeObjectAttributes (&ObjectAttributes,
                                &NtPathU,
-                               0,
+                               OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL);
 
@@ -119,6 +94,23 @@ FindFirstChangeNotificationW (
                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                         FILE_DIRECTORY_FILE);
 
+   /*
+   FIXME: I think we should use FILE_OPEN_FOR_BACKUP_INTENT. See M$ Q188321
+   -Gunnar
+   */
+
+
+
+   /* FIXME: We free the string alloced by RtlDosPathNameToNtPathName_U, but what 
+    * about the special case where the user can pass a \\?\ path? We must not free
+    * the users buffer!. But should we even call RtlDosPathNameToNtPathName_U in that
+    * case??? -Gunnar
+    */
+
+   RtlFreeUnicodeString( &NtPathU);
+   
+   
+
    if (!NT_SUCCESS(Status))
    {
       SetLastErrorByStatus(Status);
@@ -157,15 +149,16 @@ FindNextChangeNotification (
    NTSTATUS Status;
 
    Status = NtNotifyChangeDirectoryFile(hChangeHandle,
-                                        NULL,
-                                        NULL,
-                                        NULL,
-                                        &IoStatus,
-                                        NULL,//Buffer,
-                                        0,//BufferLength,
-                                        FILE_NOTIFY_CHANGE_SECURITY,//meaningless for subsequent calls, but must contain a valid flag(s)
-                                        0//meaningless for subsequent calls 
-                                        );
+      NULL,
+      NULL,
+      NULL,
+      &IoStatus,
+      NULL,//Buffer,
+      0,//BufferLength,
+      FILE_NOTIFY_CHANGE_SECURITY,//meaningless/ignored for subsequent calls, but must contain a valid flag
+      0 //meaningless/ignored for subsequent calls 
+      );
+      
    if (!NT_SUCCESS(Status))
    {
       SetLastErrorByStatus(Status);
@@ -175,4 +168,62 @@ FindNextChangeNotification (
    return TRUE;
 }
 
+
+extern VOID STDCALL
+(ApcRoutine)(PVOID ApcContext, 
+      struct _IO_STATUS_BLOCK* IoStatusBlock, 
+      ULONG Reserved);
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+ReadDirectoryChangesW(
+    HANDLE hDirectory,
+    LPVOID lpBuffer OPTIONAL,
+    DWORD nBufferLength,
+    BOOL bWatchSubtree,
+    DWORD dwNotifyFilter,
+    LPDWORD lpBytesReturned, /* undefined for asych. operations */
+    LPOVERLAPPED lpOverlapped OPTIONAL,
+    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */
+    )
+{
+   NTSTATUS Status;
+   IO_STATUS_BLOCK IoStatus;
+  
+   if (lpOverlapped )
+      lpOverlapped->Internal = STATUS_PENDING;
+  
+   Status = NtNotifyChangeDirectoryFile(
+      hDirectory,
+      lpOverlapped ? lpOverlapped->hEvent : NULL,
+      lpCompletionRoutine ? ApcRoutine : NULL, /* ApcRoutine OPTIONAL???? */
+      lpCompletionRoutine, /* ApcContext */
+      lpOverlapped ? (PIO_STATUS_BLOCK)lpOverlapped : &IoStatus,
+      lpBuffer,
+      nBufferLength,
+      dwNotifyFilter,
+      bWatchSubtree
+      );   
+  
+   if (!NT_SUCCESS(Status))
+   {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+   }
+
+   
+   /* NOTE: lpBytesReturned is undefined for asynch. operations */
+   *lpBytesReturned = IoStatus.Information;
+   
+   return TRUE;
+}
+
+
+
+
+
 /* EOF */
index 6ce97ce..f998feb 100644 (file)
@@ -321,40 +321,18 @@ CopyFileExA (
        DWORD                   dwCopyFlags
        )
 {
-       UNICODE_STRING ExistingFileNameU;
-       UNICODE_STRING NewFileNameU;
-       ANSI_STRING ExistingFileName;
-       ANSI_STRING NewFileName;
+       PWCHAR ExistingFileNameW;
+   PWCHAR NewFileNameW;
        BOOL Result;
 
-       RtlInitAnsiString (&ExistingFileName,
-                          (LPSTR)lpExistingFileName);
-
-       RtlInitAnsiString (&NewFileName,
-                          (LPSTR)lpNewFileName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-       {
-               RtlAnsiStringToUnicodeString (&ExistingFileNameU,
-                                             &ExistingFileName,
-                                             TRUE);
-               RtlAnsiStringToUnicodeString (&NewFileNameU,
-                                             &NewFileName,
-                                             TRUE);
-       }
-       else
-       {
-               RtlOemStringToUnicodeString (&ExistingFileNameU,
-                                            &ExistingFileName,
-                                            TRUE);
-               RtlOemStringToUnicodeString (&NewFileNameU,
-                                            &NewFileName,
-                                            TRUE);
-       }
-
-       Result = CopyFileExW (ExistingFileNameU.Buffer,
-                             NewFileNameU.Buffer,
+   if (!(ExistingFileNameW = FilenameA2W(lpExistingFileName, FALSE)))
+      return FALSE;
+
+   if (!(NewFileNameW = FilenameA2W(lpNewFileName, TRUE)))
+      return FALSE;
+
+   Result = CopyFileExW (ExistingFileNameW ,
+                         NewFileNameW ,
                              lpProgressRoutine,
                              lpData,
                              pbCancel,
@@ -362,10 +340,7 @@ CopyFileExA (
 
        RtlFreeHeap (RtlGetProcessHeap (),
                     0,
-                    ExistingFileNameU.Buffer);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    NewFileNameU.Buffer);
+                NewFileNameW);
 
        return Result;
 }
index 811c7ae..67ccd9b 100644 (file)
@@ -34,26 +34,15 @@ HANDLE STDCALL CreateFileA (LPCSTR                  lpFileName,
                            DWORD                       dwFlagsAndAttributes,
                            HANDLE                      hTemplateFile)
 {
-   UNICODE_STRING FileNameU;
-   ANSI_STRING FileName;
+   PWCHAR FileNameW;
    HANDLE FileHandle;
    
    DPRINT("CreateFileA(lpFileName %s)\n",lpFileName);
    
-   RtlInitAnsiString (&FileName,
-                     (LPSTR)lpFileName);
-   
-   /* convert ansi (or oem) string to unicode */
-   if (bIsFileApiAnsi)
-     RtlAnsiStringToUnicodeString (&FileNameU,
-                                  &FileName,
-                                  TRUE);
-   else
-     RtlOemStringToUnicodeString (&FileNameU,
-                                 &FileName,
-                                 TRUE);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_HANDLE_VALUE;
 
-   FileHandle = CreateFileW (FileNameU.Buffer,
+   FileHandle = CreateFileW (FileNameW,
                             dwDesiredAccess,
                             dwShareMode,
                             lpSecurityAttributes,
@@ -61,10 +50,6 @@ HANDLE STDCALL CreateFileA (LPCSTR                   lpFileName,
                             dwFlagsAndAttributes,
                             hTemplateFile);
    
-   RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               FileNameU.Buffer);
-   
    return FileHandle;
 }
 
@@ -85,20 +70,14 @@ HANDLE STDCALL CreateFileW (LPCWSTR                 lpFileName,
    UNICODE_STRING NtPathU;
    HANDLE FileHandle;
    NTSTATUS Status;
-   ULONG Flags = 0;
+   ULONG FileAttributes, Flags = 0;
    CSRSS_API_REQUEST Request;
    CSRSS_API_REPLY Reply;
+   PVOID EaBuffer = NULL;
+   ULONG EaLength = 0;
 
    DPRINT("CreateFileW(lpFileName %S)\n",lpFileName);
 
-   if(hTemplateFile != NULL && hTemplateFile != INVALID_HANDLE_VALUE)
-   {
-    /* FIXME */
-    DPRINT1("Template file feature not supported yet\n");
-    SetLastError(ERROR_NOT_SUPPORTED);
-    return INVALID_HANDLE_VALUE;
-   }
-
    /* validate & translate the creation disposition */
    switch (dwCreationDisposition)
      {
@@ -143,57 +122,56 @@ HANDLE STDCALL CreateFileW (LPCWSTR                       lpFileName,
   /* validate & translate the flags */
 
    /* translate the flags that need no validation */
-  if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)){
-    /* yes, nonalert is correct! apc's are not delivered
-    while waiting for file io to complete */
-    Flags |= FILE_SYNCHRONOUS_IO_NONALERT;
-  }
+   if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
+   {
+      /* yes, nonalert is correct! apc's are not delivered
+      while waiting for file io to complete */
+      Flags |= FILE_SYNCHRONOUS_IO_NONALERT;
+   }
    
    if(dwFlagsAndAttributes & FILE_FLAG_WRITE_THROUGH)
-    Flags |= FILE_WRITE_THROUGH;
+      Flags |= FILE_WRITE_THROUGH;
 
    if(dwFlagsAndAttributes & FILE_FLAG_NO_BUFFERING)
-    Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
+      Flags |= FILE_NO_INTERMEDIATE_BUFFERING;
 
    if(dwFlagsAndAttributes & FILE_FLAG_RANDOM_ACCESS)
-    Flags |= FILE_RANDOM_ACCESS;
+      Flags |= FILE_RANDOM_ACCESS;
    
    if(dwFlagsAndAttributes & FILE_FLAG_SEQUENTIAL_SCAN)
-    Flags |= FILE_SEQUENTIAL_ONLY;
+      Flags |= FILE_SEQUENTIAL_ONLY;
    
    if(dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE)
-    Flags |= FILE_DELETE_ON_CLOSE;
+      Flags |= FILE_DELETE_ON_CLOSE;
    
    if(dwFlagsAndAttributes & FILE_FLAG_BACKUP_SEMANTICS)
    {
-    if(dwDesiredAccess & GENERIC_ALL)
-      Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
-    else
-    {
-      if(dwDesiredAccess & GENERIC_READ)
-        Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
-      
-      if(dwDesiredAccess & GENERIC_WRITE)
-        Flags |= FILE_OPEN_FOR_RECOVERY;
-    }
+      if(dwDesiredAccess & GENERIC_ALL)
+         Flags |= FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
+      else
+      {
+         if(dwDesiredAccess & GENERIC_READ)
+            Flags |= FILE_OPEN_FOR_BACKUP_INTENT;
+
+         if(dwDesiredAccess & GENERIC_WRITE)
+            Flags |= FILE_OPEN_FOR_RECOVERY;
+      }
    }
    else
-    Flags |= FILE_NON_DIRECTORY_FILE;
-    
-    
-  /* handle may allways be waited on and querying attributes are allways allowed */
-  dwDesiredAccess |= SYNCHRONIZE|FILE_READ_ATTRIBUTES; 
+      Flags |= FILE_NON_DIRECTORY_FILE;
 
-   /* FILE_FLAG_POSIX_SEMANTICS is handled later */
-
-#if 0
-   /* FIXME: Win32 constants to be defined */
    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_REPARSE_POINT)
-    Flags |= FILE_OPEN_REPARSE_POINT;
-   
+      Flags |= FILE_OPEN_REPARSE_POINT;
+
    if(dwFlagsAndAttributes & FILE_FLAG_OPEN_NO_RECALL)
-    Flags |= FILE_OPEN_NO_RECALL;
-#endif
+      Flags |= FILE_OPEN_NO_RECALL;
+
+   FileAttributes = (dwFlagsAndAttributes & (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY));
+    
+   /* handle may allways be waited on and querying attributes are allways allowed */
+   dwDesiredAccess |= SYNCHRONIZE | FILE_READ_ATTRIBUTES;
+
+   /* FILE_FLAG_POSIX_SEMANTICS is handled later */
 
    /* check for console output */
    if (0 == _wcsicmp(L"CONOUT$", lpFileName))
@@ -234,15 +212,82 @@ HANDLE STDCALL CreateFileW (LPCWSTR                       lpFileName,
          return Reply.Data.GetInputHandleReply.InputHandle;
       }
    }
+   
+   if (hTemplateFile != NULL)
+   {
+      FILE_EA_INFORMATION EaInformation;
+
+      for (;;)
+      {
+         /* try to get the size of the extended attributes, if we fail just continue
+            creating the file without copying the attributes! */
+         Status = NtQueryInformationFile(hTemplateFile,
+                                         &IoStatusBlock,
+                                         &EaInformation,
+                                         sizeof(FILE_EA_INFORMATION),
+                                         FileEaInformation);
+         if (NT_SUCCESS(Status) && (EaInformation.EaSize != 0))
+         {
+            /* there's extended attributes to read, let's give it a try */
+            EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                       0,
+                                       EaInformation.EaSize);
+            if (EaBuffer == NULL)
+            {
+               /* the template file handle is valid and has extended attributes,
+                  however we seem to lack some memory here. We should fail here! */
+               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+               return INVALID_HANDLE_VALUE;
+            }
+            
+            Status = NtQueryEaFile(hTemplateFile,
+                                   &IoStatusBlock,
+                                   EaBuffer,
+                                   EaInformation.EaSize,
+                                   FALSE,
+                                   NULL,
+                                   0,
+                                   NULL,
+                                   TRUE);
+            
+            if (NT_SUCCESS(Status))
+            {
+               /* we successfully read the extended attributes, break the loop
+                  and continue */
+               EaLength = EaInformation.EaSize;
+               break;
+            }
+            else
+            {
+               RtlFreeHeap(RtlGetProcessHeap(),
+                           0,
+                           EaBuffer);
+               EaBuffer = NULL;
+               
+               if (Status != STATUS_BUFFER_TOO_SMALL)
+               {
+                  /* unless we just allocated not enough memory, break the loop
+                     and just continue without copying extended attributes */
+                  break;
+               }
+            }
+         }
+         else
+         {
+            /* we either failed to get the size of the extended attributes or
+               they're empty, just continue as there's no need to copy
+               attributes */
+            break;
+         }
+      }
+   }
 
    /* build the object attributes */
-   InitializeObjectAttributes(
-    &ObjectAttributes,
-    &NtPathU,
-    0,
-    NULL,
-    NULL
-   );
+   InitializeObjectAttributes(&ObjectAttributes,
+                              &NtPathU,
+                              0,
+                              NULL,
+                              NULL);
 
    if (lpSecurityAttributes)
    {
@@ -261,14 +306,22 @@ HANDLE STDCALL CreateFileW (LPCWSTR                       lpFileName,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
-                         dwFlagsAndAttributes,
+                         FileAttributes,
                          dwShareMode,
                          dwCreationDisposition,
                          Flags,
-                         NULL,
-                         0);
+                         EaBuffer,
+                         EaLength);
 
    RtlFreeUnicodeString(&NtPathU);
+   
+   /* free the extended attributes buffer if allocated */
+   if (EaBuffer != NULL)
+   {
+      RtlFreeHeap(RtlGetProcessHeap(),
+                  0,
+                  EaBuffer);
+   }
 
    /* error */
    if (!NT_SUCCESS(Status))
index 1084bd4..ae6e236 100644 (file)
@@ -25,6 +25,9 @@ UNICODE_STRING WindowsDirectory;
 
 /* FUNCTIONS *****************************************************************/
 
+
+
+
 /*
  * @implemented
  */
@@ -35,71 +38,19 @@ GetCurrentDirectoryA (
        LPSTR   lpBuffer
        )
 {
-       ANSI_STRING AnsiString;
-       UNICODE_STRING UnicodeString;
-       ULONG Length;
-
-       /* allocate buffer for unicode string */
-       UnicodeString.Length = 0;
-       UnicodeString.MaximumLength = nBufferLength * sizeof(WCHAR);
-       if (nBufferLength > 0)
-       {
-               UnicodeString.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
-                                                       0,
-                                                       UnicodeString.MaximumLength);
-
-               /* initialize ansi string */
-               AnsiString.Length = 0;
-               AnsiString.MaximumLength = nBufferLength;
-               AnsiString.Buffer = lpBuffer;
-       }
-       else
-       {
-               UnicodeString.Buffer = NULL;
-       }
-
-       /* get current directory */
-       UnicodeString.Length = RtlGetCurrentDirectory_U (UnicodeString.MaximumLength,
-                                                        UnicodeString.Buffer);
-       DPRINT("UnicodeString.Buffer %wZ\n", &UnicodeString);
-
-       /* convert unicode string to ansi (or oem) */
-       if (bIsFileApiAnsi)
-       {
-               Length = RtlUnicodeStringToAnsiSize (&UnicodeString);
-               if (Length > nBufferLength)
-               {
-                       RtlFreeHeap (RtlGetProcessHeap (),
-                                    0,
-                                    UnicodeString.Buffer);
-                       return Length-1;
-               }
-               RtlUnicodeStringToAnsiString (&AnsiString,
-                                             &UnicodeString,
-                                             FALSE);
-       }
-       else
-       {
-               Length = RtlUnicodeStringToOemSize (&UnicodeString);
-               if (Length > nBufferLength)
-               {
-                       RtlFreeHeap (RtlGetProcessHeap (),
-                                    0,
-                                    UnicodeString.Buffer);
-                       return Length-1;
-               }
-               RtlUnicodeStringToOemString (&AnsiString,
-                                            &UnicodeString,
-                                            FALSE);
-       }
-       DPRINT("AnsiString.Buffer %s\n", AnsiString.Buffer);
-
-       /* free unicode string */
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    UnicodeString.Buffer);
-
-       return AnsiString.Length;
+   WCHAR BufferW[MAX_PATH];
+   DWORD ret;
+
+   ret = GetCurrentDirectoryW(MAX_PATH, BufferW);
+
+   if (!ret) return 0;
+   if (ret > MAX_PATH)
+   {
+      SetLastError(ERROR_FILENAME_EXCED_RANGE);
+      return 0;
+   }
+   
+   return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
 }
 
 
@@ -122,6 +73,7 @@ GetCurrentDirectoryW (
 }
 
 
+
 /*
  * @implemented
  */
@@ -131,34 +83,14 @@ SetCurrentDirectoryA (
        LPCSTR  lpPathName
        )
 {
-       ANSI_STRING AnsiString;
-       UNICODE_STRING UnicodeString;
-       NTSTATUS Status;
-
-       RtlInitAnsiString (&AnsiString,
-                          (LPSTR)lpPathName);
-
-       /* convert ansi (or oem) to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&UnicodeString,
-                                             &AnsiString,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&UnicodeString,
-                                            &AnsiString,
-                                            TRUE);
-
-       Status = RtlSetCurrentDirectory_U (&UnicodeString);
+   PWCHAR PathNameW;
 
-       RtlFreeUnicodeString (&UnicodeString);
+   DPRINT("setcurrdir: %s\n",lpPathName);
 
-       if (!NT_SUCCESS(Status))
-       {
-               SetLastErrorByStatus (Status);
-               return FALSE;
-       }
+   if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+      return FALSE;
 
-       return TRUE;
+   return SetCurrentDirectoryW(PathNameW);
 }
 
 
@@ -190,6 +122,8 @@ SetCurrentDirectoryW (
 
 /*
  * @implemented
+ *
+ * NOTE: Windows returns a dos/short (8.3) path 
  */
 DWORD
 STDCALL
@@ -198,138 +132,82 @@ GetTempPathA (
        LPSTR   lpBuffer
        )
 {
-       UNICODE_STRING UnicodeString;
-       ANSI_STRING AnsiString;
-       DWORD Length;
-
-       AnsiString.Length = 0;
-       AnsiString.MaximumLength = nBufferLength;
-       AnsiString.Buffer = lpBuffer;
-
-       /* initialize allocate unicode string */
-       UnicodeString.Length = 0;
-       if(nBufferLength > 0)
-       {
-         UnicodeString.MaximumLength = (nBufferLength + 1) * sizeof(WCHAR);
-         UnicodeString.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
-                                                 0,
-                                                 UnicodeString.MaximumLength);
-         if (UnicodeString.Buffer == NULL)
-         {
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return 0;
-         }
-       }
-       else
-       {
-          UnicodeString.MaximumLength = 0;
-          UnicodeString.Buffer = NULL;
-       }
+   WCHAR BufferW[MAX_PATH];
+   DWORD ret;
 
-       Length = GetTempPathW (nBufferLength,
-                              UnicodeString.Buffer);
+   ret = GetTempPathW(MAX_PATH, BufferW);
 
-       if (nBufferLength >= Length)
-       {
-                /* only touch the buffer if the supplied buffer length is at least
-                   the length that GetTempPathW returned! */
-               UnicodeString.Length = Length * sizeof(WCHAR);
-
-               /* convert unicode string to ansi (or oem) */
-               if (bIsFileApiAnsi)
-                       RtlUnicodeStringToAnsiString (&AnsiString,
-                                                     &UnicodeString,
-                                                     FALSE);
-               else
-                       RtlUnicodeStringToOemString (&AnsiString,
-                                                    &UnicodeString,
-                                                    FALSE);
-       }
+   if (!ret)
+      return 0;
 
-       /* free unicode string buffer */
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    UnicodeString.Buffer);
+   if (ret > MAX_PATH)
+   {
+      SetLastError(ERROR_FILENAME_EXCED_RANGE);
+      return 0;
+   }
 
-       return Length;
+   return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
 }
 
 
 /*
  * @implemented
+ *
+ * ripped from wine
  */
 DWORD
 STDCALL
 GetTempPathW (
-       DWORD   nBufferLength,
-       LPWSTR  lpBuffer
+       DWORD   count,
+   LPWSTR   path
        )
 {
-       UNICODE_STRING Name;
-       PUNICODE_STRING Value;
-       PTEB Teb;
-       DWORD Length;
-       NTSTATUS Status;
-
-       Teb = NtCurrentTeb();
-       Teb->StaticUnicodeString.Length = 0;
-       Teb->StaticUnicodeString.MaximumLength = MAX_PATH * sizeof(WCHAR);
-       Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
-       Value = &Teb->StaticUnicodeString;
-
-       RtlRosInitUnicodeStringFromLiteral (&Name,
-                                           L"TMP");
-
-       Status = RtlQueryEnvironmentVariable_U (NULL,
-                                               &Name,
-                                               Value);
-       if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
-       {
-               RtlRosInitUnicodeStringFromLiteral (&Name,
-                                                   L"TEMP");
-
-               Status = RtlQueryEnvironmentVariable_U (NULL,
-                                                       &Name,
-                                                       Value);
-               if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
-               {
-                       Value->Length = RtlGetCurrentDirectory_U(Value->MaximumLength,
-                                                                Value->Buffer);
-               }
-       }
-
-       if (!NT_SUCCESS(Status))
-       {
-               SetLastError(RtlNtStatusToDosError(Status));
-               return 0;
-       }
-
-       Length = Value->Length / sizeof(WCHAR) + 1;
-       if (nBufferLength < Value->Length / sizeof(WCHAR) + 2)
-               Length++;
-
-       if (nBufferLength >= Value->Length /sizeof(WCHAR) + 1)
-       {
-               if (nBufferLength < Value->Length / sizeof(WCHAR) + 2)
-               {
-                       memcpy (lpBuffer,
-                               Value->Buffer,
-                               nBufferLength * sizeof(WCHAR));
-               }
-               else
-               {
-                       memcpy (lpBuffer,
-                               Value->Buffer,
-                               Value->Length);
-                       lpBuffer[Value->Length / sizeof(WCHAR)] = L'\\';
-                       lpBuffer[Value->Length / sizeof(WCHAR) + 1] = 0;
-               }
-       } else if (nBufferLength > 0)
-       {
-                lpBuffer[0] = L'\0';
-       }
+   WCHAR tmp_path[MAX_PATH];
+   WCHAR tmp_full_path[MAX_PATH];
+   UINT ret;
+
+   DPRINT("GetTempPathW(%lu,%p)\n", nBufferLength, lpBuffer);
+
+   if (!(ret = GetEnvironmentVariableW( L"TMP", tmp_path, MAX_PATH )))
+     if (!(ret = GetEnvironmentVariableW( L"TEMP", tmp_path, MAX_PATH )))
+         if (!(ret = GetCurrentDirectoryW( MAX_PATH, tmp_path )))
+             return 0;
+
+   if (ret > MAX_PATH)
+   {
+     SetLastError(ERROR_FILENAME_EXCED_RANGE);
+     return 0;
+   }
+
+   ret = GetFullPathNameW(tmp_path, MAX_PATH, tmp_full_path, NULL);
+   if (!ret) return 0;
+
+   if (ret > MAX_PATH - 2)
+   {
+     SetLastError(ERROR_FILENAME_EXCED_RANGE);
+     return 0;
+   }
+
+   if (tmp_full_path[ret-1] != '\\')
+   {
+     tmp_full_path[ret++] = '\\';
+     tmp_full_path[ret]   = '\0';
+   }
+
+   ret++; /* add space for terminating 0 */
+
+   if (count)
+   {
+     lstrcpynW(path, tmp_full_path, count);
+     if (count >= ret)
+         ret--; /* return length without 0 */
+     else if (count < 4)
+         path[0] = 0; /* avoid returning ambiguous "X:" */
+   }
+
+   DPRINT("GetTempPathW returning %u, %s\n", ret, path);
+   return ret;
 
-       return Length;
 }
 
 
@@ -343,37 +221,7 @@ GetSystemDirectoryA (
        UINT    uSize
        )
 {
-       ANSI_STRING String;
-       ULONG Length;
-       NTSTATUS Status;
-
-       Length = RtlUnicodeStringToAnsiSize (&SystemDirectory);   //len of ansi str incl. nullchar
-
-       if (lpBuffer == NULL)
-               return Length;
-
-       if (uSize >= Length){
-               String.Length = 0;
-               String.MaximumLength = uSize;
-               String.Buffer = lpBuffer;
-
-               /* convert unicode string to ansi (or oem) */
-               if (bIsFileApiAnsi)
-                       Status = RtlUnicodeStringToAnsiString (&String,
-                                                     &SystemDirectory,
-                                                     FALSE);
-               else
-                       Status = RtlUnicodeStringToOemString (&String,
-                                                    &SystemDirectory,
-                                                    FALSE);
-               if (!NT_SUCCESS(Status) )
-                       return 0;
-
-               return Length-1;  //good: ret chars excl. nullchar
-
-       }
-
-       return Length;   //bad: ret space needed incl. nullchar
+   return FilenameU2A_FitOrFail(lpBuffer, uSize, &SystemDirectory);   
 }
 
 
@@ -416,38 +264,7 @@ GetWindowsDirectoryA (
        UINT    uSize
        )
 {
-       ANSI_STRING String;
-       ULONG Length;
-       NTSTATUS Status;
-
-       Length = RtlUnicodeStringToAnsiSize (&WindowsDirectory); //len of ansi str incl. nullchar
-       
-       if (lpBuffer == NULL)
-               return Length;
-
-       if (uSize >= Length){
-
-               String.Length = 0;
-               String.MaximumLength = uSize;
-               String.Buffer = lpBuffer;
-
-               /* convert unicode string to ansi (or oem) */
-               if (bIsFileApiAnsi)
-                       Status = RtlUnicodeStringToAnsiString (&String,
-                                                     &WindowsDirectory,
-                                                     FALSE);
-               else
-                       Status = RtlUnicodeStringToOemString (&String,
-                                                    &WindowsDirectory,
-                                                    FALSE);
-
-               if (!NT_SUCCESS(Status))
-                       return 0;
-
-               return Length-1;        //good: ret chars excl. nullchar
-       }
-
-       return Length;  //bad: ret space needed incl. nullchar
+   return FilenameU2A_FitOrFail(lpBuffer, uSize, &WindowsDirectory);   
 }
 
 
index 59131a9..b643c84 100644 (file)
@@ -28,30 +28,12 @@ DeleteFileA (
        LPCSTR  lpFileName
        )
 {
-       UNICODE_STRING FileNameU;
-       ANSI_STRING FileName;
-       BOOL Result;
-
-       RtlInitAnsiString (&FileName,
-                          (LPSTR)lpFileName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&FileNameU,
-                                             &FileName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&FileNameU,
-                                            &FileName,
-                                            TRUE);
-
-       Result = DeleteFileW (FileNameU.Buffer);
-
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    FileNameU.Buffer);
-
-       return Result;
+       PWCHAR FileNameW;
+   
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
+
+       return DeleteFileW (FileNameW);
 }
 
 
index b46e2d0..f7d60b5 100644 (file)
@@ -34,9 +34,13 @@ CreateDirectoryA (
         LPSECURITY_ATTRIBUTES   lpSecurityAttributes
         )
 {
-        return CreateDirectoryExA (NULL,
-                                   lpPathName,
-                                   lpSecurityAttributes);
+   PWCHAR PathNameW;
+   
+   if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+      return FALSE;
+
+   return CreateDirectoryW (PathNameW,
+                            lpSecurityAttributes);
 }
 
 
@@ -50,65 +54,30 @@ CreateDirectoryExA (
         LPCSTR                  lpNewDirectory,
         LPSECURITY_ATTRIBUTES   lpSecurityAttributes)
 {
-        UNICODE_STRING TmplDirU;
-        UNICODE_STRING NewDirU;
-        ANSI_STRING TmplDir;
-        ANSI_STRING NewDir;
-        BOOL Result;
-
-        RtlInitUnicodeString (&TmplDirU,
-                              NULL);
-
-        RtlInitUnicodeString (&NewDirU,
-                              NULL);
-
-        if (lpTemplateDirectory != NULL)
-        {
-                RtlInitAnsiString (&TmplDir,
-                                   (LPSTR)lpTemplateDirectory);
-
-                /* convert ansi (or oem) string to unicode */
-                if (bIsFileApiAnsi)
-                        RtlAnsiStringToUnicodeString (&TmplDirU,
-                                                      &TmplDir,
-                                                      TRUE);
-                else
-                        RtlOemStringToUnicodeString (&TmplDirU,
-                                                     &TmplDir,
-                                                     TRUE);
-        }
+   PWCHAR TemplateDirectoryW;
+   PWCHAR NewDirectoryW;
+   BOOL ret;
 
-        if (lpNewDirectory != NULL)
-        {
-                RtlInitAnsiString (&NewDir,
-                                   (LPSTR)lpNewDirectory);
-
-                /* convert ansi (or oem) string to unicode */
-                if (bIsFileApiAnsi)
-                        RtlAnsiStringToUnicodeString (&NewDirU,
-                                                      &NewDir,
-                                                      TRUE);
-                else
-                        RtlOemStringToUnicodeString (&NewDirU,
-                                                     &NewDir,
-                                                     TRUE);
-        }
-
-        Result = CreateDirectoryExW (TmplDirU.Buffer,
-                                     NewDirU.Buffer,
-                                     lpSecurityAttributes);
-
-        if (lpTemplateDirectory != NULL)
-                RtlFreeHeap (RtlGetProcessHeap (),
-                             0,
-                             TmplDirU.Buffer);
+   if (!(TemplateDirectoryW = FilenameA2W(lpTemplateDirectory, TRUE)))
+      return FALSE;
+      
+   if (!(NewDirectoryW = FilenameA2W(lpNewDirectory, FALSE)))
+   {
+      RtlFreeHeap (RtlGetProcessHeap (),
+                   0,
+                   TemplateDirectoryW);
+      return FALSE;
+   }
+      
+   ret = CreateDirectoryExW (TemplateDirectoryW,
+                             NewDirectoryW,
+                             lpSecurityAttributes);
 
-        if (lpNewDirectory != NULL)
-                RtlFreeHeap (RtlGetProcessHeap (),
-                             0,
-                             NewDirU.Buffer);
+   RtlFreeHeap (RtlGetProcessHeap (),
+                0,
+                TemplateDirectoryW);
 
-        return Result;
+   return ret;
 }
 
 
@@ -122,9 +91,55 @@ CreateDirectoryW (
         LPSECURITY_ATTRIBUTES   lpSecurityAttributes
         )
 {
-        return CreateDirectoryExW (NULL,
-                                   lpPathName,
-                                   lpSecurityAttributes);
+        OBJECT_ATTRIBUTES ObjectAttributes;
+        IO_STATUS_BLOCK IoStatusBlock;
+        UNICODE_STRING NtPathU;
+        HANDLE DirectoryHandle;
+        NTSTATUS Status;
+
+        DPRINT ("lpPathName %S lpSecurityAttributes %p\n",
+                lpPathName, lpSecurityAttributes);
+
+        if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName,
+                                           &NtPathU,
+                                           NULL,
+                                           NULL))
+        {
+                SetLastError(ERROR_PATH_NOT_FOUND);
+                return FALSE;
+        }
+
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &NtPathU,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   (lpSecurityAttributes ? lpSecurityAttributes->lpSecurityDescriptor : NULL));
+
+        Status = NtCreateFile (&DirectoryHandle,
+                               GENERIC_READ,
+                               &ObjectAttributes,
+                               &IoStatusBlock,
+                               NULL,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ | FILE_SHARE_WRITE,
+                               FILE_CREATE,
+                               FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+                               NULL,
+                               0);
+
+        RtlFreeHeap (RtlGetProcessHeap (),
+                     0,
+                     NtPathU.Buffer);
+
+        if (!NT_SUCCESS(Status))
+        {
+                SetLastErrorByStatus(Status);
+                return FALSE;
+        }
+
+        NtClose (DirectoryHandle);
+
+        return TRUE;
 }
 
 
@@ -141,54 +156,178 @@ CreateDirectoryExW (
 {
         OBJECT_ATTRIBUTES ObjectAttributes;
         IO_STATUS_BLOCK IoStatusBlock;
-        UNICODE_STRING NtPathU;
-        HANDLE DirectoryHandle;
+        UNICODE_STRING NtPathU, NtTemplatePathU;
+        HANDLE DirectoryHandle, TemplateHandle;
+        FILE_EA_INFORMATION EaInformation;
         NTSTATUS Status;
+        PVOID EaBuffer = NULL;
+        ULONG EaLength = 0;
 
         DPRINT ("lpTemplateDirectory %S lpNewDirectory %S lpSecurityAttributes %p\n",
                 lpTemplateDirectory, lpNewDirectory, lpSecurityAttributes);
 
-  // Can't create empty directory
-  if(lpNewDirectory == NULL || *lpNewDirectory == 0)
-  {
-    SetLastError(ERROR_PATH_NOT_FOUND);
-    return FALSE;
-  }
+        /*
+         * Read the extended attributes from the template directory
+         */
 
-        if (lpTemplateDirectory != NULL && *lpTemplateDirectory != 0)
+        if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpTemplateDirectory,
+                                           &NtTemplatePathU,
+                                           NULL,
+                                           NULL))
         {
-                // get object attributes from template directory
-                DPRINT("KERNEL32:FIXME:%s:%d\n",__FILE__,__LINE__);
+                SetLastError(ERROR_PATH_NOT_FOUND);
                 return FALSE;
         }
+        
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &NtTemplatePathU,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+
+        Status = NtCreateFile (&TemplateHandle,
+                               GENERIC_READ,
+                               &ObjectAttributes,
+                               &IoStatusBlock,
+                               NULL,
+                               0,
+                               FILE_SHARE_READ | FILE_SHARE_WRITE,
+                               FILE_OPEN,
+                               FILE_DIRECTORY_FILE,
+                               NULL,
+                               0);
+        if (!NT_SUCCESS(Status))
+        {
+                RtlFreeHeap (RtlGetProcessHeap (),
+                             0,
+                             NtTemplatePathU.Buffer);
+                SetLastErrorByStatus (Status);
+                return FALSE;
+        }
+        
+        for (;;)
+        {
+          Status = NtQueryInformationFile(TemplateHandle,
+                                          &IoStatusBlock,
+                                          &EaInformation,
+                                          sizeof(FILE_EA_INFORMATION),
+                                          FileEaInformation);
+          if (NT_SUCCESS(Status) && (EaInformation.EaSize != 0))
+          {
+            EaBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                       0,
+                                       EaInformation.EaSize);
+            if (EaBuffer == NULL)
+            {
+               Status = STATUS_INSUFFICIENT_RESOURCES;
+               break;
+            }
+            
+            Status = NtQueryEaFile(TemplateHandle,
+                                   &IoStatusBlock,
+                                   EaBuffer,
+                                   EaInformation.EaSize,
+                                   FALSE,
+                                   NULL,
+                                   0,
+                                   NULL,
+                                   TRUE);
+
+            if (NT_SUCCESS(Status))
+            {
+               /* we successfully read the extended attributes */
+               EaLength = EaInformation.EaSize;
+               break;
+            }
+            else
+            {
+               RtlFreeHeap(RtlGetProcessHeap(),
+                           0,
+                           EaBuffer);
+               EaBuffer = NULL;
+
+               if (Status != STATUS_BUFFER_TOO_SMALL)
+               {
+                  /* unless we just allocated not enough memory, break the loop
+                     and just continue without copying extended attributes */
+                  break;
+               }
+            }
+          }
+          else
+          {
+            /* failure or no extended attributes present, break the loop */
+            break;
+          }
+        }
+        
+        NtClose(TemplateHandle);
+        
+        RtlFreeHeap (RtlGetProcessHeap (),
+                     0,
+                     NtTemplatePathU.Buffer);
+        
+        if (!NT_SUCCESS(Status))
+        {
+                /* free the he extended attributes buffer */
+                if (EaBuffer != NULL)
+                {
+                        RtlFreeHeap (RtlGetProcessHeap (),
+                                     0,
+                                     EaBuffer);
+                }
+
+                SetLastErrorByStatus (Status);
+                return FALSE;
+        }
+
+        /*
+         * Create the new directory and copy over the extended attributes if
+         * needed
+         */
 
         if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpNewDirectory,
                                            &NtPathU,
                                            NULL,
                                            NULL))
+        {
+                /* free the he extended attributes buffer */
+                if (EaBuffer != NULL)
+                {
+                        RtlFreeHeap (RtlGetProcessHeap (),
+                                     0,
+                                     EaBuffer);
+                }
+                
+                SetLastError(ERROR_PATH_NOT_FOUND);
                 return FALSE;
+        }
 
-        DPRINT ("NtPathU \'%wZ\'\n", &NtPathU);
-
-        ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-        ObjectAttributes.RootDirectory = NULL;
-        ObjectAttributes.ObjectName = &NtPathU;
-        ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
-        ObjectAttributes.SecurityDescriptor = NULL;
-        ObjectAttributes.SecurityQualityOfService = NULL;
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &NtPathU,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   (lpSecurityAttributes ? lpSecurityAttributes->lpSecurityDescriptor : NULL));
 
         Status = NtCreateFile (&DirectoryHandle,
-                               DIRECTORY_ALL_ACCESS,
+                               GENERIC_READ,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                NULL,
-                               FILE_ATTRIBUTE_DIRECTORY,
-                               0,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ | FILE_SHARE_WRITE,
                                FILE_CREATE,
-                               FILE_DIRECTORY_FILE,
-                               NULL,
-                               0);
-        DPRINT("Status: %lx\n", Status);
+                               FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+                               EaBuffer,
+                               EaLength);
+
+        /* free the he extended attributes buffer */
+        if (EaBuffer != NULL)
+        {
+                RtlFreeHeap (RtlGetProcessHeap (),
+                             0,
+                             EaBuffer);
+        }
 
         RtlFreeHeap (RtlGetProcessHeap (),
                      0,
@@ -215,30 +354,14 @@ RemoveDirectoryA (
         LPCSTR  lpPathName
         )
 {
-        UNICODE_STRING PathNameU;
-        ANSI_STRING PathName;
-        BOOL Result;
-
-        RtlInitAnsiString (&PathName,
-                           (LPSTR)lpPathName);
-
-        /* convert ansi (or oem) string to unicode */
-        if (bIsFileApiAnsi)
-                RtlAnsiStringToUnicodeString (&PathNameU,
-                                              &PathName,
-                                              TRUE);
-        else
-                RtlOemStringToUnicodeString (&PathNameU,
-                                             &PathName,
-                                             TRUE);
+   PWCHAR PathNameW;
+   
+   DPRINT("RemoveDirectoryA(%s)\n",lpPathName);
 
-        Result = RemoveDirectoryW (PathNameU.Buffer);
+   if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+       return FALSE;
 
-        RtlFreeHeap (RtlGetProcessHeap (),
-                     0,
-                     PathNameU.Buffer);
-
-        return Result;
+   return RemoveDirectoryW (PathNameW);
 }
 
 
@@ -266,17 +389,16 @@ RemoveDirectoryW (
                                            NULL))
                 return FALSE;
 
-        ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-        ObjectAttributes.RootDirectory = NULL;
-        ObjectAttributes.ObjectName = &NtPathU;
-        ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
-        ObjectAttributes.SecurityDescriptor = NULL;
-        ObjectAttributes.SecurityQualityOfService = NULL;
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &NtPathU,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
 
         DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
 
         Status = NtCreateFile (&DirectoryHandle,
-                               FILE_WRITE_ATTRIBUTES,    /* 0x110080 */
+                               DELETE,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                NULL,
@@ -305,18 +427,10 @@ RemoveDirectoryW (
                                        &FileDispInfo,
                                        sizeof(FILE_DISPOSITION_INFORMATION),
                                        FileDispositionInformation);
+        NtClose(DirectoryHandle);
+        
         if (!NT_SUCCESS(Status))
         {
-                CHECKPOINT;
-                NtClose(DirectoryHandle);
-                SetLastErrorByStatus (Status);
-                return FALSE;
-        }
-
-        Status = NtClose (DirectoryHandle);
-        if (!NT_SUCCESS(Status))
-        {
-                CHECKPOINT;
                 SetLastErrorByStatus (Status);
                 return FALSE;
         }
@@ -337,70 +451,49 @@ GetFullPathNameA (
         LPSTR   *lpFilePart
         )
 {
-    UNICODE_STRING nameW;
-    WCHAR bufferW[MAX_PATH];
-    DWORD ret;
-    LPWSTR FilePart = NULL;
-
-    DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
-           "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
-
-    if (!lpFileName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-    }
+   WCHAR BufferW[MAX_PATH];
+   PWCHAR FileNameW;
+   DWORD ret;
+   LPWSTR FilePartW = NULL;
 
-    if (!RtlCreateUnicodeStringFromAsciiz(&nameW, (LPSTR)lpFileName))
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
+   DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
+        "lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
 
-    if (lpFilePart)
-    {
-            *lpFilePart = NULL;
-    }
-
-    ret = GetFullPathNameW(nameW.Buffer, MAX_PATH, bufferW, &FilePart);
-
-    if (MAX_PATH < ret)
-    {
-        SetLastError(ERROR_FILENAME_EXCED_RANGE);
-        ret = 0;
-    }
-    else if (0 < ret)
-    {
-        if (ret < nBufferLength)
-        {
-            ANSI_STRING AnsiBuffer;
-            UNICODE_STRING UnicodeBuffer;
-
-            UnicodeBuffer.Length = wcslen(bufferW) * sizeof(WCHAR);
-            UnicodeBuffer.MaximumLength = MAX_PATH * sizeof(WCHAR);
-            UnicodeBuffer.Buffer = bufferW;
-            AnsiBuffer.MaximumLength = nBufferLength;
-            AnsiBuffer.Length = 0;
-            AnsiBuffer.Buffer = lpBuffer;
-            RtlUnicodeStringToAnsiString(&AnsiBuffer, &UnicodeBuffer, FALSE);
-
-            if (lpFilePart && FilePart != NULL)
-            {
-                *lpFilePart = (FilePart - bufferW) + lpBuffer;
-            }
-        }
-        else
-        {
-            ret++;
-        }
-    }
+   if (!lpFileName)
+   {
+     SetLastError(ERROR_INVALID_PARAMETER);
+     return 0;
+   }
 
-    RtlFreeUnicodeString(&nameW);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return 0;
 
-    DPRINT("lpBuffer %s lpFilePart %s Length %ld\n",
-           lpBuffer, (lpFilePart == NULL) ? "NULL" : *lpFilePart, nameW.Length);
+   ret = GetFullPathNameW(FileNameW, MAX_PATH, BufferW, &FilePartW);
+   
+   if (!ret)
+      return 0;
+      
+   if (ret > MAX_PATH)
+   {
+      SetLastError(ERROR_FILENAME_EXCED_RANGE);
+      return 0;
+   }
+   
+   ret = FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
+   
+   if (ret < nBufferLength && lpFilePart)
+   {
+      /* if the path closed with '\', FilePart is NULL */
+      if (!FilePartW) 
+         *lpFilePart=NULL;
+      else
+         *lpFilePart = (FilePartW - BufferW) + lpBuffer;
+   }
+   
+   DPRINT("GetFullPathNameA ret: lpBuffer %s lpFilePart %s\n",
+        lpBuffer, (lpFilePart == NULL) ? "NULL" : *lpFilePart);
 
-    return ret;
+   return ret;
 }
 
 
@@ -426,17 +519,10 @@ GetFullPathNameW (
                                    lpBuffer,
                                    lpFilePart);
 
-    DPRINT("lpBuffer %S lpFilePart %S Length %ld\n",
+    DPRINT("GetFullPathNameW ret: lpBuffer %S lpFilePart %S Length %ld\n",
            lpBuffer, (lpFilePart == NULL) ? L"NULL" : *lpFilePart, Length / sizeof(WCHAR));
 
-    Length = Length / sizeof(WCHAR);
-    if (nBufferLength < Length + 1)
-    {
-        DPRINT("Adjusting Length for terminator\n");
-        Length++;
-    }
-
-    return Length;
+    return Length/sizeof(WCHAR);
 }
 
 
@@ -452,9 +538,9 @@ GetShortPathNameA (
         DWORD   shortlen
         )
 {
-    UNICODE_STRING longpathW;
-    WCHAR shortpathW[MAX_PATH];
-    DWORD ret, retW;
+    PWCHAR LongPathW;
+    WCHAR ShortPathW[MAX_PATH];
+    DWORD ret;
 
     if (!longpath)
     {
@@ -462,33 +548,21 @@ GetShortPathNameA (
         return 0;
     }
 
-    if (!RtlCreateUnicodeStringFromAsciiz(&longpathW, longpath))
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
+    if (!(LongPathW = FilenameA2W(longpath, FALSE)))
+      return 0;
 
-    retW = GetShortPathNameW(longpathW.Buffer, shortpathW, MAX_PATH);
+    ret = GetShortPathNameW(LongPathW, ShortPathW, MAX_PATH);
 
-    if (!retW)
-        ret = 0;
-    else if (retW > PATH_MAX)
+    if (!ret)
+        return 0;
+    
+    if (ret > MAX_PATH)
     {
         SetLastError(ERROR_FILENAME_EXCED_RANGE);
-        ret = 0;
-    }
-    else
-    {
-        ret = WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, NULL, 0, NULL, NULL);
-        if (ret <= shortlen)
-        {
-            WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, shortpath, shortlen, NULL, NULL);
-            ret--; /* length without 0 */
-        }
+        return 0;
     }
-
-    RtlFreeUnicodeString(&longpathW);
-    return ret;
+    
+    return FilenameW2A_FitOrFail(shortpath, shortlen, ShortPathW, ret+1);
 }
 
 
@@ -513,6 +587,8 @@ GetShortPathNameW (
     UNICODE_STRING      ustr;
     WCHAR               ustr_buf[8+1+3+1];
 
+   DPRINT("GetShortPathNameW: %S\n",longpath);
+
     if (!longpath)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
@@ -931,38 +1007,18 @@ SetDllDirectoryW(
 BOOL
 STDCALL
 SetDllDirectoryA(
-    LPCSTR lpPathName
+    LPCSTR lpPathName /* can be NULL */
     )
 {
-  UNICODE_STRING PathNameU;
-  ANSI_STRING PathNameA;
-  BOOL Ret;
+  PWCHAR PathNameW=NULL;
   
-  if(lpPathName != NULL)
-  {
-    RtlInitAnsiString(&PathNameA, lpPathName);
-    if(bIsFileApiAnsi)
-    {
-      RtlAnsiStringToUnicodeString(&PathNameU, &PathNameA, TRUE);
-    }
-    else
-    {
-      RtlOemStringToUnicodeString(&PathNameU, &PathNameA, TRUE);
-    }
-  }
-  else
+  if(lpPathName)
   {
-    PathNameU.Buffer = NULL;
+     if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
+        return FALSE;
   }
   
-  Ret = SetDllDirectoryW(PathNameU.Buffer);
-  
-  if(lpPathName != NULL)
-  {
-    RtlFreeUnicodeString(&PathNameU);
-  }
-
-  return Ret;
+  return SetDllDirectoryW(PathNameW);
 }
 
 /*
@@ -1012,51 +1068,184 @@ GetDllDirectoryA(
     LPSTR lpBuffer
     )
 {
-  UNICODE_STRING PathNameU;
-  ANSI_STRING PathNameA;
-  DWORD Ret;
-  
-  if(nBufferLength > 0)
+  WCHAR BufferW[MAX_PATH];
+  DWORD ret;
+
+  ret = GetDllDirectoryW(MAX_PATH, BufferW);
+
+  if (!ret)
+     return 0;
+     
+  if (ret > MAX_PATH)
   {
-    if(!(PathNameU.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(),
-                                                   0,
-                                                   nBufferLength * sizeof(WCHAR))))
+     SetLastError(ERROR_FILENAME_EXCED_RANGE);
+     return 0;
+  }
+  
+  return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
+}
+
+
+/*
+ * @unimplemented
+ */
+BOOL STDCALL
+NeedCurrentDirectoryForExePathW(LPCWSTR ExeName)
+{
+  DPRINT1("NeedCurrentDirectoryForExePathW(0x%x) not implemented!\n", ExeName);
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+NeedCurrentDirectoryForExePathA(LPCSTR ExeName)
+{
+  PWCHAR ExeNameW;
+  
+  if (!(ExeNameW = FilenameA2W(ExeName, FALSE)))
+    return FALSE;     
+  
+  return NeedCurrentDirectoryForExePathW(ExeNameW);
+}
+
+
+
+
+
+/***********************************************************************
+ * @implemented
+ *
+ *           GetLongPathNameW   (KERNEL32.@)
+ *
+ * NOTES
+ *  observed (Win2000):
+ *  shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
+ *  shortpath="":   LastError=ERROR_PATH_NOT_FOUND, ret=0
+ */
+DWORD STDCALL GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
+{
+#define    MAX_PATHNAME_LEN 1024
+
+    WCHAR               tmplongpath[MAX_PATHNAME_LEN];
+    LPCWSTR             p;
+    DWORD               sp = 0, lp = 0;
+    DWORD               tmplen;
+    BOOL                unixabsolute = (shortpath[0] == '/');
+    WIN32_FIND_DATAW    wfd;
+    HANDLE              goit;
+
+    if (!shortpath)
     {
-      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-      return 0;
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+    if (!shortpath[0])
+    {
+        SetLastError(ERROR_PATH_NOT_FOUND);
+        return 0;
     }
-    PathNameU.Length = 0;
-    PathNameU.MaximumLength = nBufferLength * sizeof(WCHAR);
-  }
 
-  Ret = GetDllDirectoryW(nBufferLength,
-                         ((nBufferLength > 0) ? PathNameU.Buffer : NULL));
+    DPRINT("GetLongPathNameW(%s,%p,%ld)\n", shortpath, longpath, longlen);
 
-  if(nBufferLength > 0)
-  {
-    PathNameU.Length = Ret * sizeof(WCHAR);
-    
-    PathNameA.Length = 0;
-    PathNameA.MaximumLength = nBufferLength;
-    PathNameA.Buffer = lpBuffer;
-    
-    if(Ret > 0)
+    if (shortpath[0] == '\\' && shortpath[1] == '\\')
     {
-      if(bIsFileApiAnsi)
-      {
-        RtlUnicodeStringToAnsiString(&PathNameA, &PathNameU, FALSE);
-      }
-      else
-      {
-        RtlUnicodeStringToOemString(&PathNameA, &PathNameU, FALSE);
-      }
+        DPRINT1("ERR: UNC pathname %s\n", shortpath);
+        lstrcpynW( longpath, shortpath, longlen );
+        return wcslen(longpath);
     }
-    lpBuffer[Ret] = '\0';
 
-    RtlFreeHeap(RtlGetProcessHeap(), 0, PathNameU.Buffer);
-  }
-  
-  return Ret;
+    /* check for drive letter */
+    if (!unixabsolute && shortpath[1] == ':' )
+    {
+        tmplongpath[0] = shortpath[0];
+        tmplongpath[1] = ':';
+        lp = sp = 2;
+    }
+
+    while (shortpath[sp])
+    {
+        /* check for path delimiters and reproduce them */
+        if (shortpath[sp] == '\\' || shortpath[sp] == '/')
+        {
+            if (!lp || tmplongpath[lp-1] != '\\')
+            {
+                /* strip double "\\" */
+                tmplongpath[lp++] = '\\';
+            }
+            tmplongpath[lp] = 0; /* terminate string */
+            sp++;
+            continue;
+        }
+
+        p = shortpath + sp;
+        if (sp == 0 && p[0] == '.' && (p[1] == '/' || p[1] == '\\'))
+        {
+            tmplongpath[lp++] = *p++;
+            tmplongpath[lp++] = *p++;
+        }
+        for (; *p && *p != '/' && *p != '\\'; p++);
+        tmplen = p - (shortpath + sp);
+        lstrcpynW(tmplongpath + lp, shortpath + sp, tmplen + 1);
+        /* Check if the file exists and use the existing file name */
+        goit = FindFirstFileW(tmplongpath, &wfd);
+        if (goit == INVALID_HANDLE_VALUE)
+        {
+            DPRINT("not found %s!\n", tmplongpath);
+            SetLastError ( ERROR_FILE_NOT_FOUND );
+            return 0;
+        }
+        FindClose(goit);
+        wcscpy(tmplongpath + lp, wfd.cFileName);
+        lp += wcslen(tmplongpath + lp);
+        sp += tmplen;
+    }
+    tmplen = wcslen(shortpath) - 1;
+    if ((shortpath[tmplen] == '/' || shortpath[tmplen] == '\\') &&
+        (tmplongpath[lp - 1] != '/' && tmplongpath[lp - 1] != '\\'))
+        tmplongpath[lp++] = shortpath[tmplen];
+    tmplongpath[lp] = 0;
+
+    tmplen = wcslen(tmplongpath) + 1;
+    if (tmplen <= longlen)
+    {
+        wcscpy(longpath, tmplongpath);
+        DPRINT("returning %s\n", longpath);
+        tmplen--; /* length without 0 */
+    }
+
+    return tmplen;
+}
+
+
+
+/***********************************************************************
+ *           GetLongPathNameA   (KERNEL32.@)
+ */
+DWORD STDCALL GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
+{
+    WCHAR *shortpathW;
+    WCHAR longpathW[MAX_PATH];
+    DWORD ret;
+
+    DPRINT("GetLongPathNameA %s, %i\n",shortpath,longlen );
+
+    if (!(shortpathW = FilenameA2W( shortpath, FALSE )))
+      return 0;
+
+    ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);
+
+    if (!ret) return 0;
+    if (ret > MAX_PATH)
+    {
+        SetLastError(ERROR_FILENAME_EXCED_RANGE);
+        return 0;
+    }
+    
+    return FilenameW2A_FitOrFail(longpath, longlen, longpathW,  ret+1 );
 }
 
 /* EOF */
index 0c3eb45..3768245 100644 (file)
@@ -25,6 +25,156 @@ BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
 
 /* FUNCTIONS ****************************************************************/
 
+
+
+PWCHAR
+FilenameA2W(LPCSTR NameA, BOOL alloc)
+{
+   ANSI_STRING str;
+   UNICODE_STRING strW;
+   PUNICODE_STRING pstrW;
+   NTSTATUS Status;
+
+   ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
+   ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
+
+   RtlInitAnsiString(&str, NameA);
+   pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
+
+   if (bIsFileApiAnsi)
+        Status= RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
+   else
+        Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
+
+    if (NT_SUCCESS(Status))
+       return pstrW->Buffer;
+
+    if (Status== STATUS_BUFFER_OVERFLOW)
+        SetLastError( ERROR_FILENAME_EXCED_RANGE );
+    else
+        SetLastErrorByStatus(Status);
+        
+    return NULL;
+}
+
+
+/*
+No copy/conversion is done if the dest. buffer is too small.
+
+Returns:
+   Success: number of TCHARS copied into dest. buffer NOT including nullterm
+   Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD 
+FilenameU2A_FitOrFail(
+   LPSTR  DestA,
+   INT destLen, /* buffer size in TCHARS incl. nullchar */
+   PUNICODE_STRING SourceU
+   )
+{
+   DWORD ret;
+
+   ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
+   /* ret incl. nullchar */
+    
+   if (DestA && ret <= destLen)
+   {
+      ANSI_STRING str;
+       
+      str.Buffer = DestA;
+      str.MaximumLength = destLen;
+       
+       
+      if (bIsFileApiAnsi)
+         RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
+      else
+         RtlUnicodeStringToOemString(&str, SourceU, FALSE );
+            
+      ret = str.Length;  /* SUCCESS: length without terminating 0 */
+   }
+    
+   return ret;
+}
+
+
+/*
+No copy/conversion is done if the dest. buffer is too small.
+
+Returns:
+   Success: number of TCHARS copied into dest. buffer NOT including nullterm
+   Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD 
+FilenameW2A_FitOrFail(
+   LPSTR  DestA,
+   INT destLen, /* buffer size in TCHARS incl. nullchar */
+   LPCWSTR SourceW,
+   INT sourceLen /* buffer size in TCHARS incl. nullchar */
+   )
+{
+   UNICODE_STRING strW;
+
+   if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
+
+   strW.Buffer = (PWCHAR)SourceW;
+   strW.MaximumLength = sourceLen * sizeof(WCHAR);
+   strW.Length = strW.MaximumLength - sizeof(WCHAR);
+
+   return FilenameU2A_FitOrFail(DestA, destLen, &strW);     
+}
+
+
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD 
+FilenameA2W_N( 
+   LPWSTR dest, 
+   INT destlen, /* buffer size in TCHARS incl. nullchar */
+   LPCSTR src, 
+   INT srclen /* buffer size in TCHARS incl. nullchar */
+   )
+{
+    DWORD ret;
+
+    if (srclen < 0) srclen = strlen( src ) + 1;
+    
+    if (bIsFileApiAnsi)
+        RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen  );    
+    else
+        RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
+    
+    if (ret) dest[(ret/sizeof(WCHAR))-1]=0;
+    
+    return ret/sizeof(WCHAR);
+}
+
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD 
+FilenameW2A_N( 
+   LPSTR dest, 
+   INT destlen, /* buffer size in TCHARS incl. nullchar */
+   LPCWSTR src, 
+   INT srclen /* buffer size in TCHARS incl. nullchar */
+   )
+{
+    DWORD ret;
+
+    if (srclen < 0) srclen = wcslen( src ) + 1;
+    
+    if (bIsFileApiAnsi)
+        RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR));
+    else
+        RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );    
+        
+    if (ret) dest[ret-1]=0;
+    
+    return ret;
+}
+
+
 /*
  * @implemented
  */
@@ -518,29 +668,12 @@ DWORD STDCALL
 GetCompressedFileSizeA(LPCSTR lpFileName,
                       LPDWORD lpFileSizeHigh)
 {
-   UNICODE_STRING FileNameU;
-   ANSI_STRING FileName;
-   DWORD Size;
+   PWCHAR FileNameW;
 
-   RtlInitAnsiString(&FileName,
-                    (LPSTR)lpFileName);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_FILE_SIZE;
 
-   /* convert ansi (or oem) string to unicode */
-   if (bIsFileApiAnsi)
-     RtlAnsiStringToUnicodeString(&FileNameU,
-                                 &FileName,
-                                 TRUE);
-   else
-     RtlOemStringToUnicodeString(&FileNameU,
-                                &FileName,
-                                TRUE);
-
-   Size = GetCompressedFileSizeW(FileNameU.Buffer,
-                                lpFileSizeHigh);
-
-   RtlFreeUnicodeString (&FileNameU);
-
-   return Size;
+   return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
 }
 
 
@@ -563,23 +696,28 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
+             
+   if (hFile == INVALID_HANDLE_VALUE)
+      return INVALID_FILE_SIZE;
 
    errCode = NtQueryInformationFile(hFile,
                                    &IoStatusBlock,
                                    &FileCompression,
                                    sizeof(FILE_COMPRESSION_INFORMATION),
                                    FileCompressionInformation);
+
+   CloseHandle(hFile);
+
    if (!NT_SUCCESS(errCode))
      {
-       CloseHandle(hFile);
        SetLastErrorByStatus(errCode);
        return INVALID_FILE_SIZE;
      }
-   CloseHandle(hFile);
 
    if(lpFileSizeHigh)
     *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
 
+   SetLastError(NO_ERROR);
    return FileCompression.CompressedFileSize.u.LowPart;
 }
 
@@ -773,27 +911,12 @@ GetFileAttributesExA(LPCSTR lpFileName,
                     GET_FILEEX_INFO_LEVELS fInfoLevelId, 
                     LPVOID lpFileInformation)
 {
-       UNICODE_STRING FileNameU;
-       ANSI_STRING FileName;
-       BOOL Result;
-       RtlInitAnsiString (&FileName,
-                          (LPSTR)lpFileName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&FileNameU,
-                                             &FileName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&FileNameU,
-                                            &FileName,
-                                            TRUE);
-
-        Result = GetFileAttributesExW(FileNameU.Buffer, fInfoLevelId, lpFileInformation);
-
-       RtlFreeUnicodeString (&FileNameU);
+   PWCHAR FileNameW;
+   
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
 
-       return Result;
+   return GetFileAttributesExW(FileNameW, fInfoLevelId, lpFileInformation);
 }
 
 
@@ -803,29 +926,16 @@ GetFileAttributesExA(LPCSTR lpFileName,
 DWORD STDCALL
 GetFileAttributesA(LPCSTR lpFileName)
 {
-        WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
-       UNICODE_STRING FileNameU;
-       ANSI_STRING FileName;
-       BOOL Result;
-
-       RtlInitAnsiString (&FileName,
-                          (LPSTR)lpFileName);
+   WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+   PWSTR FileNameW;
+       BOOL ret;
 
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&FileNameU,
-                                             &FileName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&FileNameU,
-                                            &FileName,
-                                            TRUE);
-
-        Result = GetFileAttributesExW(FileNameU.Buffer, GetFileExInfoStandard, &FileAttributeData);
-
-       RtlFreeUnicodeString (&FileNameU);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_FILE_ATTRIBUTES;
+   
+   ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
 
-       return Result ? FileAttributeData.dwFileAttributes : 0xffffffff;
+   return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
 }
 
 
@@ -842,36 +952,20 @@ GetFileAttributesW(LPCWSTR lpFileName)
 
   Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
 
-  return Result ? FileAttributeData.dwFileAttributes : 0xffffffff;
+  return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
 }
 
 BOOL STDCALL
-SetFileAttributesA(LPCSTR lpFileName,
-                  DWORD dwFileAttributes)
+SetFileAttributesA(
+   LPCSTR lpFileName,
+       DWORD dwFileAttributes)
 {
-  UNICODE_STRING FileNameU;
-  ANSI_STRING FileName;
-  BOOL Result;
-
-  RtlInitAnsiString (&FileName,
-                    (LPSTR)lpFileName);
-
-  /* convert ansi (or oem) string to unicode */
-  if (bIsFileApiAnsi)
-    RtlAnsiStringToUnicodeString (&FileNameU,
-                                 &FileName,
-                                 TRUE);
-   else
-    RtlOemStringToUnicodeString (&FileNameU,
-                                &FileName,
-                                TRUE);
+   PWCHAR FileNameW;
 
-  Result = SetFileAttributesW (FileNameU.Buffer,
-                              dwFileAttributes);
-
-  RtlFreeUnicodeString (&FileNameU);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
 
-  return Result;
+   return SetFileAttributesW(FileNameW, dwFileAttributes);
 }
 
 
@@ -956,102 +1050,93 @@ SetFileAttributesW(LPCWSTR lpFileName,
 }
 
 
-/*
- * @implemented
- */
-UINT STDCALL
-GetTempFileNameA(LPCSTR lpPathName,
-                LPCSTR lpPrefixString,
-                UINT uUnique,
-                LPSTR lpTempFileName)
-{
-   HANDLE hFile;
-   UINT unique = uUnique;
-   UINT len;
-   const char *format = "%.*s\\~%.3s%4.4x.TMP";
-
-   DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
-         "uUnique %x, lpTempFileName %x)\n", lpPathName, 4, 
-         lpPrefixString, uUnique, lpTempFileName);
-  
-   if (lpPathName == NULL)
-     return 0;
 
-   len = strlen(lpPathName);
-   if (len > 0 && (lpPathName[len-1] == '\\' || lpPathName[len-1] == '/'))
-     len--;
 
-   if (uUnique == 0)
-     uUnique = GetCurrentTime();
+/***********************************************************************
+ *           GetTempFileNameA   (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
+{
+   WCHAR BufferW[MAX_PATH];
+   PWCHAR PathW;
+   WCHAR PrefixW[3+1];
+   UINT ret;
    
-   sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
+   if (!(PathW = FilenameA2W(path, FALSE)))
+      return 0;
+    
+   if (prefix)
+      FilenameA2W_N(PrefixW, 3+1, prefix, -1);
    
-   if (unique)
-     return uUnique;
+   ret = GetTempFileNameW(PathW, prefix ? PrefixW : NULL, unique, BufferW);
+    
+   if (ret)
+      FilenameW2A_N(buffer, MAX_PATH, BufferW, -1);
    
-   while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                              CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                              0)) == INVALID_HANDLE_VALUE)
-   {
-      if (GetLastError() != ERROR_FILE_EXISTS)
-      {
-         return 0;
-      }
-      sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
-   }
-   CloseHandle(hFile);
-   return uUnique;
+   return ret;
 }
 
-
-/*
- * @implemented
+/***********************************************************************
+ *           GetTempFileNameW   (KERNEL32.@)
  */
-UINT STDCALL
-GetTempFileNameW(LPCWSTR lpPathName,
-                LPCWSTR lpPrefixString,
-                UINT uUnique,
-                LPWSTR lpTempFileName)
+UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer )
 {
-   HANDLE hFile;
-   UINT unique = uUnique;
-   UINT len;
-   const WCHAR *format = L"%.*s\\~%.3s%4.4x.TMP";
-   
-   DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
-         "uUnique %x, lpTempFileName %x)\n", lpPathName, 4, 
-         lpPrefixString, uUnique, lpTempFileName);
+    static const WCHAR formatW[] = L"%x.tmp";
 
-   if (lpPathName == NULL)
-     return 0;
+    int i;
+    LPWSTR p;
 
-   len = wcslen(lpPathName);
-   if (len > 0 && (lpPathName[len-1] == L'\\' || lpPathName[len-1] == L'/'))
-     len--;
-   
-   if (uUnique == 0)
-     uUnique = GetCurrentTime();
-   
-   swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
-   
-   if (unique)
-     return uUnique;
-  
-   while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                              CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                              0)) == INVALID_HANDLE_VALUE)
-   {
-      if (GetLastError() != ERROR_FILE_EXISTS)
-      {
-         return 0;
-      }
-      swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
-   }
-   CloseHandle(hFile);
-   return uUnique;
+    if ( !path || !prefix || !buffer )
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    wcscpy( buffer, path );
+    p = buffer + wcslen(buffer);
+
+    /* add a \, if there isn't one  */
+    if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\';
+
+    for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
+
+    unique &= 0xffff;
+
+    if (unique) swprintf( p, formatW, unique );
+    else
+    {
+        /* get a "random" unique number and try to create the file */
+        HANDLE handle;
+        UINT num = GetTickCount() & 0xffff;
+
+        if (!num) num = 1;
+        unique = num;
+        do
+        {
+            swprintf( p, formatW, unique );
+            handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL,
+                                  CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+            if (handle != INVALID_HANDLE_VALUE)
+            {  /* We created it */
+                DPRINT("created %S\n", buffer);
+                CloseHandle( handle );
+                break;
+            }
+            if (GetLastError() != ERROR_FILE_EXISTS &&
+                GetLastError() != ERROR_SHARING_VIOLATION)
+                break;  /* No need to go on */
+            if (!(++unique & 0xffff)) unique = 1;
+        } while (unique != num);
+    }
+
+    DPRINT("returning %S\n", buffer);
+    return unique;
 }
 
 
+
+
+
 /*
  * @implemented
  */
@@ -1258,6 +1343,7 @@ SetFileValidData(
 }
 
 
+
 /*
  * @implemented
  */
@@ -1324,10 +1410,7 @@ SetFileShortNameA(
     LPCSTR lpShortName
     )
 {
-  NTSTATUS Status;
-  BOOL Ret;
-  ANSI_STRING ShortNameA;
-  UNICODE_STRING ShortName;
+  PWCHAR ShortNameW;
   
   if(IsConsoleHandle(hFile))
   {
@@ -1341,22 +1424,10 @@ SetFileShortNameA(
     return FALSE;
   }
   
-  RtlInitAnsiString(&ShortNameA, (LPSTR)lpShortName);
-  
-  if(bIsFileApiAnsi)
-    Status = RtlAnsiStringToUnicodeString(&ShortName, &ShortNameA, TRUE);
-  else
-    Status = RtlOemStringToUnicodeString(&ShortName, &ShortNameA, TRUE);
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastErrorByStatus(Status);
-    return FALSE;
-  }
-  
-  Ret = SetFileShortNameW(hFile, ShortName.Buffer);
-  
-  RtlFreeUnicodeString(&ShortName);
-  return Ret;
+  if (!(ShortNameW = FilenameA2W(lpShortName, FALSE)))
+     return FALSE;
+
+  return SetFileShortNameW(hFile, ShortNameW);
 }
 
 
index 522544a..984a2dd 100644 (file)
@@ -200,9 +200,7 @@ CreateHardLinkA(LPCSTR lpFileName,
                 LPCSTR lpExistingFileName,
                 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
-  ANSI_STRING FileNameA, ExistingFileNameA;
-  UNICODE_STRING FileName, ExistingFileName;
-  NTSTATUS Status;
+  PWCHAR FileNameW, ExistingFileNameW;
   BOOL Ret;
   
   if(!lpFileName || !lpExistingFileName)
@@ -211,34 +209,15 @@ CreateHardLinkA(LPCSTR lpFileName,
     return FALSE;
   }
   
-  RtlInitAnsiString(&FileNameA, (LPSTR)lpFileName);
-  RtlInitAnsiString(&ExistingFileNameA, (LPSTR)lpExistingFileName);
-  
-  if(bIsFileApiAnsi)
-    Status = RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
-  else
-    Status = RtlOemStringToUnicodeString(&FileName, &FileNameA, TRUE);
-  if(!NT_SUCCESS(Status))
-  {
-    SetLastErrorByStatus(Status);
+  if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
     return FALSE;
-  }
-  
-  if(bIsFileApiAnsi)
-    Status = RtlAnsiStringToUnicodeString(&ExistingFileName, &ExistingFileNameA, TRUE);
-  else
-    Status = RtlOemStringToUnicodeString(&ExistingFileName, &ExistingFileNameA, TRUE);
-  if(!NT_SUCCESS(Status))
-  {
-    RtlFreeUnicodeString(&FileName);
-    SetLastErrorByStatus(Status);
+
+  if (!(ExistingFileNameW = FilenameA2W(lpExistingFileName, TRUE)))
     return FALSE;
-  }
-  
-  Ret = CreateHardLinkW(FileName.Buffer, ExistingFileName.Buffer, lpSecurityAttributes);
+    
+  Ret = CreateHardLinkW(FileNameW , ExistingFileNameW , lpSecurityAttributes);
   
-  RtlFreeUnicodeString(&FileName);
-  RtlFreeUnicodeString(&ExistingFileName);
+  RtlFreeHeap(RtlGetProcessHeap(), 0, ExistingFileNameW);
   
   return Ret;
 }
index 97cc4a0..797f514 100644 (file)
@@ -39,6 +39,7 @@ LockFile(
    
        Overlapped.Offset = dwFileOffsetLow;
        Overlapped.OffsetHigh = dwFileOffsetHigh;
+   Overlapped.hEvent = NULL;
        dwReserved = 0;
 
        return LockFileEx(hFile, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK,dwReserved,nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &Overlapped ) ;
@@ -57,7 +58,7 @@ LockFileEx(
           DWORD dwReserved,
           DWORD nNumberOfBytesToLockLow,
           DWORD nNumberOfBytesToLockHigh,
-          LPOVERLAPPED lpOverlapped
+          LPOVERLAPPED lpOverlapped /* required! */
           )
 {
    LARGE_INTEGER BytesToLock;  
@@ -66,7 +67,7 @@ LockFileEx(
    NTSTATUS errCode;
    LARGE_INTEGER Offset;
    
-   if(dwReserved != 0) 
+   if(dwReserved != 0 || lpOverlapped==NULL
      {      
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
@@ -91,7 +92,7 @@ LockFileEx(
    BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
    
    errCode = NtLockFile(hFile,
-                       NULL,
+         lpOverlapped->hEvent,
                        NULL,
                        NULL,
                        (PIO_STATUS_BLOCK)lpOverlapped,
@@ -124,13 +125,13 @@ UnlockFile(
           DWORD nNumberOfBytesToUnlockHigh
           )
 {
-       DWORD dwReserved;
        OVERLAPPED Overlapped;
+   DWORD dwReserved;
        Overlapped.Offset = dwFileOffsetLow;
        Overlapped.OffsetHigh = dwFileOffsetHigh;
-       dwReserved = 0;
-       return UnlockFileEx(hFile, dwReserved, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, &Overlapped);
-
+   dwReserved = 0;
+   
+   return UnlockFileEx(hFile, dwReserved, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, &Overlapped);
 }
 
 
@@ -144,19 +145,14 @@ UnlockFileEx(
        DWORD dwReserved,
        DWORD nNumberOfBytesToUnLockLow,
        DWORD nNumberOfBytesToUnLockHigh,
-       LPOVERLAPPED lpOverlapped
+       LPOVERLAPPED lpOverlapped /* required! */
        )
 {
    LARGE_INTEGER BytesToUnLock;
    LARGE_INTEGER StartAddress;
    NTSTATUS errCode;
    
-   if(dwReserved != 0) 
-     {
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-     }
-   if ( lpOverlapped == NULL ) 
+   if(dwReserved != 0 || lpOverlapped == NULL) 
      {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
index c4d7215..a7ae400 100644 (file)
@@ -306,52 +306,25 @@ MoveFileWithProgressA (
        DWORD                   dwFlags
        )
 {
-       UNICODE_STRING ExistingFileNameU;
-       UNICODE_STRING NewFileNameU;
-       ANSI_STRING ExistingFileName;
-       ANSI_STRING NewFileName;
-       BOOL Result;
-
-       RtlInitAnsiString (&ExistingFileName,
-                          (LPSTR)lpExistingFileName);
-
-       RtlInitAnsiString (&NewFileName,
-                          (LPSTR)lpNewFileName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-       {
-               RtlAnsiStringToUnicodeString (&ExistingFileNameU,
-                                             &ExistingFileName,
-                                             TRUE);
-               RtlAnsiStringToUnicodeString (&NewFileNameU,
-                                             &NewFileName,
-                                             TRUE);
-       }
-       else
-       {
-               RtlOemStringToUnicodeString (&ExistingFileNameU,
-                                            &ExistingFileName,
-                                            TRUE);
-               RtlOemStringToUnicodeString (&NewFileNameU,
-                                            &NewFileName,
-                                            TRUE);
-       }
-
-       Result = MoveFileWithProgressW (ExistingFileNameU.Buffer,
-                                       NewFileNameU.Buffer,
+       PWCHAR ExistingFileNameW;
+   PWCHAR NewFileNameW;
+       BOOL ret;
+   
+   if (!(ExistingFileNameW = FilenameA2W(lpExistingFileName, FALSE)))
+      return FALSE;
+
+   if (!(NewFileNameW= FilenameA2W(lpNewFileName, TRUE)))
+      return FALSE;
+
+   ret = MoveFileWithProgressW (ExistingFileNameW ,
+                                   NewFileNameW,
                                        lpProgressRoutine,
                                        lpData,
                                        dwFlags);
 
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    ExistingFileNameU.Buffer);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    NewFileNameU.Buffer);
+   RtlFreeHeap (RtlGetProcessHeap (), 0, NewFileNameW);
 
-       return Result;
+       return ret;
 }
 
 
index 687888b..3d41ff7 100644 (file)
@@ -330,20 +330,15 @@ ConnectNamedPipe(HANDLE hNamedPipe,
                           0,
                           NULL,
                           0);
-  if ((lpOverlapped != NULL) && (Status == STATUS_PENDING))
-    return TRUE;
-
   if ((lpOverlapped == NULL) && (Status == STATUS_PENDING))
     {
       Status = NtWaitForSingleObject(hNamedPipe,
                                     FALSE,
                                     NULL);
-      if (!NT_SUCCESS(Status))
+      if (NT_SUCCESS(Status))
        {
-         SetLastErrorByStatus(Status);
-         return FALSE;
+         Status = Iosb.Status;
        }
-      Status = Iosb.Status;
     }
 
   if ((!NT_SUCCESS(Status) && Status != STATUS_PIPE_CONNECTED) ||
index 2f90342..27a8ea3 100644 (file)
@@ -188,43 +188,19 @@ GetDiskFreeSpaceA (
        LPDWORD lpTotalNumberOfClusters
        )
 {
-       UNICODE_STRING RootPathNameU;
-       ANSI_STRING RootPathName;
-       BOOL Result;
-
-       RtlInitAnsiString (&RootPathName,
-                          (LPSTR)lpRootPathName);
-
-       RtlInitUnicodeString (&RootPathNameU,
-                             NULL);
-
-       if (lpRootPathName)
-       {
-               /* convert ansi (or oem) string to unicode */
-               if (bIsFileApiAnsi)
-                       RtlAnsiStringToUnicodeString (&RootPathNameU,
-                                                     &RootPathName,
-                                                     TRUE);
-               else
-                       RtlOemStringToUnicodeString (&RootPathNameU,
-                                                    &RootPathName,
-                                                    TRUE);
-       }
+   PWCHAR RootPathNameW=NULL;
 
-       Result = GetDiskFreeSpaceW (RootPathNameU.Buffer,
+   if (lpRootPathName)
+   {
+      if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
+         return FALSE;
+   }
+      
+       return GetDiskFreeSpaceW (RootPathNameW,
                                    lpSectorsPerCluster,
                                    lpBytesPerSector,
                                    lpNumberOfFreeClusters,
                                    lpTotalNumberOfClusters);
-
-       if (lpRootPathName)
-       {
-               RtlFreeHeap (RtlGetProcessHeap (),
-                            0,
-                            RootPathNameU.Buffer);
-       }
-
-       return Result;
 }
 
 
@@ -290,48 +266,24 @@ GetDiskFreeSpaceW(
  */
 BOOL STDCALL
 GetDiskFreeSpaceExA (
-       LPCSTR          lpDirectoryName,
+       LPCSTR lpDirectoryName   OPTIONAL,
        PULARGE_INTEGER lpFreeBytesAvailableToCaller,
        PULARGE_INTEGER lpTotalNumberOfBytes,
        PULARGE_INTEGER lpTotalNumberOfFreeBytes
        )
 {
-       UNICODE_STRING DirectoryNameU;
-       ANSI_STRING DirectoryName;
-       BOOL Result;
-
-       RtlInitAnsiString (&DirectoryName,
-                          (LPSTR)lpDirectoryName);
-
-       RtlInitUnicodeString (&DirectoryNameU,
-                             NULL);
+   PWCHAR DirectoryNameW=NULL;
 
        if (lpDirectoryName)
        {
-               /* convert ansi (or oem) string to unicode */
-               if (bIsFileApiAnsi)
-                       RtlAnsiStringToUnicodeString (&DirectoryNameU,
-                                                     &DirectoryName,
-                                                     TRUE);
-               else
-                       RtlOemStringToUnicodeString (&DirectoryNameU,
-                                                    &DirectoryName,
-                                                    TRUE);
+      if (!(DirectoryNameW = FilenameA2W(lpDirectoryName, FALSE)))
+         return FALSE;
        }
 
-       Result = GetDiskFreeSpaceExW (DirectoryNameU.Buffer,
+   return GetDiskFreeSpaceExW (DirectoryNameW ,
                                      lpFreeBytesAvailableToCaller,
                                      lpTotalNumberOfBytes,
                                      lpTotalNumberOfFreeBytes);
-
-       if (lpDirectoryName)
-       {
-               RtlFreeHeap (RtlGetProcessHeap (),
-                            0,
-                            DirectoryNameU.Buffer);
-       }
-
-       return Result;
 }
 
 
@@ -340,7 +292,7 @@ GetDiskFreeSpaceExA (
  */
 BOOL STDCALL
 GetDiskFreeSpaceExW(
-    LPCWSTR lpDirectoryName,
+    LPCWSTR lpDirectoryName OPTIONAL,
     PULARGE_INTEGER lpFreeBytesAvailableToCaller,
     PULARGE_INTEGER lpTotalNumberOfBytes,
     PULARGE_INTEGER lpTotalNumberOfFreeBytes
@@ -353,6 +305,10 @@ GetDiskFreeSpaceExW(
     HANDLE hFile;
     NTSTATUS errCode;
 
+    /*
+    FIXME: this is obviously wrong for UNC paths, symbolic directories etc.
+    -Gunnar
+    */
     if (lpDirectoryName)
     {
         wcsncpy (RootPathName, lpDirectoryName, 3);
@@ -408,30 +364,12 @@ GetDiskFreeSpaceExW(
 UINT STDCALL
 GetDriveTypeA(LPCSTR lpRootPathName)
 {
-       UNICODE_STRING RootPathNameU;
-       ANSI_STRING RootPathName;
-       UINT Result;
-
-       RtlInitAnsiString (&RootPathName,
-                          (LPSTR)lpRootPathName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&RootPathNameU,
-                                             &RootPathName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&RootPathNameU,
-                                            &RootPathName,
-                                            TRUE);
-
-       Result = GetDriveTypeW (RootPathNameU.Buffer);
-
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    RootPathNameU.Buffer);
+   PWCHAR RootPathNameW;
+   
+   if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
+      return DRIVE_UNKNOWN;
 
-       return Result;
+   return GetDriveTypeW(RootPathNameW);
 }
 
 
@@ -505,27 +443,16 @@ GetVolumeInformationA(
        DWORD   nFileSystemNameSize
        )
 {
-  UNICODE_STRING RootPathNameU;
   UNICODE_STRING FileSystemNameU;
   UNICODE_STRING VolumeNameU;
-  ANSI_STRING RootPathName;
   ANSI_STRING VolumeName;
   ANSI_STRING FileSystemName;
+  PWCHAR RootPathNameW;
   BOOL Result;
 
-  RtlInitAnsiString (&RootPathName,
-                    (LPSTR)lpRootPathName);
-
-  /* convert ansi (or oem) string to unicode */
-  if (bIsFileApiAnsi)
-    RtlAnsiStringToUnicodeString (&RootPathNameU,
-                                 &RootPathName,
-                                 TRUE);
-  else
-    RtlOemStringToUnicodeString (&RootPathNameU,
-                                &RootPathName,
-                                TRUE);
-
+  if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
+     return FALSE;
+  
   if (lpVolumeNameBuffer)
     {
       VolumeNameU.Length = 0;
@@ -544,7 +471,7 @@ GetVolumeInformationA(
                                                FileSystemNameU.MaximumLength);
     }
 
-  Result = GetVolumeInformationW (RootPathNameU.Buffer,
+  Result = GetVolumeInformationW (RootPathNameW,
                                  lpVolumeNameBuffer ? VolumeNameU.Buffer : NULL,
                                  nVolumeNameSize,
                                  lpVolumeSerialNumber,
@@ -604,9 +531,6 @@ GetVolumeInformationA(
        }
     }
 
-  RtlFreeHeap (RtlGetProcessHeap (),
-              0,
-              RootPathNameU.Buffer);
   if (lpVolumeNameBuffer)
     {
       RtlFreeHeap (RtlGetProcessHeap (),
@@ -750,49 +674,31 @@ BOOL
 STDCALL
 SetVolumeLabelA (
        LPCSTR  lpRootPathName,
-       LPCSTR  lpVolumeName
+       LPCSTR  lpVolumeName /* NULL if deleting label */
        )
 {
-       UNICODE_STRING RootPathNameU;
-       ANSI_STRING RootPathName;
-       UNICODE_STRING VolumeNameU;
-       ANSI_STRING VolumeName;
+       PWCHAR RootPathNameW;
+   PWCHAR VolumeNameW = NULL;
        BOOL Result;
 
-       RtlInitAnsiString (&RootPathName,
-                          (LPSTR)lpRootPathName);
-       RtlInitAnsiString (&VolumeName,
-                          (LPSTR)lpVolumeName);
-
-       /* convert ansi (or oem) strings to unicode */
-       if (bIsFileApiAnsi)
-       {
-               RtlAnsiStringToUnicodeString (&RootPathNameU,
-                                             &RootPathName,
-                                             TRUE);
-               RtlAnsiStringToUnicodeString (&VolumeNameU,
-                                             &VolumeName,
-                                             TRUE);
-       }
-       else
-       {
-               RtlOemStringToUnicodeString (&RootPathNameU,
-                                            &RootPathName,
-                                            TRUE);
-               RtlOemStringToUnicodeString (&VolumeNameU,
-                                            &VolumeName,
-                                            TRUE);
-       }
+   if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
+      return FALSE;
 
-       Result = SetVolumeLabelW (RootPathNameU.Buffer,
-                                 VolumeNameU.Buffer);
+   if (lpVolumeName)
+   {
+      if (!(VolumeNameW = FilenameA2W(lpVolumeName, TRUE)))
+         return FALSE;
+   }
+      
+   Result = SetVolumeLabelW (RootPathNameW,
+                             VolumeNameW);
 
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    RootPathNameU.Buffer);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    VolumeNameU.Buffer);
+   if (VolumeNameW)
+   {
+          RtlFreeHeap (RtlGetProcessHeap (),
+                       0,
+                   VolumeNameW );
+   }
 
        return Result;
 }
@@ -802,8 +708,10 @@ SetVolumeLabelA (
  * @implemented
  */
 BOOL STDCALL
-SetVolumeLabelW(LPCWSTR lpRootPathName,
-               LPCWSTR lpVolumeName)
+SetVolumeLabelW(
+   LPCWSTR lpRootPathName,
+   LPCWSTR lpVolumeName /* NULL if deleting label */
+   )
 {
    PFILE_FS_LABEL_INFORMATION LabelInfo;
    IO_STATUS_BLOCK IoStatusBlock;
index b4515c0..c659c87 100755 (executable)
@@ -60,5 +60,15 @@ HANDLE STDCALL OpenConsoleW (LPWSTR wsName,
 
 PTEB GetTeb(VOID);
 
+
+PWCHAR FilenameA2W(LPCSTR NameA, BOOL alloc);
+   
+DWORD FilenameW2A_FitOrFail(LPSTR  DestA, INT destLen, LPCWSTR SourceW, INT sourceLen);
+DWORD FilenameU2A_FitOrFail(LPSTR  DestA, INT destLen, PUNICODE_STRING SourceU);
+
+
+
+
+
 #endif /* ndef _KERNEL32_INCLUDE_KERNEL32_H */
 
index d4d562b..315f50f 100644 (file)
@@ -73,6 +73,7 @@
                <file>time.c</file>\r
                <file>timerqueue.c</file>\r
                <file>toolhelp.c</file>\r
+               <file>version.c</file>\r
        </directory>\r
        <directory name="process">\r
                <file>cmdline.c</file>\r
index 4ffc491..89ad6a5 100644 (file)
@@ -35,7 +35,7 @@ MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o \
                misc/sysinfo.o misc/profile.o \
                misc/muldiv.o misc/nls.o misc/computername.o \
                misc/perfcnt.o misc/lzexpand_main.o misc/lcformat.o \
-               misc/chartype.o
+               misc/chartype.o misc/version.o
 
 FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
                file/iocompl.o file/volume.o file/deviceio.o file/dosdev.o \
index 7d6b1d3..0f0c9f5 100644 (file)
@@ -7,10 +7,15 @@
  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
  *                  modified from WINE [ Onno Hovers, (onno@stack.urc.tue.nl) ]
  *                                     Robert Dickenson (robd@mok.lvcom.com)
+ *                                     Saveliy Tretiakov (saveliyt@mail.ru)
  * UPDATE HISTORY:
  *                  Created 01/11/98
- *                                     RDD (30/09/2002) implemented many function bodies to call serial driver.
- *                                      KJK (11/02/2003) implemented BuildCommDCB & BuildCommDCBAndTimeouts
+ *                  RDD (30/09/2002) implemented many function bodies to call serial driver.
+ *                  KJK (11/02/2003) implemented BuildCommDCB & BuildCommDCBAndTimeouts
+ *                  ST  (21/03/2005) implemented GetCommProperties 
+ *                  ST  (24/03/2005) implemented ClearCommError. Corrected many functions.
+ *                  ST  (05/04/2005) implemented CommConfigDialog
+ *                                      
  */
 
 #include <k32.h>
 /* TYPES */
 
 /* Pointer to a callback that handles a particular parameter */
-typedef BOOL (*COMMDCB_PARAM_CALLBACK)
-(
- DCB *,
- COMMTIMEOUTS *,
- BOOL *,
- LPWSTR *
-);
+typedef BOOL (*COMMDCB_PARAM_CALLBACK)(DCB *, COMMTIMEOUTS *, BOOL *, LPWSTR *);
 
 /* Symbolic flag of any length */
 typedef struct _COMMDCB_PARAM_STRFLAG
 {
- UNICODE_STRING String;
- ULONG_PTR Value;
-} COMMDCB_PARAM_STRFLAG;
   UNICODE_STRING String;
   ULONG_PTR Value;
+} COMMDCB_PARAM_STRFLAG, *PCOMMDCB_PARAM_STRFLAG;
 
 /* One char long symbolic flag */
 typedef struct _COMMDCB_PARAM_CHARFLAG
 {
- WCHAR Char;
- ULONG_PTR Value;
-} COMMDCB_PARAM_CHARFLAG;
   WCHAR Char;
   ULONG_PTR Value;
+} COMMDCB_PARAM_CHARFLAG, *PCOMMDCB_PARAM_CHARFLAG;
 
 /* MACROS */
-/* stupid Borland C++ requires this */
-#define _L(__S__) L ## __S__
 
 /* Declare a parameter handler */
 #define COMMDCB_PARAM_HANDLER(__P__) \
  BOOL COMMDCB_ ## __P__ ## Param \
  ( \
-  DCB * Dcb, \
-  COMMTIMEOUTS * Timeouts, \
-  BOOL * StopBitsSet, \
-  LPWSTR * StrTail \
+     DCB * Dcb, \
+     COMMTIMEOUTS * Timeouts, \
+     BOOL *StopBitsSet, \
+     LPWSTR *StrTail \
  )
 
 /* UTILITIES */
@@ -64,67 +61,54 @@ typedef struct _COMMDCB_PARAM_CHARFLAG
  Lookup a string flag and return its numerical value. The flags array must be
  sorted - a dichotomycal search is performed
 */
-BOOL COMMDCB_LookupStrFlag
-(
- UNICODE_STRING * Flag,
- COMMDCB_PARAM_STRFLAG * Flags,
- int FlagCount,
- ULONG_PTR * Value
-)
+static BOOL
+COMMDCB_LookupStrFlag(PUNICODE_STRING Flag,
+                      PCOMMDCB_PARAM_STRFLAG Flags,
+                      int FlagCount,
+                      PULONG_PTR Value)
 {
- /* Lower and upper bound for dichotomycal search */
- int nLowerBound = 0;
- int nUpperBound = FlagCount - 1;
-
- do
- {
-  LONG nComparison;
-  /* pick the element in the middle of the area of interest as the pivot */
-  int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
-
-  /* compare the string with the pivot */
-  nComparison = RtlCompareUnicodeString
-  (
-   Flag,
-   &Flags[nCurFlag].String,
-   TRUE
-  );
-
-  /* string is equal */
-  if(nComparison == 0)
-  {
-   /* return the flag's value */
-   *Value = Flags[nCurFlag].Value;
-
-   /* success */
-   return TRUE;
-  }
-  /* string is less than */
-  else if(nComparison < 0)
-  {
-   /*
-    restrict the search to the first half of the current slice, minus the pivot
-   */
-   nUpperBound = nCurFlag - 1;
-
-   /* fallthrough */
-  }
-  /* string is greater than */
-  else
-  {
-   /*
-    restrict the search to the second half of the current slice, minus the pivot
-   */
-   nLowerBound = nCurFlag + 1;
-
-   /* fallthrough */
-  }
- }
- /* continue until the slice is empty */
- while(nLowerBound <= nUpperBound);
-
- /* string not found: failure */
- return FALSE;
+    /* Lower and upper bound for dichotomycal search */
+    int nLowerBound = 0;
+    int nUpperBound = FlagCount - 1;
+
+    do
+    {
+        LONG nComparison;
+        /* pick the element in the middle of the area of interest as the pivot */
+        int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
+
+        /* compare the string with the pivot */
+        nComparison = RtlCompareUnicodeString(Flag,
+                                              &Flags[nCurFlag].String,
+                                              TRUE);
+
+        /* string is equal */
+        if(nComparison == 0)
+        {
+            /* return the flag's value */
+            *Value = Flags[nCurFlag].Value;
+
+            /* success */
+            return TRUE;
+        }
+        else if(nComparison < 0)
+        {
+            /*
+             * restrict the search to the first half of the current slice, minus the pivot
+             */
+            nUpperBound = nCurFlag - 1;
+        }
+        else
+        {
+            /*
+             * restrict the search to the second half of the current slice, minus the pivot
+             */
+            nLowerBound = nCurFlag + 1;
+        }
+    } while(nLowerBound <= nUpperBound);
+
+    /* string not found: failure */
+    return FALSE;
 }
 
 /* PARSERS */
@@ -132,624 +116,636 @@ BOOL COMMDCB_LookupStrFlag
  Find the next character flag and return its numerical value. The flags array
  must be sorted - a dichotomycal search is performed
 */
-BOOL COMMDCB_ParseCharFlag
-(
- LPWSTR * StrTail,
- COMMDCB_PARAM_CHARFLAG * Flags,
- int FlagCount,
- ULONG_PTR * Value
-)
+static BOOL
+COMMDCB_ParseCharFlag(LPWSTR *StrTail,
+                      PCOMMDCB_PARAM_CHARFLAG Flags,
+                      int FlagCount,
+                      PULONG_PTR Value)
 {
- /* Lower and upper bound for dichotomycal search */
- int nLowerBound = 0;
- int nUpperBound = FlagCount - 1;
- /* get the first character as the flag */
- WCHAR wcFlag = (*StrTail)[0];
-
- /* premature end of string, or the character is whitespace */
- if(!wcFlag || iswspace(wcFlag))
-  /* failure */
-  return FALSE;
+    /* Lower and upper bound for dichotomycal search */
+    int nLowerBound = 0;
+    int nUpperBound = FlagCount - 1;
+    /* get the first character as the flag */
+    WCHAR wcFlag = (*StrTail)[0];
+
+    /* premature end of string, or the character is whitespace */
+    if(!wcFlag || iswspace(wcFlag))
+        return FALSE;
  
- /* uppercase the character for case-insensitive search */
- wcFlag = towupper(wcFlag);
   /* uppercase the character for case-insensitive search */
   wcFlag = towupper(wcFlag);
 
- /* skip the character flag */
++ (*StrTail);
   /* skip the character flag */
   (*StrTail)++;
 
- /* see COMMDCB_LookupStrFlag for a description of the algorithm */
- do
- {
-  LONG nComparison;
-  int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
   /* see COMMDCB_LookupStrFlag for a description of the algorithm */
   do
   {
+        LONG nComparison;
+        int nCurFlag = nLowerBound + (nUpperBound - nLowerBound) / 2;
 
-  nComparison = wcFlag - towupper(Flags[nCurFlag].Char);
+        nComparison = wcFlag - towupper(Flags[nCurFlag].Char);
 
-  if(nComparison == 0)
-  {
-   *Value = Flags[nCurFlag].Value;
+        if(nComparison == 0)
+        {
+            *Value = Flags[nCurFlag].Value;
     
-   return TRUE;
-  }
-  else if(nComparison < 0)
-  {
-   nUpperBound = nCurFlag - 1;
-  }
-  else
-  {
-   nLowerBound = nCurFlag + 1;
-  }
- }
- while(nUpperBound >= nLowerBound);
-
- /* flag not found: failure */
- return FALSE;
+            return TRUE;
+        }
+        else if(nComparison < 0)
+        {
+            nUpperBound = nCurFlag - 1;
+        }
+        else
+        {
+            nLowerBound = nCurFlag + 1;
+        }
+    } while(nUpperBound >= nLowerBound);
+
+    /* flag not found: failure */
+    return FALSE;
 }
 
 /*
  Find the next string flag and return its numerical value. The flags array must
  be sorted - a dichotomycal search is performed
 */
-BOOL COMMDCB_ParseStrFlag
-(
- LPWSTR * StrTail,
- COMMDCB_PARAM_STRFLAG * Flags,
- int FlagCount,
- ULONG_PTR * Value
-)
+static BOOL
+COMMDCB_ParseStrFlag(LPWSTR *StrTail,
+                     PCOMMDCB_PARAM_STRFLAG Flags,
+                     int FlagCount,
+                     PULONG_PTR Value)
 {
LPWSTR pwcNewTail = *StrTail;
- UNICODE_STRING wstrFlag;
   LPWSTR pwcNewTail;
   UNICODE_STRING wstrFlag;
 
- /* scan the string until the first space character or the terminating null */
- while(pwcNewTail[0] && !iswspace(pwcNewTail[0]))
-  ++ pwcNewTail;
+    /* scan the string until the first space character or the terminating null */
+    for(pwcNewTail = *StrTail;
+        pwcNewTail[0] && !iswspace(pwcNewTail[0]);
+        pwcNewTail++);
 
- /* string flag empty */
- if(pwcNewTail == *StrTail)
-  /* failure */
-  return FALSE;
+    /* string flag empty */
+    if(pwcNewTail == *StrTail)
+        return FALSE;
 
- /* build the UNICODE_STRING description of the string flag */
- wstrFlag.Buffer = *StrTail;
- wstrFlag.Length = (pwcNewTail - *StrTail) * sizeof(WCHAR);
- wstrFlag.MaximumLength = wstrFlag.Length;
   /* build the UNICODE_STRING description of the string flag */
   wstrFlag.Buffer = *StrTail;
   wstrFlag.Length = (pwcNewTail - *StrTail) * sizeof(WCHAR);
   wstrFlag.MaximumLength = wstrFlag.Length;
 
- /* skip the string flag */
- *StrTail = pwcNewTail;
   /* skip the string flag */
   *StrTail = pwcNewTail;
 
- /* lookup the string flag's value and return it */
- return COMMDCB_LookupStrFlag(&wstrFlag, Flags, FlagCount, Value);
   /* lookup the string flag's value and return it */
   return COMMDCB_LookupStrFlag(&wstrFlag, Flags, FlagCount, Value);
 }
 
 /*
  Parse a boolean value in the symbolic form on/off
 */
-BOOL COMMDCB_ParseBool(LPWSTR * StrTail, BOOL * Value)
+static BOOL
+COMMDCB_ParseBool(LPWSTR *StrTail,
+                  PBOOL Value)
 {
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_BoolFlags[] =
- {
-  { ROS_STRING_INITIALIZER(L"off"), FALSE },
-  { ROS_STRING_INITIALIZER(L"on"),  TRUE }
- };
-
- /* try to recognize the next flag as a boolean */
- bRetVal = COMMDCB_ParseStrFlag
- (
-  StrTail,
-  a_BoolFlags,
-  sizeof(a_BoolFlags) / sizeof(a_BoolFlags[0]),
-  &nValue
- );
-
- /* failure */
- if(!bRetVal) return FALSE;
-
- /* success */
- *Value = nValue ? TRUE : FALSE;
- return TRUE;
+    BOOL bRetVal;
+    ULONG_PTR nValue;
+    static COMMDCB_PARAM_STRFLAG a_BoolFlags[] = {
+       { ROS_STRING_INITIALIZER(L"off"), FALSE },
+       { ROS_STRING_INITIALIZER(L"on"),  TRUE }
+    };
+
+    /* try to recognize the next flag as a boolean */
+    bRetVal = COMMDCB_ParseStrFlag(StrTail,
+                                   a_BoolFlags,
+                                   sizeof(a_BoolFlags) / sizeof(a_BoolFlags[0]),
+                                   &nValue);
+
+
+    if(!bRetVal)
+        return FALSE;
+
+    /* success */
+    *Value = (nValue ? TRUE : FALSE);
+    return TRUE;
 }
 
 /*
  Parse a decimal integer
 */
-BOOL COMMDCB_ParseInt(LPWSTR * StrTail, DWORD * Value)
+static BOOL
+COMMDCB_ParseInt(LPWSTR *StrTail,
+                 DWORD *Value)
 {
- LPWSTR pwcPrevTail = *StrTail;
- DWORD nValue = wcstoul(*StrTail, StrTail, 10);
   LPWSTR pwcPrevTail = *StrTail;
   DWORD nValue = wcstoul(*StrTail, StrTail, 10);
  
- /* no character was consumed: failure */
- if(pwcPrevTail == *StrTail) return FALSE;
+    /* no character was consumed: failure */
+    if(pwcPrevTail == *StrTail)
+        return FALSE;
 
- /* success */
- *Value = nValue;
- return TRUE;
   /* success */
   *Value = nValue;
   return TRUE;
 }
 
 /* PARAMETER HANDLERS */
 /* baud= */
 COMMDCB_PARAM_HANDLER(baud)
 {
- DWORD nValue;
   DWORD nValue;
  
- (void)Timeouts;
-
- /* parse the baudrate */
- if(!COMMDCB_ParseInt(StrTail, &nValue))
-  /* failure */
-  return FALSE;
-
- switch(nValue)
- {
-  /* documented abbreviations */
-  case 11: Dcb->BaudRate = 110; break;
-  case 15: Dcb->BaudRate = 150; break;
-  case 30: Dcb->BaudRate = 300; break;
-  case 60: Dcb->BaudRate = 600; break;
-  case 12: Dcb->BaudRate = 1200; break;
-  case 24: Dcb->BaudRate = 2400; break;
-  case 48: Dcb->BaudRate = 4800; break;
-  case 96: Dcb->BaudRate = 9600; break;
-  case 19: Dcb->BaudRate = 19200; break;
-  /* literal value */
-  default: Dcb->BaudRate = nValue; break;
- }
-
- /* if the stop bits haven't been specified explicitely */
- if(!(*StopBitsSet))
- {
-  /* default the stop bits to 2 for 110 baud */
-  if(Dcb->BaudRate == 110) Dcb->StopBits = TWOSTOPBITS;
-  /* else, default the stop bits to 1 */  
-  else Dcb->StopBits = ONESTOPBIT;
- }
-
- /* success */
- return TRUE;
+    (void)Timeouts;
+
+    /* parse the baudrate */
+    if(!COMMDCB_ParseInt(StrTail, &nValue))
+        return FALSE;
+
+    switch(nValue)
+    {
+        /* documented abbreviations */
+        case 11:
+            Dcb->BaudRate = 110;
+            break;
+        case 15:
+            Dcb->BaudRate = 150;
+            break;
+        case 30:
+            Dcb->BaudRate = 300;
+            break;
+        case 60:
+            Dcb->BaudRate = 600;
+            break;
+        case 12:
+            Dcb->BaudRate = 1200;
+            break;
+        case 24:
+            Dcb->BaudRate = 2400;
+            break;
+        case 48:
+            Dcb->BaudRate = 4800;
+            break;
+        case 96:
+            Dcb->BaudRate = 9600;
+            break;
+        case 19:
+            Dcb->BaudRate = 19200;
+            break;
+
+        /* literal value */
+        default:
+            Dcb->BaudRate = nValue;
+            break;
+    }
+
+    /* if the stop bits haven't been specified explicitely */
+    if(!(*StopBitsSet))
+    {
+        /* default the stop bits to 2 for 110 baud */
+        if(Dcb->BaudRate == 110)
+            Dcb->StopBits = TWOSTOPBITS;
+        /* else, default the stop bits to 1 */
+        else
+            Dcb->StopBits = ONESTOPBIT;
+    }
+
+    /* success */
+    return TRUE;
 }
 
 /* data= */
 COMMDCB_PARAM_HANDLER(data)
 {
- DWORD nValue;
   DWORD nValue;
 
- (void)Timeouts;
- (void)StopBitsSet;
   (void)Timeouts;
   (void)StopBitsSet;
 
- /* parse the data bits */
- if(!COMMDCB_ParseInt(StrTail, &nValue))
-  /* failure */
-  return FALSE;
+    /* parse the data bits */
+    if(!COMMDCB_ParseInt(StrTail, &nValue))
+        return FALSE;
 
- /* value out of range: failure */
- if(nValue < 5 || nValue > 8) return FALSE;
+    /* value out of range: failure */
+    if(nValue < 5 || nValue > 8)
+        return FALSE;
   
- /* success */
- Dcb->ByteSize = nValue;
- return TRUE;
   /* success */
   Dcb->ByteSize = nValue;
   return TRUE;
 }
 
 /* dtr= */
 COMMDCB_PARAM_HANDLER(dtr)
 {
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_DTRFlags[] =
- {
-  { ROS_STRING_INITIALIZER(L"hs"),  DTR_CONTROL_HANDSHAKE },
-  { ROS_STRING_INITIALIZER(L"off"), DTR_CONTROL_DISABLE },
-  { ROS_STRING_INITIALIZER(L"on"),  DTR_CONTROL_ENABLE }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseStrFlag
- (
-  StrTail,
-  a_DTRFlags,
-  sizeof(a_DTRFlags) / sizeof(a_DTRFlags[0]),
-  &nValue
- );
-
- /* failure */
- if(!bRetVal) return FALSE;
-
- /* success */
- Dcb->fDtrControl = nValue;
- return TRUE;
+    BOOL bRetVal;
+    ULONG_PTR nValue;
+    static COMMDCB_PARAM_STRFLAG a_DTRFlags[] = {
+        { ROS_STRING_INITIALIZER(L"hs"),  DTR_CONTROL_HANDSHAKE },
+        { ROS_STRING_INITIALIZER(L"off"), DTR_CONTROL_DISABLE },
+        { ROS_STRING_INITIALIZER(L"on"),  DTR_CONTROL_ENABLE }
+    };
+
+    (void)Timeouts;
+    (void)StopBitsSet;
+
+    /* parse the flag */
+    bRetVal = COMMDCB_ParseStrFlag(StrTail,
+                                   a_DTRFlags,
+                                   sizeof(a_DTRFlags) / sizeof(a_DTRFlags[0]),
+                                   &nValue);
+
+    /* failure */
+    if(!bRetVal)
+        return FALSE;
+
+    /* success */
+    Dcb->fDtrControl = nValue;
+    return TRUE;
 }
 
 /* idsr= */
 COMMDCB_PARAM_HANDLER(idsr)
 {
- BOOL bValue;
   BOOL bValue;
  
- (void)Timeouts;
- (void)StopBitsSet;
   (void)Timeouts;
   (void)StopBitsSet;
 
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
-  /* failure */
-  return FALSE;
+    /* parse the flag */
+    if(!COMMDCB_ParseBool(StrTail, &bValue))
+       return FALSE;
 
- /* success */
- Dcb->fDsrSensitivity = bValue;
- return TRUE;
   /* success */
   Dcb->fDsrSensitivity = bValue;
   return TRUE;
 }
 
 /* octs= */
 COMMDCB_PARAM_HANDLER(octs)
 {
- BOOL bValue;
   BOOL bValue;
 
- (void)Timeouts;
- (void)StopBitsSet;
   (void)Timeouts;
   (void)StopBitsSet;
 
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
-  /* failure */
-  return FALSE;
+    /* parse the flag */
+    if(!COMMDCB_ParseBool(StrTail, &bValue))
+        return FALSE;
 
- /* success */
- Dcb->fOutxCtsFlow = bValue;
- return TRUE;
   /* success */
   Dcb->fOutxCtsFlow = bValue;
   return TRUE;
 }
 
 /* odsr= */
 COMMDCB_PARAM_HANDLER(odsr)
 {
- BOOL bValue;
   BOOL bValue;
 
- (void)Timeouts;
- (void)StopBitsSet;
   (void)Timeouts;
   (void)StopBitsSet;
 
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
-  /* failure */
-  return FALSE;
+    /* parse the flag */
+    if(!COMMDCB_ParseBool(StrTail, &bValue))
+        return FALSE;
 
- /* success */
- Dcb->fOutxDsrFlow = bValue;
- return TRUE;
   /* success */
   Dcb->fOutxDsrFlow = bValue;
   return TRUE;
 }
 
 /* parity= */
 COMMDCB_PARAM_HANDLER(parity)
 {
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_CHARFLAG a_ParityFlags[] =
- {
-  { L'e', EVENPARITY },
-  { L'm', MARKPARITY },
-  { L'n', NOPARITY },
-  { L'o', ODDPARITY },
-  { L's', SPACEPARITY }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseCharFlag
- (
-  StrTail,
-  a_ParityFlags,
-  sizeof(a_ParityFlags) / sizeof(a_ParityFlags[0]),
-  &nValue
- );
-
- /* failure */
- if(!bRetVal) return FALSE;
-
- /* success */
- Dcb->Parity = nValue;
- return TRUE;
+    BOOL bRetVal;
+    ULONG_PTR nValue;
+    static COMMDCB_PARAM_CHARFLAG a_ParityFlags[] = {
+        { L'e', EVENPARITY },
+        { L'm', MARKPARITY },
+        { L'n', NOPARITY },
+        { L'o', ODDPARITY },
+        { L's', SPACEPARITY }
+    };
+
+    (void)Timeouts;
+    (void)StopBitsSet;
+
+    /* parse the flag */
+    bRetVal = COMMDCB_ParseCharFlag(StrTail,
+                                    a_ParityFlags,
+                                    sizeof(a_ParityFlags) / sizeof(a_ParityFlags[0]),
+                                    &nValue);
+
+    /* failure */
+    if(!bRetVal)
+        return FALSE;
+
+    /* success */
+    Dcb->Parity = nValue;
+    return TRUE;
 }
 
 /* rts= */
 COMMDCB_PARAM_HANDLER(rts)
 {
- DWORD nRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_RTSFlags[] =
- {
-  { ROS_STRING_INITIALIZER(L"hs"),  RTS_CONTROL_HANDSHAKE },
-  { ROS_STRING_INITIALIZER(L"off"), RTS_CONTROL_DISABLE },
-  { ROS_STRING_INITIALIZER(L"on"),  RTS_CONTROL_ENABLE },
-  { ROS_STRING_INITIALIZER(L"tg"),  RTS_CONTROL_TOGGLE }
- };
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- nRetVal = COMMDCB_ParseStrFlag
- (
-  StrTail,
-  a_RTSFlags,
-  sizeof(a_RTSFlags) / sizeof(a_RTSFlags[0]),
-  &nValue
- );
-
- /* failure */
- if(!nRetVal) return FALSE;
-
- /* success */
- Dcb->fRtsControl = nValue;
- return TRUE;
+    DWORD nRetVal;
+    ULONG_PTR nValue;
+    static COMMDCB_PARAM_STRFLAG a_RTSFlags[] = {
+        { ROS_STRING_INITIALIZER(L"hs"),  RTS_CONTROL_HANDSHAKE },
+        { ROS_STRING_INITIALIZER(L"off"), RTS_CONTROL_DISABLE },
+        { ROS_STRING_INITIALIZER(L"on"),  RTS_CONTROL_ENABLE },
+        { ROS_STRING_INITIALIZER(L"tg"),  RTS_CONTROL_TOGGLE }
+    };
+
+    (void)Timeouts;
+    (void)StopBitsSet;
+
+    /* parse the flag */
+    nRetVal = COMMDCB_ParseStrFlag(StrTail,
+                                   a_RTSFlags,
+                                   sizeof(a_RTSFlags) / sizeof(a_RTSFlags[0]),
+                                   &nValue);
+
+    /* failure */
+    if(!nRetVal)
+        return FALSE;
+
+    /* success */
+    Dcb->fRtsControl = nValue;
+    return TRUE;
 }
 
 /* stop= */
 COMMDCB_PARAM_HANDLER(stop)
 {
- BOOL bRetVal;
- ULONG_PTR nValue;
- static COMMDCB_PARAM_STRFLAG a_StopFlags[] =
- {
-  { ROS_STRING_INITIALIZER(L"1"),   ONESTOPBIT },
-  { ROS_STRING_INITIALIZER(L"1.5"), ONE5STOPBITS },
-  { ROS_STRING_INITIALIZER(L"2"),   TWOSTOPBITS }
- };
-
- (void)Timeouts;
-
- /* parse the flag */
- bRetVal = COMMDCB_ParseStrFlag
- (
-  StrTail,
-  a_StopFlags,
-  sizeof(a_StopFlags) / sizeof(a_StopFlags[0]),
-  &nValue
- );
-
- /* failure */
- if(!bRetVal) return FALSE;
-
- /* tell the baud= handler that the stop bits have been specified explicitely */
- *StopBitsSet = TRUE;
-
- /* success */
- Dcb->StopBits = nValue;
- return TRUE;
+    BOOL bRetVal;
+    ULONG_PTR nValue;
+    static COMMDCB_PARAM_STRFLAG a_StopFlags[] = {
+        { ROS_STRING_INITIALIZER(L"1"),   ONESTOPBIT },
+        { ROS_STRING_INITIALIZER(L"1.5"), ONE5STOPBITS },
+        { ROS_STRING_INITIALIZER(L"2"),   TWOSTOPBITS }
+    };
+
+    (void)Timeouts;
+
+    /* parse the flag */
+    bRetVal = COMMDCB_ParseStrFlag(StrTail,
+                                   a_StopFlags,
+                                   sizeof(a_StopFlags) / sizeof(a_StopFlags[0]),
+                                   &nValue);
+
+    /* failure */
+    if(!bRetVal)
+        return FALSE;
+
+    /* tell the baud= handler that the stop bits have been specified explicitely */
+    *StopBitsSet = TRUE;
+
+    /* success */
+    Dcb->StopBits = nValue;
+    return TRUE;
 }
 
 /* to= */
 COMMDCB_PARAM_HANDLER(to)
 {
- BOOL bValue;
-
- (void)Dcb;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
-  /* failure */
-  return FALSE;
-
- /* for BuildCommDCB(), Timeouts is NULL */
- if(Timeouts)
- {
-  /* why? no idea. All values taken from Windows 2000 with experimentation */
-  Timeouts->ReadIntervalTimeout = 0;
-  Timeouts->ReadTotalTimeoutMultiplier = 0;
-  Timeouts->ReadTotalTimeoutConstant = 0;
-  Timeouts->WriteTotalTimeoutMultiplier = 0;
-
-  /* timeout */
-  if(bValue) Timeouts->WriteTotalTimeoutConstant = 60000;
-  /* no timeout */
-  else Timeouts->WriteTotalTimeoutConstant = 0;
- }
-
- /* success */
- return TRUE;
+    BOOL bValue;
+
+    (void)Dcb;
+    (void)StopBitsSet;
+
+    /* parse the flag */
+    if(!COMMDCB_ParseBool(StrTail, &bValue))
+        return FALSE;
+
+    /* for BuildCommDCB(), Timeouts is NULL */
+    if(Timeouts)
+    {
+        /* why? no idea. All values taken from Windows 2000 with experimentation */
+        Timeouts->ReadIntervalTimeout = 0;
+        Timeouts->ReadTotalTimeoutMultiplier = 0;
+        Timeouts->ReadTotalTimeoutConstant = 0;
+        Timeouts->WriteTotalTimeoutMultiplier = 0;
+
+        if(bValue)
+        {
+            /* timeout */
+            Timeouts->WriteTotalTimeoutConstant = 60000;
+        }
+        else
+        {
+            /* no timeout */
+            Timeouts->WriteTotalTimeoutConstant = 0;
+        }
+    }
+
+    /* success */
+    return TRUE;
 }
 
 /* xon= */
 COMMDCB_PARAM_HANDLER(xon)
 {
- BOOL bValue;
-
- (void)Timeouts;
- (void)StopBitsSet;
-
- /* parse the flag */
- if(!COMMDCB_ParseBool(StrTail, &bValue))
-  /* failure */
-  return FALSE;
-
- /* XON/XOFF */
- if(bValue) Dcb->fInX = Dcb->fOutX = TRUE;
- /* no XON/XOFF */
- else Dcb->fInX = Dcb->fOutX = FALSE;
-
- /* success */
- return TRUE;
+    BOOL bValue;
+
+    (void)Timeouts;
+    (void)StopBitsSet;
+
+    /* parse the flag */
+    if(!COMMDCB_ParseBool(StrTail, &bValue))
+        return FALSE;
+
+    if(bValue)
+    {
+        /* XON/XOFF */
+        Dcb->fInX = Dcb->fOutX = TRUE;
+    }
+    else
+    {
+        /* no XON/XOFF */
+        Dcb->fInX = Dcb->fOutX = FALSE;
+    }
+
+    /* success */
+    return TRUE;
 }
 
 /* FUNCTIONS */
 #define COMMDCB_PARAM(__P__) \
  { \
-  ROS_STRING_INITIALIZER(_L(#__P__)), \
+  ROS_STRING_INITIALIZER( L""#__P__ ), \
   (ULONG_PTR)&COMMDCB_ ## __P__ ## Param \
  }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
-BuildCommDCBAndTimeoutsW
-(
- LPCWSTR lpDef,
- LPDCB lpDCB,
- LPCOMMTIMEOUTS lpCommTimeouts
-)
+BuildCommDCBAndTimeoutsW(LPCWSTR lpDef,
+                         LPDCB lpDCB,
+                         LPCOMMTIMEOUTS lpCommTimeouts)
 {
- /* tell the baud= handler that the stop bits should be defaulted */
- BOOL bStopBitsSet = FALSE;
-
- /* parameter validation */
- if(lpDCB->DCBlength != sizeof(DCB)) goto InvalidParam;
-
- /* set defaults */
- lpDCB->StopBits = ONESTOPBIT;
-
- /*
-  The documentation for MODE says that data= defaults to 7, but BuildCommDCB
-  doesn't seem to set it
- */
- /* lpDCB->ByteSize = 7; */
-
- /* skip COMx[n] */
- if
- (
-  lpDef[0] &&
-  towupper(lpDef[0]) == L'C' &&
-  lpDef[1] &&
-  towupper(lpDef[1]) == L'O' &&
-  lpDef[2] &&
-  towupper(lpDef[2]) == L'M'
- )
- {
-  DWORD nDummy;
-
-  /* skip "COM" */
-  lpDef += 3;
-
-  /* premature end of string */
-  if(!lpDef[0]) goto InvalidParam;
-
-  /* skip "x" */
-  if(!COMMDCB_ParseInt((LPWSTR *)&lpDef, &nDummy)) goto InvalidParam;
-
-  /* skip ":" */
-  if(lpDef[0] == L':') ++ lpDef;
- }
-
- /* skip leading whitespace */
- while(lpDef[0] && iswspace(lpDef[0])) ++ lpDef;
-
- /* repeat until the end of the string */
- while(lpDef[0])
- {
-  static COMMDCB_PARAM_STRFLAG a_Params[] =
-  {
-   COMMDCB_PARAM(baud),
-   COMMDCB_PARAM(data),
-   COMMDCB_PARAM(dtr),
-   COMMDCB_PARAM(idsr),
-   COMMDCB_PARAM(octs),
-   COMMDCB_PARAM(odsr),
-   COMMDCB_PARAM(parity),
-   COMMDCB_PARAM(rts),
-   COMMDCB_PARAM(stop),
-   COMMDCB_PARAM(to),
-   COMMDCB_PARAM(xon)
-  };
-  BOOL bRetVal;
-  COMMDCB_PARAM_CALLBACK pCallback;
-  UNICODE_STRING wstrParam;
-  LPWSTR pwcPrevTail = (LPWSTR)lpDef;
-
-  /* get the parameter */
-  while(lpDef[0] && lpDef[0] != L'=') ++ lpDef;
-
-  /* premature end of string */
-  if(!lpDef[0]) goto InvalidParam;
-
-  /* build the parameter's UNICODE_STRING */
-  wstrParam.Buffer = pwcPrevTail;
-  wstrParam.Length = (lpDef - pwcPrevTail) * sizeof(WCHAR);
-  wstrParam.MaximumLength = wstrParam.Length;
-
-  /* skip the "=" */
-  ++ lpDef;
-
-  /* lookup the callback for the parameter */
-  bRetVal = COMMDCB_LookupStrFlag
-  (
-   &wstrParam,
-   a_Params,
-   sizeof(a_Params) / sizeof(a_Params[0]),
-   (ULONG_PTR *)&pCallback
-  );
-
-  /* invalid parameter */
-  if(!bRetVal) goto InvalidParam;
-
-  /* call the callback to parse the parameter's argument */
-  if(!pCallback(lpDCB, lpCommTimeouts, &bStopBitsSet, (LPWSTR *)&lpDef))
-   /* failure */
-   goto InvalidParam;
-
-  /* skip trailing whitespace */
-  while(lpDef[0] && iswspace(lpDef[0])) ++ lpDef;
- }
-
- /* success */
- return TRUE;
+    /* tell the baud= handler that the stop bits should be defaulted */
+    BOOL bStopBitsSet = FALSE;
+
+    /* parameter validation */
+    if(lpDCB->DCBlength != sizeof(DCB))
+        goto InvalidParam;
+
+    /* set defaults */
+    lpDCB->StopBits = ONESTOPBIT;
+
+    /*
+     * The documentation for MODE says that data= defaults to 7, but BuildCommDCB
+     * doesn't seem to set it
+     */
+    /* lpDCB->ByteSize = 7; */
+
+    /* skip COMx[n] */
+    if(lpDef[0] &&
+       towupper(lpDef[0]) == L'C' &&
+       lpDef[1] &&
+       towupper(lpDef[1]) == L'O' &&
+       lpDef[2] &&
+       towupper(lpDef[2]) == L'M')
+    {
+        DWORD nDummy;
+
+        /* skip "COM" */
+        lpDef += 3;
+
+        /* premature end of string */
+        if(!lpDef[0])
+            goto InvalidParam;
+
+        /* skip "x" */
+        if(!COMMDCB_ParseInt((LPWSTR *)&lpDef, &nDummy))
+            goto InvalidParam;
+
+        /* skip ":" */
+        if(lpDef[0] == L':')
+            lpDef++;
+    }
+
+    /* skip leading whitespace */
+    while(lpDef[0] && iswspace(lpDef[0]))
+        lpDef++;
+
+    /* repeat until the end of the string */
+    while(lpDef[0])
+    {
+        static COMMDCB_PARAM_STRFLAG a_Params[] = {
+            COMMDCB_PARAM(baud),
+            COMMDCB_PARAM(data),
+            COMMDCB_PARAM(dtr),
+            COMMDCB_PARAM(idsr),
+            COMMDCB_PARAM(octs),
+            COMMDCB_PARAM(odsr),
+            COMMDCB_PARAM(parity),
+            COMMDCB_PARAM(rts),
+            COMMDCB_PARAM(stop),
+            COMMDCB_PARAM(to),
+            COMMDCB_PARAM(xon)
+        };
+        BOOL bRetVal;
+        COMMDCB_PARAM_CALLBACK pCallback;
+        UNICODE_STRING wstrParam;
+        LPWSTR pwcPrevTail = (LPWSTR)lpDef;
+
+        /* get the parameter */
+        while(lpDef[0] && lpDef[0] != L'=')
+            lpDef++;
+
+        /* premature end of string */
+        if(!lpDef[0])
+            goto InvalidParam;
+
+        /* build the parameter's UNICODE_STRING */
+        wstrParam.Buffer = pwcPrevTail;
+        wstrParam.Length = (lpDef - pwcPrevTail) * sizeof(WCHAR);
+        wstrParam.MaximumLength = wstrParam.Length;
+
+        /* skip the "=" */
+        lpDef++;
+
+        /* lookup the callback for the parameter */
+        bRetVal = COMMDCB_LookupStrFlag(&wstrParam,
+                                        a_Params,
+                                        sizeof(a_Params) / sizeof(a_Params[0]),
+                                        (ULONG_PTR *)&pCallback);
+
+        /* invalid parameter */
+        if(!bRetVal)
+            goto InvalidParam;
+
+        /* call the callback to parse the parameter's argument */
+        if(!pCallback(lpDCB, lpCommTimeouts, &bStopBitsSet, (LPWSTR *)&lpDef))
+            goto InvalidParam;
+
+        /* skip trailing whitespace */
+        while(lpDef[0] && iswspace(lpDef[0]))
+            lpDef++;
+    }
+
+    /* success */
+    return TRUE;
 
 InvalidParam:
- /* failure */
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
-BuildCommDCBAndTimeoutsA(LPCSTR lpDef, LPDCB lpDCB,    LPCOMMTIMEOUTS lpCommTimeouts)
+BuildCommDCBAndTimeoutsA(LPCSTR lpDef,
+                         LPDCB lpDCB,
+                         LPCOMMTIMEOUTS lpCommTimeouts)
 {
NTSTATUS nErrCode;
- BOOL bRetVal;
- ANSI_STRING strDef;
- UNICODE_STRING wstrDef;
   NTSTATUS Status;
   BOOL bRetVal;
   ANSI_STRING strDef;
   UNICODE_STRING wstrDef;
 
- RtlInitAnsiString(&strDef, (LPSTR)lpDef);
   RtlInitAnsiString(&strDef, (LPSTR)lpDef);
  
nErrCode = RtlAnsiStringToUnicodeString(&wstrDef, &strDef, TRUE);
   Status = RtlAnsiStringToUnicodeString(&wstrDef, &strDef, TRUE);
 
if(!NT_SUCCESS(nErrCode))
- {
-  SetLastErrorByStatus(nErrCode);
-  return FALSE;
- }
   if(!NT_SUCCESS(Status))
   {
+        SetLastErrorByStatus(Status);
+        return FALSE;
   }
  
- bRetVal = BuildCommDCBAndTimeoutsW(wstrDef.Buffer, lpDCB, lpCommTimeouts);
   bRetVal = BuildCommDCBAndTimeoutsW(wstrDef.Buffer, lpDCB, lpCommTimeouts);
 
- RtlFreeUnicodeString(&wstrDef);
   RtlFreeUnicodeString(&wstrDef);
  
- return bRetVal;
   return bRetVal;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 BuildCommDCBA(LPCSTR lpDef, LPDCB lpDCB)
 {
- return BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
   return BuildCommDCBAndTimeoutsA(lpDef, lpDCB, NULL);
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 BuildCommDCBW(LPCWSTR lpDef, LPDCB lpDCB)
 {
- return BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
   return BuildCommDCBAndTimeoutsW(lpDef, lpDCB, NULL);
 }
 
 
@@ -760,91 +756,129 @@ BOOL
 STDCALL
 ClearCommBreak(HANDLE hFile)
 {
-       BOOL result = FALSE;
-       DWORD dwBytesReturned;
-
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
+    DWORD dwBytesReturned;
+    return DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_OFF, 
+                        NULL, 0, NULL, 0, &dwBytesReturned, NULL);
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
-ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat)
+ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpComStat)
 {
-       BOOL result = FALSE;
+       BOOL status = FALSE;
        DWORD dwBytesReturned;
-
-       if (hFile == INVALID_HANDLE_VALUE) {
-               //SetLastError(CE_MODE);
-               return FALSE;
-       }
-       if (lpErrors == NULL) {
-        DPRINT("ERROR: GetCommState() - NULL Errors pointer\n");
-               return FALSE;
-       }
-//     *lpErrors = CE_BREAK;
-//     *lpErrors = CE_FRAME;
-//     *lpErrors = CE_IOE;
-//     *lpErrors = CE_MODE;
-//     *lpErrors = CE_OVERRUN;
-//     *lpErrors = CE_RXOVER;
-//     *lpErrors = CE_RXPARITY;
-//     *lpErrors = CE_TXFULL;
-/*
-CE_BREAK The hardware detected a break condition. 
-CE_FRAME The hardware detected a framing error. 
-CE_IOE An I/O error occurred during communications with the device. 
-CE_MODE The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error. 
-CE_OVERRUN A character-buffer overrun has occurred. The next character is lost. 
-CE_RXOVER An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character. 
-CE_RXPARITY The hardware detected a parity error. 
-CE_TXFULL The application tried to transmit a character, but the output buffer was full. 
- */
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_RESET_DEVICE, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
-
-       if (lpStat != NULL) {
-               lpStat->fCtsHold = 0;
-               lpStat->fDsrHold = 0;
-               lpStat->fRlsdHold = 0;
-               lpStat->fXoffHold = 0;
-               lpStat->fXoffSent = 0;
-               lpStat->fEof = 0;
-               lpStat->fTxim = 0;
-               lpStat->cbInQue = 0;
-               lpStat->cbOutQue = 0;
+        SERIAL_STATUS SerialStatus;
+        
+        status = DeviceIoControl(hFile, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, 
+                        &SerialStatus, sizeof(SERIAL_STATUS), &dwBytesReturned, NULL);
+        
+        if(!NT_SUCCESS(status))
+        {
+            return status;
+        }
+        
+        if(lpErrors)
+        {
+            *lpErrors = 0;
+            if(SerialStatus.Errors & SERIAL_ERROR_BREAK)
+                *lpErrors |= CE_BREAK;
+            if(SerialStatus.Errors & SERIAL_ERROR_FRAMING)
+                *lpErrors |= CE_FRAME;
+            if(SerialStatus.Errors & SERIAL_ERROR_OVERRUN)
+                *lpErrors |= CE_OVERRUN;
+            if(SerialStatus.Errors & SERIAL_ERROR_QUEUEOVERRUN )
+                *lpErrors |= CE_RXOVER;
+            if(SerialStatus.Errors & SERIAL_ERROR_PARITY)
+                *lpErrors |= CE_RXPARITY;
+        }
+        
+       if (lpComStat) 
+        {
+            ZeroMemory(lpComStat, sizeof(COMSTAT));
+            
+            if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_CTS)
+                lpComStat->fCtsHold = TRUE;
+            if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_DSR)
+                lpComStat->fDsrHold = TRUE;
+            if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_DCD)
+                lpComStat->fRlsdHold = TRUE;
+            if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_FOR_XON)
+                lpComStat->fXoffHold = TRUE;
+            if(SerialStatus.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT)
+                lpComStat->fXoffSent = TRUE;
+            
+            if(SerialStatus.EofReceived)
+                lpComStat->fEof = TRUE;
+            
+            if(SerialStatus.WaitForImmediate)
+                lpComStat->fTxim = TRUE;
+
+            lpComStat->cbInQue = SerialStatus.AmountInInQueue;
+            lpComStat->cbOutQue = SerialStatus.AmountInOutQueue;
        }
        return TRUE;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 CommConfigDialogA(LPCSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+       PWCHAR NameW;
+       BOOL result;
+       
+       /* don't use the static thread buffer so operations in serialui
+          don't overwrite the string */
+       if(!(NameW = FilenameA2W(lpszName, TRUE)))
+       {
+               return FALSE;
+       }
+       
+       result = CommConfigDialogW(NameW, hWnd, lpCC);
+
+       RtlFreeHeap(RtlGetProcessHeap(), 0, NameW);
+       
+       return result;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 CommConfigDialogW(LPCWSTR lpszName, HWND hWnd, LPCOMMCONFIG lpCC)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+       BOOL (STDCALL *drvCommDlgW)(LPCWSTR, HWND, LPCOMMCONFIG);
+       HMODULE hSerialuiDll;
+       BOOL result;
+       
+       //FIXME: Get dll name from registry. (setupapi needed)
+       if(!(hSerialuiDll = LoadLibraryW(L"serialui.dll")))
+       {
+               DPRINT("CommConfigDialogW: serialui.dll not found.\n");
+               return FALSE;
+       }
+       
+       drvCommDlgW = GetProcAddress(hSerialuiDll, "drvCommConfigDialogW");
+       
+       if(!drvCommDlgW)
+       {
+               DPRINT("CommConfigDialogW: serialui does not export drvCommConfigDialogW\n");
+               FreeLibrary(hSerialuiDll);
+               return FALSE;
+       }
+       
+       result = drvCommDlgW(lpszName, hWnd, lpCC);
+       FreeLibrary(hSerialuiDll);
+       return result;
 }
 
 
@@ -858,9 +892,6 @@ EscapeCommFunction(HANDLE hFile, DWORD dwFunc)
        BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
        switch (dwFunc) {
     case CLRDTR: // Clears the DTR (data-terminal-ready) signal. 
         result = DeviceIoControl(hFile, IOCTL_SERIAL_CLR_DTR, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
@@ -891,7 +922,7 @@ EscapeCommFunction(HANDLE hFile, DWORD dwFunc)
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
                break;
        }
-       return TRUE;
+       return result;
 }
 
 
@@ -914,15 +945,9 @@ BOOL
 STDCALL
 GetCommMask(HANDLE hFile, LPDWORD lpEvtMask)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
-
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_WAIT_MASK, 
+        return DeviceIoControl(hFile, IOCTL_SERIAL_GET_WAIT_MASK, 
                NULL, 0, lpEvtMask, sizeof(DWORD), &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -933,27 +958,23 @@ BOOL
 STDCALL
 GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
+       return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
                NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 GetCommProperties(HANDLE hFile, LPCOMMPROP lpCommProp)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+       DWORD dwBytesReturned;
+       return DeviceIoControl(hFile, IOCTL_SERIAL_GET_PROPERTIES, 0, 0, 
+               lpCommProp, sizeof(COMMPROP), &dwBytesReturned, 0);
 }
 
 
@@ -974,22 +995,19 @@ GetCommState(HANDLE hFile, LPDCB lpDCB)
 
     DPRINT("GetCommState(%d, %p)\n", hFile, lpDCB);
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-        DPRINT("ERROR: GetCommState() - INVALID_HANDLE_VALUE\n");
-               return FALSE;
-       }
        if (lpDCB == NULL) {
         DPRINT("ERROR: GetCommState() - NULL DCB pointer\n");
                return FALSE;
        }
-       if (lpDCB->DCBlength != sizeof(DCB)) {
-        DPRINT("ERROR: GetCommState() - Invalid DCB size\n");
-               return FALSE;
-       }
 
-//    DPRINT("    GetCommState() CALLING DeviceIoControl\n");
-//    result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
-//    DPRINT("    GetCommState() DeviceIoControl returned %d\n", result);
+       lpDCB->DCBlength = sizeof(DCB);
+       
+       /* FIXME: need to fill following fields (1 bit):
+        * fBinary: binary mode, no EOF check
+        * fParity: enable parity checking
+        * fOutX  : XON/XOFF out flow control
+        * fInX   : XON/XOFF in flow control
+        */
 
        result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_BAUD_RATE,
                         NULL, 0, &BaudRate, sizeof(BaudRate),&dwBytesReturned, NULL);
@@ -1077,20 +1095,16 @@ BOOL
 STDCALL
 GetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
        if (lpCommTimeouts == NULL) {
                return FALSE;
        }
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_GET_TIMEOUTS,
+        
+       return DeviceIoControl(hFile, IOCTL_SERIAL_GET_TIMEOUTS,
                                                         NULL, 0, 
                                                         lpCommTimeouts, sizeof(COMMTIMEOUTS), 
                                                         &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1125,15 +1139,10 @@ BOOL
 STDCALL
 PurgeComm(HANDLE hFile, DWORD dwFlags)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_PURGE, 
+        return DeviceIoControl(hFile, IOCTL_SERIAL_PURGE, 
                &dwFlags, sizeof(DWORD), NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1144,14 +1153,9 @@ BOOL
 STDCALL
 SetCommBreak(HANDLE hFile)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
+        return DeviceIoControl(hFile, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
 }
 
 
@@ -1174,15 +1178,10 @@ BOOL
 STDCALL
 SetCommMask(HANDLE hFile, DWORD dwEvtMask)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-    result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_WAIT_MASK, 
+        return DeviceIoControl(hFile, IOCTL_SERIAL_SET_WAIT_MASK, 
                &dwEvtMask, sizeof(DWORD), NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1203,10 +1202,6 @@ SetCommState(HANDLE      hFile, LPDCB lpDCB)
 
     DPRINT("SetCommState(%d, %p) - ENTERED\n", hFile, lpDCB);
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-        DPRINT("SetCommState() - ERROR: INVALID_HANDLE_VALUE\n");
-               return FALSE;
-       }
        if (lpDCB == NULL) {
         DPRINT("SetCommState() - ERROR: NULL DCB pointer passed\n");
                return FALSE;
@@ -1324,13 +1319,9 @@ BOOL
 STDCALL
 SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
        SERIAL_TIMEOUTS Timeouts;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
        if (lpCommTimeouts == NULL) {
                return FALSE;
        }
@@ -1339,9 +1330,9 @@ SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts)
        Timeouts.ReadTotalTimeoutConstant = lpCommTimeouts->ReadTotalTimeoutConstant;
        Timeouts.WriteTotalTimeoutMultiplier = lpCommTimeouts->WriteTotalTimeoutMultiplier;
        Timeouts.WriteTotalTimeoutConstant = lpCommTimeouts->WriteTotalTimeoutConstant;
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_TIMEOUTS,
+       
+        return DeviceIoControl(hFile, IOCTL_SERIAL_SET_TIMEOUTS,
                &Timeouts, sizeof(Timeouts), NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1376,18 +1367,13 @@ BOOL
 STDCALL
 SetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
        SERIAL_QUEUE_SIZE QueueSize;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
     QueueSize.InSize = dwInQueue;
     QueueSize.OutSize = dwOutQueue;
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_SET_QUEUE_SIZE,
+    return DeviceIoControl(hFile, IOCTL_SERIAL_SET_QUEUE_SIZE,
                &QueueSize, sizeof(QueueSize), NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1398,15 +1384,9 @@ BOOL
 STDCALL
 TransmitCommChar(HANDLE hFile, char cChar)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
-
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_IMMEDIATE_CHAR,
+       return DeviceIoControl(hFile, IOCTL_SERIAL_IMMEDIATE_CHAR,
                &cChar, sizeof(cChar), NULL, 0, &dwBytesReturned, NULL);
-       return TRUE;
 }
 
 
@@ -1417,18 +1397,14 @@ BOOL
 STDCALL
 WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped)
 {
-       BOOL result = FALSE;
        DWORD dwBytesReturned;
 
-       if (hFile == INVALID_HANDLE_VALUE) {
-               return FALSE;
-       }
        if (lpEvtMask == NULL) {
                return FALSE;
        }
-       result = DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK,
+        
+       return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK,
                NULL, 0, lpEvtMask, sizeof(DWORD), &dwBytesReturned, lpOverlapped);
-       return TRUE;
 }
 
 /* EOF */
index 17e1bbc..0b52172 100644 (file)
@@ -82,7 +82,7 @@ DllMain(HANDLE hDll,
        LPVOID lpReserved)
 {
   NTSTATUS Status;
-
+  
   (void)lpReserved;
 
   DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
@@ -147,8 +147,9 @@ DllMain(HANDLE hDll,
        RtlInitializeCriticalSection(&ConsoleLock);
        SetConsoleCtrlHandler(DefaultConsoleCtrlHandler, TRUE);
 
-       /* Insert more dll attach stuff here! */
 
+   /* Insert more dll attach stuff here! */
+   
        DllInitialized = TRUE;
        break;
 
index 239448f..6dddc0c 100644 (file)
@@ -219,159 +219,6 @@ SetEnvironmentVariableW (
 }
 
 
-/*
- * @implemented
- */
-DWORD
-STDCALL
-GetVersion(VOID)
-{
-  PPEB pPeb = NtCurrentPeb();
-  DWORD nVersion;
-
-  nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
-
-  /* behave consistently when posing as another operating system */
-  /* build number */
-  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
-    nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
-  /* non-NT platform flag */
-  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
-    nVersion |= 0x80000000;
-
-  return nVersion;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-STDCALL
-GetVersionExW(
-    LPOSVERSIONINFOW lpVersionInformation
-    )
-{
-  NTSTATUS Status;
-  
-  if(lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW) &&
-     lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW))
-  {
-    /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
-       enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
-       would've been much more appropriate... */
-    SetLastError(ERROR_INSUFFICIENT_BUFFER);
-    return FALSE;
-  }
-
-  Status = RtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation);
-  if(NT_SUCCESS(Status))
-  {
-    int ln, maxlen;
-    
-    /* append a reactos specific string to the szCSDVersion string */
-
-    /* FIXME - we shouldn't do this when there is a (ros-specific) compatibility
-               flag set so we don't screw applications that might depend on a
-               certain string */
-
-    ln = wcslen(lpVersionInformation->szCSDVersion) + 1;
-    maxlen = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0]) - 1);
-    if(maxlen > ln)
-    {
-      PWCHAR szVer = lpVersionInformation->szCSDVersion + ln;
-      RtlZeroMemory(szVer, (maxlen - ln + 1) * sizeof(WCHAR));
-      wcsncpy(szVer,
-              L"ReactOS " KERNEL_VERSION_STR L" (Build " KERNEL_VERSION_BUILD_STR L")",
-              maxlen - ln);
-    }
-    
-    return TRUE;
-  }
-
-  return FALSE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-STDCALL
-GetVersionExA(
-    LPOSVERSIONINFOA lpVersionInformation
-    )
-{
-  OSVERSIONINFOEXW viw;
-  
-  RtlZeroMemory(&viw, sizeof(viw));
-  
-  switch(lpVersionInformation->dwOSVersionInfoSize)
-  {
-    case sizeof(OSVERSIONINFOA):
-      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
-      break;
-
-    case sizeof(OSVERSIONINFOEXA):
-      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
-      break;
-
-    default:
-      /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
-         enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
-         would've been much more appropriate... */
-      SetLastError(ERROR_INSUFFICIENT_BUFFER);
-      return FALSE;
-  }
-  
-  if(GetVersionExW((LPOSVERSIONINFOW)&viw))
-  {
-    ANSI_STRING CSDVersionA;
-    UNICODE_STRING CSDVersionW;
-    
-    /* copy back fields that match both supported structures */
-    lpVersionInformation->dwMajorVersion = viw.dwMajorVersion;
-    lpVersionInformation->dwMinorVersion = viw.dwMinorVersion;
-    lpVersionInformation->dwBuildNumber = viw.dwBuildNumber;
-    lpVersionInformation->dwPlatformId = viw.dwPlatformId;
-    
-    /* convert the win version string */
-    RtlInitUnicodeString(&CSDVersionW, viw.szCSDVersion);
-    
-    CSDVersionA.Length = 0;
-    CSDVersionA.MaximumLength = sizeof(lpVersionInformation->szCSDVersion);
-    CSDVersionA.Buffer = lpVersionInformation->szCSDVersion;
-    
-    RtlUnicodeStringToAnsiString(&CSDVersionA, &CSDVersionW, FALSE);
-
-    /* convert the ReactOS version string */
-    CSDVersionW.Buffer = viw.szCSDVersion + CSDVersionW.Length / sizeof(WCHAR) + 1;
-    CSDVersionW.MaximumLength = sizeof(viw.szCSDVersion) - (CSDVersionW.Length + sizeof(WCHAR));
-    CSDVersionW.Length = wcslen(CSDVersionW.Buffer) * sizeof(WCHAR);
-    CSDVersionA.Buffer = lpVersionInformation->szCSDVersion + CSDVersionA.Length + 1;
-    CSDVersionA.MaximumLength = sizeof(lpVersionInformation->szCSDVersion) - (CSDVersionA.Length + 1);
-    CSDVersionA.Length = 0;
-
-    RtlUnicodeStringToAnsiString(&CSDVersionA, &CSDVersionW, FALSE);
-    
-    /* copy back the extended fields */
-    if(viw.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW))
-    {
-      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMajor = viw.wServicePackMajor;
-      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMinor = viw.wServicePackMinor;
-      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wSuiteMask = viw.wSuiteMask;
-      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wProductType = viw.wProductType;
-      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wReserved = viw.wReserved;
-    }
-    
-    return TRUE;
-  }
-  
-  return FALSE;
-}
-
-
 /*
  * @implemented
  */
index 1fbf659..1c6f973 100644 (file)
@@ -21,6 +21,70 @@ typedef struct tagLOADPARMS32 {
 
 /* FUNCTIONS ****************************************************************/
 
+/**
+ * @name GetDllLoadPath
+ *
+ * Internal function to compute the load path to use for a given dll.
+ *
+ * @remarks Returned pointer must be freed by caller.
+ */
+
+LPWSTR STDCALL
+GetDllLoadPath(LPCWSTR lpModule)
+{
+        ULONG Pos = 0, Length = 0;
+        PWCHAR EnvironmentBufferW = NULL;
+        LPCWSTR lpModuleEnd = NULL;
+        UNICODE_STRING ModuleName;
+
+       if (lpModule != NULL)
+       {
+               lpModuleEnd = lpModule + wcslen(lpModule);
+       }
+       else
+       {
+               ModuleName = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName;
+               lpModule = ModuleName.Buffer;
+               lpModuleEnd = lpModule + (ModuleName.Length / sizeof(WCHAR));
+       }
+
+       if (lpModule != NULL)
+       {
+               while (lpModuleEnd > lpModule && *lpModuleEnd != L'/' &&
+                      *lpModuleEnd != L'\\' && *lpModuleEnd != L':')
+                       --lpModuleEnd;
+               Length = (lpModuleEnd - lpModule) + 1;          
+       }
+
+       Length += GetCurrentDirectoryW(0, NULL);
+       Length += GetSystemDirectoryW(NULL, 0);
+       Length += GetWindowsDirectoryW(NULL, 0);
+       Length += GetEnvironmentVariableW(L"PATH", NULL, 0);
+
+       EnvironmentBufferW = RtlAllocateHeap(RtlGetProcessHeap(), 0,
+                                             Length * sizeof(WCHAR));
+       if (EnvironmentBufferW == NULL)
+               return NULL;
+
+       if (lpModule)
+       {
+               RtlCopyMemory(EnvironmentBufferW, lpModule,
+                             (lpModuleEnd - lpModule) * sizeof(WCHAR));
+               Pos += lpModuleEnd - lpModule;
+               EnvironmentBufferW[Pos++] = L';';
+       }
+       Pos += GetCurrentDirectoryW(Length, EnvironmentBufferW + Pos);
+       EnvironmentBufferW[Pos++] = L';';
+       Pos += GetSystemDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
+       EnvironmentBufferW[Pos++] = L';';
+       Pos += GetWindowsDirectoryW(EnvironmentBufferW + Pos, Length - Pos);
+       EnvironmentBufferW[Pos++] = L';';
+       Pos += GetEnvironmentVariableW(L"PATH", EnvironmentBufferW + Pos, Length - Pos);
+       EnvironmentBufferW[Pos] = 0;
+
+       return EnvironmentBufferW;
+}
+
 /*
  * @implemented
  */
@@ -66,40 +130,12 @@ LoadLibraryExA (
        DWORD   dwFlags
        )
 {
-       UNICODE_STRING LibFileNameU;
-       ANSI_STRING LibFileName;
-       HINSTANCE hInst;
-       NTSTATUS Status;
-
-        (void)hFile;
-
-       RtlInitAnsiString (&LibFileName,
-                          (LPSTR)lpLibFileName);
-
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&LibFileNameU,
-                                             &LibFileName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&LibFileNameU,
-                                            &LibFileName,
-                                            TRUE);
+   PWCHAR FileNameW;
+   
+   if (!(FileNameW = FilenameA2W(lpLibFileName, FALSE)))
+      return FALSE;
 
-       Status = LdrLoadDll(NULL,
-                           dwFlags,
-                           &LibFileNameU,
-                           (PVOID*)&hInst);
-
-       RtlFreeUnicodeString (&LibFileNameU);
-
-       if ( !NT_SUCCESS(Status))
-       {
-               SetLastErrorByStatus (Status);
-               return NULL;
-       }
-
-       return hInst;
+   return LoadLibraryExW(FileNameW, hFile, dwFlags);
 }
 
 
@@ -130,6 +166,7 @@ LoadLibraryExW (
        UNICODE_STRING DllName;
        HINSTANCE hInst;
        NTSTATUS Status;
+       PWSTR SearchPath;
 
         (void)hFile;
 
@@ -141,8 +178,12 @@ LoadLibraryExW (
          LOAD_LIBRARY_AS_DATAFILE |
          LOAD_WITH_ALTERED_SEARCH_PATH;
 
-       RtlInitUnicodeString (&DllName, (LPWSTR)lpLibFileName);
-       Status = LdrLoadDll(NULL, dwFlags, &DllName, (PVOID*)&hInst);
+       SearchPath = GetDllLoadPath(
+         dwFlags & LOAD_WITH_ALTERED_SEARCH_PATH ? lpLibFileName : NULL);
+
+       RtlInitUnicodeString(&DllName, (LPWSTR)lpLibFileName);
+       Status = LdrLoadDll(SearchPath, dwFlags, &DllName, (PVOID*)&hInst);
+       RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
        if ( !NT_SUCCESS(Status))
        {
                SetLastErrorByStatus (Status);
index fdb9ac4..d9acdda 100644 (file)
@@ -819,7 +819,10 @@ static BOOL PROFILE_Open( LPCWSTR filename )
                 MRUProfile[j] = MRUProfile[j-1];
              CurProfile=tempProfile;
           }
-          GetFileTime(hFile, NULL, NULL, &LastWriteTime);
+          if (hFile != INVALID_HANDLE_VALUE)
+             GetFileTime(hFile, NULL, NULL, &LastWriteTime);
+          else
+             LastWriteTime.dwHighDateTime = LastWriteTime.dwLowDateTime = 0;
           if (memcmp(&CurProfile->LastWriteTime, &LastWriteTime, sizeof(FILETIME)))
           {
              DPRINT("(%S): already opened (mru = %d)\n",
@@ -830,9 +833,10 @@ static BOOL PROFILE_Open( LPCWSTR filename )
               DPRINT("(%S): already opened, needs refreshing (mru = %d)\n",
                      buffer, i );
           }
-          CloseHandle(hFile);
+          if (hFile != INVALID_HANDLE_VALUE)
+             CloseHandle(hFile);
           return TRUE;
-        }
+       }
     }
 
     /* Flush the old current profile */
index ff6907d..f0a0ed8 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <k32.h>
+#include <ddk/ldrfuncs.h>
 
 #define NDEBUG
 #include "../include/debug.h"
@@ -312,40 +313,173 @@ EnumResourceLanguagesA (
 }
 
 
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-EnumResourceNamesW (
-       HINSTANCE               hModule,
-       LPCWSTR                 lpType,
-       ENUMRESNAMEPROCW        lpEnumFunc,
-       LONG                    lParam
-       )
+
+/* retrieve the resource name to pass to the ntdll functions */
+static NTSTATUS get_res_nameA( LPCSTR name, UNICODE_STRING *str )
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    if (!HIWORD(name))
+    {
+        str->Buffer = (LPWSTR)name;
+        return STATUS_SUCCESS;
+    }
+    if (name[0] == '#')
+    {
+        ULONG value;
+        if (RtlCharToInteger( name + 1, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
+            return STATUS_INVALID_PARAMETER;
+        str->Buffer = (LPWSTR)value;
+        return STATUS_SUCCESS;
+    }
+    RtlCreateUnicodeStringFromAsciiz( str, name );
+    RtlUpcaseUnicodeString( str, str, FALSE );
+    return STATUS_SUCCESS;
 }
 
+/* retrieve the resource name to pass to the ntdll functions */
+static NTSTATUS get_res_nameW( LPCWSTR name, UNICODE_STRING *str )
+{
+    if (!HIWORD(name))
+    {
+        str->Buffer = (LPWSTR)name;
+        return STATUS_SUCCESS;
+    }
+    if (name[0] == '#')
+    {
+        ULONG value;
+        RtlInitUnicodeString( str, name + 1 );
+        if (RtlUnicodeStringToInteger( str, 10, &value ) != STATUS_SUCCESS || HIWORD(value))
+            return STATUS_INVALID_PARAMETER;
+        str->Buffer = (LPWSTR)value;
+        return STATUS_SUCCESS;
+    }
+    RtlCreateUnicodeString( str, name );
+    RtlUpcaseUnicodeString( str, str, FALSE );
+    return STATUS_SUCCESS;
+}
 
-/*
- * @unimplemented
+/**********************************************************************
+ * EnumResourceNamesA   (KERNEL32.@)
  */
-BOOL
-STDCALL
-EnumResourceNamesA (
-       HINSTANCE               hModule,
-       LPCSTR                  lpType,
-       ENUMRESNAMEPROCA        lpEnumFunc,
-       LONG                    lParam
-       )
+BOOL STDCALL EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG_PTR lparam )
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    int i;
+    BOOL ret = FALSE;
+    DWORD len = 0, newlen;
+    LPSTR name = NULL;
+    NTSTATUS status;
+    UNICODE_STRING typeW;
+    LDR_RESOURCE_INFO info;
+    PIMAGE_RESOURCE_DIRECTORY basedir, resdir;
+    const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
+    const IMAGE_RESOURCE_DIR_STRING_U *str;
+
+    DPRINT( "%p %s %p %lx\n", hmod, type, lpfun, lparam );
+
+    if (!hmod) hmod = GetModuleHandleA( NULL );
+    typeW.Buffer = NULL;
+    if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
+        goto done;
+    if ((status = get_res_nameA( type, &typeW )) != STATUS_SUCCESS)
+        goto done;
+    info.Type = (ULONG)typeW.Buffer;
+    if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
+        goto done;
+
+    et = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
+    for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
+    {
+        if (et[i].NameIsString)
+        {
+            str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].NameOffset);
+            newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
+            if (newlen + 1 > len)
+            {
+                len = newlen + 1;
+                HeapFree( GetProcessHeap(), 0, name );
+                if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
+                {
+                    ret = FALSE;
+                    break;
+                }
+            }
+            WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
+            name[newlen] = 0;
+            ret = lpfun(hmod,type,name,lparam);
+        }
+        else
+        {
+            ret = lpfun( hmod, type, (LPSTR)(int)et[i].Id, lparam );
+        }
+        if (!ret) break;
+    }
+done:
+    HeapFree( GetProcessHeap(), 0, name );
+    if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
+    if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
+    return ret;
 }
 
 
+/**********************************************************************
+ * EnumResourceNamesW   (KERNEL32.@)
+ */
+BOOL STDCALL EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam )
+{
+    int i, len = 0;
+    BOOL ret = FALSE;
+    LPWSTR name = NULL;
+    NTSTATUS status;
+    UNICODE_STRING typeW;
+    LDR_RESOURCE_INFO info;
+    PIMAGE_RESOURCE_DIRECTORY basedir, resdir;
+    const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
+    const IMAGE_RESOURCE_DIR_STRING_U *str;
+
+    DPRINT( "%p %s %p %lx\n", hmod, type, lpfun, lparam );
+
+    if (!hmod) hmod = GetModuleHandleW( NULL );
+    typeW.Buffer = NULL;
+    if ((status = LdrFindResourceDirectory_U( hmod, NULL, 0, &basedir )) != STATUS_SUCCESS)
+        goto done;
+    if ((status = get_res_nameW( type, &typeW )) != STATUS_SUCCESS)
+        goto done;
+    info.Type = (ULONG)typeW.Buffer;
+    if ((status = LdrFindResourceDirectory_U( hmod, &info, 1, &resdir )) != STATUS_SUCCESS)
+        goto done;
+
+    et = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resdir + 1);
+    for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
+    {
+        if (et[i].NameIsString)
+        {
+            str = (IMAGE_RESOURCE_DIR_STRING_U *) ((LPBYTE) basedir + et[i].NameOffset);
+            if (str->Length + 1 > len)
+            {
+                len = str->Length + 1;
+                HeapFree( GetProcessHeap(), 0, name );
+                if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+                {
+                    ret = FALSE;
+                    break;
+                }
+            }
+            memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
+            name[str->Length] = 0;
+            ret = lpfun(hmod,type,name,lparam);
+        }
+        else
+        {
+            ret = lpfun( hmod, type, (LPWSTR)(int)et[i].Id, lparam );
+        }
+        if (!ret) break;
+    }
+done:
+    HeapFree( GetProcessHeap(), 0, name );
+    if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
+    if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
+    return ret;
+}
+
 /*
  * @unimplemented
  */
index 5b963cb..573a16f 100644 (file)
@@ -788,25 +788,8 @@ QueueUserWorkItem(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-ReadDirectoryChangesW(
-    HANDLE hDirectory,
-    LPVOID lpBuffer,
-    DWORD nBufferLength,
-    BOOL bWatchSubtree,
-    DWORD dwNotifyFilter,
-    LPDWORD lpBytesReturned,
-    LPOVERLAPPED lpOverlapped,
-    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
-    )
-{
-    STUB;
-    return 0;
-}
+
+
 
 /*
  * @unimplemented
@@ -1156,20 +1139,7 @@ GetFirmwareEnvironmentVariableW(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-DWORD
-STDCALL
-GetLongPathNameW(
-    LPCWSTR lpszShortPath,
-    LPWSTR  lpszLongPath,
-    DWORD    cchBuffer
-    )
-{
-    STUB;
-    return 0;
-}
+
 
 /*
  * @unimplemented
@@ -1308,21 +1278,6 @@ SetVolumeMountPointW(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-VerifyVersionInfoW(
-    LPOSVERSIONINFOEXW lpVersionInformation,
-    DWORD dwTypeMask,
-    DWORDLONG dwlConditionMask
-    )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
@@ -1443,20 +1398,7 @@ GetFirmwareEnvironmentVariableA(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-DWORD
-STDCALL
-GetLongPathNameA(
-    LPCSTR lpszShortPath,
-    LPSTR  lpszLongPath,
-    DWORD    cchBuffer
-    )
-{
-    STUB;
-    return 0;
-}
+
 
 /*
  * @unimplemented
@@ -1595,36 +1537,6 @@ SetVolumeMountPointA(
     return 0;
 }
 
-/*
- * @unimplemented
- */
-BOOL
-STDCALL
-VerifyVersionInfoA(
-    LPOSVERSIONINFOEXA lpVersionInformation,
-    DWORD dwTypeMask,
-    DWORDLONG dwlConditionMask
-    )
-{
-    STUB;
-    return 0;
-}
-
-/*
- * @unimplemented
- */
-ULONGLONG
-STDCALL
-VerSetConditionMask(
-        ULONGLONG   ConditionMask,
-        DWORD   TypeMask,
-        BYTE    Condition
-        )
-{
-    STUB;
-    return 0;
-}
-
 /*
  * @unimplemented
  */
index d74617f..c0aea8a 100644 (file)
@@ -500,12 +500,12 @@ GetSystemTimes(
     LPFILETIME lpUserTime
     )
 {
-   SYSTEM_PROCESSORTIME_INFO SysProcTime;
+   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcPerfInfo;
    NTSTATUS Status;
    
    Status = ZwQuerySystemInformation(SystemProcessorPerformanceInformation,
-                                     &SysProcTime,
-                                     sizeof(SysProcTime),
+                                     &SysProcPerfInfo,
+                                     sizeof(SysProcPerfInfo),
                                      NULL);
                                      
    if (!NT_SUCCESS(Status))
@@ -517,14 +517,14 @@ GetSystemTimes(
        Good only for one processor system.
  */
 
-   lpIdleTime->dwLowDateTime = SysProcTime.TotalProcessorRunTime.LowPart;
-   lpIdleTime->dwHighDateTime = SysProcTime.TotalProcessorRunTime.HighPart;
+   lpIdleTime->dwLowDateTime = SysProcPerfInfo.IdleTime.LowPart;
+   lpIdleTime->dwHighDateTime = SysProcPerfInfo.IdleTime.HighPart;
 
-   lpKernelTime->dwLowDateTime = SysProcTime.TotalProcessorTime.LowPart;
-   lpKernelTime->dwHighDateTime = SysProcTime.TotalProcessorTime.HighPart;
+   lpKernelTime->dwLowDateTime = SysProcPerfInfo.KernelTime.LowPart;
+   lpKernelTime->dwHighDateTime = SysProcPerfInfo.KernelTime.HighPart;
 
-   lpUserTime->dwLowDateTime = SysProcTime.TotalProcessorUserTime.LowPart;
-   lpUserTime->dwHighDateTime = SysProcTime.TotalProcessorUserTime.HighPart;
+   lpUserTime->dwLowDateTime = SysProcPerfInfo.UserTime.LowPart;
+   lpUserTime->dwHighDateTime = SysProcPerfInfo.UserTime.HighPart;
    
    return TRUE;
 }
diff --git a/reactos/lib/kernel32/misc/version.c b/reactos/lib/kernel32/misc/version.c
new file mode 100644 (file)
index 0000000..94952f6
--- /dev/null
@@ -0,0 +1,236 @@
+/* $Id$
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/kernel32/misc/version.c
+ * PURPOSE:         Version functions
+ * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
+ * UPDATE HISTORY:
+ *                  Created 01/11/98
+ */
+
+#include <k32.h>
+
+#define NDEBUG
+#include "../include/debug.h"
+
+
+/* FUNCTIONS ******************************************************************/
+
+
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+GetVersion(VOID)
+{
+  PPEB pPeb = NtCurrentPeb();
+  DWORD nVersion;
+
+  nVersion = MAKEWORD(pPeb->OSMajorVersion, pPeb->OSMinorVersion);
+
+  /* behave consistently when posing as another operating system */
+  /* build number */
+  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_WINDOWS)
+    nVersion |= ((DWORD)(pPeb->OSBuildNumber)) << 16;
+  /* non-NT platform flag */
+  if(pPeb->OSPlatformId != VER_PLATFORM_WIN32_NT)
+    nVersion |= 0x80000000;
+
+  return nVersion;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetVersionExW(
+    LPOSVERSIONINFOW lpVersionInformation
+    )
+{
+  NTSTATUS Status;
+  
+  if(lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW) &&
+     lpVersionInformation->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW))
+  {
+    /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
+       enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
+       would've been much more appropriate... */
+    SetLastError(ERROR_INSUFFICIENT_BUFFER);
+    return FALSE;
+  }
+
+  Status = RtlGetVersion((PRTL_OSVERSIONINFOW)lpVersionInformation);
+  if(NT_SUCCESS(Status))
+  {
+    int ln, maxlen;
+    
+    /* append a reactos specific string to the szCSDVersion string */
+
+    /* FIXME - we shouldn't do this when there is a (ros-specific) compatibility
+               flag set so we don't screw applications that might depend on a
+               certain string */
+
+    ln = wcslen(lpVersionInformation->szCSDVersion) + 1;
+    maxlen = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0]) - 1);
+    if(maxlen > ln)
+    {
+      PWCHAR szVer = lpVersionInformation->szCSDVersion + ln;
+      RtlZeroMemory(szVer, (maxlen - ln + 1) * sizeof(WCHAR));
+      wcsncpy(szVer,
+              L"ReactOS " KERNEL_VERSION_STR L" (Build " KERNEL_VERSION_BUILD_STR L")",
+              maxlen - ln);
+    }
+    
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetVersionExA(
+    LPOSVERSIONINFOA lpVersionInformation
+    )
+{
+  OSVERSIONINFOEXW viw;
+  
+  RtlZeroMemory(&viw, sizeof(viw));
+  
+  switch(lpVersionInformation->dwOSVersionInfoSize)
+  {
+    case sizeof(OSVERSIONINFOA):
+      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+      break;
+
+    case sizeof(OSVERSIONINFOEXA):
+      viw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
+      break;
+
+    default:
+      /* for some reason win sets ERROR_INSUFFICIENT_BUFFER even if it is large
+         enough but doesn't match the exact sizes supported, ERROR_INVALID_PARAMETER
+         would've been much more appropriate... */
+      SetLastError(ERROR_INSUFFICIENT_BUFFER);
+      return FALSE;
+  }
+  
+  if(GetVersionExW((LPOSVERSIONINFOW)&viw))
+  {
+    ANSI_STRING CSDVersionA;
+    UNICODE_STRING CSDVersionW;
+    
+    /* copy back fields that match both supported structures */
+    lpVersionInformation->dwMajorVersion = viw.dwMajorVersion;
+    lpVersionInformation->dwMinorVersion = viw.dwMinorVersion;
+    lpVersionInformation->dwBuildNumber = viw.dwBuildNumber;
+    lpVersionInformation->dwPlatformId = viw.dwPlatformId;
+    
+    /* convert the win version string */
+    RtlInitUnicodeString(&CSDVersionW, viw.szCSDVersion);
+    
+    CSDVersionA.Length = 0;
+    CSDVersionA.MaximumLength = sizeof(lpVersionInformation->szCSDVersion);
+    CSDVersionA.Buffer = lpVersionInformation->szCSDVersion;
+    
+    RtlUnicodeStringToAnsiString(&CSDVersionA, &CSDVersionW, FALSE);
+
+    /* convert the ReactOS version string */
+    CSDVersionW.Buffer = viw.szCSDVersion + CSDVersionW.Length / sizeof(WCHAR) + 1;
+    CSDVersionW.MaximumLength = sizeof(viw.szCSDVersion) - (CSDVersionW.Length + sizeof(WCHAR));
+    CSDVersionW.Length = wcslen(CSDVersionW.Buffer) * sizeof(WCHAR);
+    CSDVersionA.Buffer = lpVersionInformation->szCSDVersion + CSDVersionA.Length + 1;
+    CSDVersionA.MaximumLength = sizeof(lpVersionInformation->szCSDVersion) - (CSDVersionA.Length + 1);
+    CSDVersionA.Length = 0;
+
+    RtlUnicodeStringToAnsiString(&CSDVersionA, &CSDVersionW, FALSE);
+    
+    /* copy back the extended fields */
+    if(viw.dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW))
+    {
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMajor = viw.wServicePackMajor;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wServicePackMinor = viw.wServicePackMinor;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wSuiteMask = viw.wSuiteMask;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wProductType = viw.wProductType;
+      ((LPOSVERSIONINFOEXA)lpVersionInformation)->wReserved = viw.wReserved;
+    }
+    
+    return TRUE;
+  }
+  
+  return FALSE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+VerifyVersionInfoW(
+    LPOSVERSIONINFOEXW lpVersionInformation,
+    DWORD dwTypeMask,
+    DWORDLONG dwlConditionMask
+    )
+{
+  NTSTATUS Status;
+  
+  Status = RtlVerifyVersionInfo((PRTL_OSVERSIONINFOEXW)lpVersionInformation,
+                                dwTypeMask,
+                                dwlConditionMask);
+  switch(Status)
+  {
+    case STATUS_INVALID_PARAMETER:
+      SetLastError(ERROR_BAD_ARGUMENTS);
+      return FALSE;
+
+    case STATUS_REVISION_MISMATCH:
+      SetLastError(ERROR_OLD_WIN_VERSION);
+      return FALSE;
+
+    default:
+      /* RtlVerifyVersionInfo shouldn't report any other failure code! */
+      ASSERT(NT_SUCCESS(Status));
+      return TRUE;
+  }
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+VerifyVersionInfoA(
+    LPOSVERSIONINFOEXA lpVersionInformation,
+    DWORD dwTypeMask,
+    DWORDLONG dwlConditionMask
+    )
+{
+  OSVERSIONINFOEXW viex;
+  
+  viex.dwOSVersionInfoSize = sizeof(viex);
+  viex.dwMajorVersion = lpVersionInformation->dwMajorVersion;
+  viex.dwMinorVersion = lpVersionInformation->dwMinorVersion;
+  viex.dwBuildNumber = lpVersionInformation->dwBuildNumber;
+  viex.dwPlatformId = lpVersionInformation->dwPlatformId;
+  /* NOTE: szCSDVersion is ignored, we don't need to convert it to unicode */
+  viex.wServicePackMajor = lpVersionInformation->wServicePackMajor;
+  viex.wServicePackMinor = lpVersionInformation->wServicePackMinor;
+  viex.wSuiteMask = lpVersionInformation->wSuiteMask;
+  viex.wProductType = lpVersionInformation->wProductType;
+  viex.wReserved = lpVersionInformation->wReserved;
+  
+  return VerifyVersionInfoW(&viex, dwTypeMask, dwlConditionMask);
+}
+
+/* EOF */
index 8aacef2..596d14c 100644 (file)
@@ -27,74 +27,69 @@ PRTL_BASE_PROCESS_START_ROUTINE RtlBaseProcessStartRoutine;
 
 typedef NTSTATUS STDCALL (K32_MBSTR_TO_WCSTR)
 (
- UNICODE_STRING *,
- ANSI_STRING *,
- BOOLEAN
  UNICODE_STRING *,
  ANSI_STRING *,
  BOOLEAN
 );
 
-NTSTATUS STDCALL K32MbStrToWcStr
-(
- IN K32_MBSTR_TO_WCSTR * True,
- UNICODE_STRING * DestStr,
- ANSI_STRING * SourceStr,
- BOOLEAN Allocate
-)
+NTSTATUS STDCALL K32MbStrToWcStr(IN K32_MBSTR_TO_WCSTR * True,
+                                UNICODE_STRING * DestStr,
+                                ANSI_STRING * SourceStr,
+                                BOOLEAN Allocate)
 {
- if(SourceStr->Buffer == NULL)
- {
-  DestStr->Length = DestStr->MaximumLength = 0;
-  DestStr->Buffer = NULL;
-  return STATUS_SUCCESS;
- }
-
- return True(DestStr, SourceStr, Allocate);
  if(SourceStr->Buffer == NULL)
  {
+      DestStr->Length = DestStr->MaximumLength = 0;
+      DestStr->Buffer = NULL;
+      return STATUS_SUCCESS;
  }
+
  return True(DestStr, SourceStr, Allocate);
 }
 
-VOID STDCALL RtlRosR32AttribsToNativeAttribs
-(
- OUT OBJECT_ATTRIBUTES * NativeAttribs,
- IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL
-)
+VOID STDCALL RtlRosR32AttribsToNativeAttribs(OUT OBJECT_ATTRIBUTES * NativeAttribs,
+                                            IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL)
 {
- NativeAttribs->Length = sizeof(*NativeAttribs);
- NativeAttribs->ObjectName = NULL;
- NativeAttribs->RootDirectory = NULL;
- NativeAttribs->Attributes = 0;
- NativeAttribs->SecurityQualityOfService = NULL;
  NativeAttribs->Length = sizeof(*NativeAttribs);
  NativeAttribs->ObjectName = NULL;
  NativeAttribs->RootDirectory = NULL;
  NativeAttribs->Attributes = 0;
  NativeAttribs->SecurityQualityOfService = NULL;
  
 
- if(Ros32Attribs != NULL && Ros32Attribs->nLength >= sizeof(*Ros32Attribs))
- {
-  NativeAttribs->SecurityDescriptor = Ros32Attribs->lpSecurityDescriptor;
  if(Ros32Attribs != NULL && Ros32Attribs->nLength >= sizeof(*Ros32Attribs))
  {
+      NativeAttribs->SecurityDescriptor = Ros32Attribs->lpSecurityDescriptor;
   
-  if(Ros32Attribs->bInheritHandle)
-   NativeAttribs->Attributes |= OBJ_INHERIT;
- }
- else
-  NativeAttribs->SecurityDescriptor = NULL;
+      if(Ros32Attribs->bInheritHandle)
+      {
+         NativeAttribs->Attributes |= OBJ_INHERIT;
+      }
+   }
+   else
+   {
+      NativeAttribs->SecurityDescriptor = NULL;
+   }
 }
 
-VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed
-(
- OUT OBJECT_ATTRIBUTES * NativeAttribs,
- IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL,
- OUT UNICODE_STRING * NativeName OPTIONAL,
- IN WCHAR * Ros32Name OPTIONAL,
- IN HANDLE Ros32NameRoot OPTIONAL
-)
+VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed(OUT OBJECT_ATTRIBUTES * NativeAttribs,
+                                                 IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL,
+                                                 OUT UNICODE_STRING * NativeName OPTIONAL,
+                                                 IN WCHAR * Ros32Name OPTIONAL,
+                                                 IN HANDLE Ros32NameRoot OPTIONAL)
 {
- if(!NativeAttribs) return;
  if(!NativeAttribs) return;
 
- RtlRosR32AttribsToNativeAttribs(NativeAttribs, Ros32Attribs);
  RtlRosR32AttribsToNativeAttribs(NativeAttribs, Ros32Attribs);
 
- if(Ros32Name != NULL && NativeName != NULL)
- {
-  RtlInitUnicodeString(NativeName, Ros32Name);
  if(Ros32Name != NULL && NativeName != NULL)
  {
+      RtlInitUnicodeString(NativeName, Ros32Name);
 
-  NativeAttribs->ObjectName = NativeName;
-  NativeAttribs->RootDirectory = Ros32NameRoot;
-  NativeAttribs->Attributes |= OBJ_CASE_INSENSITIVE;
- }
+      NativeAttribs->ObjectName = NativeName;
+      NativeAttribs->RootDirectory = Ros32NameRoot;
+      NativeAttribs->Attributes |= OBJ_CASE_INSENSITIVE;
  }
 }
 
 
@@ -144,12 +139,9 @@ BOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
    BOOL bRetVal;
    STARTUPINFOW wsiStartupInfo;
 
-   NTSTATUS STDCALL_FUNC (*pTrue)
-   (
-      UNICODE_STRING *,
-      ANSI_STRING *,
-      BOOLEAN
-   );
+   NTSTATUS STDCALL_FUNC (*pTrue)(UNICODE_STRING *,
+                                  ANSI_STRING *,
+                                 BOOLEAN);
 
    ULONG STDCALL_FUNC (*pRtlMbStringToUnicodeSize)(ANSI_STRING *);
 
@@ -291,7 +283,7 @@ _except_handler(EXCEPTION_RECORD *ExceptionRecord,
                void * DispatcherContext)
 {
    EXCEPTION_POINTERS ExceptionInfo;
-   EXCEPTION_DISPOSITION ExceptionDisposition;
+   EXCEPTION_DISPOSITION ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
 
    ExceptionInfo.ExceptionRecord = ExceptionRecord;
    ExceptionInfo.ContextRecord = ContextRecord;
@@ -308,19 +300,19 @@ _except_handler(EXCEPTION_RECORD *ExceptionRecord,
       }
       _SEH_END;
    }
-   else 
-   {
-      ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
-   }
 
    if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
       ExitProcess(ExceptionRecord->ExceptionCode);
 
    /* translate EXCEPTION_XXX defines into EXCEPTION_DISPOSITION enum values */
    if (ExceptionDisposition == EXCEPTION_CONTINUE_EXECUTION)
-     return ExceptionContinueExecution;
+   {
+      return ExceptionContinueExecution;
+   }
    else if (ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH)
-     return ExceptionContinueSearch;
+   {
+      return ExceptionContinueSearch;
+   }
 
    return -1; /* unknown return from UnhandledExceptionFilter */
 }
@@ -343,102 +335,93 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress,
 }
 
 
-HANDLE STDCALL KlCreateFirstThread
-(
- HANDLE ProcessHandle,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- PSECTION_IMAGE_INFORMATION Sii,
- LPTHREAD_START_ROUTINE lpStartAddress,
- DWORD dwCreationFlags,
- LPDWORD lpThreadId
-)
+HANDLE STDCALL KlCreateFirstThread(HANDLE ProcessHandle,
+                                  LPSECURITY_ATTRIBUTES lpThreadAttributes,
+                                  PSECTION_IMAGE_INFORMATION Sii,
+                                  LPTHREAD_START_ROUTINE lpStartAddress,
+                                  DWORD dwCreationFlags,
+                                  LPDWORD lpThreadId)
 {
- OBJECT_ATTRIBUTES oaThreadAttribs;
- CLIENT_ID cidClientId;
- PVOID pTrueStartAddress;
- NTSTATUS nErrCode;
- HANDLE hThread;
-
- /* convert the thread attributes */
- RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes);
-
- /* native image */
- if(Sii->Subsystem != IMAGE_SUBSYSTEM_NATIVE)
-  pTrueStartAddress = (PVOID)BaseProcessStart;
- /* Win32 image */
- else
-  pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine;
-
- DPRINT
- (
-  "RtlRosCreateUserThreadVa\n"
-  "(\n"
-  " ProcessHandle    %p,\n"
-  " ObjectAttributes %p,\n"
-  " CreateSuspended  %d,\n"
-  " StackZeroBits    %d,\n"
-  " StackReserve     %lu,\n"
-  " StackCommit      %lu,\n"
-  " StartAddress     %p,\n"
-  " ThreadHandle     %p,\n"
-  " ClientId         %p,\n"
-  " ParameterCount   %u,\n"
-  " Parameters[0]    %p,\n"
-  " Parameters[1]    %p\n"
-  ")\n",
-  ProcessHandle,
-  &oaThreadAttribs,
-  dwCreationFlags & CREATE_SUSPENDED,
-  0,
-  Sii->StackReserve,
-  Sii->StackCommit,
-  pTrueStartAddress,
-  &hThread,
-  &cidClientId,
-  2,
-  lpStartAddress,
-  PEB_BASE
- );
-
- /* create the first thread */
- nErrCode = RtlRosCreateUserThreadVa
- (
-  ProcessHandle,
-  &oaThreadAttribs,
-  dwCreationFlags & CREATE_SUSPENDED,
-  0,
-  &(Sii->StackReserve),
-  &(Sii->StackCommit),
-  pTrueStartAddress,
-  &hThread,
-  &cidClientId,
-  2,
-  (ULONG_PTR)lpStartAddress,
-  (ULONG_PTR)PEB_BASE
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode))
- {
-  SetLastErrorByStatus(nErrCode);
-  return NULL;
- }
+   OBJECT_ATTRIBUTES oaThreadAttribs;
+   CLIENT_ID cidClientId;
+   PVOID pTrueStartAddress;
+   NTSTATUS nErrCode;
+   HANDLE hThread;
+
+   /* convert the thread attributes */
+   RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes);
+
+   /* native image */
+   if(Sii->Subsystem != IMAGE_SUBSYSTEM_NATIVE)
+   {
+      pTrueStartAddress = (PVOID)BaseProcessStart;
+   }
+   /* Win32 image */
+   else
+   {
+      pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine;
+   }
+
+   DPRINT("RtlRosCreateUserThreadVa\n"
+          "(\n"
+         " ProcessHandle    %p,\n"
+         " ObjectAttributes %p,\n"
+         " CreateSuspended  %d,\n"
+         " StackZeroBits    %d,\n"
+         " StackReserve     %lu,\n"
+         " StackCommit      %lu,\n"
+         " StartAddress     %p,\n"
+         " ThreadHandle     %p,\n"  
+         " ClientId         %p,\n"
+         " ParameterCount   %u,\n"
+         " Parameters[0]    %p,\n"
+         " Parameters[1]    %p\n"
+         ")\n",
+         ProcessHandle,
+         &oaThreadAttribs,
+         dwCreationFlags & CREATE_SUSPENDED,  
+         0,
+         Sii->StackReserve,
+         Sii->StackCommit,
+         pTrueStartAddress,
+         &hThread,
+         &cidClientId,
+         2,
+          lpStartAddress,
+         PEB_BASE);
+
+   /* create the first thread */
+   nErrCode = RtlRosCreateUserThreadVa(ProcessHandle,
+                                       &oaThreadAttribs,
+                                      dwCreationFlags & CREATE_SUSPENDED,
+                                      0,
+                                      &(Sii->StackReserve),
+                                      &(Sii->StackCommit),
+                                      pTrueStartAddress,
+                                      &hThread,
+                                      &cidClientId,
+                                      2,
+                                       (ULONG_PTR)lpStartAddress,
+                                      (ULONG_PTR)PEB_BASE);
+   /* failure */
+   if(!NT_SUCCESS(nErrCode))
+   {
+      SetLastErrorByStatus(nErrCode);
+      return NULL;
+   }
  
- DPRINT
- (
-  "StackReserve          %p\n"
-  "StackCommit           %p\n"
-  "ThreadHandle          %p\n"
-  "ClientId.UniqueThread %p\n",
-  Sii->StackReserve,
-  Sii->StackCommit,
-  hThread,
-  cidClientId.UniqueThread
- );
-
- /* success */
- if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
- return hThread;
+   DPRINT("StackReserve          %p\n"
+          "StackCommit           %p\n"
+         "ThreadHandle          %p\n"
+         "ClientId.UniqueThread %p\n",
+         Sii->StackReserve,
+         Sii->StackCommit,
+         hThread,
+         cidClientId.UniqueThread);
+
+   /* success */
+   if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
+   return hThread;
 }
 
 HANDLE KlMapFile(LPCWSTR lpApplicationName)
@@ -476,20 +459,20 @@ HANDLE KlMapFile(LPCWSTR lpApplicationName)
     */
 
    Status = NtOpenFile(&hFile,
-                       SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       FILE_SHARE_DELETE|FILE_SHARE_READ,
-                       FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
+                       SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_DELETE|FILE_SHARE_READ,
+                      FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
 
    RtlFreeUnicodeString (&ApplicationNameString);
 
    if (!NT_SUCCESS(Status))
-     {
-       DPRINT("Failed to open file\n");
-       SetLastErrorByStatus (Status);
-       return(NULL);
-     }
+   {
+      DPRINT("Failed to open file\n");
+      SetLastErrorByStatus (Status);
+      return(NULL);
+   }
 
    Status = NtCreateSection(&hSection,
                            SECTION_ALL_ACCESS,
@@ -501,32 +484,29 @@ HANDLE KlMapFile(LPCWSTR lpApplicationName)
    NtClose(hFile);
 
    if (!NT_SUCCESS(Status))
-     {
-       DPRINT("Failed to create section\n");
-       SetLastErrorByStatus (Status);
-       return(NULL);
-     }
+   {
+      DPRINT("Failed to create section\n");
+      SetLastErrorByStatus (Status);
+      return(NULL);
+   }
 
    return(hSection);
 }
 
-static NTSTATUS KlInitPeb
-(
- HANDLE ProcessHandle,
- PRTL_USER_PROCESS_PARAMETERS Ppb,
- PVOID * ImageBaseAddress,
- ULONG ImageSubSystem
-)
+static NTSTATUS KlInitPeb(HANDLE ProcessHandle,
+                         PRTL_USER_PROCESS_PARAMETERS Ppb,
+                         PVOID * ImageBaseAddress,
+                         ULONG ImageSubSystem)
 {
- NTSTATUS Status;
- PVOID PpbBase;
- ULONG PpbSize;
- ULONG BytesWritten;
- ULONG Offset;
- PVOID ParentEnv = NULL;
- PVOID EnvPtr = NULL;
- PWCHAR ptr;
- ULONG EnvSize = 0, EnvSize1 = 0;
  NTSTATUS Status;
  PVOID PpbBase;
  ULONG PpbSize;
  ULONG BytesWritten;
  ULONG Offset;
  PVOID ParentEnv = NULL;
  PVOID EnvPtr = NULL;
  PWCHAR ptr;
  ULONG EnvSize = 0, EnvSize1 = 0;
 
    /* create the Environment */
    if (Ppb->Environment != NULL)
@@ -535,7 +515,7 @@ static NTSTATUS KlInitPeb
       ptr = ParentEnv;
       while (*ptr)
       {
-         while(*ptr++);
+         while(*ptr++);
       }
       ptr++;
       EnvSize = (PVOID)ptr - ParentEnv;
@@ -545,41 +525,41 @@ static NTSTATUS KlInitPeb
       MEMORY_BASIC_INFORMATION MemInfo;
       ParentEnv = NtCurrentPeb()->ProcessParameters->Environment;
 
-       Status = NtQueryVirtualMemory (NtCurrentProcess (),
-                                      ParentEnv,
-                                      MemoryBasicInformation,
-                                      &MemInfo,
-                                      sizeof(MEMORY_BASIC_INFORMATION),
-                                      NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            return Status;
-         }
-       EnvSize = MemInfo.RegionSize;
-     }
+      Status = NtQueryVirtualMemory (NtCurrentProcess (),
+                                    ParentEnv,
+                                    MemoryBasicInformation,
+                                    &MemInfo,
+                                    sizeof(MEMORY_BASIC_INFORMATION),
+                                    NULL);
+      if (!NT_SUCCESS(Status))
+      {
+         return Status;
+      }
+      EnvSize = MemInfo.RegionSize;
+   }
    DPRINT("EnvironmentSize %ld\n", EnvSize);
 
    /* allocate and initialize new environment block */
    if (EnvSize != 0)
-     {
-       EnvSize1 = EnvSize;
-       Status = NtAllocateVirtualMemory(ProcessHandle,
-                                        &EnvPtr,
-                                        0,
-                                        &EnvSize1,
-                                        MEM_RESERVE | MEM_COMMIT,
-                                        PAGE_READWRITE);
-       if (!NT_SUCCESS(Status))
-         {
-            return(Status);
-         }
-
-       NtWriteVirtualMemory(ProcessHandle,
-                            EnvPtr,
-                            ParentEnv,
-                            EnvSize,
-                            &BytesWritten);
-     }
+   {
+      EnvSize1 = EnvSize;
+      Status = NtAllocateVirtualMemory(ProcessHandle,
+                                      &EnvPtr,
+                                      0,
+                                      &EnvSize1,
+                                      MEM_RESERVE | MEM_COMMIT,
+                                      PAGE_READWRITE);
+      if (!NT_SUCCESS(Status))
+      {
+         return(Status);
+      }
+
+      NtWriteVirtualMemory(ProcessHandle,
+                          EnvPtr,
+                          ParentEnv,
+                          EnvSize,
+                          &BytesWritten);
+   }
 
    /* create the PPB */
    PpbBase = NULL;
@@ -591,9 +571,9 @@ static NTSTATUS KlInitPeb
                                    MEM_RESERVE | MEM_COMMIT,
                                    PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
+   {
+      return(Status);
+   }
 
    //DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength);
    NtWriteVirtualMemory(ProcessHandle,
@@ -651,102 +631,102 @@ static LPWSTR FASTCALL
 GetFileName(LPCWSTR CurDir, LPCWSTR AppName, LPWSTR CmdLine, LPWSTR Buffer,
             unsigned BufLen)
 {
-  WCHAR *Name, *Pos, *Ret = NULL;
-  const WCHAR *p;
+   WCHAR *Name, *Pos, *Ret = NULL;
+   const WCHAR *p;
 
-  /* if we have an app name, everything is easy */
+   /* if we have an app name, everything is easy */
 
-  if (NULL != AppName)
-    {
+   if (NULL != AppName)
+   {
       /* use the unmodified app name as file name */
       wcsncpy(Buffer, AppName, BufLen );
       Ret = CmdLine;
       if (NULL == Ret || L'\0' == CmdLine[0])
-        {
-          /* no command-line, create one */
-          Ret = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(AppName) + 3) * sizeof(WCHAR));
-          if (NULL != Ret)
-            {
-              Ret[0] = L'"';
-              wcscpy(Ret + 1, AppName);
-              wcscat(Ret, L"\"");
-            }
-        }
-        return Ret;
-    }
-
-  if (NULL == CmdLine)
-    {
+      {
+         /* no command-line, create one */
+         Ret = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(AppName) + 3) * sizeof(WCHAR));
+         if (NULL != Ret)
+         {
+            Ret[0] = L'"';
+            wcscpy(Ret + 1, AppName);
+            wcscat(Ret, L"\"");
+         }
+      }
+      return Ret;
+   }
+
+   if (NULL == CmdLine)
+   {
       SetLastError(ERROR_INVALID_PARAMETER);
       return NULL;
-    }
+   }
 
-  /* first check for a quoted file name */
-  if (L'"' == CmdLine[0] && NULL != (p = wcschr(CmdLine + 1, L'"')))
-    {
+   /* first check for a quoted file name */
+   if (L'"' == CmdLine[0] && NULL != (p = wcschr(CmdLine + 1, L'"')))
+   {
       int Len = p - CmdLine - 1;
       /* extract the quoted portion as file name */
       Name = RtlAllocateHeap(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR));
       if (NULL == Name)
-        {
-          return NULL;
-        }
+      {
+         return NULL;
+      }
       memcpy(Name, CmdLine + 1, Len * sizeof(WCHAR));
       Name[Len] = L'\0';
 
       if (SearchPathW(NULL, Name, L".exe", BufLen, Buffer, NULL))
-        {
-          Ret = CmdLine;  /* no change necessary */
-        }
+      {
+         Ret = CmdLine;  /* no change necessary */
+      }
 
       RtlFreeHeap(GetProcessHeap(), 0, Name);
       return Ret;
-    }
+   }
 
-  /* now try the command-line word by word */
-  Name = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(CmdLine) + 1) * sizeof(WCHAR));
-  if (NULL == Name)
-    {
+   /* now try the command-line word by word */
+   Name = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(CmdLine) + 1) * sizeof(WCHAR));
+   if (NULL == Name)
+   {
       return NULL;
-    }
-  Pos = Name;
-  p = CmdLine;
+   }
+   Pos = Name;
+   p = CmdLine;
 
-  while (L'\0' != *p)
-    {
+   while (L'\0' != *p)
+   {
       do
-        {
-          *Pos++ = *p++;
-        }
+      {
+         *Pos++ = *p++;
+      }
       while (L'\0' != *p && L' ' != *p);
       *Pos = 0;
       if (SearchPathW(NULL, Name, L".exe", BufLen, Buffer, NULL))
-        {
-          Ret = CmdLine;
-          break;
-        }
-    }
-
-  if (NULL == Ret || NULL == wcschr(Name, L' '))
-    {
+      {
+         Ret = CmdLine;
+         break;
+      }
+   }
+
+   if (NULL == Ret || NULL == wcschr(Name, L' '))
+   {
       RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
       return Ret;
-    }
+   }
 
-  /* now build a new command-line with quotes */
-  Ret = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(CmdLine) + 3) * sizeof(WCHAR));
-  if (NULL == Ret)
-    {
+   /* now build a new command-line with quotes */
+   Ret = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(CmdLine) + 3) * sizeof(WCHAR));
+   if (NULL == Ret)
+   {
       RtlFreeHeap(GetProcessHeap(), 0, Name); /* no change necessary */
       return NULL;
-    }
-  Ret[0] = L'"';
-  wcscpy(Ret + 1, Name);
-  wcscat(Ret, L"\"");
-  wcscat(Ret, p);
-
-  RtlFreeHeap(GetProcessHeap(), 0, Name);
-  return Ret;
+   }
+   Ret[0] = L'"';
+   wcscpy(Ret + 1, Name);
+   wcscat(Ret, L"\"");
+   wcscat(Ret, p);
+
+   RtlFreeHeap(GetProcessHeap(), 0, Name);
+   return Ret;
 }
 
 
@@ -754,19 +734,16 @@ GetFileName(LPCWSTR CurDir, LPCWSTR AppName, LPWSTR CmdLine, LPWSTR Buffer,
  * @implemented
  */
 BOOL STDCALL 
-CreateProcessW
-(
- LPCWSTR lpApplicationName,
- LPWSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- BOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFOW lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation
-)
+CreateProcessW(LPCWSTR lpApplicationName,
+              LPWSTR lpCommandLine,
+              LPSECURITY_ATTRIBUTES lpProcessAttributes,
+              LPSECURITY_ATTRIBUTES lpThreadAttributes,
+              BOOL bInheritHandles,
+              DWORD dwCreationFlags,
+              LPVOID lpEnvironment,
+              LPCWSTR lpCurrentDirectory,
+              LPSTARTUPINFOW lpStartupInfo,
+              LPPROCESS_INFORMATION lpProcessInformation)
 {
    HANDLE hSection, hProcess, hThread;
    NTSTATUS Status;
@@ -798,99 +775,99 @@ CreateProcessW
    PVOID ProcSecurity = NULL;
    
    DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n",
-          lpApplicationName, lpCommandLine);
+         lpApplicationName, lpCommandLine);
 
    TidyCmdLine = GetFileName(lpCurrentDirectory, lpApplicationName, lpCommandLine, Name,
                              sizeof(Name) / sizeof(WCHAR));
    if (NULL == TidyCmdLine)
-     {
-        return FALSE;
-     }
+   {
+      return FALSE;
+   }
    DPRINT("TidyCmdLine '%S'\n", TidyCmdLine);
 
    if (lpApplicationName != NULL && lpApplicationName[0] != 0)
-     {
-        wcscpy (TempApplicationNameW, lpApplicationName);
-        i = wcslen(TempApplicationNameW);
-        if (TempApplicationNameW[i - 1] == L'.')
-          {
-            TempApplicationNameW[i - 1] = 0;
-          }
-        else
-          {
-            s = max(wcsrchr(TempApplicationNameW, L'\\'), wcsrchr(TempApplicationNameW, L'/'));
-            if (s == NULL)
-              {
-                s = TempApplicationNameW;
-              }
-            else
-              {
-                s++;
-              }
+   {
+      wcscpy (TempApplicationNameW, lpApplicationName);
+      i = wcslen(TempApplicationNameW);
+      if (TempApplicationNameW[i - 1] == L'.')
+      {
+         TempApplicationNameW[i - 1] = 0;
+      }
+      else
+      {
+         s = max(wcsrchr(TempApplicationNameW, L'\\'), wcsrchr(TempApplicationNameW, L'/'));
+         if (s == NULL)
+         {
+            s = TempApplicationNameW;
+         }
+         else
+         {
+            s++;
+         }
+         e = wcsrchr(s, L'.');
+         if (e == NULL)
+         {
+            wcscat(s, L".exe");
             e = wcsrchr(s, L'.');
-            if (e == NULL)
-              {
-                wcscat(s, L".exe");
-                e = wcsrchr(s, L'.');
-              }
-          }
-     }
+         }
+      }
+   }
    else if (L'"' == TidyCmdLine[0])
-     {
-        wcscpy(TempApplicationNameW, TidyCmdLine + 1);
-        s = wcschr(TempApplicationNameW, L'"');
-        if (NULL == s)
-          {
-            return FALSE;
-          }
-        *s = L'\0';
-     }
+   {
+      wcscpy(TempApplicationNameW, TidyCmdLine + 1);
+      s = wcschr(TempApplicationNameW, L'"');
+      if (NULL == s)
+      {
+         return FALSE;
+      }
+      *s = L'\0';
+   }
    else
-     {
-        wcscpy(TempApplicationNameW, TidyCmdLine);
-        s = wcschr(TempApplicationNameW, L' ');
-        if (NULL != s)
-          {
-            *s = L'\0';
-          }
-     }
+   {
+      wcscpy(TempApplicationNameW, TidyCmdLine);
+      s = wcschr(TempApplicationNameW, L' ');
+      if (NULL != s)
+      {
+         *s = L'\0';
+      }
+   }
    s = max(wcsrchr(TempApplicationNameW, L'\\'), wcsrchr(TempApplicationNameW, L'/'));
    if (NULL == s)
-     {
-        s = TempApplicationNameW;
-     }
+   {
+      s = TempApplicationNameW;
+   }
    s = wcsrchr(s, L'.');
    if (NULL == s)
-     {
-        wcscat(TempApplicationNameW, L".exe");
-     }
+   {
+      wcscat(TempApplicationNameW, L".exe");
+   }
 
    if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s))
    {
-     return FALSE;
+      return FALSE;
    }
 
    e = wcsrchr(s, L'.');
    if (e != NULL && (!_wcsicmp(e, L".bat") || !_wcsicmp(e, L".cmd")))
    {
-       // the command is a batch file
-       IsBatchFile = TRUE;
-       if (lpApplicationName != NULL && lpApplicationName[0])
-       {
-         // FIXME: use COMSPEC for the command interpreter
-         wcscpy(TempCommandLineNameW, L"cmd /c ");
-         wcscat(TempCommandLineNameW, lpApplicationName);
-         lpCommandLine = TempCommandLineNameW;
-         wcscpy(TempApplicationNameW, L"cmd.exe");
-          if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s))
-         {
-            return FALSE;
-         }
-       }
-       else
-       {
-         return FALSE;
-       }
+      // the command is a batch file
+      IsBatchFile = TRUE;
+      if (lpApplicationName != NULL && lpApplicationName[0])
+      {
+        // FIXME: use COMSPEC for the command interpreter
+        wcscpy(TempCommandLineNameW, L"cmd /c ");
+        wcscat(TempCommandLineNameW, lpApplicationName);
+        lpCommandLine = TempCommandLineNameW;
+        wcscpy(TempApplicationNameW, L"cmd.exe");
+         if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s))
+        {
+           return FALSE;
+        }
+      }
+      else
+      {
+        return FALSE;
+      }
    }
    
    /*
@@ -905,16 +882,16 @@ CreateProcessW
 
    /* Initialize the current directory string */
    if (lpCurrentDirectory != NULL)
-     {
-       RtlInitUnicodeString(&CurrentDirectory_U,
-                           lpCurrentDirectory);
-     }
+   {
+      RtlInitUnicodeString(&CurrentDirectory_U,
+                          lpCurrentDirectory);
+   }
    else
-     {
-       GetCurrentDirectoryW(256, TempCurrentDirectoryW);
-       RtlInitUnicodeString(&CurrentDirectory_U,
-                           TempCurrentDirectoryW);
-     }
+   {
+      GetCurrentDirectoryW(256, TempCurrentDirectoryW);
+      RtlInitUnicodeString(&CurrentDirectory_U,
+                          TempCurrentDirectoryW);
+   }
 
    /*
     * Create a section for the executable
@@ -924,91 +901,95 @@ CreateProcessW
    if (hSection == NULL)
    {
 /////////////////////////////////////////
-        /*
-         * Inspect the image to determine executable flavour
-         */
-        IO_STATUS_BLOCK IoStatusBlock;
-        UNICODE_STRING ApplicationNameString;
-        OBJECT_ATTRIBUTES ObjectAttributes;
-        PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
-        IMAGE_DOS_HEADER DosHeader;
-        IO_STATUS_BLOCK Iosb;
-        LARGE_INTEGER Offset;
-        HANDLE hFile = NULL;
-
-        DPRINT("Inspecting Image Header for image type id\n");
-
-        // Find the application name
-        if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpApplicationName,
-                &ApplicationNameString, NULL, NULL)) {
-            return FALSE;
-        }
-        DPRINT("ApplicationName %S\n",ApplicationNameString.Buffer);
-
-        InitializeObjectAttributes(&ObjectAttributes,
-                             &ApplicationNameString,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             SecurityDescriptor);
+      /*
+       * Inspect the image to determine executable flavour
+       */
+      IO_STATUS_BLOCK IoStatusBlock;
+      UNICODE_STRING ApplicationNameString;
+      OBJECT_ATTRIBUTES ObjectAttributes;
+      PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+      IMAGE_DOS_HEADER DosHeader;
+      IO_STATUS_BLOCK Iosb;
+      LARGE_INTEGER Offset;
+      HANDLE hFile = NULL;
+      DPRINT("Inspecting Image Header for image type id\n");
+
+      // Find the application name
+      if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpApplicationName,
+                                        &ApplicationNameString, NULL, NULL)) 
+      {
+         return FALSE;
+      }
+      DPRINT("ApplicationName %S\n",ApplicationNameString.Buffer);
+
+      InitializeObjectAttributes(&ObjectAttributes,
+                                &ApplicationNameString,
+                                OBJ_CASE_INSENSITIVE,
+                                NULL,
+                                SecurityDescriptor);
 
-        // Try to open the executable
-        Status = NtOpenFile(&hFile,
-                       SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       FILE_SHARE_DELETE|FILE_SHARE_READ,
-                       FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
-
-        RtlFreeUnicodeString(&ApplicationNameString);
-
-        if (!NT_SUCCESS(Status)) {
-            DPRINT("Failed to open file\n");
-            SetLastErrorByStatus(Status);
-            return FALSE;
-        }
-
-        // Read the dos header
-        Offset.QuadPart = 0;
-        Status = ZwReadFile(hFile,
-                     NULL,
-                     NULL,
-                     NULL,
-                     &Iosb,
-                     &DosHeader,
-                     sizeof(DosHeader),
-                     &Offset,
-                     0);
-
-        if (!NT_SUCCESS(Status)) {
-            DPRINT("Failed to read from file\n");
-            SetLastErrorByStatus(Status);
-            return FALSE;
-        }
-        if (Iosb.Information != sizeof(DosHeader)) {
-            DPRINT("Failed to read dos header from file\n");
-            SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
-            return FALSE;
-        }
-
-        // Check the DOS signature
-        if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
-            DPRINT("Failed dos magic check\n");
-            SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
-            return FALSE;
-        }
-        NtClose(hFile);
-
-        DPRINT("Launching VDM...\n");
-        return CreateProcessW(L"ntvdm.exe",
-                (LPWSTR)lpApplicationName,
-                lpProcessAttributes,
-                lpThreadAttributes,
-                bInheritHandles,
-                dwCreationFlags,
-                lpEnvironment,
-                lpCurrentDirectory,
-                lpStartupInfo,
-                lpProcessInformation);
+      // Try to open the executable
+      Status = NtOpenFile(&hFile,
+                         SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
+                         &ObjectAttributes,
+                         &IoStatusBlock,
+                         FILE_SHARE_DELETE|FILE_SHARE_READ,
+                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
+
+      RtlFreeUnicodeString(&ApplicationNameString);
+
+      if (!NT_SUCCESS(Status)) 
+      {
+         DPRINT("Failed to open file\n");
+                SetLastErrorByStatus(Status);
+         return FALSE;
+      }
+
+      // Read the dos header
+      Offset.QuadPart = 0;
+      Status = ZwReadFile(hFile,
+                         NULL,
+                         NULL,
+                         NULL,
+                         &Iosb,
+                         &DosHeader,
+                         sizeof(DosHeader),
+                         &Offset,
+                         0);
+
+      if (!NT_SUCCESS(Status)) 
+      {
+         DPRINT("Failed to read from file\n");
+                SetLastErrorByStatus(Status);
+         return FALSE;
+      }
+      if (Iosb.Information != sizeof(DosHeader)) 
+      {
+         DPRINT("Failed to read dos header from file\n");
+                SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
+         return FALSE;
+      }
+
+      // Check the DOS signature
+      if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) 
+      {
+         DPRINT("Failed dos magic check\n");
+         SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
+         return FALSE;
+      }
+      NtClose(hFile);
+
+      DPRINT("Launching VDM...\n");
+      return CreateProcessW(L"ntvdm.exe",
+                           (LPWSTR)lpApplicationName,
+                           lpProcessAttributes,
+                           lpThreadAttributes,
+                           bInheritHandles,
+                           dwCreationFlags,
+                           lpEnvironment,
+                           lpCurrentDirectory,
+                           lpStartupInfo,
+                           lpProcessInformation);
    }
 /////////////////////////////////////////
 
@@ -1022,27 +1003,27 @@ CreateProcessW
                           &i);
    if (! NT_SUCCESS(Status))
    {
-     NtClose(hSection);
-     DPRINT("Unable to get SectionImageInformation, status 0x%x\n", Status);
-     SetLastErrorByStatus(Status);
-     return FALSE;
+      NtClose(hSection);
+      DPRINT("Unable to get SectionImageInformation, status 0x%x\n", Status);
+      SetLastErrorByStatus(Status);
+      return FALSE;
    }
 
    if (0 != (Sii.Characteristics & IMAGE_FILE_DLL))
    {
-     NtClose(hSection);
-     DPRINT("Can't execute a DLL\n");
-     SetLastError(ERROR_BAD_EXE_FORMAT);
-     return FALSE;
+      NtClose(hSection);
+      DPRINT("Can't execute a DLL\n");
+      SetLastError(ERROR_BAD_EXE_FORMAT);
+      return FALSE;
    }
 
    if (IMAGE_SUBSYSTEM_WINDOWS_GUI != Sii.Subsystem
        && IMAGE_SUBSYSTEM_WINDOWS_CUI != Sii.Subsystem)
    {
-     NtClose(hSection);
-     DPRINT("Invalid subsystem %d\n", Sii.Subsystem);
-     SetLastError(ERROR_CHILD_NOT_COMPLETE);
-     return FALSE;
+      NtClose(hSection);
+      DPRINT("Invalid subsystem %d\n", Sii.Subsystem);
+      SetLastError(ERROR_CHILD_NOT_COMPLETE);
+      return FALSE;
    }
 
    /*
@@ -1051,11 +1032,11 @@ CreateProcessW
 
    if(lpProcessAttributes != NULL)
    {
-     if(lpProcessAttributes->bInheritHandle)
-     {
-       ProcAttributes |= OBJ_INHERIT;
-     }
-     ProcSecurity = lpProcessAttributes->lpSecurityDescriptor;
+      if(lpProcessAttributes->bInheritHandle)
+      {
+         ProcAttributes |= OBJ_INHERIT;
+      }
+      ProcSecurity = lpProcessAttributes->lpSecurityDescriptor;
    }
 
    InitializeObjectAttributes(&ProcObjectAttributes,
@@ -1070,34 +1051,34 @@ CreateProcessW
    
    if(dwCreationFlags & IDLE_PRIORITY_CLASS)
    {
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
    }
    else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
    {
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
    }
    else if(dwCreationFlags & NORMAL_PRIORITY_CLASS)
    {
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
    }
    else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
    {
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
    }
    else if(dwCreationFlags & HIGH_PRIORITY_CLASS)
    {
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
    }
    else if(dwCreationFlags & REALTIME_PRIORITY_CLASS)
    {
-     /* FIXME - This is a privileged operation. If we don't have the privilege we should
+      /* FIXME - This is a privileged operation. If we don't have the privilege we should
                 rather use PROCESS_PRIORITY_CLASS_HIGH. */
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
    }
    else
    {
-     /* FIXME - what to do in this case? */
-     PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
+      /* FIXME - what to do in this case? */
+      PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
    }
 
    /*
@@ -1150,7 +1131,7 @@ CreateProcessW
                              lpStartupInfo && lpStartupInfo->lpReserved2 ? &RuntimeInfo_U : NULL);
 
    if (lpStartupInfo && lpStartupInfo->lpReserved2)
-       RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer);
+      RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer);
 
 
    /*
@@ -1159,12 +1140,12 @@ CreateProcessW
    if (Ppb->CurrentDirectoryHandle)
    {
       Status = NtDuplicateObject (NtCurrentProcess(),
-                        Ppb->CurrentDirectoryHandle,
-                        hProcess,
-                        &Ppb->CurrentDirectoryHandle,
-                        0,
-                        TRUE,
-                        DUPLICATE_SAME_ACCESS);
+                                 Ppb->CurrentDirectoryHandle,
+                                 hProcess,
+                                 &Ppb->CurrentDirectoryHandle,
+                                 0,
+                                 TRUE,
+                                 DUPLICATE_SAME_ACCESS);
       /* FIXME - handle failure!!!!! */
    }
    
@@ -1190,20 +1171,20 @@ CreateProcessW
     */
    CsrRequest.Type = CSRSS_CREATE_PROCESS;
    CsrRequest.Data.CreateProcessRequest.NewProcessId = 
-     ProcessBasicInfo.UniqueProcessId;
+      ProcessBasicInfo.UniqueProcessId;
    if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
-     {
-        /* Do not create a console for GUI applications */
-        dwCreationFlags &= ~CREATE_NEW_CONSOLE;
-        dwCreationFlags |= DETACHED_PROCESS;
-     }
+   {
+      /* Do not create a console for GUI applications */
+      dwCreationFlags &= ~CREATE_NEW_CONSOLE;
+      dwCreationFlags |= DETACHED_PROCESS;
+   }
    else if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
-     {
-        if (NULL == Ppb->hConsole)
-          {
-            dwCreationFlags |= CREATE_NEW_CONSOLE;
-          }
-     }
+   {
+      if (NULL == Ppb->hConsole)
+      {
+         dwCreationFlags |= CREATE_NEW_CONSOLE;
+      }
+   }
    CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
    CsrRequest.Data.CreateProcessRequest.CtrlDispatcher = ConsoleControlDispatcher;
    Status = CsrClientCallServer(&CsrRequest, 
@@ -1211,9 +1192,9 @@ CreateProcessW
                                sizeof(CSRSS_API_REQUEST),
                                sizeof(CSRSS_API_REPLY));
    if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
-     {
-       DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
-     }
+   {
+      DbgPrint("Failed to tell csrss about new process. Expect trouble.\n");
+   }
 
    Ppb->hConsole = CsrReply.Data.CreateProcessReply.Console;
 
@@ -1289,7 +1270,7 @@ CreateProcessW
    }
 
    /* Now duplicate handles if required */
-   if (InputDup)
+   if (InputDup && Ppb->hStdInput != NULL)
    {
       if (IsConsoleHandle(Ppb->hStdInput))
       {
@@ -1312,7 +1293,7 @@ CreateProcessW
       }
    }
 
-   if (OutputDup)
+   if (OutputDup && Ppb->hStdOutput != NULL)
    {
       if (IsConsoleHandle(Ppb->hStdOutput))
       {
@@ -1335,7 +1316,7 @@ CreateProcessW
       }
    }
 
-   if (ErrorDup)
+   if (ErrorDup && Ppb->hStdError != NULL)
    {
       if (IsConsoleHandle(Ppb->hStdError))
       {
@@ -1376,26 +1357,26 @@ CreateProcessW
     * Initialize some other fields in the PPB
     */
    if (lpStartupInfo)
-     {
-       Ppb->dwFlags = lpStartupInfo->dwFlags;
-       if (Ppb->dwFlags & STARTF_USESHOWWINDOW)
-        {
-          Ppb->wShowWindow = lpStartupInfo->wShowWindow;
-        }
-       else
-        {
-          Ppb->wShowWindow = SW_SHOWDEFAULT;
-        }
-       Ppb->dwX = lpStartupInfo->dwX;
-       Ppb->dwY = lpStartupInfo->dwY;
-       Ppb->dwXSize = lpStartupInfo->dwXSize;
-       Ppb->dwYSize = lpStartupInfo->dwYSize;
-       Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;
-     }
+   {
+      Ppb->dwFlags = lpStartupInfo->dwFlags;
+      if (Ppb->dwFlags & STARTF_USESHOWWINDOW)
+      {
+         Ppb->wShowWindow = lpStartupInfo->wShowWindow;
+      }
+      else
+      {
+         Ppb->wShowWindow = SW_SHOWDEFAULT;
+      }
+      Ppb->dwX = lpStartupInfo->dwX;
+      Ppb->dwY = lpStartupInfo->dwY;
+      Ppb->dwXSize = lpStartupInfo->dwXSize;
+      Ppb->dwYSize = lpStartupInfo->dwYSize;
+      Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;
+   }
    else
-     {
-       Ppb->Flags = 0;
-     }
+   {
+      Ppb->Flags = 0;
+   }
    
    /*
     * Create Process Environment Block
@@ -1410,17 +1391,17 @@ CreateProcessW
     * Create the thread for the kernel
     */
    DPRINT("Creating thread for process (EntryPoint = 0x%.08x)\n",
-    (PVOID)((ULONG_PTR)ImageBaseAddress + Sii.EntryPoint));
+          (PVOID)((ULONG_PTR)ImageBaseAddress + Sii.EntryPoint));
    hThread =  KlCreateFirstThread(hProcess,
                                  lpThreadAttributes,
-          &Sii,
-          (PVOID)((ULONG_PTR)ImageBaseAddress + Sii.EntryPoint),
+                                 &Sii,
+                                 (PVOID)((ULONG_PTR)ImageBaseAddress + Sii.EntryPoint),
                                  dwCreationFlags,
                                  &lpProcessInformation->dwThreadId);
    if (hThread == INVALID_HANDLE_VALUE)
-     {
-       return FALSE;
-     }
+   {
+      return FALSE;
+   }
 
    lpProcessInformation->hProcess = hProcess;
    lpProcessInformation->hThread = hThread;
index c273c65..1caf587 100644 (file)
@@ -29,7 +29,7 @@ _except_handler(EXCEPTION_RECORD *ExceptionRecord,
                void * DispatcherContext)
 {
    EXCEPTION_POINTERS ExceptionInfo;
-   EXCEPTION_DISPOSITION ExceptionDisposition;
+   EXCEPTION_DISPOSITION ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
 
    ExceptionInfo.ExceptionRecord = ExceptionRecord;
    ExceptionInfo.ContextRecord = ContextRecord;
@@ -46,10 +46,6 @@ _except_handler(EXCEPTION_RECORD *ExceptionRecord,
       }
       _SEH_END;
    }
-   else 
-   {
-      ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
-   }
 
    if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
       ExitThread(ExceptionRecord->ExceptionCode);
@@ -330,9 +326,9 @@ GetTeb(VOID)
 BOOL STDCALL
 SwitchToThread(VOID)
 {
-  NTSTATUS errCode;
-  errCode = NtYieldExecution();
-  return TRUE;
+  NTSTATUS Status;
+  Status = NtYieldExecution();
+  return Status != STATUS_NO_YIELD_PERFORMED;
 }
 
 
index 7f289bc..6ff37fb 100644 (file)
@@ -28,7 +28,7 @@ STRINGTABLE DISCARDABLE
 IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Netzwerkkennung eingeben"\r
-FONT 8, "Helv"\r
+FONT 8, "MS Shell Dlg"\r
 {\r
  LTEXT "Bitte geben Sie Benutzernamen und Kennwort ein:", IDC_EXPLAIN, 40, 6, 150, 15\r
  LTEXT "Proxy", -1, 40, 26, 50, 10\r
index b6f9d80..97886b8 100644 (file)
@@ -28,7 +28,7 @@ STRINGTABLE DISCARDABLE
 IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Enter Network Password"\r
-FONT 8, "Helv"\r
+FONT 8, "MS Shell Dlg"\r
 {\r
  LTEXT "Please enter your username and password:", IDC_EXPLAIN, 40, 6, 150, 15\r
  LTEXT "Proxy", -1, 40, 26, 50, 10\r
index 8ee191a..1d7e32e 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 STRINGTABLE DISCARDABLE\r
 {\r
index e5def78..c0b844e 100644 (file)
@@ -1,47 +1,47 @@
-/*
- * MPR dll resources
- * French language support
- *
- * Copyright (C) 2005 Jonathan Ernst
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
-
-STRINGTABLE DISCARDABLE
-{
-    IDS_ENTIRENETWORK "Le réseau entier"
-}
-
-IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Entrez le mot de passe réseau"
-FONT 8, "Helv"
-{
- LTEXT "Veuillez saisir votre nom d'utilisateur et votre mot de passe:", IDC_EXPLAIN, 40, 6, 150, 15
- LTEXT "Proxy", -1, 40, 26, 50, 10
-/* LTEXT "Realm", -1, 40, 46, 50, 10 */
- LTEXT "Utilisateur", -1, 40, 66, 50, 10
- LTEXT "Mot de passe", -1, 40, 86, 50, 10
- LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
- LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
- EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
- EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
- CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD,
-           80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
- PUSHBUTTON "Annuler", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
-}
+/*\r
+ * MPR dll resources\r
+ * French language support\r
+ *\r
+ * Copyright (C) 2005 Jonathan Ernst\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+    IDS_ENTIRENETWORK "Le réseau entier"\r
+}\r
+\r
+IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Entrez le mot de passe réseau"\r
+FONT 8, "MS Shell Dlg"\r
+{\r
+ LTEXT "Veuillez saisir votre nom d'utilisateur et votre mot de passe:", IDC_EXPLAIN, 40, 6, 150, 15\r
+ LTEXT "Proxy", -1, 40, 26, 50, 10\r
+/* LTEXT "Realm", -1, 40, 46, 50, 10 */\r
+ LTEXT "Utilisateur", -1, 40, 66, 50, 10\r
+ LTEXT "Mot de passe", -1, 40, 86, 50, 10\r
+ LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0\r
+ LTEXT "" IDC_REALM, 80, 46, 150, 14, 0\r
+ EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP\r
+ EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD\r
+ CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD,\r
+           80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP\r
+ PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON\r
+ PUSHBUTTON "Annuler", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP\r
+}\r
index 5ad2f9f..fc65bfd 100644 (file)
@@ -24,3 +24,23 @@ STRINGTABLE DISCARDABLE
 {\r
     IDS_ENTIRENETWORK "Toda a rede"\r
 }\r
+\r
+IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Entre a senha da rede"\r
+FONT 8, "MS Shell Dlg"\r
+{\r
+ LTEXT "Por favor, entre como o nome de usuário e a senha:", IDC_EXPLAIN, 40, 6, 150, 15\r
+ LTEXT "Proxy", -1, 40, 26, 50, 10\r
+/* LTEXT "Realm", -1, 40, 46, 50, 10 */\r
+ LTEXT "Usuário", -1, 40, 66, 50, 10\r
+ LTEXT "Senha", -1, 40, 86, 50, 10\r
+ LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0\r
+ LTEXT "" IDC_REALM, 80, 46, 150, 14, 0\r
+ EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP\r
+ EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD\r
+ CHECKBOX "&Salvar esta senha (Inseguro)", IDC_SAVEPASSWORD,\r
+           80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP\r
+ PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON\r
+ PUSHBUTTON "Cancelar", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP\r
+}\r
index 8c9c4b4..6aa4071 100644 (file)
@@ -412,6 +412,8 @@ PSOCKET_INFORMATION GetSocketStructure(
        SOCKET Handle
 );
 
+VOID DeleteSocketStructure( SOCKET Handle );
+
 int GetSocketInformation(
        PSOCKET_INFORMATION Socket,
        ULONG                           AfdInformationClass,
index dde09e3..6a375ae 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * COPYRIGHT:   See COPYING in the top level directory
  * PROJECT:     ReactOS Ancillary Function Driver DLL
@@ -61,7 +62,7 @@ WSPSocket(
        ULONG                                           SizeOfEA;
        PAFD_CREATE_PACKET                      AfdPacket;
        HANDLE                                          Sock;
-       PSOCKET_INFORMATION                     Socket = NULL;
+       PSOCKET_INFORMATION                     Socket = NULL, PrevSocket = NULL;
     PFILE_FULL_EA_INFORMATION  EABuffer = NULL;
        PHELPER_DATA                            HelperData;
        PVOID                                           HelperDLLContext;
@@ -224,6 +225,16 @@ WSPSocket(
        /* Save Handle */
        Socket->Handle = (SOCKET)Sock;
 
+        /* XXX See if there's a structure we can reuse -- We need to do this
+         * more properly. */
+        PrevSocket = GetSocketStructure( (SOCKET)Sock );
+
+        if( PrevSocket ) {
+            RtlCopyMemory( PrevSocket, Socket, sizeof(*Socket) );
+            RtlFreeHeap( GlobalHeap, 0, Socket );
+            Socket = PrevSocket;
+        }
+
        /* Save Group Info */
        if (g != 0) {
                GetSocketInformation(Socket, AFD_INFO_GROUP_ID_TYPE, 0, &GroupData);
@@ -234,13 +245,13 @@ WSPSocket(
 
        /* Get Window Sizes and Save them */
        GetSocketInformation (Socket,
-                                                       AFD_INFO_SEND_WINDOW_SIZE, 
-                                                       &Socket->SharedData.SizeOfSendBuffer, 
-                                                       NULL);
+                              AFD_INFO_SEND_WINDOW_SIZE, 
+                              &Socket->SharedData.SizeOfSendBuffer, 
+                              NULL);
        GetSocketInformation (Socket, 
-                                                       AFD_INFO_RECEIVE_WINDOW_SIZE, 
-                                                       &Socket->SharedData.SizeOfRecvBuffer, 
-                                                       NULL);
+                              AFD_INFO_RECEIVE_WINDOW_SIZE, 
+                              &Socket->SharedData.SizeOfRecvBuffer, 
+                              NULL);
 
        /* Save in Process Sockets List */
        Sockets[SocketCount] = Socket;
@@ -423,6 +434,7 @@ WSPCloseSocket(
 
     /* Close the handle */
     NtClose((HANDLE)Handle);
+
     return NO_ERROR;
 }
 
@@ -590,6 +602,9 @@ WSPSelect(
        ( readfds ? readfds->fd_count : 0 ) + 
        ( writefds ? writefds->fd_count : 0 ) + 
        ( exceptfds ? exceptfds->fd_count : 0 );
+
+    if( HandleCount < 0 || nfds != 0 ) HandleCount = nfds * 3;
+
     PollBufferSize = sizeof(*PollInfo) + 
        (HandleCount * sizeof(AFD_HANDLE));
     
@@ -861,12 +876,12 @@ WSPAccept(
 
                /* Set up Address in SOCKADDR Format */
                RtlCopyMemory (RemoteAddress, 
-                                               &ListenReceiveData->Address.Address[0].AddressType, 
-                                               sizeof(RemoteAddress));
+                               &ListenReceiveData->Address.Address[0].AddressType, 
+                               sizeof(*RemoteAddress));
 
                /* Build Caller ID */
                CallerID.buf = (PVOID)RemoteAddress;
-               CallerID.len = sizeof(RemoteAddress);
+               CallerID.len = sizeof(*RemoteAddress);
 
                /* Build Caller Data */
                CallerData.buf = PendingData;
@@ -985,8 +1000,8 @@ WSPAccept(
         if( SocketAddress ) {
             RtlCopyMemory (SocketAddress, 
                            &ListenReceiveData->Address.Address[0].AddressType, 
-                           sizeof(RemoteAddress));
-            if( *SocketAddressLength )
+                           sizeof(*RemoteAddress));
+            if( SocketAddressLength )
                 *SocketAddressLength = 
                     ListenReceiveData->Address.Address[0].AddressLength;
         }
@@ -1285,6 +1300,13 @@ WSPGetSockName(
                        RtlCopyMemory (Name->sa_data,
                                       SocketAddress->Address[0].Address, 
                                       SocketAddress->Address[0].AddressLength);
+                       *NameLength = 2 + SocketAddress->Address[0].AddressLength;
+                        AFD_DbgPrint
+                            (MID_TRACE,
+                             ("NameLength %d Address: %x Port %x\n",
+                              *NameLength, 
+                              ((struct sockaddr_in *)Name)->sin_addr.s_addr,
+                              ((struct sockaddr_in *)Name)->sin_port));
                        HeapFree(GlobalHeap, 0, TdiAddress);
                        return 0;
                } else {
@@ -1363,6 +1385,13 @@ WSPGetPeerName(
                        RtlCopyMemory (Name->sa_data,
                                       SocketAddress->Address[0].Address, 
                                       SocketAddress->Address[0].AddressLength);
+                       *NameLength = 2 + SocketAddress->Address[0].AddressLength;
+                        AFD_DbgPrint
+                            (MID_TRACE,
+                             ("NameLength %d Address: %s Port %x\n",
+                              *NameLength, 
+                              ((struct sockaddr_in *)Name)->sin_addr.s_addr,
+                              ((struct sockaddr_in *)Name)->sin_port));
                        HeapFree(GlobalHeap, 0, TdiAddress);
                        return 0;
                } else {
@@ -1682,6 +1711,9 @@ SetSocketInformation(
                InfoData.Information.LargeInteger = *LargeInteger;
        }
 
+        AFD_DbgPrint(MID_TRACE,("XXX Info %x (Data %x)\n",
+                                AfdInformationClass, *Ulong));
+
        /* Send IOCTL */
        Status = NtDeviceIoControlFile( (HANDLE)Socket->Handle,
                                        SockEvent,
index ebad074..3659e52 100644 (file)
  *      24-11-2003  Created
  */
 #include <windows.h>
-#include <WinWlx.h>
+#include <winwlx.h>
 #include "msgina.h"
 #include "resource.h"
 
+#include <wine/debug.h>
+
 extern HINSTANCE hDllInstance;
 
 typedef struct _DISPLAYSTATUSMSG
@@ -203,7 +205,7 @@ WlxActivateUserShell(
   if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, 
                   L"SOFTWARE\\ReactOS\\Windows NT\\CurrentVersion\\Winlogon", 
                   0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
-  {DbgPrint("GINA: Failed: 1\n");
+  {ERR("GINA: Failed: 1\n");
     VirtualFree(pEnvironment, 0, MEM_RELEASE);
     return FALSE;
   }
@@ -211,7 +213,7 @@ WlxActivateUserShell(
   if((RegQueryValueEx(hKey, L"Userinit", NULL, &ValueType, (LPBYTE)pszUserInitApp, 
                      &BufSize) != ERROR_SUCCESS) || 
                      !((ValueType == REG_SZ) || (ValueType == REG_EXPAND_SZ)))
-  {DbgPrint("GINA: Failed: 2\n");
+  {ERR("GINA: Failed: 2\n");
     RegCloseKey(hKey);
     VirtualFree(pEnvironment, 0, MEM_RELEASE);
     return FALSE;
@@ -243,7 +245,7 @@ WlxActivateUserShell(
                             NULL,
                             &si,
                             &pi);
-  if(!Ret) DbgPrint("GINA: Failed: 3\n");
+  if(!Ret) ERR("GINA: Failed: 3\n");
   VirtualFree(pEnvironment, 0, MEM_RELEASE);
   return Ret;
 }
@@ -281,22 +283,22 @@ WlxLoggedOnSAS(
     }
     case WLX_SAS_TYPE_SC_INSERT:
     {
-      DbgPrint("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
+      FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
       break;
     }
     case WLX_SAS_TYPE_SC_REMOVE:
     {
-      DbgPrint("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
+      FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
       break;
     }
     case WLX_SAS_TYPE_TIMEOUT:
     {
-      DbgPrint("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
+      FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_TIMEOUT not supported!\n");
       break;
     }
     default:
     {
-      DbgPrint("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
+      WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
       break;
     }
   }
@@ -494,7 +496,7 @@ WlxLoggedOutSAS(
 
   if(!phToken)
   {
-    DbgPrint("msgina: phToken == NULL!\n");
+    WARN("msgina: phToken == NULL!\n");
     return WLX_SAS_ACTION_NONE;
   }
 
@@ -503,13 +505,13 @@ WlxLoggedOutSAS(
                 LOGON32_PROVIDER_DEFAULT,
                 phToken))
   {
-    DbgPrint("msgina: Logonuser() failed\n");
+    WARN("msgina: Logonuser() failed\n");
     return WLX_SAS_ACTION_NONE;
   }
   
   if(!(*phToken))
   {
-    DbgPrint("msgina: *phToken == NULL!\n");
+    WARN("msgina: *phToken == NULL!\n");
     return WLX_SAS_ACTION_NONE;
   }
 
@@ -524,7 +526,7 @@ WlxLoggedOutSAS(
                           sizeof(TOKEN_STATISTICS),
                           &cbStats))
   {
-    DbgPrint("msgina: Couldn't get Autentication id from user token!\n");
+    WARN("msgina: Couldn't get Autentication id from user token!\n");
     return WLX_SAS_ACTION_NONE;
   }
   *pAuthenticationId = Stats.AuthenticationId; 
index 9ca8ac5..e36fd15 100644 (file)
  *      24-11-2003  Created
  */
 #include <windows.h>
-#include <WinWlx.h>
-
-#define UNIMPLEMENTED \
-  DbgPrint("MSGINA:  %s at %s:%d is UNIMPLEMENTED!\n",__FUNCTION__,__FILE__,__LINE__)
+#include <winwlx.h>
 
+#include <wine/debug.h>
 
 /*
  * @unimplemented
index 27ce824..14ad0ed 100644 (file)
@@ -11,6 +11,7 @@ C_SRCS = \
        appsearch.c \\r
        create.c \\r
        custom.c \\r
+       delete.c \\r
        dialog.c \\r
        distinct.c \\r
        format.c \\r
index 5b4c8e1..aef211a 100644 (file)
-/*\r
- * Implementation of the Microsoft Installer (msi.dll)\r
- *\r
- * Copyright 2004 Aric Stewart for CodeWeavers\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-/*\r
- * Pages I need\r
- *\r
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installexecutesequence_table.asp\r
-\r
-http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/standard_actions_reference.asp\r
- */\r
-\r
-#include <stdarg.h>\r
-#include <stdio.h>\r
-\r
-#include <fcntl.h>\r
-#define COBJMACROS\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winerror.h"\r
-#include "winreg.h"\r
-#include "wine/debug.h"\r
-#include "fdi.h"\r
-#include "msi.h"\r
-#include "msiquery.h"\r
-//#include "msvcrt/fcntl.h"\r
-#include "objbase.h"\r
-#include "objidl.h"\r
-#include "msipriv.h"\r
-#include "winnls.h"\r
-#include "winuser.h"\r
-#include "shlobj.h"\r
-#include "wine/unicode.h"\r
-#include "ver.h"\r
-#include "action.h"\r
-\r
-#define REG_PROGRESS_VALUE 13200\r
-#define COMPONENT_PROGRESS_VALUE 24000\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(msi);\r
-\r
-/*\r
- * Prototypes\r
- */\r
-static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);\r
-static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);\r
-static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq);\r
-static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, \r
-                            LPWSTR *FilePath);\r
-\r
-/* \r
- * action handlers\r
- */\r
-typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);\r
-\r
-static UINT ACTION_LaunchConditions(MSIPACKAGE *package);\r
-static UINT ACTION_CostInitialize(MSIPACKAGE *package);\r
-static UINT ACTION_CreateFolders(MSIPACKAGE *package);\r
-static UINT ACTION_CostFinalize(MSIPACKAGE *package);\r
-static UINT ACTION_FileCost(MSIPACKAGE *package);\r
-static UINT ACTION_InstallFiles(MSIPACKAGE *package);\r
-static UINT ACTION_DuplicateFiles(MSIPACKAGE *package);\r
-static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package);\r
-static UINT ACTION_InstallInitialize(MSIPACKAGE *package);\r
-static UINT ACTION_InstallValidate(MSIPACKAGE *package);\r
-static UINT ACTION_ProcessComponents(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterUser(MSIPACKAGE *package);\r
-static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);\r
-static UINT ACTION_PublishProduct(MSIPACKAGE *package);\r
-static UINT ACTION_WriteIniValues(MSIPACKAGE *package);\r
-static UINT ACTION_SelfRegModules(MSIPACKAGE *package);\r
-static UINT ACTION_PublishFeatures(MSIPACKAGE *package);\r
-static UINT ACTION_RegisterProduct(MSIPACKAGE *package);\r
-static UINT ACTION_InstallExecute(MSIPACKAGE *package);\r
-static UINT ACTION_InstallFinalize(MSIPACKAGE *package);\r
-static UINT ACTION_ForceReboot(MSIPACKAGE *package);\r
-static UINT ACTION_ResolveSource(MSIPACKAGE *package);\r
-\r
\r
-/*\r
- * consts and values used\r
- */\r
-static const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};\r
-static const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};\r
-static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};\r
-static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};\r
-static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};\r
-static const WCHAR c_collen[] = {'C',':','\\',0};\r
\r
-static const WCHAR cszbs[]={'\\',0};\r
-\r
-const static WCHAR szCreateFolders[] =\r
-{'C','r','e','a','t','e','F','o','l','d','e','r','s',0};\r
-const static WCHAR szCostFinalize[] =\r
-{'C','o','s','t','F','i','n','a','l','i','z','e',0};\r
-const static WCHAR szInstallFiles[] =\r
-{'I','n','s','t','a','l','l','F','i','l','e','s',0};\r
-const static WCHAR szDuplicateFiles[] =\r
-{'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};\r
-const static WCHAR szWriteRegistryValues[] =\r
-{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};\r
-const static WCHAR szCostInitialize[] =\r
-{'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};\r
-const static WCHAR szFileCost[] = \r
-{'F','i','l','e','C','o','s','t',0};\r
-const static WCHAR szInstallInitialize[] = \r
-{'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};\r
-const static WCHAR szInstallValidate[] = \r
-{'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};\r
-const static WCHAR szLaunchConditions[] = \r
-{'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};\r
-const static WCHAR szProcessComponents[] = \r
-{'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};\r
-const static WCHAR szRegisterTypeLibraries[] = \r
-{'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r',\r
-'i','e','s',0};\r
-const static WCHAR szRegisterClassInfo[] = \r
-{'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};\r
-const static WCHAR szRegisterProgIdInfo[] = \r
-{'R','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};\r
-const static WCHAR szCreateShortcuts[] = \r
-{'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0};\r
-const static WCHAR szPublishProduct[] = \r
-{'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};\r
-const static WCHAR szWriteIniValues[] = \r
-{'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0};\r
-const static WCHAR szSelfRegModules[] = \r
-{'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0};\r
-const static WCHAR szPublishFeatures[] = \r
-{'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};\r
-const static WCHAR szRegisterProduct[] = \r
-{'R','e','g','i','s','t','e','r','P','r','o','d','u','c','t',0};\r
-const static WCHAR szInstallExecute[] = \r
-{'I','n','s','t','a','l','l','E','x','e','c','u','t','e',0};\r
-const static WCHAR szInstallExecuteAgain[] = \r
-{'I','n','s','t','a','l','l','E','x','e','c','u','t','e','A','g','a','i','n',0};\r
-const static WCHAR szInstallFinalize[] = \r
-{'I','n','s','t','a','l','l','F','i','n','a','l','i','z','e',0};\r
-const static WCHAR szForceReboot[] = \r
-{'F','o','r','c','e','R','e','b','o','o','t',0};\r
-const static WCHAR szResolveSource[] =\r
-{'R','e','s','o','l','v','e','S','o','u','r','c','e',0};\r
-const static WCHAR szAppSearch[] = \r
-{'A','p','p','S','e','a','r','c','h',0};\r
-const static WCHAR szAllocateRegistrySpace[] = \r
-{'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y','S','p','a','c','e',0};\r
-const static WCHAR szBindImage[] = \r
-{'B','i','n','d','I','m','a','g','e',0};\r
-const static WCHAR szCCPSearch[] = \r
-{'C','C','P','S','e','a','r','c','h',0};\r
-const static WCHAR szDeleteServices[] = \r
-{'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0};\r
-const static WCHAR szDisableRollback[] = \r
-{'D','i','s','a','b','l','e','R','o','l','l','b','a','c','k',0};\r
-const static WCHAR szExecuteAction[] = \r
-{'E','x','e','c','u','t','e','A','c','t','i','o','n',0};\r
-const static WCHAR szFindRelatedProducts[] = \r
-{'F','i','n','d','R','e','l','a','t','e','d','P','r','o','d','u','c','t','s',0};\r
-const static WCHAR szInstallAdminPackage[] = \r
-{'I','n','s','t','a','l','l','A','d','m','i','n','P','a','c','k','a','g','e',0};\r
-const static WCHAR szInstallSFPCatalogFile[] = \r
-{'I','n','s','t','a','l','l','S','F','P','C','a','t','a','l','o','g','F','i','l','e',0};\r
-const static WCHAR szIsolateComponents[] = \r
-{'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};\r
-const static WCHAR szMigrateFeatureStates[] = \r
-{'M','i','g','r','a','t','e','F','e','a','t','u','r','e','S','t','a','t','e','s',0};\r
-const static WCHAR szMoveFiles[] = \r
-{'M','o','v','e','F','i','l','e','s',0};\r
-const static WCHAR szMsiPublishAssemblies[] = \r
-{'M','s','i','P','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};\r
-const static WCHAR szMsiUnpublishAssemblies[] = \r
-{'M','s','i','U','n','p','u','b','l','i','s','h','A','s','s','e','m','b','l','i','e','s',0};\r
-const static WCHAR szInstallODBC[] = \r
-{'I','n','s','t','a','l','l','O','D','B','C',0};\r
-const static WCHAR szInstallServices[] = \r
-{'I','n','s','t','a','l','l','S','e','r','v','i','c','e','s',0};\r
-const static WCHAR szPatchFiles[] = \r
-{'P','a','t','c','h','F','i','l','e','s',0};\r
-const static WCHAR szPublishComponents[] = \r
-{'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};\r
-const static WCHAR szRegisterComPlus[] =\r
-{'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};\r
-const static WCHAR szRegisterExtensionInfo[] =\r
-{'R','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};\r
-const static WCHAR szRegisterFonts[] =\r
-{'R','e','g','i','s','t','e','r','F','o','n','t','s',0};\r
-const static WCHAR szRegisterMIMEInfo[] =\r
-{'R','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};\r
-const static WCHAR szRegisterUser[] =\r
-{'R','e','g','i','s','t','e','r','U','s','e','r',0};\r
-const static WCHAR szRemoveDuplicateFiles[] =\r
-{'R','e','m','o','v','e','D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};\r
-const static WCHAR szRemoveEnvironmentStrings[] =\r
-{'R','e','m','o','v','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};\r
-const static WCHAR szRemoveExistingProducts[] =\r
-{'R','e','m','o','v','e','E','x','i','s','t','i','n','g','P','r','o','d','u','c','t','s',0};\r
-const static WCHAR szRemoveFiles[] =\r
-{'R','e','m','o','v','e','F','i','l','e','s',0};\r
-const static WCHAR szRemoveFolders[] =\r
-{'R','e','m','o','v','e','F','o','l','d','e','r','s',0};\r
-const static WCHAR szRemoveIniValues[] =\r
-{'R','e','m','o','v','e','I','n','i','V','a','l','u','e','s',0};\r
-const static WCHAR szRemoveODBC[] =\r
-{'R','e','m','o','v','e','O','D','B','C',0};\r
-const static WCHAR szRemoveRegistryValues[] =\r
-{'R','e','m','o','v','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};\r
-const static WCHAR szRemoveShortcuts[] =\r
-{'R','e','m','o','v','e','S','h','o','r','t','c','u','t','s',0};\r
-const static WCHAR szRMCCPSearch[] =\r
-{'R','M','C','C','P','S','e','a','r','c','h',0};\r
-const static WCHAR szScheduleReboot[] =\r
-{'S','c','h','e','d','u','l','e','R','e','b','o','o','t',0};\r
-const static WCHAR szSelfUnregModules[] =\r
-{'S','e','l','f','U','n','r','e','g','M','o','d','u','l','e','s',0};\r
-const static WCHAR szSetODBCFolders[] =\r
-{'S','e','t','O','D','B','C','F','o','l','d','e','r','s',0};\r
-const static WCHAR szStartServices[] =\r
-{'S','t','a','r','t','S','e','r','v','i','c','e','s',0};\r
-const static WCHAR szStopServices[] =\r
-{'S','t','o','p','S','e','r','v','i','c','e','s',0};\r
-const static WCHAR szUnpublishComponents[] =\r
-{'U','n','p','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};\r
-const static WCHAR szUnpublishFeatures[] =\r
-{'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};\r
-const static WCHAR szUnregisterClassInfo[] =\r
-{'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};\r
-const static WCHAR szUnregisterComPlus[] =\r
-{'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};\r
-const static WCHAR szUnregisterExtensionInfo[] =\r
-{'U','n','r','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n','I','n','f','o',0};\r
-const static WCHAR szUnregisterFonts[] =\r
-{'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};\r
-const static WCHAR szUnregisterMIMEInfo[] =\r
-{'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};\r
-const static WCHAR szUnregisterProgIdInfo[] =\r
-{'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};\r
-const static WCHAR szUnregisterTypeLibraries[] =\r
-{'U','n','r','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r','i','e','s',0};\r
-const static WCHAR szValidateProductID[] =\r
-{'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};\r
-const static WCHAR szWriteEnvironmentStrings[] =\r
-{'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t','S','t','r','i','n','g','s',0};\r
-\r
-struct _actions {\r
-    LPCWSTR action;\r
-    STANDARDACTIONHANDLER handler;\r
-};\r
-\r
-struct _actions StandardActions[] = {\r
-    { szAllocateRegistrySpace, NULL},\r
-    { szAppSearch, ACTION_AppSearch },\r
-    { szBindImage, NULL},\r
-    { szCCPSearch, NULL},\r
-    { szCostFinalize, ACTION_CostFinalize },\r
-    { szCostInitialize, ACTION_CostInitialize },\r
-    { szCreateFolders, ACTION_CreateFolders },\r
-    { szCreateShortcuts, ACTION_CreateShortcuts },\r
-    { szDeleteServices, NULL},\r
-    { szDisableRollback, NULL},\r
-    { szDuplicateFiles, ACTION_DuplicateFiles},\r
-    { szExecuteAction, NULL},\r
-    { szFileCost, ACTION_FileCost },\r
-    { szFindRelatedProducts, NULL},\r
-    { szForceReboot, ACTION_ForceReboot },\r
-    { szInstallAdminPackage, NULL},\r
-    { szInstallExecute, ACTION_InstallExecute },\r
-    { szInstallExecuteAgain, ACTION_InstallExecute },\r
-    { szInstallFiles, ACTION_InstallFiles},\r
-    { szInstallFinalize, ACTION_InstallFinalize },\r
-    { szInstallInitialize, ACTION_InstallInitialize },\r
-    { szInstallSFPCatalogFile, NULL},\r
-    { szInstallValidate, ACTION_InstallValidate },\r
-    { szIsolateComponents, NULL},\r
-    { szLaunchConditions, ACTION_LaunchConditions },\r
-    { szMigrateFeatureStates, NULL},\r
-    { szMoveFiles, NULL},\r
-    { szMsiPublishAssemblies, NULL},\r
-    { szMsiUnpublishAssemblies, NULL},\r
-    { szInstallODBC, NULL},\r
-    { szInstallServices, NULL},\r
-    { szPatchFiles, NULL},\r
-    { szProcessComponents, ACTION_ProcessComponents },\r
-    { szPublishComponents, NULL},\r
-    { szPublishFeatures, ACTION_PublishFeatures },\r
-    { szPublishProduct, ACTION_PublishProduct },\r
-    { szRegisterClassInfo, ACTION_RegisterClassInfo },\r
-    { szRegisterComPlus, NULL},\r
-    { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo },\r
-    { szRegisterFonts, NULL},\r
-    { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo },\r
-    { szRegisterProduct, ACTION_RegisterProduct },\r
-    { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo },\r
-    { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries },\r
-    { szRegisterUser, ACTION_RegisterUser},\r
-    { szRemoveDuplicateFiles, NULL},\r
-    { szRemoveEnvironmentStrings, NULL},\r
-    { szRemoveExistingProducts, NULL},\r
-    { szRemoveFiles, NULL},\r
-    { szRemoveFolders, NULL},\r
-    { szRemoveIniValues, NULL},\r
-    { szRemoveODBC, NULL},\r
-    { szRemoveRegistryValues, NULL},\r
-    { szRemoveShortcuts, NULL},\r
-    { szResolveSource, ACTION_ResolveSource},\r
-    { szRMCCPSearch, NULL},\r
-    { szScheduleReboot, NULL},\r
-    { szSelfRegModules, ACTION_SelfRegModules },\r
-    { szSelfUnregModules, NULL},\r
-    { szSetODBCFolders, NULL},\r
-    { szStartServices, NULL},\r
-    { szStopServices, NULL},\r
-    { szUnpublishComponents, NULL},\r
-    { szUnpublishFeatures, NULL},\r
-    { szUnregisterClassInfo, NULL},\r
-    { szUnregisterComPlus, NULL},\r
-    { szUnregisterExtensionInfo, NULL},\r
-    { szUnregisterFonts, NULL},\r
-    { szUnregisterMIMEInfo, NULL},\r
-    { szUnregisterProgIdInfo, NULL},\r
-    { szUnregisterTypeLibraries, NULL},\r
-    { szValidateProductID, NULL},\r
-    { szWriteEnvironmentStrings, NULL},\r
-    { szWriteIniValues, ACTION_WriteIniValues },\r
-    { szWriteRegistryValues, ACTION_WriteRegistryValues},\r
-    { NULL, NULL},\r
-};\r
-\r
-\r
-/******************************************************** \r
- * helper functions to get around current HACKS and such\r
- ********************************************************/\r
-inline static void reduce_to_longfilename(WCHAR* filename)\r
-{\r
-    LPWSTR p = strchrW(filename,'|');\r
-    if (p)\r
-        memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));\r
-}\r
-\r
-WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)\r
-{\r
-    UINT rc;\r
-    DWORD sz;\r
-    LPWSTR ret;\r
-   \r
-    sz = 0; \r
-    if (MSI_RecordIsNull(row,index))\r
-        return NULL;\r
-\r
-    rc = MSI_RecordGetStringW(row,index,NULL,&sz);\r
-\r
-    /* having an empty string is different than NULL */\r
-    if (sz == 0)\r
-    {\r
-        ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));\r
-        ret[0] = 0;\r
-        return ret;\r
-    }\r
-\r
-    sz ++;\r
-    ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));\r
-    rc = MSI_RecordGetStringW(row,index,ret,&sz);\r
-    if (rc!=ERROR_SUCCESS)\r
-    {\r
-        ERR("Unable to load dynamic string\n");\r
-        HeapFree(GetProcessHeap(), 0, ret);\r
-        ret = NULL;\r
-    }\r
-    return ret;\r
-}\r
-\r
-LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc)\r
-{\r
-    DWORD sz = 0;\r
-    LPWSTR str;\r
-    UINT r;\r
-\r
-    r = MSI_GetPropertyW(package, prop, NULL, &sz);\r
-    if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)\r
-    {\r
-        if (rc)\r
-            *rc = r;\r
-        return NULL;\r
-    }\r
-    sz++;\r
-    str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));\r
-    r = MSI_GetPropertyW(package, prop, str, &sz);\r
-    if (r != ERROR_SUCCESS)\r
-    {\r
-        HeapFree(GetProcessHeap(),0,str);\r
-        str = NULL;\r
-    }\r
-    if (rc)\r
-        *rc = r;\r
-    return str;\r
-}\r
-\r
-int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )\r
-{\r
-    int rc = -1;\r
-    DWORD i;\r
-\r
-    for (i = 0; i < package->loaded_components; i++)\r
-    {\r
-        if (strcmpW(Component,package->components[i].Component)==0)\r
-        {\r
-            rc = i;\r
-            break;\r
-        }\r
-    }\r
-    return rc;\r
-}\r
-\r
-int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )\r
-{\r
-    int rc = -1;\r
-    DWORD i;\r
-\r
-    for (i = 0; i < package->loaded_features; i++)\r
-    {\r
-        if (strcmpW(Feature,package->features[i].Feature)==0)\r
-        {\r
-            rc = i;\r
-            break;\r
-        }\r
-    }\r
-    return rc;\r
-}\r
-\r
-int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)\r
-{\r
-    int rc = -1;\r
-    DWORD i;\r
-\r
-    for (i = 0; i < package->loaded_files; i++)\r
-    {\r
-        if (strcmpW(file,package->files[i].File)==0)\r
-        {\r
-            rc = i;\r
-            break;\r
-        }\r
-    }\r
-    return rc;\r
-}\r
-\r
-int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)\r
-{\r
-    DWORD i;\r
-    DWORD index;\r
-\r
-    if (!package)\r
-        return -2;\r
-\r
-    for (i=0; i < package->loaded_files; i++)\r
-        if (strcmpW(package->files[i].File,name)==0)\r
-            return -1;\r
-\r
-    index = package->loaded_files;\r
-    package->loaded_files++;\r
-    if (package->loaded_files== 1)\r
-        package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));\r
-    else\r
-        package->files = HeapReAlloc(GetProcessHeap(),0,\r
-            package->files , package->loaded_files * sizeof(MSIFILE));\r
-\r
-    memset(&package->files[index],0,sizeof(MSIFILE));\r
-\r
-    package->files[index].File = dupstrW(name);\r
-    package->files[index].TargetPath = dupstrW(path);\r
-    package->files[index].Temporary = TRUE;\r
-\r
-    TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));  \r
-\r
-    return 0;\r
-}\r
-\r
-static void remove_tracked_tempfiles(MSIPACKAGE* package)\r
-{\r
-    DWORD i;\r
-\r
-    if (!package)\r
-        return;\r
-\r
-    for (i = 0; i < package->loaded_files; i++)\r
-    {\r
-        if (package->files[i].Temporary)\r
-        {\r
-            TRACE("Cleaning up %s\n",debugstr_w(package->files[i].TargetPath));\r
-            DeleteFileW(package->files[i].TargetPath);\r
-        }\r
-\r
-    }\r
-}\r
-\r
-/* wrapper to resist a need for a full rewrite right now */\r
-DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data )\r
-{\r
-    if (ptr)\r
-    {\r
-        MSIRECORD *rec = MSI_CreateRecord(1);\r
-        DWORD size = 0;\r
-\r
-        MSI_RecordSetStringW(rec,0,ptr);\r
-        MSI_FormatRecordW(package,rec,NULL,&size);\r
-        if (size >= 0)\r
-        {\r
-            size++;\r
-            *data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));\r
-            if (size > 1)\r
-                MSI_FormatRecordW(package,rec,*data,&size);\r
-            else\r
-                *data[0] = 0;\r
-            msiobj_release( &rec->hdr );\r
-            return sizeof(WCHAR)*size;\r
-        }\r
-        msiobj_release( &rec->hdr );\r
-    }\r
-\r
-    *data = NULL;\r
-    return 0;\r
-}\r
-\r
-/* Called when the package is being closed */\r
-void ACTION_free_package_structures( MSIPACKAGE* package)\r
-{\r
-    INT i;\r
-    \r
-    TRACE("Freeing package action data\n");\r
-\r
-    remove_tracked_tempfiles(package);\r
-\r
-    /* No dynamic buffers in features */\r
-    if (package->features && package->loaded_features > 0)\r
-        HeapFree(GetProcessHeap(),0,package->features);\r
-\r
-    for (i = 0; i < package->loaded_folders; i++)\r
-    {\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].Directory);\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].TargetDefault);\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].SourceDefault);\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedSource);\r
-        HeapFree(GetProcessHeap(),0,package->folders[i].Property);\r
-    }\r
-    if (package->folders && package->loaded_folders > 0)\r
-        HeapFree(GetProcessHeap(),0,package->folders);\r
-\r
-    /* no dynamic buffers in components */ \r
-    if (package->components && package->loaded_components > 0)\r
-        HeapFree(GetProcessHeap(),0,package->components);\r
-\r
-    for (i = 0; i < package->loaded_files; i++)\r
-    {\r
-        HeapFree(GetProcessHeap(),0,package->files[i].File);\r
-        HeapFree(GetProcessHeap(),0,package->files[i].FileName);\r
-        HeapFree(GetProcessHeap(),0,package->files[i].Version);\r
-        HeapFree(GetProcessHeap(),0,package->files[i].Language);\r
-        HeapFree(GetProcessHeap(),0,package->files[i].SourcePath);\r
-        HeapFree(GetProcessHeap(),0,package->files[i].TargetPath);\r
-    }\r
-\r
-    if (package->files && package->loaded_files > 0)\r
-        HeapFree(GetProcessHeap(),0,package->files);\r
-\r
-    for (i = 0; i < package->DeferredActionCount; i++)\r
-        HeapFree(GetProcessHeap(),0,package->DeferredAction[i]);\r
-    HeapFree(GetProcessHeap(),0,package->DeferredAction);\r
-\r
-    for (i = 0; i < package->CommitActionCount; i++)\r
-        HeapFree(GetProcessHeap(),0,package->CommitAction[i]);\r
-    HeapFree(GetProcessHeap(),0,package->CommitAction);\r
-\r
-    HeapFree(GetProcessHeap(),0,package->PackagePath);\r
-}\r
-\r
-static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )\r
-{\r
-    MSIRECORD * row;\r
-\r
-    row = MSI_CreateRecord(4);\r
-    MSI_RecordSetInteger(row,1,a);\r
-    MSI_RecordSetInteger(row,2,b);\r
-    MSI_RecordSetInteger(row,3,c);\r
-    MSI_RecordSetInteger(row,4,d);\r
-    MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);\r
-    msiobj_release(&row->hdr);\r
-\r
-    msi_dialog_check_messages(package->dialog, NULL);\r
-}\r
-\r
-static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)\r
-{\r
-    static const WCHAR Query_t[] = \r
-{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',\r
-'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',\r
-' ','\'','%','s','\'',0};\r
-    WCHAR message[1024];\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    DWORD size;\r
-\r
-    if (!package->LastAction || strcmpW(package->LastAction,action))\r
-    {\r
-        rc = MSI_OpenQuery(package->db, &view, Query_t, action);\r
-        if (rc != ERROR_SUCCESS)\r
-            return;\r
-\r
-        rc = MSI_ViewExecute(view, 0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            return;\r
-        }\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            return;\r
-        }\r
-\r
-        if (MSI_RecordIsNull(row,3))\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return;\r
-        }\r
-\r
-        /* update the cached actionformat */\r
-        HeapFree(GetProcessHeap(),0,package->ActionFormat);\r
-        package->ActionFormat = load_dynamic_stringW(row,3);\r
-\r
-        HeapFree(GetProcessHeap(),0,package->LastAction);\r
-        package->LastAction = dupstrW(action);\r
-\r
-        msiobj_release(&row->hdr);\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-    MSI_RecordSetStringW(record,0,package->ActionFormat);\r
-    size = 1024;\r
-    MSI_FormatRecordW(package,record,message,&size);\r
-\r
-    row = MSI_CreateRecord(1);\r
-    MSI_RecordSetStringW(row,1,message);\r
\r
-    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);\r
-    msiobj_release(&row->hdr);\r
-}\r
-\r
-\r
-static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)\r
-{\r
-    static const WCHAR template_s[]=\r
-{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ','%','s','.',0};\r
-    static const WCHAR format[] = \r
-{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};\r
-    static const WCHAR Query_t[] = \r
-{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',\r
-'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',\r
-' ','\'','%','s','\'',0};\r
-    WCHAR message[1024];\r
-    WCHAR timet[0x100];\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    WCHAR *ActionText=NULL;\r
-\r
-    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, Query_t, action);\r
-    if (rc != ERROR_SUCCESS)\r
-        return;\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return;\r
-    }\r
-    rc = MSI_ViewFetch(view,&row);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return;\r
-    }\r
-\r
-    ActionText = load_dynamic_stringW(row,2);\r
-    msiobj_release(&row->hdr);\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-    sprintfW(message,template_s,timet,action,ActionText);\r
-\r
-    row = MSI_CreateRecord(1);\r
-    MSI_RecordSetStringW(row,1,message);\r
\r
-    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row);\r
-    msiobj_release(&row->hdr);\r
-    HeapFree(GetProcessHeap(),0,ActionText);\r
-}\r
-\r
-static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, \r
-                          UINT rc)\r
-{\r
-    MSIRECORD * row;\r
-    static const WCHAR template_s[]=\r
-{'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ','%','s',\r
-'.',0};\r
-    static const WCHAR template_e[]=\r
-{'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ','%','s',\r
-'.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ','%','i','.',0};\r
-    static const WCHAR format[] = \r
-{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};\r
-    WCHAR message[1024];\r
-    WCHAR timet[0x100];\r
-\r
-    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);\r
-    if (start)\r
-        sprintfW(message,template_s,timet,action);\r
-    else\r
-        sprintfW(message,template_e,timet,action,rc);\r
-    \r
-    row = MSI_CreateRecord(1);\r
-    MSI_RecordSetStringW(row,1,message);\r
\r
-    MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);\r
-    msiobj_release(&row->hdr);\r
-}\r
-\r
-/*\r
- *  build_directory_name()\r
- *\r
- *  This function is to save messing round with directory names\r
- *  It handles adding backslashes between path segments, \r
- *   and can add \ at the end of the directory name if told to.\r
- *\r
- *  It takes a variable number of arguments.\r
- *  It always allocates a new string for the result, so make sure\r
- *   to free the return value when finished with it.\r
- *\r
- *  The first arg is the number of path segments that follow.\r
- *  The arguments following count are a list of path segments.\r
- *  A path segment may be NULL.\r
- *\r
- *  Path segments will be added with a \ separating them.\r
- *  A \ will not be added after the last segment, however if the\r
- *    last segment is NULL, then the last character will be a \\r
- * \r
- */\r
-static LPWSTR build_directory_name(DWORD count, ...)\r
-{\r
-    DWORD sz = 1, i;\r
-    LPWSTR dir;\r
-    va_list va;\r
-\r
-    va_start(va,count);\r
-    for(i=0; i<count; i++)\r
-    {\r
-        LPCWSTR str = va_arg(va,LPCWSTR);\r
-        if (str)\r
-            sz += strlenW(str) + 1;\r
-    }\r
-    va_end(va);\r
-\r
-    dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));\r
-    dir[0]=0;\r
-\r
-    va_start(va,count);\r
-    for(i=0; i<count; i++)\r
-    {\r
-        LPCWSTR str = va_arg(va,LPCWSTR);\r
-        if (!str)\r
-            continue;\r
-        strcatW(dir, str);\r
-        if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')\r
-            strcatW(dir, cszbs);\r
-    }\r
-    return dir;\r
-}\r
-\r
-\r
-/****************************************************\r
- * TOP level entry points \r
- *****************************************************/\r
-\r
-UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,\r
-                              LPCWSTR szCommandLine)\r
-{\r
-    DWORD sz;\r
-    WCHAR buffer[10];\r
-    UINT rc;\r
-    static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};\r
-    static const WCHAR szAction[] = {'A','C','T','I','O','N',0};\r
-    static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};\r
-\r
-    MSI_SetPropertyW(package, szAction, szInstall);\r
-\r
-    if (szPackagePath)   \r
-    {\r
-        LPWSTR p, check, path;\r
\r
-        package->PackagePath = dupstrW(szPackagePath);\r
-        path = dupstrW(szPackagePath);\r
-        p = strrchrW(path,'\\');    \r
-        if (p)\r
-        {\r
-            p++;\r
-            *p=0;\r
-        }\r
-        else\r
-        {\r
-            HeapFree(GetProcessHeap(),0,path);\r
-            path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));\r
-            GetCurrentDirectoryW(MAX_PATH,path);\r
-            strcatW(path,cszbs);\r
-        }\r
-\r
-        check = load_dynamic_property(package, cszSourceDir,NULL);\r
-        if (!check)\r
-            MSI_SetPropertyW(package, cszSourceDir, path);\r
-        else\r
-            HeapFree(GetProcessHeap(), 0, check);\r
-\r
-        HeapFree(GetProcessHeap(), 0, path);\r
-    }\r
-\r
-    if (szCommandLine)\r
-    {\r
-        LPWSTR ptr,ptr2;\r
-        ptr = (LPWSTR)szCommandLine;\r
-       \r
-        while (*ptr)\r
-        {\r
-            WCHAR *prop = NULL;\r
-            WCHAR *val = NULL;\r
-\r
-            TRACE("Looking at %s\n",debugstr_w(ptr));\r
-\r
-            ptr2 = strchrW(ptr,'=');\r
-            if (ptr2)\r
-            {\r
-                BOOL quote=FALSE;\r
-                DWORD len = 0;\r
-\r
-                while (*ptr == ' ') ptr++;\r
-                len = ptr2-ptr;\r
-                prop = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));\r
-                strncpyW(prop,ptr,len);\r
-                prop[len]=0;\r
-                ptr2++;\r
-           \r
-                len = 0; \r
-                ptr = ptr2; \r
-                while (*ptr && (quote || (!quote && *ptr!=' ')))\r
-                {\r
-                    if (*ptr == '"')\r
-                        quote = !quote;\r
-                    ptr++;\r
-                    len++;\r
-                }\r
-               \r
-                if (*ptr2=='"')\r
-                {\r
-                    ptr2++;\r
-                    len -= 2;\r
-                }\r
-                val = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));\r
-                strncpyW(val,ptr2,len);\r
-                val[len] = 0;\r
-\r
-                if (strlenW(prop) > 0)\r
-                {\r
-                    TRACE("Found commandline property (%s) = (%s)\n", \r
-                                       debugstr_w(prop), debugstr_w(val));\r
-                    MSI_SetPropertyW(package,prop,val);\r
-                }\r
-                HeapFree(GetProcessHeap(),0,val);\r
-                HeapFree(GetProcessHeap(),0,prop);\r
-            }\r
-            ptr++;\r
-        }\r
-    }\r
-  \r
-    sz = 10; \r
-    if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS)\r
-    {\r
-        if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)\r
-        {\r
-            rc = ACTION_ProcessUISequence(package);\r
-            if (rc == ERROR_SUCCESS)\r
-                rc = ACTION_ProcessExecSequence(package,TRUE);\r
-        }\r
-        else\r
-            rc = ACTION_ProcessExecSequence(package,FALSE);\r
-    }\r
-    else\r
-        rc = ACTION_ProcessExecSequence(package,FALSE);\r
-    \r
-    if (rc == -1)\r
-    {\r
-        /* install was halted but should be considered a success */\r
-        rc = ERROR_SUCCESS;\r
-    }\r
-\r
-    /* process the ending type action */\r
-    if (rc == ERROR_SUCCESS)\r
-        ACTION_PerformActionSequence(package,-1);\r
-    else if (rc == ERROR_INSTALL_USEREXIT) \r
-        ACTION_PerformActionSequence(package,-2);\r
-    else if (rc == ERROR_FUNCTION_FAILED) \r
-        ACTION_PerformActionSequence(package,-3);\r
-    else if (rc == ERROR_INSTALL_SUSPEND) \r
-        ACTION_PerformActionSequence(package,-4);\r
-\r
-    /* finish up running custom actions */\r
-    ACTION_FinishCustomActions(package);\r
-    \r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)\r
-{\r
-    MSIQUERY * view;\r
-    UINT rc;\r
-    WCHAR buffer[0x100];\r
-    DWORD sz = 0x100;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] =  {\r
-   's','e','l','e','c','t',' ','*',' ',\r
-   'f','r','o','m',' ',\r
-       'I','n','s','t','a','l','l','E','x','e','c','u','t','e',\r
-       'S','e','q','u','e','n','c','e',' ',\r
-   'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ',\r
-       '=',' ','%','i',0};\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);\r
-\r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        rc = MSI_ViewExecute(view, 0);\r
-\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            goto end;\r
-        }\r
-       \r
-        TRACE("Running the actions\n"); \r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            goto end;\r
-        }\r
-\r
-        /* check conditions */\r
-        if (!MSI_RecordIsNull(row,2))\r
-        {\r
-            LPWSTR cond = NULL;\r
-            cond = load_dynamic_stringW(row,2);\r
-\r
-            if (cond)\r
-            {\r
-                /* this is a hack to skip errors in the condition code */\r
-                if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)\r
-                {\r
-                    HeapFree(GetProcessHeap(),0,cond);\r
-                    msiobj_release(&row->hdr);\r
-                    goto end;\r
-                }\r
-                else\r
-                    HeapFree(GetProcessHeap(),0,cond);\r
-            }\r
-        }\r
-\r
-        sz=0x100;\r
-        rc =  MSI_RecordGetStringW(row,1,buffer,&sz);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            ERR("Error is %x\n",rc);\r
-            msiobj_release(&row->hdr);\r
-            goto end;\r
-        }\r
-\r
-        rc = ACTION_PerformAction(package,buffer);\r
-        msiobj_release(&row->hdr);\r
-end:\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-    else\r
-        rc = ERROR_SUCCESS;\r
-\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)\r
-{\r
-    MSIQUERY * view;\r
-    UINT rc;\r
-    static const WCHAR ExecSeqQuery[] =  {\r
-       's','e','l','e','c','t',' ','*',' ',\r
-       'f','r','o','m',' ',\r
-           'I','n','s','t','a','l','l','E','x','e','c','u','t','e',\r
-           'S','e','q','u','e','n','c','e',' ',\r
-       'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ',\r
-           '>',' ','%','i',' ','o','r','d','e','r',' ',\r
-       'b','y',' ','S','e','q','u','e','n','c','e',0 };\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR IVQuery[] = {\r
-       's','e','l','e','c','t',' ','S','e','q','u','e','n','c','e',' ',\r
-       'f','r','o','m',' ','I','n','s','t','a','l','l',\r
-           'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e',' ',\r
-       'w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',' ',\r
-           '`','I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`',\r
-       0};\r
-    INT seq = 0;\r
-\r
-    /* get the sequence number */\r
-    if (UIran)\r
-    {\r
-        rc = MSI_DatabaseOpenViewW(package->db, IVQuery, &view);\r
-        if (rc != ERROR_SUCCESS)\r
-            return rc;\r
-        rc = MSI_ViewExecute(view, 0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return rc;\r
-        }\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return rc;\r
-        }\r
-        seq = MSI_RecordGetInteger(row,1);\r
-        msiobj_release(&row->hdr);\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);\r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        rc = MSI_ViewExecute(view, 0);\r
-\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            goto end;\r
-        }\r
-       \r
-        TRACE("Running the actions\n"); \r
-\r
-        while (1)\r
-        {\r
-            WCHAR buffer[0x100];\r
-            DWORD sz = 0x100;\r
-\r
-            rc = MSI_ViewFetch(view,&row);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                rc = ERROR_SUCCESS;\r
-                break;\r
-            }\r
-\r
-            /* check conditions */\r
-            if (!MSI_RecordIsNull(row,2))\r
-            {\r
-                LPWSTR cond = NULL;\r
-                cond = load_dynamic_stringW(row,2);\r
-\r
-                if (cond)\r
-                {\r
-                    /* this is a hack to skip errors in the condition code */\r
-                    if (MSI_EvaluateConditionW(package, cond) ==\r
-                            MSICONDITION_FALSE)\r
-                    {\r
-                        HeapFree(GetProcessHeap(),0,cond);\r
-                        msiobj_release(&row->hdr);\r
-                        continue; \r
-                    }\r
-                    else\r
-                        HeapFree(GetProcessHeap(),0,cond);\r
-                }\r
-            }\r
-\r
-            sz=0x100;\r
-            rc =  MSI_RecordGetStringW(row,1,buffer,&sz);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Error is %x\n",rc);\r
-                msiobj_release(&row->hdr);\r
-                break;\r
-            }\r
-\r
-            rc = ACTION_PerformAction(package,buffer);\r
-\r
-            if (rc == ERROR_FUNCTION_NOT_CALLED)\r
-                rc = ERROR_SUCCESS;\r
-\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Execution halted due to error (%i)\n",rc);\r
-                msiobj_release(&row->hdr);\r
-                break;\r
-            }\r
-\r
-            msiobj_release(&row->hdr);\r
-        }\r
-\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-end:\r
-    return rc;\r
-}\r
-\r
-\r
-static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)\r
-{\r
-    MSIQUERY * view;\r
-    UINT rc;\r
-    static const WCHAR ExecSeqQuery [] = {\r
-      's','e','l','e','c','t',' ','*',' ',\r
-      'f','r','o','m',' ','I','n','s','t','a','l','l',\r
-            'U','I','S','e','q','u','e','n','c','e',' ',\r
-      'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ', '>',' ','0',' ',\r
-      'o','r','d','e','r',' ','b','y',' ','S','e','q','u','e','n','c','e',0};\r
-    \r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    \r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        rc = MSI_ViewExecute(view, 0);\r
-\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            goto end;\r
-        }\r
-       \r
-        TRACE("Running the actions \n"); \r
-\r
-        while (1)\r
-        {\r
-            WCHAR buffer[0x100];\r
-            DWORD sz = 0x100;\r
-            MSIRECORD * row = 0;\r
-\r
-            rc = MSI_ViewFetch(view,&row);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                rc = ERROR_SUCCESS;\r
-                break;\r
-            }\r
-\r
-            /* check conditions */\r
-            if (!MSI_RecordIsNull(row,2))\r
-            {\r
-                LPWSTR cond = NULL;\r
-                cond = load_dynamic_stringW(row,2);\r
-\r
-                if (cond)\r
-                {\r
-                    /* this is a hack to skip errors in the condition code */\r
-                    if (MSI_EvaluateConditionW(package, cond) ==\r
-                            MSICONDITION_FALSE)\r
-                    {\r
-                        HeapFree(GetProcessHeap(),0,cond);\r
-                        msiobj_release(&row->hdr);\r
-                        continue; \r
-                    }\r
-                    else\r
-                        HeapFree(GetProcessHeap(),0,cond);\r
-                }\r
-            }\r
-\r
-            sz=0x100;\r
-            rc =  MSI_RecordGetStringW(row,1,buffer,&sz);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Error is %x\n",rc);\r
-                msiobj_release(&row->hdr);\r
-                break;\r
-            }\r
-\r
-            rc = ACTION_PerformUIAction(package,buffer);\r
-\r
-            if (rc == ERROR_FUNCTION_NOT_CALLED)\r
-                rc = ERROR_SUCCESS;\r
-\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Execution halted due to error (%i)\n",rc);\r
-                msiobj_release(&row->hdr);\r
-                break;\r
-            }\r
-\r
-            msiobj_release(&row->hdr);\r
-        }\r
-\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-end:\r
-    return rc;\r
-}\r
-\r
-/********************************************************\r
- * ACTION helper functions and functions that perform the actions\r
- *******************************************************/\r
-BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action, UINT* rc)\r
-{\r
-    BOOL ret = FALSE; \r
-\r
-    int i;\r
-    i = 0;\r
-    while (StandardActions[i].action != NULL)\r
-    {\r
-        if (strcmpW(StandardActions[i].action, action)==0)\r
-        {\r
-            ui_actioninfo(package, action, TRUE, 0);\r
-            ui_actionstart(package, action);\r
-            if (StandardActions[i].handler)\r
-            {\r
-                *rc = StandardActions[i].handler(package);\r
-            }\r
-            else\r
-            {\r
-                FIXME("UNHANDLED Standard Action %s\n",debugstr_w(action));\r
-                *rc = ERROR_SUCCESS;\r
-            }\r
-            ui_actioninfo(package, action, FALSE, *rc);\r
-            ret = TRUE;\r
-            break;\r
-        }\r
-        i++;\r
-    }\r
-    return ret;\r
-}\r
-\r
-BOOL ACTION_HandleDialogBox(MSIPACKAGE *package, LPCWSTR dialog, UINT* rc)\r
-{\r
-    BOOL ret = FALSE;\r
-\r
-    /*\r
-     * for the UI when we get that working\r
-     *\r
-    if (ACTION_DialogBox(package,dialog) == ERROR_SUCCESS)\r
-    {\r
-        *rc = package->CurrentInstallState;\r
-        ret = TRUE;\r
-    }\r
-    */\r
-    return ret;\r
-}\r
-\r
-BOOL ACTION_HandleCustomAction(MSIPACKAGE* package, LPCWSTR action, UINT* rc)\r
-{\r
-    BOOL ret=FALSE;\r
-    UINT arc;\r
-\r
-    arc = ACTION_CustomAction(package,action,FALSE);\r
-\r
-    if (arc != ERROR_CALL_NOT_IMPLEMENTED)\r
-    {\r
-        *rc = arc;\r
-        ret = TRUE;\r
-    }\r
-    return ret;\r
-}\r
-\r
-/* \r
- * A lot of actions are really important even if they don't do anything\r
- * explicit... Lots of properties are set at the beginning of the installation\r
- * CostFinalize does a bunch of work to translate the directories and such\r
- * \r
- * But until I get write access to the database that is hard, so I am going to\r
- * hack it to see if I can get something to run.\r
- */\r
-UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)\r
-{\r
-    UINT rc = ERROR_SUCCESS; \r
-    BOOL handled;\r
-\r
-    TRACE("Performing action (%s)\n",debugstr_w(action));\r
-\r
-    handled = ACTION_HandleStandardAction(package, action, &rc);\r
-\r
-    if (!handled)\r
-        handled = ACTION_HandleCustomAction(package, action, &rc);\r
-\r
-    if (!handled)\r
-    {\r
-        FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));\r
-        rc = ERROR_FUNCTION_NOT_CALLED;\r
-    }\r
-\r
-    package->CurrentInstallState = rc;\r
-    return rc;\r
-}\r
-\r
-UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action)\r
-{\r
-    UINT rc = ERROR_SUCCESS;\r
-    BOOL handled = FALSE;\r
-\r
-    TRACE("Performing action (%s)\n",debugstr_w(action));\r
-\r
-    handled = ACTION_HandleStandardAction(package, action, &rc);\r
-\r
-    if (!handled)\r
-        handled = ACTION_HandleCustomAction(package, action, &rc);\r
-\r
-    if (!handled)\r
-        handled = ACTION_HandleDialogBox(package, action, &rc);\r
-\r
-    msi_dialog_check_messages( package->dialog, NULL );\r
-\r
-    if (!handled)\r
-    {\r
-        FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));\r
-        rc = ERROR_FUNCTION_NOT_CALLED;\r
-    }\r
-\r
-    package->CurrentInstallState = rc;\r
-    return rc;\r
-}\r
-\r
-/***********************************************************************\r
- *            create_full_pathW\r
- *\r
- * Recursively create all directories in the path.\r
- *\r
- * shamelessly stolen from setupapi/queue.c\r
- */\r
-static BOOL create_full_pathW(const WCHAR *path)\r
-{\r
-    BOOL ret = TRUE;\r
-    int len;\r
-    WCHAR *new_path;\r
-\r
-    new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) *\r
-                                              sizeof(WCHAR));\r
-\r
-    strcpyW(new_path, path);\r
-\r
-    while((len = strlenW(new_path)) && new_path[len - 1] == '\\')\r
-    new_path[len - 1] = 0;\r
-\r
-    while(!CreateDirectoryW(new_path, NULL))\r
-    {\r
-        WCHAR *slash;\r
-        DWORD last_error = GetLastError();\r
-        if(last_error == ERROR_ALREADY_EXISTS)\r
-            break;\r
-\r
-        if(last_error != ERROR_PATH_NOT_FOUND)\r
-        {\r
-            ret = FALSE;\r
-            break;\r
-        }\r
-\r
-        if(!(slash = strrchrW(new_path, '\\')))\r
-        {\r
-            ret = FALSE;\r
-            break;\r
-        }\r
-\r
-        len = slash - new_path;\r
-        new_path[len] = 0;\r
-        if(!create_full_pathW(new_path))\r
-        {\r
-            ret = FALSE;\r
-            break;\r
-        }\r
-        new_path[len] = '\\';\r
-    }\r
-\r
-    HeapFree(GetProcessHeap(), 0, new_path);\r
-    return ret;\r
-}\r
-\r
-/*\r
- * Also we cannot enable/disable components either, so for now I am just going \r
- * to do all the directories for all the components.\r
- */\r
-static UINT ACTION_CreateFolders(MSIPACKAGE *package)\r
-{\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','D','i','r','e','c','t','o','r','y','_',' ',\r
-        'f','r','o','m',' ','C','r','e','a','t','e','F','o','l','d','e','r',0 };\r
-    UINT rc;\r
-    MSIQUERY *view;\r
-    MSIFOLDER *folder;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-    \r
-    while (1)\r
-    {\r
-        WCHAR dir[0x100];\r
-        LPWSTR full_path;\r
-        DWORD sz;\r
-        MSIRECORD *row = NULL, *uirow;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        sz=0x100;\r
-        rc = MSI_RecordGetStringW(row,1,dir,&sz);\r
-\r
-        if (rc!= ERROR_SUCCESS)\r
-        {\r
-            ERR("Unable to get folder id \n");\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        sz = MAX_PATH;\r
-        full_path = resolve_folder(package,dir,FALSE,FALSE,&folder);\r
-        if (!full_path)\r
-        {\r
-            ERR("Unable to resolve folder id %s\n",debugstr_w(dir));\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        TRACE("Folder is %s\n",debugstr_w(full_path));\r
-\r
-        /* UI stuff */\r
-        uirow = MSI_CreateRecord(1);\r
-        MSI_RecordSetStringW(uirow,1,full_path);\r
-        ui_actiondata(package,szCreateFolders,uirow);\r
-        msiobj_release( &uirow->hdr );\r
-\r
-        if (folder->State == 0)\r
-            create_full_pathW(full_path);\r
-\r
-        folder->State = 3;\r
-\r
-        msiobj_release(&row->hdr);\r
-        HeapFree(GetProcessHeap(),0,full_path);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-   \r
-    return rc;\r
-}\r
-\r
-static int load_component(MSIPACKAGE* package, MSIRECORD * row)\r
-{\r
-    int index = package->loaded_components;\r
-    DWORD sz;\r
-\r
-    /* fill in the data */\r
-\r
-    package->loaded_components++;\r
-    if (package->loaded_components == 1)\r
-        package->components = HeapAlloc(GetProcessHeap(),0,\r
-                                        sizeof(MSICOMPONENT));\r
-    else\r
-        package->components = HeapReAlloc(GetProcessHeap(),0,\r
-            package->components, package->loaded_components * \r
-            sizeof(MSICOMPONENT));\r
-\r
-    memset(&package->components[index],0,sizeof(MSICOMPONENT));\r
-\r
-    sz = 96;       \r
-    MSI_RecordGetStringW(row,1,package->components[index].Component,&sz);\r
-\r
-    TRACE("Loading Component %s\n",\r
-           debugstr_w(package->components[index].Component));\r
-\r
-    sz = 0x100;\r
-    if (!MSI_RecordIsNull(row,2))\r
-        MSI_RecordGetStringW(row,2,package->components[index].ComponentId,&sz);\r
-            \r
-    sz = 96;       \r
-    MSI_RecordGetStringW(row,3,package->components[index].Directory,&sz);\r
-\r
-    package->components[index].Attributes = MSI_RecordGetInteger(row,4);\r
-\r
-    sz = 0x100;       \r
-    MSI_RecordGetStringW(row,5,package->components[index].Condition,&sz);\r
-\r
-    sz = 96;       \r
-    MSI_RecordGetStringW(row,6,package->components[index].KeyPath,&sz);\r
-\r
-    package->components[index].Installed = INSTALLSTATE_ABSENT;\r
-    package->components[index].Action = INSTALLSTATE_UNKNOWN;\r
-    package->components[index].ActionRequest = INSTALLSTATE_UNKNOWN;\r
-\r
-    package->components[index].Enabled = TRUE;\r
-\r
-    return index;\r
-}\r
-\r
-static void load_feature(MSIPACKAGE* package, MSIRECORD * row)\r
-{\r
-    int index = package->loaded_features;\r
-    DWORD sz;\r
-    static const WCHAR Query1[] = {'S','E','L','E','C','T',' ','C','o','m','p',\r
-        'o','n','e','n','t','_',' ','F','R','O','M',' ','F','e','a','t','u','r','e',\r
-        'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ','F','e',\r
-        'a','t','u','r','e','_','=','\'','%','s','\'',0};\r
-    static const WCHAR Query2[] = {'S','E','L','E','C','T',' ','*',' ','F','R',\r
-        'O','M',' ','C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ','C',\r
-        'o','m','p','o','n','e','n','t','=','\'','%','s','\'',0};\r
-    MSIQUERY * view;\r
-    MSIQUERY * view2;\r
-    MSIRECORD * row2;\r
-    MSIRECORD * row3;\r
-    UINT    rc;\r
-\r
-    /* fill in the data */\r
-\r
-    package->loaded_features ++;\r
-    if (package->loaded_features == 1)\r
-        package->features = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFEATURE));\r
-    else\r
-        package->features = HeapReAlloc(GetProcessHeap(),0,package->features,\r
-                                package->loaded_features * sizeof(MSIFEATURE));\r
-\r
-    memset(&package->features[index],0,sizeof(MSIFEATURE));\r
-    \r
-    sz = 96;       \r
-    MSI_RecordGetStringW(row,1,package->features[index].Feature,&sz);\r
-\r
-    TRACE("Loading feature %s\n",debugstr_w(package->features[index].Feature));\r
-\r
-    sz = 96;\r
-    if (!MSI_RecordIsNull(row,2))\r
-        MSI_RecordGetStringW(row,2,package->features[index].Feature_Parent,&sz);\r
-\r
-    sz = 0x100;\r
-     if (!MSI_RecordIsNull(row,3))\r
-        MSI_RecordGetStringW(row,3,package->features[index].Title,&sz);\r
-\r
-     sz = 0x100;\r
-     if (!MSI_RecordIsNull(row,4))\r
-        MSI_RecordGetStringW(row,4,package->features[index].Description,&sz);\r
-\r
-    if (!MSI_RecordIsNull(row,5))\r
-        package->features[index].Display = MSI_RecordGetInteger(row,5);\r
-  \r
-    package->features[index].Level= MSI_RecordGetInteger(row,6);\r
-\r
-     sz = 96;\r
-     if (!MSI_RecordIsNull(row,7))\r
-        MSI_RecordGetStringW(row,7,package->features[index].Directory,&sz);\r
-\r
-    package->features[index].Attributes= MSI_RecordGetInteger(row,8);\r
-\r
-    package->features[index].Installed = INSTALLSTATE_ABSENT;\r
-    package->features[index].Action = INSTALLSTATE_UNKNOWN;\r
-    package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN;\r
-\r
-    /* load feature components */\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, Query1, package->features[index].Feature);\r
-    if (rc != ERROR_SUCCESS)\r
-        return;\r
-    rc = MSI_ViewExecute(view,0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return;\r
-    }\r
-    while (1)\r
-    {\r
-        DWORD sz = 0x100;\r
-        WCHAR buffer[0x100];\r
-        DWORD rc;\r
-        INT c_indx;\r
-        INT cnt = package->features[index].ComponentCount;\r
-\r
-        rc = MSI_ViewFetch(view,&row2);\r
-        if (rc != ERROR_SUCCESS)\r
-            break;\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row2,1,buffer,&sz);\r
-\r
-        /* check to see if the component is already loaded */\r
-        c_indx = get_loaded_component(package,buffer);\r
-        if (c_indx != -1)\r
-        {\r
-            TRACE("Component %s already loaded at %i\n", debugstr_w(buffer),\r
-                  c_indx);\r
-            package->features[index].Components[cnt] = c_indx;\r
-            package->features[index].ComponentCount ++;\r
-            continue;\r
-        }\r
-\r
-        rc = MSI_OpenQuery(package->db, &view2, Query2, buffer);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            msiobj_release( &row2->hdr );\r
-            continue;\r
-        }\r
-        rc = MSI_ViewExecute(view2,0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            msiobj_release( &row2->hdr );\r
-            MSI_ViewClose(view2);\r
-            msiobj_release( &view2->hdr );  \r
-            continue;\r
-        }\r
-        while (1)\r
-        {\r
-            DWORD rc;\r
-\r
-            rc = MSI_ViewFetch(view2,&row3);\r
-            if (rc != ERROR_SUCCESS)\r
-                break;\r
-            c_indx = load_component(package,row3);\r
-            msiobj_release( &row3->hdr );\r
-\r
-            package->features[index].Components[cnt] = c_indx;\r
-            package->features[index].ComponentCount ++;\r
-            TRACE("Loaded new component to index %i\n",c_indx);\r
-        }\r
-        MSI_ViewClose(view2);\r
-        msiobj_release( &view2->hdr );\r
-        msiobj_release( &row2->hdr );\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-}\r
-\r
-/*\r
- * I am not doing any of the costing functionality yet. \r
- * Mostly looking at doing the Component and Feature loading\r
- *\r
- * The native MSI does A LOT of modification to tables here. Mostly adding\r
- * a lot of temporary columns to the Feature and Component tables. \r
- *\r
- *    note: Native msi also tracks the short filename. But I am only going to\r
- *          track the long ones.  Also looking at this directory table\r
- *          it appears that the directory table does not get the parents\r
- *          resolved base on property only based on their entries in the \r
- *          directory table.\r
- */\r
-static UINT ACTION_CostInitialize(MSIPACKAGE *package)\r
-{\r
-    MSIQUERY * view;\r
-    MSIRECORD * row;\r
-    UINT rc;\r
-    static const WCHAR Query_all[] = {\r
-       'S','E','L','E','C','T',' ','*',' ',\r
-       'F','R','O','M',' ','F','e','a','t','u','r','e',0};\r
-    static const WCHAR szCosting[] = {\r
-       'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };\r
-    static const WCHAR szZero[] = { '0', 0 };\r
-\r
-    MSI_SetPropertyW(package, szCosting, szZero);\r
-    MSI_SetPropertyW(package, cszRootDrive , c_collen);\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-    rc = MSI_ViewExecute(view,0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-    while (1)\r
-    {\r
-        DWORD rc;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-            break;\r
-       \r
-        load_feature(package,row); \r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT load_file(MSIPACKAGE* package, MSIRECORD * row)\r
-{\r
-    DWORD index = package->loaded_files;\r
-    DWORD i;\r
-    LPWSTR buffer;\r
-\r
-    /* fill in the data */\r
-\r
-    package->loaded_files++;\r
-    if (package->loaded_files== 1)\r
-        package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));\r
-    else\r
-        package->files = HeapReAlloc(GetProcessHeap(),0,\r
-            package->files , package->loaded_files * sizeof(MSIFILE));\r
-\r
-    memset(&package->files[index],0,sizeof(MSIFILE));\r
\r
-    package->files[index].File = load_dynamic_stringW(row, 1);\r
-    buffer = load_dynamic_stringW(row, 2);\r
-\r
-    package->files[index].ComponentIndex = -1;\r
-    for (i = 0; i < package->loaded_components; i++)\r
-        if (strcmpW(package->components[i].Component,buffer)==0)\r
-        {\r
-            package->files[index].ComponentIndex = i;\r
-            break;\r
-        }\r
-    if (package->files[index].ComponentIndex == -1)\r
-        ERR("Unfound Component %s\n",debugstr_w(buffer));\r
-    HeapFree(GetProcessHeap(), 0, buffer);\r
-\r
-    package->files[index].FileName = load_dynamic_stringW(row,3);\r
-\r
-    reduce_to_longfilename(package->files[index].FileName);\r
-    \r
-    package->files[index].FileSize = MSI_RecordGetInteger(row,4);\r
-    package->files[index].Version = load_dynamic_stringW(row, 5);\r
-    package->files[index].Language = load_dynamic_stringW(row, 6);\r
-    package->files[index].Attributes= MSI_RecordGetInteger(row,7);\r
-    package->files[index].Sequence= MSI_RecordGetInteger(row,8);\r
-\r
-    package->files[index].Temporary = FALSE;\r
-    package->files[index].State = 0;\r
-\r
-    TRACE("File Loaded (%s)\n",debugstr_w(package->files[index].File));  \r
\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_FileCost(MSIPACKAGE *package)\r
-{\r
-    MSIQUERY * view;\r
-    MSIRECORD * row;\r
-    UINT rc;\r
-    static const WCHAR Query[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'F','R','O','M',' ','F','i','l','e',' ',\r
-        'O','r','d','e','r',' ','b','y',' ','S','e','q','u','e','n','c','e', 0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-   \r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return ERROR_SUCCESS;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-        load_file(package,row);\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)\r
-\r
-{\r
-    static const WCHAR Query[] =\r
-        {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','D','i','r','e','c',\r
-         't','o','r','y',' ','w','h','e','r','e',' ','`','D','i','r','e','c','t',\r
-         'o','r','y','`',' ','=',' ','`','%','s','`',0};\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    LPWSTR targetdir, parent, srcdir;\r
-    MSIRECORD * row = 0;\r
-    INT index = -1;\r
-    DWORD i;\r
-\r
-    TRACE("Looking for dir %s\n",debugstr_w(dir));\r
-\r
-    for (i = 0; i < package->loaded_folders; i++)\r
-    {\r
-        if (strcmpW(package->folders[i].Directory,dir)==0)\r
-        {\r
-            TRACE(" %s retuning on index %lu\n",debugstr_w(dir),i);\r
-            return i;\r
-        }\r
-    }\r
-\r
-    TRACE("Working to load %s\n",debugstr_w(dir));\r
-\r
-    index = package->loaded_folders++;\r
-    if (package->loaded_folders==1)\r
-        package->folders = HeapAlloc(GetProcessHeap(),0,\r
-                                        sizeof(MSIFOLDER));\r
-    else\r
-        package->folders= HeapReAlloc(GetProcessHeap(),0,\r
-            package->folders, package->loaded_folders* \r
-            sizeof(MSIFOLDER));\r
-\r
-    memset(&package->folders[index],0,sizeof(MSIFOLDER));\r
-\r
-    package->folders[index].Directory = dupstrW(dir);\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, Query, dir);\r
-    if (rc != ERROR_SUCCESS)\r
-        return -1;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return -1;\r
-    }\r
-\r
-    rc = MSI_ViewFetch(view,&row);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return -1;\r
-    }\r
-\r
-    targetdir = load_dynamic_stringW(row,3);\r
-\r
-    /* split src and target dir */\r
-    if (strchrW(targetdir,':'))\r
-    {\r
-        srcdir=strchrW(targetdir,':');\r
-        *srcdir=0;\r
-        srcdir ++;\r
-    }\r
-    else\r
-        srcdir=NULL;\r
-\r
-    /* for now only pick long filename versions */\r
-    if (strchrW(targetdir,'|'))\r
-    {\r
-        targetdir = strchrW(targetdir,'|'); \r
-        *targetdir = 0;\r
-        targetdir ++;\r
-    }\r
-    if (srcdir && strchrW(srcdir,'|'))\r
-    {\r
-        srcdir= strchrW(srcdir,'|'); \r
-        *srcdir= 0;\r
-        srcdir ++;\r
-    }\r
-\r
-    /* now check for root dirs */\r
-    if (targetdir[0] == '.' && targetdir[1] == 0)\r
-        targetdir = NULL;\r
-        \r
-    if (srcdir && srcdir[0] == '.' && srcdir[1] == 0)\r
-        srcdir = NULL;\r
-\r
-    if (targetdir)\r
-    {\r
-        TRACE("   TargetDefault = %s\n",debugstr_w(targetdir));\r
-        HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault);\r
-        package->folders[index].TargetDefault = dupstrW(targetdir);\r
-    }\r
-\r
-    if (srcdir)\r
-       package->folders[index].SourceDefault = dupstrW(srcdir);\r
-    else if (targetdir)\r
-        package->folders[index].SourceDefault = dupstrW(targetdir);\r
-    HeapFree(GetProcessHeap(), 0, targetdir);\r
-\r
-    parent = load_dynamic_stringW(row,2);\r
-    if (parent) \r
-    {\r
-        i = load_folder(package,parent);\r
-        package->folders[index].ParentIndex = i;\r
-        TRACE("Parent is index %i... %s %s\n",\r
-                    package->folders[index].ParentIndex,\r
-        debugstr_w(package->folders[package->folders[index].ParentIndex].Directory),\r
-                    debugstr_w(parent));\r
-    }\r
-    else\r
-        package->folders[index].ParentIndex = -2;\r
-    HeapFree(GetProcessHeap(), 0, parent);\r
-\r
-    package->folders[index].Property = load_dynamic_property(package, dir,NULL);\r
-\r
-    msiobj_release(&row->hdr);\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    TRACE(" %s retuning on index %i\n",debugstr_w(dir),index);\r
-    return index;\r
-}\r
-\r
-\r
-LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, \r
-                      BOOL set_prop, MSIFOLDER **folder)\r
-{\r
-    DWORD i;\r
-    LPWSTR p, path = NULL;\r
-\r
-    TRACE("Working to resolve %s\n",debugstr_w(name));\r
-\r
-    /* special resolving for Target and Source root dir */\r
-    if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)\r
-    {\r
-        if (!source)\r
-        {\r
-            path = load_dynamic_property(package,cszTargetDir,NULL);\r
-            if (!path)\r
-            {\r
-                path = load_dynamic_property(package,cszRootDrive,NULL);\r
-                if (set_prop)\r
-                    MSI_SetPropertyW(package,cszTargetDir,path);\r
-            }\r
-            if (folder)\r
-            {\r
-                for (i = 0; i < package->loaded_folders; i++)\r
-                {\r
-                    if (strcmpW(package->folders[i].Directory,name)==0)\r
-                        break;\r
-                }\r
-                *folder = &(package->folders[i]);\r
-            }\r
-            return path;\r
-        }\r
-        else\r
-        {\r
-            path = load_dynamic_property(package,cszSourceDir,NULL);\r
-            if (!path)\r
-            {\r
-                path = load_dynamic_property(package,cszDatabase,NULL);\r
-                if (path)\r
-                {\r
-                    p = strrchrW(path,'\\');\r
-                    if (p)\r
-                        *(p+1) = 0;\r
-                }\r
-            }\r
-            if (folder)\r
-            {\r
-                for (i = 0; i < package->loaded_folders; i++)\r
-                {\r
-                    if (strcmpW(package->folders[i].Directory,name)==0)\r
-                        break;\r
-                }\r
-                *folder = &(package->folders[i]);\r
-            }\r
-            return path;\r
-        }\r
-    }\r
-\r
-    for (i = 0; i < package->loaded_folders; i++)\r
-    {\r
-        if (strcmpW(package->folders[i].Directory,name)==0)\r
-            break;\r
-    }\r
-\r
-    if (i >= package->loaded_folders)\r
-        return NULL;\r
-\r
-    if (folder)\r
-        *folder = &(package->folders[i]);\r
-\r
-    if (!source && package->folders[i].ResolvedTarget)\r
-    {\r
-        path = dupstrW(package->folders[i].ResolvedTarget);\r
-        TRACE("   already resolved to %s\n",debugstr_w(path));\r
-        return path;\r
-    }\r
-    else if (source && package->folders[i].ResolvedSource)\r
-    {\r
-        path = dupstrW(package->folders[i].ResolvedSource);\r
-        return path;\r
-    }\r
-    else if (!source && package->folders[i].Property)\r
-    {\r
-        path = build_directory_name(2, package->folders[i].Property, NULL);\r
-                    \r
-        TRACE("   internally set to %s\n",debugstr_w(path));\r
-        if (set_prop)\r
-            MSI_SetPropertyW(package,name,path);\r
-        return path;\r
-    }\r
-\r
-    if (package->folders[i].ParentIndex >= 0)\r
-    {\r
-        LPWSTR parent = package->folders[package->folders[i].ParentIndex].Directory;\r
-\r
-        TRACE(" ! Parent is %s\n", debugstr_w(parent));\r
-\r
-        p = resolve_folder(package, parent, source, set_prop, NULL);\r
-        if (!source)\r
-        {\r
-            TRACE("   TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault));\r
-            path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL);\r
-            package->folders[i].ResolvedTarget = dupstrW(path);\r
-            TRACE("   resolved into %s\n",debugstr_w(path));\r
-            if (set_prop)\r
-                MSI_SetPropertyW(package,name,path);\r
-        }\r
-        else \r
-        {\r
-            path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);\r
-            package->folders[i].ResolvedSource = dupstrW(path);\r
-        }\r
-        HeapFree(GetProcessHeap(),0,p);\r
-    }\r
-    return path;\r
-}\r
-\r
-/* update compoennt state based on a feature change */\r
-void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)\r
-{\r
-    int i;\r
-    INSTALLSTATE newstate;\r
-    MSIFEATURE *feature;\r
-\r
-    i = get_loaded_feature(package,szFeature);\r
-    if (i < 0)\r
-        return;\r
-\r
-    feature = &package->features[i];\r
-    newstate = feature->ActionRequest;\r
-\r
-    for( i = 0; i < feature->ComponentCount; i++)\r
-    {\r
-        MSICOMPONENT* component = &package->components[feature->Components[i]];\r
-\r
-        if (!component->Enabled)\r
-            continue;\r
-        else\r
-        {\r
-            if (newstate == INSTALLSTATE_LOCAL)\r
-                component->ActionRequest = INSTALLSTATE_LOCAL;\r
-            else \r
-            {\r
-                int j,k;\r
-\r
-                component->ActionRequest = newstate;\r
-\r
-                /*if any other feature wants is local we need to set it local*/\r
-                for (j = 0; \r
-                     j < package->loaded_features &&\r
-                     component->ActionRequest != INSTALLSTATE_LOCAL; \r
-                     j++)\r
-                {\r
-                    for (k = 0; k < package->features[j].ComponentCount; k++)\r
-                        if ( package->features[j].Components[k] ==\r
-                             feature->Components[i] )\r
-                        {\r
-                            if (package->features[j].ActionRequest == \r
-                                INSTALLSTATE_LOCAL)\r
-                                component->ActionRequest = INSTALLSTATE_LOCAL;\r
-                            break;\r
-                        }\r
-                }\r
-            }\r
-        }\r
-    } \r
-}\r
-\r
-static UINT SetFeatureStates(MSIPACKAGE *package)\r
-{\r
-    LPWSTR level;\r
-    INT install_level;\r
-    DWORD i;\r
-    INT j;\r
-    LPWSTR override = NULL;\r
-    static const WCHAR all[]={'A','L','L',0};\r
-    static const WCHAR szlevel[] = {\r
-        'I','N','S','T','A','L','L','L','E','V','E','L',0};\r
-    static const WCHAR szAddLocal[] = {\r
-        'A','D','D','L','O','C','A','L',0};\r
-\r
-    /* I do not know if this is where it should happen.. but */\r
-\r
-    TRACE("Checking Install Level\n");\r
-\r
-    level = load_dynamic_property(package,szlevel,NULL);\r
-    if (level)\r
-    {\r
-        install_level = atoiW(level);\r
-        HeapFree(GetProcessHeap(), 0, level);\r
-    }\r
-    else\r
-        install_level = 1;\r
-\r
-    /* ok hereis the rub\r
-     * ADDLOCAL and its friend OVERRIDE INSTALLLEVLE\r
-     * I have confirmed this if ADDLOCALis stated then the INSTALLLEVEL is\r
-     * itnored for all the features. seems strange, epsecially since it is not\r
-     * documented anywhere, but it is how it works. \r
-     */\r
-    \r
-    override = load_dynamic_property(package,szAddLocal,NULL);\r
-  \r
-    if (override)\r
-    {\r
-        for(i = 0; i < package->loaded_features; i++)\r
-        {\r
-            if (strcmpiW(override,all)==0)\r
-            {\r
-                package->features[i].ActionRequest= INSTALLSTATE_LOCAL;\r
-                package->features[i].Action = INSTALLSTATE_LOCAL;\r
-            }\r
-            else\r
-            {\r
-                LPWSTR ptr = override;\r
-                LPWSTR ptr2 = strchrW(override,',');\r
-\r
-                while (ptr)\r
-                {\r
-                    if ((ptr2 && \r
-                        strncmpW(ptr,package->features[i].Feature, ptr2-ptr)==0)\r
-                        || (!ptr2 &&\r
-                        strcmpW(ptr,package->features[i].Feature)==0))\r
-                    {\r
-                        package->features[i].ActionRequest= INSTALLSTATE_LOCAL;\r
-                        package->features[i].Action = INSTALLSTATE_LOCAL;\r
-                        break;\r
-                    }\r
-                    if (ptr2)\r
-                    {\r
-                        ptr=ptr2+1;\r
-                        ptr2 = strchrW(ptr,',');\r
-                    }\r
-                    else\r
-                        break;\r
-                }\r
-            }\r
-        }\r
-        HeapFree(GetProcessHeap(),0,override);\r
-    } \r
-    else\r
-    {\r
-        for(i = 0; i < package->loaded_features; i++)\r
-        {\r
-            BOOL feature_state= ((package->features[i].Level > 0) &&\r
-                             (package->features[i].Level <= install_level));\r
-\r
-            if (feature_state)\r
-            {\r
-                package->features[i].ActionRequest= INSTALLSTATE_LOCAL;\r
-                package->features[i].Action = INSTALLSTATE_LOCAL;\r
-            }\r
-        }\r
-    }\r
-\r
-    /*\r
-     * now we want to enable or disable components base on feature \r
-    */\r
-\r
-    for(i = 0; i < package->loaded_features; i++)\r
-    {\r
-        MSIFEATURE* feature = &package->features[i];\r
-        TRACE("Examining Feature %s (Installed %i, Action %i, Request %i)\n",\r
-            debugstr_w(feature->Feature), feature->Installed, feature->Action,\r
-            feature->ActionRequest);\r
-\r
-        for( j = 0; j < feature->ComponentCount; j++)\r
-        {\r
-            MSICOMPONENT* component = &package->components[\r
-                                                    feature->Components[j]];\r
-\r
-            if (!component->Enabled)\r
-            {\r
-                component->Action = INSTALLSTATE_ABSENT;\r
-                component->ActionRequest = INSTALLSTATE_ABSENT;\r
-            }\r
-            else\r
-            {\r
-                if (feature->Action == INSTALLSTATE_LOCAL)\r
-                    component->Action = INSTALLSTATE_LOCAL;\r
-                if (feature->ActionRequest == INSTALLSTATE_LOCAL)\r
-                    component->ActionRequest = INSTALLSTATE_LOCAL;\r
-            }\r
-        }\r
-    } \r
-\r
-    for(i = 0; i < package->loaded_components; i++)\r
-    {\r
-        MSICOMPONENT* component= &package->components[i];\r
-\r
-        TRACE("Result: Component %s (Installed %i, Action %i, Request %i)\n",\r
-            debugstr_w(component->Component), component->Installed, \r
-            component->Action, component->ActionRequest);\r
-    }\r
-\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-/* \r
- * A lot is done in this function aside from just the costing.\r
- * The costing needs to be implemented at some point but for now I am going\r
- * to focus on the directory building\r
- *\r
- */\r
-static UINT ACTION_CostFinalize(MSIPACKAGE *package)\r
-{\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ',\r
-        'D','i','r','e','c','t','o','r','y',0};\r
-    static const WCHAR ConditionQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ',\r
-        'C','o','n','d','i','t','i','o','n',0};\r
-    static const WCHAR szCosting[] = {\r
-       'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };\r
-    static const WCHAR szlevel[] = {\r
-        'I','N','S','T','A','L','L','L','E','V','E','L',0};\r
-    static const WCHAR szOne[] = { '1', 0 };\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    DWORD i;\r
-    LPWSTR level;\r
-\r
-    TRACE("Building Directory properties\n");\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        rc = MSI_ViewExecute(view, 0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return rc;\r
-        }\r
-\r
-        while (1)\r
-        {\r
-            WCHAR name[0x100];\r
-            LPWSTR path;\r
-            MSIRECORD * row = 0;\r
-            DWORD sz;\r
-\r
-            rc = MSI_ViewFetch(view,&row);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                rc = ERROR_SUCCESS;\r
-                break;\r
-            }\r
-\r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,1,name,&sz);\r
-\r
-            /* This helper function now does ALL the work */\r
-            TRACE("Dir %s ...\n",debugstr_w(name));\r
-            load_folder(package,name);\r
-            path = resolve_folder(package,name,FALSE,TRUE,NULL);\r
-            TRACE("resolves to %s\n",debugstr_w(path));\r
-            HeapFree( GetProcessHeap(), 0, path);\r
-\r
-            msiobj_release(&row->hdr);\r
-        }\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-    TRACE("File calculations %i files\n",package->loaded_files);\r
-\r
-    for (i = 0; i < package->loaded_files; i++)\r
-    {\r
-        MSICOMPONENT* comp = NULL;\r
-        MSIFILE* file= NULL;\r
-\r
-        file = &package->files[i];\r
-        if (file->ComponentIndex >= 0)\r
-            comp = &package->components[file->ComponentIndex];\r
-\r
-        if (file->Temporary == TRUE)\r
-            continue;\r
-\r
-        if (comp)\r
-        {\r
-            LPWSTR p;\r
-\r
-            /* calculate target */\r
-            p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);\r
-\r
-            HeapFree(GetProcessHeap(),0,file->TargetPath);\r
-\r
-            TRACE("file %s is named %s\n",\r
-                   debugstr_w(file->File),debugstr_w(file->FileName));       \r
-\r
-            file->TargetPath = build_directory_name(2, p, file->FileName);\r
-\r
-            HeapFree(GetProcessHeap(),0,p);\r
-\r
-            TRACE("file %s resolves to %s\n",\r
-                   debugstr_w(file->File),debugstr_w(file->TargetPath));       \r
-\r
-            if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)\r
-            {\r
-                file->State = 1;\r
-                comp->Cost += file->FileSize;\r
-            }\r
-            else\r
-            {\r
-                if (file->Version)\r
-                {\r
-                    DWORD handle;\r
-                    DWORD versize;\r
-                    UINT sz;\r
-                    LPVOID version;\r
-                    static const WCHAR name[] = \r
-                    {'\\',0};\r
-                    static const WCHAR name_fmt[] = \r
-                    {'%','u','.','%','u','.','%','u','.','%','u',0};\r
-                    WCHAR filever[0x100];\r
-                    VS_FIXEDFILEINFO *lpVer;\r
-\r
-                    TRACE("Version comparison.. \n");\r
-                    versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);\r
-                    version = HeapAlloc(GetProcessHeap(),0,versize);\r
-                    GetFileVersionInfoW(file->TargetPath, 0, versize, version);\r
-\r
-                    VerQueryValueW(version, name, (LPVOID*)&lpVer, &sz);\r
-\r
-                    sprintfW(filever,name_fmt,\r
-                        HIWORD(lpVer->dwFileVersionMS),\r
-                        LOWORD(lpVer->dwFileVersionMS),\r
-                        HIWORD(lpVer->dwFileVersionLS),\r
-                        LOWORD(lpVer->dwFileVersionLS));\r
-\r
-                    TRACE("new %s old %s\n", debugstr_w(file->Version),\r
-                          debugstr_w(filever));\r
-                    if (strcmpiW(filever,file->Version)<0)\r
-                    {\r
-                        file->State = 2;\r
-                        FIXME("cost should be diff in size\n");\r
-                        comp->Cost += file->FileSize;\r
-                    }\r
-                    else\r
-                        file->State = 3;\r
-                    HeapFree(GetProcessHeap(),0,version);\r
-                }\r
-                else\r
-                    file->State = 3;\r
-            }\r
-        } \r
-    }\r
-\r
-    TRACE("Evaluating Condition Table\n");\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ConditionQuery, &view);\r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        rc = MSI_ViewExecute(view, 0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return rc;\r
-        }\r
-    \r
-        while (1)\r
-        {\r
-            WCHAR Feature[0x100];\r
-            MSIRECORD * row = 0;\r
-            DWORD sz;\r
-            int feature_index;\r
-\r
-            rc = MSI_ViewFetch(view,&row);\r
-\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                rc = ERROR_SUCCESS;\r
-                break;\r
-            }\r
-\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,1,Feature,&sz);\r
-\r
-            feature_index = get_loaded_feature(package,Feature);\r
-            if (feature_index < 0)\r
-                ERR("FAILED to find loaded feature %s\n",debugstr_w(Feature));\r
-            else\r
-            {\r
-                LPWSTR Condition;\r
-                Condition = load_dynamic_stringW(row,3);\r
-\r
-                if (MSI_EvaluateConditionW(package,Condition) == \r
-                    MSICONDITION_TRUE)\r
-                {\r
-                    int level = MSI_RecordGetInteger(row,2);\r
-                    TRACE("Reseting feature %s to level %i\n",\r
-                           debugstr_w(Feature), level);\r
-                    package->features[feature_index].Level = level;\r
-                }\r
-                HeapFree(GetProcessHeap(),0,Condition);\r
-            }\r
-\r
-            msiobj_release(&row->hdr);\r
-        }\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-    }\r
-\r
-    TRACE("Enabling or Disabling Components\n");\r
-    for (i = 0; i < package->loaded_components; i++)\r
-    {\r
-        if (package->components[i].Condition[0])\r
-        {\r
-            if (MSI_EvaluateConditionW(package,\r
-                package->components[i].Condition) == MSICONDITION_FALSE)\r
-            {\r
-                TRACE("Disabling component %s\n",\r
-                      debugstr_w(package->components[i].Component));\r
-                package->components[i].Enabled = FALSE;\r
-            }\r
-        }\r
-    }\r
-\r
-    MSI_SetPropertyW(package,szCosting,szOne);\r
-    /* set default run level if not set */\r
-    level = load_dynamic_property(package,szlevel,NULL);\r
-    if (!level)\r
-        MSI_SetPropertyW(package,szlevel, szOne);\r
-    else\r
-        HeapFree(GetProcessHeap(),0,level);\r
-\r
-    return SetFeatureStates(package);\r
-\r
-}\r
-\r
-/*\r
- * This is a helper function for handling embedded cabinet media\r
- */\r
-static UINT writeout_cabinet_stream(MSIPACKAGE *package, WCHAR* stream_name,\r
-                                    WCHAR* source)\r
-{\r
-    UINT rc;\r
-    USHORT* data;\r
-    UINT    size;\r
-    DWORD   write;\r
-    HANDLE  the_file;\r
-    WCHAR tmp[MAX_PATH];\r
-\r
-    rc = read_raw_stream_data(package->db,stream_name,&data,&size); \r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-\r
-    write = MAX_PATH;\r
-    if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write))\r
-        GetTempPathW(MAX_PATH,tmp);\r
-\r
-    GetTempFileNameW(tmp,stream_name,0,source);\r
-\r
-    track_tempfile(package,strrchrW(source,'\\'), source);\r
-    the_file = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,\r
-                           FILE_ATTRIBUTE_NORMAL, NULL);\r
-\r
-    if (the_file == INVALID_HANDLE_VALUE)\r
-    {\r
-        rc = ERROR_FUNCTION_FAILED;\r
-        goto end;\r
-    }\r
-\r
-    WriteFile(the_file,data,size,&write,NULL);\r
-    CloseHandle(the_file);\r
-    TRACE("wrote %li bytes to %s\n",write,debugstr_w(source));\r
-end:\r
-    HeapFree(GetProcessHeap(),0,data);\r
-    return rc;\r
-}\r
-\r
-\r
-/* Support functions for FDI functions */\r
-typedef struct\r
-{\r
-    MSIPACKAGE* package;\r
-    LPCSTR cab_path;\r
-    LPCSTR file_name;\r
-} CabData;\r
-\r
-static void * cabinet_alloc(ULONG cb)\r
-{\r
-    return HeapAlloc(GetProcessHeap(), 0, cb);\r
-}\r
-\r
-static void cabinet_free(void *pv)\r
-{\r
-    HeapFree(GetProcessHeap(), 0, pv);\r
-}\r
-\r
-static INT_PTR cabinet_open(char *pszFile, int oflag, int pmode)\r
-{\r
-    DWORD dwAccess = 0;\r
-    DWORD dwShareMode = 0;\r
-    DWORD dwCreateDisposition = OPEN_EXISTING;\r
-    switch (oflag & _O_ACCMODE)\r
-    {\r
-    case _O_RDONLY:\r
-        dwAccess = GENERIC_READ;\r
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;\r
-        break;\r
-    case _O_WRONLY:\r
-        dwAccess = GENERIC_WRITE;\r
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;\r
-        break;\r
-    case _O_RDWR:\r
-        dwAccess = GENERIC_READ | GENERIC_WRITE;\r
-        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;\r
-        break;\r
-    }\r
-    if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))\r
-        dwCreateDisposition = CREATE_NEW;\r
-    else if (oflag & _O_CREAT)\r
-        dwCreateDisposition = CREATE_ALWAYS;\r
-    return (INT_PTR)CreateFileA(pszFile, dwAccess, dwShareMode, NULL, dwCreateDisposition, 0, NULL);\r
-}\r
-\r
-static UINT cabinet_read(INT_PTR hf, void *pv, UINT cb)\r
-{\r
-    DWORD dwRead;\r
-    if (ReadFile((HANDLE)hf, pv, cb, &dwRead, NULL))\r
-        return dwRead;\r
-    return 0;\r
-}\r
-\r
-static UINT cabinet_write(INT_PTR hf, void *pv, UINT cb)\r
-{\r
-    DWORD dwWritten;\r
-    if (WriteFile((HANDLE)hf, pv, cb, &dwWritten, NULL))\r
-        return dwWritten;\r
-    return 0;\r
-}\r
-\r
-static int cabinet_close(INT_PTR hf)\r
-{\r
-    return CloseHandle((HANDLE)hf) ? 0 : -1;\r
-}\r
-\r
-static long cabinet_seek(INT_PTR hf, long dist, int seektype)\r
-{\r
-    /* flags are compatible and so are passed straight through */\r
-    return SetFilePointer((HANDLE)hf, dist, NULL, seektype);\r
-}\r
-\r
-static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)\r
-{\r
-    /* FIXME: try to do more processing in this function */\r
-    switch (fdint)\r
-    {\r
-    case fdintCOPY_FILE:\r
-    {\r
-        CabData *data = (CabData*) pfdin->pv;\r
-        ULONG len = strlen(data->cab_path) + strlen(pfdin->psz1);\r
-        char *file;\r
-\r
-        LPWSTR trackname;\r
-        LPWSTR trackpath;\r
-        LPWSTR tracknametmp;\r
-        static const WCHAR tmpprefix[] = {'C','A','B','T','M','P','_',0};\r
-       \r
-        if (data->file_name && strcmp(data->file_name,pfdin->psz1))\r
-                return 0;\r
-        \r
-        file = cabinet_alloc((len+1)*sizeof(char));\r
-        strcpy(file, data->cab_path);\r
-        strcat(file, pfdin->psz1);\r
-\r
-        TRACE("file: %s\n", debugstr_a(file));\r
-\r
-        /* track this file so it can be deleted if not installed */\r
-        trackpath=strdupAtoW(file);\r
-        tracknametmp=strdupAtoW(strrchr(file,'\\')+1);\r
-        trackname = HeapAlloc(GetProcessHeap(),0,(strlenW(tracknametmp) + \r
-                                  strlenW(tmpprefix)+1) * sizeof(WCHAR));\r
-\r
-        strcpyW(trackname,tmpprefix);\r
-        strcatW(trackname,tracknametmp);\r
-\r
-        track_tempfile(data->package, trackname, trackpath);\r
-\r
-        HeapFree(GetProcessHeap(),0,trackpath);\r
-        HeapFree(GetProcessHeap(),0,trackname);\r
-        HeapFree(GetProcessHeap(),0,tracknametmp);\r
-\r
-        return cabinet_open(file, _O_WRONLY | _O_CREAT, 0);\r
-    }\r
-    case fdintCLOSE_FILE_INFO:\r
-    {\r
-        FILETIME ft;\r
-           FILETIME ftLocal;\r
-        if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))\r
-            return -1;\r
-        if (!LocalFileTimeToFileTime(&ft, &ftLocal))\r
-            return -1;\r
-        if (!SetFileTime((HANDLE)pfdin->hf, &ftLocal, 0, &ftLocal))\r
-            return -1;\r
-\r
-        cabinet_close(pfdin->hf);\r
-        return 1;\r
-    }\r
-    default:\r
-        return 0;\r
-    }\r
-}\r
-\r
-/***********************************************************************\r
- *            extract_cabinet_file\r
- *\r
- * Extract files from a cab file.\r
- */\r
-static BOOL extract_a_cabinet_file(MSIPACKAGE* package, const WCHAR* source, \r
-                                 const WCHAR* path, const WCHAR* file)\r
-{\r
-    HFDI hfdi;\r
-    ERF erf;\r
-    BOOL ret;\r
-    char *cabinet;\r
-    char *cab_path;\r
-    char *file_name;\r
-    CabData data;\r
-\r
-    TRACE("Extracting %s (%s) to %s\n",debugstr_w(source), \r
-                    debugstr_w(file), debugstr_w(path));\r
-\r
-    hfdi = FDICreate(cabinet_alloc,\r
-                     cabinet_free,\r
-                     cabinet_open,\r
-                     cabinet_read,\r
-                     cabinet_write,\r
-                     cabinet_close,\r
-                     cabinet_seek,\r
-                     0,\r
-                     &erf);\r
-    if (!hfdi)\r
-    {\r
-        ERR("FDICreate failed\n");\r
-        return FALSE;\r
-    }\r
-\r
-    if (!(cabinet = strdupWtoA( source )))\r
-    {\r
-        FDIDestroy(hfdi);\r
-        return FALSE;\r
-    }\r
-    if (!(cab_path = strdupWtoA( path )))\r
-    {\r
-        FDIDestroy(hfdi);\r
-        HeapFree(GetProcessHeap(), 0, cabinet);\r
-        return FALSE;\r
-    }\r
-\r
-    data.package = package;\r
-    data.cab_path = cab_path;\r
-    if (file)\r
-        file_name = strdupWtoA(file);\r
-    else\r
-        file_name = NULL;\r
-    data.file_name = file_name;\r
-\r
-    ret = FDICopy(hfdi, cabinet, "", 0, cabinet_notify, NULL, &data);\r
-\r
-    if (!ret)\r
-        ERR("FDICopy failed\n");\r
-\r
-    FDIDestroy(hfdi);\r
-\r
-    HeapFree(GetProcessHeap(), 0, cabinet);\r
-    HeapFree(GetProcessHeap(), 0, cab_path);\r
-    HeapFree(GetProcessHeap(), 0, file_name);\r
-\r
-    return ret;\r
-}\r
-\r
-static UINT ready_media_for_file(MSIPACKAGE *package, UINT sequence, \r
-                                 WCHAR* path, WCHAR* file)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static WCHAR source[MAX_PATH];\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ',\r
-        'f','r','o','m',' ','M','e','d','i','a',' ',\r
-        'w','h','e','r','e',' ','L','a','s','t','S','e','q','u','e','n','c','e',' ','>','=',' ','%','i',' ',\r
-        'o','r','d','e','r',' ','b','y',' ','L','a','s','t','S','e','q','u','e','n','c','e',0};\r
-    WCHAR Query[1024];\r
-    WCHAR cab[0x100];\r
-    DWORD sz=0x100;\r
-    INT seq;\r
-    static UINT last_sequence = 0; \r
-\r
-    if (sequence <= last_sequence)\r
-    {\r
-        TRACE("Media already ready (%u, %u)\n",sequence,last_sequence);\r
-        /*extract_a_cabinet_file(package, source,path,file); */\r
-        return ERROR_SUCCESS;\r
-    }\r
-\r
-    sprintfW(Query,ExecSeqQuery,sequence);\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    rc = MSI_ViewFetch(view,&row);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-    seq = MSI_RecordGetInteger(row,2);\r
-    last_sequence = seq;\r
-\r
-    if (!MSI_RecordIsNull(row,4))\r
-    {\r
-        sz=0x100;\r
-        MSI_RecordGetStringW(row,4,cab,&sz);\r
-        TRACE("Source is CAB %s\n",debugstr_w(cab));\r
-        /* the stream does not contain the # character */\r
-        if (cab[0]=='#')\r
-        {\r
-            writeout_cabinet_stream(package,&cab[1],source);\r
-            strcpyW(path,source);\r
-            *(strrchrW(path,'\\')+1)=0;\r
-        }\r
-        else\r
-        {\r
-            sz = MAX_PATH;\r
-            if (MSI_GetPropertyW(package, cszSourceDir, source, &sz))\r
-            {\r
-                ERR("No Source dir defined \n");\r
-                rc = ERROR_FUNCTION_FAILED;\r
-            }\r
-            else\r
-            {\r
-                strcpyW(path,source);\r
-                strcatW(source,cab);\r
-                /* extract the cab file into a folder in the temp folder */\r
-                sz = MAX_PATH;\r
-                if (MSI_GetPropertyW(package, cszTempFolder,path, &sz) \r
-                                    != ERROR_SUCCESS)\r
-                    GetTempPathW(MAX_PATH,path);\r
-            }\r
-        }\r
-        rc = !extract_a_cabinet_file(package, source,path,NULL);\r
-    }\r
-    else\r
-    {\r
-        sz = MAX_PATH;\r
-        MSI_GetPropertyW(package,cszSourceDir,source,&sz);\r
-        strcpyW(path,source);\r
-    }\r
-    msiobj_release(&row->hdr);\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-inline static UINT create_component_directory ( MSIPACKAGE* package, INT component)\r
-{\r
-    UINT rc = ERROR_SUCCESS;\r
-    MSIFOLDER *folder;\r
-    LPWSTR install_path;\r
-\r
-    install_path = resolve_folder(package, package->components[component].Directory,\r
-                        FALSE, FALSE, &folder);\r
-    if (!install_path)\r
-        return ERROR_FUNCTION_FAILED; \r
-\r
-    /* create the path */\r
-    if (folder->State == 0)\r
-    {\r
-        create_full_pathW(install_path);\r
-        folder->State = 2;\r
-    }\r
-    HeapFree(GetProcessHeap(), 0, install_path);\r
-\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_InstallFiles(MSIPACKAGE *package)\r
-{\r
-    UINT rc = ERROR_SUCCESS;\r
-    DWORD index;\r
-    MSIRECORD * uirow;\r
-    WCHAR uipath[MAX_PATH];\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    /* increment progress bar each time action data is sent */\r
-    ui_progress(package,1,1,0,0);\r
-\r
-    for (index = 0; index < package->loaded_files; index++)\r
-    {\r
-        WCHAR path_to_source[MAX_PATH];\r
-        MSIFILE *file;\r
-        \r
-        file = &package->files[index];\r
-\r
-        if (file->Temporary)\r
-            continue;\r
-\r
-        if (package->components[file->ComponentIndex].ActionRequest != \r
-             INSTALLSTATE_LOCAL)\r
-        {\r
-            ui_progress(package,2,file->FileSize,0,0);\r
-            TRACE("File %s is not scheduled for install\n",\r
-                   debugstr_w(file->File));\r
-\r
-            continue;\r
-        }\r
-\r
-        if ((file->State == 1) || (file->State == 2))\r
-        {\r
-            LPWSTR p;\r
-            INT len;\r
-            MSICOMPONENT* comp = NULL;\r
-\r
-            TRACE("Installing %s\n",debugstr_w(file->File));\r
-            rc = ready_media_for_file(package,file->Sequence,path_to_source,\r
-                            file->File);\r
-            /* \r
-             * WARNING!\r
-             * our file table could change here because a new temp file\r
-             * may have been created\r
-             */\r
-            file = &package->files[index];\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Unable to ready media\n");\r
-                rc = ERROR_FUNCTION_FAILED;\r
-                break;\r
-            }\r
-\r
-            create_component_directory( package, file->ComponentIndex);\r
-\r
-            /* recalculate file paths because things may have changed */\r
-\r
-            if (file->ComponentIndex >= 0)\r
-                comp = &package->components[file->ComponentIndex];\r
-\r
-            p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);\r
-            HeapFree(GetProcessHeap(),0,file->TargetPath);\r
-\r
-            file->TargetPath = build_directory_name(2, p, file->FileName);\r
-\r
-            len = strlenW(path_to_source) + strlenW(file->File) + 2;\r
-            file->SourcePath = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));\r
-            strcpyW(file->SourcePath, path_to_source);\r
-            strcatW(file->SourcePath, file->File);\r
-\r
-            TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),\r
-                  debugstr_w(file->TargetPath));\r
-\r
-            /* the UI chunk */\r
-            uirow=MSI_CreateRecord(9);\r
-            MSI_RecordSetStringW(uirow,1,file->File);\r
-            strcpyW(uipath,file->TargetPath);\r
-            *(strrchrW(uipath,'\\')+1)=0;\r
-            MSI_RecordSetStringW(uirow,9,uipath);\r
-            MSI_RecordSetInteger(uirow,6,file->FileSize);\r
-            ui_actiondata(package,szInstallFiles,uirow);\r
-            msiobj_release( &uirow->hdr );\r
-            ui_progress(package,2,file->FileSize,0,0);\r
-\r
-            if (!MoveFileW(file->SourcePath,file->TargetPath))\r
-            {\r
-                rc = GetLastError();\r
-                ERR("Unable to move file (%s -> %s) (error %d)\n",\r
-                     debugstr_w(file->SourcePath), debugstr_w(file->TargetPath),\r
-                      rc);\r
-                if (rc == ERROR_ALREADY_EXISTS && file->State == 2)\r
-                {\r
-                    CopyFileW(file->SourcePath,file->TargetPath,FALSE);\r
-                    DeleteFileW(file->SourcePath);\r
-                    rc = 0;\r
-                }\r
-                else if (rc == ERROR_FILE_NOT_FOUND)\r
-                {\r
-                    ERR("Source File Not Found!  Continueing\n");\r
-                    rc = 0;\r
-                }\r
-                else\r
-                {\r
-                    ERR("Ignoring Error and continuing...\n");\r
-                    rc = 0;\r
-                }\r
-            }\r
-            else\r
-                file->State = 4;\r
-        }\r
-    }\r
-\r
-    return rc;\r
-}\r
-\r
-inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key, \r
-                                   LPWSTR* file_source)\r
-{\r
-    DWORD index;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    for (index = 0; index < package->loaded_files; index ++)\r
-    {\r
-        if (strcmpW(file_key,package->files[index].File)==0)\r
-        {\r
-            if (package->files[index].State >= 2)\r
-            {\r
-                *file_source = dupstrW(package->files[index].TargetPath);\r
-                return ERROR_SUCCESS;\r
-            }\r
-            else\r
-                return ERROR_FILE_NOT_FOUND;\r
-        }\r
-    }\r
-\r
-    return ERROR_FUNCTION_FAILED;\r
-}\r
-\r
-static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ',\r
-        'D','u','p','l','i','c','a','t','e','F','i','l','e',0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        WCHAR file_key[0x100];\r
-        WCHAR *file_source = NULL;\r
-        WCHAR dest_name[0x100];\r
-        LPWSTR dest_path, dest;\r
-        WCHAR component[0x100];\r
-        INT component_index;\r
-\r
-        DWORD sz=0x100;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        sz=0x100;\r
-        rc = MSI_RecordGetStringW(row,2,component,&sz);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            ERR("Unable to get component\n");\r
-            msiobj_release(&row->hdr);\r
-            break;\r
-        }\r
-\r
-        component_index = get_loaded_component(package,component);\r
-        if (package->components[component_index].ActionRequest != \r
-             INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping copy due to disabled component\n");\r
-\r
-            /* the action taken was the same as the current install state */        \r
-            package->components[component_index].Action =\r
-                package->components[component_index].Installed;\r
-\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        package->components[component_index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[component_index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        sz=0x100;\r
-        rc = MSI_RecordGetStringW(row,3,file_key,&sz);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            ERR("Unable to get file key\n");\r
-            msiobj_release(&row->hdr);\r
-            break;\r
-        }\r
-\r
-        rc = get_file_target(package,file_key,&file_source);\r
-\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            ERR("Original file unknown %s\n",debugstr_w(file_key));\r
-            msiobj_release(&row->hdr);\r
-            HeapFree(GetProcessHeap(),0,file_source);\r
-            continue;\r
-        }\r
-\r
-        if (MSI_RecordIsNull(row,4))\r
-        {\r
-            strcpyW(dest_name,strrchrW(file_source,'\\')+1);\r
-        }\r
-        else\r
-        {\r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,4,dest_name,&sz);\r
-            reduce_to_longfilename(dest_name);\r
-         }\r
-\r
-        if (MSI_RecordIsNull(row,5))\r
-        {\r
-            LPWSTR p;\r
-            dest_path = dupstrW(file_source);\r
-            p = strrchrW(dest_path,'\\');\r
-            if (p)\r
-                *p=0;\r
-        }\r
-        else\r
-        {\r
-            WCHAR destkey[0x100];\r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,5,destkey,&sz);\r
-            sz = 0x100;\r
-            dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL);\r
-            if (!dest_path)\r
-            {\r
-                ERR("Unable to get destination folder\n");\r
-                msiobj_release(&row->hdr);\r
-                HeapFree(GetProcessHeap(),0,file_source);\r
-                break;\r
-            }\r
-        }\r
-\r
-        dest = build_directory_name(2, dest_path, dest_name);\r
-        HeapFree(GetProcessHeap(), 0, dest_path);\r
-           \r
-        TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),\r
-              debugstr_w(dest)); \r
-        \r
-        if (strcmpW(file_source,dest))\r
-            rc = !CopyFileW(file_source,dest,TRUE);\r
-        else\r
-            rc = ERROR_SUCCESS;\r
-        \r
-        if (rc != ERROR_SUCCESS)\r
-            ERR("Failed to copy file\n");\r
-\r
-        FIXME("We should track these duplicate files as well\n");   \r
\r
-        msiobj_release(&row->hdr);\r
-        HeapFree(GetProcessHeap(),0,dest);\r
-        HeapFree(GetProcessHeap(),0,file_source);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-\r
-/* OK this value is "interpreted" and then formatted based on the \r
-   first few characters */\r
-static LPSTR parse_value(MSIPACKAGE *package, WCHAR *value, DWORD *type, \r
-                         DWORD *size)\r
-{\r
-    LPSTR data = NULL;\r
-    if (value[0]=='#' && value[1]!='#' && value[1]!='%')\r
-    {\r
-        if (value[1]=='x')\r
-        {\r
-            LPWSTR ptr;\r
-            CHAR byte[5];\r
-            LPWSTR deformated;\r
-            int count;\r
-\r
-            deformat_string(package, &value[2], &deformated);\r
-\r
-            /* binary value type */\r
-            ptr = deformated; \r
-            *type=REG_BINARY;\r
-            *size = strlenW(ptr)/2;\r
-            data = HeapAlloc(GetProcessHeap(),0,*size);\r
-          \r
-            byte[0] = '0'; \r
-            byte[1] = 'x'; \r
-            byte[4] = 0; \r
-            count = 0;\r
-            while (*ptr)\r
-            {\r
-                byte[2]= *ptr;\r
-                ptr++;\r
-                byte[3]= *ptr;\r
-                ptr++;\r
-                data[count] = (BYTE)strtol(byte,NULL,0);\r
-                count ++;\r
-            }\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-\r
-            TRACE("Data %li bytes(%i)\n",*size,count);\r
-        }\r
-        else\r
-        {\r
-            LPWSTR deformated;\r
-            deformat_string(package, &value[1], &deformated);\r
-\r
-            *type=REG_DWORD; \r
-            *size = sizeof(DWORD);\r
-            data = HeapAlloc(GetProcessHeap(),0,*size);\r
-            *(LPDWORD)data = atoiW(deformated); \r
-            TRACE("DWORD %i\n",*data);\r
-\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-        }\r
-    }\r
-    else\r
-    {\r
-        static const WCHAR szMulti[] = {'[','~',']',0};\r
-        WCHAR *ptr;\r
-        *type=REG_SZ;\r
-\r
-        if (value[0]=='#')\r
-        {\r
-            if (value[1]=='%')\r
-            {\r
-                ptr = &value[2];\r
-                *type=REG_EXPAND_SZ;\r
-            }\r
-            else\r
-                ptr = &value[1];\r
-         }\r
-         else\r
-            ptr=value;\r
-\r
-        if (strstrW(value,szMulti))\r
-            *type = REG_MULTI_SZ;\r
-\r
-        *size = deformat_string(package, ptr,(LPWSTR*)&data);\r
-    }\r
-    return data;\r
-}\r
-\r
-static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ',\r
-        'f','r','o','m',' ','R','e','g','i','s','t','r','y',0 };\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    /* increment progress bar each time action data is sent */\r
-    ui_progress(package,1,REG_PROGRESS_VALUE,1,0);\r
-\r
-    while (1)\r
-    {\r
-        static const WCHAR szHCR[] = \r
-{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T','\\',0};\r
-        static const WCHAR szHCU[] =\r
-{'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',0};\r
-        static const WCHAR szHLM[] =\r
-{'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',\r
-'\\',0};\r
-        static const WCHAR szHU[] =\r
-{'H','K','E','Y','_','U','S','E','R','S','\\',0};\r
-\r
-        LPSTR value_data = NULL;\r
-        HKEY  root_key, hkey;\r
-        DWORD type,size;\r
-        LPWSTR value, key, name, component, deformated;\r
-        LPCWSTR szRoot;\r
-        INT component_index;\r
-        MSIRECORD * uirow;\r
-        LPWSTR uikey;\r
-        INT   root;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-        ui_progress(package,2,0,0,0);\r
-\r
-        value = NULL;\r
-        key = NULL;\r
-        uikey = NULL;\r
-        name = NULL;\r
-\r
-        component = load_dynamic_stringW(row, 6);\r
-        component_index = get_loaded_component(package,component);\r
-\r
-        if (package->components[component_index].ActionRequest != \r
-             INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping write due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[component_index].Action =\r
-                package->components[component_index].Installed;\r
-\r
-            goto next;\r
-        }\r
-\r
-        package->components[component_index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[component_index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        /* null values have special meanings during uninstalls and such */\r
-        \r
-        if(MSI_RecordIsNull(row,5))\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            goto next;\r
-        }\r
-\r
-        root = MSI_RecordGetInteger(row,2);\r
-        key = load_dynamic_stringW(row, 3);\r
-      \r
-        name = load_dynamic_stringW(row, 4);\r
-   \r
-        /* get the root key */\r
-        switch (root)\r
-        {\r
-            case 0:  root_key = HKEY_CLASSES_ROOT; \r
-                     szRoot = szHCR;\r
-                     break;\r
-            case 1:  root_key = HKEY_CURRENT_USER;\r
-                     szRoot = szHCU;\r
-                     break;\r
-            case 2:  root_key = HKEY_LOCAL_MACHINE;\r
-                     szRoot = szHLM;\r
-                     break;\r
-            case 3:  root_key = HKEY_USERS; \r
-                     szRoot = szHU;\r
-                     break;\r
-            default:\r
-                 ERR("Unknown root %i\n",root);\r
-                 root_key=NULL;\r
-                 szRoot = NULL;\r
-                 break;\r
-        }\r
-        if (!root_key)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            goto next;\r
-        }\r
-\r
-        deformat_string(package, key , &deformated);\r
-        size = strlenW(deformated) + strlenW(szRoot) + 1;\r
-        uikey = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));\r
-        strcpyW(uikey,szRoot);\r
-        strcatW(uikey,deformated);\r
-\r
-        if (RegCreateKeyW( root_key, deformated, &hkey))\r
-        {\r
-            ERR("Could not create key %s\n",debugstr_w(deformated));\r
-            msiobj_release(&row->hdr);\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-            goto next;\r
-        }\r
-        HeapFree(GetProcessHeap(),0,deformated);\r
-\r
-        value = load_dynamic_stringW(row,5);\r
-        value_data = parse_value(package, value, &type, &size); \r
-\r
-        deformat_string(package, name, &deformated);\r
-\r
-        if (value_data)\r
-        {\r
-            TRACE("Setting value %s\n",debugstr_w(deformated));\r
-            RegSetValueExW(hkey, deformated, 0, type, value_data, size);\r
-\r
-            uirow = MSI_CreateRecord(3);\r
-            MSI_RecordSetStringW(uirow,2,deformated);\r
-            MSI_RecordSetStringW(uirow,1,uikey);\r
-\r
-            if (type == REG_SZ)\r
-                MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data);\r
-            else\r
-                MSI_RecordSetStringW(uirow,3,value);\r
-\r
-            ui_actiondata(package,szWriteRegistryValues,uirow);\r
-            msiobj_release( &uirow->hdr );\r
-\r
-            HeapFree(GetProcessHeap(),0,value_data);\r
-        }\r
-        HeapFree(GetProcessHeap(),0,value);\r
-        HeapFree(GetProcessHeap(),0,deformated);\r
-\r
-        msiobj_release(&row->hdr);\r
-        RegCloseKey(hkey);\r
-next:\r
-        HeapFree(GetProcessHeap(),0,uikey);\r
-        HeapFree(GetProcessHeap(),0,key);\r
-        HeapFree(GetProcessHeap(),0,name);\r
-        HeapFree(GetProcessHeap(),0,component);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_InstallInitialize(MSIPACKAGE *package)\r
-{\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-\r
-static UINT ACTION_InstallValidate(MSIPACKAGE *package)\r
-{\r
-    DWORD progress = 0;\r
-    DWORD total = 0;\r
-    static const WCHAR q1[]={\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'F','R','O','M',' ','R','e','g','i','s','t','r','y',0};\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    int i;\r
-\r
-    TRACE(" InstallValidate \n");\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, q1, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-    while (1)\r
-    {\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-        progress +=1;\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-    total = total + progress * REG_PROGRESS_VALUE;\r
-    total = total + package->loaded_components * COMPONENT_PROGRESS_VALUE;\r
-    for (i=0; i < package->loaded_files; i++)\r
-        total += package->files[i].FileSize;\r
-    ui_progress(package,0,total,0,0);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_LaunchConditions(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view = NULL;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','L','a','u','n','c','h','C','o','n','d','i','t','i','o','n',0};\r
-    static const WCHAR title[]=\r
-            {'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0};\r
-\r
-    TRACE("Checking launch conditions\n");\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    rc = ERROR_SUCCESS;\r
-    while (rc == ERROR_SUCCESS)\r
-    {\r
-        LPWSTR cond = NULL; \r
-        LPWSTR message = NULL;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        cond = load_dynamic_stringW(row,1);\r
-\r
-        if (MSI_EvaluateConditionW(package,cond) != MSICONDITION_TRUE)\r
-        {\r
-            LPWSTR deformated;\r
-            message = load_dynamic_stringW(row,2);\r
-            deformat_string(package,message,&deformated); \r
-            MessageBoxW(NULL,deformated,title,MB_OK);\r
-            HeapFree(GetProcessHeap(),0,message);\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-            rc = ERROR_FUNCTION_FAILED;\r
-        }\r
-        HeapFree(GetProcessHeap(),0,cond);\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static LPWSTR resolve_keypath( MSIPACKAGE* package, INT\r
-                            component_index)\r
-{\r
-    MSICOMPONENT* cmp = &package->components[component_index];\r
-\r
-    if (cmp->KeyPath[0]==0)\r
-    {\r
-        LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);\r
-        return p;\r
-    }\r
-    if (cmp->Attributes & 0x4)\r
-    {\r
-        MSIQUERY * view;\r
-        MSIRECORD * row = 0;\r
-        UINT rc,root,len;\r
-        LPWSTR key,deformated,buffer,name,deformated_name;\r
-        static const WCHAR ExecSeqQuery[] = {\r
-        's','e','l','e','c','t',' ','*',' ',\r
-        'f','r','o','m',' ','R','e','g','i','s','t','r','y',' ',\r
-'w','h','e','r','e',' ','R','e','g','i','s','t','r','y',' ','=',' '\r
-,'`','%','s','`',0 };\r
-        static const WCHAR fmt[]={'%','0','2','i',':','%','s',0};\r
-        static const WCHAR fmt2[]={'%','0','2','i',':','%','s','\\','%','s',0};\r
-\r
-        rc = MSI_OpenQuery(package->db,&view,ExecSeqQuery,cmp->KeyPath);\r
-\r
-        if (rc!=ERROR_SUCCESS)\r
-            return NULL;\r
-\r
-        rc = MSI_ViewExecute(view, 0);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return NULL;\r
-        }\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            MSI_ViewClose(view);\r
-            msiobj_release(&view->hdr);\r
-            return NULL;\r
-        }\r
-\r
-        root = MSI_RecordGetInteger(row,2);\r
-        key = load_dynamic_stringW(row, 3);\r
-        name = load_dynamic_stringW(row, 4);\r
-        deformat_string(package, key , &deformated);\r
-        deformat_string(package, name, &deformated_name);\r
-\r
-        len = strlenW(deformated) + 5;\r
-        if (deformated_name)\r
-            len+=strlenW(deformated_name);\r
-\r
-        buffer = HeapAlloc(GetProcessHeap(),0, len *sizeof(WCHAR));\r
-\r
-        if (deformated_name)\r
-            sprintfW(buffer,fmt2,root,deformated,deformated_name);\r
-        else\r
-            sprintfW(buffer,fmt,root,deformated);\r
-\r
-        HeapFree(GetProcessHeap(),0,key);\r
-        HeapFree(GetProcessHeap(),0,deformated);\r
-        HeapFree(GetProcessHeap(),0,name);\r
-        HeapFree(GetProcessHeap(),0,deformated_name);\r
-        msiobj_release(&row->hdr);\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-\r
-        return buffer;\r
-    }\r
-    else if (cmp->Attributes & 0x20)\r
-    {\r
-        FIXME("UNIMPLEMENTED keypath as ODBC Source\n");\r
-        return NULL;\r
-    }\r
-    else\r
-    {\r
-        int j;\r
-        j = get_loaded_file(package,cmp->KeyPath);\r
-\r
-        if (j>=0)\r
-        {\r
-            LPWSTR p = dupstrW(package->files[j].TargetPath);\r
-            return p;\r
-        }\r
-    }\r
-    return NULL;\r
-}\r
-\r
-/*\r
- * Ok further analysis makes me think that this work is\r
- * actually done in the PublishComponents and PublishFeatures\r
- * step, and not here.  It appears like the keypath and all that is\r
- * resolved in this step, however actually written in the Publish steps.\r
- * But we will leave it here for now because it is unclear\r
- */\r
-static UINT ACTION_ProcessComponents(MSIPACKAGE *package)\r
-{\r
-    LPWSTR productcode;\r
-    WCHAR squished_pc[GUID_SIZE];\r
-    WCHAR squished_cc[GUID_SIZE];\r
-    UINT rc;\r
-    DWORD i;\r
-    HKEY hkey=0,hkey2=0;\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    /* writes the Component and Features values to the registry */\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    rc = MSIREG_OpenComponents(&hkey);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-      \r
-    squash_guid(productcode,squished_pc);\r
-    ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);\r
-    for (i = 0; i < package->loaded_components; i++)\r
-    {\r
-        ui_progress(package,2,0,0,0);\r
-        if (package->components[i].ComponentId[0]!=0)\r
-        {\r
-            WCHAR *keypath = NULL;\r
-            MSIRECORD * uirow;\r
-\r
-            squash_guid(package->components[i].ComponentId,squished_cc);\r
-            rc = RegCreateKeyW(hkey,squished_cc,&hkey2);\r
-            if (rc != ERROR_SUCCESS)\r
-                continue;\r
-           \r
-            keypath = resolve_keypath(package,i);\r
-            if (keypath)\r
-            {\r
-                RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPVOID)keypath,\r
-                            (strlenW(keypath)+1)*sizeof(WCHAR));\r
-                RegCloseKey(hkey2);\r
-        \r
-                /* UI stuff */\r
-                uirow = MSI_CreateRecord(3);\r
-                MSI_RecordSetStringW(uirow,1,productcode);\r
-                MSI_RecordSetStringW(uirow,2,package->components[i].\r
-                                                        ComponentId);\r
-                MSI_RecordSetStringW(uirow,3,keypath);\r
-                ui_actiondata(package,szProcessComponents,uirow);\r
-                msiobj_release( &uirow->hdr );\r
-                HeapFree(GetProcessHeap(),0,keypath);\r
-            }\r
-        }\r
-    } \r
-end:\r
-    HeapFree(GetProcessHeap(), 0, productcode);\r
-    RegCloseKey(hkey);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)\r
-{\r
-    /* \r
-     * OK this is a bit confusing.. I am given a _Component key and I believe\r
-     * that the file that is being registered as a type library is the "key file\r
-     * of that component" which I interpret to mean "The file in the KeyPath of\r
-     * that component".\r
-     */\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR Query[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','T','y','p','e','L','i','b',0};\r
-    ITypeLib *ptLib;\r
-    HRESULT res;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {   \r
-        WCHAR component[0x100];\r
-        DWORD sz;\r
-        INT index;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,3,component,&sz);\r
-\r
-        index = get_loaded_component(package,component);\r
-        if (index < 0)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        if (package->components[index].ActionRequest != INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping typelib reg due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[index].Action =\r
-                package->components[index].Installed;\r
-\r
-            continue;\r
-        }\r
-\r
-        package->components[index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        index = get_loaded_file(package,package->components[index].KeyPath); \r
-   \r
-        if (index < 0)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        res = LoadTypeLib(package->files[index].TargetPath,&ptLib);\r
-        if (SUCCEEDED(res))\r
-        {\r
-            LPWSTR help;\r
-            WCHAR helpid[0x100];\r
-\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,6,helpid,&sz);\r
-\r
-            help = resolve_folder(package,helpid,FALSE,FALSE,NULL);\r
-            res = RegisterTypeLib(ptLib,package->files[index].TargetPath,help);\r
-            HeapFree(GetProcessHeap(),0,help);\r
-\r
-            if (!SUCCEEDED(res))\r
-                ERR("Failed to register type library %s\n",\r
-                     debugstr_w(package->files[index].TargetPath));\r
-            else\r
-            {\r
-                /* Yes the row has more fields than I need, but #1 is \r
-                   correct and the only one I need. Why make a new row? */\r
-\r
-                ui_actiondata(package,szRegisterTypeLibraries,row);\r
-                \r
-                TRACE("Registered %s\n",\r
-                       debugstr_w(package->files[index].TargetPath));\r
-            }\r
-\r
-            if (ptLib)\r
-                ITypeLib_Release(ptLib);\r
-        }\r
-        else\r
-            ERR("Failed to load type library %s\n",\r
-                debugstr_w(package->files[index].TargetPath));\r
-        \r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-   \r
-}\r
-\r
-static UINT register_appid(MSIPACKAGE *package, LPCWSTR clsid, LPCWSTR app )\r
-{\r
-    static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = \r
-        {'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','p','p','I'\r
-        ,'d',' ','w','h','e','r','e',' ','A','p','p','I','d','=','`','%','s','`',0};\r
-    HKEY hkey2,hkey3;\r
-    LPWSTR buffer=0;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, clsid);\r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    RegCreateKeyW(HKEY_CLASSES_ROOT,szAppID,&hkey2);\r
-    RegCreateKeyW(hkey2,clsid,&hkey3);\r
-    RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)app,\r
-                   (strlenW(app)+1)*sizeof(WCHAR));\r
-\r
-    rc = MSI_ViewFetch(view,&row);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,2)) \r
-    {\r
-        LPWSTR deformated=0;\r
-        UINT size; \r
-        static const WCHAR szRemoteServerName[] =\r
-             {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',0};\r
-        buffer = load_dynamic_stringW(row,2);\r
-        size = deformat_string(package,buffer,&deformated);\r
-        RegSetValueExW(hkey3,szRemoteServerName,0,REG_SZ,(LPVOID)deformated,\r
-                       size);\r
-        HeapFree(GetProcessHeap(),0,deformated);\r
-        HeapFree(GetProcessHeap(),0,buffer);\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,3)) \r
-    {\r
-        static const WCHAR szLocalService[] =\r
-             {'L','o','c','a','l','S','e','r','v','i','c','e',0};\r
-        UINT size;\r
-        buffer = load_dynamic_stringW(row,3);\r
-        size = (strlenW(buffer)+1) * sizeof(WCHAR);\r
-        RegSetValueExW(hkey3,szLocalService,0,REG_SZ,(LPVOID)buffer,size);\r
-        HeapFree(GetProcessHeap(),0,buffer);\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,4)) \r
-    {\r
-        static const WCHAR szService[] =\r
-             {'S','e','r','v','i','c','e','P','a','r','a','m','e','t','e','r','s',0};\r
-        UINT size;\r
-        buffer = load_dynamic_stringW(row,4);\r
-        size = (strlenW(buffer)+1) * sizeof(WCHAR);\r
-        RegSetValueExW(hkey3,szService,0,REG_SZ,(LPVOID)buffer,size);\r
-        HeapFree(GetProcessHeap(),0,buffer);\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,5)) \r
-    {\r
-        static const WCHAR szDLL[] =\r
-             {'D','l','l','S','u','r','r','o','g','a','t','e',0};\r
-        UINT size;\r
-        buffer = load_dynamic_stringW(row,5);\r
-        size = (strlenW(buffer)+1) * sizeof(WCHAR);\r
-        RegSetValueExW(hkey3,szDLL,0,REG_SZ,(LPVOID)buffer,size);\r
-        HeapFree(GetProcessHeap(),0,buffer);\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,6)) \r
-    {\r
-        static const WCHAR szActivate[] =\r
-             {'A','c','t','i','v','a','t','e','A','s','S','t','o','r','a','g','e',0};\r
-        static const WCHAR szY[] = {'Y',0};\r
-\r
-        if (MSI_RecordGetInteger(row,6))\r
-            RegSetValueExW(hkey3,szActivate,0,REG_SZ,(LPVOID)szY,4);\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,7)) \r
-    {\r
-        static const WCHAR szRunAs[] = {'R','u','n','A','s',0};\r
-        static const WCHAR szUser[] = \r
-             {'I','n','t','e','r','a','c','t','i','v','e',' ','U','s','e','r',0};\r
-\r
-        if (MSI_RecordGetInteger(row,7))\r
-            RegSetValueExW(hkey3,szRunAs,0,REG_SZ,(LPVOID)szUser,34);\r
-    }\r
-\r
-    msiobj_release(&row->hdr);\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    RegCloseKey(hkey3);\r
-    RegCloseKey(hkey2);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)\r
-{\r
-    /* \r
-     * Again I am assuming the words, "Whose key file represents" when referring\r
-     * to a Component as to meaning that Components KeyPath file\r
-     *\r
-     * Also there is a very strong connection between ClassInfo and ProgID\r
-     * that I am mostly glossing over.  \r
-     * What would be more propper is to load the ClassInfo and the ProgID info\r
-     * into memory data structures and then be able to enable and disable them\r
-     * based on component. \r
-     */\r
-    \r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','C','l','a','s','s',0};\r
-    static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };\r
-    static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 };\r
-    static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };\r
-    static const WCHAR szSpace[] = {' ',0};\r
-    HKEY hkey,hkey2,hkey3;\r
-    LPWSTR argument,deformated;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = RegCreateKeyW(HKEY_CLASSES_ROOT,szCLSID,&hkey);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        rc = ERROR_SUCCESS;\r
-        goto end;\r
-    }\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        goto end;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        WCHAR clsid[0x100];\r
-        WCHAR buffer[0x100];\r
-        WCHAR desc[0x100];\r
-        DWORD sz;\r
-        INT index;\r
-        DWORD size;\r
-     \r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        sz=0x100;\r
-        MSI_RecordGetStringW(row,3,buffer,&sz);\r
-\r
-        index = get_loaded_component(package,buffer);\r
-\r
-        if (index < 0)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        if (package->components[index].ActionRequest != INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping class reg due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[index].Action =\r
-                package->components[index].Installed;\r
-\r
-            continue;\r
-        }\r
-\r
-        package->components[index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        sz=0x100;\r
-        MSI_RecordGetStringW(row,1,clsid,&sz);\r
-        RegCreateKeyW(hkey,clsid,&hkey2);\r
-\r
-        if (!MSI_RecordIsNull(row,5))\r
-        {\r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,5,desc,&sz);\r
-\r
-            RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)desc,\r
-                           (strlenW(desc)+1)*sizeof(WCHAR));\r
-        }\r
-        else\r
-            desc[0]=0;\r
-\r
-        sz=0x100;\r
-        MSI_RecordGetStringW(row,2,buffer,&sz);\r
-\r
-        RegCreateKeyW(hkey2,buffer,&hkey3);\r
-\r
-        index = get_loaded_file(package,package->components[index].KeyPath);\r
-\r
-        argument = load_dynamic_stringW(row,11); \r
-        size = deformat_string(package,argument,&deformated);\r
-        if (deformated)\r
-            size+=sizeof(WCHAR);\r
-        HeapFree(GetProcessHeap(),0,argument);\r
-        size += (strlenW(package->files[index].TargetPath))*sizeof(WCHAR);\r
-\r
-        argument = (LPWSTR)HeapAlloc(GetProcessHeap(),0,size+sizeof(WCHAR));\r
-        strcpyW(argument,package->files[index].TargetPath);\r
-        if (deformated)\r
-        {\r
-            strcatW(argument,szSpace);\r
-            strcatW(argument,deformated);\r
-        }\r
-\r
-        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);\r
-        HeapFree(GetProcessHeap(),0,deformated);\r
-        HeapFree(GetProcessHeap(),0,argument);\r
-\r
-        RegCloseKey(hkey3);\r
-\r
-        if (!MSI_RecordIsNull(row,4))\r
-        {\r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,4,buffer,&sz);\r
-\r
-            RegCreateKeyW(hkey2,szProgID,&hkey3);\r
-    \r
-            RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)buffer,\r
-                       (strlenW(buffer)+1)*sizeof(WCHAR));\r
-\r
-            RegCloseKey(hkey3);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,6))\r
-        { \r
-            sz=0x100;\r
-            MSI_RecordGetStringW(row,6,buffer,&sz);\r
-\r
-            RegSetValueExW(hkey2,szAppID,0,REG_SZ,(LPVOID)buffer,\r
-                       (strlenW(buffer)+1)*sizeof(WCHAR));\r
-\r
-            register_appid(package,buffer,desc);\r
-        }\r
-\r
-\r
-        if (!MSI_RecordIsNull(row,7))\r
-        {\r
-            FIXME("Process field 7\n");\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,8))\r
-        {\r
-            static const WCHAR szDefaultIcon[] = \r
-            {'D','e','f','a','u','l','t','I','c','o','n',0};\r
-\r
-            LPWSTR FileName = load_dynamic_stringW(row,8);\r
-            LPWSTR FilePath;\r
-            INT index;\r
-\r
-            RegCreateKeyW(hkey2,szDefaultIcon,&hkey3);\r
-            build_icon_path(package,FileName,&FilePath);\r
-            if (!MSI_RecordIsNull(row,9))\r
-            {\r
-                static const WCHAR index_fmt[] = {',','%','i',0};\r
-                WCHAR index_buf[20];\r
-                index = MSI_RecordGetInteger(row,9);\r
-                sprintfW(index_buf,index_fmt,index);\r
-                size = strlenW(FilePath)+strlenW(index_buf)+1;\r
-                size *= sizeof(WCHAR);\r
-                HeapReAlloc(GetProcessHeap(),0,FilePath,size);\r
-            }\r
-            RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)FilePath,\r
-                           (strlenW(FilePath)+1) * sizeof(WCHAR));\r
-            HeapFree(GetProcessHeap(),0,FilePath);\r
-            HeapFree(GetProcessHeap(),0,FileName);\r
-            RegCloseKey(hkey3);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,10))\r
-        {\r
-            static const WCHAR szInproc32[] = {\r
-            'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};\r
-            static const WCHAR szInproc[] = {\r
-            'I','n','p','r','o','c','H','a','n','d','l','e','r',0};\r
-            INT i = MSI_RecordGetInteger(row,10);\r
-            if (i != MSI_NULL_INTEGER && i > 0 &&  i < 4)\r
-            {\r
-                static const WCHAR ole2[] = {'o','l','e','2','.','d','l','l',0};\r
-                static const WCHAR ole32[] = {\r
-                        'o','l','e','3','2','.','d','l','l',0};\r
-                switch(i)\r
-                {\r
-                    case 1:\r
-                        size = strlenW(ole2) * sizeof(WCHAR);\r
-                        RegCreateKeyW(hkey2,szInproc,&hkey3);\r
-                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole2, size);\r
-                        RegCloseKey(hkey3);\r
-                        break;\r
-                    case 2:\r
-                        size = strlenW(ole32) * sizeof(WCHAR);\r
-                        RegCreateKeyW(hkey2,szInproc32,&hkey3);\r
-                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole32,size);\r
-                        RegCloseKey(hkey3);\r
-                        break;\r
-                    case 3:\r
-                        size = strlenW(ole2) * sizeof(WCHAR);\r
-                        RegCreateKeyW(hkey2,szInproc,&hkey3);\r
-                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole2, size);\r
-                        RegCloseKey(hkey3);\r
-                        size = strlenW(ole32) * sizeof(WCHAR);\r
-                        RegCreateKeyW(hkey2,szInproc32,&hkey3);\r
-                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole32,size);\r
-                        RegCloseKey(hkey3);\r
-                        break;\r
-                }\r
-                \r
-            }\r
-            else\r
-            {\r
-                RegCreateKeyW(hkey2,szInproc32,&hkey3);\r
-                argument = load_dynamic_stringW(row,10);\r
-                reduce_to_longfilename(argument);\r
-                size = strlenW(argument)*sizeof(WCHAR);\r
-\r
-                RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);\r
-                HeapFree(GetProcessHeap(),0,argument);\r
-\r
-                RegCloseKey(hkey3);\r
-            }\r
-        }\r
-\r
-        RegCloseKey(hkey2);\r
-\r
-        ui_actiondata(package,szRegisterClassInfo,row);\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-end:\r
-    RegCloseKey(hkey);\r
-    return rc;\r
-}\r
-\r
-static UINT register_progid_base(MSIPACKAGE* package, MSIRECORD * row, \r
-                                LPWSTR clsid)\r
-{\r
-    static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };\r
-    static const WCHAR szDefaultIcon[] = {\r
-        'D','e','f','a','u','l','t','I','c','o','n',0};\r
-    HKEY hkey,hkey2;\r
-    WCHAR buffer[0x100];\r
-    DWORD sz;\r
-\r
-\r
-    sz = 0x100;\r
-    MSI_RecordGetStringW(row,1,buffer,&sz);\r
-    RegCreateKeyW(HKEY_CLASSES_ROOT,buffer,&hkey);\r
-\r
-    if (!MSI_RecordIsNull(row,4))\r
-    {\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,4,buffer,&sz);\r
-        RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)buffer, (strlenW(buffer)+1) *\r
-                       sizeof(WCHAR));\r
-    }\r
-\r
-    if (!MSI_RecordIsNull(row,3))\r
-    {   \r
-        sz = 0x100;\r
-    \r
-        MSI_RecordGetStringW(row,3,buffer,&sz);\r
-        RegCreateKeyW(hkey,szCLSID,&hkey2);\r
-        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)buffer, (strlenW(buffer)+1) *\r
-                       sizeof(WCHAR));\r
-\r
-        if (clsid)\r
-            strcpyW(clsid,buffer);\r
-\r
-        RegCloseKey(hkey2);\r
-    }\r
-    else\r
-    {\r
-        FIXME("UNHANDLED case, Parent progid but classid is NULL\n");\r
-        return ERROR_FUNCTION_FAILED;\r
-    }\r
-    if (!MSI_RecordIsNull(row,5))\r
-    {\r
-        INT index = MSI_RecordGetInteger(row,6); \r
-        LPWSTR FileName = load_dynamic_stringW(row,5);\r
-        LPWSTR FilePath,IconPath;\r
-        static const WCHAR fmt[] = {'%','s',',','%','i',0};\r
-\r
-        RegCreateKeyW(hkey,szDefaultIcon,&hkey2);\r
-        build_icon_path(package,FileName,&FilePath);\r
-       \r
-        IconPath = HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*\r
-                    sizeof(WCHAR));\r
-\r
-        sprintfW(IconPath,fmt,FilePath,index);\r
-        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)IconPath,\r
-                           (strlenW(IconPath)+1) * sizeof(WCHAR));\r
-        HeapFree(GetProcessHeap(),0,FilePath);\r
-        HeapFree(GetProcessHeap(),0,FileName);\r
-        RegCloseKey(hkey2);\r
-    }\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid);\r
-\r
-static UINT register_parent_progid(MSIPACKAGE *package, LPCWSTR parent, \r
-                                   LPWSTR clsid)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR Query_t[] = \r
-        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','P','r','o','g'\r
-        ,'I','d',' ','w','h','e','r','e',' ','P','r','o','g','I','d',' ','=',' ','`'\r
-        ,'%','s','`',0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_OpenQuery(package->db, &view, Query_t, parent);\r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    rc = MSI_ViewFetch(view,&row);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    register_progid(package,row,clsid);\r
-\r
-    msiobj_release(&row->hdr);\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)\r
-{\r
-    UINT rc = ERROR_SUCCESS; \r
-\r
-    if (MSI_RecordIsNull(row,2))\r
-        rc = register_progid_base(package,row,clsid);\r
-    else\r
-    {\r
-        WCHAR buffer[0x1000];\r
-        DWORD sz, disp;\r
-        HKEY hkey,hkey2;\r
-        static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };\r
-        static const WCHAR szDefaultIcon[] = {\r
-                'D','e','f','a','u','l','t','I','c','o','n',0};\r
-\r
-        /* check if already registered */\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,1,buffer,&sz);\r
-        RegCreateKeyExW(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0,\r
-                        KEY_ALL_ACCESS, NULL, &hkey, &disp );\r
-        if (disp == REG_OPENED_EXISTING_KEY)\r
-        {\r
-            TRACE("Key already registered\n");\r
-            RegCloseKey(hkey);\r
-            return rc;\r
-        }\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,2,buffer,&sz);\r
-        rc = register_parent_progid(package,buffer,clsid);\r
-\r
-        /* clsid is same as parent */\r
-        RegCreateKeyW(hkey,szCLSID,&hkey2);\r
-        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)clsid, (strlenW(clsid)+1) *\r
-                       sizeof(WCHAR));\r
-\r
-        RegCloseKey(hkey2);\r
-\r
-\r
-        if (!MSI_RecordIsNull(row,4))\r
-        {\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,4,buffer,&sz);\r
-            RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)buffer,\r
-                           (strlenW(buffer)+1) * sizeof(WCHAR));\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,5))\r
-        {\r
-            LPWSTR FileName = load_dynamic_stringW(row,5);\r
-            LPWSTR FilePath;\r
-            RegCreateKeyW(hkey,szDefaultIcon,&hkey2);\r
-            build_icon_path(package,FileName,&FilePath);\r
-            RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)FilePath,\r
-                           (strlenW(FilePath)+1) * sizeof(WCHAR));\r
-            HeapFree(GetProcessHeap(),0,FilePath);\r
-            HeapFree(GetProcessHeap(),0,FileName);\r
-            RegCloseKey(hkey2);\r
-        }\r
-\r
-        RegCloseKey(hkey);\r
-    }\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)\r
-{\r
-    /* \r
-     * Sigh, here I am just brute force registering all progids\r
-     * this needs to be linked to the Classes that have been registered\r
-     * but the easiest way to do that is to load all these stuff into\r
-     * memory for easy checking.\r
-     *\r
-     * Gives me something to continue to work toward.\r
-     */\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR Query[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'F','R','O','M',' ','P','r','o','g','I','d',0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        WCHAR clsid[0x1000];\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-        \r
-        register_progid(package,row,clsid);\r
-        ui_actiondata(package,szRegisterProgIdInfo,row);\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, \r
-                            LPWSTR *FilePath)\r
-{\r
-    LPWSTR ProductCode;\r
-    LPWSTR SystemFolder;\r
-    LPWSTR dest;\r
-    UINT rc;\r
-\r
-    static const WCHAR szInstaller[] = \r
-        {'I','n','s','t','a','l','l','e','r','\\',0};\r
-    static const WCHAR szProductCode[] =\r
-        {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    static const WCHAR szFolder[] =\r
-        {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};\r
-\r
-    ProductCode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!ProductCode)\r
-        return rc;\r
-\r
-    SystemFolder = load_dynamic_property(package,szFolder,NULL);\r
-\r
-    dest = build_directory_name(3, SystemFolder, szInstaller, ProductCode);\r
-\r
-    create_full_pathW(dest);\r
-\r
-    *FilePath = build_directory_name(2, dest, icon_name);\r
-\r
-    HeapFree(GetProcessHeap(),0,SystemFolder);\r
-    HeapFree(GetProcessHeap(),0,ProductCode);\r
-    HeapFree(GetProcessHeap(),0,dest);\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR Query[] = {\r
-       'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ',\r
-       'S','h','o','r','t','c','u','t',0};\r
-    IShellLinkW *sl;\r
-    IPersistFile *pf;\r
-    HRESULT res;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    res = CoInitialize( NULL );\r
-    if (FAILED (res))\r
-    {\r
-        ERR("CoInitialize failed\n");\r
-        return ERROR_FUNCTION_FAILED;\r
-    }\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return ERROR_SUCCESS;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        LPWSTR target_file, target_folder;\r
-        WCHAR buffer[0x100];\r
-        DWORD sz;\r
-        DWORD index;\r
-        static const WCHAR szlnk[]={'.','l','n','k',0};\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-        \r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,4,buffer,&sz);\r
-\r
-        index = get_loaded_component(package,buffer);\r
-\r
-        if (index < 0)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        if (package->components[index].ActionRequest != INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping shortcut creation due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[index].Action =\r
-                package->components[index].Installed;\r
-\r
-            continue;\r
-        }\r
-\r
-        package->components[index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        ui_actiondata(package,szCreateShortcuts,row);\r
-\r
-        res = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,\r
-                              &IID_IShellLinkW, (LPVOID *) &sl );\r
-\r
-        if (FAILED(res))\r
-        {\r
-            ERR("Is IID_IShellLink\n");\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        res = IShellLinkW_QueryInterface( sl, &IID_IPersistFile,(LPVOID*) &pf );\r
-        if( FAILED( res ) )\r
-        {\r
-            ERR("Is IID_IPersistFile\n");\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,2,buffer,&sz);\r
-        target_folder = resolve_folder(package, buffer,FALSE,FALSE,NULL);\r
-\r
-        /* may be needed because of a bug somehwere else */\r
-        create_full_pathW(target_folder);\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,3,buffer,&sz);\r
-        reduce_to_longfilename(buffer);\r
-        if (!strchrW(buffer,'.') || strcmpiW(strchrW(buffer,'.'),szlnk))\r
-            strcatW(buffer,szlnk);\r
-        target_file = build_directory_name(2, target_folder, buffer);\r
-        HeapFree(GetProcessHeap(),0,target_folder);\r
-\r
-        sz = 0x100;\r
-        MSI_RecordGetStringW(row,5,buffer,&sz);\r
-        if (strchrW(buffer,'['))\r
-        {\r
-            LPWSTR deformated;\r
-            deformat_string(package,buffer,&deformated);\r
-            IShellLinkW_SetPath(sl,deformated);\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-        }\r
-        else\r
-        {\r
-            FIXME("UNHANDLED shortcut format, advertised shortcut\n");\r
-            IPersistFile_Release( pf );\r
-            IShellLinkW_Release( sl );\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,6))\r
-        {\r
-            LPWSTR deformated;\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,6,buffer,&sz);\r
-            deformat_string(package,buffer,&deformated);\r
-            IShellLinkW_SetArguments(sl,deformated);\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,7))\r
-        {\r
-            LPWSTR deformated;\r
-            deformated = load_dynamic_stringW(row,7);\r
-            IShellLinkW_SetDescription(sl,deformated);\r
-            HeapFree(GetProcessHeap(),0,deformated);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,8))\r
-            IShellLinkW_SetHotkey(sl,MSI_RecordGetInteger(row,8));\r
-\r
-        if (!MSI_RecordIsNull(row,9))\r
-        {\r
-            WCHAR *Path = NULL;\r
-            INT index; \r
-\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,9,buffer,&sz);\r
-\r
-            build_icon_path(package,buffer,&Path);\r
-            index = MSI_RecordGetInteger(row,10);\r
-\r
-            IShellLinkW_SetIconLocation(sl,Path,index);\r
-            HeapFree(GetProcessHeap(),0,Path);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,11))\r
-            IShellLinkW_SetShowCmd(sl,MSI_RecordGetInteger(row,11));\r
-\r
-        if (!MSI_RecordIsNull(row,12))\r
-        {\r
-            LPWSTR Path;\r
-            sz = 0x100;\r
-            MSI_RecordGetStringW(row,12,buffer,&sz);\r
-            Path = resolve_folder(package, buffer, FALSE, FALSE, NULL);\r
-            IShellLinkW_SetWorkingDirectory(sl,Path);\r
-            HeapFree(GetProcessHeap(), 0, Path);\r
-        }\r
-\r
-        TRACE("Writing shortcut to %s\n",debugstr_w(target_file));\r
-        IPersistFile_Save(pf,target_file,FALSE);\r
-    \r
-        HeapFree(GetProcessHeap(),0,target_file);    \r
-\r
-        IPersistFile_Release( pf );\r
-        IShellLinkW_Release( sl );\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-\r
-    CoUninitialize();\r
-\r
-    return rc;\r
-}\r
-\r
-\r
-/*\r
- * 99% of the work done here is only done for \r
- * advertised installs. However this is where the\r
- * Icon table is processed and written out\r
- * so that is what I am going to do here.\r
- */\r
-static UINT ACTION_PublishProduct(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR Query[]={\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','I','c','o','n',0};\r
-    DWORD sz;\r
-    /* for registry stuff */\r
-    LPWSTR productcode;\r
-    HKEY hkey=0;\r
-    HKEY hukey=0;\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    static const WCHAR szProductName[] = {\r
-         'P','r','o','d','u','c','t','N','a','m','e',0};\r
-    static const WCHAR szPackageCode[] = {\r
-         'P','a','c','k','a','g','e','C','o','d','e',0};\r
-    LPWSTR buffer;\r
-    DWORD size;\r
-    MSIHANDLE hDb, hSumInfo;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto next;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        goto next;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        HANDLE the_file;\r
-        WCHAR *FilePath=NULL;\r
-        WCHAR *FileName=NULL;\r
-        CHAR buffer[1024];\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-    \r
-        FileName = load_dynamic_stringW(row,1);\r
-        if (!FileName)\r
-        {\r
-            ERR("Unable to get FileName\n");\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        build_icon_path(package,FileName,&FilePath);\r
-\r
-        HeapFree(GetProcessHeap(),0,FileName);\r
-\r
-        TRACE("Creating icon file at %s\n",debugstr_w(FilePath));\r
-        \r
-        the_file = CreateFileW(FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,\r
-                           FILE_ATTRIBUTE_NORMAL, NULL);\r
-\r
-        if (the_file == INVALID_HANDLE_VALUE)\r
-        {\r
-            ERR("Unable to create file %s\n",debugstr_w(FilePath));\r
-            msiobj_release(&row->hdr);\r
-            HeapFree(GetProcessHeap(),0,FilePath);\r
-            continue;\r
-        }\r
-\r
-        do \r
-        {\r
-            DWORD write;\r
-            sz = 1024;\r
-            rc = MSI_RecordReadStream(row,2,buffer,&sz);\r
-            if (rc != ERROR_SUCCESS)\r
-            {\r
-                ERR("Failed to get stream\n");\r
-                CloseHandle(the_file);  \r
-                DeleteFileW(FilePath);\r
-                break;\r
-            }\r
-            WriteFile(the_file,buffer,sz,&write,NULL);\r
-        } while (sz == 1024);\r
-\r
-        HeapFree(GetProcessHeap(),0,FilePath);\r
-\r
-        CloseHandle(the_file);\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-next:\r
-    /* ok there is a lot more done here but i need to figure out what */\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    rc = MSIREG_OpenProductsKey(productcode,&hkey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-    rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-\r
-    buffer = load_dynamic_property(package,szProductName,NULL);\r
-    size = strlenW(buffer)*sizeof(WCHAR);\r
-    RegSetValueExW(hukey,szProductName,0,REG_SZ, (LPSTR)buffer,size);\r
-    HeapFree(GetProcessHeap(),0,buffer);\r
-    FIXME("Need to write more keys to the user registry\n");\r
-  \r
-    hDb= msiobj_findhandle( &package->db->hdr );\r
-    rc = MsiGetSummaryInformationW(hDb, NULL, 0, &hSumInfo); \r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        WCHAR guidbuffer[0x200];\r
-        size = 0x200;\r
-        rc = MsiSummaryInfoGetPropertyW(hSumInfo, 8, NULL, NULL, NULL,\r
-                                        guidbuffer, &size);\r
-        if (rc == ERROR_SUCCESS)\r
-        {\r
-            WCHAR squashed[GUID_SIZE];\r
-            /* for now we only care about the first guid */\r
-            LPWSTR ptr = strchrW(guidbuffer,';');\r
-            if (ptr) *ptr = 0;\r
-            squash_guid(guidbuffer,squashed);\r
-            size = strlenW(guidbuffer)*sizeof(WCHAR);\r
-            RegSetValueExW(hukey,szPackageCode,0,REG_SZ, (LPSTR)guidbuffer,\r
-                           size);\r
-            \r
-        }\r
-        else\r
-        {\r
-            ERR("Unable to query Revision_Number... \n");\r
-            rc = ERROR_SUCCESS;\r
-        }\r
-        MsiCloseHandle(hSumInfo);\r
-    }\r
-    else\r
-    {\r
-        ERR("Unable to open Summary Information\n");\r
-        rc = ERROR_SUCCESS;\r
-    }\r
-\r
-end:\r
-\r
-    HeapFree(GetProcessHeap(),0,productcode);    \r
-    RegCloseKey(hkey);\r
-    RegCloseKey(hukey);\r
-\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_WriteIniValues(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {'S','e','l','e','c','t',' ','*',\r
-        ' ','f','r','o','m',' ','I','n','i','F','i','l','e',0};\r
-    static const WCHAR szWindowsFolder[] =\r
-          {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        TRACE("no IniFile table\n");\r
-        return ERROR_SUCCESS;\r
-    }\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        LPWSTR component,filename,dirproperty,section,key,value,identifier;\r
-        LPWSTR deformated_section, deformated_key, deformated_value;\r
-        LPWSTR folder, fullname = NULL;\r
-        MSIRECORD * uirow;\r
-        INT component_index,action;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        component = load_dynamic_stringW(row, 8);\r
-        component_index = get_loaded_component(package,component);\r
-        HeapFree(GetProcessHeap(),0,component);\r
-\r
-        if (package->components[component_index].ActionRequest != \r
-             INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping ini file due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[component_index].Action =\r
-                package->components[component_index].Installed;\r
-\r
-            continue;\r
-        }\r
-\r
-        package->components[component_index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[component_index].Installed = INSTALLSTATE_LOCAL;\r
-   \r
-        identifier = load_dynamic_stringW(row,1); \r
-        filename = load_dynamic_stringW(row,2);\r
-        dirproperty = load_dynamic_stringW(row,3);\r
-        section = load_dynamic_stringW(row,4);\r
-        key = load_dynamic_stringW(row,5);\r
-        value = load_dynamic_stringW(row,6);\r
-        action = MSI_RecordGetInteger(row,7);\r
-\r
-        deformat_string(package,section,&deformated_section);\r
-        deformat_string(package,key,&deformated_key);\r
-        deformat_string(package,value,&deformated_value);\r
-\r
-        if (dirproperty)\r
-        {\r
-            folder = resolve_folder(package, dirproperty, FALSE, FALSE, NULL);\r
-            if (!folder)\r
-                folder = load_dynamic_property(package,dirproperty,NULL);\r
-        }\r
-        else\r
-            folder = load_dynamic_property(package, szWindowsFolder, NULL);\r
-\r
-        if (!folder)\r
-        {\r
-            ERR("Unable to resolve folder! (%s)\n",debugstr_w(dirproperty));\r
-            goto cleanup;\r
-        }\r
-\r
-        fullname = build_directory_name(3, folder, filename, NULL);\r
-\r
-        if (action == 0)\r
-        {\r
-            TRACE("Adding value %s to section %s in %s\n",\r
-                debugstr_w(deformated_key), debugstr_w(deformated_section),\r
-                debugstr_w(fullname));\r
-            WritePrivateProfileStringW(deformated_section, deformated_key,\r
-                                       deformated_value, fullname);\r
-        }\r
-        else if (action == 1)\r
-        {\r
-            WCHAR returned[10];\r
-            GetPrivateProfileStringW(deformated_section, deformated_key, NULL,\r
-                                     returned, 10, fullname);\r
-            if (returned[0] == 0)\r
-            {\r
-                TRACE("Adding value %s to section %s in %s\n",\r
-                    debugstr_w(deformated_key), debugstr_w(deformated_section),\r
-                    debugstr_w(fullname));\r
-\r
-                WritePrivateProfileStringW(deformated_section, deformated_key,\r
-                                       deformated_value, fullname);\r
-            }\r
-        }\r
-        else if (action == 3)\r
-        {\r
-            FIXME("Append to existing section not yet implemented\n");\r
-        }\r
-        \r
-        uirow = MSI_CreateRecord(4);\r
-        MSI_RecordSetStringW(uirow,1,identifier);\r
-        MSI_RecordSetStringW(uirow,2,deformated_section);\r
-        MSI_RecordSetStringW(uirow,3,deformated_key);\r
-        MSI_RecordSetStringW(uirow,4,deformated_value);\r
-        ui_actiondata(package,szWriteIniValues,uirow);\r
-        msiobj_release( &uirow->hdr );\r
-cleanup:\r
-        HeapFree(GetProcessHeap(),0,identifier);\r
-        HeapFree(GetProcessHeap(),0,fullname);\r
-        HeapFree(GetProcessHeap(),0,filename);\r
-        HeapFree(GetProcessHeap(),0,key);\r
-        HeapFree(GetProcessHeap(),0,value);\r
-        HeapFree(GetProcessHeap(),0,section);\r
-        HeapFree(GetProcessHeap(),0,dirproperty);\r
-        HeapFree(GetProcessHeap(),0,folder);\r
-        HeapFree(GetProcessHeap(),0,deformated_key);\r
-        HeapFree(GetProcessHeap(),0,deformated_value);\r
-        HeapFree(GetProcessHeap(),0,deformated_section);\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_SelfRegModules(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {'S','e','l','e','c','t',' ','*',' ',\r
-'f','r','o','m',' ','S','e','l','f','R','e','g',0};\r
-\r
-    static const WCHAR ExeStr[] = {\r
-'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','s',' ',0};\r
-    STARTUPINFOW si;\r
-    PROCESS_INFORMATION info;\r
-    BOOL brc;\r
-\r
-    memset(&si,0,sizeof(STARTUPINFOW));\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        TRACE("no SelfReg table\n");\r
-        return ERROR_SUCCESS;\r
-    }\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        LPWSTR filename;\r
-        INT index;\r
-        DWORD len;\r
-\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        filename = load_dynamic_stringW(row,1);\r
-        index = get_loaded_file(package,filename);\r
-\r
-        if (index < 0)\r
-        {\r
-            ERR("Unable to find file id %s\n",debugstr_w(filename));\r
-            HeapFree(GetProcessHeap(),0,filename);\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-        HeapFree(GetProcessHeap(),0,filename);\r
-\r
-        len = strlenW(ExeStr);\r
-        len += strlenW(package->files[index].TargetPath);\r
-        len +=2;\r
-\r
-        filename = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));\r
-        strcpyW(filename,ExeStr);\r
-        strcatW(filename,package->files[index].TargetPath);\r
-\r
-        TRACE("Registering %s\n",debugstr_w(filename));\r
-        brc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL,\r
-                  c_collen, &si, &info);\r
-\r
-        if (brc)\r
-            msi_dialog_check_messages(package->dialog, info.hProcess);\r
\r
-        HeapFree(GetProcessHeap(),0,filename);\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_PublishFeatures(MSIPACKAGE *package)\r
-{\r
-    LPWSTR productcode;\r
-    UINT rc;\r
-    DWORD i;\r
-    HKEY hkey=0;\r
-    HKEY hukey=0;\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    \r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    rc = MSIREG_OpenFeaturesKey(productcode,&hkey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-    rc = MSIREG_OpenUserFeaturesKey(productcode,&hukey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-    /* here the guids are base 85 encoded */\r
-    for (i = 0; i < package->loaded_features; i++)\r
-    {\r
-        LPWSTR data = NULL;\r
-        GUID clsid;\r
-        int j;\r
-        INT size;\r
-\r
-        size = package->features[i].ComponentCount*21;\r
-        size +=1;\r
-        if (package->features[i].Feature_Parent[0])\r
-            size += strlenW(package->features[i].Feature_Parent)+2;\r
-\r
-        data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));\r
-\r
-        data[0] = 0;\r
-        for (j = 0; j < package->features[i].ComponentCount; j++)\r
-        {\r
-            WCHAR buf[21];\r
-            memset(buf,0,sizeof(buf));\r
-            TRACE("From %s\n",debugstr_w(package->components\r
-                            [package->features[i].Components[j]].ComponentId));\r
-            CLSIDFromString(package->components\r
-                            [package->features[i].Components[j]].ComponentId,\r
-                            &clsid);\r
-            encode_base85_guid(&clsid,buf);\r
-            TRACE("to %s\n",debugstr_w(buf));\r
-            strcatW(data,buf);\r
-        }\r
-        if (package->features[i].Feature_Parent[0])\r
-        {\r
-            static const WCHAR sep[] = {'\2',0};\r
-            strcatW(data,sep);\r
-            strcatW(data,package->features[i].Feature_Parent);\r
-        }\r
-\r
-        size = (strlenW(data)+1)*sizeof(WCHAR);\r
-        RegSetValueExW(hkey,package->features[i].Feature,0,REG_SZ,\r
-                       (LPSTR)data,size);\r
-        HeapFree(GetProcessHeap(),0,data);\r
-\r
-        size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR);\r
-        RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,\r
-                       (LPSTR)package->features[i].Feature_Parent,size);\r
-    }\r
-\r
-end:\r
-    RegCloseKey(hkey);\r
-    RegCloseKey(hukey);\r
-    HeapFree(GetProcessHeap(), 0, productcode);\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterProduct(MSIPACKAGE *package)\r
-{\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    HKEY hkey=0;\r
-    LPWSTR buffer;\r
-    LPWSTR productcode;\r
-    UINT rc,i;\r
-    DWORD size;\r
-    static WCHAR szNONE[] = {0};\r
-    static const WCHAR szWindowsInstaler[] = \r
-    {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};\r
-    static const WCHAR szPropKeys[][80] = \r
-    {\r
-{'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0},\r
-{'A','R','P','C','O','N','T','A','C','T'},\r
-{'A','R','P','C','O','M','M','E','N','T','S',0},\r
-{'P','r','o','d','u','c','t','N','a','m','e',0},\r
-{'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0},\r
-{'A','R','P','H','E','L','P','L','I','N','K',0},\r
-{'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0},\r
-{'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0},\r
-{'S','O','U','R','C','E','D','I','R',0},\r
-{'M','a','n','u','f','a','c','t','u','r','e','r',0},\r
-{'A','R','P','R','E','A','D','M','E',0},\r
-{'A','R','P','S','I','Z','E',0},\r
-{'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0},\r
-{'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0},\r
-{0},\r
-    };\r
-\r
-    static const WCHAR szRegKeys[][80] = \r
-    {\r
-{'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0},\r
-{'C','o','n','t','a','c','t',0},\r
-{'C','o','m','m','e','n','t','s',0},\r
-{'D','i','s','p','l','a','y','N','a','m','e',0},\r
-{'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0},\r
-{'H','e','l','p','L','i','n','k',0},\r
-{'H','e','l','p','T','e','l','e','p','h','o','n','e',0},\r
-{'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0},\r
-{'I','n','s','t','a','l','l','S','o','u','r','c','e',0},\r
-{'P','u','b','l','i','s','h','e','r',0},\r
-{'R','e','a','d','m','e',0},\r
-{'S','i','z','e',0},\r
-{'U','R','L','I','n','f','o','A','b','o','u','t',0},\r
-{'U','R','L','U','p','d','a','t','e','I','n','f','o',0},\r
-{0},\r
-    };\r
-\r
-    static const WCHAR path[] = {\r
-    'C',':','\\','W','i','n','d','o','w','s','\\',\r
-    'I','n','s','t','a','l','l','e','r','\\'};\r
-    static const WCHAR fmt[] = {\r
-    'C',':','\\','W','i','n','d','o','w','s','\\',\r
-    'I','n','s','t','a','l','l','e','r','\\',\r
-    '%','x','.','m','s','i',0};\r
-    static const WCHAR szLocalPackage[]=\r
-         {'L','o','c','a','l','P','a','c','k','a','g','e',0};\r
-    WCHAR packagefile[MAX_PATH];\r
-    INT num,start;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-    /* dump all the info i can grab */\r
-    FIXME("Flesh out more information \n");\r
-\r
-    i = 0;\r
-    while (szPropKeys[i][0]!=0)\r
-    {\r
-        buffer = load_dynamic_property(package,szPropKeys[i],&rc);\r
-        if (rc != ERROR_SUCCESS)\r
-            buffer = szNONE;\r
-        size = strlenW(buffer)*sizeof(WCHAR);\r
-        RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);\r
-        i++;\r
-    }\r
-\r
-    rc = 0x1;\r
-    size = sizeof(rc);\r
-    RegSetValueExW(hkey,szWindowsInstaler,0,REG_DWORD,(LPSTR)&rc,size);\r
-    \r
-    /* copy the package locally */\r
-    num = GetTickCount() & 0xffff;\r
-    if (!num) \r
-        num = 1;\r
-    start = num;\r
-    sprintfW(packagefile,fmt,num);\r
-    do \r
-    {\r
-        HANDLE handle = CreateFileW(packagefile,GENERIC_WRITE, 0, NULL,\r
-                                  CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );\r
-        if (handle != INVALID_HANDLE_VALUE)\r
-        {\r
-            CloseHandle(handle);\r
-            break;\r
-        }\r
-        if (GetLastError() != ERROR_FILE_EXISTS &&\r
-            GetLastError() != ERROR_SHARING_VIOLATION)\r
-            break;\r
-        if (!(++num & 0xffff)) num = 1;\r
-        sprintfW(packagefile,fmt,num);\r
-    } while (num != start);\r
-\r
-    create_full_pathW(path);\r
-    TRACE("Copying to local package %s\n",debugstr_w(packagefile));\r
-    CopyFileW(package->PackagePath,packagefile,FALSE);\r
-    size = strlenW(packagefile)*sizeof(WCHAR);\r
-    RegSetValueExW(hkey,szLocalPackage,0,REG_SZ,(LPSTR)packagefile,size);\r
-    \r
-end:\r
-    HeapFree(GetProcessHeap(),0,productcode);\r
-    RegCloseKey(hkey);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_InstallExecute(MSIPACKAGE *package)\r
-{\r
-    int i;\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    for (i = 0; i < package->DeferredActionCount; i++)\r
-    {\r
-        LPWSTR action;\r
-        action = package->DeferredAction[i];\r
-        ui_actionstart(package, action);\r
-        TRACE("Executing Action (%s)\n",debugstr_w(action));\r
-        ACTION_CustomAction(package,action,TRUE);\r
-        HeapFree(GetProcessHeap(),0,package->DeferredAction[i]);\r
-    }\r
-    HeapFree(GetProcessHeap(),0,package->DeferredAction);\r
-\r
-    package->DeferredActionCount = 0;\r
-    package->DeferredAction = NULL;\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_InstallFinalize(MSIPACKAGE *package)\r
-{\r
-    int i;\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    /* first do the same as an InstallExecute */\r
-    ACTION_InstallExecute(package);\r
-\r
-    /* then handle Commit Actions */\r
-    for (i = 0; i < package->CommitActionCount; i++)\r
-    {\r
-        LPWSTR action;\r
-        action = package->CommitAction[i];\r
-        ui_actionstart(package, action);\r
-        TRACE("Executing Commit Action (%s)\n",debugstr_w(action));\r
-        ACTION_CustomAction(package,action,TRUE);\r
-        HeapFree(GetProcessHeap(),0,package->CommitAction[i]);\r
-    }\r
-    HeapFree(GetProcessHeap(),0,package->CommitAction);\r
-\r
-    package->CommitActionCount = 0;\r
-    package->CommitAction = NULL;\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-static UINT ACTION_ForceReboot(MSIPACKAGE *package)\r
-{\r
-    static const WCHAR RunOnce[] = {\r
-    'S','o','f','t','w','a','r','e','\\',\r
-    'M','i','c','r','o','s','o','f','t','\\',\r
-    'W','i','n','d','o','w','s','\\',\r
-    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',\r
-    'R','u','n','O','n','c','e'};\r
-    static const WCHAR InstallRunOnce[] = {\r
-    'S','o','f','t','w','a','r','e','\\',\r
-    'M','i','c','r','o','s','o','f','t','\\',\r
-    'W','i','n','d','o','w','s','\\',\r
-    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',\r
-    'I','n','s','t','a','l','l','e','r','\\',\r
-    'R','u','n','O','n','c','e','E','n','t','r','i','e','s'};\r
-\r
-    static const WCHAR msiexec_fmt[] = {\r
-    'C',':','\\','W','i','n','d','o','w','s','\\','S','y','s','t','e','m',\r
-    '\\','M','s','i','E','x','e','c','.','e','x','e',' ','/','@',' ',\r
-    '\"','%','s','\"',0};\r
-    static const WCHAR install_fmt[] = {\r
-    '/','I',' ','\"','%','s','\"',' ',\r
-    'A','F','T','E','R','R','E','B','O','O','T','=','1',' ',\r
-    'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};\r
-    WCHAR buffer[256];\r
-    HKEY hkey,hukey;\r
-    LPWSTR productcode;\r
-    WCHAR  squished_pc[100];\r
-    INT rc;\r
-    DWORD size;\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    static const WCHAR szLUS[] = {\r
-         'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};\r
-    static const WCHAR szSourceList[] = {\r
-         'S','o','u','r','c','e','L','i','s','t',0};\r
-    static const WCHAR szPackageName[] = { \r
-        'P','a','c','k','a','g','e','N','a','m','e',0};\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    squash_guid(productcode,squished_pc);\r
-\r
-    RegCreateKeyW(HKEY_LOCAL_MACHINE,RunOnce,&hkey);\r
-    sprintfW(buffer,msiexec_fmt,squished_pc);\r
-\r
-    size = strlenW(buffer)*sizeof(WCHAR);\r
-    RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);\r
-    RegCloseKey(hkey);\r
-\r
-    TRACE("Reboot command %s\n",debugstr_w(buffer));\r
-\r
-    RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);\r
-    sprintfW(buffer,install_fmt,productcode,squished_pc);\r
-    RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);\r
-    RegCloseKey(hkey);\r
-\r
-    rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);\r
-    if (rc == ERROR_SUCCESS)\r
-    {\r
-        HKEY hukey2;\r
-        LPWSTR buf;\r
-        RegCreateKeyW(hukey, szSourceList, &hukey2);\r
-        buf = load_dynamic_property(package,cszSourceDir,NULL);\r
-        size = strlenW(buf)*sizeof(WCHAR);\r
-        RegSetValueExW(hukey2,szLUS,0,REG_SZ,(LPSTR)buf,size);\r
-        HeapFree(GetProcessHeap(),0,buf); \r
-\r
-        buf = strrchrW(package->PackagePath,'\\');\r
-        if (buf)\r
-        {\r
-            buf++;\r
-            size = strlenW(buf)*sizeof(WCHAR);\r
-            RegSetValueExW(hukey2,szPackageName,0,REG_SZ,(LPSTR)buf,size);\r
-        }\r
-\r
-        RegCloseKey(hukey2);\r
-    }\r
-    HeapFree(GetProcessHeap(),0,productcode);\r
-\r
-    return ERROR_INSTALL_SUSPEND;\r
-}\r
-\r
-UINT ACTION_ResolveSource(MSIPACKAGE* package)\r
-{\r
-    /*\r
-     * we are currently doing what should be done here in the top level Install\r
-     * however for Adminastrative and uninstalls this step will be needed\r
-     */\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-\r
-static UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','E','x','t','e','n','s','i','o','n',0};\r
-    static const WCHAR szContentType[] = \r
-{ 'C','o','n','t','e','n','t',' ','T','y','p','e',0 };\r
-    HKEY hkey;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        rc = ERROR_SUCCESS;\r
-        goto end;\r
-    }\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        goto end;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        WCHAR buffer[0x100];\r
-        WCHAR extension[257];\r
-        LPWSTR exten;\r
-        DWORD sz;\r
-        INT index;\r
-     \r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        sz=0x100;\r
-        MSI_RecordGetStringW(row,2,buffer,&sz);\r
-\r
-        index = get_loaded_component(package,buffer);\r
-\r
-        if (index < 0)\r
-        {\r
-            msiobj_release(&row->hdr);\r
-            continue;\r
-        }\r
-\r
-        if (package->components[index].ActionRequest != INSTALLSTATE_LOCAL)\r
-        {\r
-            TRACE("Skipping extension reg due to disabled component\n");\r
-            msiobj_release(&row->hdr);\r
-\r
-            package->components[index].Action =\r
-                package->components[index].Installed;\r
-\r
-            continue;\r
-        }\r
-\r
-        package->components[index].Action = INSTALLSTATE_LOCAL;\r
-        package->components[index].Installed = INSTALLSTATE_LOCAL;\r
-\r
-        exten = load_dynamic_stringW(row,1);\r
-        extension[0] = '.';\r
-        extension[1] = 0;\r
-        strcatW(extension,exten);\r
-        HeapFree(GetProcessHeap(),0,exten);\r
-\r
-        RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey);\r
-\r
-        if (!MSI_RecordIsNull(row,4))\r
-        {\r
-            LPWSTR mime = load_dynamic_stringW(row,4);\r
-            RegSetValueExW(hkey,szContentType,0,REG_SZ,(LPVOID)mime,\r
-                           (strlenW(mime)+1)*sizeof(WCHAR));\r
-            HeapFree(GetProcessHeap(),0,mime);\r
-        }\r
-\r
-        if (!MSI_RecordIsNull(row,3))\r
-        {\r
-            static const WCHAR szSN[] = \r
-            {'\\','S','h','e','l','l','N','e','w',0};\r
-            HKEY hkey2;\r
-            LPWSTR newkey;\r
-            LPWSTR progid= load_dynamic_stringW(row,3);\r
-\r
-            RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)progid,\r
-                           (strlenW(progid)+1)*sizeof(WCHAR));\r
-\r
-            newkey = HeapAlloc(GetProcessHeap(),0,\r
-                           (strlenW(progid)+strlenW(szSN)+1) * sizeof(WCHAR)); \r
-\r
-            strcpyW(newkey,progid);\r
-            strcatW(newkey,szSN);\r
-            RegCreateKeyW(hkey,newkey,&hkey2);\r
-            RegCloseKey(hkey2);\r
-\r
-            HeapFree(GetProcessHeap(),0,progid);\r
-            HeapFree(GetProcessHeap(),0,newkey);\r
-        }\r
-\r
-\r
-        RegCloseKey(hkey);\r
-\r
-        ui_actiondata(package,szRegisterExtensionInfo,row);\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-end:\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {\r
-        'S','E','L','E','C','T',' ','*',' ',\r
-        'f','r','o','m',' ','M','I','M','E',0};\r
-    static const WCHAR szExten[] = \r
-{ 'E','x','t','e','n','s','i','o','n',0 };\r
-    HKEY hkey;\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        rc = ERROR_SUCCESS;\r
-        goto end;\r
-    }\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        goto end;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        WCHAR extension[257];\r
-        LPWSTR exten;\r
-        LPWSTR mime;\r
-        static const WCHAR fmt[] = \r
-{'M','I','M','E','\\',\r
-'D','a','t','a','b','a','s','e','\\',\r
-'C','o','n','t','e','n','t',' ','T','y','p','e','\\',\r
-'%','s',0};\r
-        LPWSTR key;\r
-     \r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        mime = load_dynamic_stringW(row,1);\r
-        exten = load_dynamic_stringW(row,2);\r
-        extension[0] = '.';\r
-        extension[1] = 0;\r
-        strcatW(extension,exten);\r
-        HeapFree(GetProcessHeap(),0,exten);\r
-\r
-        key = HeapAlloc(GetProcessHeap(),0,(strlenW(mime)+strlenW(fmt)+1) *\r
-                                            sizeof(WCHAR));\r
-        sprintfW(key,fmt,mime);\r
-        RegCreateKeyW(HKEY_CLASSES_ROOT,key,&hkey);\r
-        RegSetValueExW(hkey,szExten,0,REG_SZ,(LPVOID)extension,\r
-                           (strlenW(extension)+1)*sizeof(WCHAR));\r
-\r
-        HeapFree(GetProcessHeap(),0,mime);\r
-        HeapFree(GetProcessHeap(),0,key);\r
-\r
-        if (!MSI_RecordIsNull(row,3))\r
-        {\r
-            FIXME("Handle non null for field 3\n");\r
-        }\r
-\r
-        RegCloseKey(hkey);\r
-\r
-        ui_actiondata(package,szRegisterMIMEInfo,row);\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-\r
-end:\r
-    return rc;\r
-}\r
-\r
-static UINT ACTION_RegisterUser(MSIPACKAGE *package)\r
-{\r
-    static const WCHAR szProductCode[]=\r
-         {'P','r','o','d','u','c','t','C','o','d','e',0};\r
-    static const WCHAR szProductID[]=\r
-         {'P','r','o','d','u','c','t','I','D',0};\r
-    HKEY hkey=0;\r
-    LPWSTR buffer;\r
-    LPWSTR productcode;\r
-    LPWSTR productid;\r
-    UINT rc,i;\r
-    DWORD size;\r
-\r
-    static const WCHAR szPropKeys[][80] = \r
-    {\r
-{'P','r','o','d','u','c','t','I','D',0},\r
-{'U','S','E','R','N','A','M','E',0},\r
-{'C','O','M','P','A','N','Y','N','A','M','E',0},\r
-{0},\r
-    };\r
-\r
-    static const WCHAR szRegKeys[][80] = \r
-    {\r
-{'P','r','o','d','u','c','t','I','D',0},\r
-{'R','e','g','O','w','n','e','r',0},\r
-{'R','e','g','C','o','m','p','a','n','y',0},\r
-{0},\r
-    };\r
-\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    productid = load_dynamic_property(package,szProductID,&rc);\r
-    if (!productid)\r
-        return ERROR_SUCCESS;\r
-\r
-    productcode = load_dynamic_property(package,szProductCode,&rc);\r
-    if (!productcode)\r
-        return rc;\r
-\r
-    rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);\r
-    if (rc != ERROR_SUCCESS)\r
-        goto end;\r
-\r
-    i = 0;\r
-    while (szPropKeys[i][0]!=0)\r
-    {\r
-        buffer = load_dynamic_property(package,szPropKeys[i],&rc);\r
-        if (rc == ERROR_SUCCESS)\r
-        {\r
-            size = strlenW(buffer)*sizeof(WCHAR);\r
-            RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);\r
-        }\r
-        i++;\r
-    }\r
-\r
-end:\r
-    HeapFree(GetProcessHeap(),0,productcode);\r
-    HeapFree(GetProcessHeap(),0,productid);\r
-    RegCloseKey(hkey);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-/* Msi functions that seem appropriate here */\r
-UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )\r
-{\r
-    LPWSTR szwAction;\r
-    UINT rc;\r
-\r
-    TRACE(" exteral attempt at action %s\n",szAction);\r
-\r
-    if (!szAction)\r
-        return ERROR_FUNCTION_FAILED;\r
-    if (hInstall == 0)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    szwAction = strdupAtoW(szAction);\r
-\r
-    if (!szwAction)\r
-        return ERROR_FUNCTION_FAILED; \r
-\r
-\r
-    rc = MsiDoActionW(hInstall, szwAction);\r
-    HeapFree(GetProcessHeap(),0,szwAction);\r
-    return rc;\r
-}\r
-\r
-UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )\r
-{\r
-    MSIPACKAGE *package;\r
-    UINT ret = ERROR_INVALID_HANDLE;\r
-\r
-    TRACE(" external attempt at action %s \n",debugstr_w(szAction));\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if( package )\r
-    {\r
-        ret = ACTION_PerformAction(package,szAction);\r
-        msiobj_release( &package->hdr );\r
-    }\r
-    return ret;\r
-}\r
-\r
-UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, \r
-                               LPSTR szPathBuf, DWORD* pcchPathBuf) \r
-{\r
-    LPWSTR szwFolder;\r
-    LPWSTR szwPathBuf;\r
-    UINT rc;\r
-\r
-    TRACE("getting folder %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);\r
-\r
-    if (!szFolder)\r
-        return ERROR_FUNCTION_FAILED;\r
-    if (hInstall == 0)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    szwFolder = strdupAtoW(szFolder);\r
-\r
-    if (!szwFolder)\r
-        return ERROR_FUNCTION_FAILED; \r
-\r
-    szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));\r
-\r
-    rc = MsiGetTargetPathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);\r
-\r
-    WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,\r
-                         *pcchPathBuf, NULL, NULL );\r
-\r
-    HeapFree(GetProcessHeap(),0,szwFolder);\r
-    HeapFree(GetProcessHeap(),0,szwPathBuf);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR\r
-                                szPathBuf, DWORD* pcchPathBuf) \r
-{\r
-    LPWSTR path;\r
-    UINT rc = ERROR_FUNCTION_FAILED;\r
-    MSIPACKAGE *package;\r
-\r
-    TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-    path = resolve_folder(package, szFolder, FALSE, FALSE, NULL);\r
-    msiobj_release( &package->hdr );\r
-\r
-    if (path && (strlenW(path) > *pcchPathBuf))\r
-    {\r
-        *pcchPathBuf = strlenW(path)+1;\r
-        rc = ERROR_MORE_DATA;\r
-    }\r
-    else if (path)\r
-    {\r
-        *pcchPathBuf = strlenW(path)+1;\r
-        strcpyW(szPathBuf,path);\r
-        TRACE("Returning Path %s\n",debugstr_w(path));\r
-        rc = ERROR_SUCCESS;\r
-    }\r
-    HeapFree(GetProcessHeap(),0,path);\r
-    \r
-    return rc;\r
-}\r
-\r
-\r
-UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, \r
-                               LPSTR szPathBuf, DWORD* pcchPathBuf) \r
-{\r
-    LPWSTR szwFolder;\r
-    LPWSTR szwPathBuf;\r
-    UINT rc;\r
-\r
-    TRACE("getting source %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);\r
-\r
-    if (!szFolder)\r
-        return ERROR_FUNCTION_FAILED;\r
-    if (hInstall == 0)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    szwFolder = strdupAtoW(szFolder);\r
-    if (!szwFolder)\r
-        return ERROR_FUNCTION_FAILED; \r
-\r
-    szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));\r
-\r
-    rc = MsiGetSourcePathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);\r
-\r
-    WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,\r
-                         *pcchPathBuf, NULL, NULL );\r
-\r
-    HeapFree(GetProcessHeap(),0,szwFolder);\r
-    HeapFree(GetProcessHeap(),0,szwPathBuf);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR\r
-                                szPathBuf, DWORD* pcchPathBuf) \r
-{\r
-    LPWSTR path;\r
-    UINT rc = ERROR_FUNCTION_FAILED;\r
-    MSIPACKAGE *package;\r
-\r
-    TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if( !package )\r
-        return ERROR_INVALID_HANDLE;\r
-    path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);\r
-    msiobj_release( &package->hdr );\r
-\r
-    if (path && strlenW(path) > *pcchPathBuf)\r
-    {\r
-        *pcchPathBuf = strlenW(path)+1;\r
-        rc = ERROR_MORE_DATA;\r
-    }\r
-    else if (path)\r
-    {\r
-        *pcchPathBuf = strlenW(path)+1;\r
-        strcpyW(szPathBuf,path);\r
-        TRACE("Returning Path %s\n",debugstr_w(path));\r
-        rc = ERROR_SUCCESS;\r
-    }\r
-    HeapFree(GetProcessHeap(),0,path);\r
-    \r
-    return rc;\r
-}\r
-\r
-\r
-UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, \r
-                             LPCSTR szFolderPath)\r
-{\r
-    LPWSTR szwFolder;\r
-    LPWSTR szwFolderPath;\r
-    UINT rc;\r
-\r
-    if (!szFolder)\r
-        return ERROR_FUNCTION_FAILED;\r
-    if (hInstall == 0)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    szwFolder = strdupAtoW(szFolder);\r
-    if (!szwFolder)\r
-        return ERROR_FUNCTION_FAILED; \r
-\r
-    szwFolderPath = strdupAtoW(szFolderPath);\r
-    if (!szwFolderPath)\r
-    {\r
-        HeapFree(GetProcessHeap(),0,szwFolder);\r
-        return ERROR_FUNCTION_FAILED; \r
-    }\r
-\r
-    rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);\r
-\r
-    HeapFree(GetProcessHeap(),0,szwFolder);\r
-    HeapFree(GetProcessHeap(),0,szwFolderPath);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, \r
-                             LPCWSTR szFolderPath)\r
-{\r
-    DWORD i;\r
-    LPWSTR path = NULL;\r
-    LPWSTR path2 = NULL;\r
-    MSIFOLDER *folder;\r
-\r
-    TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));\r
-\r
-    if (package==NULL)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    if (szFolderPath[0]==0)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    if (GetFileAttributesW(szFolderPath) == INVALID_FILE_ATTRIBUTES)\r
-        return ERROR_FUNCTION_FAILED;\r
-\r
-    path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);\r
-\r
-    if (!path)\r
-        return ERROR_INVALID_PARAMETER;\r
-\r
-    HeapFree(GetProcessHeap(),0,folder->Property);\r
-    folder->Property = build_directory_name(2, szFolderPath, NULL);\r
-\r
-    if (strcmpiW(path, folder->Property) == 0)\r
-    {\r
-        /*\r
-         *  Resolved Target has not really changed, so just \r
-         *  set this folder and do not recalculate everything.\r
-         */\r
-        HeapFree(GetProcessHeap(),0,folder->ResolvedTarget);\r
-        folder->ResolvedTarget = NULL;\r
-        path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);\r
-        HeapFree(GetProcessHeap(),0,path2);\r
-    }\r
-    else\r
-    {\r
-        for (i = 0; i < package->loaded_folders; i++)\r
-        {\r
-            HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);\r
-            package->folders[i].ResolvedTarget=NULL;\r
-        }\r
-\r
-        for (i = 0; i < package->loaded_folders; i++)\r
-        {\r
-            path2=resolve_folder(package, package->folders[i].Directory, FALSE,\r
-                       TRUE, NULL);\r
-            HeapFree(GetProcessHeap(),0,path2);\r
-        }\r
-    }\r
-    HeapFree(GetProcessHeap(),0,path);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, \r
-                             LPCWSTR szFolderPath)\r
-{\r
-    MSIPACKAGE *package;\r
-    UINT ret;\r
-\r
-    TRACE("(%s %s)\n",debugstr_w(szFolder),debugstr_w(szFolderPath));\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );\r
-    msiobj_release( &package->hdr );\r
-    return ret;\r
-}\r
-\r
-/***********************************************************************\r
- *           MsiGetMode    (MSI.@)\r
- *\r
- * Returns an internal installer state (if it is running in a mode iRunMode)\r
- *\r
- * PARAMS\r
- *   hInstall    [I]  Handle to the installation\r
- *   hRunMode    [I]  Checking run mode\r
- *        MSIRUNMODE_ADMIN             Administrative mode\r
- *        MSIRUNMODE_ADVERTISE         Advertisement mode\r
- *        MSIRUNMODE_MAINTENANCE       Maintenance mode\r
- *        MSIRUNMODE_ROLLBACKENABLED   Rollback is enabled\r
- *        MSIRUNMODE_LOGENABLED        Log file is writing\r
- *        MSIRUNMODE_OPERATIONS        Operations in progress??\r
- *        MSIRUNMODE_REBOOTATEND       We need to reboot after installation completed\r
- *        MSIRUNMODE_REBOOTNOW         We need to reboot to continue the installation\r
- *        MSIRUNMODE_CABINET           Files from cabinet are installed\r
- *        MSIRUNMODE_SOURCESHORTNAMES  Long names in source files is suppressed\r
- *        MSIRUNMODE_TARGETSHORTNAMES  Long names in destination files is suppressed\r
- *        MSIRUNMODE_RESERVED11        Reserved\r
- *        MSIRUNMODE_WINDOWS9X         Running under Windows95/98\r
- *        MSIRUNMODE_ZAWENABLED        Demand installation is supported\r
- *        MSIRUNMODE_RESERVED14        Reserved\r
- *        MSIRUNMODE_RESERVED15        Reserved\r
- *        MSIRUNMODE_SCHEDULED         called from install script\r
- *        MSIRUNMODE_ROLLBACK          called from rollback script\r
- *        MSIRUNMODE_COMMIT            called from commit script\r
- *\r
- * RETURNS\r
- *    In the state: TRUE\r
- *    Not in the state: FALSE\r
- *\r
- */\r
-\r
-BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)\r
-{\r
-    FIXME("STUB (iRunMode=%i)\n",iRunMode);\r
-    return TRUE;\r
-}\r
-\r
-/*\r
- * According to the docs, when this is called it immediately recalculates\r
- * all the component states as well\r
- */\r
-UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,\r
-                                INSTALLSTATE iState)\r
-{\r
-    LPWSTR szwFeature = NULL;\r
-    UINT rc;\r
-\r
-    szwFeature = strdupAtoW(szFeature);\r
-\r
-    if (!szwFeature)\r
-        return ERROR_FUNCTION_FAILED;\r
-   \r
-    rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); \r
-\r
-    HeapFree(GetProcessHeap(),0,szwFeature);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,\r
-                                INSTALLSTATE iState)\r
-{\r
-    MSIPACKAGE* package;\r
-    INT index;\r
-\r
-    TRACE(" %s to %i\n",debugstr_w(szFeature), iState);\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-\r
-    index = get_loaded_feature(package,szFeature);\r
-    if (index < 0)\r
-        return ERROR_UNKNOWN_FEATURE;\r
-\r
-    package->features[index].ActionRequest= iState;\r
-    ACTION_UpdateComponentStates(package,szFeature);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    LPWSTR szwFeature = NULL;\r
-    UINT rc;\r
-    \r
-    szwFeature = strdupAtoW(szFeature);\r
-\r
-    rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);\r
-\r
-    HeapFree( GetProcessHeap(), 0 , szwFeature);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    INT index;\r
-\r
-    index = get_loaded_feature(package,szFeature);\r
-    if (index < 0)\r
-        return ERROR_UNKNOWN_FEATURE;\r
-\r
-    if (piInstalled)\r
-        *piInstalled = package->features[index].Installed;\r
-\r
-    if (piAction)\r
-        *piAction = package->features[index].Action;\r
-\r
-    TRACE("returning %i %i\n",*piInstalled,*piAction);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPWSTR szFeature,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    MSIPACKAGE* package;\r
-    UINT ret;\r
-\r
-    TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled,\r
-piAction);\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-    ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);\r
-    msiobj_release( &package->hdr );\r
-    return ret;\r
-}\r
-\r
-UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    LPWSTR szwComponent= NULL;\r
-    UINT rc;\r
-    \r
-    szwComponent= strdupAtoW(szComponent);\r
-\r
-    rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);\r
-\r
-    HeapFree( GetProcessHeap(), 0 , szwComponent);\r
-\r
-    return rc;\r
-}\r
-\r
-UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    INT index;\r
-\r
-    TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), piInstalled,\r
-piAction);\r
-\r
-    index = get_loaded_component(package,szComponent);\r
-    if (index < 0)\r
-        return ERROR_UNKNOWN_COMPONENT;\r
-\r
-    if (piInstalled)\r
-        *piInstalled = package->components[index].Installed;\r
-\r
-    if (piAction)\r
-        *piAction = package->components[index].Action;\r
-\r
-    TRACE("states (%i, %i)\n",\r
-(piInstalled)?*piInstalled:-1,(piAction)?*piAction:-1);\r
-\r
-    return ERROR_SUCCESS;\r
-}\r
-\r
-UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent,\r
-                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)\r
-{\r
-    MSIPACKAGE* package;\r
-    UINT ret;\r
-\r
-    TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),\r
-           piInstalled, piAction);\r
-\r
-    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);\r
-    if (!package)\r
-        return ERROR_INVALID_HANDLE;\r
-    ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);\r
-    msiobj_release( &package->hdr );\r
-    return ret;\r
-}\r
-\r
-#if 0\r
-static UINT ACTION_Template(MSIPACKAGE *package)\r
-{\r
-    UINT rc;\r
-    MSIQUERY * view;\r
-    MSIRECORD * row = 0;\r
-    static const WCHAR ExecSeqQuery[] = {0};\r
-\r
-    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);\r
-    if (rc != ERROR_SUCCESS)\r
-        return rc;\r
-\r
-    rc = MSI_ViewExecute(view, 0);\r
-    if (rc != ERROR_SUCCESS)\r
-    {\r
-        MSI_ViewClose(view);\r
-        msiobj_release(&view->hdr);\r
-        return rc;\r
-    }\r
-\r
-    while (1)\r
-    {\r
-        rc = MSI_ViewFetch(view,&row);\r
-        if (rc != ERROR_SUCCESS)\r
-        {\r
-            rc = ERROR_SUCCESS;\r
-            break;\r
-        }\r
-\r
-        msiobj_release(&row->hdr);\r
-    }\r
-    MSI_ViewClose(view);\r
-    msiobj_release(&view->hdr);\r
-    return rc;\r
-}\r
-#endif\r
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Aric Stewart 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Pages I need
+ *
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installexecutesequence_table.asp
+
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/standard_actions_reference.asp
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
+#include "wine/debug.h"
+#include "fdi.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msidefs.h"
+#include "fcntl.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+#include "winuser.h"
+#include "shlobj.h"
+#include "wine/unicode.h"
+#include "winver.h"
+#include "action.h"
+
+#define REG_PROGRESS_VALUE 13200
+#define COMPONENT_PROGRESS_VALUE 24000
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * Prototypes
+ */
+static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);
+static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
+static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq);
+static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, 
+                            LPWSTR *FilePath);
+
+/* 
+ * action handlers
+ */
+typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
+
+static UINT ACTION_LaunchConditions(MSIPACKAGE *package);
+static UINT ACTION_CostInitialize(MSIPACKAGE *package);
+static UINT ACTION_CreateFolders(MSIPACKAGE *package);
+static UINT ACTION_CostFinalize(MSIPACKAGE *package);
+static UINT ACTION_FileCost(MSIPACKAGE *package);
+static UINT ACTION_InstallFiles(MSIPACKAGE *package);
+static UINT ACTION_DuplicateFiles(MSIPACKAGE *package);
+static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package);
+static UINT ACTION_InstallInitialize(MSIPACKAGE *package);
+static UINT ACTION_InstallValidate(MSIPACKAGE *package);
+static UINT ACTION_ProcessComponents(MSIPACKAGE *package);
+static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package);
+static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package);
+static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
+static UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
+static UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
+static UINT ACTION_RegisterUser(MSIPACKAGE *package);
+static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);
+static UINT ACTION_PublishProduct(MSIPACKAGE *package);
+static UINT ACTION_WriteIniValues(MSIPACKAGE *package);
+static UINT ACTION_SelfRegModules(MSIPACKAGE *package);
+static UINT ACTION_PublishFeatures(MSIPACKAGE *package);
+static UINT ACTION_RegisterProduct(MSIPACKAGE *package);
+static UINT ACTION_InstallExecute(MSIPACKAGE *package);
+static UINT ACTION_InstallFinalize(MSIPACKAGE *package);
+static UINT ACTION_ForceReboot(MSIPACKAGE *package);
+static UINT ACTION_ResolveSource(MSIPACKAGE *package);
+static UINT ACTION_ExecuteAction(MSIPACKAGE *package);
+static UINT ACTION_RegisterFonts(MSIPACKAGE *package);
+
+/*
+ * consts and values used
+ */
+static const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
+static const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
+static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
+static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
+static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};
+static const WCHAR c_colon[] = {'C',':','\\',0};
+static const WCHAR szProductCode[]=
+    {'P','r','o','d','u','c','t','C','o','d','e',0};
+static const WCHAR cszbs[]={'\\',0};
+const static WCHAR szCreateFolders[] =
+    {'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
+const static WCHAR szCostFinalize[] =
+    {'C','o','s','t','F','i','n','a','l','i','z','e',0};
+const static WCHAR szInstallFiles[] =
+    {'I','n','s','t','a','l','l','F','i','l','e','s',0};
+const static WCHAR szDuplicateFiles[] =
+    {'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
+const static WCHAR szWriteRegistryValues[] =
+    {'W','r','i','t','e','R','e','g','i','s','t','r','y',
+            'V','a','l','u','e','s',0};
+const static WCHAR szCostInitialize[] =
+    {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
+const static WCHAR szFileCost[] = 
+    {'F','i','l','e','C','o','s','t',0};
+const static WCHAR szInstallInitialize[] = 
+    {'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
+const static WCHAR szInstallValidate[] = 
+    {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
+const static WCHAR szLaunchConditions[] = 
+    {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
+const static WCHAR szProcessComponents[] = 
+    {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
+const static WCHAR szRegisterTypeLibraries[] = 
+    {'R','e','g','i','s','t','e','r','T','y','p','e',
+            'L','i','b','r','a','r','i','e','s',0};
+const static WCHAR szRegisterClassInfo[] = 
+    {'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
+const static WCHAR szRegisterProgIdInfo[] = 
+    {'R','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};
+const static WCHAR szCreateShortcuts[] = 
+    {'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0};
+const static WCHAR szPublishProduct[] = 
+    {'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
+const static WCHAR szWriteIniValues[] = 
+    {'W','r','i','t','e','I','n','i','V','a','l','u','e','s',0};
+const static WCHAR szSelfRegModules[] = 
+    {'S','e','l','f','R','e','g','M','o','d','u','l','e','s',0};
+const static WCHAR szPublishFeatures[] = 
+    {'P','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
+const static WCHAR szRegisterProduct[] = 
+    {'R','e','g','i','s','t','e','r','P','r','o','d','u','c','t',0};
+const static WCHAR szInstallExecute[] = 
+    {'I','n','s','t','a','l','l','E','x','e','c','u','t','e',0};
+const static WCHAR szInstallExecuteAgain[] = 
+    {'I','n','s','t','a','l','l','E','x','e','c','u','t','e',
+            'A','g','a','i','n',0};
+const static WCHAR szInstallFinalize[] = 
+    {'I','n','s','t','a','l','l','F','i','n','a','l','i','z','e',0};
+const static WCHAR szForceReboot[] = 
+    {'F','o','r','c','e','R','e','b','o','o','t',0};
+const static WCHAR szResolveSource[] =
+    {'R','e','s','o','l','v','e','S','o','u','r','c','e',0};
+const static WCHAR szAppSearch[] = 
+    {'A','p','p','S','e','a','r','c','h',0};
+const static WCHAR szAllocateRegistrySpace[] = 
+    {'A','l','l','o','c','a','t','e','R','e','g','i','s','t','r','y',
+            'S','p','a','c','e',0};
+const static WCHAR szBindImage[] = 
+    {'B','i','n','d','I','m','a','g','e',0};
+const static WCHAR szCCPSearch[] = 
+    {'C','C','P','S','e','a','r','c','h',0};
+const static WCHAR szDeleteServices[] = 
+    {'D','e','l','e','t','e','S','e','r','v','i','c','e','s',0};
+const static WCHAR szDisableRollback[] = 
+    {'D','i','s','a','b','l','e','R','o','l','l','b','a','c','k',0};
+const static WCHAR szExecuteAction[] = 
+    {'E','x','e','c','u','t','e','A','c','t','i','o','n',0};
+const static WCHAR szFindRelatedProducts[] = 
+    {'F','i','n','d','R','e','l','a','t','e','d',
+            'P','r','o','d','u','c','t','s',0};
+const static WCHAR szInstallAdminPackage[] = 
+    {'I','n','s','t','a','l','l','A','d','m','i','n',
+            'P','a','c','k','a','g','e',0};
+const static WCHAR szInstallSFPCatalogFile[] = 
+    {'I','n','s','t','a','l','l','S','F','P','C','a','t','a','l','o','g',
+            'F','i','l','e',0};
+const static WCHAR szIsolateComponents[] = 
+    {'I','s','o','l','a','t','e','C','o','m','p','o','n','e','n','t','s',0};
+const static WCHAR szMigrateFeatureStates[] = 
+    {'M','i','g','r','a','t','e','F','e','a','t','u','r','e',
+            'S','t','a','t','e','s',0};
+const static WCHAR szMoveFiles[] = 
+    {'M','o','v','e','F','i','l','e','s',0};
+const static WCHAR szMsiPublishAssemblies[] = 
+    {'M','s','i','P','u','b','l','i','s','h',
+            'A','s','s','e','m','b','l','i','e','s',0};
+const static WCHAR szMsiUnpublishAssemblies[] = 
+    {'M','s','i','U','n','p','u','b','l','i','s','h',
+            'A','s','s','e','m','b','l','i','e','s',0};
+const static WCHAR szInstallODBC[] = 
+    {'I','n','s','t','a','l','l','O','D','B','C',0};
+const static WCHAR szInstallServices[] = 
+    {'I','n','s','t','a','l','l','S','e','r','v','i','c','e','s',0};
+const static WCHAR szPatchFiles[] = 
+    {'P','a','t','c','h','F','i','l','e','s',0};
+const static WCHAR szPublishComponents[] = 
+    {'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t','s',0};
+const static WCHAR szRegisterComPlus[] =
+    {'R','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
+const static WCHAR szRegisterExtensionInfo[] =
+    {'R','e','g','i','s','t','e','r','E','x','t','e','n','s','i','o','n',
+            'I','n','f','o',0};
+const static WCHAR szRegisterFonts[] =
+    {'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
+const static WCHAR szRegisterMIMEInfo[] =
+    {'R','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
+const static WCHAR szRegisterUser[] =
+    {'R','e','g','i','s','t','e','r','U','s','e','r',0};
+const static WCHAR szRemoveDuplicateFiles[] =
+    {'R','e','m','o','v','e','D','u','p','l','i','c','a','t','e',
+            'F','i','l','e','s',0};
+const static WCHAR szRemoveEnvironmentStrings[] =
+    {'R','e','m','o','v','e','E','n','v','i','r','o','n','m','e','n','t',
+            'S','t','r','i','n','g','s',0};
+const static WCHAR szRemoveExistingProducts[] =
+    {'R','e','m','o','v','e','E','x','i','s','t','i','n','g',
+            'P','r','o','d','u','c','t','s',0};
+const static WCHAR szRemoveFiles[] =
+    {'R','e','m','o','v','e','F','i','l','e','s',0};
+const static WCHAR szRemoveFolders[] =
+    {'R','e','m','o','v','e','F','o','l','d','e','r','s',0};
+const static WCHAR szRemoveIniValues[] =
+    {'R','e','m','o','v','e','I','n','i','V','a','l','u','e','s',0};
+const static WCHAR szRemoveODBC[] =
+    {'R','e','m','o','v','e','O','D','B','C',0};
+const static WCHAR szRemoveRegistryValues[] =
+    {'R','e','m','o','v','e','R','e','g','i','s','t','r','y',
+            'V','a','l','u','e','s',0};
+const static WCHAR szRemoveShortcuts[] =
+    {'R','e','m','o','v','e','S','h','o','r','t','c','u','t','s',0};
+const static WCHAR szRMCCPSearch[] =
+    {'R','M','C','C','P','S','e','a','r','c','h',0};
+const static WCHAR szScheduleReboot[] =
+    {'S','c','h','e','d','u','l','e','R','e','b','o','o','t',0};
+const static WCHAR szSelfUnregModules[] =
+    {'S','e','l','f','U','n','r','e','g','M','o','d','u','l','e','s',0};
+const static WCHAR szSetODBCFolders[] =
+    {'S','e','t','O','D','B','C','F','o','l','d','e','r','s',0};
+const static WCHAR szStartServices[] =
+    {'S','t','a','r','t','S','e','r','v','i','c','e','s',0};
+const static WCHAR szStopServices[] =
+    {'S','t','o','p','S','e','r','v','i','c','e','s',0};
+const static WCHAR szUnpublishComponents[] =
+    {'U','n','p','u','b','l','i','s','h',
+            'C','o','m','p','o','n','e','n','t','s',0};
+const static WCHAR szUnpublishFeatures[] =
+    {'U','n','p','u','b','l','i','s','h','F','e','a','t','u','r','e','s',0};
+const static WCHAR szUnregisterClassInfo[] =
+    {'U','n','r','e','g','i','s','t','e','r','C','l','a','s','s',
+            'I','n','f','o',0};
+const static WCHAR szUnregisterComPlus[] =
+    {'U','n','r','e','g','i','s','t','e','r','C','o','m','P','l','u','s',0};
+const static WCHAR szUnregisterExtensionInfo[] =
+    {'U','n','r','e','g','i','s','t','e','r',
+            'E','x','t','e','n','s','i','o','n','I','n','f','o',0};
+const static WCHAR szUnregisterFonts[] =
+    {'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};
+const static WCHAR szUnregisterMIMEInfo[] =
+    {'U','n','r','e','g','i','s','t','e','r','M','I','M','E','I','n','f','o',0};
+const static WCHAR szUnregisterProgIdInfo[] =
+    {'U','n','r','e','g','i','s','t','e','r','P','r','o','g','I','d',
+            'I','n','f','o',0};
+const static WCHAR szUnregisterTypeLibraries[] =
+    {'U','n','r','e','g','i','s','t','e','r','T','y','p','e',
+            'L','i','b','r','a','r','i','e','s',0};
+const static WCHAR szValidateProductID[] =
+    {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
+const static WCHAR szWriteEnvironmentStrings[] =
+    {'W','r','i','t','e','E','n','v','i','r','o','n','m','e','n','t',
+            'S','t','r','i','n','g','s',0};
+
+struct _actions {
+    LPCWSTR action;
+    STANDARDACTIONHANDLER handler;
+};
+
+static struct _actions StandardActions[] = {
+    { szAllocateRegistrySpace, NULL},
+    { szAppSearch, ACTION_AppSearch },
+    { szBindImage, NULL},
+    { szCCPSearch, NULL},
+    { szCostFinalize, ACTION_CostFinalize },
+    { szCostInitialize, ACTION_CostInitialize },
+    { szCreateFolders, ACTION_CreateFolders },
+    { szCreateShortcuts, ACTION_CreateShortcuts },
+    { szDeleteServices, NULL},
+    { szDisableRollback, NULL},
+    { szDuplicateFiles, ACTION_DuplicateFiles },
+    { szExecuteAction, ACTION_ExecuteAction },
+    { szFileCost, ACTION_FileCost },
+    { szFindRelatedProducts, NULL},
+    { szForceReboot, ACTION_ForceReboot },
+    { szInstallAdminPackage, NULL},
+    { szInstallExecute, ACTION_InstallExecute },
+    { szInstallExecuteAgain, ACTION_InstallExecute },
+    { szInstallFiles, ACTION_InstallFiles},
+    { szInstallFinalize, ACTION_InstallFinalize },
+    { szInstallInitialize, ACTION_InstallInitialize },
+    { szInstallSFPCatalogFile, NULL},
+    { szInstallValidate, ACTION_InstallValidate },
+    { szIsolateComponents, NULL},
+    { szLaunchConditions, ACTION_LaunchConditions },
+    { szMigrateFeatureStates, NULL},
+    { szMoveFiles, NULL},
+    { szMsiPublishAssemblies, NULL},
+    { szMsiUnpublishAssemblies, NULL},
+    { szInstallODBC, NULL},
+    { szInstallServices, NULL},
+    { szPatchFiles, NULL},
+    { szProcessComponents, ACTION_ProcessComponents },
+    { szPublishComponents, NULL},
+    { szPublishFeatures, ACTION_PublishFeatures },
+    { szPublishProduct, ACTION_PublishProduct },
+    { szRegisterClassInfo, ACTION_RegisterClassInfo },
+    { szRegisterComPlus, NULL},
+    { szRegisterExtensionInfo, ACTION_RegisterExtensionInfo },
+    { szRegisterFonts, ACTION_RegisterFonts },
+    { szRegisterMIMEInfo, ACTION_RegisterMIMEInfo },
+    { szRegisterProduct, ACTION_RegisterProduct },
+    { szRegisterProgIdInfo, ACTION_RegisterProgIdInfo },
+    { szRegisterTypeLibraries, ACTION_RegisterTypeLibraries },
+    { szRegisterUser, ACTION_RegisterUser},
+    { szRemoveDuplicateFiles, NULL},
+    { szRemoveEnvironmentStrings, NULL},
+    { szRemoveExistingProducts, NULL},
+    { szRemoveFiles, NULL},
+    { szRemoveFolders, NULL},
+    { szRemoveIniValues, NULL},
+    { szRemoveODBC, NULL},
+    { szRemoveRegistryValues, NULL},
+    { szRemoveShortcuts, NULL},
+    { szResolveSource, ACTION_ResolveSource},
+    { szRMCCPSearch, NULL},
+    { szScheduleReboot, NULL},
+    { szSelfRegModules, ACTION_SelfRegModules },
+    { szSelfUnregModules, NULL},
+    { szSetODBCFolders, NULL},
+    { szStartServices, NULL},
+    { szStopServices, NULL},
+    { szUnpublishComponents, NULL},
+    { szUnpublishFeatures, NULL},
+    { szUnregisterClassInfo, NULL},
+    { szUnregisterComPlus, NULL},
+    { szUnregisterExtensionInfo, NULL},
+    { szUnregisterFonts, NULL},
+    { szUnregisterMIMEInfo, NULL},
+    { szUnregisterProgIdInfo, NULL},
+    { szUnregisterTypeLibraries, NULL},
+    { szValidateProductID, NULL},
+    { szWriteEnvironmentStrings, NULL},
+    { szWriteIniValues, ACTION_WriteIniValues },
+    { szWriteRegistryValues, ACTION_WriteRegistryValues},
+    { NULL, NULL},
+};
+
+
+/******************************************************** 
+ * helper functions to get around current HACKS and such
+ ********************************************************/
+inline static void reduce_to_longfilename(WCHAR* filename)
+{
+    LPWSTR p = strchrW(filename,'|');
+    if (p)
+        memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
+}
+
+WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
+{
+    UINT rc;
+    DWORD sz;
+    LPWSTR ret;
+   
+    sz = 0; 
+    if (MSI_RecordIsNull(row,index))
+        return NULL;
+
+    rc = MSI_RecordGetStringW(row,index,NULL,&sz);
+
+    /* having an empty string is different than NULL */
+    if (sz == 0)
+    {
+        ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));
+        ret[0] = 0;
+        return ret;
+    }
+
+    sz ++;
+    ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
+    rc = MSI_RecordGetStringW(row,index,ret,&sz);
+    if (rc!=ERROR_SUCCESS)
+    {
+        ERR("Unable to load dynamic string\n");
+        HeapFree(GetProcessHeap(), 0, ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
+LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc)
+{
+    DWORD sz = 0;
+    LPWSTR str;
+    UINT r;
+
+    r = MSI_GetPropertyW(package, prop, NULL, &sz);
+    if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
+    {
+        if (rc)
+            *rc = r;
+        return NULL;
+    }
+    sz++;
+    str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+    r = MSI_GetPropertyW(package, prop, str, &sz);
+    if (r != ERROR_SUCCESS)
+    {
+        HeapFree(GetProcessHeap(),0,str);
+        str = NULL;
+    }
+    if (rc)
+        *rc = r;
+    return str;
+}
+
+int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
+{
+    int rc = -1;
+    DWORD i;
+
+    for (i = 0; i < package->loaded_components; i++)
+    {
+        if (strcmpW(Component,package->components[i].Component)==0)
+        {
+            rc = i;
+            break;
+        }
+    }
+    return rc;
+}
+
+int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
+{
+    int rc = -1;
+    DWORD i;
+
+    for (i = 0; i < package->loaded_features; i++)
+    {
+        if (strcmpW(Feature,package->features[i].Feature)==0)
+        {
+            rc = i;
+            break;
+        }
+    }
+    return rc;
+}
+
+int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
+{
+    int rc = -1;
+    DWORD i;
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        if (strcmpW(file,package->files[i].File)==0)
+        {
+            rc = i;
+            break;
+        }
+    }
+    return rc;
+}
+
+int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
+{
+    DWORD i;
+    DWORD index;
+
+    if (!package)
+        return -2;
+
+    for (i=0; i < package->loaded_files; i++)
+        if (strcmpW(package->files[i].File,name)==0)
+            return -1;
+
+    index = package->loaded_files;
+    package->loaded_files++;
+    if (package->loaded_files== 1)
+        package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));
+    else
+        package->files = HeapReAlloc(GetProcessHeap(),0,
+            package->files , package->loaded_files * sizeof(MSIFILE));
+
+    memset(&package->files[index],0,sizeof(MSIFILE));
+
+    package->files[index].File = dupstrW(name);
+    package->files[index].TargetPath = dupstrW(path);
+    package->files[index].Temporary = TRUE;
+
+    TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));  
+
+    return 0;
+}
+
+static void remove_tracked_tempfiles(MSIPACKAGE* package)
+{
+    DWORD i;
+
+    if (!package)
+        return;
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        if (package->files[i].Temporary)
+        {
+            TRACE("Cleaning up %s\n",debugstr_w(package->files[i].TargetPath));
+            DeleteFileW(package->files[i].TargetPath);
+        }
+
+    }
+}
+
+/* wrapper to resist a need for a full rewrite right now */
+DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data )
+{
+    if (ptr)
+    {
+        MSIRECORD *rec = MSI_CreateRecord(1);
+        DWORD size = 0;
+
+        MSI_RecordSetStringW(rec,0,ptr);
+        MSI_FormatRecordW(package,rec,NULL,&size);
+        if (size >= 0)
+        {
+            size++;
+            *data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
+            if (size > 1)
+                MSI_FormatRecordW(package,rec,*data,&size);
+            else
+                *data[0] = 0;
+            msiobj_release( &rec->hdr );
+            return sizeof(WCHAR)*size;
+        }
+        msiobj_release( &rec->hdr );
+    }
+
+    *data = NULL;
+    return 0;
+}
+
+/* Called when the package is being closed */
+void ACTION_free_package_structures( MSIPACKAGE* package)
+{
+    INT i;
+    
+    TRACE("Freeing package action data\n");
+
+    remove_tracked_tempfiles(package);
+
+    /* No dynamic buffers in features */
+    if (package->features && package->loaded_features > 0)
+        HeapFree(GetProcessHeap(),0,package->features);
+
+    for (i = 0; i < package->loaded_folders; i++)
+    {
+        HeapFree(GetProcessHeap(),0,package->folders[i].Directory);
+        HeapFree(GetProcessHeap(),0,package->folders[i].TargetDefault);
+        HeapFree(GetProcessHeap(),0,package->folders[i].SourceDefault);
+        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
+        HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedSource);
+        HeapFree(GetProcessHeap(),0,package->folders[i].Property);
+    }
+    if (package->folders && package->loaded_folders > 0)
+        HeapFree(GetProcessHeap(),0,package->folders);
+
+    for (i = 0; i < package->loaded_components; i++)
+        HeapFree(GetProcessHeap(),0,package->components[i].FullKeypath);
+
+    if (package->components && package->loaded_components > 0)
+        HeapFree(GetProcessHeap(),0,package->components);
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        HeapFree(GetProcessHeap(),0,package->files[i].File);
+        HeapFree(GetProcessHeap(),0,package->files[i].FileName);
+        HeapFree(GetProcessHeap(),0,package->files[i].Version);
+        HeapFree(GetProcessHeap(),0,package->files[i].Language);
+        HeapFree(GetProcessHeap(),0,package->files[i].SourcePath);
+        HeapFree(GetProcessHeap(),0,package->files[i].TargetPath);
+    }
+
+    if (package->files && package->loaded_files > 0)
+        HeapFree(GetProcessHeap(),0,package->files);
+
+    for (i = 0; i < package->DeferredActionCount; i++)
+        HeapFree(GetProcessHeap(),0,package->DeferredAction[i]);
+    HeapFree(GetProcessHeap(),0,package->DeferredAction);
+
+    for (i = 0; i < package->CommitActionCount; i++)
+        HeapFree(GetProcessHeap(),0,package->CommitAction[i]);
+    HeapFree(GetProcessHeap(),0,package->CommitAction);
+
+    HeapFree(GetProcessHeap(),0,package->PackagePath);
+}
+
+static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )
+{
+    MSIRECORD * row;
+
+    row = MSI_CreateRecord(4);
+    MSI_RecordSetInteger(row,1,a);
+    MSI_RecordSetInteger(row,2,b);
+    MSI_RecordSetInteger(row,3,c);
+    MSI_RecordSetInteger(row,4,d);
+    MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
+    msiobj_release(&row->hdr);
+
+    msi_dialog_check_messages(package->dialog, NULL);
+}
+
+static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
+{
+    static const WCHAR Query_t[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'A','c','t','i','o', 'n','T','e','x','t',' ','W','H','E','R','E',' ',
+         'A','c','t','i','o','n',' ','=', ' ','\'','%','s','\'',0};
+    WCHAR message[1024];
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    DWORD size;
+
+    if (!package->LastAction || strcmpW(package->LastAction,action))
+    {
+        rc = MSI_OpenQuery(package->db, &view, Query_t, action);
+        if (rc != ERROR_SUCCESS)
+            return;
+
+        rc = MSI_ViewExecute(view, 0);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            return;
+        }
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            return;
+        }
+
+        if (MSI_RecordIsNull(row,3))
+        {
+            msiobj_release(&row->hdr);
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return;
+        }
+
+        /* update the cached actionformat */
+        HeapFree(GetProcessHeap(),0,package->ActionFormat);
+        package->ActionFormat = load_dynamic_stringW(row,3);
+
+        HeapFree(GetProcessHeap(),0,package->LastAction);
+        package->LastAction = dupstrW(action);
+
+        msiobj_release(&row->hdr);
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    MSI_RecordSetStringW(record,0,package->ActionFormat);
+    size = 1024;
+    MSI_FormatRecordW(package,record,message,&size);
+
+    row = MSI_CreateRecord(1);
+    MSI_RecordSetStringW(row,1,message);
+    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);
+    msiobj_release(&row->hdr);
+}
+
+
+static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)
+{
+    static const WCHAR template_s[]=
+        {'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ', '%','s',
+         '.',0};
+    static const WCHAR format[] = 
+        {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
+    static const WCHAR Query_t[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'A','c','t','i','o', 'n','T','e','x','t',' ','W','H','E','R','E', ' ',
+         'A','c','t','i','o','n',' ','=', ' ','\'','%','s','\'',0};
+    WCHAR message[1024];
+    WCHAR timet[0x100];
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    WCHAR *ActionText=NULL;
+
+    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
+
+    rc = MSI_OpenQuery(package->db, &view, Query_t, action);
+    if (rc != ERROR_SUCCESS)
+        return;
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return;
+    }
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return;
+    }
+
+    ActionText = load_dynamic_stringW(row,2);
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    sprintfW(message,template_s,timet,action,ActionText);
+
+    row = MSI_CreateRecord(1);
+    MSI_RecordSetStringW(row,1,message);
+    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row);
+    msiobj_release(&row->hdr);
+    HeapFree(GetProcessHeap(),0,ActionText);
+}
+
+static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, 
+                          UINT rc)
+{
+    MSIRECORD * row;
+    static const WCHAR template_s[]=
+        {'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ',
+         '%','s', '.',0};
+    static const WCHAR template_e[]=
+        {'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ',
+         '%','s', '.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ',
+         '%','i','.',0};
+    static const WCHAR format[] = 
+        {'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
+    WCHAR message[1024];
+    WCHAR timet[0x100];
+
+    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
+    if (start)
+        sprintfW(message,template_s,timet,action);
+    else
+        sprintfW(message,template_e,timet,action,rc);
+    
+    row = MSI_CreateRecord(1);
+    MSI_RecordSetStringW(row,1,message);
+    MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
+    msiobj_release(&row->hdr);
+}
+
+/*
+ *  build_directory_name()
+ *
+ *  This function is to save messing round with directory names
+ *  It handles adding backslashes between path segments, 
+ *   and can add \ at the end of the directory name if told to.
+ *
+ *  It takes a variable number of arguments.
+ *  It always allocates a new string for the result, so make sure
+ *   to free the return value when finished with it.
+ *
+ *  The first arg is the number of path segments that follow.
+ *  The arguments following count are a list of path segments.
+ *  A path segment may be NULL.
+ *
+ *  Path segments will be added with a \ separating them.
+ *  A \ will not be added after the last segment, however if the
+ *    last segment is NULL, then the last character will be a \
+ * 
+ */
+static LPWSTR build_directory_name(DWORD count, ...)
+{
+    DWORD sz = 1, i;
+    LPWSTR dir;
+    va_list va;
+
+    va_start(va,count);
+    for(i=0; i<count; i++)
+    {
+        LPCWSTR str = va_arg(va,LPCWSTR);
+        if (str)
+            sz += strlenW(str) + 1;
+    }
+    va_end(va);
+
+    dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
+    dir[0]=0;
+
+    va_start(va,count);
+    for(i=0; i<count; i++)
+    {
+        LPCWSTR str = va_arg(va,LPCWSTR);
+        if (!str)
+            continue;
+        strcatW(dir, str);
+        if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
+            strcatW(dir, cszbs);
+    }
+    return dir;
+}
+
+static BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, INT index, 
+                                            INSTALLSTATE check )
+{
+    if (package->components[index].Installed == check)
+        return FALSE;
+
+    if (package->components[index].ActionRequest == check)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+static BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE* package, INT index, 
+                                            INSTALLSTATE check )
+{
+    if (package->features[index].Installed == check)
+        return FALSE;
+
+    if (package->features[index].ActionRequest == check)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+/****************************************************
+ * TOP level entry points 
+ *****************************************************/
+
+UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
+                              LPCWSTR szCommandLine)
+{
+    DWORD sz;
+    WCHAR buffer[10];
+    UINT rc;
+    static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
+    static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
+    static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
+
+    MSI_SetPropertyW(package, szAction, szInstall);
+    package->ExecuteSequenceRun = FALSE;
+
+    if (szPackagePath)   
+    {
+        LPWSTR p, check, path;
+        package->PackagePath = dupstrW(szPackagePath);
+        path = dupstrW(szPackagePath);
+        p = strrchrW(path,'\\');    
+        if (p)
+        {
+            p++;
+            *p=0;
+        }
+        else
+        {
+            HeapFree(GetProcessHeap(),0,path);
+            path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
+            GetCurrentDirectoryW(MAX_PATH,path);
+            strcatW(path,cszbs);
+        }
+
+        check = load_dynamic_property(package, cszSourceDir,NULL);
+        if (!check)
+            MSI_SetPropertyW(package, cszSourceDir, path);
+        else
+            HeapFree(GetProcessHeap(), 0, check);
+
+        HeapFree(GetProcessHeap(), 0, path);
+    }
+
+    if (szCommandLine)
+    {
+        LPWSTR ptr,ptr2;
+        ptr = (LPWSTR)szCommandLine;
+       
+        while (*ptr)
+        {
+            WCHAR *prop = NULL;
+            WCHAR *val = NULL;
+
+            TRACE("Looking at %s\n",debugstr_w(ptr));
+
+            ptr2 = strchrW(ptr,'=');
+            if (ptr2)
+            {
+                BOOL quote=FALSE;
+                DWORD len = 0;
+
+                while (*ptr == ' ') ptr++;
+                len = ptr2-ptr;
+                prop = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
+                strncpyW(prop,ptr,len);
+                prop[len]=0;
+                ptr2++;
+           
+                len = 0; 
+                ptr = ptr2; 
+                while (*ptr && (quote || (!quote && *ptr!=' ')))
+                {
+                    if (*ptr == '"')
+                        quote = !quote;
+                    ptr++;
+                    len++;
+                }
+               
+                if (*ptr2=='"')
+                {
+                    ptr2++;
+                    len -= 2;
+                }
+                val = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
+                strncpyW(val,ptr2,len);
+                val[len] = 0;
+
+                if (strlenW(prop) > 0)
+                {
+                    TRACE("Found commandline property (%s) = (%s)\n", 
+                                       debugstr_w(prop), debugstr_w(val));
+                    MSI_SetPropertyW(package,prop,val);
+                }
+                HeapFree(GetProcessHeap(),0,val);
+                HeapFree(GetProcessHeap(),0,prop);
+            }
+            ptr++;
+        }
+    }
+  
+    sz = 10; 
+    if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS)
+    {
+        if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)
+        {
+            rc = ACTION_ProcessUISequence(package);
+            if (rc == ERROR_SUCCESS)
+                rc = ACTION_ProcessExecSequence(package,TRUE);
+        }
+        else
+            rc = ACTION_ProcessExecSequence(package,FALSE);
+    }
+    else
+        rc = ACTION_ProcessExecSequence(package,FALSE);
+    
+    if (rc == -1)
+    {
+        /* install was halted but should be considered a success */
+        rc = ERROR_SUCCESS;
+    }
+
+    /* process the ending type action */
+    if (rc == ERROR_SUCCESS)
+        ACTION_PerformActionSequence(package,-1);
+    else if (rc == ERROR_INSTALL_USEREXIT) 
+        ACTION_PerformActionSequence(package,-2);
+    else if (rc == ERROR_FUNCTION_FAILED) 
+        ACTION_PerformActionSequence(package,-3);
+    else if (rc == ERROR_INSTALL_SUSPEND) 
+        ACTION_PerformActionSequence(package,-4);
+
+    /* finish up running custom actions */
+    ACTION_FinishCustomActions(package);
+    
+    return rc;
+}
+
+static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
+{
+    MSIQUERY * view;
+    UINT rc;
+    WCHAR buffer[0x100];
+    DWORD sz = 0x100;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'I','n','s','t','a','l','l','E','x','e','c','u','t','e',
+         'S','e','q','u','e','n','c','e',' ', 'W','H','E','R','E',' ',
+         'S','e','q','u','e','n','c','e',' ', '=',' ','%','i',0};
+
+    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
+
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            goto end;
+        }
+       
+        TRACE("Running the actions\n"); 
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            goto end;
+        }
+
+        /* check conditions */
+        if (!MSI_RecordIsNull(row,2))
+        {
+            LPWSTR cond = NULL;
+            cond = load_dynamic_stringW(row,2);
+
+            if (cond)
+            {
+                /* this is a hack to skip errors in the condition code */
+                if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
+                {
+                    HeapFree(GetProcessHeap(),0,cond);
+                    msiobj_release(&row->hdr);
+                    goto end;
+                }
+                else
+                    HeapFree(GetProcessHeap(),0,cond);
+            }
+        }
+
+        sz=0x100;
+        rc =  MSI_RecordGetStringW(row,1,buffer,&sz);
+        if (rc != ERROR_SUCCESS)
+        {
+            ERR("Error is %x\n",rc);
+            msiobj_release(&row->hdr);
+            goto end;
+        }
+
+        rc = ACTION_PerformAction(package,buffer);
+        msiobj_release(&row->hdr);
+end:
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+    else
+        rc = ERROR_SUCCESS;
+
+    return rc;
+}
+
+static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)
+{
+    MSIQUERY * view;
+    UINT rc;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'I','n','s','t','a','l','l','E','x','e','c','u','t','e',
+         'S','e','q','u','e','n','c','e',' ', 'W','H','E','R','E',' ',
+         'S','e','q','u','e','n','c','e',' ', '>',' ','%','i',' ',
+         'O','R','D','E','R',' ', 'B','Y',' ',
+         'S','e','q','u','e','n','c','e',0 };
+    MSIRECORD * row = 0;
+    static const WCHAR IVQuery[] =
+        {'S','E','L','E','C','T',' ','S','e','q','u','e','n','c','e',' ',
+         'F','R','O','M',' ','I','n','s','t','a','l','l',
+         'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e',' ',
+         'W','H','E','R','E',' ','A','c','t','i','o','n',' ','=',' ','`',
+         'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`', 0};
+    INT seq = 0;
+
+
+    if (package->ExecuteSequenceRun)
+    {
+        TRACE("Execute Sequence already Run\n");
+        return ERROR_SUCCESS;
+    }
+
+    package->ExecuteSequenceRun = TRUE;
+    
+    /* get the sequence number */
+    if (UIran)
+    {
+        rc = MSI_DatabaseOpenViewW(package->db, IVQuery, &view);
+        if (rc != ERROR_SUCCESS)
+            return rc;
+        rc = MSI_ViewExecute(view, 0);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return rc;
+        }
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return rc;
+        }
+        seq = MSI_RecordGetInteger(row,1);
+        msiobj_release(&row->hdr);
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            goto end;
+        }
+       
+        TRACE("Running the actions\n"); 
+
+        while (1)
+        {
+            WCHAR buffer[0x100];
+            DWORD sz = 0x100;
+
+            rc = MSI_ViewFetch(view,&row);
+            if (rc != ERROR_SUCCESS)
+            {
+                rc = ERROR_SUCCESS;
+                break;
+            }
+
+            /* check conditions */
+            if (!MSI_RecordIsNull(row,2))
+            {
+                LPWSTR cond = NULL;
+                cond = load_dynamic_stringW(row,2);
+
+                if (cond)
+                {
+                    /* this is a hack to skip errors in the condition code */
+                    if (MSI_EvaluateConditionW(package, cond) ==
+                            MSICONDITION_FALSE)
+                    {
+                        HeapFree(GetProcessHeap(),0,cond);
+                        msiobj_release(&row->hdr);
+                        continue; 
+                    }
+                    else
+                        HeapFree(GetProcessHeap(),0,cond);
+                }
+            }
+
+            sz=0x100;
+            rc =  MSI_RecordGetStringW(row,1,buffer,&sz);
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Error is %x\n",rc);
+                msiobj_release(&row->hdr);
+                break;
+            }
+
+            rc = ACTION_PerformAction(package,buffer);
+
+            if (rc == ERROR_FUNCTION_NOT_CALLED)
+                rc = ERROR_SUCCESS;
+
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Execution halted due to error (%i)\n",rc);
+                msiobj_release(&row->hdr);
+                break;
+            }
+
+            msiobj_release(&row->hdr);
+        }
+
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+end:
+    return rc;
+}
+
+
+static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
+{
+    MSIQUERY * view;
+    UINT rc;
+    static const WCHAR ExecSeqQuery [] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e',
+         ' ','W','H','E','R','E',' ', 'S','e','q','u','e','n','c','e',' ',
+         '>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
+         'S','e','q','u','e','n','c','e',0};
+    
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            goto end;
+        }
+       
+        TRACE("Running the actions \n"); 
+
+        while (1)
+        {
+            WCHAR buffer[0x100];
+            DWORD sz = 0x100;
+            MSIRECORD * row = 0;
+
+            rc = MSI_ViewFetch(view,&row);
+            if (rc != ERROR_SUCCESS)
+            {
+                rc = ERROR_SUCCESS;
+                break;
+            }
+
+            /* check conditions */
+            if (!MSI_RecordIsNull(row,2))
+            {
+                LPWSTR cond = NULL;
+                cond = load_dynamic_stringW(row,2);
+
+                if (cond)
+                {
+                    /* this is a hack to skip errors in the condition code */
+                    if (MSI_EvaluateConditionW(package, cond) ==
+                            MSICONDITION_FALSE)
+                    {
+                        HeapFree(GetProcessHeap(),0,cond);
+                        msiobj_release(&row->hdr);
+                        continue; 
+                    }
+                    else
+                        HeapFree(GetProcessHeap(),0,cond);
+                }
+            }
+
+            sz=0x100;
+            rc =  MSI_RecordGetStringW(row,1,buffer,&sz);
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Error is %x\n",rc);
+                msiobj_release(&row->hdr);
+                break;
+            }
+
+            rc = ACTION_PerformUIAction(package,buffer);
+
+            if (rc == ERROR_FUNCTION_NOT_CALLED)
+                rc = ERROR_SUCCESS;
+
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Execution halted due to error (%i)\n",rc);
+                msiobj_release(&row->hdr);
+                break;
+            }
+
+            msiobj_release(&row->hdr);
+        }
+
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+end:
+    return rc;
+}
+
+/********************************************************
+ * ACTION helper functions and functions that perform the actions
+ *******************************************************/
+BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action, UINT* rc)
+{
+    BOOL ret = FALSE; 
+
+    int i;
+    i = 0;
+    while (StandardActions[i].action != NULL)
+    {
+        if (strcmpW(StandardActions[i].action, action)==0)
+        {
+            ui_actioninfo(package, action, TRUE, 0);
+            ui_actionstart(package, action);
+            if (StandardActions[i].handler)
+            {
+                *rc = StandardActions[i].handler(package);
+            }
+            else
+            {
+                FIXME("UNHANDLED Standard Action %s\n",debugstr_w(action));
+                *rc = ERROR_SUCCESS;
+            }
+            ui_actioninfo(package, action, FALSE, *rc);
+            ret = TRUE;
+            break;
+        }
+        i++;
+    }
+    return ret;
+}
+
+BOOL ACTION_HandleDialogBox(MSIPACKAGE *package, LPCWSTR dialog, UINT* rc)
+{
+    BOOL ret = FALSE;
+
+    /*
+     * for the UI when we get that working
+     *
+    if (ACTION_DialogBox(package,dialog) == ERROR_SUCCESS)
+    {
+        *rc = package->CurrentInstallState;
+        ret = TRUE;
+    }
+    */
+    return ret;
+}
+
+BOOL ACTION_HandleCustomAction(MSIPACKAGE* package, LPCWSTR action, UINT* rc)
+{
+    BOOL ret=FALSE;
+    UINT arc;
+
+    arc = ACTION_CustomAction(package,action,FALSE);
+
+    if (arc != ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        *rc = arc;
+        ret = TRUE;
+    }
+    return ret;
+}
+
+/* 
+ * A lot of actions are really important even if they don't do anything
+ * explicit... Lots of properties are set at the beginning of the installation
+ * CostFinalize does a bunch of work to translate the directories and such
+ * 
+ * But until I get write access to the database that is hard, so I am going to
+ * hack it to see if I can get something to run.
+ */
+UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)
+{
+    UINT rc = ERROR_SUCCESS; 
+    BOOL handled;
+
+    TRACE("Performing action (%s)\n",debugstr_w(action));
+
+    handled = ACTION_HandleStandardAction(package, action, &rc);
+
+    if (!handled)
+        handled = ACTION_HandleCustomAction(package, action, &rc);
+
+    if (!handled)
+    {
+        FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+        rc = ERROR_FUNCTION_NOT_CALLED;
+    }
+
+    package->CurrentInstallState = rc;
+    return rc;
+}
+
+UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action)
+{
+    UINT rc = ERROR_SUCCESS;
+    BOOL handled = FALSE;
+
+    TRACE("Performing action (%s)\n",debugstr_w(action));
+
+    handled = ACTION_HandleStandardAction(package, action, &rc);
+
+    if (!handled)
+        handled = ACTION_HandleCustomAction(package, action, &rc);
+
+    if (!handled)
+        handled = ACTION_HandleDialogBox(package, action, &rc);
+
+    msi_dialog_check_messages( package->dialog, NULL );
+
+    if (!handled)
+    {
+        FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+        rc = ERROR_FUNCTION_NOT_CALLED;
+    }
+
+    package->CurrentInstallState = rc;
+    return rc;
+}
+
+/***********************************************************************
+ *            create_full_pathW
+ *
+ * Recursively create all directories in the path.
+ *
+ * shamelessly stolen from setupapi/queue.c
+ */
+static BOOL create_full_pathW(const WCHAR *path)
+{
+    BOOL ret = TRUE;
+    int len;
+    WCHAR *new_path;
+
+    new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) *
+                                              sizeof(WCHAR));
+
+    strcpyW(new_path, path);
+
+    while((len = strlenW(new_path)) && new_path[len - 1] == '\\')
+    new_path[len - 1] = 0;
+
+    while(!CreateDirectoryW(new_path, NULL))
+    {
+        WCHAR *slash;
+        DWORD last_error = GetLastError();
+        if(last_error == ERROR_ALREADY_EXISTS)
+            break;
+
+        if(last_error != ERROR_PATH_NOT_FOUND)
+        {
+            ret = FALSE;
+            break;
+        }
+
+        if(!(slash = strrchrW(new_path, '\\')))
+        {
+            ret = FALSE;
+            break;
+        }
+
+        len = slash - new_path;
+        new_path[len] = 0;
+        if(!create_full_pathW(new_path))
+        {
+            ret = FALSE;
+            break;
+        }
+        new_path[len] = '\\';
+    }
+
+    HeapFree(GetProcessHeap(), 0, new_path);
+    return ret;
+}
+
+/*
+ * Also we cannot enable/disable components either, so for now I am just going 
+ * to do all the directories for all the components.
+ */
+static UINT ACTION_CreateFolders(MSIPACKAGE *package)
+{
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','D','i','r','e','c','t','o','r','y','_',
+         ' ','F','R','O','M',' ',
+         'C','r','e','a','t','e','F','o','l','d','e','r',0 };
+    UINT rc;
+    MSIQUERY *view;
+    MSIFOLDER *folder;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+    
+    while (1)
+    {
+        WCHAR dir[0x100];
+        LPWSTR full_path;
+        DWORD sz;
+        MSIRECORD *row = NULL, *uirow;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz=0x100;
+        rc = MSI_RecordGetStringW(row,1,dir,&sz);
+
+        if (rc!= ERROR_SUCCESS)
+        {
+            ERR("Unable to get folder id \n");
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        sz = MAX_PATH;
+        full_path = resolve_folder(package,dir,FALSE,FALSE,&folder);
+        if (!full_path)
+        {
+            ERR("Unable to resolve folder id %s\n",debugstr_w(dir));
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        TRACE("Folder is %s\n",debugstr_w(full_path));
+
+        /* UI stuff */
+        uirow = MSI_CreateRecord(1);
+        MSI_RecordSetStringW(uirow,1,full_path);
+        ui_actiondata(package,szCreateFolders,uirow);
+        msiobj_release( &uirow->hdr );
+
+        if (folder->State == 0)
+            create_full_pathW(full_path);
+
+        folder->State = 3;
+
+        msiobj_release(&row->hdr);
+        HeapFree(GetProcessHeap(),0,full_path);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+   
+    return rc;
+}
+
+static int load_component(MSIPACKAGE* package, MSIRECORD * row)
+{
+    int index = package->loaded_components;
+    DWORD sz;
+
+    /* fill in the data */
+
+    package->loaded_components++;
+    if (package->loaded_components == 1)
+        package->components = HeapAlloc(GetProcessHeap(),0,
+                                        sizeof(MSICOMPONENT));
+    else
+        package->components = HeapReAlloc(GetProcessHeap(),0,
+            package->components, package->loaded_components * 
+            sizeof(MSICOMPONENT));
+
+    memset(&package->components[index],0,sizeof(MSICOMPONENT));
+
+    sz = 96;       
+    MSI_RecordGetStringW(row,1,package->components[index].Component,&sz);
+
+    TRACE("Loading Component %s\n",
+           debugstr_w(package->components[index].Component));
+
+    sz = 0x100;
+    if (!MSI_RecordIsNull(row,2))
+        MSI_RecordGetStringW(row,2,package->components[index].ComponentId,&sz);
+            
+    sz = 96;       
+    MSI_RecordGetStringW(row,3,package->components[index].Directory,&sz);
+
+    package->components[index].Attributes = MSI_RecordGetInteger(row,4);
+
+    sz = 0x100;       
+    MSI_RecordGetStringW(row,5,package->components[index].Condition,&sz);
+
+    sz = 96;       
+    MSI_RecordGetStringW(row,6,package->components[index].KeyPath,&sz);
+
+    package->components[index].Installed = INSTALLSTATE_UNKNOWN;
+    package->components[index].Action = INSTALLSTATE_UNKNOWN;
+    package->components[index].ActionRequest = INSTALLSTATE_UNKNOWN;
+
+    package->components[index].Enabled = TRUE;
+
+    return index;
+}
+
+static void load_feature(MSIPACKAGE* package, MSIRECORD * row)
+{
+    int index = package->loaded_features;
+    DWORD sz;
+    static const WCHAR Query1[] = 
+        {'S','E','L','E','C','T',' ','C','o','m','p','o','n','e','n','t','_',
+         ' ','F','R','O','M',' ','F','e','a','t','u','r','e',
+         'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ',
+         'F','e', 'a','t','u','r','e','_','=','\'','%','s','\'',0};
+    static const WCHAR Query2[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ', 
+         'C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ', 
+         'C','o','m','p','o','n','e','n','t','=','\'','%','s','\'',0};
+    MSIQUERY * view;
+    MSIQUERY * view2;
+    MSIRECORD * row2;
+    MSIRECORD * row3;
+    UINT    rc;
+
+    /* fill in the data */
+
+    package->loaded_features ++;
+    if (package->loaded_features == 1)
+        package->features = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFEATURE));
+    else
+        package->features = HeapReAlloc(GetProcessHeap(),0,package->features,
+                                package->loaded_features * sizeof(MSIFEATURE));
+
+    memset(&package->features[index],0,sizeof(MSIFEATURE));
+    
+    sz = 96;       
+    MSI_RecordGetStringW(row,1,package->features[index].Feature,&sz);
+
+    TRACE("Loading feature %s\n",debugstr_w(package->features[index].Feature));
+
+    sz = 96;
+    if (!MSI_RecordIsNull(row,2))
+        MSI_RecordGetStringW(row,2,package->features[index].Feature_Parent,&sz);
+
+    sz = 0x100;
+     if (!MSI_RecordIsNull(row,3))
+        MSI_RecordGetStringW(row,3,package->features[index].Title,&sz);
+
+     sz = 0x100;
+     if (!MSI_RecordIsNull(row,4))
+        MSI_RecordGetStringW(row,4,package->features[index].Description,&sz);
+
+    if (!MSI_RecordIsNull(row,5))
+        package->features[index].Display = MSI_RecordGetInteger(row,5);
+  
+    package->features[index].Level= MSI_RecordGetInteger(row,6);
+
+     sz = 96;
+     if (!MSI_RecordIsNull(row,7))
+        MSI_RecordGetStringW(row,7,package->features[index].Directory,&sz);
+
+    package->features[index].Attributes= MSI_RecordGetInteger(row,8);
+
+    package->features[index].Installed = INSTALLSTATE_UNKNOWN;
+    package->features[index].Action = INSTALLSTATE_UNKNOWN;
+    package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN;
+
+    /* load feature components */
+
+    rc = MSI_OpenQuery(package->db, &view, Query1, package->features[index].Feature);
+    if (rc != ERROR_SUCCESS)
+        return;
+    rc = MSI_ViewExecute(view,0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return;
+    }
+    while (1)
+    {
+        DWORD sz = 0x100;
+        WCHAR buffer[0x100];
+        DWORD rc;
+        INT c_indx;
+        INT cnt = package->features[index].ComponentCount;
+
+        rc = MSI_ViewFetch(view,&row2);
+        if (rc != ERROR_SUCCESS)
+            break;
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row2,1,buffer,&sz);
+
+        /* check to see if the component is already loaded */
+        c_indx = get_loaded_component(package,buffer);
+        if (c_indx != -1)
+        {
+            TRACE("Component %s already loaded at %i\n", debugstr_w(buffer),
+                  c_indx);
+            package->features[index].Components[cnt] = c_indx;
+            package->features[index].ComponentCount ++;
+            continue;
+        }
+
+        rc = MSI_OpenQuery(package->db, &view2, Query2, buffer);
+        if (rc != ERROR_SUCCESS)
+        {
+            msiobj_release( &row2->hdr );
+            continue;
+        }
+        rc = MSI_ViewExecute(view2,0);
+        if (rc != ERROR_SUCCESS)
+        {
+            msiobj_release( &row2->hdr );
+            MSI_ViewClose(view2);
+            msiobj_release( &view2->hdr );  
+            continue;
+        }
+        while (1)
+        {
+            DWORD rc;
+
+            rc = MSI_ViewFetch(view2,&row3);
+            if (rc != ERROR_SUCCESS)
+                break;
+            c_indx = load_component(package,row3);
+            msiobj_release( &row3->hdr );
+
+            package->features[index].Components[cnt] = c_indx;
+            package->features[index].ComponentCount ++;
+            TRACE("Loaded new component to index %i\n",c_indx);
+        }
+        MSI_ViewClose(view2);
+        msiobj_release( &view2->hdr );
+        msiobj_release( &row2->hdr );
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+}
+
+/*
+ * I am not doing any of the costing functionality yet. 
+ * Mostly looking at doing the Component and Feature loading
+ *
+ * The native MSI does A LOT of modification to tables here. Mostly adding
+ * a lot of temporary columns to the Feature and Component tables. 
+ *
+ *    note: Native msi also tracks the short filename. But I am only going to
+ *          track the long ones.  Also looking at this directory table
+ *          it appears that the directory table does not get the parents
+ *          resolved base on property only based on their entries in the 
+ *          directory table.
+ */
+static UINT ACTION_CostInitialize(MSIPACKAGE *package)
+{
+    MSIQUERY * view;
+    MSIRECORD * row;
+    UINT rc;
+    static const WCHAR Query_all[] =
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'F','e','a','t','u','r','e',0};
+    static const WCHAR szCosting[] =
+        {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
+    static const WCHAR szZero[] = { '0', 0 };
+
+    MSI_SetPropertyW(package, szCosting, szZero);
+    MSI_SetPropertyW(package, cszRootDrive , c_colon);
+
+    rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+    rc = MSI_ViewExecute(view,0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+    while (1)
+    {
+        DWORD rc;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+            break;
+       
+        load_feature(package,row); 
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT load_file(MSIPACKAGE* package, MSIRECORD * row)
+{
+    DWORD index = package->loaded_files;
+    DWORD i;
+    LPWSTR buffer;
+
+    /* fill in the data */
+
+    package->loaded_files++;
+    if (package->loaded_files== 1)
+        package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));
+    else
+        package->files = HeapReAlloc(GetProcessHeap(),0,
+            package->files , package->loaded_files * sizeof(MSIFILE));
+
+    memset(&package->files[index],0,sizeof(MSIFILE));
+    package->files[index].File = load_dynamic_stringW(row, 1);
+    buffer = load_dynamic_stringW(row, 2);
+
+    package->files[index].ComponentIndex = -1;
+    for (i = 0; i < package->loaded_components; i++)
+        if (strcmpW(package->components[i].Component,buffer)==0)
+        {
+            package->files[index].ComponentIndex = i;
+            break;
+        }
+    if (package->files[index].ComponentIndex == -1)
+        ERR("Unfound Component %s\n",debugstr_w(buffer));
+    HeapFree(GetProcessHeap(), 0, buffer);
+
+    package->files[index].FileName = load_dynamic_stringW(row,3);
+
+    reduce_to_longfilename(package->files[index].FileName);
+    
+    package->files[index].FileSize = MSI_RecordGetInteger(row,4);
+    package->files[index].Version = load_dynamic_stringW(row, 5);
+    package->files[index].Language = load_dynamic_stringW(row, 6);
+    package->files[index].Attributes= MSI_RecordGetInteger(row,7);
+    package->files[index].Sequence= MSI_RecordGetInteger(row,8);
+
+    package->files[index].Temporary = FALSE;
+    package->files[index].State = 0;
+
+    TRACE("File Loaded (%s)\n",debugstr_w(package->files[index].File));  
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_FileCost(MSIPACKAGE *package)
+{
+    MSIQUERY * view;
+    MSIRECORD * row;
+    UINT rc;
+    static const WCHAR Query[] =
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'F','i','l','e',' ', 'O','R','D','E','R',' ','B','Y',' ',
+         'S','e','q','u','e','n','c','e', 0};
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+   
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return ERROR_SUCCESS;
+    }
+
+    while (1)
+    {
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+        load_file(package,row);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    return ERROR_SUCCESS;
+}
+
+static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
+{
+    static const WCHAR Query[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'D','i','r','e','c', 't','o','r','y',' ','W','H','E','R','E',' ','`',
+         'D','i','r','e','c','t', 'o','r','y','`',' ','=',' ','`','%','s','`',
+         0};
+    UINT rc;
+    MSIQUERY * view;
+    LPWSTR ptargetdir, targetdir, parent, srcdir;
+    MSIRECORD * row = 0;
+    INT index = -1;
+    DWORD i;
+
+    TRACE("Looking for dir %s\n",debugstr_w(dir));
+
+    for (i = 0; i < package->loaded_folders; i++)
+    {
+        if (strcmpW(package->folders[i].Directory,dir)==0)
+        {
+            TRACE(" %s retuning on index %lu\n",debugstr_w(dir),i);
+            return i;
+        }
+    }
+
+    TRACE("Working to load %s\n",debugstr_w(dir));
+
+    index = package->loaded_folders++;
+    if (package->loaded_folders==1)
+        package->folders = HeapAlloc(GetProcessHeap(),0,
+                                        sizeof(MSIFOLDER));
+    else
+        package->folders= HeapReAlloc(GetProcessHeap(),0,
+            package->folders, package->loaded_folders* 
+            sizeof(MSIFOLDER));
+
+    memset(&package->folders[index],0,sizeof(MSIFOLDER));
+
+    package->folders[index].Directory = dupstrW(dir);
+
+    rc = MSI_OpenQuery(package->db, &view, Query, dir);
+    if (rc != ERROR_SUCCESS)
+        return -1;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return -1;
+    }
+
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return -1;
+    }
+
+    ptargetdir = targetdir = load_dynamic_stringW(row,3);
+
+    /* split src and target dir */
+    if (strchrW(targetdir,':'))
+    {
+        srcdir=strchrW(targetdir,':');
+        *srcdir=0;
+        srcdir ++;
+    }
+    else
+        srcdir=NULL;
+
+    /* for now only pick long filename versions */
+    if (strchrW(targetdir,'|'))
+    {
+        targetdir = strchrW(targetdir,'|'); 
+        *targetdir = 0;
+        targetdir ++;
+    }
+    if (srcdir && strchrW(srcdir,'|'))
+    {
+        srcdir= strchrW(srcdir,'|'); 
+        *srcdir= 0;
+        srcdir ++;
+    }
+
+    /* now check for root dirs */
+    if (targetdir[0] == '.' && targetdir[1] == 0)
+        targetdir = NULL;
+        
+    if (srcdir && srcdir[0] == '.' && srcdir[1] == 0)
+        srcdir = NULL;
+
+    if (targetdir)
+    {
+        TRACE("   TargetDefault = %s\n",debugstr_w(targetdir));
+        HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault);
+        package->folders[index].TargetDefault = dupstrW(targetdir);
+    }
+
+    if (srcdir)
+       package->folders[index].SourceDefault = dupstrW(srcdir);
+    else if (targetdir)
+        package->folders[index].SourceDefault = dupstrW(targetdir);
+    HeapFree(GetProcessHeap(), 0, ptargetdir);
+
+    parent = load_dynamic_stringW(row,2);
+    if (parent) 
+    {
+        i = load_folder(package,parent);
+        package->folders[index].ParentIndex = i;
+        TRACE("Parent is index %i... %s %s\n",
+                    package->folders[index].ParentIndex,
+        debugstr_w(package->folders[package->folders[index].ParentIndex].Directory),
+                    debugstr_w(parent));
+    }
+    else
+        package->folders[index].ParentIndex = -2;
+    HeapFree(GetProcessHeap(), 0, parent);
+
+    package->folders[index].Property = load_dynamic_property(package, dir,NULL);
+
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    TRACE(" %s retuning on index %i\n",debugstr_w(dir),index);
+    return index;
+}
+
+
+LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
+                      BOOL set_prop, MSIFOLDER **folder)
+{
+    DWORD i;
+    LPWSTR p, path = NULL;
+
+    TRACE("Working to resolve %s\n",debugstr_w(name));
+
+    /* special resolving for Target and Source root dir */
+    if (strcmpW(name,cszTargetDir)==0 || strcmpW(name,cszSourceDir)==0)
+    {
+        if (!source)
+        {
+            path = load_dynamic_property(package,cszTargetDir,NULL);
+            if (!path)
+            {
+                path = load_dynamic_property(package,cszRootDrive,NULL);
+                if (set_prop)
+                    MSI_SetPropertyW(package,cszTargetDir,path);
+            }
+            if (folder)
+            {
+                for (i = 0; i < package->loaded_folders; i++)
+                {
+                    if (strcmpW(package->folders[i].Directory,name)==0)
+                        break;
+                }
+                *folder = &(package->folders[i]);
+            }
+            return path;
+        }
+        else
+        {
+            path = load_dynamic_property(package,cszSourceDir,NULL);
+            if (!path)
+            {
+                path = load_dynamic_property(package,cszDatabase,NULL);
+                if (path)
+                {
+                    p = strrchrW(path,'\\');
+                    if (p)
+                        *(p+1) = 0;
+                }
+            }
+            if (folder)
+            {
+                for (i = 0; i < package->loaded_folders; i++)
+                {
+                    if (strcmpW(package->folders[i].Directory,name)==0)
+                        break;
+                }
+                *folder = &(package->folders[i]);
+            }
+            return path;
+        }
+    }
+
+    for (i = 0; i < package->loaded_folders; i++)
+    {
+        if (strcmpW(package->folders[i].Directory,name)==0)
+            break;
+    }
+
+    if (i >= package->loaded_folders)
+        return NULL;
+
+    if (folder)
+        *folder = &(package->folders[i]);
+
+    if (!source && package->folders[i].ResolvedTarget)
+    {
+        path = dupstrW(package->folders[i].ResolvedTarget);
+        TRACE("   already resolved to %s\n",debugstr_w(path));
+        return path;
+    }
+    else if (source && package->folders[i].ResolvedSource)
+    {
+        path = dupstrW(package->folders[i].ResolvedSource);
+        return path;
+    }
+    else if (!source && package->folders[i].Property)
+    {
+        path = build_directory_name(2, package->folders[i].Property, NULL);
+                    
+        TRACE("   internally set to %s\n",debugstr_w(path));
+        if (set_prop)
+            MSI_SetPropertyW(package,name,path);
+        return path;
+    }
+
+    if (package->folders[i].ParentIndex >= 0)
+    {
+        LPWSTR parent = package->folders[package->folders[i].ParentIndex].Directory;
+
+        TRACE(" ! Parent is %s\n", debugstr_w(parent));
+
+        p = resolve_folder(package, parent, source, set_prop, NULL);
+        if (!source)
+        {
+            TRACE("   TargetDefault = %s\n",debugstr_w(package->folders[i].TargetDefault));
+            path = build_directory_name(3, p, package->folders[i].TargetDefault, NULL);
+            package->folders[i].ResolvedTarget = dupstrW(path);
+            TRACE("   resolved into %s\n",debugstr_w(path));
+            if (set_prop)
+                MSI_SetPropertyW(package,name,path);
+        }
+        else 
+        {
+            path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
+            package->folders[i].ResolvedSource = dupstrW(path);
+        }
+        HeapFree(GetProcessHeap(),0,p);
+    }
+    return path;
+}
+
+/* scan for and update current install states */
+void ACTION_UpdateInstallStates(MSIPACKAGE *package)
+{
+    int i;
+    LPWSTR productcode;
+
+    productcode = load_dynamic_property(package,szProductCode,NULL);
+
+    for (i = 0; i < package->loaded_components; i++)
+    {
+        INSTALLSTATE res;
+        res = MsiGetComponentPathW(productcode, 
+                        package->components[i].ComponentId , NULL, NULL);
+        if (res < 0)
+            res = INSTALLSTATE_ABSENT;
+        package->components[i].Installed = res;
+    }
+
+    for (i = 0; i < package->loaded_features; i++)
+    {
+        INSTALLSTATE res = -10;
+        int j;
+        for (j = 0; j < package->features[i].ComponentCount; j++)
+        {
+            MSICOMPONENT* component = &package->components[package->features[i].
+                                                           Components[j]];
+            if (res == -10)
+                res = component->Installed;
+            else
+            {
+                if (res == component->Installed)
+                    continue;
+
+                if (res != component->Installed)
+                        res = INSTALLSTATE_INCOMPLETE;
+            }
+        }
+    }
+}
+
+/* update compoennt state based on a feature change */
+void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
+{
+    int i;
+    INSTALLSTATE newstate;
+    MSIFEATURE *feature;
+
+    i = get_loaded_feature(package,szFeature);
+    if (i < 0)
+        return;
+
+    feature = &package->features[i];
+    newstate = feature->ActionRequest;
+
+    for( i = 0; i < feature->ComponentCount; i++)
+    {
+        MSICOMPONENT* component = &package->components[feature->Components[i]];
+
+        if (!component->Enabled)
+            continue;
+        else
+        {
+            if (newstate == INSTALLSTATE_LOCAL)
+                component->ActionRequest = INSTALLSTATE_LOCAL;
+            else 
+            {
+                int j,k;
+
+                component->ActionRequest = newstate;
+
+                /*if any other feature wants is local we need to set it local*/
+                for (j = 0; 
+                     j < package->loaded_features &&
+                     component->ActionRequest != INSTALLSTATE_LOCAL; 
+                     j++)
+                {
+                    for (k = 0; k < package->features[j].ComponentCount; k++)
+                        if ( package->features[j].Components[k] ==
+                             feature->Components[i] )
+                        {
+                            if (package->features[j].ActionRequest == 
+                                INSTALLSTATE_LOCAL)
+                                component->ActionRequest = INSTALLSTATE_LOCAL;
+                            break;
+                        }
+                }
+            }
+        }
+    } 
+}
+
+static BOOL process_state_property (MSIPACKAGE* package, LPCWSTR property, 
+                                    INSTALLSTATE state)
+{
+    static const WCHAR all[]={'A','L','L',0};
+    LPWSTR override = NULL;
+    INT i;
+    BOOL rc = FALSE;
+
+    override = load_dynamic_property(package, property, NULL);
+    if (override)
+    {
+        rc = TRUE;
+        for(i = 0; i < package->loaded_features; i++)
+        {
+            if (strcmpiW(override,all)==0)
+            {
+                package->features[i].ActionRequest= state;
+                package->features[i].Action = state;
+            }
+            else
+            {
+                LPWSTR ptr = override;
+                LPWSTR ptr2 = strchrW(override,',');
+
+                while (ptr)
+                {
+                    if ((ptr2 && 
+                        strncmpW(ptr,package->features[i].Feature, ptr2-ptr)==0)
+                        || (!ptr2 &&
+                        strcmpW(ptr,package->features[i].Feature)==0))
+                    {
+                        package->features[i].ActionRequest= state;
+                        package->features[i].Action = state;
+                        break;
+                    }
+                    if (ptr2)
+                    {
+                        ptr=ptr2+1;
+                        ptr2 = strchrW(ptr,',');
+                    }
+                    else
+                        break;
+                }
+            }
+        }
+        HeapFree(GetProcessHeap(),0,override);
+    } 
+
+    return rc;
+}
+
+static UINT SetFeatureStates(MSIPACKAGE *package)
+{
+    LPWSTR level;
+    INT install_level;
+    DWORD i;
+    INT j;
+    static const WCHAR szlevel[] =
+        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
+    static const WCHAR szAddLocal[] =
+        {'A','D','D','L','O','C','A','L',0};
+    static const WCHAR szRemove[] =
+        {'R','E','M','O','V','E',0};
+    BOOL override = FALSE;
+
+    /* I do not know if this is where it should happen.. but */
+
+    TRACE("Checking Install Level\n");
+
+    level = load_dynamic_property(package,szlevel,NULL);
+    if (level)
+    {
+        install_level = atoiW(level);
+        HeapFree(GetProcessHeap(), 0, level);
+    }
+    else
+        install_level = 1;
+
+    /* ok hereis the _real_ rub
+     * all these activation/deactivation things happen in order and things
+     * later on the list override things earlier on the list.
+     * 1) INSTALLLEVEL processing
+     * 2) ADDLOCAL
+     * 3) REMOVE
+     * 4) ADDSOURCE
+     * 5) ADDDEFAULT
+     * 6) REINSTALL
+     * 7) COMPADDLOCAL
+     * 8) COMPADDSOURCE
+     * 9) FILEADDLOCAL
+     * 10) FILEADDSOURCE
+     * 11) FILEADDDEFAULT
+     * I have confirmed that if ADDLOCAL is stated then the INSTALLLEVEL is
+     * ignored for all the features. seems strange, especially since it is not
+     * documented anywhere, but it is how it works. 
+     *
+     * I am still ignoring a lot of these. But that is ok for now, ADDLOCAL and
+     * REMOVE are the big ones, since we don't handle administrative installs
+     * yet anyway.
+     */
+    override |= process_state_property(package,szAddLocal,INSTALLSTATE_LOCAL);
+    override |= process_state_property(package,szRemove,INSTALLSTATE_ABSENT);
+
+    if (!override)
+    {
+        for(i = 0; i < package->loaded_features; i++)
+        {
+            BOOL feature_state = ((package->features[i].Level > 0) &&
+                             (package->features[i].Level <= install_level));
+
+            if (feature_state)
+            {
+                package->features[i].ActionRequest = INSTALLSTATE_LOCAL;
+                package->features[i].Action = INSTALLSTATE_LOCAL;
+            }
+        }
+    }
+
+    /*
+     * now we want to enable or disable components base on feature 
+    */
+
+    for(i = 0; i < package->loaded_features; i++)
+    {
+        MSIFEATURE* feature = &package->features[i];
+        TRACE("Examining Feature %s (Installed %i, Action %i, Request %i)\n",
+            debugstr_w(feature->Feature), feature->Installed, feature->Action,
+            feature->ActionRequest);
+
+        for( j = 0; j < feature->ComponentCount; j++)
+        {
+            MSICOMPONENT* component = &package->components[
+                                                    feature->Components[j]];
+
+            if (!component->Enabled)
+            {
+                component->Action = INSTALLSTATE_UNKNOWN;
+                component->ActionRequest = INSTALLSTATE_UNKNOWN;
+            }
+            else
+            {
+                if (feature->Action == INSTALLSTATE_LOCAL)
+                {
+                    component->Action = INSTALLSTATE_LOCAL;
+                    component->ActionRequest = INSTALLSTATE_LOCAL;
+                }
+                else if (feature->ActionRequest == INSTALLSTATE_ABSENT)
+                {
+                    if (component->Action == INSTALLSTATE_UNKNOWN)
+                    {
+                        component->Action = INSTALLSTATE_ABSENT;
+                        component->ActionRequest = INSTALLSTATE_ABSENT;
+                    }
+                }
+            }
+        }
+    } 
+
+    for(i = 0; i < package->loaded_components; i++)
+    {
+        MSICOMPONENT* component= &package->components[i];
+
+        TRACE("Result: Component %s (Installed %i, Action %i, Request %i)\n",
+            debugstr_w(component->Component), component->Installed, 
+            component->Action, component->ActionRequest);
+    }
+
+
+    return ERROR_SUCCESS;
+}
+
+/* 
+ * A lot is done in this function aside from just the costing.
+ * The costing needs to be implemented at some point but for now I am going
+ * to focus on the directory building
+ *
+ */
+static UINT ACTION_CostFinalize(MSIPACKAGE *package)
+{
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'D','i','r','e','c','t','o','r','y',0};
+    static const WCHAR ConditionQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'C','o','n','d','i','t','i','o','n',0};
+    static const WCHAR szCosting[] =
+        {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
+    static const WCHAR szlevel[] =
+        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
+    static const WCHAR szOne[] = { '1', 0 };
+    UINT rc;
+    MSIQUERY * view;
+    DWORD i;
+    LPWSTR level;
+
+    TRACE("Building Directory properties\n");
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return rc;
+        }
+
+        while (1)
+        {
+            WCHAR name[0x100];
+            LPWSTR path;
+            MSIRECORD * row = 0;
+            DWORD sz;
+
+            rc = MSI_ViewFetch(view,&row);
+            if (rc != ERROR_SUCCESS)
+            {
+                rc = ERROR_SUCCESS;
+                break;
+            }
+
+            sz=0x100;
+            MSI_RecordGetStringW(row,1,name,&sz);
+
+            /* This helper function now does ALL the work */
+            TRACE("Dir %s ...\n",debugstr_w(name));
+            load_folder(package,name);
+            path = resolve_folder(package,name,FALSE,TRUE,NULL);
+            TRACE("resolves to %s\n",debugstr_w(path));
+            HeapFree( GetProcessHeap(), 0, path);
+
+            msiobj_release(&row->hdr);
+        }
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    TRACE("File calculations %i files\n",package->loaded_files);
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        MSICOMPONENT* comp = NULL;
+        MSIFILE* file= NULL;
+
+        file = &package->files[i];
+        if (file->ComponentIndex >= 0)
+            comp = &package->components[file->ComponentIndex];
+
+        if (file->Temporary == TRUE)
+            continue;
+
+        if (comp)
+        {
+            LPWSTR p;
+
+            /* calculate target */
+            p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
+
+            HeapFree(GetProcessHeap(),0,file->TargetPath);
+
+            TRACE("file %s is named %s\n",
+                   debugstr_w(file->File),debugstr_w(file->FileName));       
+
+            file->TargetPath = build_directory_name(2, p, file->FileName);
+
+            HeapFree(GetProcessHeap(),0,p);
+
+            TRACE("file %s resolves to %s\n",
+                   debugstr_w(file->File),debugstr_w(file->TargetPath));       
+
+            if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
+            {
+                file->State = 1;
+                comp->Cost += file->FileSize;
+            }
+            else
+            {
+                if (file->Version)
+                {
+                    DWORD handle;
+                    DWORD versize;
+                    UINT sz;
+                    LPVOID version;
+                    static const WCHAR name[] = 
+                        {'\\',0};
+                    static const WCHAR name_fmt[] = 
+                        {'%','u','.','%','u','.','%','u','.','%','u',0};
+                    WCHAR filever[0x100];
+                    VS_FIXEDFILEINFO *lpVer;
+
+                    TRACE("Version comparison.. \n");
+                    versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);
+                    version = HeapAlloc(GetProcessHeap(),0,versize);
+                    GetFileVersionInfoW(file->TargetPath, 0, versize, version);
+
+                    VerQueryValueW(version, name, (LPVOID*)&lpVer, &sz);
+
+                    sprintfW(filever,name_fmt,
+                        HIWORD(lpVer->dwFileVersionMS),
+                        LOWORD(lpVer->dwFileVersionMS),
+                        HIWORD(lpVer->dwFileVersionLS),
+                        LOWORD(lpVer->dwFileVersionLS));
+
+                    TRACE("new %s old %s\n", debugstr_w(file->Version),
+                          debugstr_w(filever));
+                    if (strcmpiW(filever,file->Version)<0)
+                    {
+                        file->State = 2;
+                        FIXME("cost should be diff in size\n");
+                        comp->Cost += file->FileSize;
+                    }
+                    else
+                        file->State = 3;
+                    HeapFree(GetProcessHeap(),0,version);
+                }
+                else
+                    file->State = 3;
+            }
+        } 
+    }
+
+    TRACE("Evaluating Condition Table\n");
+
+    rc = MSI_DatabaseOpenViewW(package->db, ConditionQuery, &view);
+    if (rc == ERROR_SUCCESS)
+    {
+        rc = MSI_ViewExecute(view, 0);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return rc;
+        }
+    
+        while (1)
+        {
+            WCHAR Feature[0x100];
+            MSIRECORD * row = 0;
+            DWORD sz;
+            int feature_index;
+
+            rc = MSI_ViewFetch(view,&row);
+
+            if (rc != ERROR_SUCCESS)
+            {
+                rc = ERROR_SUCCESS;
+                break;
+            }
+
+            sz = 0x100;
+            MSI_RecordGetStringW(row,1,Feature,&sz);
+
+            feature_index = get_loaded_feature(package,Feature);
+            if (feature_index < 0)
+                ERR("FAILED to find loaded feature %s\n",debugstr_w(Feature));
+            else
+            {
+                LPWSTR Condition;
+                Condition = load_dynamic_stringW(row,3);
+
+                if (MSI_EvaluateConditionW(package,Condition) == 
+                    MSICONDITION_TRUE)
+                {
+                    int level = MSI_RecordGetInteger(row,2);
+                    TRACE("Reseting feature %s to level %i\n",
+                           debugstr_w(Feature), level);
+                    package->features[feature_index].Level = level;
+                }
+                HeapFree(GetProcessHeap(),0,Condition);
+            }
+
+            msiobj_release(&row->hdr);
+        }
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+    TRACE("Enabling or Disabling Components\n");
+    for (i = 0; i < package->loaded_components; i++)
+    {
+        if (package->components[i].Condition[0])
+        {
+            if (MSI_EvaluateConditionW(package,
+                package->components[i].Condition) == MSICONDITION_FALSE)
+            {
+                TRACE("Disabling component %s\n",
+                      debugstr_w(package->components[i].Component));
+                package->components[i].Enabled = FALSE;
+            }
+        }
+    }
+
+    MSI_SetPropertyW(package,szCosting,szOne);
+    /* set default run level if not set */
+    level = load_dynamic_property(package,szlevel,NULL);
+    if (!level)
+        MSI_SetPropertyW(package,szlevel, szOne);
+    else
+        HeapFree(GetProcessHeap(),0,level);
+
+    ACTION_UpdateInstallStates(package);
+
+    return SetFeatureStates(package);
+}
+
+/*
+ * This is a helper function for handling embedded cabinet media
+ */
+static UINT writeout_cabinet_stream(MSIPACKAGE *package, WCHAR* stream_name,
+                                    WCHAR* source)
+{
+    UINT rc;
+    USHORT* data;
+    UINT    size;
+    DWORD   write;
+    HANDLE  the_file;
+    WCHAR tmp[MAX_PATH];
+
+    rc = read_raw_stream_data(package->db,stream_name,&data,&size); 
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    write = MAX_PATH;
+    if (MSI_GetPropertyW(package, cszTempFolder, tmp, &write))
+        GetTempPathW(MAX_PATH,tmp);
+
+    GetTempFileNameW(tmp,stream_name,0,source);
+
+    track_tempfile(package,strrchrW(source,'\\'), source);
+    the_file = CreateFileW(source, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                           FILE_ATTRIBUTE_NORMAL, NULL);
+
+    if (the_file == INVALID_HANDLE_VALUE)
+    {
+        rc = ERROR_FUNCTION_FAILED;
+        goto end;
+    }
+
+    WriteFile(the_file,data,size,&write,NULL);
+    CloseHandle(the_file);
+    TRACE("wrote %li bytes to %s\n",write,debugstr_w(source));
+end:
+    HeapFree(GetProcessHeap(),0,data);
+    return rc;
+}
+
+
+/* Support functions for FDI functions */
+typedef struct
+{
+    MSIPACKAGE* package;
+    LPCSTR cab_path;
+    LPCSTR file_name;
+} CabData;
+
+static void * cabinet_alloc(ULONG cb)
+{
+    return HeapAlloc(GetProcessHeap(), 0, cb);
+}
+
+static void cabinet_free(void *pv)
+{
+    HeapFree(GetProcessHeap(), 0, pv);
+}
+
+static INT_PTR cabinet_open(char *pszFile, int oflag, int pmode)
+{
+    DWORD dwAccess = 0;
+    DWORD dwShareMode = 0;
+    DWORD dwCreateDisposition = OPEN_EXISTING;
+    switch (oflag & _O_ACCMODE)
+    {
+    case _O_RDONLY:
+        dwAccess = GENERIC_READ;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
+        break;
+    case _O_WRONLY:
+        dwAccess = GENERIC_WRITE;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+        break;
+    case _O_RDWR:
+        dwAccess = GENERIC_READ | GENERIC_WRITE;
+        dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+        break;
+    }
+    if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
+        dwCreateDisposition = CREATE_NEW;
+    else if (oflag & _O_CREAT)
+        dwCreateDisposition = CREATE_ALWAYS;
+    return (INT_PTR)CreateFileA(pszFile, dwAccess, dwShareMode, NULL, 
+                                dwCreateDisposition, 0, NULL);
+}
+
+static UINT cabinet_read(INT_PTR hf, void *pv, UINT cb)
+{
+    DWORD dwRead;
+    if (ReadFile((HANDLE)hf, pv, cb, &dwRead, NULL))
+        return dwRead;
+    return 0;
+}
+
+static UINT cabinet_write(INT_PTR hf, void *pv, UINT cb)
+{
+    DWORD dwWritten;
+    if (WriteFile((HANDLE)hf, pv, cb, &dwWritten, NULL))
+        return dwWritten;
+    return 0;
+}
+
+static int cabinet_close(INT_PTR hf)
+{
+    return CloseHandle((HANDLE)hf) ? 0 : -1;
+}
+
+static long cabinet_seek(INT_PTR hf, long dist, int seektype)
+{
+    /* flags are compatible and so are passed straight through */
+    return SetFilePointer((HANDLE)hf, dist, NULL, seektype);
+}
+
+static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
+{
+    /* FIXME: try to do more processing in this function */
+    switch (fdint)
+    {
+    case fdintCOPY_FILE:
+    {
+        CabData *data = (CabData*) pfdin->pv;
+        ULONG len = strlen(data->cab_path) + strlen(pfdin->psz1);
+        char *file;
+
+        LPWSTR trackname;
+        LPWSTR trackpath;
+        LPWSTR tracknametmp;
+        static const WCHAR tmpprefix[] = {'C','A','B','T','M','P','_',0};
+       
+        if (data->file_name && strcmp(data->file_name,pfdin->psz1))
+                return 0;
+        
+        file = cabinet_alloc((len+1)*sizeof(char));
+        strcpy(file, data->cab_path);
+        strcat(file, pfdin->psz1);
+
+        TRACE("file: %s\n", debugstr_a(file));
+
+        /* track this file so it can be deleted if not installed */
+        trackpath=strdupAtoW(file);
+        tracknametmp=strdupAtoW(strrchr(file,'\\')+1);
+        trackname = HeapAlloc(GetProcessHeap(),0,(strlenW(tracknametmp) + 
+                                  strlenW(tmpprefix)+1) * sizeof(WCHAR));
+
+        strcpyW(trackname,tmpprefix);
+        strcatW(trackname,tracknametmp);
+
+        track_tempfile(data->package, trackname, trackpath);
+
+        HeapFree(GetProcessHeap(),0,trackpath);
+        HeapFree(GetProcessHeap(),0,trackname);
+        HeapFree(GetProcessHeap(),0,tracknametmp);
+
+        return cabinet_open(file, _O_WRONLY | _O_CREAT, 0);
+    }
+    case fdintCLOSE_FILE_INFO:
+    {
+        FILETIME ft;
+           FILETIME ftLocal;
+        if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
+            return -1;
+        if (!LocalFileTimeToFileTime(&ft, &ftLocal))
+            return -1;
+        if (!SetFileTime((HANDLE)pfdin->hf, &ftLocal, 0, &ftLocal))
+            return -1;
+
+        cabinet_close(pfdin->hf);
+        return 1;
+    }
+    default:
+        return 0;
+    }
+}
+
+/***********************************************************************
+ *            extract_cabinet_file
+ *
+ * Extract files from a cab file.
+ */
+static BOOL extract_a_cabinet_file(MSIPACKAGE* package, const WCHAR* source, 
+                                 const WCHAR* path, const WCHAR* file)
+{
+    HFDI hfdi;
+    ERF erf;
+    BOOL ret;
+    char *cabinet;
+    char *cab_path;
+    char *file_name;
+    CabData data;
+
+    TRACE("Extracting %s (%s) to %s\n",debugstr_w(source), 
+                    debugstr_w(file), debugstr_w(path));
+
+    hfdi = FDICreate(cabinet_alloc,
+                     cabinet_free,
+                     cabinet_open,
+                     cabinet_read,
+                     cabinet_write,
+                     cabinet_close,
+                     cabinet_seek,
+                     0,
+                     &erf);
+    if (!hfdi)
+    {
+        ERR("FDICreate failed\n");
+        return FALSE;
+    }
+
+    if (!(cabinet = strdupWtoA( source )))
+    {
+        FDIDestroy(hfdi);
+        return FALSE;
+    }
+    if (!(cab_path = strdupWtoA( path )))
+    {
+        FDIDestroy(hfdi);
+        HeapFree(GetProcessHeap(), 0, cabinet);
+        return FALSE;
+    }
+
+    data.package = package;
+    data.cab_path = cab_path;
+    if (file)
+        file_name = strdupWtoA(file);
+    else
+        file_name = NULL;
+    data.file_name = file_name;
+
+    ret = FDICopy(hfdi, cabinet, "", 0, cabinet_notify, NULL, &data);
+
+    if (!ret)
+        ERR("FDICopy failed\n");
+
+    FDIDestroy(hfdi);
+
+    HeapFree(GetProcessHeap(), 0, cabinet);
+    HeapFree(GetProcessHeap(), 0, cab_path);
+    HeapFree(GetProcessHeap(), 0, file_name);
+
+    return ret;
+}
+
+static UINT ready_media_for_file(MSIPACKAGE *package, UINT sequence, 
+                                 WCHAR* path, WCHAR* file)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static WCHAR source[MAX_PATH];
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'M','e','d','i','a',' ','W','H','E','R','E',' ',
+         'L','a','s','t','S','e','q','u','e','n','c','e',' ','>','=',' ','%',
+         'i',' ','O','R','D','E','R',' ','B','Y',' ',
+         'L','a','s','t','S','e','q','u','e','n','c','e',0};
+    WCHAR Query[1024];
+    WCHAR cab[0x100];
+    DWORD sz=0x100;
+    INT seq;
+    static UINT last_sequence = 0; 
+
+    if (sequence <= last_sequence)
+    {
+        TRACE("Media already ready (%u, %u)\n",sequence,last_sequence);
+        /*extract_a_cabinet_file(package, source,path,file); */
+        return ERROR_SUCCESS;
+    }
+
+    sprintfW(Query,ExecSeqQuery,sequence);
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+    seq = MSI_RecordGetInteger(row,2);
+    last_sequence = seq;
+
+    if (!MSI_RecordIsNull(row,4))
+    {
+        sz=0x100;
+        MSI_RecordGetStringW(row,4,cab,&sz);
+        TRACE("Source is CAB %s\n",debugstr_w(cab));
+        /* the stream does not contain the # character */
+        if (cab[0]=='#')
+        {
+            writeout_cabinet_stream(package,&cab[1],source);
+            strcpyW(path,source);
+            *(strrchrW(path,'\\')+1)=0;
+        }
+        else
+        {
+            sz = MAX_PATH;
+            if (MSI_GetPropertyW(package, cszSourceDir, source, &sz))
+            {
+                ERR("No Source dir defined \n");
+                rc = ERROR_FUNCTION_FAILED;
+            }
+            else
+            {
+                strcpyW(path,source);
+                strcatW(source,cab);
+                /* extract the cab file into a folder in the temp folder */
+                sz = MAX_PATH;
+                if (MSI_GetPropertyW(package, cszTempFolder,path, &sz) 
+                                    != ERROR_SUCCESS)
+                    GetTempPathW(MAX_PATH,path);
+            }
+        }
+        rc = !extract_a_cabinet_file(package, source,path,NULL);
+    }
+    else
+    {
+        sz = MAX_PATH;
+        MSI_GetPropertyW(package,cszSourceDir,source,&sz);
+        strcpyW(path,source);
+    }
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+inline static UINT create_component_directory ( MSIPACKAGE* package, INT component)
+{
+    UINT rc = ERROR_SUCCESS;
+    MSIFOLDER *folder;
+    LPWSTR install_path;
+
+    install_path = resolve_folder(package, package->components[component].Directory,
+                        FALSE, FALSE, &folder);
+    if (!install_path)
+        return ERROR_FUNCTION_FAILED; 
+
+    /* create the path */
+    if (folder->State == 0)
+    {
+        create_full_pathW(install_path);
+        folder->State = 2;
+    }
+    HeapFree(GetProcessHeap(), 0, install_path);
+
+    return rc;
+}
+
+static UINT ACTION_InstallFiles(MSIPACKAGE *package)
+{
+    UINT rc = ERROR_SUCCESS;
+    DWORD index;
+    MSIRECORD * uirow;
+    WCHAR uipath[MAX_PATH];
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    /* increment progress bar each time action data is sent */
+    ui_progress(package,1,1,0,0);
+
+    for (index = 0; index < package->loaded_files; index++)
+    {
+        WCHAR path_to_source[MAX_PATH];
+        MSIFILE *file;
+        
+        file = &package->files[index];
+
+        if (file->Temporary)
+            continue;
+
+
+        if (!ACTION_VerifyComponentForAction(package, file->ComponentIndex, 
+                                       INSTALLSTATE_LOCAL))
+        {
+            ui_progress(package,2,file->FileSize,0,0);
+            TRACE("File %s is not scheduled for install\n",
+                   debugstr_w(file->File));
+
+            continue;
+        }
+
+        if ((file->State == 1) || (file->State == 2))
+        {
+            LPWSTR p;
+            INT len;
+            MSICOMPONENT* comp = NULL;
+
+            TRACE("Installing %s\n",debugstr_w(file->File));
+            rc = ready_media_for_file(package,file->Sequence,path_to_source,
+                            file->File);
+            /* 
+             * WARNING!
+             * our file table could change here because a new temp file
+             * may have been created
+             */
+            file = &package->files[index];
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Unable to ready media\n");
+                rc = ERROR_FUNCTION_FAILED;
+                break;
+            }
+
+            create_component_directory( package, file->ComponentIndex);
+
+            /* recalculate file paths because things may have changed */
+
+            if (file->ComponentIndex >= 0)
+                comp = &package->components[file->ComponentIndex];
+
+            p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
+            HeapFree(GetProcessHeap(),0,file->TargetPath);
+
+            file->TargetPath = build_directory_name(2, p, file->FileName);
+
+            len = strlenW(path_to_source) + strlenW(file->File) + 2;
+            file->SourcePath = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+            strcpyW(file->SourcePath, path_to_source);
+            strcatW(file->SourcePath, file->File);
+
+            TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),
+                  debugstr_w(file->TargetPath));
+
+            /* the UI chunk */
+            uirow=MSI_CreateRecord(9);
+            MSI_RecordSetStringW(uirow,1,file->File);
+            strcpyW(uipath,file->TargetPath);
+            *(strrchrW(uipath,'\\')+1)=0;
+            MSI_RecordSetStringW(uirow,9,uipath);
+            MSI_RecordSetInteger(uirow,6,file->FileSize);
+            ui_actiondata(package,szInstallFiles,uirow);
+            msiobj_release( &uirow->hdr );
+            ui_progress(package,2,file->FileSize,0,0);
+
+            if (!MoveFileW(file->SourcePath,file->TargetPath))
+            {
+                rc = GetLastError();
+                ERR("Unable to move file (%s -> %s) (error %d)\n",
+                     debugstr_w(file->SourcePath), debugstr_w(file->TargetPath),
+                      rc);
+                if (rc == ERROR_ALREADY_EXISTS && file->State == 2)
+                {
+                    CopyFileW(file->SourcePath,file->TargetPath,FALSE);
+                    DeleteFileW(file->SourcePath);
+                    rc = 0;
+                }
+                else if (rc == ERROR_FILE_NOT_FOUND)
+                {
+                    ERR("Source File Not Found!  Continuing\n");
+                    rc = 0;
+                }
+                else
+                {
+                    ERR("Ignoring Error and continuing...\n");
+                    rc = 0;
+                }
+            }
+            else
+                file->State = 4;
+        }
+    }
+
+    return rc;
+}
+
+inline static UINT get_file_target(MSIPACKAGE *package, LPCWSTR file_key, 
+                                   LPWSTR* file_source)
+{
+    DWORD index;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    for (index = 0; index < package->loaded_files; index ++)
+    {
+        if (strcmpW(file_key,package->files[index].File)==0)
+        {
+            if (package->files[index].State >= 2)
+            {
+                *file_source = dupstrW(package->files[index].TargetPath);
+                return ERROR_SUCCESS;
+            }
+            else
+                return ERROR_FILE_NOT_FOUND;
+        }
+    }
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'D','u','p','l','i','c','a','t','e','F','i','l','e',0};
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        WCHAR file_key[0x100];
+        WCHAR *file_source = NULL;
+        WCHAR dest_name[0x100];
+        LPWSTR dest_path, dest;
+        WCHAR component[0x100];
+        INT component_index;
+
+        DWORD sz=0x100;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz=0x100;
+        rc = MSI_RecordGetStringW(row,2,component,&sz);
+        if (rc != ERROR_SUCCESS)
+        {
+            ERR("Unable to get component\n");
+            msiobj_release(&row->hdr);
+            break;
+        }
+
+        component_index = get_loaded_component(package,component);
+
+        if (!ACTION_VerifyComponentForAction(package, component_index, 
+                                       INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping copy due to disabled component\n");
+
+            /* the action taken was the same as the current install state */        
+            package->components[component_index].Action =
+                package->components[component_index].Installed;
+
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        package->components[component_index].Action = INSTALLSTATE_LOCAL;
+
+        sz=0x100;
+        rc = MSI_RecordGetStringW(row,3,file_key,&sz);
+        if (rc != ERROR_SUCCESS)
+        {
+            ERR("Unable to get file key\n");
+            msiobj_release(&row->hdr);
+            break;
+        }
+
+        rc = get_file_target(package,file_key,&file_source);
+
+        if (rc != ERROR_SUCCESS)
+        {
+            ERR("Original file unknown %s\n",debugstr_w(file_key));
+            msiobj_release(&row->hdr);
+            HeapFree(GetProcessHeap(),0,file_source);
+            continue;
+        }
+
+        if (MSI_RecordIsNull(row,4))
+        {
+            strcpyW(dest_name,strrchrW(file_source,'\\')+1);
+        }
+        else
+        {
+            sz=0x100;
+            MSI_RecordGetStringW(row,4,dest_name,&sz);
+            reduce_to_longfilename(dest_name);
+         }
+
+        if (MSI_RecordIsNull(row,5))
+        {
+            LPWSTR p;
+            dest_path = dupstrW(file_source);
+            p = strrchrW(dest_path,'\\');
+            if (p)
+                *p=0;
+        }
+        else
+        {
+            WCHAR destkey[0x100];
+            sz=0x100;
+            MSI_RecordGetStringW(row,5,destkey,&sz);
+            sz = 0x100;
+            dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL);
+            if (!dest_path)
+            {
+                ERR("Unable to get destination folder\n");
+                msiobj_release(&row->hdr);
+                HeapFree(GetProcessHeap(),0,file_source);
+                break;
+            }
+        }
+
+        dest = build_directory_name(2, dest_path, dest_name);
+           
+        TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),
+              debugstr_w(dest)); 
+        
+        if (strcmpW(file_source,dest))
+            rc = !CopyFileW(file_source,dest,TRUE);
+        else
+            rc = ERROR_SUCCESS;
+        
+        if (rc != ERROR_SUCCESS)
+            ERR("Failed to copy file %s -> %s, last error %ld\n", debugstr_w(file_source), debugstr_w(dest_path), GetLastError());
+
+        FIXME("We should track these duplicate files as well\n");   
+        msiobj_release(&row->hdr);
+        HeapFree(GetProcessHeap(),0,dest_path);
+        HeapFree(GetProcessHeap(),0,dest);
+        HeapFree(GetProcessHeap(),0,file_source);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+
+/* OK this value is "interpreted" and then formatted based on the 
+   first few characters */
+static LPSTR parse_value(MSIPACKAGE *package, WCHAR *value, DWORD *type, 
+                         DWORD *size)
+{
+    LPSTR data = NULL;
+    if (value[0]=='#' && value[1]!='#' && value[1]!='%')
+    {
+        if (value[1]=='x')
+        {
+            LPWSTR ptr;
+            CHAR byte[5];
+            LPWSTR deformated;
+            int count;
+
+            deformat_string(package, &value[2], &deformated);
+
+            /* binary value type */
+            ptr = deformated; 
+            *type=REG_BINARY;
+            *size = strlenW(ptr)/2;
+            data = HeapAlloc(GetProcessHeap(),0,*size);
+          
+            byte[0] = '0'; 
+            byte[1] = 'x'; 
+            byte[4] = 0; 
+            count = 0;
+            while (*ptr)
+            {
+                byte[2]= *ptr;
+                ptr++;
+                byte[3]= *ptr;
+                ptr++;
+                data[count] = (BYTE)strtol(byte,NULL,0);
+                count ++;
+            }
+            HeapFree(GetProcessHeap(),0,deformated);
+
+            TRACE("Data %li bytes(%i)\n",*size,count);
+        }
+        else
+        {
+            LPWSTR deformated;
+            LPWSTR p;
+            DWORD d = 0;
+            deformat_string(package, &value[1], &deformated);
+
+            *type=REG_DWORD; 
+            *size = sizeof(DWORD);
+            data = HeapAlloc(GetProcessHeap(),0,*size);
+            p = deformated;
+            if (*p == '-')
+                p++;
+            while (*p)
+            {
+                if ( (*p < '0') || (*p > '9') )
+                    break;
+                d *= 10;
+                d += (*p - '0');
+                p++;
+            }
+            if (deformated[0] == '-')
+                d = -d;
+            *(LPDWORD)data = d;
+            TRACE("DWORD %li\n",*(LPDWORD)data);
+
+            HeapFree(GetProcessHeap(),0,deformated);
+        }
+    }
+    else
+    {
+        static const WCHAR szMulti[] = {'[','~',']',0};
+        WCHAR *ptr;
+        *type=REG_SZ;
+
+        if (value[0]=='#')
+        {
+            if (value[1]=='%')
+            {
+                ptr = &value[2];
+                *type=REG_EXPAND_SZ;
+            }
+            else
+                ptr = &value[1];
+         }
+         else
+            ptr=value;
+
+        if (strstrW(value,szMulti))
+            *type = REG_MULTI_SZ;
+
+        *size = deformat_string(package, ptr,(LPWSTR*)&data);
+    }
+    return data;
+}
+
+static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'R','e','g','i','s','t','r','y',0 };
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    /* increment progress bar each time action data is sent */
+    ui_progress(package,1,REG_PROGRESS_VALUE,1,0);
+
+    while (1)
+    {
+        static const WCHAR szHCR[] = 
+            {'H','K','E','Y','_','C','L','A','S','S','E','S','_',
+             'R','O','O','T','\\',0};
+        static const WCHAR szHCU[] =
+            {'H','K','E','Y','_','C','U','R','R','E','N','T','_',
+             'U','S','E','R','\\',0};
+        static const WCHAR szHLM[] =
+            {'H','K','E','Y','_','L','O','C','A','L','_',
+             'M','A','C','H','I','N','E','\\',0};
+        static const WCHAR szHU[] =
+            {'H','K','E','Y','_','U','S','E','R','S','\\',0};
+
+        LPSTR value_data = NULL;
+        HKEY  root_key, hkey;
+        DWORD type,size;
+        LPWSTR value, key, name, component, deformated;
+        LPCWSTR szRoot;
+        INT component_index;
+        MSIRECORD * uirow;
+        LPWSTR uikey;
+        INT   root;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+        ui_progress(package,2,0,0,0);
+
+        value = NULL;
+        key = NULL;
+        uikey = NULL;
+        name = NULL;
+
+        component = load_dynamic_stringW(row, 6);
+        component_index = get_loaded_component(package,component);
+
+        if (!ACTION_VerifyComponentForAction(package, component_index, 
+                                       INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping write due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[component_index].Action =
+                package->components[component_index].Installed;
+
+            goto next;
+        }
+
+        package->components[component_index].Action = INSTALLSTATE_LOCAL;
+
+        name = load_dynamic_stringW(row, 4);
+        if( MSI_RecordIsNull(row,5) && name )
+        {
+            /* null values can have special meanings */
+            if (name[0]=='-' && name[1] == 0)
+            {
+                msiobj_release(&row->hdr);
+                goto next;
+            }
+            else if ((name[0]=='+' && name[1] == 0) || 
+                     (name[0] == '*' && name[1] == 0))
+            {
+                HeapFree(GetProcessHeap(),0,name);
+                name = NULL;
+            }
+        }
+
+        root = MSI_RecordGetInteger(row,2);
+        key = load_dynamic_stringW(row, 3);
+      
+   
+        /* get the root key */
+        switch (root)
+        {
+            case 0:  root_key = HKEY_CLASSES_ROOT; 
+                     szRoot = szHCR;
+                     break;
+            case 1:  root_key = HKEY_CURRENT_USER;
+                     szRoot = szHCU;
+                     break;
+            case 2:  root_key = HKEY_LOCAL_MACHINE;
+                     szRoot = szHLM;
+                     break;
+            case 3:  root_key = HKEY_USERS; 
+                     szRoot = szHU;
+                     break;
+            default:
+                 ERR("Unknown root %i\n",root);
+                 root_key=NULL;
+                 szRoot = NULL;
+                 break;
+        }
+        if (!root_key)
+        {
+            msiobj_release(&row->hdr);
+            goto next;
+        }
+
+        deformat_string(package, key , &deformated);
+        size = strlenW(deformated) + strlenW(szRoot) + 1;
+        uikey = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
+        strcpyW(uikey,szRoot);
+        strcatW(uikey,deformated);
+
+        if (RegCreateKeyW( root_key, deformated, &hkey))
+        {
+            ERR("Could not create key %s\n",debugstr_w(deformated));
+            msiobj_release(&row->hdr);
+            HeapFree(GetProcessHeap(),0,deformated);
+            goto next;
+        }
+        HeapFree(GetProcessHeap(),0,deformated);
+
+        value = load_dynamic_stringW(row,5);
+        if (value)
+            value_data = parse_value(package, value, &type, &size); 
+        else
+        {
+            value_data = NULL;
+            size = 0;
+            type = REG_SZ;
+        }
+
+        deformat_string(package, name, &deformated);
+
+        TRACE("Setting value %s\n",debugstr_w(deformated));
+        RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+
+        uirow = MSI_CreateRecord(3);
+        MSI_RecordSetStringW(uirow,2,deformated);
+        MSI_RecordSetStringW(uirow,1,uikey);
+
+        if (type == REG_SZ)
+            MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data);
+        else
+            MSI_RecordSetStringW(uirow,3,value);
+
+        ui_actiondata(package,szWriteRegistryValues,uirow);
+        msiobj_release( &uirow->hdr );
+
+        HeapFree(GetProcessHeap(),0,value_data);
+        HeapFree(GetProcessHeap(),0,value);
+        HeapFree(GetProcessHeap(),0,deformated);
+
+        msiobj_release(&row->hdr);
+        RegCloseKey(hkey);
+next:
+        HeapFree(GetProcessHeap(),0,uikey);
+        HeapFree(GetProcessHeap(),0,key);
+        HeapFree(GetProcessHeap(),0,name);
+        HeapFree(GetProcessHeap(),0,component);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
+{
+    return ERROR_SUCCESS;
+}
+
+
+static UINT ACTION_InstallValidate(MSIPACKAGE *package)
+{
+    DWORD progress = 0;
+    DWORD total = 0;
+    static const WCHAR q1[]=
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'R','e','g','i','s','t','r','y',0};
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    int i;
+
+    TRACE(" InstallValidate \n");
+
+    rc = MSI_DatabaseOpenViewW(package->db, q1, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+    while (1)
+    {
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+        progress +=1;
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    total = total + progress * REG_PROGRESS_VALUE;
+    total = total + package->loaded_components * COMPONENT_PROGRESS_VALUE;
+    for (i=0; i < package->loaded_files; i++)
+        total += package->files[i].FileSize;
+    ui_progress(package,0,total,0,0);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view = NULL;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n',0};
+    static const WCHAR title[]=
+        {'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0};
+
+    TRACE("Checking launch conditions\n");
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    rc = ERROR_SUCCESS;
+    while (rc == ERROR_SUCCESS)
+    {
+        LPWSTR cond = NULL; 
+        LPWSTR message = NULL;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        cond = load_dynamic_stringW(row,1);
+
+        if (MSI_EvaluateConditionW(package,cond) != MSICONDITION_TRUE)
+        {
+            LPWSTR deformated;
+            message = load_dynamic_stringW(row,2);
+            deformat_string(package,message,&deformated); 
+            MessageBoxW(NULL,deformated,title,MB_OK);
+            HeapFree(GetProcessHeap(),0,message);
+            HeapFree(GetProcessHeap(),0,deformated);
+            rc = ERROR_FUNCTION_FAILED;
+        }
+        HeapFree(GetProcessHeap(),0,cond);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static LPWSTR resolve_keypath( MSIPACKAGE* package, INT
+                            component_index)
+{
+    MSICOMPONENT* cmp = &package->components[component_index];
+
+    if (cmp->KeyPath[0]==0)
+    {
+        LPWSTR p = resolve_folder(package,cmp->Directory,FALSE,FALSE,NULL);
+        return p;
+    }
+    if (cmp->Attributes & msidbComponentAttributesRegistryKeyPath)
+    {
+        MSIQUERY * view;
+        MSIRECORD * row = 0;
+        UINT rc,root,len;
+        LPWSTR key,deformated,buffer,name,deformated_name;
+        static const WCHAR ExecSeqQuery[] =
+            {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+             'R','e','g','i','s','t','r','y',' ','W','H','E','R','E',' ',
+             'R','e','g','i','s','t','r','y',' ','=',' ' ,'`','%','s','`',0 };
+        static const WCHAR fmt[]={'%','0','2','i',':','\\','%','s','\\',0};
+        static const WCHAR fmt2[]=
+            {'%','0','2','i',':','\\','%','s','\\','%','s',0};
+
+        rc = MSI_OpenQuery(package->db,&view,ExecSeqQuery,cmp->KeyPath);
+
+        if (rc!=ERROR_SUCCESS)
+            return NULL;
+
+        rc = MSI_ViewExecute(view, 0);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return NULL;
+        }
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            MSI_ViewClose(view);
+            msiobj_release(&view->hdr);
+            return NULL;
+        }
+
+        root = MSI_RecordGetInteger(row,2);
+        key = load_dynamic_stringW(row, 3);
+        name = load_dynamic_stringW(row, 4);
+        deformat_string(package, key , &deformated);
+        deformat_string(package, name, &deformated_name);
+
+        len = strlenW(deformated) + 6;
+        if (deformated_name)
+            len+=strlenW(deformated_name);
+
+        buffer = HeapAlloc(GetProcessHeap(),0, len *sizeof(WCHAR));
+
+        if (deformated_name)
+            sprintfW(buffer,fmt2,root,deformated,deformated_name);
+        else
+            sprintfW(buffer,fmt,root,deformated);
+
+        HeapFree(GetProcessHeap(),0,key);
+        HeapFree(GetProcessHeap(),0,deformated);
+        HeapFree(GetProcessHeap(),0,name);
+        HeapFree(GetProcessHeap(),0,deformated_name);
+        msiobj_release(&row->hdr);
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+
+        return buffer;
+    }
+    else if (cmp->Attributes & msidbComponentAttributesODBCDataSource)
+    {
+        FIXME("UNIMPLEMENTED keypath as ODBC Source\n");
+        return NULL;
+    }
+    else
+    {
+        int j;
+        j = get_loaded_file(package,cmp->KeyPath);
+
+        if (j>=0)
+        {
+            LPWSTR p = dupstrW(package->files[j].TargetPath);
+            return p;
+        }
+    }
+    return NULL;
+}
+
+static HKEY openSharedDLLsKey()
+{
+    HKEY hkey=0;
+    static const WCHAR path[] =
+        {'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','h','a','r','e','d','D','L','L','s',0};
+
+    RegCreateKeyW(HKEY_LOCAL_MACHINE,path,&hkey);
+    return hkey;
+}
+
+static UINT ACTION_GetSharedDLLsCount(LPCWSTR dll)
+{
+    HKEY hkey;
+    DWORD count=0;
+    DWORD type;
+    DWORD sz = sizeof(count);
+    DWORD rc;
+    
+    hkey = openSharedDLLsKey();
+    rc = RegQueryValueExW(hkey, dll, NULL, &type, (LPBYTE)&count, &sz);
+    if (rc != ERROR_SUCCESS)
+        count = 0;
+    RegCloseKey(hkey);
+    return count;
+}
+
+static UINT ACTION_WriteSharedDLLsCount(LPCWSTR path, UINT count)
+{
+    HKEY hkey;
+
+    hkey = openSharedDLLsKey();
+    if (count > 0)
+        RegSetValueExW(hkey,path,0,REG_DWORD,
+                    (LPBYTE)&count,sizeof(count));
+    else
+        RegDeleteValueW(hkey,path);
+    RegCloseKey(hkey);
+    return count;
+}
+
+/*
+ * Return TRUE if the count should be written out and FALSE if not
+ */
+static void ACTION_RefCountComponent( MSIPACKAGE* package, UINT index)
+{
+    INT count = 0;
+    BOOL write = FALSE;
+    INT j;
+
+    /* only refcount DLLs */
+    if (package->components[index].KeyPath[0]==0 || 
+        package->components[index].Attributes & 
+            msidbComponentAttributesRegistryKeyPath || 
+        package->components[index].Attributes & 
+            msidbComponentAttributesODBCDataSource)
+        write = FALSE;
+    else
+    {
+        count = ACTION_GetSharedDLLsCount(package->components[index].
+                        FullKeypath);
+        write = (count > 0);
+
+        if (package->components[index].Attributes & 
+                    msidbComponentAttributesSharedDllRefCount)
+            write = TRUE;
+    }
+
+    /* increment counts */
+    for (j = 0; j < package->loaded_features; j++)
+    {
+        int i;
+
+        if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_LOCAL))
+            continue;
+
+        for (i = 0; i < package->features[j].ComponentCount; i++)
+        {
+            if (package->features[j].Components[i] == index)
+                count++;
+        }
+    }
+    /* decrement counts */
+    for (j = 0; j < package->loaded_features; j++)
+    {
+        int i;
+        if (!ACTION_VerifyFeatureForAction(package,j,INSTALLSTATE_ABSENT))
+            continue;
+
+        for (i = 0; i < package->features[j].ComponentCount; i++)
+        {
+            if (package->features[j].Components[i] == index)
+                count--;
+        }
+    }
+
+    /* ref count all the files in the component */
+    if (write)
+        for (j = 0; j < package->loaded_files; j++)
+        {
+            if (package->files[j].Temporary)
+                continue;
+            if (package->files[j].ComponentIndex == index)
+                ACTION_WriteSharedDLLsCount(package->files[j].TargetPath,count);
+        }
+    
+    /* add a count for permenent */
+    if (package->components[index].Attributes &
+                                msidbComponentAttributesPermanent)
+        count ++;
+    
+    package->components[index].RefCount = count;
+
+    if (write)
+        ACTION_WriteSharedDLLsCount(package->components[index].FullKeypath,
+            package->components[index].RefCount);
+}
+
+/*
+ * Ok further analysis makes me think that this work is
+ * actually done in the PublishComponents and PublishFeatures
+ * step, and not here.  It appears like the keypath and all that is
+ * resolved in this step, however actually written in the Publish steps.
+ * But we will leave it here for now because it is unclear
+ */
+static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
+{
+    LPWSTR productcode;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR squished_cc[GUID_SIZE];
+    UINT rc;
+    DWORD i;
+    HKEY hkey=0,hkey2=0;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    /* writes the Component and Features values to the registry */
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    rc = MSIREG_OpenComponents(&hkey);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+      
+    squash_guid(productcode,squished_pc);
+    ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);
+    for (i = 0; i < package->loaded_components; i++)
+    {
+        ui_progress(package,2,0,0,0);
+        if (package->components[i].ComponentId[0]!=0)
+        {
+            WCHAR *keypath = NULL;
+            MSIRECORD * uirow;
+
+            squash_guid(package->components[i].ComponentId,squished_cc);
+            rc = RegCreateKeyW(hkey,squished_cc,&hkey2);
+            if (rc != ERROR_SUCCESS)
+                continue;
+           
+            keypath = resolve_keypath(package,i);
+            package->components[i].FullKeypath = keypath;
+
+            /* do the refcounting */
+            ACTION_RefCountComponent( package, i);
+
+            TRACE("Component %s, Keypath=%s, RefCount=%i\n", 
+                            debugstr_w(package->components[i].Component), 
+                            debugstr_w(package->components[i].FullKeypath), 
+                            package->components[i].RefCount);
+            /*
+            * Write the keypath out if the component is to be registered
+            * and delete the key if the component is to be deregistered
+            */
+            if (ACTION_VerifyComponentForAction(package, i,
+                                    INSTALLSTATE_LOCAL))
+            {
+                if (keypath)
+                {
+                    RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPVOID)keypath,
+                                (strlenW(keypath)+1)*sizeof(WCHAR));
+
+                    if (package->components[i].Attributes & 
+                                msidbComponentAttributesPermanent)
+                    {
+                        static const WCHAR szPermKey[] =
+                            { '0','0','0','0','0','0','0','0','0','0','0','0',
+                              '0','0','0','0','0','0','0', '0','0','0','0','0',
+                              '0','0','0','0','0','0','0','0',0};
+
+                        RegSetValueExW(hkey2,szPermKey,0,REG_SZ,
+                                        (LPVOID)keypath,
+                                        (strlenW(keypath)+1)*sizeof(WCHAR));
+                    }
+                    
+                    RegCloseKey(hkey2);
+        
+                    /* UI stuff */
+                    uirow = MSI_CreateRecord(3);
+                    MSI_RecordSetStringW(uirow,1,productcode);
+                    MSI_RecordSetStringW(uirow,2,package->components[i].
+                                                            ComponentId);
+                    MSI_RecordSetStringW(uirow,3,keypath);
+                    ui_actiondata(package,szProcessComponents,uirow);
+                    msiobj_release( &uirow->hdr );
+               }
+            }
+            else if (ACTION_VerifyComponentForAction(package, i,
+                                    INSTALLSTATE_ABSENT))
+            {
+                DWORD res;
+                RegDeleteValueW(hkey2,squished_pc);
+
+                /* if the key is empty delete it */
+                res = RegEnumKeyExW(hkey2,0,NULL,0,0,NULL,0,NULL);
+                RegCloseKey(hkey2);
+                if (res == ERROR_NO_MORE_ITEMS)
+                    RegDeleteKeyW(hkey,squished_cc);
+        
+                /* UI stuff */
+                uirow = MSI_CreateRecord(2);
+                MSI_RecordSetStringW(uirow,1,productcode);
+                MSI_RecordSetStringW(uirow,2,package->components[i].
+                                ComponentId);
+                ui_actiondata(package,szProcessComponents,uirow);
+                msiobj_release( &uirow->hdr );
+            }
+        }
+    } 
+end:
+    HeapFree(GetProcessHeap(), 0, productcode);
+    RegCloseKey(hkey);
+    return rc;
+}
+
+static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
+{
+    /* 
+     * OK this is a bit confusing.. I am given a _Component key and I believe
+     * that the file that is being registered as a type library is the "key file
+     * of that component" which I interpret to mean "The file in the KeyPath of
+     * that component".
+     */
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR Query[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'T','y','p','e','L','i','b',0};
+    ITypeLib *ptLib;
+    HRESULT res;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {   
+        WCHAR component[0x100];
+        DWORD sz;
+        INT index;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row,3,component,&sz);
+
+        index = get_loaded_component(package,component);
+        if (index < 0)
+        {
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        if (!ACTION_VerifyComponentForAction(package, index,
+                                INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping typelib reg due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[index].Action =
+                package->components[index].Installed;
+
+            continue;
+        }
+
+        package->components[index].Action = INSTALLSTATE_LOCAL;
+
+        index = get_loaded_file(package,package->components[index].KeyPath); 
+   
+        if (index < 0)
+        {
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        res = LoadTypeLib(package->files[index].TargetPath,&ptLib);
+        if (SUCCEEDED(res))
+        {
+            LPWSTR help;
+            WCHAR helpid[0x100];
+
+            sz = 0x100;
+            MSI_RecordGetStringW(row,6,helpid,&sz);
+
+            help = resolve_folder(package,helpid,FALSE,FALSE,NULL);
+            res = RegisterTypeLib(ptLib,package->files[index].TargetPath,help);
+            HeapFree(GetProcessHeap(),0,help);
+
+            if (!SUCCEEDED(res))
+                ERR("Failed to register type library %s\n",
+                     debugstr_w(package->files[index].TargetPath));
+            else
+            {
+                /* Yes the row has more fields than I need, but #1 is 
+                   correct and the only one I need. Why make a new row? */
+
+                ui_actiondata(package,szRegisterTypeLibraries,row);
+                
+                TRACE("Registered %s\n",
+                       debugstr_w(package->files[index].TargetPath));
+            }
+
+            if (ptLib)
+                ITypeLib_Release(ptLib);
+        }
+        else
+            ERR("Failed to load type library %s\n",
+                debugstr_w(package->files[index].TargetPath));
+        
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+   
+}
+
+static UINT register_appid(MSIPACKAGE *package, LPCWSTR clsid, LPCWSTR app )
+{
+    static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'A','p','p','I' ,'d',' ','w','h','e','r','e',' ',
+         'A','p','p','I','d','=','`','%','s','`',0};
+    HKEY hkey2,hkey3;
+    LPWSTR buffer=0;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, clsid);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    RegCreateKeyW(HKEY_CLASSES_ROOT,szAppID,&hkey2);
+    RegCreateKeyW(hkey2,clsid,&hkey3);
+    RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)app,
+                   (strlenW(app)+1)*sizeof(WCHAR));
+
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    if (!MSI_RecordIsNull(row,2)) 
+    {
+        LPWSTR deformated=0;
+        UINT size; 
+        static const WCHAR szRemoteServerName[] =
+             {'R','e','m','o','t','e','S','e','r','v','e','r','N','a','m','e',
+              0};
+        buffer = load_dynamic_stringW(row,2);
+        size = deformat_string(package,buffer,&deformated);
+        RegSetValueExW(hkey3,szRemoteServerName,0,REG_SZ,(LPVOID)deformated,
+                       size);
+        HeapFree(GetProcessHeap(),0,deformated);
+        HeapFree(GetProcessHeap(),0,buffer);
+    }
+
+    if (!MSI_RecordIsNull(row,3)) 
+    {
+        static const WCHAR szLocalService[] =
+             {'L','o','c','a','l','S','e','r','v','i','c','e',0};
+        UINT size;
+        buffer = load_dynamic_stringW(row,3);
+        size = (strlenW(buffer)+1) * sizeof(WCHAR);
+        RegSetValueExW(hkey3,szLocalService,0,REG_SZ,(LPVOID)buffer,size);
+        HeapFree(GetProcessHeap(),0,buffer);
+    }
+
+    if (!MSI_RecordIsNull(row,4)) 
+    {
+        static const WCHAR szService[] =
+             {'S','e','r','v','i','c','e',
+              'P','a','r','a','m','e','t','e','r','s',0};
+        UINT size;
+        buffer = load_dynamic_stringW(row,4);
+        size = (strlenW(buffer)+1) * sizeof(WCHAR);
+        RegSetValueExW(hkey3,szService,0,REG_SZ,(LPVOID)buffer,size);
+        HeapFree(GetProcessHeap(),0,buffer);
+    }
+
+    if (!MSI_RecordIsNull(row,5)) 
+    {
+        static const WCHAR szDLL[] =
+             {'D','l','l','S','u','r','r','o','g','a','t','e',0};
+        UINT size;
+        buffer = load_dynamic_stringW(row,5);
+        size = (strlenW(buffer)+1) * sizeof(WCHAR);
+        RegSetValueExW(hkey3,szDLL,0,REG_SZ,(LPVOID)buffer,size);
+        HeapFree(GetProcessHeap(),0,buffer);
+    }
+
+    if (!MSI_RecordIsNull(row,6)) 
+    {
+        static const WCHAR szActivate[] =
+             {'A','c','t','i','v','a','t','e','A','s',
+              'S','t','o','r','a','g','e',0};
+        static const WCHAR szY[] = {'Y',0};
+
+        if (MSI_RecordGetInteger(row,6))
+            RegSetValueExW(hkey3,szActivate,0,REG_SZ,(LPVOID)szY,4);
+    }
+
+    if (!MSI_RecordIsNull(row,7)) 
+    {
+        static const WCHAR szRunAs[] = {'R','u','n','A','s',0};
+        static const WCHAR szUser[] = 
+             {'I','n','t','e','r','a','c','t','i','v','e',' ',
+              'U','s','e','r',0};
+
+        if (MSI_RecordGetInteger(row,7))
+            RegSetValueExW(hkey3,szRunAs,0,REG_SZ,(LPVOID)szUser,34);
+    }
+
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    RegCloseKey(hkey3);
+    RegCloseKey(hkey2);
+    return rc;
+}
+
+static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
+{
+    /* 
+     * Again I am assuming the words, "Whose key file represents" when referring
+     * to a Component as to meaning that Components KeyPath file
+     *
+     * Also there is a very strong connection between ClassInfo and ProgID
+     * that I am mostly glossing over.  
+     * What would be more propper is to load the ClassInfo and the ProgID info
+     * into memory data structures and then be able to enable and disable them
+     * based on component. 
+     */
+    
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'C','l','a','s','s',0};
+    static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
+    static const WCHAR szProgID[] = { 'P','r','o','g','I','D',0 };
+    static const WCHAR szAppID[] = { 'A','p','p','I','D',0 };
+    static const WCHAR szSpace[] = {' ',0};
+    HKEY hkey,hkey2,hkey3;
+    LPWSTR argument,deformated;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = RegCreateKeyW(HKEY_CLASSES_ROOT,szCLSID,&hkey);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_FUNCTION_FAILED;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+    {
+        rc = ERROR_SUCCESS;
+        goto end;
+    }
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        goto end;
+    }
+
+    while (1)
+    {
+        WCHAR clsid[0x100];
+        WCHAR buffer[0x100];
+        WCHAR desc[0x100];
+        DWORD sz;
+        INT index;
+        DWORD size;
+     
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz=0x100;
+        MSI_RecordGetStringW(row,3,buffer,&sz);
+
+        index = get_loaded_component(package,buffer);
+
+        if (index < 0)
+        {
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        if (!ACTION_VerifyComponentForAction(package, index,
+                                INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping class reg due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[index].Action =
+                package->components[index].Installed;
+
+            continue;
+        }
+
+        package->components[index].Action = INSTALLSTATE_LOCAL;
+
+        sz=0x100;
+        MSI_RecordGetStringW(row,1,clsid,&sz);
+        RegCreateKeyW(hkey,clsid,&hkey2);
+
+        if (!MSI_RecordIsNull(row,5))
+        {
+            sz=0x100;
+            MSI_RecordGetStringW(row,5,desc,&sz);
+
+            RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)desc,
+                           (strlenW(desc)+1)*sizeof(WCHAR));
+        }
+        else
+            desc[0]=0;
+
+        sz=0x100;
+        MSI_RecordGetStringW(row,2,buffer,&sz);
+
+        RegCreateKeyW(hkey2,buffer,&hkey3);
+
+        index = get_loaded_file(package,package->components[index].KeyPath);
+
+        argument = load_dynamic_stringW(row,11); 
+        size = deformat_string(package,argument,&deformated);
+        if (deformated)
+            size+=sizeof(WCHAR);
+        HeapFree(GetProcessHeap(),0,argument);
+        size += (strlenW(package->files[index].TargetPath))*sizeof(WCHAR);
+
+        argument = (LPWSTR)HeapAlloc(GetProcessHeap(),0,size+sizeof(WCHAR));
+        strcpyW(argument,package->files[index].TargetPath);
+        if (deformated)
+        {
+            strcatW(argument,szSpace);
+            strcatW(argument,deformated);
+        }
+
+        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);
+        HeapFree(GetProcessHeap(),0,deformated);
+        HeapFree(GetProcessHeap(),0,argument);
+
+        RegCloseKey(hkey3);
+
+        if (!MSI_RecordIsNull(row,4))
+        {
+            sz=0x100;
+            MSI_RecordGetStringW(row,4,buffer,&sz);
+
+            RegCreateKeyW(hkey2,szProgID,&hkey3);
+    
+            RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)buffer,
+                       (strlenW(buffer)+1)*sizeof(WCHAR));
+
+            RegCloseKey(hkey3);
+        }
+
+        if (!MSI_RecordIsNull(row,6))
+        { 
+            sz=0x100;
+            MSI_RecordGetStringW(row,6,buffer,&sz);
+
+            RegSetValueExW(hkey2,szAppID,0,REG_SZ,(LPVOID)buffer,
+                       (strlenW(buffer)+1)*sizeof(WCHAR));
+
+            register_appid(package,buffer,desc);
+        }
+
+
+        if (!MSI_RecordIsNull(row,7))
+        {
+            FIXME("Process field 7\n");
+        }
+
+        if (!MSI_RecordIsNull(row,8))
+        {
+            static const WCHAR szDefaultIcon[] = 
+                {'D','e','f','a','u','l','t','I','c','o','n',0};
+
+            LPWSTR FileName = load_dynamic_stringW(row,8);
+            LPWSTR FilePath;
+            INT index;
+
+            RegCreateKeyW(hkey2,szDefaultIcon,&hkey3);
+            build_icon_path(package,FileName,&FilePath);
+            if (!MSI_RecordIsNull(row,9))
+            {
+                static const WCHAR index_fmt[] = {',','%','i',0};
+                WCHAR index_buf[20];
+                index = MSI_RecordGetInteger(row,9);
+                sprintfW(index_buf,index_fmt,index);
+                size = strlenW(FilePath)+strlenW(index_buf)+1;
+                size *= sizeof(WCHAR);
+                HeapReAlloc(GetProcessHeap(),0,FilePath,size);
+            }
+            RegSetValueExW(hkey3,NULL,0,REG_SZ,(LPVOID)FilePath,
+                           (strlenW(FilePath)+1) * sizeof(WCHAR));
+            HeapFree(GetProcessHeap(),0,FilePath);
+            HeapFree(GetProcessHeap(),0,FileName);
+            RegCloseKey(hkey3);
+        }
+
+        if (!MSI_RecordIsNull(row,10))
+        {
+            static const WCHAR szInproc32[] =
+                {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',
+                 0};
+            static const WCHAR szInproc[] =
+                {'I','n','p','r','o','c','H','a','n','d','l','e','r',0};
+            INT i = MSI_RecordGetInteger(row,10);
+            if (i != MSI_NULL_INTEGER && i > 0 &&  i < 4)
+            {
+                static const WCHAR ole2[] = {'o','l','e','2','.','d','l','l',0};
+                static const WCHAR ole32[] =
+                    {'o','l','e','3','2','.','d','l','l',0};
+                switch(i)
+                {
+                    case 1:
+                        size = strlenW(ole2) * sizeof(WCHAR);
+                        RegCreateKeyW(hkey2,szInproc,&hkey3);
+                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole2, size);
+                        RegCloseKey(hkey3);
+                        break;
+                    case 2:
+                        size = strlenW(ole32) * sizeof(WCHAR);
+                        RegCreateKeyW(hkey2,szInproc32,&hkey3);
+                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole32,size);
+                        RegCloseKey(hkey3);
+                        break;
+                    case 3:
+                        size = strlenW(ole2) * sizeof(WCHAR);
+                        RegCreateKeyW(hkey2,szInproc,&hkey3);
+                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole2, size);
+                        RegCloseKey(hkey3);
+                        size = strlenW(ole32) * sizeof(WCHAR);
+                        RegCreateKeyW(hkey2,szInproc32,&hkey3);
+                        RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)ole32,size);
+                        RegCloseKey(hkey3);
+                        break;
+                }
+                
+            }
+            else
+            {
+                RegCreateKeyW(hkey2,szInproc32,&hkey3);
+                argument = load_dynamic_stringW(row,10);
+                reduce_to_longfilename(argument);
+                size = strlenW(argument)*sizeof(WCHAR);
+
+                RegSetValueExW(hkey3,NULL,0,REG_SZ, (LPVOID)argument, size);
+                HeapFree(GetProcessHeap(),0,argument);
+
+                RegCloseKey(hkey3);
+            }
+        }
+
+        RegCloseKey(hkey2);
+
+        ui_actiondata(package,szRegisterClassInfo,row);
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+end:
+    RegCloseKey(hkey);
+    return rc;
+}
+
+static UINT register_progid_base(MSIPACKAGE* package, MSIRECORD * row, 
+                                LPWSTR clsid)
+{
+    static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
+    static const WCHAR szDefaultIcon[] =
+        {'D','e','f','a','u','l','t','I','c','o','n',0};
+    HKEY hkey,hkey2;
+    WCHAR buffer[0x100];
+    DWORD sz;
+
+
+    sz = 0x100;
+    MSI_RecordGetStringW(row,1,buffer,&sz);
+    RegCreateKeyW(HKEY_CLASSES_ROOT,buffer,&hkey);
+
+    if (!MSI_RecordIsNull(row,4))
+    {
+        sz = 0x100;
+        MSI_RecordGetStringW(row,4,buffer,&sz);
+        RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)buffer, (strlenW(buffer)+1) *
+                       sizeof(WCHAR));
+    }
+
+    if (!MSI_RecordIsNull(row,3))
+    {   
+        sz = 0x100;
+    
+        MSI_RecordGetStringW(row,3,buffer,&sz);
+        RegCreateKeyW(hkey,szCLSID,&hkey2);
+        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)buffer, (strlenW(buffer)+1) *
+                       sizeof(WCHAR));
+
+        if (clsid)
+            strcpyW(clsid,buffer);
+
+        RegCloseKey(hkey2);
+    }
+    else
+    {
+        FIXME("UNHANDLED case, Parent progid but classid is NULL\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+    if (!MSI_RecordIsNull(row,5))
+    {
+        INT index = MSI_RecordGetInteger(row,6); 
+        LPWSTR FileName = load_dynamic_stringW(row,5);
+        LPWSTR FilePath,IconPath;
+        static const WCHAR fmt[] = {'%','s',',','%','i',0};
+
+        RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
+        build_icon_path(package,FileName,&FilePath);
+       
+        IconPath = HeapAlloc(GetProcessHeap(),0,(strlenW(FilePath)+5)*
+                    sizeof(WCHAR));
+
+        sprintfW(IconPath,fmt,FilePath,index);
+        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)IconPath,
+                           (strlenW(IconPath)+1) * sizeof(WCHAR));
+        HeapFree(GetProcessHeap(),0,FilePath);
+        HeapFree(GetProcessHeap(),0,FileName);
+        RegCloseKey(hkey2);
+    }
+    return ERROR_SUCCESS;
+}
+
+static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid);
+
+static UINT register_parent_progid(MSIPACKAGE *package, LPCWSTR parent, 
+                                   LPWSTR clsid)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR Query_t[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'P','r','o','g' ,'I','d',' ','W','H','E','R','E',' ',
+         'P','r','o','g','I','d',' ','=',' ','`' ,'%','s','`',0};
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_OpenQuery(package->db, &view, Query_t, parent);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    rc = MSI_ViewFetch(view,&row);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    register_progid(package,row,clsid);
+
+    msiobj_release(&row->hdr);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static UINT register_progid(MSIPACKAGE *package, MSIRECORD * row, LPWSTR clsid)
+{
+    UINT rc = ERROR_SUCCESS; 
+
+    if (MSI_RecordIsNull(row,2))
+        rc = register_progid_base(package,row,clsid);
+    else
+    {
+        WCHAR buffer[0x1000];
+        DWORD sz, disp;
+        HKEY hkey,hkey2;
+        static const WCHAR szCLSID[] = { 'C','L','S','I','D',0 };
+        static const WCHAR szDefaultIcon[] =
+            {'D','e','f','a','u','l','t','I','c','o','n',0};
+
+        /* check if already registered */
+        sz = 0x100;
+        MSI_RecordGetStringW(row,1,buffer,&sz);
+        RegCreateKeyExW(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0,
+                        KEY_ALL_ACCESS, NULL, &hkey, &disp );
+        if (disp == REG_OPENED_EXISTING_KEY)
+        {
+            TRACE("Key already registered\n");
+            RegCloseKey(hkey);
+            return rc;
+        }
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row,2,buffer,&sz);
+        rc = register_parent_progid(package,buffer,clsid);
+
+        /* clsid is same as parent */
+        RegCreateKeyW(hkey,szCLSID,&hkey2);
+        RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)clsid, (strlenW(clsid)+1) *
+                       sizeof(WCHAR));
+
+        RegCloseKey(hkey2);
+
+
+        if (!MSI_RecordIsNull(row,4))
+        {
+            sz = 0x100;
+            MSI_RecordGetStringW(row,4,buffer,&sz);
+            RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)buffer,
+                           (strlenW(buffer)+1) * sizeof(WCHAR));
+        }
+
+        if (!MSI_RecordIsNull(row,5))
+        {
+            LPWSTR FileName = load_dynamic_stringW(row,5);
+            LPWSTR FilePath;
+            RegCreateKeyW(hkey,szDefaultIcon,&hkey2);
+            build_icon_path(package,FileName,&FilePath);
+            RegSetValueExW(hkey2,NULL,0,REG_SZ,(LPVOID)FilePath,
+                           (strlenW(FilePath)+1) * sizeof(WCHAR));
+            HeapFree(GetProcessHeap(),0,FilePath);
+            HeapFree(GetProcessHeap(),0,FileName);
+            RegCloseKey(hkey2);
+        }
+
+        RegCloseKey(hkey);
+    }
+    return rc;
+}
+
+static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
+{
+    /* 
+     * Sigh, here I am just brute force registering all progids
+     * this needs to be linked to the Classes that have been registered
+     * but the easiest way to do that is to load all these stuff into
+     * memory for easy checking.
+     *
+     * Gives me something to continue to work toward.
+     */
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR Query[] =
+        {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+         'P','r','o','g','I','d',0};
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        WCHAR clsid[0x1000];
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+        
+        register_progid(package,row,clsid);
+        ui_actiondata(package,szRegisterProgIdInfo,row);
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name, 
+                            LPWSTR *FilePath)
+{
+    LPWSTR ProductCode;
+    LPWSTR SystemFolder;
+    LPWSTR dest;
+    UINT rc;
+
+    static const WCHAR szInstaller[] = 
+        {'I','n','s','t','a','l','l','e','r','\\',0};
+    static const WCHAR szFolder[] =
+        {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+
+    ProductCode = load_dynamic_property(package,szProductCode,&rc);
+    if (!ProductCode)
+        return rc;
+
+    SystemFolder = load_dynamic_property(package,szFolder,NULL);
+
+    dest = build_directory_name(3, SystemFolder, szInstaller, ProductCode);
+
+    create_full_pathW(dest);
+
+    *FilePath = build_directory_name(2, dest, icon_name);
+
+    HeapFree(GetProcessHeap(),0,SystemFolder);
+    HeapFree(GetProcessHeap(),0,ProductCode);
+    HeapFree(GetProcessHeap(),0,dest);
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR Query[] =
+        {'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ',
+         'S','h','o','r','t','c','u','t',0};
+    IShellLinkW *sl;
+    IPersistFile *pf;
+    HRESULT res;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    res = CoInitialize( NULL );
+    if (FAILED (res))
+    {
+        ERR("CoInitialize failed\n");
+        return ERROR_FUNCTION_FAILED;
+    }
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        LPWSTR target_file, target_folder;
+        WCHAR buffer[0x100];
+        DWORD sz;
+        DWORD index;
+        static const WCHAR szlnk[]={'.','l','n','k',0};
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+        
+        sz = 0x100;
+        MSI_RecordGetStringW(row,4,buffer,&sz);
+
+        index = get_loaded_component(package,buffer);
+
+        if (index < 0)
+        {
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        if (!ACTION_VerifyComponentForAction(package, index,
+                                INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping shortcut creation due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[index].Action =
+                package->components[index].Installed;
+
+            continue;
+        }
+
+        package->components[index].Action = INSTALLSTATE_LOCAL;
+
+        ui_actiondata(package,szCreateShortcuts,row);
+
+        res = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+                              &IID_IShellLinkW, (LPVOID *) &sl );
+
+        if (FAILED(res))
+        {
+            ERR("Is IID_IShellLink\n");
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        res = IShellLinkW_QueryInterface( sl, &IID_IPersistFile,(LPVOID*) &pf );
+        if( FAILED( res ) )
+        {
+            ERR("Is IID_IPersistFile\n");
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row,2,buffer,&sz);
+        target_folder = resolve_folder(package, buffer,FALSE,FALSE,NULL);
+
+        /* may be needed because of a bug somehwere else */
+        create_full_pathW(target_folder);
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row,3,buffer,&sz);
+        reduce_to_longfilename(buffer);
+        if (!strchrW(buffer,'.') || strcmpiW(strchrW(buffer,'.'),szlnk))
+            strcatW(buffer,szlnk);
+        target_file = build_directory_name(2, target_folder, buffer);
+        HeapFree(GetProcessHeap(),0,target_folder);
+
+        sz = 0x100;
+        MSI_RecordGetStringW(row,5,buffer,&sz);
+        if (strchrW(buffer,'['))
+        {
+            LPWSTR deformated;
+            deformat_string(package,buffer,&deformated);
+            IShellLinkW_SetPath(sl,deformated);
+            HeapFree(GetProcessHeap(),0,deformated);
+        }
+        else
+        {
+            LPWSTR keypath;
+            FIXME("poorly handled shortcut format, advertised shortcut\n");
+            keypath = dupstrW(package->components[index].FullKeypath);
+            IShellLinkW_SetPath(sl,keypath);
+            HeapFree(GetProcessHeap(),0,keypath);
+        }
+
+        if (!MSI_RecordIsNull(row,6))
+        {
+            LPWSTR deformated;
+            sz = 0x100;
+            MSI_RecordGetStringW(row,6,buffer,&sz);
+            deformat_string(package,buffer,&deformated);
+            IShellLinkW_SetArguments(sl,deformated);
+            HeapFree(GetProcessHeap(),0,deformated);
+        }
+
+        if (!MSI_RecordIsNull(row,7))
+        {
+            LPWSTR deformated;
+            deformated = load_dynamic_stringW(row,7);
+            IShellLinkW_SetDescription(sl,deformated);
+            HeapFree(GetProcessHeap(),0,deformated);
+        }
+
+        if (!MSI_RecordIsNull(row,8))
+            IShellLinkW_SetHotkey(sl,MSI_RecordGetInteger(row,8));
+
+        if (!MSI_RecordIsNull(row,9))
+        {
+            WCHAR *Path = NULL;
+            INT index; 
+
+            sz = 0x100;
+            MSI_RecordGetStringW(row,9,buffer,&sz);
+
+            build_icon_path(package,buffer,&Path);
+            index = MSI_RecordGetInteger(row,10);
+
+            IShellLinkW_SetIconLocation(sl,Path,index);
+            HeapFree(GetProcessHeap(),0,Path);
+        }
+
+        if (!MSI_RecordIsNull(row,11))
+            IShellLinkW_SetShowCmd(sl,MSI_RecordGetInteger(row,11));
+
+        if (!MSI_RecordIsNull(row,12))
+        {
+            LPWSTR Path;
+            sz = 0x100;
+            MSI_RecordGetStringW(row,12,buffer,&sz);
+            Path = resolve_folder(package, buffer, FALSE, FALSE, NULL);
+            IShellLinkW_SetWorkingDirectory(sl,Path);
+            HeapFree(GetProcessHeap(), 0, Path);
+        }
+
+        TRACE("Writing shortcut to %s\n",debugstr_w(target_file));
+        IPersistFile_Save(pf,target_file,FALSE);
+    
+        HeapFree(GetProcessHeap(),0,target_file);    
+
+        IPersistFile_Release( pf );
+        IShellLinkW_Release( sl );
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+
+    CoUninitialize();
+
+    return rc;
+}
+
+
+/*
+ * 99% of the work done here is only done for 
+ * advertised installs. However this is where the
+ * Icon table is processed and written out
+ * so that is what I am going to do here.
+ */
+static UINT ACTION_PublishProduct(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR Query[]=
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'I','c','o','n',0};
+    DWORD sz;
+    /* for registry stuff */
+    LPWSTR productcode;
+    HKEY hkey=0;
+    HKEY hukey=0;
+    static const WCHAR szProductName[] =
+        {'P','r','o','d','u','c','t','N','a','m','e',0};
+    static const WCHAR szPackageCode[] =
+        {'P','a','c','k','a','g','e','C','o','d','e',0};
+    LPWSTR buffer;
+    DWORD size;
+    MSIHANDLE hDb, hSumInfo;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+    if (rc != ERROR_SUCCESS)
+        goto next;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        goto next;
+    }
+
+    while (1)
+    {
+        HANDLE the_file;
+        WCHAR *FilePath=NULL;
+        WCHAR *FileName=NULL;
+        CHAR buffer[1024];
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+    
+        FileName = load_dynamic_stringW(row,1);
+        if (!FileName)
+        {
+            ERR("Unable to get FileName\n");
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        build_icon_path(package,FileName,&FilePath);
+
+        HeapFree(GetProcessHeap(),0,FileName);
+
+        TRACE("Creating icon file at %s\n",debugstr_w(FilePath));
+        
+        the_file = CreateFileW(FilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                           FILE_ATTRIBUTE_NORMAL, NULL);
+
+        if (the_file == INVALID_HANDLE_VALUE)
+        {
+            ERR("Unable to create file %s\n",debugstr_w(FilePath));
+            msiobj_release(&row->hdr);
+            HeapFree(GetProcessHeap(),0,FilePath);
+            continue;
+        }
+
+        do 
+        {
+            DWORD write;
+            sz = 1024;
+            rc = MSI_RecordReadStream(row,2,buffer,&sz);
+            if (rc != ERROR_SUCCESS)
+            {
+                ERR("Failed to get stream\n");
+                CloseHandle(the_file);  
+                DeleteFileW(FilePath);
+                break;
+            }
+            WriteFile(the_file,buffer,sz,&write,NULL);
+        } while (sz == 1024);
+
+        HeapFree(GetProcessHeap(),0,FilePath);
+
+        CloseHandle(the_file);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+next:
+    /* ok there is a lot more done here but i need to figure out what */
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    rc = MSIREG_OpenProductsKey(productcode,&hkey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+
+    buffer = load_dynamic_property(package,szProductName,NULL);
+    size = strlenW(buffer)*sizeof(WCHAR);
+    RegSetValueExW(hukey,szProductName,0,REG_SZ, (LPSTR)buffer,size);
+    HeapFree(GetProcessHeap(),0,buffer);
+    FIXME("Need to write more keys to the user registry\n");
+  
+    hDb= alloc_msihandle( &package->db->hdr );
+    rc = MsiGetSummaryInformationW(hDb, NULL, 0, &hSumInfo); 
+    MsiCloseHandle(hDb);
+    if (rc == ERROR_SUCCESS)
+    {
+        WCHAR guidbuffer[0x200];
+        size = 0x200;
+        rc = MsiSummaryInfoGetPropertyW(hSumInfo, 9, NULL, NULL, NULL,
+                                        guidbuffer, &size);
+        if (rc == ERROR_SUCCESS)
+        {
+            WCHAR squashed[GUID_SIZE];
+            /* for now we only care about the first guid */
+            LPWSTR ptr = strchrW(guidbuffer,';');
+            if (ptr) *ptr = 0;
+            squash_guid(guidbuffer,squashed);
+            size = strlenW(squashed)*sizeof(WCHAR);
+            RegSetValueExW(hukey,szPackageCode,0,REG_SZ, (LPSTR)squashed,
+                           size);
+        }
+        else
+        {
+            ERR("Unable to query Revision_Number... \n");
+            rc = ERROR_SUCCESS;
+        }
+        MsiCloseHandle(hSumInfo);
+    }
+    else
+    {
+        ERR("Unable to open Summary Information\n");
+        rc = ERROR_SUCCESS;
+    }
+
+end:
+
+    HeapFree(GetProcessHeap(),0,productcode);    
+    RegCloseKey(hkey);
+    RegCloseKey(hukey);
+
+    return rc;
+}
+
+static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'I','n','i','F','i','l','e',0};
+    static const WCHAR szWindowsFolder[] =
+          {'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+    {
+        TRACE("no IniFile table\n");
+        return ERROR_SUCCESS;
+    }
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        LPWSTR component,filename,dirproperty,section,key,value,identifier;
+        LPWSTR deformated_section, deformated_key, deformated_value;
+        LPWSTR folder, fullname = NULL;
+        MSIRECORD * uirow;
+        INT component_index,action;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        component = load_dynamic_stringW(row, 8);
+        component_index = get_loaded_component(package,component);
+        HeapFree(GetProcessHeap(),0,component);
+
+        if (!ACTION_VerifyComponentForAction(package, component_index,
+                                INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping ini file due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[component_index].Action =
+                package->components[component_index].Installed;
+
+            continue;
+        }
+
+        package->components[component_index].Action = INSTALLSTATE_LOCAL;
+   
+        identifier = load_dynamic_stringW(row,1); 
+        filename = load_dynamic_stringW(row,2);
+        dirproperty = load_dynamic_stringW(row,3);
+        section = load_dynamic_stringW(row,4);
+        key = load_dynamic_stringW(row,5);
+        value = load_dynamic_stringW(row,6);
+        action = MSI_RecordGetInteger(row,7);
+
+        deformat_string(package,section,&deformated_section);
+        deformat_string(package,key,&deformated_key);
+        deformat_string(package,value,&deformated_value);
+
+        if (dirproperty)
+        {
+            folder = resolve_folder(package, dirproperty, FALSE, FALSE, NULL);
+            if (!folder)
+                folder = load_dynamic_property(package,dirproperty,NULL);
+        }
+        else
+            folder = load_dynamic_property(package, szWindowsFolder, NULL);
+
+        if (!folder)
+        {
+            ERR("Unable to resolve folder! (%s)\n",debugstr_w(dirproperty));
+            goto cleanup;
+        }
+
+        fullname = build_directory_name(3, folder, filename, NULL);
+
+        if (action == 0)
+        {
+            TRACE("Adding value %s to section %s in %s\n",
+                debugstr_w(deformated_key), debugstr_w(deformated_section),
+                debugstr_w(fullname));
+            WritePrivateProfileStringW(deformated_section, deformated_key,
+                                       deformated_value, fullname);
+        }
+        else if (action == 1)
+        {
+            WCHAR returned[10];
+            GetPrivateProfileStringW(deformated_section, deformated_key, NULL,
+                                     returned, 10, fullname);
+            if (returned[0] == 0)
+            {
+                TRACE("Adding value %s to section %s in %s\n",
+                    debugstr_w(deformated_key), debugstr_w(deformated_section),
+                    debugstr_w(fullname));
+
+                WritePrivateProfileStringW(deformated_section, deformated_key,
+                                       deformated_value, fullname);
+            }
+        }
+        else if (action == 3)
+        {
+            FIXME("Append to existing section not yet implemented\n");
+        }
+        
+        uirow = MSI_CreateRecord(4);
+        MSI_RecordSetStringW(uirow,1,identifier);
+        MSI_RecordSetStringW(uirow,2,deformated_section);
+        MSI_RecordSetStringW(uirow,3,deformated_key);
+        MSI_RecordSetStringW(uirow,4,deformated_value);
+        ui_actiondata(package,szWriteIniValues,uirow);
+        msiobj_release( &uirow->hdr );
+cleanup:
+        HeapFree(GetProcessHeap(),0,identifier);
+        HeapFree(GetProcessHeap(),0,fullname);
+        HeapFree(GetProcessHeap(),0,filename);
+        HeapFree(GetProcessHeap(),0,key);
+        HeapFree(GetProcessHeap(),0,value);
+        HeapFree(GetProcessHeap(),0,section);
+        HeapFree(GetProcessHeap(),0,dirproperty);
+        HeapFree(GetProcessHeap(),0,folder);
+        HeapFree(GetProcessHeap(),0,deformated_key);
+        HeapFree(GetProcessHeap(),0,deformated_value);
+        HeapFree(GetProcessHeap(),0,deformated_section);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] = 
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'S','e','l','f','R','e','g',0};
+
+    static const WCHAR ExeStr[] =
+        {'r','e','g','s','v','r','3','2','.','e','x','e',' ','/','s',' ',0};
+    STARTUPINFOW si;
+    PROCESS_INFORMATION info;
+    BOOL brc;
+
+    memset(&si,0,sizeof(STARTUPINFOW));
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+    {
+        TRACE("no SelfReg table\n");
+        return ERROR_SUCCESS;
+    }
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        LPWSTR filename;
+        INT index;
+        DWORD len;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        filename = load_dynamic_stringW(row,1);
+        index = get_loaded_file(package,filename);
+
+        if (index < 0)
+        {
+            ERR("Unable to find file id %s\n",debugstr_w(filename));
+            HeapFree(GetProcessHeap(),0,filename);
+            msiobj_release(&row->hdr);
+            continue;
+        }
+        HeapFree(GetProcessHeap(),0,filename);
+
+        len = strlenW(ExeStr);
+        len += strlenW(package->files[index].TargetPath);
+        len +=2;
+
+        filename = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
+        strcpyW(filename,ExeStr);
+        strcatW(filename,package->files[index].TargetPath);
+
+        TRACE("Registering %s\n",debugstr_w(filename));
+        brc = CreateProcessW(NULL, filename, NULL, NULL, FALSE, 0, NULL,
+                  c_colon, &si, &info);
+
+        if (brc)
+            msi_dialog_check_messages(package->dialog, info.hProcess);
+        HeapFree(GetProcessHeap(),0,filename);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+
+static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
+{
+    LPWSTR productcode;
+    UINT rc;
+    DWORD i;
+    HKEY hkey=0;
+    HKEY hukey=0;
+    
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    rc = MSIREG_OpenFeaturesKey(productcode,&hkey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    rc = MSIREG_OpenUserFeaturesKey(productcode,&hukey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    /* here the guids are base 85 encoded */
+    for (i = 0; i < package->loaded_features; i++)
+    {
+        LPWSTR data = NULL;
+        GUID clsid;
+        int j;
+        INT size;
+
+        if (!ACTION_VerifyFeatureForAction(package,i,INSTALLSTATE_LOCAL))
+            continue;
+
+        size = package->features[i].ComponentCount*21;
+        size +=1;
+        if (package->features[i].Feature_Parent[0])
+            size += strlenW(package->features[i].Feature_Parent)+2;
+
+        data = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
+
+        data[0] = 0;
+        for (j = 0; j < package->features[i].ComponentCount; j++)
+        {
+            WCHAR buf[21];
+            memset(buf,0,sizeof(buf));
+            TRACE("From %s\n",debugstr_w(package->components
+                            [package->features[i].Components[j]].ComponentId));
+            CLSIDFromString(package->components
+                            [package->features[i].Components[j]].ComponentId,
+                            &clsid);
+            encode_base85_guid(&clsid,buf);
+            TRACE("to %s\n",debugstr_w(buf));
+            strcatW(data,buf);
+        }
+        if (package->features[i].Feature_Parent[0])
+        {
+            static const WCHAR sep[] = {'\2',0};
+            strcatW(data,sep);
+            strcatW(data,package->features[i].Feature_Parent);
+        }
+
+        size = (strlenW(data)+1)*sizeof(WCHAR);
+        RegSetValueExW(hkey,package->features[i].Feature,0,REG_SZ,
+                       (LPSTR)data,size);
+        HeapFree(GetProcessHeap(),0,data);
+
+        size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR);
+        RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,
+                       (LPSTR)package->features[i].Feature_Parent,size);
+    }
+
+end:
+    RegCloseKey(hkey);
+    RegCloseKey(hukey);
+    HeapFree(GetProcessHeap(), 0, productcode);
+    return rc;
+}
+
+static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
+{
+    HKEY hkey=0;
+    LPWSTR buffer;
+    LPWSTR productcode;
+    UINT rc,i;
+    DWORD size;
+    static WCHAR szNONE[] = {0};
+    static const WCHAR szWindowsInstaler[] = 
+    {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
+    static const WCHAR szPropKeys[][80] = 
+    {
+{'A','R','P','A','U','T','H','O','R','I','Z','E','D','C','D','F','P','R','E','F','I','X',0},
+{'A','R','P','C','O','N','T','A','C','T',0},
+{'A','R','P','C','O','M','M','E','N','T','S',0},
+{'P','r','o','d','u','c','t','N','a','m','e',0},
+{'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0},
+{'A','R','P','H','E','L','P','L','I','N','K',0},
+{'A','R','P','H','E','L','P','T','E','L','E','P','H','O','N','E',0},
+{'A','R','P','I','N','S','T','A','L','L','L','O','C','A','T','I','O','N',0},
+{'S','o','u','r','c','e','D','i','r',0},
+{'M','a','n','u','f','a','c','t','u','r','e','r',0},
+{'A','R','P','R','E','A','D','M','E',0},
+{'A','R','P','S','I','Z','E',0},
+{'A','R','P','U','R','L','I','N','F','O','A','B','O','U','T',0},
+{'A','R','P','U','R','L','U','P','D','A','T','E','I','N','F','O',0},
+{0},
+    };
+
+    static const WCHAR szRegKeys[][80] = 
+    {
+{'A','u','t','h','o','r','i','z','e','d','C','D','F','P','r','e','f','i','x',0},
+{'C','o','n','t','a','c','t',0},
+{'C','o','m','m','e','n','t','s',0},
+{'D','i','s','p','l','a','y','N','a','m','e',0},
+{'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0},
+{'H','e','l','p','L','i','n','k',0},
+{'H','e','l','p','T','e','l','e','p','h','o','n','e',0},
+{'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0},
+{'I','n','s','t','a','l','l','S','o','u','r','c','e',0},
+{'P','u','b','l','i','s','h','e','r',0},
+{'R','e','a','d','m','e',0},
+{'S','i','z','e',0},
+{'U','R','L','I','n','f','o','A','b','o','u','t',0},
+{'U','R','L','U','p','d','a','t','e','I','n','f','o',0},
+{0},
+    };
+
+    static const WCHAR installerPathFmt[] = {
+    '%','s','\\',
+    'I','n','s','t','a','l','l','e','r','\\',0};
+    static const WCHAR fmt[] = {
+    '%','s','\\',
+    'I','n','s','t','a','l','l','e','r','\\',
+    '%','x','.','m','s','i',0};
+    static const WCHAR szLocalPackage[]=
+         {'L','o','c','a','l','P','a','c','k','a','g','e',0};
+    WCHAR windir[MAX_PATH], path[MAX_PATH], packagefile[MAX_PATH];
+    INT num,start;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    /* dump all the info i can grab */
+    FIXME("Flesh out more information \n");
+
+    i = 0;
+    while (szPropKeys[i][0]!=0)
+    {
+        buffer = load_dynamic_property(package,szPropKeys[i],&rc);
+        if (rc != ERROR_SUCCESS)
+            buffer = szNONE;
+        size = strlenW(buffer)*sizeof(WCHAR);
+        RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);
+        i++;
+    }
+
+    rc = 0x1;
+    size = sizeof(rc);
+    RegSetValueExW(hkey,szWindowsInstaler,0,REG_DWORD,(LPSTR)&rc,size);
+    
+    /* copy the package locally */
+    num = GetTickCount() & 0xffff;
+    if (!num) 
+        num = 1;
+    start = num;
+    GetWindowsDirectoryW(windir, sizeof(windir) / sizeof(windir[0]));
+    snprintfW(packagefile,sizeof(packagefile)/sizeof(packagefile[0]),fmt,
+     windir,num);
+    do 
+    {
+        HANDLE handle = CreateFileW(packagefile,GENERIC_WRITE, 0, NULL,
+                                  CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+        if (handle != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle(handle);
+            break;
+        }
+        if (GetLastError() != ERROR_FILE_EXISTS &&
+            GetLastError() != ERROR_SHARING_VIOLATION)
+            break;
+        if (!(++num & 0xffff)) num = 1;
+        sprintfW(packagefile,fmt,num);
+    } while (num != start);
+
+    snprintfW(path,sizeof(path)/sizeof(path[0]),installerPathFmt,windir);
+    create_full_pathW(path);
+    TRACE("Copying to local package %s\n",debugstr_w(packagefile));
+    CopyFileW(package->PackagePath,packagefile,FALSE);
+    size = strlenW(packagefile)*sizeof(WCHAR);
+    RegSetValueExW(hkey,szLocalPackage,0,REG_SZ,(LPSTR)packagefile,size);
+    
+end:
+    HeapFree(GetProcessHeap(),0,productcode);
+    RegCloseKey(hkey);
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_InstallExecute(MSIPACKAGE *package)
+{
+    int i;
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    for (i = 0; i < package->DeferredActionCount; i++)
+    {
+        LPWSTR action;
+        action = package->DeferredAction[i];
+        ui_actionstart(package, action);
+        TRACE("Executing Action (%s)\n",debugstr_w(action));
+        ACTION_CustomAction(package,action,TRUE);
+        HeapFree(GetProcessHeap(),0,package->DeferredAction[i]);
+    }
+    HeapFree(GetProcessHeap(),0,package->DeferredAction);
+
+    package->DeferredActionCount = 0;
+    package->DeferredAction = NULL;
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
+{
+    int i;
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    /* first do the same as an InstallExecute */
+    ACTION_InstallExecute(package);
+
+    /* then handle Commit Actions */
+    for (i = 0; i < package->CommitActionCount; i++)
+    {
+        LPWSTR action;
+        action = package->CommitAction[i];
+        ui_actionstart(package, action);
+        TRACE("Executing Commit Action (%s)\n",debugstr_w(action));
+        ACTION_CustomAction(package,action,TRUE);
+        HeapFree(GetProcessHeap(),0,package->CommitAction[i]);
+    }
+    HeapFree(GetProcessHeap(),0,package->CommitAction);
+
+    package->CommitActionCount = 0;
+    package->CommitAction = NULL;
+
+    return ERROR_SUCCESS;
+}
+
+static UINT ACTION_ForceReboot(MSIPACKAGE *package)
+{
+    static const WCHAR RunOnce[] = {
+    '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','\\',
+    'R','u','n','O','n','c','e',0};
+    static const WCHAR InstallRunOnce[] = {
+    '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','\\',
+    'I','n','s','t','a','l','l','e','r','\\',
+    'R','u','n','O','n','c','e','E','n','t','r','i','e','s',0};
+
+    static const WCHAR msiexec_fmt[] = {
+    '%','s',
+    '\\','M','s','i','E','x','e','c','.','e','x','e',' ','/','@',' ',
+    '\"','%','s','\"',0};
+    static const WCHAR install_fmt[] = {
+    '/','I',' ','\"','%','s','\"',' ',
+    'A','F','T','E','R','R','E','B','O','O','T','=','1',' ',
+    'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};
+    WCHAR buffer[256], sysdir[MAX_PATH];
+    HKEY hkey,hukey;
+    LPWSTR productcode;
+    WCHAR  squished_pc[100];
+    INT rc;
+    DWORD size;
+    static const WCHAR szLUS[] = {
+         'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
+    static const WCHAR szSourceList[] = {
+         'S','o','u','r','c','e','L','i','s','t',0};
+    static const WCHAR szPackageName[] = { 
+        'P','a','c','k','a','g','e','N','a','m','e',0};
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    squash_guid(productcode,squished_pc);
+
+    GetSystemDirectoryW(sysdir, sizeof(sysdir)/sizeof(sysdir[0]));
+    RegCreateKeyW(HKEY_LOCAL_MACHINE,RunOnce,&hkey);
+    snprintfW(buffer,sizeof(buffer)/sizeof(buffer[0]),msiexec_fmt,sysdir,
+     squished_pc);
+
+    size = strlenW(buffer)*sizeof(WCHAR);
+    RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);
+    RegCloseKey(hkey);
+
+    TRACE("Reboot command %s\n",debugstr_w(buffer));
+
+    RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);
+    sprintfW(buffer,install_fmt,productcode,squished_pc);
+
+    size = strlenW(buffer)*sizeof(WCHAR);
+    RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);
+    RegCloseKey(hkey);
+
+    rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);
+    if (rc == ERROR_SUCCESS)
+    {
+        HKEY hukey2;
+        LPWSTR buf;
+        RegCreateKeyW(hukey, szSourceList, &hukey2);
+        buf = load_dynamic_property(package,cszSourceDir,NULL);
+        size = strlenW(buf)*sizeof(WCHAR);
+        RegSetValueExW(hukey2,szLUS,0,REG_SZ,(LPSTR)buf,size);
+        HeapFree(GetProcessHeap(),0,buf); 
+
+        buf = strrchrW(package->PackagePath,'\\');
+        if (buf)
+        {
+            buf++;
+            size = strlenW(buf)*sizeof(WCHAR);
+            RegSetValueExW(hukey2,szPackageName,0,REG_SZ,(LPSTR)buf,size);
+        }
+
+        RegCloseKey(hukey2);
+    }
+    HeapFree(GetProcessHeap(),0,productcode);
+
+    return ERROR_INSTALL_SUSPEND;
+}
+
+UINT ACTION_ResolveSource(MSIPACKAGE* package)
+{
+    /*
+     * we are currently doing what should be done here in the top level Install
+     * however for Adminastrative and uninstalls this step will be needed
+     */
+    return ERROR_SUCCESS;
+}
+
+
+static UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'E','x','t','e','n','s','i','o','n',0};
+    static const WCHAR szContentType[] = 
+        {'C','o','n','t','e','n','t',' ','T','y','p','e',0 };
+    HKEY hkey;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+    {
+        rc = ERROR_SUCCESS;
+        goto end;
+    }
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        goto end;
+    }
+
+    while (1)
+    {
+        WCHAR buffer[0x100];
+        WCHAR extension[257];
+        LPWSTR exten;
+        DWORD sz;
+        INT index;
+     
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz=0x100;
+        MSI_RecordGetStringW(row,2,buffer,&sz);
+
+        index = get_loaded_component(package,buffer);
+
+        if (index < 0)
+        {
+            msiobj_release(&row->hdr);
+            continue;
+        }
+
+        if (!ACTION_VerifyComponentForAction(package, index,
+                                INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping extension reg due to disabled component\n");
+            msiobj_release(&row->hdr);
+
+            package->components[index].Action =
+                package->components[index].Installed;
+
+            continue;
+        }
+
+        package->components[index].Action = INSTALLSTATE_LOCAL;
+
+        exten = load_dynamic_stringW(row,1);
+        extension[0] = '.';
+        extension[1] = 0;
+        strcatW(extension,exten);
+        HeapFree(GetProcessHeap(),0,exten);
+
+        RegCreateKeyW(HKEY_CLASSES_ROOT,extension,&hkey);
+
+        if (!MSI_RecordIsNull(row,4))
+        {
+            LPWSTR mime = load_dynamic_stringW(row,4);
+            RegSetValueExW(hkey,szContentType,0,REG_SZ,(LPVOID)mime,
+                           (strlenW(mime)+1)*sizeof(WCHAR));
+            HeapFree(GetProcessHeap(),0,mime);
+        }
+
+        if (!MSI_RecordIsNull(row,3))
+        {
+            static const WCHAR szSN[] = 
+                {'\\','S','h','e','l','l','N','e','w',0};
+            HKEY hkey2;
+            LPWSTR newkey;
+            LPWSTR progid= load_dynamic_stringW(row,3);
+
+            RegSetValueExW(hkey,NULL,0,REG_SZ,(LPVOID)progid,
+                           (strlenW(progid)+1)*sizeof(WCHAR));
+
+            newkey = HeapAlloc(GetProcessHeap(),0,
+                           (strlenW(progid)+strlenW(szSN)+1) * sizeof(WCHAR)); 
+
+            strcpyW(newkey,progid);
+            strcatW(newkey,szSN);
+            RegCreateKeyW(hkey,newkey,&hkey2);
+            RegCloseKey(hkey2);
+
+            HeapFree(GetProcessHeap(),0,progid);
+            HeapFree(GetProcessHeap(),0,newkey);
+        }
+
+
+        RegCloseKey(hkey);
+
+        ui_actiondata(package,szRegisterExtensionInfo,row);
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+end:
+    return rc;
+}
+
+static UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'M','I','M','E',0};
+    static const WCHAR szExten[] = 
+        {'E','x','t','e','n','s','i','o','n',0 };
+    HKEY hkey;
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+    {
+        rc = ERROR_SUCCESS;
+        goto end;
+    }
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        goto end;
+    }
+
+    while (1)
+    {
+        WCHAR extension[257];
+        LPWSTR exten;
+        LPWSTR mime;
+        static const WCHAR fmt[] = 
+            {'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\',
+             'C','o','n','t','e','n','t',' ','T','y','p','e','\\', '%','s',0};
+        LPWSTR key;
+     
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        mime = load_dynamic_stringW(row,1);
+        exten = load_dynamic_stringW(row,2);
+        extension[0] = '.';
+        extension[1] = 0;
+        strcatW(extension,exten);
+        HeapFree(GetProcessHeap(),0,exten);
+
+        key = HeapAlloc(GetProcessHeap(),0,(strlenW(mime)+strlenW(fmt)+1) *
+                                            sizeof(WCHAR));
+        sprintfW(key,fmt,mime);
+        RegCreateKeyW(HKEY_CLASSES_ROOT,key,&hkey);
+        RegSetValueExW(hkey,szExten,0,REG_SZ,(LPVOID)extension,
+                           (strlenW(extension)+1)*sizeof(WCHAR));
+
+        HeapFree(GetProcessHeap(),0,mime);
+        HeapFree(GetProcessHeap(),0,key);
+
+        if (!MSI_RecordIsNull(row,3))
+        {
+            FIXME("Handle non null for field 3\n");
+        }
+
+        RegCloseKey(hkey);
+
+        ui_actiondata(package,szRegisterMIMEInfo,row);
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+end:
+    return rc;
+}
+
+static UINT ACTION_RegisterUser(MSIPACKAGE *package)
+{
+    static const WCHAR szProductID[]=
+         {'P','r','o','d','u','c','t','I','D',0};
+    HKEY hkey=0;
+    LPWSTR buffer;
+    LPWSTR productcode;
+    LPWSTR productid;
+    UINT rc,i;
+    DWORD size;
+
+    static const WCHAR szPropKeys[][80] = 
+    {
+        {'P','r','o','d','u','c','t','I','D',0},
+        {'U','S','E','R','N','A','M','E',0},
+        {'C','O','M','P','A','N','Y','N','A','M','E',0},
+        {0},
+    };
+
+    static const WCHAR szRegKeys[][80] = 
+    {
+        {'P','r','o','d','u','c','t','I','D',0},
+        {'R','e','g','O','w','n','e','r',0},
+        {'R','e','g','C','o','m','p','a','n','y',0},
+        {0},
+    };
+
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    productid = load_dynamic_property(package,szProductID,&rc);
+    if (!productid)
+        return ERROR_SUCCESS;
+
+    productcode = load_dynamic_property(package,szProductCode,&rc);
+    if (!productcode)
+        return rc;
+
+    rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    i = 0;
+    while (szPropKeys[i][0]!=0)
+    {
+        buffer = load_dynamic_property(package,szPropKeys[i],&rc);
+        if (rc == ERROR_SUCCESS)
+        {
+            size = strlenW(buffer)*sizeof(WCHAR);
+            RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);
+        }
+        i++;
+    }
+
+end:
+    HeapFree(GetProcessHeap(),0,productcode);
+    HeapFree(GetProcessHeap(),0,productid);
+    RegCloseKey(hkey);
+
+    return ERROR_SUCCESS;
+}
+
+
+static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
+{
+    UINT rc;
+    rc = ACTION_ProcessExecSequence(package,TRUE);
+    return rc;
+}
+
+
+/*
+ * Code based off of code located here
+ * http://www.codeproject.com/gdi/fontnamefromfile.asp
+ *
+ * Using string index 4 (full font name) instead of 1 (family name)
+ */
+static LPWSTR load_ttfname_from(LPCWSTR filename)
+{
+    HANDLE handle;
+    LPWSTR ret = NULL;
+    int i;
+
+    typedef struct _tagTT_OFFSET_TABLE{
+        USHORT uMajorVersion;
+        USHORT uMinorVersion;
+        USHORT uNumOfTables;
+        USHORT uSearchRange;
+        USHORT uEntrySelector;
+        USHORT uRangeShift;
+    }TT_OFFSET_TABLE;
+
+    typedef struct _tagTT_TABLE_DIRECTORY{
+        char szTag[4]; /* table name */
+        ULONG uCheckSum; /* Check sum */
+        ULONG uOffset; /* Offset from beginning of file */
+        ULONG uLength; /* length of the table in bytes */
+    }TT_TABLE_DIRECTORY;
+
+    typedef struct _tagTT_NAME_TABLE_HEADER{
+    USHORT uFSelector; /* format selector. Always 0 */
+    USHORT uNRCount; /* Name Records count */
+    USHORT uStorageOffset; /* Offset for strings storage, 
+                            * from start of the table */
+    }TT_NAME_TABLE_HEADER;
+   
+    typedef struct _tagTT_NAME_RECORD{
+        USHORT uPlatformID;
+        USHORT uEncodingID;
+        USHORT uLanguageID;
+        USHORT uNameID;
+        USHORT uStringLength;
+        USHORT uStringOffset; /* from start of storage area */
+    }TT_NAME_RECORD;
+
+#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
+#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
+
+    handle = CreateFileW(filename ,GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                    FILE_ATTRIBUTE_NORMAL, 0 );
+    if (handle != INVALID_HANDLE_VALUE)
+    {
+        TT_TABLE_DIRECTORY tblDir;
+        BOOL bFound = FALSE;
+        TT_OFFSET_TABLE ttOffsetTable;
+
+        ReadFile(handle,&ttOffsetTable, sizeof(TT_OFFSET_TABLE),NULL,NULL);
+        ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
+        ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
+        ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
+        
+        if (ttOffsetTable.uMajorVersion != 1 || 
+                        ttOffsetTable.uMinorVersion != 0)
+            return NULL;
+
+        for (i=0; i< ttOffsetTable.uNumOfTables; i++)
+        {
+            ReadFile(handle,&tblDir, sizeof(TT_TABLE_DIRECTORY),NULL,NULL);
+            if (strncmp(tblDir.szTag,"name",4)==0)
+            {
+                bFound = TRUE;
+                tblDir.uLength = SWAPLONG(tblDir.uLength);
+                tblDir.uOffset = SWAPLONG(tblDir.uOffset);
+                break;
+            }
+        }
+
+        if (bFound)
+        {
+            TT_NAME_TABLE_HEADER ttNTHeader;
+            TT_NAME_RECORD ttRecord;
+
+            SetFilePointer(handle, tblDir.uOffset, NULL, FILE_BEGIN);
+            ReadFile(handle,&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER),
+                            NULL,NULL);
+
+            ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
+            ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
+            bFound = FALSE;
+            for(i=0; i<ttNTHeader.uNRCount; i++)
+            {
+                ReadFile(handle,&ttRecord, sizeof(TT_NAME_RECORD),NULL,NULL);
+                ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
+                /* 4 is the Full Font Name */
+                if(ttRecord.uNameID == 4)
+                {
+                    int nPos;
+                    LPSTR buf;
+                    static const LPSTR tt = " (TrueType)";
+
+                    ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
+                    ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
+                    nPos = SetFilePointer(handle, 0, NULL, FILE_CURRENT);
+                    SetFilePointer(handle, tblDir.uOffset + 
+                                    ttRecord.uStringOffset + 
+                                    ttNTHeader.uStorageOffset,
+                                    NULL, FILE_BEGIN);
+                    buf = HeapAlloc(GetProcessHeap(), 0, 
+                                    ttRecord.uStringLength + 1 + strlen(tt));
+                    memset(buf, 0, ttRecord.uStringLength + 1 + strlen(tt));
+                    ReadFile(handle, buf, ttRecord.uStringLength, NULL, NULL);
+                    if (strlen(buf) > 0)
+                    {
+                        strcat(buf,tt);
+                        ret = strdupAtoW(buf);
+                        HeapFree(GetProcessHeap(),0,buf);
+                        break;
+                    }
+
+                    HeapFree(GetProcessHeap(),0,buf);
+                    SetFilePointer(handle,nPos, NULL, FILE_BEGIN);
+                }
+            }
+        }
+        CloseHandle(handle);
+    }
+
+    TRACE("Returning fontname %s\n",debugstr_w(ret));
+    return ret;
+}
+
+static UINT ACTION_RegisterFonts(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+         'F','o','n','t',0};
+    static const WCHAR regfont1[] =
+        {'S','o','f','t','w','a','r','e','\\',
+         'M','i','c','r','o','s','o','f','t','\\',
+         'W','i','n','d','o','w','s',' ','N','T','\\',
+         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+         'F','o','n','t','s',0};
+    static const WCHAR regfont2[] =
+        {'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','\\',
+         'F','o','n','t','s',0};
+    HKEY hkey1;
+    HKEY hkey2;
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont1,&hkey1);
+    RegCreateKeyW(HKEY_LOCAL_MACHINE,regfont2,&hkey2);
+    
+    while (1)
+    {
+        LPWSTR name;
+        LPWSTR file;
+        UINT index;
+        DWORD size;
+
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        file = load_dynamic_stringW(row,1);
+        index = get_loaded_file(package,file);
+        if (index < 0)
+        {
+            ERR("Unable to load file\n");
+            HeapFree(GetProcessHeap(),0,file);
+            continue;
+        }
+
+        /* check to make sure that component is installed */
+        if (!ACTION_VerifyComponentForAction(package, 
+                package->files[index].ComponentIndex, INSTALLSTATE_LOCAL))
+        {
+            TRACE("Skipping: Component not scheduled for install\n");
+            HeapFree(GetProcessHeap(),0,file);
+
+            msiobj_release(&row->hdr);
+
+            continue;
+        }
+
+        if (MSI_RecordIsNull(row,2))
+            name = load_ttfname_from(package->files[index].TargetPath);
+        else
+            name = load_dynamic_stringW(row,2);
+
+        if (name)
+        {
+            size = strlenW(package->files[index].FileName) * sizeof(WCHAR);
+            RegSetValueExW(hkey1,name,0,REG_SZ,
+                        (LPBYTE)package->files[index].FileName,size);
+            RegSetValueExW(hkey2,name,0,REG_SZ,
+                        (LPBYTE)package->files[index].FileName,size);
+        }
+        
+        HeapFree(GetProcessHeap(),0,file);
+        HeapFree(GetProcessHeap(),0,name);
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    RegCloseKey(hkey1);
+    RegCloseKey(hkey2);
+
+    return rc;
+}
+
+/* Msi functions that seem appropriate here */
+UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
+{
+    LPWSTR szwAction;
+    UINT rc;
+
+    TRACE(" exteral attempt at action %s\n",szAction);
+
+    if (!szAction)
+        return ERROR_FUNCTION_FAILED;
+    if (hInstall == 0)
+        return ERROR_FUNCTION_FAILED;
+
+    szwAction = strdupAtoW(szAction);
+
+    if (!szwAction)
+        return ERROR_FUNCTION_FAILED; 
+
+
+    rc = MsiDoActionW(hInstall, szwAction);
+    HeapFree(GetProcessHeap(),0,szwAction);
+    return rc;
+}
+
+UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
+{
+    MSIPACKAGE *package;
+    UINT ret = ERROR_INVALID_HANDLE;
+
+    TRACE(" external attempt at action %s \n",debugstr_w(szAction));
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if( package )
+    {
+        ret = ACTION_PerformUIAction(package,szAction);
+        msiobj_release( &package->hdr );
+    }
+    return ret;
+}
+
+UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder, 
+                               LPSTR szPathBuf, DWORD* pcchPathBuf) 
+{
+    LPWSTR szwFolder;
+    LPWSTR szwPathBuf;
+    UINT rc;
+
+    TRACE("getting folder %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);
+
+    if (!szFolder)
+        return ERROR_FUNCTION_FAILED;
+    if (hInstall == 0)
+        return ERROR_FUNCTION_FAILED;
+
+    szwFolder = strdupAtoW(szFolder);
+
+    if (!szwFolder)
+        return ERROR_FUNCTION_FAILED; 
+
+    szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));
+
+    rc = MsiGetTargetPathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);
+
+    WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,
+                         *pcchPathBuf, NULL, NULL );
+
+    HeapFree(GetProcessHeap(),0,szwFolder);
+    HeapFree(GetProcessHeap(),0,szwPathBuf);
+
+    return rc;
+}
+
+UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
+                                szPathBuf, DWORD* pcchPathBuf) 
+{
+    LPWSTR path;
+    UINT rc = ERROR_FUNCTION_FAILED;
+    MSIPACKAGE *package;
+
+    TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+    path = resolve_folder(package, szFolder, FALSE, FALSE, NULL);
+    msiobj_release( &package->hdr );
+
+    if (path && (strlenW(path) > *pcchPathBuf))
+    {
+        *pcchPathBuf = strlenW(path)+1;
+        rc = ERROR_MORE_DATA;
+    }
+    else if (path)
+    {
+        *pcchPathBuf = strlenW(path)+1;
+        strcpyW(szPathBuf,path);
+        TRACE("Returning Path %s\n",debugstr_w(path));
+        rc = ERROR_SUCCESS;
+    }
+    HeapFree(GetProcessHeap(),0,path);
+    
+    return rc;
+}
+
+
+UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder, 
+                               LPSTR szPathBuf, DWORD* pcchPathBuf) 
+{
+    LPWSTR szwFolder;
+    LPWSTR szwPathBuf;
+    UINT rc;
+
+    TRACE("getting source %s %p %li\n",szFolder,szPathBuf, *pcchPathBuf);
+
+    if (!szFolder)
+        return ERROR_FUNCTION_FAILED;
+    if (hInstall == 0)
+        return ERROR_FUNCTION_FAILED;
+
+    szwFolder = strdupAtoW(szFolder);
+    if (!szwFolder)
+        return ERROR_FUNCTION_FAILED; 
+
+    szwPathBuf = HeapAlloc( GetProcessHeap(), 0 , *pcchPathBuf * sizeof(WCHAR));
+
+    rc = MsiGetSourcePathW(hInstall, szwFolder, szwPathBuf,pcchPathBuf);
+
+    WideCharToMultiByte( CP_ACP, 0, szwPathBuf, *pcchPathBuf, szPathBuf,
+                         *pcchPathBuf, NULL, NULL );
+
+    HeapFree(GetProcessHeap(),0,szwFolder);
+    HeapFree(GetProcessHeap(),0,szwPathBuf);
+
+    return rc;
+}
+
+UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder, LPWSTR
+                                szPathBuf, DWORD* pcchPathBuf) 
+{
+    LPWSTR path;
+    UINT rc = ERROR_FUNCTION_FAILED;
+    MSIPACKAGE *package;
+
+    TRACE("(%s %p %li)\n",debugstr_w(szFolder),szPathBuf,*pcchPathBuf);
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if( !package )
+        return ERROR_INVALID_HANDLE;
+    path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
+    msiobj_release( &package->hdr );
+
+    if (path && strlenW(path) > *pcchPathBuf)
+    {
+        *pcchPathBuf = strlenW(path)+1;
+        rc = ERROR_MORE_DATA;
+    }
+    else if (path)
+    {
+        *pcchPathBuf = strlenW(path)+1;
+        strcpyW(szPathBuf,path);
+        TRACE("Returning Path %s\n",debugstr_w(path));
+        rc = ERROR_SUCCESS;
+    }
+    HeapFree(GetProcessHeap(),0,path);
+    
+    return rc;
+}
+
+
+UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, 
+                             LPCSTR szFolderPath)
+{
+    LPWSTR szwFolder;
+    LPWSTR szwFolderPath;
+    UINT rc;
+
+    if (!szFolder)
+        return ERROR_FUNCTION_FAILED;
+    if (hInstall == 0)
+        return ERROR_FUNCTION_FAILED;
+
+    szwFolder = strdupAtoW(szFolder);
+    if (!szwFolder)
+        return ERROR_FUNCTION_FAILED; 
+
+    szwFolderPath = strdupAtoW(szFolderPath);
+    if (!szwFolderPath)
+    {
+        HeapFree(GetProcessHeap(),0,szwFolder);
+        return ERROR_FUNCTION_FAILED; 
+    }
+
+    rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);
+
+    HeapFree(GetProcessHeap(),0,szwFolder);
+    HeapFree(GetProcessHeap(),0,szwFolderPath);
+
+    return rc;
+}
+
+UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, 
+                             LPCWSTR szFolderPath)
+{
+    DWORD i;
+    LPWSTR path = NULL;
+    LPWSTR path2 = NULL;
+    MSIFOLDER *folder;
+
+    TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
+
+    if (package==NULL)
+        return ERROR_INVALID_HANDLE;
+
+    if (szFolderPath[0]==0)
+        return ERROR_FUNCTION_FAILED;
+
+    if (GetFileAttributesW(szFolderPath) == INVALID_FILE_ATTRIBUTES)
+        return ERROR_FUNCTION_FAILED;
+
+    path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
+
+    if (!path)
+        return ERROR_INVALID_PARAMETER;
+
+    HeapFree(GetProcessHeap(),0,folder->Property);
+    folder->Property = build_directory_name(2, szFolderPath, NULL);
+
+    if (strcmpiW(path, folder->Property) == 0)
+    {
+        /*
+         *  Resolved Target has not really changed, so just 
+         *  set this folder and do not recalculate everything.
+         */
+        HeapFree(GetProcessHeap(),0,folder->ResolvedTarget);
+        folder->ResolvedTarget = NULL;
+        path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
+        HeapFree(GetProcessHeap(),0,path2);
+    }
+    else
+    {
+        for (i = 0; i < package->loaded_folders; i++)
+        {
+            HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
+            package->folders[i].ResolvedTarget=NULL;
+        }
+
+        for (i = 0; i < package->loaded_folders; i++)
+        {
+            path2=resolve_folder(package, package->folders[i].Directory, FALSE,
+                       TRUE, NULL);
+            HeapFree(GetProcessHeap(),0,path2);
+        }
+    }
+    HeapFree(GetProcessHeap(),0,path);
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, 
+                             LPCWSTR szFolderPath)
+{
+    MSIPACKAGE *package;
+    UINT ret;
+
+    TRACE("(%s %s)\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+/***********************************************************************
+ *           MsiGetMode    (MSI.@)
+ *
+ * Returns an internal installer state (if it is running in a mode iRunMode)
+ *
+ * PARAMS
+ *   hInstall    [I]  Handle to the installation
+ *   hRunMode    [I]  Checking run mode
+ *        MSIRUNMODE_ADMIN             Administrative mode
+ *        MSIRUNMODE_ADVERTISE         Advertisement mode
+ *        MSIRUNMODE_MAINTENANCE       Maintenance mode
+ *        MSIRUNMODE_ROLLBACKENABLED   Rollback is enabled
+ *        MSIRUNMODE_LOGENABLED        Log file is writing
+ *        MSIRUNMODE_OPERATIONS        Operations in progress??
+ *        MSIRUNMODE_REBOOTATEND       We need to reboot after installation completed
+ *        MSIRUNMODE_REBOOTNOW         We need to reboot to continue the installation
+ *        MSIRUNMODE_CABINET           Files from cabinet are installed
+ *        MSIRUNMODE_SOURCESHORTNAMES  Long names in source files is suppressed
+ *        MSIRUNMODE_TARGETSHORTNAMES  Long names in destination files is suppressed
+ *        MSIRUNMODE_RESERVED11        Reserved
+ *        MSIRUNMODE_WINDOWS9X         Running under Windows95/98
+ *        MSIRUNMODE_ZAWENABLED        Demand installation is supported
+ *        MSIRUNMODE_RESERVED14        Reserved
+ *        MSIRUNMODE_RESERVED15        Reserved
+ *        MSIRUNMODE_SCHEDULED         called from install script
+ *        MSIRUNMODE_ROLLBACK          called from rollback script
+ *        MSIRUNMODE_COMMIT            called from commit script
+ *
+ * RETURNS
+ *    In the state: TRUE
+ *    Not in the state: FALSE
+ *
+ */
+
+BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
+{
+    FIXME("STUB (iRunMode=%i)\n",iRunMode);
+    return TRUE;
+}
+
+/*
+ * According to the docs, when this is called it immediately recalculates
+ * all the component states as well
+ */
+UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
+                                INSTALLSTATE iState)
+{
+    LPWSTR szwFeature = NULL;
+    UINT rc;
+
+    szwFeature = strdupAtoW(szFeature);
+
+    if (!szwFeature)
+        return ERROR_FUNCTION_FAILED;
+   
+    rc = MsiSetFeatureStateW(hInstall,szwFeature, iState); 
+
+    HeapFree(GetProcessHeap(),0,szwFeature);
+
+    return rc;
+}
+
+UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
+                                INSTALLSTATE iState)
+{
+    MSIPACKAGE* package;
+    INT index;
+    UINT rc = ERROR_SUCCESS;
+
+    TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    index = get_loaded_feature(package,szFeature);
+    if (index < 0)
+    {
+        rc = ERROR_UNKNOWN_FEATURE;
+        goto end;
+    }
+
+    package->features[index].ActionRequest= iState;
+    ACTION_UpdateComponentStates(package,szFeature);
+
+end:
+    msiobj_release( &package->hdr );
+    return rc;
+}
+
+UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    LPWSTR szwFeature = NULL;
+    UINT rc;
+    
+    szwFeature = strdupAtoW(szFeature);
+
+    rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
+
+    HeapFree( GetProcessHeap(), 0 , szwFeature);
+
+    return rc;
+}
+
+UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    INT index;
+
+    index = get_loaded_feature(package,szFeature);
+    if (index < 0)
+        return ERROR_UNKNOWN_FEATURE;
+
+    if (piInstalled)
+        *piInstalled = package->features[index].Installed;
+
+    if (piAction)
+        *piAction = package->features[index].Action;
+
+    TRACE("returning %i %i\n",*piInstalled,*piAction);
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPWSTR szFeature,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    MSIPACKAGE* package;
+    UINT ret;
+
+    TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled,
+piAction);
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    LPWSTR szwComponent= NULL;
+    UINT rc;
+    
+    szwComponent= strdupAtoW(szComponent);
+
+    rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
+
+    HeapFree( GetProcessHeap(), 0 , szwComponent);
+
+    return rc;
+}
+
+UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    INT index;
+
+    TRACE("%p %s %p %p\n", package, debugstr_w(szComponent), piInstalled,
+piAction);
+
+    index = get_loaded_component(package,szComponent);
+    if (index < 0)
+        return ERROR_UNKNOWN_COMPONENT;
+
+    if (piInstalled)
+        *piInstalled = package->components[index].Installed;
+
+    if (piAction)
+        *piAction = package->components[index].Action;
+
+    TRACE("states (%i, %i)\n",
+(piInstalled)?*piInstalled:-1,(piAction)?*piAction:-1);
+
+    return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent,
+                  INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
+{
+    MSIPACKAGE* package;
+    UINT ret;
+
+    TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
+           piInstalled, piAction);
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+    ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
+    msiobj_release( &package->hdr );
+    return ret;
+}
+
+#if 0
+static UINT ACTION_Template(MSIPACKAGE *package)
+{
+    UINT rc;
+    MSIQUERY * view;
+    MSIRECORD * row = 0;
+    static const WCHAR ExecSeqQuery[] = {0};
+
+    rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MSI_ViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+        return rc;
+    }
+
+    while (1)
+    {
+        rc = MSI_ViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        msiobj_release(&row->hdr);
+    }
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+    return rc;
+}
+#endif
index 221e2a2..1ac1430 100644 (file)
@@ -53,6 +53,9 @@ typedef struct tagMSICOMPONENT
 
     BOOL Enabled;
     INT  Cost;
+    INT  RefCount;
+
+    LPWSTR FullKeypath;
 } MSICOMPONENT;
 
 typedef struct tagMSIFOLDER
index 60059b6..8918d7f 100644 (file)
@@ -629,7 +629,7 @@ static BOOL ACTION_IsFullPath(LPCWSTR path)
     WCHAR first = toupperW(path[0]);
     BOOL ret;
 
-    if (first >= 'A' && first <= 'A' && path[1] == ':')
+    if (first >= 'A' && first <= 'Z' && path[1] == ':')
         ret = TRUE;
     else if (path[0] == '\\' && path[1] == '\\')
         ret = TRUE;
@@ -644,6 +644,7 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
     UINT rc;
     BOOL found;
 
+    TRACE("%p, %p, %s, %d\n", package, sig, debugstr_w(expanded), depth);
     if (ACTION_IsFullPath(expanded))
     {
         if (sig->File)
@@ -681,6 +682,7 @@ static UINT ACTION_SearchDirectory(MSIPACKAGE *package, MSISIGNATURE *sig,
                 }
             }
     }
+    TRACE("returning %d\n", rc);
     return rc;
 }
 
index ae79b3d..3f5686a 100644 (file)
@@ -45,7 +45,7 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/summa
 #include "winuser.h"
 #include "shlobj.h"
 #include "wine/unicode.h"
-#include "ver.h"
+#include "winver.h"
 #include "action.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
diff --git a/reactos/lib/msi/delete.c b/reactos/lib/msi/delete.c
new file mode 100644 (file)
index 0000000..fdb1c00
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2005 Mike McCormack 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/*
+ * Code to delete rows from a table.
+ *
+ * We delete rows by blanking them out rather than trying to remove the row.
+ * This appears to be what the native MSI does (or tries to do). For the query:
+ *
+ * delete from Property
+ *
+ * some non-zero entries are left in the table by native MSI.  I'm not sure if
+ * that's a bug in the way I'm running the query, or a just a bug.
+ */
+
+typedef struct tagMSIDELETEVIEW
+{
+    MSIVIEW        view;
+    MSIDATABASE   *db;
+    MSIVIEW       *table;
+} MSIDELETEVIEW;
+
+static UINT DELETE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %d %d %p\n", dv, row, col, val );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %d %d %p\n", dv, row, col, stm );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %d %d %04x\n", dv, row, col, val );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_insert_row( struct tagMSIVIEW *view, UINT *num )  
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %p\n", dv, num );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+    UINT r, i, j, rows = 0, cols = 0;
+
+    TRACE("%p %p\n", dv, record);
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    r = dv->table->ops->execute( dv->table, record );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    r = dv->table->ops->get_dimensions( dv->table, &rows, &cols );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    TRACE("blanking %d rows\n", rows); 
+
+    /* blank out all the rows that match */
+    for( i=0; i<rows; i++ )
+        for( j=1; j<=cols; j++ )
+            dv->table->ops->set_int( dv->table, i, j, 0 );
+
+    return ERROR_SUCCESS;
+}
+
+static UINT DELETE_close( struct tagMSIVIEW *view )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p\n", dv );
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return dv->table->ops->close( dv->table );
+}
+
+static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %p %p\n", dv, rows, cols );
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    *rows = 0;
+
+    return dv->table->ops->get_dimensions( dv->table, NULL, cols );
+}
+
+static UINT DELETE_get_column_info( struct tagMSIVIEW *view,
+                UINT n, LPWSTR *name, UINT *type )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %d %p %p\n", dv, n, name, type );
+
+    if( !dv->table )
+         return ERROR_FUNCTION_FAILED;
+
+    return dv->table->ops->get_column_info( dv->table, n, name, type );
+}
+
+static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
+                MSIRECORD *rec )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p %d %p\n", dv, eModifyMode, rec );
+
+    return ERROR_FUNCTION_FAILED;
+}
+
+static UINT DELETE_delete( struct tagMSIVIEW *view )
+{
+    MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
+
+    TRACE("%p\n", dv );
+
+    if( dv->table )
+        dv->table->ops->delete( dv->table );
+
+    HeapFree( GetProcessHeap(), 0, dv );
+
+    return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS delete_ops =
+{
+    DELETE_fetch_int,
+    DELETE_fetch_stream,
+    DELETE_set_int,
+    DELETE_insert_row,
+    DELETE_execute,
+    DELETE_close,
+    DELETE_get_dimensions,
+    DELETE_get_column_info,
+    DELETE_modify,
+    DELETE_delete
+};
+
+UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+    MSIDELETEVIEW *dv = NULL;
+
+    TRACE("%p\n", dv );
+
+    dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+    if( !dv )
+        return ERROR_FUNCTION_FAILED;
+    
+    /* fill the structure */
+    dv->view.ops = &delete_ops;
+    dv->db = db;
+    dv->table = table;
+
+    *view = &dv->view;
+
+    return ERROR_SUCCESS;
+}
index db8328f..ccd01a4 100644 (file)
@@ -41,6 +41,9 @@ const WCHAR szMsiDialogClass[] = {
     'M','s','i','D','i','a','l','o','g','C','l','o','s','e','C','l','a','s','s',0
 };
 const static WCHAR szStatic[] = { 'S','t','a','t','i','c',0 };
+const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
+
+const static WCHAR szButtonData[] = { 'M','S','I','D','A','T','A',0 };
 
 struct msi_control_tag;
 typedef struct msi_control_tag msi_control;
@@ -83,10 +86,19 @@ struct control_handler
     msi_dialog_control_func func;
 };
 
+typedef struct
+{
+    msi_dialog* dialog;
+    msi_control *parent;
+    DWORD       attributes;
+} radio_button_group_descr;
+
 static UINT msi_dialog_checkbox_handler( msi_dialog *, msi_control *, WPARAM );
 static void msi_dialog_checkbox_sync_state( msi_dialog *, msi_control * );
 static UINT msi_dialog_button_handler( msi_dialog *, msi_control *, WPARAM );
 static UINT msi_dialog_edit_handler( msi_dialog *, msi_control *, WPARAM );
+static UINT msi_dialog_radiogroup_handler( msi_dialog *, msi_control *, WPARAM param );
+static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
 
 INT msi_dialog_scale_unit( msi_dialog *dialog, INT val )
@@ -275,7 +287,6 @@ static UINT msi_dialog_text_control( msi_dialog *dialog, MSIRECORD *rec )
 
 static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
 {
-    const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
     msi_control *control;
 
     TRACE("%p %p\n", dialog, rec);
@@ -288,7 +299,6 @@ static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
 
 static UINT msi_dialog_checkbox_control( msi_dialog *dialog, MSIRECORD *rec )
 {
-    const static WCHAR szButton[] = { 'B','U','T','T','O','N', 0 };
     msi_control *control;
     LPCWSTR prop;
 
@@ -319,7 +329,7 @@ static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec )
 
     TRACE("%p %p\n", dialog, rec);
 
-    msi_dialog_add_control( dialog, rec, szEdit,
+    msi_dialog_add_control( dialog, rec, szEdit, WS_BORDER |
                  ES_MULTILINE | WS_VSCROLL | ES_READONLY | ES_AUTOVSCROLL );
 
     return ERROR_SUCCESS;
@@ -350,7 +360,7 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
     LPCWSTR prop;
     LPWSTR val;
 
-    control = msi_dialog_add_control( dialog, rec, szEdit, 0 );
+    control = msi_dialog_add_control( dialog, rec, szEdit, WS_BORDER );
     control->handler = msi_dialog_edit_handler;
     prop = MSI_RecordGetString( rec, 9 );
     if( prop )
@@ -361,8 +371,125 @@ static UINT msi_dialog_edit_control( msi_dialog *dialog, MSIRECORD *rec )
     return ERROR_SUCCESS;
 }
 
+static UINT msi_dialog_pathedit_control( msi_dialog *dialog, MSIRECORD *rec )
+{
+    FIXME("not implemented properly\n");
+    return msi_dialog_edit_control( dialog, rec );
+}
+
+static UINT msi_dialog_create_radiobutton( MSIRECORD *rec, LPVOID param )
+{
+    radio_button_group_descr *group = (radio_button_group_descr *)param;
+    msi_dialog *dialog = group->dialog;
+    msi_control *control;
+    LPCWSTR prop;
+    DWORD x, y, width, height, style;
+    DWORD attributes = group->attributes;
+    LPCWSTR text, name;
+    LPWSTR font = NULL, title = NULL;
+
+    style = WS_CHILD | BS_AUTORADIOBUTTON | BS_MULTILINE;
+    name = MSI_RecordGetString( rec, 3 );
+    control = HeapAlloc( GetProcessHeap(), 0,
+                         sizeof *control + strlenW(name)*sizeof(WCHAR) );
+    strcpyW( control->name, name );
+    control->next = dialog->control_list;
+    dialog->control_list = control;
+
+    x = MSI_RecordGetInteger( rec, 4 );
+    y = MSI_RecordGetInteger( rec, 5 );
+    width = MSI_RecordGetInteger( rec, 6 );
+    height = MSI_RecordGetInteger( rec, 7 );
+    text = MSI_RecordGetString( rec, 8 );
+
+    x = msi_dialog_scale_unit( dialog, x );
+    y = msi_dialog_scale_unit( dialog, y );
+    width = msi_dialog_scale_unit( dialog, width );
+    height = msi_dialog_scale_unit( dialog, height );
+
+    if( attributes & 1 )
+        style |= WS_VISIBLE;
+    if( ~attributes & 2 )
+        style |= WS_DISABLED;
+
+    if( text )
+    {
+        font = msi_dialog_get_style( &text );
+        deformat_string( dialog->package, text, &title );
+    }
+
+    control->hwnd = CreateWindowW( szButton, title, style, x, y, width, height,
+        group->parent->hwnd, NULL, NULL, NULL );
+
+    TRACE("Dialog %s control %s hwnd %p\n", debugstr_w(dialog->name), debugstr_w(text), control->hwnd);
+
+    msi_dialog_set_font( dialog, control->hwnd,
+            font ? font : dialog->default_font );
+
+    HeapFree( GetProcessHeap(), 0, font );
+    HeapFree( GetProcessHeap(), 0, title );
+
+    control->handler = msi_dialog_radiogroup_handler;
+
+    prop = MSI_RecordGetString( rec, 1 );
+    if( prop )
+        control->property = dupstrW( prop );
+
+    return ERROR_SUCCESS;
+}
+
+static UINT msi_dialog_radiogroup_control( msi_dialog *dialog, MSIRECORD *rec )
+{
+    static const WCHAR query[] = {
+        'S','E','L','E','C','T',' ','*',' ',
+        'F','R','O','M',' ','R','a','d','i','o','B','u','t','t','o','n',' ',
+        'W','H','E','R','E',' ',
+           '`','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
+    UINT r;
+    LPCWSTR prop;
+    msi_control *control;
+    MSIQUERY *view = NULL;
+    radio_button_group_descr group;
+    MSIPACKAGE *package = dialog->package;
+
+    prop = MSI_RecordGetString( rec, 9 );
+
+    TRACE("%p %p %s\n", dialog, rec, debugstr_w( prop ));
+
+    /* Create parent group box to hold radio buttons */
+    control = msi_dialog_add_control( dialog, rec, szButton, BS_OWNERDRAW );
+
+    if (control->hwnd)
+    {
+        WNDPROC oldproc = (WNDPROC) SetWindowLongPtrW(control->hwnd, GWLP_WNDPROC,
+            (LONG_PTR)MSIRadioGroup_WndProc);
+        SetPropW(control->hwnd, szButtonData, oldproc);
+    }
+
+    if( prop )
+        control->property = dupstrW( prop );
+
+    /* query the Radio Button table for all control in this group */
+    r = MSI_OpenQuery( package->db, &view, query, prop );
+    if( r != ERROR_SUCCESS )
+    {
+        ERR("query failed for dialog %s radio group %s\n", 
+            debugstr_w(dialog->name), debugstr_w(prop));
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    group.dialog = dialog;
+    group.parent = control;
+    group.attributes = MSI_RecordGetInteger( rec, 8 );
+
+    r = MSI_IterateRecords( view, 0, msi_dialog_create_radiobutton, &group );
+    msiobj_release( &view->hdr );
+
+    return r;
+}
+
 static const WCHAR szText[] = { 'T','e','x','t',0 };
-static const WCHAR szButton[] = { 'P','u','s','h','B','u','t','t','o','n',0 };
+static const WCHAR szPushButton[] = { 'P','u','s','h','B','u','t','t','o','n',0 };
 static const WCHAR szLine[] = { 'L','i','n','e',0 };
 static const WCHAR szBitmap[] = { 'B','i','t','m','a','p',0 };
 static const WCHAR szCheckBox[] = { 'C','h','e','c','k','B','o','x',0 };
@@ -371,11 +498,14 @@ static const WCHAR szScrollableText[] = {
 static const WCHAR szComboBox[] = { 'C','o','m','b','o','B','o','x',0 };
 static const WCHAR szEdit[] = { 'E','d','i','t',0 };
 static const WCHAR szMaskedEdit[] = { 'M','a','s','k','e','d','E','d','i','t',0 };
+static const WCHAR szPathEdit[] = { 'P','a','t','h','E','d','i','t',0 };
+static const WCHAR szRadioButtonGroup[] = { 
+    'R','a','d','i','o','B','u','t','t','o','n','G','r','o','u','p',0 };
 
 struct control_handler msi_dialog_handler[] =
 {
     { szText, msi_dialog_text_control },
-    { szButton, msi_dialog_button_control },
+    { szPushButton, msi_dialog_button_control },
     { szLine, msi_dialog_line_control },
     { szBitmap, msi_dialog_bitmap_control },
     { szCheckBox, msi_dialog_checkbox_control },
@@ -383,6 +513,8 @@ struct control_handler msi_dialog_handler[] =
     { szComboBox, msi_dialog_combo_control },
     { szEdit, msi_dialog_edit_control },
     { szMaskedEdit, msi_dialog_edit_control },
+    { szPathEdit, msi_dialog_pathedit_control },
+    { szRadioButtonGroup, msi_dialog_radiogroup_control },
 };
 
 #define NUM_CONTROL_TYPES (sizeof msi_dialog_handler/sizeof msi_dialog_handler[0])
@@ -791,6 +923,20 @@ static UINT msi_dialog_edit_handler( msi_dialog *dialog,
     return ERROR_SUCCESS;
 }
 
+static UINT msi_dialog_radiogroup_handler( msi_dialog *dialog,
+                msi_control *control, WPARAM param )
+{
+    if( HIWORD(param) != BN_CLICKED )
+        return ERROR_SUCCESS;
+
+    TRACE("clicked radio button %s, set %s\n", debugstr_w(control->name),
+          debugstr_w(control->property));
+
+    MSI_SetPropertyW( dialog->package, control->property, control->name );
+
+    return msi_dialog_button_handler( dialog, control, param );
+}
+
 static LRESULT msi_dialog_oncommand( msi_dialog *dialog, WPARAM param, HWND hwnd )
 {
     msi_control *control;
@@ -816,6 +962,7 @@ static LRESULT WINAPI MSIDialog_WndProc( HWND hwnd, UINT msg,
 {
     msi_dialog *dialog = (LPVOID) GetWindowLongPtrW( hwnd, GWLP_USERDATA );
 
+    TRACE(" 0x%04x\n", msg);
     switch (msg)
     {
     case WM_CREATE:
@@ -971,3 +1118,15 @@ void msi_dialog_unregister_class( void )
 {
     UnregisterClassW( szMsiDialogClass, NULL );
 }
+
+static LRESULT WINAPI MSIRadioGroup_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    WNDPROC oldproc = (WNDPROC) GetPropW(hWnd, szButtonData);
+
+    TRACE("hWnd %p msg %04x wParam 0x%08x lParam 0x%08lx\n", hWnd, msg, wParam, lParam);
+
+    if (msg == WM_COMMAND) /* Forward notifications to dialog */
+        SendMessageW(GetParent(hWnd), msg, wParam, lParam);
+
+    return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam);
+}
index a5a9d2b..7e5b6dc 100644 (file)
@@ -44,7 +44,7 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msifo
 #include "winuser.h"
 #include "shlobj.h"
 #include "wine/unicode.h"
-#include "ver.h"
+#include "winver.h"
 #include "action.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -231,13 +231,13 @@ static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
     *nested = FALSE;
     for (i = 1; (*mark - source) + i < len_remaining && count > 0; i++)
     {
-        if ((*mark)[i] == '['
+        if ((*mark)[i] == '[' && (*mark)[i-1] != '\\')
         {
             count ++;
             total_count ++;
             *nested = TRUE;
         }
-        else if ((*mark)[i] == ']')
+        else if ((*mark)[i] == ']' && (*mark)[i-1] != '\\')
         {
             count --;
         }
@@ -538,11 +538,8 @@ UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord,
 
     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
 
-    if( record )
-    {
-        r = MSI_FormatRecordW( package, record, szResult, sz );
-        msiobj_release( &record->hdr );
-    }
+    r = MSI_FormatRecordW( package, record, szResult, sz );
+    msiobj_release( &record->hdr );
     if (package)
         msiobj_release( &package->hdr );
     return r;
@@ -572,11 +569,8 @@ UINT WINAPI MsiFormatRecordA( MSIHANDLE hInstall, MSIHANDLE hRecord,
 
     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
 
-    if( record )
-    {
-        r = MSI_FormatRecordA( package, record, szResult, sz );
-        msiobj_release( &record->hdr );
-    }
+    r = MSI_FormatRecordA( package, record, szResult, sz );
+    msiobj_release( &record->hdr );
     if (package)
         msiobj_release( &package->hdr );
     return r;
index 78f8ce7..7534f04 100644 (file)
@@ -487,6 +487,11 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
         goto end;\r
 \r
     package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);\r
+    if (!package)\r
+    {\r
+        rc = ERROR_INVALID_HANDLE;\r
+        goto end;\r
+    }\r
   \r
     sz = strlenW(szInstalled);\r
 \r
@@ -865,7 +870,7 @@ INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
  *   id            [I]  id of the string to be loaded\r
  *   lpBuffer      [O]  buffer for the string to be written to\r
  *   nBufferMax    [I]  maximum size of the buffer in characters\r
- *   lang          [I]  the prefered language for the string\r
+ *   lang          [I]  the preferred language for the string\r
  *\r
  * RETURNS\r
  *\r
@@ -973,219 +978,6 @@ UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uT
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
-UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)\r
-{\r
-    DWORD r;\r
-    WCHAR szwGuid[GUID_SIZE];\r
-\r
-    TRACE("%ld %p\n",index,lpguid);\r
-    \r
-    if (NULL == lpguid) {\r
-      return ERROR_INVALID_PARAMETER;\r
-    }\r
-    r = MsiEnumProductsW(index, szwGuid);\r
-    if( r == ERROR_SUCCESS )\r
-        WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)\r
-{\r
-    HKEY hkeyFeatures = 0;\r
-    DWORD r;\r
-    WCHAR szKeyName[33];\r
-\r
-    TRACE("%ld %p\n",index,lpguid);\r
-\r
-    if (NULL == lpguid)\r
-        return ERROR_INVALID_PARAMETER;\r
-\r
-    r = MSIREG_OpenFeatures(&hkeyFeatures);\r
-    if( r != ERROR_SUCCESS )\r
-        goto end;\r
-\r
-    r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);\r
-\r
-    unsquash_guid(szKeyName, lpguid);\r
-\r
-end:\r
-\r
-    if( hkeyFeatures )\r
-        RegCloseKey(hkeyFeatures);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index, \r
-      LPSTR szFeature, LPSTR szParent)\r
-{\r
-    DWORD r;\r
-    WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];\r
-    LPWSTR szwProduct = NULL;\r
-\r
-    TRACE("%s %ld %p %p\n",debugstr_a(szProduct),index,szFeature,szParent);\r
-\r
-    if( szProduct )\r
-    {\r
-        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );\r
-        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );\r
-        if( szwProduct )\r
-            MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );\r
-        else\r
-            return ERROR_FUNCTION_FAILED;\r
-    }\r
-\r
-    r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);\r
-    if( r == ERROR_SUCCESS )\r
-    {\r
-        WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,\r
-                            szFeature, GUID_SIZE, NULL, NULL);\r
-        WideCharToMultiByte(CP_ACP, 0, szwParent, -1,\r
-                            szParent, GUID_SIZE, NULL, NULL);\r
-    }\r
-\r
-    HeapFree( GetProcessHeap(), 0, szwProduct);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index, \r
-      LPWSTR szFeature, LPWSTR szParent)\r
-{\r
-    HKEY hkeyProduct = 0;\r
-    DWORD r, sz;\r
-\r
-    TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);\r
-\r
-    r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);\r
-    if( r != ERROR_SUCCESS )\r
-        goto end;\r
-\r
-    sz = GUID_SIZE;\r
-    r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);\r
-\r
-end:\r
-    if( hkeyProduct )\r
-        RegCloseKey(hkeyProduct);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)\r
-{\r
-    DWORD r;\r
-    WCHAR szwGuid[GUID_SIZE];\r
-\r
-    TRACE("%ld %p\n",index,lpguid);\r
-\r
-    r = MsiEnumComponentsW(index, szwGuid);\r
-    if( r == ERROR_SUCCESS )\r
-        WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)\r
-{\r
-    HKEY hkeyComponents = 0;\r
-    DWORD r;\r
-    WCHAR szKeyName[33];\r
-\r
-    TRACE("%ld %p\n",index,lpguid);\r
-\r
-    r = MSIREG_OpenComponents(&hkeyComponents);\r
-    if( r != ERROR_SUCCESS )\r
-        goto end;\r
-\r
-    r = RegEnumKeyW(hkeyComponents, index, szKeyName, GUID_SIZE);\r
-\r
-    unsquash_guid(szKeyName, lpguid);\r
-\r
-end:\r
-\r
-    if( hkeyComponents )\r
-        RegCloseKey(hkeyComponents);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)\r
-{\r
-    DWORD r;\r
-    WCHAR szwProduct[GUID_SIZE];\r
-    LPWSTR szwComponent = NULL;\r
-\r
-    TRACE("%s %ld %p\n",debugstr_a(szComponent),index,szProduct);\r
-\r
-    if( szComponent )\r
-    {\r
-        UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );\r
-        szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );\r
-        if( szwComponent )\r
-            MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );\r
-        else\r
-            return ERROR_FUNCTION_FAILED;\r
-    }\r
-\r
-    r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);\r
-    if( r == ERROR_SUCCESS )\r
-    {\r
-        WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,\r
-                            szProduct, GUID_SIZE, NULL, NULL);\r
-    }\r
-\r
-    HeapFree( GetProcessHeap(), 0, szwComponent);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)\r
-{\r
-    HKEY hkeyComp = 0;\r
-    DWORD r, sz;\r
-    WCHAR szValName[GUID_SIZE];\r
-\r
-    TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);\r
-\r
-    r = MSIREG_OpenComponentsKey(szComponent,&hkeyComp,FALSE);\r
-    if( r != ERROR_SUCCESS )\r
-        goto end;\r
-\r
-    sz = GUID_SIZE;\r
-    r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);\r
-    if( r != ERROR_SUCCESS )\r
-        goto end;\r
-\r
-    unsquash_guid(szValName, szProduct);\r
-\r
-end:\r
-    if( hkeyComp )\r
-        RegCloseKey(hkeyComp);\r
-\r
-    return r;\r
-}\r
-\r
-UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex,\r
-                LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,\r
-                LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)\r
-{\r
-    FIXME("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex,\r
-          lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,\r
-          pcchApplicationDataBuf);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
-}\r
-\r
-UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex,\r
-                LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,\r
-                LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )\r
-{\r
-    FIXME("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,\r
-          lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,\r
-          pcchApplicationDataBuf);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
-}\r
-\r
 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,\r
                 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,\r
                 DWORD* pcchPathBuf ) \r
@@ -1343,41 +1135,72 @@ INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
     WCHAR squished_pc[GUID_SIZE];\r
     UINT rc;\r
     INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;\r
-    HKEY hkey=0;\r
+    HKEY hkey = 0;\r
+    LPWSTR path = NULL;\r
+    DWORD sz, type;\r
 \r
     TRACE("%s %s %p %p\n", debugstr_w(szProduct),\r
            debugstr_w(szComponent), lpPathBuf, pcchBuf);\r
 \r
+    if( lpPathBuf && !pcchBuf )\r
+        return INSTALLSTATE_INVALIDARG;\r
+\r
     squash_guid(szProduct,squished_pc);\r
 \r
-    rc = MSIREG_OpenProductsKey(szProduct,&hkey,FALSE);\r
-    if (rc != ERROR_SUCCESS)\r
+    rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);\r
+    if( rc != ERROR_SUCCESS )\r
         goto end;\r
 \r
     RegCloseKey(hkey);\r
 \r
-    rc = MSIREG_OpenComponentsKey(szComponent,&hkey,FALSE);\r
-    if (rc != ERROR_SUCCESS)\r
+    rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);\r
+    if( rc != ERROR_SUCCESS )\r
         goto end;\r
 \r
-    *pcchBuf *= sizeof(WCHAR);\r
-    rc = RegQueryValueExW(hkey,squished_pc,NULL,NULL,(LPVOID)lpPathBuf,\r
-                          pcchBuf);\r
-    *pcchBuf /= sizeof(WCHAR);\r
+    sz = 0;\r
+    type = 0;\r
+    rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );\r
+    if( rc != ERROR_SUCCESS )\r
+        goto end;\r
+    if( type != REG_SZ )\r
+        goto end;\r
 \r
-    if (rc!= ERROR_SUCCESS)\r
+    sz += sizeof(WCHAR);\r
+    path = HeapAlloc( GetProcessHeap(), 0, sz );\r
+    if( !path )\r
+        goto end;\r
+\r
+    rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );\r
+    if( rc != ERROR_SUCCESS )\r
         goto end;\r
 \r
     TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),\r
-           debugstr_w(szProduct), debugstr_w(lpPathBuf));\r
+           debugstr_w(szProduct), debugstr_w(path));\r
 \r
-    FIXME("Only working for installed files, not registry keys\n");\r
-    if (GetFileAttributesW(lpPathBuf) != INVALID_FILE_ATTRIBUTES)\r
-        rrc = INSTALLSTATE_LOCAL;\r
+    if (path[0]=='0')\r
+    {\r
+        FIXME("Registry entry.. check entry\n");\r
+            rrc = INSTALLSTATE_LOCAL;\r
+    }\r
     else\r
-        rrc = INSTALLSTATE_ABSENT;\r
+    {\r
+        /* PROBABLY a file */\r
+        if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )\r
+            rrc = INSTALLSTATE_LOCAL;\r
+        else\r
+            rrc = INSTALLSTATE_ABSENT;\r
+    }\r
+\r
+    if( pcchBuf )\r
+    {\r
+        sz = sz / sizeof(WCHAR);\r
+        if( *pcchBuf >= sz )\r
+            strcpyW( lpPathBuf, path );\r
+        *pcchBuf = sz;\r
+    }\r
 \r
 end:\r
+    HeapFree(GetProcessHeap(), 0, path );\r
     RegCloseKey(hkey);\r
     return rrc;\r
 }\r
@@ -1421,7 +1244,10 @@ INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)\r
 {\r
     FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));\r
-    return INSTALLSTATE_UNKNOWN;\r
+    /*\r
+     * Iterates all the features components and the features parents components\r
+     */\r
+    return INSTALLSTATE_LOCAL;\r
 }\r
 \r
 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,\r
@@ -1655,22 +1481,6 @@ BOOL WINAPI MSI_DllCanUnloadNow(void)
     return S_FALSE;\r
 }\r
 \r
-UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,\r
-                                    DWORD iProductIndex, LPWSTR lpProductBuf)\r
-{\r
-    FIXME("%s %lu %lu %p\n", debugstr_w(szUpgradeCode), dwReserved,\r
-          iProductIndex, lpProductBuf);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
-}\r
-\r
-UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,\r
-                                    DWORD iProductIndex, LPSTR lpProductBuf)\r
-{\r
-    FIXME("%s %lu %lu %p\n", debugstr_a(szUpgradeCode), dwReserved,\r
-          iProductIndex, lpProductBuf);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
-}\r
-\r
 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,\r
                                 DWORD* pdwUseCount, WORD* pwDateUsed)\r
 {\r
@@ -1687,11 +1497,42 @@ UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
-UINT WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature, \r
+INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature, \r
                              DWORD dwInstallMode, DWORD dwReserved)\r
 {\r
     FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),\r
           dwInstallMode, dwReserved);\r
+\r
+    /*\r
+     * Polls all the components of the feature to find install state and then\r
+     *  writes:\r
+     *    Software\\Microsoft\\Windows\\CurrentVersion\\\r
+     *    Installer\\Products\\<squishguid>\\<feature>\r
+     *      "Usage"=dword:........\r
+     */  \r
\r
+    return INSTALLSTATE_LOCAL; \r
+}\r
+\r
+INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature, \r
+                             DWORD dwInstallMode, DWORD dwReserved)\r
+{\r
+    FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),\r
+          dwInstallMode, dwReserved);\r
+   \r
+    return INSTALLSTATE_LOCAL; \r
+}\r
+\r
+INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)\r
+{\r
+    FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));\r
+   \r
+    return INSTALLSTATE_LOCAL; \r
+}\r
+\r
+INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)\r
+{\r
+    FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));\r
    \r
     return INSTALLSTATE_LOCAL; \r
 }\r
@@ -1749,17 +1590,33 @@ UINT WINAPI MsiCreateAndVerifyInstallerDirectory(void)
 }\r
 \r
 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,\r
-                                  LPSTR szProductCode, LPSTR szFeatureId,\r
-                                  LPSTR szComponentCode)\r
+                                   LPSTR szProductCode, LPSTR szFeatureId,\r
+                                   LPSTR szComponentCode )\r
 {\r
     FIXME("\n");\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,\r
-                                  LPWSTR szProductCode, LPWSTR szFeatureId,\r
-                                  LPWSTR szComponentCode)\r
+                                   LPWSTR szProductCode, LPWSTR szFeatureId,\r
+                                   LPWSTR szComponentCode )\r
 {\r
     FIXME("\n");\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
+\r
+UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature, \r
+                                  DWORD dwReinstallMode )\r
+{\r
+    FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),\r
+                           dwReinstallMode);\r
+    return ERROR_SUCCESS;\r
+}\r
+\r
+UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature, \r
+                                  DWORD dwReinstallMode )\r
+{\r
+    FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),\r
+                           dwReinstallMode);\r
+    return ERROR_SUCCESS;\r
+}\r
index adf5138..af6906c 100644 (file)
@@ -27,4 +27,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 \r
 #include "version.rc"\r
 \r
+#include "msi_De.rc"\r
 #include "msi_En.rc"\r
+#include "msi_Es.rc"\r
+#include "msi_Fr.rc"\r
+#include "msi_Pt.rc"\r
index ad1cd0d..a5a7d44 100644 (file)
 123 stdcall MsiRecordSetStreamW(long long wstr)\r
 124 stdcall MsiRecordSetStringA(long long str)\r
 125 stdcall MsiRecordSetStringW(long long wstr)\r
-126 stub MsiReinstallFeatureA\r
+126 stdcall MsiReinstallFeatureA(str str long)\r
 127 stub MsiReinstallFeatureFromDescriptorA\r
 128 stub MsiReinstallFeatureFromDescriptorW\r
-129 stub MsiReinstallFeatureW\r
+129 stdcall MsiReinstallFeatureW(wstr wstr long)\r
 130 stdcall MsiReinstallProductA(str long)\r
 131 stdcall MsiReinstallProductW(wstr long)\r
 132 stub MsiSequenceA\r
 151 stdcall MsiSummaryInfoPersist(long)\r
 152 stdcall MsiSummaryInfoSetPropertyA(long long long long ptr str)\r
 153 stdcall MsiSummaryInfoSetPropertyW(long long long long ptr wstr)\r
-154 stub MsiUseFeatureA\r
-155 stub MsiUseFeatureW\r
+154 stdcall MsiUseFeatureA(str str)\r
+155 stdcall MsiUseFeatureW(wstr wstr)\r
 156 stdcall MsiVerifyPackageA(str)\r
 157 stdcall MsiVerifyPackageW(wstr)\r
 158 stdcall MsiViewClose(long)\r
 189 stdcall MsiConfigureProductExA(str long long str)\r
 190 stdcall MsiConfigureProductExW(wstr long long wstr)\r
 191 stub MsiInvalidateFeatureCache\r
-192 stub MsiUseFeatureExA\r
+192 stdcall MsiUseFeatureExA(str str long long)\r
 193 stdcall MsiUseFeatureExW(wstr wstr long long)\r
 194 stdcall MsiGetFileVersionA(str str ptr str ptr)\r
 195 stdcall MsiGetFileVersionW(wstr wstr ptr wstr ptr)\r
similarity index 53%
rename from reactos/include/wine/heap.h
rename to reactos/lib/msi/msi_De.rc
index e3bf4fb..0b15276 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Win32 heap definitions
+ * German resources for MSI
  *
- * Copyright 1996 Alexandre Julliard
+ * Copyright 2005 Henning Gerhardt
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef __WINE_HEAP_H
-#define __WINE_HEAP_H
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
 
-#include <stdarg.h>
-#include <string.h>
-
-#include <windef.h>
-#include <winbase.h>
-#include <winnls.h>
-
-/* strdup macros */
-/* DO NOT USE IT!!  it will go away soon */
-
-inline static LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
+STRINGTABLE DISCARDABLE
 {
-    LPSTR ret;
-    INT len;
-
-    if (!str) return NULL;
-    len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
-    ret = HeapAlloc( heap, flags, len );
-    if(ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
-    return ret;
+       5 "Der Pfad %s wurde nicht gefunden."
+       9 "Bitte Disk %s einlegen."
+       10 "schlechte Parameter"
+       11 "Geben Sie das Verzeichnis ein, dass %s enthält."
+       12 "Die Installationsquelle für das Feature fehlt."
+       13 "Das Netzwerklaufwerk für das Feature fehlt."
+       14 "Feature von:"
+       15 "Wählen Sie das Verzeichnis aus, dass %s enthält."
 }
-
-#endif  /* __WINE_HEAP_H */
diff --git a/reactos/lib/msi/msi_Es.rc b/reactos/lib/msi/msi_Es.rc
new file mode 100644 (file)
index 0000000..3270f47
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Spanish resources for MSI
+ *
+ * Copyright 2005 José Manuel Ferrer Ortiz
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+       5 "ruta %s no encontrada"
+       9 "inserte el disco %s"
+       10 "parámetros incorrectos"
+       11 "introduzca qué carpeta contiene %s"
+       12 "instalar fuente para característica ausente"
+       13 "unidad de red para característica ausente"
+       14 "característica de:"
+       15 "elija qué carpeta contiene %s"
+}
diff --git a/reactos/lib/msi/msi_Fr.rc b/reactos/lib/msi/msi_Fr.rc
new file mode 100644 (file)
index 0000000..d1551ab
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * French resources for MSI
+ *
+ * Copyright 2005 Jonathan Ernst
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+       5 "Le chemin %s est introuvable"
+       9 "insérez le disque %s"
+       10 "mauvais paramètres"
+       11 "saisissez le nom du dossier contenant %s"
+       12 "source d'installation pour la fonctionnalité manquante"
+       13 "lecteur réseau pour la fonctionnalité manquant"
+       14 "fonctionnalité depuis:"
+       15 "sélectionnez le dossier contenant %s"
+}
diff --git a/reactos/lib/msi/msi_Pt.rc b/reactos/lib/msi/msi_Pt.rc
new file mode 100644 (file)
index 0000000..aa87ad2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Portuguese resources for MSI
+ *
+ * Copyright 2005 Marcelo Duarte
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+       5 "caminho %s não encontrado"
+       9 "insira disco %s"
+       10 "parâmetros inválidos"
+       11 "entre qual pasta contém %s"
+       12 "instalar fonte para característica faltando"
+       13 "drive de rede para  característica faltando"
+       14 "característica de:"
+       15 "escolha qual pasta contém %s"
+}
index 98e7350..eed3e54 100644 (file)
@@ -214,6 +214,8 @@ typedef struct tagMSIPACKAGE
     UINT CurrentInstallState;\r
     msi_dialog *dialog;\r
     LPWSTR next_dialog;\r
+\r
+    BOOL ExecuteSequenceRun;\r
 } MSIPACKAGE;\r
 \r
 typedef struct tagMSIPREVIEW\r
@@ -362,6 +364,7 @@ extern UINT MSIREG_OpenComponents(HKEY* key);
 extern UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);\r
 extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);\r
 extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);\r
+extern UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);\r
 \r
 /* msi dialog interface */\r
 typedef VOID (*msi_dialog_event_handler)( MSIPACKAGE*, LPCWSTR, LPCWSTR, msi_dialog* );\r
index 29665bd..cfe1ecf 100644 (file)
@@ -1,7 +1,7 @@
 /*\r
  * Implementation of the Microsoft Installer (msi.dll)\r
  *\r
- * Copyright 2002-2004 Mike McCormack for CodeWeavers\r
+ * Copyright 2002-2005 Mike McCormack for CodeWeavers\r
  *\r
  * This library is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU Lesser General Public\r
@@ -212,6 +212,9 @@ UINT MSI_IterateRecords( MSIQUERY *view, DWORD *count,
     if( count )\r
         *count = n;\r
 \r
+    if( r == ERROR_NO_MORE_ITEMS )\r
+        r = ERROR_SUCCESS;\r
+\r
     return r;\r
 }\r
 \r
@@ -420,8 +423,7 @@ UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
     msiobj_unlock( &rec->hdr );\r
 \r
 out:\r
-    if( query )\r
-        msiobj_release( &query->hdr );\r
+    msiobj_release( &query->hdr );\r
     if( rec )\r
         msiobj_release( &rec->hdr );\r
 \r
@@ -460,7 +462,10 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR
 \r
     rec = MSI_CreateRecord( count );\r
     if( !rec )\r
-        return ERROR_FUNCTION_FAILED;\r
+    {\r
+        r = ERROR_FUNCTION_FAILED;\r
+        goto out;\r
+    }\r
 \r
     for( i=0; i<count; i++ )\r
     {\r
@@ -475,8 +480,7 @@ UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hR
     *hRec = alloc_msihandle( &rec->hdr );\r
 \r
 out:\r
-    if( query )\r
-        msiobj_release( &query->hdr );\r
+    msiobj_release( &query->hdr );\r
     if( rec )\r
         msiobj_release( &rec->hdr );\r
 \r
@@ -514,8 +518,7 @@ UINT WINAPI MsiViewModify( MSIHANDLE hView, MSIMODIFY eModifyMode,
     r = view->ops->modify( view, eModifyMode, rec );\r
 \r
 out:\r
-    if( query )\r
-        msiobj_release( &query->hdr );\r
+    msiobj_release( &query->hdr );\r
     if( rec )\r
         msiobj_release( &rec->hdr );\r
 \r
@@ -574,18 +577,116 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
     return r;\r
 }\r
 \r
-UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, \r
-                    LPCSTR table, MSIHANDLE* rec)\r
+struct msi_primary_key_record_info\r
 {\r
-    FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
+    DWORD n;\r
+    MSIRECORD *rec;\r
+};\r
+\r
+static UINT msi_primary_key_iterator( MSIRECORD *rec, LPVOID param )\r
+{\r
+    struct msi_primary_key_record_info *info = param;\r
+    LPCWSTR name;\r
+    DWORD type;\r
+\r
+    type = MSI_RecordGetInteger( rec, 4 );\r
+    if( type & MSITYPE_KEY )\r
+    {\r
+        info->n++;\r
+        if( info->rec )\r
+        {\r
+            name = MSI_RecordGetString( rec, 3 );\r
+            MSI_RecordSetStringW( info->rec, info->n, name );\r
+        }\r
+    }\r
+\r
+    return ERROR_SUCCESS;\r
 }\r
 \r
-UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,\r
-                    LPCWSTR table, MSIHANDLE* rec)\r
+UINT MSI_DatabaseGetPrimaryKeys( MSIDATABASE *db,\r
+                LPCWSTR table, MSIRECORD **prec )\r
 {\r
-    FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);\r
-    return ERROR_CALL_NOT_IMPLEMENTED;\r
+    static const WCHAR sql[] = {\r
+        's','e','l','e','c','t',' ','*',' ',\r
+        'f','r','o','m',' ','`','_','C','o','l','u','m','n','s','`',' ',\r
+        'w','h','e','r','e',' ',\r
+        '`','T','a','b','l','e','`',' ','=',' ','\'','%','s','\'',0 };\r
+    struct msi_primary_key_record_info info;\r
+    MSIQUERY *query = NULL;\r
+    MSIVIEW *view;\r
+    UINT r;\r
+    \r
+    r = MSI_OpenQuery( db, &query, sql, table );\r
+    if( r != ERROR_SUCCESS )\r
+        return r;\r
+\r
+    view = query->view;\r
+\r
+    /* count the number of primary key records */\r
+    info.n = 0;\r
+    info.rec = 0;\r
+    r = MSI_IterateRecords( query, 0, msi_primary_key_iterator, &info );\r
+    if( r == ERROR_SUCCESS )\r
+    {\r
+        TRACE("Found %ld primary keys\n", info.n );\r
+\r
+        /* allocate a record and fill in the names of the tables */\r
+        info.rec = MSI_CreateRecord( info.n );\r
+        info.n = 0;\r
+        r = MSI_IterateRecords( query, 0, msi_primary_key_iterator, &info );\r
+        if( r == ERROR_SUCCESS )\r
+            *prec = info.rec;\r
+        else\r
+            msiobj_release( &info.rec->hdr );\r
+    }\r
+    msiobj_release( &query->hdr );\r
+\r
+    return r;\r
+}\r
+\r
+UINT WINAPI MsiDatabaseGetPrimaryKeysW( MSIHANDLE hdb,\r
+                    LPCWSTR table, MSIHANDLE* phRec )\r
+{\r
+    MSIRECORD *rec = NULL;\r
+    MSIDATABASE *db;\r
+    UINT r;\r
+\r
+    TRACE("%ld %s %p\n", hdb, debugstr_w(table), phRec);\r
+\r
+    db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );\r
+    if( !db )\r
+        return ERROR_INVALID_HANDLE;\r
+\r
+    r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );\r
+    if( r == ERROR_SUCCESS )\r
+    {\r
+        *phRec = alloc_msihandle( &rec->hdr );\r
+        msiobj_release( &rec->hdr );\r
+    }\r
+    msiobj_release( &db->hdr );\r
+\r
+    return r;\r
+}\r
+\r
+UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, \r
+                    LPCSTR table, MSIHANDLE* phRec)\r
+{\r
+    LPWSTR szwTable = NULL;\r
+    DWORD len;\r
+    UINT r;\r
+\r
+    TRACE("%ld %s %p\n", hdb, debugstr_a(table), phRec);\r
+\r
+    if( table )\r
+    {\r
+        len = MultiByteToWideChar( CP_ACP, 0, table, -1, NULL, 0 );\r
+        szwTable = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );\r
+        MultiByteToWideChar( CP_ACP, 0, table, -1, szwTable, len );\r
+    }\r
+    r = MsiDatabaseGetPrimaryKeysW( hdb, szwTable, phRec );\r
+    HeapFree( GetProcessHeap(), 0, szwTable );\r
+\r
+    return r;\r
 }\r
 \r
 UINT WINAPI MsiDatabaseIsTablePersistentA(\r
index 72d1a8d..60f939e 100644 (file)
@@ -60,7 +60,7 @@ void MSI_FreePackage( MSIOBJECTHDR *arg)
     msiobj_release( &package->db->hdr );\r
 }\r
 \r
-static const UINT clone_properties(MSIDATABASE *db)\r
+static UINT clone_properties(MSIDATABASE *db)\r
 {\r
     MSIQUERY * view = NULL;\r
     UINT rc;\r
@@ -617,7 +617,7 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
 \r
     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );\r
     if( !package )\r
-        goto out;\r
+        return ERROR_INVALID_HANDLE;\r
 \r
     record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );\r
     if( !record )\r
@@ -626,8 +626,7 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
     ret = MSI_ProcessMessage( package, eMessageType, record );\r
 \r
 out:\r
-    if( package )\r
-        msiobj_release( &package->hdr );\r
+    msiobj_release( &package->hdr );\r
     if( record )\r
         msiobj_release( &record->hdr );\r
 \r
index 03c7436..5df8ef0 100644 (file)
@@ -77,6 +77,7 @@ UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview )
         msiobj_release( &preview->hdr );
         r = ERROR_SUCCESS;
     }
+    msiobj_release( &db->hdr );
 
     return r;
 }
index dfe5816..b66cc58 100644 (file)
@@ -131,6 +131,8 @@ UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
 UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table,\r
                         column_assignment *list, struct expr *expr );\r
 \r
+UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );\r
+\r
 void delete_expr( struct expr *e );\r
 void delete_string_list( string_list *sl );\r
 void delete_value_list( value_list *vl );\r
index 967017c..99722e3 100644 (file)
@@ -210,6 +210,7 @@ UINT WINAPI MsiRecordClearData( MSIHANDLE handle )
         rec->fields[i].u.iVal = 0;\r
     }\r
     msiobj_unlock( &rec->hdr );\r
+    msiobj_release( &rec->hdr );\r
 \r
     return ERROR_SUCCESS;\r
 }\r
index 61c03c6..ad3fa1c 100644 (file)
@@ -117,6 +117,23 @@ static const WCHAR szInstaller_Products_fmt[] = {
 'P','r','o','d','u','c','t','s','\\',
 '%','s',0};
 
+static const WCHAR szInstaller_UpgradeCodes[] = {
+'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','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'U','p','g','r','a','d','e','C','o','d','e','s',0};
+
+static const WCHAR szInstaller_UpgradeCodes_fmt[] = {
+'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','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'U','p','g','r','a','d','e','C','o','d','e','s','\\',
+'%','s',0};
+
 BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
 {
     DWORD i,n=0;
@@ -389,6 +406,26 @@ UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
     return rc;
 }
 
+UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n",debugstr_w(szUpgradeCode));
+    squash_guid(szUpgradeCode,squished_pc);
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath,szInstaller_UpgradeCodes_fmt,squished_pc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+
+    return rc;
+}
+
 /*************************************************************************
  *  MsiDecomposeDescriptorW   [MSI.@]
  *
@@ -484,3 +521,281 @@ UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct,
 
     return r;
 }
+
+UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
+{
+    DWORD r;
+    WCHAR szwGuid[GUID_SIZE];
+
+    TRACE("%ld %p\n",index,lpguid);
+    
+    if (NULL == lpguid)
+        return ERROR_INVALID_PARAMETER;
+    r = MsiEnumProductsW(index, szwGuid);
+    if( r == ERROR_SUCCESS )
+        WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
+{
+    HKEY hkeyFeatures = 0;
+    DWORD r;
+    WCHAR szKeyName[33];
+
+    TRACE("%ld %p\n",index,lpguid);
+
+    if (NULL == lpguid)
+        return ERROR_INVALID_PARAMETER;
+
+    r = MSIREG_OpenFeatures(&hkeyFeatures);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
+
+    unsquash_guid(szKeyName, lpguid);
+
+end:
+
+    if( hkeyFeatures )
+        RegCloseKey(hkeyFeatures);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index, 
+      LPSTR szFeature, LPSTR szParent)
+{
+    DWORD r;
+    WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
+    LPWSTR szwProduct = NULL;
+
+    TRACE("%s %ld %p %p\n",debugstr_a(szProduct),index,szFeature,szParent);
+
+    if( szProduct )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        if( szwProduct )
+            MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+        else
+            return ERROR_FUNCTION_FAILED;
+    }
+
+    r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
+    if( r == ERROR_SUCCESS )
+    {
+        WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
+                            szFeature, GUID_SIZE, NULL, NULL);
+        WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
+                            szParent, GUID_SIZE, NULL, NULL);
+    }
+
+    HeapFree( GetProcessHeap(), 0, szwProduct);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index, 
+      LPWSTR szFeature, LPWSTR szParent)
+{
+    HKEY hkeyProduct = 0;
+    DWORD r, sz;
+
+    TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
+
+    r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    sz = GUID_SIZE;
+    r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
+
+end:
+    if( hkeyProduct )
+        RegCloseKey(hkeyProduct);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
+{
+    DWORD r;
+    WCHAR szwGuid[GUID_SIZE];
+
+    TRACE("%ld %p\n",index,lpguid);
+
+    r = MsiEnumComponentsW(index, szwGuid);
+    if( r == ERROR_SUCCESS )
+        WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
+{
+    HKEY hkeyComponents = 0;
+    DWORD r;
+    WCHAR szKeyName[33];
+
+    TRACE("%ld %p\n",index,lpguid);
+
+    r = MSIREG_OpenComponents(&hkeyComponents);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    r = RegEnumKeyW(hkeyComponents, index, szKeyName, GUID_SIZE);
+
+    unsquash_guid(szKeyName, lpguid);
+
+end:
+
+    if( hkeyComponents )
+        RegCloseKey(hkeyComponents);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
+{
+    DWORD r;
+    WCHAR szwProduct[GUID_SIZE];
+    LPWSTR szwComponent = NULL;
+
+    TRACE("%s %ld %p\n",debugstr_a(szComponent),index,szProduct);
+
+    if( szComponent )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
+        szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        if( szwComponent )
+            MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
+        else
+            return ERROR_FUNCTION_FAILED;
+    }
+
+    r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
+    if( r == ERROR_SUCCESS )
+    {
+        WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,
+                            szProduct, GUID_SIZE, NULL, NULL);
+    }
+
+    HeapFree( GetProcessHeap(), 0, szwComponent);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
+{
+    HKEY hkeyComp = 0;
+    DWORD r, sz;
+    WCHAR szValName[GUID_SIZE];
+
+    TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
+
+    r = MSIREG_OpenComponentsKey(szComponent,&hkeyComp,FALSE);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    sz = GUID_SIZE;
+    r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
+    if( r != ERROR_SUCCESS )
+        goto end;
+
+    unsquash_guid(szValName, szProduct);
+
+end:
+    if( hkeyComp )
+        RegCloseKey(hkeyComp);
+
+    return r;
+}
+
+UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex,
+                LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
+                LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
+{
+    FIXME("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex,
+          lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
+          pcchApplicationDataBuf);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex,
+                LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
+                LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )
+{
+    FIXME("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,
+          lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
+          pcchApplicationDataBuf);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
+                                    DWORD iProductIndex, LPWSTR lpProductBuf)
+{
+    UINT rc;
+    HKEY hkey;
+    WCHAR szKeyName[33];
+
+    TRACE("%s %lu %lu %p\n", debugstr_w(szUpgradeCode), dwReserved,
+          iProductIndex, lpProductBuf);
+
+    if (NULL == szUpgradeCode)
+        return ERROR_INVALID_PARAMETER;
+    if (NULL == lpProductBuf)
+        return ERROR_INVALID_PARAMETER;
+    rc = MSIREG_OpenUpgradeCodesKey(szUpgradeCode, &hkey, FALSE);
+    if (rc != ERROR_SUCCESS)
+    {
+        rc = ERROR_NO_MORE_ITEMS;
+        goto end;
+    }
+
+    rc = RegEnumKeyW(hkey, iProductIndex, szKeyName,
+     sizeof(szKeyName) / sizeof(szKeyName[0]));
+
+    unsquash_guid(szKeyName, lpProductBuf);
+    RegCloseKey(hkey);
+
+end:
+    return rc;
+}
+
+UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,
+                                    DWORD iProductIndex, LPSTR lpProductBuf)
+{
+    UINT rc;
+    int len;
+    LPWSTR szUpgradeCodeW = NULL;
+
+    TRACE("%s %lu %lu %p\n", debugstr_a(szUpgradeCode), dwReserved,
+          iProductIndex, lpProductBuf);
+    if (!szUpgradeCode)
+        return ERROR_INVALID_PARAMETER;
+    len = MultiByteToWideChar(CP_ACP, 0, szUpgradeCode, -1, NULL, 0);
+    szUpgradeCodeW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
+     len * sizeof(WCHAR));
+    if (szUpgradeCodeW)
+    {
+        WCHAR productW[39];
+
+        MultiByteToWideChar(CP_ACP, 0, szUpgradeCode, -1, szUpgradeCodeW, len);
+        rc = MsiEnumRelatedProductsW(szUpgradeCodeW, dwReserved,
+         iProductIndex, productW);
+        if (rc == ERROR_SUCCESS)
+        {
+            LPWSTR ptr;
+
+            for (ptr = productW; *ptr; )
+                *lpProductBuf++ = *ptr++;
+        }
+        HeapFree(GetProcessHeap(), 0, szUpgradeCodeW);
+    }
+    else
+        rc = ERROR_OUTOFMEMORY;
+    return rc;
+}
index 478856d..874691c 100644 (file)
@@ -562,18 +562,18 @@ union yyalloc
 #endif
 
 /* YYFINAL -- State number of the termination state. */
-#define YYFINAL  23
+#define YYFINAL  27
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   126
+#define YYLAST   128
 
 /* YYNTOKENS -- Number of terminals. */
 #define YYNTOKENS  147
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  25
+#define YYNNTS  26
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  63
+#define YYNRULES  65
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  123
+#define YYNSTATES  126
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -633,53 +633,53 @@ static const unsigned char yytranslate[] =
    YYRHS.  */
 static const unsigned char yyprhs[] =
 {
-       0,     0,     3,     5,     7,     9,    11,    22,    34,    41,
-      49,    56,    61,    66,    69,    71,    74,    76,    80,    82,
-      87,    89,    91,    93,    95,    97,    99,   104,   106,   110,
-     115,   117,   121,   123,   126,   131,   135,   139,   143,   147,
-     151,   155,   159,   163,   167,   171,   175,   180,   182,   184,
-     186,   190,   192,   196,   200,   202,   205,   207,   209,   211,
-     215,   217,   219,   221
+       0,     0,     3,     5,     7,     9,    11,    13,    24,    36,
+      43,    51,    58,    61,    66,    71,    74,    76,    79,    81,
+      85,    87,    92,    94,    96,    98,   100,   102,   104,   109,
+     111,   115,   120,   122,   126,   128,   131,   136,   140,   144,
+     148,   152,   156,   160,   164,   168,   172,   176,   180,   185,
+     187,   189,   191,   195,   197,   201,   205,   207,   210,   212,
+     214,   216,   220,   222,   224,   226
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const short yyrhs[] =
 {
-     148,     0,    -1,   158,    -1,   150,    -1,   149,    -1,   151,
-      -1,    67,    72,   170,    83,   160,   110,   134,    83,   164,
-     110,    -1,    67,    72,   170,    83,   160,   110,   134,    83,
-     164,   110,   122,    -1,    31,   121,   170,    83,   152,   110,
-      -1,    31,   121,   170,    83,   152,   110,    59,    -1,   130,
-     170,   114,   165,   137,   162,    -1,   153,   102,    77,   160,
-      -1,   153,    24,   169,   154,    -1,   169,   154,    -1,   155,
-      -1,   155,    86,    -1,   156,    -1,   156,    90,    92,    -1,
-      19,    -1,    19,    83,   157,   110,    -1,    82,    -1,   115,
-      -1,    69,    -1,    81,    -1,    93,    -1,    70,    -1,   159,
-      99,    16,   160,    -1,   159,    -1,   112,   160,   161,    -1,
-     112,    38,   160,   161,    -1,   169,    -1,   169,    24,   160,
-      -1,   118,    -1,    52,   170,    -1,    52,   170,   137,   162,
-      -1,    83,   162,   110,    -1,   168,    45,   168,    -1,   162,
-       7,   162,    -1,   162,    97,   162,    -1,   168,    45,   163,
-      -1,   168,    57,   163,    -1,   168,    85,   163,    -1,   168,
-      78,   163,    -1,   168,    54,   163,    -1,   168,    89,   163,
-      -1,   168,    73,    92,    -1,   168,    73,    90,    92,    -1,
-     168,    -1,   167,    -1,   167,    -1,   167,    24,   164,    -1,
-     166,    -1,   166,    24,   165,    -1,   169,    45,   167,    -1,
-      70,    -1,    88,    70,    -1,   120,    -1,   138,    -1,   169,
-      -1,   170,    39,   171,    -1,   171,    -1,   171,    -1,    66,
-      -1,   120,    -1
+     148,     0,    -1,   159,    -1,   150,    -1,   149,    -1,   151,
+      -1,   152,    -1,    67,    72,   171,    83,   161,   110,   134,
+      83,   165,   110,    -1,    67,    72,   171,    83,   161,   110,
+     134,    83,   165,   110,   122,    -1,    31,   121,   171,    83,
+     153,   110,    -1,    31,   121,   171,    83,   153,   110,    59,
+      -1,   130,   171,   114,   166,   137,   163,    -1,    35,   162,
+      -1,   154,   102,    77,   161,    -1,   154,    24,   170,   155,
+      -1,   170,   155,    -1,   156,    -1,   156,    86,    -1,   157,
+      -1,   157,    90,    92,    -1,    19,    -1,    19,    83,   158,
+     110,    -1,    82,    -1,   115,    -1,    69,    -1,    81,    -1,
+      93,    -1,    70,    -1,   160,    99,    16,   161,    -1,   160,
+      -1,   112,   161,   162,    -1,   112,    38,   161,   162,    -1,
+     170,    -1,   170,    24,   161,    -1,   118,    -1,    52,   171,
+      -1,    52,   171,   137,   163,    -1,    83,   163,   110,    -1,
+     169,    45,   169,    -1,   163,     7,   163,    -1,   163,    97,
+     163,    -1,   169,    45,   164,    -1,   169,    57,   164,    -1,
+     169,    85,   164,    -1,   169,    78,   164,    -1,   169,    54,
+     164,    -1,   169,    89,   164,    -1,   169,    73,    92,    -1,
+     169,    73,    90,    92,    -1,   169,    -1,   168,    -1,   168,
+      -1,   168,    24,   165,    -1,   167,    -1,   167,    24,   166,
+      -1,   170,    45,   168,    -1,    70,    -1,    88,    70,    -1,
+     120,    -1,   138,    -1,   170,    -1,   171,    39,   172,    -1,
+     172,    -1,   172,    -1,    66,    -1,   120,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short yyrline[] =
 {
-       0,   142,   142,   147,   152,   157,   165,   173,   184,   194,
-     207,   218,   228,   247,   259,   263,   271,   275,   282,   286,
-     290,   294,   298,   302,   306,   313,   324,   335,   339,   353,
-     371,   384,   397,   404,   415,   434,   438,   442,   446,   450,
-     454,   458,   462,   466,   470,   474,   478,   485,   486,   490,
-     502,   517,   518,   527,   543,   547,   551,   555,   562,   569,
-     573,   580,   587,   591
+       0,   143,   143,   148,   153,   158,   163,   171,   179,   190,
+     200,   213,   224,   235,   245,   264,   276,   280,   288,   292,
+     299,   303,   307,   311,   315,   319,   323,   330,   341,   352,
+     356,   370,   388,   401,   414,   421,   432,   451,   455,   459,
+     463,   467,   471,   475,   479,   483,   487,   491,   495,   502,
+     503,   507,   519,   534,   535,   544,   560,   564,   568,   572,
+     579,   586,   590,   597,   604,   608
 };
 #endif
 
@@ -716,11 +716,11 @@ static const char *const yytname[] =
   "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", "TK_WHEN", "TK_WHERE", 
   "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN", "FUNCTION", "COMMENT", 
   "UNCLOSED_STRING", "SPACE", "ILLEGAL", "END_OF_FILE", "$accept", 
-  "onequery", "oneinsert", "onecreate", "oneupdate", "table_def", 
-  "column_def", "column_type", "data_type_l", "data_type", "data_count", 
-  "oneselect", "unorderedsel", "selcollist", "from", "expr", "val", 
-  "constlist", "update_assign_list", "column_assignment", "const_val", 
-  "column_val", "column", "table", "string_or_id", 0
+  "onequery", "oneinsert", "onecreate", "oneupdate", "onedelete", 
+  "table_def", "column_def", "column_type", "data_type_l", "data_type", 
+  "data_count", "oneselect", "unorderedsel", "selcollist", "from", "expr", 
+  "val", "constlist", "update_assign_list", "column_assignment", 
+  "const_val", "column_val", "column", "table", "string_or_id", 0
 };
 #endif
 
@@ -750,25 +750,25 @@ static const unsigned short yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,   147,   148,   148,   148,   148,   149,   149,   150,   150,
-     151,   152,   153,   153,   154,   154,   155,   155,   156,   156,
-     156,   156,   156,   156,   156,   157,   158,   158,   159,   159,
-     160,   160,   160,   161,   161,   162,   162,   162,   162,   162,
-     162,   162,   162,   162,   162,   162,   162,   163,   163,   164,
-     164,   165,   165,   166,   167,   167,   167,   167,   168,   169,
-     169,   170,   171,   171
+       0,   147,   148,   148,   148,   148,   148,   149,   149,   150,
+     150,   151,   152,   153,   154,   154,   155,   155,   156,   156,
+     157,   157,   157,   157,   157,   157,   157,   158,   159,   159,
+     160,   160,   161,   161,   161,   162,   162,   163,   163,   163,
+     163,   163,   163,   163,   163,   163,   163,   163,   163,   164,
+     164,   165,   165,   166,   166,   167,   168,   168,   168,   168,
+     169,   170,   170,   171,   172,   172
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const unsigned char yyr2[] =
 {
-       0,     2,     1,     1,     1,     1,    10,    11,     6,     7,
-       6,     4,     4,     2,     1,     2,     1,     3,     1,     4,
-       1,     1,     1,     1,     1,     1,     4,     1,     3,     4,
-       1,     3,     1,     2,     4,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     4,     1,     1,     1,
-       3,     1,     3,     3,     1,     2,     1,     1,     1,     3,
-       1,     1,     1,     1
+       0,     2,     1,     1,     1,     1,     1,    10,    11,     6,
+       7,     6,     2,     4,     4,     2,     1,     2,     1,     3,
+       1,     4,     1,     1,     1,     1,     1,     1,     4,     1,
+       3,     4,     1,     3,     1,     2,     4,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     4,     1,
+       1,     1,     3,     1,     3,     3,     1,     2,     1,     1,
+       1,     3,     1,     1,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -776,113 +776,113 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       0,     0,     0,     0,     0,     0,     4,     3,     5,     2,
-      27,     0,     0,     0,    62,    32,    63,     0,    30,     0,
-      60,     0,    61,     1,     0,     0,     0,     0,     0,    28,
-       0,     0,     0,     0,     0,     0,    29,    33,    31,    59,
-       0,    51,     0,    26,     0,     0,     0,     0,     0,     0,
-       0,     0,     8,     0,     0,    18,    22,    23,    20,    24,
-      21,    13,    14,    16,     0,     0,    34,     0,    58,    10,
-      52,    54,     0,    56,    57,    53,     9,     0,     0,     0,
-      15,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    55,    12,    11,    25,     0,    17,     0,
-      35,    37,    38,    56,    39,    48,    36,    43,    47,    40,
-       0,    45,    42,    41,    44,    19,     0,    49,    46,     6,
-       0,     7,    50
+       0,     0,     0,     0,     0,     0,     0,     4,     3,     5,
+       6,     2,    29,     0,     0,    12,     0,     0,    64,    34,
+      65,     0,    32,     0,    62,     0,    63,     1,     0,     0,
+      35,     0,     0,    30,     0,     0,     0,     0,     0,     0,
+       0,    31,    33,    61,     0,    53,     0,    28,     0,     0,
+       0,     0,    36,     0,    60,     0,     0,     0,     0,     9,
+       0,     0,    20,    24,    25,    22,    26,    23,    15,    16,
+      18,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    11,    54,    56,     0,    58,    59,    55,    10,
+       0,     0,     0,    17,     0,    37,    39,    40,    58,    41,
+      50,    38,    45,    49,    42,     0,    47,    44,    43,    46,
+       0,    57,    14,    13,    27,     0,    19,    48,     0,    21,
+       0,    51,     7,     0,     8,    52
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const yysigned_char yydefgoto[] =
 {
-      -1,     5,     6,     7,     8,    44,    45,    61,    62,    63,
-      97,     9,    10,    17,    29,    66,   104,   116,    40,    41,
-     105,    67,    68,    19,    20
+      -1,     6,     7,     8,     9,    10,    48,    49,    68,    69,
+      70,   115,    11,    12,    21,    15,    52,    99,   120,    44,
+      45,   100,    53,    54,    23,    24
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -104
+#define YYPACT_NINF -106
 static const yysigned_char yypact[] =
 {
-     -30,  -103,   -52,   -34,   -51,    21,  -104,  -104,  -104,  -104,
-     -70,   -51,   -51,   -57,  -104,  -104,  -104,   -26,    11,    -6,
-      -1,   -69,  -104,  -104,    32,   -25,   -15,   -26,   -51,  -104,
-     -57,   -51,   -51,   -57,   -51,   -57,  -104,   -71,  -104,  -104,
-     -67,    47,    27,  -104,   -36,   -19,   -17,   -29,   -53,   -53,
-     -51,   -63,    26,   -51,    17,   -10,  -104,  -104,  -104,  -104,
-    -104,  -104,     5,     7,   -35,   -53,    -4,    35,  -104,    -4,
-    -104,  -104,    37,  -104,  -104,  -104,  -104,   -17,   -57,    39,
-    -104,    18,    28,    -7,   -53,   -53,   -60,   -60,   -60,   -73,
-     -60,   -60,   -60,  -104,  -104,  -104,  -104,     4,  -104,   -63,
-    -104,    -4,    -4,    77,  -104,  -104,  -104,  -104,  -104,  -104,
-      25,  -104,  -104,  -104,  -104,  -104,     8,    95,  -104,     0,
-     -63,  -104,  -104
+     -30,  -105,   -33,   -54,   -34,   -51,    22,  -106,  -106,  -106,
+    -106,  -106,   -79,   -51,   -51,  -106,   -51,   -60,  -106,  -106,
+    -106,   -33,    17,    10,    11,   -63,  -106,  -106,    41,   -24,
+     -75,   -13,   -33,  -106,   -60,   -51,   -51,   -60,   -51,   -45,
+     -60,  -106,  -106,  -106,   -65,    50,    32,  -106,   -32,   -15,
+     -17,   -45,    -4,    26,  -106,   -22,   -45,   -51,   -59,    30,
+     -51,    24,    19,  -106,  -106,  -106,  -106,  -106,  -106,    21,
+      15,    -7,   -45,   -45,   -53,   -53,   -53,   -78,   -53,   -53,
+     -53,   -28,    -4,  -106,  -106,    46,  -106,  -106,  -106,  -106,
+     -17,   -60,    47,  -106,    27,  -106,    -4,    -4,    79,  -106,
+    -106,  -106,  -106,  -106,  -106,    28,  -106,  -106,  -106,  -106,
+      38,  -106,  -106,  -106,  -106,    12,  -106,  -106,   -59,  -106,
+      13,   100,     3,   -59,  -106,  -106
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yysigned_char yypgoto[] =
 {
-    -104,  -104,  -104,  -104,  -104,  -104,  -104,    44,  -104,  -104,
-    -104,  -104,  -104,     1,    96,   -38,    14,     6,    75,  -104,
-     -43,   -37,     9,    12,    84
+    -106,  -106,  -106,  -106,  -106,  -106,  -106,  -106,    36,  -106,
+    -106,  -106,  -106,  -106,   -10,     7,   -25,    16,     4,    71,
+    -106,   -50,    34,     6,    40,    20
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -64
+#define YYTABLE_NINF -66
 static const yysigned_char yytable[] =
 {
-      84,     1,    55,    84,    13,    53,    14,    71,    75,    14,
-      71,    69,    18,    14,    27,    14,    21,   110,    11,   111,
-      12,    23,    18,    25,    26,    72,    28,    83,    72,    24,
-      65,    38,    14,    31,    43,    30,    47,     2,   -61,    18,
-      37,    42,    18,    46,    18,    32,   101,   102,    33,   106,
-     108,   108,    56,   108,   108,   108,   117,    73,    34,    42,
-     103,    15,    77,    16,    57,    58,    48,    16,    35,    16,
-      49,    50,    51,    79,    52,    74,    59,   117,    74,    95,
-      86,    64,     3,    54,    15,    76,    16,    18,    22,    87,
-      85,    80,    88,    85,    78,    22,    22,    81,    60,    82,
-       4,   107,   109,   100,   112,   113,   114,    93,    89,    96,
-      98,    99,    22,    90,   115,    39,   -63,   118,   119,   120,
-      91,    94,   121,    36,    92,    70,   122
+      72,     1,    62,    72,    17,     2,    18,    32,    88,    60,
+      22,    84,   105,    18,   106,    18,    13,    84,    16,    14,
+      28,    18,    27,    22,    42,    26,    71,    47,    33,    85,
+      55,    82,    18,    26,    26,    85,    26,     3,    51,    41,
+      22,    34,    46,    22,    50,    25,    22,    96,    97,    35,
+     -63,    36,    63,    29,    30,    43,    31,    37,    19,    38,
+      20,    86,    39,    46,    64,    65,    90,    98,   121,    20,
+      40,    74,    56,   121,    57,    20,    66,    58,    59,    87,
+      75,   113,     4,    76,    19,    87,    20,    61,    81,    89,
+      73,   102,   104,    73,   107,   108,   109,    22,    67,    77,
+       5,    91,    92,    95,    78,    94,   110,    93,   101,   103,
+     103,    79,   103,   103,   103,    80,   111,   114,   -65,   116,
+     117,   118,   119,   122,   123,   124,   112,   125,    83
 };
 
 static const unsigned char yycheck[] =
 {
-       7,    31,    19,     7,    38,    24,    66,    70,    51,    66,
-      70,    49,     3,    66,    13,    66,     4,    90,   121,    92,
-      72,     0,    13,    11,    12,    88,    52,    65,    88,    99,
-      83,    30,    66,    39,    33,    24,    35,    67,    39,    30,
-      28,    32,    33,    34,    35,   114,    84,    85,    16,    86,
-      87,    88,    69,    90,    91,    92,    99,   120,    83,    50,
-     120,   118,    53,   120,    81,    82,   137,   120,    83,   120,
-     137,    24,    45,    83,   110,   138,    93,   120,   138,    78,
-      45,   110,   112,   102,   118,    59,   120,    78,     4,    54,
-      97,    86,    57,    97,    77,    11,    12,    90,   115,   134,
-     130,    87,    88,   110,    90,    91,    92,    70,    73,    70,
-      92,    83,    28,    78,   110,    31,    39,    92,   110,    24,
-      85,    77,   122,    27,    89,    50,   120
+       7,    31,    19,     7,    38,    35,    66,    17,    58,    24,
+       4,    70,    90,    66,    92,    66,   121,    70,    72,    52,
+      99,    66,     0,    17,    34,     5,    51,    37,    21,    88,
+      40,    56,    66,    13,    14,    88,    16,    67,    83,    32,
+      34,    24,    36,    37,    38,     5,    40,    72,    73,    39,
+      39,   114,    69,    13,    14,    35,    16,    16,   118,    83,
+     120,   120,   137,    57,    81,    82,    60,   120,   118,   120,
+      83,    45,   137,   123,    24,   120,    93,    45,   110,   138,
+      54,    91,   112,    57,   118,   138,   120,   102,   110,    59,
+      97,    75,    76,    97,    78,    79,    80,    91,   115,    73,
+     130,    77,    83,   110,    78,    90,   134,    86,    74,    75,
+      76,    85,    78,    79,    80,    89,    70,    70,    39,    92,
+      92,    83,   110,   110,    24,   122,    90,   123,    57
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,    31,    67,   112,   130,   148,   149,   150,   151,   158,
-     159,   121,    72,    38,    66,   118,   120,   160,   169,   170,
-     171,   170,   171,     0,    99,   170,   170,   160,    52,   161,
-      24,    39,   114,    16,    83,    83,   161,   170,   160,   171,
-     165,   166,   169,   160,   152,   153,   169,   160,   137,   137,
-      24,    45,   110,    24,   102,    19,    69,    81,    82,    93,
-     115,   154,   155,   156,   110,    83,   162,   168,   169,   162,
-     165,    70,    88,   120,   138,   167,    59,   169,    77,    83,
-      86,    90,   134,   162,     7,    97,    45,    54,    57,    73,
-      78,    85,    89,    70,   154,   160,    70,   157,    92,    83,
-     110,   162,   162,   120,   163,   167,   168,   163,   168,   163,
-      90,    92,   163,   163,   163,   110,   164,   167,    92,   110,
-      24,   122,   164
+       0,    31,    35,    67,   112,   130,   148,   149,   150,   151,
+     152,   159,   160,   121,    52,   162,    72,    38,    66,   118,
+     120,   161,   170,   171,   172,   171,   172,     0,    99,   171,
+     171,   171,   161,   162,    24,    39,   114,    16,    83,   137,
+      83,   162,   161,   172,   166,   167,   170,   161,   153,   154,
+     170,    83,   163,   169,   170,   161,   137,    24,    45,   110,
+      24,   102,    19,    69,    81,    82,    93,   115,   155,   156,
+     157,   163,     7,    97,    45,    54,    57,    73,    78,    85,
+      89,   110,   163,   166,    70,    88,   120,   138,   168,    59,
+     170,    77,    83,    86,    90,   110,   163,   163,   120,   164,
+     168,   169,   164,   169,   164,    90,    92,   164,   164,   164,
+     134,    70,   155,   161,    70,   158,    92,    92,    83,   110,
+     165,   168,   110,    24,   122,   165
 };
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -1493,7 +1493,7 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 143 "./sql.y"
+#line 144 "./sql.y"
     {
         SQL_input* sql = (SQL_input*) info;
         *sql->view = yyvsp[0].query;
@@ -1501,7 +1501,7 @@ yyreduce:
     break;
 
   case 3:
-#line 148 "./sql.y"
+#line 149 "./sql.y"
     {
         SQL_input* sql = (SQL_input*) info;
         *sql->view = yyvsp[0].query;
@@ -1509,7 +1509,7 @@ yyreduce:
     break;
 
   case 4:
-#line 153 "./sql.y"
+#line 154 "./sql.y"
     {
         SQL_input* sql = (SQL_input*) info;
         *sql->view = yyvsp[0].query;
@@ -1517,7 +1517,7 @@ yyreduce:
     break;
 
   case 5:
-#line 158 "./sql.y"
+#line 159 "./sql.y"
     {
         SQL_input* sql = (SQL_input*) info;
         *sql->view = yyvsp[0].query;
@@ -1525,7 +1525,15 @@ yyreduce:
     break;
 
   case 6:
-#line 166 "./sql.y"
+#line 164 "./sql.y"
+    {
+        SQL_input* sql = (SQL_input*) info;
+        *sql->view = yyvsp[0].query;
+    ;}
+    break;
+
+  case 7:
+#line 172 "./sql.y"
     {
         SQL_input *sql = (SQL_input*) info;
         MSIVIEW *insert = NULL; 
@@ -1535,8 +1543,8 @@ yyreduce:
     ;}
     break;
 
-  case 7:
-#line 174 "./sql.y"
+  case 8:
+#line 180 "./sql.y"
     {
         SQL_input *sql = (SQL_input*) info;
         MSIVIEW *insert = NULL; 
@@ -1546,8 +1554,8 @@ yyreduce:
     ;}
     break;
 
-  case 8:
-#line 185 "./sql.y"
+  case 9:
+#line 191 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL; 
@@ -1559,8 +1567,8 @@ yyreduce:
         ;}
     break;
 
-  case 9:
-#line 195 "./sql.y"
+  case 10:
+#line 201 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *create = NULL; 
@@ -1572,8 +1580,8 @@ yyreduce:
         ;}
     break;
 
-  case 10:
-#line 208 "./sql.y"
+  case 11:
+#line 214 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *update = NULL; 
@@ -1583,8 +1591,19 @@ yyreduce:
         ;}
     break;
 
-  case 11:
-#line 219 "./sql.y"
+  case 12:
+#line 225 "./sql.y"
+    {
+            SQL_input* sql = (SQL_input*) info;
+            MSIVIEW *delete = NULL; 
+
+            DELETE_CreateView( sql->db, &delete, yyvsp[0].query );
+            yyval.query = delete;
+        ;}
+    break;
+
+  case 13:
+#line 236 "./sql.y"
     {
             if( SQL_MarkPrimaryKeys( yyvsp[-3].column_info, yyvsp[0].column_list ) )
                 yyval.column_info = yyvsp[-3].column_info;
@@ -1593,8 +1612,8 @@ yyreduce:
         ;}
     break;
 
-  case 12:
-#line 229 "./sql.y"
+  case 14:
+#line 246 "./sql.y"
     {
             create_col_info *ci;
 
@@ -1615,8 +1634,8 @@ yyreduce:
         ;}
     break;
 
-  case 13:
-#line 248 "./sql.y"
+  case 15:
+#line 265 "./sql.y"
     {
             yyval.column_info = HeapAlloc( GetProcessHeap(), 0, sizeof *yyval.column_info );
             if( ! yyval.column_info )
@@ -1627,86 +1646,86 @@ yyreduce:
         ;}
     break;
 
-  case 14:
-#line 260 "./sql.y"
+  case 16:
+#line 277 "./sql.y"
     {
             yyval.column_type = yyvsp[0].column_type | MSITYPE_VALID;
         ;}
     break;
 
-  case 15:
-#line 264 "./sql.y"
+  case 17:
+#line 281 "./sql.y"
     {
             FIXME("LOCALIZABLE ignored\n");
             yyval.column_type = yyvsp[-1].column_type | MSITYPE_VALID;
         ;}
     break;
 
-  case 16:
-#line 272 "./sql.y"
+  case 18:
+#line 289 "./sql.y"
     {
             yyval.column_type |= MSITYPE_NULLABLE;
         ;}
     break;
 
-  case 17:
-#line 276 "./sql.y"
+  case 19:
+#line 293 "./sql.y"
     {
             yyval.column_type = yyvsp[-2].column_type;
         ;}
     break;
 
-  case 18:
-#line 283 "./sql.y"
+  case 20:
+#line 300 "./sql.y"
     {
             yyval.column_type = MSITYPE_STRING | 1;
         ;}
     break;
 
-  case 19:
-#line 287 "./sql.y"
+  case 21:
+#line 304 "./sql.y"
     {
             yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type;
         ;}
     break;
 
-  case 20:
-#line 291 "./sql.y"
+  case 22:
+#line 308 "./sql.y"
     {
             yyval.column_type = 2;
         ;}
     break;
 
-  case 21:
-#line 295 "./sql.y"
+  case 23:
+#line 312 "./sql.y"
     {
             yyval.column_type = 2;
         ;}
     break;
 
-  case 22:
-#line 299 "./sql.y"
+  case 24:
+#line 316 "./sql.y"
     {
             yyval.column_type = 2;
         ;}
     break;
 
-  case 23:
-#line 303 "./sql.y"
+  case 25:
+#line 320 "./sql.y"
     {
             yyval.column_type = 4;
         ;}
     break;
 
-  case 24:
-#line 307 "./sql.y"
+  case 26:
+#line 324 "./sql.y"
     {
             yyval.column_type = 0;
         ;}
     break;
 
-  case 25:
-#line 314 "./sql.y"
+  case 27:
+#line 331 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             int val = SQL_getint(sql);
@@ -1716,8 +1735,8 @@ yyreduce:
         ;}
     break;
 
-  case 26:
-#line 325 "./sql.y"
+  case 28:
+#line 342 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
 
@@ -1730,8 +1749,8 @@ yyreduce:
         ;}
     break;
 
-  case 28:
-#line 340 "./sql.y"
+  case 30:
+#line 357 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             if( !yyvsp[0].query )
@@ -1747,8 +1766,8 @@ yyreduce:
         ;}
     break;
 
-  case 29:
-#line 354 "./sql.y"
+  case 31:
+#line 371 "./sql.y"
     {
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *view = yyvsp[0].query;
@@ -1765,8 +1784,8 @@ yyreduce:
         ;}
     break;
 
-  case 30:
-#line 372 "./sql.y"
+  case 32:
+#line 389 "./sql.y"
     { 
             string_list *list;
 
@@ -1781,8 +1800,8 @@ yyreduce:
         ;}
     break;
 
-  case 31:
-#line 385 "./sql.y"
+  case 33:
+#line 402 "./sql.y"
     { 
             string_list *list;
 
@@ -1797,15 +1816,15 @@ yyreduce:
         ;}
     break;
 
-  case 32:
-#line 398 "./sql.y"
+  case 34:
+#line 415 "./sql.y"
     {
             yyval.column_list = NULL;
         ;}
     break;
 
-  case 33:
-#line 405 "./sql.y"
+  case 35:
+#line 422 "./sql.y"
     { 
             SQL_input* sql = (SQL_input*) info;
             UINT r;
@@ -1818,8 +1837,8 @@ yyreduce:
         ;}
     break;
 
-  case 34:
-#line 416 "./sql.y"
+  case 36:
+#line 433 "./sql.y"
     { 
             SQL_input* sql = (SQL_input*) info;
             MSIVIEW *view = NULL;
@@ -1837,92 +1856,92 @@ yyreduce:
         ;}
     break;
 
-  case 35:
-#line 435 "./sql.y"
+  case 37:
+#line 452 "./sql.y"
     {
             yyval.expr = yyvsp[-1].expr;
         ;}
     break;
 
-  case 36:
-#line 439 "./sql.y"
+  case 38:
+#line 456 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
         ;}
     break;
 
-  case 37:
-#line 443 "./sql.y"
+  case 39:
+#line 460 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_AND, yyvsp[0].expr );
         ;}
     break;
 
-  case 38:
-#line 447 "./sql.y"
+  case 40:
+#line 464 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_OR, yyvsp[0].expr );
         ;}
     break;
 
-  case 39:
-#line 451 "./sql.y"
+  case 41:
+#line 468 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
         ;}
     break;
 
-  case 40:
-#line 455 "./sql.y"
+  case 42:
+#line 472 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_GT, yyvsp[0].expr );
         ;}
     break;
 
-  case 41:
-#line 459 "./sql.y"
+  case 43:
+#line 476 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_LT, yyvsp[0].expr );
         ;}
     break;
 
-  case 42:
-#line 463 "./sql.y"
+  case 44:
+#line 480 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_LE, yyvsp[0].expr );
         ;}
     break;
 
-  case 43:
-#line 467 "./sql.y"
+  case 45:
+#line 484 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_GE, yyvsp[0].expr );
         ;}
     break;
 
-  case 44:
-#line 471 "./sql.y"
+  case 46:
+#line 488 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_NE, yyvsp[0].expr );
         ;}
     break;
 
-  case 45:
-#line 475 "./sql.y"
+  case 47:
+#line 492 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-2].expr, OP_ISNULL, NULL );
         ;}
     break;
 
-  case 46:
-#line 479 "./sql.y"
+  case 48:
+#line 496 "./sql.y"
     {
             yyval.expr = EXPR_complex( yyvsp[-3].expr, OP_NOTNULL, NULL );
         ;}
     break;
 
-  case 49:
-#line 491 "./sql.y"
+  case 51:
+#line 508 "./sql.y"
     {
             value_list *vals;
 
@@ -1936,8 +1955,8 @@ yyreduce:
         ;}
     break;
 
-  case 50:
-#line 503 "./sql.y"
+  case 52:
+#line 520 "./sql.y"
     {
             value_list *vals;
 
@@ -1951,8 +1970,8 @@ yyreduce:
         ;}
     break;
 
-  case 52:
-#line 519 "./sql.y"
+  case 54:
+#line 536 "./sql.y"
     {
             yyvsp[-2].update_col_info.col_list->next = yyvsp[0].update_col_info.col_list;
             yyvsp[-2].update_col_info.val_list->next = yyvsp[0].update_col_info.val_list;
@@ -1960,8 +1979,8 @@ yyreduce:
         ;}
     break;
 
-  case 53:
-#line 528 "./sql.y"
+  case 55:
+#line 545 "./sql.y"
     {
             yyval.update_col_info.col_list = HeapAlloc( GetProcessHeap(), 0, sizeof *yyval.update_col_info.col_list );
             if( !yyval.update_col_info.col_list )
@@ -1976,71 +1995,71 @@ yyreduce:
         ;}
     break;
 
-  case 54:
-#line 544 "./sql.y"
+  case 56:
+#line 561 "./sql.y"
     {
             yyval.expr = EXPR_ival( &yyvsp[0].str, 1 );
         ;}
     break;
 
-  case 55:
-#line 548 "./sql.y"
+  case 57:
+#line 565 "./sql.y"
     {
             yyval.expr = EXPR_ival( &yyvsp[0].str, -1 );
         ;}
     break;
 
-  case 56:
-#line 552 "./sql.y"
+  case 58:
+#line 569 "./sql.y"
     {
             yyval.expr = EXPR_sval( &yyvsp[0].str );
         ;}
     break;
 
-  case 57:
-#line 556 "./sql.y"
+  case 59:
+#line 573 "./sql.y"
     {
             yyval.expr = EXPR_wildcard();
         ;}
     break;
 
-  case 58:
-#line 563 "./sql.y"
+  case 60:
+#line 580 "./sql.y"
     {
             yyval.expr = EXPR_column( yyvsp[0].string );
         ;}
     break;
 
-  case 59:
-#line 570 "./sql.y"
+  case 61:
+#line 587 "./sql.y"
     {
             yyval.string = yyvsp[0].string;  /* FIXME */
         ;}
     break;
 
-  case 60:
-#line 574 "./sql.y"
+  case 62:
+#line 591 "./sql.y"
     {
             yyval.string = yyvsp[0].string;
         ;}
     break;
 
-  case 61:
-#line 581 "./sql.y"
+  case 63:
+#line 598 "./sql.y"
     {
             yyval.string = yyvsp[0].string;
         ;}
     break;
 
-  case 62:
-#line 588 "./sql.y"
+  case 64:
+#line 605 "./sql.y"
     {
             yyval.string = SQL_getstring( &yyvsp[0].str );
         ;}
     break;
 
-  case 63:
-#line 592 "./sql.y"
+  case 65:
+#line 609 "./sql.y"
     {
             yyval.string = SQL_getstring( &yyvsp[0].str );
         ;}
@@ -2050,7 +2069,7 @@ yyreduce:
     }
 
 /* Line 999 of yacc.c.  */
-#line 2054 "sql.tab.c"
+#line 2073 "sql.tab.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -2256,7 +2275,7 @@ yyreturn:
 }
 
 
-#line 597 "./sql.y"
+#line 614 "./sql.y"
 
 
 int SQL_lex( void *SQL_lval, SQL_input *sql)
index ca91850..5bd2c7d 100644 (file)
@@ -129,7 +129,8 @@ static struct expr * EXPR_wildcard();
 \r
 %type <string> column table string_or_id\r
 %type <column_list> selcollist\r
-%type <query> from unorderedsel oneselect onequery onecreate oneinsert oneupdate\r
+%type <query> from unorderedsel oneselect onequery onecreate oneinsert\r
+%type <query> oneupdate onedelete\r
 %type <expr> expr val column_val const_val\r
 %type <column_type> column_type data_type data_type_l data_count\r
 %type <column_info> column_def table_def\r
@@ -159,6 +160,11 @@ onequery:
         SQL_input* sql = (SQL_input*) info;\r
         *sql->view = $1;\r
     }\r
+  | onedelete\r
+    {\r
+        SQL_input* sql = (SQL_input*) info;\r
+        *sql->view = $1;\r
+    }\r
     ;\r
 \r
 oneinsert:\r
@@ -214,6 +220,17 @@ oneupdate:
         }\r
     ;\r
 \r
+onedelete:\r
+    TK_DELETE from\r
+        {\r
+            SQL_input* sql = (SQL_input*) info;\r
+            MSIVIEW *delete = NULL; \r
+\r
+            DELETE_CreateView( sql->db, &delete, $2 );\r
+            $$ = delete;\r
+        }\r
+    ;\r
+\r
 table_def:\r
     column_def TK_PRIMARY TK_KEY selcollist\r
         {\r
index fbc39d0..16e4516 100644 (file)
@@ -110,11 +110,9 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
     if( FAILED( r ) )\r
     {\r
         ERR("IStorage -> IPropertySetStorage failed\n");\r
-        if (db)\r
-            msiobj_release(&db->hdr);\r
-        return ERROR_FUNCTION_FAILED;\r
+        ret = ERROR_FUNCTION_FAILED;\r
+        goto end;\r
     }\r
-    ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);\r
 \r
     grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;\r
     r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );\r
@@ -137,7 +135,7 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
     suminfo->propstg = ps;\r
     handle = alloc_msihandle( &suminfo->hdr );\r
     if( handle )\r
-    *phSummaryInfo = handle;\r
+        *phSummaryInfo = handle;\r
     else\r
         ret = ERROR_FUNCTION_FAILED;\r
     msiobj_release( &suminfo->hdr );\r
@@ -147,7 +145,7 @@ end:
         IPropertyStorage_Release(ps);\r
     if( psstg )\r
         IPropertySetStorage_Release(psstg);\r
-    if (db)\r
+    if( db )\r
         msiobj_release(&db->hdr);\r
 \r
     return ret;\r
@@ -163,6 +161,7 @@ UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
     if( !suminfo )\r
         return ERROR_INVALID_HANDLE;\r
 \r
+    msiobj_release( &suminfo->hdr );\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
@@ -174,6 +173,7 @@ UINT WINAPI MsiSummaryInfoGetPropertyA(
     HRESULT r;\r
     PROPSPEC spec;\r
     PROPVARIANT var;\r
+    UINT rc = ERROR_SUCCESS;\r
 \r
     TRACE("%ld %d %p %p %p %p %p\n",\r
         hSummaryInfo, uiProperty, puiDataType, piValue,\r
@@ -188,7 +188,10 @@ UINT WINAPI MsiSummaryInfoGetPropertyA(
 \r
     r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);\r
     if( FAILED(r) )\r
-        return ERROR_FUNCTION_FAILED;\r
+    {\r
+        rc = ERROR_FUNCTION_FAILED;\r
+        goto end;\r
+    }\r
 \r
     if( puiDataType )\r
         *puiDataType = var.vt;\r
@@ -217,7 +220,9 @@ UINT WINAPI MsiSummaryInfoGetPropertyA(
         break;\r
     }\r
 \r
-    return ERROR_SUCCESS;\r
+end:\r
+    msiobj_release( &suminfo->hdr );\r
+    return rc;\r
 }\r
 \r
 UINT WINAPI MsiSummaryInfoGetPropertyW(\r
@@ -228,6 +233,7 @@ UINT WINAPI MsiSummaryInfoGetPropertyW(
     HRESULT r;\r
     PROPSPEC spec;\r
     PROPVARIANT var;\r
+    UINT rc = ERROR_SUCCESS;\r
 \r
     TRACE("%ld %d %p %p %p %p %p\n",\r
         hSummaryInfo, uiProperty, puiDataType, piValue,\r
@@ -242,7 +248,10 @@ UINT WINAPI MsiSummaryInfoGetPropertyW(
 \r
     r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);\r
     if( FAILED(r) )\r
-        return ERROR_FUNCTION_FAILED;\r
+    {\r
+        rc = ERROR_FUNCTION_FAILED;\r
+        goto end;\r
+    }\r
 \r
     if( puiDataType )\r
         *puiDataType = var.vt;\r
@@ -272,24 +281,31 @@ UINT WINAPI MsiSummaryInfoGetPropertyW(
         break;\r
     }\r
 \r
-    return ERROR_SUCCESS;\r
+end:\r
+    msiobj_release( &suminfo->hdr );\r
+    return rc;\r
 }\r
 \r
 UINT WINAPI MsiSummaryInfoSetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty,\r
                                        UINT uiDataType, INT iValue, \r
-                                       FILETIME* pftValue, LPSTR szValue)\r
+                                       FILETIME* pftValue, LPSTR szValue )\r
 {\r
+    FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty,\r
+          uiDataType, iValue, pftValue, debugstr_a(szValue) );\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
 UINT WINAPI MsiSummaryInfoSetPropertyW( MSIHANDLE hSummaryInfo, UINT uiProperty,\r
                                        UINT uiDataType, INT iValue, \r
-                                       FILETIME* pftValue, LPWSTR szValue)\r
+                                       FILETIME* pftValue, LPWSTR szValue )\r
 {\r
+    FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty,\r
+          uiDataType, iValue, pftValue, debugstr_w(szValue) );\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
 \r
-UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE hSummaryInfo)\r
+UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE hSummaryInfo )\r
 {\r
+    FIXME("%ld\n", hSummaryInfo );\r
     return ERROR_CALL_NOT_IMPLEMENTED;\r
 }\r
index 5e1891b..63ee0db 100644 (file)
@@ -1220,7 +1220,10 @@ static UINT TABLE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
     TRACE("%p %p\n", tv, record);\r
 \r
     if( tv->table )\r
-        return ERROR_FUNCTION_FAILED;\r
+    {\r
+        release_table( tv->db, tv->table );\r
+        tv->table = NULL;\r
+    }\r
 \r
     r = get_table( tv->db, tv->name, &tv->table );\r
     if( r != ERROR_SUCCESS )\r
index 2754f99..8b84d3a 100644 (file)
@@ -247,6 +247,7 @@ static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
     if( !wv->reorder )\r
         return ERROR_FUNCTION_FAILED;\r
 \r
+    wv->row_count = 0;\r
     for( i=0; i<count; i++ )\r
     {\r
         val = 0;\r
index f9101ba..fd15330 100644 (file)
@@ -225,7 +225,6 @@ NtSetEaFile@16
 NtSetEvent@8
 NtSetHighEventPair@4
 NtSetHighWaitLowEventPair@4
-NtSetHighWaitLowThread@0
 NtSetInformationFile@20
 NtSetInformationJobObject@16
 NtSetInformationKey@16
@@ -238,7 +237,6 @@ NtSetIoCompletion@20
 NtSetLdtEntries@24
 NtSetLowEventPair@4
 NtSetLowWaitHighEventPair@4
-NtSetLowWaitHighThread@0
 NtSetSecurityObject@12
 NtSetSystemEnvironmentValue@8
 NtSetSystemInformation@12
@@ -298,6 +296,7 @@ RtlAddAuditAccessAce@24
 RtlAddAuditAccessAceEx@28
 ;RtlAddCompoundAce
 RtlAddRange@36
+RtlAddVectoredExceptionHandler@8
 RtlAdjustPrivilege@16
 RtlAllocateAndInitializeSid@44
 RtlAllocateHandle@8
@@ -364,6 +363,7 @@ RtlCreateUserThread@40
 RtlCustomCPToUnicodeN@24
 RtlCutoverTimeToSystemTime@16
 RtlDeNormalizeProcessParams@4
+RtlDecodePointer=RtlEncodePointer@4
 RtlDecompressBuffer@24
 RtlDecompressFragment@32
 RtlDelete@4
@@ -396,6 +396,7 @@ RtlDowncaseUnicodeString@12
 RtlDumpResource@4
 RtlDuplicateUnicodeString@12
 RtlEmptyAtomTable@8
+RtlEncodePointer@4
 RtlEnlargedIntegerMultiply@8
 RtlEnlargedUnsignedDivide@16
 RtlEnlargedUnsignedMultiply@8
@@ -593,6 +594,7 @@ RtlRealSuccessor@4
 RtlReleasePebLock@0
 RtlReleaseResource@4
 ;RtlRemoteCall
+RtlRemoveVectoredExceptionHandler@4
 RtlResetRtlTranslations@4
 RtlRestoreLastWin32Error@4=RtlSetLastWin32Error@4
 RtlRunDecodeUnicodeString@8
@@ -669,6 +671,8 @@ RtlValidSecurityDescriptor@4
 RtlValidSid@4
 RtlValidateHeap@12
 RtlValidateProcessHeaps@0
+RtlValidateUnicodeString@8
+RtlVerifyVersionInfo@16
 ;RtlWalkHeap
 RtlWriteRegistryValue@24
 ;RtlZeroHeap
@@ -849,7 +853,6 @@ ZwSetEaFile@16
 ZwSetEvent@8
 ZwSetHighEventPair@4
 ZwSetHighWaitLowEventPair@4
-ZwSetHighWaitLowThread@0
 ZwSetInformationFile@20
 ZwSetInformationKey@16
 ZwSetInformationObject@16
@@ -861,7 +864,6 @@ ZwSetIoCompletion@20
 ZwSetLdtEntries@24
 ZwSetLowEventPair@4
 ZwSetLowWaitHighEventPair@4
-ZwSetLowWaitHighThread@0
 ZwSetSecurityObject@12
 ZwSetSystemEnvironmentValue@8
 ZwSetSystemInformation@12
index 91676aa..46bc9cd 100644 (file)
@@ -320,9 +320,9 @@ LdrAccessResource(IN  PVOID BaseAddress,
  */
 NTSTATUS STDCALL
 LdrFindResourceDirectory_U(IN PVOID BaseAddress,
-                           WCHAR** name,
-                           DWORD level,
-                           OUT PVOID* addr)
+                           IN PLDR_RESOURCE_INFO info,
+                           IN ULONG level,
+                          OUT PIMAGE_RESOURCE_DIRECTORY* addr)
 {
     PIMAGE_RESOURCE_DIRECTORY ResDir;
     PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
@@ -330,6 +330,7 @@ LdrFindResourceDirectory_U(IN PVOID BaseAddress,
     ULONG i;
     NTSTATUS Status = STATUS_SUCCESS;
     WCHAR* ws;
+    PWCHAR* name = (PWCHAR*) info;
 
     /* Get the pointer to the resource directory */
     ResDir = (PIMAGE_RESOURCE_DIRECTORY)
index e775fab..c6e972a 100644 (file)
@@ -39,6 +39,8 @@ PLDR_MODULE ExeModule;
 
 NTSTATUS LdrpAttachThread (VOID);
 
+VOID RtlpInitializeVectoredExceptionHandling(VOID);
+
 
 #define VALUE_BUFFER_SIZE 256
 
@@ -306,6 +308,9 @@ __true_LdrInitializeThunk (ULONG Unknown1,
            ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
          }
             
+       /* initialized vectored exception handling */
+       RtlpInitializeVectoredExceptionHandling();
+
        /* initalize peb lock support */
        RtlInitializeCriticalSection (&PebLock);
        Peb->FastPebLock = &PebLock;
index 0ef7154..79f5d0c 100644 (file)
@@ -186,9 +186,14 @@ LdrpInitializeTlsForThread(VOID)
    PTLS_DATA TlsInfo;
    PVOID TlsData;
    ULONG i;
-
+   PTEB Teb = NtCurrentTeb();
+   
    DPRINT("LdrpInitializeTlsForThread() called for %wZ\n", &ExeModule->BaseDllName);
 
+   Teb->StaticUnicodeString.Length = 0;
+   Teb->StaticUnicodeString.MaximumLength = sizeof(Teb->StaticUnicodeBuffer);
+   Teb->StaticUnicodeString.Buffer = Teb->StaticUnicodeBuffer;
+
    if (LdrpTlsCount > 0)
      {
        TlsPointers = RtlAllocateHeap(RtlGetProcessHeap(),
@@ -201,7 +206,7 @@ LdrpInitializeTlsForThread(VOID)
          }
 
        TlsData = (PVOID)TlsPointers + LdrpTlsCount * sizeof(PVOID);
-       NtCurrentTeb()->ThreadLocalStoragePointer = TlsPointers;
+       Teb->ThreadLocalStoragePointer = TlsPointers;
 
        TlsInfo = LdrpTlsArray;
        for (i = 0; i < LdrpTlsCount; i++, TlsInfo++)
@@ -682,7 +687,7 @@ LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
                            SECTION_ALL_ACCESS,
                            NULL,
                            NULL,
-                           PAGE_READWRITE,
+                           PAGE_READONLY,
                            SEC_COMMIT | (MapAsDataFile ? 0 : SEC_IMAGE),
                            FileHandle);
   NtClose(FileHandle);
@@ -2048,7 +2053,7 @@ LdrpLoadModule(IN PWSTR SearchPath OPTIONAL,
                                     &ViewSize,
                                     0,
                                     MEM_COMMIT,
-                                    PAGE_READWRITE);
+                                    PAGE_READONLY);
         if (!NT_SUCCESS(Status))
           {
             DPRINT1("map view of section failed (Status %x)\n", Status);
@@ -2875,10 +2880,10 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
   DPRINT ("LdrVerifyImageMatchesChecksum() called\n");
 
   Status = NtCreateSection (&SectionHandle,
-                            SECTION_MAP_EXECUTE,
+                            SECTION_MAP_READ,
                             NULL,
                             NULL,
-                            PAGE_EXECUTE,
+                            PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandle);
   if (!NT_SUCCESS(Status))
@@ -2898,7 +2903,7 @@ LdrVerifyImageMatchesChecksum (IN HANDLE FileHandle,
                                &ViewSize,
                                ViewShare,
                                0,
-                               PAGE_EXECUTE);
+                               PAGE_READONLY);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("NtMapViewOfSection() failed (Status %lx)\n", Status);
index 5c294b7..559c522 100644 (file)
@@ -23,7 +23,7 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \
   -Wl,--section-alignment,0x1000 \
   -nostartfiles -nostdlib
 
-TARGET_SDKLIBS = rosrtl.a rtl.a string.a
+TARGET_SDKLIBS = rtl.a rosrtl.a string.a
 
 TARGET_GCCLIBS = gcc
 
@@ -59,7 +59,6 @@ RTL_I386_OBJECTS = \
        rtl/i386/aulldiv.o \
        rtl/i386/aullrem.o \
        rtl/i386/aullshr.o \
-       rtl/i386/chkstk.o \
        rtl/i386/float.o \
        rtl/i386/ftol.o
 
@@ -77,13 +76,11 @@ RTL_OBJECTS = \
        rtl/message.o \
        rtl/misc.o \
        rtl/path.o \
-       rtl/ppb.o \
        rtl/process.o \
        rtl/propvar.o \
        rtl/rangelist.o \
        rtl/resource.o \
        rtl/teb.o \
-       rtl/thread.o \
        rtl/timerqueue.o \
        rtl/libsupp.o
 
index a5df8e6..fcb08f1 100644 (file)
@@ -3,8 +3,8 @@
        <importlibrary definition="def/ntdll.def" />\r
        <define name="__NTDLL__" />\r
        <define name="_DISABLE_TIDENTS" />\r
-       <library>rosrtl</library>\r
        <library>rtl</library>\r
+       <library>rosrtl</library>\r
        <library>string</library>\r
        <linkerflag>-lgcc</linkerflag>\r
        <directory name="csr">\r
@@ -37,7 +37,6 @@
                        <file>aulldiv.s</file>\r
                        <file>aullrem.s</file>\r
                        <file>aullshr.s</file>\r
-                       <file>chkstk.s</file>\r
                        <file>exception.c</file>\r
                        <file>float.c</file>\r
                        <file>ftol.c</file>\r
                <file>message.c</file>\r
                <file>misc.c</file>\r
                <file>path.c</file>\r
-               <file>ppb.c</file>\r
                <file>process.c</file>\r
                <file>propvar.c</file>\r
                <file>rangelist.c</file>\r
                <file>resource.c</file>\r
                <file>teb.c</file>\r
-               <file>thread.c</file>\r
                <file>timerqueue.c</file>\r
        </directory>\r
        <directory name="stdio">\r
index 16a9625..a42319e 100644 (file)
@@ -136,7 +136,7 @@ RtlEnterCriticalSection(
     HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
     
     /* Try to Lock it */
-    if (InterlockedIncrement(&CriticalSection->LockCount)) {
+    if (InterlockedIncrement(&CriticalSection->LockCount) != 0) {
 
         /* 
          * We've failed to lock it! Does this thread
@@ -332,12 +332,10 @@ RtlLeaveCriticalSection(
         CriticalSection->OwningThread = 0;
         
         /* Was someone wanting us? This needs to be done atomically. */
-        if (InterlockedDecrement(&CriticalSection->LockCount) >= 0) {
-        
-            /* Let him have us */
-            RtlpUnWaitCriticalSection(CriticalSection);
+        InterlockedDecrement(&CriticalSection->LockCount);
         
-        }
+        /* Let him have us */
+        RtlpUnWaitCriticalSection(CriticalSection);
     }
     
     /* Sucessful! */
index 2dde237..6a91cd6 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+static CRITICAL_SECTION RtlpVectoredExceptionLock;
+static LIST_ENTRY RtlpVectoredExceptionHead;
+
+typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
+{
+  LIST_ENTRY ListEntry;
+  PVECTORED_EXCEPTION_HANDLER VectoredHandler;
+} RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
+
+/* FIXME - stupid ld won't resolve RtlDecodePointer! Since their implementation
+           is the same just use RtlEncodePointer for now! */
+#define RtlDecodePointer RtlEncodePointer
+
 /* FUNCTIONS ***************************************************************/
 
 VOID STDCALL
@@ -35,20 +48,63 @@ ULONG
 RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
        IN PCONTEXT  Context);
 
+EXCEPTION_DISPOSITION
+RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD  ExceptionRecord,
+                                     IN PCONTEXT  Context)
+{
+  PLIST_ENTRY CurrentEntry;
+  PRTL_VECTORED_EXCEPTION_HANDLER veh;
+  PVECTORED_EXCEPTION_HANDLER VectoredHandler;
+  EXCEPTION_POINTERS ExceptionInfo;
+  
+  ExceptionInfo.ExceptionRecord = ExceptionRecord;
+  ExceptionInfo.ContextRecord = Context;
+  
+  if(RtlpVectoredExceptionHead.Flink != &RtlpVectoredExceptionHead)
+  {
+    RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+    for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
+        CurrentEntry != &RtlpVectoredExceptionHead;
+        CurrentEntry = CurrentEntry->Flink)
+    {
+      veh = CONTAINING_RECORD(CurrentEntry,
+                              RTL_VECTORED_EXCEPTION_HANDLER,
+                              ListEntry);
+      VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
+      if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
+      {
+        RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+        return ExceptionContinueSearch;
+      }
+    }
+    RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+  }
+  
+  return ExceptionContinueExecution;
+}
+
 VOID STDCALL
 KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,
                          PCONTEXT Context)
 {
   EXCEPTION_RECORD NestedExceptionRecord;
   NTSTATUS Status;
-
-  if (RtlpDispatchException(ExceptionRecord, Context) != ExceptionContinueExecution)
+  
+  if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,
+                                          Context) != ExceptionContinueExecution)
     {
       Status = NtContinue(Context, FALSE);
     }
   else
     {
-      Status = NtRaiseException(ExceptionRecord, Context, FALSE);
+      if(RtlpDispatchException(ExceptionRecord, Context) != ExceptionContinueExecution)
+        {
+          Status = NtContinue(Context, FALSE);
+        }
+      else
+        {
+          Status = NtRaiseException(ExceptionRecord, Context, FALSE);
+        }
     }
 
   NestedExceptionRecord.ExceptionCode = Status;
@@ -87,4 +143,83 @@ RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress,
   NtTerminateProcess(NtCurrentProcess(), ExitStatus);
 }
 
+
+VOID
+RtlpInitializeVectoredExceptionHandling(VOID)
+{
+  InitializeListHead(&RtlpVectoredExceptionHead);
+  RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
+}
+
+
+/*
+ * @implemented
+ */
+PVOID STDCALL
+RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
+                               IN PVECTORED_EXCEPTION_HANDLER VectoredHandler)
+{
+  PRTL_VECTORED_EXCEPTION_HANDLER veh;
+  
+  veh = RtlAllocateHeap(RtlGetProcessHeap(),
+                        0,
+                        sizeof(RTL_VECTORED_EXCEPTION_HANDLER));
+  if(veh != NULL)
+  {
+    veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
+    RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+    if(FirstHandler != 0)
+    {
+      InsertHeadList(&RtlpVectoredExceptionHead,
+                     &veh->ListEntry);
+    }
+    else
+    {
+      InsertTailList(&RtlpVectoredExceptionHead,
+                     &veh->ListEntry);
+    }
+    RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+  }
+  
+  return veh;
+}
+
+
+/*
+ * @implemented
+ */
+ULONG STDCALL
+RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
+{
+  PLIST_ENTRY CurrentEntry;
+  PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
+  ULONG Removed = FALSE;
+  
+  RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+  for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
+      CurrentEntry != &RtlpVectoredExceptionHead;
+      CurrentEntry = CurrentEntry->Flink)
+  {
+    veh = CONTAINING_RECORD(CurrentEntry,
+                            RTL_VECTORED_EXCEPTION_HANDLER,
+                            ListEntry);
+    if(veh == VectoredHandlerHandle)
+    {
+      RemoveEntryList(&veh->ListEntry);
+      Removed = TRUE;
+      break;
+    }
+  }
+  RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+  
+  if(Removed)
+  {
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                veh);
+  }
+
+  return Removed;
+}
+
 /* EOF */
index 1f6e70a..97dc732 100644 (file)
 
 /* FUNCTIONS ***************************************************************/
 
+KPROCESSOR_MODE
+RtlpGetMode()
+{ 
+   return UserMode; 
+}
+
+
 PVOID 
 STDCALL
 ExAllocatePool(
index 7534591..4f36db0 100644 (file)
@@ -15,6 +15,9 @@
 #include <ddk/ntddk.h>
 #include <ntdll/rtl.h>
 
+#define NDEBUG
+#include <ntdll/ntdll.h>
+
 /**********************************************************************
  * NAME                                                        EXPORTED
  *     RtlGetNtProductType
@@ -107,3 +110,30 @@ RtlGetNtGlobalFlags(VOID)
        PPEB pPeb = NtCurrentPeb();
        return pPeb->NtGlobalFlag;
 }
+
+
+/*
+ * @implemented
+ */
+PVOID
+STDCALL
+RtlEncodePointer(IN PVOID Pointer)
+{
+  ULONG Cookie;
+  NTSTATUS Status;
+
+  Status = NtQueryInformationProcess(NtCurrentProcess(),
+                                     ProcessCookie,
+                                     &Cookie,
+                                     sizeof(Cookie),
+                                     NULL);
+
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT1("Failed to receive the process cookie! Status: 0x%x\n", Status);
+    return Pointer;
+  }
+
+  return (PVOID)((ULONG_PTR)Pointer ^ Cookie);
+}
+
index 3e60798..ff4c3b9 100644 (file)
@@ -241,59 +241,33 @@ RtlGetCurrentDirectory_U(ULONG MaximumLength,
  * @implemented
  */
 NTSTATUS STDCALL
-RtlSetCurrentDirectory_U(PUNICODE_STRING name)
+RtlSetCurrentDirectory_U(PUNICODE_STRING dir)
 {
    UNICODE_STRING full;
    UNICODE_STRING envvar;
+   FILE_FS_DEVICE_INFORMATION device_info;
    OBJECT_ATTRIBUTES Attr;
    IO_STATUS_BLOCK iosb;
    PCURDIR cd;
    NTSTATUS Status;
    ULONG size;
    HANDLE handle = NULL;
-   PWSTR wcs;
-   PWSTR buf = 0;
-   PFILE_NAME_INFORMATION filenameinfo;
-   ULONG backslashcount = 0;
-   ULONG Index;
    WCHAR var[4];
+   PWSTR ptr;
    
-   DPRINT ("RtlSetCurrentDirectory %wZ\n", name);
+   DPRINT("RtlSetCurrentDirectory %wZ\n", dir);
    
    RtlAcquirePebLock ();
+   
    cd = (PCURDIR)&NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName;
 
-   size = cd->DosPath.MaximumLength;
-   buf = RtlAllocateHeap (RtlGetProcessHeap(),
-                         0,
-                         size);
-   if (buf == NULL)
-     {
-       RtlReleasePebLock ();
-       return STATUS_NO_MEMORY;
-     }
-   
-   size = RtlGetFullPathName_U (name->Buffer, size, buf, 0);
-   if (!size)
-     {
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    buf);
-       RtlReleasePebLock ();
-       return STATUS_OBJECT_NAME_INVALID;
-     }
+   if (!RtlDosPathNameToNtPathName_U (dir->Buffer, &full, 0, 0))
+   {
+      RtlReleasePebLock ();
+      return STATUS_OBJECT_NAME_INVALID;
+   }
    
-   if (!RtlDosPathNameToNtPathName_U (buf, &full, 0, 0))
-     {
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    buf);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    full.Buffer);
-       RtlReleasePebLock ();
-       return STATUS_OBJECT_NAME_INVALID;
-     }
+   DPRINT("RtlSetCurrentDirectory: full %wZ\n",&full);
    
    InitializeObjectAttributes (&Attr,
                               &full,
@@ -307,114 +281,124 @@ RtlSetCurrentDirectory_U(PUNICODE_STRING name)
                        &iosb,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+         
    if (!NT_SUCCESS(Status))
-     {
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    buf);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    full.Buffer);
-       RtlReleasePebLock ();
-       return Status;
-     }
+   {
+      RtlFreeUnicodeString( &full);
+      RtlReleasePebLock ();
+      return Status;
+   }
+
+   /* don't keep the directory handle open on removable media */
+   if (NT_SUCCESS(NtQueryVolumeInformationFile( handle, &iosb, &device_info,
+                                                sizeof(device_info), FileFsDeviceInformation )) &&
+     (device_info.Characteristics & FILE_REMOVABLE_MEDIA))
+   {
+      DPRINT1("don't keep the directory handle open on removable media\n");
+      NtClose( handle );
+      handle = 0;
+   }
 
+
+/* What the heck is this all about??? It looks like its getting the long path,
+ * and if does, ITS WRONG! If current directory is set with a short path,
+ * GetCurrentDir should return a short path.
+ * If anyone agrees with me, remove this stuff.
+ * -Gunnar
+ */
+#if 0
    filenameinfo = RtlAllocateHeap(RtlGetProcessHeap(),
-                                 0,
-                                 MAX_PATH*sizeof(WCHAR)+sizeof(ULONG));
+              0,
+              MAX_PATH*sizeof(WCHAR)+sizeof(ULONG));
    
    Status = NtQueryInformationFile(handle,
-                                  &iosb,
-                                  filenameinfo,
-                                  MAX_PATH*sizeof(WCHAR)+sizeof(ULONG),
-                                  FileNameInformation);
+               &iosb,
+               filenameinfo,
+               MAX_PATH*sizeof(WCHAR)+sizeof(ULONG),
+               FileNameInformation);
    if (!NT_SUCCESS(Status))
      {
-       RtlFreeHeap(RtlGetProcessHeap(),
-                   0,
-                   filenameinfo);
-       RtlFreeHeap(RtlGetProcessHeap(),
-                   0,
-                   buf);
-       RtlFreeHeap(RtlGetProcessHeap(),
-                   0,
-                   full.Buffer);
-       RtlReleasePebLock();
-       return(Status);
+   RtlFreeHeap(RtlGetProcessHeap(),
+          0,
+          filenameinfo);
+   RtlFreeHeap(RtlGetProcessHeap(),
+          0,
+          buf);
+   RtlFreeHeap(RtlGetProcessHeap(),
+          0,
+          full.Buffer);
+   RtlReleasePebLock();
+   return(Status);
      }
    
    /* If it's just "\", we need special handling */
    if (filenameinfo->FileNameLength > sizeof(WCHAR))
      {
-       wcs = buf + size / sizeof(WCHAR) - 1;
-       if (*wcs == L'\\')
-         {
-           *(wcs) = 0;
-           wcs--;
-           size -= sizeof(WCHAR);
-         }
+   wcs = buf + size / sizeof(WCHAR) - 1;
+   if (*wcs == L'\\')
+     {
+       *(wcs) = 0;
+       wcs--;
+       size -= sizeof(WCHAR);
+     }
 
-       for (Index = 0;
-            Index < filenameinfo->FileNameLength / sizeof(WCHAR);
-            Index++)
-         {
-            if (filenameinfo->FileName[Index] == '\\') backslashcount++;
-         }
+   for (Index = 0;
+        Index < filenameinfo->FileNameLength / sizeof(WCHAR);
+        Index++)
+     {
+        if (filenameinfo->FileName[Index] == '\\') backslashcount++;
+     }
 
-       DPRINT("%d \n",backslashcount);
-       for (;backslashcount;wcs--)
-         {
-            if (*wcs=='\\') backslashcount--;
-         }
-       wcs++;
+   DPRINT("%d \n",backslashcount);
+   for (;backslashcount;wcs--)
+     {
+        if (*wcs=='\\') backslashcount--;
+     }
+   wcs++;
 
-       RtlCopyMemory(wcs, filenameinfo->FileName, filenameinfo->FileNameLength);
-       wcs[filenameinfo->FileNameLength / sizeof(WCHAR)] = 0;
+   RtlCopyMemory(wcs, filenameinfo->FileName, filenameinfo->FileNameLength);
+   wcs[filenameinfo->FileNameLength / sizeof(WCHAR)] = 0;
 
-       size = (wcs - buf) * sizeof(WCHAR) + filenameinfo->FileNameLength;
+   size = (wcs - buf) * sizeof(WCHAR) + filenameinfo->FileNameLength;
      }
-   
-   RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               filenameinfo);
-   
-   /* append backslash if missing */
-   wcs = buf + size / sizeof(WCHAR) - 1;
-   if (*wcs != L'\\')
-     {
-       *(++wcs) = L'\\';
-       *(++wcs) = 0;
-       size += sizeof(WCHAR);
-     }
-   
-   memmove(cd->DosPath.Buffer,
-          buf,
-          size + sizeof(WCHAR));
-   cd->DosPath.Length = size;
+#endif
+
+
 
    if (cd->Handle)
-     NtClose(cd->Handle);
+      NtClose(cd->Handle);
    cd->Handle = handle;
 
+   /* append trailing \ if missing */
+   size = full.Length / sizeof(WCHAR);
+   ptr = full.Buffer;
+   ptr += 4;  /* skip \??\ prefix */
+   size -= 4;
+   
+   /* This is ok because RtlDosPathNameToNtPathName_U returns a nullterminated string.
+    * So the nullterm is replaced with \
+    * -Gunnar
+    */
+   if (size && ptr[size - 1] != '\\') ptr[size++] = '\\';
+
+   memcpy( cd->DosPath.Buffer, ptr, size * sizeof(WCHAR));
+   cd->DosPath.Buffer[size] = 0;
+   cd->DosPath.Length = size * sizeof(WCHAR);
+
+
+   /* FIXME: whats this all about??? Wine doesnt have this. -Gunnar */
    if (cd->DosPath.Buffer[1]==':')
-     {
-       envvar.Length = 2 * swprintf (var, L"=%c:", cd->DosPath.Buffer[0]);
-       envvar.MaximumLength = 8;
-       envvar.Buffer = var;
+   {
+      envvar.Length = 2 * swprintf (var, L"=%c:", cd->DosPath.Buffer[0]);
+      envvar.MaximumLength = 8;
+      envvar.Buffer = var;
    
-       RtlSetEnvironmentVariable(NULL,
-                                 &envvar,
-                                 &cd->DosPath);
+      RtlSetEnvironmentVariable(NULL,
+                 &envvar,
+                 &cd->DosPath);
    }
    
-   RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               buf);
-   
-   RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               full.Buffer);
-   
+   RtlFreeUnicodeString( &full);
    RtlReleasePebLock();
    
    return STATUS_SUCCESS;
@@ -964,13 +948,10 @@ RtlDoesFileExists_U(IN PWSTR FileName)
 {
        UNICODE_STRING NtFileName;
        OBJECT_ATTRIBUTES Attr;
+   FILE_BASIC_INFORMATION Info;
        NTSTATUS Status;
        CURDIR CurDir;
-       PWSTR Buffer;
 
-       /* only used by replacement code */
-       HANDLE FileHandle;
-       IO_STATUS_BLOCK StatusBlock;
 
        if (!RtlDosPathNameToNtPathName_U (FileName,
                                           &NtFileName,
@@ -978,9 +959,6 @@ RtlDoesFileExists_U(IN PWSTR FileName)
                                           &CurDir))
                return FALSE;
 
-       /* don't forget to free it! */
-       Buffer = NtFileName.Buffer;
-
        if (CurDir.DosPath.Length)
                NtFileName = CurDir.DosPath;
        else
@@ -992,24 +970,11 @@ RtlDoesFileExists_U(IN PWSTR FileName)
                                    CurDir.Handle,
                                    NULL);
 
-       /* FIXME: not implemented yet */
-//     Status = NtQueryAttributesFile (&Attr, NULL);
-
-       /* REPLACEMENT start */
-       Status = NtOpenFile (&FileHandle,
-                            0x10001,
-                            &Attr,
-                            &StatusBlock,
-                            1,
-                            FILE_SYNCHRONOUS_IO_NONALERT);
-       if (NT_SUCCESS(Status))
-               NtClose (FileHandle);
-       /* REPLACEMENT end */
-
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    Buffer);
+       Status = NtQueryAttributesFile (&Attr, &Info);
 
+   RtlFreeUnicodeString(&NtFileName);
+   
+   
        if (NT_SUCCESS(Status) ||
            Status == STATUS_SHARING_VIOLATION ||
            Status == STATUS_ACCESS_DENIED)
index 760696f..04cac8d 100644 (file)
 
 /* FUNCTIONS ****************************************************************/
 
-static NTSTATUS RtlpCreateFirstThread
-(
- HANDLE ProcessHandle,
- ULONG StackReserve,
- ULONG StackCommit,
- LPTHREAD_START_ROUTINE lpStartAddress,
- PCLIENT_ID ClientId,
- PHANDLE ThreadHandle
-)
-{
- return RtlCreateUserThread
- (
-  ProcessHandle,
-  NULL,
-  FALSE,
-  0,
-  &StackReserve,
-  &StackCommit,
-  lpStartAddress,
-  (PVOID)PEB_BASE,
-  ThreadHandle,
-  ClientId
- );
-}
 
 PPEB
 STDCALL
@@ -55,273 +31,26 @@ RtlpCurrentPeb(VOID)
     return NtCurrentPeb();
 }
 
-static NTSTATUS
-RtlpMapFile(PUNICODE_STRING ImageFileName,
-            PRTL_USER_PROCESS_PARAMETERS Ppb,
-           ULONG Attributes,
-           PHANDLE Section)
-{
-   HANDLE hFile;
-   IO_STATUS_BLOCK IoStatusBlock;
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
-   NTSTATUS Status;
-   
-   hFile = NULL;
-
-   RtlDeNormalizeProcessParams (Ppb);
-
-//   DbgPrint("ImagePathName %x\n", Ppb->ImagePathName.Buffer);
-   
-   InitializeObjectAttributes(&ObjectAttributes,
-                             ImageFileName,
-                             Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
-                             NULL,
-                             SecurityDescriptor);
-
-   RtlNormalizeProcessParams (Ppb);
-   
-   /*
-    * Try to open the executable
-    */
-
-   Status = NtOpenFile(&hFile,
-                       SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
-                       &ObjectAttributes,
-                       &IoStatusBlock,
-                       FILE_SHARE_DELETE|FILE_SHARE_READ,
-                       FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
-
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   Status = NtCreateSection(Section,
-                           SECTION_ALL_ACCESS,
-                           NULL,
-                           NULL,
-                           PAGE_EXECUTE,
-                           SEC_IMAGE,
-                           hFile);
-   NtClose(hFile);
-
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
 
-   return(STATUS_SUCCESS);
-}
-
-static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
-                          PRTL_USER_PROCESS_PARAMETERS Ppb,
-                          PVOID* ImageBaseAddress)
+/*
+ * @implemented
+ */
+VOID STDCALL
+RtlAcquirePebLock(VOID)
 {
-   NTSTATUS Status;
-   PVOID PpbBase;
-   ULONG PpbSize;
-   ULONG BytesWritten;
-   ULONG Offset;
-   PVOID EnvPtr = NULL;
-   ULONG EnvSize = 0;
-
-   /* create the Environment */
-   if (Ppb->Environment != NULL)
-     {
-       MEMORY_BASIC_INFORMATION MemInfo;
-
-       Status = NtQueryVirtualMemory (NtCurrentProcess (),
-                                      Ppb->Environment,
-                                      MemoryBasicInformation,
-                                      &MemInfo,
-                                      sizeof(MEMORY_BASIC_INFORMATION),
-                                      NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            return Status;
-         }
-       EnvSize = MemInfo.RegionSize;
-     }
-   DPRINT("EnvironmentSize %ld\n", EnvSize);
-
-   /* allocate and initialize new environment block */
-   if (EnvSize != 0)
-     {
-       Status = NtAllocateVirtualMemory(ProcessHandle,
-                                        &EnvPtr,
-                                        0,
-                                        &EnvSize,
-                                        MEM_RESERVE | MEM_COMMIT,
-                                        PAGE_READWRITE);
-       if (!NT_SUCCESS(Status))
-         {
-            return(Status);
-         }
-
-       NtWriteVirtualMemory(ProcessHandle,
-                            EnvPtr,
-                            Ppb->Environment,
-                            EnvSize,
-                            &BytesWritten);
-     }
-   DPRINT("EnvironmentPointer %p\n", EnvPtr);
-
-   /* create the PPB */
-   PpbBase = NULL;
-   PpbSize = Ppb->AllocationSize;
-
-   Status = NtAllocateVirtualMemory(ProcessHandle,
-                                   &PpbBase,
-                                   0,
-                                   &PpbSize,
-                                   MEM_RESERVE | MEM_COMMIT,
-                                   PAGE_READWRITE);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize);
-
-   /* write process parameters block*/
-   RtlDeNormalizeProcessParams (Ppb);
-   NtWriteVirtualMemory(ProcessHandle,
-                       PpbBase,
-                       Ppb,
-                       Ppb->AllocationSize,
-
-                       &BytesWritten);
-   RtlNormalizeProcessParams (Ppb);
-
-   /* write pointer to environment */
-   Offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
-   NtWriteVirtualMemory(ProcessHandle,
-                       (PVOID)(PpbBase + Offset),
-                       &EnvPtr,
-                       sizeof(EnvPtr),
-                       &BytesWritten);
-
-   /* write pointer to process parameter block */
-   Offset = FIELD_OFFSET(PEB, ProcessParameters);
-   NtWriteVirtualMemory(ProcessHandle,
-                       (PVOID)(PEB_BASE + Offset),
-                       &PpbBase,
-                       sizeof(PpbBase),
-                       &BytesWritten);
-
-   /* Read image base address. */
-   Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
-   NtReadVirtualMemory(ProcessHandle,
-                      (PVOID)(PEB_BASE + Offset),
-                      ImageBaseAddress,
-                      sizeof(PVOID),
-                      &BytesWritten);
-
-   return(STATUS_SUCCESS);
+   PPEB Peb = NtCurrentPeb ();
+   Peb->FastPebLockRoutine (Peb->FastPebLock);
 }
 
+
 /*
  * @implemented
  */
-NTSTATUS STDCALL
-RtlCreateUserProcess(PUNICODE_STRING ImageFileName,
-                    ULONG Attributes,
-                    PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
-                    PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
-                    PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
-                    HANDLE ParentProcess,
-                    BOOLEAN CurrentDirectory,
-                    HANDLE DebugPort,
-                    HANDLE ExceptionPort,
-                    PRTL_PROCESS_INFO ProcessInfo)
+VOID STDCALL
+RtlReleasePebLock(VOID)
 {
-   HANDLE hSection;
-   NTSTATUS Status;
-   PROCESS_BASIC_INFORMATION ProcessBasicInfo;
-   ULONG retlen;
-   SECTION_IMAGE_INFORMATION Sii;
-   ULONG ResultLength;
-   PVOID ImageBaseAddress;
-   
-   DPRINT("RtlCreateUserProcess\n");
-   
-   Status = RtlpMapFile(ImageFileName,
-                        ProcessParameters,
-                       Attributes,
-                       &hSection);
-   if( !NT_SUCCESS( Status ) )
-     return Status;
-
-   /*
-    * Create a new process
-    */
-   if (ParentProcess == NULL)
-     ParentProcess = NtCurrentProcess();
-
-   Status = NtCreateProcess(&(ProcessInfo->ProcessHandle),
-                           PROCESS_ALL_ACCESS,
-                           NULL,
-                           ParentProcess,
-                           CurrentDirectory,
-                           hSection,
-                           DebugPort,
-                           ExceptionPort);
-   if (!NT_SUCCESS(Status))
-     {
-       NtClose(hSection);
-       return(Status);
-     }
-   
-   /*
-    * Get some information about the process
-    */
-   NtQueryInformationProcess(ProcessInfo->ProcessHandle,
-                            ProcessBasicInformation,
-                            &ProcessBasicInfo,
-                            sizeof(ProcessBasicInfo),
-                            &retlen);
-   DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
-         ProcessBasicInfo.UniqueProcessId);
-   ProcessInfo->ClientId.UniqueProcess = (HANDLE)ProcessBasicInfo.UniqueProcessId;
-
-   /*
-    * Create Process Environment Block
-    */
-   DPRINT("Creating peb\n");
-   KlInitPeb(ProcessInfo->ProcessHandle,
-            ProcessParameters,
-            &ImageBaseAddress);
-
-   Status = NtQuerySection(hSection,
-                          SectionImageInformation,
-                          &Sii,
-                          sizeof(Sii),
-                          &ResultLength);
-   if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
-     {
-       DPRINT("Failed to get section image information.\n");
-       NtClose(hSection);
-       return(Status);
-     }
-
-   DPRINT("Creating thread for process\n");
-   Status = RtlpCreateFirstThread(ProcessInfo->ProcessHandle,
-                                 Sii.StackReserve,
-                                 Sii.StackCommit,
-                                 ImageBaseAddress + (ULONG)Sii.EntryPoint,
-                                 &ProcessInfo->ClientId,
-                                 &ProcessInfo->ThreadHandle);
-
-   NtClose(hSection);
-   
-   if (!NT_SUCCESS(Status))
-   {
-       DPRINT("Failed to create thread\n");
-       return(Status);
-   }
-
-   return(STATUS_SUCCESS);
+   PPEB Peb = NtCurrentPeb ();
+   Peb->FastPebUnlockRoutine (Peb->FastPebLock);
 }
 
 
index bb8e1ca..7aafca5 100644 (file)
@@ -9,7 +9,10 @@
 #include <ddk/ntddk.h>
 #include <napi/teb.h>
 
+
 PTEB STDCALL
 _NtCurrentTeb() { return NtCurrentTeb(); }
 
+
+
 /* EOF */
index a8dcde7..22ee513 100644 (file)
@@ -422,13 +422,36 @@ _FUNCTION_ {
                     }\r
                }\r
                break;\r
-           case 'n': {\r
-                   if (!suppress) {\r
-                       int*n = va_arg(ap, int*);\r
-                       *n = consumed - (nch!=_EOF_);\r
-                   }\r
-               }\r
-               break;\r
+       case 'n': {\r
+          if (!suppress) {\r
+         int*n = va_arg(ap, int*);\r
+\r
+         /* \r
+         *n = consumed - (nch!=_EOF_);\r
+         \r
+         FIXME: The above is the Wine version and it doesnt work in ros\r
+         when %n is at end of input string (return one too many).\r
+         But does it fail in Wine too?? If so wine also needs fixin.\r
+         -Gunnar\r
+         */\r
+\r
+         *n = consumed - 1;\r
+          }\r
+          /* This is an odd one: according to the standard,\r
+           * "Execution of a %n directive does not increment the\r
+           * assignment count returned at the completion of\r
+           * execution" even if it wasn't suppressed with the\r
+           * '*' flag.  The Corrigendum to the standard seems\r
+           * to contradict this (comment out the assignment to\r
+           * suppress below if you want to implement these\r
+           * alternate semantics) but the windows program I'm\r
+           * looking at expects the behavior I've coded here\r
+           * (which happens to be what glibc does as well).\r
+           */\r
+          suppress = 1;\r
+          st = 1;\r
+           }\r
+      break;\r
            case '[': {\r
                     _CHAR_ *str = suppress ? NULL : va_arg(ap, _CHAR_*);\r
                     _CHAR_ *sptr = str;\r
index 229f136..81dafe3 100644 (file)
@@ -34,6 +34,7 @@ C_SRCS = \
        regsvr.c \\r
        rpc.c \\r
        stg_bigblockfile.c \\r
+       stg_prop.c \\r
        stg_stream.c \\r
        storage32.c \\r
        stubmanager.c\r
index e21eb5b..124cdde 100644 (file)
@@ -82,7 +82,7 @@
 \r
 /* For CoGetMalloc (MEMCTX_TASK is currently ignored) */\r
 #ifndef MEMCTX_TASK\r
-  #define MEMCTX_TASK -1\r
+define MEMCTX_TASK -1\r
 #endif\r
 \r
 WINE_DEFAULT_DEBUG_CHANNEL(ole);\r
@@ -799,7 +799,7 @@ LRESULT CALLBACK OLEClipbrd_WndProc
      * (Recall that in OleSetClipboard, we used SetClipboardData to\r
      * make all HGLOBAL formats supported by the source IDataObject\r
      * available using delayed rendering)\r
-     * On receiving this mesage we must actually render the data in the\r
+     * On receiving this message we must actually render the data in the\r
      * specified format and place it on the clipboard by calling the\r
      * SetClipboardData function.\r
      */\r
index a3da9bf..ffa5af0 100644 (file)
  *\r
  *   - Implement the service control manager (in rpcss) to keep track\r
  *     of registered class objects: ISCM::ServerRegisterClsid et al\r
- *   - Implement the OXID resolver so we don't need magic pipe names for\r
+ *   - Implement the OXID resolver so we don't need magic endpoint names for\r
  *     clients and servers to meet up\r
- *   - Flip our marshalling on top of the RPC runtime transport API,\r
- *     so we no longer use named pipes to communicate\r
- *   - Implement RPC thread affinity (should fix InstallShield painting\r
- *     problems)\r
+ *\r
+ *   - Pump the message loop during RPC calls.\r
+ *   - Call IMessageFilter functions.\r
  *\r
  *   - Make all ole interface marshaling use NDR to be wire compatible with\r
  *     native DCOM\r
@@ -163,7 +162,7 @@ static CRITICAL_SECTION_DEBUG dll_cs_debug =
 };\r
 static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };\r
 \r
-static const char aptWinClass[] = "WINE_OLE32_APT_CLASS";\r
+static const WCHAR wszAptWinClass[] = {'W','I','N','E','_','O','L','E','3','2','_','A','P','T','_','C','L','A','S','S',0};\r
 static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);\r
 \r
 static void COMPOBJ_DLLList_Add(HANDLE hLibrary);\r
@@ -171,7 +170,7 @@ static void COMPOBJ_DllList_FreeUnused(int Timeout);
 \r
 void COMPOBJ_InitProcess( void )\r
 {\r
-    WNDCLASSA wclass;\r
+    WNDCLASSW wclass;\r
 \r
     /* Dispatching to the correct thread in an apartment is done through\r
      * window messages rather than RPC transports. When an interface is\r
@@ -183,15 +182,15 @@ void COMPOBJ_InitProcess( void )
      * was unmarshalled.\r
      */\r
     memset(&wclass, 0, sizeof(wclass));\r
-    wclass.lpfnWndProc = &COM_AptWndProc;\r
+    wclass.lpfnWndProc = COM_AptWndProc;\r
     wclass.hInstance = OLE32_hInstance;\r
-    wclass.lpszClassName = aptWinClass;\r
-    RegisterClassA(&wclass);\r
+    wclass.lpszClassName = wszAptWinClass;\r
+    RegisterClassW(&wclass);\r
 }\r
 \r
 void COMPOBJ_UninitProcess( void )\r
 {\r
-    UnregisterClassA(aptWinClass, OLE32_hInstance);\r
+    UnregisterClassW(wszAptWinClass, OLE32_hInstance);\r
 }\r
 \r
 void COM_TlsDestroy()\r
@@ -239,7 +238,7 @@ static APARTMENT *apartment_construct(DWORD model)
     {\r
         /* FIXME: should be randomly generated by in an RPC call to rpcss */\r
         apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId();\r
-        apt->win = CreateWindowA(aptWinClass, NULL, 0,\r
+        apt->win = CreateWindowW(wszAptWinClass, NULL, 0,\r
                                  0, 0, 0, 0,\r
                                  0, 0, OLE32_hInstance, NULL);\r
     }\r
@@ -249,8 +248,6 @@ static APARTMENT *apartment_construct(DWORD model)
         apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe;\r
     }\r
 \r
-    apt->shutdown_event = CreateEventW(NULL, TRUE, FALSE, NULL);\r
-    \r
     TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));\r
 \r
     /* the locking here is not currently needed for the MTA case, but it\r
@@ -354,8 +351,6 @@ DWORD COM_ApartmentRelease(struct apartment *apt)
         if (apt->filter) IUnknown_Release(apt->filter);\r
 \r
         DeleteCriticalSection(&apt->cs);\r
-        SetEvent(apt->shutdown_event);\r
-        CloseHandle(apt->shutdown_event);\r
         CloseHandle(apt->thread);\r
         HeapFree(GetProcessHeap(), 0, apt);\r
     }\r
@@ -425,10 +420,15 @@ HWND COM_GetApartmentWin(OXID oxid, BOOL ref)
     return apt->win;\r
 }\r
 \r
-/* Currently inter-thread marshalling is not fully implemented, so this does nothing */\r
 static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
 {\r
-  return DefWindowProcA(hWnd, msg, wParam, lParam);\r
+    switch (msg)\r
+    {\r
+    case DM_EXECUTERPC:\r
+        return RPC_ExecuteCall((RPCOLEMESSAGE *)wParam, (IRpcStubBuffer *)lParam);\r
+    default:\r
+        return DefWindowProcW(hWnd, msg, wParam, lParam);\r
+    }\r
 }\r
 \r
 /*****************************************************************************\r
@@ -473,7 +473,7 @@ static void COMPOBJ_DLLList_Add(HANDLE hLibrary)
 static void COMPOBJ_DllList_FreeUnused(int Timeout)\r
 {\r
     OpenDll *curr, *next, *prev = NULL;\r
-    typedef HRESULT(*DllCanUnloadNowFunc)(void);\r
+    typedef HRESULT (WINAPI *DllCanUnloadNowFunc)(void);\r
     DllCanUnloadNowFunc DllCanUnloadNow;\r
 \r
     TRACE("\n");\r
@@ -1629,7 +1629,7 @@ HRESULT WINAPI CoGetClassObject(
     /* Next try out of process */\r
     if (CLSCTX_LOCAL_SERVER & dwClsContext)\r
     {\r
-        return create_marshalled_proxy(rclsid,iid,ppv);\r
+        return RPC_GetLocalClassObject(rclsid,iid,ppv);\r
     }\r
 \r
     /* Finally try remote: this requires networked DCOM (a lot of work) */\r
index 056f149..a421a58 100644 (file)
@@ -53,10 +53,12 @@ typedef struct apartment APARTMENT;
 \r
 typedef enum ifstub_state\r
 {\r
-    IFSTUB_STATE_NORMAL_MARSHALED,\r
-    IFSTUB_STATE_NORMAL_UNMARSHALED,\r
-    IFSTUB_STATE_TABLE_MARSHALED\r
-} IFSTUB_STATE;\r
+    STUBSTATE_NORMAL_MARSHALED,\r
+    STUBSTATE_NORMAL_UNMARSHALED,\r
+    STUBSTATE_TABLE_WEAK_MARSHALED,\r
+    STUBSTATE_TABLE_WEAK_UNMARSHALED,\r
+    STUBSTATE_TABLE_STRONG,\r
+} STUB_STATE;\r
 \r
 /* an interface stub */\r
 struct ifstub   \r
@@ -66,7 +68,6 @@ struct ifstub
     IID               iid;        /* RO */\r
     IPID              ipid;       /* RO */\r
     IUnknown         *iface;      /* RO */\r
-    IFSTUB_STATE      state;      /* CS stub_manager->lock */\r
 };\r
 \r
 \r
@@ -78,11 +79,12 @@ struct stub_manager
     CRITICAL_SECTION  lock;\r
     APARTMENT        *apt;        /* owning apt (RO) */\r
 \r
-    ULONG             extrefs;    /* number of 'external' references (LOCK) */\r
+    ULONG             extrefs;    /* number of 'external' references (CS lock) */\r
     ULONG             refs;       /* internal reference count (CS apt->cs) */\r
     OID               oid;        /* apartment-scoped unique identifier (RO) */\r
     IUnknown         *object;     /* the object we are managing the stub for (RO) */\r
     ULONG             next_ipid;  /* currently unused (LOCK) */\r
+    STUB_STATE        state;      /* state machine (CS lock) */\r
 };\r
 \r
 /* imported interface proxy */\r
@@ -95,6 +97,7 @@ struct ifproxy
   IPID ipid;               /* imported interface ID (RO) */\r
   LPRPCPROXYBUFFER proxy;  /* interface proxy (RO) */\r
   DWORD refs;              /* imported (public) references (CS parent->cs) */\r
+  IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */\r
 };\r
 \r
 /* imported object / proxy manager */\r
@@ -103,7 +106,6 @@ struct proxy_manager
   const IMultiQIVtbl *lpVtbl;\r
   struct apartment *parent; /* owning apartment (RO) */\r
   struct list entry;        /* entry in apartment (CS parent->cs) */\r
-  LPRPCCHANNELBUFFER chan;  /* channel to object (CS cs) */\r
   OXID oxid;                /* object exported ID (RO) */\r
   OID oid;                  /* object ID (RO) */\r
   struct list interfaces;   /* imported interfaces (CS cs) */\r
@@ -130,11 +132,10 @@ struct apartment
   struct list proxies;     /* imported objects (CS cs) */\r
   struct list stubmgrs;    /* stub managers for exported objects (CS cs) */\r
   BOOL remunk_exported;    /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */\r
+  LONG remoting_started;   /* has the RPC system been started for this apartment? (LOCK) */\r
 \r
-  /* FIXME: These should all be removed long term as they leak information that should be encapsulated */\r
+  /* FIXME: OID's should be given out by RPCSS */\r
   OID oidc;                /* object ID counter, starts at 1, zero is invalid OID (CS cs) */\r
-  DWORD listenertid;       /* id of apartment_listener_thread */\r
-  HANDLE shutdown_event;   /* event used to tell the client_dispatch_thread to shut down */\r
 };\r
 \r
 /* this is what is stored in TEB->ReservedForOle */\r
@@ -146,59 +147,49 @@ struct oletls
     DWORD            inits;        /* number of times CoInitializeEx called */\r
 };\r
 \r
+\r
+/* Global Interface Table Functions */\r
+\r
 extern void* StdGlobalInterfaceTable_Construct(void);\r
 extern void  StdGlobalInterfaceTable_Destroy(void* self);\r
 extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);\r
+extern void* StdGlobalInterfaceTableInstance;\r
 \r
 /* FIXME: these shouldn't be needed, except for 16-bit functions */\r
 extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);\r
 HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);\r
 \r
-extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv);\r
-\r
-extern void* StdGlobalInterfaceTableInstance;\r
-\r
-/* Standard Marshalling definitions */\r
-typedef struct _wine_marshal_id {\r
-    OXID    oxid;       /* id of apartment */\r
-    OID     oid;        /* id of stub manager */\r
-    IPID    ipid;       /* id of interface pointer */\r
-} wine_marshal_id;\r
-\r
-inline static BOOL\r
-MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {\r
-    return\r
-       (mid1->oxid == mid2->oxid)      &&\r
-       (mid1->oid == mid2->oid)        &&\r
-       IsEqualGUID(&(mid1->ipid),&(mid2->ipid))\r
-    ;\r
-}\r
-\r
 HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt);\r
 HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);\r
 \r
+/* Stub Manager */\r
+\r
 ULONG stub_manager_int_addref(struct stub_manager *This);\r
 ULONG stub_manager_int_release(struct stub_manager *This);\r
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);\r
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags);\r
 ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);\r
 ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);\r
-struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, BOOL tablemarshal);\r
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid);\r
 struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);\r
 struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object);\r
 void apartment_disconnect_object(APARTMENT *apt, void *object);\r
-BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);\r
-BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);\r
+BOOL stub_manager_notify_unmarshal(struct stub_manager *m);\r
+BOOL stub_manager_is_table_marshaled(struct stub_manager *m);\r
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs);\r
 HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);\r
 HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);\r
-IRpcStubBuffer *ipid_to_stubbuffer(const IPID *ipid);\r
+IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);\r
 HRESULT start_apartment_remote_unknown(void);\r
 \r
-IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid);\r
-\r
-void start_apartment_listener_thread(void);\r
+/* RPC Backend */\r
 \r
-extern HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf);\r
-void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);\r
+void    RPC_StartRemoting(struct apartment *apt);\r
+HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);\r
+HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub);\r
+HRESULT RPC_RegisterInterface(REFIID riid);\r
+void    RPC_UnregisterInterface(REFIID riid);\r
+void    RPC_StartLocalServer(REFCLSID clsid, IStream *stream);\r
+HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);\r
 \r
 /* This function initialize the Running Object Table */\r
 HRESULT WINAPI RunningObjectTableImpl_Initialize(void);\r
@@ -209,12 +200,17 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize(void);
 /* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */\r
 int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);\r
 \r
-/* compobj.c */\r
+\r
+/* Apartment Functions */\r
+\r
 APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref);\r
 APARTMENT *COM_ApartmentFromTID(DWORD tid);\r
 DWORD COM_ApartmentAddRef(struct apartment *apt);\r
 DWORD COM_ApartmentRelease(struct apartment *apt);\r
 \r
+/* messages used by the apartment window (not compatible with native) */\r
+#define DM_EXECUTERPC   (WM_USER + 0) /* WPARAM = (RPCOLEMESSAGE *), LPARAM = (IRpcStubBuffer *) */\r
+\r
 /*\r
  * Per-thread values are stored in the TEB on offset 0xF80,\r
  * see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm\r
index 5c12734..6a33aa8 100644 (file)
@@ -386,11 +386,10 @@ static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpFile(
        LPOLESTR szHelpFile)\r
 {\r
        _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);\r
-       TRACE("(%p)\n",This);\r
+       TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile));\r
        if (This->bstrHelpFile != NULL)\r
            ERRORINFO_SysFreeString(This->bstrHelpFile);\r
        This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile);\r
-\r
        return S_OK;\r
 }\r
 \r
@@ -399,9 +398,8 @@ static HRESULT WINAPI ICreateErrorInfoImpl_SetHelpContext(
        DWORD dwHelpContext)\r
 {\r
        _ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);\r
-       TRACE("(%p)\n",This);\r
+       TRACE("(%p,%ld)\n",This,dwHelpContext);\r
        This->m_dwHelpContext = dwHelpContext;\r
-\r
        return S_OK;\r
 }\r
 \r
index d953698..8c4fffe 100644 (file)
@@ -157,7 +157,7 @@ HRESULT WINAPI FileMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
 {\r
     FileMonikerImpl *This = (FileMonikerImpl *)iface;\r
 \r
-  TRACE("(%p,%p,%p)\n",This,riid,ppvObject);\r
+  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);\r
 \r
     /* Perform a sanity check on the parameters.*/\r
     if ( (This==0) || (ppvObject==0) )\r
@@ -223,7 +223,7 @@ ULONG WINAPI FileMonikerImpl_Release(IMoniker* iface)
 HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,\r
                                           CLSID *pClassID)/* Pointer to CLSID of object */\r
 {\r
-    TRACE("(%p,%p),stub!\n",iface,pClassID);\r
+    TRACE("(%p,%p)\n",iface,pClassID);\r
 \r
     if (pClassID==NULL)\r
         return E_POINTER;\r
@@ -473,7 +473,7 @@ HRESULT WINAPI FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPa
     static const WCHAR bkSlash[]={'\\',0};\r
     BYTE addBkSlash;\r
 \r
-    TRACE("(%p,%p)\n",This,lpszPathName);\r
+    TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));\r
 \r
     /* Initialize the virtual fgunction table. */\r
     This->lpvtbl1      = &VT_FileMonikerImpl;\r
@@ -566,7 +566,7 @@ HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface,
 \r
     *ppvResult=0;\r
 \r
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);\r
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);\r
 \r
     if(pmkToLeft==NULL){\r
 \r
@@ -673,7 +673,7 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
     IStorage *pstg=0;\r
     HRESULT res;\r
 \r
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);\r
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);\r
 \r
     if (pmkToLeft==NULL){\r
 \r
@@ -708,7 +708,7 @@ HRESULT WINAPI FileMonikerImpl_BindToStorage(IMoniker* iface,
     }\r
     else {\r
 \r
-        FIXME("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);\r
+        FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);\r
 \r
         return E_NOTIMPL;\r
     }\r
@@ -1243,6 +1243,8 @@ HRESULT WINAPI FileMonikerImpl_GetDisplayName(IMoniker* iface,
 \r
     strcpyW(*ppszDisplayName,This->filePathName);\r
 \r
+    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));\r
+    \r
     return S_OK;\r
 }\r
 \r
@@ -1283,7 +1285,7 @@ HRESULT WINAPI FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid
 \r
     ICOM_THIS_From_IROTData(IMoniker, iface);\r
 \r
-    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);\r
+    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);\r
 \r
     return FileMonikerImpl_QueryInterface(This, riid, ppvObject);\r
 }\r
@@ -1329,29 +1331,28 @@ HRESULT WINAPI FileMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
  ******************************************************************************/\r
 HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)\r
 {\r
-    FileMonikerImpl* newFileMoniker = 0;\r
-    HRESULT  hr = E_FAIL;\r
-    IID riid=IID_IMoniker;\r
+    FileMonikerImpl* newFileMoniker;\r
+    HRESULT  hr;\r
 \r
-    TRACE("(%p,%p)\n",lpszPathName,ppmk);\r
+    TRACE("(%s,%p)\n",debugstr_w(lpszPathName),ppmk);\r
 \r
-    if (ppmk==NULL)\r
+    if (!ppmk)\r
         return E_POINTER;\r
 \r
-    if(lpszPathName==NULL)\r
+    if(!lpszPathName)\r
         return MK_E_SYNTAX;\r
 \r
-    *ppmk=0;\r
+    *ppmk=NULL;\r
 \r
     newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));\r
 \r
-    if (newFileMoniker == 0)\r
+    if (!newFileMoniker)\r
         return E_OUTOFMEMORY;\r
 \r
     hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);\r
 \r
     if (SUCCEEDED(hr))\r
-       hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)ppmk);\r
+       hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&IID_IMoniker,(void**)ppmk);\r
     else\r
         HeapFree(GetProcessHeap(),0,newFileMoniker);\r
 \r
index 18c02c2..a6ab947 100644 (file)
@@ -223,6 +223,7 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
   IStream* stream = NULL;\r
   HRESULT hres;\r
   StdGITEntry* entry;\r
+  static const LARGE_INTEGER zero;\r
 \r
   TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);\r
 \r
@@ -230,8 +231,18 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
   \r
   /* marshal the interface */\r
   TRACE("About to marshal the interface\n");\r
-  hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream);\r
+\r
+  hres = CreateStreamOnHGlobal(0, TRUE, &stream);\r
   if (hres) return hres;\r
+  hres = CoMarshalInterface(stream, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);\r
+  if (hres)\r
+  {\r
+    IStream_Release(stream);\r
+    return hres;\r
+  }\r
+\r
+  IStream_Seek(stream, zero, SEEK_SET, NULL);\r
+\r
   entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));\r
   if (entry == NULL) return E_OUTOFMEMORY;\r
 \r
@@ -261,6 +272,7 @@ HRESULT WINAPI StdGlobalInterfaceTable_RegisterInterfaceInGlobal(IGlobalInterfac
 HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {\r
   StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;\r
   StdGITEntry* entry;\r
+  HRESULT hr;\r
 \r
   TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);\r
   \r
@@ -271,6 +283,12 @@ HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfac
   }\r
   \r
   /* Free the stream */\r
+  hr = CoReleaseMarshalData(entry->stream);\r
+  if (hr != S_OK)\r
+  {\r
+    WARN("Failed to release marshal data, hr = 0x%08lx\n", hr);\r
+    return hr;\r
+  }\r
   IStream_Release(entry->stream);\r
                    \r
   /* chop entry out of the list, and free the memory */\r
index 4c1e4e3..7c59545 100644 (file)
@@ -156,7 +156,7 @@ HRESULT WINAPI ItemMonikerImpl_QueryInterface(IMoniker* iface,REFIID riid,void**
 {\r
     ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
 \r
-  TRACE("(%p,%p,%p)\n",This,riid,ppvObject);\r
+  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);\r
 \r
   /* Perform a sanity check on the parameters.*/\r
     if ( (This==0) || (ppvObject==0) )\r
@@ -221,7 +221,7 @@ ULONG WINAPI ItemMonikerImpl_Release(IMoniker* iface)
  ******************************************************************************/\r
 HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)\r
 {\r
-    TRACE("(%p,%p),stub!\n",iface,pClassID);\r
+    TRACE("(%p,%p)\n",iface,pClassID);\r
 \r
     if (pClassID==NULL)\r
         return E_POINTER;\r
@@ -257,6 +257,8 @@ HRESULT WINAPI ItemMonikerImpl_Load(IMoniker* iface,IStream* pStm)
     CHAR *itemNameA,*itemDelimiterA;\r
     ULONG bread;\r
 \r
+    TRACE("\n");\r
+\r
     /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */\r
 \r
     /* read item delimiter string length + 1 */\r
@@ -335,6 +337,8 @@ HRESULT WINAPI ItemMonikerImpl_Save(IMoniker* iface,
     WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);\r
     WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);\r
 \r
+    TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");\r
+\r
     res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);\r
     res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);\r
     res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);\r
@@ -381,7 +385,7 @@ HRESULT WINAPI ItemMonikerImpl_Construct(ItemMonikerImpl* This, LPCOLESTR lpszDe
     static const OLECHAR emptystr[1];\r
     LPCOLESTR  delim;\r
 \r
-    TRACE("(%p,%p)\n",This,lpszItem);\r
+    TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));\r
 \r
     /* Initialize the virtual fgunction table. */\r
     This->lpvtbl1      = &VT_ItemMonikerImpl;\r
@@ -437,7 +441,7 @@ HRESULT WINAPI ItemMonikerImpl_BindToObject(IMoniker* iface,
     IID    refid=IID_IOleItemContainer;\r
     IOleItemContainer *poic=0;\r
 \r
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);\r
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);\r
 \r
     if(ppvResult ==NULL)\r
         return E_POINTER;\r
@@ -473,7 +477,7 @@ HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface,
     HRESULT   res;\r
     IOleItemContainer *poic=0;\r
 \r
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);\r
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);\r
 \r
     *ppvResult=0;\r
 \r
@@ -781,6 +785,9 @@ HRESULT WINAPI ItemMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)\r
 {\r
     DWORD mkSys;\r
+    \r
+    TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);\r
+\r
     IMoniker_IsSystemMoniker(pmkOther,&mkSys);\r
     /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */\r
     /* to this moniker and returns MK_S_US */\r
@@ -841,6 +848,8 @@ HRESULT WINAPI ItemMonikerImpl_GetDisplayName(IMoniker* iface,
     lstrcpyW(*ppszDisplayName,This->itemDelimiter);\r
     lstrcatW(*ppszDisplayName,This->itemName);\r
 \r
+    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));\r
+\r
     return S_OK;\r
 }\r
 \r
@@ -860,6 +869,8 @@ HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface,
     HRESULT res;\r
     ItemMonikerImpl *This = (ItemMonikerImpl *)iface;\r
 \r
+    TRACE("%s\n", debugstr_w(pszDisplayName));\r
+\r
     /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */\r
     if (pmkToLeft==NULL)\r
 \r
@@ -955,15 +966,14 @@ HRESULT WINAPI ItemMonikerROTDataImpl_GetComparaisonData(IROTData* iface,
  ******************************************************************************/\r
 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR  lpszItem, LPMONIKER * ppmk)\r
 {\r
-    ItemMonikerImpl* newItemMoniker = 0;\r
-    HRESULT        hr = S_OK;\r
-    IID riid=IID_IMoniker;\r
+    ItemMonikerImpl* newItemMoniker;\r
+    HRESULT        hr;\r
 \r
-    TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);\r
+    TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);\r
 \r
     newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));\r
 \r
-    if (newItemMoniker == 0)\r
+    if (!newItemMoniker)\r
         return STG_E_INSUFFICIENTMEMORY;\r
 \r
     hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);\r
@@ -974,5 +984,5 @@ HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR  lpszItem, LPMONI
     return hr;\r
     }\r
 \r
-    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);\r
+    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);\r
 }\r
index 2ae897a..b0839c7 100644 (file)
@@ -117,13 +117,15 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
 \r
     stdobjref->oxid = apt->oxid;\r
 \r
+    /* FIXME: what happens if we register an interface twice with different\r
+     * marshaling flags? */\r
     if ((manager = get_stub_manager_from_object(apt, obj)))\r
         TRACE("registering new ifstub on pre-existing manager\n");\r
     else\r
     {\r
         TRACE("constructing new stub manager\n");\r
 \r
-        manager = new_stub_manager(apt, obj);\r
+        manager = new_stub_manager(apt, obj, mshlflags);\r
         if (!manager)\r
             return E_OUTOFMEMORY;\r
     }\r
@@ -131,7 +133,7 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
 \r
     tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));\r
 \r
-    ifstub = stub_manager_new_ifstub(manager, stub, obj, riid, tablemarshal);\r
+    ifstub = stub_manager_new_ifstub(manager, stub, obj, riid);\r
     if (!ifstub)\r
     {\r
         IRpcStubBuffer_Release(stub);\r
@@ -153,6 +155,9 @@ HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkn
             stub_manager_ext_addref(manager, 1);\r
     }\r
 \r
+    /* FIXME: check return value */\r
+    RPC_RegisterInterface(riid);\r
+\r
     stdobjref->ipid = ifstub->ipid;\r
 \r
     stub_manager_int_release(manager);\r
@@ -372,12 +377,17 @@ static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
     return hr;\r
 }\r
 \r
+/* should be called inside This->parent->cs critical section */\r
 static void ifproxy_disconnect(struct ifproxy * This)\r
 {\r
     ifproxy_release_public_refs(This);\r
     if (This->proxy) IRpcProxyBuffer_Disconnect(This->proxy);\r
+\r
+    IRpcChannelBuffer_Release(This->chan);\r
+    This->chan = NULL;\r
 }\r
 \r
+/* should be called in This->parent->cs critical section if it is an entry in parent's list */\r
 static void ifproxy_destroy(struct ifproxy * This)\r
 {\r
     TRACE("%p\n", This);\r
@@ -388,6 +398,12 @@ static void ifproxy_destroy(struct ifproxy * This)
 \r
     list_remove(&This->entry);\r
 \r
+    if (This->chan)\r
+    {\r
+        IRpcChannelBuffer_Release(This->chan);\r
+        This->chan = NULL;\r
+    }\r
+\r
     /* note: we don't call Release for This->proxy because its lifetime is\r
      * controlled by the return value from ClientIdentity_Release, which this\r
      * function is always called from */\r
@@ -397,7 +413,7 @@ static void ifproxy_destroy(struct ifproxy * This)
 \r
 static HRESULT proxy_manager_construct(\r
     APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,\r
-    IRpcChannelBuffer * channel, struct proxy_manager ** proxy_manager)\r
+    struct proxy_manager ** proxy_manager)\r
 {\r
     struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));\r
     if (!This) return E_OUTOFMEMORY;\r
@@ -423,9 +439,6 @@ static HRESULT proxy_manager_construct(
      * should store the STDOBJREF flags in the proxy manager. */\r
     This->sorflags = sorflags;\r
 \r
-    assert(channel);\r
-    This->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */\r
-\r
     /* we create the IRemUnknown proxy on demand */\r
     This->remunk = NULL;\r
 \r
@@ -473,8 +486,8 @@ static HRESULT proxy_manager_query_local_interface(struct proxy_manager * This,
 }\r
 \r
 static HRESULT proxy_manager_create_ifproxy(\r
-    struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs,\r
-    struct ifproxy ** iif_out)\r
+    struct proxy_manager * This, const IPID *ipid, REFIID riid, ULONG cPublicRefs,\r
+    IRpcChannelBuffer * channel, struct ifproxy ** iif_out)\r
 {\r
     HRESULT hr;\r
     IPSFactoryBuffer * psfb;\r
@@ -484,11 +497,14 @@ static HRESULT proxy_manager_create_ifproxy(
     list_init(&ifproxy->entry);\r
 \r
     ifproxy->parent = This;\r
-    ifproxy->ipid = ipid;\r
+    ifproxy->ipid = *ipid;\r
     ifproxy->iid = *riid;\r
     ifproxy->refs = cPublicRefs;\r
     ifproxy->proxy = NULL;\r
 \r
+    assert(channel);\r
+    ifproxy->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */\r
+\r
     /* the IUnknown interface is special because it does not have a\r
      * proxy associated with the ifproxy as we handle IUnknown ourselves */\r
     if (IsEqualIID(riid, &IID_IUnknown))\r
@@ -517,7 +533,7 @@ static HRESULT proxy_manager_create_ifproxy(
                 debugstr_guid(riid), hr);\r
 \r
         if (hr == S_OK)\r
-            hr = IRpcProxyBuffer_Connect(ifproxy->proxy, This->chan);\r
+            hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan);\r
     }\r
 \r
     /* get at least one external reference to the object to keep it alive */\r
@@ -532,7 +548,7 @@ static HRESULT proxy_manager_create_ifproxy(
 \r
         *iif_out = ifproxy;\r
         TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n",\r
-              ifproxy, debugstr_guid(&ipid), debugstr_guid(riid), cPublicRefs);\r
+              ifproxy, debugstr_guid(ipid), debugstr_guid(riid), cPublicRefs);\r
     }\r
     else\r
         ifproxy_destroy(ifproxy);\r
@@ -579,11 +595,6 @@ static void proxy_manager_disconnect(struct proxy_manager * This)
     /* apartment is being destroyed so don't keep a pointer around to it */\r
     This->parent = NULL;\r
 \r
-    /* FIXME: will this still be necessary if/when we use a real RPC\r
-     * channel? */\r
-    IRpcChannelBuffer_Release(This->chan);\r
-    This->chan = NULL;\r
-\r
     LeaveCriticalSection(&This->cs);\r
 }\r
 \r
@@ -671,7 +682,6 @@ static void proxy_manager_destroy(struct proxy_manager * This)
     }\r
 \r
     if (This->remunk) IRemUnknown_Release(This->remunk);\r
-    if (This->chan) IRpcChannelBuffer_Release(This->chan);\r
 \r
     DeleteCriticalSection(&This->cs);\r
 \r
@@ -792,8 +802,8 @@ StdMarshalImpl_MarshalInterface(
       return CO_E_NOTINITIALIZED;\r
   }\r
 \r
-  start_apartment_listener_thread(); /* just to be sure we have one running. */\r
-  start_apartment_remote_unknown();\r
+  /* make sure this apartment can be reached from other threads / processes */\r
+  RPC_StartRemoting(apt);\r
 \r
   hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);\r
   if (hres != S_OK)\r
@@ -839,18 +849,9 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
      * object */\r
     if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))\r
     {\r
-        IRpcChannelBuffer *chanbuf;\r
-        wine_marshal_id mid;\r
-\r
-        mid.oxid = stdobjref->oxid;\r
-        mid.oid = stdobjref->oid;\r
-        mid.ipid = stdobjref->ipid;\r
-\r
-        hr = PIPE_GetNewPipeBuf(&mid,&chanbuf);\r
-        if (hr == S_OK)\r
-            hr = proxy_manager_construct(apt, stdobjref->flags,\r
-                                         stdobjref->oxid, stdobjref->oid,\r
-                                         chanbuf, &proxy_manager);\r
+        hr = proxy_manager_construct(apt, stdobjref->flags,\r
+                                     stdobjref->oxid, stdobjref->oid,\r
+                                     &proxy_manager);\r
     }\r
     else\r
         TRACE("proxy manager already created, using\n");\r
@@ -860,9 +861,14 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
         struct ifproxy * ifproxy;\r
         hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);\r
         if (hr == E_NOINTERFACE)\r
-            hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref->ipid,\r
-                                              riid, stdobjref->cPublicRefs,\r
-                                              &ifproxy);\r
+        {\r
+            IRpcChannelBuffer *chanbuf;\r
+            hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);\r
+            if (hr == S_OK)\r
+                hr = proxy_manager_create_ifproxy(proxy_manager, &stdobjref->ipid,\r
+                                                  riid, stdobjref->cPublicRefs,\r
+                                                  chanbuf, &ifproxy);\r
+        }\r
 \r
         if (hr == S_OK)\r
         {\r
@@ -911,7 +917,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
       hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);\r
       \r
       /* unref the ifstub. FIXME: only do this on success? */\r
-      if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))\r
+      if (!stub_manager_is_table_marshaled(stubmgr))\r
           stub_manager_ext_release(stubmgr, 1);\r
 \r
       stub_manager_int_release(stubmgr);\r
@@ -927,7 +933,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
   {\r
       if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))\r
       {\r
-          if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))\r
+          if (!stub_manager_notify_unmarshal(stubmgr))\r
               hres = CO_E_OBJNOTCONNECTED;\r
 \r
           stub_manager_int_release(stubmgr);\r
@@ -982,9 +988,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm) {
         return RPC_E_INVALID_OBJREF;\r
     }\r
 \r
-    /* FIXME: don't release if table-weak and already unmarshaled an object */\r
-    /* FIXME: this should also depend on stdobjref.cPublicRefs */\r
-    stub_manager_ext_release(stubmgr, 1);\r
+    stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs);\r
 \r
     stub_manager_int_release(stubmgr);\r
     COM_ApartmentRelease(apt);\r
@@ -1418,11 +1422,19 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
 \r
     if (hr == S_OK)\r
     {\r
-        hr = IUnknown_QueryInterface(object, &iid, ppv);\r
-        if (hr)\r
-            ERR("Couldn't query for interface %s, hr = 0x%08lx\n",\r
-                debugstr_guid(riid), hr);\r
-        IUnknown_Release(object);\r
+        if (!IsEqualIID(riid, &iid))\r
+        {\r
+            TRACE("requested interface != marshalled interface, additional QI needed\n");\r
+            hr = IUnknown_QueryInterface(object, &iid, ppv);\r
+            if (hr)\r
+                ERR("Couldn't query for interface %s, hr = 0x%08lx\n",\r
+                    debugstr_guid(riid), hr);\r
+            IUnknown_Release(object);\r
+        }\r
+        else\r
+        {\r
+            *ppv = object;\r
+        }\r
     }\r
 \r
     IMarshal_Release(pMarshal);\r
index cfa0b5a..3760001 100644 (file)
@@ -1036,7 +1036,7 @@ static BOOL OLEMenu_FindMainMenuIndex( HMENU hMainMenu, HMENU hPopupMenu, UINT *
  * All menu messages from these groups should be routed to the server.\r
  *\r
  * RETURNS: TRUE if the popup menu is part of a server owned group\r
- *          FASE if the popup menu is part of a container owned group\r
+ *          FALSE if the popup menu is part of a container owned group\r
  */\r
 BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDescriptor )\r
 {\r
index 3a8d333..678db39 100644 (file)
 @ stub SNB_UserUnmarshal\r
 @ stdcall StgCreateDocfile(wstr long long ptr)\r
 @ stdcall StgCreateDocfileOnILockBytes(ptr long long ptr)\r
+@ stdcall StgCreatePropSetStg(ptr long ptr)\r
 @ stdcall StgCreateStorageEx(wstr long long long ptr ptr ptr ptr)\r
 @ stub StgGetIFillLockBytesOnFile\r
 @ stub StgGetIFillLockBytesOnILockBytes\r
index fe35b86..9cc776b 100644 (file)
@@ -43,6 +43,7 @@
        <file>regsvr.c</file>\r
        <file>rpc.c</file>\r
        <file>stg_bigblockfile.c</file>\r
+       <file>stg_prop.c</file>\r
        <file>stg_stream.c</file>\r
        <file>storage32.c</file>\r
        <file>stubmanager.c</file>\r
index 951d166..2653017 100644 (file)
@@ -191,10 +191,8 @@ CFStub_Invoke(
 \r
        msg->cbBuffer = ststg.cbSize.u.LowPart;\r
 \r
-       if (msg->Buffer)\r
-           msg->Buffer = HeapReAlloc(GetProcessHeap(),0,msg->Buffer,ststg.cbSize.u.LowPart);\r
-       else\r
-           msg->Buffer = HeapAlloc(GetProcessHeap(),0,ststg.cbSize.u.LowPart);\r
+        I_RpcGetBuffer((RPC_MESSAGE *)msg);\r
+        if (hres) return hres;\r
 \r
        seekto.u.LowPart = 0;seekto.u.HighPart = 0;\r
        hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);\r
@@ -547,10 +545,10 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
 \r
     /* out */\r
     pMsg->cbBuffer = cIids * sizeof(REMQIRESULT);\r
-    if (pMsg->Buffer)\r
-        pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer);\r
-       else\r
-        pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer);\r
+\r
+    I_RpcGetBuffer((RPC_MESSAGE *)pMsg);\r
+    if (hr) return hr;\r
+\r
     buf = pMsg->Buffer;\r
     /* FIXME: pQIResults is a unique pointer so pQIResults can be NULL! */\r
     memcpy(buf, pQIResults, cIids * sizeof(REMQIRESULT));\r
@@ -574,12 +572,13 @@ static HRESULT WINAPI RemUnkStub_Invoke(LPRPCSTUBBUFFER iface,
 \r
     /* out */\r
     pMsg->cbBuffer = cIids * sizeof(HRESULT);\r
-    if (pMsg->Buffer)\r
-        pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer);\r
-       else\r
-        pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer);\r
-    buf = pMsg->Buffer;\r
-    memcpy(buf, pResults, cIids * sizeof(HRESULT));\r
+\r
+    I_RpcGetBuffer((RPC_MESSAGE *)pMsg);\r
+    if (!hr)\r
+    {\r
+        buf = pMsg->Buffer;\r
+        memcpy(buf, pResults, cIids * sizeof(HRESULT));\r
+    }\r
 \r
     CoTaskMemFree(pResults);\r
 \r
index e726204..c4c0bb2 100644 (file)
@@ -1,6 +1,7 @@
 /*\r
  *     (Local) RPC Stuff\r
  *\r
+ * Copyright 2001  Ove Kåven, TransGaming Technologies\r
  * Copyright 2002  Marcus Meissner\r
  * Copyright 2005  Mike Hearn, Rob Shearman for CodeWeavers\r
  *\r
 \r
 WINE_DEFAULT_DEBUG_CHANNEL(ole);\r
 \r
-#define PIPEPREF "\\\\.\\pipe\\"\r
-#define OLESTUBMGR PIPEPREF"WINE_OLE_StubMgr"\r
+static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg);\r
 \r
-#define REQTYPE_REQUEST                0\r
-#define REQTYPE_RESPONSE       1\r
+/* we only use one function to dispatch calls for all methods - we use the\r
+ * RPC_IF_OLE flag to tell the RPC runtime that this is the case */\r
+static RPC_DISPATCH_FUNCTION rpc_dispatch_table[1] = { dispatch_rpc }; /* (RO) */\r
+static RPC_DISPATCH_TABLE rpc_dispatch = { 1, rpc_dispatch_table }; /* (RO) */\r
 \r
-struct request_header\r
+static struct list registered_interfaces = LIST_INIT(registered_interfaces); /* (CS csRegIf) */\r
+static CRITICAL_SECTION csRegIf;\r
+static CRITICAL_SECTION_DEBUG csRegIf_debug =\r
 {\r
-    DWORD              reqid;\r
-    IPID               ipid;\r
-    DWORD              iMethod;\r
-    DWORD              cbBuffer;\r
+    0, 0, &csRegIf,\r
+    { &csRegIf_debug.ProcessLocksList, &csRegIf_debug.ProcessLocksList },\r
+      0, 0, { 0, (DWORD)(__FILE__ ": dcom registered server interfaces") }\r
 };\r
+static CRITICAL_SECTION csRegIf = { &csRegIf_debug, -1, 0, 0, 0, 0 };\r
+\r
+static WCHAR wszPipeTransport[] = {'n','c','a','c','n','_','n','p',0};\r
+\r
 \r
-struct response_header\r
+struct registered_if\r
 {\r
-    DWORD              reqid;\r
-    DWORD              cbBuffer;\r
-    DWORD              retval;\r
+    struct list entry;\r
+    DWORD refs; /* ref count */\r
+    RPC_SERVER_INTERFACE If; /* interface registered with the RPC runtime */\r
 };\r
 \r
+/* get the pipe endpoint specified of the specified apartment */\r
+static inline void get_rpc_endpoint(LPWSTR endpoint, const OXID *oxid)\r
+{\r
+    /* FIXME: should get endpoint from rpcss */\r
+    static const WCHAR wszEndpointFormat[] = {'\\','p','i','p','e','\\','O','L','E','_','%','0','8','l','x','%','0','8','l','x',0};\r
+    wsprintfW(endpoint, wszEndpointFormat, (DWORD)(*oxid >> 32),(DWORD)*oxid);\r
+}\r
 \r
-#define REQSTATE_START                 0\r
-#define REQSTATE_REQ_QUEUED            1\r
-#define REQSTATE_REQ_WAITING_FOR_REPLY 2\r
-#define REQSTATE_REQ_GOT               3\r
-#define REQSTATE_INVOKING              4\r
-#define REQSTATE_RESP_QUEUED           5\r
-#define REQSTATE_RESP_GOT              6\r
-#define REQSTATE_DONE                  6\r
+typedef struct\r
+{\r
+    const IRpcChannelBufferVtbl *lpVtbl;\r
+    DWORD                  refs;\r
+} RpcChannelBuffer;\r
 \r
-struct rpc\r
+typedef struct\r
 {\r
-    int                                state;\r
-    HANDLE                     hPipe;  /* temp copy of handle */\r
-    struct request_header      reqh;\r
-    struct response_header     resph;\r
-    LPBYTE                     Buffer;\r
-};\r
+    RpcChannelBuffer       super; /* superclass */\r
 \r
-/* fixme: this should have a lock */\r
-static struct rpc **reqs = NULL;\r
-static int nrofreqs = 0;\r
+    RPC_BINDING_HANDLE     bind; /* handle to the remote server */\r
+} ClientRpcChannelBuffer;\r
 \r
-/* This pipe is _thread_ based, each thread which talks to a remote\r
- * apartment (oxid) has its own pipe. The same structure is used both\r
- * for outgoing and incoming RPCs.\r
- */\r
-struct pipe\r
+static HRESULT WINAPI RpcChannelBuffer_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv)\r
 {\r
-    wine_marshal_id    mid;    /* target mid */\r
-    DWORD              tid;    /* thread which owns this pipe */\r
-    HANDLE             hPipe;\r
+    *ppv = NULL;\r
+    if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown))\r
+    {\r
+        *ppv = (LPVOID)iface;\r
+        IUnknown_AddRef(iface);\r
+        return S_OK;\r
+    }\r
+    return E_NOINTERFACE;\r
+}\r
 \r
-    int                        pending;\r
-    HANDLE             hThread;\r
-    CRITICAL_SECTION   crit;\r
+static ULONG WINAPI RpcChannelBuffer_AddRef(LPRPCCHANNELBUFFER iface)\r
+{\r
+    RpcChannelBuffer *This = (RpcChannelBuffer *)iface;\r
+    return InterlockedIncrement(&This->refs);\r
+}\r
 \r
-    APARTMENT          *apt;    /* apartment of the marshalling thread for the stub dispatch case */\r
-};\r
+static ULONG WINAPI ServerRpcChannelBuffer_Release(LPRPCCHANNELBUFFER iface)\r
+{\r
+    RpcChannelBuffer *This = (RpcChannelBuffer *)iface;\r
+    ULONG ref;\r
 \r
-typedef struct _PipeBuf {\r
-    IRpcChannelBufferVtbl *lpVtbl;\r
-    DWORD                  ref;\r
+    ref = InterlockedDecrement(&This->refs);\r
+    if (ref)\r
+        return ref;\r
 \r
-    wine_marshal_id        mid;\r
-    HANDLE                 pipe;\r
-} PipeBuf;\r
+    HeapFree(GetProcessHeap(), 0, This);\r
+    return 0;\r
+}\r
 \r
+static ULONG WINAPI ClientRpcChannelBuffer_Release(LPRPCCHANNELBUFFER iface)\r
+{\r
+    ClientRpcChannelBuffer *This = (ClientRpcChannelBuffer *)iface;\r
+    ULONG ref;\r
 \r
+    ref = InterlockedDecrement(&This->super.refs);\r
+    if (ref)\r
+        return ref;\r
 \r
-/* some helper functions */\r
+    RpcBindingFree(&This->bind);\r
+    HeapFree(GetProcessHeap(), 0, This);\r
+    return 0;\r
+}\r
 \r
-static HRESULT WINAPI read_pipe(HANDLE hf, LPVOID ptr, DWORD size)\r
+static HRESULT WINAPI ServerRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid)\r
 {\r
-    DWORD res;\r
-    \r
-    if (!ReadFile(hf,ptr,size,&res,NULL))\r
-    {\r
-        ERR("Failed to read from %p, le is %ld\n",hf,GetLastError());\r
-        return E_FAIL;\r
-    }\r
-    \r
-    if (res != size)\r
-    {\r
-        if (!res)\r
-        {\r
-           WARN("%p disconnected\n", hf);\r
-           return RPC_E_DISCONNECTED;\r
-        }\r
-        ERR("Read only %ld of %ld bytes from %p.\n",res,size,hf);\r
-        return E_FAIL;\r
-    }\r
-    return S_OK;\r
-}\r
+    RpcChannelBuffer *This = (RpcChannelBuffer *)iface;\r
+    RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;\r
+    RPC_STATUS status;\r
 \r
-static HRESULT WINAPI\r
-write_pipe(HANDLE hf, LPVOID ptr, DWORD size) {\r
-    DWORD res;\r
-    if (!WriteFile(hf,ptr,size,&res,NULL)) {\r
-       FIXME("Failed to write to %p, le is %ld\n",hf,GetLastError());\r
-       return E_FAIL;\r
-    }\r
-    if (res!=size) {\r
-       FIXME("Wrote only %ld of %ld bytes to %p.\n",res,size,hf);\r
-       return E_FAIL;\r
-    }\r
-    return S_OK;\r
+    TRACE("(%p)->(%p,%p)\n", This, olemsg, riid);\r
+\r
+    status = I_RpcGetBuffer(msg);\r
+\r
+    TRACE("-- %ld\n", status);\r
+\r
+    return HRESULT_FROM_WIN32(status);\r
 }\r
 \r
-static HANDLE dupe_handle(HANDLE h)\r
+static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid)\r
 {\r
-    HANDLE h2;\r
-    \r
-    if (!DuplicateHandle(GetCurrentProcess(), h, GetCurrentProcess(),\r
-                         &h2, 0, FALSE, DUPLICATE_SAME_ACCESS))\r
-    {\r
-        ERR("could not duplicate handle: %ld\n", GetLastError());\r
-        return INVALID_HANDLE_VALUE;\r
-    }\r
+    ClientRpcChannelBuffer *This = (ClientRpcChannelBuffer *)iface;\r
+    RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;\r
+    RPC_CLIENT_INTERFACE *cif;\r
+    RPC_STATUS status;\r
+\r
+    TRACE("(%p)->(%p,%p)\n", This, olemsg, riid);\r
+\r
+    cif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_CLIENT_INTERFACE));\r
+    if (!cif)\r
+        return E_OUTOFMEMORY;\r
+\r
+    cif->Length = sizeof(RPC_CLIENT_INTERFACE);\r
+    /* RPC interface ID = COM interface ID */\r
+    cif->InterfaceId.SyntaxGUID = *riid;\r
+    /* COM objects always have a version of 0.0 */\r
+    cif->InterfaceId.SyntaxVersion.MajorVersion = 0;\r
+    cif->InterfaceId.SyntaxVersion.MinorVersion = 0;\r
+    msg->RpcInterfaceInformation = cif;\r
+    msg->Handle = This->bind;\r
     \r
-    return h2;\r
+    status = I_RpcGetBuffer(msg);\r
+\r
+    TRACE("-- %ld\n", status);\r
+\r
+    return HRESULT_FROM_WIN32(status);\r
 }\r
 \r
+struct rpc_sendreceive_params\r
+{\r
+    RPC_MESSAGE *msg;\r
+    RPC_STATUS   status;\r
+};\r
 \r
+/* this thread runs an outgoing RPC */\r
+static DWORD WINAPI rpc_sendreceive_thread(LPVOID param)\r
+{\r
+    struct rpc_sendreceive_params *data = (struct rpc_sendreceive_params *) param;\r
+    \r
+    TRACE("starting up\n");\r
 \r
+    /* FIXME: trap and rethrow RPC exceptions in app thread */\r
+    data->status = I_RpcSendReceive(data->msg);\r
 \r
-static DWORD WINAPI client_dispatch_thread(LPVOID);\r
+    TRACE("completed with status 0x%lx\n", data->status);\r
+    \r
+    return 0;\r
+}\r
 \r
-/* FIXME: this all needs to be made thread safe */\r
-static HRESULT RPC_GetRequest(struct rpc **req)\r
+static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus)\r
 {\r
-    static int reqid = 0;\r
-    int i;\r
+    RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;\r
+    HRESULT hr = S_OK;\r
+    HANDLE thread;\r
+    struct rpc_sendreceive_params *params;\r
+    DWORD tid, res;\r
+    RPC_STATUS status;\r
+    \r
+    TRACE("(%p)\n", msg);\r
+\r
+    params = HeapAlloc(GetProcessHeap(), 0, sizeof(*params));\r
+    if (!params) return E_OUTOFMEMORY;\r
+    \r
+    params->msg = msg;\r
+\r
+    /* we use a separate thread here because we need to be able to\r
+     * pump the message loop in the application thread: if we do not,\r
+     * any windows created by this thread will hang and RPCs that try\r
+     * and re-enter this STA from an incoming server thread will\r
+     * deadlock. InstallShield is an example of that.\r
+     */\r
+    \r
+    thread = CreateThread(NULL, 0, rpc_sendreceive_thread, params, 0, &tid);\r
+    if (!thread)\r
+    {\r
+        ERR("Could not create RpcSendReceive thread, error %lx\n", GetLastError());\r
+        return E_UNEXPECTED;\r
+    }\r
 \r
-    /* try to reuse */\r
-    for (i = 0; i < nrofreqs; i++)\r
+    while (TRUE)\r
     {\r
-        if (reqs[i]->state == REQSTATE_DONE)\r
+        TRACE("waiting for rpc completion or window message\n");\r
+        res = MsgWaitForMultipleObjectsEx(1, &thread, INFINITE, QS_ALLINPUT, 0);\r
+        \r
+        if (res == WAIT_OBJECT_0 + 1)  /* messages available */\r
         {\r
-            TRACE("reusing reqs[%d]\n", i);\r
-            \r
-            reqs[i]->reqh.reqid  = reqid++;\r
-            reqs[i]->resph.reqid = reqs[i]->reqh.reqid;\r
-            reqs[i]->hPipe = INVALID_HANDLE_VALUE;\r
-            reqs[i]->state = REQSTATE_START;\r
-            *req = reqs[i];\r
-            return S_OK;\r
+            MSG message;\r
+            while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))\r
+            {\r
+                /* FIXME: filter the messages here */\r
+                if (message.message == DM_EXECUTERPC)\r
+                    TRACE("received DM_EXECUTRPC dispatch request, re-entering ...\n");\r
+                else\r
+                    TRACE("received message whilst waiting for RPC: 0x%x\n", message.message);\r
+                TranslateMessage(&message);\r
+                DispatchMessageW(&message);\r
+            }\r
+        }\r
+        else if (res == WAIT_OBJECT_0) \r
+        {\r
+            break; /* RPC is completed */\r
+        }\r
+        else\r
+        {\r
+            ERR("Unexpected wait termination: %ld, %ld\n", res, GetLastError());\r
+            hr = E_UNEXPECTED;\r
+            break;\r
         }\r
     }\r
+\r
+    CloseHandle(thread);\r
+\r
+    status = params->status;\r
+    HeapFree(GetProcessHeap(), 0, params);\r
+    params = NULL;\r
+    if (hr) return hr;\r
     \r
-    TRACE("creating new struct rpc (request)\n");\r
-    \r
-    if (reqs)\r
-       reqs = (struct rpc**)HeapReAlloc(\r
-                       GetProcessHeap(),\r
-                       HEAP_ZERO_MEMORY,\r
-                       reqs,\r
-                       sizeof(struct rpc*)*(nrofreqs+1)\r
-               );\r
+    if (pstatus) *pstatus = status;\r
+\r
+    TRACE("RPC call status: 0x%lx\n", status);\r
+    if (status == RPC_S_OK)\r
+        hr = S_OK;\r
+    else if (status == RPC_S_CALL_FAILED)\r
+        hr = *(HRESULT *)msg->Buffer;\r
     else\r
-       reqs = (struct rpc**)HeapAlloc(\r
-                       GetProcessHeap(),\r
-                       HEAP_ZERO_MEMORY,\r
-                       sizeof(struct rpc*)\r
-               );\r
-    \r
-    if (!reqs) return E_OUTOFMEMORY;\r
-    \r
-    reqs[nrofreqs] = (struct rpc*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(struct rpc));\r
-    reqs[nrofreqs]->reqh.reqid = reqid++;\r
-    reqs[nrofreqs]->resph.reqid = reqs[nrofreqs]->reqh.reqid;\r
-    reqs[nrofreqs]->hPipe = INVALID_HANDLE_VALUE;\r
-    reqs[nrofreqs]->state = REQSTATE_START;\r
-    *req = reqs[nrofreqs];\r
-    \r
-    nrofreqs++;\r
-    \r
-    return S_OK;\r
-}\r
+        hr = HRESULT_FROM_WIN32(status);\r
 \r
-static HRESULT WINAPI\r
-PipeBuf_QueryInterface(\r
-    LPRPCCHANNELBUFFER iface,REFIID riid,LPVOID *ppv\r
-) {\r
-    *ppv = NULL;\r
-    if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) {\r
-       *ppv = (LPVOID)iface;\r
-       IUnknown_AddRef(iface);\r
-       return S_OK;\r
-    }\r
-    return E_NOINTERFACE;\r
+    TRACE("-- 0x%08lx\n", hr);\r
+\r
+    return hr;\r
 }\r
 \r
-static ULONG WINAPI\r
-PipeBuf_AddRef(LPRPCCHANNELBUFFER iface) {\r
-    PipeBuf *This = (PipeBuf *)iface;\r
-    return InterlockedIncrement(&This->ref);\r
+static HRESULT WINAPI ServerRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg)\r
+{\r
+    RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;\r
+    RPC_STATUS status;\r
+\r
+    TRACE("(%p)\n", msg);\r
+\r
+    status = I_RpcFreeBuffer(msg);\r
+\r
+    TRACE("-- %ld\n", status);\r
+\r
+    return HRESULT_FROM_WIN32(status);\r
 }\r
 \r
-static ULONG WINAPI\r
-PipeBuf_Release(LPRPCCHANNELBUFFER iface) {\r
-    PipeBuf *This = (PipeBuf *)iface;\r
-    ULONG ref;\r
+static HRESULT WINAPI ClientRpcChannelBuffer_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg)\r
+{\r
+    RPC_MESSAGE *msg = (RPC_MESSAGE *)olemsg;\r
+    RPC_STATUS status;\r
 \r
-    ref = InterlockedDecrement(&This->ref);\r
-    if (ref)\r
-       return ref;\r
+    TRACE("(%p)\n", msg);\r
 \r
-    CloseHandle(This->pipe);\r
-    HeapFree(GetProcessHeap(),0,This);\r
-    return 0;\r
+    status = I_RpcFreeBuffer(msg);\r
+\r
+    HeapFree(GetProcessHeap(), 0, msg->RpcInterfaceInformation);\r
+    msg->RpcInterfaceInformation = NULL;\r
+\r
+    TRACE("-- %ld\n", status);\r
+\r
+    return HRESULT_FROM_WIN32(status);\r
 }\r
 \r
-static HRESULT WINAPI\r
-PipeBuf_GetBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg,REFIID riid)\r
+static HRESULT WINAPI RpcChannelBuffer_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext)\r
 {\r
-    TRACE("(%p,%s)\n",msg,debugstr_guid(riid));\r
-    /* probably reuses IID in real. */\r
-    if (msg->cbBuffer && (msg->Buffer == NULL))\r
-       msg->Buffer = HeapAlloc(GetProcessHeap(),0,msg->cbBuffer);\r
-    return S_OK;\r
+    FIXME("(%p,%p), stub!\n", pdwDestContext, ppvDestContext);\r
+    return E_FAIL;\r
 }\r
 \r
-static HRESULT\r
-COM_InvokeAndRpcSend(struct rpc *req) {\r
-    IRpcStubBuffer     *stub;\r
-    RPCOLEMESSAGE      msg;\r
-    HRESULT            hres;\r
-    DWORD              reqtype;\r
-\r
-    if (!(stub = ipid_to_stubbuffer(&(req->reqh.ipid))))\r
-        /* ipid_to_stubbuffer will already have logged the error */\r
-        return RPC_E_DISCONNECTED;\r
-\r
-    IUnknown_AddRef(stub);\r
-    msg.Buffer         = req->Buffer;\r
-    msg.iMethod                = req->reqh.iMethod;\r
-    msg.cbBuffer       = req->reqh.cbBuffer;\r
-    msg.dataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;\r
-    req->state         = REQSTATE_INVOKING;\r
-    req->resph.retval  = IRpcStubBuffer_Invoke(stub,&msg,NULL);\r
-    IUnknown_Release(stub);\r
-    req->Buffer                = msg.Buffer;\r
-    req->resph.cbBuffer        = msg.cbBuffer;\r
-    reqtype            = REQTYPE_RESPONSE;\r
-    hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype));\r
-    if (hres) return hres;\r
-    hres = write_pipe(req->hPipe,&(req->resph),sizeof(req->resph));\r
-    if (hres) return hres;\r
-    hres = write_pipe(req->hPipe,req->Buffer,req->resph.cbBuffer);\r
-    if (hres) return hres;\r
-    req->state = REQSTATE_DONE;\r
+static HRESULT WINAPI RpcChannelBuffer_IsConnected(LPRPCCHANNELBUFFER iface)\r
+{\r
+    TRACE("()\n");\r
+    /* native does nothing too */\r
     return S_OK;\r
 }\r
 \r
-static HRESULT process_incoming_rpc(HANDLE pipe);\r
-\r
-static HRESULT RPC_QueueRequestAndWait(struct rpc *req, HANDLE pipe)\r
+static const IRpcChannelBufferVtbl ClientRpcChannelBufferVtbl =\r
 {\r
-    int                 i;\r
-    struct rpc         *xreq;\r
-    HRESULT             hres;\r
-    DWORD               reqtype;\r
-\r
-    req->hPipe = pipe;\r
-    req->state = REQSTATE_REQ_WAITING_FOR_REPLY;\r
-    reqtype = REQTYPE_REQUEST;\r
-    hres = write_pipe(req->hPipe,&reqtype,sizeof(reqtype));\r
-    if (hres) return hres;\r
-    hres = write_pipe(req->hPipe,&(req->reqh),sizeof(req->reqh));\r
-    if (hres) return hres;\r
-    hres = write_pipe(req->hPipe,req->Buffer,req->reqh.cbBuffer);\r
-    if (hres) return hres;\r
+    RpcChannelBuffer_QueryInterface,\r
+    RpcChannelBuffer_AddRef,\r
+    ClientRpcChannelBuffer_Release,\r
+    ClientRpcChannelBuffer_GetBuffer,\r
+    RpcChannelBuffer_SendReceive,\r
+    ClientRpcChannelBuffer_FreeBuffer,\r
+    RpcChannelBuffer_GetDestCtx,\r
+    RpcChannelBuffer_IsConnected\r
+};\r
 \r
-    /* This loop is about allowing re-entrancy. While waiting for the\r
-     * response to one RPC we may receive a request starting another. */\r
-    while (!hres) {\r
-       hres = process_incoming_rpc(pipe);\r
-       if (hres) break;\r
-\r
-       for (i=0;i<nrofreqs;i++) {\r
-           xreq = reqs[i];\r
-           if ((xreq->state==REQSTATE_REQ_GOT) && (xreq->hPipe==req->hPipe)) {\r
-               hres = COM_InvokeAndRpcSend(xreq);\r
-               if (hres) break;\r
-           }\r
-       }\r
-       if (req->state == REQSTATE_RESP_GOT)\r
-           return S_OK;\r
-    }\r
-    if (FAILED(hres))\r
-        WARN("-- 0x%08lx\n", hres);\r
-    return hres;\r
-}\r
+static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =\r
+{\r
+    RpcChannelBuffer_QueryInterface,\r
+    RpcChannelBuffer_AddRef,\r
+    ServerRpcChannelBuffer_Release,\r
+    ServerRpcChannelBuffer_GetBuffer,\r
+    RpcChannelBuffer_SendReceive,\r
+    ServerRpcChannelBuffer_FreeBuffer,\r
+    RpcChannelBuffer_GetDestCtx,\r
+    RpcChannelBuffer_IsConnected\r
+};\r
 \r
-static HRESULT WINAPI\r
-PipeBuf_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *msg, ULONG *status)\r
+/* returns a channel buffer for proxies */\r
+HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **chan)\r
 {\r
-    PipeBuf     *This = (PipeBuf *)iface;\r
-    struct rpc *req;\r
-    HRESULT      hres;\r
+    ClientRpcChannelBuffer *This;\r
+    WCHAR                   endpoint[200];\r
+    RPC_BINDING_HANDLE      bind;\r
+    RPC_STATUS              status;\r
+    LPWSTR                  string_binding;\r
+\r
+    /* connect to the apartment listener thread */\r
+    get_rpc_endpoint(endpoint, oxid);\r
+\r
+    TRACE("proxy pipe: connecting to endpoint: %s\n", debugstr_w(endpoint));\r
+\r
+    status = RpcStringBindingComposeW(\r
+        NULL,\r
+        wszPipeTransport,\r
+        NULL,\r
+        endpoint,\r
+        NULL,\r
+        &string_binding);\r
+        \r
+    if (status == RPC_S_OK)\r
+    {\r
+        status = RpcBindingFromStringBindingW(string_binding, &bind);\r
 \r
-    if (This->mid.oxid == COM_CurrentApt()->oxid) {\r
-       ERR("Need to call directly!\n");\r
-       return E_FAIL;\r
+        if (status == RPC_S_OK)\r
+        {\r
+            IPID ipid2 = *ipid; /* why can't RpcBindingSetObject take a const? */\r
+            status = RpcBindingSetObject(bind, &ipid2);\r
+            if (status != RPC_S_OK)\r
+                RpcBindingFree(&bind);\r
+        }\r
+\r
+        RpcStringFreeW(&string_binding);\r
     }\r
 \r
-    hres = RPC_GetRequest(&req);\r
-    if (hres) return hres;\r
-    req->reqh.iMethod  = msg->iMethod;\r
-    req->reqh.cbBuffer = msg->cbBuffer;\r
-    req->reqh.ipid = This->mid.ipid;\r
-    req->Buffer = msg->Buffer;\r
-    TRACE(" ->    rpc   ->\n");\r
-    hres = RPC_QueueRequestAndWait(req, This->pipe);\r
-    TRACE(" <- response <-\n");\r
-    if (hres)\r
+    if (status != RPC_S_OK)\r
     {\r
-        req->state = REQSTATE_DONE;\r
-       return hres;\r
+        ERR("Couldn't get binding for endpoint %s, status = %ld\n", debugstr_w(endpoint), status);\r
+        return HRESULT_FROM_WIN32(status);\r
     }\r
-    \r
-    msg->cbBuffer = req->resph.cbBuffer;\r
-    msg->Buffer          = req->Buffer;\r
-    *status       = req->resph.retval;\r
-    req->state    = REQSTATE_DONE;\r
-    \r
+\r
+    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));\r
+    if (!This)\r
+    {\r
+        RpcBindingFree(&bind);\r
+        return E_OUTOFMEMORY;\r
+    }\r
+\r
+    This->super.lpVtbl = &ClientRpcChannelBufferVtbl;\r
+    This->super.refs = 1;\r
+    This->bind = bind;\r
+\r
+    *chan = (IRpcChannelBuffer*)This;\r
+\r
     return S_OK;\r
 }\r
 \r
-\r
-static HRESULT WINAPI\r
-PipeBuf_FreeBuffer(LPRPCCHANNELBUFFER iface,RPCOLEMESSAGE* msg)\r
+HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan)\r
 {\r
-    TRACE("(%p)\n",msg);\r
-    HeapFree(GetProcessHeap(), 0, msg->Buffer);\r
+    RpcChannelBuffer *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));\r
+    if (!This)\r
+        return E_OUTOFMEMORY;\r
+\r
+    This->lpVtbl = &ServerRpcChannelBufferVtbl;\r
+    This->refs = 1;\r
+    \r
+    *chan = (IRpcChannelBuffer*)This;\r
+\r
     return S_OK;\r
 }\r
 \r
-static HRESULT WINAPI\r
-PipeBuf_GetDestCtx(LPRPCCHANNELBUFFER iface,DWORD* pdwDestContext,void** ppvDestContext)\r
+\r
+HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub)\r
 {\r
-    FIXME("(%p,%p), stub!\n",pdwDestContext,ppvDestContext);\r
-    return E_FAIL;\r
+    /* FIXME: pass server channel buffer, but don't create it every time */\r
+    return IRpcStubBuffer_Invoke(stub, msg, NULL);\r
 }\r
 \r
-static HRESULT WINAPI\r
-PipeBuf_IsConnected(LPRPCCHANNELBUFFER iface)\r
+static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)\r
 {\r
-    FIXME("(), stub!\n");\r
-    return S_OK;\r
-}\r
+    IRpcStubBuffer     *stub;\r
+    APARTMENT          *apt;\r
+    IPID                ipid;\r
 \r
-static IRpcChannelBufferVtbl pipebufvt = {\r
-    PipeBuf_QueryInterface,\r
-    PipeBuf_AddRef,\r
-    PipeBuf_Release,\r
-    PipeBuf_GetBuffer,\r
-    PipeBuf_SendReceive,\r
-    PipeBuf_FreeBuffer,\r
-    PipeBuf_GetDestCtx,\r
-    PipeBuf_IsConnected\r
-};\r
+    RpcBindingInqObject(msg->Handle, &ipid);\r
 \r
-/* returns a pipebuf for proxies */\r
-HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf)\r
-{\r
-    wine_marshal_id  ourid;\r
-    HANDLE           handle;\r
-    PipeBuf         *pbuf;\r
-    char             pipefn[200];\r
+    stub = ipid_to_apt_and_stubbuffer(&ipid, &apt);\r
+    if (!apt || !stub)\r
+    {\r
+        if (apt) COM_ApartmentRelease(apt);\r
+        /* ipid_to_apt_and_stubbuffer will already have logged the error */\r
+        return RpcRaiseException(RPC_E_DISCONNECTED);\r
+    }\r
 \r
-    /* connect to the apartment listener thread */\r
-    sprintf(pipefn,OLESTUBMGR"_%08lx%08lx",(DWORD)(mid->oxid >> 32),(DWORD)mid->oxid);\r
+    /* Note: this is the important difference between STAs and MTAs - we\r
+     * always execute RPCs to STAs in the thread that originally created the\r
+     * apartment (i.e. the one that pumps messages to the window) */\r
+    if (apt->model & COINIT_APARTMENTTHREADED)\r
+        SendMessageW(apt->win, DM_EXECUTERPC, (WPARAM)msg, (LPARAM)stub);\r
+    else\r
+        RPC_ExecuteCall((RPCOLEMESSAGE *)msg, stub);\r
 \r
-    TRACE("proxy pipe: connecting to apartment listener thread: %s\n", pipefn);\r
+    COM_ApartmentRelease(apt);\r
+    IRpcStubBuffer_Release(stub);\r
+}\r
 \r
-    while (TRUE)\r
+/* stub registration */\r
+HRESULT RPC_RegisterInterface(REFIID riid)\r
+{\r
+    struct registered_if *rif;\r
+    BOOL found = FALSE;\r
+    HRESULT hr = S_OK;\r
+    \r
+    TRACE("(%s)\n", debugstr_guid(riid));\r
+\r
+    EnterCriticalSection(&csRegIf);\r
+    LIST_FOR_EACH_ENTRY(rif, &registered_interfaces, struct registered_if, entry)\r
     {\r
-        BOOL ret = WaitNamedPipeA(pipefn, NMPWAIT_USE_DEFAULT_WAIT);\r
-        if (!ret)\r
+        if (IsEqualGUID(&rif->If.InterfaceId.SyntaxGUID, riid))\r
         {\r
-            ERR("Could not open named pipe %s, error %ld\n", pipefn, GetLastError());\r
-            return RPC_E_SERVER_DIED;\r
+            rif->refs++;\r
+            found = TRUE;\r
+            break;\r
         }\r
+    }\r
+    if (!found)\r
+    {\r
+        TRACE("Creating new interface\n");\r
 \r
-        handle = CreateFileA(pipefn, GENERIC_READ | GENERIC_WRITE,\r
-                             0, NULL, OPEN_EXISTING, 0, 0);\r
-\r
-        if (handle == INVALID_HANDLE_VALUE)\r
+        rif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rif));\r
+        if (rif)\r
         {\r
-            if (GetLastError() == ERROR_PIPE_BUSY) continue;\r
-            \r
-            ERR("Could not open named pipe %s, error %ld\n", pipefn, GetLastError());\r
-            return RPC_E_SERVER_DIED;\r
+            RPC_STATUS status;\r
+\r
+            rif->refs = 1;\r
+            rif->If.Length = sizeof(RPC_SERVER_INTERFACE);\r
+            /* RPC interface ID = COM interface ID */\r
+            rif->If.InterfaceId.SyntaxGUID = *riid;\r
+            rif->If.DispatchTable = &rpc_dispatch;\r
+            /* all other fields are 0, including the version asCOM objects\r
+             * always have a version of 0.0 */\r
+            status = RpcServerRegisterIfEx(\r
+                (RPC_IF_HANDLE)&rif->If,\r
+                NULL, NULL,\r
+                RPC_IF_OLE | RPC_IF_AUTOLISTEN,\r
+                RPC_C_LISTEN_MAX_CALLS_DEFAULT,\r
+                NULL);\r
+            if (status == RPC_S_OK)\r
+                list_add_tail(&registered_interfaces, &rif->entry);\r
+            else\r
+            {\r
+                ERR("RpcServerRegisterIfEx failed with error %ld\n", status);\r
+                HeapFree(GetProcessHeap(), 0, rif);\r
+                hr = HRESULT_FROM_WIN32(status);\r
+            }\r
         }\r
+        else\r
+            hr = E_OUTOFMEMORY;\r
+    }\r
+    LeaveCriticalSection(&csRegIf);\r
+    return hr;\r
+}\r
 \r
-        break;\r
+/* stub unregistration */\r
+void RPC_UnregisterInterface(REFIID riid)\r
+{\r
+    struct registered_if *rif;\r
+    EnterCriticalSection(&csRegIf);\r
+    LIST_FOR_EACH_ENTRY(rif, &registered_interfaces, struct registered_if, entry)\r
+    {\r
+        if (IsEqualGUID(&rif->If.InterfaceId.SyntaxGUID, riid))\r
+        {\r
+            if (!--rif->refs)\r
+            {\r
+#if 0 /* this is a stub in builtin and spams the console with FIXME's */\r
+                IID iid = *riid; /* RpcServerUnregisterIf doesn't take const IID */\r
+                RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, &iid, 0);\r
+                list_remove(&rif->entry);\r
+                HeapFree(GetProcessHeap(), 0, rif);\r
+#endif\r
+            }\r
+            break;\r
+        }\r
     }\r
+    LeaveCriticalSection(&csRegIf);\r
+}\r
+\r
+/* make the apartment reachable by other threads and processes and create the\r
+ * IRemUnknown object */\r
+void RPC_StartRemoting(struct apartment *apt)\r
+{\r
+    if (!InterlockedExchange(&apt->remoting_started, TRUE))\r
+    {\r
+        WCHAR endpoint[200];\r
+        RPC_STATUS status;\r
+\r
+        get_rpc_endpoint(endpoint, &apt->oxid);\r
     \r
-    memset(&ourid,0,sizeof(ourid));\r
-    ourid.oxid = COM_CurrentApt()->oxid;\r
-    \r
-    TRACE("constructing new pipebuf for proxy\n");\r
-    \r
-    pbuf = (PipeBuf*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PipeBuf));\r
-    pbuf->lpVtbl = &pipebufvt;\r
-    pbuf->ref   = 1;\r
-    memcpy(&(pbuf->mid),mid,sizeof(*mid));\r
-    pbuf->pipe  = dupe_handle(handle);\r
-    \r
-    *pipebuf = (IRpcChannelBuffer*)pbuf;\r
-    \r
-    return S_OK;\r
+        status = RpcServerUseProtseqEpW(\r
+            wszPipeTransport,\r
+            RPC_C_PROTSEQ_MAX_REQS_DEFAULT,\r
+            endpoint,\r
+            NULL);\r
+        if (status != RPC_S_OK)\r
+            ERR("Couldn't register endpoint %s\n", debugstr_w(endpoint));\r
+\r
+        /* FIXME: move remote unknown exporting into this function */\r
+    }\r
+    start_apartment_remote_unknown();\r
 }\r
 \r
-static HRESULT\r
-create_server(REFCLSID rclsid)\r
+\r
+static HRESULT create_server(REFCLSID rclsid)\r
 {\r
     static const WCHAR  embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };\r
     HKEY                key;\r
@@ -512,8 +618,10 @@ create_server(REFCLSID rclsid)
 \r
     if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {\r
         WARN("failed to run local server %s\n", debugstr_w(exe));\r
-        return E_FAIL;\r
+        return HRESULT_FROM_WIN32(GetLastError());\r
     }\r
+    CloseHandle(pinfo.hProcess);\r
+    CloseHandle(pinfo.hThread);\r
 \r
     return S_OK;\r
 }\r
@@ -521,8 +629,7 @@ create_server(REFCLSID rclsid)
 /*\r
  * start_local_service()  - start a service given its name and parameters\r
  */\r
-static DWORD\r
-start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)\r
+static DWORD start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)\r
 {\r
     SC_HANDLE handle, hsvc;\r
     DWORD     r = ERROR_FUNCTION_FAILED;\r
@@ -559,8 +666,7 @@ start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
  *\r
  * Note:  Local Services are not supported under Windows 9x\r
  */\r
-static HRESULT\r
-create_local_service(REFCLSID rclsid)\r
+static HRESULT create_local_service(REFCLSID rclsid)\r
 {\r
     HRESULT hres = REGDB_E_READREGDB;\r
     WCHAR buf[40], keyname[50];\r
@@ -625,8 +731,10 @@ create_local_service(REFCLSID rclsid)
     return hres;\r
 }\r
 \r
-/* http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, Figure 4 */\r
-HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)\r
+#define PIPEPREF "\\\\.\\pipe\\"\r
+\r
+/* FIXME: should call to rpcss instead */\r
+HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)\r
 {\r
     HRESULT        hres;\r
     HANDLE         hPipe;\r
@@ -637,8 +745,8 @@ HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
     LARGE_INTEGER  seekto;\r
     ULARGE_INTEGER newpos;\r
     int            tries = 0;\r
-    \r
-    static const int MAXTRIES = 10000;\r
+\r
+    static const int MAXTRIES = 30; /* 30 seconds */\r
 \r
     TRACE("rclsid=%s, iid=%s\n", debugstr_guid(rclsid), debugstr_guid(iid));\r
 \r
@@ -691,302 +799,13 @@ out:
 }\r
 \r
 \r
-/* this reads an RPC from the given pipe and places it in the global reqs array  */\r
-static HRESULT process_incoming_rpc(HANDLE pipe)\r
-{\r
-    DWORD       reqtype;\r
-    HRESULT     hres = S_OK;\r
-\r
-    hres = read_pipe(pipe,&reqtype,sizeof(reqtype));\r
-    if (hres) return hres;\r
-\r
-    /* only received by servers */\r
-    if (reqtype == REQTYPE_REQUEST)\r
-    {\r
-       struct rpc *xreq;\r
-\r
-       RPC_GetRequest(&xreq);\r
-        \r
-       xreq->hPipe = pipe;\r
-       hres = read_pipe(pipe,&(xreq->reqh),sizeof(xreq->reqh));\r
-       if (hres)\r
-        {\r
-            xreq->state = REQSTATE_DONE;\r
-            return hres;\r
-        }\r
-        \r
-       xreq->resph.reqid = xreq->reqh.reqid;\r
-       xreq->Buffer = HeapAlloc(GetProcessHeap(),0, xreq->reqh.cbBuffer);\r
-       hres = read_pipe(pipe,xreq->Buffer,xreq->reqh.cbBuffer);\r
-       if (hres) goto end;\r
-\r
-        TRACE("received RPC for IPID %s\n", debugstr_guid(&xreq->reqh.ipid));\r
-        \r
-       xreq->state = REQSTATE_REQ_GOT;\r
-       goto end;\r
-    }\r
-    else if (reqtype == REQTYPE_RESPONSE)\r
-    {\r
-       struct response_header  resph;\r
-       int i;\r
-\r
-       hres = read_pipe(pipe,&resph,sizeof(resph));\r
-       if (hres) goto end;\r
-\r
-        TRACE("read RPC response\n");\r
-        \r
-       for (i = nrofreqs; i--;)\r
-        {\r
-           struct rpc *xreq = reqs[i];\r
-            \r
-           if (xreq->state != REQSTATE_REQ_WAITING_FOR_REPLY)\r
-               continue;\r
-            \r
-           if (xreq->reqh.reqid == resph.reqid)\r
-            {\r
-               memcpy(&(xreq->resph),&resph,sizeof(resph));\r
-\r
-               if (xreq->Buffer)\r
-                   xreq->Buffer = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->Buffer,xreq->resph.cbBuffer);\r
-               else\r
-                   xreq->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,xreq->resph.cbBuffer);\r
-\r
-               hres = read_pipe(pipe,xreq->Buffer,xreq->resph.cbBuffer);\r
-               if (hres) goto end;\r
-\r
-                TRACE("received response for reqid 0x%lx\n", xreq->reqh.reqid);\r
-                \r
-               xreq->state = REQSTATE_RESP_GOT;\r
-               goto end;\r
-           }\r
-       }\r
-        \r
-       ERR("protocol error: did not find request for id %lx\n",resph.reqid);\r
-       hres = E_FAIL;\r
-       goto end;\r
-    }\r
-    \r
-    ERR("protocol error: unknown reqtype %ld\n",reqtype);\r
-    hres = E_FAIL;\r
-end:\r
-    return hres;\r
-}\r
-\r
-struct stub_dispatch_params\r
-{\r
-    struct apartment *apt;\r
-    HANDLE            pipe;\r
-};\r
-\r
-/* This thread listens on the given pipe for requests to any stub manager */\r
-static DWORD WINAPI client_dispatch_thread(LPVOID param)\r
-{\r
-    HANDLE              pipe = ((struct stub_dispatch_params *)param)->pipe;\r
-    struct apartment   *apt  = ((struct stub_dispatch_params *)param)->apt;\r
-    HRESULT             hres = S_OK;\r
-    HANDLE              shutdown_event = dupe_handle(apt->shutdown_event);\r
-    \r
-    HeapFree(GetProcessHeap(), 0, param);\r
-    \r
-    /* join marshalling apartment. fixme: this stuff is all very wrong, threading needs to work like native */\r
-    COM_CurrentInfo()->apt = apt;\r
-\r
-    while (TRUE)\r
-    {\r
-        int i;\r
-\r
-        TRACE("waiting for RPC on OXID: %08lx%08lx\n", (DWORD)(apt->oxid >> 32), (DWORD)(apt->oxid));\r
-        \r
-        /* read a new request into the global array, block if no requests have been sent */\r
-        hres = process_incoming_rpc(pipe);\r
-        if (hres) break;\r
-\r
-        /* do you expect me to talk? */\r
-        if (WaitForSingleObject(shutdown_event, 0) == WAIT_OBJECT_0)\r
-        {\r
-            /* no mr bond, i expect you to die! bwahaha */\r
-            CloseHandle(shutdown_event);\r
-            break;\r
-        }\r
-        \r
-        TRACE("received RPC on OXID: %08lx%08lx\n", (DWORD)(apt->oxid >> 32), (DWORD)(apt->oxid));        \r
-\r
-        /* now scan the array looking for the RPC just loaded */\r
-        for (i=nrofreqs;i--;)\r
-        {\r
-            struct rpc *req = reqs[i];\r
-            \r
-            if ((req->state == REQSTATE_REQ_GOT) && (req->hPipe == pipe))\r
-            {\r
-                hres = COM_InvokeAndRpcSend(req);\r
-                if (!hres) break;\r
-            }\r
-        }\r
-    }\r
-\r
-    TRACE("exiting with hres %lx\n",hres);\r
-\r
-    /* leave marshalling apartment. fixme: this stuff is all very wrong, threading needs to work like native */\r
-    COM_CurrentInfo()->apt = NULL;\r
-\r
-    DisconnectNamedPipe(pipe);\r
-    CloseHandle(pipe);\r
-    return 0;\r
-}\r
-\r
-struct apartment_listener_params\r
-{\r
-    APARTMENT *apt;\r
-    HANDLE event;\r
-};\r
-\r
-/* This thread listens on a named pipe for each apartment that exports\r
- * objects. It deals with incoming connection requests. Each time a\r
- * client connects a separate thread is spawned for that particular\r
- * connection.\r
- *\r
- * This architecture is different in native DCOM.\r
- */\r
-static DWORD WINAPI apartment_listener_thread(LPVOID p)\r
-{\r
-    char pipefn[200];\r
-    HANDLE listenPipe, thread_handle;\r
-    OVERLAPPED overlapped;\r
-    HANDLE wait[2];\r
-    \r
-    struct apartment_listener_params * params = (struct apartment_listener_params *)p;\r
-    struct apartment *apt = params->apt;\r
-    HANDLE event = params->event;\r
-    HANDLE apt_shutdown_event = dupe_handle(apt->shutdown_event);\r
-    OXID   this_oxid = apt->oxid; /* copy here so we can print it when we shut down */\r
-\r
-    HeapFree(GetProcessHeap(), 0, params);\r
-\r
-    overlapped.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL);\r
-    \r
-    /* we must join the marshalling threads apartment. we already have a ref here */\r
-    COM_CurrentInfo()->apt = apt;\r
-\r
-    sprintf(pipefn,OLESTUBMGR"_%08lx%08lx", (DWORD)(apt->oxid >> 32), (DWORD)(apt->oxid));\r
-    TRACE("Apartment listener thread starting on (%s)\n",pipefn);\r
-\r
-    while (TRUE)\r
-    {\r
-        struct stub_dispatch_params *params;\r
-        DWORD res;\r
-\r
-       listenPipe = CreateNamedPipeA(\r
-           pipefn,\r
-           PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,\r
-           PIPE_TYPE_BYTE|PIPE_WAIT,\r
-           PIPE_UNLIMITED_INSTANCES,\r
-           4096,\r
-           4096,\r
-           500 /* 0.5 seconds */,\r
-           NULL\r
-       );\r
-\r
-       /* tell function that started this thread that we have attempted to created the\r
-        * named pipe. */\r
-       if (event) {\r
-           SetEvent(event);\r
-           event = NULL;\r
-       }\r
-\r
-       if (listenPipe == INVALID_HANDLE_VALUE) {\r
-           FIXME("pipe creation failed for %s, error %ld\n",pipefn,GetLastError());\r
-           break; /* permanent failure, so quit stubmgr thread */\r
-       }\r
-\r
-        TRACE("waiting for a client ...\n");\r
-        \r
-       /* an already connected pipe is not an error */\r
-       if (!ConnectNamedPipe(listenPipe, &overlapped))\r
-        {\r
-            DWORD le = GetLastError();\r
-            \r
-            if ((le != ERROR_IO_PENDING) && (le != ERROR_PIPE_CONNECTED))\r
-            {\r
-                ERR("Failure during ConnectNamedPipe %ld!\n",GetLastError());\r
-                CloseHandle(listenPipe);\r
-                continue;\r
-            }\r
-       }\r
-\r
-        /* wait for action */\r
-        wait[0] = apt_shutdown_event;\r
-        wait[1] = overlapped.hEvent;\r
-        res = WaitForMultipleObjectsEx(2, wait, FALSE, INFINITE, FALSE);\r
-        if (res == WAIT_OBJECT_0) break;\r
-\r
-        ResetEvent(overlapped.hEvent);\r
-        \r
-        /* start the stub dispatch thread for this connection */\r
-        TRACE("starting stub dispatch thread for OXID %08lx%08lx\n", (DWORD)(apt->oxid >> 32), (DWORD)(apt->oxid));\r
-        params = HeapAlloc(GetProcessHeap(), 0, sizeof(struct stub_dispatch_params));\r
-        if (!params)\r
-        {\r
-            ERR("out of memory, dropping this client\n");\r
-            CloseHandle(listenPipe);\r
-            continue;\r
-        }\r
-        params->apt = apt;\r
-        params->pipe = listenPipe;\r
-        thread_handle = CreateThread(NULL, 0, &client_dispatch_thread, params, 0, NULL);\r
-        CloseHandle(thread_handle);\r
-    }\r
-\r
-    TRACE("shutting down: %s\n", wine_dbgstr_longlong(this_oxid));\r
-\r
-    /* we must leave the marshalling threads apartment. we don't have a ref here */\r
-    COM_CurrentInfo()->apt = NULL;\r
-\r
-    DisconnectNamedPipe(listenPipe);\r
-    CloseHandle(listenPipe);\r
-    CloseHandle(overlapped.hEvent);\r
-    CloseHandle(apt_shutdown_event);\r
-    return 0;\r
-}\r
-\r
-void start_apartment_listener_thread()\r
-{\r
-    APARTMENT *apt = COM_CurrentApt();\r
-    \r
-    assert( apt );\r
-    \r
-    TRACE("apt->listenertid=%ld\n", apt->listenertid);\r
-\r
-    /* apt->listenertid is a hack which needs to die at some point, as\r
-     * it leaks information into the apartment structure. in fact,\r
-     * this thread isn't quite correct anyway as native RPC doesn't\r
-     * use a thread per apartment at all, instead the dispatch thread\r
-     * either enters the apartment to perform the RPC (for MTAs, RTAs)\r
-     * or does a context switch into it for STAs.\r
-     */\r
-    \r
-    if (!apt->listenertid)\r
-    {\r
-        HANDLE thread;\r
-        HANDLE event = CreateEventW(NULL, TRUE, FALSE, NULL);\r
-        struct apartment_listener_params * params = HeapAlloc(GetProcessHeap(), 0, sizeof(*params));\r
-\r
-        params->apt = apt;\r
-        params->event = event;\r
-        thread = CreateThread(NULL, 0, apartment_listener_thread, params, 0, &apt->listenertid);\r
-        CloseHandle(thread);\r
-        /* wait for pipe to be created before returning, otherwise we\r
-         * might try to use it and fail */\r
-        WaitForSingleObject(event, INFINITE);\r
-        CloseHandle(event);\r
-    }\r
-}\r
-\r
 struct local_server_params\r
 {\r
     CLSID clsid;\r
     IStream *stream;\r
 };\r
 \r
+/* FIXME: should call to rpcss instead */\r
 static DWORD WINAPI local_server_thread(LPVOID param)\r
 {\r
     struct local_server_params * lsp = (struct local_server_params *)param;\r
index 47ed338..c67d8a9 100644 (file)
@@ -866,8 +866,11 @@ static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This)
  */\r
 static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)\r
 {\r
-    if (openFlags & (STGM_WRITE | STGM_READWRITE))\r
-       return PAGE_READWRITE;\r
-    else\r
-       return PAGE_READONLY;\r
+    switch(STGM_ACCESS_MODE(openFlags))\r
+    {\r
+    case STGM_WRITE:\r
+    case STGM_READWRITE:\r
+        return PAGE_READWRITE;\r
+    }\r
+    return PAGE_READONLY;\r
 }\r
diff --git a/reactos/lib/ole32/stg_prop.c b/reactos/lib/ole32/stg_prop.c
new file mode 100644 (file)
index 0000000..543d161
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * Compound Storage (32 bit version)
+ * Storage implementation
+ *
+ * This file contains the compound file implementation
+ * of the storage interface.
+ *
+ * Copyright 1999 Francis Beaudet
+ * Copyright 1999 Sylvain St-Germain
+ * Copyright 1999 Thuy Nguyen
+ * Copyright 2005 Mike McCormack
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winuser.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+#include "storage32.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(storage);
+
+#define _IPropertySetStorage_Offset ((int)(&(((StorageImpl*)0)->base.pssVtbl)))
+#define _ICOM_THIS_From_IPropertySetStorage(class, name) \
+    class* This = (class*)(((char*)name)-_IPropertySetStorage_Offset)
+
+static IPropertyStorageVtbl IPropertyStorage_Vtbl;
+
+/***********************************************************************
+ * Implementation of IPropertyStorage
+ */
+typedef struct tagPropertyStorage_impl
+{
+    IPropertyStorageVtbl *vtbl;
+    DWORD ref;
+    IStream *stm;
+} PropertyStorage_impl;
+
+/************************************************************************
+ * IPropertyStorage_fnQueryInterface (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnQueryInterface(
+    IPropertyStorage *iface,
+    REFIID riid,
+    void** ppvObject)
+{
+    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
+
+    if ( (This==0) || (ppvObject==0) )
+        return E_INVALIDARG;
+
+    *ppvObject = 0;
+
+    if (IsEqualGUID(&IID_IUnknown, riid) ||
+        IsEqualGUID(&IID_IPropertyStorage, riid))
+    {
+        IPropertyStorage_AddRef(iface);
+        *ppvObject = (IPropertyStorage*)iface;
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnAddRef (IPropertyStorage)
+ */
+static ULONG WINAPI IPropertyStorage_fnAddRef(
+    IPropertyStorage *iface)
+{
+    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
+    return InterlockedIncrement(&This->ref);
+}
+
+/************************************************************************
+ * IPropertyStorage_fnRelease (IPropertyStorage)
+ */
+static ULONG WINAPI IPropertyStorage_fnRelease(
+    IPropertyStorage *iface)
+{
+    PropertyStorage_impl *This = (PropertyStorage_impl *)iface;
+    ULONG ref;
+
+    ref = InterlockedDecrement(&This->ref);
+    if (ref == 0)
+    {
+        TRACE("Destroying %p\n", This);
+        IStream_Release(This->stm);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnReadMultiple (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnReadMultiple(
+    IPropertyStorage* iface,
+    ULONG cpspec,
+    const PROPSPEC rgpspec[],
+    PROPVARIANT rgpropvar[])
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnWriteMultiple (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnWriteMultiple(
+    IPropertyStorage* iface,
+    ULONG cpspec,
+    const PROPSPEC rgpspec[],
+    const PROPVARIANT rgpropvar[],
+    PROPID propidNameFirst)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnDeleteMultiple (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnDeleteMultiple(
+    IPropertyStorage* iface,
+    ULONG cpspec,
+    const PROPSPEC rgpspec[])
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnReadPropertyNames (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnReadPropertyNames(
+    IPropertyStorage* iface,
+    ULONG cpropid,
+    const PROPID rgpropid[],
+    LPOLESTR rglpwstrName[])
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnWritePropertyNames (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnWritePropertyNames(
+    IPropertyStorage* iface,
+    ULONG cpropid,
+    const PROPID rgpropid[],
+    const LPOLESTR rglpwstrName[])
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnDeletePropertyNames (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnDeletePropertyNames(
+    IPropertyStorage* iface,
+    ULONG cpropid,
+    const PROPID rgpropid[])
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnCommit (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnCommit(
+    IPropertyStorage* iface,
+    DWORD grfCommitFlags)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnRevert (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnRevert(
+    IPropertyStorage* iface)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnEnum (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnEnum(
+    IPropertyStorage* iface,
+    IEnumSTATPROPSTG** ppenum)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnSetTimes (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnSetTimes(
+    IPropertyStorage* iface,
+    const FILETIME* pctime,
+    const FILETIME* patime,
+    const FILETIME* pmtime)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnSetClass (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnSetClass(
+    IPropertyStorage* iface,
+    REFCLSID clsid)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/************************************************************************
+ * IPropertyStorage_fnStat (IPropertyStorage)
+ */
+static HRESULT WINAPI IPropertyStorage_fnStat(
+    IPropertyStorage* iface,
+    STATPROPSETSTG* statpsstg)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+/***********************************************************************
+ * PropertyStorage_Contruct
+ */
+static HRESULT PropertyStorage_Contruct(IStream *stm, IPropertyStorage** pps)
+{
+    PropertyStorage_impl *ps;
+
+    ps = HeapAlloc(GetProcessHeap(), 0, sizeof *ps);
+    if (!ps)
+        return E_OUTOFMEMORY;
+
+    ps->vtbl = &IPropertyStorage_Vtbl;
+    ps->ref = 1;
+    ps->stm = stm;
+
+    *pps = (IPropertyStorage*)ps;
+
+    TRACE("PropertyStorage %p constructed\n", ps);
+
+    return S_OK;
+}
+
+
+/***********************************************************************
+ * Implementation of IPropertySetStorage
+ */
+
+static LPCWSTR format_id_to_name(REFFMTID rfmtid)
+{
+    static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y',
+        'I','n','f','o','r','m','a','t','i','o','n',0 };
+
+    if (IsEqualGUID(&FMTID_SummaryInformation, rfmtid))
+        return szSummaryInfo;
+    ERR("Unknown format id %s\n", debugstr_guid(rfmtid));
+    return NULL;
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnQueryInterface (IUnknown)
+ *
+ *  This method forwards to the common QueryInterface implementation
+ */
+static HRESULT WINAPI IPropertySetStorage_fnQueryInterface(
+    IPropertySetStorage *ppstg,
+    REFIID riid,
+    void** ppvObject)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    return StorageBaseImpl_QueryInterface( (IStorage*)This, riid, ppvObject );
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnAddRef (IUnknown)
+ *
+ *  This method forwards to the common AddRef implementation
+ */
+static ULONG WINAPI IPropertySetStorage_fnAddRef(
+    IPropertySetStorage *ppstg)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    return StorageBaseImpl_AddRef( (IStorage*)This );
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnRelease (IUnknown)
+ *
+ *  This method forwards to the common Release implementation
+ */
+static ULONG WINAPI IPropertySetStorage_fnRelease(
+    IPropertySetStorage *ppstg)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    return StorageBaseImpl_Release( (IStorage*)This );
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnCreate (IPropertySetStorage)
+ */
+static HRESULT WINAPI IPropertySetStorage_fnCreate(
+    IPropertySetStorage *ppstg,
+    REFFMTID rfmtid,
+    const CLSID* pclsid,
+    DWORD grfFlags,
+    DWORD grfMode,
+    IPropertyStorage** ppprstg)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    LPCWSTR name = NULL;
+    IStream *stm = NULL;
+    HRESULT r;
+
+    TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
+
+    /* be picky */
+    if (grfMode != (STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE))
+        return STG_E_INVALIDFLAG;
+
+    if (!rfmtid)
+        return E_INVALIDARG;
+
+    name = format_id_to_name(rfmtid);
+    if (!name)
+        return STG_E_FILENOTFOUND;
+
+    r = IStorage_CreateStream( (IStorage*)This, name, grfMode, 0, 0, &stm );
+    if (FAILED(r))
+        return r;
+
+    return PropertyStorage_Contruct(stm, ppprstg);
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnOpen (IPropertySetStorage)
+ */
+static HRESULT WINAPI IPropertySetStorage_fnOpen(
+    IPropertySetStorage *ppstg,
+    REFFMTID rfmtid,
+    DWORD grfMode,
+    IPropertyStorage** ppprstg)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    IStream *stm = NULL;
+    LPCWSTR name = NULL;
+    HRESULT r;
+
+    TRACE("%p %s %08lx %p\n", This, debugstr_guid(rfmtid), grfMode, ppprstg);
+
+    /* be picky */
+    if (grfMode != (STGM_READWRITE|STGM_SHARE_EXCLUSIVE) &&
+        grfMode != (STGM_READ|STGM_SHARE_EXCLUSIVE))
+        return STG_E_INVALIDFLAG;
+
+    if (!rfmtid)
+        return E_INVALIDARG;
+
+    name = format_id_to_name(rfmtid);
+    if (!name)
+        return STG_E_FILENOTFOUND;
+
+    r = IStorage_OpenStream((IStorage*) This, name, 0, grfMode, 0, &stm );
+    if (FAILED(r))
+        return r;
+
+    return PropertyStorage_Contruct(stm, ppprstg);
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnDelete (IPropertySetStorage)
+ */
+static HRESULT WINAPI IPropertySetStorage_fnDelete(
+    IPropertySetStorage *ppstg,
+    REFFMTID rfmtid)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    IStorage *stg = NULL;
+    LPCWSTR name = NULL;
+
+    TRACE("%p %s\n", This, debugstr_guid(rfmtid));
+
+    if (!rfmtid)
+        return E_INVALIDARG;
+
+    name = format_id_to_name(rfmtid);
+    if (!name)
+        return STG_E_FILENOTFOUND;
+
+    stg = (IStorage*) This;
+    return IStorage_DestroyElement(stg, name);
+}
+
+/************************************************************************
+ * IPropertySetStorage_fnEnum (IPropertySetStorage)
+ */
+static HRESULT WINAPI IPropertySetStorage_fnEnum(
+    IPropertySetStorage *ppstg,
+    IEnumSTATPROPSETSTG** ppenum)
+{
+    _ICOM_THIS_From_IPropertySetStorage(StorageImpl, ppstg);
+    FIXME("%p\n", This);
+    return E_NOTIMPL;
+}
+
+
+/***********************************************************************
+ * vtables
+ */
+IPropertySetStorageVtbl IPropertySetStorage_Vtbl =
+{
+    IPropertySetStorage_fnQueryInterface,
+    IPropertySetStorage_fnAddRef,
+    IPropertySetStorage_fnRelease,
+    IPropertySetStorage_fnCreate,
+    IPropertySetStorage_fnOpen,
+    IPropertySetStorage_fnDelete,
+    IPropertySetStorage_fnEnum
+};
+
+static IPropertyStorageVtbl IPropertyStorage_Vtbl =
+{
+    IPropertyStorage_fnQueryInterface,
+    IPropertyStorage_fnAddRef,
+    IPropertyStorage_fnRelease,
+    IPropertyStorage_fnReadMultiple,
+    IPropertyStorage_fnWriteMultiple,
+    IPropertyStorage_fnDeleteMultiple,
+    IPropertyStorage_fnReadPropertyNames,
+    IPropertyStorage_fnWritePropertyNames,
+    IPropertyStorage_fnDeletePropertyNames,
+    IPropertyStorage_fnCommit,
+    IPropertyStorage_fnRevert,
+    IPropertyStorage_fnEnum,
+    IPropertyStorage_fnSetTimes,
+    IPropertyStorage_fnSetClass,
+    IPropertyStorage_fnStat,
+};
index e6569f5..476f2e6 100644 (file)
@@ -443,7 +443,12 @@ HRESULT WINAPI StgStreamImpl_Write(
   /*\r
    * Do we have permission to write to this stream?\r
    */\r
-  if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE))) {\r
+  switch(STGM_ACCESS_MODE(This->grfMode))\r
+  {\r
+  case STGM_WRITE:\r
+  case STGM_READWRITE:\r
+      break;\r
+  default:\r
       return STG_E_ACCESSDENIED;\r
   }\r
 \r
index 633657f..cbfeeca 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 1999 Francis Beaudet\r
  * Copyright 1999 Sylvain St-Germain\r
  * Copyright 1999 Thuy Nguyen\r
+ * Copyright 2005 Mike McCormack\r
  *\r
  * This library is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU Lesser General Public\r
@@ -51,8 +52,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(storage);
 \r
 #define FILE_BEGIN 0\r
 \r
-#define STGM_SHARE_MODE(stgm) ((stgm)&0xf0)\r
-\r
 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */\r
 #define OLESTREAM_ID 0x501\r
 #define OLESTREAM_MAX_STR_LEN 255\r
@@ -222,7 +221,7 @@ static IEnumSTATSTGVtbl IEnumSTATSTGImpl_Vtbl =
     IEnumSTATSTGImpl_Clone\r
 };\r
 \r
-\r
+extern IPropertySetStorageVtbl IPropertySetStorage_Vtbl;\r
 \r
 \r
 \r
@@ -266,6 +265,10 @@ HRESULT WINAPI StorageBaseImpl_QueryInterface(
   {\r
     *ppvObject = (IStorage*)This;\r
   }\r
+  else if (memcmp(&IID_IPropertySetStorage, riid, sizeof(IID_IPropertySetStorage)) == 0)\r
+  {\r
+    *ppvObject = (IStorage*)&This->pssVtbl;\r
+  }\r
 \r
   /*\r
    * Check that we obtained an interface.\r
@@ -294,7 +297,11 @@ ULONG WINAPI StorageBaseImpl_AddRef(
             IStorage* iface)\r
 {\r
   StorageBaseImpl *This = (StorageBaseImpl *)iface;\r
-  return InterlockedIncrement(&This->ref);\r
+  ULONG ref = InterlockedIncrement(&This->ref);\r
+\r
+  TRACE("(%p) AddRef to %ld\n", This, ref);\r
+\r
+  return ref;\r
 }\r
 \r
 /************************************************************************\r
@@ -314,6 +321,8 @@ ULONG WINAPI StorageBaseImpl_Release(
    */\r
   ULONG ref = InterlockedDecrement(&This->ref);\r
 \r
+  TRACE("(%p) ReleaseRef to %ld\n", This, ref);\r
+\r
   /*\r
    * If the reference count goes down to 0, perform suicide.\r
    */\r
@@ -381,7 +390,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStream(
   /*\r
    * As documented.\r
    */\r
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||\r
+  if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||\r
         (grfMode & STGM_DELETEONRELEASE) ||\r
         (grfMode & STGM_TRANSACTED) )\r
   {\r
@@ -500,7 +509,7 @@ HRESULT WINAPI StorageBaseImpl_OpenStorage(
   /*\r
    * As documented.\r
    */\r
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) ||\r
+  if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||\r
         (grfMode & STGM_DELETEONRELEASE) ||\r
         (grfMode & STGM_PRIORITY) )\r
   {\r
@@ -882,7 +891,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
   if ( FAILED( validateSTGM(grfMode) ))\r
     return STG_E_INVALIDFLAG;\r
 \r
-  if ( !(grfMode & STGM_SHARE_EXCLUSIVE) )\r
+  if (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE) \r
     return STG_E_INVALIDFLAG;\r
 \r
   /*\r
@@ -914,7 +923,7 @@ HRESULT WINAPI StorageBaseImpl_CreateStream(
     /*\r
      * An element with this name already exists\r
      */\r
-    if (grfMode & STGM_CREATE)\r
+    if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)\r
     {\r
       IStorage_DestroyElement(iface, pwcsName);\r
     }\r
@@ -1089,8 +1098,8 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   /*\r
    * Create a property enumeration and search the properties\r
    */\r
-  propertyEnumeration = IEnumSTATSTGImpl_Construct( This->ancestorStorage,\r
-                                                    This->rootPropertySetIndex);\r
+  propertyEnumeration = IEnumSTATSTGImpl_Construct( This->base.ancestorStorage,\r
+                                                    This->base.rootPropertySetIndex);\r
 \r
   foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,\r
                                                      pwcsName,\r
@@ -1102,7 +1111,7 @@ HRESULT WINAPI StorageImpl_CreateStorage(
     /*\r
      * An element with this name already exists\r
      */\r
-    if (grfMode & STGM_CREATE)\r
+    if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)\r
       IStorage_DestroyElement(iface, pwcsName);\r
     else\r
       return STG_E_FILEALREADYEXISTS;\r
@@ -1141,13 +1150,13 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   /*\r
    * Obtain a free property in the property chain\r
    */\r
-  newPropertyIndex = getFreeProperty(This->ancestorStorage);\r
+  newPropertyIndex = getFreeProperty(This->base.ancestorStorage);\r
 \r
   /*\r
    * Save the new property into the new property spot\r
    */\r
   StorageImpl_WriteProperty(\r
-    This->ancestorStorage,\r
+    This->base.ancestorStorage,\r
     newPropertyIndex,\r
     &newProperty);\r
 \r
@@ -1200,7 +1209,7 @@ static ULONG getFreeProperty(
     /*\r
      * Start by reading the root property\r
      */\r
-    readSuccessful = StorageImpl_ReadProperty(storage->ancestorStorage,\r
+    readSuccessful = StorageImpl_ReadProperty(storage->base.ancestorStorage,\r
                                                currentPropertyIndex,\r
                                                &currentProperty);\r
     if (readSuccessful)\r
@@ -1239,7 +1248,7 @@ static ULONG getFreeProperty(
      * obtain the new count of property blocks\r
      */\r
     blockCount = BlockChainStream_GetCount(\r
-                   storage->ancestorStorage->rootBlockChain)+1;\r
+                   storage->base.ancestorStorage->rootBlockChain)+1;\r
 \r
     /*\r
      * initialize the size used by the property stream\r
@@ -1250,7 +1259,7 @@ static ULONG getFreeProperty(
     /*\r
      * add a property block to the property chain\r
      */\r
-    BlockChainStream_SetSize(storage->ancestorStorage->rootBlockChain, newSize);\r
+    BlockChainStream_SetSize(storage->base.ancestorStorage->rootBlockChain, newSize);\r
 \r
     /*\r
      * memset the empty property in order to initialize the unused newly\r
@@ -1269,7 +1278,7 @@ static ULONG getFreeProperty(
       propertyIndex++)\r
     {\r
       StorageImpl_WriteProperty(\r
-        storage->ancestorStorage,\r
+        storage->base.ancestorStorage,\r
         propertyIndex,\r
         &emptyProperty);\r
     }\r
@@ -1322,8 +1331,8 @@ static void updatePropertyChain(
   /*\r
    * Read the root property\r
    */\r
-  StorageImpl_ReadProperty(storage->ancestorStorage,\r
-                             storage->rootPropertySetIndex,\r
+  StorageImpl_ReadProperty(storage->base.ancestorStorage,\r
+                             storage->base.rootPropertySetIndex,\r
                              &currentProperty);\r
 \r
   if (currentProperty.dirProperty != PROPERTY_NULL)\r
@@ -1343,7 +1352,7 @@ static void updatePropertyChain(
     /*\r
      * Read\r
      */\r
-    StorageImpl_ReadProperty(storage->ancestorStorage,\r
+    StorageImpl_ReadProperty(storage->base.ancestorStorage,\r
                                currentProperty.dirProperty,\r
                                &currentProperty);\r
 \r
@@ -1359,7 +1368,7 @@ static void updatePropertyChain(
       {\r
         if (previous != PROPERTY_NULL)\r
         {\r
-          StorageImpl_ReadProperty(storage->ancestorStorage,\r
+          StorageImpl_ReadProperty(storage->base.ancestorStorage,\r
                                      previous,\r
                                      &currentProperty);\r
           current = previous;\r
@@ -1367,7 +1376,7 @@ static void updatePropertyChain(
         else\r
         {\r
           currentProperty.previousProperty = newPropertyIndex;\r
-          StorageImpl_WriteProperty(storage->ancestorStorage,\r
+          StorageImpl_WriteProperty(storage->base.ancestorStorage,\r
                                       current,\r
                                       &currentProperty);\r
           found = 1;\r
@@ -1377,7 +1386,7 @@ static void updatePropertyChain(
       {\r
         if (next != PROPERTY_NULL)\r
         {\r
-          StorageImpl_ReadProperty(storage->ancestorStorage,\r
+          StorageImpl_ReadProperty(storage->base.ancestorStorage,\r
                                      next,\r
                                      &currentProperty);\r
           current = next;\r
@@ -1385,7 +1394,7 @@ static void updatePropertyChain(
         else\r
         {\r
           currentProperty.nextProperty = newPropertyIndex;\r
-          StorageImpl_WriteProperty(storage->ancestorStorage,\r
+          StorageImpl_WriteProperty(storage->base.ancestorStorage,\r
                                       current,\r
                                       &currentProperty);\r
           found = 1;\r
@@ -1410,8 +1419,8 @@ static void updatePropertyChain(
      * The root storage is empty, link the new property to it's dir property\r
      */\r
     currentProperty.dirProperty = newPropertyIndex;\r
-    StorageImpl_WriteProperty(storage->ancestorStorage,\r
-                                storage->rootPropertySetIndex,\r
+    StorageImpl_WriteProperty(storage->base.ancestorStorage,\r
+                                storage->base.rootPropertySetIndex,\r
                                 &currentProperty);\r
   }\r
 }\r
@@ -1657,8 +1666,8 @@ HRESULT WINAPI StorageImpl_DestroyElement(
    * Create a property enumeration to search the property with the given name\r
    */\r
   propertyEnumeration = IEnumSTATSTGImpl_Construct(\r
-    This->ancestorStorage,\r
-    This->rootPropertySetIndex);\r
+    This->base.ancestorStorage,\r
+    This->base.rootPropertySetIndex);\r
 \r
   foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty(\r
     propertyEnumeration,\r
@@ -1682,8 +1691,8 @@ HRESULT WINAPI StorageImpl_DestroyElement(
    * First, read This's StgProperty..\r
    */\r
   res = StorageImpl_ReadProperty(\r
-          This->ancestorStorage,\r
-          This->rootPropertySetIndex,\r
+          This->base.ancestorStorage,\r
+          This->base.rootPropertySetIndex,\r
           &parentProperty);\r
 \r
   assert(res);\r
@@ -1698,7 +1707,7 @@ HRESULT WINAPI StorageImpl_DestroyElement(
      * Set data as it would have been done in the else part...\r
      */\r
     typeOfRelation   = PROPERTY_RELATION_DIR;\r
-    parentPropertyId = This->rootPropertySetIndex;\r
+    parentPropertyId = This->base.rootPropertySetIndex;\r
   }\r
   else\r
   {\r
@@ -1709,8 +1718,8 @@ HRESULT WINAPI StorageImpl_DestroyElement(
     IEnumSTATSTGImpl* propertyEnumeration2;\r
 \r
     propertyEnumeration2 = IEnumSTATSTGImpl_Construct(\r
-      This->ancestorStorage,\r
-      This->rootPropertySetIndex);\r
+      This->base.ancestorStorage,\r
+      This->base.rootPropertySetIndex);\r
 \r
     typeOfRelation = IEnumSTATSTGImpl_FindParentProperty(\r
       propertyEnumeration2,\r
@@ -1847,7 +1856,7 @@ static HRESULT deleteStorageProperty(
    */\r
   propertyToDelete.sizeOfNameString = 0;\r
 \r
-  StorageImpl_WriteProperty(parentStorage->ancestorStorage,\r
+  StorageImpl_WriteProperty(parentStorage->base.ancestorStorage,\r
                             indexOfPropertyToDelete,\r
                             &propertyToDelete);\r
 \r
@@ -1914,7 +1923,7 @@ static HRESULT deleteStreamProperty(
    * but since we are here to zap it, I don't do it...\r
    */\r
   StorageImpl_WriteProperty(\r
-    parentStorage->ancestorStorage,\r
+    parentStorage->base.ancestorStorage,\r
     indexOfPropertyToDelete,\r
     &propertyToDelete);\r
 \r
@@ -1942,7 +1951,7 @@ static HRESULT findPlaceholder(
    * Read the storage property\r
    */\r
   res = StorageImpl_ReadProperty(\r
-          storage->ancestorStorage,\r
+          storage->base.ancestorStorage,\r
           storePropertyIndex,\r
           &storeProperty);\r
 \r
@@ -1998,7 +2007,7 @@ static HRESULT findPlaceholder(
   }\r
 \r
   hr = StorageImpl_WriteProperty(\r
-         storage->ancestorStorage,\r
+         storage->base.ancestorStorage,\r
          storePropertyIndex,\r
          &storeProperty);\r
 \r
@@ -2140,7 +2149,7 @@ static HRESULT adjustPropertyChain(
    * Write back the parent property\r
    */\r
   res = StorageImpl_WriteProperty(\r
-          This->ancestorStorage,\r
+          This->base.ancestorStorage,\r
           parentPropertyId,\r
           &parentProperty);\r
   if(! res)\r
@@ -2213,14 +2222,15 @@ HRESULT StorageImpl_Construct(
   /*\r
    * Initialize the virtual function table.\r
    */\r
-  This->lpVtbl = &Storage32Impl_Vtbl;\r
-  This->v_destructor = &StorageImpl_Destroy;\r
+  This->base.lpVtbl = &Storage32Impl_Vtbl;\r
+  This->base.pssVtbl = &IPropertySetStorage_Vtbl;\r
+  This->base.v_destructor = &StorageImpl_Destroy;\r
 \r
   /*\r
    * This is the top-level storage so initialize the ancestor pointer\r
    * to this.\r
    */\r
-  This->ancestorStorage = This;\r
+  This->base.ancestorStorage = This;\r
 \r
   /*\r
    * Initialize the physical support of the storage.\r
@@ -2372,13 +2382,13 @@ HRESULT StorageImpl_Construct(
       if ( (currentProperty.sizeOfNameString != 0 ) &&\r
            (currentProperty.propertyType     == PROPTYPE_ROOT) )\r
       {\r
-        This->rootPropertySetIndex = currentPropertyIndex;\r
+        This->base.rootPropertySetIndex = currentPropertyIndex;\r
       }\r
     }\r
 \r
     currentPropertyIndex++;\r
 \r
-  } while (readSuccessful && (This->rootPropertySetIndex == PROPERTY_NULL) );\r
+  } while (readSuccessful && (This->base.rootPropertySetIndex == PROPERTY_NULL) );\r
 \r
   if (!readSuccessful)\r
   {\r
@@ -2390,15 +2400,15 @@ HRESULT StorageImpl_Construct(
    * Create the block chain abstraction for the small block root chain.\r
    */\r
   if(!(This->smallBlockRootChain =\r
-       BlockChainStream_Construct(This, NULL, This->rootPropertySetIndex)))\r
+       BlockChainStream_Construct(This, NULL, This->base.rootPropertySetIndex)))\r
     return STG_E_READFAULT;\r
 \r
   return hr;\r
 }\r
 \r
-void StorageImpl_Destroy(\r
-  StorageImpl* This)\r
+void StorageImpl_Destroy(StorageBaseImpl* iface)\r
 {\r
+  StorageImpl *This = (StorageImpl*) iface;\r
   TRACE("(%p)\n", This);\r
 \r
   HeapFree(GetProcessHeap(), 0, This->pwcsName);\r
@@ -3138,7 +3148,7 @@ BOOL StorageImpl_ReadProperty(
   if (readSuccessful)\r
   {\r
     /* replace the name of root entry (often "Root Entry") by the file name */\r
-    WCHAR *propName = (index == This->rootPropertySetIndex) ?\r
+    WCHAR *propName = (index == This->base.rootPropertySetIndex) ?\r
                        This->filename : (WCHAR *)currentProperty+OFFSET_PS_NAME;\r
 \r
     memset(buffer->name, 0, sizeof(buffer->name));\r
@@ -3484,19 +3494,19 @@ StorageInternalImpl* StorageInternalImpl_Construct(
     /*\r
      * Initialize the virtual function table.\r
      */\r
-    newStorage->lpVtbl = &Storage32InternalImpl_Vtbl;\r
-    newStorage->v_destructor = &StorageInternalImpl_Destroy;\r
+    newStorage->base.lpVtbl = &Storage32InternalImpl_Vtbl;\r
+    newStorage->base.v_destructor = &StorageInternalImpl_Destroy;\r
 \r
     /*\r
      * Keep the ancestor storage pointer and nail a reference to it.\r
      */\r
-    newStorage->ancestorStorage = ancestorStorage;\r
-    StorageBaseImpl_AddRef((IStorage*)(newStorage->ancestorStorage));\r
+    newStorage->base.ancestorStorage = ancestorStorage;\r
+    StorageBaseImpl_AddRef((IStorage*)(newStorage->base.ancestorStorage));\r
 \r
     /*\r
      * Keep the index of the root property set for this storage,\r
      */\r
-    newStorage->rootPropertySetIndex = rootPropertyIndex;\r
+    newStorage->base.rootPropertySetIndex = rootPropertyIndex;\r
 \r
     return newStorage;\r
   }\r
@@ -3504,10 +3514,11 @@ StorageInternalImpl* StorageInternalImpl_Construct(
   return 0;\r
 }\r
 \r
-void StorageInternalImpl_Destroy(\r
-  StorageInternalImpl* This)\r
+void StorageInternalImpl_Destroy( StorageBaseImpl *iface)\r
 {\r
-  StorageBaseImpl_Release((IStorage*)This->ancestorStorage);\r
+  StorageInternalImpl* This = (StorageInternalImpl*) iface;\r
+\r
+  StorageBaseImpl_Release((IStorage*)This->base.ancestorStorage);\r
   HeapFree(GetProcessHeap(), 0, This);\r
 }\r
 \r
@@ -4938,7 +4949,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
 \r
         StorageImpl_ReadProperty(\r
           This->parentStorage,\r
-          This->parentStorage->rootPropertySetIndex,\r
+          This->parentStorage->base.rootPropertySetIndex,\r
           &rootProp);\r
 \r
         rootProp.startingBlock = sbStartIndex;\r
@@ -4947,7 +4958,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
 \r
         StorageImpl_WriteProperty(\r
           This->parentStorage,\r
-          This->parentStorage->rootPropertySetIndex,\r
+          This->parentStorage->base.rootPropertySetIndex,\r
           &rootProp);\r
       }\r
     }\r
@@ -4966,7 +4977,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
 \r
     StorageImpl_ReadProperty(\r
       This->parentStorage,\r
-      This->parentStorage->rootPropertySetIndex,\r
+      This->parentStorage->base.rootPropertySetIndex,\r
       &rootProp);\r
 \r
     if (rootProp.size.u.LowPart <\r
@@ -4980,7 +4991,7 @@ ULONG SmallBlockChainStream_GetNextFreeBlock(
 \r
       StorageImpl_WriteProperty(\r
         This->parentStorage,\r
-        This->parentStorage->rootPropertySetIndex,\r
+        This->parentStorage->base.rootPropertySetIndex,\r
         &rootProp);\r
     }\r
   }\r
@@ -5415,7 +5426,7 @@ HRESULT WINAPI StgCreateDocfile(
 {\r
   StorageImpl* newStorage = 0;\r
   HANDLE       hFile      = INVALID_HANDLE_VALUE;\r
-  HRESULT        hr         = S_OK;\r
+  HRESULT        hr         = STG_E_INVALIDFLAG;\r
   DWORD          shareMode;\r
   DWORD          accessMode;\r
   DWORD          creationMode;\r
@@ -5438,16 +5449,33 @@ HRESULT WINAPI StgCreateDocfile(
    * Validate the STGM flags\r
    */\r
   if ( FAILED( validateSTGM(grfMode) ))\r
-    return STG_E_INVALIDFLAG;\r
+    goto end;\r
 \r
   /* StgCreateDocFile always opens for write */\r
-  if (!(grfMode & (STGM_WRITE|STGM_READWRITE)))\r
-    return STG_E_INVALIDFLAG;\r
+  switch(STGM_ACCESS_MODE(grfMode))\r
+  {\r
+  case STGM_WRITE:\r
+  case STGM_READWRITE:\r
+    break;\r
+  default:\r
+    goto end;\r
+  }\r
+\r
+  /* can't share write */\r
+  switch(STGM_SHARE_MODE(grfMode))\r
+  {\r
+  case STGM_SHARE_EXCLUSIVE:\r
+  case STGM_SHARE_DENY_WRITE:\r
+    break;\r
+  default:\r
+    goto end;\r
+  }\r
+\r
+  /* shared reading requires transacted mode */\r
+  if( STGM_SHARE_MODE(grfMode) == STGM_SHARE_DENY_WRITE &&\r
+     !(grfMode&STGM_TRANSACTED) )\r
+    goto end;\r
 \r
-  /* always opens non-shared */\r
-  if (!(grfMode & STGM_SHARE_EXCLUSIVE))\r
-    return STG_E_INVALIDFLAG;\r
-      \r
   /*\r
    * Generate a unique name.\r
    */\r
@@ -5456,10 +5484,8 @@ HRESULT WINAPI StgCreateDocfile(
     WCHAR tempPath[MAX_PATH];\r
     static const WCHAR prefix[] = { 'S', 'T', 'O', 0 };\r
 \r
-    if (!(grfMode & STGM_SHARE_EXCLUSIVE))\r
-      return STG_E_INVALIDFLAG;\r
-    if (!(grfMode & (STGM_WRITE|STGM_READWRITE)))\r
-      return STG_E_INVALIDFLAG;\r
+    if (STGM_SHARE_MODE(grfMode) == STGM_SHARE_EXCLUSIVE)\r
+      goto end;\r
 \r
     memset(tempPath, 0, sizeof(tempPath));\r
     memset(tempFileName, 0, sizeof(tempFileName));\r
@@ -5470,7 +5496,10 @@ HRESULT WINAPI StgCreateDocfile(
     if (GetTempFileNameW(tempPath, prefix, 0, tempFileName) != 0)\r
       pwcsName = tempFileName;\r
     else\r
-      return STG_E_INSUFFICIENTMEMORY;\r
+    {\r
+      hr = STG_E_INSUFFICIENTMEMORY;\r
+      goto end;\r
+    }\r
 \r
     creationMode = TRUNCATE_EXISTING;\r
   }\r
@@ -5501,16 +5530,18 @@ HRESULT WINAPI StgCreateDocfile(
   hFile = CreateFileW(pwcsName,\r
                         accessMode,\r
                         shareMode,\r
-            NULL,\r
+                        NULL,\r
                         creationMode,\r
                         fileAttributes,\r
-            0);\r
+                        0);\r
 \r
   if (hFile == INVALID_HANDLE_VALUE)\r
   {\r
     if(GetLastError() == ERROR_FILE_EXISTS)\r
-      return STG_E_FILEALREADYEXISTS;\r
-    return E_FAIL;\r
+      hr = STG_E_FILEALREADYEXISTS;\r
+    else\r
+      hr = E_FAIL;\r
+    goto end;\r
   }\r
 \r
   /*\r
@@ -5519,7 +5550,10 @@ HRESULT WINAPI StgCreateDocfile(
   newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl));\r
 \r
   if (newStorage == 0)\r
-    return STG_E_INSUFFICIENTMEMORY;\r
+  {\r
+    hr = STG_E_INSUFFICIENTMEMORY;\r
+    goto end;\r
+  }\r
 \r
   hr = StorageImpl_Construct(\r
          newStorage,\r
@@ -5533,7 +5567,7 @@ HRESULT WINAPI StgCreateDocfile(
   if (FAILED(hr))\r
   {\r
     HeapFree(GetProcessHeap(), 0, newStorage);\r
-    return hr;\r
+    goto end;\r
   }\r
 \r
   /*\r
@@ -5543,6 +5577,8 @@ HRESULT WINAPI StgCreateDocfile(
          (IStorage*)newStorage,\r
          (REFIID)&IID_IStorage,\r
          (void**)ppstgOpen);\r
+end:\r
+  TRACE("<-- %p  r = %08lx\n", *ppstgOpen, hr);\r
 \r
   return hr;\r
 }\r
@@ -5557,6 +5593,23 @@ HRESULT WINAPI StgCreateStorageEx(const WCHAR* pwcsName, DWORD grfMode, DWORD st
     return STG_E_UNIMPLEMENTEDFUNCTION;\r
 }\r
 \r
+/******************************************************************************\r
+ *              StgCreatePropSetStg       [OLE32.@]\r
+ */\r
+HRESULT WINAPI StgCreatePropSetStg(IStorage *pstg, DWORD reserved,\r
+ IPropertySetStorage **ppPropSetStg)\r
+{\r
+    HRESULT hr;\r
+\r
+    TRACE("(%p, 0x%lx, %p): stub\n", pstg, reserved, ppPropSetStg);\r
+    if (reserved)\r
+        hr = STG_E_INVALIDPARAMETER;\r
+    else\r
+        hr = StorageBaseImpl_QueryInterface(pstg, &IID_IPropertySetStorage,\r
+         (void**)ppPropSetStg);\r
+    return hr;\r
+}\r
+\r
 /******************************************************************************\r
  *              StgOpenStorage        [OLE32.@]\r
  */\r
@@ -5850,11 +5903,23 @@ HRESULT WINAPI StgOpenStorageOnILockBytes(
  *\r
  *\r
  */\r
-HRESULT WINAPI StgSetTimes(OLECHAR const *str, FILETIME const *a,\r
-                           FILETIME const *b, FILETIME const *c )\r
+HRESULT WINAPI StgSetTimes(OLECHAR const *str, FILETIME const *pctime,\r
+                           FILETIME const *patime, FILETIME const *pmtime)\r
 {\r
-  FIXME("(%s, %p, %p, %p),stub!\n", debugstr_w(str), a, b, c);\r
-  return S_OK;\r
+  IStorage *stg = NULL;\r
+  HRESULT r;\r
\r
+  TRACE("%s %p %p %p\n", debugstr_w(str), pctime, patime, pmtime);\r
+\r
+  r = StgOpenStorage(str, NULL, STGM_READWRITE | STGM_SHARE_DENY_WRITE,\r
+                     0, 0, &stg);\r
+  if( SUCCEEDED(r) )\r
+  {\r
+    r = IStorage_SetElementTimes(stg, NULL, pctime, patime, pmtime);\r
+    IStorage_Release(stg);\r
+  }\r
+\r
+  return r;\r
 }\r
 \r
 /******************************************************************************\r
@@ -5985,6 +6050,9 @@ HRESULT  WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
 /****************************************************************************\r
  * This method validate a STGM parameter that can contain the values below\r
  *\r
+ * The stgm modes in 0x0000ffff are not bit masks, but distinct 4 bit values.\r
+ * The stgm values contained in 0xffff0000 are bitmasks.\r
+ *\r
  * STGM_DIRECT               0x00000000\r
  * STGM_TRANSACTED           0x00010000\r
  * STGM_SIMPLE               0x08000000\r
@@ -6010,79 +6078,74 @@ HRESULT  WINAPI OleSaveToStream(IPersistStream *pPStm,IStream *pStm)
  */\r
 static HRESULT validateSTGM(DWORD stgm)\r
 {\r
-  BOOL bSTGM_TRANSACTED       = ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED);\r
-  BOOL bSTGM_SIMPLE           = ((stgm & STGM_SIMPLE) == STGM_SIMPLE);\r
-  BOOL bSTGM_DIRECT           = ! (bSTGM_TRANSACTED || bSTGM_SIMPLE);\r
-\r
-  BOOL bSTGM_WRITE            = ((stgm & STGM_WRITE) == STGM_WRITE);\r
-  BOOL bSTGM_READWRITE        = ((stgm & STGM_READWRITE) == STGM_READWRITE);\r
-  BOOL bSTGM_READ             = ! (bSTGM_WRITE || bSTGM_READWRITE);\r
-\r
-  BOOL bSTGM_SHARE_DENY_NONE  =\r
-                     ((stgm & STGM_SHARE_DENY_NONE)  == STGM_SHARE_DENY_NONE);\r
+  DWORD access = STGM_ACCESS_MODE(stgm);\r
+  DWORD share  = STGM_SHARE_MODE(stgm);\r
+  DWORD create = STGM_CREATE_MODE(stgm);\r
 \r
-  BOOL bSTGM_SHARE_DENY_READ  =\r
-                     ((stgm & STGM_SHARE_DENY_READ)  == STGM_SHARE_DENY_READ);\r
-\r
-  BOOL bSTGM_SHARE_DENY_WRITE =\r
-                     ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);\r
+  if (stgm&~STGM_KNOWN_FLAGS)\r
+  {\r
+    ERR("unknown flags %08lx\n", stgm);\r
+    return E_FAIL;\r
+  }\r
 \r
-  BOOL bSTGM_SHARE_EXCLUSIVE  =\r
-                     ((stgm & STGM_SHARE_EXCLUSIVE)  == STGM_SHARE_EXCLUSIVE);\r
+  switch (access)\r
+  {\r
+  case STGM_READ:\r
+  case STGM_WRITE:\r
+  case STGM_READWRITE:\r
+    break;\r
+  default:\r
+    return E_FAIL;\r
+  }\r
 \r
-  BOOL bSTGM_CREATE           = ((stgm & STGM_CREATE) == STGM_CREATE);\r
-  BOOL bSTGM_CONVERT          = ((stgm & STGM_CONVERT) == STGM_CONVERT);\r
+  switch (share)\r
+  {\r
+  case STGM_SHARE_DENY_NONE:\r
+  case STGM_SHARE_DENY_READ:\r
+  case STGM_SHARE_DENY_WRITE:\r
+  case STGM_SHARE_EXCLUSIVE:\r
+    break;\r
+  default:\r
+    return E_FAIL;\r
+  }\r
 \r
-  BOOL bSTGM_NOSCRATCH        = ((stgm & STGM_NOSCRATCH) == STGM_NOSCRATCH);\r
-  BOOL bSTGM_NOSNAPSHOT       = ((stgm & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT);\r
+  switch (create)\r
+  {\r
+  case STGM_CREATE:\r
+  case STGM_FAILIFTHERE:\r
+    break;\r
+  default:\r
+    return E_FAIL;\r
+  }\r
 \r
   /*\r
    * STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE\r
    */\r
-  if ( ! bSTGM_DIRECT )\r
-    if( bSTGM_TRANSACTED && bSTGM_SIMPLE )\r
-      return E_FAIL;\r
-\r
-  /*\r
-   * STGM_WRITE |  STGM_READWRITE | STGM_READ\r
-   */\r
-  if ( ! bSTGM_READ )\r
-    if( bSTGM_WRITE && bSTGM_READWRITE )\r
-      return E_FAIL;\r
-\r
-  /*\r
-   * STGM_SHARE_DENY_NONE | others\r
-   * (I assume here that DENY_READ implies DENY_WRITE)\r
-   */\r
-  if ( bSTGM_SHARE_DENY_NONE )\r
-    if ( bSTGM_SHARE_DENY_READ ||\r
-         bSTGM_SHARE_DENY_WRITE ||\r
-         bSTGM_SHARE_EXCLUSIVE)\r
+  if ( (stgm & STGM_TRANSACTED) && (stgm & STGM_SIMPLE) )\r
       return E_FAIL;\r
 \r
   /*\r
    * STGM_CREATE | STGM_CONVERT\r
    * if both are false, STGM_FAILIFTHERE is set to TRUE\r
    */\r
-  if ( bSTGM_CREATE && bSTGM_CONVERT )\r
+  if ( create == STGM_CREATE && (stgm & STGM_CONVERT) )\r
     return E_FAIL;\r
 \r
   /*\r
    * STGM_NOSCRATCH requires STGM_TRANSACTED\r
    */\r
-  if ( bSTGM_NOSCRATCH && ! bSTGM_TRANSACTED )\r
+  if ( (stgm & STGM_NOSCRATCH) && (stgm & STGM_TRANSACTED) )\r
     return E_FAIL;\r
 \r
   /*\r
    * STGM_NOSNAPSHOT requires STGM_TRANSACTED and\r
    * not STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE`\r
    */\r
-  if (bSTGM_NOSNAPSHOT)\r
-  {\r
-    if ( ! ( bSTGM_TRANSACTED &&\r
-           !(bSTGM_SHARE_EXCLUSIVE || bSTGM_SHARE_DENY_WRITE)) )\r
+  if ( (stgm & STGM_NOSNAPSHOT) &&\r
+        (!(stgm & STGM_TRANSACTED) ||\r
+         share == STGM_SHARE_EXCLUSIVE ||\r
+         share == STGM_SHARE_DENY_WRITE) )\r
     return E_FAIL;\r
-  }\r
 \r
   return S_OK;\r
 }\r
@@ -6095,29 +6158,20 @@ static HRESULT validateSTGM(DWORD stgm)
  */\r
 static DWORD GetShareModeFromSTGM(DWORD stgm)\r
 {\r
-  DWORD dwShareMode = 0;\r
-  BOOL bSTGM_SHARE_DENY_NONE  =\r
-                     ((stgm & STGM_SHARE_DENY_NONE)  == STGM_SHARE_DENY_NONE);\r
-\r
-  BOOL bSTGM_SHARE_DENY_READ  =\r
-                     ((stgm & STGM_SHARE_DENY_READ)  == STGM_SHARE_DENY_READ);\r
-\r
-  BOOL bSTGM_SHARE_DENY_WRITE =\r
-                     ((stgm & STGM_SHARE_DENY_WRITE) == STGM_SHARE_DENY_WRITE);\r
-\r
-  BOOL bSTGM_SHARE_EXCLUSIVE  =\r
-                     ((stgm & STGM_SHARE_EXCLUSIVE)  == STGM_SHARE_EXCLUSIVE);\r
-\r
-  if ((bSTGM_SHARE_EXCLUSIVE) || (bSTGM_SHARE_DENY_READ))\r
-    dwShareMode = 0;\r
-\r
-  if (bSTGM_SHARE_DENY_NONE)\r
-    dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;\r
-\r
-  if (bSTGM_SHARE_DENY_WRITE)\r
-    dwShareMode = FILE_SHARE_READ;\r
-\r
-  return dwShareMode;\r
+  switch (STGM_SHARE_MODE(stgm))\r
+  {\r
+  case STGM_SHARE_DENY_NONE:\r
+    return FILE_SHARE_READ | FILE_SHARE_WRITE;\r
+  case STGM_SHARE_DENY_READ:\r
+    return FILE_SHARE_WRITE;\r
+  case STGM_SHARE_DENY_WRITE:\r
+    return FILE_SHARE_READ;\r
+  case STGM_SHARE_EXCLUSIVE:\r
+    return 0;\r
+  }\r
+  ERR("Invalid share mode!\n");\r
+  assert(0);\r
+  return 0;\r
 }\r
 \r
 /****************************************************************************\r
@@ -6128,21 +6182,17 @@ static DWORD GetShareModeFromSTGM(DWORD stgm)
  */\r
 static DWORD GetAccessModeFromSTGM(DWORD stgm)\r
 {\r
-  DWORD dwDesiredAccess = GENERIC_READ;\r
-  BOOL bSTGM_WRITE     = ((stgm & STGM_WRITE) == STGM_WRITE);\r
-  BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE);\r
-  BOOL bSTGM_READ      = ! (bSTGM_WRITE || bSTGM_READWRITE);\r
-\r
-  if (bSTGM_READ)\r
-    dwDesiredAccess = GENERIC_READ;\r
-\r
-  if (bSTGM_WRITE)\r
-    dwDesiredAccess |= GENERIC_WRITE;\r
-\r
-  if (bSTGM_READWRITE)\r
-    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;\r
-\r
-  return dwDesiredAccess;\r
+  switch (STGM_ACCESS_MODE(stgm))\r
+  {\r
+  case STGM_READ:\r
+    return GENERIC_READ;\r
+  case STGM_WRITE:\r
+  case STGM_READWRITE:\r
+    return GENERIC_READ | GENERIC_WRITE;\r
+  }\r
+  ERR("Invalid access mode!\n");\r
+  assert(0);\r
+  return 0;\r
 }\r
 \r
 /****************************************************************************\r
@@ -6153,16 +6203,19 @@ static DWORD GetAccessModeFromSTGM(DWORD stgm)
  */\r
 static DWORD GetCreationModeFromSTGM(DWORD stgm)\r
 {\r
-  if ( stgm & STGM_CREATE)\r
+  switch(STGM_CREATE_MODE(stgm))\r
+  {\r
+  case STGM_CREATE:\r
     return CREATE_ALWAYS;\r
-  if (stgm & STGM_CONVERT) {\r
+  case STGM_CONVERT:\r
     FIXME("STGM_CONVERT not implemented!\n");\r
     return CREATE_NEW;\r
+  case STGM_FAILIFTHERE:\r
+    return CREATE_NEW;\r
   }\r
-  /* All other cases */\r
-  if (stgm & ~ (STGM_CREATE|STGM_CONVERT))\r
-       FIXME("unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT));\r
-  return CREATE_NEW;\r
+  ERR("Invalid create mode!\n");\r
+  assert(0);\r
+  return 0;\r
 }\r
 \r
 \r
@@ -6831,7 +6884,7 @@ HRESULT WINAPI ReadFmtUserTypeStg (LPSTORAGE pstg, CLIPFORMAT* pcf, LPOLESTR* lp
                     STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm );\r
     if( FAILED ( r ) )\r
     {\r
-        ERR("Failed to open stream\n");\r
+        WARN("Failed to open stream r = %08lx\n", r);\r
         return r;\r
     }\r
 \r
index 40602ea..2a17dc4 100644 (file)
@@ -100,6 +100,14 @@ static const ULONG PROPERTY_NULL             = 0xFFFFFFFF;
 #define LIMIT_TO_USE_SMALL_BLOCK 0x1000\r
 #define NUM_BLOCKS_PER_DEPOT_BLOCK 128\r
 \r
+#define STGM_ACCESS_MODE(stgm)   ((stgm)&0x0000f)\r
+#define STGM_SHARE_MODE(stgm)    ((stgm)&0x000f0)\r
+#define STGM_CREATE_MODE(stgm)   ((stgm)&0x0f000)\r
+\r
+#define STGM_KNOWN_FLAGS (0xf0ff | \\r
+     STGM_TRANSACTED | STGM_CONVERT | STGM_PRIORITY | STGM_NOSCRATCH | \\r
+     STGM_NOSNAPSHOT | STGM_DIRECT_SWMR | STGM_DELETEONRELEASE | STGM_SIMPLE)\r
+\r
 /*\r
  * These are signatures to detect the type of Document file.\r
  */\r
@@ -207,6 +215,8 @@ struct StorageBaseImpl
   IStorageVtbl *lpVtbl;    /* Needs to be the first item in the struct\r
                            * since we want to cast this in a Storage32 pointer */\r
 \r
+  IPropertySetStorageVtbl *pssVtbl; /* interface for adding a properties stream */\r
+\r
   /*\r
    * Reference count of this object\r
    */\r
@@ -298,17 +308,7 @@ HRESULT WINAPI StorageBaseImpl_SetClass(
  */\r
 struct StorageImpl\r
 {\r
-  IStorageVtbl *lpVtbl;  /* Needs to be the first item in the struct\r
-                         * since we want to cast this in a Storage32 pointer */\r
-\r
-  /*\r
-   * Declare the member of the Storage32BaseImpl class to allow\r
-   * casting as a Storage32BaseImpl\r
-   */\r
-  ULONG                        ref;\r
-  struct StorageImpl* ancestorStorage;\r
-  ULONG                 rootPropertySetIndex;\r
-  void (*v_destructor)(struct StorageImpl*);\r
+  struct StorageBaseImpl base;\r
 \r
   /*\r
    * The following data members are specific to the Storage32Impl\r
@@ -405,7 +405,7 @@ HRESULT WINAPI StorageImpl_Stat(IStorage* iface,
                                 DWORD     grfStatFlag); /* [in] */\r
 \r
 void StorageImpl_Destroy(\r
-           StorageImpl* This);\r
+           StorageBaseImpl* This);\r
 \r
 HRESULT StorageImpl_Construct(\r
             StorageImpl* This,\r
@@ -498,17 +498,7 @@ void Storage32Impl_SetExtDepotBlock(StorageImpl* This,
  */\r
 struct StorageInternalImpl\r
 {\r
-  IStorageVtbl *lpVtbl;         /* Needs to be the first item in the struct\r
-                                * since we want to cast this in a Storage32 pointer */\r
-\r
-  /*\r
-   * Declare the member of the Storage32BaseImpl class to allow\r
-   * casting as a Storage32BaseImpl\r
-   */\r
-  ULONG                             ref;\r
-  struct StorageImpl* ancestorStorage;\r
-  ULONG                    rootPropertySetIndex;\r
-  void (*v_destructor)(struct StorageInternalImpl*);\r
+  struct StorageBaseImpl base;\r
 \r
   /*\r
    * There is no specific data for this class.\r
@@ -523,7 +513,7 @@ StorageInternalImpl* StorageInternalImpl_Construct(
            ULONG          rootTropertyIndex);\r
 \r
 void StorageInternalImpl_Destroy(\r
-                   StorageInternalImpl* This);\r
+                   StorageBaseImpl* This);\r
 \r
 HRESULT WINAPI StorageInternalImpl_Commit(\r
            IStorage*            iface,\r
index 24c7751..ea8161f 100644 (file)
@@ -29,6 +29,7 @@
 \r
 #include <assert.h>\r
 #include <stdarg.h>\r
+#include <limits.h>\r
 \r
 #include "windef.h"\r
 #include "winbase.h"\r
@@ -48,7 +49,7 @@ static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const
 /* creates a new stub manager and adds it into the apartment. caller must\r
  * release stub manager when it is no longer required. the apartment and\r
  * external refs together take one implicit ref */\r
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)\r
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags)\r
 {\r
     struct stub_manager *sm;\r
 \r
@@ -74,6 +75,13 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
      * the marshalled ifptr.\r
      */\r
     sm->extrefs = 0;\r
+\r
+    if (mshlflags & MSHLFLAGS_TABLESTRONG)\r
+        sm->state = STUBSTATE_TABLE_STRONG;\r
+    else if (mshlflags & MSHLFLAGS_TABLEWEAK)\r
+        sm->state = STUBSTATE_TABLE_WEAK_UNMARSHALED;\r
+    else\r
+        sm->state = STUBSTATE_NORMAL_MARSHALED;\r
     \r
     EnterCriticalSection(&apt->cs);\r
     sm->oid    = apt->oidc++;\r
@@ -228,8 +236,16 @@ ULONG stub_manager_int_release(struct stub_manager *This)
 /* add some external references (ie from a client that unmarshaled an ifptr) */\r
 ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs)\r
 {\r
-    ULONG rc = InterlockedExchangeAdd(&m->extrefs, refs) + refs;\r
+    ULONG rc;\r
+\r
+    EnterCriticalSection(&m->lock);\r
+    \r
+    /* make sure we don't overflow extrefs */\r
+    refs = min(refs, (ULONG_MAX-1 - m->extrefs));\r
+    rc = (m->extrefs += refs);\r
 \r
+    LeaveCriticalSection(&m->lock);\r
+    \r
     TRACE("added %lu refs to %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);\r
 \r
     return rc;\r
@@ -238,7 +254,15 @@ ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs)
 /* remove some external references */\r
 ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs)\r
 {\r
-    ULONG rc = InterlockedExchangeAdd(&m->extrefs, -refs) - refs;\r
+    ULONG rc;\r
+\r
+    EnterCriticalSection(&m->lock);\r
+\r
+    /* make sure we don't underflow extrefs */\r
+    refs = min(refs, m->extrefs);\r
+    rc = (m->extrefs -= refs);\r
+\r
+    LeaveCriticalSection(&m->lock);\r
     \r
     TRACE("removed %lu refs from %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);\r
 \r
@@ -321,24 +345,27 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
     return S_OK;\r
 }\r
 \r
-IRpcStubBuffer *ipid_to_stubbuffer(const IPID *ipid)\r
+/* gets the apartment and IRpcStubBuffer from an object. the caller must\r
+ * release the references to both objects */\r
+IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt)\r
 {\r
     IRpcStubBuffer *ret = NULL;\r
-    APARTMENT *apt;\r
     struct stub_manager *stubmgr;\r
     struct ifstub *ifstub;\r
     HRESULT hr;\r
 \r
-    hr = ipid_to_stub_manager(ipid, &apt, &stubmgr);\r
+    *stub_apt = NULL;\r
+\r
+    hr = ipid_to_stub_manager(ipid, stub_apt, &stubmgr);\r
     if (hr != S_OK) return NULL;\r
 \r
     ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid);\r
     if (ifstub)\r
         ret = ifstub->stubbuffer;\r
 \r
-    stub_manager_int_release(stubmgr);\r
+    if (ret) IRpcStubBuffer_AddRef(ret);\r
 \r
-    COM_ApartmentRelease(apt);\r
+    stub_manager_int_release(stubmgr);\r
 \r
     return ret;\r
 }\r
@@ -367,12 +394,12 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
 }\r
 \r
 /* registers a new interface stub COM object with the stub manager and returns registration record */\r
-struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, BOOL tablemarshal)\r
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid)\r
 {\r
     struct ifstub *stub;\r
 \r
-    TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s, tablemarshal=%s\n",\r
-          wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid), tablemarshal ? "TRUE" : "FALSE");\r
+    TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n",\r
+          wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid));\r
 \r
     stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));\r
     if (!stub) return NULL;\r
@@ -383,11 +410,6 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
     /* no need to ref this, same object as sb */\r
     stub->iface = iptr;\r
 \r
-    if (tablemarshal)\r
-        stub->state = IFSTUB_STATE_TABLE_MARSHALED;\r
-    else\r
-        stub->state = IFSTUB_STATE_NORMAL_MARSHALED;\r
-\r
     stub->iid = *iid;\r
 \r
     /* FIXME: hack for IRemUnknown because we don't notify SCM of our IPID\r
@@ -415,8 +437,10 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
 static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *ifstub)\r
 {\r
     TRACE("m=%p, m->oid=%s, ipid=%s\n", m, wine_dbgstr_longlong(m->oid), debugstr_guid(&ifstub->ipid));\r
-    \r
+\r
     list_remove(&ifstub->entry);\r
+\r
+    RPC_UnregisterInterface(&ifstub->iid);\r
         \r
     IUnknown_Release(ifstub->stubbuffer);\r
     IUnknown_Release(ifstub->iface);\r
@@ -425,33 +449,30 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
 }\r
 \r
 /* returns TRUE if it is possible to unmarshal, FALSE otherwise. */\r
-BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)\r
+BOOL stub_manager_notify_unmarshal(struct stub_manager *m)\r
 {\r
-    struct ifstub *ifstub;\r
     BOOL ret;\r
 \r
-    ifstub = stub_manager_ipid_to_ifstub(m, ipid);\r
-    if (!ifstub)\r
-    {\r
-        WARN("Can't find ifstub for OID %s, IPID %s\n",\r
-            wine_dbgstr_longlong(m->oid), wine_dbgstr_guid(ipid));\r
-        return FALSE;\r
-    }\r
-\r
     EnterCriticalSection(&m->lock);\r
 \r
-    switch (ifstub->state)\r
+    switch (m->state)\r
     {\r
-    case IFSTUB_STATE_TABLE_MARSHALED:\r
+    case STUBSTATE_TABLE_STRONG:\r
+    case STUBSTATE_TABLE_WEAK_MARSHALED:\r
+        /* no transition */\r
+        ret = TRUE;\r
+        break;\r
+    case STUBSTATE_TABLE_WEAK_UNMARSHALED:\r
+        m->state = STUBSTATE_TABLE_WEAK_MARSHALED;\r
         ret = TRUE;\r
         break;\r
-    case IFSTUB_STATE_NORMAL_MARSHALED:\r
-        ifstub->state = IFSTUB_STATE_NORMAL_UNMARSHALED;\r
+    case STUBSTATE_NORMAL_MARSHALED:\r
+        m->state = STUBSTATE_NORMAL_UNMARSHALED;\r
         ret = TRUE;\r
         break;\r
     default:\r
-        WARN("object OID %s, IPID %s already unmarshaled\n",\r
-            wine_dbgstr_longlong(m->oid), wine_dbgstr_guid(ipid));\r
+        WARN("object OID %s already unmarshaled\n",\r
+            wine_dbgstr_longlong(m->oid));\r
         ret = FALSE;\r
         break;\r
     }\r
@@ -461,22 +482,39 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
     return ret;\r
 }\r
 \r
-/* is an ifstub table marshaled? */\r
-BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)\r
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs)\r
 {\r
-    struct ifstub *ifstub;\r
-    BOOL ret;\r
+    EnterCriticalSection(&m->lock);\r
 \r
-    ifstub = stub_manager_ipid_to_ifstub(m, ipid);\r
-    if (!ifstub)\r
+    switch (m->state)\r
     {\r
-        WARN("Can't find ifstub for OID %s, IPID %s\n",\r
-            wine_dbgstr_longlong(m->oid), wine_dbgstr_guid(ipid));\r
-        return FALSE;\r
+    case STUBSTATE_NORMAL_MARSHALED:\r
+    case STUBSTATE_NORMAL_UNMARSHALED: /* FIXME: check this */\r
+        /* nothing to change */\r
+        break;\r
+    case STUBSTATE_TABLE_WEAK_UNMARSHALED:\r
+    case STUBSTATE_TABLE_STRONG:\r
+        refs = 1;\r
+        break;\r
+    case STUBSTATE_TABLE_WEAK_MARSHALED:\r
+        refs = 0; /* like native */\r
+        break;\r
     }\r
 \r
+    stub_manager_ext_release(m, refs);\r
+\r
+    LeaveCriticalSection(&m->lock);\r
+}\r
+\r
+/* is an ifstub table marshaled? */\r
+BOOL stub_manager_is_table_marshaled(struct stub_manager *m)\r
+{\r
+    BOOL ret;\r
+\r
     EnterCriticalSection(&m->lock);\r
-    ret = (ifstub->state == IFSTUB_STATE_TABLE_MARSHALED);\r
+    ret = ((m->state == STUBSTATE_TABLE_STRONG) ||\r
+           (m->state == STUBSTATE_TABLE_WEAK_MARSHALED) ||\r
+           (m->state == STUBSTATE_TABLE_WEAK_UNMARSHALED));\r
     LeaveCriticalSection(&m->lock);\r
 \r
     return ret;\r
@@ -688,7 +726,7 @@ HRESULT start_apartment_remote_unknown()
         {\r
             STDOBJREF stdobjref; /* dummy - not used */\r
             /* register it with the stub manager */\r
-            hr = register_ifstub(COM_CurrentApt(), &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);\r
+            hr = register_ifstub(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown, MSHLFLAGS_NORMAL);\r
             /* release our reference to the object as the stub manager will manage the life cycle for us */\r
             IRemUnknown_Release(pRemUnknown);\r
             if (hr == S_OK)\r
index b53541c..e27d49a 100644 (file)
@@ -5,7 +5,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@\r
 MODULE    = oleaut32.dll\r
 IMPORTS   = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll\r
-DELAYIMPORTS = comctl32\r
+DELAYIMPORTS = comctl32 urlmon\r
 EXTRALIBS = $(LIBUNICODE) -luuid\r
 \r
 C_SRCS = \\r
@@ -16,6 +16,7 @@ C_SRCS = \
        oleaut.c \\r
        olefont.c \\r
        olepicture.c \\r
+       recinfo.c \\r
        regsvr.c \\r
        safearray.c \\r
        stubs.c \\r
index c885233..5bbec06 100644 (file)
@@ -6,7 +6,7 @@ TARGET_OBJECTS = @C_SRCS@
 \r
 TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__\r
 \r
-TARGET_SDKLIBS = @IMPORTS@ winmm.a wine.a wine_uuid.a ntdll.a\r
+TARGET_SDKLIBS = @IMPORTS@ urlmon.a winmm.a wine.a wine_uuid.a ntdll.a\r
 \r
 TARGET_BASE = $(TARGET_BASE_LIB_OLEAUT32)\r
 \r
index 1426814..1b2f8f3 100644 (file)
@@ -571,28 +571,6 @@ ULONG WINAPI OaBuildVersion()
     }\r
 }\r
 \r
-/******************************************************************************\r
- *      GetRecordInfoFromGuids  [OLEAUT32.322]\r
- *\r
- * RETURNS\r
- *  Success: S_OK\r
- *  Failure: E_INVALIDARG, if any argument is invalid.\r
- *\r
- * BUGS\r
- *  Unimplemented\r
- */\r
-HRESULT WINAPI GetRecordInfoFromGuids(\r
-    REFGUID rGuidTypeLib,\r
-    ULONG uVerMajor,\r
-    ULONG uVerMinor,\r
-    LCID lcid,\r
-    REFGUID rGuidTypeInfo,\r
-    IRecordInfo** ppRecInfo)\r
-{\r
-    FIXME("(%p,%ld,%ld,%ld,%p,%p),stub!\n",rGuidTypeLib, uVerMajor, uVerMinor, lcid, rGuidTypeInfo, ppRecInfo);\r
-    return E_NOTIMPL;\r
-}\r
-\r
 /******************************************************************************\r
  *             OleTranslateColor       [OLEAUT32.421]\r
  *\r
index 9eac485..d1ebc0e 100644 (file)
@@ -42,7 +42,7 @@
 \r
 /*\r
  * FIXME:\r
- *  Finnish, Greek, Hebrew, Japanese, Korean, Portuguese,\r
+ *  Finnish, Greek, Hebrew, Japanese, Korean,\r
  *  Turkish, Slovenian (at least) are localised in XP Home.\r
  *  I expect Chinese etc are localised in Asian Editions also.\r
  */\r
index ab04bf2..a3a67a1 100644 (file)
 320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer\r
 321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer\r
 322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr)\r
-323 stub GetRecordInfoFromTypeInfo # stdcall (ptr ptr)\r
+323 stdcall GetRecordInfoFromTypeInfo(ptr ptr)\r
 325 stub SetVarConversionLocaleSetting\r
 326 stub GetVarConversionLocaleSetting\r
 327 stdcall SetOaNoCache()\r
 421 stdcall OleTranslateColor(long long long)\r
 422 stub OleLoadPictureFile\r
 423 stub OleSavePictureFile\r
-424 stub OleLoadPicturePath\r
+424 stdcall OleLoadPicturePath(wstr ptr long long ptr ptr)\r
 425 stdcall VarUI4FromI8(long long ptr)\r
 426 stdcall VarUI4FromUI8(long long ptr)\r
 427 stdcall VarI8FromUI8(long long ptr)\r
index b718a7c..e885c4e 100644 (file)
@@ -22,6 +22,7 @@
        <library>rpcrt4</library>\r
        <library>ole32</library>\r
        <library>comctl32</library>\r
+       <library>urlmon</library>\r
        <file>connpt.c</file>\r
        <file>dispatch.c</file>\r
        <file>hash.c</file>\r
@@ -29,6 +30,7 @@
        <file>oleaut.c</file>\r
        <file>olefont.c</file>\r
        <file>olepicture.c</file>\r
+       <file>recinfo.c</file>\r
        <file>regsvr.c</file>\r
        <file>safearray.c</file>\r
        <file>stubs.c</file>\r
index a11ce14..5d1b9c9 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 STRINGTABLE DISCARDABLE\r
 {\r
index 09e8e2b..6ad98e2 100644 (file)
@@ -1068,8 +1068,16 @@ static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
   IFont*         iface,\r
   TEXTMETRICOLE* ptm)\r
 {\r
-  FIXME("(%p, %p), stub!\n",iface,ptm);\r
-  return E_NOTIMPL;\r
+  HDC hdcRef;\r
+  HFONT hOldFont, hNewFont;\r
+\r
+  hdcRef = GetDC(0);\r
+  OLEFontImpl_get_hFont(iface, &hNewFont);\r
+  hOldFont = SelectObject(hdcRef, hNewFont);\r
+  GetTextMetricsW(hdcRef, ptm);\r
+  SelectObject(hdcRef, hOldFont);\r
+  ReleaseDC(0, hdcRef);\r
+  return S_OK;\r
 }\r
 \r
 /************************************************************************\r
index 4573677..2883c34 100644 (file)
@@ -71,7 +71,9 @@
 #include "olectl.h"\r
 #include "oleauto.h"\r
 #include "connpt.h"\r
+#include "urlmon.h"\r
 #include "wine/debug.h"\r
+#include "wine/unicode.h"\r
 \r
 #include "wine/wingdi16.h"\r
 #include "cursoricon.h"\r
@@ -106,7 +108,7 @@ typedef struct OLEPictureImpl {
     IPersistStreamVtbl *lpvtbl3;\r
     IConnectionPointContainerVtbl *lpvtbl4;\r
 \r
-  /* Object referenece count */\r
+  /* Object reference count */\r
     DWORD ref;\r
 \r
   /* We own the object and must destroy it ourselves */\r
@@ -705,7 +707,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
   TRACE("(%p)->(%p).\n", This, pdwAttr);\r
   *pdwAttr = 0;\r
   switch (This->desc.picType) {\r
-  case PICTYPE_BITMAP:         break;  /* not 'truely' scalable, see MSDN. */\r
+  case PICTYPE_BITMAP:         break;  /* not 'truly' scalable, see MSDN. */\r
   case PICTYPE_ICON: *pdwAttr     = PICTURE_TRANSPARENT;break;\r
   case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;\r
   default:FIXME("Unknown pictype %d\n",This->desc.picType);break;\r
@@ -1514,9 +1516,15 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt
     GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData, pInfoBitmap, DIB_RGB_COLORS);\r
 \r
     /* Calculate the total length required for the BMP data */\r
-    if (pInfoBitmap->bmiHeader.biClrUsed != 0) iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;\r
-    else if (pInfoBitmap->bmiHeader.biBitCount <= 8) iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;\r
-    else iNumPaletteEntries = 0;\r
+    if (pInfoBitmap->bmiHeader.biClrUsed != 0) {\r
+       iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;\r
+       if (iNumPaletteEntries > 256) iNumPaletteEntries = 256;\r
+    } else {\r
+       if (pInfoBitmap->bmiHeader.biBitCount <= 8)\r
+           iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;\r
+       else\r
+           iNumPaletteEntries = 0;\r
+    }\r
     *pLength =\r
         sizeof(BITMAPFILEHEADER) +\r
         sizeof(BITMAPINFOHEADER) +\r
@@ -1624,6 +1632,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
                                ||      (pInfoBitmap->bmiHeader.biBitCount == 24)\r
                                ||      (pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {\r
                                iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;\r
+                               if (iNumEntriesPalette > 256) iNumEntriesPalette = 256; \r
                        } else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32)\r
                                && pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {\r
                                iNumEntriesPalette = 3;\r
@@ -1820,7 +1829,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
 \r
   VariantInit(pVarResult);\r
   V_VT(pVarResult) = VT_BOOL;\r
-  V_UNION(pVarResult,boolVal) = FALSE;\r
+  V_BOOL(pVarResult) = FALSE;\r
   return S_OK;\r
 }\r
 \r
@@ -1984,6 +1993,113 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
   return hr;\r
 }\r
 \r
+/***********************************************************************\r
+ * OleLoadPicturePath (OLEAUT32.424)\r
+ */\r
+HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,\r
+               DWORD dwReserved, OLE_COLOR clrReserved, REFIID riid,\r
+               LPVOID *ppvRet )\r
+{\r
+  static const WCHAR file[] = { 'f','i','l','e',':','/','/',0 };\r
+  IPicture *ipicture;\r
+  HANDLE hFile;\r
+  DWORD dwFileSize;\r
+  HGLOBAL hGlobal = NULL;\r
+  DWORD dwBytesRead = 0;\r
+  IStream *stream;\r
+  BOOL bRead;\r
+  IPersistStream *pStream;\r
+  HRESULT hRes;\r
+\r
+  TRACE("(%s,%p,%ld,%08lx,%s,%p): stub\n",\r
+        debugstr_w(szURLorPath), punkCaller, dwReserved, clrReserved,\r
+        debugstr_guid(riid), ppvRet);\r
+\r
+  if (!ppvRet) return E_POINTER;\r
+\r
+  if (strncmpW(szURLorPath, file, 7) == 0) {       \r
+      szURLorPath += 7;\r
+  \r
+      hFile = CreateFileW(szURLorPath, GENERIC_READ, 0, NULL, OPEN_EXISTING,\r
+                                  0, NULL);\r
+      if (hFile == INVALID_HANDLE_VALUE)\r
+         return E_UNEXPECTED;\r
+\r
+      dwFileSize = GetFileSize(hFile, NULL);\r
+      if (dwFileSize != INVALID_FILE_SIZE )\r
+      {\r
+         hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize);\r
+         if ( hGlobal)\r
+         {\r
+             bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL);\r
+             if (!bRead)\r
+             {\r
+                 GlobalFree(hGlobal);\r
+                 hGlobal = 0;\r
+             }\r
+         }\r
+      }\r
+      CloseHandle(hFile);\r
+      \r
+      if (!hGlobal)\r
+         return E_UNEXPECTED;\r
+\r
+      hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);\r
+      if (FAILED(hRes)) \r
+      {\r
+         GlobalFree(hGlobal);\r
+         return hRes;\r
+      }\r
+  } else {\r
+      IMoniker *pmnk;\r
+      IBindCtx *pbc;\r
+\r
+      hRes = CreateBindCtx(0, &pbc);\r
+      if (SUCCEEDED(hRes)) \r
+      {\r
+         hRes = CreateURLMoniker(NULL, szURLorPath, &pmnk);\r
+         if (SUCCEEDED(hRes))\r
+         {              \r
+             hRes = IMoniker_BindToStorage(pmnk, pbc, NULL, &IID_IStream, (LPVOID*)&stream);\r
+             IMoniker_Release(pmnk);\r
+         }\r
+         IBindCtx_Release(pbc);\r
+      }\r
+      if (FAILED(hRes))\r
+         return hRes;\r
+  }\r
+\r
+  hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER, \r
+                  &IID_IPicture, (LPVOID*)&ipicture);\r
+  if (hRes != S_OK) {\r
+      IStream_Release(stream);\r
+      return hRes;\r
+  }\r
+  \r
+  hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, (LPVOID*)&pStream);\r
+  if (hRes) {\r
+      IStream_Release(stream);\r
+      IPicture_Release(ipicture);\r
+      return hRes;\r
+  }\r
+\r
+  hRes = IPersistStream_Load(pStream, stream); \r
+  IPersistStream_Release(pStream);\r
+  IStream_Release(stream);\r
+\r
+  if (hRes) {\r
+      IPicture_Release(ipicture);\r
+      return hRes;\r
+  }\r
+\r
+  hRes = IPicture_QueryInterface(ipicture,riid,ppvRet);\r
+  if (hRes)\r
+      FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));\r
+  \r
+  IPicture_Release(ipicture);\r
+  return hRes;\r
+}\r
+\r
 /*******************************************************************************\r
  * StdPic ClassFactory\r
  */\r
@@ -2017,12 +2133,8 @@ static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) {
 static HRESULT WINAPI SPCF_CreateInstance(\r
        LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj\r
 ) {\r
-       PICTDESC        pd;\r
-\r
-       FIXME("(%p,%p,%s,%p), creating stdpic with PICTYPE_NONE.\n",iface,pOuter,debugstr_guid(riid),ppobj);\r
-       pd.cbSizeofstruct = sizeof(pd);\r
-       pd.picType = PICTYPE_NONE;\r
-       return OleCreatePictureIndirect(&pd,riid,TRUE,ppobj);\r
+    /* Creates an uninitialized picture */\r
+    return OleCreatePictureIndirect(NULL,riid,TRUE,ppobj);\r
 \r
 }\r
 \r
diff --git a/reactos/lib/oleaut32/recinfo.c b/reactos/lib/oleaut32/recinfo.c
new file mode 100644 (file)
index 0000000..d7851c1
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2005 Jacek Caban
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "oaidl.h"
+#include "oleauto.h"
+
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+typedef struct {
+    enum VARENUM vt;
+    VARKIND varkind;
+    ULONG offset;
+    BSTR name;
+} fieldstr;
+
+typedef struct {
+    IRecordInfoVtbl *lpVtbl;
+    ULONG ref;
+
+    GUID guid;
+    UINT lib_index;
+    WORD n_vars;
+    ULONG size;
+    BSTR name;
+    fieldstr *fields;
+    ITypeInfo *pTypeInfo;
+} IRecordInfoImpl;
+
+static HRESULT copy_to_variant(void *src, VARIANT *pvar, enum VARENUM vt)
+{
+    TRACE("%p %p %d\n", src, pvar, vt);
+
+#define CASE_COPY(x) \
+    case VT_ ## x: \
+        V_ ## x(pvar) = *(typeof(V_ ## x(pvar))*)src; \
+        break 
+
+    switch(vt) {
+        CASE_COPY(I2);
+        CASE_COPY(I4);
+        CASE_COPY(R4);
+        CASE_COPY(R8);
+        CASE_COPY(CY);
+        CASE_COPY(DATE);
+        CASE_COPY(BSTR);
+        CASE_COPY(ERROR);
+        CASE_COPY(BOOL);
+        CASE_COPY(DECIMAL);
+        CASE_COPY(I1);
+        CASE_COPY(UI1);
+        CASE_COPY(UI2);
+        CASE_COPY(UI4);
+        CASE_COPY(I8);
+        CASE_COPY(UI8);
+        CASE_COPY(INT);
+        CASE_COPY(UINT);
+        CASE_COPY(INT_PTR);
+        CASE_COPY(UINT_PTR);
+    default:
+        FIXME("Not supported type: %d\n", vt);
+        return E_NOTIMPL;
+    };
+#undef CASE_COPY
+
+    V_VT(pvar) = vt;
+    return S_OK;
+}
+
+static HRESULT copy_from_variant(VARIANT *src, void *dest, enum VARENUM vt)
+{
+    VARIANT var;
+    HRESULT hres;
+
+    TRACE("(%p(%d) %p %d)\n", src, V_VT(src), dest, vt);
+
+    hres = VariantChangeType(&var, src, 0, vt);
+    if(FAILED(hres))
+        return hres;
+
+#define CASE_COPY(x) \
+    case VT_ ## x: \
+        *(typeof(V_ ## x(&var))*)dest = V_ ## x(&var); \
+        break
+
+    switch(vt) {
+        CASE_COPY(I2);
+        CASE_COPY(I4);
+        CASE_COPY(R4);
+        CASE_COPY(R8);
+        CASE_COPY(CY);
+        CASE_COPY(DATE);
+        CASE_COPY(BSTR);
+        CASE_COPY(ERROR);
+        CASE_COPY(BOOL);
+        CASE_COPY(DECIMAL);
+        CASE_COPY(I1);
+        CASE_COPY(UI1);
+        CASE_COPY(UI2);
+        CASE_COPY(UI4);
+        CASE_COPY(I8);
+        CASE_COPY(UI8);
+        CASE_COPY(INT);
+        CASE_COPY(UINT);
+        CASE_COPY(INT_PTR);
+        CASE_COPY(UINT_PTR);
+    default:
+        FIXME("Not supported type: %d\n", V_VT(&var));
+        return E_NOTIMPL;
+    };
+#undef CASE_COPY
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID riid,
+                                                void **ppvObject)
+{
+    TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
+
+    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRecordInfo, riid)) {
+       *ppvObject = iface;
+       IRecordInfo_AddRef(iface);
+       return S_OK;
+    }
+
+    FIXME("Not supported interface: %s\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    ULONG ref = InterlockedIncrement(&This->ref);
+    TRACE("(%p) -> %ld\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) -> %ld\n", This, ref);
+
+    if(!ref) {
+        int i;
+        for(i=0; i<This->n_vars; i++)
+            SysFreeString(This->fields[i].name);
+        HeapFree(GetProcessHeap(), 0, This->name);
+        HeapFree(GetProcessHeap(), 0, This->fields);
+        ITypeInfo_Release(This->pTypeInfo);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    TRACE("(%p)->(%p)\n", This, pvNew);
+
+    if(!pvNew)
+        return E_INVALIDARG;
+
+    memset(pvNew, 0, This->size);
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    int i;
+    PVOID var;
+
+    TRACE("(%p)->(%p)\n", This, pvExisting);
+
+    if(!pvExisting)
+        return E_INVALIDARG;
+
+    for(i=0; i<This->n_vars; i++) {
+        if(This->fields[i].varkind != VAR_PERINSTANCE) {
+            ERR("varkind != VAR_PERINSTANCE\n");
+            continue;
+        }
+        var = ((PBYTE)pvExisting)+This->fields[i].offset;
+        switch(This->fields[i].vt) {
+            case VT_BSTR:
+                /* NOTE: Windows implementatino reads DWORD (len) before string,
+                 *       but it seems to do nothing with this */
+                *(BSTR*)var = NULL;
+                break;
+            case VT_I2:
+            case VT_I4:
+            case VT_R8:
+            case VT_CY:
+            case VT_DATE:
+            case VT_ERROR:
+            case VT_BOOL:
+            case VT_DECIMAL:
+            case VT_I1:
+            case VT_UI1:
+            case VT_UI2:
+            case VT_UI4:
+            case VT_I8:
+            case VT_UI8:
+            case VT_INT:
+            case VT_UINT:
+                break;
+            case VT_INT_PTR:
+            case VT_UINT_PTR:
+                *(void**)var = NULL;
+                break;
+            default:
+                FIXME("Not supported vt = %d\n", This->fields[i].vt);
+                break;
+        }
+    }
+    
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting,
+                                                PVOID pvNew)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew);
+    
+    if(!pvExisting || !pvNew)
+        return E_INVALIDARG;
+
+    memcpy(pvExisting, pvNew, This->size);
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p)\n", This, pguid);
+
+    if(!pguid)
+        return E_INVALIDARG;
+
+    memcpy(pguid, &This->guid, sizeof(GUID));
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrName)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p)\n", This, pbstrName);
+
+    if(!pbstrName)
+        return E_INVALIDARG;
+
+    *pbstrName = SysAllocString(This->name);
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    
+    TRACE("(%p)->(%p)\n", This, pcbSize);
+
+    if(!pcbSize)
+        return E_INVALIDARG;
+    
+    *pcbSize = This->size;
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p)\n", This, ppTypeInfo);
+
+    if(!ppTypeInfo)
+        return E_INVALIDARG;
+
+    ITypeInfo_AddRef(This->pTypeInfo);
+    *ppTypeInfo = This->pTypeInfo;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
+                                                LPCOLESTR szFieldName, VARIANT *pvarField)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    int i;
+
+    TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField);
+
+    if(!pvData || !szFieldName || !pvarField)
+        return E_INVALIDARG;
+
+    for(i=0; i<This->n_vars; i++)
+        if(!strcmpW(This->fields[i].name, szFieldName))
+            break;
+    if(i == This->n_vars)
+        return TYPE_E_FIELDNOTFOUND;
+    
+    VariantClear(pvarField);
+    return copy_to_variant(((PBYTE)pvData)+This->fields[i].offset, pvarField,
+            This->fields[i].vt);
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
+                            LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    int i;
+
+    TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);
+
+    if(!pvData || !szFieldName || !pvarField)
+        return E_INVALIDARG;
+
+    for(i=0; i<This->n_vars; i++)
+        if(!strcmpW(This->fields[i].name, szFieldName))
+            break;
+    if(i == This->n_vars)
+        return TYPE_E_FIELDNOTFOUND;
+
+    VariantClear(pvarField);
+    V_VT(pvarField) = VT_BYREF|This->fields[i].vt;
+    V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset;
+    *ppvDataCArray = NULL;
+    return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData,
+                                            LPCOLESTR szFieldName, VARIANT *pvarField)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    int i;
+
+    TRACE("(%p)->(%08lx %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
+                                    pvarField);
+
+    if(!pvData || !szFieldName || !pvarField
+            || (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
+        return E_INVALIDARG;
+
+    if(wFlags == INVOKE_PROPERTYPUTREF) {
+        FIXME("wFlag == INVOKE_PROPERTYPUTREF not supported\n");
+        return E_NOTIMPL;
+    }
+
+    for(i=0; i<This->n_vars; i++)
+        if(!strcmpW(This->fields[i].name, szFieldName))
+            break;
+    if(i == This->n_vars)
+        return TYPE_E_FIELDNOTFOUND;
+
+    return copy_from_variant(pvarField, ((PBYTE)pvData)+This->fields[i].offset,
+            This->fields[i].vt);
+}
+
+static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags,
+                PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    int i;
+
+    FIXME("(%p)->(%08lx %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
+
+    if(!pvData || !szFieldName || !pvarField
+            || (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
+        return E_INVALIDARG;
+
+    for(i=0; i<This->n_vars; i++)
+        if(!strcmpW(This->fields[i].name, szFieldName))
+            break;
+    if(i == This->n_vars)
+        return TYPE_E_FIELDNOTFOUND;
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames,
+                                                BSTR *rgBstrNames)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+    ULONG n = This->n_vars;
+    int i;
+
+    TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames);
+
+    if(!pcNames)
+        return E_INVALIDARG;
+
+    if(*pcNames < n)
+        n =  *pcNames;
+
+    if(rgBstrNames) {
+        for(i=0; i<n; i++)
+            rgBstrNames[i] = SysAllocString(This->fields[i].name);
+    }
+    
+    *pcNames = n;
+    return S_OK;
+}
+
+static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    FIXME("(%p)->(%p) stub\n", This, pRecordInfo);
+
+    return FALSE;
+}
+
+static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)\n", This);
+
+    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->size);
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource,
+                                                    PVOID *ppvDest)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest);
+
+    if(!pvSource || !ppvDest)
+        return E_INVALIDARG;
+    
+    *ppvDest = IRecordInfo_RecordCreate(iface);
+    return IRecordInfo_RecordCopy(iface, pvSource, *ppvDest);
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
+{
+    IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+    TRACE("(%p)->(%p)\n", This, pvRecord);
+
+    if(!HeapFree(GetProcessHeap(), 0, pvRecord))
+        return E_INVALIDARG;
+
+    return S_OK;
+}
+
+static IRecordInfoVtbl IRecordInfoImplVtbl = {
+    IRecordInfoImpl_QueryInterface,
+    IRecordInfoImpl_AddRef,
+    IRecordInfoImpl_Release,
+    IRecordInfoImpl_RecordInit,
+    IRecordInfoImpl_RecordClear,
+    IRecordInfoImpl_RecordCopy,
+    IRecordInfoImpl_GetGuid,
+    IRecordInfoImpl_GetName,
+    IRecordInfoImpl_GetSize,
+    IRecordInfoImpl_GetTypeInfo,
+    IRecordInfoImpl_GetField,
+    IRecordInfoImpl_GetFieldNoCopy,
+    IRecordInfoImpl_PutField,
+    IRecordInfoImpl_PutFieldNoCopy,
+    IRecordInfoImpl_GetFieldNames,
+    IRecordInfoImpl_IsMatchingType,
+    IRecordInfoImpl_RecordCreate,
+    IRecordInfoImpl_RecordCreateCopy,
+    IRecordInfoImpl_RecordDestroy
+};
+
+/******************************************************************************
+ *      GetRecordInfoFromGuids  [OLEAUT32.322]
+ *
+ * RETURNS
+ *  Success: S_OK
+ *  Failure: E_INVALIDARG, if any argument is invalid.
+ */
+HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor,
+                        ULONG uVerMinor, LCID lcid, REFGUID rGuidTypeInfo, IRecordInfo** ppRecInfo)
+{
+    ITypeInfo *pTypeInfo;
+    ITypeLib *pTypeLib;
+    HRESULT hres;
+    
+    TRACE("(%p,%ld,%ld,%ld,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor,
+            lcid, rGuidTypeInfo, ppRecInfo);
+
+    hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib);
+    if(FAILED(hres)) {
+        WARN("LoadRegTypeLib failed!\n");
+        return hres;
+    }
+
+    hres = ITypeLib_GetTypeInfoOfGuid(pTypeLib, rGuidTypeInfo, &pTypeInfo);
+    ITypeLib_Release(pTypeLib);
+    if(FAILED(hres)) {
+        WARN("GetTypeInfoOfGuid failed!\n");
+        return hres;
+    }
+
+    hres = GetRecordInfoFromTypeInfo(pTypeInfo, ppRecInfo);
+    ITypeInfo_Release(pTypeInfo);
+    return hres;
+}
+
+/******************************************************************************
+ *      GetRecordInfoFromTypeInfo [OLEAUT32.332]
+ */
+HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo) {
+    HRESULT hres;
+    TYPEATTR *typeattr;
+    IRecordInfoImpl *ret;
+    ITypeInfo *pTypeInfo;
+    int i;
+    GUID guid;
+
+    TRACE("(%p %p)\n", pTI, ppRecInfo);
+
+    if(!pTI || !ppRecInfo)
+        return E_INVALIDARG;
+    
+    hres = ITypeInfo_GetTypeAttr(pTI, &typeattr);
+    if(FAILED(hres) || !typeattr) {
+        WARN("GetTypeAttr failed: %08lx\n", hres);
+        return hres;
+    }
+
+    if(typeattr->typekind == TKIND_ALIAS) {
+        hres = ITypeInfo_GetRefTypeInfo(pTI, typeattr->tdescAlias.u.hreftype, &pTypeInfo);
+        memcpy(&guid, &typeattr->guid, sizeof(GUID));
+        ITypeInfo_ReleaseTypeAttr(pTI, typeattr);
+        if(FAILED(hres)) {
+            WARN("GetRefTypeInfo failed: %08lx\n", hres);
+            return hres;
+        }
+        ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr);
+    }else  {
+        pTypeInfo = pTI;
+        ITypeInfo_AddRef(pTypeInfo);
+        memcpy(&guid, &typeattr->guid, sizeof(GUID));
+    }
+
+    if(typeattr->typekind != TKIND_RECORD) {
+        WARN("typekind != TKIND_RECORD\n");
+        ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
+        ITypeInfo_Release(pTypeInfo);
+        return E_INVALIDARG;
+    }
+
+    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
+    ret->lpVtbl = &IRecordInfoImplVtbl;
+    ret->ref = 1;
+    ret->pTypeInfo = pTypeInfo;
+    ret->n_vars = typeattr->cVars;
+    ret->size = typeattr->cbSizeInstance;
+    ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
+
+    memcpy(&ret->guid, &guid, sizeof(GUID));
+
+    /* NOTE: Windows implementation calls ITypeInfo::GetCantainingTypeLib and
+     *       ITypeLib::GetLibAttr, but we currently don't need this.
+     */
+
+    hres = ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &ret->name, NULL, NULL, NULL);
+    if(FAILED(hres)) {
+        WARN("ITypeInfo::GetDocumentation failed\n");
+        ret->name = NULL;
+    }
+
+    ret->fields = HeapAlloc(GetProcessHeap(), 0, ret->n_vars*sizeof(VARDESC));
+    for(i = 0; i<ret->n_vars; i++) {
+        VARDESC *vardesc;
+        hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc);
+        if(FAILED(hres)) {
+            WARN("GetVarDesc failed\n");
+            continue;
+        }
+        ret->fields[i].vt = vardesc->elemdescVar.tdesc.vt;
+        ret->fields[i].varkind = vardesc->varkind;
+        ret->fields[i].offset = vardesc->u.oInst;
+        hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name,
+                NULL, NULL, NULL);
+        if(FAILED(hres))
+            WARN("GetDocumentation failed: %08lx\n", hres);
+        ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
+    }
+        
+    *ppRecInfo = (IRecordInfo*)ret;
+
+    return S_OK;
+}
index ca56e7f..c237dab 100644 (file)
@@ -315,6 +315,9 @@ HRESULT WINAPI LoadTypeLibEx(
 \r
     TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);\r
 \r
+    /* by default try and load using LoadLibrary (for builtin stdole32.tlb) */\r
+    memcpy(szPath, szFile, (strlenW(szFile)+1)*sizeof(WCHAR));\r
+    \r
     *pptLib = NULL;\r
     if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,\r
                    NULL)) {\r
@@ -331,9 +334,6 @@ HRESULT WINAPI LoadTypeLibEx(
                return TYPE_E_CANTLOADLIBRARY;\r
            if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY)\r
                return TYPE_E_CANTLOADLIBRARY;\r
-       } else {\r
-           TRACE("Wanted to load %s as typelib, but file was not found.\n",debugstr_w(szFile));\r
-           return TYPE_E_CANTLOADLIBRARY;\r
        }\r
     }\r
 \r
@@ -848,9 +848,10 @@ typedef struct tagITypeLibImpl
                                   libary. Only used while read MSFT\r
                                   typelibs */\r
 \r
-    /* typelibs are cached, keyed by path, so store the linked list info within them */\r
+    /* typelibs are cached, keyed by path and index, so store the linked list info within them */\r
     struct tagITypeLibImpl *next, *prev;\r
     WCHAR *path;\r
+    INT index;\r
 } ITypeLibImpl;\r
 \r
 static struct ITypeLib2Vtbl tlbvt;\r
@@ -865,7 +866,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);
 \r
 /*======================= ITypeInfo implementation =======================*/\r
 \r
-/* data for refernced types */\r
+/* data for referenced types */\r
 typedef struct tagTLBRefType\r
 {\r
     INT index;              /* Type index for internal ref or for external ref\r
@@ -1497,7 +1498,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
 \r
     if(offset <0) { /* data are packed in here */\r
         V_VT(pVar) = (offset & 0x7c000000 )>> 26;\r
-        V_UNION(pVar, iVal) = offset & 0x3ffffff;\r
+        V_I2(pVar) = offset & 0x3ffffff;\r
         return;\r
     }\r
     MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,\r
@@ -1537,7 +1538,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
            } else {\r
                 ptr=TLB_Alloc(size);/* allocate temp buffer */\r
                MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */\r
-               V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);\r
+               V_BSTR(pVar)=SysAllocStringLen(NULL,size);\r
                /* FIXME: do we need a AtoW conversion here? */\r
                V_UNION(pVar, bstrVal[size])=L'\0';\r
                while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];\r
@@ -1570,7 +1571,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
     }\r
 \r
     if(size>0) /* (big|small) endian correct? */\r
-        MSFT_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );\r
+        MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );\r
     return;\r
 }\r
 /*\r
@@ -1924,7 +1925,7 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
         recoffset += reclength;\r
     }\r
 }\r
-/* fill in data for a hreftype (offset). When the refernced type is contained\r
+/* fill in data for a hreftype (offset). When the referenced type is contained\r
  * in the typelib, it's just an (file) offset in the type info base dir.\r
  * If comes from import, it's an offset+1 in the ImpInfo table\r
  * */\r
@@ -2169,7 +2170,7 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
     EnterCriticalSection(&cache_section);\r
     for (entry = tlb_cache_first; entry != NULL; entry = entry->next)\r
     {\r
-        if (!strcmpiW(entry->path, pszFileName))\r
+        if (!strcmpiW(entry->path, pszFileName) && entry->index == index)\r
         {\r
             TRACE("cache hit\n");\r
             *ppTypeLib = (ITypeLib2*)entry;\r
@@ -2209,8 +2210,13 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
       }\r
       CloseHandle(hFile);\r
     }\r
+    else\r
+    {\r
+      TRACE("not found, trying to load %s as library\n", debugstr_w(pszFileName));\r
+    }\r
 \r
-    if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )\r
+    /* if the file is a DLL or not found, try loading it with LoadLibrary */\r
+    if (((WORD)dwSignature == IMAGE_DOS_SIGNATURE) || (dwSignature == 0))\r
     {\r
       /* find the typelibrary resource*/\r
       HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|\r
@@ -2258,6 +2264,7 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
        impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszFileName)+1) * sizeof(WCHAR));\r
        lstrcpyW(impl->path, pszFileName);\r
        /* We should really canonicalise the path here. */\r
+        impl->index = index;\r
 \r
         /* FIXME: check if it has added already in the meantime */\r
         EnterCriticalSection(&cache_section);\r
@@ -3074,7 +3081,7 @@ static SLTG_TypeInfoTail *SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
   return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);\r
 }\r
 \r
-/* Because SLTG_OtherTypeInfo is such a painfull struct, we make a more\r
+/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more\r
    managable copy of it into this */\r
 typedef struct {\r
   WORD small_no;\r
@@ -4109,8 +4116,8 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
     TRACE("(%p)->(%lu)\n",This, ref);\r
 \r
     if (ref)   {\r
-      /* We don't release ITypeLib when ref=0 becouse\r
-         it means that funtion is called by ITypeLi2_Release */\r
+      /* We don't release ITypeLib when ref=0 because\r
+         it means that function is called by ITypeLib2_Release */\r
       ITypeLib2_Release((ITypeLib2*)This->pTypeLib);\r
     } else   {\r
       FIXME("destroy child objects\n");\r
@@ -4518,12 +4525,12 @@ _copy_arg(      ITypeInfo2 *tinfo, TYPEDESC *tdesc,
     }\r
 \r
     if (V_VT(arg) == vt) {\r
-       memcpy(argpos, &V_UNION(arg,lVal), arglen);\r
+       memcpy(argpos, &V_I4(arg), arglen);\r
        return S_OK;\r
     }\r
 \r
     if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) {\r
-       memcpy(argpos, &V_UNION(arg,parray), sizeof(SAFEARRAY*));\r
+       memcpy(argpos, &V_ARRAY(arg), sizeof(SAFEARRAY*));\r
        return S_OK;\r
     }\r
 \r
@@ -4533,13 +4540,13 @@ _copy_arg(      ITypeInfo2 *tinfo, TYPEDESC *tdesc,
     }\r
     /* Deref BYREF vars if there is need */\r
     if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==vt)) {\r
-        memcpy(argpos,(void*)V_UNION(arg,lVal), arglen);\r
+        memcpy(argpos,(void*)V_I4(arg), arglen);\r
        return S_OK;\r
     }\r
     if (vt==VT_UNKNOWN && V_VT(arg)==VT_DISPATCH) {\r
        /* in this context, if the type lib specifies IUnknown*, giving an\r
            IDispatch* is correct; so, don't invoke VariantChangeType */\r
-       memcpy(argpos,&V_UNION(arg,lVal), arglen);\r
+       memcpy(argpos,&V_I4(arg), arglen);\r
        return S_OK;\r
     }\r
     if ((vt == VT_PTR) && tdesc)\r
@@ -4555,7 +4562,7 @@ _copy_arg(        ITypeInfo2 *tinfo, TYPEDESC *tdesc,
            FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "\r
                   "while coercing from vt 0x%x. Copying 4 byte.\n",\r
                   tdesc->u.hreftype,V_VT(arg));\r
-           memcpy(argpos, &V_UNION(arg,lVal), 4);\r
+           memcpy(argpos, &V_I4(arg), 4);\r
            return S_OK;\r
        }\r
        hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);\r
@@ -4569,11 +4576,11 @@ _copy_arg(      ITypeInfo2 *tinfo, TYPEDESC *tdesc,
        case TKIND_ENUM:\r
           switch ( V_VT( arg ) ) {\r
           case VT_I2:\r
-             *argpos = V_UNION(arg,iVal);\r
+             *argpos = V_I2(arg);\r
              hres = S_OK;\r
              break;\r
           case VT_I4:\r
-             memcpy(argpos, &V_UNION(arg,lVal), 4);\r
+             memcpy(argpos, &V_I4(arg), 4);\r
              hres = S_OK;\r
              break;\r
           default:\r
@@ -4592,15 +4599,15 @@ _copy_arg(      ITypeInfo2 *tinfo, TYPEDESC *tdesc,
            if (V_VT(arg) == VT_DISPATCH) {\r
                IDispatch *disp;\r
                if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) {\r
-                   memcpy(argpos, &V_UNION(arg,pdispVal), 4);\r
+                   memcpy(argpos, &V_DISPATCH(arg), 4);\r
                    hres = S_OK;\r
                     break;\r
                }\r
-               hres=IUnknown_QueryInterface(V_UNION(arg,pdispVal),\r
+               hres=IUnknown_QueryInterface(V_DISPATCH(arg),\r
                                              &IID_IDispatch,(LPVOID*)&disp);\r
                if (SUCCEEDED(hres)) {\r
                    memcpy(argpos,&disp,4);\r
-                   IUnknown_Release(V_UNION(arg,pdispVal));\r
+                   IUnknown_Release(V_DISPATCH(arg));\r
                    hres = S_OK;\r
                     break;\r
                }\r
@@ -4610,7 +4617,7 @@ _copy_arg(        ITypeInfo2 *tinfo, TYPEDESC *tdesc,
                 break;\r
            }\r
            if (V_VT(arg) == VT_UNKNOWN) {\r
-               memcpy(argpos, &V_UNION(arg,punkVal), 4);\r
+               memcpy(argpos, &V_UNKNOWN(arg), 4);\r
                hres = S_OK;\r
                 break;\r
            }\r
@@ -4621,7 +4628,7 @@ _copy_arg(        ITypeInfo2 *tinfo, TYPEDESC *tdesc,
 \r
        case TKIND_DISPATCH:\r
            if (V_VT(arg) == VT_DISPATCH) {\r
-               memcpy(argpos, &V_UNION(arg,pdispVal), 4);\r
+               memcpy(argpos, &V_DISPATCH(arg), 4);\r
                hres = S_OK;\r
            }\r
             else {\r
@@ -4646,7 +4653,7 @@ _copy_arg(        ITypeInfo2 *tinfo, TYPEDESC *tdesc,
     oldvt = V_VT(arg);\r
     VariantInit(&va);\r
     if (VariantChangeType(&va,arg,0,vt)==S_OK) {\r
-       memcpy(argpos,&V_UNION(&va,lVal), arglen);\r
+       memcpy(argpos,&V_I4(&va), arglen);\r
        FIXME("Should not use VariantChangeType here."\r
               " (conversion from 0x%x -> 0x%x) %08lx\n",\r
                V_VT(arg), vt, *argpos\r
@@ -4768,7 +4775,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                         if(i < func_desc->cParams - func_desc->cParamsOpt)\r
                             ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");\r
                         if(V_VT(arg) == VT_EMPTY\r
-                          || ((V_VT(arg) & VT_BYREF) && !V_BYREF(arg))) {\r
+                          || ((V_ISBYREF(arg)) && !V_BYREF(arg))) {\r
                                /* FIXME: Documentation says that we do this when parameter is left unspecified.\r
                                          How to determine it? */\r
 \r
@@ -4834,7 +4841,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                        continue;\r
 \r
                    VariantInit(pVarResult);\r
-                   memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD));\r
+                   memcpy(&V_INT(pVarResult),&args2[args2pos],arglen*sizeof(DWORD));\r
 \r
                    if (tdesc->vt == VT_PTR)\r
                        tdesc = tdesc->u.lptdesc;\r
index 0c13afe..aba0b6a 100644 (file)
@@ -140,7 +140,7 @@ typedef struct tagMSFT_ImpFile {
     int guid;\r
     LCID lcid;\r
     int version;\r
-    char filename[0]; /* preceeded by two bytes of encoded (length << 2) + flags in the low two bits. */\r
+    char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */\r
 } MSFT_ImpFile;\r
 \r
 typedef struct tagICreateTypeLib2Impl\r
@@ -2055,7 +2055,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
 static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData(\r
         ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */\r
         UINT indexFunc,          /* [I] The index of the function on which the parameter resides. */\r
-        UINT indexParam,         /* [I] The index of the paramter on which to set the custom data. */\r
+        UINT indexParam,         /* [I] The index of the parameter on which to set the custom data. */\r
         REFGUID guid,            /* [I] The GUID used as a key to retrieve the custom data. */\r
         VARIANT* pVarVal)        /* [I] The custom data. */\r
 {\r
index 10c2a3e..6eb8733 100644 (file)
@@ -190,7 +190,7 @@ static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
   ULONG size;\r
   HRESULT hr;\r
 \r
-  if (V_VT(pvar) & VT_ARRAY) {\r
+  if (V_ISARRAY(pvar)) {\r
     FIXME("wire-size safearray\n");\r
     return 0;\r
   }\r
@@ -527,7 +527,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
   /* count by-ref args */\r
   for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {\r
     VARIANTARG* arg = &pDispParams->rgvarg[u];\r
-    if (V_VT(arg) & VT_BYREF) {\r
+    if (V_ISBYREF(arg)) {\r
       cVarRef++;\r
     }\r
   }\r
@@ -537,7 +537,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
     /* make list of by-ref args */\r
     for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {\r
       VARIANTARG* arg = &pDispParams->rgvarg[u];\r
-      if (V_VT(arg) & VT_BYREF) {\r
+      if (V_ISBYREF(arg)) {\r
        rgVarRefIdx[cVarRef] = u;\r
        VariantInit(&rgVarRef[cVarRef]);\r
        cVarRef++;\r
index ba91af1..ef2c06e 100644 (file)
@@ -94,7 +94,7 @@ static const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' };
  *  characters. Literal characters are copied unmodified to the formatted\r
  *  output at the position they occupy in the format string. Any character\r
  *  that is not recognised as a token is treated as a literal. A literal can\r
- *  also be specified by preceeding it with a backslash character\r
+ *  also be specified by preceding it with a backslash character\r
  *  (e.g. "\L\i\t\e\r\a\l") or enclosing it in double quotes.\r
  *\r
  *  A user-defined format can have up to 4 sections, depending on the type of\r
@@ -885,7 +885,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
         TRACE("h\n");\r
       }\r
       fmt_state &= ~FMT_STATE_OPEN_COPY;\r
-      /* Note that now we have seen an hours token, the next occurence of\r
+      /* Note that now we have seen an hours token, the next occurrence of\r
        * 'mm' indicates minutes, not months.\r
        */\r
       fmt_state |= FMT_STATE_SEEN_HOURS;\r
index 0aa8bfc..43855ae 100644 (file)
@@ -984,7 +984,7 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
       {\r
         VARIANTARG vTmp, vSrcDeref;\r
 \r
-        if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc))\r
+        if(V_ISBYREF(pvargSrc) && !V_BYREF(pvargSrc))\r
           res = DISP_E_TYPEMISMATCH;\r
         else\r
         {\r
@@ -2531,7 +2531,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     }\r
 \r
     xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));\r
-    if (xmask & (1<<VT_R8)) {\r
+    if (xmask & VTBIT_R8) {\r
        rc = VariantChangeType(&lv,left,0,VT_R8);\r
        if (FAILED(rc)) return rc;\r
        rc = VariantChangeType(&rv,right,0,VT_R8);\r
@@ -2542,7 +2542,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
        if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;\r
        return E_FAIL; /* can't get here */\r
     }\r
-    if (xmask & (1<<VT_R4)) {\r
+    if (xmask & VTBIT_R4) {\r
        rc = VariantChangeType(&lv,left,0,VT_R4);\r
        if (FAILED(rc)) return rc;\r
        rc = VariantChangeType(&rv,right,0,VT_R4);\r
@@ -2558,29 +2558,29 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
            Use LONGLONG to maximize ranges                              */\r
     lOk = TRUE;\r
     switch (V_VT(left)&VT_TYPEMASK) {\r
-    case VT_I1   : lVal = V_UNION(left,cVal); break;\r
-    case VT_I2   : lVal = V_UNION(left,iVal); break;\r
-    case VT_I4   : lVal = V_UNION(left,lVal); break;\r
-    case VT_INT  : lVal = V_UNION(left,lVal); break;\r
-    case VT_UI1  : lVal = V_UNION(left,bVal); break;\r
-    case VT_UI2  : lVal = V_UNION(left,uiVal); break;\r
-    case VT_UI4  : lVal = V_UNION(left,ulVal); break;\r
-    case VT_UINT : lVal = V_UNION(left,ulVal); break;\r
-    case VT_BOOL : lVal = V_UNION(left,boolVal); break;\r
+    case VT_I1   : lVal = V_I1(left); break;\r
+    case VT_I2   : lVal = V_I2(left); break;\r
+    case VT_I4   :\r
+    case VT_INT  : lVal = V_I4(left); break;\r
+    case VT_UI1  : lVal = V_UI1(left); break;\r
+    case VT_UI2  : lVal = V_UI2(left); break;\r
+    case VT_UI4  :\r
+    case VT_UINT : lVal = V_UI4(left); break;\r
+    case VT_BOOL : lVal = V_BOOL(left); break;\r
     default: lOk = FALSE;\r
     }\r
 \r
     rOk = TRUE;\r
     switch (V_VT(right)&VT_TYPEMASK) {\r
-    case VT_I1   : rVal = V_UNION(right,cVal); break;\r
-    case VT_I2   : rVal = V_UNION(right,iVal); break;\r
-    case VT_I4   : rVal = V_UNION(right,lVal); break;\r
-    case VT_INT  : rVal = V_UNION(right,lVal); break;\r
-    case VT_UI1  : rVal = V_UNION(right,bVal); break;\r
-    case VT_UI2  : rVal = V_UNION(right,uiVal); break;\r
-    case VT_UI4  : rVal = V_UNION(right,ulVal); break;\r
-    case VT_UINT : rVal = V_UNION(right,ulVal); break;\r
-    case VT_BOOL : rVal = V_UNION(right,boolVal); break;\r
+    case VT_I1   : rVal = V_I1(right); break;\r
+    case VT_I2   : rVal = V_I2(right); break;\r
+    case VT_I4   :\r
+    case VT_INT  : rVal = V_I4(right); break;\r
+    case VT_UI1  : rVal = V_UI1(right); break;\r
+    case VT_UI2  : rVal = V_UI2(right); break;\r
+    case VT_UI4  :\r
+    case VT_UINT : rVal = V_UI4(right); break;\r
+    case VT_BOOL : rVal = V_BOOL(right); break;\r
     default: rOk = FALSE;\r
     }\r
 \r
@@ -2598,20 +2598,20 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&\r
         (V_VT(right)&VT_TYPEMASK) == VT_DATE) {\r
 \r
-        if (floor(V_UNION(left,date)) == floor(V_UNION(right,date))) {\r
+        if (floor(V_DATE(left)) == floor(V_DATE(right))) {\r
             /* Due to floating point rounding errors, calculate varDate in whole numbers) */\r
             double wholePart = 0.0;\r
             double leftR;\r
             double rightR;\r
 \r
             /* Get the fraction * 24*60*60 to make it into whole seconds */\r
-            wholePart = (double) floor( V_UNION(left,date) );\r
+            wholePart = (double) floor( V_DATE(left) );\r
             if (wholePart == 0) wholePart = 1;\r
-            leftR = floor(fmod( V_UNION(left,date), wholePart ) * (24*60*60));\r
+            leftR = floor(fmod( V_DATE(left), wholePart ) * (24*60*60));\r
 \r
-            wholePart = (double) floor( V_UNION(right,date) );\r
+            wholePart = (double) floor( V_DATE(right) );\r
             if (wholePart == 0) wholePart = 1;\r
-            rightR = floor(fmod( V_UNION(right,date), wholePart ) * (24*60*60));\r
+            rightR = floor(fmod( V_DATE(right), wholePart ) * (24*60*60));\r
 \r
             if (leftR < rightR) {\r
                 return VARCMP_LT;\r
@@ -2621,9 +2621,9 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
                 return VARCMP_EQ;\r
             }\r
 \r
-        } else if (V_UNION(left,date) < V_UNION(right,date)) {\r
+        } else if (V_DATE(left) < V_DATE(right)) {\r
             return VARCMP_LT;\r
-        } else if (V_UNION(left,date) > V_UNION(right,date)) {\r
+        } else if (V_DATE(left) > V_DATE(right)) {\r
             return VARCMP_GT;\r
         }\r
     }\r
@@ -2665,29 +2665,29 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 \r
         lOk = TRUE;\r
         switch (V_VT(left)&VT_TYPEMASK) {\r
-        case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;\r
-        case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;\r
-        case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;\r
-        case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;\r
-        case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;\r
-        case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;\r
-        case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;\r
-        case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;\r
-        case VT_BOOL : rVal = V_UNION(left,boolVal); resT=VT_I4; break;\r
+        case VT_I1   : lVal = V_I1(left);  resT=VT_I4; break;\r
+        case VT_I2   : lVal = V_I2(left);  resT=VT_I2; break;\r
+        case VT_I4   :\r
+        case VT_INT  : lVal = V_I4(left);  resT=VT_I4; break;\r
+        case VT_UI1  : lVal = V_UI1(left);  resT=VT_I4; break;\r
+        case VT_UI2  : lVal = V_UI2(left); resT=VT_I4; break;\r
+        case VT_UI4  :\r
+        case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;\r
+        case VT_BOOL : rVal = V_BOOL(left); resT=VT_I4; break;\r
         default: lOk = FALSE;\r
         }\r
 \r
         rOk = TRUE;\r
         switch (V_VT(right)&VT_TYPEMASK) {\r
-        case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;\r
-        case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;\r
-        case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;\r
-        case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;\r
-        case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;\r
-        case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;\r
-        case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;\r
-        case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;\r
-        case VT_BOOL : rVal = V_UNION(right,boolVal); resT=VT_I4; break;\r
+        case VT_I1   : rVal = V_I1(right);  resT=VT_I4; break;\r
+        case VT_I2   : rVal = V_I2(right);  resT=max(VT_I2, resT); break;\r
+        case VT_I4   :\r
+        case VT_INT  : rVal = V_I4(right);  resT=VT_I4; break;\r
+        case VT_UI1  : rVal = V_UI1(right);  resT=VT_I4; break;\r
+        case VT_UI2  : rVal = V_UI2(right); resT=VT_I4; break;\r
+        case VT_UI4  :\r
+        case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;\r
+        case VT_BOOL : rVal = V_BOOL(right); resT=VT_I4; break;\r
         default: rOk = FALSE;\r
         }\r
 \r
@@ -2695,11 +2695,11 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
             res = (lVal & rVal);\r
             V_VT(result) = resT;\r
             switch (resT) {\r
-            case VT_I2   : V_UNION(result,iVal)  = res; break;\r
-            case VT_I4   : V_UNION(result,lVal)  = res; break;\r
+            case VT_I2   : V_I2(result)  = res; break;\r
+            case VT_I4   : V_I4(result)  = res; break;\r
             default:\r
                 FIXME("Unexpected result variant type %x\n", resT);\r
-                V_UNION(result,lVal)  = res;\r
+                V_I4(result)  = res;\r
             }\r
             rc = S_OK;\r
 \r
@@ -2747,32 +2747,32 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 \r
         lOk = TRUE;\r
         switch (V_VT(left)&VT_TYPEMASK) {\r
-        case VT_I1   : lVal = V_UNION(left,cVal);   break;\r
-        case VT_I2   : lVal = V_UNION(left,iVal);   break;\r
-        case VT_I4   : lVal = V_UNION(left,lVal);   break;\r
-        case VT_INT  : lVal = V_UNION(left,lVal);   break;\r
-        case VT_UI1  : lVal = V_UNION(left,bVal);   break;\r
-        case VT_UI2  : lVal = V_UNION(left,uiVal);  break;\r
-        case VT_UI4  : lVal = V_UNION(left,ulVal);  break;\r
-        case VT_UINT : lVal = V_UNION(left,ulVal);  break;\r
-        case VT_R4   : lVal = V_UNION(left,fltVal);  break;\r
-        case VT_R8   : lVal = V_UNION(left,dblVal);  break;\r
+        case VT_I1   : lVal = V_I1(left);   break;\r
+        case VT_I2   : lVal = V_I2(left);   break;\r
+        case VT_I4   :\r
+        case VT_INT  : lVal = V_I4(left);   break;\r
+        case VT_UI1  : lVal = V_UI1(left);   break;\r
+        case VT_UI2  : lVal = V_UI2(left);  break;\r
+        case VT_UI4  :\r
+        case VT_UINT : lVal = V_UI4(left);  break;\r
+        case VT_R4   : lVal = V_R4(left);  break;\r
+        case VT_R8   : lVal = V_R8(left);  break;\r
        case VT_NULL : lVal = 0.0;  break;\r
         default: lOk = FALSE;\r
         }\r
 \r
         rOk = TRUE;\r
         switch (V_VT(right)&VT_TYPEMASK) {\r
-        case VT_I1   : rVal = V_UNION(right,cVal);  break;\r
-        case VT_I2   : rVal = V_UNION(right,iVal);  break;\r
-        case VT_I4   : rVal = V_UNION(right,lVal);  break;\r
-        case VT_INT  : rVal = V_UNION(right,lVal);  break;\r
-        case VT_UI1  : rVal = V_UNION(right,bVal);  break;\r
-        case VT_UI2  : rVal = V_UNION(right,uiVal); break;\r
-        case VT_UI4  : rVal = V_UNION(right,ulVal); break;\r
-        case VT_UINT : rVal = V_UNION(right,ulVal); break;\r
-        case VT_R4   : rVal = V_UNION(right,fltVal);break;\r
-        case VT_R8   : rVal = V_UNION(right,dblVal);break;\r
+        case VT_I1   : rVal = V_I1(right);  break;\r
+        case VT_I2   : rVal = V_I2(right);  break;\r
+        case VT_I4   :\r
+        case VT_INT  : rVal = V_I4(right);  break;\r
+        case VT_UI1  : rVal = V_UI1(right);  break;\r
+        case VT_UI2  : rVal = V_UI2(right); break;\r
+        case VT_UI4  :\r
+        case VT_UINT : rVal = V_UI4(right); break;\r
+        case VT_R4   : rVal = V_R4(right);break;\r
+        case VT_R8   : rVal = V_R8(right);break;\r
        case VT_NULL : rVal = 0.0; break;\r
         default: rOk = FALSE;\r
         }\r
@@ -2780,7 +2780,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
         if (lOk && rOk) {\r
             res = (lVal + rVal);\r
             V_VT(result) = VT_R8;\r
-            V_UNION(result,dblVal)  = res;\r
+            V_R8(result)  = res;\r
             rc = S_OK;\r
         } else {\r
            FIXME("Unhandled type pair %d / %d in double addition.\n",\r
@@ -2801,30 +2801,30 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 \r
         lOk = TRUE;\r
         switch (V_VT(left)&VT_TYPEMASK) {\r
-        case VT_I1   : lVal = V_UNION(left,cVal);   break;\r
-        case VT_I2   : lVal = V_UNION(left,iVal);   break;\r
-        case VT_I4   : lVal = V_UNION(left,lVal);   break;\r
-        case VT_INT  : lVal = V_UNION(left,lVal);   break;\r
-        case VT_UI1  : lVal = V_UNION(left,bVal);   break;\r
-        case VT_UI2  : lVal = V_UNION(left,uiVal);  break;\r
-        case VT_UI4  : lVal = V_UNION(left,ulVal);  break;\r
-        case VT_UINT : lVal = V_UNION(left,ulVal);  break;\r
-        case VT_R4   : lVal = V_UNION(left,fltVal);  break;\r
+        case VT_I1   : lVal = V_I1(left);   break;\r
+        case VT_I2   : lVal = V_I2(left);   break;\r
+        case VT_I4   :\r
+        case VT_INT  : lVal = V_I4(left);   break;\r
+        case VT_UI1  : lVal = V_UI1(left);   break;\r
+        case VT_UI2  : lVal = V_UI2(left);  break;\r
+        case VT_UI4  :\r
+        case VT_UINT : lVal = V_UI4(left);  break;\r
+        case VT_R4   : lVal = V_R4(left);  break;\r
        case VT_NULL : lVal = 0.0;  break;\r
         default: lOk = FALSE;\r
         }\r
 \r
         rOk = TRUE;\r
         switch (V_VT(right)&VT_TYPEMASK) {\r
-        case VT_I1   : rVal = V_UNION(right,cVal);  break;\r
-        case VT_I2   : rVal = V_UNION(right,iVal);  break;\r
-        case VT_I4   : rVal = V_UNION(right,lVal);  break;\r
-        case VT_INT  : rVal = V_UNION(right,lVal);  break;\r
-        case VT_UI1  : rVal = V_UNION(right,bVal);  break;\r
-        case VT_UI2  : rVal = V_UNION(right,uiVal); break;\r
-        case VT_UI4  : rVal = V_UNION(right,ulVal); break;\r
-        case VT_UINT : rVal = V_UNION(right,ulVal); break;\r
-        case VT_R4   : rVal = V_UNION(right,fltVal);break;\r
+        case VT_I1   : rVal = V_I1(right);  break;\r
+        case VT_I2   : rVal = V_I2(right);  break;\r
+        case VT_I4   :\r
+        case VT_INT  : rVal = V_I4(right);  break;\r
+        case VT_UI1  : rVal = V_UI1(right);  break;\r
+        case VT_UI2  : rVal = V_UI2(right); break;\r
+        case VT_UI4  :\r
+        case VT_UINT : rVal = V_UI4(right); break;\r
+        case VT_R4   : rVal = V_R4(right);break;\r
        case VT_NULL : rVal = 0.0; break;\r
         default: rOk = FALSE;\r
         }\r
@@ -2832,7 +2832,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
         if (lOk && rOk) {\r
             res = (lVal + rVal);\r
             V_VT(result) = VT_R4;\r
-            V_UNION(result,fltVal)  = res;\r
+            V_R4(result)  = res;\r
             rc = S_OK;\r
         } else {\r
            FIXME("Unhandled type pair %d / %d in float addition.\n",\r
@@ -2861,28 +2861,28 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 \r
         lOk = TRUE;\r
         switch (V_VT(left)&VT_TYPEMASK) {\r
-        case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;\r
-        case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;\r
-        case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;\r
-        case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;\r
-        case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;\r
-        case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;\r
-        case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;\r
-        case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;\r
+        case VT_I1   : lVal = V_I1(left);  resT=VT_I4; break;\r
+        case VT_I2   : lVal = V_I2(left);  resT=VT_I2; break;\r
+        case VT_I4   :\r
+        case VT_INT  : lVal = V_I4(left);  resT=VT_I4; break;\r
+        case VT_UI1  : lVal = V_UI1(left);  resT=VT_I4; break;\r
+        case VT_UI2  : lVal = V_UI2(left); resT=VT_I4; break;\r
+        case VT_UI4  :\r
+        case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;\r
        case VT_NULL : lVal = 0; resT = VT_I4; break;\r
         default: lOk = FALSE;\r
         }\r
 \r
         rOk = TRUE;\r
         switch (V_VT(right)&VT_TYPEMASK) {\r
-        case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;\r
-        case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;\r
-        case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;\r
-        case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;\r
-        case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;\r
-        case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;\r
-        case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;\r
-        case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;\r
+        case VT_I1   : rVal = V_I1(right);  resT=VT_I4; break;\r
+        case VT_I2   : rVal = V_I2(right);  resT=max(VT_I2, resT); break;\r
+        case VT_I4   :\r
+        case VT_INT  : rVal = V_I4(right);  resT=VT_I4; break;\r
+        case VT_UI1  : rVal = V_UI1(right);  resT=VT_I4; break;\r
+        case VT_UI2  : rVal = V_UI2(right); resT=VT_I4; break;\r
+        case VT_UI4  :\r
+        case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;\r
        case VT_NULL : rVal = 0; resT=VT_I4; break;\r
         default: rOk = FALSE;\r
         }\r
@@ -2891,11 +2891,11 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
             res = (lVal + rVal);\r
             V_VT(result) = resT;\r
             switch (resT) {\r
-            case VT_I2   : V_UNION(result,iVal)  = res; break;\r
-            case VT_I4   : V_UNION(result,lVal)  = res; break;\r
+            case VT_I2   : V_I2(result)  = res; break;\r
+            case VT_I4   : V_I4(result)  = res; break;\r
             default:\r
                 FIXME("Unexpected result variant type %x\n", resT);\r
-                V_UNION(result,lVal)  = res;\r
+                V_I4(result)  = res;\r
             }\r
             rc = S_OK;\r
 \r
@@ -2927,11 +2927,11 @@ HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     lvt = V_VT(left)&VT_TYPEMASK;\r
     rvt = V_VT(right)&VT_TYPEMASK;\r
     found = FALSE;resvt=VT_VOID;\r
-    if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {\r
+    if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {\r
        found = TRUE;\r
        resvt = VT_R8;\r
     }\r
-    if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {\r
+    if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {\r
        found = TRUE;\r
        resvt = VT_I4;\r
     }\r
@@ -2984,11 +2984,11 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     lvt = V_VT(left)&VT_TYPEMASK;\r
     rvt = V_VT(right)&VT_TYPEMASK;\r
     found = FALSE;resvt = VT_VOID;\r
-    if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {\r
+    if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {\r
        found = TRUE;\r
        resvt = VT_R8;\r
     }\r
-    if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {\r
+    if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {\r
        found = TRUE;\r
        resvt = VT_I4;\r
     }\r
@@ -3045,7 +3045,7 @@ HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
        found = TRUE;\r
        resvt = VT_R8;\r
     }\r
-    if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {\r
+    if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {\r
        found = TRUE;\r
        resvt = VT_I4;\r
     }\r
index 37f0161..0138f33 100644 (file)
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 UIINSERTOBJECT DIALOG DISCARDABLE  0, 0, 294, 151\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
index b8e1ce4..ed84aeb 100644 (file)
@@ -1,59 +1,59 @@
-/*
- * oledlg dll resources
- * French language support
- *
- * Copyright (C) 2005 Jonathan Ernst
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
-
-UIINSERTOBJECT DIALOG DISCARDABLE  0, 0, 294, 151
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Insérer Objet"
-FONT 8, "MS Shell Dlg"
-BEGIN
-    LISTBOX         IDC_OBJTYPELIST,82,19,131,66,LBS_SORT |
-                    LBS_NOINTEGRALHEIGHT | WS_VISIBLE | WS_VSCROLL |
-                    WS_TABSTOP
-    LTEXT           "Type d'objet:",IDC_OBJTYPELBL,82,7,53,8,WS_VISIBLE
-    DEFPUSHBUTTON   "OK",IDOK,221,7,66,14
-    PUSHBUTTON      "Annuler",IDCANCEL,221,24,66,14
-    GROUPBOX        "Résultat",IDC_RESULT,7,103,208,41
-    CONTROL         "Créer Nouveau",IDC_CREATENEW,"Button",BS_AUTORADIOBUTTON | 
-                    WS_GROUP,7,20,62,10
-    CONTROL         "Créer Contrôle",IDC_CREATECONTROL,"Button",
-                    BS_AUTORADIOBUTTON | NOT WS_VISIBLE,7,54,62,10
-    CONTROL         "Créer Depuis Fichier",IDC_CREATEFROMFILE,"Button",
-                    BS_AUTORADIOBUTTON,7,37,67,10
-    LTEXT           "",IDC_RESULTDESC,49,112,159,23
-    PUSHBUTTON      "&Ajoute Contrôle...",IDC_ADDCONTROL,81,88,63,14,NOT WS_VISIBLE
-    CONTROL         "Afficher Comme Icône",IDC_ASICON,"Button",BS_AUTOCHECKBOX | 
-                    WS_TABSTOP | NOT WS_VISIBLE,223,58,64,10
-    PUSHBUTTON      "Parcourir...",IDC_BROWSE,83,53,50,14,NOT WS_VISIBLE
-    LTEXT           "Fichier:",IDC_FILELBL,83,27,20,8, NOT WS_VISIBLE
-    EDITTEXT        IDC_FILE,83,37,132,13,ES_AUTOHSCROLL | NOT WS_VISIBLE
-END
-
-STRINGTABLE DISCARDABLE
-{
-  IDS_RESULTOBJDESC    "Insérer un nouvel object %s dans votre document"
-  IDS_RESULTFILEOBJDESC        "Insère le contenu du fichier comme un objet dans votre document afin que vous puissiez l'activer en utilisant le programme avec lequel vous l'avez créé."
-  IDS_BROWSE            "Parcourir"
-  IDS_NOTOLEMOD         "Le fichier ne semble pas être un module OLE valide. Impossible d'enregistrer le contrôle OLE."
-  IDS_NOTOLEMODCAPTION  "Ajouter Contrôle"
-}
+/*\r
+ * oledlg dll resources\r
+ * French language support\r
+ *\r
+ * Copyright (C) 2005 Jonathan Ernst\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+\r
+LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT\r
+\r
+UIINSERTOBJECT DIALOG DISCARDABLE  0, 0, 294, 151\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Insérer Objet"\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+    LISTBOX         IDC_OBJTYPELIST,82,19,131,66,LBS_SORT |\r
+                    LBS_NOINTEGRALHEIGHT | WS_VISIBLE | WS_VSCROLL |\r
+                    WS_TABSTOP\r
+    LTEXT           "Type d'objet:",IDC_OBJTYPELBL,82,7,53,8,WS_VISIBLE\r
+    DEFPUSHBUTTON   "OK",IDOK,221,7,66,14\r
+    PUSHBUTTON      "Annuler",IDCANCEL,221,24,66,14\r
+    GROUPBOX        "Résultat",IDC_RESULT,7,103,208,41\r
+    CONTROL         "Créer Nouveau",IDC_CREATENEW,"Button",BS_AUTORADIOBUTTON | \r
+                    WS_GROUP,7,20,62,10\r
+    CONTROL         "Créer Contrôle",IDC_CREATECONTROL,"Button",\r
+                    BS_AUTORADIOBUTTON | NOT WS_VISIBLE,7,54,62,10\r
+    CONTROL         "Créer Depuis Fichier",IDC_CREATEFROMFILE,"Button",\r
+                    BS_AUTORADIOBUTTON,7,37,67,10\r
+    LTEXT           "",IDC_RESULTDESC,49,112,159,23\r
+    PUSHBUTTON      "&Ajoute Contrôle...",IDC_ADDCONTROL,81,88,63,14,NOT WS_VISIBLE\r
+    CONTROL         "Afficher Comme Icône",IDC_ASICON,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP | NOT WS_VISIBLE,223,58,64,10\r
+    PUSHBUTTON      "Parcourir...",IDC_BROWSE,83,53,50,14,NOT WS_VISIBLE\r
+    LTEXT           "Fichier:",IDC_FILELBL,83,27,20,8, NOT WS_VISIBLE\r
+    EDITTEXT        IDC_FILE,83,37,132,13,ES_AUTOHSCROLL | NOT WS_VISIBLE\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+  IDS_RESULTOBJDESC    "Insérer un nouvel object %s dans votre document"\r
+  IDS_RESULTFILEOBJDESC        "Insère le contenu du fichier comme un objet dans votre document afin que vous puissiez l'activer en utilisant le programme avec lequel vous l'avez créé."\r
+  IDS_BROWSE            "Parcourir"\r
+  IDS_NOTOLEMOD         "Le fichier ne semble pas être un module OLE valide. Impossible d'enregistrer le contrôle OLE."\r
+  IDS_NOTOLEMODCAPTION  "Ajouter Contrôle"\r
+}\r
index bf0eeea..5544321 100644 (file)
@@ -11,7 +11,7 @@ TARGET_SDKLIBS = pseh.a epsapi.a ntdll.a kernel32.a
 TARGET_CFLAGS = -I./include -Wall -Werror
 
 # require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS -D_SEH_NO_NATIVE_NLG
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D_SEH_NO_NATIVE_NLG -D__USE_W32API
 
 TARGET_LFLAGS = -nostartfiles -nostdlib
 
index 34b79d1..ff2464c 100644 (file)
@@ -282,7 +282,7 @@ InternalGetMappedFileName(BOOLEAN bUnicode,
   }
 
   /* allocate the memory */
-  pmsnName = PsaiMalloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer));
+  pmsnName = PsaiMalloc(nBufSize + sizeof(MEMORY_SECTION_NAME));
 
   if(pmsnName == NULL)
   {
@@ -315,7 +315,7 @@ InternalGetMappedFileName(BOOLEAN bUnicode,
    if(bUnicode)
    {
      /* destination is an Unicode string: direct copy */
-     memcpy((LPWSTR)lpName, pmsnName->NameBuffer, pmsnName->SectionFileName.Length);
+     memcpy((LPWSTR)lpName, pmsnName + 1, pmsnName->SectionFileName.Length);
 
      PsaiFree(pmsnName);
 
index 5e62992..81a2cfe 100644 (file)
@@ -3,6 +3,7 @@
        <include base="psapi">.</include>\r
        <include base="psapi">include</include>\r
        <define name="_DISABLE_TIDENTS" />\r
+       <define name="__USE_W32API" />\r
        <library>epsapi</library>\r
        <library>pseh</library>\r
        <library>ntdll</library>\r
diff --git a/reactos/lib/riched20/riched20.xml b/reactos/lib/riched20/riched20.xml
new file mode 100644 (file)
index 0000000..cfc5135
--- /dev/null
@@ -0,0 +1,33 @@
+<module name="riched20" type="win32dll" baseaddress="${BASEADDRESS_RICHED20}">
+       <importlibrary definition="riched20.spec.def" />
+       <include base="riched20">.</include>
+       <include base="ReactOS">include/wine</include>
+       <define name="UNICODE" />
+       <define name="_UNICODE" />
+       <define name="__REACTOS__" />
+       <define name="__USE_W32API" />
+       <define name="_WIN32_IE">0x600</define>
+       <define name="_WIN32_WINNT">0x501</define>
+       <define name="WINVER">0x501</define>
+       <library>uuid</library>
+       <library>wine</library>
+       <library>ntdll</library>
+       <library>kernel32</library>
+       <library>user32</library>
+       <library>gdi32</library>
+       <file>caret.c</file>
+       <file>context.c</file>
+       <file>editor.c</file>
+       <file>list.c</file>
+       <file>paint.c</file>
+       <file>para.c</file>
+       <file>reader.c</file>
+       <file>richole.c</file>
+       <file>row.c</file>
+       <file>run.c</file>
+       <file>string.c</file>
+       <file>style.c</file>
+       <file>undo.c</file>
+       <file>wrap.c</file>
+       <file>riched20.spec</file>
+</module>
index acd29fd..d8d709e 100644 (file)
@@ -3,11 +3,9 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@\r
 VPATH     = @srcdir@\r
 MODULE    = riched32.dll\r
-IMPORTS   = user32 kernel32\r
+IMPORTS   = riched20 user32 kernel32\r
 \r
 C_SRCS = \\r
-       reader.c \\r
-       text-writer.c \\r
        richedit.c\r
 \r
 @MAKE_DLL_RULES@\r
index 69a875a..6500a26 100644 (file)
@@ -13,8 +13,7 @@
        <library>ntdll</library>\r
        <library>kernel32</library>\r
        <library>user32</library>\r
-       <file>reader.c</file>\r
+       <library>riched20</library>\r
        <file>richedit.c</file>\r
-       <file>text-writer.c</file>\r
        <file>riched32.spec</file>\r
 </module>\r
index 648c7be..e0d5616 100644 (file)
@@ -1,11 +1,10 @@
 /*\r
  * RichEdit32  functions\r
  *\r
- * This module is a simple wrapper for the edit controls.\r
- * At the point, it is good only for application who use the RICHEDIT\r
- * control to display RTF text.\r
+ * This module is a simple wrapper for the RichEdit 2.0 control\r
  *\r
  * Copyright 2000 by Jean-Claude Batista\r
+ * Copyright 2005 Mike McCormack\r
  *\r
  * This library is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU Lesser General Public\r
 #include "wingdi.h"\r
 #include "winreg.h"\r
 #include "winerror.h"\r
-#include "riched32.h"\r
+#include "winuser.h"\r
 #include "richedit.h"\r
-#define NO_SHLWAPI_STREAM\r
 #include "shlwapi.h"\r
 \r
-#include "rtf.h"\r
-#include "rtf2text.h"\r
 #include "wine/debug.h"\r
 \r
-#define ID_EDIT      1\r
-\r
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);\r
 \r
-HANDLE RICHED32_hHeap = NULL;\r
-/* LPSTR  RICHED32_aSubclass = NULL; */\r
-static WNDPROC lpfnEditWndProc = NULL;\r
-static INT RTFInfoOffset = 0;\r
-\r
-#define TRACE_EDIT_MSG32(str) \\r
-        TRACE(\\r
-                     "32 bit : " str ": hwnd=%p, wParam=%08x, lParam=%08x\n"\\r
-                     , \\r
-                     hwnd, (UINT)wParam, (UINT)lParam)\r
+/* Window procedure of the RichEdit 1.0 control in riched20.dll */\r
+extern LRESULT WINAPI RichEdit10ANSIWndProc(HWND, UINT, WPARAM, LPARAM);\r
 \r
-LPVOID* WINAPI CreateIRichEditOle();\r
-VOID RICHEDIT_InitEditControlInfo(void);\r
-\r
-/***********************************************************************\r
- * DllMain [Internal] Initializes the internal 'RICHED32.DLL'.\r
- *\r
- * PARAMS\r
- *     hinstDLL    [I] handle to the DLL's instance\r
- *     fdwReason   [I]\r
- *     lpvReserved [I] reserved, must be NULL\r
- *\r
- * RETURNS\r
- *     Success: TRUE\r
- *     Failure: FALSE\r
- */\r
-\r
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
-{\r
-    TRACE("\n");\r
-    switch (fdwReason)\r
-    {\r
-    case DLL_PROCESS_ATTACH:\r
-        DisableThreadLibraryCalls(hinstDLL);\r
-        /* create private heap */\r
-        RICHED32_hHeap = HeapCreate (0, 0x10000, 0);\r
-        /* Retrieve edit control class info */\r
-        RICHEDIT_InitEditControlInfo();\r
-        /* register the Rich Edit class */\r
-        RICHED32_Register ();\r
-        break;\r
-\r
-    case DLL_PROCESS_DETACH:\r
-        /* unregister all common control classes */\r
-        RICHED32_Unregister ();\r
-        HeapDestroy (RICHED32_hHeap);\r
-        RICHED32_hHeap = NULL;\r
-        break;\r
-    }\r
-    return TRUE;\r
-}\r
-\r
-/* Support routines for window procedure */\r
-   INT RICHEDIT_GetTextRange(HWND hwnd,TEXTRANGEA *tr);\r
-   INT RICHEDIT_GetSelText(HWND hwnd,LPSTR lpstrBuffer);\r
-\r
-typedef struct _RTFControl_info\r
-{\r
-    HWND hwndParent;\r
-    char* rtfBuffer;\r
-    RTF_Info *parser;\r
-} RTFControl_Info;\r
-\r
-/*\r
- *\r
- * DESCRIPTION:\r
- * Window procedure of the RichEdit control.\r
- *\r
- */\r
-static LRESULT WINAPI RICHED32_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,\r
-                                   LPARAM lParam)\r
-{\r
-    LONG newstyle = 0;\r
-    LONG style = 0;\r
-    RTFControl_Info *info;\r
-    CHARRANGE *cr;\r
-\r
-    info = (RTFControl_Info *) GetWindowLongW( hwnd, RTFInfoOffset );\r
-\r
-    TRACE("uMsg: 0x%x hwnd: %p\n",uMsg,hwnd);\r
-\r
-    switch (uMsg)\r
-    {\r
-\r
-    case WM_CREATE:\r
-            TRACE_EDIT_MSG32("WM_CREATE Passed to default");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-        \r
-    case WM_NCCREATE :\r
-           TRACE_EDIT_MSG32("WM_NCCREATE");\r
-\r
-            info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,\r
-                              sizeof (RTFControl_Info));\r
-            info->parser = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,\r
-                              sizeof (RTF_Info));\r
-            SetWindowLongW( hwnd, RTFInfoOffset, (LONG)info );\r
-\r
-           /* remove SCROLLBARS from the current window style */\r
-           info->hwndParent = ((LPCREATESTRUCTA) lParam)->hwndParent;\r
-\r
-           newstyle = style = ((LPCREATESTRUCTA) lParam)->style;\r
-            newstyle &= ~WS_HSCROLL;\r
-            newstyle &= ~WS_VSCROLL;\r
-            newstyle &= ~ES_AUTOHSCROLL;\r
-            newstyle &= ~ES_AUTOVSCROLL;\r
-           SetWindowLongA(hwnd,GWL_STYLE, newstyle);\r
-\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_SETFOCUS :\r
-           TRACE_EDIT_MSG32("WM_SETFOCUS");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_SIZE :\r
-            TRACE_EDIT_MSG32("WM_SIZE");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_COMMAND :\r
-        TRACE_EDIT_MSG32("WM_COMMAND");\r
-       switch(HIWORD(wParam)) {\r
-               case EN_CHANGE:\r
-               case EN_HSCROLL:\r
-               case EN_KILLFOCUS:\r
-               case EN_SETFOCUS:\r
-               case EN_UPDATE:\r
-               case EN_VSCROLL:\r
-                       return SendMessageA(info->hwndParent, WM_COMMAND,\r
-                               wParam, (LPARAM)(hwnd));\r
-\r
-               case EN_ERRSPACE:\r
-               case EN_MAXTEXT:\r
-                       MessageBoxA (hwnd, "RichEdit control out of space.",\r
-                                  "ERROR", MB_OK | MB_ICONSTOP) ;\r
-                       return 0 ;\r
-               }\r
-\r
-    case EM_STREAMIN:\r
-            TRACE_EDIT_MSG32("EM_STREAMIN");\r
-\r
-           /* setup the RTF parser */\r
-           RTFSetEditStream(info->parser,( EDITSTREAM*)lParam);\r
-           info->parser->rtfFormat = wParam&(SF_TEXT|SF_RTF);\r
-           info->parser->hwndEdit = hwnd;\r
-           WriterInit(info->parser);\r
-           RTFInit (info->parser);\r
-           BeginFile(info->parser);\r
-\r
-           /* do the parsing */\r
-           RTFRead (info->parser);\r
-            RTFFlushOutputBuffer( info->parser );\r
-\r
-            /* put the cursor at the top */\r
-            SendMessageA( hwnd, EM_SETSEL, 0, 0 );\r
-\r
-            return 0;\r
-\r
-/* Messages specific to Richedit controls */\r
-\r
-    case EM_AUTOURLDETECT:\r
-            TRACE_EDIT_MSG32("EM_AUTOURLDETECT Ignored");\r
-           return 0;\r
-\r
-    case EM_CANPASTE:\r
-            TRACE_EDIT_MSG32("EM_CANPASTE Ignored");\r
-           return 0;\r
-\r
-    case EM_CANREDO:\r
-            TRACE_EDIT_MSG32("EM_CANREDO Ignored");\r
-           return 0;\r
-\r
-    case EM_DISPLAYBAND:\r
-            TRACE_EDIT_MSG32("EM_DISPLAYBAND Ignored");\r
-           return 0;\r
-\r
-    case EM_EXGETSEL:\r
-            TRACE_EDIT_MSG32("EM_EXGETSEL -> EM_GETSEL");\r
-            cr = (VOID *) lParam;\r
-            CallWindowProcA(lpfnEditWndProc, hwnd, EM_GETSEL, (INT)&cr->cpMin, (INT)&cr->cpMax);\r
-            TRACE("cpMin: 0x%x cpMax: 0x%x\n",(INT)cr->cpMin,(INT)cr->cpMax);\r
-            return 0;\r
-\r
-    case EM_EXLIMITTEXT:\r
-        {\r
-           DWORD limit = lParam;\r
-           TRACE_EDIT_MSG32("EM_EXLIMITTEXT");\r
-           if (limit > 65534)\r
-           {\r
-                limit = 0xFFFFFFFF;\r
-           }\r
-           return CallWindowProcA(lpfnEditWndProc, hwnd, EM_SETLIMITTEXT, limit, 0);\r
-        }\r
-\r
-    case EM_EXLINEFROMCHAR:\r
-            TRACE_EDIT_MSG32("EM_EXLINEFROMCHAR -> LINEFROMCHAR");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, EM_LINEFROMCHAR, lParam, wParam);\r
-\r
-    case EM_EXSETSEL:\r
-            TRACE_EDIT_MSG32("EM_EXSETSEL -> EM_SETSEL");\r
-            cr = (VOID *) lParam;\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, EM_SETSEL, cr->cpMin, cr->cpMax);\r
-\r
-    case EM_FINDTEXT:\r
-            TRACE_EDIT_MSG32("EM_FINDTEXT Ignored");\r
-            return 0;\r
-\r
-    case EM_FINDTEXTEX:\r
-            TRACE_EDIT_MSG32("EM_FINDTEXTEX Ignored");\r
-            return 0;\r
-\r
-    case EM_FINDTEXTEXW:\r
-            TRACE_EDIT_MSG32("EM_FINDTEXTEXW Ignored");\r
-            return 0;\r
-\r
-    case EM_FINDTEXTW:\r
-            TRACE_EDIT_MSG32("EM_FINDTEXTW Ignored");\r
-            return 0;\r
-\r
-    case EM_FINDWORDBREAK:\r
-            TRACE_EDIT_MSG32("EM_FINDWORDBREAK Ignored");\r
-            return 0;\r
-\r
-    case EM_FORMATRANGE:\r
-            TRACE_EDIT_MSG32("EM_FORMATRANGE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETAUTOURLDETECT:\r
-            TRACE_EDIT_MSG32("EM_GETAUTOURLDETECT Ignored");\r
-            return 0;\r
-\r
-    case EM_GETBIDIOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_GETBIDIOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_GETCHARFORMAT:\r
-            TRACE_EDIT_MSG32("EM_GETCHARFORMAT Ignored");\r
-            return 0;\r
-\r
-    case EM_GETEDITSTYLE:\r
-            TRACE_EDIT_MSG32("EM_GETEDITSTYLE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETEVENTMASK:\r
-            TRACE_EDIT_MSG32("EM_GETEVENTMASK Ignored");\r
-            return 0;\r
-\r
-    case EM_GETIMECOLOR:\r
-            TRACE_EDIT_MSG32("EM_GETIMECOLOR Ignored");\r
-            return 0;\r
-\r
-    case EM_GETIMECOMPMODE:\r
-            TRACE_EDIT_MSG32("EM_GETIMECOMPMODE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETIMEOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_GETIMEOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_GETLANGOPTIONS:\r
-            TRACE_EDIT_MSG32("STUB: EM_GETLANGOPTIONS");\r
-            return 0;\r
-\r
-    case EM_GETOLEINTERFACE:\r
-            TRACE_EDIT_MSG32("EM_GETOLEINTERFACE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_GETOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_GETPARAFORMAT:\r
-            TRACE_EDIT_MSG32("EM_GETPARAFORMAT Ignored");\r
-            return 0;\r
-\r
-    case EM_GETPUNCTUATION:\r
-            TRACE_EDIT_MSG32("EM_GETPUNCTUATION Ignored");\r
-            return 0;\r
-\r
-    case EM_GETREDONAME:\r
-            TRACE_EDIT_MSG32("EM_GETREDONAME Ignored");\r
-            return 0;\r
-\r
-    case EM_GETSCROLLPOS:\r
-            TRACE_EDIT_MSG32("EM_GETSCROLLPOS Ignored");\r
-            return 0;\r
-\r
-    case EM_GETSELTEXT:\r
-            TRACE_EDIT_MSG32("EM_GETSELTEXT");\r
-            return RICHEDIT_GetSelText(hwnd,(void *)lParam);\r
-\r
-    case EM_GETTEXTEX:\r
-            TRACE_EDIT_MSG32("EM_GETTEXTEX Ignored");\r
-            return 0;\r
-\r
-    case EM_GETTEXTLENGTHEX:\r
-            TRACE_EDIT_MSG32("EM_GETTEXTLENGTHEX Ignored");\r
-            return 0;\r
-\r
-    case EM_GETTEXTMODE:\r
-            TRACE_EDIT_MSG32("EM_GETTEXTMODE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETTEXTRANGE:\r
-            TRACE_EDIT_MSG32("EM_GETTEXTRANGE");\r
-            return RICHEDIT_GetTextRange(hwnd,(TEXTRANGEA *)lParam);\r
-\r
-    case EM_GETTYPOGRAPHYOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_GETTYPOGRAPHYOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_GETUNDONAME:\r
-            TRACE_EDIT_MSG32("EM_GETUNDONAME Ignored");\r
-            return 0;\r
-\r
-    case EM_GETWORDBREAKPROCEX:\r
-            TRACE_EDIT_MSG32("EM_GETWORDBREAKPROCEX Ignored");\r
-            return 0;\r
-\r
-    case EM_GETWORDWRAPMODE:\r
-            TRACE_EDIT_MSG32("EM_GETWORDWRAPMODE Ignored");\r
-            return 0;\r
-\r
-    case EM_GETZOOM:\r
-            TRACE_EDIT_MSG32("EM_GETZOOM Ignored");\r
-            return 0;\r
-\r
-    case EM_HIDESELECTION:\r
-            TRACE_EDIT_MSG32("EM_HIDESELECTION Ignored");\r
-            return 0;\r
-\r
-    case EM_PASTESPECIAL:\r
-            TRACE_EDIT_MSG32("EM_PASTESPECIAL Ignored");\r
-            return 0;\r
-\r
-    case EM_RECONVERSION:\r
-            TRACE_EDIT_MSG32("EM_RECONVERSION Ignored");\r
-            return 0;\r
-\r
-    case EM_REDO:\r
-            TRACE_EDIT_MSG32("EM_REDO Ignored");\r
-            return 0;\r
-\r
-    case EM_REQUESTRESIZE:\r
-            TRACE_EDIT_MSG32("EM_REQUESTRESIZE Ignored");\r
-            return 0;\r
-\r
-    case EM_SELECTIONTYPE:\r
-            TRACE_EDIT_MSG32("EM_SELECTIONTYPE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETBIDIOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_SETBIDIOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETBKGNDCOLOR:\r
-            TRACE_EDIT_MSG32("EM_SETBKGNDCOLOR Ignored");\r
-            return 0;\r
-\r
-    case EM_SETCHARFORMAT:\r
-            TRACE_EDIT_MSG32("EM_SETCHARFORMAT Ignored");\r
-            return 0;\r
-\r
-    case EM_SETEDITSTYLE:\r
-            TRACE_EDIT_MSG32("EM_SETEDITSTYLE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETEVENTMASK:\r
-            TRACE_EDIT_MSG32("EM_SETEVENTMASK Ignored");\r
-            return 0;\r
-\r
-    case EM_SETFONTSIZE:\r
-            TRACE_EDIT_MSG32("EM_SETFONTSIZE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETIMECOLOR:\r
-            TRACE_EDIT_MSG32("EM_SETIMECOLO Ignored");\r
-            return 0;\r
-\r
-    case EM_SETIMEOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_SETIMEOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETLANGOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_SETLANGOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETOLECALLBACK:\r
-            TRACE_EDIT_MSG32("EM_SETOLECALLBACK Ignored");\r
-            return 0;\r
-\r
-    case EM_SETOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_SETOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETPALETTE:\r
-            TRACE_EDIT_MSG32("EM_SETPALETTE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETPARAFORMAT:\r
-            TRACE_EDIT_MSG32("EM_SETPARAFORMAT Ignored");\r
-            return 0;\r
-\r
-    case EM_SETPUNCTUATION:\r
-            TRACE_EDIT_MSG32("EM_SETPUNCTUATION Ignored");\r
-            return 0;\r
-\r
-    case EM_SETSCROLLPOS:\r
-            TRACE_EDIT_MSG32("EM_SETSCROLLPOS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETTARGETDEVICE:\r
-            TRACE_EDIT_MSG32("EM_SETTARGETDEVICE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETTEXTEX:\r
-            TRACE_EDIT_MSG32("EM_SETTEXTEX Ignored");\r
-            return 0;\r
-\r
-    case EM_SETTEXTMODE:\r
-            TRACE_EDIT_MSG32("EM_SETTEXTMODE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETTYPOGRAPHYOPTIONS:\r
-            TRACE_EDIT_MSG32("EM_SETTYPOGRAPHYOPTIONS Ignored");\r
-            return 0;\r
-\r
-    case EM_SETUNDOLIMIT:\r
-            TRACE_EDIT_MSG32("EM_SETUNDOLIMIT Ignored");\r
-            return 0;\r
-\r
-    case EM_SETWORDBREAKPROCEX:\r
-            TRACE_EDIT_MSG32("EM_SETWORDBREAKPROCEX Ignored");\r
-            return 0;\r
-\r
-    case EM_SETWORDWRAPMODE:\r
-            TRACE_EDIT_MSG32("EM_SETWORDWRAPMODE Ignored");\r
-            return 0;\r
-\r
-    case EM_SETZOOM:\r
-            TRACE_EDIT_MSG32("EM_SETZOOM Ignored");\r
-            return 0;\r
-\r
-    case EM_SHOWSCROLLBAR:\r
-            TRACE_EDIT_MSG32("EM_SHOWSCROLLBAR Ignored");\r
-            return 0;\r
-\r
-    case EM_STOPGROUPTYPING:\r
-            TRACE_EDIT_MSG32("EM_STOPGROUPTYPING Ignored");\r
-            return 0;\r
-\r
-    case EM_STREAMOUT:\r
-            TRACE_EDIT_MSG32("EM_STREAMOUT Ignored");\r
-            return 0;\r
-\r
-/* Messages dispatched to the edit control */\r
-     case EM_CANUNDO:\r
-            TRACE_EDIT_MSG32("EM_CANUNDO Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_CHARFROMPOS:\r
-            TRACE_EDIT_MSG32("EM_CHARFROMPOS Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_EMPTYUNDOBUFFER:\r
-            TRACE_EDIT_MSG32("EM_EMPTYUNDOBUFFER Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_FMTLINES:\r
-            TRACE_EDIT_MSG32("EM_FMTLINES Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETFIRSTVISIBLELINE:\r
-            TRACE_EDIT_MSG32("EM_GETFIRSTVISIBLELINE Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETHANDLE:\r
-            TRACE_EDIT_MSG32("EM_GETHANDLE Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
- /*    case EM_GETIMESTATUS:*/\r
-     case EM_GETLIMITTEXT:\r
-            TRACE_EDIT_MSG32("EM_GETLIMITTEXT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETLINE:\r
-            TRACE_EDIT_MSG32("EM_GETLINE Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETLINECOUNT:\r
-            TRACE_EDIT_MSG32("EM_GETLINECOUNT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETMARGINS:\r
-            TRACE_EDIT_MSG32("EM_GETMARGINS Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETMODIFY:\r
-            TRACE_EDIT_MSG32("EM_GETMODIFY Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETPASSWORDCHAR:\r
-            TRACE_EDIT_MSG32("EM_GETPASSWORDCHAR Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETRECT:\r
-            TRACE_EDIT_MSG32("EM_GETRECT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETSEL:\r
-            TRACE_EDIT_MSG32("EM_GETSEL Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETTHUMB:\r
-            TRACE_EDIT_MSG32("EM_GETTHUMB Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_GETWORDBREAKPROC:\r
-            TRACE_EDIT_MSG32("EM_GETWORDBREAKPROC Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_LINEFROMCHAR:\r
-            TRACE_EDIT_MSG32("EM_LINEFROMCHAR Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_LINEINDEX:\r
-            TRACE_EDIT_MSG32("EM_LINEINDEX Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_LINELENGTH:\r
-            TRACE_EDIT_MSG32("EM_LINELENGTH Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_LINESCROLL:\r
-            TRACE_EDIT_MSG32("EM_LINESCROLL Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_POSFROMCHAR:\r
-            TRACE_EDIT_MSG32("EM_POSFROMCHAR Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_REPLACESEL:\r
-            TRACE_EDIT_MSG32("case EM_REPLACESEL Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SCROLL:\r
-            TRACE_EDIT_MSG32("case EM_SCROLL Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SCROLLCARET:\r
-     case WM_USER+49:  /* EM_SCROLLCARET too */\r
-            TRACE_EDIT_MSG32("EM_SCROLLCARET Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, EM_SCROLLCARET, wParam, lParam);\r
-     case EM_SETHANDLE:\r
-            TRACE_EDIT_MSG32("EM_SETHANDLE Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
- /*    case EM_SETIMESTATUS:*/\r
-     case EM_SETLIMITTEXT:\r
-            TRACE_EDIT_MSG32("EM_SETLIMITTEXT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETMARGINS:\r
-            TRACE_EDIT_MSG32("case EM_SETMARGINS Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETMODIFY:\r
-            TRACE_EDIT_MSG32("EM_SETMODIFY Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETPASSWORDCHAR:\r
-            TRACE_EDIT_MSG32("EM_SETPASSWORDCHAR Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETREADONLY:\r
-            TRACE_EDIT_MSG32("EM_SETREADONLY Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETRECT:\r
-            TRACE_EDIT_MSG32("EM_SETRECT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETRECTNP:\r
-            TRACE_EDIT_MSG32("EM_SETRECTNP Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETSEL:\r
-            TRACE_EDIT_MSG32("EM_SETSEL Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETTABSTOPS:\r
-            TRACE_EDIT_MSG32("EM_SETTABSTOPS Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_SETWORDBREAKPROC:\r
-            TRACE_EDIT_MSG32("EM_SETWORDBREAKPROC Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case EM_UNDO:\r
-            TRACE_EDIT_MSG32("EM_UNDO Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-     case WM_STYLECHANGING:\r
-            TRACE_EDIT_MSG32("WM_STYLECHANGING Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_STYLECHANGED:\r
-            TRACE_EDIT_MSG32("WM_STYLECHANGED Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_GETTEXT:\r
-            TRACE_EDIT_MSG32("WM_GETTEXT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_GETTEXTLENGTH:\r
-            TRACE_EDIT_MSG32("WM_GETTEXTLENGTH Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_SETTEXT:\r
-            TRACE_EDIT_MSG32("WM_SETTEXT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_CUT:\r
-            TRACE_EDIT_MSG32("WM_CUT Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-     case WM_COPY:\r
-            TRACE_EDIT_MSG32("WM_COPY Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_PASTE:\r
-            TRACE_EDIT_MSG32("WM_PASTE Passed to edit control");\r
-            return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    /* Messages passed to default handler. */\r
-    case WM_NCCALCSIZE:\r
-        TRACE_EDIT_MSG32("WM_NCCALCSIZE Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_NCPAINT:\r
-        TRACE_EDIT_MSG32("WM_NCPAINT Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_PAINT:\r
-        TRACE_EDIT_MSG32("WM_PAINT Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_ERASEBKGND:\r
-        TRACE_EDIT_MSG32("WM_ERASEBKGND Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_KILLFOCUS:\r
-        TRACE_EDIT_MSG32("WM_KILLFOCUS Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_DESTROY:\r
-        TRACE_EDIT_MSG32("WM_DESTROY Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_CHILDACTIVATE:\r
-       TRACE_EDIT_MSG32("WM_CHILDACTIVATE Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_WINDOWPOSCHANGING:\r
-        TRACE_EDIT_MSG32("WM_WINDOWPOSCHANGING Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_WINDOWPOSCHANGED:\r
-        TRACE_EDIT_MSG32("WM_WINDOWPOSCHANGED Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-/*    case WM_INITIALUPDATE:\r
-        TRACE_EDIT_MSG32("WM_INITIALUPDATE Passed to default");\r
-        return DefWindowProcA( hwnd,uMsg,wParam,lParam); */\r
-    case WM_CTLCOLOREDIT:\r
-        TRACE_EDIT_MSG32("WM_CTLCOLOREDIT Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_SETCURSOR:\r
-        TRACE_EDIT_MSG32("WM_SETCURSOR Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_MOVE:\r
-        TRACE_EDIT_MSG32("WM_MOVE Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_SHOWWINDOW:\r
-        TRACE_EDIT_MSG32("WM_SHOWWINDOW Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_PARENTNOTIFY:\r
-        TRACE_EDIT_MSG32("WM_PARENTNOTIFY Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_SETREDRAW:\r
-        TRACE_EDIT_MSG32("WM_SETREDRAW Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_NCDESTROY:\r
-    {\r
-        TRACE_EDIT_MSG32("WM_NCDESTROY Passed to default");\r
-        HeapFree( GetProcessHeap(), 0, info->parser );\r
-        HeapFree( GetProcessHeap(), 0, info );\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    }\r
-\r
-    case WM_NCHITTEST:\r
-        TRACE_EDIT_MSG32("WM_NCHITTEST Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_CTLCOLORSTATIC:\r
-        TRACE_EDIT_MSG32("WM_CTLCOLORSTATIC Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_NCMOUSEMOVE:\r
-        TRACE_EDIT_MSG32("WM_NCMOUSEMOVE Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_CLEAR:\r
-        TRACE_EDIT_MSG32("WM_CLEAR Passed to default");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-   /*\r
-    * used by IE in the EULA box\r
-    */\r
-    case WM_ALTTABACTIVE:\r
-        TRACE_EDIT_MSG32("WM_ALTTABACTIVE");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_GETDLGCODE:\r
-        TRACE_EDIT_MSG32("WM_GETDLGCODE");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-    case WM_SETFONT:\r
-        TRACE_EDIT_MSG32("WM_SETFONT");\r
-        return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-\r
-    }\r
-\r
-    if ((uMsg >= WM_USER) && (uMsg < WM_APP)) {\r
-       FIXME("Unknown message 0x%x Passed to default hwnd=%p, wParam=%08x, lParam=%08x\n",\r
-              uMsg, hwnd, (UINT)wParam, (UINT)lParam);\r
-    }\r
-\r
-   return CallWindowProcA(lpfnEditWndProc, hwnd, uMsg, wParam, lParam);\r
-}\r
 \r
 /***********************************************************************\r
  * DllGetVersion [RICHED32.2]\r
  *\r
- * Retrieves version information of the 'RICHED32.DLL'\r
- *\r
- * PARAMS\r
- *     pdvi [O] pointer to version information structure.\r
- *\r
- * RETURNS\r
- *     Success: S_OK\r
- *     Failure: E_INVALIDARG\r
- *\r
- * NOTES\r
- *     Returns version of a comctl32.dll from IE4.01 SP1.\r
+ * Retrieves version information\r
  */\r
-\r
-HRESULT WINAPI\r
-RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)\r
+HRESULT WINAPI RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)\r
 {\r
     TRACE("\n");\r
 \r
-    if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {\r
-\r
+    if (pdvi->cbSize != sizeof(DLLVERSIONINFO))\r
        return E_INVALIDARG;\r
-    }\r
 \r
     pdvi->dwMajorVersion = 4;\r
     pdvi->dwMinorVersion = 0;\r
@@ -760,99 +60,47 @@ RICHED32_DllGetVersion (DLLVERSIONINFO *pdvi)
     return S_OK;\r
 }\r
 \r
-/***\r
- * DESCRIPTION:\r
- * Registers the window class.\r
- *\r
- * PARAMETER(S):\r
- * None\r
- *\r
- * RETURN:\r
- * None\r
- */\r
-VOID RICHED32_Register(void)\r
+/* Unregisters the window class. */\r
+static BOOL RICHED32_Unregister(void)\r
 {\r
-    WNDCLASSA wndClass;\r
-\r
     TRACE("\n");\r
 \r
+    UnregisterClassA(RICHEDIT_CLASS10A, NULL);\r
+    return TRUE;\r
+}\r
+\r
+\r
+/* Registers the window class. */\r
+static BOOL RICHED32_Register(void)\r
+{\r
+    WNDCLASSA wndClass;\r
+\r
     ZeroMemory(&wndClass, sizeof(WNDCLASSA));\r
     wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;\r
-    wndClass.lpfnWndProc = RICHED32_WindowProc;\r
+    wndClass.lpfnWndProc = RichEdit10ANSIWndProc;\r
     wndClass.cbClsExtra = 0;\r
-    wndClass.cbWndExtra = RTFInfoOffset + sizeof(RTFControl_Info*);\r
+    wndClass.cbWndExtra = 4;\r
     wndClass.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);\r
     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);\r
     wndClass.lpszClassName = RICHEDIT_CLASS10A; /* WC_RICHED32A; */\r
 \r
-    RegisterClassA (&wndClass);\r
-}\r
+    RegisterClassA(&wndClass);\r
 \r
-/***\r
- * DESCRIPTION:\r
- * Unregisters the window class.\r
- *\r
- * PARAMETER(S):\r
- * None\r
- *\r
- * RETURN:\r
- * None\r
- */\r
-VOID RICHED32_Unregister(void)\r
-{\r
-    TRACE("\n");\r
-\r
-    UnregisterClassA(RICHEDIT_CLASS10A, NULL);\r
+    return TRUE;\r
 }\r
 \r
-\r
-/***\r
- * DESCRIPTION:\r
- * Initialize edit control class info\r
- */\r
-VOID RICHEDIT_InitEditControlInfo(void)\r
+/* Initialization function */\r
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
 {\r
-    WNDCLASSA wcEdit;\r
-\r
-    if (GetClassInfoA(0, "edit",  &wcEdit))\r
+    TRACE("\n");\r
+    switch (fdwReason)\r
     {\r
-        lpfnEditWndProc = wcEdit.lpfnWndProc;\r
-        RTFInfoOffset = wcEdit.cbWndExtra;\r
-    }\r
-    else\r
-        ERR("Failed to retrieve edit control class info\n");\r
-}\r
-\r
-\r
-INT RICHEDIT_GetTextRange(HWND hwnd,TEXTRANGEA *tr)\r
-{\r
-    UINT alloc_size, text_size, range_size;\r
-    char *text;\r
-\r
-    TRACE("start: 0x%x stop: 0x%x\n",(INT)tr->chrg.cpMin,(INT)tr->chrg.cpMax);\r
-\r
-    if (!(alloc_size = SendMessageA(hwnd,WM_GETTEXTLENGTH,0,0))) return FALSE;\r
-    if (!(text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (alloc_size+1))))\r
-               return FALSE;\r
-    text_size = SendMessageA(hwnd,WM_GETTEXT,alloc_size,(INT)text);\r
+    case DLL_PROCESS_ATTACH:\r
+        DisableThreadLibraryCalls(hinstDLL);\r
+        return RICHED32_Register();\r
 \r
-    if (text_size > tr->chrg.cpMin)\r
-    {\r
-       range_size = (text_size> tr->chrg.cpMax) ? (tr->chrg.cpMax - tr->chrg.cpMin) : (text_size - tr->chrg.cpMin);\r
-       TRACE("EditText: %.30s ...\n",text+tr->chrg.cpMin);\r
-       memcpy(tr->lpstrText,text+tr->chrg.cpMin,range_size);\r
+    case DLL_PROCESS_DETACH:\r
+        return RICHED32_Unregister();\r
     }\r
-    else range_size = 0;\r
-    HeapFree(GetProcessHeap(), 0, text);\r
-\r
-    return range_size;\r
-}\r
-\r
-INT RICHEDIT_GetSelText(HWND hwnd,LPSTR lpstrBuffer)\r
-{\r
-    TEXTRANGEA textrange;\r
-\r
-    textrange.lpstrText = lpstrBuffer;\r
-    SendMessageA(hwnd,EM_GETSEL,(INT)&textrange.chrg.cpMin,(INT)&textrange.chrg.cpMax);\r
-    return RICHEDIT_GetTextRange(hwnd,&textrange);\r
+    return TRUE;\r
 }\r
index 780176d..4d01c11 100644 (file)
  * Copied from kernel32
  */
 
+/* PowerPC Functions from gatomic.c in glib
+ *
+ * GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
 /************************************************************************
 *           InterlockedIncrement                                       *
@@ -36,6 +59,7 @@ STDCALL
 InterlockedIncrement(PLONG Addend)
 {
        long ret = 0;
+#ifdef _M_IX86
        __asm__
        (                
           "\tlock\n"   /* for SMP systems */
@@ -48,6 +72,10 @@ InterlockedIncrement(PLONG Addend)
           "2:\n"
           :"=r" (ret):"r" (Addend), "0" (0): "memory"
        );
+#elif defined(_M_PPC)
+        ret = *Addend;
+        ret = InterlockedExchangeAdd( Addend, ret + 1 );
+#endif
        return ret;
 }
 
@@ -67,6 +95,7 @@ STDCALL
 InterlockedDecrement(LPLONG lpAddend)
 {
        long ret;
+#ifdef _M_IX86
        __asm__
        (                
           "\tlock\n"   /* for SMP systems */
@@ -79,6 +108,10 @@ InterlockedDecrement(LPLONG lpAddend)
           "2:\n"
           :"=r" (ret):"r" (lpAddend), "0" (0): "memory"          
        );
+#elif defined(_M_PPC)
+        ret = *lpAddend;
+        ret = InterlockedExchangeAdd( lpAddend, ret - 1 );
+#endif
        return ret;
 
 
@@ -97,14 +130,17 @@ LONG
 STDCALL 
 InterlockedExchange(LPLONG target, LONG value )
 {
-       
        long ret;
+#ifdef _M_IX86
        __asm__ ( /* lock for SMP systems */
                   "lock\n\txchgl %0,(%1)"
                   :"=r" (ret):"r" (target), "0" (value):"memory" );
+#elif defined(_M_PPC)
+        do {
+            ret = *(volatile LONG *)target;
+        } while( InterlockedCompareExchange( target, value, ret ) != ret );
+#endif
        return ret;
-
-
 }
 
 /************************************************************************
@@ -124,8 +160,21 @@ InterlockedCompareExchange(
             LONG Comperand     ) 
 {
     LONG ret;
+#ifdef _M_IX86
     __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
                           : "=a" (ret) : "r" (Destination), "r" (Exchange), "0" (Comperand) : "memory" );
+#elif defined(_M_PPC)
+    __asm__ __volatile__ ("sync\n"
+                          "1: lwarx   %0,0,%1\n"
+                          "   subf.   %0,%2,%0\n"
+                          "   bne     2f\n"
+                          "   stwcx.  %3,0,%1\n"
+                          "   bne-    1b\n"
+                          "2: isync"
+                          : "=&r" (ret)
+                          : "b" (Destination), "r" (Comperand), "r" (Exchange)
+                          : "cr0", "memory"); 
+#endif
     return ret;
 }
 
@@ -145,14 +194,20 @@ InterlockedExchangeAdd(
            LONG Increment 
 ) 
 {
-
        LONG ret;
+#ifdef _M_IX86
        __asm__ ( /* lock for SMP systems */
                   "lock\n\t"
                   "xaddl %0,(%1)"
                   :"=r" (ret)
                   :"r" (Addend), "0" (Increment)
                   :"memory" );
+#elif defined(_M_PPC)
+        LONG newval;
+        do {
+            ret = *(volatile LONG *)Addend;
+            newval = ret + Increment;
+        } while (InterlockedCompareExchange(Addend, ret, newval) != ret);
+#endif
        return ret;
-
 }
index 33ff8f5..314f7ee 100644 (file)
@@ -45,21 +45,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
 #define BUFFER_PARANOIA 20\r
 \r
 #if defined(__i386__)\r
-  #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \\r
+define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \\r
     (*((UINT32 *)(pchar)) = (uint32))\r
 \r
-  #define LITTLE_ENDIAN_UINT32_READ(pchar) \\r
+define LITTLE_ENDIAN_UINT32_READ(pchar) \\r
     (*((UINT32 *)(pchar)))\r
 #else\r
   /* these would work for i386 too, but less efficient */\r
-  #define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \\r
+define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \\r
     (*(pchar)     = LOBYTE(LOWORD(uint32)), \\r
      *((pchar)+1) = HIBYTE(LOWORD(uint32)), \\r
      *((pchar)+2) = LOBYTE(HIWORD(uint32)), \\r
      *((pchar)+3) = HIBYTE(HIWORD(uint32)), \\r
      (uint32)) /* allow as r-value */\r
 \r
-  #define LITTLE_ENDIAN_UINT32_READ(pchar) \\r
+define LITTLE_ENDIAN_UINT32_READ(pchar) \\r
     (MAKELONG( \\r
       MAKEWORD(*(pchar), *((pchar)+1)), \\r
       MAKEWORD(*((pchar)+2), *((pchar)+3))))\r
@@ -78,14 +78,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
     MAKEWORD(*((pchar)+1), *(pchar))))\r
 \r
 #ifdef NDR_LOCAL_IS_BIG_ENDIAN\r
-  #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \\r
+define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \\r
     BIG_ENDIAN_UINT32_WRITE(pchar, uint32)\r
-  #define NDR_LOCAL_UINT32_READ(pchar) \\r
+define NDR_LOCAL_UINT32_READ(pchar) \\r
     BIG_ENDIAN_UINT32_READ(pchar)\r
 #else\r
-  #define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \\r
+define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \\r
     LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)\r
-  #define NDR_LOCAL_UINT32_READ(pchar) \\r
+define NDR_LOCAL_UINT32_READ(pchar) \\r
     LITTLE_ENDIAN_UINT32_READ(pchar)\r
 #endif\r
 \r
@@ -388,7 +388,12 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
   TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);\r
   \r
   assert(pFormat);\r
-  if (*pFormat == RPC_FC_C_CSTRING) {\r
+  if (pszMessage == NULL) {\r
+    TRACE("string=%s\n", debugstr_a(pszMessage));\r
+    len = 0;\r
+    esize = 0;\r
+  }\r
+  else if (*pFormat == RPC_FC_C_CSTRING) {\r
     TRACE("string=%s\n", debugstr_a(pszMessage));\r
     len = strlen(pszMessage)+1;\r
     esize = 1;\r
@@ -416,8 +421,10 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
   c += 8;                         /* offset: 0 */\r
   NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */\r
   c += 4;\r
-  memcpy(c, pszMessage, len*esize); /* the string itself */\r
-  c += len*esize;\r
+  if (len != 0) {\r
+    memcpy(c, pszMessage, len*esize); /* the string itself */\r
+    c += len*esize;\r
+  }\r
   pStubMsg->Buffer = c;\r
 \r
   STD_OVERFLOW_CHECK(pStubMsg);\r
@@ -435,7 +442,12 @@ void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
   TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);\r
 \r
   assert(pFormat);\r
-  if (*pFormat == RPC_FC_C_CSTRING) {\r
+  if (pMemory == NULL) {\r
+    /* we need 12 octets for the [maxlen, offset, len] DWORDS */\r
+    TRACE("string=NULL\n");\r
+    pStubMsg->BufferLength += 12 + BUFFER_PARANOIA;\r
+  }\r
+  else if (*pFormat == RPC_FC_C_CSTRING) {\r
     /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */\r
     TRACE("string=%s\n", debugstr_a(pMemory));\r
     pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;\r
@@ -528,6 +540,11 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
     /* for clients, memory should be provided by caller */\r
   }\r
 \r
+  if (len == 0) {\r
+    *ppMemory = NULL;\r
+    return NULL;\r
+  }\r
+\r
   pMem = *ppMemory + ofs*esize;\r
 \r
   if (pMem != pStubMsg->Buffer)\r
@@ -572,6 +589,8 @@ void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
   switch (type) {\r
   case RPC_FC_RP: /* ref pointer (always non-null) */\r
     break;\r
+  case RPC_FC_UP: /* unique pointer */\r
+    break;\r
   default:\r
     FIXME("unhandled ptr type=%02x\n", type);\r
   }\r
@@ -609,6 +628,8 @@ void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
   switch (type) {\r
   case RPC_FC_RP: /* ref pointer (always non-null) */\r
     break;\r
+  case RPC_FC_UP: /* unique pointer */\r
+    break;\r
   default:\r
     FIXME("unhandled ptr type=%02x\n", type);\r
   }\r
@@ -645,6 +666,8 @@ void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
   switch (type) {\r
   case RPC_FC_RP: /* ref pointer (always non-null) */\r
     break;\r
+  case RPC_FC_UP: /* unique pointer */\r
+    break;\r
   default:\r
     FIXME("unhandled ptr type=%02x\n", type);\r
   }\r
index 76f972b..f2929b8 100644 (file)
@@ -233,12 +233,12 @@ unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_M
 unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle)\r
 {\r
   TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle);\r
-  \r
+\r
   assert( stubmsg && stubmsg->RpcMsg );\r
 \r
   /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */\r
   stubmsg->RpcMsg->Handle = handle;\r
-  \r
+\r
   stubmsg->RpcMsg->BufferLength = buflen;\r
   if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)\r
     return NULL;\r
@@ -248,6 +248,7 @@ unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buf
   stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;\r
   return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);\r
 }\r
+\r
 /***********************************************************************\r
  *           NdrFreeBuffer [RPCRT4.@]\r
  */\r
@@ -262,28 +263,34 @@ void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg)
 /************************************************************************\r
  *           NdrSendReceive [RPCRT4.@]\r
  */\r
-unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer  )\r
+unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *pStubMsg, unsigned char *buffer  )\r
 {\r
-  TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);\r
+  TRACE("(pStubMsg == ^%p, buffer == ^%p)\n", pStubMsg, buffer);\r
 \r
   /* FIXME: how to handle errors? (raise exception?) */\r
-  if (!stubmsg) {\r
+  if (!pStubMsg) {\r
     ERR("NULL stub message.  No action taken.\n");\r
     return NULL;\r
   }\r
-  if (!stubmsg->RpcMsg) {\r
+  if (!pStubMsg->RpcMsg) {\r
     ERR("RPC Message not present in stub message.  No action taken.\n");\r
     return NULL;\r
   }\r
 \r
   /* FIXME: Seems wrong.  Where should this really come from, and when? */\r
-  stubmsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;\r
+  pStubMsg->RpcMsg->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION;\r
 \r
-  if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) {\r
+  if (I_RpcSendReceive(pStubMsg->RpcMsg) != RPC_S_OK) {\r
     WARN("I_RpcSendReceive did not return success.\n");\r
     /* FIXME: raise exception? */\r
+    return NULL;\r
   }\r
 \r
+  pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;\r
+  pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;\r
+  pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;\r
+  pStubMsg->Buffer = pStubMsg->BufferStart;\r
+\r
   /* FIXME: is this the right return value? */\r
   return NULL;\r
 }\r
index 82e1690..849b8f0 100644 (file)
@@ -147,11 +147,12 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
                                          RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);\r
         HeapFree(GetProcessHeap(), 0, pname);\r
         memset(&Connection->ovl, 0, sizeof(Connection->ovl));\r
-        Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
-        if (!ConnectNamedPipe(Connection->conn, &Connection->ovl)) {\r
+        Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+       Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) {\r
           WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());\r
           if (GetLastError() == ERROR_PIPE_CONNECTED) {\r
-            SetEvent(Connection->ovl.hEvent);\r
+            SetEvent(Connection->ovl[0].hEvent);\r
             return RPC_S_OK;\r
           } else if (GetLastError() == ERROR_IO_PENDING) {\r
             return RPC_S_OK;\r
@@ -171,13 +172,16 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
                                          RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);\r
         HeapFree(GetProcessHeap(), 0, pname);\r
         memset(&Connection->ovl, 0, sizeof(Connection->ovl));\r
-        Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
-        if (!ConnectNamedPipe(Connection->conn, &Connection->ovl)) {\r
-          WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());\r
+        Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) {\r
           if (GetLastError() == ERROR_PIPE_CONNECTED) {\r
-            SetEvent(Connection->ovl.hEvent);\r
+            SetEvent(Connection->ovl[0].hEvent);\r
+            return RPC_S_OK;\r
+          } else if (GetLastError() == ERROR_IO_PENDING) {\r
             return RPC_S_OK;\r
           }\r
+          WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());\r
           return RPC_S_SERVER_UNAVAILABLE;\r
         }\r
       }\r
@@ -211,7 +215,7 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
             return RPC_S_SERVER_TOO_BUSY;\r
           } else {\r
             err = GetLastError();\r
-            TRACE("connection failed, error=%lx\n", err);\r
+            WARN("connection failed, error=%lx\n", err);\r
             HeapFree(GetProcessHeap(), 0, pname);\r
             return RPC_S_SERVER_UNAVAILABLE;\r
           }\r
@@ -223,7 +227,8 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
         /* pipe is connected; change to message-read mode. */\r
         dwMode = PIPE_READMODE_MESSAGE; \r
         SetNamedPipeHandleState(conn, &dwMode, NULL, NULL);\r
-        Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
         Connection->conn = conn;\r
       }\r
       /* protseq=ncacn_np: named pipes */\r
@@ -243,7 +248,7 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
           err = GetLastError();\r
           /* we don't need to handle ERROR_PIPE_BUSY here,\r
            * the doc says that it is returned to the app */\r
-          TRACE("connection failed, error=%lx\n", err);\r
+          WARN("connection failed, error=%lx\n", err);\r
           HeapFree(GetProcessHeap(), 0, pname);\r
           if (err == ERROR_PIPE_BUSY)\r
             return RPC_S_SERVER_TOO_BUSY;\r
@@ -257,7 +262,8 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
         /* pipe is connected; change to message-read mode. */\r
         dwMode = PIPE_READMODE_MESSAGE;\r
         SetNamedPipeHandleState(conn, &dwMode, NULL, NULL);\r
-        Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+        Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);\r
         Connection->conn = conn;\r
       } else {\r
         ERR("protseq %s not supported\n", Connection->Protseq);\r
@@ -276,9 +282,13 @@ RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
     CloseHandle(Connection->conn);\r
     Connection->conn = 0;\r
   }\r
-  if (Connection->ovl.hEvent) {\r
-    CloseHandle(Connection->ovl.hEvent);\r
-    Connection->ovl.hEvent = 0;\r
+  if (Connection->ovl[0].hEvent) {\r
+    CloseHandle(Connection->ovl[0].hEvent);\r
+    Connection->ovl[0].hEvent = 0;\r
+  }\r
+  if (Connection->ovl[1].hEvent) {\r
+    CloseHandle(Connection->ovl[1].hEvent);\r
+    Connection->ovl[1].hEvent = 0;\r
   }\r
   return RPC_S_OK;\r
 }\r
@@ -292,7 +302,8 @@ RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* Old
     /* because of the way named pipes work, we'll transfer the connected pipe\r
      * to the child, then reopen the server binding to continue listening */\r
     NewConnection->conn = OldConnection->conn;\r
-    NewConnection->ovl = OldConnection->ovl;\r
+    NewConnection->ovl[0] = OldConnection->ovl[0];\r
+    NewConnection->ovl[1] = OldConnection->ovl[1];\r
     OldConnection->conn = 0;\r
     memset(&OldConnection->ovl, 0, sizeof(OldConnection->ovl));\r
     *Connection = NewConnection;\r
@@ -397,7 +408,7 @@ RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, UUID* ObjectUuid)
 RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection)\r
 {\r
   RpcBinding* NewBinding;\r
-  TRACE("(*RpcBinding == ^%p, Connection == ^%p)\n", *Binding, Connection);\r
+  TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding, Connection);\r
 \r
   RPCRT4_AllocBinding(&NewBinding, Connection->server);\r
   NewBinding->Protseq = RPCRT4_strdupA(Connection->Protseq);\r
@@ -1094,3 +1105,22 @@ RPC_STATUS WINAPI RpcNetworkIsProtseqValidW(LPWSTR protseq) {
   FIXME("Unknown protseq %s - we probably need to implement it one day\n", debugstr_w(protseq));\r
   return RPC_S_PROTSEQ_NOT_SUPPORTED;\r
 }\r
+\r
+/***********************************************************************\r
+ *             RpcImpersonateClient (RPCRT4.@)\r
+ *\r
+ * Impersonates the client connected via a binding handle so that security\r
+ * checks are done in the context of the client.\r
+ *\r
+ * PARAMS\r
+ *  BindingHandle [I] Handle to the binding to the client.\r
+ *\r
+ * RETURNS\r
+ *  Success: RPS_S_OK.\r
+ *  Failure: RPC_STATUS value.\r
+ */\r
+RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle)\r
+{\r
+    FIXME("(%p): stub\n", BindingHandle);\r
+    return RPC_S_NO_CONTEXT_AVAILABLE;\r
+}\r
index 0d7daa5..61f796b 100644 (file)
@@ -32,7 +32,7 @@ typedef struct _RpcConnection
   LPSTR NetworkAddr;\r
   LPSTR Endpoint;\r
   HANDLE conn, thread;\r
-  OVERLAPPED ovl;\r
+  OVERLAPPED ovl[2];\r
   USHORT MaxTransmissionSize;\r
   /* The active interface bound to server. */\r
   RPC_SYNTAX_IDENTIFIER ActiveInterface;\r
index d10e56c..a57c25c 100644 (file)
@@ -265,12 +265,12 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
     }\r
 \r
     /* transmit packet header */\r
-    ResetEvent(Connection->ovl.hEvent);\r
-    if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl)) {\r
+    if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl[1]) &&\r
+       ERROR_IO_PENDING != GetLastError()) {\r
       WARN("WriteFile failed with error %ld\n", GetLastError());\r
       return GetLastError();\r
     }\r
-    if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &count, TRUE)) {\r
+    if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {\r
       WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
       return GetLastError();\r
     }\r
@@ -282,12 +282,12 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
     }\r
 \r
     /* send the fragment data */\r
-    ResetEvent(Connection->ovl.hEvent);\r
-    if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl)) {\r
+    if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl[1]) &&\r
+       ERROR_IO_PENDING != GetLastError()) {\r
       WARN("WriteFile failed with error %ld\n", GetLastError());\r
       return GetLastError();\r
     }\r
-    if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &count, TRUE)) {\r
+    if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {\r
       WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
       return GetLastError();\r
     }\r
@@ -319,13 +319,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
   TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);\r
 \r
   /* read packet common header */\r
-  ResetEvent(Connection->ovl.hEvent);\r
-  if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl)) {\r
+  if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&\r
+      ERROR_IO_PENDING != GetLastError()) {\r
     WARN("ReadFile failed with error %ld\n", GetLastError());\r
     status = RPC_S_PROTOCOL_ERROR;\r
     goto fail;\r
   }\r
-  if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {\r
+  if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {\r
     if (GetLastError() != ERROR_MORE_DATA) {\r
       WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
       status = RPC_S_PROTOCOL_ERROR;\r
@@ -333,6 +333,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
     }\r
   }\r
   if (dwRead != sizeof(common_hdr)) {\r
+    WARN("Short read of header, %ld/%d bytes\n", dwRead, sizeof(common_hdr));\r
     status = RPC_S_PROTOCOL_ERROR;\r
     goto fail;\r
   }\r
@@ -347,6 +348,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
 \r
   hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr);\r
   if (hdr_length == 0) {\r
+    WARN("header length == 0\n");\r
     status = RPC_S_PROTOCOL_ERROR;\r
     goto fail;\r
   }\r
@@ -355,14 +357,14 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
   memcpy(*Header, &common_hdr, sizeof(common_hdr));\r
 \r
   /* read the rest of packet header */\r
-  ResetEvent(Connection->ovl.hEvent);\r
   if (!ReadFile(Connection->conn, &(*Header)->common + 1,\r
-                hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl)) {\r
+                hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&\r
+      ERROR_IO_PENDING != GetLastError()) {\r
     WARN("ReadFile failed with error %ld\n", GetLastError());\r
     status = RPC_S_PROTOCOL_ERROR;\r
     goto fail;\r
   }\r
-  if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {\r
+  if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {\r
     if (GetLastError() != ERROR_MORE_DATA) {\r
       WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
       status = RPC_S_PROTOCOL_ERROR;\r
@@ -370,6 +372,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
     }\r
   }\r
   if (dwRead != hdr_length - sizeof(common_hdr)) {\r
+    WARN("bad header length, %ld/%ld bytes\n", dwRead, hdr_length - sizeof(common_hdr));\r
     status = RPC_S_PROTOCOL_ERROR;\r
     goto fail;\r
   }\r
@@ -386,6 +389,9 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
   default:\r
     pMsg->BufferLength = common_hdr.frag_len - hdr_length;\r
   }\r
+\r
+  TRACE("buffer length = %u\n", pMsg->BufferLength);\r
+\r
   status = I_RpcGetBuffer(pMsg);\r
   if (status != RPC_S_OK) goto fail;\r
 \r
@@ -403,13 +409,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
     }\r
 \r
     if (data_length == 0) dwRead = 0; else {\r
-      ResetEvent(Connection->ovl.hEvent);\r
-      if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl)) {\r
+      if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl[0]) &&\r
+         ERROR_IO_PENDING != GetLastError()) {\r
         WARN("ReadFile failed with error %ld\n", GetLastError());\r
         status = RPC_S_PROTOCOL_ERROR;\r
         goto fail;\r
       }\r
-      if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {\r
+      if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {\r
         if (GetLastError() != ERROR_MORE_DATA) {\r
           WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
           status = RPC_S_PROTOCOL_ERROR;\r
@@ -418,12 +424,15 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
       }\r
     }\r
     if (dwRead != data_length) {\r
+      WARN("bad data length, %ld/%ld\n", dwRead, data_length);\r
       status = RPC_S_PROTOCOL_ERROR;\r
       goto fail;\r
     }\r
 \r
+    /* when there is no more data left, it should be the last packet */\r
     if (buffer_length == pMsg->BufferLength &&\r
         ((*Header)->common.flags & RPC_FLG_LAST) == 0) {\r
+      WARN("no more data left, but not last packet\n");\r
       status = RPC_S_PROTOCOL_ERROR;\r
       goto fail;\r
     }\r
@@ -433,13 +442,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
       TRACE("next header\n");\r
 \r
       /* read the header of next packet */\r
-      ResetEvent(Connection->ovl.hEvent);\r
-      if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl)) {\r
+      if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl[0]) &&\r
+         ERROR_IO_PENDING != GetLastError()) {\r
         WARN("ReadFile failed with error %ld\n", GetLastError());\r
         status = GetLastError();\r
         goto fail;\r
       }\r
-      if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {\r
+      if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {\r
         if (GetLastError() != ERROR_MORE_DATA) {\r
           WARN("GetOverlappedResult failed with error %ld\n", GetLastError());\r
           status = RPC_S_PROTOCOL_ERROR;\r
@@ -616,6 +625,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
     status = RPC_S_CALL_FAILED; /* ? */\r
     goto fail;\r
   default:\r
+    WARN("bad packet type %d\n", hdr->common.ptype);\r
     goto fail;\r
   }\r
 \r
index bb3cb95..158033f 100644 (file)
@@ -93,7 +93,14 @@ static CRITICAL_SECTION listen_cs = { &listen_cs_debug, -1, 0, 0, 0, 0 };
 \r
 static BOOL std_listen;\r
 static LONG listen_count = -1;\r
-static HANDLE mgr_event, server_thread;\r
+/* set on change of configuration (e.g. listening on new protseq) */\r
+static HANDLE mgr_event;\r
+/* mutex for ensuring only one thread can change state at a time */\r
+static HANDLE mgr_mutex;\r
+/* set when server thread has finished opening connections */\r
+static HANDLE server_ready_event;\r
+/* thread that waits for connections */\r
+static HANDLE server_thread;\r
 \r
 static CRITICAL_SECTION spacket_cs;\r
 static CRITICAL_SECTION_DEBUG spacket_cs_debug =\r
@@ -463,6 +470,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
   RpcServerProtseq* cps;\r
   RpcConnection* conn;\r
   RpcConnection* cconn;\r
+  BOOL set_ready_event = FALSE;\r
 \r
   TRACE("(the_arg == ^%p)\n", the_arg);\r
 \r
@@ -475,7 +483,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
       conn = cps->conn;\r
       while (conn) {\r
         RPCRT4_OpenConnection(conn);\r
-        if (conn->ovl.hEvent) count++;\r
+        if (conn->ovl[0].hEvent) count++;\r
         conn = conn->Next;\r
       }\r
       cps = cps->Next;\r
@@ -492,18 +500,29 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
     while (cps) {\r
       conn = cps->conn;\r
       while (conn) {\r
-        if (conn->ovl.hEvent) objs[count++] = conn->ovl.hEvent;\r
+        if (conn->ovl[0].hEvent) objs[count++] = conn->ovl[0].hEvent;\r
         conn = conn->Next;\r
       }\r
       cps = cps->Next;\r
     }\r
     LeaveCriticalSection(&server_cs);\r
 \r
+    if (set_ready_event)\r
+    {\r
+        /* signal to function that changed state that we are now sync'ed */\r
+        SetEvent(server_ready_event);\r
+        set_ready_event = FALSE;\r
+    }\r
+\r
     /* start waiting */\r
     res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);\r
     if (res == WAIT_OBJECT_0) {\r
-      ResetEvent(m_event);\r
-      if (!std_listen) break;\r
+      if (!std_listen)\r
+      {\r
+        SetEvent(server_ready_event);\r
+        break;\r
+      }\r
+      set_ready_event = TRUE;\r
     }\r
     else if (res == WAIT_FAILED) {\r
       ERR("wait failed\n");\r
@@ -517,7 +536,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
       while (cps) {\r
         conn = cps->conn;\r
         while (conn) {\r
-          if (conn->ovl.hEvent == b_handle) break;\r
+          if (conn->ovl[0].hEvent == b_handle) break;\r
           conn = conn->Next;\r
         }\r
         if (conn) break;\r
@@ -548,13 +567,31 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
   return 0;\r
 }\r
 \r
+/* tells the server thread that the state has changed and waits for it to\r
+ * make the changes */\r
+static void RPCRT4_sync_with_server_thread(void)\r
+{\r
+  /* make sure we are the only thread sync'ing the server state, otherwise\r
+   * there is a race with the server thread setting an older state and setting\r
+   * the server_ready_event when the new state hasn't yet been applied */\r
+  WaitForSingleObject(mgr_mutex, INFINITE);\r
+\r
+  SetEvent(mgr_event);\r
+  /* wait for server thread to make the requested changes before returning */\r
+  WaitForSingleObject(server_ready_event, INFINITE);\r
+\r
+  ReleaseMutex(mgr_mutex);\r
+}\r
+\r
 static void RPCRT4_start_listen(void)\r
 {\r
   TRACE("\n");\r
 \r
   EnterCriticalSection(&listen_cs);\r
   if (! ++listen_count) {\r
-    if (!mgr_event) mgr_event = CreateEventW(NULL, TRUE, FALSE, NULL);\r
+    if (!mgr_mutex) mgr_mutex = CreateMutexW(NULL, FALSE, NULL);\r
+    if (!mgr_event) mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);\r
+    if (!server_ready_event) server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);\r
     if (!server_sem) server_sem = CreateSemaphoreW(NULL, 0, MAX_THREADS, NULL);\r
     if (!worker_tls) worker_tls = TlsAlloc();\r
     std_listen = TRUE;\r
@@ -562,7 +599,7 @@ static void RPCRT4_start_listen(void)
     LeaveCriticalSection(&listen_cs);\r
   } else {\r
     LeaveCriticalSection(&listen_cs);\r
-    SetEvent(mgr_event);\r
+    RPCRT4_sync_with_server_thread();\r
   }\r
 }\r
 \r
@@ -574,7 +611,7 @@ static void RPCRT4_stop_listen(void)
   else if (--listen_count == -1) {\r
     std_listen = FALSE;\r
     LeaveCriticalSection(&listen_cs);\r
-    SetEvent(mgr_event);\r
+    RPCRT4_sync_with_server_thread();\r
   } else\r
     LeaveCriticalSection(&listen_cs);\r
   assert(listen_count > -2);\r
@@ -589,7 +626,7 @@ static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
   protseqs = ps;\r
   LeaveCriticalSection(&server_cs);\r
 \r
-  if (std_listen) SetEvent(mgr_event);\r
+  if (std_listen) RPCRT4_sync_with_server_thread();\r
 \r
   return RPC_S_OK;\r
 }\r
index c2250a8..b098786 100644 (file)
@@ -72,7 +72,7 @@
 @ stub RpcGetAsyncCallStatus\r
 @ stub RpcIfIdVectorFree\r
 @ stub RpcIfInqId\r
-@ stub RpcImpersonateClient\r
+@ stdcall RpcImpersonateClient(ptr)\r
 @ stub RpcInitializeAsyncHandle\r
 @ stub RpcMgmtBindingInqParameter # win9x\r
 @ stub RpcMgmtBindingSetParameter # win9x\r
index 62b1843..230baae 100644 (file)
@@ -84,7 +84,9 @@ HANDLE RPCRT4_RpcssNPConnect(void)
     if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))\r
     {\r
       ERR("Named pipe unavailable after waiting.  Something is probably wrong.\n");\r
-      return NULL;\r
+      CloseHandle(the_pipe);\r
+      the_pipe = NULL;\r
+      break;\r
     }\r
 \r
   }\r
index c94c228..c98583e 100644 (file)
@@ -187,8 +187,7 @@ RtlClearBits(PRTL_BITMAP BitMapHeader,
   if (StartingIndex >= Size || NumberToClear == 0)
     return;
 
-  if (StartingIndex + NumberToClear > Size)
-    NumberToClear = Size - StartingIndex;
+  ASSERT(StartingIndex + NumberToClear <= Size);
 
   Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
   while (NumberToClear)
@@ -834,8 +833,7 @@ RtlSetBits(PRTL_BITMAP BitMapHeader,
   if (StartingIndex >= Size || NumberToSet == 0)
     return;
 
-  if (StartingIndex + NumberToSet > Size)
-    NumberToSet = Size - StartingIndex;
+  ASSERT(StartingIndex + NumberToSet <= Size);
 
   Ptr = (PULONG)BitMapHeader->Buffer + (StartingIndex / 32);
   while (NumberToSet)
index 7765d67..3e7541b 100644 (file)
@@ -20,7 +20,7 @@
 /* INCLUDES *****************************************************************/
 
 #include <ddk/ntddk.h>
-#include <errors.h>
+#include <winerror.h>
 
 #define NDEBUG
 #include <debug.h>
index 013dfb8..6987763 100644 (file)
@@ -18,7 +18,10 @@ endif
 
 TARGET_OBJECTS = \
        acl.o \
+       ppb.o \
        bit.o \
+       thread.o \
+       process.o \
        bitmap.o \
        bootdata.o \
        compress.o \
@@ -46,6 +49,7 @@ TARGET_OBJECTS = \
        unicode.o \
        unicodeprefix.o \
        version.o \
+       i386/chkstk.o \
        i386/exception.o \
        i386/except.o
 
similarity index 94%
rename from reactos/lib/ntdll/rtl/ppb.c
rename to reactos/lib/rtl/ppb.c
index d05a963..c923244 100644 (file)
@@ -12,7 +12,6 @@
 /* INCLUDES ****************************************************************/
 
 #include <ddk/ntddk.h>
-#include <windows.h>
 #include <ntdll/ldr.h>
 #include <napi/teb.h>
 #include <ntdll/base.h>
 #define ALIGN(x,align)      (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
 
 
-/* FUNCTIONS ****************************************************************/
+KPROCESSOR_MODE
+RtlpGetMode();
 
-/*
- * @implemented
- */
-VOID STDCALL
-RtlAcquirePebLock(VOID)
-{
-   PPEB Peb = NtCurrentPeb ();
-   Peb->FastPebLockRoutine (Peb->FastPebLock);
-}
 
+/* FUNCTIONS ****************************************************************/
 
-/*
- * @implemented
- */
-VOID STDCALL
-RtlReleasePebLock(VOID)
-{
-   PPEB Peb = NtCurrentPeb ();
-   Peb->FastPebUnlockRoutine (Peb->FastPebLock);
-}
 
 static inline VOID
 RtlpCopyParameterString(PWCHAR *Ptr,
@@ -100,7 +83,7 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
    EmptyString.MaximumLength = sizeof(WCHAR);
    EmptyString.Buffer = L"";
 
-   if (NtCurrentPeb()->ProcessParameters)
+   if (RtlpGetMode() == UserMode)
      {
        if (DllPath == NULL)
          DllPath = &NtCurrentPeb()->ProcessParameters->DllPath;
@@ -152,7 +135,7 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
    /* Calculate the required block size */
    RegionSize = ROUNDUP(Length, PAGE_SIZE);
 
-   Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+   Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                    (PVOID*)&Param,
                                    0,
                                    &RegionSize,
@@ -253,7 +236,7 @@ RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
 {
    ULONG RegionSize = 0;
 
-   return NtFreeVirtualMemory (NtCurrentProcess (),
+   return ZwFreeVirtualMemory (NtCurrentProcess (),
                        (PVOID)ProcessParameters,
                        &RegionSize,
                        MEM_RELEASE);
diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c
new file mode 100644 (file)
index 0000000..ff27c21
--- /dev/null
@@ -0,0 +1,317 @@
+/* $Id$
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/ntdll/rtl/process.c
+ * PURPOSE:         Process functions
+ * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
+ * UPDATE HISTORY:
+ *                  Created 01/11/98
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <napi/i386/segment.h>
+#include <ntdll/ldr.h>
+#include <ntdll/base.h>
+#include <ntdll/rtl.h>
+
+#define NDEBUG
+#include <ntdll/ntdll.h>
+
+/* FUNCTIONS ****************************************************************/
+
+
+static NTSTATUS
+RtlpMapFile(PUNICODE_STRING ImageFileName,
+            PRTL_USER_PROCESS_PARAMETERS Ppb,
+           ULONG Attributes,
+           PHANDLE Section)
+{
+   HANDLE hFile;
+   IO_STATUS_BLOCK IoStatusBlock;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+   NTSTATUS Status;
+   
+   hFile = NULL;
+
+   RtlDeNormalizeProcessParams (Ppb);
+
+//   DbgPrint("ImagePathName %x\n", Ppb->ImagePathName.Buffer);
+   
+   InitializeObjectAttributes(&ObjectAttributes,
+                             ImageFileName,
+                             Attributes & (OBJ_CASE_INSENSITIVE | OBJ_INHERIT),
+                             NULL,
+                             SecurityDescriptor);
+
+   RtlNormalizeProcessParams (Ppb);
+   
+   /*
+    * Try to open the executable
+    */
+
+   Status = ZwOpenFile(&hFile,
+                       SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
+                       &ObjectAttributes,
+                       &IoStatusBlock,
+                       FILE_SHARE_DELETE|FILE_SHARE_READ,
+                       FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
+
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+
+   Status = ZwCreateSection(Section,
+                           SECTION_ALL_ACCESS,
+                           NULL,
+                           NULL,
+                           PAGE_EXECUTE,
+                           SEC_IMAGE,
+                           hFile);
+   ZwClose(hFile);
+
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+
+   return(STATUS_SUCCESS);
+}
+
+static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
+                          PRTL_USER_PROCESS_PARAMETERS Ppb,
+                          PVOID* ImageBaseAddress)
+{
+   NTSTATUS Status;
+   PVOID PpbBase;
+   ULONG PpbSize;
+   ULONG BytesWritten;
+   ULONG Offset;
+   PVOID EnvPtr = NULL;
+   ULONG EnvSize = 0;
+
+   /* create the Environment */
+   if (Ppb->Environment != NULL)
+     {
+       MEMORY_BASIC_INFORMATION MemInfo;
+
+   Status = ZwQueryVirtualMemory (NtCurrentProcess (),
+                                      Ppb->Environment,
+                                      MemoryBasicInformation,
+                                      &MemInfo,
+                                      sizeof(MEMORY_BASIC_INFORMATION),
+                                      NULL);
+       if (!NT_SUCCESS(Status))
+         {
+            return Status;
+         }
+       EnvSize = MemInfo.RegionSize;
+     }
+   DPRINT("EnvironmentSize %ld\n", EnvSize);
+
+   /* allocate and initialize new environment block */
+   if (EnvSize != 0)
+     {
+   Status = ZwAllocateVirtualMemory(ProcessHandle,
+                                        &EnvPtr,
+                                        0,
+                                        &EnvSize,
+                                        MEM_RESERVE | MEM_COMMIT,
+                                        PAGE_READWRITE);
+       if (!NT_SUCCESS(Status))
+         {
+            return(Status);
+         }
+
+   ZwWriteVirtualMemory(ProcessHandle,
+                            EnvPtr,
+                            Ppb->Environment,
+                            EnvSize,
+                            &BytesWritten);
+     }
+   DPRINT("EnvironmentPointer %p\n", EnvPtr);
+
+   /* create the PPB */
+   PpbBase = NULL;
+   PpbSize = Ppb->AllocationSize;
+
+   Status = ZwAllocateVirtualMemory(ProcessHandle,
+                                   &PpbBase,
+                                   0,
+                                   &PpbSize,
+                                   MEM_RESERVE | MEM_COMMIT,
+                                   PAGE_READWRITE);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+
+   DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize);
+
+   /* write process parameters block*/
+   RtlDeNormalizeProcessParams (Ppb);
+   ZwWriteVirtualMemory(ProcessHandle,
+                       PpbBase,
+                       Ppb,
+                       Ppb->AllocationSize,
+
+                       &BytesWritten);
+   RtlNormalizeProcessParams (Ppb);
+
+   /* write pointer to environment */
+   Offset = FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment);
+   ZwWriteVirtualMemory(ProcessHandle,
+                       (PVOID)(PpbBase + Offset),
+                       &EnvPtr,
+                       sizeof(EnvPtr),
+                       &BytesWritten);
+
+   /* write pointer to process parameter block */
+   Offset = FIELD_OFFSET(PEB, ProcessParameters);
+   ZwWriteVirtualMemory(ProcessHandle,
+                       (PVOID)(PEB_BASE + Offset),
+                       &PpbBase,
+                       sizeof(PpbBase),
+                       &BytesWritten);
+
+   /* Read image base address. */
+   Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
+   ZwReadVirtualMemory(ProcessHandle,
+                      (PVOID)(PEB_BASE + Offset),
+                      ImageBaseAddress,
+                      sizeof(PVOID),
+                      &BytesWritten);
+
+   return(STATUS_SUCCESS);
+}
+
+
+/*
+ * @implemented
+ *
+ * Creates a process and its initial thread.
+ *
+ * NOTES:
+ *  - The first thread is created suspended, so it needs a manual resume!!!
+ *  - If ParentProcess is NULL, current process is used
+ *  - ProcessParameters must be normalized
+ *  - Attributes are object attribute flags used when opening the ImageFileName. 
+ *    Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
+ *
+ * -Gunnar
+ */
+NTSTATUS STDCALL
+RtlCreateUserProcess(
+   IN PUNICODE_STRING ImageFileName,
+   IN ULONG Attributes,
+   IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
+   IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor  OPTIONAL,
+   IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor  OPTIONAL,
+   IN HANDLE ParentProcess  OPTIONAL,
+   IN BOOLEAN InheritHandles,
+   IN HANDLE DebugPort  OPTIONAL,
+   IN HANDLE ExceptionPort  OPTIONAL,
+   OUT PRTL_PROCESS_INFO ProcessInfo
+   )
+{
+   HANDLE hSection;
+   NTSTATUS Status;
+   PROCESS_BASIC_INFORMATION ProcessBasicInfo;
+   ULONG retlen;
+   SECTION_IMAGE_INFORMATION Sii;
+   ULONG ResultLength;
+   PVOID ImageBaseAddress;
+   
+   DPRINT("RtlCreateUserProcess\n");
+   
+   Status = RtlpMapFile(ImageFileName,
+                        ProcessParameters,
+                       Attributes,
+                       &hSection);
+   if( !NT_SUCCESS( Status ) )
+     return Status;
+
+   /*
+    * Create a new process
+    */
+   if (ParentProcess == NULL)
+     ParentProcess = NtCurrentProcess();
+
+   Status = ZwCreateProcess(&(ProcessInfo->ProcessHandle),
+                           PROCESS_ALL_ACCESS,
+                           NULL,
+                           ParentProcess,
+             InheritHandles,
+                           hSection,
+                           DebugPort,
+                           ExceptionPort);
+   if (!NT_SUCCESS(Status))
+     {
+   ZwClose(hSection);
+       return(Status);
+     }
+   
+   /*
+    * Get some information about the process
+    */
+   ZwQueryInformationProcess(ProcessInfo->ProcessHandle,
+                            ProcessBasicInformation,
+                            &ProcessBasicInfo,
+                            sizeof(ProcessBasicInfo),
+                            &retlen);
+   DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
+         ProcessBasicInfo.UniqueProcessId);
+   ProcessInfo->ClientId.UniqueProcess = (HANDLE)ProcessBasicInfo.UniqueProcessId;
+
+   /*
+    * Create Process Environment Block
+    */
+   DPRINT("Creating peb\n");
+   KlInitPeb(ProcessInfo->ProcessHandle,
+            ProcessParameters,
+            &ImageBaseAddress);
+
+   Status = ZwQuerySection(hSection,
+                          SectionImageInformation,
+                          &Sii,
+                          sizeof(Sii),
+                          &ResultLength);
+   if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
+     {
+       DPRINT("Failed to get section image information.\n");
+       ZwClose(hSection);
+       return(Status);
+     }
+
+   DPRINT("Creating thread for process\n");
+   Status = RtlCreateUserThread(
+      ProcessInfo->ProcessHandle,
+      NULL,
+      TRUE, /* CreateSuspended? */
+      0,
+      &Sii.StackReserve,
+      &Sii.StackCommit,
+      ImageBaseAddress + (ULONG)Sii.EntryPoint,
+      (PVOID)PEB_BASE,
+      &ProcessInfo->ThreadHandle,
+      &ProcessInfo->ClientId
+      );
+
+   ZwClose(hSection);
+   
+   if (!NT_SUCCESS(Status))
+   {
+       DPRINT("Failed to create thread\n");
+       return(Status);
+   }
+
+   return(STATUS_SUCCESS);
+}
+
+
+
+/* EOF */
index 147aa85..9a68976 100644 (file)
@@ -1,5 +1,6 @@
 <module name="rtl" type="staticlibrary">\r
        <directory name="i386">\r
+               <file>chkstk.s</file>\r
                <file>except.s</file>\r
                <file>exception.c</file>\r
        </directory>\r
        <file>mem.c</file>\r
        <file>network.c</file>\r
        <file>nls.c</file>\r
+       <file>ppb.c</file>\r
+       <file>process.c</file>\r
        <file>random.c</file>\r
        <file>registry.c</file>\r
        <file>sd.c</file>\r
        <file>security.c</file>\r
        <file>sid.c</file>\r
        <file>splaytree.c</file>\r
+       <file>thread.c</file>\r
        <file>time.c</file>\r
        <file>timezone.c</file>\r
        <file>unicode.c</file>\r
index 4c87664..1194d3a 100644 (file)
@@ -200,7 +200,7 @@ RtlCopySidAndAttributesArray(ULONG Count,
       RtlCopySid(SidLength,
                  SidArea,
                  Src[i].Sid);
-      SidArea = SidArea + SidLength;
+      SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
    }
    *RemainingSidArea = SidArea;
    *RemainingSidAreaSize = Length;
similarity index 99%
rename from reactos/lib/ntdll/rtl/thread.c
rename to reactos/lib/rtl/thread.c
index f92aaca..50780f0 100644 (file)
@@ -18,7 +18,6 @@
 
 /* INCLUDES *****************************************************************/
 
-#define NTOS_MODE_USER
 #include <ntos.h>
 
 #define NDEBUG
index 9905fc9..8236047 100644 (file)
@@ -2256,6 +2256,8 @@ RtlCreateUnicodeString(
 
 /*
  * private
+ *
+ * Creates a nullterminated UNICODE_STRING
  */
 BOOLEAN
 FASTCALL
@@ -2671,4 +2673,33 @@ RtlpDuplicateUnicodeString(
    return STATUS_SUCCESS;
 }
 
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+RtlValidateUnicodeString(IN ULONG Flags,
+                         IN PUNICODE_STRING UnicodeString)
+{
+  /* currently no flags are supported! */
+  ASSERT(Flags == 0);
+  
+  if ((Flags == 0) &&
+      ((UnicodeString == NULL) ||
+       ((UnicodeString->Length != 0) &&
+        (UnicodeString->Buffer != NULL) &&
+        ((UnicodeString->Length % sizeof(WCHAR)) == 0) &&
+        ((UnicodeString->MaximumLength % sizeof(WCHAR)) == 0) &&
+        (UnicodeString->MaximumLength >= UnicodeString->Length))))
+  {
+    /* a NULL pointer as a unicode string is considered to be a valid unicode
+       string! */
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+}
+
 /* EOF */
index 5d954b4..49920db 100644 (file)
@@ -1,6 +1,10 @@
 /*
  *  ReactOS kernel
  *  Copyright (C) 2004 ReactOS Team
+ *  Copyright 1997 Marcus Meissner
+ *  Copyright 1998 Patrik Stridvall
+ *  Copyright 1998, 2003 Andreas Mohr
+ *  Copyright 1997, 2003 Alexandre Julliard
  *
  *  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
 
 /* GLOBALS ******************************************************************/
 
+NTSTATUS
+STDCALL
+RtlGetVersion(
+    OUT PRTL_OSVERSIONINFOW lpVersionInformation
+    );
 
 /* FUNCTIONS ****************************************************************/
 
 /*
-* @unimplemented
+* @implemented
 */
-/*
 NTSTATUS
 STDCALL
 RtlVerifyVersionInfo(
        IN PRTL_OSVERSIONINFOEXW VersionInfo,
        IN ULONG TypeMask,
-       IN ULONGLONG  ConditionMask
+       IN ULONGLONG ConditionMask
        )
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+    RTL_OSVERSIONINFOEXW ver;
+    NTSTATUS status;
+
+    /* FIXME:
+        - Check the following special case on Windows (various versions):
+          o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
+          o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
+        - MSDN talks about some tests being impossible. Check what really happens.
+     */
+
+    ver.dwOSVersionInfoSize = sizeof(ver);
+    if ((status = RtlGetVersion( (PRTL_OSVERSIONINFOW)&ver )) != STATUS_SUCCESS) return status;
+
+    if(!(TypeMask && ConditionMask)) return STATUS_INVALID_PARAMETER;
+
+    if(TypeMask & VER_PRODUCT_TYPE)
+        switch(ConditionMask >> 7*3 & 0x07) {
+            case VER_EQUAL:
+                if(ver.wProductType != VersionInfo->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wProductType <= VersionInfo->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wProductType < VersionInfo->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wProductType >= VersionInfo->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wProductType > VersionInfo->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_SUITENAME)
+        switch(ConditionMask >> 6*3 & 0x07)
+        {
+            case VER_AND:
+                if((VersionInfo->wSuiteMask & ver.wSuiteMask) != VersionInfo->wSuiteMask)
+                    return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_OR:
+                if(!(VersionInfo->wSuiteMask & ver.wSuiteMask) && VersionInfo->wSuiteMask)
+                    return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_PLATFORMID)
+        switch(ConditionMask >> 3*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwPlatformId != VersionInfo->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwPlatformId <= VersionInfo->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwPlatformId < VersionInfo->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwPlatformId >= VersionInfo->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwPlatformId > VersionInfo->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_BUILDNUMBER)
+        switch(ConditionMask >> 2*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwBuildNumber != VersionInfo->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwBuildNumber <= VersionInfo->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwBuildNumber < VersionInfo->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwBuildNumber >= VersionInfo->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwBuildNumber > VersionInfo->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_MAJORVERSION)
+        switch(ConditionMask >> 1*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwMajorVersion != VersionInfo->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwMajorVersion <= VersionInfo->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwMajorVersion < VersionInfo->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwMajorVersion >= VersionInfo->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwMajorVersion > VersionInfo->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_MINORVERSION)
+        switch(ConditionMask >> 0*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwMinorVersion != VersionInfo->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwMinorVersion <= VersionInfo->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwMinorVersion < VersionInfo->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwMinorVersion >= VersionInfo->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwMinorVersion > VersionInfo->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_SERVICEPACKMAJOR)
+        switch(ConditionMask >> 5*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.wServicePackMajor != VersionInfo->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wServicePackMajor <= VersionInfo->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wServicePackMajor < VersionInfo->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wServicePackMajor >= VersionInfo->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wServicePackMajor > VersionInfo->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(TypeMask & VER_SERVICEPACKMINOR)
+        switch(ConditionMask >> 4*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.wServicePackMinor != VersionInfo->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wServicePackMinor <= VersionInfo->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wServicePackMinor < VersionInfo->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wServicePackMinor >= VersionInfo->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wServicePackMinor > VersionInfo->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+
+    return STATUS_SUCCESS;
 }
-*/
+
 
 /*
  Header hell made me do it, don't blame me. Please move these somewhere more
index de1b31f..22b194a 100644 (file)
 
 /* INCLUDES *****************************************************************/
 
-#include <windows.h>
 #include <stdio.h>
+#include <stdarg.h>
+
+#include <windef.h>
+#include <winbase.h>
 
 #include "debug.h"
 
index c71ee02..1839ada 100644 (file)
@@ -28,6 +28,7 @@
 /* INCLUDES *****************************************************************/
 
 #include <windows.h>
+#include <winerror.h>
 #include <string.h>
 
 #include <samlib.h>
diff --git a/reactos/lib/serialui/Makefile b/reactos/lib/serialui/Makefile
new file mode 100644 (file)
index 0000000..829ba3e
--- /dev/null
@@ -0,0 +1,36 @@
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = dynlink
+
+TARGET_NAME = serialui
+
+TARGET_BASE = $(TARGET_BASE_LIB_SERIALUI)
+
+TARGET_CFLAGS = \
+       -I./include \
+       -Wall \
+       -Werror \
+       -fno-builtin \
+       -DUNICODE \
+       -DLE \
+       -DDBG \
+       -D__USE_W32API
+
+TARGET_LFLAGS = -nostartfiles -nostdlib
+
+TARGET_SDKLIBS = kernel32.a user32.a shlwapi.a
+
+TARGET_OBJECTS = serialui.o
+
+DEP_OBJECTS := $(TARGET_OBJECTS)
+
+TARGET_CLEAN = $(DEP_FILES)
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
diff --git a/reactos/lib/serialui/resource.h b/reactos/lib/serialui/resource.h
new file mode 100644 (file)
index 0000000..05402aa
--- /dev/null
@@ -0,0 +1,32 @@
+#define IDS_EVENPARITY 2001
+#define IDS_MARKPARITY 2002
+#define IDS_NOPARITY 2003
+#define IDS_ODDPARITY 2004
+#define IDS_SPACEPARITY 2005
+
+#define IDS_ONESTOPBIT 2006
+#define IDS_ONE5STOPBITS 2007
+#define IDS_TWOSTOPBITS 2008
+
+#define IDS_FC_NO 2009
+#define IDS_FC_CTSRTS 2010
+#define IDS_FC_XONXOFF 2011
+
+#define IDS_TITLE 2012
+
+#define IDD_COMMDLG 1000
+#define IDC_GRP1 1001
+#define IDC_OKBTN 1002
+#define IDC_CANCELBTN 1003
+#define IDC_BTN 1004
+#define IDC_STC1 1005
+#define IDC_STC2 1006
+#define IDC_STC3 1007
+#define IDC_STC4 1008
+#define IDC_STC5 1009
+#define IDC_BAUDRATE 1010
+#define IDC_BYTESIZE 1011
+#define IDC_PARITY 1012
+#define IDC_STOPBITS 1013
+#define IDC_FLOW 1014
+#define IDC_RESTOREBTN 1015
diff --git a/reactos/lib/serialui/serialui.c b/reactos/lib/serialui/serialui.c
new file mode 100644 (file)
index 0000000..ba9461b
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS SerialUI DLL
+ * FILE:        serialui.c
+ * PUROPSE:     A dialog box to cunfigure COM port.
+ *              Functions to set(and get too) default configuration.
+ * PROGRAMMERS: Saveliy Tretiakov (saveliyt@mail.ru)
+ * REVISIONS:
+ *              ST   (05/04/2005) Created. Implemented drvCommConfigDialog.
+ */
+
+#include <serialui.h>
+
+static HINSTANCE hDllInstance;
+
+/************************************
+ *
+ *  DATA
+ *
+ ************************************/
+
+const DWORD Bauds[] = {
+       CBR_110,
+       CBR_300,
+       CBR_600,
+       CBR_1200,
+       CBR_2400,
+       CBR_4800,
+       CBR_9600,
+       CBR_14400,
+       CBR_19200,
+       CBR_38400,
+       CBR_56000,
+       CBR_57600,
+       CBR_115200,
+       CBR_128000,
+       CBR_256000,
+       0
+};
+
+const BYTE ByteSizes[] = {
+       5,
+       6,
+       7,
+       8,
+       0
+};
+
+
+const PARITY_INFO Parities[] = {
+       { EVENPARITY, IDS_EVENPARITY },
+       { MARKPARITY, IDS_MARKPARITY },
+       { NOPARITY, IDS_NOPARITY },
+       { ODDPARITY, IDS_ODDPARITY },
+       { SPACEPARITY, IDS_SPACEPARITY },
+       { 0, 0 }
+};
+
+const STOPBIT_INFO StopBits[] = {
+       { ONESTOPBIT, IDS_ONESTOPBIT },
+       { ONE5STOPBITS, IDS_ONE5STOPBITS },
+       { TWOSTOPBITS, IDS_TWOSTOPBITS },
+       { 0, 0 }
+};
+
+
+/************************************
+ *
+ *  DLLMAIN
+ *
+ ************************************/
+
+BOOL
+STDCALL
+DllMain(HINSTANCE hInstance,
+       DWORD dwReason,
+       LPVOID reserved)
+{
+       if(dwReason==DLL_PROCESS_ATTACH)
+       {
+               hDllInstance = hInstance;
+       }
+       else if(dwReason==DLL_THREAD_ATTACH)
+       {
+               DisableThreadLibraryCalls(hInstance);
+       }
+
+       return TRUE;
+}
+
+
+/************************************
+ *
+ *  EXPORTS
+ *
+ ************************************/
+
+/*
+ * @implemented
+ */
+BOOL WINAPI drvCommConfigDialogW(LPCWSTR lpszDevice,
+       HWND hWnd,
+       LPCOMMCONFIG lpCommConfig)
+{
+       DIALOG_INFO DialogInfo;
+
+       if(!lpszDevice || !lpCommConfig)
+       {
+               return FALSE;
+       }
+
+       DialogInfo.lpszDevice = lpszDevice;
+       DialogInfo.lpCC = lpCommConfig;
+
+       return DialogBoxParamW(hDllInstance, MAKEINTRESOURCEW(IDD_COMMDLG),
+                                       hWnd, (DLGPROC)CommDlgProc, (LPARAM)&DialogInfo);
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI drvCommConfigDialogA(LPCSTR lpszDevice,
+       HWND hWnd,
+       LPCOMMCONFIG lpCommConfig)
+{
+       BOOL result;
+       UINT len;
+       WCHAR *wstr;
+
+       len = MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, NULL, 0);
+       if((wstr = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR))))
+       {
+               MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, wstr, len);
+               result = drvCommConfigDialogW(wstr, hWnd, lpCommConfig);
+               HeapFree(GetProcessHeap(), 0, wstr);
+               return result;
+       }
+       else
+               return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL WINAPI drvSetDefaultCommConfigW(LPCWSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       DWORD dwSize)
+{
+       UNIMPLEMENTED
+}
+
+/*
+ * @unimplemented
+ */
+BOOL WINAPI drvSetDefaultCommConfigA(LPCSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       DWORD dwSize)
+{
+       UNIMPLEMENTED
+}
+
+/*
+ * @unimplemented
+ */
+BOOL WINAPI drvGetDefaultCommConfigW(LPCWSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       LPDWORD lpdwSize)
+{
+       UNIMPLEMENTED
+}
+
+/*
+ * @unimplemented
+ */
+BOOL WINAPI drvGetDefaultCommConfigA(LPCSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       LPDWORD lpdwSize)
+{
+       UNIMPLEMENTED
+}
+
+
+/************************************
+ *
+ *  INTERNALS
+ *
+ ************************************/
+
+LRESULT CommDlgProc(HWND hDlg,
+       UINT Msg,
+       WPARAM wParam,
+       LPARAM lParam)
+{
+       LPDIALOG_INFO lpDlgInfo = NULL;
+       HWND hBox;
+
+       switch (Msg)
+       {
+
+               case WM_INITDIALOG:
+               {
+                       WCHAR wstr[255];
+                       RECT rc, rcDlg, rcOwner;
+                       HWND hOwner;
+                       INT i;
+
+                       lpDlgInfo = (LPDIALOG_INFO)lParam;
+                       SetWindowLongPtrW(hDlg, DWL_USER, (LONG_PTR)lpDlgInfo);
+
+                       /* Set title */
+                       if(LoadStringW(hDllInstance, IDS_TITLE, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                       {
+                               SetWindowTextW(hDlg, wstr);
+                       }
+
+                        /* FIXME - this won't work correctly systems with multiple monitors! */
+                        if(!(hOwner = GetParent(hDlg)))
+                               hOwner = GetDesktopWindow();
+
+                       /* Position dialog in the center of owner window */
+                       GetWindowRect(hOwner, &rcOwner);
+                       GetWindowRect(hDlg, &rcDlg);
+                       CopyRect(&rc, &rcOwner);
+                       OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
+                       OffsetRect(&rc, -rc.left, -rc.top);
+                       OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
+                       SetWindowPos(hDlg, HWND_TOP,
+                               rcOwner.left + (rc.right / 2),
+                               rcOwner.top + (rc.bottom / 2),
+                               0, 0, SWP_NOSIZE);
+
+                       /* Initialize baud rate combo */
+                       if(!(hBox = GetDlgItem(hDlg, IDC_BAUDRATE)))
+                               EndDialog(hDlg, 0);
+
+                       for(i = 0; Bauds[i]; i++)
+                       {
+                                wsprintf(wstr, L"%d", Bauds[i]);
+                                SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
+                               if(Bauds[i] == lpDlgInfo->lpCC->dcb.BaudRate)
+                                       SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
+                       }
+
+                       if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
+                               SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BAUD_INDEX, 0);
+
+                       /* Initialize byte size combo */
+                       if(!(hBox = GetDlgItem(hDlg, IDC_BYTESIZE)))
+                               EndDialog(hDlg, 0);
+
+                       for(i = 0; ByteSizes[i]; i++)
+                       {
+                                wsprintf(wstr, L"%d", Bauds[i]);
+                                SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
+                               if(ByteSizes[i] == lpDlgInfo->lpCC->dcb.ByteSize)
+                                       SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
+                       }
+
+                       if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
+                               SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BYTESIZE_INDEX, 0);
+
+                       /* Initialize parity combo */
+                       if(!(hBox = GetDlgItem(hDlg, IDC_PARITY)))
+                               EndDialog(hDlg, 0);
+
+                       for(i = 0; Parities[i].StrId; i++)
+                       {
+                               if(LoadStringW(hDllInstance, Parities[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                               {
+                                       SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
+                                       if(Parities[i].Parity == lpDlgInfo->lpCC->dcb.Parity)
+                                               SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
+                               }
+                       }
+
+                       if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
+                               SendMessageW(hBox, CB_SETCURSEL, DEFAULT_PARITY_INDEX, 0);
+
+                       /* Initialize stop bits combo */
+                       if(!(hBox = GetDlgItem(hDlg, IDC_STOPBITS)))
+                               EndDialog(hDlg, 0);
+
+                       for(i = 0; StopBits[i].StrId; i++)
+                       {
+                               if(LoadStringW(hDllInstance, StopBits[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                               {
+                                       SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
+                                       if(StopBits[i].StopBit == lpDlgInfo->lpCC->dcb.StopBits)
+                                               SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
+                               }
+                       }
+
+                       if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
+                               SendMessageW(hBox, CB_SETCURSEL, DEFAULT_STOPBITS_INDEX, 0);
+
+                       /* Initialize flow control combo */
+                       if(!(hBox = GetDlgItem(hDlg, IDC_FLOW)))
+                               EndDialog(hDlg, 0);
+
+                       if(LoadStringW(hDllInstance, IDS_FC_NO, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                       {
+                               SendMessageW(hBox, CB_INSERTSTRING, 0, (LPARAM)wstr);
+                               SendMessageW(hBox, CB_SETCURSEL, 0, 0);
+                               lpDlgInfo->InitialFlowIndex = 0;
+                       }
+
+
+                       if(LoadStringW(hDllInstance, IDS_FC_CTSRTS, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                       {
+                               SendMessageW(hBox, CB_INSERTSTRING, 1, (LPARAM)wstr);
+                               if(lpDlgInfo->lpCC->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE
+                                       || lpDlgInfo->lpCC->dcb.fOutxCtsFlow == TRUE)
+                               {
+                                       SendMessageW(hBox, CB_SETCURSEL, 1, 0);
+                                       lpDlgInfo->InitialFlowIndex = 1;
+                               }
+                       }
+
+                       if(LoadStringW(hDllInstance, IDS_FC_XONXOFF, wstr, sizeof(wstr) / sizeof(wstr[0])))
+                       {
+                               SendMessageW(hBox, CB_INSERTSTRING, 2, (LPARAM)wstr);
+                               if(lpDlgInfo->lpCC->dcb.fOutX || lpDlgInfo->lpCC->dcb.fInX)
+                               {
+                                       SendMessageW(hBox, CB_SETCURSEL, 2, 0);
+                                       lpDlgInfo->InitialFlowIndex = 2;
+                               }
+                       }
+
+                       /* Set focus */
+                       SetFocus(GetDlgItem(hDlg, IDC_OKBTN));
+
+                       return FALSE;
+               } /* WM_INITDIALOG */
+
+               case WM_COMMAND:
+               {
+                       switch(wParam)
+                       {
+                               case IDC_CANCELBTN:
+                                       EndDialog(hDlg, FALSE);
+                                       break;
+                               case IDC_OKBTN:
+                                       OkButton(hDlg);
+                                       EndDialog(hDlg, TRUE);
+                                       break;
+                       }
+                       return TRUE;
+               } /* WM_COMMAND */
+
+               case WM_CLOSE:
+               {
+                       EndDialog(hDlg, FALSE);
+                       return TRUE;
+               } /* WM_CLOSE */
+
+                       default:
+                       return FALSE;
+       }
+
+}
+
+
+VOID OkButton(HWND hDlg)
+{
+       LPDIALOG_INFO lpDlgInfo;
+       UINT Index;
+
+       lpDlgInfo = (LPDIALOG_INFO) GetWindowLongPtrW(hDlg, DWL_USER);
+
+       /* Baud rate */
+       Index = SendMessageW(GetDlgItem(hDlg, IDC_BAUDRATE), CB_GETCURSEL, 0, 0);
+       lpDlgInfo->lpCC->dcb.BaudRate = Bauds[Index];
+
+       /* Byte size */
+       Index = SendMessageW(GetDlgItem(hDlg, IDC_BYTESIZE), CB_GETCURSEL, 0, 0);
+       lpDlgInfo->lpCC->dcb.ByteSize = ByteSizes[Index];
+
+       /* Parity */
+       Index = SendMessageW(GetDlgItem(hDlg, IDC_PARITY), CB_GETCURSEL, 0, 0);
+       lpDlgInfo->lpCC->dcb.Parity = Parities[Index].Parity;
+
+       /* Stop bits */
+       Index = SendMessageW(GetDlgItem(hDlg, IDC_STOPBITS), CB_GETCURSEL, 0, 0);
+       lpDlgInfo->lpCC->dcb.StopBits = StopBits[Index].StopBit;
+       
+       /* Flow Control */
+       Index = SendMessageW(GetDlgItem(hDlg, IDC_FLOW), CB_GETCURSEL, 0, 0);
+       if(lpDlgInfo->InitialFlowIndex != Index)
+       {
+               switch(Index)
+               {
+                       case 0: /* NO */
+                               lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
+                               lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
+                               lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
+                               lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
+                               lpDlgInfo->lpCC->dcb.fOutX = FALSE;
+                               lpDlgInfo->lpCC->dcb.fInX = FALSE;
+                               break;
+                       case 1: /* CTS/RTS */
+                               lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
+                               lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
+                               lpDlgInfo->lpCC->dcb.fOutxCtsFlow = TRUE;
+                               lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
+                               lpDlgInfo->lpCC->dcb.fOutX = FALSE;
+                               lpDlgInfo->lpCC->dcb.fInX = FALSE;
+                               break;
+                       case 2: /* XON/XOFF */
+                               lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
+                               lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
+                               lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
+                               lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
+                               lpDlgInfo->lpCC->dcb.fOutX = TRUE;
+                               lpDlgInfo->lpCC->dcb.fInX = TRUE;
+                               break;
+               }
+       }
+}
diff --git a/reactos/lib/serialui/serialui.def b/reactos/lib/serialui/serialui.def
new file mode 100644 (file)
index 0000000..2b38aba
--- /dev/null
@@ -0,0 +1,10 @@
+LIBRARY serialui.dll
+
+EXPORTS
+drvCommConfigDialogW@12
+drvCommConfigDialogA@12
+drvSetDefaultCommConfigW@12
+drvSetDefaultCommConfigA@12
+drvGetDefaultCommConfigW@12 
+drvGetDefaultCommConfigA@12
+
diff --git a/reactos/lib/serialui/serialui.h b/reactos/lib/serialui/serialui.h
new file mode 100644 (file)
index 0000000..e998a21
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS SerialUI DLL
+ * FILE:        serialui.h
+ * PURPOSE:     header file
+ * PROGRAMMERS: Saveliy Tretiakov (saveliyt@mail.ru)
+ */
+
+#include <windows.h>
+#include <shlwapi.h>
+#include "resource.h"
+
+#define UNIMPLEMENTED \
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED); \
+  return FALSE;
+
+#define DEFAULT_BAUD_INDEX 6
+#define DEFAULT_BYTESIZE_INDEX 3
+#define DEFAULT_PARITY_INDEX 2
+#define DEFAULT_STOPBITS_INDEX 0
+
+typedef struct _DIALOG_INFO
+{
+       LPCWSTR lpszDevice;
+       UINT InitialFlowIndex;
+       LPCOMMCONFIG lpCC;
+} DIALOG_INFO, *LPDIALOG_INFO;
+
+typedef struct _PARITY_INFO
+{
+       BYTE Parity;
+       UINT StrId;
+} PARITY_INFO, *PPARITY_INFO;
+
+typedef struct _STOPBIT_INFO
+{
+       BYTE StopBit;
+       UINT StrId;
+} STOPBIT_INFO, *PSTOPBIT_INFO;
+
+
+/************************************
+ *
+ *  EXPORTS
+ *
+ ************************************/
+
+BOOL WINAPI drvCommConfigDialogW(LPCWSTR lpszDevice,
+       HWND hWnd,
+       LPCOMMCONFIG lpCommConfig);
+
+BOOL WINAPI drvCommConfigDialogA(LPCSTR lpszDevice,
+       HWND hWnd,
+       LPCOMMCONFIG lpCommConfig);
+
+BOOL WINAPI drvSetDefaultCommConfigW(LPCWSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       DWORD dwSize);
+
+BOOL WINAPI drvSetDefaultCommConfigA(LPCSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       DWORD dwSize);
+
+BOOL WINAPI drvGetDefaultCommConfigW(LPCWSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       LPDWORD lpdwSize);
+
+BOOL WINAPI drvGetDefaultCommConfigA(LPCSTR lpszDevice,
+       LPCOMMCONFIG lpCommConfig,
+       LPDWORD lpdwSize);
+
+
+/************************************
+ *
+ *  INTERNALS
+ *
+ ************************************/
+
+LRESULT CommDlgProc(HWND hDlg,
+       UINT Msg,
+       WPARAM wParam,
+       LPARAM lParam);
+
+VOID OkButton(HWND hDlg);
+
+
diff --git a/reactos/lib/serialui/serialui.rc b/reactos/lib/serialui/serialui.rc
new file mode 100644 (file)
index 0000000..75adeb6
--- /dev/null
@@ -0,0 +1,48 @@
+#include "resource.h"
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS SerialUI DLL\0"
+#define REACTOS_STR_INTERNAL_NAME      "serialui\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "serialui.dll\0"
+#include <reactos/version.rc>
+
+
+STRINGTABLE LOADONCALL DISCARDABLE
+BEGIN
+       IDS_EVENPARITY, "Even"
+       IDS_MARKPARITY, "Mark"
+       IDS_NOPARITY, "No parity"
+       IDS_ODDPARITY, "Odd"
+       IDS_SPACEPARITY, "Space"
+
+       IDS_ONESTOPBIT, "1 stop bit"
+       IDS_ONE5STOPBITS, "1.5 stop bits"
+       IDS_TWOSTOPBITS, "2 stop bits"
+
+       IDS_FC_NO, "No"
+       IDS_FC_CTSRTS, "CTS/RTS"
+       IDS_FC_XONXOFF, "XON/XOFF"
+
+       IDS_TITLE, "Properties for %s"
+END
+
+IDD_COMMDLG DIALOGEX 6,5,222,175
+FONT 8,"MS Sans Serif"
+STYLE 0x10C80080
+EXSTYLE 0x00000001
+BEGIN
+       CONTROL "",IDC_GRP1,"Button",0x50000007,6,5,210,146,0x00000000
+       CONTROL "OK",IDC_OKBTN,"Button",0x50010000,98,156,56,13,0x00000000
+       CONTROL "Cancel",IDC_CANCELBTN,"Button",0x50010000,158,156,56,13,0x00000000
+       CONTROL "Baud rate:",IDC_STC1,"Static",0x50000000,24,31,42,9,0x00000000
+       CONTROL "Byte size:",IDC_STC2,"Static",0x50000000,24,53,42,9,0x00000000
+       CONTROL "Parity:",IDC_STC3,"Static",0x50000000,24,73,42,9,0x00000000
+       CONTROL "Stop bits:",IDC_STC4,"Static",0x50000000,24,96,42,9,0x00000000
+       CONTROL "Flow control:",IDC_STC5,"Static",0x50000000,24,120,42,9,0x00000000
+       CONTROL "",IDC_BAUDRATE,"ComboBox",0x50210003,98,29,100,50,0x00000000
+       CONTROL "",IDC_BYTESIZE,"ComboBox",0x50210003,98,49,100,50,0x00000000
+       CONTROL "",IDC_PARITY,"ComboBox",0x50210003,98,72,100,50,0x00000000
+       CONTROL "",IDC_STOPBITS,"ComboBox",0x50210003,98,94,100,50,0x00000000
+       CONTROL "",IDC_FLOW,"ComboBox",0x50210003,98,116,100,50,0x00000000
+END
+
index 330eedd..54d5ab0 100644 (file)
@@ -1,35 +1,35 @@
-/*
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Kopíruji soubory..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Storno", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Zdroj:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Cíl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * Czech resources for SETUPAPI\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ * Copyright 2004 David Kredba\r
+ * \r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Kopíruji soubory..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Storno", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Zdroj:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Cíl:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
diff --git a/reactos/lib/setupapi/Da.rc b/reactos/lib/setupapi/Da.rc
new file mode 100644 (file)
index 0000000..5b4c24d
--- /dev/null
@@ -0,0 +1,15 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Overførere Filer..."
+FONT 8, "MS Shell Dlg"
+BEGIN
+       PUSHBUTTON "Fortryd", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+       LTEXT "Kilde:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
+       LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD |
+WS_VISIBLE | WS_TABSTOP
+END
index 0fd9555..0850739 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * German resources for SETUPAPI
- *
- * Copyright 2004 Henning Gerhardt
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Dateien kopieren..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Abbrechen", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Quelle:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Ziel:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * German resources for SETUPAPI\r
+ *\r
+ * Copyright 2004 Henning Gerhardt\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Dateien kopieren..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Abbrechen", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Quelle:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Ziel:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index aa504ca..bd142fa 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * English resources for SETUPAPI
- *
- * Copyright 2001 Andreas Mohr
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Copying Files..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * English resources for SETUPAPI\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Copying Files..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Cancel", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index f09e276..6ccd146 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * Spanish resources for SETUPAPI
- *
- * Copyright 2003 José Manuel Ferrer Ortiz
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Copiando archivos..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Origen:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * Spanish resources for SETUPAPI\r
+ *\r
+ * Copyright 2003 José Manuel Ferrer Ortiz\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Copiando archivos..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Origen:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index 40f0171..43d4fb3 100644 (file)
@@ -1,35 +1,35 @@
-/*
- * French resources for SETUPAPI
- *
- * Copyright 2001 Andreas Mohr
- * Copyright 2003 Vincent Béron
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Copie de fichiers..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Annuler", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * French resources for SETUPAPI\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ * Copyright 2003 Vincent Béron\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Copie de fichiers..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Annuler", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Source:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destination:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index dc7b679..7a47c7e 100644 (file)
@@ -1,35 +1,35 @@
-/*
- * Italian resources for SETUPAPI
- *
- * Copyright 2001 Andreas Mohr
- * Copyright 2003 Ivan Leo Puoti
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Copia dei file in corso..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Anulla", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Origine:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Destinazione:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * Italian resources for SETUPAPI\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ * Copyright 2003 Ivan Leo Puoti\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Copia dei file in corso..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Anulla", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Origine:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destinazione:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index 0351366..96cb39c 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * Japanese resources for SETUPAPI
- *
- * Copyright 2004 Hajime Segawa
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "\83t\83@\83C\83\8b\82ð\83R\83s\81[\82µ\82Ä\82¢\82Ü\82·..."
-FONT 9, "MS UI Gothic"
-BEGIN
-       PUSHBUTTON "\83L\83\83\83\93\83Z\83\8b", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "\83R\83s\81[\8c³:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "\83R\83s\81[\90æ:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * Japanese resources for SETUPAPI\r
+ *\r
+ * Copyright 2004 Hajime Segawa\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "\83t\83@\83C\83\8b\82ð\83R\83s\81[\82µ\82Ä\82¢\82Ü\82·..."\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+       PUSHBUTTON "\83L\83\83\83\93\83Z\83\8b", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "\83R\83s\81[\8c³:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "\83R\83s\81[\90æ:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index e502e29..6321589 100644 (file)
@@ -1,35 +1,37 @@
-EXTRADEFS = -D_SETUPAPI_
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR    = @srcdir@
-VPATH     = @srcdir@
-MODULE    = setupapi.dll
-IMPORTS   = user32 version advapi32 rpcrt4 kernel32 ntdll
-DELAYIMPORTS = shell32
-EXTRALIBS = $(LIBUNICODE)
-
-C_SRCS = \
-       cfgmgr.c \
-       devinst.c \
-       dirid.c \
-       diskspace.c \
-       install.c \
-       misc.c \
-       parser.c \
-       queue.c \
-       setupcab.c \
-       stubs.c
-
-C_SRCS16 = \
-       devinst16.c \
-       infparse.c \
-       setupx_main.c \
-       virtcopy.c
-
-SPEC_SRCS16 = setupx.spec
-
-RC_SRCS= setupapi.rc
-
-@MAKE_DLL_RULES@
-
-### Dependencies:
+EXTRADEFS = -D_SETUPAPI_\r
+TOPSRCDIR = @top_srcdir@\r
+TOPOBJDIR = ../..\r
+SRCDIR    = @srcdir@\r
+VPATH     = @srcdir@\r
+MODULE    = setupapi.dll\r
+IMPORTS   = user32 version advapi32 rpcrt4 kernel32 ntdll\r
+DELAYIMPORTS = shell32\r
+EXTRALIBS = $(LIBUNICODE)\r
+\r
+C_SRCS = \\r
+       pnp_c.c \\r
+       cfgmgr.c \\r
+       devinst.c \\r
+       dirid.c \\r
+       diskspace.c \\r
+       install.c \\r
+       misc.c \\r
+       parser.c \\r
+       queue.c \\r
+       setupcab.c \\r
+       stubs.c \\r
+       rpc.c\r
+\r
+C_SRCS16 = \\r
+       devinst16.c \\r
+       infparse.c \\r
+       setupx_main.c \\r
+       virtcopy.c\r
+\r
+SPEC_SRCS16 = setupx.spec\r
+\r
+RC_SRCS= setupapi.rc\r
+\r
+@MAKE_DLL_RULES@\r
+\r
+### Dependencies:\r
index 76dc7ed..d7c6f13 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * setupapi (Dutch resources)
- *
- * Copyright 2003 Hans Leidekker
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Bestanden worden gekopiëerd..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Annuleren", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Bron:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Bestemming:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * setupapi (Dutch resources)\r
+ *\r
+ * Copyright 2003 Hans Leidekker\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Bestanden worden gekopiëerd..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Annuleren", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Bron:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Bestemming:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index 69bede2..dacb2b4 100644 (file)
@@ -1,34 +1,50 @@
-/*
- * Portuguese resources for SETUPAPI
- *
- * Copyright 2003 Marcelo Duarte
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Copiando arquivos..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * Portuguese resources for SETUPAPI\r
+ *\r
+ * Copyright 2003 Marcelo Duarte\r
+ * Copyright 2004 Américo José Melo\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Copiando arquivos..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
+\r
+LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "A copiar ficheiros..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Cancelar", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Origem:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Destino:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index 3efa242..09ee4f6 100644 (file)
@@ -1,34 +1,34 @@
-/*
- * SETUPAPI (Russian resources)
- *
- * Copyright 2003 Igor Stepin
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
-
-COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105
-STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION
-CAPTION "Êîïèðîâàíèå ôàéëîâ..."
-FONT 8, "MS Shell Dlg"
-BEGIN
-       PUSHBUTTON "Îòìåíà", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-       LTEXT "Îòêóäà:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "Êóäà:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP
-       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP
-       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP
-END
+/*\r
+ * SETUPAPI (Russian resources)\r
+ *\r
+ * Copyright 2003 Igor Stepin\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT\r
+\r
+COPYFILEDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 20, 20, 208, 105\r
+STYLE DS_MODALFRAME | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION\r
+CAPTION "Êîïèðîâàíèå ôàéëîâ..."\r
+FONT 8, "MS Shell Dlg"\r
+BEGIN\r
+       PUSHBUTTON "Îòìåíà", IDCANCEL, 79, 84, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+       LTEXT "Îòêóäà:", -1, 7, 7, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", SOURCESTRORD, 7, 18, 194, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "Êóäà:", -1, 7, 30, 77, 11, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       LTEXT "", DESTSTRORD, 7, 41, 194, 22, WS_CHILD | WS_VISIBLE | WS_GROUP\r
+       CONTROL "", PROGRESSORD, "setupx_progress", 7, 63, 194, 13, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
index 91021b5..517a7b9 100644 (file)
 #include "winreg.h"\r
 #include "setupapi.h"\r
 #include "cfgmgr32.h"\r
+#include "setupapi_private.h"\r
+\r
+#include "rpc.h"\r
+\r
+#include "pnp_c.h"\r
 \r
 #include "wine/debug.h"\r
 \r
 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
 \r
+typedef struct _MACHINE_INFO\r
+{\r
+  RPC_BINDING_HANDLE BindingHandle;\r
+} MACHINE_INFO, *PMACHINE_INFO;\r
+\r
 \r
 /***********************************************************************\r
  * CM_Connect_MachineA [SETUPAPI.@]\r
@@ -46,14 +56,10 @@ CONFIGRET WINAPI CM_Connect_MachineA(PCSTR UNCServerName, PHMACHINE phMachine)
     TRACE("%s %p\n", UNCServerName, phMachine);\r
 \r
     if (UNCServerName == NULL || *UNCServerName == 0)\r
-    {\r
         return CM_Connect_MachineW(NULL, phMachine);\r
-    }\r
 \r
     if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))\r
-    {\r
         return CR_INVALID_DATA;\r
-    }\r
 \r
     ret = CM_Connect_MachineW(pServerNameW, phMachine);\r
 \r
@@ -68,8 +74,23 @@ CONFIGRET WINAPI CM_Connect_MachineA(PCSTR UNCServerName, PHMACHINE phMachine)
  */\r
 CONFIGRET WINAPI CM_Connect_MachineW(PCWSTR UNCServerName, PHMACHINE phMachine)\r
 {\r
-    FIXME("%s %p\n", debugstr_w(UNCServerName), phMachine);\r
-    return CR_ACCESS_DENIED;\r
+    PMACHINE_INFO pMachine;\r
+\r
+    TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);\r
+\r
+    pMachine = (PMACHINE_INFO)GlobalAlloc(GPTR, sizeof(MACHINE_INFO));\r
+    if (pMachine == NULL)\r
+        return CR_OUT_OF_MEMORY;\r
+\r
+    if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))\r
+    {\r
+        GlobalFree(pMachine);\r
+        return CR_INVALID_MACHINENAME;\r
+    }\r
+\r
+    phMachine = (PHMACHINE)pMachine;\r
+\r
+    return CR_SUCCESS;\r
 }\r
 \r
 \r
@@ -78,7 +99,41 @@ CONFIGRET WINAPI CM_Connect_MachineW(PCWSTR UNCServerName, PHMACHINE phMachine)
  */\r
 CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)\r
 {\r
-    FIXME("%lx\n", hMachine);\r
+    PMACHINE_INFO pMachine;\r
+\r
+    TRACE("%lx\n", hMachine);\r
+\r
+    if (hMachine == NULL)\r
+        return CR_SUCCESS;\r
+\r
+    pMachine = (PMACHINE_INFO)hMachine;\r
+    if (!PnpUnbindRpc(pMachine->BindingHandle))\r
+        return CR_ACCESS_DENIED;\r
+\r
+    GlobalFree(pMachine);\r
+\r
+    return CR_SUCCESS;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Child [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Child(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)\r
+{\r
+    TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);\r
+    return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Child_Ex [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Child_Ex(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)\r
+{\r
+    TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);\r
     return CR_SUCCESS;\r
 }\r
 \r
@@ -153,9 +208,8 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(\r
     PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)\r
 {\r
-    FIXME("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);\r
-    *pulLen = 2;\r
-    return CR_SUCCESS;\r
+    TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);\r
+    return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);\r
 }\r
 \r
 \r
@@ -181,3 +235,128 @@ CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
     *pulLen = 2;\r
     return CR_SUCCESS;\r
 }\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Parent [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Parent(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)\r
+{\r
+    TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);\r
+    return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Parent_Ex [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Parent_Ex(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)\r
+{\r
+    TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);\r
+    return CR_SUCCESS;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Sibling [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Sibling(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)\r
+{\r
+    TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);\r
+    return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Sibling_Ex [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Get_Sibling_Ex(\r
+    PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)\r
+{\r
+    TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);\r
+    return CR_SUCCESS;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Version [SETUPAPI.@]\r
+ */\r
+WORD WINAPI CM_Get_Version(VOID)\r
+{\r
+    TRACE("\n");\r
+    return CM_Get_Version_Ex(NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Get_Version_Ex [SETUPAPI.@]\r
+ */\r
+WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)\r
+{\r
+    RPC_BINDING_HANDLE BindingHandle = NULL;\r
+    RPC_STATUS Status;\r
+\r
+    FIXME("%lx\n", hMachine);\r
+\r
+    if (hMachine != NULL)\r
+    {\r
+        BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;\r
+        if (BindingHandle == NULL)\r
+            return 0;\r
+    }\r
+    else\r
+    {\r
+        Status = PnpGetLocalBindingHandle(&BindingHandle);\r
+        if (Status != RPC_S_OK)\r
+            return 0;\r
+    }\r
+\r
+    return PNP_GetVersion(BindingHandle);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Locate_DevNodeA [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Locate_DevNodeA(\r
+    PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)\r
+{\r
+  FIXME("%p %p %lu\n", pdnDevInst, pDeviceID, ulFlags);\r
+  return CR_SUCCESS;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Locate_DevNodeW [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Locate_DevNodeW(\r
+    PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)\r
+{\r
+  TRACE("%p %p %lu\n", pdnDevInst, pDeviceID, ulFlags);\r
+  return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Locate_DevNode_ExA [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Locate_DevNode_ExA(\r
+    PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)\r
+{\r
+  FIXME("%p %p %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);\r
+  return CR_SUCCESS;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CM_Locate_DevNode_ExW [SETUPAPI.@]\r
+ */\r
+CONFIGRET WINAPI CM_Locate_DevNode_ExW(\r
+    PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)\r
+{\r
+  FIXME("%p %p %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);\r
+  return CR_SUCCESS;\r
+}\r
index 645dbb9..30f8978 100644 (file)
-/*
- * SetupAPI device installer
- *
- * Copyright 2000 Andreas Mohr 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winnt.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "wine/debug.h"
-#include "wine/unicode.h"
-
-#include "rpc.h"
-#include "rpcdce.h"
-
-#include "setupapi_private.h"
-
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-/* Unicode constants */
-static const WCHAR ClassGUID[]  = {'C','l','a','s','s','G','U','I','D',0};
-static const WCHAR Class[]  = {'C','l','a','s','s',0};
-static const WCHAR ClassInstall32[]  = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
-static const WCHAR NoDisplayClass[]  = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
-static const WCHAR NoInstallClass[]  = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
-static const WCHAR NoUseClass[]  = {'N','o','U','s','e','C','l','a','s','s',0};
-static const WCHAR NtExtension[]  = {'.','N','T',0};
-static const WCHAR NtPlatformExtension[]  = {'.','N','T','x','8','6',0};
-static const WCHAR Version[]  = {'V','e','r','s','i','o','n',0};
-static const WCHAR WinExtension[]  = {'.','W','i','n',0};
-
-/* Registry key and value names */
-static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
-                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                  'C','o','n','t','r','o','l','\\',
-                                  'C','l','a','s','s',0};
-
-static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
-                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                  'C','o','n','t','r','o','l','\\',
-                                  'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
-
-/***********************************************************************
- *              SetupDiBuildClassInfoList  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiBuildClassInfoList(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    TRACE("\n");
-    return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiBuildClassInfoListExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiBuildClassInfoListExA(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR MachineNameW = NULL;
-    BOOL bResult;
-
-    TRACE("\n");
-
-    if (MachineName)
-    {
-        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-            return FALSE;
-    }
-
-    bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
-                                           ClassGuidListSize, RequiredSize,
-                                           MachineNameW, Reserved);
-
-    if (MachineNameW)
-        MyFree(MachineNameW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *             SetupDiBuildClassInfoListExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiBuildClassInfoListExW(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCWSTR MachineName,
-        PVOID Reserved)
-{
-    WCHAR szKeyName[40];
-    HKEY hClassesKey;
-    HKEY hClassKey;
-    DWORD dwLength;
-    DWORD dwIndex;
-    LONG lError;
-    DWORD dwGuidListIndex = 0;
-
-    TRACE("\n");
-
-    if (RequiredSize != NULL)
-       *RequiredSize = 0;
-
-    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
-                                            KEY_ALL_ACCESS,
-                                            DIOCR_INSTALLER,
-                                            MachineName,
-                                            Reserved);
-    if (hClassesKey == INVALID_HANDLE_VALUE)
-    {
-       return FALSE;
-    }
-
-    for (dwIndex = 0; ; dwIndex++)
-    {
-       dwLength = 40;
-       lError = RegEnumKeyExW(hClassesKey,
-                              dwIndex,
-                              szKeyName,
-                              &dwLength,
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL);
-       TRACE("RegEnumKeyExW() returns %ld\n", lError);
-       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
-       {
-           TRACE("Key name: %p\n", szKeyName);
-
-           if (RegOpenKeyExW(hClassesKey,
-                             szKeyName,
-                             0,
-                             KEY_ALL_ACCESS,
-                             &hClassKey))
-           {
-               RegCloseKey(hClassesKey);
-               return FALSE;
-           }
-
-           if (!RegQueryValueExW(hClassKey,
-                                 NoUseClass,
-                                 NULL,
-                                 NULL,
-                                 NULL,
-                                 NULL))
-           {
-               TRACE("'NoUseClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           if ((Flags & DIBCI_NOINSTALLCLASS) &&
-               (!RegQueryValueExW(hClassKey,
-                                  NoInstallClass,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL)))
-           {
-               TRACE("'NoInstallClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           if ((Flags & DIBCI_NODISPLAYCLASS) &&
-               (!RegQueryValueExW(hClassKey,
-                                  NoDisplayClass,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL)))
-           {
-               TRACE("'NoDisplayClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           RegCloseKey(hClassKey);
-
-           TRACE("Guid: %p\n", szKeyName);
-           if (dwGuidListIndex < ClassGuidListSize)
-           {
-               if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
-               {
-                   szKeyName[37] = 0;
-               }
-               TRACE("Guid: %p\n", &szKeyName[1]);
-
-               UuidFromStringW(&szKeyName[1],
-                               &ClassGuidList[dwGuidListIndex]);
-           }
-
-           dwGuidListIndex++;
-       }
-
-       if (lError != ERROR_SUCCESS)
-           break;
-    }
-
-    RegCloseKey(hClassesKey);
-
-    if (RequiredSize != NULL)
-       *RequiredSize = dwGuidListIndex;
-
-    if (ClassGuidListSize < dwGuidListIndex)
-    {
-       SetLastError(ERROR_INSUFFICIENT_BUFFER);
-       return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameA(
-        LPCSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameW(
-        LPCWSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExA(
-        LPCSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR ClassNameW = NULL;
-    LPWSTR MachineNameW = NULL;
-    BOOL bResult;
-
-    FIXME("\n");
-
-    ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
-    if (ClassNameW == NULL)
-        return FALSE;
-
-    if (MachineNameW)
-    {
-        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-        {
-            MyFree(ClassNameW);
-            return FALSE;
-        }
-    }
-
-    bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
-                                           ClassGuidListSize, RequiredSize,
-                                           MachineNameW, Reserved);
-
-    if (MachineNameW)
-        MyFree(MachineNameW);
-
-    MyFree(ClassNameW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExW(
-        LPCWSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCWSTR MachineName,
-        PVOID Reserved)
-{
-    WCHAR szKeyName[40];
-    WCHAR szClassName[256];
-    HKEY hClassesKey;
-    HKEY hClassKey;
-    DWORD dwLength;
-    DWORD dwIndex;
-    LONG lError;
-    DWORD dwGuidListIndex = 0;
-
-    if (RequiredSize != NULL)
-       *RequiredSize = 0;
-
-    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
-                                            KEY_ALL_ACCESS,
-                                            DIOCR_INSTALLER,
-                                            MachineName,
-                                            Reserved);
-    if (hClassesKey == INVALID_HANDLE_VALUE)
-    {
-       return FALSE;
-    }
-
-    for (dwIndex = 0; ; dwIndex++)
-    {
-       dwLength = 40;
-       lError = RegEnumKeyExW(hClassesKey,
-                              dwIndex,
-                              szKeyName,
-                              &dwLength,
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL);
-       TRACE("RegEnumKeyExW() returns %ld\n", lError);
-       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
-       {
-           TRACE("Key name: %p\n", szKeyName);
-
-           if (RegOpenKeyExW(hClassesKey,
-                             szKeyName,
-                             0,
-                             KEY_ALL_ACCESS,
-                             &hClassKey))
-           {
-               RegCloseKey(hClassesKey);
-               return FALSE;
-           }
-
-           dwLength = 256 * sizeof(WCHAR);
-           if (!RegQueryValueExW(hClassKey,
-                                 Class,
-                                 NULL,
-                                 NULL,
-                                 (LPBYTE)szClassName,
-                                 &dwLength))
-           {
-               TRACE("Class name: %p\n", szClassName);
-
-               if (strcmpiW(szClassName, ClassName) == 0)
-               {
-                   TRACE("Found matching class name\n");
-
-                   TRACE("Guid: %p\n", szKeyName);
-                   if (dwGuidListIndex < ClassGuidListSize)
-                   {
-                       if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
-                       {
-                           szKeyName[37] = 0;
-                       }
-                       TRACE("Guid: %p\n", &szKeyName[1]);
-
-                       UuidFromStringW(&szKeyName[1],
-                                       &ClassGuidList[dwGuidListIndex]);
-                   }
-
-                   dwGuidListIndex++;
-               }
-           }
-
-           RegCloseKey(hClassKey);
-       }
-
-       if (lError != ERROR_SUCCESS)
-           break;
-    }
-
-    RegCloseKey(hClassesKey);
-
-    if (RequiredSize != NULL)
-       *RequiredSize = dwGuidListIndex;
-
-    if (ClassGuidListSize < dwGuidListIndex)
-    {
-       SetLastError(ERROR_INSUFFICIENT_BUFFER);
-       return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidA(
-        const GUID* ClassGuid,
-        PSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize)
-{
-  return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
-                                     ClassNameSize, RequiredSize,
-                                     NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidW(
-        const GUID* ClassGuid,
-        PWSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize)
-{
-  return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
-                                     ClassNameSize, RequiredSize,
-                                     NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExA(
-        const GUID* ClassGuid,
-        PSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-  FIXME("\n");
-  return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiClassNameFromGuidExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExW(
-        const GUID* ClassGuid,
-        PWSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    HKEY hKey;
-    DWORD dwLength;
-
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
-                                     KEY_ALL_ACCESS,
-                                     DIOCR_INSTALLER,
-                                     MachineName,
-                                     Reserved);
-    if (hKey == INVALID_HANDLE_VALUE)
-    {
-       return FALSE;
-    }
-
-    if (RequiredSize != NULL)
-    {
-       dwLength = 0;
-       if (RegQueryValueExW(hKey,
-                            Class,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &dwLength))
-       {
-           RegCloseKey(hKey);
-           return FALSE;
-       }
-
-       *RequiredSize = dwLength / sizeof(WCHAR);
-    }
-
-    dwLength = ClassNameSize * sizeof(WCHAR);
-    if (RegQueryValueExW(hKey,
-                        Class,
-                        NULL,
-                        NULL,
-                        (LPBYTE)ClassName,
-                        &dwLength))
-    {
-       RegCloseKey(hKey);
-       return FALSE;
-    }
-
-    RegCloseKey(hKey);
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoList (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
-                           HWND hwndParent)
-{
-  return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
-                              HWND hwndParent,
-                              PCSTR MachineName,
-                              PVOID Reserved)
-{
-    LPWSTR MachineNameW = NULL;
-    HDEVINFO hDevInfo;
-
-    TRACE("\n");
-
-    if (MachineName)
-    {
-        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-              return (HDEVINFO)INVALID_HANDLE_VALUE;
-    }
-
-    hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
-                                              MachineNameW, Reserved);
-
-    if (MachineNameW)
-        MyFree(MachineNameW);
-
-    return hDevInfo;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
-                              HWND hwndParent,
-                              PCWSTR MachineName,
-                              PVOID Reserved)
-{
-  FIXME("\n");
-  return (HDEVINFO)INVALID_HANDLE_VALUE;
-}
-
-/***********************************************************************
- *             SetupDiDestroyDeviceInfoList (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
-{
-  FIXME("%p\n", devinfo);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiEnumDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiEnumDeviceInfo(
-        HDEVINFO  devinfo,
-        DWORD  index,
-        PSP_DEVINFO_DATA info)
-{
-    FIXME("%p %ld %p\n", devinfo, index, info);
-
-    if(info==NULL)
-        return FALSE;
-    if(info->cbSize < sizeof(*info))
-        return FALSE;
-
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiEnumDeviceInterfaces (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiEnumDeviceInterfaces(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       CONST GUID * InterfaceClassGuid,
-       DWORD MemberIndex,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetActualSectionToInstallA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallA(
-        HINF InfHandle,
-        PCSTR InfSectionName,
-        PSTR InfSectionWithExt,
-        DWORD InfSectionWithExtSize,
-        PDWORD RequiredSize,
-        PSTR *Extension)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetActualSectionToInstallW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallW(
-        HINF InfHandle,
-        PCWSTR InfSectionName,
-        PWSTR InfSectionWithExt,
-        DWORD InfSectionWithExtSize,
-        PDWORD RequiredSize,
-        PWSTR *Extension)
-{
-    WCHAR szBuffer[MAX_PATH];
-    DWORD dwLength;
-    DWORD dwFullLength;
-    LONG lLineCount = -1;
-
-    lstrcpyW(szBuffer, InfSectionName);
-    dwLength = lstrlenW(szBuffer);
-
-    if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
-    {
-       /* Test section name with '.NTx86' extension */
-       lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
-       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
-
-       if (lLineCount == -1)
-       {
-           /* Test section name with '.NT' extension */
-           lstrcpyW(&szBuffer[dwLength], NtExtension);
-           lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
-       }
-    }
-    else
-    {
-       /* Test section name with '.Win' extension */
-       lstrcpyW(&szBuffer[dwLength], WinExtension);
-       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
-    }
-
-    if (lLineCount == -1)
-    {
-       /* Test section name without extension */
-       szBuffer[dwLength] = 0;
-       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
-    }
-
-    if (lLineCount == -1)
-    {
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-    }
-
-    dwFullLength = lstrlenW(szBuffer);
-
-    if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
-    {
-       if (InfSectionWithExtSize < (dwFullLength + 1))
-       {
-           SetLastError(ERROR_INSUFFICIENT_BUFFER);
-           return FALSE;
-       }
-
-       lstrcpyW(InfSectionWithExt, szBuffer);
-       if (Extension != NULL)
-       {
-           *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
-       }
-    }
-
-    if (RequiredSize != NULL)
-    {
-       *RequiredSize = dwFullLength + 1;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionA(
-        const GUID* ClassGuid,
-        PSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize)
-{
-  return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
-                                       ClassDescriptionSize,
-                                       RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionW(
-        const GUID* ClassGuid,
-        PWSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize)
-{
-  return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
-                                       ClassDescriptionSize,
-                                       RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExA(
-        const GUID* ClassGuid,
-        PSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-  FIXME("\n");
-  return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExW(
-        const GUID* ClassGuid,
-        PWSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    HKEY hKey;
-    DWORD dwLength;
-
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
-                                     KEY_ALL_ACCESS,
-                                     DIOCR_INSTALLER,
-                                     MachineName,
-                                     Reserved);
-    if (hKey == INVALID_HANDLE_VALUE)
-    {
-       WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
-       return FALSE;
-    }
-
-    if (RequiredSize != NULL)
-    {
-       dwLength = 0;
-       if (RegQueryValueExW(hKey,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &dwLength))
-       {
-           RegCloseKey(hKey);
-           return FALSE;
-       }
-
-       *RequiredSize = dwLength / sizeof(WCHAR);
-    }
-
-    dwLength = ClassDescriptionSize * sizeof(WCHAR);
-    if (RegQueryValueExW(hKey,
-                        NULL,
-                        NULL,
-                        NULL,
-                        (LPBYTE)ClassDescription,
-                        &dwLength))
-    {
-       RegCloseKey(hKey);
-       return FALSE;
-    }
-
-    RegCloseKey(hKey);
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDevsA (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsA(
-       CONST GUID *class,
-       LPCSTR enumstr,
-       HWND parent,
-       DWORD flags)
-{
-    FIXME("%s %s %p %08lx\n",debugstr_guid(class),enumstr,parent,flags);
-
-    return (HDEVINFO) INVALID_HANDLE_VALUE;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDevsW (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsW(
-       CONST GUID *class,
-       LPCWSTR enumstr,
-       HWND parent,
-       DWORD flags)
-{
-    FIXME("%s %s %p %08lx\n",debugstr_guid(class),debugstr_w(enumstr),parent,flags);
-
-    return (HDEVINFO) INVALID_HANDLE_VALUE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
-      HDEVINFO DeviceInfoSet,
-      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-      PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
-      DWORD DeviceInterfaceDetailDataSize,
-      PDWORD RequiredSize,
-      PSP_DEVINFO_DATA DeviceInfoData)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
-      HDEVINFO DeviceInfoSet,
-      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-      PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
-      DWORD DeviceInterfaceDetailDataSize,
-      PDWORD RequiredSize,
-      PSP_DEVINFO_DATA DeviceInfoData)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
-        HDEVINFO  devinfo,
-        PSP_DEVINFO_DATA  DeviceInfoData,
-        DWORD   Property,
-        PDWORD  PropertyRegDataType,
-        PBYTE   PropertyBuffer,
-        DWORD   PropertyBufferSize,
-        PDWORD  RequiredSize)
-{
-    FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
-        Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
-        RequiredSize);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiInstallClassA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassA(
-        HWND hwndParent,
-        PCSTR InfFileName,
-        DWORD Flags,
-        HSPFILEQ FileQueue)
-{
-    UNICODE_STRING FileNameW;
-    BOOL Result;
-
-    if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
-
-    RtlFreeUnicodeString(&FileNameW);
-
-    return Result;
-}
-
-static HKEY CreateClassKey(HINF hInf)
-{
-    WCHAR FullBuffer[MAX_PATH];
-    WCHAR Buffer[MAX_PATH];
-    DWORD RequiredSize;
-    HKEY hClassKey;
-
-    if (!SetupGetLineTextW(NULL,
-                          hInf,
-                          Version,
-                          ClassGUID,
-                          Buffer,
-                          MAX_PATH,
-                          &RequiredSize))
-    {
-       return INVALID_HANDLE_VALUE;
-    }
-
-    lstrcpyW(FullBuffer, ControlClass);
-    lstrcatW(FullBuffer, Buffer);
-
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                     FullBuffer,
-                     0,
-                     KEY_ALL_ACCESS,
-                     &hClassKey))
-    {
-       if (!SetupGetLineTextW(NULL,
-                              hInf,
-                              Version,
-                              Class,
-                              Buffer,
-                              MAX_PATH,
-                              &RequiredSize))
-       {
-           return INVALID_HANDLE_VALUE;
-       }
-
-       if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                           FullBuffer,
-                           0,
-                           NULL,
-                           REG_OPTION_NON_VOLATILE,
-                           KEY_ALL_ACCESS,
-                           NULL,
-                           &hClassKey,
-                           NULL))
-       {
-           return INVALID_HANDLE_VALUE;
-       }
-
-    }
-
-    if (RegSetValueExW(hClassKey,
-                      Class,
-                      0,
-                      REG_SZ,
-                      (LPBYTE)Buffer,
-                      RequiredSize * sizeof(WCHAR)))
-    {
-       RegCloseKey(hClassKey);
-       RegDeleteKeyW(HKEY_LOCAL_MACHINE,
-                     FullBuffer);
-       return INVALID_HANDLE_VALUE;
-    }
-
-    return hClassKey;
-}
-
-/***********************************************************************
- *             SetupDiInstallClassW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassW(
-        HWND hwndParent,
-        PCWSTR InfFileName,
-        DWORD Flags,
-        HSPFILEQ FileQueue)
-{
-    WCHAR SectionName[MAX_PATH];
-    DWORD SectionNameLength = 0;
-    HINF hInf;
-    BOOL bFileQueueCreated = FALSE;
-    HKEY hClassKey;
-
-
-    FIXME("\n");
-
-    if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
-    {
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-    }
-
-    /* Open the .inf file */
-    hInf = SetupOpenInfFileW(InfFileName,
-                            NULL,
-                            INF_STYLE_WIN4,
-                            NULL);
-    if (hInf == INVALID_HANDLE_VALUE)
-    {
-
-       return FALSE;
-    }
-
-    /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
-    hClassKey = CreateClassKey(hInf);
-    if (hClassKey == INVALID_HANDLE_VALUE)
-    {
-       SetupCloseInfFile(hInf);
-       return FALSE;
-    }
-
-
-    /* Try to append a layout file */
-#if 0
-    SetupOpenAppendInfFileW(NULL, hInf, NULL);
-#endif
-
-    /* Retrieve the actual section name */
-    SetupDiGetActualSectionToInstallW(hInf,
-                                     ClassInstall32,
-                                     SectionName,
-                                     MAX_PATH,
-                                     &SectionNameLength,
-                                     NULL);
-
-#if 0
-    if (!(Flags & DI_NOVCP))
-    {
-       FileQueue = SetupOpenFileQueue();
-       if (FileQueue == INVALID_HANDLE_VALUE)
-       {
-           SetupCloseInfFile(hInf);
-           return FALSE;
-       }
-
-       bFileQueueCreated = TRUE;
-
-    }
-#endif
-
-    SetupInstallFromInfSectionW(NULL,
-                               hInf,
-                               SectionName,
-                               SPINST_REGISTRY,
-                               hClassKey,
-                               NULL,
-                               0,
-                               NULL,
-                               NULL,
-                               INVALID_HANDLE_VALUE,
-                               NULL);
-
-    /* FIXME: More code! */
-
-    if (bFileQueueCreated)
-       SetupCloseFileQueue(FileQueue);
-
-    SetupCloseInfFile(hInf);
-
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKey  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKey(
-        const GUID* ClassGuid,
-        REGSAM samDesired)
-{
-    return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
-                                     DIOCR_INSTALLER, NULL, NULL);
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKeyExA  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExA(
-        const GUID* ClassGuid,
-        REGSAM samDesired,
-        DWORD Flags,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-    PWSTR MachineNameW = NULL;
-    HKEY hKey;
-
-    TRACE("\n");
-
-    if (MachineName)
-    {
-        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-            return INVALID_HANDLE_VALUE;
-    }
-
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
-                                     Flags, MachineNameW, Reserved);
-
-    if (MachineNameW)
-        MyFree(MachineNameW);
-
-    return hKey;
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKeyExW  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExW(
-        const GUID* ClassGuid,
-        REGSAM samDesired,
-        DWORD Flags,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR lpGuidString;
-    HKEY hClassesKey;
-    HKEY hClassKey;
-    LPCWSTR lpKeyName;
-
-    if (MachineName != NULL)
-    {
-        FIXME("Remote access not supported yet!\n");
-        return INVALID_HANDLE_VALUE;
-    }
-
-    if (Flags == DIOCR_INSTALLER)
-    {
-        lpKeyName = ControlClass;
-    }
-    else if (Flags == DIOCR_INTERFACE)
-    {
-        lpKeyName = DeviceClasses;
-    }
-    else
-    {
-        ERR("Invalid Flags parameter!\n");
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                     lpKeyName,
-                     0,
-                     KEY_ALL_ACCESS,
-                     &hClassesKey))
-    {
-       return INVALID_HANDLE_VALUE;
-    }
-
-    if (ClassGuid == NULL)
-        return hClassesKey;
-
-    if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
-    {
-       RegCloseKey(hClassesKey);
-       return FALSE;
-    }
-
-    if (RegOpenKeyExW(hClassesKey,
-                     lpGuidString,
-                     0,
-                     KEY_ALL_ACCESS,
-                     &hClassKey))
-    {
-       RpcStringFreeW(&lpGuidString);
-       RegCloseKey(hClassesKey);
-       return FALSE;
-    }
-
-    RpcStringFreeW(&lpGuidString);
-    RegCloseKey(hClassesKey);
-
-    return hClassKey;
-}
-
-/***********************************************************************
- *             SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceW(
-       HDEVINFO DeviceInfoSet,
-       PCWSTR DevicePath,
-       DWORD OpenFlags,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    FIXME("%p %s %08lx %p\n",
-        DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceA(
-       HDEVINFO DeviceInfoSet,
-       PCSTR DevicePath,
-       DWORD OpenFlags,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    FIXME("%p %s %08lx %p\n", DeviceInfoSet,
-        debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiSetClassInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetClassInstallParamsA(
-       HDEVINFO  DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_CLASSINSTALL_HEADER ClassInstallParams,
-       DWORD ClassInstallParamsSize)
-{
-    FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
-          ClassInstallParams->InstallFunction, ClassInstallParamsSize);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiCallClassInstaller (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCallClassInstaller(
-       DWORD InstallFunction,
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData)
-{
-    FIXME("%ld %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstallParamsA(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
-{
-    FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiOpenDevRegKey (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenDevRegKey(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       DWORD Scope,
-       DWORD HwProfile,
-       DWORD KeyType,
-       REGSAM samDesired)
-{
-    FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
-          Scope, HwProfile, KeyType, samDesired);
-    return INVALID_HANDLE_VALUE;
-}
+/*\r
+ * SetupAPI device installer\r
+ *\r
+ * Copyright 2000 Andreas Mohr for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include "config.h"\r
+#include "wine/port.h"\r
\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winnt.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "wine/debug.h"\r
+#include "wine/unicode.h"\r
+#include "initguid.h"\r
+#include "winioctl.h"\r
+#include "rpc.h"\r
+#include "rpcdce.h"\r
+\r
+#include "setupapi_private.h"\r
+\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+/* Unicode constants */\r
+static const WCHAR ClassGUID[]  = {'C','l','a','s','s','G','U','I','D',0};\r
+static const WCHAR Class[]  = {'C','l','a','s','s',0};\r
+static const WCHAR ClassInstall32[]  = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};\r
+static const WCHAR NoDisplayClass[]  = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};\r
+static const WCHAR NoInstallClass[]  = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};\r
+static const WCHAR NoUseClass[]  = {'N','o','U','s','e','C','l','a','s','s',0};\r
+static const WCHAR NtExtension[]  = {'.','N','T',0};\r
+static const WCHAR NtPlatformExtension[]  = {'.','N','T','x','8','6',0};\r
+static const WCHAR Version[]  = {'V','e','r','s','i','o','n',0};\r
+static const WCHAR WinExtension[]  = {'.','W','i','n',0};\r
+\r
+/* Registry key and value names */\r
+static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',\r
+                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',\r
+                                  'C','o','n','t','r','o','l','\\',\r
+                                  'C','l','a','s','s',0};\r
+\r
+static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',\r
+                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',\r
+                                  'C','o','n','t','r','o','l','\\',\r
+                                  'D','e','v','i','c','e','C','l','a','s','s','e','s',0};\r
+\r
+/***********************************************************************\r
+ *              SetupDiBuildClassInfoList  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiBuildClassInfoList(\r
+        DWORD Flags,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize)\r
+{\r
+    TRACE("\n");\r
+    return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,\r
+                                        ClassGuidListSize, RequiredSize,\r
+                                        NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *              SetupDiBuildClassInfoListExA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiBuildClassInfoListExA(\r
+        DWORD Flags,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize,\r
+        LPCSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    LPWSTR MachineNameW = NULL;\r
+    BOOL bResult;\r
+\r
+    TRACE("\n");\r
+\r
+    if (MachineName)\r
+    {\r
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);\r
+        if (MachineNameW == NULL) return FALSE;\r
+    }\r
+\r
+    bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,\r
+                                           ClassGuidListSize, RequiredSize,\r
+                                           MachineNameW, Reserved);\r
+\r
+    if (MachineNameW)\r
+        MyFree(MachineNameW);\r
+\r
+    return bResult;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiBuildClassInfoListExW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiBuildClassInfoListExW(\r
+        DWORD Flags,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize,\r
+        LPCWSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    WCHAR szKeyName[40];\r
+    HKEY hClassesKey;\r
+    HKEY hClassKey;\r
+    DWORD dwLength;\r
+    DWORD dwIndex;\r
+    LONG lError;\r
+    DWORD dwGuidListIndex = 0;\r
+\r
+    TRACE("\n");\r
+\r
+    if (RequiredSize != NULL)\r
+       *RequiredSize = 0;\r
+\r
+    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,\r
+                                            KEY_ALL_ACCESS,\r
+                                            DIOCR_INSTALLER,\r
+                                            MachineName,\r
+                                            Reserved);\r
+    if (hClassesKey == INVALID_HANDLE_VALUE)\r
+    {\r
+       return FALSE;\r
+    }\r
+\r
+    for (dwIndex = 0; ; dwIndex++)\r
+    {\r
+       dwLength = 40;\r
+       lError = RegEnumKeyExW(hClassesKey,\r
+                              dwIndex,\r
+                              szKeyName,\r
+                              &dwLength,\r
+                              NULL,\r
+                              NULL,\r
+                              NULL,\r
+                              NULL);\r
+       TRACE("RegEnumKeyExW() returns %ld\n", lError);\r
+       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)\r
+       {\r
+           TRACE("Key name: %p\n", szKeyName);\r
+\r
+           if (RegOpenKeyExW(hClassesKey,\r
+                             szKeyName,\r
+                             0,\r
+                             KEY_ALL_ACCESS,\r
+                             &hClassKey))\r
+           {\r
+               RegCloseKey(hClassesKey);\r
+               return FALSE;\r
+           }\r
+\r
+           if (!RegQueryValueExW(hClassKey,\r
+                                 NoUseClass,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 NULL))\r
+           {\r
+               TRACE("'NoUseClass' value found!\n");\r
+               RegCloseKey(hClassKey);\r
+               continue;\r
+           }\r
+\r
+           if ((Flags & DIBCI_NOINSTALLCLASS) &&\r
+               (!RegQueryValueExW(hClassKey,\r
+                                  NoInstallClass,\r
+                                  NULL,\r
+                                  NULL,\r
+                                  NULL,\r
+                                  NULL)))\r
+           {\r
+               TRACE("'NoInstallClass' value found!\n");\r
+               RegCloseKey(hClassKey);\r
+               continue;\r
+           }\r
+\r
+           if ((Flags & DIBCI_NODISPLAYCLASS) &&\r
+               (!RegQueryValueExW(hClassKey,\r
+                                  NoDisplayClass,\r
+                                  NULL,\r
+                                  NULL,\r
+                                  NULL,\r
+                                  NULL)))\r
+           {\r
+               TRACE("'NoDisplayClass' value found!\n");\r
+               RegCloseKey(hClassKey);\r
+               continue;\r
+           }\r
+\r
+           RegCloseKey(hClassKey);\r
+\r
+           TRACE("Guid: %p\n", szKeyName);\r
+           if (dwGuidListIndex < ClassGuidListSize)\r
+           {\r
+               if (szKeyName[0] == L'{' && szKeyName[37] == L'}')\r
+               {\r
+                   szKeyName[37] = 0;\r
+               }\r
+               TRACE("Guid: %p\n", &szKeyName[1]);\r
+\r
+               UuidFromStringW(&szKeyName[1],\r
+                               &ClassGuidList[dwGuidListIndex]);\r
+           }\r
+\r
+           dwGuidListIndex++;\r
+       }\r
+\r
+       if (lError != ERROR_SUCCESS)\r
+           break;\r
+    }\r
+\r
+    RegCloseKey(hClassesKey);\r
+\r
+    if (RequiredSize != NULL)\r
+       *RequiredSize = dwGuidListIndex;\r
+\r
+    if (ClassGuidListSize < dwGuidListIndex)\r
+    {\r
+       SetLastError(ERROR_INSUFFICIENT_BUFFER);\r
+       return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiClassGuidsFromNameA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassGuidsFromNameA(\r
+        LPCSTR ClassName,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,\r
+                                      ClassGuidListSize, RequiredSize,\r
+                                      NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiClassGuidsFromNameW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassGuidsFromNameW(\r
+        LPCWSTR ClassName,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,\r
+                                      ClassGuidListSize, RequiredSize,\r
+                                      NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiClassGuidsFromNameExA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassGuidsFromNameExA(\r
+        LPCSTR ClassName,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize,\r
+        LPCSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    LPWSTR ClassNameW = NULL;\r
+    LPWSTR MachineNameW = NULL;\r
+    BOOL bResult;\r
+\r
+    FIXME("\n");\r
+\r
+    ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);\r
+    if (ClassNameW == NULL)\r
+        return FALSE;\r
+\r
+    if (MachineNameW)\r
+    {\r
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);\r
+        if (MachineNameW == NULL)\r
+        {\r
+            MyFree(ClassNameW);\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,\r
+                                           ClassGuidListSize, RequiredSize,\r
+                                           MachineNameW, Reserved);\r
+\r
+    if (MachineNameW)\r
+        MyFree(MachineNameW);\r
+\r
+    MyFree(ClassNameW);\r
+\r
+    return bResult;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiClassGuidsFromNameExW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassGuidsFromNameExW(\r
+        LPCWSTR ClassName,\r
+        LPGUID ClassGuidList,\r
+        DWORD ClassGuidListSize,\r
+        PDWORD RequiredSize,\r
+        LPCWSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    WCHAR szKeyName[40];\r
+    WCHAR szClassName[256];\r
+    HKEY hClassesKey;\r
+    HKEY hClassKey;\r
+    DWORD dwLength;\r
+    DWORD dwIndex;\r
+    LONG lError;\r
+    DWORD dwGuidListIndex = 0;\r
+\r
+    if (RequiredSize != NULL)\r
+       *RequiredSize = 0;\r
+\r
+    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,\r
+                                            KEY_ALL_ACCESS,\r
+                                            DIOCR_INSTALLER,\r
+                                            MachineName,\r
+                                            Reserved);\r
+    if (hClassesKey == INVALID_HANDLE_VALUE)\r
+    {\r
+       return FALSE;\r
+    }\r
+\r
+    for (dwIndex = 0; ; dwIndex++)\r
+    {\r
+       dwLength = 40;\r
+       lError = RegEnumKeyExW(hClassesKey,\r
+                              dwIndex,\r
+                              szKeyName,\r
+                              &dwLength,\r
+                              NULL,\r
+                              NULL,\r
+                              NULL,\r
+                              NULL);\r
+       TRACE("RegEnumKeyExW() returns %ld\n", lError);\r
+       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)\r
+       {\r
+           TRACE("Key name: %p\n", szKeyName);\r
+\r
+           if (RegOpenKeyExW(hClassesKey,\r
+                             szKeyName,\r
+                             0,\r
+                             KEY_ALL_ACCESS,\r
+                             &hClassKey))\r
+           {\r
+               RegCloseKey(hClassesKey);\r
+               return FALSE;\r
+           }\r
+\r
+           dwLength = 256 * sizeof(WCHAR);\r
+           if (!RegQueryValueExW(hClassKey,\r
+                                 Class,\r
+                                 NULL,\r
+                                 NULL,\r
+                                 (LPBYTE)szClassName,\r
+                                 &dwLength))\r
+           {\r
+               TRACE("Class name: %p\n", szClassName);\r
+\r
+               if (strcmpiW(szClassName, ClassName) == 0)\r
+               {\r
+                   TRACE("Found matching class name\n");\r
+\r
+                   TRACE("Guid: %p\n", szKeyName);\r
+                   if (dwGuidListIndex < ClassGuidListSize)\r
+                   {\r
+                       if (szKeyName[0] == L'{' && szKeyName[37] == L'}')\r
+                       {\r
+                           szKeyName[37] = 0;\r
+                       }\r
+                       TRACE("Guid: %p\n", &szKeyName[1]);\r
+\r
+                       UuidFromStringW(&szKeyName[1],\r
+                                       &ClassGuidList[dwGuidListIndex]);\r
+                   }\r
+\r
+                   dwGuidListIndex++;\r
+               }\r
+           }\r
+\r
+           RegCloseKey(hClassKey);\r
+       }\r
+\r
+       if (lError != ERROR_SUCCESS)\r
+           break;\r
+    }\r
+\r
+    RegCloseKey(hClassesKey);\r
+\r
+    if (RequiredSize != NULL)\r
+       *RequiredSize = dwGuidListIndex;\r
+\r
+    if (ClassGuidListSize < dwGuidListIndex)\r
+    {\r
+       SetLastError(ERROR_INSUFFICIENT_BUFFER);\r
+       return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *              SetupDiClassNameFromGuidA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassNameFromGuidA(\r
+        const GUID* ClassGuid,\r
+        PSTR ClassName,\r
+        DWORD ClassNameSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,\r
+                                     ClassNameSize, RequiredSize,\r
+                                     NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *              SetupDiClassNameFromGuidW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassNameFromGuidW(\r
+        const GUID* ClassGuid,\r
+        PWSTR ClassName,\r
+        DWORD ClassNameSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,\r
+                                     ClassNameSize, RequiredSize,\r
+                                     NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *              SetupDiClassNameFromGuidExA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassNameFromGuidExA(\r
+        const GUID* ClassGuid,\r
+        PSTR ClassName,\r
+        DWORD ClassNameSize,\r
+        PDWORD RequiredSize,\r
+        PCSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+  FIXME("\n");\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiClassNameFromGuidExW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiClassNameFromGuidExW(\r
+        const GUID* ClassGuid,\r
+        PWSTR ClassName,\r
+        DWORD ClassNameSize,\r
+        PDWORD RequiredSize,\r
+        PCWSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    HKEY hKey;\r
+    DWORD dwLength;\r
+\r
+    hKey = SetupDiOpenClassRegKeyExW(ClassGuid,\r
+                                     KEY_ALL_ACCESS,\r
+                                     DIOCR_INSTALLER,\r
+                                     MachineName,\r
+                                     Reserved);\r
+    if (hKey == INVALID_HANDLE_VALUE)\r
+    {\r
+       return FALSE;\r
+    }\r
+\r
+    if (RequiredSize != NULL)\r
+    {\r
+       dwLength = 0;\r
+       if (RegQueryValueExW(hKey,\r
+                            Class,\r
+                            NULL,\r
+                            NULL,\r
+                            NULL,\r
+                            &dwLength))\r
+       {\r
+           RegCloseKey(hKey);\r
+           return FALSE;\r
+       }\r
+\r
+       *RequiredSize = dwLength / sizeof(WCHAR);\r
+    }\r
+\r
+    dwLength = ClassNameSize * sizeof(WCHAR);\r
+    if (RegQueryValueExW(hKey,\r
+                        Class,\r
+                        NULL,\r
+                        NULL,\r
+                        (LPBYTE)ClassName,\r
+                        &dwLength))\r
+    {\r
+       RegCloseKey(hKey);\r
+       return FALSE;\r
+    }\r
+\r
+    RegCloseKey(hKey);\r
+\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiCreateDeviceInfoList (SETUPAPI.@)\r
+ */\r
+HDEVINFO WINAPI\r
+SetupDiCreateDeviceInfoList(const GUID *ClassGuid,\r
+                           HWND hwndParent)\r
+{\r
+  return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiCreateDeviceInfoListExA (SETUPAPI.@)\r
+ */\r
+HDEVINFO WINAPI\r
+SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,\r
+                              HWND hwndParent,\r
+                              PCSTR MachineName,\r
+                              PVOID Reserved)\r
+{\r
+    LPWSTR MachineNameW = NULL;\r
+    HDEVINFO hDevInfo;\r
+\r
+    TRACE("\n");\r
+\r
+    if (MachineName)\r
+    {\r
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);\r
+        if (MachineNameW == NULL)\r
+            return (HDEVINFO)INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,\r
+                                              MachineNameW, Reserved);\r
+\r
+    if (MachineNameW)\r
+        MyFree(MachineNameW);\r
+\r
+    return hDevInfo;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiCreateDeviceInfoListExW (SETUPAPI.@)\r
+ */\r
+HDEVINFO WINAPI\r
+SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,\r
+                              HWND hwndParent,\r
+                              PCWSTR MachineName,\r
+                              PVOID Reserved)\r
+{\r
+  FIXME("\n");\r
+  return (HDEVINFO)INVALID_HANDLE_VALUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiEnumDeviceInfo (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiEnumDeviceInfo(\r
+        HDEVINFO  devinfo,\r
+        DWORD  index,\r
+        PSP_DEVINFO_DATA info)\r
+{\r
+    FIXME("%p %ld %p\n", devinfo, index, info);\r
+\r
+    if(info==NULL)\r
+        return FALSE;\r
+    if(info->cbSize < sizeof(*info))\r
+        return FALSE;\r
+\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetActualSectionToInstallA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetActualSectionToInstallA(\r
+        HINF InfHandle,\r
+        PCSTR InfSectionName,\r
+        PSTR InfSectionWithExt,\r
+        DWORD InfSectionWithExtSize,\r
+        PDWORD RequiredSize,\r
+        PSTR *Extension)\r
+{\r
+    FIXME("\n");\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetActualSectionToInstallW (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetActualSectionToInstallW(\r
+        HINF InfHandle,\r
+        PCWSTR InfSectionName,\r
+        PWSTR InfSectionWithExt,\r
+        DWORD InfSectionWithExtSize,\r
+        PDWORD RequiredSize,\r
+        PWSTR *Extension)\r
+{\r
+    WCHAR szBuffer[MAX_PATH];\r
+    DWORD dwLength;\r
+    DWORD dwFullLength;\r
+    LONG lLineCount = -1;\r
+\r
+    lstrcpyW(szBuffer, InfSectionName);\r
+    dwLength = lstrlenW(szBuffer);\r
+\r
+    if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
+    {\r
+       /* Test section name with '.NTx86' extension */\r
+       lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);\r
+       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);\r
+\r
+       if (lLineCount == -1)\r
+       {\r
+           /* Test section name with '.NT' extension */\r
+           lstrcpyW(&szBuffer[dwLength], NtExtension);\r
+           lLineCount = SetupGetLineCountW(InfHandle, szBuffer);\r
+       }\r
+    }\r
+    else\r
+    {\r
+       /* Test section name with '.Win' extension */\r
+       lstrcpyW(&szBuffer[dwLength], WinExtension);\r
+       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);\r
+    }\r
+\r
+    if (lLineCount == -1)\r
+    {\r
+       /* Test section name without extension */\r
+       szBuffer[dwLength] = 0;\r
+       lLineCount = SetupGetLineCountW(InfHandle, szBuffer);\r
+    }\r
+\r
+    if (lLineCount == -1)\r
+    {\r
+       SetLastError(ERROR_INVALID_PARAMETER);\r
+       return FALSE;\r
+    }\r
+\r
+    dwFullLength = lstrlenW(szBuffer);\r
+\r
+    if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)\r
+    {\r
+       if (InfSectionWithExtSize < (dwFullLength + 1))\r
+       {\r
+           SetLastError(ERROR_INSUFFICIENT_BUFFER);\r
+           return FALSE;\r
+       }\r
+\r
+       lstrcpyW(InfSectionWithExt, szBuffer);\r
+       if (Extension != NULL)\r
+       {\r
+           *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];\r
+       }\r
+    }\r
+\r
+    if (RequiredSize != NULL)\r
+    {\r
+       *RequiredSize = dwFullLength + 1;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDescriptionA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetClassDescriptionA(\r
+        const GUID* ClassGuid,\r
+        PSTR ClassDescription,\r
+        DWORD ClassDescriptionSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,\r
+                                       ClassDescriptionSize,\r
+                                       RequiredSize, NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDescriptionW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetClassDescriptionW(\r
+        const GUID* ClassGuid,\r
+        PWSTR ClassDescription,\r
+        DWORD ClassDescriptionSize,\r
+        PDWORD RequiredSize)\r
+{\r
+  return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,\r
+                                       ClassDescriptionSize,\r
+                                       RequiredSize, NULL, NULL);\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDescriptionExA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetClassDescriptionExA(\r
+        const GUID* ClassGuid,\r
+        PSTR ClassDescription,\r
+        DWORD ClassDescriptionSize,\r
+        PDWORD RequiredSize,\r
+        PCSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+  FIXME("\n");\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDescriptionExW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetClassDescriptionExW(\r
+        const GUID* ClassGuid,\r
+        PWSTR ClassDescription,\r
+        DWORD ClassDescriptionSize,\r
+        PDWORD RequiredSize,\r
+        PCWSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    HKEY hKey;\r
+    DWORD dwLength;\r
+\r
+    hKey = SetupDiOpenClassRegKeyExW(ClassGuid,\r
+                                     KEY_ALL_ACCESS,\r
+                                     DIOCR_INSTALLER,\r
+                                     MachineName,\r
+                                     Reserved);\r
+    if (hKey == INVALID_HANDLE_VALUE)\r
+    {\r
+       WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());\r
+       return FALSE;\r
+    }\r
+\r
+    if (RequiredSize != NULL)\r
+    {\r
+       dwLength = 0;\r
+       if (RegQueryValueExW(hKey,\r
+                            NULL,\r
+                            NULL,\r
+                            NULL,\r
+                            NULL,\r
+                            &dwLength))\r
+       {\r
+           RegCloseKey(hKey);\r
+           return FALSE;\r
+       }\r
+\r
+       *RequiredSize = dwLength / sizeof(WCHAR);\r
+    }\r
+\r
+    dwLength = ClassDescriptionSize * sizeof(WCHAR);\r
+    if (RegQueryValueExW(hKey,\r
+                        NULL,\r
+                        NULL,\r
+                        NULL,\r
+                        (LPBYTE)ClassDescription,\r
+                        &dwLength))\r
+    {\r
+       RegCloseKey(hKey);\r
+       return FALSE;\r
+    }\r
+\r
+    RegCloseKey(hKey);\r
+\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDevsA (SETUPAPI.@)\r
+ */\r
+HDEVINFO WINAPI SetupDiGetClassDevsA(\r
+       CONST GUID *class,\r
+       LPCSTR enumstr,\r
+       HWND parent,\r
+       DWORD flags)\r
+{\r
+    HDEVINFO ret;\r
+    LPWSTR enumstrW = NULL;\r
+\r
+    if (enumstr)\r
+    {\r
+        int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);\r
+        enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));\r
+        if (!enumstrW)\r
+        {\r
+            ret = (HDEVINFO)INVALID_HANDLE_VALUE;\r
+            goto end;\r
+        }\r
+        MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);\r
+    }\r
+    ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);\r
+    HeapFree(GetProcessHeap(), 0, enumstrW);\r
+\r
+end:\r
+    return ret;\r
+}\r
+\r
+#define SETUP_SERIAL_PORT_MAGIC 0xd00ff055\r
+\r
+typedef struct _SerialPortName\r
+{\r
+    WCHAR name[5];\r
+} SerialPortName;\r
+\r
+typedef struct _SerialPortList\r
+{\r
+    DWORD magic;\r
+    UINT  numPorts;\r
+    SerialPortName names[1];\r
+} SerialPortList;\r
+\r
+static HDEVINFO SETUP_CreateSerialDeviceList(void)\r
+{\r
+    static const size_t initialSize = 100;\r
+    size_t size;\r
+    WCHAR buf[initialSize];\r
+    LPWSTR devices;\r
+    HDEVINFO ret;\r
+    BOOL failed = FALSE;\r
+\r
+    devices = buf;\r
+    size = initialSize;\r
+    do {\r
+        if (QueryDosDeviceW(NULL, devices, size) == 0)\r
+        {\r
+            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\r
+            {\r
+                size *= 2;\r
+                if (devices != buf)\r
+                    HeapFree(GetProcessHeap(), 0, devices);\r
+                devices = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,\r
+                 size * sizeof(WCHAR));\r
+                if (!devices)\r
+                    failed = TRUE;\r
+                else\r
+                    *devices = 0;\r
+            }\r
+            else\r
+                failed = TRUE;\r
+        }\r
+    } while (!*devices && !failed);\r
+    if (!failed)\r
+    {\r
+        static const WCHAR comW[] = { 'C','O','M',0 };\r
+        LPWSTR ptr;\r
+        UINT numSerialPorts = 0;\r
+        SerialPortList *list;\r
+\r
+        for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)\r
+        {\r
+            if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))\r
+                numSerialPorts++;\r
+        }\r
+        list = HeapAlloc(GetProcessHeap(), 0, sizeof(SerialPortList) +\r
+         numSerialPorts ? (numSerialPorts - 1) * sizeof(SerialPortName) : 0);\r
+        if (list)\r
+        {\r
+            list->magic = SETUP_SERIAL_PORT_MAGIC;\r
+            list->numPorts = 0;\r
+            for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1)\r
+            {\r
+                if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1))\r
+                {\r
+                    strncpyW(list->names[list->numPorts].name, ptr,\r
+                     sizeof(list->names[list->numPorts].name) /\r
+                     sizeof(list->names[list->numPorts].name[0]));\r
+                    TRACE("Adding %s to list\n",\r
+                     debugstr_w(list->names[list->numPorts].name));\r
+                    list->numPorts++;\r
+                }\r
+            }\r
+            TRACE("list->numPorts is %d\n", list->numPorts);\r
+        }\r
+        ret = (HDEVINFO)list;\r
+    }\r
+    else\r
+        ret = (HDEVINFO)INVALID_HANDLE_VALUE;\r
+    if (devices != buf)\r
+        HeapFree(GetProcessHeap(), 0, devices);\r
+    TRACE("returning %p\n", ret);\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetClassDevsW (SETUPAPI.@)\r
+ */\r
+HDEVINFO WINAPI SetupDiGetClassDevsW(\r
+       CONST GUID *class,\r
+       LPCWSTR enumstr,\r
+       HWND parent,\r
+       DWORD flags)\r
+{\r
+    HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;\r
+\r
+    TRACE("%s %s %p 0x%08lx\n", debugstr_guid(class), debugstr_w(enumstr),\r
+     parent, flags);\r
+\r
+    if (enumstr)\r
+        FIXME(": unimplemented for enumerator strings (%s)\n",\r
+         debugstr_w(enumstr));\r
+    else if (flags & DIGCF_ALLCLASSES)\r
+        FIXME(": unimplemented for DIGCF_ALLCLASSES\n");\r
+    else\r
+    {\r
+        if (IsEqualIID(class, &GUID_DEVINTERFACE_COMPORT))\r
+            ret = SETUP_CreateSerialDeviceList();\r
+        else if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR))\r
+            ret = SETUP_CreateSerialDeviceList();\r
+        else\r
+            FIXME("(%s): stub\n", debugstr_guid(class));\r
+    }\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiEnumDeviceInterfaces (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiEnumDeviceInterfaces(\r
+       HDEVINFO DeviceInfoSet,\r
+       PSP_DEVINFO_DATA DeviceInfoData,\r
+       CONST GUID * InterfaceClassGuid,\r
+       DWORD MemberIndex,\r
+       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)\r
+{\r
+    BOOL ret = FALSE;\r
+\r
+    TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData,\r
+     debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);\r
+    if (!DeviceInterfaceData)\r
+        SetLastError(ERROR_INVALID_PARAMETER);\r
+    else if (DeviceInfoData)\r
+        FIXME(": unimplemented with PSP_DEVINFO_DATA set\n");\r
+    else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)\r
+    {\r
+        /* FIXME: this assumes the only possible enumeration is of serial\r
+         * ports.\r
+         */\r
+        SerialPortList *list = (SerialPortList *)DeviceInfoSet;\r
+\r
+        if (list->magic == SETUP_SERIAL_PORT_MAGIC)\r
+        {\r
+            if (MemberIndex >= list->numPorts)\r
+                SetLastError(ERROR_NO_MORE_ITEMS);\r
+            else\r
+            {\r
+                DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);\r
+                memcpy(&DeviceInterfaceData->InterfaceClassGuid,\r
+                 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,\r
+                 sizeof(DeviceInterfaceData->InterfaceClassGuid));\r
+                DeviceInterfaceData->Flags = 0;\r
+                /* Note: this appears to be dangerous, passing a private\r
+                 * pointer a heap-allocated datum to the caller.  However, the\r
+                 * expected lifetime of the device data is the same as the\r
+                 * HDEVINFO; once that is closed, the data are no longer valid.\r
+                 */\r
+                DeviceInterfaceData->Reserved =\r
+                 (ULONG_PTR)&list->names[MemberIndex].name;\r
+                ret = TRUE;\r
+            }\r
+        }\r
+        else\r
+            SetLastError(ERROR_INVALID_HANDLE);\r
+    }\r
+    else\r
+        SetLastError(ERROR_INVALID_HANDLE);\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiDestroyDeviceInfoList (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)\r
+{\r
+    BOOL ret = FALSE;\r
+\r
+    TRACE("%p\n", devinfo);\r
+    if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)\r
+    {\r
+        /* FIXME: this assumes the only possible enumeration is of serial\r
+         * ports.\r
+         */\r
+        SerialPortList *list = (SerialPortList *)devinfo;\r
+\r
+        if (list->magic == SETUP_SERIAL_PORT_MAGIC)\r
+        {\r
+            HeapFree(GetProcessHeap(), 0, list);\r
+            ret = TRUE;\r
+        }\r
+        else\r
+            SetLastError(ERROR_INVALID_HANDLE);\r
+    }\r
+    else\r
+        SetLastError(ERROR_INVALID_HANDLE);\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(\r
+      HDEVINFO DeviceInfoSet,\r
+      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,\r
+      PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,\r
+      DWORD DeviceInterfaceDetailDataSize,\r
+      PDWORD RequiredSize,\r
+      PSP_DEVINFO_DATA DeviceInfoData)\r
+{\r
+    BOOL ret = FALSE;\r
+\r
+    TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,\r
+     DeviceInterfaceData, DeviceInterfaceDetailData,\r
+     DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);\r
+    if (!DeviceInterfaceData)\r
+        SetLastError(ERROR_INVALID_PARAMETER);\r
+    else if ((DeviceInterfaceDetailDataSize && !DeviceInterfaceDetailData) ||\r
+     (DeviceInterfaceDetailData && !DeviceInterfaceDetailDataSize))\r
+        SetLastError(ERROR_INVALID_PARAMETER);\r
+    else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE)\r
+    {\r
+        /* FIXME: this assumes the only possible enumeration is of serial\r
+         * ports.\r
+         */\r
+        SerialPortList *list = (SerialPortList *)DeviceInfoSet;\r
+\r
+        if (list->magic == SETUP_SERIAL_PORT_MAGIC)\r
+        {\r
+            LPCWSTR devName = (LPCWSTR)DeviceInterfaceData->Reserved;\r
+            DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A) +\r
+             lstrlenW(devName);\r
+\r
+            if (sizeRequired > DeviceInterfaceDetailDataSize)\r
+            {\r
+                SetLastError(ERROR_INSUFFICIENT_BUFFER);\r
+                if (RequiredSize)\r
+                    *RequiredSize = sizeRequired;\r
+            }\r
+            else\r
+            {\r
+                LPSTR dst = DeviceInterfaceDetailData->DevicePath;\r
+                LPCWSTR src = devName;\r
+\r
+                /* MSDN claims cbSize must be set by the caller, but it lies */\r
+                DeviceInterfaceDetailData->cbSize =\r
+                 sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);\r
+                for ( ; *src; src++, dst++)\r
+                    *dst = *src;\r
+                *dst = '\0';\r
+                TRACE("DevicePath is %s\n",\r
+                 debugstr_a(DeviceInterfaceDetailData->DevicePath));\r
+                if (DeviceInfoData)\r
+                {\r
+                    DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA);\r
+                    memcpy(&DeviceInfoData->ClassGuid,\r
+                     &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR,\r
+                     sizeof(DeviceInfoData->ClassGuid));\r
+                    DeviceInfoData->DevInst = 0;\r
+                    DeviceInfoData->Reserved = (ULONG_PTR)devName;\r
+                }\r
+                ret = TRUE;\r
+            }\r
+        }\r
+        else\r
+            SetLastError(ERROR_INVALID_HANDLE);\r
+    }\r
+    else\r
+        SetLastError(ERROR_INVALID_HANDLE);\r
+    TRACE("Returning %d\n", ret);\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(\r
+      HDEVINFO DeviceInfoSet,\r
+      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,\r
+      PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,\r
+      DWORD DeviceInterfaceDetailDataSize,\r
+      PDWORD RequiredSize,\r
+      PSP_DEVINFO_DATA DeviceInfoData)\r
+{\r
+    FIXME("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,\r
+     DeviceInterfaceData, DeviceInterfaceDetailData,\r
+     DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(\r
+        HDEVINFO  devinfo,\r
+        PSP_DEVINFO_DATA  DeviceInfoData,\r
+        DWORD   Property,\r
+        PDWORD  PropertyRegDataType,\r
+        PBYTE   PropertyBuffer,\r
+        DWORD   PropertyBufferSize,\r
+        PDWORD  RequiredSize)\r
+{\r
+    FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,\r
+        Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,\r
+        RequiredSize);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiInstallClassA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiInstallClassA(\r
+        HWND hwndParent,\r
+        PCSTR InfFileName,\r
+        DWORD Flags,\r
+        HSPFILEQ FileQueue)\r
+{\r
+    UNICODE_STRING FileNameW;\r
+    BOOL Result;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))\r
+    {\r
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
+        return FALSE;\r
+    }\r
+\r
+    Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);\r
+\r
+    RtlFreeUnicodeString(&FileNameW);\r
+\r
+    return Result;\r
+}\r
+\r
+static HKEY CreateClassKey(HINF hInf)\r
+{\r
+    WCHAR FullBuffer[MAX_PATH];\r
+    WCHAR Buffer[MAX_PATH];\r
+    DWORD RequiredSize;\r
+    HKEY hClassKey;\r
+\r
+    if (!SetupGetLineTextW(NULL,\r
+                          hInf,\r
+                          Version,\r
+                          ClassGUID,\r
+                          Buffer,\r
+                          MAX_PATH,\r
+                          &RequiredSize))\r
+    {\r
+       return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    lstrcpyW(FullBuffer, ControlClass);\r
+    lstrcatW(FullBuffer, Buffer);\r
+\r
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,\r
+                     FullBuffer,\r
+                     0,\r
+                     KEY_ALL_ACCESS,\r
+                     &hClassKey))\r
+    {\r
+       if (!SetupGetLineTextW(NULL,\r
+                              hInf,\r
+                              Version,\r
+                              Class,\r
+                              Buffer,\r
+                              MAX_PATH,\r
+                              &RequiredSize))\r
+       {\r
+           return INVALID_HANDLE_VALUE;\r
+       }\r
+\r
+       if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,\r
+                           FullBuffer,\r
+                           0,\r
+                           NULL,\r
+                           REG_OPTION_NON_VOLATILE,\r
+                           KEY_ALL_ACCESS,\r
+                           NULL,\r
+                           &hClassKey,\r
+                           NULL))\r
+       {\r
+           return INVALID_HANDLE_VALUE;\r
+       }\r
+\r
+    }\r
+\r
+    if (RegSetValueExW(hClassKey,\r
+                      Class,\r
+                      0,\r
+                      REG_SZ,\r
+                      (LPBYTE)Buffer,\r
+                      RequiredSize * sizeof(WCHAR)))\r
+    {\r
+       RegCloseKey(hClassKey);\r
+       RegDeleteKeyW(HKEY_LOCAL_MACHINE,\r
+                     FullBuffer);\r
+       return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    return hClassKey;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiInstallClassW (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiInstallClassW(\r
+        HWND hwndParent,\r
+        PCWSTR InfFileName,\r
+        DWORD Flags,\r
+        HSPFILEQ FileQueue)\r
+{\r
+    WCHAR SectionName[MAX_PATH];\r
+    DWORD SectionNameLength = 0;\r
+    HINF hInf;\r
+    BOOL bFileQueueCreated = FALSE;\r
+    HKEY hClassKey;\r
+\r
+\r
+    FIXME("\n");\r
+\r
+    if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))\r
+    {\r
+       SetLastError(ERROR_INVALID_PARAMETER);\r
+       return FALSE;\r
+    }\r
+\r
+    /* Open the .inf file */\r
+    hInf = SetupOpenInfFileW(InfFileName,\r
+                            NULL,\r
+                            INF_STYLE_WIN4,\r
+                            NULL);\r
+    if (hInf == INVALID_HANDLE_VALUE)\r
+    {\r
+\r
+       return FALSE;\r
+    }\r
+\r
+    /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */\r
+    hClassKey = CreateClassKey(hInf);\r
+    if (hClassKey == INVALID_HANDLE_VALUE)\r
+    {\r
+       SetupCloseInfFile(hInf);\r
+       return FALSE;\r
+    }\r
+\r
+\r
+    /* Try to append a layout file */\r
+#if 0\r
+    SetupOpenAppendInfFileW(NULL, hInf, NULL);\r
+#endif\r
+\r
+    /* Retrieve the actual section name */\r
+    SetupDiGetActualSectionToInstallW(hInf,\r
+                                     ClassInstall32,\r
+                                     SectionName,\r
+                                     MAX_PATH,\r
+                                     &SectionNameLength,\r
+                                     NULL);\r
+\r
+#if 0\r
+    if (!(Flags & DI_NOVCP))\r
+    {\r
+       FileQueue = SetupOpenFileQueue();\r
+       if (FileQueue == INVALID_HANDLE_VALUE)\r
+       {\r
+           SetupCloseInfFile(hInf);\r
+           return FALSE;\r
+       }\r
+\r
+       bFileQueueCreated = TRUE;\r
+\r
+    }\r
+#endif\r
+\r
+    SetupInstallFromInfSectionW(NULL,\r
+                               hInf,\r
+                               SectionName,\r
+                               SPINST_REGISTRY,\r
+                               hClassKey,\r
+                               NULL,\r
+                               0,\r
+                               NULL,\r
+                               NULL,\r
+                               INVALID_HANDLE_VALUE,\r
+                               NULL);\r
+\r
+    /* FIXME: More code! */\r
+\r
+    if (bFileQueueCreated)\r
+       SetupCloseFileQueue(FileQueue);\r
+\r
+    SetupCloseInfFile(hInf);\r
+\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenClassRegKey  (SETUPAPI.@)\r
+ */\r
+HKEY WINAPI SetupDiOpenClassRegKey(\r
+        const GUID* ClassGuid,\r
+        REGSAM samDesired)\r
+{\r
+    return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,\r
+                                     DIOCR_INSTALLER, NULL, NULL);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenClassRegKeyExA  (SETUPAPI.@)\r
+ */\r
+HKEY WINAPI SetupDiOpenClassRegKeyExA(\r
+        const GUID* ClassGuid,\r
+        REGSAM samDesired,\r
+        DWORD Flags,\r
+        PCSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    PWSTR MachineNameW = NULL;\r
+    HKEY hKey;\r
+\r
+    TRACE("\n");\r
+\r
+    if (MachineName)\r
+    {\r
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);\r
+        if (MachineNameW == NULL)\r
+            return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,\r
+                                     Flags, MachineNameW, Reserved);\r
+\r
+    if (MachineNameW)\r
+        MyFree(MachineNameW);\r
+\r
+    return hKey;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenClassRegKeyExW  (SETUPAPI.@)\r
+ */\r
+HKEY WINAPI SetupDiOpenClassRegKeyExW(\r
+        const GUID* ClassGuid,\r
+        REGSAM samDesired,\r
+        DWORD Flags,\r
+        PCWSTR MachineName,\r
+        PVOID Reserved)\r
+{\r
+    LPWSTR lpGuidString;\r
+    HKEY hClassesKey;\r
+    HKEY hClassKey;\r
+    LPCWSTR lpKeyName;\r
+\r
+    if (MachineName != NULL)\r
+    {\r
+        FIXME("Remote access not supported yet!\n");\r
+        return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    if (Flags == DIOCR_INSTALLER)\r
+    {\r
+        lpKeyName = ControlClass;\r
+    }\r
+    else if (Flags == DIOCR_INTERFACE)\r
+    {\r
+        lpKeyName = DeviceClasses;\r
+    }\r
+    else\r
+    {\r
+        ERR("Invalid Flags parameter!\n");\r
+        SetLastError(ERROR_INVALID_PARAMETER);\r
+        return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,\r
+                     lpKeyName,\r
+                     0,\r
+                     KEY_ALL_ACCESS,\r
+                     &hClassesKey))\r
+    {\r
+       return INVALID_HANDLE_VALUE;\r
+    }\r
+\r
+    if (ClassGuid == NULL)\r
+        return hClassesKey;\r
+\r
+    if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)\r
+    {\r
+       RegCloseKey(hClassesKey);\r
+       return FALSE;\r
+    }\r
+\r
+    if (RegOpenKeyExW(hClassesKey,\r
+                     lpGuidString,\r
+                     0,\r
+                     KEY_ALL_ACCESS,\r
+                     &hClassKey))\r
+    {\r
+       RpcStringFreeW(&lpGuidString);\r
+       RegCloseKey(hClassesKey);\r
+       return FALSE;\r
+    }\r
+\r
+    RpcStringFreeW(&lpGuidString);\r
+    RegCloseKey(hClassesKey);\r
+\r
+    return hClassKey;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenDeviceInterfaceW (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiOpenDeviceInterfaceW(\r
+       HDEVINFO DeviceInfoSet,\r
+       PCWSTR DevicePath,\r
+       DWORD OpenFlags,\r
+       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)\r
+{\r
+    FIXME("%p %s %08lx %p\n",\r
+        DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenDeviceInterfaceA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiOpenDeviceInterfaceA(\r
+       HDEVINFO DeviceInfoSet,\r
+       PCSTR DevicePath,\r
+       DWORD OpenFlags,\r
+       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)\r
+{\r
+    FIXME("%p %s %08lx %p\n", DeviceInfoSet,\r
+        debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiSetClassInstallParamsA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiSetClassInstallParamsA(\r
+       HDEVINFO  DeviceInfoSet,\r
+       PSP_DEVINFO_DATA DeviceInfoData,\r
+       PSP_CLASSINSTALL_HEADER ClassInstallParams,\r
+       DWORD ClassInstallParamsSize)\r
+{\r
+    FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,\r
+          ClassInstallParams->InstallFunction, ClassInstallParamsSize);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiCallClassInstaller (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiCallClassInstaller(\r
+       DWORD InstallFunction,\r
+       HDEVINFO DeviceInfoSet,\r
+       PSP_DEVINFO_DATA DeviceInfoData)\r
+{\r
+    FIXME("%ld %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceInstallParamsA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceInstallParamsA(\r
+       HDEVINFO DeviceInfoSet,\r
+       PSP_DEVINFO_DATA DeviceInfoData,\r
+       PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)\r
+{\r
+    FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiOpenDevRegKey (SETUPAPI.@)\r
+ */\r
+HKEY WINAPI SetupDiOpenDevRegKey(\r
+       HDEVINFO DeviceInfoSet,\r
+       PSP_DEVINFO_DATA DeviceInfoData,\r
+       DWORD Scope,\r
+       DWORD HwProfile,\r
+       DWORD KeyType,\r
+       REGSAM samDesired)\r
+{\r
+    FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,\r
+          Scope, HwProfile, KeyType, samDesired);\r
+    return INVALID_HANDLE_VALUE;\r
+}\r
index f0c5154..b746b1a 100644 (file)
-/*
- * SetupAPI device installer
- *
- * Copyright 2000 Andreas Mohr 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "setupx16.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-/***********************************************************************
- *             DiGetClassDevs (SETUPX.304)
- * Return a list of installed system devices.
- * Uses HKLM\\ENUM to list devices.
- */
-RETERR16 WINAPI DiGetClassDevs16(LPLPDEVICE_INFO16 lplpdi,
-                                 LPCSTR lpszClassName, HWND16 hwndParent, INT16 iFlags)
-{
-    LPDEVICE_INFO16 lpdi;
-
-    FIXME("(%p, '%s', %04x, %04x), semi-stub.\n",
-          lplpdi, lpszClassName, hwndParent, iFlags);
-    lpdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO16));
-    lpdi->cbSize = sizeof(DEVICE_INFO16);
-    *lplpdi = (LPDEVICE_INFO16)MapLS(lpdi);
-    return OK;
-}
-
-/***********************************************************************
- *             DiBuildCompatDrvList (SETUPX.300)
- */
-RETERR16 WINAPI DiBuildCompatDrvList16(LPDEVICE_INFO16 lpdi)
-{
-    FIXME("(%p): stub\n", lpdi);
-    lpdi->lpCompatDrvList = NULL;
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiBuildClassDrvList (SETUPX.301)
- */
-RETERR16 WINAPI DiBuildClassDrvList16(LPDEVICE_INFO16 lpdi)
-{
-    FIXME("(%p): stub\n", lpdi);
-    lpdi->lpCompatDrvList = NULL;
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiCallClassInstaller (SETUPX.308)
- */
-RETERR16 WINAPI DiCallClassInstaller16(DI_FUNCTION16 diFctn, LPDEVICE_INFO16 lpdi)
-{
-    FIXME("(%x, %p): stub\n", diFctn, lpdi);
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiCreateDevRegKey (SETUPX.318)
- */
-RETERR16 WINAPI DiCreateDevRegKey16(LPDEVICE_INFO16 lpdi,
-                                    VOID* p2, WORD w3,
-                                    LPCSTR s4, WORD w5)
-{
-    FIXME("(%p, %p, %x, %s, %x): stub\n", lpdi, p2, w3, debugstr_a(s4), w5);
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiDeleteDevRegKey (SETUPX.344)
- */
-RETERR16 WINAPI DiDeleteDevRegKey16(LPDEVICE_INFO16 lpdi, INT16 iFlags)
-{
-    FIXME("(%p, %x): stub\n", lpdi, iFlags);
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiCreateDeviceInfo (SETUPX.303)
- */
-RETERR16 WINAPI DiCreateDeviceInfo16(LPLPDEVICE_INFO16 lplpdi,
-                                     LPCSTR lpszDescription, DWORD dnDevnode,
-                                     HKEY16 hkey, LPCSTR lpszRegsubkey,
-                                     LPCSTR lpszClassName, HWND16 hwndParent)
-{
-    LPDEVICE_INFO16 lpdi;
-    FIXME("(%p %s %08lx %x %s %s %x): stub\n", lplpdi,
-          debugstr_a(lpszDescription), dnDevnode, hkey,
-          debugstr_a(lpszRegsubkey), debugstr_a(lpszClassName), hwndParent);
-    lpdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO16));
-    lpdi->cbSize = sizeof(DEVICE_INFO16);
-    strcpy(lpdi->szClassName, lpszClassName);
-    lpdi->hwndParent = hwndParent;
-    *lplpdi = (LPDEVICE_INFO16)MapLS(lpdi);
-    return OK;
-}
-
-/***********************************************************************
- *             DiDestroyDeviceInfoList (SETUPX.305)
- */
-RETERR16 WINAPI DiDestroyDeviceInfoList16(LPDEVICE_INFO16 lpdi)
-{
-    FIXME("(%p): stub\n", lpdi);
-    return FALSE;
-}
-
-/***********************************************************************
- *             DiOpenDevRegKey (SETUPX.319)
- */
-RETERR16 WINAPI DiOpenDevRegKey16(LPDEVICE_INFO16 lpdi,
-                                  LPHKEY16 lphk,INT16 iFlags)
-{
-    FIXME("(%p %p %d): stub\n", lpdi, lphk, iFlags);
-    return FALSE;
-}
+/*\r
+ * SetupAPI device installer\r
+ *\r
+ * Copyright 2000 Andreas Mohr for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "setupx16.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+/***********************************************************************\r
+ *             DiGetClassDevs (SETUPX.304)\r
+ * Return a list of installed system devices.\r
+ * Uses HKLM\\ENUM to list devices.\r
+ */\r
+RETERR16 WINAPI DiGetClassDevs16(LPLPDEVICE_INFO16 lplpdi,\r
+                                 LPCSTR lpszClassName, HWND16 hwndParent, INT16 iFlags)\r
+{\r
+    LPDEVICE_INFO16 lpdi;\r
+\r
+    FIXME("(%p, '%s', %04x, %04x), semi-stub.\n",\r
+          lplpdi, lpszClassName, hwndParent, iFlags);\r
+    lpdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO16));\r
+    lpdi->cbSize = sizeof(DEVICE_INFO16);\r
+    *lplpdi = (LPDEVICE_INFO16)MapLS(lpdi);\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiBuildCompatDrvList (SETUPX.300)\r
+ */\r
+RETERR16 WINAPI DiBuildCompatDrvList16(LPDEVICE_INFO16 lpdi)\r
+{\r
+    FIXME("(%p): stub\n", lpdi);\r
+    lpdi->lpCompatDrvList = NULL;\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiBuildClassDrvList (SETUPX.301)\r
+ */\r
+RETERR16 WINAPI DiBuildClassDrvList16(LPDEVICE_INFO16 lpdi)\r
+{\r
+    FIXME("(%p): stub\n", lpdi);\r
+    lpdi->lpCompatDrvList = NULL;\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiCallClassInstaller (SETUPX.308)\r
+ */\r
+RETERR16 WINAPI DiCallClassInstaller16(DI_FUNCTION16 diFctn, LPDEVICE_INFO16 lpdi)\r
+{\r
+    FIXME("(%x, %p): stub\n", diFctn, lpdi);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiCreateDevRegKey (SETUPX.318)\r
+ */\r
+RETERR16 WINAPI DiCreateDevRegKey16(LPDEVICE_INFO16 lpdi,\r
+                                    VOID* p2, WORD w3,\r
+                                    LPCSTR s4, WORD w5)\r
+{\r
+    FIXME("(%p, %p, %x, %s, %x): stub\n", lpdi, p2, w3, debugstr_a(s4), w5);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiDeleteDevRegKey (SETUPX.344)\r
+ */\r
+RETERR16 WINAPI DiDeleteDevRegKey16(LPDEVICE_INFO16 lpdi, INT16 iFlags)\r
+{\r
+    FIXME("(%p, %x): stub\n", lpdi, iFlags);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiCreateDeviceInfo (SETUPX.303)\r
+ */\r
+RETERR16 WINAPI DiCreateDeviceInfo16(LPLPDEVICE_INFO16 lplpdi,\r
+                                     LPCSTR lpszDescription, DWORD dnDevnode,\r
+                                     HKEY16 hkey, LPCSTR lpszRegsubkey,\r
+                                     LPCSTR lpszClassName, HWND16 hwndParent)\r
+{\r
+    LPDEVICE_INFO16 lpdi;\r
+    FIXME("(%p %s %08lx %x %s %s %x): stub\n", lplpdi,\r
+          debugstr_a(lpszDescription), dnDevnode, hkey,\r
+          debugstr_a(lpszRegsubkey), debugstr_a(lpszClassName), hwndParent);\r
+    lpdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO16));\r
+    lpdi->cbSize = sizeof(DEVICE_INFO16);\r
+    strcpy(lpdi->szClassName, lpszClassName);\r
+    lpdi->hwndParent = hwndParent;\r
+    *lplpdi = (LPDEVICE_INFO16)MapLS(lpdi);\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiDestroyDeviceInfoList (SETUPX.305)\r
+ */\r
+RETERR16 WINAPI DiDestroyDeviceInfoList16(LPDEVICE_INFO16 lpdi)\r
+{\r
+    FIXME("(%p): stub\n", lpdi);\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             DiOpenDevRegKey (SETUPX.319)\r
+ */\r
+RETERR16 WINAPI DiOpenDevRegKey16(LPDEVICE_INFO16 lpdi,\r
+                                  LPHKEY16 lphk,INT16 iFlags)\r
+{\r
+    FIXME("(%p %p %d): stub\n", lpdi, lphk, iFlags);\r
+    return FALSE;\r
+}\r
index 639da02..cec3373 100644 (file)
-/*
- * Directory id handling
- *
- * Copyright 2002 Alexandre Julliard 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winerror.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "shlobj.h"
-#include "wine/unicode.h"
-#include "setupapi_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-#define MAX_SYSTEM_DIRID DIRID_PRINTPROCESSOR
-#define MIN_CSIDL_DIRID 0x4000
-#define MAX_CSIDL_DIRID 0x403f
-
-struct user_dirid
-{
-    int    id;
-    WCHAR *str;
-};
-
-static int nb_user_dirids;     /* number of user dirids in use */
-static int alloc_user_dirids;  /* number of allocated user dirids */
-static struct user_dirid *user_dirids;
-static const WCHAR *system_dirids[MAX_SYSTEM_DIRID+1];
-static const WCHAR *csidl_dirids[MAX_CSIDL_DIRID-MIN_CSIDL_DIRID+1];
-
-/* retrieve the string for unknown dirids */
-static const WCHAR *get_unknown_dirid(void)
-{
-    static WCHAR *unknown_dirid;
-    static const WCHAR unknown_str[] = {'\\','u','n','k','n','o','w','n',0};
-
-    if (!unknown_dirid)
-    {
-        UINT len = GetSystemDirectoryW( NULL, 0 ) + strlenW(unknown_str);
-        if (!(unknown_dirid = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
-        GetSystemDirectoryW( unknown_dirid, len );
-        strcatW( unknown_dirid, unknown_str );
-    }
-    return unknown_dirid;
-}
-
-static const WCHAR *get_csidl_dir(DWORD csidl);
-
-/* create the string for a system dirid */
-static const WCHAR *create_system_dirid( int dirid )
-{
-    static const WCHAR Null[]    = {0};
-    static const WCHAR C_Root[]  = {'C',':','\\',0};
-    static const WCHAR Drivers[] = {'\\','d','r','i','v','e','r','s',0};
-    static const WCHAR Inf[]     = {'\\','i','n','f',0};
-    static const WCHAR Help[]    = {'\\','h','e','l','p',0};
-    static const WCHAR Fonts[]   = {'\\','f','o','n','t','s',0};
-    static const WCHAR Viewers[] = {'\\','v','i','e','w','e','r','s',0};
-    static const WCHAR System[]  = {'\\','s','y','s','t','e','m',0};
-    static const WCHAR Spool[]   = {'\\','s','p','o','o','l',0};
-    static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
-
-    WCHAR buffer[MAX_PATH+32], *str;
-    int len;
-
-    switch(dirid)
-    {
-    case DIRID_NULL:
-        return Null;
-    case DIRID_WINDOWS:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        break;
-    case DIRID_SYSTEM:
-        GetSystemDirectoryW( buffer, MAX_PATH );
-        break;
-    case DIRID_DRIVERS:
-        GetSystemDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Drivers );
-        break;
-    case DIRID_INF:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Inf );
-        break;
-    case DIRID_HELP:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Help );
-        break;
-    case DIRID_FONTS:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Fonts );
-        break;
-    case DIRID_VIEWERS:
-        GetSystemDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Viewers );
-        break;
-    case DIRID_APPS:
-        return C_Root;  /* FIXME */
-    case DIRID_SHARED:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        break;
-    case DIRID_BOOT:
-        return C_Root;  /* FIXME */
-    case DIRID_SYSTEM16:
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, System );
-        break;
-    case DIRID_SPOOL:
-    case DIRID_SPOOLDRIVERS:  /* FIXME */
-        GetWindowsDirectoryW( buffer, MAX_PATH );
-        strcatW( buffer, Spool );
-        break;
-    case DIRID_USERPROFILE:
-        if (GetEnvironmentVariableW( UserProfile, buffer, MAX_PATH )) break;
-        return get_csidl_dir(CSIDL_PROFILE);
-    case DIRID_LOADER:
-        return C_Root;  /* FIXME */
-    case DIRID_COLOR:  /* FIXME */
-    case DIRID_PRINTPROCESSOR:  /* FIXME */
-    default:
-        FIXME( "unknown dirid %d\n", dirid );
-        return get_unknown_dirid();
-    }
-    len = (strlenW(buffer) + 1) * sizeof(WCHAR);
-    if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
-    return str;
-}
-
-static const WCHAR *get_csidl_dir( DWORD csidl )
-{
-    WCHAR buffer[MAX_PATH], *str;
-    int len;
-
-    if (!SHGetSpecialFolderPathW( NULL, buffer, csidl, TRUE ))
-    {
-        FIXME( "CSIDL %lx not found\n", csidl );
-        return get_unknown_dirid();
-    }
-    len = (strlenW(buffer) + 1) * sizeof(WCHAR);
-    if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
-    return str;
-}
-
-/* retrieve the string corresponding to a dirid, or NULL if none */
-const WCHAR *DIRID_get_string( HINF hinf, int dirid )
-{
-    int i;
-
-    if (dirid == DIRID_ABSOLUTE || dirid == DIRID_ABSOLUTE_16BIT) dirid = DIRID_NULL;
-
-    if (dirid >= DIRID_USER)
-    {
-        for (i = 0; i < nb_user_dirids; i++)
-            if (user_dirids[i].id == dirid) return user_dirids[i].str;
-        ERR("user id %d not found\n", dirid );
-        return NULL;
-    }
-    else if (dirid >= MIN_CSIDL_DIRID)
-    {
-        if (dirid > MAX_CSIDL_DIRID) return get_unknown_dirid();
-        dirid -= MIN_CSIDL_DIRID;
-        if (!csidl_dirids[dirid]) csidl_dirids[dirid] = get_csidl_dir( dirid );
-        return csidl_dirids[dirid];
-    }
-    else
-    {
-        if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();
-        if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf );
-        if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );
-        return system_dirids[dirid];
-    }
-}
-
-/* store a user dirid string */
-static BOOL store_user_dirid( HINF hinf, int id, WCHAR *str )
-{
-    int i;
-
-    for (i = 0; i < nb_user_dirids; i++) if (user_dirids[i].id == id) break;
-
-    if (i < nb_user_dirids) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
-    else
-    {
-        if (nb_user_dirids >= alloc_user_dirids)
-        {
-            int new_size = max( 32, alloc_user_dirids * 2 );
-
-           struct user_dirid *new;
-
-           if (user_dirids)
-                new = HeapReAlloc( GetProcessHeap(), 0, user_dirids,
-                                                  new_size * sizeof(*new) );
-           else
-                new = HeapAlloc( GetProcessHeap(), 0, 
-                                                  new_size * sizeof(*new) );
-
-            if (!new) return FALSE;
-            user_dirids = new;
-            alloc_user_dirids = new_size;
-        }
-        nb_user_dirids++;
-    }
-    user_dirids[i].id  = id;
-    user_dirids[i].str = str;
-    TRACE("id %d -> %s\n", id, debugstr_w(str) );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupSetDirectoryIdA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupSetDirectoryIdA( HINF hinf, DWORD id, PCSTR dir )
-{
-    UNICODE_STRING dirW;
-    int i;
-
-    if (!id)  /* clear everything */
-    {
-        for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
-        nb_user_dirids = 0;
-        return TRUE;
-    }
-    if (id < DIRID_USER)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-
-    /* duplicate the string */
-    if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return FALSE;
-    }
-    return store_user_dirid( hinf, id, dirW.Buffer );
-}
-
-
-/***********************************************************************
- *             SetupSetDirectoryIdW    (SETUPAPI.@)
- */
-BOOL WINAPI SetupSetDirectoryIdW( HINF hinf, DWORD id, PCWSTR dir )
-{
-    int i, len;
-    WCHAR *str;
-
-    if (!id)  /* clear everything */
-    {
-        for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
-        nb_user_dirids = 0;
-        return TRUE;
-    }
-    if (id < DIRID_USER)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-
-    /* duplicate the string */
-    len = (strlenW(dir)+1) * sizeof(WCHAR);
-    if (!(str = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
-    memcpy( str, dir, len );
-    return store_user_dirid( hinf, id, str );
-}
+/*\r
+ * Directory id handling\r
+ *\r
+ * Copyright 2002 Alexandre Julliard for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "winerror.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "shlobj.h"\r
+#include "wine/unicode.h"\r
+#include "setupapi_private.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+#define MAX_SYSTEM_DIRID DIRID_PRINTPROCESSOR\r
+#define MIN_CSIDL_DIRID 0x4000\r
+#define MAX_CSIDL_DIRID 0x403f\r
+\r
+struct user_dirid\r
+{\r
+    int    id;\r
+    WCHAR *str;\r
+};\r
+\r
+static int nb_user_dirids;     /* number of user dirids in use */\r
+static int alloc_user_dirids;  /* number of allocated user dirids */\r
+static struct user_dirid *user_dirids;\r
+static const WCHAR *system_dirids[MAX_SYSTEM_DIRID+1];\r
+static const WCHAR *csidl_dirids[MAX_CSIDL_DIRID-MIN_CSIDL_DIRID+1];\r
+\r
+/* retrieve the string for unknown dirids */\r
+static const WCHAR *get_unknown_dirid(void)\r
+{\r
+    static WCHAR *unknown_dirid;\r
+    static const WCHAR unknown_str[] = {'\\','u','n','k','n','o','w','n',0};\r
+\r
+    if (!unknown_dirid)\r
+    {\r
+        UINT len = GetSystemDirectoryW( NULL, 0 ) + strlenW(unknown_str);\r
+        if (!(unknown_dirid = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;\r
+        GetSystemDirectoryW( unknown_dirid, len );\r
+        strcatW( unknown_dirid, unknown_str );\r
+    }\r
+    return unknown_dirid;\r
+}\r
+\r
+static const WCHAR *get_csidl_dir(DWORD csidl);\r
+\r
+/* create the string for a system dirid */\r
+static const WCHAR *create_system_dirid( int dirid )\r
+{\r
+    static const WCHAR Null[]    = {0};\r
+    static const WCHAR C_Root[]  = {'C',':','\\',0};\r
+    static const WCHAR Drivers[] = {'\\','d','r','i','v','e','r','s',0};\r
+    static const WCHAR Inf[]     = {'\\','i','n','f',0};\r
+    static const WCHAR Help[]    = {'\\','h','e','l','p',0};\r
+    static const WCHAR Fonts[]   = {'\\','f','o','n','t','s',0};\r
+    static const WCHAR Viewers[] = {'\\','v','i','e','w','e','r','s',0};\r
+    static const WCHAR System[]  = {'\\','s','y','s','t','e','m',0};\r
+    static const WCHAR Spool[]   = {'\\','s','p','o','o','l',0};\r
+    static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};\r
+\r
+    WCHAR buffer[MAX_PATH+32], *str;\r
+    int len;\r
+\r
+    switch(dirid)\r
+    {\r
+    case DIRID_NULL:\r
+        return Null;\r
+    case DIRID_WINDOWS:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        break;\r
+    case DIRID_SYSTEM:\r
+        GetSystemDirectoryW( buffer, MAX_PATH );\r
+        break;\r
+    case DIRID_DRIVERS:\r
+        GetSystemDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Drivers );\r
+        break;\r
+    case DIRID_INF:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Inf );\r
+        break;\r
+    case DIRID_HELP:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Help );\r
+        break;\r
+    case DIRID_FONTS:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Fonts );\r
+        break;\r
+    case DIRID_VIEWERS:\r
+        GetSystemDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Viewers );\r
+        break;\r
+    case DIRID_APPS:\r
+        return C_Root;  /* FIXME */\r
+    case DIRID_SHARED:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        break;\r
+    case DIRID_BOOT:\r
+        return C_Root;  /* FIXME */\r
+    case DIRID_SYSTEM16:\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, System );\r
+        break;\r
+    case DIRID_SPOOL:\r
+    case DIRID_SPOOLDRIVERS:  /* FIXME */\r
+        GetWindowsDirectoryW( buffer, MAX_PATH );\r
+        strcatW( buffer, Spool );\r
+        break;\r
+    case DIRID_USERPROFILE:\r
+        if (GetEnvironmentVariableW( UserProfile, buffer, MAX_PATH )) break;\r
+        return get_csidl_dir(CSIDL_PROFILE);\r
+    case DIRID_LOADER:\r
+        return C_Root;  /* FIXME */\r
+    case DIRID_COLOR:  /* FIXME */\r
+    case DIRID_PRINTPROCESSOR:  /* FIXME */\r
+    default:\r
+        FIXME( "unknown dirid %d\n", dirid );\r
+        return get_unknown_dirid();\r
+    }\r
+    len = (strlenW(buffer) + 1) * sizeof(WCHAR);\r
+    if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );\r
+    return str;\r
+}\r
+\r
+static const WCHAR *get_csidl_dir( DWORD csidl )\r
+{\r
+    WCHAR buffer[MAX_PATH], *str;\r
+    int len;\r
+\r
+    if (!SHGetSpecialFolderPathW( NULL, buffer, csidl, TRUE ))\r
+    {\r
+        FIXME( "CSIDL %lx not found\n", csidl );\r
+        return get_unknown_dirid();\r
+    }\r
+    len = (strlenW(buffer) + 1) * sizeof(WCHAR);\r
+    if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );\r
+    return str;\r
+}\r
+\r
+/* retrieve the string corresponding to a dirid, or NULL if none */\r
+const WCHAR *DIRID_get_string( HINF hinf, int dirid )\r
+{\r
+    int i;\r
+\r
+    if (dirid == DIRID_ABSOLUTE || dirid == DIRID_ABSOLUTE_16BIT) dirid = DIRID_NULL;\r
+\r
+    if (dirid >= DIRID_USER)\r
+    {\r
+        for (i = 0; i < nb_user_dirids; i++)\r
+            if (user_dirids[i].id == dirid) return user_dirids[i].str;\r
+        ERR("user id %d not found\n", dirid );\r
+        return NULL;\r
+    }\r
+    else if (dirid >= MIN_CSIDL_DIRID)\r
+    {\r
+        if (dirid > MAX_CSIDL_DIRID) return get_unknown_dirid();\r
+        dirid -= MIN_CSIDL_DIRID;\r
+        if (!csidl_dirids[dirid]) csidl_dirids[dirid] = get_csidl_dir( dirid );\r
+        return csidl_dirids[dirid];\r
+    }\r
+    else\r
+    {\r
+        if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();\r
+        if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf );\r
+        if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );\r
+        return system_dirids[dirid];\r
+    }\r
+}\r
+\r
+/* store a user dirid string */\r
+static BOOL store_user_dirid( HINF hinf, int id, WCHAR *str )\r
+{\r
+    int i;\r
+\r
+    for (i = 0; i < nb_user_dirids; i++) if (user_dirids[i].id == id) break;\r
+\r
+    if (i < nb_user_dirids) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );\r
+    else\r
+    {\r
+        if (nb_user_dirids >= alloc_user_dirids)\r
+        {\r
+            int new_size = max( 32, alloc_user_dirids * 2 );\r
+\r
+           struct user_dirid *new;\r
+\r
+           if (user_dirids)\r
+                new = HeapReAlloc( GetProcessHeap(), 0, user_dirids,\r
+                                                  new_size * sizeof(*new) );\r
+           else\r
+                new = HeapAlloc( GetProcessHeap(), 0, \r
+                                                  new_size * sizeof(*new) );\r
+\r
+            if (!new) return FALSE;\r
+            user_dirids = new;\r
+            alloc_user_dirids = new_size;\r
+        }\r
+        nb_user_dirids++;\r
+    }\r
+    user_dirids[i].id  = id;\r
+    user_dirids[i].str = str;\r
+    TRACE("id %d -> %s\n", id, debugstr_w(str) );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupSetDirectoryIdA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupSetDirectoryIdA( HINF hinf, DWORD id, PCSTR dir )\r
+{\r
+    UNICODE_STRING dirW;\r
+    int i;\r
+\r
+    if (!id)  /* clear everything */\r
+    {\r
+        for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );\r
+        nb_user_dirids = 0;\r
+        return TRUE;\r
+    }\r
+    if (id < DIRID_USER)\r
+    {\r
+        SetLastError( ERROR_INVALID_PARAMETER );\r
+        return FALSE;\r
+    }\r
+\r
+    /* duplicate the string */\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return FALSE;\r
+    }\r
+    return store_user_dirid( hinf, id, dirW.Buffer );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupSetDirectoryIdW    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupSetDirectoryIdW( HINF hinf, DWORD id, PCWSTR dir )\r
+{\r
+    int i, len;\r
+    WCHAR *str;\r
+\r
+    if (!id)  /* clear everything */\r
+    {\r
+        for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );\r
+        nb_user_dirids = 0;\r
+        return TRUE;\r
+    }\r
+    if (id < DIRID_USER)\r
+    {\r
+        SetLastError( ERROR_INVALID_PARAMETER );\r
+        return FALSE;\r
+    }\r
+\r
+    /* duplicate the string */\r
+    len = (strlenW(dir)+1) * sizeof(WCHAR);\r
+    if (!(str = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;\r
+    memcpy( str, dir, len );\r
+    return store_user_dirid( hinf, id, str );\r
+}\r
index 72c6928..4bff4c6 100644 (file)
-/*
- * SetupAPI DiskSpace functions
- *
- * Copyright 2004 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "setupapi.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-typedef struct {
-    WCHAR   lpzName[20];
-    LONGLONG dwFreeSpace;
-    LONGLONG dwWantedSpace;
-} DRIVE_ENTRY, *LPDRIVE_ENTRY;
-
-typedef struct {
-    DWORD   dwDriveCount;
-    DRIVE_ENTRY Drives[26];
-} DISKSPACELIST, *LPDISKSPACELIST;
-
-
-/***********************************************************************
- *             SetupCreateDiskSpaceListW  (SETUPAPI.@)
- */
-HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags)
-{
-    WCHAR drives[255];
-    DWORD rc;
-    WCHAR *ptr;
-    LPDISKSPACELIST list=NULL;
-
-    rc = GetLogicalDriveStringsW(255,drives);
-
-    if (rc == 0)
-        return NULL;
-
-    list = (LPDISKSPACELIST)HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST));
-
-    list->dwDriveCount = 0;
-    
-    ptr = drives;
-    
-    while (*ptr)
-    {
-        DWORD type = GetDriveTypeW(ptr);
-        DWORD len;
-        if (type == DRIVE_FIXED)
-        {
-            DWORD clusters;
-            DWORD sectors;
-            DWORD bytes;
-            DWORD total;
-            lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr);
-            GetDiskFreeSpaceW(ptr,&sectors,&bytes,&clusters,&total);
-            list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors *
-                                                           bytes;
-            list->Drives[list->dwDriveCount].dwWantedSpace = 0;
-            list->dwDriveCount++;
-        }
-       len = lstrlenW(ptr);
-       len++;
-       ptr+=sizeof(WCHAR)*len;
-    }
-    return  (HANDLE)list;
-}
-
-
-/***********************************************************************
- *             SetupCreateDiskSpaceListA  (SETUPAPI.@)
- */
-HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT Flags)
-{
-    return SetupCreateDiskSpaceListW( Reserved1, Reserved2, Flags );
-}
-
-
-/***********************************************************************
- *             SetupAddInstallSectionToDiskSpaceListA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, 
-                        HINF InfHandle, HINF LayoutInfHandle, 
-                        LPSTR SectionName, PVOID Reserved1, UINT Reserved2)
-{
-    FIXME ("Stub\n");
-    return TRUE;
-}
-
-/***********************************************************************
-*              SetupQuerySpaceRequiredOnDriveA  (SETUPAPI.@)
-*/
-BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, 
-                        LPSTR DriveSpec, LONGLONG* SpaceRequired, 
-                        PVOID Reserved1, UINT Reserved2)
-{
-    WCHAR driveW[20];
-    unsigned int i;
-    LPDISKSPACELIST list = (LPDISKSPACELIST)DiskSpace;
-    BOOL rc = FALSE;
-    static const WCHAR bkslsh[]= {'\\',0};
-
-    MultiByteToWideChar(CP_ACP,0,DriveSpec,-1,driveW,20);
-
-    lstrcatW(driveW,bkslsh);
-
-    TRACE("Looking for drive %s\n",debugstr_w(driveW));
-    for (i = 0; i < list->dwDriveCount; i++)
-    {
-        TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName));
-        if (lstrcmpW(driveW,list->Drives[i].lpzName)==0)
-        {
-            rc = TRUE;
-            *SpaceRequired = list->Drives[i].dwWantedSpace;
-            break;
-        }
-    }
-
-    return rc;
-}
-
-/***********************************************************************
-*              SetupDestroyDiskSpaceList  (SETUPAPI.@)
-*/
-BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace)
-{
-    LPDISKSPACELIST list = (LPDISKSPACELIST)DiskSpace;
-    HeapFree(GetProcessHeap(),0,list);
-    return TRUE; 
-}
+/*\r
+ * SetupAPI DiskSpace functions\r
+ *\r
+ * Copyright 2004 CodeWeavers (Aric Stewart)\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "winreg.h"\r
+#include "setupapi.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+typedef struct {\r
+    WCHAR   lpzName[20];\r
+    LONGLONG dwFreeSpace;\r
+    LONGLONG dwWantedSpace;\r
+} DRIVE_ENTRY, *LPDRIVE_ENTRY;\r
+\r
+typedef struct {\r
+    DWORD   dwDriveCount;\r
+    DRIVE_ENTRY Drives[26];\r
+} DISKSPACELIST, *LPDISKSPACELIST;\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupCreateDiskSpaceListW  (SETUPAPI.@)\r
+ */\r
+HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags)\r
+{\r
+    WCHAR drives[255];\r
+    DWORD rc;\r
+    WCHAR *ptr;\r
+    LPDISKSPACELIST list=NULL;\r
+\r
+    rc = GetLogicalDriveStringsW(255,drives);\r
+\r
+    if (rc == 0)\r
+        return NULL;\r
+\r
+    list = (LPDISKSPACELIST)HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST));\r
+\r
+    list->dwDriveCount = 0;\r
+    \r
+    ptr = drives;\r
+    \r
+    while (*ptr)\r
+    {\r
+        DWORD type = GetDriveTypeW(ptr);\r
+        DWORD len;\r
+        if (type == DRIVE_FIXED)\r
+        {\r
+            DWORD clusters;\r
+            DWORD sectors;\r
+            DWORD bytes;\r
+            DWORD total;\r
+            lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr);\r
+            GetDiskFreeSpaceW(ptr,&sectors,&bytes,&clusters,&total);\r
+            list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors *\r
+                                                           bytes;\r
+            list->Drives[list->dwDriveCount].dwWantedSpace = 0;\r
+            list->dwDriveCount++;\r
+        }\r
+       len = lstrlenW(ptr);\r
+       len++;\r
+       ptr+=sizeof(WCHAR)*len;\r
+    }\r
+    return  (HANDLE)list;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupCreateDiskSpaceListA  (SETUPAPI.@)\r
+ */\r
+HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT Flags)\r
+{\r
+    return SetupCreateDiskSpaceListW( Reserved1, Reserved2, Flags );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupAddInstallSectionToDiskSpaceListA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, \r
+                        HINF InfHandle, HINF LayoutInfHandle, \r
+                        LPSTR SectionName, PVOID Reserved1, UINT Reserved2)\r
+{\r
+    FIXME ("Stub\n");\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+*              SetupQuerySpaceRequiredOnDriveA  (SETUPAPI.@)\r
+*/\r
+BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace, \r
+                        LPSTR DriveSpec, LONGLONG* SpaceRequired, \r
+                        PVOID Reserved1, UINT Reserved2)\r
+{\r
+    WCHAR driveW[20];\r
+    unsigned int i;\r
+    LPDISKSPACELIST list = (LPDISKSPACELIST)DiskSpace;\r
+    BOOL rc = FALSE;\r
+    static const WCHAR bkslsh[]= {'\\',0};\r
+\r
+    MultiByteToWideChar(CP_ACP,0,DriveSpec,-1,driveW,20);\r
+\r
+    lstrcatW(driveW,bkslsh);\r
+\r
+    TRACE("Looking for drive %s\n",debugstr_w(driveW));\r
\r
+    for (i = 0; i < list->dwDriveCount; i++)\r
+    {\r
+        TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName));\r
+        if (lstrcmpW(driveW,list->Drives[i].lpzName)==0)\r
+        {\r
+            rc = TRUE;\r
+            *SpaceRequired = list->Drives[i].dwWantedSpace;\r
+            break;\r
+        }\r
+    }\r
+\r
+    return rc;\r
+}\r
+\r
+/***********************************************************************\r
+*              SetupDestroyDiskSpaceList  (SETUPAPI.@)\r
+*/\r
+BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace)\r
+{\r
+    LPDISKSPACELIST list = (LPDISKSPACELIST)DiskSpace;\r
+    HeapFree(GetProcessHeap(),0,list);\r
+    return TRUE; \r
+}\r
index c508db6..467f376 100644 (file)
-/*
- * SetupX .inf file parsing functions
- *
- * Copyright 2000 Andreas Mohr 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * FIXME:
- * - return values ???
- * - this should be reimplemented at some point to have its own
- *   file parsing instead of using profile functions,
- *   as some SETUPX exports probably demand that
- *   (IpSaveRestorePosition, IpFindNextMatchLine, ...).
- */
-
-#include <stdarg.h>
-#include <string.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "setupx16.h"
-#include "setupapi_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-#define MAX_HANDLES 16384
-#define FIRST_HANDLE 32
-
-static HINF handles[MAX_HANDLES];
-
-
-static RETERR16 alloc_hinf16( HINF hinf, HINF16 *hinf16 )
-{
-    int i;
-    for (i = 0; i < MAX_HANDLES; i++)
-    {
-        if (!handles[i])
-        {
-            handles[i] = hinf;
-            *hinf16 = i + FIRST_HANDLE;
-            return OK;
-        }
-    }
-    return ERR_IP_OUT_OF_HANDLES;
-}
-
-static HINF get_hinf( HINF16 hinf16 )
-{
-    int idx = hinf16 - FIRST_HANDLE;
-    if (idx < 0 || idx >= MAX_HANDLES) return 0;
-    return handles[idx];
-}
-
-
-static HINF free_hinf16( HINF16 hinf16 )
-{
-    HINF ret;
-    int idx = hinf16 - FIRST_HANDLE;
-
-    if (idx < 0 || idx >= MAX_HANDLES) return 0;
-    ret = handles[idx];
-    handles[idx] = 0;
-    return ret;
-}
-
-/* convert last error code to a RETERR16 value */
-static RETERR16 get_last_error(void)
-{
-    switch(GetLastError())
-    {
-    case ERROR_EXPECTED_SECTION_NAME:
-    case ERROR_BAD_SECTION_NAME_LINE:
-    case ERROR_SECTION_NAME_TOO_LONG: return ERR_IP_INVALID_SECT_NAME;
-    case ERROR_SECTION_NOT_FOUND: return ERR_IP_SECT_NOT_FOUND;
-    case ERROR_LINE_NOT_FOUND: return ERR_IP_LINE_NOT_FOUND;
-    default: return IP_ERROR;  /* FIXME */
-    }
-}
-
-
-/***********************************************************************
- *             IpOpen (SETUPX.2)
- *
- */
-RETERR16 WINAPI IpOpen16( LPCSTR filename, HINF16 *hinf16 )
-{
-    HINF hinf = SetupOpenInfFileA( filename, NULL, INF_STYLE_WIN4, NULL );
-    if (hinf == (HINF)INVALID_HANDLE_VALUE) return get_last_error();
-    return alloc_hinf16( hinf, hinf16 );
-}
-
-
-/***********************************************************************
- *             IpClose (SETUPX.4)
- */
-RETERR16 WINAPI IpClose16( HINF16 hinf16 )
-{
-    HINF hinf = free_hinf16( hinf16 );
-    if (!hinf) return ERR_IP_INVALID_HINF;
-    SetupCloseInfFile( hinf );
-    return OK;
-}
-
-
-/***********************************************************************
- *             IpGetProfileString (SETUPX.210)
- */
-RETERR16 WINAPI IpGetProfileString16( HINF16 hinf16, LPCSTR section, LPCSTR entry,
-                                      LPSTR buffer, WORD buflen )
-{
-    DWORD required_size;
-    HINF hinf = get_hinf( hinf16 );
-
-    if (!hinf) return ERR_IP_INVALID_HINF;
-    if (!SetupGetLineTextA( NULL, hinf, section, entry, buffer, buflen, &required_size ))
-        return get_last_error();
-    TRACE("%p: section %s entry %s ret %s\n",
-          hinf, debugstr_a(section), debugstr_a(entry), debugstr_a(buffer) );
-    return OK;
-}
-
-
-/***********************************************************************
- *             GenFormStrWithoutPlaceHolders (SETUPX.103)
- *
- * ought to be pretty much implemented, I guess...
- */
-void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR dst, LPCSTR src, HINF16 hinf16 )
-{
-    UNICODE_STRING srcW;
-    HINF hinf = get_hinf( hinf16 );
-
-    if (!hinf) return;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &srcW, src )) return;
-    PARSER_string_substA( hinf, srcW.Buffer, dst, MAX_INF_STRING_LENGTH );
-    RtlFreeUnicodeString( &srcW );
-    TRACE( "%s -> %s\n", debugstr_a(src), debugstr_a(dst) );
-}
-
-/***********************************************************************
- *             GenInstall (SETUPX.101)
- *
- * generic installer function for .INF file sections
- *
- * This is not perfect - patch whenever you can !
- *
- * wFlags == GENINSTALL_DO_xxx
- * e.g. NetMeeting:
- * first call GENINSTALL_DO_REGSRCPATH | GENINSTALL_DO_FILES,
- * second call GENINSTALL_DO_LOGCONFIG | CFGAUTO | INI2REG | REG | INI
- */
-RETERR16 WINAPI GenInstall16( HINF16 hinf16, LPCSTR section, WORD genflags )
-{
-    UINT flags = 0;
-    HINF hinf = get_hinf( hinf16 );
-    RETERR16 ret = OK;
-    void *context;
-
-    if (!hinf) return ERR_IP_INVALID_HINF;
-
-    if (genflags & GENINSTALL_DO_FILES) flags |= SPINST_FILES;
-    if (genflags & GENINSTALL_DO_INI) flags |= SPINST_INIFILES;
-    if (genflags & GENINSTALL_DO_REG) flags |= SPINST_REGISTRY;
-    if (genflags & GENINSTALL_DO_INI2REG) flags |= SPINST_INI2REG;
-    if (genflags & GENINSTALL_DO_LOGCONFIG) flags |= SPINST_LOGCONFIG;
-    if (genflags & GENINSTALL_DO_REGSRCPATH) FIXME( "unsupported flag: GENINSTALL_DO_REGSRCPATH\n" );
-    if (genflags & GENINSTALL_DO_CFGAUTO) FIXME( "unsupported flag: GENINSTALL_DO_CFGAUTO\n" );
-    if (genflags & GENINSTALL_DO_PERUSER) FIXME( "unsupported flag: GENINSTALL_DO_PERUSER\n" );
-
-    context = SetupInitDefaultQueueCallback( 0 );
-    if (!SetupInstallFromInfSectionA( 0, hinf, section, flags, 0, NULL,
-                                      SP_COPY_NEWER_OR_SAME, SetupDefaultQueueCallbackA,
-                                      context, 0, 0 ))
-        ret = get_last_error();
-
-    SetupTermDefaultQueueCallback( context );
-    return ret;
-}
+/*\r
+ * SetupX .inf file parsing functions\r
+ *\r
+ * Copyright 2000 Andreas Mohr for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * FIXME:\r
+ * - return values ???\r
+ * - this should be reimplemented at some point to have its own\r
+ *   file parsing instead of using profile functions,\r
+ *   as some SETUPX exports probably demand that\r
+ *   (IpSaveRestorePosition, IpFindNextMatchLine, ...).\r
+ */\r
+\r
+#include <stdarg.h>\r
+#include <string.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "setupx16.h"\r
+#include "setupapi_private.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+#define MAX_HANDLES 16384\r
+#define FIRST_HANDLE 32\r
+\r
+static HINF handles[MAX_HANDLES];\r
+\r
+\r
+static RETERR16 alloc_hinf16( HINF hinf, HINF16 *hinf16 )\r
+{\r
+    int i;\r
+    for (i = 0; i < MAX_HANDLES; i++)\r
+    {\r
+        if (!handles[i])\r
+        {\r
+            handles[i] = hinf;\r
+            *hinf16 = i + FIRST_HANDLE;\r
+            return OK;\r
+        }\r
+    }\r
+    return ERR_IP_OUT_OF_HANDLES;\r
+}\r
+\r
+static HINF get_hinf( HINF16 hinf16 )\r
+{\r
+    int idx = hinf16 - FIRST_HANDLE;\r
+    if (idx < 0 || idx >= MAX_HANDLES) return 0;\r
+    return handles[idx];\r
+}\r
+\r
+\r
+static HINF free_hinf16( HINF16 hinf16 )\r
+{\r
+    HINF ret;\r
+    int idx = hinf16 - FIRST_HANDLE;\r
+\r
+    if (idx < 0 || idx >= MAX_HANDLES) return 0;\r
+    ret = handles[idx];\r
+    handles[idx] = 0;\r
+    return ret;\r
+}\r
+\r
+/* convert last error code to a RETERR16 value */\r
+static RETERR16 get_last_error(void)\r
+{\r
+    switch(GetLastError())\r
+    {\r
+    case ERROR_EXPECTED_SECTION_NAME:\r
+    case ERROR_BAD_SECTION_NAME_LINE:\r
+    case ERROR_SECTION_NAME_TOO_LONG: return ERR_IP_INVALID_SECT_NAME;\r
+    case ERROR_SECTION_NOT_FOUND: return ERR_IP_SECT_NOT_FOUND;\r
+    case ERROR_LINE_NOT_FOUND: return ERR_IP_LINE_NOT_FOUND;\r
+    default: return IP_ERROR;  /* FIXME */\r
+    }\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             IpOpen (SETUPX.2)\r
+ *\r
+ */\r
+RETERR16 WINAPI IpOpen16( LPCSTR filename, HINF16 *hinf16 )\r
+{\r
+    HINF hinf = SetupOpenInfFileA( filename, NULL, INF_STYLE_WIN4, NULL );\r
+    if (hinf == (HINF)INVALID_HANDLE_VALUE) return get_last_error();\r
+    return alloc_hinf16( hinf, hinf16 );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             IpClose (SETUPX.4)\r
+ */\r
+RETERR16 WINAPI IpClose16( HINF16 hinf16 )\r
+{\r
+    HINF hinf = free_hinf16( hinf16 );\r
+    if (!hinf) return ERR_IP_INVALID_HINF;\r
+    SetupCloseInfFile( hinf );\r
+    return OK;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             IpGetProfileString (SETUPX.210)\r
+ */\r
+RETERR16 WINAPI IpGetProfileString16( HINF16 hinf16, LPCSTR section, LPCSTR entry,\r
+                                      LPSTR buffer, WORD buflen )\r
+{\r
+    DWORD required_size;\r
+    HINF hinf = get_hinf( hinf16 );\r
+\r
+    if (!hinf) return ERR_IP_INVALID_HINF;\r
+    if (!SetupGetLineTextA( NULL, hinf, section, entry, buffer, buflen, &required_size ))\r
+        return get_last_error();\r
+    TRACE("%p: section %s entry %s ret %s\n",\r
+          hinf, debugstr_a(section), debugstr_a(entry), debugstr_a(buffer) );\r
+    return OK;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             GenFormStrWithoutPlaceHolders (SETUPX.103)\r
+ *\r
+ * ought to be pretty much implemented, I guess...\r
+ */\r
+void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR dst, LPCSTR src, HINF16 hinf16 )\r
+{\r
+    UNICODE_STRING srcW;\r
+    HINF hinf = get_hinf( hinf16 );\r
+\r
+    if (!hinf) return;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &srcW, src )) return;\r
+    PARSER_string_substA( hinf, srcW.Buffer, dst, MAX_INF_STRING_LENGTH );\r
+    RtlFreeUnicodeString( &srcW );\r
+    TRACE( "%s -> %s\n", debugstr_a(src), debugstr_a(dst) );\r
+}\r
+\r
+/***********************************************************************\r
+ *             GenInstall (SETUPX.101)\r
+ *\r
+ * generic installer function for .INF file sections\r
+ *\r
+ * This is not perfect - patch whenever you can !\r
+ *\r
+ * wFlags == GENINSTALL_DO_xxx\r
+ * e.g. NetMeeting:\r
+ * first call GENINSTALL_DO_REGSRCPATH | GENINSTALL_DO_FILES,\r
+ * second call GENINSTALL_DO_LOGCONFIG | CFGAUTO | INI2REG | REG | INI\r
+ */\r
+RETERR16 WINAPI GenInstall16( HINF16 hinf16, LPCSTR section, WORD genflags )\r
+{\r
+    UINT flags = 0;\r
+    HINF hinf = get_hinf( hinf16 );\r
+    RETERR16 ret = OK;\r
+    void *context;\r
+\r
+    if (!hinf) return ERR_IP_INVALID_HINF;\r
+\r
+    if (genflags & GENINSTALL_DO_FILES) flags |= SPINST_FILES;\r
+    if (genflags & GENINSTALL_DO_INI) flags |= SPINST_INIFILES;\r
+    if (genflags & GENINSTALL_DO_REG) flags |= SPINST_REGISTRY;\r
+    if (genflags & GENINSTALL_DO_INI2REG) flags |= SPINST_INI2REG;\r
+    if (genflags & GENINSTALL_DO_LOGCONFIG) flags |= SPINST_LOGCONFIG;\r
+    if (genflags & GENINSTALL_DO_REGSRCPATH) FIXME( "unsupported flag: GENINSTALL_DO_REGSRCPATH\n" );\r
+    if (genflags & GENINSTALL_DO_CFGAUTO) FIXME( "unsupported flag: GENINSTALL_DO_CFGAUTO\n" );\r
+    if (genflags & GENINSTALL_DO_PERUSER) FIXME( "unsupported flag: GENINSTALL_DO_PERUSER\n" );\r
+\r
+    context = SetupInitDefaultQueueCallback( 0 );\r
+    if (!SetupInstallFromInfSectionA( 0, hinf, section, flags, 0, NULL,\r
+                                      SP_COPY_NEWER_OR_SAME, SetupDefaultQueueCallbackA,\r
+                                      context, 0, 0 ))\r
+        ret = get_last_error();\r
+\r
+    SetupTermDefaultQueueCallback( context );\r
+    return ret;\r
+}\r
index 344e919..5215d1f 100644 (file)
-/*
- * Setupapi install routines
- *
- * Copyright 2002 Alexandre Julliard 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winerror.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "setupapi_private.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-/* info passed to callback functions dealing with files */
-struct files_callback_info
-{
-    HSPFILEQ queue;
-    PCWSTR   src_root;
-    UINT     copy_flags;
-    HINF     layout;
-};
-
-/* info passed to callback functions dealing with the registry */
-struct registry_callback_info
-{
-    HKEY default_root;
-    BOOL delete;
-};
-
-/* info passed to callback functions dealing with registering dlls */
-struct register_dll_info
-{
-    PSP_FILE_CALLBACK_W callback;
-    PVOID               callback_context;
-    BOOL                unregister;
-};
-
-typedef BOOL (*iterate_fields_func)( HINF hinf, PCWSTR field, void *arg );
-
-/* Unicode constants */
-static const WCHAR CopyFiles[]  = {'C','o','p','y','F','i','l','e','s',0};
-static const WCHAR DelFiles[]   = {'D','e','l','F','i','l','e','s',0};
-static const WCHAR RenFiles[]   = {'R','e','n','F','i','l','e','s',0};
-static const WCHAR Ini2Reg[]    = {'I','n','i','2','R','e','g',0};
-static const WCHAR LogConf[]    = {'L','o','g','C','o','n','f',0};
-static const WCHAR AddReg[]     = {'A','d','d','R','e','g',0};
-static const WCHAR DelReg[]     = {'D','e','l','R','e','g',0};
-static const WCHAR BitReg[]     = {'B','i','t','R','e','g',0};
-static const WCHAR UpdateInis[] = {'U','p','d','a','t','e','I','n','i','s',0};
-static const WCHAR CopyINF[]    = {'C','o','p','y','I','N','F',0};
-static const WCHAR UpdateIniFields[] = {'U','p','d','a','t','e','I','n','i','F','i','e','l','d','s',0};
-static const WCHAR RegisterDlls[]    = {'R','e','g','i','s','t','e','r','D','l','l','s',0};
-static const WCHAR UnregisterDlls[]  = {'U','n','r','e','g','i','s','t','e','r','D','l','l','s',0};
-static const WCHAR ProfileItems[]    = {'P','r','o','f','i','l','e','I','t','e','m','s',0};
-
-
-/***********************************************************************
- *            get_field_string
- *
- * Retrieve the contents of a field, dynamically growing the buffer if necessary.
- */
-static WCHAR *get_field_string( INFCONTEXT *context, DWORD index, WCHAR *buffer,
-                                WCHAR *static_buffer, DWORD *size )
-{
-    DWORD required;
-
-    if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;
-    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-    {
-        /* now grow the buffer */
-        if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required*sizeof(WCHAR) ))) return NULL;
-        *size = required;
-        if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;
-    }
-    if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
-    return NULL;
-}
-
-
-/***********************************************************************
- *            copy_files_callback
- *
- * Called once for each CopyFiles entry in a given section.
- */
-static BOOL copy_files_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    struct files_callback_info *info = arg;
-
-    if (field[0] == '@')  /* special case: copy single file */
-        SetupQueueDefaultCopyW( info->queue, info->layout, info->src_root, NULL, field, info->copy_flags );
-    else
-        SetupQueueCopySectionW( info->queue, info->src_root, info->layout, hinf, field, info->copy_flags );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            delete_files_callback
- *
- * Called once for each DelFiles entry in a given section.
- */
-static BOOL delete_files_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    struct files_callback_info *info = arg;
-    SetupQueueDeleteSectionW( info->queue, hinf, 0, field );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            rename_files_callback
- *
- * Called once for each RenFiles entry in a given section.
- */
-static BOOL rename_files_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    struct files_callback_info *info = arg;
-    SetupQueueRenameSectionW( info->queue, hinf, 0, field );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            get_root_key
- *
- * Retrieve the registry root key from its name.
- */
-static HKEY get_root_key( const WCHAR *name, HKEY def_root )
-{
-    static const WCHAR HKCR[] = {'H','K','C','R',0};
-    static const WCHAR HKCU[] = {'H','K','C','U',0};
-    static const WCHAR HKLM[] = {'H','K','L','M',0};
-    static const WCHAR HKU[]  = {'H','K','U',0};
-    static const WCHAR HKR[]  = {'H','K','R',0};
-
-    if (!strcmpiW( name, HKCR )) return HKEY_CLASSES_ROOT;
-    if (!strcmpiW( name, HKCU )) return HKEY_CURRENT_USER;
-    if (!strcmpiW( name, HKLM )) return HKEY_LOCAL_MACHINE;
-    if (!strcmpiW( name, HKU )) return HKEY_USERS;
-    if (!strcmpiW( name, HKR )) return def_root;
-    return 0;
-}
-
-
-/***********************************************************************
- *            append_multi_sz_value
- *
- * Append a multisz string to a multisz registry value.
- */
-static void append_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *strings,
-                                   DWORD str_size )
-{
-    DWORD size, type, total;
-    WCHAR *buffer, *p;
-
-    if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
-    if (type != REG_MULTI_SZ) return;
-
-    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return;
-    if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
-
-    /* compare each string against all the existing ones */
-    total = size;
-    while (*strings)
-    {
-        int len = strlenW(strings) + 1;
-
-        for (p = buffer; *p; p += strlenW(p) + 1)
-            if (!strcmpiW( p, strings )) break;
-
-        if (!*p)  /* not found, need to append it */
-        {
-            memcpy( p, strings, len * sizeof(WCHAR) );
-            p[len] = 0;
-            total += len;
-        }
-        strings += len;
-    }
-    if (total != size)
-    {
-        TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) );
-        RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total );
-    }
- done:
-    HeapFree( GetProcessHeap(), 0, buffer );
-}
-
-
-/***********************************************************************
- *            delete_multi_sz_value
- *
- * Remove a string from a multisz registry value.
- */
-static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )
-{
-    DWORD size, type;
-    WCHAR *buffer, *src, *dst;
-
-    if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
-    if (type != REG_MULTI_SZ) return;
-    /* allocate double the size, one for value before and one for after */
-    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return;
-    if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
-    src = buffer;
-    dst = buffer + size;
-    while (*src)
-    {
-        int len = strlenW(src) + 1;
-        if (strcmpiW( src, string ))
-        {
-            memcpy( dst, src, len * sizeof(WCHAR) );
-            dst += len;
-        }
-        src += len;
-    }
-    *dst++ = 0;
-    if (dst != buffer + 2*size)  /* did we remove something? */
-    {
-        TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) );
-        RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,
-                        (BYTE *)(buffer + size), dst - (buffer + size) );
-    }
- done:
-    HeapFree( GetProcessHeap(), 0, buffer );
-}
-
-
-/***********************************************************************
- *            do_reg_operation
- *
- * Perform an add/delete registry operation depending on the flags.
- */
-static BOOL do_reg_operation( HKEY hkey, const WCHAR *value, INFCONTEXT *context, INT flags )
-{
-    DWORD type, size;
-
-    if (flags & (FLG_ADDREG_DELREG_BIT | FLG_ADDREG_DELVAL))  /* deletion */
-    {
-        if (*value && !(flags & FLG_DELREG_KEYONLY_COMMON))
-        {
-            if ((flags & FLG_DELREG_MULTI_SZ_DELSTRING) == FLG_DELREG_MULTI_SZ_DELSTRING)
-            {
-                WCHAR *str;
-
-                if (!SetupGetStringFieldW( context, 5, NULL, 0, &size ) || !size) return TRUE;
-                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
-                SetupGetStringFieldW( context, 5, str, size, NULL );
-                delete_multi_sz_value( hkey, value, str );
-                HeapFree( GetProcessHeap(), 0, str );
-            }
-            else RegDeleteValueW( hkey, value );
-        }
-        else RegDeleteKeyW( hkey, NULL );
-        return TRUE;
-    }
-
-    if (flags & (FLG_ADDREG_KEYONLY|FLG_ADDREG_KEYONLY_COMMON)) return TRUE;
-
-    if (flags & (FLG_ADDREG_NOCLOBBER|FLG_ADDREG_OVERWRITEONLY))
-    {
-        BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL );
-        if (exists && (flags & FLG_ADDREG_NOCLOBBER)) return TRUE;
-        if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) return TRUE;
-    }
-
-    switch(flags & FLG_ADDREG_TYPE_MASK)
-    {
-    case FLG_ADDREG_TYPE_SZ:        type = REG_SZ; break;
-    case FLG_ADDREG_TYPE_MULTI_SZ:  type = REG_MULTI_SZ; break;
-    case FLG_ADDREG_TYPE_EXPAND_SZ: type = REG_EXPAND_SZ; break;
-    case FLG_ADDREG_TYPE_BINARY:    type = REG_BINARY; break;
-    case FLG_ADDREG_TYPE_DWORD:     type = REG_DWORD; break;
-    case FLG_ADDREG_TYPE_NONE:      type = REG_NONE; break;
-    default:                        type = flags >> 16; break;
-    }
-
-    if (!(flags & FLG_ADDREG_BINVALUETYPE) ||
-        (type == REG_DWORD && SetupGetFieldCount(context) == 5))
-    {
-        static const WCHAR empty;
-        WCHAR *str = NULL;
-
-        if (type == REG_MULTI_SZ)
-        {
-            if (!SetupGetMultiSzFieldW( context, 5, NULL, 0, &size )) size = 0;
-            if (size)
-            {
-                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
-                SetupGetMultiSzFieldW( context, 5, str, size, NULL );
-            }
-            if (flags & FLG_ADDREG_APPEND)
-            {
-                if (!str) return TRUE;
-                append_multi_sz_value( hkey, value, str, size );
-                HeapFree( GetProcessHeap(), 0, str );
-                return TRUE;
-            }
-            /* else fall through to normal string handling */
-        }
-        else
-        {
-            if (!SetupGetStringFieldW( context, 5, NULL, 0, &size )) size = 0;
-            if (size)
-            {
-                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
-                SetupGetStringFieldW( context, 5, str, size, NULL );
-            }
-        }
-
-        if (type == REG_DWORD)
-        {
-            DWORD dw = str ? strtoulW( str, NULL, 16 ) : 0;
-            TRACE( "setting dword %s to %lx\n", debugstr_w(value), dw );
-            RegSetValueExW( hkey, value, 0, type, (BYTE *)&dw, sizeof(dw) );
-        }
-        else
-        {
-            TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(str) );
-            if (str) RegSetValueExW( hkey, value, 0, type, (BYTE *)str, size * sizeof(WCHAR) );
-            else RegSetValueExW( hkey, value, 0, type, (const BYTE *)&empty, sizeof(WCHAR) );
-        }
-        HeapFree( GetProcessHeap(), 0, str );
-        return TRUE;
-    }
-    else  /* get the binary data */
-    {
-        BYTE *data = NULL;
-
-        if (!SetupGetBinaryField( context, 5, NULL, 0, &size )) size = 0;
-        if (size)
-        {
-            if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
-            TRACE( "setting binary data %s len %ld\n", debugstr_w(value), size );
-            SetupGetBinaryField( context, 5, data, size, NULL );
-        }
-        RegSetValueExW( hkey, value, 0, type, data, size );
-        HeapFree( GetProcessHeap(), 0, data );
-        return TRUE;
-    }
-}
-
-
-/***********************************************************************
- *            registry_callback
- *
- * Called once for each AddReg and DelReg entry in a given section.
- */
-static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    struct registry_callback_info *info = arg;
-    INFCONTEXT context;
-    HKEY root_key, hkey;
-
-    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );
-
-    for (; ok; ok = SetupFindNextLine( &context, &context ))
-    {
-        WCHAR buffer[MAX_INF_STRING_LENGTH];
-        INT flags;
-
-        /* get root */
-        if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            continue;
-        if (!(root_key = get_root_key( buffer, info->default_root )))
-            continue;
-
-        /* get key */
-        if (!SetupGetStringFieldW( &context, 2, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            *buffer = 0;
-
-        /* get flags */
-        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
-
-        if (!info->delete)
-        {
-            if (flags & FLG_ADDREG_DELREG_BIT) continue;  /* ignore this entry */
-        }
-        else
-        {
-            if (!flags) flags = FLG_ADDREG_DELREG_BIT;
-            else if (!(flags & FLG_ADDREG_DELREG_BIT)) continue;  /* ignore this entry */
-        }
-
-        if (info->delete || (flags & FLG_ADDREG_OVERWRITEONLY))
-        {
-            if (RegOpenKeyW( root_key, buffer, &hkey )) continue;  /* ignore if it doesn't exist */
-        }
-        else if (RegCreateKeyW( root_key, buffer, &hkey ))
-        {
-            ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) );
-            continue;
-        }
-        TRACE( "key %p %s\n", root_key, debugstr_w(buffer) );
-
-        /* get value name */
-        if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            *buffer = 0;
-
-        /* and now do it */
-        if (!do_reg_operation( hkey, buffer, &context, flags ))
-        {
-            RegCloseKey( hkey );
-            return FALSE;
-        }
-        RegCloseKey( hkey );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            do_register_dll
- *
- * Register or unregister a dll.
- */
-static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *path,
-                             INT flags, INT timeout, const WCHAR *args )
-{
-    HMODULE module;
-    HRESULT res;
-    SP_REGISTER_CONTROL_STATUSW status;
-
-    status.cbSize = sizeof(status);
-    status.FileName = path;
-    status.FailureCode = SPREG_SUCCESS;
-    status.Win32Error = ERROR_SUCCESS;
-
-    if (info->callback)
-    {
-        switch(info->callback( info->callback_context, SPFILENOTIFY_STARTREGISTRATION,
-                               (UINT_PTR)&status, !info->unregister ))
-        {
-        case FILEOP_ABORT:
-            SetLastError( ERROR_OPERATION_ABORTED );
-            return FALSE;
-        case FILEOP_SKIP:
-            return TRUE;
-        case FILEOP_DOIT:
-            break;
-        }
-    }
-
-    if (!(module = LoadLibraryExW( path, 0, LOAD_WITH_ALTERED_SEARCH_PATH )))
-    {
-        WARN( "could not load %s\n", debugstr_w(path) );
-        status.FailureCode = SPREG_LOADLIBRARY;
-        status.Win32Error = GetLastError();
-        goto done;
-    }
-
-    if (flags & FLG_REGSVR_DLLREGISTER)
-    {
-        const char *entry_point = info->unregister ? "DllUnregisterServer" : "DllRegisterServer";
-        HRESULT (WINAPI *func)(void) = (void *)GetProcAddress( module, entry_point );
-
-        if (!func)
-        {
-            status.FailureCode = SPREG_GETPROCADDR;
-            status.Win32Error = GetLastError();
-            goto done;
-        }
-
-        TRACE( "calling %s in %s\n", entry_point, debugstr_w(path) );
-        res = func();
-
-        if (FAILED(res))
-        {
-            WARN( "calling %s in %s returned error %lx\n", entry_point, debugstr_w(path), res );
-            status.FailureCode = SPREG_REGSVR;
-            status.Win32Error = res;
-            goto done;
-        }
-    }
-
-    if (flags & FLG_REGSVR_DLLINSTALL)
-    {
-        HRESULT (WINAPI *func)(BOOL,LPCWSTR) = (void *)GetProcAddress( module, "DllInstall" );
-
-        if (!func)
-        {
-            status.FailureCode = SPREG_GETPROCADDR;
-            status.Win32Error = GetLastError();
-            goto done;
-        }
-
-        TRACE( "calling DllInstall(%d,%s) in %s\n",
-               !info->unregister, debugstr_w(args), debugstr_w(path) );
-        res = func( !info->unregister, args );
-
-        if (FAILED(res))
-        {
-            WARN( "calling DllInstall in %s returned error %lx\n", debugstr_w(path), res );
-            status.FailureCode = SPREG_REGSVR;
-            status.Win32Error = res;
-            goto done;
-        }
-    }
-
-done:
-    if (module) FreeLibrary( module );
-    if (info->callback) info->callback( info->callback_context, SPFILENOTIFY_ENDREGISTRATION,
-                                        (UINT_PTR)&status, !info->unregister );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            register_dlls_callback
- *
- * Called once for each RegisterDlls entry in a given section.
- */
-static BOOL register_dlls_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    struct register_dll_info *info = arg;
-    INFCONTEXT context;
-    BOOL ret = TRUE;
-    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );
-
-    for (; ok; ok = SetupFindNextLine( &context, &context ))
-    {
-        WCHAR *path, *args, *p;
-        WCHAR buffer[MAX_INF_STRING_LENGTH];
-        INT flags, timeout;
-
-        /* get directory */
-        if (!(path = PARSER_get_dest_dir( &context ))) continue;
-
-        /* get dll name */
-        if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            goto done;
-        if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,
-                               (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;
-        path = p;
-        p += strlenW(p);
-        if (p == path || p[-1] != '\\') *p++ = '\\';
-        strcpyW( p, buffer );
-
-        /* get flags */
-        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
-
-        /* get timeout */
-        if (!SetupGetIntField( &context, 5, &timeout )) timeout = 60;
-
-        /* get command line */
-        args = NULL;
-        if (SetupGetStringFieldW( &context, 6, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            args = buffer;
-
-        ret = do_register_dll( info, path, flags, timeout, args );
-
-    done:
-        HeapFree( GetProcessHeap(), 0, path );
-        if (!ret) break;
-    }
-    return ret;
-}
-
-/***********************************************************************
- *            update_ini_callback
- *
- * Called once for each UpdateInis entry in a given section.
- */
-static BOOL update_ini_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    INFCONTEXT context;
-
-    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );
-
-    for (; ok; ok = SetupFindNextLine( &context, &context ))
-    {
-        WCHAR buffer[MAX_INF_STRING_LENGTH];
-        WCHAR  filename[MAX_INF_STRING_LENGTH];
-        WCHAR  section[MAX_INF_STRING_LENGTH];
-        WCHAR  entry[MAX_INF_STRING_LENGTH];
-        WCHAR  string[MAX_INF_STRING_LENGTH];
-        LPWSTR divider;
-
-        if (!SetupGetStringFieldW( &context, 1, filename,
-                                   sizeof(filename)/sizeof(WCHAR), NULL ))
-            continue;
-
-        if (!SetupGetStringFieldW( &context, 2, section,
-                                   sizeof(section)/sizeof(WCHAR), NULL ))
-            continue;
-
-        if (!SetupGetStringFieldW( &context, 4, buffer,
-                                   sizeof(buffer)/sizeof(WCHAR), NULL ))
-            continue;
-
-        divider = strchrW(buffer,'=');
-        if (divider)
-        {
-            *divider = 0;
-            strcpyW(entry,buffer);
-            divider++;
-            strcpyW(string,divider);
-        }
-        else
-        {
-            strcpyW(entry,buffer);
-            string[0]=0;
-        }
-
-        TRACE("Writing %s = %s in %s of file %s\n",debugstr_w(entry),
-               debugstr_w(string),debugstr_w(section),debugstr_w(filename));
-        WritePrivateProfileStringW(section,entry,string,filename);
-
-    }
-    return TRUE;
-}
-
-static BOOL update_ini_fields_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should update ini fields %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-static BOOL ini2reg_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should do ini2reg %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-static BOOL logconf_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should do logconf %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-static BOOL bitreg_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should do bitreg %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-static BOOL profile_items_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should do profile items %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-static BOOL copy_inf_callback( HINF hinf, PCWSTR field, void *arg )
-{
-    FIXME( "should do copy inf %s\n", debugstr_w(field) );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            iterate_section_fields
- *
- * Iterate over all fields of a certain key of a certain section
- */
-static BOOL iterate_section_fields( HINF hinf, PCWSTR section, PCWSTR key,
-                                    iterate_fields_func callback, void *arg )
-{
-    WCHAR static_buffer[200];
-    WCHAR *buffer = static_buffer;
-    DWORD size = sizeof(static_buffer)/sizeof(WCHAR);
-    INFCONTEXT context;
-    BOOL ret = FALSE;
-
-    BOOL ok = SetupFindFirstLineW( hinf, section, key, &context );
-    while (ok)
-    {
-        UINT i, count = SetupGetFieldCount( &context );
-        for (i = 1; i <= count; i++)
-        {
-            if (!(buffer = get_field_string( &context, i, buffer, static_buffer, &size )))
-                goto done;
-            if (!callback( hinf, buffer, arg ))
-            {
-                WARN("callback failed for %s %s err %ld\n",
-                     debugstr_w(section), debugstr_w(buffer), GetLastError() );
-                goto done;
-            }
-        }
-        ok = SetupFindNextMatchLineW( &context, key, &context );
-    }
-    ret = TRUE;
- done:
-    if (buffer && buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupInstallFilesFromInfSectionA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupInstallFilesFromInfSectionA( HINF hinf, HINF hlayout, HSPFILEQ queue,
-                                              PCSTR section, PCSTR src_root, UINT flags )
-{
-    UNICODE_STRING sectionW;
-    BOOL ret = FALSE;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return FALSE;
-    }
-    if (!src_root)
-        ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
-                                                NULL, flags );
-    else
-    {
-        UNICODE_STRING srcW;
-        if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))
-        {
-            ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,
-                                                    srcW.Buffer, flags );
-            RtlFreeUnicodeString( &srcW );
-        }
-        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    }
-    RtlFreeUnicodeString( &sectionW );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupInstallFilesFromInfSectionW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupInstallFilesFromInfSectionW( HINF hinf, HINF hlayout, HSPFILEQ queue,
-                                              PCWSTR section, PCWSTR src_root, UINT flags )
-{
-    struct files_callback_info info;
-
-    info.queue      = queue;
-    info.src_root   = src_root;
-    info.copy_flags = flags;
-    info.layout     = hlayout;
-    return iterate_section_fields( hinf, section, CopyFiles, copy_files_callback, &info );
-}
-
-
-/***********************************************************************
- *            SetupInstallFromInfSectionA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupInstallFromInfSectionA( HWND owner, HINF hinf, PCSTR section, UINT flags,
-                                         HKEY key_root, PCSTR src_root, UINT copy_flags,
-                                         PSP_FILE_CALLBACK_A callback, PVOID context,
-                                         HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
-{
-    UNICODE_STRING sectionW, src_rootW;
-    struct callback_WtoA_context ctx;
-    BOOL ret = FALSE;
-
-    src_rootW.Buffer = NULL;
-    if (src_root && !RtlCreateUnicodeStringFromAsciiz( &src_rootW, src_root ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return FALSE;
-    }
-
-    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        ctx.orig_context = context;
-        ctx.orig_handler = callback;
-        ret = SetupInstallFromInfSectionW( owner, hinf, sectionW.Buffer, flags, key_root,
-                                           src_rootW.Buffer, copy_flags, QUEUE_callback_WtoA,
-                                           &ctx, devinfo, devinfo_data );
-        RtlFreeUnicodeString( &sectionW );
-    }
-    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-
-    RtlFreeUnicodeString( &src_rootW );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupInstallFromInfSectionW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, UINT flags,
-                                         HKEY key_root, PCWSTR src_root, UINT copy_flags,
-                                         PSP_FILE_CALLBACK_W callback, PVOID context,
-                                         HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )
-{
-    if (flags & SPINST_FILES)
-    {
-        struct files_callback_info info;
-        HSPFILEQ queue;
-        BOOL ret;
-
-        if (!(queue = SetupOpenFileQueue())) return FALSE;
-        info.queue      = queue;
-        info.src_root   = src_root;
-        info.copy_flags = copy_flags;
-        info.layout     = hinf;
-        ret = (iterate_section_fields( hinf, section, CopyFiles, copy_files_callback, &info ) &&
-               iterate_section_fields( hinf, section, DelFiles, delete_files_callback, &info ) &&
-               iterate_section_fields( hinf, section, RenFiles, rename_files_callback, &info ) &&
-               SetupCommitFileQueueW( owner, queue, callback, context ));
-        SetupCloseFileQueue( queue );
-        if (!ret) return FALSE;
-    }
-    if (flags & SPINST_INIFILES)
-    {
-        if (!iterate_section_fields( hinf, section, UpdateInis, update_ini_callback, NULL ) ||
-            !iterate_section_fields( hinf, section, UpdateIniFields,
-                                     update_ini_fields_callback, NULL ))
-            return FALSE;
-    }
-    if (flags & SPINST_INI2REG)
-    {
-        if (!iterate_section_fields( hinf, section, Ini2Reg, ini2reg_callback, NULL ))
-            return FALSE;
-    }
-    if (flags & SPINST_LOGCONFIG)
-    {
-        if (!iterate_section_fields( hinf, section, LogConf, logconf_callback, NULL ))
-            return FALSE;
-    }
-    if (flags & SPINST_REGSVR)
-    {
-        struct register_dll_info info;
-
-        info.unregister = FALSE;
-        if (flags & SPINST_REGISTERCALLBACKAWARE)
-        {
-            info.callback         = callback;
-            info.callback_context = context;
-        }
-        else info.callback = NULL;
-
-        if (!iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info ))
-            return FALSE;
-    }
-    if (flags & SPINST_UNREGSVR)
-    {
-        struct register_dll_info info;
-
-        info.unregister = TRUE;
-        if (flags & SPINST_REGISTERCALLBACKAWARE)
-        {
-            info.callback         = callback;
-            info.callback_context = context;
-        }
-        else info.callback = NULL;
-
-        if (!iterate_section_fields( hinf, section, UnregisterDlls, register_dlls_callback, &info ))
-            return FALSE;
-    }
-    if (flags & SPINST_REGISTRY)
-    {
-        struct registry_callback_info info;
-
-        info.default_root = key_root;
-        info.delete = TRUE;
-        if (!iterate_section_fields( hinf, section, DelReg, registry_callback, &info ))
-            return FALSE;
-        info.delete = FALSE;
-        if (!iterate_section_fields( hinf, section, AddReg, registry_callback, &info ))
-            return FALSE;
-    }
-    if (flags & SPINST_BITREG)
-    {
-        if (!iterate_section_fields( hinf, section, BitReg, bitreg_callback, NULL ))
-            return FALSE;
-    }
-    if (flags & SPINST_PROFILEITEMS)
-    {
-        if (!iterate_section_fields( hinf, section, ProfileItems, profile_items_callback, NULL ))
-            return FALSE;
-    }
-    if (flags & SPINST_COPYINF)
-    {
-        if (!iterate_section_fields( hinf, section, CopyINF, copy_inf_callback, NULL ))
-            return FALSE;
-    }
-
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             InstallHinfSectionW  (SETUPAPI.@)
- *
- * NOTE: 'cmdline' is <section> <mode> <path> from
- *   RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection <section> <mode> <path>
- */
-void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show )
-{
-    WCHAR *p, *path, section[MAX_PATH];
-    void *callback_context;
-    UINT mode;
-    HINF hinf;
-
-    TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));
-
-    lstrcpynW( section, cmdline, sizeof(section)/sizeof(WCHAR) );
-
-    if (!(p = strchrW( section, ' ' ))) return;
-    *p++ = 0;
-    while (*p == ' ') p++;
-    mode = atoiW( p );
-
-    if (!(p = strchrW( p, ' ' ))) return;
-    path = p + 1;
-    while (*path == ' ') path++;
-
-    hinf = SetupOpenInfFileW( path, NULL, INF_STYLE_WIN4, NULL );
-    if (hinf == INVALID_HANDLE_VALUE) return;
-
-    callback_context = SetupInitDefaultQueueCallback( hwnd );
-    SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER,
-                                 SetupDefaultQueueCallbackW, callback_context,
-                                 NULL, NULL );
-    SetupTermDefaultQueueCallback( callback_context );
-    SetupCloseInfFile( hinf );
-
-    /* FIXME: should check the mode and maybe reboot */
-    /* there isn't much point in doing that since we */
-    /* don't yet handle deferred file copies anyway. */
-}
-
-
-/***********************************************************************
- *             InstallHinfSectionA  (SETUPAPI.@)
- */
-void WINAPI InstallHinfSectionA( HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show )
-{
-    UNICODE_STRING cmdlineW;
-
-    if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline ))
-    {
-        InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show );
-        RtlFreeUnicodeString( &cmdlineW );
-    }
-}
+/*\r
+ * Setupapi install routines\r
+ *\r
+ * Copyright 2002 Alexandre Julliard for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "winerror.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "setupapi_private.h"\r
+#include "wine/unicode.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+/* info passed to callback functions dealing with files */\r
+struct files_callback_info\r
+{\r
+    HSPFILEQ queue;\r
+    PCWSTR   src_root;\r
+    UINT     copy_flags;\r
+    HINF     layout;\r
+};\r
+\r
+/* info passed to callback functions dealing with the registry */\r
+struct registry_callback_info\r
+{\r
+    HKEY default_root;\r
+    BOOL delete;\r
+};\r
+\r
+/* info passed to callback functions dealing with registering dlls */\r
+struct register_dll_info\r
+{\r
+    PSP_FILE_CALLBACK_W callback;\r
+    PVOID               callback_context;\r
+    BOOL                unregister;\r
+};\r
+\r
+typedef BOOL (*iterate_fields_func)( HINF hinf, PCWSTR field, void *arg );\r
+\r
+/* Unicode constants */\r
+static const WCHAR CopyFiles[]  = {'C','o','p','y','F','i','l','e','s',0};\r
+static const WCHAR DelFiles[]   = {'D','e','l','F','i','l','e','s',0};\r
+static const WCHAR RenFiles[]   = {'R','e','n','F','i','l','e','s',0};\r
+static const WCHAR Ini2Reg[]    = {'I','n','i','2','R','e','g',0};\r
+static const WCHAR LogConf[]    = {'L','o','g','C','o','n','f',0};\r
+static const WCHAR AddReg[]     = {'A','d','d','R','e','g',0};\r
+static const WCHAR DelReg[]     = {'D','e','l','R','e','g',0};\r
+static const WCHAR BitReg[]     = {'B','i','t','R','e','g',0};\r
+static const WCHAR UpdateInis[] = {'U','p','d','a','t','e','I','n','i','s',0};\r
+static const WCHAR CopyINF[]    = {'C','o','p','y','I','N','F',0};\r
+static const WCHAR UpdateIniFields[] = {'U','p','d','a','t','e','I','n','i','F','i','e','l','d','s',0};\r
+static const WCHAR RegisterDlls[]    = {'R','e','g','i','s','t','e','r','D','l','l','s',0};\r
+static const WCHAR UnregisterDlls[]  = {'U','n','r','e','g','i','s','t','e','r','D','l','l','s',0};\r
+static const WCHAR ProfileItems[]    = {'P','r','o','f','i','l','e','I','t','e','m','s',0};\r
+\r
+\r
+/***********************************************************************\r
+ *            get_field_string\r
+ *\r
+ * Retrieve the contents of a field, dynamically growing the buffer if necessary.\r
+ */\r
+static WCHAR *get_field_string( INFCONTEXT *context, DWORD index, WCHAR *buffer,\r
+                                WCHAR *static_buffer, DWORD *size )\r
+{\r
+    DWORD required;\r
+\r
+    if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;\r
+    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\r
+    {\r
+        /* now grow the buffer */\r
+        if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );\r
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required*sizeof(WCHAR) ))) return NULL;\r
+        *size = required;\r
+        if (SetupGetStringFieldW( context, index, buffer, *size, &required )) return buffer;\r
+    }\r
+    if (buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );\r
+    return NULL;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            copy_files_callback\r
+ *\r
+ * Called once for each CopyFiles entry in a given section.\r
+ */\r
+static BOOL copy_files_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    struct files_callback_info *info = arg;\r
+\r
+    if (field[0] == '@')  /* special case: copy single file */\r
+        SetupQueueDefaultCopyW( info->queue, info->layout, info->src_root, NULL, field, info->copy_flags );\r
+    else\r
+        SetupQueueCopySectionW( info->queue, info->src_root, info->layout, hinf, field, info->copy_flags );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            delete_files_callback\r
+ *\r
+ * Called once for each DelFiles entry in a given section.\r
+ */\r
+static BOOL delete_files_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    struct files_callback_info *info = arg;\r
+    SetupQueueDeleteSectionW( info->queue, hinf, 0, field );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            rename_files_callback\r
+ *\r
+ * Called once for each RenFiles entry in a given section.\r
+ */\r
+static BOOL rename_files_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    struct files_callback_info *info = arg;\r
+    SetupQueueRenameSectionW( info->queue, hinf, 0, field );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            get_root_key\r
+ *\r
+ * Retrieve the registry root key from its name.\r
+ */\r
+static HKEY get_root_key( const WCHAR *name, HKEY def_root )\r
+{\r
+    static const WCHAR HKCR[] = {'H','K','C','R',0};\r
+    static const WCHAR HKCU[] = {'H','K','C','U',0};\r
+    static const WCHAR HKLM[] = {'H','K','L','M',0};\r
+    static const WCHAR HKU[]  = {'H','K','U',0};\r
+    static const WCHAR HKR[]  = {'H','K','R',0};\r
+\r
+    if (!strcmpiW( name, HKCR )) return HKEY_CLASSES_ROOT;\r
+    if (!strcmpiW( name, HKCU )) return HKEY_CURRENT_USER;\r
+    if (!strcmpiW( name, HKLM )) return HKEY_LOCAL_MACHINE;\r
+    if (!strcmpiW( name, HKU )) return HKEY_USERS;\r
+    if (!strcmpiW( name, HKR )) return def_root;\r
+    return 0;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            append_multi_sz_value\r
+ *\r
+ * Append a multisz string to a multisz registry value.\r
+ */\r
+static void append_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *strings,\r
+                                   DWORD str_size )\r
+{\r
+    DWORD size, type, total;\r
+    WCHAR *buffer, *p;\r
+\r
+    if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;\r
+    if (type != REG_MULTI_SZ) return;\r
+\r
+    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return;\r
+    if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;\r
+\r
+    /* compare each string against all the existing ones */\r
+    total = size;\r
+    while (*strings)\r
+    {\r
+        int len = strlenW(strings) + 1;\r
+\r
+        for (p = buffer; *p; p += strlenW(p) + 1)\r
+            if (!strcmpiW( p, strings )) break;\r
+\r
+        if (!*p)  /* not found, need to append it */\r
+        {\r
+            memcpy( p, strings, len * sizeof(WCHAR) );\r
+            p[len] = 0;\r
+            total += len;\r
+        }\r
+        strings += len;\r
+    }\r
+    if (total != size)\r
+    {\r
+        TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) );\r
+        RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total );\r
+    }\r
+ done:\r
+    HeapFree( GetProcessHeap(), 0, buffer );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            delete_multi_sz_value\r
+ *\r
+ * Remove a string from a multisz registry value.\r
+ */\r
+static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )\r
+{\r
+    DWORD size, type;\r
+    WCHAR *buffer, *src, *dst;\r
+\r
+    if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;\r
+    if (type != REG_MULTI_SZ) return;\r
+    /* allocate double the size, one for value before and one for after */\r
+    if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return;\r
+    if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;\r
+    src = buffer;\r
+    dst = buffer + size;\r
+    while (*src)\r
+    {\r
+        int len = strlenW(src) + 1;\r
+        if (strcmpiW( src, string ))\r
+        {\r
+            memcpy( dst, src, len * sizeof(WCHAR) );\r
+            dst += len;\r
+        }\r
+        src += len;\r
+    }\r
+    *dst++ = 0;\r
+    if (dst != buffer + 2*size)  /* did we remove something? */\r
+    {\r
+        TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) );\r
+        RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,\r
+                        (BYTE *)(buffer + size), dst - (buffer + size) );\r
+    }\r
+ done:\r
+    HeapFree( GetProcessHeap(), 0, buffer );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            do_reg_operation\r
+ *\r
+ * Perform an add/delete registry operation depending on the flags.\r
+ */\r
+static BOOL do_reg_operation( HKEY hkey, const WCHAR *value, INFCONTEXT *context, INT flags )\r
+{\r
+    DWORD type, size;\r
+\r
+    if (flags & (FLG_ADDREG_DELREG_BIT | FLG_ADDREG_DELVAL))  /* deletion */\r
+    {\r
+        if (*value && !(flags & FLG_DELREG_KEYONLY_COMMON))\r
+        {\r
+            if ((flags & FLG_DELREG_MULTI_SZ_DELSTRING) == FLG_DELREG_MULTI_SZ_DELSTRING)\r
+            {\r
+                WCHAR *str;\r
+\r
+                if (!SetupGetStringFieldW( context, 5, NULL, 0, &size ) || !size) return TRUE;\r
+                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;\r
+                SetupGetStringFieldW( context, 5, str, size, NULL );\r
+                delete_multi_sz_value( hkey, value, str );\r
+                HeapFree( GetProcessHeap(), 0, str );\r
+            }\r
+            else RegDeleteValueW( hkey, value );\r
+        }\r
+        else RegDeleteKeyW( hkey, NULL );\r
+        return TRUE;\r
+    }\r
+\r
+    if (flags & (FLG_ADDREG_KEYONLY|FLG_ADDREG_KEYONLY_COMMON)) return TRUE;\r
+\r
+    if (flags & (FLG_ADDREG_NOCLOBBER|FLG_ADDREG_OVERWRITEONLY))\r
+    {\r
+        BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL );\r
+        if (exists && (flags & FLG_ADDREG_NOCLOBBER)) return TRUE;\r
+        if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) return TRUE;\r
+    }\r
+\r
+    switch(flags & FLG_ADDREG_TYPE_MASK)\r
+    {\r
+    case FLG_ADDREG_TYPE_SZ:        type = REG_SZ; break;\r
+    case FLG_ADDREG_TYPE_MULTI_SZ:  type = REG_MULTI_SZ; break;\r
+    case FLG_ADDREG_TYPE_EXPAND_SZ: type = REG_EXPAND_SZ; break;\r
+    case FLG_ADDREG_TYPE_BINARY:    type = REG_BINARY; break;\r
+    case FLG_ADDREG_TYPE_DWORD:     type = REG_DWORD; break;\r
+    case FLG_ADDREG_TYPE_NONE:      type = REG_NONE; break;\r
+    default:                        type = flags >> 16; break;\r
+    }\r
+\r
+    if (!(flags & FLG_ADDREG_BINVALUETYPE) ||\r
+        (type == REG_DWORD && SetupGetFieldCount(context) == 5))\r
+    {\r
+        static const WCHAR empty;\r
+        WCHAR *str = NULL;\r
+\r
+        if (type == REG_MULTI_SZ)\r
+        {\r
+            if (!SetupGetMultiSzFieldW( context, 5, NULL, 0, &size )) size = 0;\r
+            if (size)\r
+            {\r
+                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;\r
+                SetupGetMultiSzFieldW( context, 5, str, size, NULL );\r
+            }\r
+            if (flags & FLG_ADDREG_APPEND)\r
+            {\r
+                if (!str) return TRUE;\r
+                append_multi_sz_value( hkey, value, str, size );\r
+                HeapFree( GetProcessHeap(), 0, str );\r
+                return TRUE;\r
+            }\r
+            /* else fall through to normal string handling */\r
+        }\r
+        else\r
+        {\r
+            if (!SetupGetStringFieldW( context, 5, NULL, 0, &size )) size = 0;\r
+            if (size)\r
+            {\r
+                if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;\r
+                SetupGetStringFieldW( context, 5, str, size, NULL );\r
+            }\r
+        }\r
+\r
+        if (type == REG_DWORD)\r
+        {\r
+            DWORD dw = str ? strtoulW( str, NULL, 16 ) : 0;\r
+            TRACE( "setting dword %s to %lx\n", debugstr_w(value), dw );\r
+            RegSetValueExW( hkey, value, 0, type, (BYTE *)&dw, sizeof(dw) );\r
+        }\r
+        else\r
+        {\r
+            TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(str) );\r
+            if (str) RegSetValueExW( hkey, value, 0, type, (BYTE *)str, size * sizeof(WCHAR) );\r
+            else RegSetValueExW( hkey, value, 0, type, (const BYTE *)&empty, sizeof(WCHAR) );\r
+        }\r
+        HeapFree( GetProcessHeap(), 0, str );\r
+        return TRUE;\r
+    }\r
+    else  /* get the binary data */\r
+    {\r
+        BYTE *data = NULL;\r
+\r
+        if (!SetupGetBinaryField( context, 5, NULL, 0, &size )) size = 0;\r
+        if (size)\r
+        {\r
+            if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;\r
+            TRACE( "setting binary data %s len %ld\n", debugstr_w(value), size );\r
+            SetupGetBinaryField( context, 5, data, size, NULL );\r
+        }\r
+        RegSetValueExW( hkey, value, 0, type, data, size );\r
+        HeapFree( GetProcessHeap(), 0, data );\r
+        return TRUE;\r
+    }\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            registry_callback\r
+ *\r
+ * Called once for each AddReg and DelReg entry in a given section.\r
+ */\r
+static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    struct registry_callback_info *info = arg;\r
+    INFCONTEXT context;\r
+    HKEY root_key, hkey;\r
+\r
+    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );\r
+\r
+    for (; ok; ok = SetupFindNextLine( &context, &context ))\r
+    {\r
+        WCHAR buffer[MAX_INF_STRING_LENGTH];\r
+        INT flags;\r
+\r
+        /* get root */\r
+        if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            continue;\r
+        if (!(root_key = get_root_key( buffer, info->default_root )))\r
+            continue;\r
+\r
+        /* get key */\r
+        if (!SetupGetStringFieldW( &context, 2, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            *buffer = 0;\r
+\r
+        /* get flags */\r
+        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;\r
+\r
+        if (!info->delete)\r
+        {\r
+            if (flags & FLG_ADDREG_DELREG_BIT) continue;  /* ignore this entry */\r
+        }\r
+        else\r
+        {\r
+            if (!flags) flags = FLG_ADDREG_DELREG_BIT;\r
+            else if (!(flags & FLG_ADDREG_DELREG_BIT)) continue;  /* ignore this entry */\r
+        }\r
+\r
+        if (info->delete || (flags & FLG_ADDREG_OVERWRITEONLY))\r
+        {\r
+            if (RegOpenKeyW( root_key, buffer, &hkey )) continue;  /* ignore if it doesn't exist */\r
+        }\r
+        else if (RegCreateKeyW( root_key, buffer, &hkey ))\r
+        {\r
+            ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) );\r
+            continue;\r
+        }\r
+        TRACE( "key %p %s\n", root_key, debugstr_w(buffer) );\r
+\r
+        /* get value name */\r
+        if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            *buffer = 0;\r
+\r
+        /* and now do it */\r
+        if (!do_reg_operation( hkey, buffer, &context, flags ))\r
+        {\r
+            RegCloseKey( hkey );\r
+            return FALSE;\r
+        }\r
+        RegCloseKey( hkey );\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            do_register_dll\r
+ *\r
+ * Register or unregister a dll.\r
+ */\r
+static BOOL do_register_dll( const struct register_dll_info *info, const WCHAR *path,\r
+                             INT flags, INT timeout, const WCHAR *args )\r
+{\r
+    HMODULE module;\r
+    HRESULT res;\r
+    SP_REGISTER_CONTROL_STATUSW status;\r
+\r
+    status.cbSize = sizeof(status);\r
+    status.FileName = path;\r
+    status.FailureCode = SPREG_SUCCESS;\r
+    status.Win32Error = ERROR_SUCCESS;\r
+\r
+    if (info->callback)\r
+    {\r
+        switch(info->callback( info->callback_context, SPFILENOTIFY_STARTREGISTRATION,\r
+                               (UINT_PTR)&status, !info->unregister ))\r
+        {\r
+        case FILEOP_ABORT:\r
+            SetLastError( ERROR_OPERATION_ABORTED );\r
+            return FALSE;\r
+        case FILEOP_SKIP:\r
+            return TRUE;\r
+        case FILEOP_DOIT:\r
+            break;\r
+        }\r
+    }\r
+\r
+    if (!(module = LoadLibraryExW( path, 0, LOAD_WITH_ALTERED_SEARCH_PATH )))\r
+    {\r
+        WARN( "could not load %s\n", debugstr_w(path) );\r
+        status.FailureCode = SPREG_LOADLIBRARY;\r
+        status.Win32Error = GetLastError();\r
+        goto done;\r
+    }\r
+\r
+    if (flags & FLG_REGSVR_DLLREGISTER)\r
+    {\r
+        const char *entry_point = info->unregister ? "DllUnregisterServer" : "DllRegisterServer";\r
+        HRESULT (WINAPI *func)(void) = (void *)GetProcAddress( module, entry_point );\r
+\r
+        if (!func)\r
+        {\r
+            status.FailureCode = SPREG_GETPROCADDR;\r
+            status.Win32Error = GetLastError();\r
+            goto done;\r
+        }\r
+\r
+        TRACE( "calling %s in %s\n", entry_point, debugstr_w(path) );\r
+        res = func();\r
+\r
+        if (FAILED(res))\r
+        {\r
+            WARN( "calling %s in %s returned error %lx\n", entry_point, debugstr_w(path), res );\r
+            status.FailureCode = SPREG_REGSVR;\r
+            status.Win32Error = res;\r
+            goto done;\r
+        }\r
+    }\r
+\r
+    if (flags & FLG_REGSVR_DLLINSTALL)\r
+    {\r
+        HRESULT (WINAPI *func)(BOOL,LPCWSTR) = (void *)GetProcAddress( module, "DllInstall" );\r
+\r
+        if (!func)\r
+        {\r
+            status.FailureCode = SPREG_GETPROCADDR;\r
+            status.Win32Error = GetLastError();\r
+            goto done;\r
+        }\r
+\r
+        TRACE( "calling DllInstall(%d,%s) in %s\n",\r
+               !info->unregister, debugstr_w(args), debugstr_w(path) );\r
+        res = func( !info->unregister, args );\r
+\r
+        if (FAILED(res))\r
+        {\r
+            WARN( "calling DllInstall in %s returned error %lx\n", debugstr_w(path), res );\r
+            status.FailureCode = SPREG_REGSVR;\r
+            status.Win32Error = res;\r
+            goto done;\r
+        }\r
+    }\r
+\r
+done:\r
+    if (module) FreeLibrary( module );\r
+    if (info->callback) info->callback( info->callback_context, SPFILENOTIFY_ENDREGISTRATION,\r
+                                        (UINT_PTR)&status, !info->unregister );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            register_dlls_callback\r
+ *\r
+ * Called once for each RegisterDlls entry in a given section.\r
+ */\r
+static BOOL register_dlls_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    struct register_dll_info *info = arg;\r
+    INFCONTEXT context;\r
+    BOOL ret = TRUE;\r
+    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );\r
+\r
+    for (; ok; ok = SetupFindNextLine( &context, &context ))\r
+    {\r
+        WCHAR *path, *args, *p;\r
+        WCHAR buffer[MAX_INF_STRING_LENGTH];\r
+        INT flags, timeout;\r
+\r
+        /* get directory */\r
+        if (!(path = PARSER_get_dest_dir( &context ))) continue;\r
+\r
+        /* get dll name */\r
+        if (!SetupGetStringFieldW( &context, 3, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            goto done;\r
+        if (!(p = HeapReAlloc( GetProcessHeap(), 0, path,\r
+                               (strlenW(path) + strlenW(buffer) + 2) * sizeof(WCHAR) ))) goto done;\r
+        path = p;\r
+        p += strlenW(p);\r
+        if (p == path || p[-1] != '\\') *p++ = '\\';\r
+        strcpyW( p, buffer );\r
+\r
+        /* get flags */\r
+        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;\r
+\r
+        /* get timeout */\r
+        if (!SetupGetIntField( &context, 5, &timeout )) timeout = 60;\r
+\r
+        /* get command line */\r
+        args = NULL;\r
+        if (SetupGetStringFieldW( &context, 6, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            args = buffer;\r
+\r
+        ret = do_register_dll( info, path, flags, timeout, args );\r
+\r
+    done:\r
+        HeapFree( GetProcessHeap(), 0, path );\r
+        if (!ret) break;\r
+    }\r
+    return ret;\r
+}\r
+\r
+/***********************************************************************\r
+ *            update_ini_callback\r
+ *\r
+ * Called once for each UpdateInis entry in a given section.\r
+ */\r
+static BOOL update_ini_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    INFCONTEXT context;\r
+\r
+    BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context );\r
+\r
+    for (; ok; ok = SetupFindNextLine( &context, &context ))\r
+    {\r
+        WCHAR buffer[MAX_INF_STRING_LENGTH];\r
+        WCHAR  filename[MAX_INF_STRING_LENGTH];\r
+        WCHAR  section[MAX_INF_STRING_LENGTH];\r
+        WCHAR  entry[MAX_INF_STRING_LENGTH];\r
+        WCHAR  string[MAX_INF_STRING_LENGTH];\r
+        LPWSTR divider;\r
+\r
+        if (!SetupGetStringFieldW( &context, 1, filename,\r
+                                   sizeof(filename)/sizeof(WCHAR), NULL ))\r
+            continue;\r
+\r
+        if (!SetupGetStringFieldW( &context, 2, section,\r
+                                   sizeof(section)/sizeof(WCHAR), NULL ))\r
+            continue;\r
+\r
+        if (!SetupGetStringFieldW( &context, 4, buffer,\r
+                                   sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            continue;\r
+\r
+        divider = strchrW(buffer,'=');\r
+        if (divider)\r
+        {\r
+            *divider = 0;\r
+            strcpyW(entry,buffer);\r
+            divider++;\r
+            strcpyW(string,divider);\r
+        }\r
+        else\r
+        {\r
+            strcpyW(entry,buffer);\r
+            string[0]=0;\r
+        }\r
+\r
+        TRACE("Writing %s = %s in %s of file %s\n",debugstr_w(entry),\r
+               debugstr_w(string),debugstr_w(section),debugstr_w(filename));\r
+        WritePrivateProfileStringW(section,entry,string,filename);\r
+\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+static BOOL update_ini_fields_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should update ini fields %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+static BOOL ini2reg_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should do ini2reg %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+static BOOL logconf_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should do logconf %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+static BOOL bitreg_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should do bitreg %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+static BOOL profile_items_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should do profile items %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+static BOOL copy_inf_callback( HINF hinf, PCWSTR field, void *arg )\r
+{\r
+    FIXME( "should do copy inf %s\n", debugstr_w(field) );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            iterate_section_fields\r
+ *\r
+ * Iterate over all fields of a certain key of a certain section\r
+ */\r
+static BOOL iterate_section_fields( HINF hinf, PCWSTR section, PCWSTR key,\r
+                                    iterate_fields_func callback, void *arg )\r
+{\r
+    WCHAR static_buffer[200];\r
+    WCHAR *buffer = static_buffer;\r
+    DWORD size = sizeof(static_buffer)/sizeof(WCHAR);\r
+    INFCONTEXT context;\r
+    BOOL ret = FALSE;\r
+\r
+    BOOL ok = SetupFindFirstLineW( hinf, section, key, &context );\r
+    while (ok)\r
+    {\r
+        UINT i, count = SetupGetFieldCount( &context );\r
+        for (i = 1; i <= count; i++)\r
+        {\r
+            if (!(buffer = get_field_string( &context, i, buffer, static_buffer, &size )))\r
+                goto done;\r
+            if (!callback( hinf, buffer, arg ))\r
+            {\r
+                WARN("callback failed for %s %s err %ld\n",\r
+                     debugstr_w(section), debugstr_w(buffer), GetLastError() );\r
+                goto done;\r
+            }\r
+        }\r
+        ok = SetupFindNextMatchLineW( &context, key, &context );\r
+    }\r
+    ret = TRUE;\r
+ done:\r
+    if (buffer && buffer != static_buffer) HeapFree( GetProcessHeap(), 0, buffer );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInstallFilesFromInfSectionA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupInstallFilesFromInfSectionA( HINF hinf, HINF hlayout, HSPFILEQ queue,\r
+                                              PCSTR section, PCSTR src_root, UINT flags )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return FALSE;\r
+    }\r
+    if (!src_root)\r
+        ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,\r
+                                                NULL, flags );\r
+    else\r
+    {\r
+        UNICODE_STRING srcW;\r
+        if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))\r
+        {\r
+            ret = SetupInstallFilesFromInfSectionW( hinf, hlayout, queue, sectionW.Buffer,\r
+                                                    srcW.Buffer, flags );\r
+            RtlFreeUnicodeString( &srcW );\r
+        }\r
+        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    }\r
+    RtlFreeUnicodeString( &sectionW );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInstallFilesFromInfSectionW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupInstallFilesFromInfSectionW( HINF hinf, HINF hlayout, HSPFILEQ queue,\r
+                                              PCWSTR section, PCWSTR src_root, UINT flags )\r
+{\r
+    struct files_callback_info info;\r
+\r
+    info.queue      = queue;\r
+    info.src_root   = src_root;\r
+    info.copy_flags = flags;\r
+    info.layout     = hlayout;\r
+    return iterate_section_fields( hinf, section, CopyFiles, copy_files_callback, &info );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInstallFromInfSectionA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupInstallFromInfSectionA( HWND owner, HINF hinf, PCSTR section, UINT flags,\r
+                                         HKEY key_root, PCSTR src_root, UINT copy_flags,\r
+                                         PSP_FILE_CALLBACK_A callback, PVOID context,\r
+                                         HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )\r
+{\r
+    UNICODE_STRING sectionW, src_rootW;\r
+    struct callback_WtoA_context ctx;\r
+    BOOL ret = FALSE;\r
+\r
+    src_rootW.Buffer = NULL;\r
+    if (src_root && !RtlCreateUnicodeStringFromAsciiz( &src_rootW, src_root ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return FALSE;\r
+    }\r
+\r
+    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        ctx.orig_context = context;\r
+        ctx.orig_handler = callback;\r
+        ret = SetupInstallFromInfSectionW( owner, hinf, sectionW.Buffer, flags, key_root,\r
+                                           src_rootW.Buffer, copy_flags, QUEUE_callback_WtoA,\r
+                                           &ctx, devinfo, devinfo_data );\r
+        RtlFreeUnicodeString( &sectionW );\r
+    }\r
+    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+\r
+    RtlFreeUnicodeString( &src_rootW );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInstallFromInfSectionW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupInstallFromInfSectionW( HWND owner, HINF hinf, PCWSTR section, UINT flags,\r
+                                         HKEY key_root, PCWSTR src_root, UINT copy_flags,\r
+                                         PSP_FILE_CALLBACK_W callback, PVOID context,\r
+                                         HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data )\r
+{\r
+    if (flags & SPINST_FILES)\r
+    {\r
+        struct files_callback_info info;\r
+        HSPFILEQ queue;\r
+        BOOL ret;\r
+\r
+        if (!(queue = SetupOpenFileQueue())) return FALSE;\r
+        info.queue      = queue;\r
+        info.src_root   = src_root;\r
+        info.copy_flags = copy_flags;\r
+        info.layout     = hinf;\r
+        ret = (iterate_section_fields( hinf, section, CopyFiles, copy_files_callback, &info ) &&\r
+               iterate_section_fields( hinf, section, DelFiles, delete_files_callback, &info ) &&\r
+               iterate_section_fields( hinf, section, RenFiles, rename_files_callback, &info ) &&\r
+               SetupCommitFileQueueW( owner, queue, callback, context ));\r
+        SetupCloseFileQueue( queue );\r
+        if (!ret) return FALSE;\r
+    }\r
+    if (flags & SPINST_INIFILES)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, UpdateInis, update_ini_callback, NULL ) ||\r
+            !iterate_section_fields( hinf, section, UpdateIniFields,\r
+                                     update_ini_fields_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_INI2REG)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, Ini2Reg, ini2reg_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_LOGCONFIG)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, LogConf, logconf_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_REGSVR)\r
+    {\r
+        struct register_dll_info info;\r
+\r
+        info.unregister = FALSE;\r
+        if (flags & SPINST_REGISTERCALLBACKAWARE)\r
+        {\r
+            info.callback         = callback;\r
+            info.callback_context = context;\r
+        }\r
+        else info.callback = NULL;\r
+\r
+        if (!iterate_section_fields( hinf, section, RegisterDlls, register_dlls_callback, &info ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_UNREGSVR)\r
+    {\r
+        struct register_dll_info info;\r
+\r
+        info.unregister = TRUE;\r
+        if (flags & SPINST_REGISTERCALLBACKAWARE)\r
+        {\r
+            info.callback         = callback;\r
+            info.callback_context = context;\r
+        }\r
+        else info.callback = NULL;\r
+\r
+        if (!iterate_section_fields( hinf, section, UnregisterDlls, register_dlls_callback, &info ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_REGISTRY)\r
+    {\r
+        struct registry_callback_info info;\r
+\r
+        info.default_root = key_root;\r
+        info.delete = TRUE;\r
+        if (!iterate_section_fields( hinf, section, DelReg, registry_callback, &info ))\r
+            return FALSE;\r
+        info.delete = FALSE;\r
+        if (!iterate_section_fields( hinf, section, AddReg, registry_callback, &info ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_BITREG)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, BitReg, bitreg_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_PROFILEITEMS)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, ProfileItems, profile_items_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+    if (flags & SPINST_COPYINF)\r
+    {\r
+        if (!iterate_section_fields( hinf, section, CopyINF, copy_inf_callback, NULL ))\r
+            return FALSE;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             InstallHinfSectionW  (SETUPAPI.@)\r
+ *\r
+ * NOTE: 'cmdline' is <section> <mode> <path> from\r
+ *   RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection <section> <mode> <path>\r
+ */\r
+void WINAPI InstallHinfSectionW( HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show )\r
+{\r
+    WCHAR *p, *path, section[MAX_PATH];\r
+    void *callback_context;\r
+    UINT mode;\r
+    HINF hinf;\r
+\r
+    TRACE("hwnd %p, handle %p, cmdline %s\n", hwnd, handle, debugstr_w(cmdline));\r
+\r
+    lstrcpynW( section, cmdline, sizeof(section)/sizeof(WCHAR) );\r
+\r
+    if (!(p = strchrW( section, ' ' ))) return;\r
+    *p++ = 0;\r
+    while (*p == ' ') p++;\r
+    mode = atoiW( p );\r
+\r
+    if (!(p = strchrW( p, ' ' ))) return;\r
+    path = p + 1;\r
+    while (*path == ' ') path++;\r
+\r
+    hinf = SetupOpenInfFileW( path, NULL, INF_STYLE_WIN4, NULL );\r
+    if (hinf == INVALID_HANDLE_VALUE) return;\r
+\r
+    callback_context = SetupInitDefaultQueueCallback( hwnd );\r
+    SetupInstallFromInfSectionW( hwnd, hinf, section, SPINST_ALL, NULL, NULL, SP_COPY_NEWER,\r
+                                 SetupDefaultQueueCallbackW, callback_context,\r
+                                 NULL, NULL );\r
+    SetupTermDefaultQueueCallback( callback_context );\r
+    SetupCloseInfFile( hinf );\r
+\r
+    /* FIXME: should check the mode and maybe reboot */\r
+    /* there isn't much point in doing that since we */\r
+    /* don't yet handle deferred file copies anyway. */\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             InstallHinfSectionA  (SETUPAPI.@)\r
+ */\r
+void WINAPI InstallHinfSectionA( HWND hwnd, HINSTANCE handle, LPCSTR cmdline, INT show )\r
+{\r
+    UNICODE_STRING cmdlineW;\r
+\r
+    if (RtlCreateUnicodeStringFromAsciiz( &cmdlineW, cmdline ))\r
+    {\r
+        InstallHinfSectionW( hwnd, handle, cmdlineW.Buffer, show );\r
+        RtlFreeUnicodeString( &cmdlineW );\r
+    }\r
+}\r
index 89601f0..4cc0fe4 100644 (file)
-/*
- * Setupapi miscellaneous functions
- *
- * Copyright 2005 Eric Kohl
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "setupapi.h"
-
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-#include "setupapi_private.h"
-
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-
-/**************************************************************************
- * MyFree [SETUPAPI.@]
- *
- * Frees an allocated memory block from the process heap.
- *
- * PARAMS
- *     lpMem [I] pointer to memory block which will be freed
- *
- * RETURNS
- *     None
- */
-VOID WINAPI MyFree(LPVOID lpMem)
-{
-    TRACE("%p\n", lpMem);
-    HeapFree(GetProcessHeap(), 0, lpMem);
-}
-
-
-/**************************************************************************
- * MyMalloc [SETUPAPI.@]
- *
- * Allocates memory block from the process heap.
- *
- * PARAMS
- *     dwSize [I] size of the allocated memory block
- *
- * RETURNS
- *     Success: pointer to allocated memory block
- *     Failure: NULL
- */
-LPVOID WINAPI MyMalloc(DWORD dwSize)
-{
-    TRACE("%lu\n", dwSize);
-    return HeapAlloc(GetProcessHeap(), 0, dwSize);
-}
-
-
-/**************************************************************************
- * MyRealloc [SETUPAPI.@]
- *
- * Changes the size of an allocated memory block or allocates a memory
- * block from the process heap.
- *
- * PARAMS
- *     lpSrc  [I] pointer to memory block which will be resized
- *     dwSize [I] new size of the memory block
- *
- * RETURNS
- *     Success: pointer to the resized memory block
- *     Failure: NULL
- *
- * NOTES
- *     If lpSrc is a NULL-pointer, then MyRealloc allocates a memory
- *     block like MyMalloc.
- */
-LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)
-{
-    TRACE("%p %lu\n", lpSrc, dwSize);
-
-    if (lpSrc == NULL)
-        return HeapAlloc(GetProcessHeap(), 0, dwSize);
-
-    return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);
-}
-
-
-/**************************************************************************
- * DuplicateString [SETUPAPI.@]
- *
- * Duplicates a unicode string.
- *
- * PARAMS
- *     lpSrc  [I] pointer to the unicode string that will be duplicated
- *
- * RETURNS
- *     Success: pointer to the duplicated unicode string
- *     Failure: NULL
- *
- * NOTES
- *     Call MyFree() to release the duplicated string.
- */
-LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)
-{
-    LPWSTR lpDst;
-
-    TRACE("%s\n", debugstr_w(lpSrc));
-
-    lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));
-    if (lpDst == NULL)
-        return NULL;
-
-    strcpyW(lpDst, lpSrc);
-
-    return lpDst;
-}
-
-
-/**************************************************************************
- * QueryRegistryValue [SETUPAPI.@]
- *
- * Retrieves value data from the registry and allocates memory for the
- * value data.
- *
- * PARAMS
- *     hKey        [I] Handle of the key to query
- *     lpValueName [I] Name of value under hkey to query
- *     lpData      [O] Destination for the values contents,
- *     lpType      [O] Destination for the value type
- *     lpcbData    [O] Destination for the size of data
- *
- * RETURNS
- *     Success: ERROR_SUCCESS
- *     Failure: Otherwise
- *
- * NOTES
- *     Use MyFree to release the lpData buffer.
- */
-LONG WINAPI QueryRegistryValue(HKEY hKey,
-                               LPCWSTR lpValueName,
-                               LPBYTE  *lpData,
-                               LPDWORD lpType,
-                               LPDWORD lpcbData)
-{
-    LONG lError;
-
-    TRACE("%lx %s %p %p %p\n",
-          hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);
-
-    /* Get required buffer size */
-    *lpcbData = 0;
-    lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);
-    if (lError != ERROR_SUCCESS)
-        return lError;
-
-    /* Allocate buffer */
-    *lpData = MyMalloc(*lpcbData);
-    if (*lpData == NULL)
-        return ERROR_NOT_ENOUGH_MEMORY;
-
-    /* Query registry value */
-    lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);
-    if (lError != ERROR_SUCCESS)
-        MyFree(*lpData);
-
-    return lError;
-}
-
-
-/**************************************************************************
- * IsUserAdmin [SETUPAPI.@]
- *
- * Checks whether the current user is a member of the Administrators group.
- *
- * PARAMS
- *     None
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-BOOL WINAPI IsUserAdmin(VOID)
-{
-    SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
-    HANDLE hToken;
-    DWORD dwSize;
-    PTOKEN_GROUPS lpGroups;
-    PSID lpSid;
-    DWORD i;
-    BOOL bResult = FALSE;
-
-    TRACE("\n");
-
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
-    {
-        return FALSE;
-    }
-
-    if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
-    {
-        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-        {
-            CloseHandle(hToken);
-            return FALSE;
-        }
-    }
-
-    lpGroups = MyMalloc(dwSize);
-    if (lpGroups == NULL)
-    {
-        CloseHandle(hToken);
-        return FALSE;
-    }
-
-    if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))
-    {
-        MyFree(lpGroups);
-        CloseHandle(hToken);
-        return FALSE;
-    }
-
-    CloseHandle(hToken);
-
-    if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
-                                  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
-                                  &lpSid))
-    {
-        MyFree(lpGroups);
-        return FALSE;
-    }
-
-    for (i = 0; i < lpGroups->GroupCount; i++)
-    {
-        if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))
-        {
-            bResult = TRUE;
-            break;
-        }
-    }
-
-    FreeSid(lpSid);
-    MyFree(lpGroups);
-
-    return bResult;
-}
-
-
-/**************************************************************************
- * MultiByteToUnicode [SETUPAPI.@]
- *
- * Converts a multi-byte string to a Unicode string.
- *
- * PARAMS
- *     lpMultiByteStr  [I] Multi-byte string to be converted
- *     uCodePage       [I] Code page
- *
- * RETURNS
- *     Success: pointer to the converted Unicode string
- *     Failure: NULL
- *
- * NOTE
- *     Use MyFree to release the returned Unicode string.
- */
-LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
-{
-    LPWSTR lpUnicodeStr;
-    int nLength;
-
-    TRACE("%s %lu\n", debugstr_a(lpMultiByteStr), uCodePage);
-
-    nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
-                                  -1, NULL, 0);
-    if (nLength == 0)
-        return NULL;
-
-    lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
-    if (lpUnicodeStr == NULL)
-        return NULL;
-
-    if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
-                             nLength, lpUnicodeStr, nLength))
-    {
-        MyFree(lpUnicodeStr);
-        return NULL;
-    }
-
-    return lpUnicodeStr;
-}
-
-
-/**************************************************************************
- * UnicodeToMultiByte [SETUPAPI.@]
- *
- * Converts a Unicode string to a multi-byte string.
- *
- * PARAMS
- *     lpUnicodeStr  [I] Unicode string to be converted
- *     uCodePage     [I] Code page
- *
- * RETURNS
- *     Success: pointer to the converted multi-byte string
- *     Failure: NULL
- *
- * NOTE
- *     Use MyFree to release the returned multi-byte string.
- */
-LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)
-{
-    LPSTR lpMultiByteStr;
-    int nLength;
-
-    TRACE("%s %lu\n", debugstr_w(lpUnicodeStr), uCodePage);
-
-    nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
-                                  NULL, 0, NULL, NULL);
-    if (nLength == 0)
-        return NULL;
-
-    lpMultiByteStr = MyMalloc(nLength);
-    if (lpMultiByteStr == NULL)
-        return NULL;
-
-    if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
-                             lpMultiByteStr, nLength, NULL, NULL))
-    {
-        MyFree(lpMultiByteStr);
-        return NULL;
-    }
-
-    return lpMultiByteStr;
-}
-
-
-/**************************************************************************
- * DoesUserHavePrivilege [SETUPAPI.@]
- *
- * Check whether the current user has got a given privilege.
- *
- * PARAMS
- *     lpPrivilegeName  [I] Name of the privilege to be checked
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)
-{
-    HANDLE hToken;
-    DWORD dwSize;
-    PTOKEN_PRIVILEGES lpPrivileges;
-    LUID PrivilegeLuid;
-    DWORD i;
-    BOOL bResult = FALSE;
-
-    TRACE("%s\n", debugstr_w(lpPrivilegeName));
-
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
-        return FALSE;
-
-    if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))
-    {
-        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-        {
-            CloseHandle(hToken);
-            return FALSE;
-        }
-    }
-
-    lpPrivileges = MyMalloc(dwSize);
-    if (lpPrivileges == NULL)
-    {
-        CloseHandle(hToken);
-        return FALSE;
-    }
-
-    if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))
-    {
-        MyFree(lpPrivileges);
-        CloseHandle(hToken);
-        return FALSE;
-    }
-
-    CloseHandle(hToken);
-
-    if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))
-    {
-        MyFree(lpPrivileges);
-        return FALSE;
-    }
-
-    for (i = 0; i < lpPrivileges->PrivilegeCount; i++)
-    {
-        if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&
-            lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)
-        {
-            bResult = TRUE;
-        }
-    }
-
-    MyFree(lpPrivileges);
-
-    return bResult;
-}
-
-
-/**************************************************************************
- * EnablePrivilege [SETUPAPI.@]
- *
- * Enables or disables one of the current users privileges.
- *
- * PARAMS
- *     lpPrivilegeName  [I] Name of the privilege to be changed
- *     bEnable          [I] TRUE: Enables the privilege
- *                          FALSE: Disables the privilege
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)
-{
-    TOKEN_PRIVILEGES Privileges;
-    HANDLE hToken;
-    BOOL bResult;
-
-    TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");
-
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
-        return FALSE;
-
-    Privileges.PrivilegeCount = 1;
-    Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
-
-    if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,
-                               &Privileges.Privileges[0].Luid))
-    {
-        CloseHandle(hToken);
-        return FALSE;
-    }
-
-    bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);
-
-    CloseHandle(hToken);
-
-    return bResult;
-}
-
-
-/**************************************************************************
- * DelayedMove [SETUPAPI.@]
- *
- * Moves a file upon the next reboot.
- *
- * PARAMS
- *     lpExistingFileName  [I] Current file name
- *     lpNewFileName       [I] New file name
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-BOOL WINAPI DelayedMove(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
-{
-    if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
-    {
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-        return FALSE;
-    }
-
-    return MoveFileExW(lpExistingFileName, lpNewFileName,
-                       MOVEFILE_REPLACE_EXISTING | MOVEFILE_DELAY_UNTIL_REBOOT);
-}
-
-
-/**************************************************************************
- * FileExists [SETUPAPI.@]
- *
- * Checks whether a file exists.
- *
- * PARAMS
- *     lpFileName     [I] Name of the file to check
- *     lpNewFileName  [O] Optional information about the existing file
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-BOOL WINAPI FileExists(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFileFindData)
-{
-    WIN32_FIND_DATAW FindData;
-    HANDLE hFind;
-    UINT uErrorMode;
-    DWORD dwError;
-
-    uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
-
-    hFind = FindFirstFileW(lpFileName, &FindData);
-    if (hFind == INVALID_HANDLE_VALUE)
-    {
-        dwError = GetLastError();
-        SetErrorMode(uErrorMode);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
-    FindClose(hFind);
-
-    if (lpFileFindData)
-        memcpy(lpFileFindData, &FindData, sizeof(WIN32_FIND_DATAW));
-
-    SetErrorMode(uErrorMode);
-
-    return TRUE;
-}
-
-
-/**************************************************************************
- * CaptureStringArg [SETUPAPI.@]
- *
- * Captures a UNICODE string.
- *
- * PARAMS
- *     lpSrc  [I] UNICODE string to be captured
- *     lpDst  [O] Pointer to the captured UNICODE string
- *
- * RETURNS
- *     Success: ERROR_SUCCESS
- *     Failure: ERROR_INVALID_PARAMETER
- *
- * NOTE
- *     Call MyFree to release the captured UNICODE string.
- */
-DWORD WINAPI CaptureStringArg(LPCWSTR pSrc, LPWSTR *pDst)
-{
-  if (pDst == NULL)
-    return ERROR_INVALID_PARAMETER;
-
-  *pDst = DuplicateString(pSrc);
-
-  return ERROR_SUCCESS;
-}
-
-
-/**************************************************************************
- * CaptureAndConvertAnsiArg [SETUPAPI.@]
- *
- * Captures an ANSI string and converts it to a UNICODE string.
- *
- * PARAMS
- *     lpSrc  [I] ANSI string to be captured
- *     lpDst  [O] Pointer to the captured UNICODE string
- *
- * RETURNS
- *     Success: ERROR_SUCCESS
- *     Failure: ERROR_INVALID_PARAMETER
- *
- * NOTE
- *     Call MyFree to release the captured UNICODE string.
- */
-DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst)
-{
-  if (pDst == NULL)
-    return ERROR_INVALID_PARAMETER;
-
-  *pDst = MultiByteToUnicode(pSrc, CP_ACP);
-
-  return ERROR_SUCCESS;
-}
+/*\r
+ * Setupapi miscellaneous functions\r
+ *\r
+ * Copyright 2005 Eric Kohl\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winreg.h"\r
+#include "setupapi.h"\r
+\r
+#include "wine/unicode.h"\r
+#include "wine/debug.h"\r
+\r
+#include "setupapi_private.h"\r
+\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+\r
+/**************************************************************************\r
+ * MyFree [SETUPAPI.@]\r
+ *\r
+ * Frees an allocated memory block from the process heap.\r
+ *\r
+ * PARAMS\r
+ *     lpMem [I] pointer to memory block which will be freed\r
+ *\r
+ * RETURNS\r
+ *     None\r
+ */\r
+VOID WINAPI MyFree(LPVOID lpMem)\r
+{\r
+    TRACE("%p\n", lpMem);\r
+    HeapFree(GetProcessHeap(), 0, lpMem);\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * MyMalloc [SETUPAPI.@]\r
+ *\r
+ * Allocates memory block from the process heap.\r
+ *\r
+ * PARAMS\r
+ *     dwSize [I] size of the allocated memory block\r
+ *\r
+ * RETURNS\r
+ *     Success: pointer to allocated memory block\r
+ *     Failure: NULL\r
+ */\r
+LPVOID WINAPI MyMalloc(DWORD dwSize)\r
+{\r
+    TRACE("%lu\n", dwSize);\r
+    return HeapAlloc(GetProcessHeap(), 0, dwSize);\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * MyRealloc [SETUPAPI.@]\r
+ *\r
+ * Changes the size of an allocated memory block or allocates a memory\r
+ * block from the process heap.\r
+ *\r
+ * PARAMS\r
+ *     lpSrc  [I] pointer to memory block which will be resized\r
+ *     dwSize [I] new size of the memory block\r
+ *\r
+ * RETURNS\r
+ *     Success: pointer to the resized memory block\r
+ *     Failure: NULL\r
+ *\r
+ * NOTES\r
+ *     If lpSrc is a NULL-pointer, then MyRealloc allocates a memory\r
+ *     block like MyMalloc.\r
+ */\r
+LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)\r
+{\r
+    TRACE("%p %lu\n", lpSrc, dwSize);\r
+\r
+    if (lpSrc == NULL)\r
+        return HeapAlloc(GetProcessHeap(), 0, dwSize);\r
+\r
+    return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * DuplicateString [SETUPAPI.@]\r
+ *\r
+ * Duplicates a unicode string.\r
+ *\r
+ * PARAMS\r
+ *     lpSrc  [I] pointer to the unicode string that will be duplicated\r
+ *\r
+ * RETURNS\r
+ *     Success: pointer to the duplicated unicode string\r
+ *     Failure: NULL\r
+ *\r
+ * NOTES\r
+ *     Call MyFree() to release the duplicated string.\r
+ */\r
+LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)\r
+{\r
+    LPWSTR lpDst;\r
+\r
+    TRACE("%s\n", debugstr_w(lpSrc));\r
+\r
+    lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));\r
+    if (lpDst == NULL)\r
+        return NULL;\r
+\r
+    strcpyW(lpDst, lpSrc);\r
+\r
+    return lpDst;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * QueryRegistryValue [SETUPAPI.@]\r
+ *\r
+ * Retrieves value data from the registry and allocates memory for the\r
+ * value data.\r
+ *\r
+ * PARAMS\r
+ *     hKey        [I] Handle of the key to query\r
+ *     lpValueName [I] Name of value under hkey to query\r
+ *     lpData      [O] Destination for the values contents,\r
+ *     lpType      [O] Destination for the value type\r
+ *     lpcbData    [O] Destination for the size of data\r
+ *\r
+ * RETURNS\r
+ *     Success: ERROR_SUCCESS\r
+ *     Failure: Otherwise\r
+ *\r
+ * NOTES\r
+ *     Use MyFree to release the lpData buffer.\r
+ */\r
+LONG WINAPI QueryRegistryValue(HKEY hKey,\r
+                               LPCWSTR lpValueName,\r
+                               LPBYTE  *lpData,\r
+                               LPDWORD lpType,\r
+                               LPDWORD lpcbData)\r
+{\r
+    LONG lError;\r
+\r
+    TRACE("%lx %s %p %p %p\n",\r
+          hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);\r
+\r
+    /* Get required buffer size */\r
+    *lpcbData = 0;\r
+    lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);\r
+    if (lError != ERROR_SUCCESS)\r
+        return lError;\r
+\r
+    /* Allocate buffer */\r
+    *lpData = MyMalloc(*lpcbData);\r
+    if (*lpData == NULL)\r
+        return ERROR_NOT_ENOUGH_MEMORY;\r
+\r
+    /* Query registry value */\r
+    lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);\r
+    if (lError != ERROR_SUCCESS)\r
+        MyFree(*lpData);\r
+\r
+    return lError;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * IsUserAdmin [SETUPAPI.@]\r
+ *\r
+ * Checks whether the current user is a member of the Administrators group.\r
+ *\r
+ * PARAMS\r
+ *     None\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+BOOL WINAPI IsUserAdmin(VOID)\r
+{\r
+    SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};\r
+    HANDLE hToken;\r
+    DWORD dwSize;\r
+    PTOKEN_GROUPS lpGroups;\r
+    PSID lpSid;\r
+    DWORD i;\r
+    BOOL bResult = FALSE;\r
+\r
+    TRACE("\n");\r
+\r
+    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))\r
+    {\r
+        return FALSE;\r
+    }\r
+\r
+    if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))\r
+    {\r
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\r
+        {\r
+            CloseHandle(hToken);\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    lpGroups = MyMalloc(dwSize);\r
+    if (lpGroups == NULL)\r
+    {\r
+        CloseHandle(hToken);\r
+        return FALSE;\r
+    }\r
+\r
+    if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))\r
+    {\r
+        MyFree(lpGroups);\r
+        CloseHandle(hToken);\r
+        return FALSE;\r
+    }\r
+\r
+    CloseHandle(hToken);\r
+\r
+    if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,\r
+                                  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,\r
+                                  &lpSid))\r
+    {\r
+        MyFree(lpGroups);\r
+        return FALSE;\r
+    }\r
+\r
+    for (i = 0; i < lpGroups->GroupCount; i++)\r
+    {\r
+        if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))\r
+        {\r
+            bResult = TRUE;\r
+            break;\r
+        }\r
+    }\r
+\r
+    FreeSid(lpSid);\r
+    MyFree(lpGroups);\r
+\r
+    return bResult;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * MultiByteToUnicode [SETUPAPI.@]\r
+ *\r
+ * Converts a multi-byte string to a Unicode string.\r
+ *\r
+ * PARAMS\r
+ *     lpMultiByteStr  [I] Multi-byte string to be converted\r
+ *     uCodePage       [I] Code page\r
+ *\r
+ * RETURNS\r
+ *     Success: pointer to the converted Unicode string\r
+ *     Failure: NULL\r
+ *\r
+ * NOTE\r
+ *     Use MyFree to release the returned Unicode string.\r
+ */\r
+LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)\r
+{\r
+    LPWSTR lpUnicodeStr;\r
+    int nLength;\r
+\r
+    TRACE("%s %lu\n", debugstr_a(lpMultiByteStr), uCodePage);\r
+\r
+    nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,\r
+                                  -1, NULL, 0);\r
+    if (nLength == 0)\r
+        return NULL;\r
+\r
+    lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));\r
+    if (lpUnicodeStr == NULL)\r
+        return NULL;\r
+\r
+    if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,\r
+                             nLength, lpUnicodeStr, nLength))\r
+    {\r
+        MyFree(lpUnicodeStr);\r
+        return NULL;\r
+    }\r
+\r
+    return lpUnicodeStr;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * UnicodeToMultiByte [SETUPAPI.@]\r
+ *\r
+ * Converts a Unicode string to a multi-byte string.\r
+ *\r
+ * PARAMS\r
+ *     lpUnicodeStr  [I] Unicode string to be converted\r
+ *     uCodePage     [I] Code page\r
+ *\r
+ * RETURNS\r
+ *     Success: pointer to the converted multi-byte string\r
+ *     Failure: NULL\r
+ *\r
+ * NOTE\r
+ *     Use MyFree to release the returned multi-byte string.\r
+ */\r
+LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)\r
+{\r
+    LPSTR lpMultiByteStr;\r
+    int nLength;\r
+\r
+    TRACE("%s %lu\n", debugstr_w(lpUnicodeStr), uCodePage);\r
+\r
+    nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,\r
+                                  NULL, 0, NULL, NULL);\r
+    if (nLength == 0)\r
+        return NULL;\r
+\r
+    lpMultiByteStr = MyMalloc(nLength);\r
+    if (lpMultiByteStr == NULL)\r
+        return NULL;\r
+\r
+    if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,\r
+                             lpMultiByteStr, nLength, NULL, NULL))\r
+    {\r
+        MyFree(lpMultiByteStr);\r
+        return NULL;\r
+    }\r
+\r
+    return lpMultiByteStr;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * DoesUserHavePrivilege [SETUPAPI.@]\r
+ *\r
+ * Check whether the current user has got a given privilege.\r
+ *\r
+ * PARAMS\r
+ *     lpPrivilegeName  [I] Name of the privilege to be checked\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)\r
+{\r
+    HANDLE hToken;\r
+    DWORD dwSize;\r
+    PTOKEN_PRIVILEGES lpPrivileges;\r
+    LUID PrivilegeLuid;\r
+    DWORD i;\r
+    BOOL bResult = FALSE;\r
+\r
+    TRACE("%s\n", debugstr_w(lpPrivilegeName));\r
+\r
+    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))\r
+        return FALSE;\r
+\r
+    if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))\r
+    {\r
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\r
+        {\r
+            CloseHandle(hToken);\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    lpPrivileges = MyMalloc(dwSize);\r
+    if (lpPrivileges == NULL)\r
+    {\r
+        CloseHandle(hToken);\r
+        return FALSE;\r
+    }\r
+\r
+    if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))\r
+    {\r
+        MyFree(lpPrivileges);\r
+        CloseHandle(hToken);\r
+        return FALSE;\r
+    }\r
+\r
+    CloseHandle(hToken);\r
+\r
+    if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))\r
+    {\r
+        MyFree(lpPrivileges);\r
+        return FALSE;\r
+    }\r
+\r
+    for (i = 0; i < lpPrivileges->PrivilegeCount; i++)\r
+    {\r
+        if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&\r
+            lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)\r
+        {\r
+            bResult = TRUE;\r
+        }\r
+    }\r
+\r
+    MyFree(lpPrivileges);\r
+\r
+    return bResult;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * EnablePrivilege [SETUPAPI.@]\r
+ *\r
+ * Enables or disables one of the current users privileges.\r
+ *\r
+ * PARAMS\r
+ *     lpPrivilegeName  [I] Name of the privilege to be changed\r
+ *     bEnable          [I] TRUE: Enables the privilege\r
+ *                          FALSE: Disables the privilege\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)\r
+{\r
+    TOKEN_PRIVILEGES Privileges;\r
+    HANDLE hToken;\r
+    BOOL bResult;\r
+\r
+    TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");\r
+\r
+    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))\r
+        return FALSE;\r
+\r
+    Privileges.PrivilegeCount = 1;\r
+    Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;\r
+\r
+    if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,\r
+                               &Privileges.Privileges[0].Luid))\r
+    {\r
+        CloseHandle(hToken);\r
+        return FALSE;\r
+    }\r
+\r
+    bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);\r
+\r
+    CloseHandle(hToken);\r
+\r
+    return bResult;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * DelayedMove [SETUPAPI.@]\r
+ *\r
+ * Moves a file upon the next reboot.\r
+ *\r
+ * PARAMS\r
+ *     lpExistingFileName  [I] Current file name\r
+ *     lpNewFileName       [I] New file name\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+BOOL WINAPI DelayedMove(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)\r
+{\r
+    if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)\r
+    {\r
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
+        return FALSE;\r
+    }\r
+\r
+    return MoveFileExW(lpExistingFileName, lpNewFileName,\r
+                       MOVEFILE_REPLACE_EXISTING | MOVEFILE_DELAY_UNTIL_REBOOT);\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * FileExists [SETUPAPI.@]\r
+ *\r
+ * Checks whether a file exists.\r
+ *\r
+ * PARAMS\r
+ *     lpFileName     [I] Name of the file to check\r
+ *     lpNewFileName  [O] Optional information about the existing file\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+BOOL WINAPI FileExists(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFileFindData)\r
+{\r
+    WIN32_FIND_DATAW FindData;\r
+    HANDLE hFind;\r
+    UINT uErrorMode;\r
+    DWORD dwError;\r
+\r
+    uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);\r
+\r
+    hFind = FindFirstFileW(lpFileName, &FindData);\r
+    if (hFind == INVALID_HANDLE_VALUE)\r
+    {\r
+        dwError = GetLastError();\r
+        SetErrorMode(uErrorMode);\r
+        SetLastError(dwError);\r
+        return FALSE;\r
+    }\r
+\r
+    FindClose(hFind);\r
+\r
+    if (lpFileFindData)\r
+        memcpy(lpFileFindData, &FindData, sizeof(WIN32_FIND_DATAW));\r
+\r
+    SetErrorMode(uErrorMode);\r
+\r
+    return TRUE;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * CaptureStringArg [SETUPAPI.@]\r
+ *\r
+ * Captures a UNICODE string.\r
+ *\r
+ * PARAMS\r
+ *     lpSrc  [I] UNICODE string to be captured\r
+ *     lpDst  [O] Pointer to the captured UNICODE string\r
+ *\r
+ * RETURNS\r
+ *     Success: ERROR_SUCCESS\r
+ *     Failure: ERROR_INVALID_PARAMETER\r
+ *\r
+ * NOTE\r
+ *     Call MyFree to release the captured UNICODE string.\r
+ */\r
+DWORD WINAPI CaptureStringArg(LPCWSTR pSrc, LPWSTR *pDst)\r
+{\r
+  if (pDst == NULL)\r
+    return ERROR_INVALID_PARAMETER;\r
+\r
+  *pDst = DuplicateString(pSrc);\r
+\r
+  return ERROR_SUCCESS;\r
+}\r
+\r
+\r
+/**************************************************************************\r
+ * CaptureAndConvertAnsiArg [SETUPAPI.@]\r
+ *\r
+ * Captures an ANSI string and converts it to a UNICODE string.\r
+ *\r
+ * PARAMS\r
+ *     lpSrc  [I] ANSI string to be captured\r
+ *     lpDst  [O] Pointer to the captured UNICODE string\r
+ *\r
+ * RETURNS\r
+ *     Success: ERROR_SUCCESS\r
+ *     Failure: ERROR_INVALID_PARAMETER\r
+ *\r
+ * NOTE\r
+ *     Call MyFree to release the captured UNICODE string.\r
+ */\r
+DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst)\r
+{\r
+  if (pDst == NULL)\r
+    return ERROR_INVALID_PARAMETER;\r
+\r
+  *pDst = MultiByteToUnicode(pSrc, CP_ACP);\r
+\r
+  return ERROR_SUCCESS;\r
+}\r
index 53c9e39..74664bd 100644 (file)
-/*
- * INF file parsing
- *
- * Copyright 2002 Alexandre Julliard 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winerror.h"
-#include "setupapi.h"
-#include "setupapi_private.h"
-
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-#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)
-
-/* inf file structure definitions */
-
-struct field
-{
-    const WCHAR *text;         /* field text */
-};
-
-struct line
-{
-    int first_field;           /* index of first field in field array */
-    int nb_fields;             /* number of fields in line */
-    int key_field;             /* index of field for key or -1 if no key */
-};
-
-struct section
-{
-    const WCHAR *name;         /* section name */
-    unsigned int nb_lines;     /* number of used lines */
-    unsigned int alloc_lines;  /* total number of allocated lines in array below */
-    struct line  lines[16];    /* lines information (grown dynamically, 16 is initial size) */
-};
-
-struct inf_file
-{
-    struct inf_file *next;            /* next appended file */
-    WCHAR           *strings;         /* buffer for string data (section names and field values) */
-    WCHAR           *string_pos;      /* position of next available string in buffer */
-    unsigned int     nb_sections;     /* number of used sections */
-    unsigned int     alloc_sections;  /* total number of allocated section pointers */
-    struct section **sections;        /* section pointers array */
-    unsigned int     nb_fields;
-    unsigned int     alloc_fields;
-    struct field    *fields;
-    int              strings_section; /* index of [Strings] section or -1 if none */
-    WCHAR           *src_root;        /* source root directory */
-};
-
-/* 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 */
-    struct inf_file  *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 */
-
-    int               cur_section;  /* index of section being parsed*/
-    struct line      *line;         /* current line */
-    unsigned int      line_pos;     /* current line position in file */
-    unsigned int      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 */
-};
-
-
-/* Unicode string constants */
-static const WCHAR Version[]    = {'V','e','r','s','i','o','n',0};
-static const WCHAR Signature[]  = {'S','i','g','n','a','t','u','r','e',0};
-static const WCHAR Chicago[]    = {'$','C','h','i','c','a','g','o','$',0};
-static const WCHAR WindowsNT[]  = {'$','W','i','n','d','o','w','s',' ','N','T','$',0};
-static const WCHAR Windows95[]  = {'$','W','i','n','d','o','w','s',' ','9','5','$',0};
-static const WCHAR LayoutFile[] = {'L','a','y','o','u','t','F','i','l','e',0};
-
-/* extend an array, allocating more memory if necessary */
-static void *grow_array( void *array, unsigned int *count, size_t elem )
-{
-    void *new_array;
-    unsigned int new_count = *count + *count / 2;
-    if (new_count < 32) new_count = 32;
-
-    if (array)
-       new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );
-    else
-       new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );
-
-    if (new_array)
-        *count = new_count;
-    else
-        HeapFree( GetProcessHeap(), 0, array );
-    return new_array;
-}
-
-
-/* find a section by name */
-static int find_section( struct inf_file *file, const WCHAR *name )
-{
-    unsigned int i;
-
-    for (i = 0; i < file->nb_sections; i++)
-        if (!strcmpiW( name, file->sections[i]->name )) return i;
-    return -1;
-}
-
-
-/* find a line by name */
-static struct line *find_line( struct inf_file *file, int section_index, const WCHAR *name )
-{
-    struct section *section;
-    struct line *line;
-    int i;
-
-    if (section_index < 0 || section_index >= file->nb_sections) return NULL;
-    section = file->sections[section_index];
-    for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
-    {
-        if (line->key_field == -1) continue;
-        if (!strcmpiW( name, file->fields[line->key_field].text )) return line;
-    }
-    return NULL;
-}
-
-
-/* add a section to the file and return the section index */
-static int add_section( struct inf_file *file, const WCHAR *name )
-{
-    struct section *section;
-
-    if (file->nb_sections >= file->alloc_sections)
-    {
-        if (!(file->sections = grow_array( file->sections, &file->alloc_sections,
-                                           sizeof(file->sections[0]) ))) return -1;
-    }
-    if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) ))) return -1;
-    section->name        = name;
-    section->nb_lines    = 0;
-    section->alloc_lines = sizeof(section->lines)/sizeof(section->lines[0]);
-    file->sections[file->nb_sections] = section;
-    return file->nb_sections++;
-}
-
-
-/* add a line to a given section */
-static struct line *add_line( struct inf_file *file, int section_index )
-{
-    struct section *section;
-    struct line *line;
-
-    assert( section_index >= 0 && section_index < file->nb_sections );
-
-    section = file->sections[section_index];
-    if (section->nb_lines == section->alloc_lines)  /* need to grow the section */
-    {
-        int size = sizeof(*section) - sizeof(section->lines) + 2*section->alloc_lines*sizeof(*line);
-        if (!(section = HeapReAlloc( GetProcessHeap(), 0, section, size ))) return NULL;
-        section->alloc_lines *= 2;
-        file->sections[section_index] = section;
-    }
-    line = &section->lines[section->nb_lines++];
-    line->first_field = file->nb_fields;
-    line->nb_fields   = 0;
-    line->key_field   = -1;
-    return line;
-}
-
-
-/* retrieve a given line from section/line index */
-inline static struct line *get_line( struct inf_file *file, unsigned int section_index,
-                                     unsigned int line_index )
-{
-    struct section *section;
-
-    if (section_index >= file->nb_sections) return NULL;
-    section = file->sections[section_index];
-    if (line_index >= section->nb_lines) return NULL;
-    return &section->lines[line_index];
-}
-
-
-/* retrieve a given field from section/line/field index */
-static struct field *get_field( struct inf_file *file, int section_index, int line_index,
-                                int field_index )
-{
-    struct line *line = get_line( file, section_index, line_index );
-
-    if (!line) return NULL;
-    if (!field_index)  /* get the key */
-    {
-        if (line->key_field == -1) return NULL;
-        return &file->fields[line->key_field];
-    }
-    field_index--;
-    if (field_index >= line->nb_fields) return NULL;
-    return &file->fields[line->first_field + field_index];
-}
-
-
-/* allocate a new field, growing the array if necessary */
-static struct field *add_field( struct inf_file *file, const WCHAR *text )
-{
-    struct field *field;
-
-    if (file->nb_fields >= file->alloc_fields)
-    {
-        if (!(file->fields = grow_array( file->fields, &file->alloc_fields,
-                                         sizeof(file->fields[0]) ))) return NULL;
-    }
-    field = &file->fields[file->nb_fields++];
-    field->text = text;
-    return field;
-}
-
-
-/* retrieve the string substitution for a directory id */
-static const WCHAR *get_dirid_subst( int dirid, unsigned int *len )
-{
-    extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );
-    const WCHAR *ret = DIRID_get_string( 0, dirid );
-    if (ret) *len = strlenW(ret);
-    return ret;
-}
-
-
-/* retrieve the string substitution for a given string, or NULL if not found */
-/* if found, len is set to the substitution length */
-static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, unsigned int *len )
-{
-    static const WCHAR percent = '%';
-
-    struct section *strings_section;
-    struct line *line;
-    struct field *field;
-    unsigned int i;
-    int dirid;
-    WCHAR *dirid_str, *end;
-    const WCHAR *ret = NULL;
-
-    if (!*len)  /* empty string (%%) is replaced by single percent */
-    {
-        *len = 1;
-        return &percent;
-    }
-    if (file->strings_section == -1) goto not_found;
-    strings_section = file->sections[file->strings_section];
-    for (i = 0, line = strings_section->lines; i < strings_section->nb_lines; i++, line++)
-    {
-        if (line->key_field == -1) continue;
-        if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue;
-        if (!file->fields[line->key_field].text[*len]) break;
-    }
-    if (i == strings_section->nb_lines || !line->nb_fields) goto not_found;
-    field = &file->fields[line->first_field];
-    *len = strlenW( field->text );
-    return field->text;
-
- not_found:  /* check for integer id */
-    if ((dirid_str = HeapAlloc( GetProcessHeap(), 0, (*len+1) * sizeof(WCHAR) )))
-    {
-        memcpy( dirid_str, str, *len * sizeof(WCHAR) );
-        dirid_str[*len] = 0;
-        dirid = strtolW( dirid_str, &end, 10 );
-        if (!*end) ret = get_dirid_subst( dirid, len );
-        HeapFree( GetProcessHeap(), 0, dirid_str );
-        return ret;
-    }
-    return NULL;
-}
-
-
-/* do string substitutions on the specified text */
-/* the buffer is assumed to be large enough */
-/* returns necessary length not including terminating null */
-unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCHAR *buffer,
-                                   unsigned int size )
-{
-    const WCHAR *start, *subst, *p;
-    unsigned int len, total = 0;
-    int inside = 0;
-
-    if (!buffer) size = MAX_STRING_LEN + 1;
-    for (p = start = text; *p; p++)
-    {
-        if (*p != '%') continue;
-        inside = !inside;
-        if (inside)  /* start of a %xx% string */
-        {
-            len = 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 = p - start - 1;
-            subst = get_string_subst( file, start + 1, &len );
-            if (!subst)
-            {
-                subst = start;
-                len = 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 = 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;
-}
-
-
-/* do string substitutions on the specified text */
-/* the buffer is assumed to be large enough */
-/* returns necessary length not including terminating null */
-unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text, char *buffer,
-                                   unsigned int size )
-{
-    WCHAR buffW[MAX_STRING_LEN+1];
-    DWORD ret;
-
-    unsigned int len = PARSER_string_substW( file, text, buffW, sizeof(buffW)/sizeof(WCHAR) );
-    if (!buffer) RtlUnicodeToMultiByteSize( &ret, buffW, len * sizeof(WCHAR) );
-    else
-    {
-        RtlUnicodeToMultiByteN( buffer, size-1, &ret, buffW, len * sizeof(WCHAR) );
-        buffer[ret] = 0;
-    }
-    return ret;
-}
-
-
-/* push some string data into the strings buffer */
-static WCHAR *push_string( struct inf_file *file, const WCHAR *string )
-{
-    WCHAR *ret = file->string_pos;
-    strcpyW( ret, string );
-    file->string_pos += strlenW( ret ) + 1;
-    return ret;
-}
-
-
-/* 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);
-}
-
-
-/* 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');
-}
-
-
-/* push data from current token start up to pos into the current token */
-static int push_token( struct parser *parser, const WCHAR *pos )
-{
-    int len = 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++) *dst = *src ? *src : ' ';
-    *dst = 0;
-    parser->start = pos;
-    return 0;
-}
-
-
-/* add a section with the current token as name */
-static int add_section_from_token( struct parser *parser )
-{
-    int section_index;
-
-    if (parser->token_len > MAX_SECTION_NAME_LEN)
-    {
-        parser->error = ERROR_SECTION_NAME_TOO_LONG;
-        return -1;
-    }
-    if ((section_index = find_section( parser->file, parser->token )) == -1)
-    {
-        /* need to create a new one */
-        const WCHAR *name = push_string( parser->file, parser->token );
-        if ((section_index = add_section( parser->file, name )) == -1)
-        {
-            parser->error = ERROR_NOT_ENOUGH_MEMORY;
-            return -1;
-        }
-    }
-    parser->token_len = 0;
-    parser->cur_section = section_index;
-    return section_index;
-}
-
-
-/* add a field containing the current token to the current line */
-static struct field *add_field_from_token( struct parser *parser, int is_key )
-{
-    struct field *field;
-    WCHAR *text;
-
-    if (!parser->line)  /* need to start a new line */
-    {
-        if (parser->cur_section == -1)  /* got a line before the first section */
-        {
-            parser->error = ERROR_WRONG_INF_STYLE;
-            return NULL;
-        }
-        if (!(parser->line = add_line( parser->file, parser->cur_section ))) goto error;
-    }
-    else assert(!is_key);
-
-    text = push_string( parser->file, parser->token );
-    if ((field = add_field( parser->file, text )))
-    {
-        if (!is_key) parser->line->nb_fields++;
-        else
-        {
-            /* replace first field by key field */
-            parser->line->key_field = parser->line->first_field;
-            parser->line->first_field++;
-        }
-        parser->token_len = 0;
-        return field;
-    }
- error:
-    parser->error = ERROR_NOT_ENOUGH_MEMORY;
-    return NULL;
-}
-
-
-/* close the current line and prepare for parsing a new one */
-static void close_current_line( struct parser *parser )
-{
-    struct line *cur_line = parser->line;
-
-    if (cur_line)
-    {
-        /* if line has a single field and no key, the field is the key too */
-        if (cur_line->nb_fields == 1 && cur_line->key_field == -1)
-            cur_line->key_field = cur_line->first_field;
-    }
-    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 '\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 ) == -1) return NULL;
-            push_state( parser, LINE_START );
-            set_state( parser, COMMENT );  /* ignore everything else on the line */
-            return p + 1;
-        }
-    }
-    parser->error = ERROR_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 '\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 */
-static DWORD parse_buffer( struct inf_file *file, const WCHAR *buffer, const WCHAR *end,
-                           UINT *error_line )
-{
-    static const WCHAR Strings[] = {'S','t','r','i','n','g','s',0};
-
-    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 = -1;
-    parser.line_pos    = 1;
-    parser.error       = 0;
-    parser.token_len   = 0;
-
-    /* parser main loop */
-    while (pos) pos = (parser_funcs[parser.state])( &parser, pos );
-
-    /* trim excess buffer space */
-    if (file->alloc_sections > file->nb_sections)
-    {
-        file->sections = HeapReAlloc( GetProcessHeap(), 0, file->sections,
-                                      file->nb_sections * sizeof(file->sections[0]) );
-        file->alloc_sections = file->nb_sections;
-    }
-    if (file->alloc_fields > file->nb_fields)
-    {
-        file->fields = HeapReAlloc( GetProcessHeap(), 0, file->fields,
-                                    file->nb_fields * sizeof(file->fields[0]) );
-        file->alloc_fields = file->nb_fields;
-    }
-    file->strings = HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, file->strings,
-                                 (file->string_pos - file->strings) * sizeof(WCHAR) );
-
-    if (parser.error)
-    {
-        if (error_line) *error_line = parser.line_pos;
-        return parser.error;
-    }
-
-    /* find the [strings] section */
-    file->strings_section = find_section( file, Strings );
-    return 0;
-}
-
-
-/* append a child INF file to its parent list, in a thread-safe manner */
-static void append_inf_file( struct inf_file *parent, struct inf_file *child )
-{
-    struct inf_file **ppnext = &parent->next;
-    child->next = NULL;
-
-    for (;;)
-    {
-        struct inf_file *next = InterlockedCompareExchangePointer( (void **)ppnext, child, NULL );
-        if (!next) return;
-        ppnext = &next->next;
-    }
-}
-
-
-/***********************************************************************
- *            parse_file
- *
- * parse an INF file.
- */
-static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *error_line )
-{
-    void *buffer;
-    DWORD err = 0;
-    struct inf_file *file;
-
-    DWORD size = GetFileSize( handle, NULL );
-    HANDLE mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, size, NULL );
-    if (!mapping) return NULL;
-    buffer = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, size );
-    NtClose( mapping );
-    if (!buffer) return NULL;
-
-    if (class) FIXME( "class %s not supported yet\n", debugstr_w(class) );
-
-    if (!(file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*file) )))
-    {
-        err = ERROR_NOT_ENOUGH_MEMORY;
-        goto done;
-    }
-
-    /* we won't need more strings space than the size of the file,
-     * so we can preallocate it here
-     */
-    if (!(file->strings = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
-    {
-        err = ERROR_NOT_ENOUGH_MEMORY;
-        goto done;
-    }
-    file->string_pos = file->strings;
-    file->strings_section = -1;
-
-    if (!RtlIsTextUnicode( buffer, size, NULL ))
-    {
-        WCHAR *new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
-        if (new_buff)
-        {
-            DWORD len = MultiByteToWideChar( CP_ACP, 0, buffer, size, new_buff,
-                                             size * sizeof(WCHAR) );
-            err = parse_buffer( file, new_buff, new_buff + len, error_line );
-            HeapFree( GetProcessHeap(), 0, new_buff );
-        }
-    }
-    else err = parse_buffer( file, buffer, (WCHAR *)((char *)buffer + size), error_line );
-
-    if (!err)  /* now check signature */
-    {
-        int version_index = find_section( file, Version );
-        if (version_index != -1)
-        {
-            struct line *line = find_line( file, version_index, Signature );
-            if (line && line->nb_fields > 0)
-            {
-                struct field *field = file->fields + line->first_field;
-                if (!strcmpiW( field->text, Chicago )) goto done;
-                if (!strcmpiW( field->text, WindowsNT )) goto done;
-                if (!strcmpiW( field->text, Windows95 )) goto done;
-            }
-        }
-        err = ERROR_WRONG_INF_STYLE;
-    }
-
- done:
-    UnmapViewOfFile( buffer );
-    if (err)
-    {
-        HeapFree( GetProcessHeap(), 0, file );
-        SetLastError( err );
-        file = NULL;
-    }
-    return file;
-}
-
-
-/***********************************************************************
- *            PARSER_get_src_root
- *
- * Retrieve the source directory of an inf file.
- */
-const WCHAR *PARSER_get_src_root( HINF hinf )
-{
-    struct inf_file *file = hinf;
-    return file->src_root;
-}
-
-
-/***********************************************************************
- *            PARSER_get_dest_dir
- *
- * retrieve a destination dir of the form "dirid,relative_path" in the given entry.
- * returned buffer must be freed by caller.
- */
-WCHAR *PARSER_get_dest_dir( INFCONTEXT *context )
-{
-    const WCHAR *dir;
-    WCHAR *ptr, *ret;
-    INT dirid;
-    DWORD len1, len2;
-
-    if (!SetupGetIntField( context, 1, &dirid )) return NULL;
-    if (!(dir = DIRID_get_string( context->Inf, dirid ))) return NULL;
-    len1 = strlenW(dir) + 1;
-    if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0;
-    if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2) * sizeof(WCHAR) ))) return NULL;
-    strcpyW( ret, dir );
-    ptr = ret + strlenW(ret);
-    if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\';
-    if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0;
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupOpenInfFileA   (SETUPAPI.@)
- */
-HINF WINAPI SetupOpenInfFileA( PCSTR name, PCSTR class, DWORD style, UINT *error )
-{
-    UNICODE_STRING nameW, classW;
-    HINF ret = (HINF)INVALID_HANDLE_VALUE;
-
-    classW.Buffer = NULL;
-    if (class && !RtlCreateUnicodeStringFromAsciiz( &classW, class ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return ret;
-    }
-    if (RtlCreateUnicodeStringFromAsciiz( &nameW, name ))
-    {
-        ret = SetupOpenInfFileW( nameW.Buffer, classW.Buffer, style, error );
-        RtlFreeUnicodeString( &nameW );
-    }
-    RtlFreeUnicodeString( &classW );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupOpenInfFileW   (SETUPAPI.@)
- */
-HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *error )
-{
-    struct inf_file *file = NULL;
-    HANDLE handle;
-    WCHAR *path, *p;
-    UINT len;
-
-    if (strchrW( name, '\\' ) || strchrW( name, '/' ))
-    {
-        if (!(len = GetFullPathNameW( name, 0, NULL, NULL ))) return (HINF)INVALID_HANDLE_VALUE;
-        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
-        {
-            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-            return (HINF)INVALID_HANDLE_VALUE;
-        }
-        GetFullPathNameW( name, len, path, NULL );
-        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-    }
-    else  /* try Windows directory */
-    {
-        static const WCHAR Inf[]      = {'\\','i','n','f','\\',0};
-        static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
-
-        len = GetWindowsDirectoryW( NULL, 0 ) + strlenW(name) + 12;
-        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
-        {
-            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-            return (HINF)INVALID_HANDLE_VALUE;
-        }
-        GetWindowsDirectoryW( path, len );
-        p = path + strlenW(path);
-        strcpyW( p, Inf );
-        strcatW( p, name );
-        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-        if (handle == INVALID_HANDLE_VALUE)
-        {
-            strcpyW( p, System32 );
-            strcatW( p, name );
-            handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-        }
-    }
-
-    if (handle != INVALID_HANDLE_VALUE)
-    {
-        file = parse_file( handle, class, error );
-        CloseHandle( handle );
-    }
-    if (!file)
-    {
-        HeapFree( GetProcessHeap(), 0, path );
-        return (HINF)INVALID_HANDLE_VALUE;
-    }
-    TRACE( "%s -> %p\n", debugstr_w(path), file );
-    file->src_root = path;
-    if ((p = strrchrW( path, '\\' ))) p[1] = 0;  /* remove file name */
-    SetLastError( 0 );
-    return (HINF)file;
-}
-
-
-/***********************************************************************
- *            SetupOpenAppendInfFileA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupOpenAppendInfFileA( PCSTR name, HINF parent_hinf, UINT *error )
-{
-    HINF child_hinf;
-
-    if (!name) return SetupOpenAppendInfFileW( NULL, parent_hinf, error );
-    child_hinf = SetupOpenInfFileA( name, NULL, INF_STYLE_WIN4, error );
-    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
-    append_inf_file( parent_hinf, child_hinf );
-    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_a(name), child_hinf );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupOpenAppendInfFileW    (SETUPAPI.@)
- */
-BOOL WINAPI SetupOpenAppendInfFileW( PCWSTR name, HINF parent_hinf, UINT *error )
-{
-    HINF child_hinf;
-
-    if (!name)
-    {
-        INFCONTEXT context;
-        WCHAR filename[MAX_PATH];
-        int idx = 1;
-
-        if (!SetupFindFirstLineW( parent_hinf, Version, LayoutFile, &context )) return FALSE;
-        while (SetupGetStringFieldW( &context, idx++, filename,
-                                     sizeof(filename)/sizeof(WCHAR), NULL ))
-        {
-            child_hinf = SetupOpenInfFileW( filename, NULL, INF_STYLE_WIN4, error );
-            if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
-            append_inf_file( parent_hinf, child_hinf );
-            TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(filename), child_hinf );
-        }
-        return TRUE;
-    }
-    child_hinf = SetupOpenInfFileW( name, NULL, INF_STYLE_WIN4, error );
-    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
-    append_inf_file( parent_hinf, child_hinf );
-    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(name), child_hinf );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupOpenMasterInf   (SETUPAPI.@)
- */
-HINF WINAPI SetupOpenMasterInf( VOID )
-{
-    static const WCHAR Layout[] = {'\\','i','n','f','\\', 'l', 'a', 'y', 'o', 'u', 't', '.', 'i', 'n', 'f', 0};
-    WCHAR Buffer[MAX_PATH];
-
-    GetWindowsDirectoryW( Buffer, MAX_PATH );
-    strcatW( Buffer, Layout );
-    return SetupOpenInfFileW( Buffer, NULL, INF_STYLE_WIN4, NULL);
-}
-
-
-
-/***********************************************************************
- *            SetupCloseInfFile   (SETUPAPI.@)
- */
-void WINAPI SetupCloseInfFile( HINF hinf )
-{
-    struct inf_file *file = hinf;
-    unsigned int i;
-
-    for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
-    HeapFree( GetProcessHeap(), 0, file->src_root );
-    HeapFree( GetProcessHeap(), 0, file->sections );
-    HeapFree( GetProcessHeap(), 0, file->fields );
-    HeapFree( GetProcessHeap(), 0, file->strings );
-    HeapFree( GetProcessHeap(), 0, file );
-}
-
-
-/***********************************************************************
- *            SetupGetLineCountA   (SETUPAPI.@)
- */
-LONG WINAPI SetupGetLineCountA( HINF hinf, PCSTR name )
-{
-    UNICODE_STRING sectionW;
-    LONG ret = -1;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, name ))
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    else
-    {
-        ret = SetupGetLineCountW( hinf, sectionW.Buffer );
-        RtlFreeUnicodeString( &sectionW );
-    }
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupGetLineCountW   (SETUPAPI.@)
- */
-LONG WINAPI SetupGetLineCountW( HINF hinf, PCWSTR section )
-{
-    struct inf_file *file = hinf;
-    int section_index;
-    LONG ret = -1;
-
-    for (file = hinf; file; file = file->next)
-    {
-        if ((section_index = find_section( file, section )) == -1) continue;
-        if (ret == -1) ret = 0;
-        ret += file->sections[section_index]->nb_lines;
-    }
-    TRACE( "(%p,%s) returning %ld\n", hinf, debugstr_w(section), ret );
-    SetLastError( (ret == -1) ? ERROR_SECTION_NOT_FOUND : 0 );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupGetLineByIndexA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetLineByIndexA( HINF hinf, PCSTR section, DWORD index, INFCONTEXT *context )
-{
-    UNICODE_STRING sectionW;
-    BOOL ret = FALSE;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    else
-    {
-        ret = SetupGetLineByIndexW( hinf, sectionW.Buffer, index, context );
-        RtlFreeUnicodeString( &sectionW );
-    }
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupGetLineByIndexW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetLineByIndexW( HINF hinf, PCWSTR section, DWORD index, INFCONTEXT *context )
-{
-    struct inf_file *file = hinf;
-    int section_index;
-
-    SetLastError( ERROR_SECTION_NOT_FOUND );
-    for (file = hinf; file; file = file->next)
-    {
-        if ((section_index = find_section( file, section )) == -1) continue;
-        SetLastError( ERROR_LINE_NOT_FOUND );
-        if (index < file->sections[section_index]->nb_lines)
-        {
-            context->Inf        = hinf;
-            context->CurrentInf = file;
-            context->Section    = section_index;
-            context->Line       = index;
-            SetLastError( 0 );
-            TRACE( "(%p,%s): returning %d/%ld\n",
-                   hinf, debugstr_w(section), section_index, index );
-            return TRUE;
-        }
-        index -= file->sections[section_index]->nb_lines;
-    }
-    TRACE( "(%p,%s) not found\n", hinf, debugstr_w(section) );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupFindFirstLineA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupFindFirstLineA( HINF hinf, PCSTR section, PCSTR key, INFCONTEXT *context )
-{
-    UNICODE_STRING sectionW, keyW;
-    BOOL ret = FALSE;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return FALSE;
-    }
-
-    if (!key) ret = SetupFindFirstLineW( hinf, sectionW.Buffer, NULL, context );
-    else
-    {
-        if (RtlCreateUnicodeStringFromAsciiz( &keyW, key ))
-        {
-            ret = SetupFindFirstLineW( hinf, sectionW.Buffer, keyW.Buffer, context );
-            RtlFreeUnicodeString( &keyW );
-        }
-        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    }
-    RtlFreeUnicodeString( &sectionW );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupFindFirstLineW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupFindFirstLineW( HINF hinf, PCWSTR section, PCWSTR key, INFCONTEXT *context )
-{
-    struct inf_file *file;
-    int section_index;
-
-    SetLastError( ERROR_SECTION_NOT_FOUND );
-    for (file = hinf; file; file = file->next)
-    {
-        if ((section_index = find_section( file, section )) == -1) continue;
-        if (key)
-        {
-            INFCONTEXT ctx;
-            ctx.Inf        = hinf;
-            ctx.CurrentInf = file;
-            ctx.Section    = section_index;
-            ctx.Line       = -1;
-            return SetupFindNextMatchLineW( &ctx, key, context );
-        }
-        SetLastError( ERROR_LINE_NOT_FOUND );  /* found at least one section */
-        if (file->sections[section_index]->nb_lines)
-        {
-            context->Inf        = hinf;
-            context->CurrentInf = file;
-            context->Section    = section_index;
-            context->Line       = 0;
-            SetLastError( 0 );
-            TRACE( "(%p,%s,%s): returning %d/0\n",
-                   hinf, debugstr_w(section), debugstr_w(key), section_index );
-            return TRUE;
-        }
-    }
-    TRACE( "(%p,%s,%s): not found\n", hinf, debugstr_w(section), debugstr_w(key) );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupFindNextLine   (SETUPAPI.@)
- */
-BOOL WINAPI SetupFindNextLine( PINFCONTEXT context_in, PINFCONTEXT context_out )
-{
-    struct inf_file *file = context_in->CurrentInf;
-    struct section *section;
-
-    if (context_in->Section >= file->nb_sections) goto error;
-
-    section = file->sections[context_in->Section];
-    if (context_in->Line+1 < section->nb_lines)
-    {
-        if (context_out != context_in) *context_out = *context_in;
-        context_out->Line++;
-        SetLastError( 0 );
-        return TRUE;
-    }
-
-    /* now search the appended files */
-
-    for (file = file->next; file; file = file->next)
-    {
-        int section_index = find_section( file, section->name );
-        if (section_index == -1) continue;
-        if (file->sections[section_index]->nb_lines)
-        {
-            context_out->Inf        = context_in->Inf;
-            context_out->CurrentInf = file;
-            context_out->Section    = section_index;
-            context_out->Line       = 0;
-            SetLastError( 0 );
-            return TRUE;
-        }
-    }
- error:
-    SetLastError( ERROR_LINE_NOT_FOUND );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupFindNextMatchLineA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupFindNextMatchLineA( PINFCONTEXT context_in, PCSTR key,
-                                     PINFCONTEXT context_out )
-{
-    UNICODE_STRING keyW;
-    BOOL ret = FALSE;
-
-    if (!key) return SetupFindNextLine( context_in, context_out );
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &keyW, key ))
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    else
-    {
-        ret = SetupFindNextMatchLineW( context_in, keyW.Buffer, context_out );
-        RtlFreeUnicodeString( &keyW );
-    }
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupFindNextMatchLineW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupFindNextMatchLineW( PINFCONTEXT context_in, PCWSTR key,
-                                     PINFCONTEXT context_out )
-{
-    struct inf_file *file = context_in->CurrentInf;
-    struct section *section;
-    struct line *line;
-    unsigned int i;
-
-    if (!key) return SetupFindNextLine( context_in, context_out );
-
-    if (context_in->Section >= file->nb_sections) goto error;
-
-    section = file->sections[context_in->Section];
-
-    for (i = context_in->Line+1, line = &section->lines[i]; i < section->nb_lines; i++, line++)
-    {
-        if (line->key_field == -1) continue;
-        if (!strcmpiW( key, file->fields[line->key_field].text ))
-        {
-            if (context_out != context_in) *context_out = *context_in;
-            context_out->Line = i;
-            SetLastError( 0 );
-            TRACE( "(%p,%s,%s): returning %d\n",
-                   file, debugstr_w(section->name), debugstr_w(key), i );
-            return TRUE;
-        }
-    }
-
-    /* now search the appended files */
-
-    for (file = file->next; file; file = file->next)
-    {
-        int section_index = find_section( file, section->name );
-        if (section_index == -1) continue;
-        section = file->sections[section_index];
-        for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
-        {
-            if (line->key_field == -1) continue;
-            if (!strcmpiW( key, file->fields[line->key_field].text ))
-            {
-                context_out->Inf        = context_in->Inf;
-                context_out->CurrentInf = file;
-                context_out->Section    = section_index;
-                context_out->Line       = i;
-                SetLastError( 0 );
-                TRACE( "(%p,%s,%s): returning %d/%d\n",
-                       file, debugstr_w(section->name), debugstr_w(key), section_index, i );
-                return TRUE;
-            }
-        }
-    }
-    TRACE( "(%p,%s,%s): not found\n",
-           context_in->CurrentInf, debugstr_w(section->name), debugstr_w(key) );
- error:
-    SetLastError( ERROR_LINE_NOT_FOUND );
-    return FALSE;
-}
-
-
-/***********************************************************************
- *             SetupGetLineTextW    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetLineTextW( PINFCONTEXT context, HINF hinf, PCWSTR section_name,
-                               PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required )
-{
-    struct inf_file *file;
-    struct line *line;
-    struct field *field;
-    int i;
-    DWORD total = 0;
-
-    if (!context)
-    {
-        INFCONTEXT new_context;
-        if (!SetupFindFirstLineW( hinf, section_name, key_name, &new_context )) return FALSE;
-        file = new_context.CurrentInf;
-        line = get_line( file, new_context.Section, new_context.Line );
-    }
-    else
-    {
-        file = context->CurrentInf;
-        if (!(line = get_line( file, context->Section, context->Line )))
-        {
-            SetLastError( ERROR_LINE_NOT_FOUND );
-            return FALSE;
-        }
-    }
-
-    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
-        total += PARSER_string_substW( file, field->text, NULL, 0 ) + 1;
-
-    if (required) *required = total;
-    if (buffer)
-    {
-        if (total > size)
-        {
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
-        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
-        {
-            unsigned int len = PARSER_string_substW( file, field->text, buffer, size );
-            if (i+1 < line->nb_fields) buffer[len] = ',';
-            buffer += len + 1;
-        }
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetLineTextA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetLineTextA( PINFCONTEXT context, HINF hinf, PCSTR section_name,
-                               PCSTR key_name, PSTR buffer, DWORD size, PDWORD required )
-{
-    struct inf_file *file;
-    struct line *line;
-    struct field *field;
-    int i;
-    DWORD total = 0;
-
-    if (!context)
-    {
-        INFCONTEXT new_context;
-        if (!SetupFindFirstLineA( hinf, section_name, key_name, &new_context )) return FALSE;
-        file = new_context.CurrentInf;
-        line = get_line( file, new_context.Section, new_context.Line );
-    }
-    else
-    {
-        file = context->CurrentInf;
-        if (!(line = get_line( file, context->Section, context->Line )))
-        {
-            SetLastError( ERROR_LINE_NOT_FOUND );
-            return FALSE;
-        }
-    }
-
-    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
-        total += PARSER_string_substA( file, field->text, NULL, 0 ) + 1;
-
-    if (required) *required = total;
-    if (buffer)
-    {
-        if (total > size)
-        {
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
-        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
-        {
-            unsigned int len = PARSER_string_substA( file, field->text, buffer, size );
-            if (i+1 < line->nb_fields) buffer[len] = ',';
-            buffer += len + 1;
-        }
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetFieldCount    (SETUPAPI.@)
- */
-DWORD WINAPI SetupGetFieldCount( PINFCONTEXT context )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct line *line = get_line( file, context->Section, context->Line );
-
-    if (!line) return 0;
-    return line->nb_fields;
-}
-
-
-/***********************************************************************
- *             SetupGetStringFieldA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetStringFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,
-                                  DWORD size, PDWORD required )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct field *field = get_field( file, context->Section, context->Line, index );
-    unsigned int len;
-
-    SetLastError(0);
-    if (!field) return FALSE;
-    len = PARSER_string_substA( file, field->text, NULL, 0 );
-    if (required) *required = len + 1;
-    if (buffer)
-    {
-        if (size <= len)
-        {
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
-        PARSER_string_substA( file, field->text, buffer, size );
-
-        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",
-               context->Inf, context->CurrentInf, context->Section, context->Line,
-               index, debugstr_a(buffer) );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetStringFieldW    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetStringFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,
-                                  DWORD size, PDWORD required )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct field *field = get_field( file, context->Section, context->Line, index );
-    unsigned int len;
-
-    SetLastError(0);
-    if (!field) return FALSE;
-    len = PARSER_string_substW( file, field->text, NULL, 0 );
-    if (required) *required = len + 1;
-    if (buffer)
-    {
-        if (size <= len)
-        {
-            SetLastError( ERROR_INSUFFICIENT_BUFFER );
-            return FALSE;
-        }
-        PARSER_string_substW( file, field->text, buffer, size );
-
-        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",
-               context->Inf, context->CurrentInf, context->Section, context->Line,
-               index, debugstr_w(buffer) );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetIntField    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetIntField( PINFCONTEXT context, DWORD index, PINT result )
-{
-    char localbuff[20];
-    char *end, *buffer = localbuff;
-    DWORD required;
-    INT res;
-    BOOL ret = FALSE;
-
-    if (!SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required ))
-    {
-        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE;
-        if (!SetupGetStringFieldA( context, index, buffer, required, NULL )) goto done;
-    }
-    res = strtol( buffer, &end, 0 );
-    if (end != buffer && !*end)
-    {
-        *result = res;
-        ret = TRUE;
-    }
-    else SetLastError( ERROR_INVALID_DATA );
-
- done:
-    if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer );
-    return ret;
-}
-
-
-/***********************************************************************
- *             SetupGetBinaryField    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetBinaryField( PINFCONTEXT context, DWORD index, BYTE *buffer,
-                                 DWORD size, LPDWORD required )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct line *line = get_line( file, context->Section, context->Line );
-    struct field *field;
-    int i;
-
-    if (!line)
-    {
-        SetLastError( ERROR_LINE_NOT_FOUND );
-        return FALSE;
-    }
-    if (!index || index >= line->nb_fields)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-    index--;  /* fields start at 0 */
-    if (required) *required = line->nb_fields - index;
-    if (!buffer) return TRUE;
-    if (size < line->nb_fields - index)
-    {
-        SetLastError( ERROR_INSUFFICIENT_BUFFER );
-        return FALSE;
-    }
-    field = &file->fields[line->first_field + index];
-    for (i = index; i < line->nb_fields; i++, field++)
-    {
-        const WCHAR *p;
-        DWORD value = 0;
-        for (p = field->text; *p && isxdigitW(*p); p++)
-        {
-            if ((value <<= 4) > 255)
-            {
-                SetLastError( ERROR_INVALID_DATA );
-                return FALSE;
-            }
-            if (*p <= '9') value |= (*p - '0');
-            else value |= (tolowerW(*p) - 'a' + 10);
-        }
-        buffer[i - index] = value;
-    }
-    if (TRACE_ON(setupapi))
-    {
-        TRACE( "%p/%p/%d/%d index %ld returning",
-               context->Inf, context->CurrentInf, context->Section, context->Line, index );
-        for (i = index; i < line->nb_fields; i++) TRACE( " %02x", buffer[i - index] );
-        TRACE( "\n" );
-    }
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetMultiSzFieldA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetMultiSzFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,
-                                   DWORD size, LPDWORD required )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct line *line = get_line( file, context->Section, context->Line );
-    struct field *field;
-    unsigned int len;
-    int i;
-    DWORD total = 1;
-
-    if (!line)
-    {
-        SetLastError( ERROR_LINE_NOT_FOUND );
-        return FALSE;
-    }
-    if (!index || index >= line->nb_fields)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-    index--;  /* fields start at 0 */
-    field = &file->fields[line->first_field + index];
-    for (i = index; i < line->nb_fields; i++, field++)
-    {
-        if (!(len = PARSER_string_substA( file, field->text, NULL, 0 ))) break;
-        total += len + 1;
-    }
-
-    if (required) *required = total;
-    if (!buffer) return TRUE;
-    if (total > size)
-    {
-        SetLastError( ERROR_INSUFFICIENT_BUFFER );
-        return FALSE;
-    }
-    field = &file->fields[line->first_field + index];
-    for (i = index; i < line->nb_fields; i++, field++)
-    {
-        if (!(len = PARSER_string_substA( file, field->text, buffer, size ))) break;
-        buffer += len + 1;
-    }
-    *buffer = 0;  /* add final null */
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             SetupGetMultiSzFieldW    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetMultiSzFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,
-                                   DWORD size, LPDWORD required )
-{
-    struct inf_file *file = context->CurrentInf;
-    struct line *line = get_line( file, context->Section, context->Line );
-    struct field *field;
-    unsigned int len;
-    int i;
-    DWORD total = 1;
-
-    if (!line)
-    {
-        SetLastError( ERROR_LINE_NOT_FOUND );
-        return FALSE;
-    }
-    if (!index || index >= line->nb_fields)
-    {
-        SetLastError( ERROR_INVALID_PARAMETER );
-        return FALSE;
-    }
-    index--;  /* fields start at 0 */
-    field = &file->fields[line->first_field + index];
-    for (i = index; i < line->nb_fields; i++, field++)
-    {
-        if (!(len = PARSER_string_substW( file, field->text, NULL, 0 ))) break;
-        total += len + 1;
-    }
-
-    if (required) *required = total;
-    if (!buffer) return TRUE;
-    if (total > size)
-    {
-        SetLastError( ERROR_INSUFFICIENT_BUFFER );
-        return FALSE;
-    }
-    field = &file->fields[line->first_field + index];
-    for (i = index; i < line->nb_fields; i++, field++)
-    {
-        if (!(len = PARSER_string_substW( file, field->text, buffer, size ))) break;
-        buffer += len + 1;
-    }
-    *buffer = 0;  /* add final null */
-    return TRUE;
-}
+/*\r
+ * INF file parsing\r
+ *\r
+ * Copyright 2002 Alexandre Julliard for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include "config.h"\r
+#include "wine/port.h"\r
+\r
+#include <assert.h>\r
+#include <limits.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "winerror.h"\r
+#include "setupapi.h"\r
+#include "setupapi_private.h"\r
+\r
+#include "wine/unicode.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+#define CONTROL_Z  '\x1a'\r
+#define MAX_SECTION_NAME_LEN  255\r
+#define MAX_FIELD_LEN         511  /* larger fields get silently truncated */\r
+/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */\r
+#define MAX_STRING_LEN        (MAX_INF_STRING_LENGTH+1)\r
+\r
+/* inf file structure definitions */\r
+\r
+struct field\r
+{\r
+    const WCHAR *text;         /* field text */\r
+};\r
+\r
+struct line\r
+{\r
+    int first_field;           /* index of first field in field array */\r
+    int nb_fields;             /* number of fields in line */\r
+    int key_field;             /* index of field for key or -1 if no key */\r
+};\r
+\r
+struct section\r
+{\r
+    const WCHAR *name;         /* section name */\r
+    unsigned int nb_lines;     /* number of used lines */\r
+    unsigned int alloc_lines;  /* total number of allocated lines in array below */\r
+    struct line  lines[16];    /* lines information (grown dynamically, 16 is initial size) */\r
+};\r
+\r
+struct inf_file\r
+{\r
+    struct inf_file *next;            /* next appended file */\r
+    WCHAR           *strings;         /* buffer for string data (section names and field values) */\r
+    WCHAR           *string_pos;      /* position of next available string in buffer */\r
+    unsigned int     nb_sections;     /* number of used sections */\r
+    unsigned int     alloc_sections;  /* total number of allocated section pointers */\r
+    struct section **sections;        /* section pointers array */\r
+    unsigned int     nb_fields;\r
+    unsigned int     alloc_fields;\r
+    struct field    *fields;\r
+    int              strings_section; /* index of [Strings] section or -1 if none */\r
+    WCHAR           *src_root;        /* source root directory */\r
+};\r
+\r
+/* parser definitions */\r
+\r
+enum parser_state\r
+{\r
+    LINE_START,      /* at beginning of a line */\r
+    SECTION_NAME,    /* parsing a section name */\r
+    KEY_NAME,        /* parsing a key name */\r
+    VALUE_NAME,      /* parsing a value name */\r
+    EOL_BACKSLASH,   /* backslash at end of line */\r
+    QUOTES,          /* inside quotes */\r
+    LEADING_SPACES,  /* leading spaces */\r
+    TRAILING_SPACES, /* trailing spaces */\r
+    COMMENT,         /* inside a comment */\r
+    NB_PARSER_STATES\r
+};\r
+\r
+struct parser\r
+{\r
+    const WCHAR      *start;        /* start position of item being parsed */\r
+    const WCHAR      *end;          /* end of buffer */\r
+    struct inf_file  *file;         /* file being built */\r
+    enum parser_state state;        /* current parser state */\r
+    enum parser_state stack[4];     /* state stack */\r
+    int               stack_pos;    /* current pos in stack */\r
+\r
+    int               cur_section;  /* index of section being parsed*/\r
+    struct line      *line;         /* current line */\r
+    unsigned int      line_pos;     /* current line position in file */\r
+    unsigned int      error;        /* error code */\r
+    unsigned int      token_len;    /* current token len */\r
+    WCHAR token[MAX_FIELD_LEN+1];   /* current token */\r
+};\r
+\r
+typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );\r
+\r
+/* parser state machine functions */\r
+static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );\r
+static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos );\r
+\r
+static const parser_state_func parser_funcs[NB_PARSER_STATES] =\r
+{\r
+    line_start_state,      /* LINE_START */\r
+    section_name_state,    /* SECTION_NAME */\r
+    key_name_state,        /* KEY_NAME */\r
+    value_name_state,      /* VALUE_NAME */\r
+    eol_backslash_state,   /* EOL_BACKSLASH */\r
+    quotes_state,          /* QUOTES */\r
+    leading_spaces_state,  /* LEADING_SPACES */\r
+    trailing_spaces_state, /* TRAILING_SPACES */\r
+    comment_state          /* COMMENT */\r
+};\r
+\r
+\r
+/* Unicode string constants */\r
+static const WCHAR Version[]    = {'V','e','r','s','i','o','n',0};\r
+static const WCHAR Signature[]  = {'S','i','g','n','a','t','u','r','e',0};\r
+static const WCHAR Chicago[]    = {'$','C','h','i','c','a','g','o','$',0};\r
+static const WCHAR WindowsNT[]  = {'$','W','i','n','d','o','w','s',' ','N','T','$',0};\r
+static const WCHAR Windows95[]  = {'$','W','i','n','d','o','w','s',' ','9','5','$',0};\r
+static const WCHAR LayoutFile[] = {'L','a','y','o','u','t','F','i','l','e',0};\r
+\r
+/* extend an array, allocating more memory if necessary */\r
+static void *grow_array( void *array, unsigned int *count, size_t elem )\r
+{\r
+    void *new_array;\r
+    unsigned int new_count = *count + *count / 2;\r
+    if (new_count < 32) new_count = 32;\r
+\r
+    if (array)\r
+       new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );\r
+    else\r
+       new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );\r
+\r
+    if (new_array)\r
+        *count = new_count;\r
+    else\r
+        HeapFree( GetProcessHeap(), 0, array );\r
+    return new_array;\r
+}\r
+\r
+\r
+/* find a section by name */\r
+static int find_section( struct inf_file *file, const WCHAR *name )\r
+{\r
+    unsigned int i;\r
+\r
+    for (i = 0; i < file->nb_sections; i++)\r
+        if (!strcmpiW( name, file->sections[i]->name )) return i;\r
+    return -1;\r
+}\r
+\r
+\r
+/* find a line by name */\r
+static struct line *find_line( struct inf_file *file, int section_index, const WCHAR *name )\r
+{\r
+    struct section *section;\r
+    struct line *line;\r
+    int i;\r
+\r
+    if (section_index < 0 || section_index >= file->nb_sections) return NULL;\r
+    section = file->sections[section_index];\r
+    for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)\r
+    {\r
+        if (line->key_field == -1) continue;\r
+        if (!strcmpiW( name, file->fields[line->key_field].text )) return line;\r
+    }\r
+    return NULL;\r
+}\r
+\r
+\r
+/* add a section to the file and return the section index */\r
+static int add_section( struct inf_file *file, const WCHAR *name )\r
+{\r
+    struct section *section;\r
+\r
+    if (file->nb_sections >= file->alloc_sections)\r
+    {\r
+        if (!(file->sections = grow_array( file->sections, &file->alloc_sections,\r
+                                           sizeof(file->sections[0]) ))) return -1;\r
+    }\r
+    if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) ))) return -1;\r
+    section->name        = name;\r
+    section->nb_lines    = 0;\r
+    section->alloc_lines = sizeof(section->lines)/sizeof(section->lines[0]);\r
+    file->sections[file->nb_sections] = section;\r
+    return file->nb_sections++;\r
+}\r
+\r
+\r
+/* add a line to a given section */\r
+static struct line *add_line( struct inf_file *file, int section_index )\r
+{\r
+    struct section *section;\r
+    struct line *line;\r
+\r
+    assert( section_index >= 0 && section_index < file->nb_sections );\r
+\r
+    section = file->sections[section_index];\r
+    if (section->nb_lines == section->alloc_lines)  /* need to grow the section */\r
+    {\r
+        int size = sizeof(*section) - sizeof(section->lines) + 2*section->alloc_lines*sizeof(*line);\r
+        if (!(section = HeapReAlloc( GetProcessHeap(), 0, section, size ))) return NULL;\r
+        section->alloc_lines *= 2;\r
+        file->sections[section_index] = section;\r
+    }\r
+    line = &section->lines[section->nb_lines++];\r
+    line->first_field = file->nb_fields;\r
+    line->nb_fields   = 0;\r
+    line->key_field   = -1;\r
+    return line;\r
+}\r
+\r
+\r
+/* retrieve a given line from section/line index */\r
+inline static struct line *get_line( struct inf_file *file, unsigned int section_index,\r
+                                     unsigned int line_index )\r
+{\r
+    struct section *section;\r
+\r
+    if (section_index >= file->nb_sections) return NULL;\r
+    section = file->sections[section_index];\r
+    if (line_index >= section->nb_lines) return NULL;\r
+    return &section->lines[line_index];\r
+}\r
+\r
+\r
+/* retrieve a given field from section/line/field index */\r
+static struct field *get_field( struct inf_file *file, int section_index, int line_index,\r
+                                int field_index )\r
+{\r
+    struct line *line = get_line( file, section_index, line_index );\r
+\r
+    if (!line) return NULL;\r
+    if (!field_index)  /* get the key */\r
+    {\r
+        if (line->key_field == -1) return NULL;\r
+        return &file->fields[line->key_field];\r
+    }\r
+    field_index--;\r
+    if (field_index >= line->nb_fields) return NULL;\r
+    return &file->fields[line->first_field + field_index];\r
+}\r
+\r
+\r
+/* allocate a new field, growing the array if necessary */\r
+static struct field *add_field( struct inf_file *file, const WCHAR *text )\r
+{\r
+    struct field *field;\r
+\r
+    if (file->nb_fields >= file->alloc_fields)\r
+    {\r
+        if (!(file->fields = grow_array( file->fields, &file->alloc_fields,\r
+                                         sizeof(file->fields[0]) ))) return NULL;\r
+    }\r
+    field = &file->fields[file->nb_fields++];\r
+    field->text = text;\r
+    return field;\r
+}\r
+\r
+\r
+/* retrieve the string substitution for a directory id */\r
+static const WCHAR *get_dirid_subst( int dirid, unsigned int *len )\r
+{\r
+    extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );\r
+    const WCHAR *ret = DIRID_get_string( 0, dirid );\r
+    if (ret) *len = strlenW(ret);\r
+    return ret;\r
+}\r
+\r
+\r
+/* retrieve the string substitution for a given string, or NULL if not found */\r
+/* if found, len is set to the substitution length */\r
+static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, unsigned int *len )\r
+{\r
+    static const WCHAR percent = '%';\r
+\r
+    struct section *strings_section;\r
+    struct line *line;\r
+    struct field *field;\r
+    unsigned int i;\r
+    int dirid;\r
+    WCHAR *dirid_str, *end;\r
+    const WCHAR *ret = NULL;\r
+\r
+    if (!*len)  /* empty string (%%) is replaced by single percent */\r
+    {\r
+        *len = 1;\r
+        return &percent;\r
+    }\r
+    if (file->strings_section == -1) goto not_found;\r
+    strings_section = file->sections[file->strings_section];\r
+    for (i = 0, line = strings_section->lines; i < strings_section->nb_lines; i++, line++)\r
+    {\r
+        if (line->key_field == -1) continue;\r
+        if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue;\r
+        if (!file->fields[line->key_field].text[*len]) break;\r
+    }\r
+    if (i == strings_section->nb_lines || !line->nb_fields) goto not_found;\r
+    field = &file->fields[line->first_field];\r
+    *len = strlenW( field->text );\r
+    return field->text;\r
+\r
+ not_found:  /* check for integer id */\r
+    if ((dirid_str = HeapAlloc( GetProcessHeap(), 0, (*len+1) * sizeof(WCHAR) )))\r
+    {\r
+        memcpy( dirid_str, str, *len * sizeof(WCHAR) );\r
+        dirid_str[*len] = 0;\r
+        dirid = strtolW( dirid_str, &end, 10 );\r
+        if (!*end) ret = get_dirid_subst( dirid, len );\r
+        HeapFree( GetProcessHeap(), 0, dirid_str );\r
+        return ret;\r
+    }\r
+    return NULL;\r
+}\r
+\r
+\r
+/* do string substitutions on the specified text */\r
+/* the buffer is assumed to be large enough */\r
+/* returns necessary length not including terminating null */\r
+unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCHAR *buffer,\r
+                                   unsigned int size )\r
+{\r
+    const WCHAR *start, *subst, *p;\r
+    unsigned int len, total = 0;\r
+    int inside = 0;\r
+\r
+    if (!buffer) size = MAX_STRING_LEN + 1;\r
+    for (p = start = text; *p; p++)\r
+    {\r
+        if (*p != '%') continue;\r
+        inside = !inside;\r
+        if (inside)  /* start of a %xx% string */\r
+        {\r
+            len = p - start;\r
+            if (len > size - 1) len = size - 1;\r
+            if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );\r
+            total += len;\r
+            size -= len;\r
+            start = p;\r
+        }\r
+        else /* end of the %xx% string, find substitution */\r
+        {\r
+            len = p - start - 1;\r
+            subst = get_string_subst( file, start + 1, &len );\r
+            if (!subst)\r
+            {\r
+                subst = start;\r
+                len = p - start + 1;\r
+            }\r
+            if (len > size - 1) len = size - 1;\r
+            if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );\r
+            total += len;\r
+            size -= len;\r
+            start = p + 1;\r
+        }\r
+    }\r
+\r
+    if (start != p) /* unfinished string, copy it */\r
+    {\r
+        len = p - start;\r
+        if (len > size - 1) len = size - 1;\r
+        if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );\r
+        total += len;\r
+    }\r
+    if (buffer && size) buffer[total] = 0;\r
+    return total;\r
+}\r
+\r
+\r
+/* do string substitutions on the specified text */\r
+/* the buffer is assumed to be large enough */\r
+/* returns necessary length not including terminating null */\r
+unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text, char *buffer,\r
+                                   unsigned int size )\r
+{\r
+    WCHAR buffW[MAX_STRING_LEN+1];\r
+    DWORD ret;\r
+\r
+    unsigned int len = PARSER_string_substW( file, text, buffW, sizeof(buffW)/sizeof(WCHAR) );\r
+    if (!buffer) RtlUnicodeToMultiByteSize( &ret, buffW, len * sizeof(WCHAR) );\r
+    else\r
+    {\r
+        RtlUnicodeToMultiByteN( buffer, size-1, &ret, buffW, len * sizeof(WCHAR) );\r
+        buffer[ret] = 0;\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/* push some string data into the strings buffer */\r
+static WCHAR *push_string( struct inf_file *file, const WCHAR *string )\r
+{\r
+    WCHAR *ret = file->string_pos;\r
+    strcpyW( ret, string );\r
+    file->string_pos += strlenW( ret ) + 1;\r
+    return ret;\r
+}\r
+\r
+\r
+/* push the current state on the parser stack */\r
+inline static void push_state( struct parser *parser, enum parser_state state )\r
+{\r
+    assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) );\r
+    parser->stack[parser->stack_pos++] = state;\r
+}\r
+\r
+\r
+/* pop the current state */\r
+inline static void pop_state( struct parser *parser )\r
+{\r
+    assert( parser->stack_pos );\r
+    parser->state = parser->stack[--parser->stack_pos];\r
+}\r
+\r
+\r
+/* set the parser state and return the previous one */\r
+inline static enum parser_state set_state( struct parser *parser, enum parser_state state )\r
+{\r
+    enum parser_state ret = parser->state;\r
+    parser->state = state;\r
+    return ret;\r
+}\r
+\r
+\r
+/* check if the pointer points to an end of file */\r
+inline static int is_eof( struct parser *parser, const WCHAR *ptr )\r
+{\r
+    return (ptr >= parser->end || *ptr == CONTROL_Z);\r
+}\r
+\r
+\r
+/* check if the pointer points to an end of line */\r
+inline static int is_eol( struct parser *parser, const WCHAR *ptr )\r
+{\r
+    return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\n');\r
+}\r
+\r
+\r
+/* push data from current token start up to pos into the current token */\r
+static int push_token( struct parser *parser, const WCHAR *pos )\r
+{\r
+    int len = pos - parser->start;\r
+    const WCHAR *src = parser->start;\r
+    WCHAR *dst = parser->token + parser->token_len;\r
+\r
+    if (len > MAX_FIELD_LEN - parser->token_len) len = MAX_FIELD_LEN - parser->token_len;\r
+\r
+    parser->token_len += len;\r
+    for ( ; len > 0; len--, dst++, src++) *dst = *src ? *src : ' ';\r
+    *dst = 0;\r
+    parser->start = pos;\r
+    return 0;\r
+}\r
+\r
+\r
+/* add a section with the current token as name */\r
+static int add_section_from_token( struct parser *parser )\r
+{\r
+    int section_index;\r
+\r
+    if (parser->token_len > MAX_SECTION_NAME_LEN)\r
+    {\r
+        parser->error = ERROR_SECTION_NAME_TOO_LONG;\r
+        return -1;\r
+    }\r
+    if ((section_index = find_section( parser->file, parser->token )) == -1)\r
+    {\r
+        /* need to create a new one */\r
+        const WCHAR *name = push_string( parser->file, parser->token );\r
+        if ((section_index = add_section( parser->file, name )) == -1)\r
+        {\r
+            parser->error = ERROR_NOT_ENOUGH_MEMORY;\r
+            return -1;\r
+        }\r
+    }\r
+    parser->token_len = 0;\r
+    parser->cur_section = section_index;\r
+    return section_index;\r
+}\r
+\r
+\r
+/* add a field containing the current token to the current line */\r
+static struct field *add_field_from_token( struct parser *parser, int is_key )\r
+{\r
+    struct field *field;\r
+    WCHAR *text;\r
+\r
+    if (!parser->line)  /* need to start a new line */\r
+    {\r
+        if (parser->cur_section == -1)  /* got a line before the first section */\r
+        {\r
+            parser->error = ERROR_WRONG_INF_STYLE;\r
+            return NULL;\r
+        }\r
+        if (!(parser->line = add_line( parser->file, parser->cur_section ))) goto error;\r
+    }\r
+    else assert(!is_key);\r
+\r
+    text = push_string( parser->file, parser->token );\r
+    if ((field = add_field( parser->file, text )))\r
+    {\r
+        if (!is_key) parser->line->nb_fields++;\r
+        else\r
+        {\r
+            /* replace first field by key field */\r
+            parser->line->key_field = parser->line->first_field;\r
+            parser->line->first_field++;\r
+        }\r
+        parser->token_len = 0;\r
+        return field;\r
+    }\r
+ error:\r
+    parser->error = ERROR_NOT_ENOUGH_MEMORY;\r
+    return NULL;\r
+}\r
+\r
+\r
+/* close the current line and prepare for parsing a new one */\r
+static void close_current_line( struct parser *parser )\r
+{\r
+    struct line *cur_line = parser->line;\r
+\r
+    if (cur_line)\r
+    {\r
+        /* if line has a single field and no key, the field is the key too */\r
+        if (cur_line->nb_fields == 1 && cur_line->key_field == -1)\r
+            cur_line->key_field = cur_line->first_field;\r
+    }\r
+    parser->line = NULL;\r
+}\r
+\r
+\r
+/* handler for parser LINE_START state */\r
+static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p;\r
+\r
+    for (p = pos; !is_eof( parser, p ); p++)\r
+    {\r
+        switch(*p)\r
+        {\r
+        case '\n':\r
+            parser->line_pos++;\r
+            close_current_line( parser );\r
+            break;\r
+        case ';':\r
+            push_state( parser, LINE_START );\r
+            set_state( parser, COMMENT );\r
+            return p + 1;\r
+        case '[':\r
+            parser->start = p + 1;\r
+            set_state( parser, SECTION_NAME );\r
+            return p + 1;\r
+        default:\r
+            if (!isspaceW(*p))\r
+            {\r
+                parser->start = p;\r
+                set_state( parser, KEY_NAME );\r
+                return p;\r
+            }\r
+            break;\r
+        }\r
+    }\r
+    close_current_line( parser );\r
+    return NULL;\r
+}\r
+\r
+\r
+/* handler for parser SECTION_NAME state */\r
+static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        if (*p == ']')\r
+        {\r
+            push_token( parser, p );\r
+            if (add_section_from_token( parser ) == -1) return NULL;\r
+            push_state( parser, LINE_START );\r
+            set_state( parser, COMMENT );  /* ignore everything else on the line */\r
+            return p + 1;\r
+        }\r
+    }\r
+    parser->error = ERROR_BAD_SECTION_NAME_LINE; /* unfinished section name */\r
+    return NULL;\r
+}\r
+\r
+\r
+/* handler for parser KEY_NAME state */\r
+static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p, *token_end = parser->start;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        if (*p == ',') break;\r
+        switch(*p)\r
+        {\r
+\r
+         case '=':\r
+            push_token( parser, token_end );\r
+            if (!add_field_from_token( parser, 1 )) return NULL;\r
+            parser->start = p + 1;\r
+            push_state( parser, VALUE_NAME );\r
+            set_state( parser, LEADING_SPACES );\r
+            return p + 1;\r
+        case ';':\r
+            push_token( parser, token_end );\r
+            if (!add_field_from_token( parser, 0 )) return NULL;\r
+            push_state( parser, LINE_START );\r
+            set_state( parser, COMMENT );\r
+            return p + 1;\r
+        case '"':\r
+            push_token( parser, token_end );\r
+            parser->start = p + 1;\r
+            push_state( parser, KEY_NAME );\r
+            set_state( parser, QUOTES );\r
+            return p + 1;\r
+        case '\\':\r
+            push_token( parser, token_end );\r
+            parser->start = p;\r
+            push_state( parser, KEY_NAME );\r
+            set_state( parser, EOL_BACKSLASH );\r
+            return p;\r
+        default:\r
+            if (!isspaceW(*p)) token_end = p + 1;\r
+            else\r
+            {\r
+                push_token( parser, p );\r
+                push_state( parser, KEY_NAME );\r
+                set_state( parser, TRAILING_SPACES );\r
+                return p;\r
+            }\r
+            break;\r
+        }\r
+    }\r
+    push_token( parser, token_end );\r
+    set_state( parser, VALUE_NAME );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser VALUE_NAME state */\r
+static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p, *token_end = parser->start;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        switch(*p)\r
+        {\r
+        case ';':\r
+            push_token( parser, token_end );\r
+            if (!add_field_from_token( parser, 0 )) return NULL;\r
+            push_state( parser, LINE_START );\r
+            set_state( parser, COMMENT );\r
+            return p + 1;\r
+        case ',':\r
+            push_token( parser, token_end );\r
+            if (!add_field_from_token( parser, 0 )) return NULL;\r
+            parser->start = p + 1;\r
+            push_state( parser, VALUE_NAME );\r
+            set_state( parser, LEADING_SPACES );\r
+            return p + 1;\r
+        case '"':\r
+            push_token( parser, token_end );\r
+            parser->start = p + 1;\r
+            push_state( parser, VALUE_NAME );\r
+            set_state( parser, QUOTES );\r
+            return p + 1;\r
+        case '\\':\r
+            push_token( parser, token_end );\r
+            parser->start = p;\r
+            push_state( parser, VALUE_NAME );\r
+            set_state( parser, EOL_BACKSLASH );\r
+            return p;\r
+        default:\r
+            if (!isspaceW(*p)) token_end = p + 1;\r
+            else\r
+            {\r
+                push_token( parser, p );\r
+                push_state( parser, VALUE_NAME );\r
+                set_state( parser, TRAILING_SPACES );\r
+                return p;\r
+            }\r
+            break;\r
+        }\r
+    }\r
+    push_token( parser, token_end );\r
+    if (!add_field_from_token( parser, 0 )) return NULL;\r
+    set_state( parser, LINE_START );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser EOL_BACKSLASH state */\r
+static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p;\r
+\r
+    for (p = pos; !is_eof( parser, p ); p++)\r
+    {\r
+        switch(*p)\r
+        {\r
+        case '\n':\r
+            parser->line_pos++;\r
+            parser->start = p + 1;\r
+            set_state( parser, LEADING_SPACES );\r
+            return p + 1;\r
+        case '\\':\r
+            continue;\r
+        case ';':\r
+            push_state( parser, EOL_BACKSLASH );\r
+            set_state( parser, COMMENT );\r
+            return p + 1;\r
+        default:\r
+            if (isspaceW(*p)) continue;\r
+            push_token( parser, p );\r
+            pop_state( parser );\r
+            return p;\r
+        }\r
+    }\r
+    parser->start = p;\r
+    pop_state( parser );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser QUOTES state */\r
+static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p, *token_end = parser->start;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        if (*p == '"')\r
+        {\r
+            if (p+1 < parser->end && p[1] == '"')  /* double quotes */\r
+            {\r
+                push_token( parser, p + 1 );\r
+                parser->start = token_end = p + 2;\r
+                p++;\r
+            }\r
+            else  /* end of quotes */\r
+            {\r
+                push_token( parser, p );\r
+                parser->start = p + 1;\r
+                pop_state( parser );\r
+                return p + 1;\r
+            }\r
+        }\r
+    }\r
+    push_token( parser, p );\r
+    pop_state( parser );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser LEADING_SPACES state */\r
+static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        if (*p == '\\')\r
+        {\r
+            parser->start = p;\r
+            set_state( parser, EOL_BACKSLASH );\r
+            return p;\r
+        }\r
+        if (!isspaceW(*p)) break;\r
+    }\r
+    parser->start = p;\r
+    pop_state( parser );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser TRAILING_SPACES state */\r
+static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p;\r
+\r
+    for (p = pos; !is_eol( parser, p ); p++)\r
+    {\r
+        if (*p == '\\')\r
+        {\r
+            set_state( parser, EOL_BACKSLASH );\r
+            return p;\r
+        }\r
+        if (!isspaceW(*p)) break;\r
+    }\r
+    pop_state( parser );\r
+    return p;\r
+}\r
+\r
+\r
+/* handler for parser COMMENT state */\r
+static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )\r
+{\r
+    const WCHAR *p = pos;\r
+\r
+    while (!is_eol( parser, p )) p++;\r
+    pop_state( parser );\r
+    return p;\r
+}\r
+\r
+\r
+/* parse a complete buffer */\r
+static DWORD parse_buffer( struct inf_file *file, const WCHAR *buffer, const WCHAR *end,\r
+                           UINT *error_line )\r
+{\r
+    static const WCHAR Strings[] = {'S','t','r','i','n','g','s',0};\r
+\r
+    struct parser parser;\r
+    const WCHAR *pos = buffer;\r
+\r
+    parser.start       = buffer;\r
+    parser.end         = end;\r
+    parser.file        = file;\r
+    parser.line        = NULL;\r
+    parser.state       = LINE_START;\r
+    parser.stack_pos   = 0;\r
+    parser.cur_section = -1;\r
+    parser.line_pos    = 1;\r
+    parser.error       = 0;\r
+    parser.token_len   = 0;\r
+\r
+    /* parser main loop */\r
+    while (pos) pos = (parser_funcs[parser.state])( &parser, pos );\r
+\r
+    /* trim excess buffer space */\r
+    if (file->alloc_sections > file->nb_sections)\r
+    {\r
+        file->sections = HeapReAlloc( GetProcessHeap(), 0, file->sections,\r
+                                      file->nb_sections * sizeof(file->sections[0]) );\r
+        file->alloc_sections = file->nb_sections;\r
+    }\r
+    if (file->alloc_fields > file->nb_fields)\r
+    {\r
+        file->fields = HeapReAlloc( GetProcessHeap(), 0, file->fields,\r
+                                    file->nb_fields * sizeof(file->fields[0]) );\r
+        file->alloc_fields = file->nb_fields;\r
+    }\r
+    file->strings = HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, file->strings,\r
+                                 (file->string_pos - file->strings) * sizeof(WCHAR) );\r
+\r
+    if (parser.error)\r
+    {\r
+        if (error_line) *error_line = parser.line_pos;\r
+        return parser.error;\r
+    }\r
+\r
+    /* find the [strings] section */\r
+    file->strings_section = find_section( file, Strings );\r
+    return 0;\r
+}\r
+\r
+\r
+/* append a child INF file to its parent list, in a thread-safe manner */\r
+static void append_inf_file( struct inf_file *parent, struct inf_file *child )\r
+{\r
+    struct inf_file **ppnext = &parent->next;\r
+    child->next = NULL;\r
+\r
+    for (;;)\r
+    {\r
+        struct inf_file *next = InterlockedCompareExchangePointer( (void **)ppnext, child, NULL );\r
+        if (!next) return;\r
+        ppnext = &next->next;\r
+    }\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            parse_file\r
+ *\r
+ * parse an INF file.\r
+ */\r
+static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *error_line )\r
+{\r
+    void *buffer;\r
+    DWORD err = 0;\r
+    struct inf_file *file;\r
+\r
+    DWORD size = GetFileSize( handle, NULL );\r
+    HANDLE mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, size, NULL );\r
+    if (!mapping) return NULL;\r
+    buffer = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, size );\r
+    NtClose( mapping );\r
+    if (!buffer) return NULL;\r
+\r
+    if (class) FIXME( "class %s not supported yet\n", debugstr_w(class) );\r
+\r
+    if (!(file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*file) )))\r
+    {\r
+        err = ERROR_NOT_ENOUGH_MEMORY;\r
+        goto done;\r
+    }\r
+\r
+    /* we won't need more strings space than the size of the file,\r
+     * so we can preallocate it here\r
+     */\r
+    if (!(file->strings = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))\r
+    {\r
+        err = ERROR_NOT_ENOUGH_MEMORY;\r
+        goto done;\r
+    }\r
+    file->string_pos = file->strings;\r
+    file->strings_section = -1;\r
+\r
+    if (!RtlIsTextUnicode( buffer, size, NULL ))\r
+    {\r
+        WCHAR *new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );\r
+        if (new_buff)\r
+        {\r
+            DWORD len = MultiByteToWideChar( CP_ACP, 0, buffer, size, new_buff,\r
+                                             size * sizeof(WCHAR) );\r
+            err = parse_buffer( file, new_buff, new_buff + len, error_line );\r
+            HeapFree( GetProcessHeap(), 0, new_buff );\r
+        }\r
+    }\r
+    else err = parse_buffer( file, buffer, (WCHAR *)((char *)buffer + size), error_line );\r
+\r
+    if (!err)  /* now check signature */\r
+    {\r
+        int version_index = find_section( file, Version );\r
+        if (version_index != -1)\r
+        {\r
+            struct line *line = find_line( file, version_index, Signature );\r
+            if (line && line->nb_fields > 0)\r
+            {\r
+                struct field *field = file->fields + line->first_field;\r
+                if (!strcmpiW( field->text, Chicago )) goto done;\r
+                if (!strcmpiW( field->text, WindowsNT )) goto done;\r
+                if (!strcmpiW( field->text, Windows95 )) goto done;\r
+            }\r
+        }\r
+        err = ERROR_WRONG_INF_STYLE;\r
+    }\r
+\r
+ done:\r
+    UnmapViewOfFile( buffer );\r
+    if (err)\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, file );\r
+        SetLastError( err );\r
+        file = NULL;\r
+    }\r
+    return file;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            PARSER_get_src_root\r
+ *\r
+ * Retrieve the source directory of an inf file.\r
+ */\r
+const WCHAR *PARSER_get_src_root( HINF hinf )\r
+{\r
+    struct inf_file *file = hinf;\r
+    return file->src_root;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            PARSER_get_dest_dir\r
+ *\r
+ * retrieve a destination dir of the form "dirid,relative_path" in the given entry.\r
+ * returned buffer must be freed by caller.\r
+ */\r
+WCHAR *PARSER_get_dest_dir( INFCONTEXT *context )\r
+{\r
+    const WCHAR *dir;\r
+    WCHAR *ptr, *ret;\r
+    INT dirid;\r
+    DWORD len1, len2;\r
+\r
+    if (!SetupGetIntField( context, 1, &dirid )) return NULL;\r
+    if (!(dir = DIRID_get_string( context->Inf, dirid ))) return NULL;\r
+    len1 = strlenW(dir) + 1;\r
+    if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0;\r
+    if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2) * sizeof(WCHAR) ))) return NULL;\r
+    strcpyW( ret, dir );\r
+    ptr = ret + strlenW(ret);\r
+    if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\';\r
+    if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0;\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenInfFileA   (SETUPAPI.@)\r
+ */\r
+HINF WINAPI SetupOpenInfFileA( PCSTR name, PCSTR class, DWORD style, UINT *error )\r
+{\r
+    UNICODE_STRING nameW, classW;\r
+    HINF ret = (HINF)INVALID_HANDLE_VALUE;\r
+\r
+    classW.Buffer = NULL;\r
+    if (class && !RtlCreateUnicodeStringFromAsciiz( &classW, class ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return ret;\r
+    }\r
+    if (RtlCreateUnicodeStringFromAsciiz( &nameW, name ))\r
+    {\r
+        ret = SetupOpenInfFileW( nameW.Buffer, classW.Buffer, style, error );\r
+        RtlFreeUnicodeString( &nameW );\r
+    }\r
+    RtlFreeUnicodeString( &classW );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenInfFileW   (SETUPAPI.@)\r
+ */\r
+HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *error )\r
+{\r
+    struct inf_file *file = NULL;\r
+    HANDLE handle;\r
+    WCHAR *path, *p;\r
+    UINT len;\r
+\r
+    if (strchrW( name, '\\' ) || strchrW( name, '/' ))\r
+    {\r
+        if (!(len = GetFullPathNameW( name, 0, NULL, NULL ))) return (HINF)INVALID_HANDLE_VALUE;\r
+        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))\r
+        {\r
+            SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+            return (HINF)INVALID_HANDLE_VALUE;\r
+        }\r
+        GetFullPathNameW( name, len, path, NULL );\r
+        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );\r
+    }\r
+    else  /* try Windows directory */\r
+    {\r
+        static const WCHAR Inf[]      = {'\\','i','n','f','\\',0};\r
+        static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};\r
+\r
+        len = GetWindowsDirectoryW( NULL, 0 ) + strlenW(name) + 12;\r
+        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))\r
+        {\r
+            SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+            return (HINF)INVALID_HANDLE_VALUE;\r
+        }\r
+        GetWindowsDirectoryW( path, len );\r
+        p = path + strlenW(path);\r
+        strcpyW( p, Inf );\r
+        strcatW( p, name );\r
+        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );\r
+        if (handle == INVALID_HANDLE_VALUE)\r
+        {\r
+            strcpyW( p, System32 );\r
+            strcatW( p, name );\r
+            handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );\r
+        }\r
+    }\r
+\r
+    if (handle != INVALID_HANDLE_VALUE)\r
+    {\r
+        file = parse_file( handle, class, error );\r
+        CloseHandle( handle );\r
+    }\r
+    if (!file)\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, path );\r
+        return (HINF)INVALID_HANDLE_VALUE;\r
+    }\r
+    TRACE( "%s -> %p\n", debugstr_w(path), file );\r
+    file->src_root = path;\r
+    if ((p = strrchrW( path, '\\' ))) p[1] = 0;  /* remove file name */\r
+    SetLastError( 0 );\r
+    return (HINF)file;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenAppendInfFileA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupOpenAppendInfFileA( PCSTR name, HINF parent_hinf, UINT *error )\r
+{\r
+    HINF child_hinf;\r
+\r
+    if (!name) return SetupOpenAppendInfFileW( NULL, parent_hinf, error );\r
+    child_hinf = SetupOpenInfFileA( name, NULL, INF_STYLE_WIN4, error );\r
+    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;\r
+    append_inf_file( parent_hinf, child_hinf );\r
+    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_a(name), child_hinf );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenAppendInfFileW    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupOpenAppendInfFileW( PCWSTR name, HINF parent_hinf, UINT *error )\r
+{\r
+    HINF child_hinf;\r
+\r
+    if (!name)\r
+    {\r
+        INFCONTEXT context;\r
+        WCHAR filename[MAX_PATH];\r
+        int idx = 1;\r
+\r
+        if (!SetupFindFirstLineW( parent_hinf, Version, LayoutFile, &context )) return FALSE;\r
+        while (SetupGetStringFieldW( &context, idx++, filename,\r
+                                     sizeof(filename)/sizeof(WCHAR), NULL ))\r
+        {\r
+            child_hinf = SetupOpenInfFileW( filename, NULL, INF_STYLE_WIN4, error );\r
+            if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;\r
+            append_inf_file( parent_hinf, child_hinf );\r
+            TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(filename), child_hinf );\r
+        }\r
+        return TRUE;\r
+    }\r
+    child_hinf = SetupOpenInfFileW( name, NULL, INF_STYLE_WIN4, error );\r
+    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;\r
+    append_inf_file( parent_hinf, child_hinf );\r
+    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(name), child_hinf );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenMasterInf   (SETUPAPI.@)\r
+ */\r
+HINF WINAPI SetupOpenMasterInf( VOID )\r
+{\r
+    static const WCHAR Layout[] = {'\\','i','n','f','\\', 'l', 'a', 'y', 'o', 'u', 't', '.', 'i', 'n', 'f', 0};\r
+    WCHAR Buffer[MAX_PATH];\r
+\r
+    GetWindowsDirectoryW( Buffer, MAX_PATH );\r
+    strcatW( Buffer, Layout );\r
+    return SetupOpenInfFileW( Buffer, NULL, INF_STYLE_WIN4, NULL);\r
+}\r
+\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupCloseInfFile   (SETUPAPI.@)\r
+ */\r
+void WINAPI SetupCloseInfFile( HINF hinf )\r
+{\r
+    struct inf_file *file = hinf;\r
+    unsigned int i;\r
+\r
+    for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );\r
+    HeapFree( GetProcessHeap(), 0, file->src_root );\r
+    HeapFree( GetProcessHeap(), 0, file->sections );\r
+    HeapFree( GetProcessHeap(), 0, file->fields );\r
+    HeapFree( GetProcessHeap(), 0, file->strings );\r
+    HeapFree( GetProcessHeap(), 0, file );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetLineCountA   (SETUPAPI.@)\r
+ */\r
+LONG WINAPI SetupGetLineCountA( HINF hinf, PCSTR name )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    LONG ret = -1;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, name ))\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    else\r
+    {\r
+        ret = SetupGetLineCountW( hinf, sectionW.Buffer );\r
+        RtlFreeUnicodeString( &sectionW );\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetLineCountW   (SETUPAPI.@)\r
+ */\r
+LONG WINAPI SetupGetLineCountW( HINF hinf, PCWSTR section )\r
+{\r
+    struct inf_file *file = hinf;\r
+    int section_index;\r
+    LONG ret = -1;\r
+\r
+    for (file = hinf; file; file = file->next)\r
+    {\r
+        if ((section_index = find_section( file, section )) == -1) continue;\r
+        if (ret == -1) ret = 0;\r
+        ret += file->sections[section_index]->nb_lines;\r
+    }\r
+    TRACE( "(%p,%s) returning %ld\n", hinf, debugstr_w(section), ret );\r
+    SetLastError( (ret == -1) ? ERROR_SECTION_NOT_FOUND : 0 );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetLineByIndexA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetLineByIndexA( HINF hinf, PCSTR section, DWORD index, INFCONTEXT *context )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    else\r
+    {\r
+        ret = SetupGetLineByIndexW( hinf, sectionW.Buffer, index, context );\r
+        RtlFreeUnicodeString( &sectionW );\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetLineByIndexW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetLineByIndexW( HINF hinf, PCWSTR section, DWORD index, INFCONTEXT *context )\r
+{\r
+    struct inf_file *file = hinf;\r
+    int section_index;\r
+\r
+    SetLastError( ERROR_SECTION_NOT_FOUND );\r
+    for (file = hinf; file; file = file->next)\r
+    {\r
+        if ((section_index = find_section( file, section )) == -1) continue;\r
+        SetLastError( ERROR_LINE_NOT_FOUND );\r
+        if (index < file->sections[section_index]->nb_lines)\r
+        {\r
+            context->Inf        = hinf;\r
+            context->CurrentInf = file;\r
+            context->Section    = section_index;\r
+            context->Line       = index;\r
+            SetLastError( 0 );\r
+            TRACE( "(%p,%s): returning %d/%ld\n",\r
+                   hinf, debugstr_w(section), section_index, index );\r
+            return TRUE;\r
+        }\r
+        index -= file->sections[section_index]->nb_lines;\r
+    }\r
+    TRACE( "(%p,%s) not found\n", hinf, debugstr_w(section) );\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupFindFirstLineA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupFindFirstLineA( HINF hinf, PCSTR section, PCSTR key, INFCONTEXT *context )\r
+{\r
+    UNICODE_STRING sectionW, keyW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return FALSE;\r
+    }\r
+\r
+    if (!key) ret = SetupFindFirstLineW( hinf, sectionW.Buffer, NULL, context );\r
+    else\r
+    {\r
+        if (RtlCreateUnicodeStringFromAsciiz( &keyW, key ))\r
+        {\r
+            ret = SetupFindFirstLineW( hinf, sectionW.Buffer, keyW.Buffer, context );\r
+            RtlFreeUnicodeString( &keyW );\r
+        }\r
+        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    }\r
+    RtlFreeUnicodeString( &sectionW );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupFindFirstLineW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupFindFirstLineW( HINF hinf, PCWSTR section, PCWSTR key, INFCONTEXT *context )\r
+{\r
+    struct inf_file *file;\r
+    int section_index;\r
+\r
+    SetLastError( ERROR_SECTION_NOT_FOUND );\r
+    for (file = hinf; file; file = file->next)\r
+    {\r
+        if ((section_index = find_section( file, section )) == -1) continue;\r
+        if (key)\r
+        {\r
+            INFCONTEXT ctx;\r
+            ctx.Inf        = hinf;\r
+            ctx.CurrentInf = file;\r
+            ctx.Section    = section_index;\r
+            ctx.Line       = -1;\r
+            return SetupFindNextMatchLineW( &ctx, key, context );\r
+        }\r
+        SetLastError( ERROR_LINE_NOT_FOUND );  /* found at least one section */\r
+        if (file->sections[section_index]->nb_lines)\r
+        {\r
+            context->Inf        = hinf;\r
+            context->CurrentInf = file;\r
+            context->Section    = section_index;\r
+            context->Line       = 0;\r
+            SetLastError( 0 );\r
+            TRACE( "(%p,%s,%s): returning %d/0\n",\r
+                   hinf, debugstr_w(section), debugstr_w(key), section_index );\r
+            return TRUE;\r
+        }\r
+    }\r
+    TRACE( "(%p,%s,%s): not found\n", hinf, debugstr_w(section), debugstr_w(key) );\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupFindNextLine   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupFindNextLine( PINFCONTEXT context_in, PINFCONTEXT context_out )\r
+{\r
+    struct inf_file *file = context_in->CurrentInf;\r
+    struct section *section;\r
+\r
+    if (context_in->Section >= file->nb_sections) goto error;\r
+\r
+    section = file->sections[context_in->Section];\r
+    if (context_in->Line+1 < section->nb_lines)\r
+    {\r
+        if (context_out != context_in) *context_out = *context_in;\r
+        context_out->Line++;\r
+        SetLastError( 0 );\r
+        return TRUE;\r
+    }\r
+\r
+    /* now search the appended files */\r
+\r
+    for (file = file->next; file; file = file->next)\r
+    {\r
+        int section_index = find_section( file, section->name );\r
+        if (section_index == -1) continue;\r
+        if (file->sections[section_index]->nb_lines)\r
+        {\r
+            context_out->Inf        = context_in->Inf;\r
+            context_out->CurrentInf = file;\r
+            context_out->Section    = section_index;\r
+            context_out->Line       = 0;\r
+            SetLastError( 0 );\r
+            return TRUE;\r
+        }\r
+    }\r
+ error:\r
+    SetLastError( ERROR_LINE_NOT_FOUND );\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupFindNextMatchLineA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupFindNextMatchLineA( PINFCONTEXT context_in, PCSTR key,\r
+                                     PINFCONTEXT context_out )\r
+{\r
+    UNICODE_STRING keyW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!key) return SetupFindNextLine( context_in, context_out );\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &keyW, key ))\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    else\r
+    {\r
+        ret = SetupFindNextMatchLineW( context_in, keyW.Buffer, context_out );\r
+        RtlFreeUnicodeString( &keyW );\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupFindNextMatchLineW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupFindNextMatchLineW( PINFCONTEXT context_in, PCWSTR key,\r
+                                     PINFCONTEXT context_out )\r
+{\r
+    struct inf_file *file = context_in->CurrentInf;\r
+    struct section *section;\r
+    struct line *line;\r
+    unsigned int i;\r
+\r
+    if (!key) return SetupFindNextLine( context_in, context_out );\r
+\r
+    if (context_in->Section >= file->nb_sections) goto error;\r
+\r
+    section = file->sections[context_in->Section];\r
+\r
+    for (i = context_in->Line+1, line = &section->lines[i]; i < section->nb_lines; i++, line++)\r
+    {\r
+        if (line->key_field == -1) continue;\r
+        if (!strcmpiW( key, file->fields[line->key_field].text ))\r
+        {\r
+            if (context_out != context_in) *context_out = *context_in;\r
+            context_out->Line = i;\r
+            SetLastError( 0 );\r
+            TRACE( "(%p,%s,%s): returning %d\n",\r
+                   file, debugstr_w(section->name), debugstr_w(key), i );\r
+            return TRUE;\r
+        }\r
+    }\r
+\r
+    /* now search the appended files */\r
+\r
+    for (file = file->next; file; file = file->next)\r
+    {\r
+        int section_index = find_section( file, section->name );\r
+        if (section_index == -1) continue;\r
+        section = file->sections[section_index];\r
+        for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)\r
+        {\r
+            if (line->key_field == -1) continue;\r
+            if (!strcmpiW( key, file->fields[line->key_field].text ))\r
+            {\r
+                context_out->Inf        = context_in->Inf;\r
+                context_out->CurrentInf = file;\r
+                context_out->Section    = section_index;\r
+                context_out->Line       = i;\r
+                SetLastError( 0 );\r
+                TRACE( "(%p,%s,%s): returning %d/%d\n",\r
+                       file, debugstr_w(section->name), debugstr_w(key), section_index, i );\r
+                return TRUE;\r
+            }\r
+        }\r
+    }\r
+    TRACE( "(%p,%s,%s): not found\n",\r
+           context_in->CurrentInf, debugstr_w(section->name), debugstr_w(key) );\r
+ error:\r
+    SetLastError( ERROR_LINE_NOT_FOUND );\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetLineTextW    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetLineTextW( PINFCONTEXT context, HINF hinf, PCWSTR section_name,\r
+                               PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required )\r
+{\r
+    struct inf_file *file;\r
+    struct line *line;\r
+    struct field *field;\r
+    int i;\r
+    DWORD total = 0;\r
+\r
+    if (!context)\r
+    {\r
+        INFCONTEXT new_context;\r
+        if (!SetupFindFirstLineW( hinf, section_name, key_name, &new_context )) return FALSE;\r
+        file = new_context.CurrentInf;\r
+        line = get_line( file, new_context.Section, new_context.Line );\r
+    }\r
+    else\r
+    {\r
+        file = context->CurrentInf;\r
+        if (!(line = get_line( file, context->Section, context->Line )))\r
+        {\r
+            SetLastError( ERROR_LINE_NOT_FOUND );\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)\r
+        total += PARSER_string_substW( file, field->text, NULL, 0 ) + 1;\r
+\r
+    if (required) *required = total;\r
+    if (buffer)\r
+    {\r
+        if (total > size)\r
+        {\r
+            SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+            return FALSE;\r
+        }\r
+        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)\r
+        {\r
+            unsigned int len = PARSER_string_substW( file, field->text, buffer, size );\r
+            if (i+1 < line->nb_fields) buffer[len] = ',';\r
+            buffer += len + 1;\r
+        }\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetLineTextA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetLineTextA( PINFCONTEXT context, HINF hinf, PCSTR section_name,\r
+                               PCSTR key_name, PSTR buffer, DWORD size, PDWORD required )\r
+{\r
+    struct inf_file *file;\r
+    struct line *line;\r
+    struct field *field;\r
+    int i;\r
+    DWORD total = 0;\r
+\r
+    if (!context)\r
+    {\r
+        INFCONTEXT new_context;\r
+        if (!SetupFindFirstLineA( hinf, section_name, key_name, &new_context )) return FALSE;\r
+        file = new_context.CurrentInf;\r
+        line = get_line( file, new_context.Section, new_context.Line );\r
+    }\r
+    else\r
+    {\r
+        file = context->CurrentInf;\r
+        if (!(line = get_line( file, context->Section, context->Line )))\r
+        {\r
+            SetLastError( ERROR_LINE_NOT_FOUND );\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)\r
+        total += PARSER_string_substA( file, field->text, NULL, 0 ) + 1;\r
+\r
+    if (required) *required = total;\r
+    if (buffer)\r
+    {\r
+        if (total > size)\r
+        {\r
+            SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+            return FALSE;\r
+        }\r
+        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)\r
+        {\r
+            unsigned int len = PARSER_string_substA( file, field->text, buffer, size );\r
+            if (i+1 < line->nb_fields) buffer[len] = ',';\r
+            buffer += len + 1;\r
+        }\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetFieldCount    (SETUPAPI.@)\r
+ */\r
+DWORD WINAPI SetupGetFieldCount( PINFCONTEXT context )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct line *line = get_line( file, context->Section, context->Line );\r
+\r
+    if (!line) return 0;\r
+    return line->nb_fields;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetStringFieldA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetStringFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,\r
+                                  DWORD size, PDWORD required )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct field *field = get_field( file, context->Section, context->Line, index );\r
+    unsigned int len;\r
+\r
+    SetLastError(0);\r
+    if (!field) return FALSE;\r
+    len = PARSER_string_substA( file, field->text, NULL, 0 );\r
+    if (required) *required = len + 1;\r
+    if (buffer)\r
+    {\r
+        if (size <= len)\r
+        {\r
+            SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+            return FALSE;\r
+        }\r
+        PARSER_string_substA( file, field->text, buffer, size );\r
+\r
+        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",\r
+               context->Inf, context->CurrentInf, context->Section, context->Line,\r
+               index, debugstr_a(buffer) );\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetStringFieldW    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetStringFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,\r
+                                  DWORD size, PDWORD required )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct field *field = get_field( file, context->Section, context->Line, index );\r
+    unsigned int len;\r
+\r
+    SetLastError(0);\r
+    if (!field) return FALSE;\r
+    len = PARSER_string_substW( file, field->text, NULL, 0 );\r
+    if (required) *required = len + 1;\r
+    if (buffer)\r
+    {\r
+        if (size <= len)\r
+        {\r
+            SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+            return FALSE;\r
+        }\r
+        PARSER_string_substW( file, field->text, buffer, size );\r
+\r
+        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",\r
+               context->Inf, context->CurrentInf, context->Section, context->Line,\r
+               index, debugstr_w(buffer) );\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetIntField    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetIntField( PINFCONTEXT context, DWORD index, PINT result )\r
+{\r
+    char localbuff[20];\r
+    char *end, *buffer = localbuff;\r
+    DWORD required;\r
+    INT res;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required ))\r
+    {\r
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;\r
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE;\r
+        if (!SetupGetStringFieldA( context, index, buffer, required, NULL )) goto done;\r
+    }\r
+    res = strtol( buffer, &end, 0 );\r
+    if (end != buffer && !*end)\r
+    {\r
+        *result = res;\r
+        ret = TRUE;\r
+    }\r
+    else SetLastError( ERROR_INVALID_DATA );\r
+\r
+ done:\r
+    if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetBinaryField    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetBinaryField( PINFCONTEXT context, DWORD index, BYTE *buffer,\r
+                                 DWORD size, LPDWORD required )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct line *line = get_line( file, context->Section, context->Line );\r
+    struct field *field;\r
+    int i;\r
+\r
+    if (!line)\r
+    {\r
+        SetLastError( ERROR_LINE_NOT_FOUND );\r
+        return FALSE;\r
+    }\r
+    if (!index || index >= line->nb_fields)\r
+    {\r
+        SetLastError( ERROR_INVALID_PARAMETER );\r
+        return FALSE;\r
+    }\r
+    index--;  /* fields start at 0 */\r
+    if (required) *required = line->nb_fields - index;\r
+    if (!buffer) return TRUE;\r
+    if (size < line->nb_fields - index)\r
+    {\r
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+        return FALSE;\r
+    }\r
+    field = &file->fields[line->first_field + index];\r
+    for (i = index; i < line->nb_fields; i++, field++)\r
+    {\r
+        const WCHAR *p;\r
+        DWORD value = 0;\r
+        for (p = field->text; *p && isxdigitW(*p); p++)\r
+        {\r
+            if ((value <<= 4) > 255)\r
+            {\r
+                SetLastError( ERROR_INVALID_DATA );\r
+                return FALSE;\r
+            }\r
+            if (*p <= '9') value |= (*p - '0');\r
+            else value |= (tolowerW(*p) - 'a' + 10);\r
+        }\r
+        buffer[i - index] = value;\r
+    }\r
+    if (TRACE_ON(setupapi))\r
+    {\r
+        TRACE( "%p/%p/%d/%d index %ld returning",\r
+               context->Inf, context->CurrentInf, context->Section, context->Line, index );\r
+        for (i = index; i < line->nb_fields; i++) TRACE( " %02x", buffer[i - index] );\r
+        TRACE( "\n" );\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetMultiSzFieldA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetMultiSzFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,\r
+                                   DWORD size, LPDWORD required )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct line *line = get_line( file, context->Section, context->Line );\r
+    struct field *field;\r
+    unsigned int len;\r
+    int i;\r
+    DWORD total = 1;\r
+\r
+    if (!line)\r
+    {\r
+        SetLastError( ERROR_LINE_NOT_FOUND );\r
+        return FALSE;\r
+    }\r
+    if (!index || index >= line->nb_fields)\r
+    {\r
+        SetLastError( ERROR_INVALID_PARAMETER );\r
+        return FALSE;\r
+    }\r
+    index--;  /* fields start at 0 */\r
+    field = &file->fields[line->first_field + index];\r
+    for (i = index; i < line->nb_fields; i++, field++)\r
+    {\r
+        if (!(len = PARSER_string_substA( file, field->text, NULL, 0 ))) break;\r
+        total += len + 1;\r
+    }\r
+\r
+    if (required) *required = total;\r
+    if (!buffer) return TRUE;\r
+    if (total > size)\r
+    {\r
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+        return FALSE;\r
+    }\r
+    field = &file->fields[line->first_field + index];\r
+    for (i = index; i < line->nb_fields; i++, field++)\r
+    {\r
+        if (!(len = PARSER_string_substA( file, field->text, buffer, size ))) break;\r
+        buffer += len + 1;\r
+    }\r
+    *buffer = 0;  /* add final null */\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupGetMultiSzFieldW    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetMultiSzFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,\r
+                                   DWORD size, LPDWORD required )\r
+{\r
+    struct inf_file *file = context->CurrentInf;\r
+    struct line *line = get_line( file, context->Section, context->Line );\r
+    struct field *field;\r
+    unsigned int len;\r
+    int i;\r
+    DWORD total = 1;\r
+\r
+    if (!line)\r
+    {\r
+        SetLastError( ERROR_LINE_NOT_FOUND );\r
+        return FALSE;\r
+    }\r
+    if (!index || index >= line->nb_fields)\r
+    {\r
+        SetLastError( ERROR_INVALID_PARAMETER );\r
+        return FALSE;\r
+    }\r
+    index--;  /* fields start at 0 */\r
+    field = &file->fields[line->first_field + index];\r
+    for (i = index; i < line->nb_fields; i++, field++)\r
+    {\r
+        if (!(len = PARSER_string_substW( file, field->text, NULL, 0 ))) break;\r
+        total += len + 1;\r
+    }\r
+\r
+    if (required) *required = total;\r
+    if (!buffer) return TRUE;\r
+    if (total > size)\r
+    {\r
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );\r
+        return FALSE;\r
+    }\r
+    field = &file->fields[line->first_field + index];\r
+    for (i = index; i < line->nb_fields; i++, field++)\r
+    {\r
+        if (!(len = PARSER_string_substW( file, field->text, buffer, size ))) break;\r
+        buffer += len + 1;\r
+    }\r
+    *buffer = 0;  /* add final null */\r
+    return TRUE;\r
+}\r
index 87693f0..66da7b7 100644 (file)
-/*
- * Setupapi file queue routines
- *
- * Copyright 2002 Alexandre Julliard 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winerror.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "wine/unicode.h"
-#include "setupapi_private.h"
-#include "winver.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-/* context structure for the default queue callback */
-struct default_callback_context
-{
-    HWND owner;
-    HWND progress;
-    UINT message;
-};
-
-struct file_op
-{
-    struct file_op *next;
-    UINT            style;
-    WCHAR          *src_root;
-    WCHAR          *src_path;
-    WCHAR          *src_file;
-    WCHAR          *src_descr;
-    WCHAR          *src_tag;
-    WCHAR          *dst_path;
-    WCHAR          *dst_file;
-};
-
-struct file_op_queue
-{
-    struct file_op *head;
-    struct file_op *tail;
-    unsigned int count;
-};
-
-struct file_queue
-{
-    struct file_op_queue copy_queue;
-    struct file_op_queue delete_queue;
-    struct file_op_queue rename_queue;
-    DWORD                flags;
-};
-
-
-inline static WCHAR *strdupW( const WCHAR *str )
-{
-    WCHAR *ret = NULL;
-    if (str)
-    {
-        int len = (strlenW(str) + 1) * sizeof(WCHAR);
-        if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( ret, str, len );
-    }
-    return ret;
-}
-
-
-inline static WCHAR *strdupAtoW( const char *str )
-{
-    WCHAR *ret = NULL;
-    if (str)
-    {
-        DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
-        if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
-            MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
-    }
-    return ret;
-}
-
-inline static char *strdupWtoA( const WCHAR *str )
-{
-    char *ret = NULL;
-    if (str)
-    {
-        DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
-        if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
-            WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
-    }
-    return ret;
-}
-
-/* append a file operation to a queue */
-inline static void queue_file_op( struct file_op_queue *queue, struct file_op *op )
-{
-    op->next = NULL;
-    if (queue->tail) queue->tail->next = op;
-    else queue->head = op;
-    queue->tail = op;
-    queue->count++;
-}
-
-/* free all the file operations on a given queue */
-static void free_file_op_queue( struct file_op_queue *queue )
-{
-    struct file_op *t, *op = queue->head;
-
-    while( op )
-    {
-        HeapFree( GetProcessHeap(), 0, op->src_root );
-        HeapFree( GetProcessHeap(), 0, op->src_path );
-        HeapFree( GetProcessHeap(), 0, op->src_file );
-        HeapFree( GetProcessHeap(), 0, op->src_descr );
-        HeapFree( GetProcessHeap(), 0, op->src_tag );
-        HeapFree( GetProcessHeap(), 0, op->dst_path );
-        if (op->dst_file != op->src_file) HeapFree( GetProcessHeap(), 0, op->dst_file );
-        t = op;
-        op = op->next;
-        HeapFree( GetProcessHeap(), 0, t );
-    }
-}
-
-/* concat 3 strings to make a path, handling separators correctly */
-static void concat_W( WCHAR *buffer, const WCHAR *src1, const WCHAR *src2, const WCHAR *src3 )
-{
-    *buffer = 0;
-    if (src1 && *src1)
-    {
-        strcpyW( buffer, src1 );
-        buffer += strlenW(buffer );
-        if (buffer[-1] != '\\') *buffer++ = '\\';
-        if (src2) while (*src2 == '\\') src2++;
-    }
-
-    if (src2)
-    {
-        strcpyW( buffer, src2 );
-        buffer += strlenW(buffer );
-        if (buffer[-1] != '\\') *buffer++ = '\\';
-        if (src3) while (*src3 == '\\') src3++;
-    }
-    if (src3)
-    {
-        strcpyW( buffer, src3 );
-        buffer += strlenW(buffer );
-    }
-}
-
-
-/***********************************************************************
- *            build_filepathsW
- *
- * Build a FILEPATHS_W structure for a given file operation.
- */
-static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
-{
-    unsigned int src_len = 1, dst_len = 1;
-    WCHAR *source = (PWSTR)paths->Source, *target = (PWSTR)paths->Target;
-
-    if (op->src_root) src_len += strlenW(op->src_root) + 1;
-    if (op->src_path) src_len += strlenW(op->src_path) + 1;
-    if (op->src_file) src_len += strlenW(op->src_file) + 1;
-    if (op->dst_path) dst_len += strlenW(op->dst_path) + 1;
-    if (op->dst_file) dst_len += strlenW(op->dst_file) + 1;
-    src_len *= sizeof(WCHAR);
-    dst_len *= sizeof(WCHAR);
-
-    if (!source || HeapSize( GetProcessHeap(), 0, source ) < src_len )
-    {
-        HeapFree( GetProcessHeap(), 0, source );
-        paths->Source = source = HeapAlloc( GetProcessHeap(), 0, src_len );
-    }
-    if (!target || HeapSize( GetProcessHeap(), 0, target ) < dst_len )
-    {
-        HeapFree( GetProcessHeap(), 0, target );
-        paths->Target = target = HeapAlloc( GetProcessHeap(), 0, dst_len );
-    }
-    if (!source || !target) return FALSE;
-    concat_W( source, op->src_root, op->src_path, op->src_file );
-    concat_W( target, NULL, op->dst_path, op->dst_file );
-    paths->Win32Error = 0;
-    paths->Flags      = 0;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            QUEUE_callback_WtoA
- *
- * Map a file callback parameters from W to A and call the A callback.
- */
-UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification,
-                                   UINT_PTR param1, UINT_PTR param2 )
-{
-    struct callback_WtoA_context *callback_ctx = context;
-    char buffer[MAX_PATH];
-    UINT ret;
-    UINT_PTR old_param2 = param2;
-
-    switch(notification)
-    {
-    case SPFILENOTIFY_COPYERROR:
-        param2 = (UINT_PTR)&buffer;
-        /* fall through */
-    case SPFILENOTIFY_STARTDELETE:
-    case SPFILENOTIFY_ENDDELETE:
-    case SPFILENOTIFY_DELETEERROR:
-    case SPFILENOTIFY_STARTRENAME:
-    case SPFILENOTIFY_ENDRENAME:
-    case SPFILENOTIFY_RENAMEERROR:
-    case SPFILENOTIFY_STARTCOPY:
-    case SPFILENOTIFY_ENDCOPY:
-        {
-            FILEPATHS_W *pathsW = (FILEPATHS_W *)param1;
-            FILEPATHS_A pathsA;
-
-            pathsA.Source     = strdupWtoA( pathsW->Source );
-            pathsA.Target     = strdupWtoA( pathsW->Target );
-            pathsA.Win32Error = pathsW->Win32Error;
-            pathsA.Flags      = pathsW->Flags;
-            ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,
-                                              (UINT_PTR)&pathsA, param2 );
-            HeapFree( GetProcessHeap(), 0, (void *)pathsA.Source );
-            HeapFree( GetProcessHeap(), 0, (void *)pathsA.Target );
-        }
-        if (notification == SPFILENOTIFY_COPYERROR)
-            MultiByteToWideChar( CP_ACP, 0, buffer, -1, (WCHAR *)old_param2, MAX_PATH );
-        break;
-
-    case SPFILENOTIFY_STARTREGISTRATION:
-    case SPFILENOTIFY_ENDREGISTRATION:
-        {
-            SP_REGISTER_CONTROL_STATUSW *statusW = (SP_REGISTER_CONTROL_STATUSW *)param1;
-            SP_REGISTER_CONTROL_STATUSA statusA;
-
-            statusA.cbSize = sizeof(statusA);
-            statusA.FileName = strdupWtoA( statusW->FileName );
-            statusA.Win32Error  = statusW->Win32Error;
-            statusA.FailureCode = statusW->FailureCode;
-            ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,
-                                              (UINT_PTR)&statusA, param2 );
-            HeapFree( GetProcessHeap(), 0, (LPSTR)statusA.FileName );
-        }
-        break;
-
-    case SPFILENOTIFY_NEEDMEDIA:
-    case SPFILENOTIFY_QUEUESCAN:
-        FIXME("mapping for %d not implemented\n",notification);
-    case SPFILENOTIFY_STARTQUEUE:
-    case SPFILENOTIFY_ENDQUEUE:
-    case SPFILENOTIFY_STARTSUBQUEUE:
-    case SPFILENOTIFY_ENDSUBQUEUE:
-    default:
-        ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification, param1, param2 );
-        break;
-    }
-    return ret;
-}
-
-
-/***********************************************************************
- *            get_src_file_info
- *
- * Retrieve the source file information for a given file.
- */
-static void get_src_file_info( HINF hinf, struct file_op *op )
-{
-    static const WCHAR SourceDisksNames[] =
-        {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};
-    static const WCHAR SourceDisksFiles[] =
-        {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};
-
-    INFCONTEXT file_ctx, disk_ctx;
-    INT id, diskid;
-    DWORD len, len2;
-
-    /* find the SourceDisksFiles entry */
-    if (!SetupFindFirstLineW( hinf, SourceDisksFiles, op->src_file, &file_ctx ))
-    {
-        const WCHAR *dir;
-
-        if ((op->style & (SP_COPY_SOURCE_ABSOLUTE|SP_COPY_SOURCEPATH_ABSOLUTE))) return;
-        /* no specific info, use .inf file source directory */
-        if (!op->src_root && (dir = DIRID_get_string( hinf, DIRID_SRCPATH )))
-            op->src_root = strdupW( dir );
-        return;
-    }
-    if (!SetupGetIntField( &file_ctx, 1, &diskid )) return;
-
-    /* now find the diskid in the SourceDisksNames section */
-    if (!SetupFindFirstLineW( hinf, SourceDisksNames, NULL, &disk_ctx )) return;
-    for (;;)
-    {
-        if (SetupGetIntField( &disk_ctx, 0, &id ) && (id == diskid)) break;
-        if (!SetupFindNextLine( &disk_ctx, &disk_ctx )) return;
-    }
-
-    /* and fill in the missing info */
-
-    if (!op->src_descr)
-    {
-        if (SetupGetStringFieldW( &disk_ctx, 1, NULL, 0, &len ) &&
-            (op->src_descr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))
-            SetupGetStringFieldW( &disk_ctx, 1, op->src_descr, len, NULL );
-    }
-    if (!op->src_tag)
-    {
-        if (SetupGetStringFieldW( &disk_ctx, 2, NULL, 0, &len ) &&
-            (op->src_tag = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))
-            SetupGetStringFieldW( &disk_ctx, 2, op->src_tag, len, NULL );
-    }
-    if (!op->src_path && !(op->style & SP_COPY_SOURCE_ABSOLUTE))
-    {
-        if (!(op->style & SP_COPY_SOURCEPATH_ABSOLUTE))
-        {
-            /* retrieve relative path for this disk */
-            if (!SetupGetStringFieldW( &disk_ctx, 4, NULL, 0, &len )) len = 0;
-        }
-        /* retrieve relative path for this file */
-        if (!SetupGetStringFieldW( &file_ctx, 2, NULL, 0, &len2 )) len2 = 0;
-
-        if ((len || len2) &&
-            (op->src_path = HeapAlloc( GetProcessHeap(), 0, (len+len2)*sizeof(WCHAR) )))
-        {
-            WCHAR *ptr = op->src_path;
-            if (len)
-            {
-                SetupGetStringFieldW( &disk_ctx, 4, op->src_path, len, NULL );
-                ptr = op->src_path + strlenW(op->src_path);
-                if (len2 && ptr > op->src_path && ptr[-1] != '\\') *ptr++ = '\\';
-            }
-            if (!SetupGetStringFieldW( &disk_ctx, 4, ptr, len2, NULL )) *ptr = 0;
-        }
-    }
-    if (!op->src_root) op->src_root = strdupW( PARSER_get_src_root(hinf) );
-}
-
-
-/***********************************************************************
- *            get_destination_dir
- *
- * Retrieve the destination dir for a given section.
- */
-static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
-{
-    static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
-    static const WCHAR Def[]  = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
-    INFCONTEXT context;
-
-    if (!SetupFindFirstLineW( hinf, Dest, section, &context ) &&
-        !SetupFindFirstLineW( hinf, Dest, Def, &context )) return NULL;
-    return PARSER_get_dest_dir( &context );
-}
-
-
-static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD );
-
-/***********************************************************************
- *            extract_cabinet_file
- *
- * Extract a file from a .cab file.
- */
-static BOOL extract_cabinet_file( const WCHAR *cabinet, const WCHAR *root,
-                                  const WCHAR *src, const WCHAR *dst )
-{
-    static const WCHAR extW[] = {'.','c','a','b',0};
-    static HMODULE advpack;
-
-    char *cab_path, *cab_file;
-    int len = strlenW( cabinet );
-
-    /* make sure the cabinet file has a .cab extension */
-    if (len <= 4 || strcmpiW( cabinet + len - 4, extW )) return FALSE;
-    if (!pExtractFiles)
-    {
-        if (!advpack && !(advpack = LoadLibraryA( "advpack.dll" )))
-        {
-            ERR( "could not load advpack.dll\n" );
-            return FALSE;
-        }
-        if (!(pExtractFiles = (void *)GetProcAddress( advpack, "ExtractFiles" )))
-        {
-            ERR( "could not find ExtractFiles in advpack.dll\n" );
-            return FALSE;
-        }
-    }
-
-    if (!(cab_path = strdupWtoA( root ))) return FALSE;
-    len = WideCharToMultiByte( CP_ACP, 0, cabinet, -1, NULL, 0, NULL, NULL );
-    if (!(cab_file = HeapAlloc( GetProcessHeap(), 0, strlen(cab_path) + len + 1 )))
-    {
-        HeapFree( GetProcessHeap(), 0, cab_path );
-        return FALSE;
-    }
-    strcpy( cab_file, cab_path );
-    if (cab_file[0] && cab_file[strlen(cab_file)-1] != '\\') strcat( cab_file, "\\" );
-    WideCharToMultiByte( CP_ACP, 0, cabinet, -1, cab_file + strlen(cab_file), len, NULL, NULL );
-    FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file) );
-    pExtractFiles( cab_file, cab_path, 0, 0, 0, 0 );
-    HeapFree( GetProcessHeap(), 0, cab_file );
-    HeapFree( GetProcessHeap(), 0, cab_path );
-    return CopyFileW( src, dst, FALSE /*FIXME*/ );
-}
-
-
-/***********************************************************************
- *            SetupOpenFileQueue   (SETUPAPI.@)
- */
-HSPFILEQ WINAPI SetupOpenFileQueue(void)
-{
-    struct file_queue *queue;
-
-    if (!(queue = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*queue))))
-        return (HSPFILEQ)INVALID_HANDLE_VALUE;
-    return queue;
-}
-
-
-/***********************************************************************
- *            SetupCloseFileQueue   (SETUPAPI.@)
- */
-BOOL WINAPI SetupCloseFileQueue( HSPFILEQ handle )
-{
-    struct file_queue *queue = handle;
-
-    free_file_op_queue( &queue->copy_queue );
-    free_file_op_queue( &queue->rename_queue );
-    free_file_op_queue( &queue->delete_queue );
-    HeapFree( GetProcessHeap(), 0, queue );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueCopyIndirectA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopyIndirectA( PSP_FILE_COPY_PARAMS_A params )
-{
-    struct file_queue *queue = params->QueueHandle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = params->CopyStyle;
-    op->src_root   = strdupAtoW( params->SourceRootPath );
-    op->src_path   = strdupAtoW( params->SourcePath );
-    op->src_file   = strdupAtoW( params->SourceFilename );
-    op->src_descr  = strdupAtoW( params->SourceDescription );
-    op->src_tag    = strdupAtoW( params->SourceTagfile );
-    op->dst_path   = strdupAtoW( params->TargetDirectory );
-    op->dst_file   = strdupAtoW( params->TargetFilename );
-
-    /* some defaults */
-    if (!op->src_file) op->src_file = op->dst_file;
-    if (params->LayoutInf)
-    {
-        get_src_file_info( params->LayoutInf, op );
-        if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );
-    }
-
-    TRACE( "root=%s path=%s file=%s -> dir=%s file=%s  descr=%s tag=%s\n",
-           debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),
-           debugstr_w(op->dst_path), debugstr_w(op->dst_file),
-           debugstr_w(op->src_descr), debugstr_w(op->src_tag) );
-
-    queue_file_op( &queue->copy_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueCopyIndirectW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params )
-{
-    struct file_queue *queue = params->QueueHandle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = params->CopyStyle;
-    op->src_root   = strdupW( params->SourceRootPath );
-    op->src_path   = strdupW( params->SourcePath );
-    op->src_file   = strdupW( params->SourceFilename );
-    op->src_descr  = strdupW( params->SourceDescription );
-    op->src_tag    = strdupW( params->SourceTagfile );
-    op->dst_path   = strdupW( params->TargetDirectory );
-    op->dst_file   = strdupW( params->TargetFilename );
-
-    /* some defaults */
-    if (!op->src_file) op->src_file = op->dst_file;
-    if (params->LayoutInf)
-    {
-        get_src_file_info( params->LayoutInf, op );
-        if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );
-    }
-
-    TRACE( "root=%s path=%s file=%s -> dir=%s file=%s  descr=%s tag=%s\n",
-           debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),
-           debugstr_w(op->dst_path), debugstr_w(op->dst_file),
-           debugstr_w(op->src_descr), debugstr_w(op->src_tag) );
-
-    queue_file_op( &queue->copy_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueCopyA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopyA( HSPFILEQ queue, PCSTR src_root, PCSTR src_path, PCSTR src_file,
-                             PCSTR src_descr, PCSTR src_tag, PCSTR dst_dir, PCSTR dst_file,
-                             DWORD style )
-{
-    SP_FILE_COPY_PARAMS_A params;
-
-    params.cbSize             = sizeof(params);
-    params.QueueHandle        = queue;
-    params.SourceRootPath     = src_root;
-    params.SourcePath         = src_path;
-    params.SourceFilename     = src_file;
-    params.SourceDescription  = src_descr;
-    params.SourceTagfile      = src_tag;
-    params.TargetDirectory    = dst_dir;
-    params.TargetFilename     = dst_file;
-    params.CopyStyle          = style;
-    params.LayoutInf          = 0;
-    params.SecurityDescriptor = NULL;
-    return SetupQueueCopyIndirectA( &params );
-}
-
-
-/***********************************************************************
- *            SetupQueueCopyW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopyW( HSPFILEQ queue, PCWSTR src_root, PCWSTR src_path, PCWSTR src_file,
-                             PCWSTR src_descr, PCWSTR src_tag, PCWSTR dst_dir, PCWSTR dst_file,
-                             DWORD style )
-{
-    SP_FILE_COPY_PARAMS_W params;
-
-    params.cbSize             = sizeof(params);
-    params.QueueHandle        = queue;
-    params.SourceRootPath     = src_root;
-    params.SourcePath         = src_path;
-    params.SourceFilename     = src_file;
-    params.SourceDescription  = src_descr;
-    params.SourceTagfile      = src_tag;
-    params.TargetDirectory    = dst_dir;
-    params.TargetFilename     = dst_file;
-    params.CopyStyle          = style;
-    params.LayoutInf          = 0;
-    params.SecurityDescriptor = NULL;
-    return SetupQueueCopyIndirectW( &params );
-}
-
-
-/***********************************************************************
- *            SetupQueueDefaultCopyA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDefaultCopyA( HSPFILEQ queue, HINF hinf, PCSTR src_root, PCSTR src_file,
-                                    PCSTR dst_file, DWORD style )
-{
-    SP_FILE_COPY_PARAMS_A params;
-
-    params.cbSize             = sizeof(params);
-    params.QueueHandle        = queue;
-    params.SourceRootPath     = src_root;
-    params.SourcePath         = NULL;
-    params.SourceFilename     = src_file;
-    params.SourceDescription  = NULL;
-    params.SourceTagfile      = NULL;
-    params.TargetDirectory    = NULL;
-    params.TargetFilename     = dst_file;
-    params.CopyStyle          = style;
-    params.LayoutInf          = hinf;
-    params.SecurityDescriptor = NULL;
-    return SetupQueueCopyIndirectA( &params );
-}
-
-
-/***********************************************************************
- *            SetupQueueDefaultCopyW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDefaultCopyW( HSPFILEQ queue, HINF hinf, PCWSTR src_root, PCWSTR src_file,
-                                    PCWSTR dst_file, DWORD style )
-{
-    SP_FILE_COPY_PARAMS_W params;
-
-    params.cbSize             = sizeof(params);
-    params.QueueHandle        = queue;
-    params.SourceRootPath     = src_root;
-    params.SourcePath         = NULL;
-    params.SourceFilename     = src_file;
-    params.SourceDescription  = NULL;
-    params.SourceTagfile      = NULL;
-    params.TargetDirectory    = NULL;
-    params.TargetFilename     = dst_file;
-    params.CopyStyle          = style;
-    params.LayoutInf          = hinf;
-    params.SecurityDescriptor = NULL;
-    return SetupQueueCopyIndirectW( &params );
-}
-
-
-/***********************************************************************
- *            SetupQueueDeleteA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDeleteA( HSPFILEQ handle, PCSTR part1, PCSTR part2 )
-{
-    struct file_queue *queue = handle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = 0;
-    op->src_root   = NULL;
-    op->src_path   = NULL;
-    op->src_file   = NULL;
-    op->src_descr  = NULL;
-    op->src_tag    = NULL;
-    op->dst_path   = strdupAtoW( part1 );
-    op->dst_file   = strdupAtoW( part2 );
-    queue_file_op( &queue->delete_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueDeleteW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDeleteW( HSPFILEQ handle, PCWSTR part1, PCWSTR part2 )
-{
-    struct file_queue *queue = handle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = 0;
-    op->src_root   = NULL;
-    op->src_path   = NULL;
-    op->src_file   = NULL;
-    op->src_descr  = NULL;
-    op->src_tag    = NULL;
-    op->dst_path   = strdupW( part1 );
-    op->dst_file   = strdupW( part2 );
-    queue_file_op( &queue->delete_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueRenameA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFilename,
-                               PCSTR TargetPath, PCSTR TargetFilename )
-{
-    struct file_queue *queue = handle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = 0;
-    op->src_root   = NULL;
-    op->src_path   = strdupAtoW( SourcePath );
-    op->src_file   = strdupAtoW( SourceFilename );
-    op->src_descr  = NULL;
-    op->src_tag    = NULL;
-    op->dst_path   = strdupAtoW( TargetPath );
-    op->dst_file   = strdupAtoW( TargetFilename );
-    queue_file_op( &queue->rename_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueRenameW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR SourceFilename,
-                               PCWSTR TargetPath, PCWSTR TargetFilename )
-{
-    struct file_queue *queue = handle;
-    struct file_op *op;
-
-    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;
-    op->style      = 0;
-    op->src_root   = NULL;
-    op->src_path   = strdupW( SourcePath );
-    op->src_file   = strdupW( SourceFilename );
-    op->src_descr  = NULL;
-    op->src_tag    = NULL;
-    op->dst_path   = strdupW( TargetPath );
-    op->dst_file   = strdupW( TargetFilename );
-    queue_file_op( &queue->rename_queue, op );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueCopySectionA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopySectionA( HSPFILEQ queue, PCSTR src_root, HINF hinf, HINF hlist,
-                                    PCSTR section, DWORD style )
-{
-    UNICODE_STRING sectionW;
-    BOOL ret = FALSE;
-
-    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return FALSE;
-    }
-    if (!src_root)
-        ret = SetupQueueCopySectionW( queue, NULL, hinf, hlist, sectionW.Buffer, style );
-    else
-    {
-        UNICODE_STRING srcW;
-        if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))
-        {
-            ret = SetupQueueCopySectionW( queue, srcW.Buffer, hinf, hlist, sectionW.Buffer, style );
-            RtlFreeUnicodeString( &srcW );
-        }
-        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    }
-    RtlFreeUnicodeString( &sectionW );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupQueueCopySectionW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, HINF hlist,
-                                    PCWSTR section, DWORD style )
-{
-    SP_FILE_COPY_PARAMS_W params;
-    INFCONTEXT context;
-    WCHAR dest[MAX_PATH], src[MAX_PATH];
-    INT flags;
-
-    TRACE( "hinf=%p/%p section=%s root=%s\n",
-           hinf, hlist, debugstr_w(section), debugstr_w(src_root) );
-
-    params.cbSize             = sizeof(params);
-    params.QueueHandle        = queue;
-    params.SourceRootPath     = src_root;
-    params.SourcePath         = NULL;
-    params.SourceDescription  = NULL;
-    params.SourceTagfile      = NULL;
-    params.TargetFilename     = dest;
-    params.CopyStyle          = style;
-    params.LayoutInf          = hinf;
-    params.SecurityDescriptor = NULL;
-
-    if (!hlist) hlist = hinf;
-    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;
-    if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) return FALSE;
-    do
-    {
-        if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL ))
-            return FALSE;
-        if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0;
-        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;  /* FIXME */
-
-        params.SourceFilename = *src ? src : NULL;
-        if (!SetupQueueCopyIndirectW( &params )) return FALSE;
-    } while (SetupFindNextLine( &context, &context ));
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupQueueDeleteSectionA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDeleteSectionA( HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section )
-{
-    UNICODE_STRING sectionW;
-    BOOL ret = FALSE;
-
-    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        ret = SetupQueueDeleteSectionW( queue, hinf, hlist, sectionW.Buffer );
-        RtlFreeUnicodeString( &sectionW );
-    }
-    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupQueueDeleteSectionW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueDeleteSectionW( HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section )
-{
-    INFCONTEXT context;
-    WCHAR *dest_dir;
-    WCHAR buffer[MAX_PATH];
-    BOOL ret = FALSE;
-    INT flags;
-
-    TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );
-
-    if (!hlist) hlist = hinf;
-    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;
-    if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;
-    do
-    {
-        if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))
-            goto done;
-        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;
-        if (!SetupQueueDeleteW( queue, dest_dir, buffer )) goto done;
-    } while (SetupFindNextLine( &context, &context ));
-
-    ret = TRUE;
- done:
-    HeapFree( GetProcessHeap(), 0, dest_dir );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupQueueRenameSectionA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueRenameSectionA( HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section )
-{
-    UNICODE_STRING sectionW;
-    BOOL ret = FALSE;
-
-    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
-    {
-        ret = SetupQueueRenameSectionW( queue, hinf, hlist, sectionW.Buffer );
-        RtlFreeUnicodeString( &sectionW );
-    }
-    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupQueueRenameSectionW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupQueueRenameSectionW( HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section )
-{
-    INFCONTEXT context;
-    WCHAR *dest_dir;
-    WCHAR src[MAX_PATH], dst[MAX_PATH];
-    BOOL ret = FALSE;
-
-    TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );
-
-    if (!hlist) hlist = hinf;
-    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;
-    if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;
-    do
-    {
-        if (!SetupGetStringFieldW( &context, 1, dst, sizeof(dst)/sizeof(WCHAR), NULL ))
-            goto done;
-        if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL ))
-            goto done;
-        if (!SetupQueueRenameW( queue, dest_dir, src, NULL, dst )) goto done;
-    } while (SetupFindNextLine( &context, &context ));
-
-    ret = TRUE;
- done:
-    HeapFree( GetProcessHeap(), 0, dest_dir );
-    return ret;
-}
-
-
-/***********************************************************************
- *            SetupCommitFileQueueA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupCommitFileQueueA( HWND owner, HSPFILEQ queue, PSP_FILE_CALLBACK_A handler,
-                                   PVOID context )
-{
-    struct callback_WtoA_context ctx;
-
-    ctx.orig_context = context;
-    ctx.orig_handler = handler;
-    return SetupCommitFileQueueW( owner, queue, QUEUE_callback_WtoA, &ctx );
-}
-
-
-/***********************************************************************
- *            create_full_pathW
- *
- * Recursively create all directories in the path.
- */
-static BOOL create_full_pathW(const WCHAR *path)
-{
-    BOOL ret = TRUE;
-    int len;
-    WCHAR *new_path;
-
-    new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) * sizeof(WCHAR));
-    strcpyW(new_path, path);
-
-    while((len = strlenW(new_path)) && new_path[len - 1] == '\\')
-       new_path[len - 1] = 0;
-
-    while(!CreateDirectoryW(new_path, NULL))
-    {
-       WCHAR *slash;
-       DWORD last_error = GetLastError();
-
-       if(last_error == ERROR_ALREADY_EXISTS)
-           break;
-
-       if(last_error != ERROR_PATH_NOT_FOUND)
-       {
-           ret = FALSE;
-           break;
-       }
-
-       if(!(slash = strrchrW(new_path, '\\')))
-       {
-           ret = FALSE;
-           break;
-       }
-
-       len = slash - new_path;
-       new_path[len] = 0;
-       if(!create_full_pathW(new_path))
-       {
-           ret = FALSE;
-           break;
-       }
-       new_path[len] = '\\';
-    }
-
-    HeapFree(GetProcessHeap(), 0, new_path);
-    return ret;
-}
-
-BOOL static do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style)
-{
-    BOOL rc = FALSE;
-    BOOL docopy = TRUE;
-
-    TRACE("copy %s to %s style 0x%lx\n",debugstr_w(source),debugstr_w(target),style);
-
-    /* before copy processing */
-    if (style & SP_COPY_REPLACEONLY)
-    {
-        if (GetFileAttributesW(target) == INVALID_FILE_ATTRIBUTES)
-            docopy = FALSE;
-    }
-    if (style & (SP_COPY_NEWER_OR_SAME | SP_COPY_NEWER_ONLY | SP_COPY_FORCE_NEWER))
-    {
-        DWORD VersionSizeSource=0;
-        DWORD VersionSizeTarget=0;
-        DWORD zero=0;
-
-        /*
-         * This is sort of an interesting workaround. You see, calling
-         * GetVersionInfoSize on a builtin dll loads that dll into memory
-         * and we do not properly unload builtin dlls.. so we effectively
-         * lock into memory all the targets we are replacing. This leads
-         * to problems when we try to register the replaced dlls.
-         *
-         * So I will test for the existence of the files first so that
-         * we just basically unconditionally replace the builtin versions.
-         */
-        if ((GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES) &&
-            (GetFileAttributesW(source) != INVALID_FILE_ATTRIBUTES))
-        {
-            VersionSizeSource = GetFileVersionInfoSizeW(source,&zero);
-            VersionSizeTarget = GetFileVersionInfoSizeW(target,&zero);
-        }
-
-        TRACE("SizeTarget %li ... SizeSource %li\n",VersionSizeTarget,
-                VersionSizeSource);
-
-        if (VersionSizeSource && VersionSizeTarget)
-        {
-            LPVOID VersionSource;
-            LPVOID VersionTarget;
-            VS_FIXEDFILEINFO *TargetInfo;
-            VS_FIXEDFILEINFO *SourceInfo;
-            UINT length;
-            WCHAR  SubBlock[2]={'\\',0};
-            DWORD  ret;
-
-            VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);
-            VersionTarget = HeapAlloc(GetProcessHeap(),0,VersionSizeTarget);
-
-            ret = GetFileVersionInfoW(source,0,VersionSizeSource,VersionSource);
-            if (ret)
-              ret = GetFileVersionInfoW(target, 0, VersionSizeTarget,
-                    VersionTarget);
-
-            if (ret)
-            {
-                ret = VerQueryValueW(VersionSource, SubBlock,
-                                    (LPVOID*)&SourceInfo, &length);
-                if (ret)
-                    ret = VerQueryValueW(VersionTarget, SubBlock,
-                                         (LPVOID*)&TargetInfo, &length);
-
-                if (ret)
-                {
-                    TRACE("Versions: Source %li.%li target %li.%li\n",
-                      SourceInfo->dwFileVersionMS, SourceInfo->dwFileVersionLS,
-                      TargetInfo->dwFileVersionMS, TargetInfo->dwFileVersionLS);
-
-                    if (TargetInfo->dwFileVersionMS > SourceInfo->dwFileVersionMS)
-                    {
-                        FIXME("Notify that target version is greater..\n");
-                        docopy = FALSE;
-                    }
-                    else if ((TargetInfo->dwFileVersionMS == SourceInfo->dwFileVersionMS)
-                             && (TargetInfo->dwFileVersionLS > SourceInfo->dwFileVersionLS))
-                    {
-                        FIXME("Notify that target version is greater..\n");
-                        docopy = FALSE;
-                    }
-                    else if ((style & SP_COPY_NEWER_ONLY) &&
-                        (TargetInfo->dwFileVersionMS ==
-                         SourceInfo->dwFileVersionMS)
-                        &&(TargetInfo->dwFileVersionLS ==
-                        SourceInfo->dwFileVersionLS))
-                    {
-                        FIXME("Notify that target version is greater..\n");
-                        docopy = FALSE;
-                    }
-                }
-            }
-            HeapFree(GetProcessHeap(),0,VersionSource);
-            HeapFree(GetProcessHeap(),0,VersionTarget);
-        }
-    }
-    if (style & (SP_COPY_NOOVERWRITE | SP_COPY_FORCE_NOOVERWRITE))
-    {
-        if (GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES)
-        {
-            FIXME("Notify user target file exists\n");
-            docopy = FALSE;
-        }
-    }
-    if (style & (SP_COPY_NODECOMP | SP_COPY_LANGUAGEAWARE | SP_COPY_FORCE_IN_USE |
-                 SP_COPY_IN_USE_NEEDS_REBOOT | SP_COPY_NOSKIP | SP_COPY_WARNIFSKIP))
-    {
-        ERR("Unsupported style(s) 0x%lx\n",style);
-    }
-
-    if (docopy)
-    {
-        rc = CopyFileW(source,target,FALSE);
-        TRACE("Did copy... rc was %i\n",rc);
-    }
-
-    /* after copy processing */
-    if (style & SP_COPY_DELETESOURCE)
-    {
-       if (rc)
-            DeleteFileW(source);
-    }
-
-    return rc;
-}
-
-/***********************************************************************
- *            SetupCommitFileQueueW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBACK_W handler,
-                                   PVOID context )
-{
-    struct file_queue *queue = handle;
-    struct file_op *op;
-    BOOL result = FALSE;
-    FILEPATHS_W paths;
-    UINT op_result;
-
-    paths.Source = paths.Target = NULL;
-
-    if (!queue->copy_queue.count && !queue->delete_queue.count && !queue->rename_queue.count)
-        return TRUE;  /* nothing to do */
-
-    if (!handler( context, SPFILENOTIFY_STARTQUEUE, (UINT)owner, 0 )) return FALSE;
-
-    /* perform deletes */
-
-    if (queue->delete_queue.count)
-    {
-        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_DELETE,
-                       queue->delete_queue.count ))) goto done;
-        for (op = queue->delete_queue.head; op; op = op->next)
-        {
-            build_filepathsW( op, &paths );
-            op_result = handler( context, SPFILENOTIFY_STARTDELETE, (UINT_PTR)&paths, FILEOP_DELETE);
-            if (op_result == FILEOP_ABORT) goto done;
-            while (op_result == FILEOP_DOIT)
-            {
-                TRACE( "deleting file %s\n", debugstr_w(paths.Target) );
-                if (DeleteFileW( paths.Target )) break;  /* success */
-                paths.Win32Error = GetLastError();
-                op_result = handler( context, SPFILENOTIFY_DELETEERROR, (UINT_PTR)&paths, 0 );
-                if (op_result == FILEOP_ABORT) goto done;
-            }
-            handler( context, SPFILENOTIFY_ENDDELETE, (UINT_PTR)&paths, 0 );
-        }
-        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_DELETE, 0 );
-    }
-
-    /* perform renames */
-
-    if (queue->rename_queue.count)
-    {
-        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_RENAME,
-                       queue->rename_queue.count ))) goto done;
-        for (op = queue->rename_queue.head; op; op = op->next)
-        {
-            build_filepathsW( op, &paths );
-            op_result = handler( context, SPFILENOTIFY_STARTRENAME, (UINT_PTR)&paths, FILEOP_RENAME);
-            if (op_result == FILEOP_ABORT) goto done;
-            while (op_result == FILEOP_DOIT)
-            {
-                TRACE( "renaming file %s -> %s\n",
-                       debugstr_w(paths.Source), debugstr_w(paths.Target) );
-                if (MoveFileW( paths.Source, paths.Target )) break;  /* success */
-                paths.Win32Error = GetLastError();
-                op_result = handler( context, SPFILENOTIFY_RENAMEERROR, (UINT_PTR)&paths, 0 );
-                if (op_result == FILEOP_ABORT) goto done;
-            }
-            handler( context, SPFILENOTIFY_ENDRENAME, (UINT_PTR)&paths, 0 );
-        }
-        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_RENAME, 0 );
-    }
-
-    /* perform copies */
-
-    if (queue->copy_queue.count)
-    {
-        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_COPY,
-                       queue->copy_queue.count ))) goto done;
-        for (op = queue->copy_queue.head; op; op = op->next)
-        {
-            WCHAR newpath[MAX_PATH];
-
-            build_filepathsW( op, &paths );
-            op_result = handler( context, SPFILENOTIFY_STARTCOPY, (UINT_PTR)&paths, FILEOP_COPY );
-            if (op_result == FILEOP_ABORT) goto done;
-            if (op_result == FILEOP_NEWPATH) op_result = FILEOP_DOIT;
-            while (op_result == FILEOP_DOIT || op_result == FILEOP_NEWPATH)
-            {
-                TRACE( "copying file %s -> %s\n",
-                       debugstr_w( op_result == FILEOP_NEWPATH ? newpath : paths.Source ),
-                       debugstr_w(paths.Target) );
-                if (op->dst_path)
-               {
-                   if (!create_full_pathW( op->dst_path ))
-                   {
-                       paths.Win32Error = GetLastError();
-                       op_result = handler( context, SPFILENOTIFY_COPYERROR,
-                                            (UINT_PTR)&paths, (UINT_PTR)newpath );
-                       if (op_result == FILEOP_ABORT) goto done;
-                   }
-               }
-                if (do_file_copyW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,
-                               paths.Target, op->style )) break;  /* success */
-                /* try to extract it from the cabinet file */
-                if (op->src_tag)
-                {
-                    if (extract_cabinet_file( op->src_tag, op->src_root,
-                                              paths.Source, paths.Target )) break;
-                }
-                paths.Win32Error = GetLastError();
-                op_result = handler( context, SPFILENOTIFY_COPYERROR,
-                                     (UINT_PTR)&paths, (UINT_PTR)newpath );
-                if (op_result == FILEOP_ABORT) goto done;
-            }
-            handler( context, SPFILENOTIFY_ENDCOPY, (UINT_PTR)&paths, 0 );
-        }
-        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_COPY, 0 );
-    }
-
-
-    result = TRUE;
-
- done:
-    handler( context, SPFILENOTIFY_ENDQUEUE, result, 0 );
-    HeapFree( GetProcessHeap(), 0, (void *)paths.Source );
-    HeapFree( GetProcessHeap(), 0, (void *)paths.Target );
-    return result;
-}
-
-
-/***********************************************************************
- *            SetupScanFileQueueA   (SETUPAPI.@)
- */
-BOOL WINAPI SetupScanFileQueueA( HSPFILEQ queue, DWORD flags, HWND window,
-                                 PSP_FILE_CALLBACK_A callback, PVOID context, PDWORD result )
-{
-    FIXME("stub\n");
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupScanFileQueueW   (SETUPAPI.@)
- */
-BOOL WINAPI SetupScanFileQueueW( HSPFILEQ queue, DWORD flags, HWND window,
-                                 PSP_FILE_CALLBACK_W callback, PVOID context, PDWORD result )
-{
-    FIXME("stub\n");
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupGetFileQueueCount   (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetFileQueueCount( HSPFILEQ handle, UINT op, PUINT result )
-{
-    struct file_queue *queue = handle;
-
-    switch(op)
-    {
-    case FILEOP_COPY:
-        *result = queue->copy_queue.count;
-        return TRUE;
-    case FILEOP_RENAME:
-        *result = queue->rename_queue.count;
-        return TRUE;
-    case FILEOP_DELETE:
-        *result = queue->delete_queue.count;
-        return TRUE;
-    }
-    return FALSE;
-}
-
-
-/***********************************************************************
- *            SetupGetFileQueueFlags   (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetFileQueueFlags( HSPFILEQ handle, PDWORD flags )
-{
-    struct file_queue *queue = handle;
-    *flags = queue->flags;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupSetFileQueueFlags   (SETUPAPI.@)
- */
-BOOL WINAPI SetupSetFileQueueFlags( HSPFILEQ handle, DWORD mask, DWORD flags )
-{
-    struct file_queue *queue = handle;
-    queue->flags = (queue->flags & ~mask) | flags;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *            SetupInitDefaultQueueCallback   (SETUPAPI.@)
- */
-PVOID WINAPI SetupInitDefaultQueueCallback( HWND owner )
-{
-    return SetupInitDefaultQueueCallbackEx( owner, 0, 0, 0, NULL );
-}
-
-
-/***********************************************************************
- *            SetupInitDefaultQueueCallbackEx   (SETUPAPI.@)
- */
-PVOID WINAPI SetupInitDefaultQueueCallbackEx( HWND owner, HWND progress, UINT msg,
-                                              DWORD reserved1, PVOID reserved2 )
-{
-    struct default_callback_context *context;
-
-    if ((context = HeapAlloc( GetProcessHeap(), 0, sizeof(*context) )))
-    {
-        context->owner    = owner;
-        context->progress = progress;
-        context->message  = msg;
-    }
-    return context;
-}
-
-
-/***********************************************************************
- *            SetupTermDefaultQueueCallback   (SETUPAPI.@)
- */
-void WINAPI SetupTermDefaultQueueCallback( PVOID context )
-{
-    HeapFree( GetProcessHeap(), 0, context );
-}
-
-
-/***********************************************************************
- *            SetupDefaultQueueCallbackA   (SETUPAPI.@)
- */
-UINT WINAPI SetupDefaultQueueCallbackA( PVOID context, UINT notification,
-                                        UINT_PTR param1, UINT_PTR param2 )
-{
-    FILEPATHS_A *paths = (FILEPATHS_A *)param1;
-
-    switch(notification)
-    {
-    case SPFILENOTIFY_STARTQUEUE:
-        TRACE( "start queue\n" );
-        return TRUE;
-    case SPFILENOTIFY_ENDQUEUE:
-        TRACE( "end queue\n" );
-        return 0;
-    case SPFILENOTIFY_STARTSUBQUEUE:
-        TRACE( "start subqueue %d count %d\n", param1, param2 );
-        return TRUE;
-    case SPFILENOTIFY_ENDSUBQUEUE:
-        TRACE( "end subqueue %d\n", param1 );
-        return 0;
-    case SPFILENOTIFY_STARTDELETE:
-        TRACE( "start delete %s\n", debugstr_a(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDDELETE:
-        TRACE( "end delete %s\n", debugstr_a(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_DELETEERROR:
-        ERR( "delete error %d %s\n", paths->Win32Error, debugstr_a(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_STARTRENAME:
-        TRACE( "start rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDRENAME:
-        TRACE( "end rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_RENAMEERROR:
-        ERR( "rename error %d %s -> %s\n", paths->Win32Error,
-             debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_STARTCOPY:
-        TRACE( "start copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDCOPY:
-        TRACE( "end copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_COPYERROR:
-        ERR( "copy error %d %s -> %s\n", paths->Win32Error,
-             debugstr_a(paths->Source), debugstr_a(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_NEEDMEDIA:
-        TRACE( "need media\n" );
-        return FILEOP_SKIP;
-    default:
-        FIXME( "notification %d params %x,%x\n", notification, param1, param2 );
-        break;
-    }
-    return 0;
-}
-
-
-/***********************************************************************
- *            SetupDefaultQueueCallbackW   (SETUPAPI.@)
- */
-UINT WINAPI SetupDefaultQueueCallbackW( PVOID context, UINT notification,
-                                        UINT_PTR param1, UINT_PTR param2 )
-{
-    FILEPATHS_W *paths = (FILEPATHS_W *)param1;
-
-    switch(notification)
-    {
-    case SPFILENOTIFY_STARTQUEUE:
-        TRACE( "start queue\n" );
-        return TRUE;
-    case SPFILENOTIFY_ENDQUEUE:
-        TRACE( "end queue\n" );
-        return 0;
-    case SPFILENOTIFY_STARTSUBQUEUE:
-        TRACE( "start subqueue %d count %d\n", param1, param2 );
-        return TRUE;
-    case SPFILENOTIFY_ENDSUBQUEUE:
-        TRACE( "end subqueue %d\n", param1 );
-        return 0;
-    case SPFILENOTIFY_STARTDELETE:
-        TRACE( "start delete %s\n", debugstr_w(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDDELETE:
-        TRACE( "end delete %s\n", debugstr_w(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_DELETEERROR:
-        ERR( "delete error %d %s\n", paths->Win32Error, debugstr_w(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_STARTRENAME:
-        TRACE( "start rename %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDRENAME:
-        TRACE( "end rename %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_RENAMEERROR:
-        ERR( "rename error %d %s -> %s\n", paths->Win32Error,
-             debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_STARTCOPY:
-        TRACE( "start copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return FILEOP_DOIT;
-    case SPFILENOTIFY_ENDCOPY:
-        TRACE( "end copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return 0;
-    case SPFILENOTIFY_COPYERROR:
-        ERR( "copy error %d %s -> %s\n", paths->Win32Error,
-             debugstr_w(paths->Source), debugstr_w(paths->Target) );
-        return FILEOP_SKIP;
-    case SPFILENOTIFY_NEEDMEDIA:
-        TRACE( "need media\n" );
-        return FILEOP_SKIP;
-    default:
-        FIXME( "notification %d params %x,%x\n", notification, param1, param2 );
-        break;
-    }
-    return 0;
-}
+/*\r
+ * Setupapi file queue routines\r
+ *\r
+ * Copyright 2002 Alexandre Julliard for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winternl.h"\r
+#include "winerror.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "wine/unicode.h"\r
+#include "setupapi_private.h"\r
+#include "winver.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+/* context structure for the default queue callback */\r
+struct default_callback_context\r
+{\r
+    HWND owner;\r
+    HWND progress;\r
+    UINT message;\r
+};\r
+\r
+struct file_op\r
+{\r
+    struct file_op *next;\r
+    UINT            style;\r
+    WCHAR          *src_root;\r
+    WCHAR          *src_path;\r
+    WCHAR          *src_file;\r
+    WCHAR          *src_descr;\r
+    WCHAR          *src_tag;\r
+    WCHAR          *dst_path;\r
+    WCHAR          *dst_file;\r
+};\r
+\r
+struct file_op_queue\r
+{\r
+    struct file_op *head;\r
+    struct file_op *tail;\r
+    unsigned int count;\r
+};\r
+\r
+struct file_queue\r
+{\r
+    struct file_op_queue copy_queue;\r
+    struct file_op_queue delete_queue;\r
+    struct file_op_queue rename_queue;\r
+    DWORD                flags;\r
+};\r
+\r
+\r
+inline static WCHAR *strdupW( const WCHAR *str )\r
+{\r
+    WCHAR *ret = NULL;\r
+    if (str)\r
+    {\r
+        int len = (strlenW(str) + 1) * sizeof(WCHAR);\r
+        if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( ret, str, len );\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+inline static WCHAR *strdupAtoW( const char *str )\r
+{\r
+    WCHAR *ret = NULL;\r
+    if (str)\r
+    {\r
+        DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );\r
+        if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))\r
+            MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );\r
+    }\r
+    return ret;\r
+}\r
+\r
+inline static char *strdupWtoA( const WCHAR *str )\r
+{\r
+    char *ret = NULL;\r
+    if (str)\r
+    {\r
+        DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );\r
+        if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))\r
+            WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );\r
+    }\r
+    return ret;\r
+}\r
+\r
+/* append a file operation to a queue */\r
+inline static void queue_file_op( struct file_op_queue *queue, struct file_op *op )\r
+{\r
+    op->next = NULL;\r
+    if (queue->tail) queue->tail->next = op;\r
+    else queue->head = op;\r
+    queue->tail = op;\r
+    queue->count++;\r
+}\r
+\r
+/* free all the file operations on a given queue */\r
+static void free_file_op_queue( struct file_op_queue *queue )\r
+{\r
+    struct file_op *t, *op = queue->head;\r
+\r
+    while( op )\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, op->src_root );\r
+        HeapFree( GetProcessHeap(), 0, op->src_path );\r
+        HeapFree( GetProcessHeap(), 0, op->src_file );\r
+        HeapFree( GetProcessHeap(), 0, op->src_descr );\r
+        HeapFree( GetProcessHeap(), 0, op->src_tag );\r
+        HeapFree( GetProcessHeap(), 0, op->dst_path );\r
+        if (op->dst_file != op->src_file) HeapFree( GetProcessHeap(), 0, op->dst_file );\r
+        t = op;\r
+        op = op->next;\r
+        HeapFree( GetProcessHeap(), 0, t );\r
+    }\r
+}\r
+\r
+/* concat 3 strings to make a path, handling separators correctly */\r
+static void concat_W( WCHAR *buffer, const WCHAR *src1, const WCHAR *src2, const WCHAR *src3 )\r
+{\r
+    *buffer = 0;\r
+    if (src1 && *src1)\r
+    {\r
+        strcpyW( buffer, src1 );\r
+        buffer += strlenW(buffer );\r
+        if (buffer[-1] != '\\') *buffer++ = '\\';\r
+        if (src2) while (*src2 == '\\') src2++;\r
+    }\r
+\r
+    if (src2)\r
+    {\r
+        strcpyW( buffer, src2 );\r
+        buffer += strlenW(buffer );\r
+        if (buffer[-1] != '\\') *buffer++ = '\\';\r
+        if (src3) while (*src3 == '\\') src3++;\r
+    }\r
+    if (src3)\r
+    {\r
+        strcpyW( buffer, src3 );\r
+        buffer += strlenW(buffer );\r
+    }\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            build_filepathsW\r
+ *\r
+ * Build a FILEPATHS_W structure for a given file operation.\r
+ */\r
+static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )\r
+{\r
+    unsigned int src_len = 1, dst_len = 1;\r
+    WCHAR *source = (PWSTR)paths->Source, *target = (PWSTR)paths->Target;\r
+\r
+    if (op->src_root) src_len += strlenW(op->src_root) + 1;\r
+    if (op->src_path) src_len += strlenW(op->src_path) + 1;\r
+    if (op->src_file) src_len += strlenW(op->src_file) + 1;\r
+    if (op->dst_path) dst_len += strlenW(op->dst_path) + 1;\r
+    if (op->dst_file) dst_len += strlenW(op->dst_file) + 1;\r
+    src_len *= sizeof(WCHAR);\r
+    dst_len *= sizeof(WCHAR);\r
+\r
+    if (!source || HeapSize( GetProcessHeap(), 0, source ) < src_len )\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, source );\r
+        paths->Source = source = HeapAlloc( GetProcessHeap(), 0, src_len );\r
+    }\r
+    if (!target || HeapSize( GetProcessHeap(), 0, target ) < dst_len )\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, target );\r
+        paths->Target = target = HeapAlloc( GetProcessHeap(), 0, dst_len );\r
+    }\r
+    if (!source || !target) return FALSE;\r
+    concat_W( source, op->src_root, op->src_path, op->src_file );\r
+    concat_W( target, NULL, op->dst_path, op->dst_file );\r
+    paths->Win32Error = 0;\r
+    paths->Flags      = 0;\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            QUEUE_callback_WtoA\r
+ *\r
+ * Map a file callback parameters from W to A and call the A callback.\r
+ */\r
+UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification,\r
+                                   UINT_PTR param1, UINT_PTR param2 )\r
+{\r
+    struct callback_WtoA_context *callback_ctx = context;\r
+    char buffer[MAX_PATH];\r
+    UINT ret;\r
+    UINT_PTR old_param2 = param2;\r
+\r
+    switch(notification)\r
+    {\r
+    case SPFILENOTIFY_COPYERROR:\r
+        param2 = (UINT_PTR)&buffer;\r
+        /* fall through */\r
+    case SPFILENOTIFY_STARTDELETE:\r
+    case SPFILENOTIFY_ENDDELETE:\r
+    case SPFILENOTIFY_DELETEERROR:\r
+    case SPFILENOTIFY_STARTRENAME:\r
+    case SPFILENOTIFY_ENDRENAME:\r
+    case SPFILENOTIFY_RENAMEERROR:\r
+    case SPFILENOTIFY_STARTCOPY:\r
+    case SPFILENOTIFY_ENDCOPY:\r
+        {\r
+            FILEPATHS_W *pathsW = (FILEPATHS_W *)param1;\r
+            FILEPATHS_A pathsA;\r
+\r
+            pathsA.Source     = strdupWtoA( pathsW->Source );\r
+            pathsA.Target     = strdupWtoA( pathsW->Target );\r
+            pathsA.Win32Error = pathsW->Win32Error;\r
+            pathsA.Flags      = pathsW->Flags;\r
+            ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,\r
+                                              (UINT_PTR)&pathsA, param2 );\r
+            HeapFree( GetProcessHeap(), 0, (void *)pathsA.Source );\r
+            HeapFree( GetProcessHeap(), 0, (void *)pathsA.Target );\r
+        }\r
+        if (notification == SPFILENOTIFY_COPYERROR)\r
+            MultiByteToWideChar( CP_ACP, 0, buffer, -1, (WCHAR *)old_param2, MAX_PATH );\r
+        break;\r
+\r
+    case SPFILENOTIFY_STARTREGISTRATION:\r
+    case SPFILENOTIFY_ENDREGISTRATION:\r
+        {\r
+            SP_REGISTER_CONTROL_STATUSW *statusW = (SP_REGISTER_CONTROL_STATUSW *)param1;\r
+            SP_REGISTER_CONTROL_STATUSA statusA;\r
+\r
+            statusA.cbSize = sizeof(statusA);\r
+            statusA.FileName = strdupWtoA( statusW->FileName );\r
+            statusA.Win32Error  = statusW->Win32Error;\r
+            statusA.FailureCode = statusW->FailureCode;\r
+            ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification,\r
+                                              (UINT_PTR)&statusA, param2 );\r
+            HeapFree( GetProcessHeap(), 0, (LPSTR)statusA.FileName );\r
+        }\r
+        break;\r
+\r
+    case SPFILENOTIFY_NEEDMEDIA:\r
+    case SPFILENOTIFY_QUEUESCAN:\r
+        FIXME("mapping for %d not implemented\n",notification);\r
+    case SPFILENOTIFY_STARTQUEUE:\r
+    case SPFILENOTIFY_ENDQUEUE:\r
+    case SPFILENOTIFY_STARTSUBQUEUE:\r
+    case SPFILENOTIFY_ENDSUBQUEUE:\r
+    default:\r
+        ret = callback_ctx->orig_handler( callback_ctx->orig_context, notification, param1, param2 );\r
+        break;\r
+    }\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            get_src_file_info\r
+ *\r
+ * Retrieve the source file information for a given file.\r
+ */\r
+static void get_src_file_info( HINF hinf, struct file_op *op )\r
+{\r
+    static const WCHAR SourceDisksNames[] =\r
+        {'S','o','u','r','c','e','D','i','s','k','s','N','a','m','e','s',0};\r
+    static const WCHAR SourceDisksFiles[] =\r
+        {'S','o','u','r','c','e','D','i','s','k','s','F','i','l','e','s',0};\r
+\r
+    INFCONTEXT file_ctx, disk_ctx;\r
+    INT id, diskid;\r
+    DWORD len, len2;\r
+\r
+    /* find the SourceDisksFiles entry */\r
+    if (!SetupFindFirstLineW( hinf, SourceDisksFiles, op->src_file, &file_ctx ))\r
+    {\r
+        const WCHAR *dir;\r
+\r
+        if ((op->style & (SP_COPY_SOURCE_ABSOLUTE|SP_COPY_SOURCEPATH_ABSOLUTE))) return;\r
+        /* no specific info, use .inf file source directory */\r
+        if (!op->src_root && (dir = DIRID_get_string( hinf, DIRID_SRCPATH )))\r
+            op->src_root = strdupW( dir );\r
+        return;\r
+    }\r
+    if (!SetupGetIntField( &file_ctx, 1, &diskid )) return;\r
+\r
+    /* now find the diskid in the SourceDisksNames section */\r
+    if (!SetupFindFirstLineW( hinf, SourceDisksNames, NULL, &disk_ctx )) return;\r
+    for (;;)\r
+    {\r
+        if (SetupGetIntField( &disk_ctx, 0, &id ) && (id == diskid)) break;\r
+        if (!SetupFindNextLine( &disk_ctx, &disk_ctx )) return;\r
+    }\r
+\r
+    /* and fill in the missing info */\r
+\r
+    if (!op->src_descr)\r
+    {\r
+        if (SetupGetStringFieldW( &disk_ctx, 1, NULL, 0, &len ) &&\r
+            (op->src_descr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))\r
+            SetupGetStringFieldW( &disk_ctx, 1, op->src_descr, len, NULL );\r
+    }\r
+    if (!op->src_tag)\r
+    {\r
+        if (SetupGetStringFieldW( &disk_ctx, 2, NULL, 0, &len ) &&\r
+            (op->src_tag = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) )))\r
+            SetupGetStringFieldW( &disk_ctx, 2, op->src_tag, len, NULL );\r
+    }\r
+    if (!op->src_path && !(op->style & SP_COPY_SOURCE_ABSOLUTE))\r
+    {\r
+        if (!(op->style & SP_COPY_SOURCEPATH_ABSOLUTE))\r
+        {\r
+            /* retrieve relative path for this disk */\r
+            if (!SetupGetStringFieldW( &disk_ctx, 4, NULL, 0, &len )) len = 0;\r
+        }\r
+        /* retrieve relative path for this file */\r
+        if (!SetupGetStringFieldW( &file_ctx, 2, NULL, 0, &len2 )) len2 = 0;\r
+\r
+        if ((len || len2) &&\r
+            (op->src_path = HeapAlloc( GetProcessHeap(), 0, (len+len2)*sizeof(WCHAR) )))\r
+        {\r
+            WCHAR *ptr = op->src_path;\r
+            if (len)\r
+            {\r
+                SetupGetStringFieldW( &disk_ctx, 4, op->src_path, len, NULL );\r
+                ptr = op->src_path + strlenW(op->src_path);\r
+                if (len2 && ptr > op->src_path && ptr[-1] != '\\') *ptr++ = '\\';\r
+            }\r
+            if (!SetupGetStringFieldW( &disk_ctx, 4, ptr, len2, NULL )) *ptr = 0;\r
+        }\r
+    }\r
+    if (!op->src_root) op->src_root = strdupW( PARSER_get_src_root(hinf) );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            get_destination_dir\r
+ *\r
+ * Retrieve the destination dir for a given section.\r
+ */\r
+static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )\r
+{\r
+    static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};\r
+    static const WCHAR Def[]  = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};\r
+    INFCONTEXT context;\r
+\r
+    if (!SetupFindFirstLineW( hinf, Dest, section, &context ) &&\r
+        !SetupFindFirstLineW( hinf, Dest, Def, &context )) return NULL;\r
+    return PARSER_get_dest_dir( &context );\r
+}\r
+\r
+\r
+static void (WINAPI *pExtractFiles)( LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD );\r
+\r
+/***********************************************************************\r
+ *            extract_cabinet_file\r
+ *\r
+ * Extract a file from a .cab file.\r
+ */\r
+static BOOL extract_cabinet_file( const WCHAR *cabinet, const WCHAR *root,\r
+                                  const WCHAR *src, const WCHAR *dst )\r
+{\r
+    static const WCHAR extW[] = {'.','c','a','b',0};\r
+    static HMODULE advpack;\r
+\r
+    char *cab_path, *cab_file;\r
+    int len = strlenW( cabinet );\r
+\r
+    /* make sure the cabinet file has a .cab extension */\r
+    if (len <= 4 || strcmpiW( cabinet + len - 4, extW )) return FALSE;\r
+    if (!pExtractFiles)\r
+    {\r
+        if (!advpack && !(advpack = LoadLibraryA( "advpack.dll" )))\r
+        {\r
+            ERR( "could not load advpack.dll\n" );\r
+            return FALSE;\r
+        }\r
+        if (!(pExtractFiles = (void *)GetProcAddress( advpack, "ExtractFiles" )))\r
+        {\r
+            ERR( "could not find ExtractFiles in advpack.dll\n" );\r
+            return FALSE;\r
+        }\r
+    }\r
+\r
+    if (!(cab_path = strdupWtoA( root ))) return FALSE;\r
+    len = WideCharToMultiByte( CP_ACP, 0, cabinet, -1, NULL, 0, NULL, NULL );\r
+    if (!(cab_file = HeapAlloc( GetProcessHeap(), 0, strlen(cab_path) + len + 1 )))\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, cab_path );\r
+        return FALSE;\r
+    }\r
+    strcpy( cab_file, cab_path );\r
+    if (cab_file[0] && cab_file[strlen(cab_file)-1] != '\\') strcat( cab_file, "\\" );\r
+    WideCharToMultiByte( CP_ACP, 0, cabinet, -1, cab_file + strlen(cab_file), len, NULL, NULL );\r
+    FIXME( "awful hack: extracting cabinet %s\n", debugstr_a(cab_file) );\r
+    pExtractFiles( cab_file, cab_path, 0, 0, 0, 0 );\r
+    HeapFree( GetProcessHeap(), 0, cab_file );\r
+    HeapFree( GetProcessHeap(), 0, cab_path );\r
+    return CopyFileW( src, dst, FALSE /*FIXME*/ );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupOpenFileQueue   (SETUPAPI.@)\r
+ */\r
+HSPFILEQ WINAPI SetupOpenFileQueue(void)\r
+{\r
+    struct file_queue *queue;\r
+\r
+    if (!(queue = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*queue))))\r
+        return (HSPFILEQ)INVALID_HANDLE_VALUE;\r
+    return queue;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupCloseFileQueue   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupCloseFileQueue( HSPFILEQ handle )\r
+{\r
+    struct file_queue *queue = handle;\r
+\r
+    free_file_op_queue( &queue->copy_queue );\r
+    free_file_op_queue( &queue->rename_queue );\r
+    free_file_op_queue( &queue->delete_queue );\r
+    HeapFree( GetProcessHeap(), 0, queue );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopyIndirectA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopyIndirectA( PSP_FILE_COPY_PARAMS_A params )\r
+{\r
+    struct file_queue *queue = params->QueueHandle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = params->CopyStyle;\r
+    op->src_root   = strdupAtoW( params->SourceRootPath );\r
+    op->src_path   = strdupAtoW( params->SourcePath );\r
+    op->src_file   = strdupAtoW( params->SourceFilename );\r
+    op->src_descr  = strdupAtoW( params->SourceDescription );\r
+    op->src_tag    = strdupAtoW( params->SourceTagfile );\r
+    op->dst_path   = strdupAtoW( params->TargetDirectory );\r
+    op->dst_file   = strdupAtoW( params->TargetFilename );\r
+\r
+    /* some defaults */\r
+    if (!op->src_file) op->src_file = op->dst_file;\r
+    if (params->LayoutInf)\r
+    {\r
+        get_src_file_info( params->LayoutInf, op );\r
+        if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );\r
+    }\r
+\r
+    TRACE( "root=%s path=%s file=%s -> dir=%s file=%s  descr=%s tag=%s\n",\r
+           debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),\r
+           debugstr_w(op->dst_path), debugstr_w(op->dst_file),\r
+           debugstr_w(op->src_descr), debugstr_w(op->src_tag) );\r
+\r
+    queue_file_op( &queue->copy_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopyIndirectW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params )\r
+{\r
+    struct file_queue *queue = params->QueueHandle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = params->CopyStyle;\r
+    op->src_root   = strdupW( params->SourceRootPath );\r
+    op->src_path   = strdupW( params->SourcePath );\r
+    op->src_file   = strdupW( params->SourceFilename );\r
+    op->src_descr  = strdupW( params->SourceDescription );\r
+    op->src_tag    = strdupW( params->SourceTagfile );\r
+    op->dst_path   = strdupW( params->TargetDirectory );\r
+    op->dst_file   = strdupW( params->TargetFilename );\r
+\r
+    /* some defaults */\r
+    if (!op->src_file) op->src_file = op->dst_file;\r
+    if (params->LayoutInf)\r
+    {\r
+        get_src_file_info( params->LayoutInf, op );\r
+        if (!op->dst_path) op->dst_path = get_destination_dir( params->LayoutInf, op->dst_file );\r
+    }\r
+\r
+    TRACE( "root=%s path=%s file=%s -> dir=%s file=%s  descr=%s tag=%s\n",\r
+           debugstr_w(op->src_root), debugstr_w(op->src_path), debugstr_w(op->src_file),\r
+           debugstr_w(op->dst_path), debugstr_w(op->dst_file),\r
+           debugstr_w(op->src_descr), debugstr_w(op->src_tag) );\r
+\r
+    queue_file_op( &queue->copy_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopyA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopyA( HSPFILEQ queue, PCSTR src_root, PCSTR src_path, PCSTR src_file,\r
+                             PCSTR src_descr, PCSTR src_tag, PCSTR dst_dir, PCSTR dst_file,\r
+                             DWORD style )\r
+{\r
+    SP_FILE_COPY_PARAMS_A params;\r
+\r
+    params.cbSize             = sizeof(params);\r
+    params.QueueHandle        = queue;\r
+    params.SourceRootPath     = src_root;\r
+    params.SourcePath         = src_path;\r
+    params.SourceFilename     = src_file;\r
+    params.SourceDescription  = src_descr;\r
+    params.SourceTagfile      = src_tag;\r
+    params.TargetDirectory    = dst_dir;\r
+    params.TargetFilename     = dst_file;\r
+    params.CopyStyle          = style;\r
+    params.LayoutInf          = 0;\r
+    params.SecurityDescriptor = NULL;\r
+    return SetupQueueCopyIndirectA( &params );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopyW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopyW( HSPFILEQ queue, PCWSTR src_root, PCWSTR src_path, PCWSTR src_file,\r
+                             PCWSTR src_descr, PCWSTR src_tag, PCWSTR dst_dir, PCWSTR dst_file,\r
+                             DWORD style )\r
+{\r
+    SP_FILE_COPY_PARAMS_W params;\r
+\r
+    params.cbSize             = sizeof(params);\r
+    params.QueueHandle        = queue;\r
+    params.SourceRootPath     = src_root;\r
+    params.SourcePath         = src_path;\r
+    params.SourceFilename     = src_file;\r
+    params.SourceDescription  = src_descr;\r
+    params.SourceTagfile      = src_tag;\r
+    params.TargetDirectory    = dst_dir;\r
+    params.TargetFilename     = dst_file;\r
+    params.CopyStyle          = style;\r
+    params.LayoutInf          = 0;\r
+    params.SecurityDescriptor = NULL;\r
+    return SetupQueueCopyIndirectW( &params );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDefaultCopyA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDefaultCopyA( HSPFILEQ queue, HINF hinf, PCSTR src_root, PCSTR src_file,\r
+                                    PCSTR dst_file, DWORD style )\r
+{\r
+    SP_FILE_COPY_PARAMS_A params;\r
+\r
+    params.cbSize             = sizeof(params);\r
+    params.QueueHandle        = queue;\r
+    params.SourceRootPath     = src_root;\r
+    params.SourcePath         = NULL;\r
+    params.SourceFilename     = src_file;\r
+    params.SourceDescription  = NULL;\r
+    params.SourceTagfile      = NULL;\r
+    params.TargetDirectory    = NULL;\r
+    params.TargetFilename     = dst_file;\r
+    params.CopyStyle          = style;\r
+    params.LayoutInf          = hinf;\r
+    params.SecurityDescriptor = NULL;\r
+    return SetupQueueCopyIndirectA( &params );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDefaultCopyW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDefaultCopyW( HSPFILEQ queue, HINF hinf, PCWSTR src_root, PCWSTR src_file,\r
+                                    PCWSTR dst_file, DWORD style )\r
+{\r
+    SP_FILE_COPY_PARAMS_W params;\r
+\r
+    params.cbSize             = sizeof(params);\r
+    params.QueueHandle        = queue;\r
+    params.SourceRootPath     = src_root;\r
+    params.SourcePath         = NULL;\r
+    params.SourceFilename     = src_file;\r
+    params.SourceDescription  = NULL;\r
+    params.SourceTagfile      = NULL;\r
+    params.TargetDirectory    = NULL;\r
+    params.TargetFilename     = dst_file;\r
+    params.CopyStyle          = style;\r
+    params.LayoutInf          = hinf;\r
+    params.SecurityDescriptor = NULL;\r
+    return SetupQueueCopyIndirectW( &params );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDeleteA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDeleteA( HSPFILEQ handle, PCSTR part1, PCSTR part2 )\r
+{\r
+    struct file_queue *queue = handle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = 0;\r
+    op->src_root   = NULL;\r
+    op->src_path   = NULL;\r
+    op->src_file   = NULL;\r
+    op->src_descr  = NULL;\r
+    op->src_tag    = NULL;\r
+    op->dst_path   = strdupAtoW( part1 );\r
+    op->dst_file   = strdupAtoW( part2 );\r
+    queue_file_op( &queue->delete_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDeleteW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDeleteW( HSPFILEQ handle, PCWSTR part1, PCWSTR part2 )\r
+{\r
+    struct file_queue *queue = handle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = 0;\r
+    op->src_root   = NULL;\r
+    op->src_path   = NULL;\r
+    op->src_file   = NULL;\r
+    op->src_descr  = NULL;\r
+    op->src_tag    = NULL;\r
+    op->dst_path   = strdupW( part1 );\r
+    op->dst_file   = strdupW( part2 );\r
+    queue_file_op( &queue->delete_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueRenameA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueRenameA( HSPFILEQ handle, PCSTR SourcePath, PCSTR SourceFilename,\r
+                               PCSTR TargetPath, PCSTR TargetFilename )\r
+{\r
+    struct file_queue *queue = handle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = 0;\r
+    op->src_root   = NULL;\r
+    op->src_path   = strdupAtoW( SourcePath );\r
+    op->src_file   = strdupAtoW( SourceFilename );\r
+    op->src_descr  = NULL;\r
+    op->src_tag    = NULL;\r
+    op->dst_path   = strdupAtoW( TargetPath );\r
+    op->dst_file   = strdupAtoW( TargetFilename );\r
+    queue_file_op( &queue->rename_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueRenameW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueRenameW( HSPFILEQ handle, PCWSTR SourcePath, PCWSTR SourceFilename,\r
+                               PCWSTR TargetPath, PCWSTR TargetFilename )\r
+{\r
+    struct file_queue *queue = handle;\r
+    struct file_op *op;\r
+\r
+    if (!(op = HeapAlloc( GetProcessHeap(), 0, sizeof(*op) ))) return FALSE;\r
+    op->style      = 0;\r
+    op->src_root   = NULL;\r
+    op->src_path   = strdupW( SourcePath );\r
+    op->src_file   = strdupW( SourceFilename );\r
+    op->src_descr  = NULL;\r
+    op->src_tag    = NULL;\r
+    op->dst_path   = strdupW( TargetPath );\r
+    op->dst_file   = strdupW( TargetFilename );\r
+    queue_file_op( &queue->rename_queue, op );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopySectionA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopySectionA( HSPFILEQ queue, PCSTR src_root, HINF hinf, HINF hlist,\r
+                                    PCSTR section, DWORD style )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+        return FALSE;\r
+    }\r
+    if (!src_root)\r
+        ret = SetupQueueCopySectionW( queue, NULL, hinf, hlist, sectionW.Buffer, style );\r
+    else\r
+    {\r
+        UNICODE_STRING srcW;\r
+        if (RtlCreateUnicodeStringFromAsciiz( &srcW, src_root ))\r
+        {\r
+            ret = SetupQueueCopySectionW( queue, srcW.Buffer, hinf, hlist, sectionW.Buffer, style );\r
+            RtlFreeUnicodeString( &srcW );\r
+        }\r
+        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    }\r
+    RtlFreeUnicodeString( &sectionW );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueCopySectionW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, HINF hlist,\r
+                                    PCWSTR section, DWORD style )\r
+{\r
+    SP_FILE_COPY_PARAMS_W params;\r
+    INFCONTEXT context;\r
+    WCHAR dest[MAX_PATH], src[MAX_PATH];\r
+    INT flags;\r
+\r
+    TRACE( "hinf=%p/%p section=%s root=%s\n",\r
+           hinf, hlist, debugstr_w(section), debugstr_w(src_root) );\r
+\r
+    params.cbSize             = sizeof(params);\r
+    params.QueueHandle        = queue;\r
+    params.SourceRootPath     = src_root;\r
+    params.SourcePath         = NULL;\r
+    params.SourceDescription  = NULL;\r
+    params.SourceTagfile      = NULL;\r
+    params.TargetFilename     = dest;\r
+    params.CopyStyle          = style;\r
+    params.LayoutInf          = hinf;\r
+    params.SecurityDescriptor = NULL;\r
+\r
+    if (!hlist) hlist = hinf;\r
+    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;\r
+    if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) return FALSE;\r
+    do\r
+    {\r
+        if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL ))\r
+            return FALSE;\r
+        if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0;\r
+        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;  /* FIXME */\r
+\r
+        params.SourceFilename = *src ? src : NULL;\r
+        if (!SetupQueueCopyIndirectW( &params )) return FALSE;\r
+    } while (SetupFindNextLine( &context, &context ));\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDeleteSectionA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDeleteSectionA( HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        ret = SetupQueueDeleteSectionW( queue, hinf, hlist, sectionW.Buffer );\r
+        RtlFreeUnicodeString( &sectionW );\r
+    }\r
+    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueDeleteSectionW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueDeleteSectionW( HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section )\r
+{\r
+    INFCONTEXT context;\r
+    WCHAR *dest_dir;\r
+    WCHAR buffer[MAX_PATH];\r
+    BOOL ret = FALSE;\r
+    INT flags;\r
+\r
+    TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );\r
+\r
+    if (!hlist) hlist = hinf;\r
+    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;\r
+    if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;\r
+    do\r
+    {\r
+        if (!SetupGetStringFieldW( &context, 1, buffer, sizeof(buffer)/sizeof(WCHAR), NULL ))\r
+            goto done;\r
+        if (!SetupGetIntField( &context, 4, &flags )) flags = 0;\r
+        if (!SetupQueueDeleteW( queue, dest_dir, buffer )) goto done;\r
+    } while (SetupFindNextLine( &context, &context ));\r
+\r
+    ret = TRUE;\r
+ done:\r
+    HeapFree( GetProcessHeap(), 0, dest_dir );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueRenameSectionA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueRenameSectionA( HSPFILEQ queue, HINF hinf, HINF hlist, PCSTR section )\r
+{\r
+    UNICODE_STRING sectionW;\r
+    BOOL ret = FALSE;\r
+\r
+    if (RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))\r
+    {\r
+        ret = SetupQueueRenameSectionW( queue, hinf, hlist, sectionW.Buffer );\r
+        RtlFreeUnicodeString( &sectionW );\r
+    }\r
+    else SetLastError( ERROR_NOT_ENOUGH_MEMORY );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupQueueRenameSectionW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupQueueRenameSectionW( HSPFILEQ queue, HINF hinf, HINF hlist, PCWSTR section )\r
+{\r
+    INFCONTEXT context;\r
+    WCHAR *dest_dir;\r
+    WCHAR src[MAX_PATH], dst[MAX_PATH];\r
+    BOOL ret = FALSE;\r
+\r
+    TRACE( "hinf=%p/%p section=%s\n", hinf, hlist, debugstr_w(section) );\r
+\r
+    if (!hlist) hlist = hinf;\r
+    if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE;\r
+    if (!(dest_dir = get_destination_dir( hinf, section ))) return FALSE;\r
+    do\r
+    {\r
+        if (!SetupGetStringFieldW( &context, 1, dst, sizeof(dst)/sizeof(WCHAR), NULL ))\r
+            goto done;\r
+        if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL ))\r
+            goto done;\r
+        if (!SetupQueueRenameW( queue, dest_dir, src, NULL, dst )) goto done;\r
+    } while (SetupFindNextLine( &context, &context ));\r
+\r
+    ret = TRUE;\r
+ done:\r
+    HeapFree( GetProcessHeap(), 0, dest_dir );\r
+    return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupCommitFileQueueA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupCommitFileQueueA( HWND owner, HSPFILEQ queue, PSP_FILE_CALLBACK_A handler,\r
+                                   PVOID context )\r
+{\r
+    struct callback_WtoA_context ctx;\r
+\r
+    ctx.orig_context = context;\r
+    ctx.orig_handler = handler;\r
+    return SetupCommitFileQueueW( owner, queue, QUEUE_callback_WtoA, &ctx );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            create_full_pathW\r
+ *\r
+ * Recursively create all directories in the path.\r
+ */\r
+static BOOL create_full_pathW(const WCHAR *path)\r
+{\r
+    BOOL ret = TRUE;\r
+    int len;\r
+    WCHAR *new_path;\r
+\r
+    new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) * sizeof(WCHAR));\r
+    strcpyW(new_path, path);\r
+\r
+    while((len = strlenW(new_path)) && new_path[len - 1] == '\\')\r
+       new_path[len - 1] = 0;\r
+\r
+    while(!CreateDirectoryW(new_path, NULL))\r
+    {\r
+       WCHAR *slash;\r
+       DWORD last_error = GetLastError();\r
+\r
+       if(last_error == ERROR_ALREADY_EXISTS)\r
+           break;\r
+\r
+       if(last_error != ERROR_PATH_NOT_FOUND)\r
+       {\r
+           ret = FALSE;\r
+           break;\r
+       }\r
+\r
+       if(!(slash = strrchrW(new_path, '\\')))\r
+       {\r
+           ret = FALSE;\r
+           break;\r
+       }\r
+\r
+       len = slash - new_path;\r
+       new_path[len] = 0;\r
+       if(!create_full_pathW(new_path))\r
+       {\r
+           ret = FALSE;\r
+           break;\r
+       }\r
+       new_path[len] = '\\';\r
+    }\r
+\r
+    HeapFree(GetProcessHeap(), 0, new_path);\r
+    return ret;\r
+}\r
+\r
+BOOL static do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style)\r
+{\r
+    BOOL rc = FALSE;\r
+    BOOL docopy = TRUE;\r
+\r
+    TRACE("copy %s to %s style 0x%lx\n",debugstr_w(source),debugstr_w(target),style);\r
+\r
+    /* before copy processing */\r
+    if (style & SP_COPY_REPLACEONLY)\r
+    {\r
+        if (GetFileAttributesW(target) == INVALID_FILE_ATTRIBUTES)\r
+            docopy = FALSE;\r
+    }\r
+    if (style & (SP_COPY_NEWER_OR_SAME | SP_COPY_NEWER_ONLY | SP_COPY_FORCE_NEWER))\r
+    {\r
+        DWORD VersionSizeSource=0;\r
+        DWORD VersionSizeTarget=0;\r
+        DWORD zero=0;\r
+\r
+        /*\r
+         * This is sort of an interesting workaround. You see, calling\r
+         * GetVersionInfoSize on a builtin dll loads that dll into memory\r
+         * and we do not properly unload builtin dlls.. so we effectively\r
+         * lock into memory all the targets we are replacing. This leads\r
+         * to problems when we try to register the replaced dlls.\r
+         *\r
+         * So I will test for the existence of the files first so that\r
+         * we just basically unconditionally replace the builtin versions.\r
+         */\r
+        if ((GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES) &&\r
+            (GetFileAttributesW(source) != INVALID_FILE_ATTRIBUTES))\r
+        {\r
+            VersionSizeSource = GetFileVersionInfoSizeW(source,&zero);\r
+            VersionSizeTarget = GetFileVersionInfoSizeW(target,&zero);\r
+        }\r
+\r
+        TRACE("SizeTarget %li ... SizeSource %li\n",VersionSizeTarget,\r
+                VersionSizeSource);\r
+\r
+        if (VersionSizeSource && VersionSizeTarget)\r
+        {\r
+            LPVOID VersionSource;\r
+            LPVOID VersionTarget;\r
+            VS_FIXEDFILEINFO *TargetInfo;\r
+            VS_FIXEDFILEINFO *SourceInfo;\r
+            UINT length;\r
+            WCHAR  SubBlock[2]={'\\',0};\r
+            DWORD  ret;\r
+\r
+            VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);\r
+            VersionTarget = HeapAlloc(GetProcessHeap(),0,VersionSizeTarget);\r
+\r
+            ret = GetFileVersionInfoW(source,0,VersionSizeSource,VersionSource);\r
+            if (ret)\r
+              ret = GetFileVersionInfoW(target, 0, VersionSizeTarget,\r
+                    VersionTarget);\r
+\r
+            if (ret)\r
+            {\r
+                ret = VerQueryValueW(VersionSource, SubBlock,\r
+                                    (LPVOID*)&SourceInfo, &length);\r
+                if (ret)\r
+                    ret = VerQueryValueW(VersionTarget, SubBlock,\r
+                                         (LPVOID*)&TargetInfo, &length);\r
+\r
+                if (ret)\r
+                {\r
+                    TRACE("Versions: Source %li.%li target %li.%li\n",\r
+                      SourceInfo->dwFileVersionMS, SourceInfo->dwFileVersionLS,\r
+                      TargetInfo->dwFileVersionMS, TargetInfo->dwFileVersionLS);\r
+\r
+                    if (TargetInfo->dwFileVersionMS > SourceInfo->dwFileVersionMS)\r
+                    {\r
+                        FIXME("Notify that target version is greater..\n");\r
+                        docopy = FALSE;\r
+                    }\r
+                    else if ((TargetInfo->dwFileVersionMS == SourceInfo->dwFileVersionMS)\r
+                             && (TargetInfo->dwFileVersionLS > SourceInfo->dwFileVersionLS))\r
+                    {\r
+                        FIXME("Notify that target version is greater..\n");\r
+                        docopy = FALSE;\r
+                    }\r
+                    else if ((style & SP_COPY_NEWER_ONLY) &&\r
+                        (TargetInfo->dwFileVersionMS ==\r
+                         SourceInfo->dwFileVersionMS)\r
+                        &&(TargetInfo->dwFileVersionLS ==\r
+                        SourceInfo->dwFileVersionLS))\r
+                    {\r
+                        FIXME("Notify that target version is greater..\n");\r
+                        docopy = FALSE;\r
+                    }\r
+                }\r
+            }\r
+            HeapFree(GetProcessHeap(),0,VersionSource);\r
+            HeapFree(GetProcessHeap(),0,VersionTarget);\r
+        }\r
+    }\r
+    if (style & (SP_COPY_NOOVERWRITE | SP_COPY_FORCE_NOOVERWRITE))\r
+    {\r
+        if (GetFileAttributesW(target) != INVALID_FILE_ATTRIBUTES)\r
+        {\r
+            FIXME("Notify user target file exists\n");\r
+            docopy = FALSE;\r
+        }\r
+    }\r
+    if (style & (SP_COPY_NODECOMP | SP_COPY_LANGUAGEAWARE | SP_COPY_FORCE_IN_USE |\r
+                 SP_COPY_IN_USE_NEEDS_REBOOT | SP_COPY_NOSKIP | SP_COPY_WARNIFSKIP))\r
+    {\r
+        ERR("Unsupported style(s) 0x%lx\n",style);\r
+    }\r
+\r
+    if (docopy)\r
+    {\r
+        rc = CopyFileW(source,target,FALSE);\r
+        TRACE("Did copy... rc was %i\n",rc);\r
+    }\r
+\r
+    /* after copy processing */\r
+    if (style & SP_COPY_DELETESOURCE)\r
+    {\r
+       if (rc)\r
+            DeleteFileW(source);\r
+    }\r
+\r
+    return rc;\r
+}\r
+\r
+/***********************************************************************\r
+ *            SetupCommitFileQueueW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupCommitFileQueueW( HWND owner, HSPFILEQ handle, PSP_FILE_CALLBACK_W handler,\r
+                                   PVOID context )\r
+{\r
+    struct file_queue *queue = handle;\r
+    struct file_op *op;\r
+    BOOL result = FALSE;\r
+    FILEPATHS_W paths;\r
+    UINT op_result;\r
+\r
+    paths.Source = paths.Target = NULL;\r
+\r
+    if (!queue->copy_queue.count && !queue->delete_queue.count && !queue->rename_queue.count)\r
+        return TRUE;  /* nothing to do */\r
+\r
+    if (!handler( context, SPFILENOTIFY_STARTQUEUE, (UINT)owner, 0 )) return FALSE;\r
+\r
+    /* perform deletes */\r
+\r
+    if (queue->delete_queue.count)\r
+    {\r
+        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_DELETE,\r
+                       queue->delete_queue.count ))) goto done;\r
+        for (op = queue->delete_queue.head; op; op = op->next)\r
+        {\r
+            build_filepathsW( op, &paths );\r
+            op_result = handler( context, SPFILENOTIFY_STARTDELETE, (UINT_PTR)&paths, FILEOP_DELETE);\r
+            if (op_result == FILEOP_ABORT) goto done;\r
+            while (op_result == FILEOP_DOIT)\r
+            {\r
+                TRACE( "deleting file %s\n", debugstr_w(paths.Target) );\r
+                if (DeleteFileW( paths.Target )) break;  /* success */\r
+                paths.Win32Error = GetLastError();\r
+                op_result = handler( context, SPFILENOTIFY_DELETEERROR, (UINT_PTR)&paths, 0 );\r
+                if (op_result == FILEOP_ABORT) goto done;\r
+            }\r
+            handler( context, SPFILENOTIFY_ENDDELETE, (UINT_PTR)&paths, 0 );\r
+        }\r
+        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_DELETE, 0 );\r
+    }\r
+\r
+    /* perform renames */\r
+\r
+    if (queue->rename_queue.count)\r
+    {\r
+        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_RENAME,\r
+                       queue->rename_queue.count ))) goto done;\r
+        for (op = queue->rename_queue.head; op; op = op->next)\r
+        {\r
+            build_filepathsW( op, &paths );\r
+            op_result = handler( context, SPFILENOTIFY_STARTRENAME, (UINT_PTR)&paths, FILEOP_RENAME);\r
+            if (op_result == FILEOP_ABORT) goto done;\r
+            while (op_result == FILEOP_DOIT)\r
+            {\r
+                TRACE( "renaming file %s -> %s\n",\r
+                       debugstr_w(paths.Source), debugstr_w(paths.Target) );\r
+                if (MoveFileW( paths.Source, paths.Target )) break;  /* success */\r
+                paths.Win32Error = GetLastError();\r
+                op_result = handler( context, SPFILENOTIFY_RENAMEERROR, (UINT_PTR)&paths, 0 );\r
+                if (op_result == FILEOP_ABORT) goto done;\r
+            }\r
+            handler( context, SPFILENOTIFY_ENDRENAME, (UINT_PTR)&paths, 0 );\r
+        }\r
+        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_RENAME, 0 );\r
+    }\r
+\r
+    /* perform copies */\r
+\r
+    if (queue->copy_queue.count)\r
+    {\r
+        if (!(handler( context, SPFILENOTIFY_STARTSUBQUEUE, FILEOP_COPY,\r
+                       queue->copy_queue.count ))) goto done;\r
+        for (op = queue->copy_queue.head; op; op = op->next)\r
+        {\r
+            WCHAR newpath[MAX_PATH];\r
+\r
+            build_filepathsW( op, &paths );\r
+            op_result = handler( context, SPFILENOTIFY_STARTCOPY, (UINT_PTR)&paths, FILEOP_COPY );\r
+            if (op_result == FILEOP_ABORT) goto done;\r
+            if (op_result == FILEOP_NEWPATH) op_result = FILEOP_DOIT;\r
+            while (op_result == FILEOP_DOIT || op_result == FILEOP_NEWPATH)\r
+            {\r
+                TRACE( "copying file %s -> %s\n",\r
+                       debugstr_w( op_result == FILEOP_NEWPATH ? newpath : paths.Source ),\r
+                       debugstr_w(paths.Target) );\r
+                if (op->dst_path)\r
+               {\r
+                   if (!create_full_pathW( op->dst_path ))\r
+                   {\r
+                       paths.Win32Error = GetLastError();\r
+                       op_result = handler( context, SPFILENOTIFY_COPYERROR,\r
+                                            (UINT_PTR)&paths, (UINT_PTR)newpath );\r
+                       if (op_result == FILEOP_ABORT) goto done;\r
+                   }\r
+               }\r
+                if (do_file_copyW( op_result == FILEOP_NEWPATH ? newpath : paths.Source,\r
+                               paths.Target, op->style )) break;  /* success */\r
+                /* try to extract it from the cabinet file */\r
+                if (op->src_tag)\r
+                {\r
+                    if (extract_cabinet_file( op->src_tag, op->src_root,\r
+                                              paths.Source, paths.Target )) break;\r
+                }\r
+                paths.Win32Error = GetLastError();\r
+                op_result = handler( context, SPFILENOTIFY_COPYERROR,\r
+                                     (UINT_PTR)&paths, (UINT_PTR)newpath );\r
+                if (op_result == FILEOP_ABORT) goto done;\r
+            }\r
+            handler( context, SPFILENOTIFY_ENDCOPY, (UINT_PTR)&paths, 0 );\r
+        }\r
+        handler( context, SPFILENOTIFY_ENDSUBQUEUE, FILEOP_COPY, 0 );\r
+    }\r
+\r
+\r
+    result = TRUE;\r
+\r
+ done:\r
+    handler( context, SPFILENOTIFY_ENDQUEUE, result, 0 );\r
+    HeapFree( GetProcessHeap(), 0, (void *)paths.Source );\r
+    HeapFree( GetProcessHeap(), 0, (void *)paths.Target );\r
+    return result;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupScanFileQueueA   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupScanFileQueueA( HSPFILEQ queue, DWORD flags, HWND window,\r
+                                 PSP_FILE_CALLBACK_A callback, PVOID context, PDWORD result )\r
+{\r
+    FIXME("stub\n");\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupScanFileQueueW   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupScanFileQueueW( HSPFILEQ queue, DWORD flags, HWND window,\r
+                                 PSP_FILE_CALLBACK_W callback, PVOID context, PDWORD result )\r
+{\r
+    FIXME("stub\n");\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetFileQueueCount   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetFileQueueCount( HSPFILEQ handle, UINT op, PUINT result )\r
+{\r
+    struct file_queue *queue = handle;\r
+\r
+    switch(op)\r
+    {\r
+    case FILEOP_COPY:\r
+        *result = queue->copy_queue.count;\r
+        return TRUE;\r
+    case FILEOP_RENAME:\r
+        *result = queue->rename_queue.count;\r
+        return TRUE;\r
+    case FILEOP_DELETE:\r
+        *result = queue->delete_queue.count;\r
+        return TRUE;\r
+    }\r
+    return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupGetFileQueueFlags   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetFileQueueFlags( HSPFILEQ handle, PDWORD flags )\r
+{\r
+    struct file_queue *queue = handle;\r
+    *flags = queue->flags;\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupSetFileQueueFlags   (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupSetFileQueueFlags( HSPFILEQ handle, DWORD mask, DWORD flags )\r
+{\r
+    struct file_queue *queue = handle;\r
+    queue->flags = (queue->flags & ~mask) | flags;\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInitDefaultQueueCallback   (SETUPAPI.@)\r
+ */\r
+PVOID WINAPI SetupInitDefaultQueueCallback( HWND owner )\r
+{\r
+    return SetupInitDefaultQueueCallbackEx( owner, 0, 0, 0, NULL );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupInitDefaultQueueCallbackEx   (SETUPAPI.@)\r
+ */\r
+PVOID WINAPI SetupInitDefaultQueueCallbackEx( HWND owner, HWND progress, UINT msg,\r
+                                              DWORD reserved1, PVOID reserved2 )\r
+{\r
+    struct default_callback_context *context;\r
+\r
+    if ((context = HeapAlloc( GetProcessHeap(), 0, sizeof(*context) )))\r
+    {\r
+        context->owner    = owner;\r
+        context->progress = progress;\r
+        context->message  = msg;\r
+    }\r
+    return context;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupTermDefaultQueueCallback   (SETUPAPI.@)\r
+ */\r
+void WINAPI SetupTermDefaultQueueCallback( PVOID context )\r
+{\r
+    HeapFree( GetProcessHeap(), 0, context );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupDefaultQueueCallbackA   (SETUPAPI.@)\r
+ */\r
+UINT WINAPI SetupDefaultQueueCallbackA( PVOID context, UINT notification,\r
+                                        UINT_PTR param1, UINT_PTR param2 )\r
+{\r
+    FILEPATHS_A *paths = (FILEPATHS_A *)param1;\r
+\r
+    switch(notification)\r
+    {\r
+    case SPFILENOTIFY_STARTQUEUE:\r
+        TRACE( "start queue\n" );\r
+        return TRUE;\r
+    case SPFILENOTIFY_ENDQUEUE:\r
+        TRACE( "end queue\n" );\r
+        return 0;\r
+    case SPFILENOTIFY_STARTSUBQUEUE:\r
+        TRACE( "start subqueue %d count %d\n", param1, param2 );\r
+        return TRUE;\r
+    case SPFILENOTIFY_ENDSUBQUEUE:\r
+        TRACE( "end subqueue %d\n", param1 );\r
+        return 0;\r
+    case SPFILENOTIFY_STARTDELETE:\r
+        TRACE( "start delete %s\n", debugstr_a(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDDELETE:\r
+        TRACE( "end delete %s\n", debugstr_a(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_DELETEERROR:\r
+        ERR( "delete error %d %s\n", paths->Win32Error, debugstr_a(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_STARTRENAME:\r
+        TRACE( "start rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDRENAME:\r
+        TRACE( "end rename %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_RENAMEERROR:\r
+        ERR( "rename error %d %s -> %s\n", paths->Win32Error,\r
+             debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_STARTCOPY:\r
+        TRACE( "start copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDCOPY:\r
+        TRACE( "end copy %s -> %s\n", debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_COPYERROR:\r
+        ERR( "copy error %d %s -> %s\n", paths->Win32Error,\r
+             debugstr_a(paths->Source), debugstr_a(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_NEEDMEDIA:\r
+        TRACE( "need media\n" );\r
+        return FILEOP_SKIP;\r
+    default:\r
+        FIXME( "notification %d params %x,%x\n", notification, param1, param2 );\r
+        break;\r
+    }\r
+    return 0;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *            SetupDefaultQueueCallbackW   (SETUPAPI.@)\r
+ */\r
+UINT WINAPI SetupDefaultQueueCallbackW( PVOID context, UINT notification,\r
+                                        UINT_PTR param1, UINT_PTR param2 )\r
+{\r
+    FILEPATHS_W *paths = (FILEPATHS_W *)param1;\r
+\r
+    switch(notification)\r
+    {\r
+    case SPFILENOTIFY_STARTQUEUE:\r
+        TRACE( "start queue\n" );\r
+        return TRUE;\r
+    case SPFILENOTIFY_ENDQUEUE:\r
+        TRACE( "end queue\n" );\r
+        return 0;\r
+    case SPFILENOTIFY_STARTSUBQUEUE:\r
+        TRACE( "start subqueue %d count %d\n", param1, param2 );\r
+        return TRUE;\r
+    case SPFILENOTIFY_ENDSUBQUEUE:\r
+        TRACE( "end subqueue %d\n", param1 );\r
+        return 0;\r
+    case SPFILENOTIFY_STARTDELETE:\r
+        TRACE( "start delete %s\n", debugstr_w(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDDELETE:\r
+        TRACE( "end delete %s\n", debugstr_w(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_DELETEERROR:\r
+        ERR( "delete error %d %s\n", paths->Win32Error, debugstr_w(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_STARTRENAME:\r
+        TRACE( "start rename %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDRENAME:\r
+        TRACE( "end rename %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_RENAMEERROR:\r
+        ERR( "rename error %d %s -> %s\n", paths->Win32Error,\r
+             debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_STARTCOPY:\r
+        TRACE( "start copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return FILEOP_DOIT;\r
+    case SPFILENOTIFY_ENDCOPY:\r
+        TRACE( "end copy %s -> %s\n", debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return 0;\r
+    case SPFILENOTIFY_COPYERROR:\r
+        ERR( "copy error %d %s -> %s\n", paths->Win32Error,\r
+             debugstr_w(paths->Source), debugstr_w(paths->Target) );\r
+        return FILEOP_SKIP;\r
+    case SPFILENOTIFY_NEEDMEDIA:\r
+        TRACE( "need media\n" );\r
+        return FILEOP_SKIP;\r
+    default:\r
+        FIXME( "notification %d params %x,%x\n", notification, param1, param2 );\r
+        break;\r
+    }\r
+    return 0;\r
+}\r
diff --git a/reactos/lib/setupapi/rpc.c b/reactos/lib/setupapi/rpc.c
new file mode 100644 (file)
index 0000000..cb3b08b
--- /dev/null
@@ -0,0 +1,82 @@
+/* rpc.c */\r
+\r
+#include <windows.h>\r
+#include <rpc.h>\r
+#include <rpcdce.h>\r
+\r
+\r
+static RPC_BINDING_HANDLE LocalBindingHandle = NULL;\r
+\r
+\r
+RPC_STATUS\r
+PnpBindRpc(LPWSTR pszMachine,\r
+           RPC_BINDING_HANDLE* BindingHandle)\r
+{\r
+  PWSTR pszStringBinding = NULL;\r
+  RPC_STATUS Status;\r
+\r
+  Status = RpcStringBindingComposeW(NULL,\r
+                                   L"ncacn_np",\r
+                                   pszMachine,\r
+                                   L"\\pipe\\umpnpmgr",\r
+                                   NULL,\r
+                                   &pszStringBinding);\r
+  if (Status != RPC_S_OK)\r
+    return Status;\r
+\r
+  Status = RpcBindingFromStringBindingW(pszStringBinding,\r
+                                       BindingHandle);\r
+\r
+  RpcStringFreeW(&pszStringBinding);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+RPC_STATUS\r
+PnpUnbindRpc(RPC_BINDING_HANDLE *BindingHandle)\r
+{\r
+  if (BindingHandle != NULL)\r
+  {\r
+    RpcBindingFree(*BindingHandle);\r
+    *BindingHandle = NULL;\r
+  }\r
+\r
+  return RPC_S_OK;\r
+}\r
+\r
+\r
+RPC_STATUS\r
+PnpGetLocalBindingHandle(RPC_BINDING_HANDLE *BindingHandle)\r
+{\r
+  if (LocalBindingHandle != NULL)\r
+  {\r
+    BindingHandle = LocalBindingHandle;\r
+    return RPC_S_OK;\r
+  }\r
+\r
+  return PnpBindRpc(NULL, BindingHandle);\r
+}\r
+\r
+\r
+RPC_STATUS\r
+PnpUnbindLocalBindingHandle(VOID)\r
+{\r
+  return PnpUnbindRpc(&LocalBindingHandle);\r
+}\r
+\r
+\r
+void __RPC_FAR * __RPC_USER\r
+midl_user_allocate(size_t len)\r
+{\r
+  return GlobalAlloc(GPTR, len);\r
+}\r
+\r
+\r
+void __RPC_USER\r
+midl_user_free(void __RPC_FAR * ptr)\r
+{\r
+  GlobalFree(ptr);\r
+}\r
+\r
+/* EOF */\r
index ed5d642..9cc3d89 100644 (file)
@@ -1,36 +1,37 @@
-/*
- * Top level resource file for SETUPX
- *
- * Copyright 2001 Andreas Mohr
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "windef.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi_private.h"
-
-#include "Cs.rc"
-#include "De.rc"
-#include "En.rc"
-#include "Es.rc"
-#include "Fr.rc"
-#include "It.rc"
-#include "Ja.rc"
-#include "Nl.rc"
-#include "Pt.rc"
-#include "Ru.rc"
+/*\r
+ * Top level resource file for SETUPX\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi_private.h"\r
+\r
+#include "Cs.rc"\r
+#include "Da.rc"\r
+#include "De.rc"\r
+#include "En.rc"\r
+#include "Es.rc"\r
+#include "Fr.rc"\r
+#include "It.rc"\r
+#include "Ja.rc"\r
+#include "Nl.rc"\r
+#include "Pt.rc"\r
+#include "Ru.rc"\r
index 262f457..277bea8 100644 (file)
-@ stub AcquireSCMLock
-@ stub AddMiniIconToList
-@ stub AddTagToGroupOrderListEntry
-@ stub AppendStringToMultiSz
-@ stub AssertFail
-@ stub CMP_Init_Detection
-@ stub CMP_RegisterNotification
-@ stub CMP_Report_LogOn
-@ stub CMP_UnregisterNotification
-@ stub CMP_WaitNoPendingInstallEvents
-@ stub CMP_WaitServices
-@ stub CM_Add_Empty_Log_Conf
-@ stub CM_Add_Empty_Log_Conf_Ex
-@ stub CM_Add_IDA
-@ stub CM_Add_IDW
-@ stub CM_Add_ID_ExA
-@ stub CM_Add_ID_ExW
-@ stub CM_Add_Range
-@ stub CM_Add_Res_Des
-@ stub CM_Add_Res_Des_Ex
-@ stdcall CM_Connect_MachineA(str ptr)
-@ stdcall CM_Connect_MachineW(wstr ptr)
-@ stub CM_Create_DevNodeA
-@ stub CM_Create_DevNodeW
-@ stub CM_Create_DevNode_ExA
-@ stub CM_Create_DevNode_ExW
-@ stub CM_Create_Range_List
-@ stub CM_Delete_Class_Key
-@ stub CM_Delete_Class_Key_Ex
-@ stub CM_Delete_DevNode_Key
-@ stub CM_Delete_DevNode_Key_Ex
-@ stub CM_Delete_Range
-@ stub CM_Detect_Resource_Conflict
-@ stub CM_Detect_Resource_Conflict_Ex
-@ stub CM_Disable_DevNode
-@ stub CM_Disable_DevNode_Ex
-@ stdcall CM_Disconnect_Machine(long)
-@ stub CM_Dup_Range_List
-@ stub CM_Enable_DevNode
-@ stub CM_Enable_DevNode_Ex
-@ stub CM_Enumerate_Classes
-@ stub CM_Enumerate_Classes_Ex
-@ stub CM_Enumerate_EnumeratorsA
-@ stub CM_Enumerate_EnumeratorsW
-@ stub CM_Enumerate_Enumerators_ExA
-@ stub CM_Enumerate_Enumerators_ExW
-@ stub CM_Find_Range
-@ stub CM_First_Range
-@ stub CM_Free_Log_Conf
-@ stub CM_Free_Log_Conf_Ex
-@ stub CM_Free_Log_Conf_Handle
-@ stub CM_Free_Range_List
-@ stub CM_Free_Res_Des
-@ stub CM_Free_Res_Des_Ex
-@ stub CM_Free_Res_Des_Handle
-@ stub CM_Get_Child
-@ stub CM_Get_Child_Ex
-@ stub CM_Get_Class_Key_NameA
-@ stub CM_Get_Class_Key_NameW
-@ stub CM_Get_Class_Key_Name_ExA
-@ stub CM_Get_Class_Key_Name_ExW
-@ stub CM_Get_Class_NameA
-@ stub CM_Get_Class_NameW
-@ stub CM_Get_Class_Name_ExA
-@ stub CM_Get_Class_Name_ExW
-@ stub CM_Get_Depth
-@ stub CM_Get_Depth_Ex
-@ stub CM_Get_DevNode_Registry_PropertyA
-@ stub CM_Get_DevNode_Registry_PropertyW
-@ stub CM_Get_DevNode_Registry_Property_ExA
-@ stub CM_Get_DevNode_Registry_Property_ExW
-@ stub CM_Get_DevNode_Status
-@ stub CM_Get_DevNode_Status_Ex
-@ stub CM_Get_Device_IDA
-@ stub CM_Get_Device_IDW
-@ stub CM_Get_Device_ID_ExA
-@ stub CM_Get_Device_ID_ExW
-@ stdcall CM_Get_Device_ID_ListA(str str long long)
-@ stdcall CM_Get_Device_ID_ListW(wstr wstr long long)
-@ stdcall CM_Get_Device_ID_List_ExA(str str long long long)
-@ stdcall CM_Get_Device_ID_List_ExW(wstr wstr long long long)
-@ stdcall CM_Get_Device_ID_List_SizeA(ptr str long)
-@ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long)
-@ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long long)
-@ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long long)
-@ stub CM_Get_Device_ID_Size
-@ stub CM_Get_Device_ID_Size_Ex
-@ stub CM_Get_Device_Interface_AliasA
-@ stub CM_Get_Device_Interface_AliasW
-@ stub CM_Get_Device_Interface_Alias_ExA
-@ stub CM_Get_Device_Interface_Alias_ExW
-@ stub CM_Get_Device_Interface_ListA
-@ stub CM_Get_Device_Interface_ListW
-@ stub CM_Get_Device_Interface_List_ExA
-@ stub CM_Get_Device_Interface_List_ExW
-@ stub CM_Get_Device_Interface_List_SizeA
-@ stub CM_Get_Device_Interface_List_SizeW
-@ stub CM_Get_Device_Interface_List_Size_ExA
-@ stub CM_Get_Device_Interface_List_Size_ExW
-@ stub CM_Get_First_Log_Conf
-@ stub CM_Get_First_Log_Conf_Ex
-@ stub CM_Get_Global_State
-@ stub CM_Get_Global_State_Ex
-@ stub CM_Get_HW_Prof_FlagsA
-@ stub CM_Get_HW_Prof_FlagsW
-@ stub CM_Get_HW_Prof_Flags_ExA
-@ stub CM_Get_HW_Prof_Flags_ExW
-@ stub CM_Get_Hardware_Profile_InfoA
-@ stub CM_Get_Hardware_Profile_InfoW
-@ stub CM_Get_Hardware_Profile_Info_ExA
-@ stub CM_Get_Hardware_Profile_Info_ExW
-@ stub CM_Get_Log_Conf_Priority
-@ stub CM_Get_Log_Conf_Priority_Ex
-@ stub CM_Get_Next_Log_Conf
-@ stub CM_Get_Next_Log_Conf_Ex
-@ stub CM_Get_Next_Res_Des
-@ stub CM_Get_Next_Res_Des_Ex
-@ stub CM_Get_Parent
-@ stub CM_Get_Parent_Ex
-@ stub CM_Get_Res_Des_Data
-@ stub CM_Get_Res_Des_Data_Ex
-@ stub CM_Get_Res_Des_Data_Size
-@ stub CM_Get_Res_Des_Data_Size_Ex
-@ stub CM_Get_Sibling
-@ stub CM_Get_Sibling_Ex
-@ stub CM_Get_Version
-@ stub CM_Get_Version_Ex
-@ stub CM_Intersect_Range_List
-@ stub CM_Invert_Range_List
-@ stub CM_Is_Dock_Station_Present
-@ stub CM_Locate_DevNodeA
-@ stub CM_Locate_DevNodeW
-@ stub CM_Locate_DevNode_ExA
-@ stub CM_Locate_DevNode_ExW
-@ stub CM_Merge_Range_List
-@ stub CM_Modify_Res_Des
-@ stub CM_Modify_Res_Des_Ex
-@ stub CM_Move_DevNode
-@ stub CM_Move_DevNode_Ex
-@ stub CM_Next_Range
-@ stub CM_Open_Class_KeyA
-@ stub CM_Open_Class_KeyW
-@ stub CM_Open_Class_Key_ExA
-@ stub CM_Open_Class_Key_ExW
-@ stub CM_Open_DevNode_Key
-@ stub CM_Open_DevNode_Key_Ex
-@ stub CM_Query_Arbitrator_Free_Data
-@ stub CM_Query_Arbitrator_Free_Data_Ex
-@ stub CM_Query_Arbitrator_Free_Size
-@ stub CM_Query_Arbitrator_Free_Size_Ex
-@ stub CM_Query_Remove_SubTree
-@ stub CM_Query_Remove_SubTree_Ex
-@ stub CM_Reenumerate_DevNode
-@ stub CM_Reenumerate_DevNode_Ex
-@ stub CM_Register_Device_Driver
-@ stub CM_Register_Device_Driver_Ex
-@ stub CM_Register_Device_InterfaceA
-@ stub CM_Register_Device_InterfaceW
-@ stub CM_Register_Device_Interface_ExA
-@ stub CM_Register_Device_Interface_ExW
-@ stub CM_Remove_SubTree
-@ stub CM_Remove_SubTree_Ex
-@ stub CM_Remove_Unmarked_Children
-@ stub CM_Remove_Unmarked_Children_Ex
-@ stub CM_Request_Device_EjectA
-@ stub CM_Request_Device_EjectW
-@ stub CM_Request_Eject_PC
-@ stub CM_Reset_Children_Marks
-@ stub CM_Reset_Children_Marks_Ex
-@ stub CM_Run_Detection
-@ stub CM_Run_Detection_Ex
-@ stub CM_Set_DevNode_Problem
-@ stub CM_Set_DevNode_Problem_Ex
-@ stub CM_Set_DevNode_Registry_PropertyA
-@ stub CM_Set_DevNode_Registry_PropertyW
-@ stub CM_Set_DevNode_Registry_Property_ExA
-@ stub CM_Set_DevNode_Registry_Property_ExW
-@ stub CM_Set_HW_Prof
-@ stub CM_Set_HW_Prof_Ex
-@ stub CM_Set_HW_Prof_FlagsA
-@ stub CM_Set_HW_Prof_FlagsW
-@ stub CM_Set_HW_Prof_Flags_ExA
-@ stub CM_Set_HW_Prof_Flags_ExW
-@ stub CM_Setup_DevNode
-@ stub CM_Setup_DevNode_Ex
-@ stub CM_Test_Range_Available
-@ stub CM_Uninstall_DevNode
-@ stub CM_Uninstall_DevNode_Ex
-@ stub CM_Unregister_Device_InterfaceA
-@ stub CM_Unregister_Device_InterfaceW
-@ stub CM_Unregister_Device_Interface_ExA
-@ stub CM_Unregister_Device_Interface_ExW
-@ stdcall CaptureAndConvertAnsiArg(str ptr)
-@ stdcall CaptureStringArg(wstr ptr)
-@ stub CenterWindowRelativeToParent
-@ stub ConcatenatePaths
-@ stdcall DelayedMove(wstr wstr)
-@ stub DelimStringToMultiSz
-@ stub DestroyTextFileReadBuffer
-@ stdcall DoesUserHavePrivilege(wstr)
-@ stdcall DuplicateString(wstr)
-@ stdcall EnablePrivilege(wstr long)
-@ stub ExtensionPropSheetPageProc
-@ stdcall FileExists(wstr ptr)
-@ stub FreeStringArray
-@ stub GetCurrentDriverSigningPolicy
-@ stub GetNewInfName
-@ stub GetSetFileTimestamp
-@ stub GetVersionInfoFromImage
-@ stub InfIsFromOemLocation
-@ stub InstallCatalog
-@ stdcall InstallHinfSection(long long str long) InstallHinfSectionA
-@ stdcall InstallHinfSectionA(long long str long)
-@ stdcall InstallHinfSectionW(long long wstr long)
-@ stub InstallStop
-@ stub InstallStopEx
-@ stdcall IsUserAdmin()
-@ stub LookUpStringInTable
-@ stub MemoryInitialize
-@ stdcall MultiByteToUnicode(str long)
-@ stub MultiSzFromSearchControl
-@ stdcall MyFree(ptr)
-@ stub MyGetFileTitle
-@ stdcall MyMalloc(long)
-@ stdcall MyRealloc(ptr long)
-@ stub OpenAndMapFileForRead
-@ stub OutOfMemory
-@ stub QueryMultiSzValueToArray
-@ stdcall QueryRegistryValue(long wstr ptr ptr ptr)
-@ stub ReadAsciiOrUnicodeTextFile
-@ stub RegistryDelnode
-@ stub RetreiveFileSecurity
-@ stub RetrieveServiceConfig
-@ stub SearchForInfFile
-@ stub SetArrayToMultiSzValue
-@ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long)
-@ stub SetupAddInstallSectionToDiskSpaceListW
-@ stub SetupAddSectionToDiskSpaceListA
-@ stub SetupAddSectionToDiskSpaceListW
-@ stub SetupAddToDiskSpaceListA
-@ stub SetupAddToDiskSpaceListW
-@ stub SetupAddToSourceListA
-@ stub SetupAddToSourceListW
-@ stub SetupAdjustDiskSpaceListA
-@ stub SetupAdjustDiskSpaceListW
-@ stub SetupCancelTemporarySourceList
-@ stdcall SetupCloseFileQueue(ptr)
-@ stdcall SetupCloseInfFile(long)
-@ stub SetupCloseLog
-@ stdcall SetupCommitFileQueue(long long ptr ptr) SetupCommitFileQueueW
-@ stdcall SetupCommitFileQueueA(long long ptr ptr)
-@ stdcall SetupCommitFileQueueW(long long ptr ptr)
-@ stub SetupCopyErrorA
-@ stub SetupCopyErrorW
-@ stdcall SetupCopyOEMInfA(str str long long ptr long ptr ptr)
-@ stub SetupCopyOEMInfW
-@ stdcall SetupCreateDiskSpaceListA(ptr long long)
-@ stdcall SetupCreateDiskSpaceListW(ptr long long)
-@ stub SetupDecompressOrCopyFileA
-@ stub SetupDecompressOrCopyFileW
-@ stub SetupDefaultQueueCallback
-@ stdcall SetupDefaultQueueCallbackA(ptr long long long)
-@ stdcall SetupDefaultQueueCallbackW(ptr long long long)
-@ stub SetupDeleteErrorA
-@ stub SetupDeleteErrorW
-@ stdcall SetupDestroyDiskSpaceList(long)
-@ stub SetupDiAskForOEMDisk
-@ stdcall SetupDiBuildClassInfoList(long ptr long ptr)
-@ stdcall SetupDiBuildClassInfoListExA(long ptr long ptr str ptr)
-@ stdcall SetupDiBuildClassInfoListExW(long ptr long ptr wstr ptr)
-@ stub SetupDiBuildDriverInfoList
-@ stdcall SetupDiCallClassInstaller(long ptr ptr)
-@ stub SetupDiCancelDriverInfoSearch
-@ stub SetupDiChangeState
-@ stdcall SetupDiClassGuidsFromNameA(str ptr long ptr)
-@ stdcall SetupDiClassGuidsFromNameExA(str ptr long ptr str ptr)
-@ stdcall SetupDiClassGuidsFromNameExW(wstr ptr long ptr wstr ptr)
-@ stdcall SetupDiClassGuidsFromNameW(wstr ptr long ptr)
-@ stdcall SetupDiClassNameFromGuidA(ptr str long ptr)
-@ stdcall SetupDiClassNameFromGuidExA(ptr str long ptr wstr ptr)
-@ stdcall SetupDiClassNameFromGuidExW(ptr wstr long ptr wstr ptr)
-@ stdcall SetupDiClassNameFromGuidW(ptr wstr long ptr)
-@ stub SetupDiCreateDevRegKeyA
-@ stub SetupDiCreateDevRegKeyW
-@ stub SetupDiCreateDeviceInfoA
-@ stdcall SetupDiCreateDeviceInfoList(ptr ptr)
-@ stdcall SetupDiCreateDeviceInfoListExA(ptr long str ptr)
-@ stdcall SetupDiCreateDeviceInfoListExW(ptr long str ptr)
-@ stub SetupDiCreateDeviceInfoW
-@ stub SetupDiDeleteDevRegKey
-@ stub SetupDiDeleteDeviceInfo
-@ stub SetupDiDeleteDeviceInterfaceData
-@ stub SetupDiDeleteDeviceRegKey
-@ stub SetupDiDestroyClassImageList
-@ stdcall SetupDiDestroyDeviceInfoList(long)
-@ stub SetupDiDestroyDriverInfoList
-@ stub SetupDiDrawMiniIcon
-@ stdcall SetupDiEnumDeviceInfo(long long ptr)
-@ stdcall SetupDiEnumDeviceInterfaces(long ptr ptr long ptr)
-@ stub SetupDiEnumDriverInfoA
-@ stub SetupDiEnumDriverInfoW
-@ stdcall SetupDiGetActualSectionToInstallA(long str str long ptr ptr)
-@ stdcall SetupDiGetActualSectionToInstallW(long wstr wstr long ptr ptr)
-@ stub SetupDiGetClassBitmapIndex
-@ stdcall SetupDiGetClassDescriptionA(ptr str long ptr)
-@ stdcall SetupDiGetClassDescriptionExA(ptr str long ptr str ptr)
-@ stdcall SetupDiGetClassDescriptionExW(ptr wstr long ptr wstr ptr)
-@ stdcall SetupDiGetClassDescriptionW(ptr wstr long ptr)
-@ stub SetupDiGetClassDevPropertySheetsA
-@ stub SetupDiGetClassDevPropertySheetsW
-@ stdcall SetupDiGetClassDevsA(ptr ptr long long)
-@ stdcall SetupDiGetClassDevsExA(ptr str ptr long ptr str ptr)
-@ stdcall SetupDiGetClassDevsExW(ptr wstr ptr long ptr wstr ptr)
-@ stdcall SetupDiGetClassDevsW(ptr ptr long long)
-@ stub SetupDiGetClassImageIndex
-@ stub SetupDiGetClassImageList
-@ stub SetupDiGetClassImageListExA
-@ stub SetupDiGetClassImageListExW
-@ stub SetupDiGetClassInstallParamsA
-@ stub SetupDiGetClassInstallParamsW
-@ stub SetupDiGetDeviceInfoListClass
-@ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr)
-@ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr)
-@ stdcall SetupDiGetDeviceInstallParamsA(ptr ptr ptr)
-@ stub SetupDiGetDeviceInstallParamsW
-@ stub SetupDiGetDeviceInstanceIdA
-@ stub SetupDiGetDeviceInstanceIdW
-@ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr)
-@ stub SetupDiGetDeviceRegistryPropertyW
-@ stub SetupDiGetDriverInfoDetailA
-@ stub SetupDiGetDriverInfoDetailW
-@ stub SetupDiGetDriverInstallParamsA
-@ stub SetupDiGetDriverInstallParamsW
-@ stub SetupDiGetDeviceInterfaceAlias
-@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr)
-@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr)
-@ stub SetupDiGetHwProfileFriendlyNameA
-@ stub SetupDiGetHwProfileFriendlyNameExA
-@ stub SetupDiGetHwProfileFriendlyNameExW
-@ stub SetupDiGetHwProfileFriendlyNameW
-@ stub SetupDiGetHwProfileList
-@ stub SetupDiGetHwProfileListExA
-@ stub SetupDiGetHwProfileListExW
-@ stub SetupDiGetINFClassA
-@ stub SetupDiGetINFClassW
-@ stub SetupDiGetSelectedDevice
-@ stub SetupDiGetSelectedDriverA
-@ stub SetupDiGetSelectedDriverW
-@ stub SetupDiGetWizardPage
-@ stdcall SetupDiInstallClassA(long str long ptr)
-@ stub SetupDiInstallClassExA
-@ stub SetupDiInstallClassExW
-@ stdcall SetupDiInstallClassW(long wstr long ptr)
-@ stub SetupDiInstallDevice
-@ stub SetupDiInstallDriverFiles
-@ stub SetupDiLoadClassIcon
-@ stub SetupDiMoveDuplicateDevice
-@ stdcall SetupDiOpenClassRegKey(ptr long)
-@ stdcall SetupDiOpenClassRegKeyExA(ptr long long str ptr)
-@ stdcall SetupDiOpenClassRegKeyExW(ptr long long wstr ptr)
-@ stdcall SetupDiOpenDevRegKey(ptr ptr long long long long)
-@ stub SetupDiOpenDeviceInfoA
-@ stub SetupDiOpenDeviceInfoW
-@ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr)
-@ stub SetupDiOpenDeviceInterfaceRegKey
-@ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr)
-@ stub SetupDiRegisterDeviceInfo
-@ stub SetupDiRemoveDevice
-@ stub SetupDiRemoveDeviceInterface
-@ stub SetupDiSelectDevice
-@ stub SetupDiSelectOEMDrv
-@ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long)
-@ stub SetupDiSetClassInstallParamsW
-@ stub SetupDiSetDeviceInstallParamsA
-@ stub SetupDiSetDeviceInstallParamsW
-@ stub SetupDiSetDeviceRegistryPropertyA
-@ stub SetupDiSetDeviceRegistryPropertyW
-@ stub SetupDiSetDriverInstallParamsA
-@ stub SetupDiSetDriverInstallParamsW
-@ stub SetupDiSetSelectedDevice
-@ stub SetupDiSetSelectedDriverA
-@ stub SetupDiSetSelectedDriverW
-@ stub SetupDiUnremoveDevice
-@ stub SetupDuplicateDiskSpaceListA
-@ stub SetupDuplicateDiskSpaceListW
-@ stdcall SetupFindFirstLineA(long str str ptr)
-@ stdcall SetupFindFirstLineW(long wstr wstr ptr)
-@ stdcall SetupFindNextLine(ptr ptr)
-@ stdcall SetupFindNextMatchLineA(ptr str ptr)
-@ stdcall SetupFindNextMatchLineW(ptr wstr ptr)
-@ stub SetupFreeSourceListA
-@ stub SetupFreeSourceListW
-@ stub SetupGetBackupInformationA
-@ stub SetupGetBackupInformationW
-@ stdcall SetupGetBinaryField(ptr long ptr long ptr)
-@ stdcall SetupGetFieldCount(ptr)
-@ stub SetupGetFileCompressionInfoA
-@ stub SetupGetFileCompressionInfoW
-@ stdcall SetupGetFileQueueCount(long long ptr)
-@ stdcall SetupGetFileQueueFlags(long ptr)
-@ stub SetupGetInfFileListA
-@ stub SetupGetInfFileListW
-@ stdcall SetupGetInfInformationA(ptr long ptr long ptr)
-@ stub SetupGetInfInformationW
-@ stub SetupGetInfSections
-@ stdcall SetupGetIntField(ptr long ptr)
-@ stdcall SetupGetLineByIndexA(long str long ptr)
-@ stdcall SetupGetLineByIndexW(long wstr long ptr)
-@ stdcall SetupGetLineCountA(long str)
-@ stdcall SetupGetLineCountW(long wstr)
-@ stdcall SetupGetLineTextA(ptr long str str ptr long ptr)
-@ stdcall SetupGetLineTextW(ptr long wstr wstr ptr long ptr)
-@ stdcall SetupGetMultiSzFieldA(ptr long ptr long ptr)
-@ stdcall SetupGetMultiSzFieldW(ptr long ptr long ptr)
-@ stub SetupGetSourceFileLocationA
-@ stub SetupGetSourceFileLocationW
-@ stub SetupGetSourceFileSizeA
-@ stub SetupGetSourceFileSizeW
-@ stub SetupGetSourceInfoA
-@ stub SetupGetSourceInfoW
-@ stdcall SetupGetStringFieldA(ptr long ptr long ptr)
-@ stdcall SetupGetStringFieldW(ptr long ptr long ptr)
-@ stub SetupGetTargetPathA
-@ stub SetupGetTargetPathW
-@ stdcall SetupInitDefaultQueueCallback(long)
-@ stdcall SetupInitDefaultQueueCallbackEx(long long long long ptr)
-@ stdcall SetupInitializeFileLogA (str long)
-@ stdcall SetupInitializeFileLogW (wstr long)
-@ stub SetupInstallFileA
-@ stub SetupInstallFileExA
-@ stub SetupInstallFileExW
-@ stub SetupInstallFileW
-@ stdcall SetupInstallFilesFromInfSectionA(long long long str str long)
-@ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long)
-@ stdcall SetupInstallFromInfSectionA(long long str long long str long ptr ptr long ptr)
-@ stdcall SetupInstallFromInfSectionW(long long wstr long long wstr long ptr ptr long ptr)
-@ stub SetupInstallServicesFromInfSectionA
-@ stub SetupInstallServicesFromInfSectionExA
-@ stub SetupInstallServicesFromInfSectionExW
-@ stub SetupInstallServicesFromInfSectionW
-@ stdcall SetupIterateCabinetA(str long ptr ptr)
-@ stdcall SetupIterateCabinetW(wstr long ptr ptr)
-@ stub SetupLogErrorA
-@ stub SetupLogErrorW
-@ stub SetupLogFileA
-@ stub SetupLogFileW
-@ stdcall SetupOpenAppendInfFileA(str long ptr)
-@ stdcall SetupOpenAppendInfFileW(wstr long ptr)
-@ stdcall SetupOpenFileQueue()
-@ stdcall SetupOpenInfFileA(str str long ptr)
-@ stdcall SetupOpenInfFileW(wstr wstr long ptr)
-@ stdcall SetupOpenMasterInf()
-@ stub SetupPromptForDiskA
-@ stub SetupPromptForDiskW
-@ stub SetupPromptReboot
-@ stub SetupQueryDrivesInDiskSpaceListA
-@ stub SetupQueryDrivesInDiskSpaceListW
-@ stub SetupQueryFileLogA
-@ stub SetupQueryFileLogW
-@ stub SetupQueryInfFileInformationA
-@ stub SetupQueryInfFileInformationW
-@ stub SetupQueryInfOriginalFileInformationA
-@ stub SetupQueryInfOriginalFileInformationW
-@ stub SetupQueryInfVersionInformationA
-@ stub SetupQueryInfVersionInformationW
-@ stub SetupQuerySourceListA
-@ stub SetupQuerySourceListW
-@ stdcall SetupQuerySpaceRequiredOnDriveA(long str ptr ptr long)
-@ stub SetupQuerySpaceRequiredOnDriveW
-@ stdcall SetupQueueCopyA(long str str str str str str str long)
-@ stdcall SetupQueueCopyIndirectA(ptr)
-@ stdcall SetupQueueCopyIndirectW(ptr)
-@ stdcall SetupQueueCopySectionA(long str long long str long)
-@ stdcall SetupQueueCopySectionW(long wstr long long wstr long)
-@ stdcall SetupQueueCopyW(long wstr wstr wstr wstr wstr wstr wstr long)
-@ stdcall SetupQueueDefaultCopyA(long long str str str long)
-@ stdcall SetupQueueDefaultCopyW(long long wstr wstr wstr long)
-@ stdcall SetupQueueDeleteA(long str str)
-@ stdcall SetupQueueDeleteSectionA(long long long str)
-@ stdcall SetupQueueDeleteSectionW(long long long wstr)
-@ stdcall SetupQueueDeleteW(long wstr wstr)
-@ stdcall SetupQueueRenameA(long str str str str)
-@ stdcall SetupQueueRenameSectionA(long long long str)
-@ stdcall SetupQueueRenameSectionW(long long long wstr)
-@ stdcall SetupQueueRenameW(long wstr wstr wstr wstr)
-@ stub SetupRemoveFileLogEntryA
-@ stub SetupRemoveFileLogEntryW
-@ stub SetupRemoveFromDiskSpaceListA
-@ stub SetupRemoveFromDiskSpaceListW
-@ stub SetupRemoveFromSourceListA
-@ stub SetupRemoveFromSourceListW
-@ stub SetupRemoveInstallSectionFromDiskSpaceListA
-@ stub SetupRemoveInstallSectionFromDiskSpaceListW
-@ stub SetupRemoveSectionFromDiskSpaceListA
-@ stub SetupRemoveSectionFromDiskSpaceListW
-@ stub SetupRenameErrorA
-@ stub SetupRenameErrorW
-@ stub SetupScanFileQueue
-@ stdcall SetupScanFileQueueA(long long long ptr ptr ptr)
-@ stdcall SetupScanFileQueueW(long long long ptr ptr ptr)
-@ stdcall SetupSetDirectoryIdA(long long str)
-@ stub SetupSetDirectoryIdExA
-@ stub SetupSetDirectoryIdExW
-@ stdcall SetupSetDirectoryIdW(long long wstr)
-@ stub SetupFileQueueAlternatePlatformA
-@ stub SetupFileQueueAlternatePlatformW
-@ stdcall SetupSetFileQueueFlags(long long long)
-@ stub SetupSetPlatformPathOverrideA
-@ stub SetupSetPlatformPathOverrideW
-@ stub SetupSetSourceListA
-@ stub SetupSetSourceListW
-@ stdcall SetupTermDefaultQueueCallback(ptr)
-@ stdcall SetupTerminateFileLog(long)
-@ stub ShouldDeviceBeExcluded
-@ stub StampFileSecurity
-@ stub StringTableAddString
-@ stub StringTableAddStringEx
-@ stub StringTableDestroy
-@ stub StringTableDuplicate
-@ stub StringTableEnum
-@ stub StringTableGetExtraData
-@ stub StringTableInitialize
-@ stub StringTableInitializeEx
-@ stub StringTableLookUpString
-@ stub StringTableLookUpStringEx
-@ stub StringTableSetExtraData
-@ stub StringTableStringFromId
-@ stub StringTableTrim
-@ stub TakeOwnershipOfFile
-@ stdcall UnicodeToMultiByte(wstr long)
-@ stub UnmapAndCloseFile
-@ stub VerifyCatalogFile
-@ stub VerifyFile
-@ stub pSetupAccessRunOnceNodeList
-@ stub pSetupAddMiniIconToList
-@ stub pSetupAddTagToGroupOrderListEntry
-@ stub pSetupAppendStringToMultiSz
-@ stub pSetupDestroyRunOnceNodeList
-@ stub pSetupDirectoryIdToPath
-@ stub pSetupGetField
-@ stub pSetupGetGlobalFlags
-@ stub pSetupGetOsLoaderDriveAndPath
-@ stub pSetupGetQueueFlags
-@ stub pSetupGetVersionDatum
-@ stub pSetupGuidFromString
-@ stub pSetupIsGuidNull
-@ stub pSetupMakeSurePathExists
-@ stub pSetupSetGlobalFlags
-@ stub pSetupSetQueueFlags
-@ stub pSetupSetSystemSourceFlags
-@ stub pSetupStringFromGuid
-@ stub pSetupVerifyQueuedCatalogs
+@ stub AcquireSCMLock\r
+@ stub AddMiniIconToList\r
+@ stub AddTagToGroupOrderListEntry\r
+@ stub AppendStringToMultiSz\r
+@ stub AssertFail\r
+@ stub CMP_Init_Detection\r
+@ stub CMP_RegisterNotification\r
+@ stub CMP_Report_LogOn\r
+@ stub CMP_UnregisterNotification\r
+@ stub CMP_WaitNoPendingInstallEvents\r
+@ stub CMP_WaitServices\r
+@ stub CM_Add_Empty_Log_Conf\r
+@ stub CM_Add_Empty_Log_Conf_Ex\r
+@ stub CM_Add_IDA\r
+@ stub CM_Add_IDW\r
+@ stub CM_Add_ID_ExA\r
+@ stub CM_Add_ID_ExW\r
+@ stub CM_Add_Range\r
+@ stub CM_Add_Res_Des\r
+@ stub CM_Add_Res_Des_Ex\r
+@ stdcall CM_Connect_MachineA(str ptr)\r
+@ stdcall CM_Connect_MachineW(wstr ptr)\r
+@ stub CM_Create_DevNodeA\r
+@ stub CM_Create_DevNodeW\r
+@ stub CM_Create_DevNode_ExA\r
+@ stub CM_Create_DevNode_ExW\r
+@ stub CM_Create_Range_List\r
+@ stub CM_Delete_Class_Key\r
+@ stub CM_Delete_Class_Key_Ex\r
+@ stub CM_Delete_DevNode_Key\r
+@ stub CM_Delete_DevNode_Key_Ex\r
+@ stub CM_Delete_Range\r
+@ stub CM_Detect_Resource_Conflict\r
+@ stub CM_Detect_Resource_Conflict_Ex\r
+@ stub CM_Disable_DevNode\r
+@ stub CM_Disable_DevNode_Ex\r
+@ stdcall CM_Disconnect_Machine(long)\r
+@ stub CM_Dup_Range_List\r
+@ stub CM_Enable_DevNode\r
+@ stub CM_Enable_DevNode_Ex\r
+@ stub CM_Enumerate_Classes\r
+@ stub CM_Enumerate_Classes_Ex\r
+@ stub CM_Enumerate_EnumeratorsA\r
+@ stub CM_Enumerate_EnumeratorsW\r
+@ stub CM_Enumerate_Enumerators_ExA\r
+@ stub CM_Enumerate_Enumerators_ExW\r
+@ stub CM_Find_Range\r
+@ stub CM_First_Range\r
+@ stub CM_Free_Log_Conf\r
+@ stub CM_Free_Log_Conf_Ex\r
+@ stub CM_Free_Log_Conf_Handle\r
+@ stub CM_Free_Range_List\r
+@ stub CM_Free_Res_Des\r
+@ stub CM_Free_Res_Des_Ex\r
+@ stub CM_Free_Res_Des_Handle\r
+@ stdcall CM_Get_Child(ptr long long)\r
+@ stdcall CM_Get_Child_Ex(ptr long long long)\r
+@ stub CM_Get_Class_Key_NameA\r
+@ stub CM_Get_Class_Key_NameW\r
+@ stub CM_Get_Class_Key_Name_ExA\r
+@ stub CM_Get_Class_Key_Name_ExW\r
+@ stub CM_Get_Class_NameA\r
+@ stub CM_Get_Class_NameW\r
+@ stub CM_Get_Class_Name_ExA\r
+@ stub CM_Get_Class_Name_ExW\r
+@ stub CM_Get_Depth\r
+@ stub CM_Get_Depth_Ex\r
+@ stub CM_Get_DevNode_Registry_PropertyA\r
+@ stub CM_Get_DevNode_Registry_PropertyW\r
+@ stub CM_Get_DevNode_Registry_Property_ExA\r
+@ stub CM_Get_DevNode_Registry_Property_ExW\r
+@ stub CM_Get_DevNode_Status\r
+@ stub CM_Get_DevNode_Status_Ex\r
+@ stub CM_Get_Device_IDA\r
+@ stub CM_Get_Device_IDW\r
+@ stub CM_Get_Device_ID_ExA\r
+@ stub CM_Get_Device_ID_ExW\r
+@ stdcall CM_Get_Device_ID_ListA(str str long long)\r
+@ stdcall CM_Get_Device_ID_ListW(wstr wstr long long)\r
+@ stdcall CM_Get_Device_ID_List_ExA(str str long long long)\r
+@ stdcall CM_Get_Device_ID_List_ExW(wstr wstr long long long)\r
+@ stdcall CM_Get_Device_ID_List_SizeA(ptr str long)\r
+@ stdcall CM_Get_Device_ID_List_SizeW(ptr wstr long)\r
+@ stdcall CM_Get_Device_ID_List_Size_ExA(ptr str long long)\r
+@ stdcall CM_Get_Device_ID_List_Size_ExW(ptr wstr long long)\r
+@ stub CM_Get_Device_ID_Size\r
+@ stub CM_Get_Device_ID_Size_Ex\r
+@ stub CM_Get_Device_Interface_AliasA\r
+@ stub CM_Get_Device_Interface_AliasW\r
+@ stub CM_Get_Device_Interface_Alias_ExA\r
+@ stub CM_Get_Device_Interface_Alias_ExW\r
+@ stub CM_Get_Device_Interface_ListA\r
+@ stub CM_Get_Device_Interface_ListW\r
+@ stub CM_Get_Device_Interface_List_ExA\r
+@ stub CM_Get_Device_Interface_List_ExW\r
+@ stub CM_Get_Device_Interface_List_SizeA\r
+@ stub CM_Get_Device_Interface_List_SizeW\r
+@ stub CM_Get_Device_Interface_List_Size_ExA\r
+@ stub CM_Get_Device_Interface_List_Size_ExW\r
+@ stub CM_Get_First_Log_Conf\r
+@ stub CM_Get_First_Log_Conf_Ex\r
+@ stub CM_Get_Global_State\r
+@ stub CM_Get_Global_State_Ex\r
+@ stub CM_Get_HW_Prof_FlagsA\r
+@ stub CM_Get_HW_Prof_FlagsW\r
+@ stub CM_Get_HW_Prof_Flags_ExA\r
+@ stub CM_Get_HW_Prof_Flags_ExW\r
+@ stub CM_Get_Hardware_Profile_InfoA\r
+@ stub CM_Get_Hardware_Profile_InfoW\r
+@ stub CM_Get_Hardware_Profile_Info_ExA\r
+@ stub CM_Get_Hardware_Profile_Info_ExW\r
+@ stub CM_Get_Log_Conf_Priority\r
+@ stub CM_Get_Log_Conf_Priority_Ex\r
+@ stub CM_Get_Next_Log_Conf\r
+@ stub CM_Get_Next_Log_Conf_Ex\r
+@ stub CM_Get_Next_Res_Des\r
+@ stub CM_Get_Next_Res_Des_Ex\r
+@ stdcall CM_Get_Parent(ptr long long)\r
+@ stdcall CM_Get_Parent_Ex(ptr long long long)\r
+@ stub CM_Get_Res_Des_Data\r
+@ stub CM_Get_Res_Des_Data_Ex\r
+@ stub CM_Get_Res_Des_Data_Size\r
+@ stub CM_Get_Res_Des_Data_Size_Ex\r
+@ stdcall CM_Get_Sibling(ptr long long)\r
+@ stdcall CM_Get_Sibling_Ex(ptr long long long)\r
+@ stdcall CM_Get_Version()\r
+@ stdcall CM_Get_Version_Ex(long)\r
+@ stub CM_Intersect_Range_List\r
+@ stub CM_Invert_Range_List\r
+@ stub CM_Is_Dock_Station_Present\r
+@ stdcall CM_Locate_DevNodeA(ptr str long)\r
+@ stdcall CM_Locate_DevNodeW(ptr wstr long)\r
+@ stdcall CM_Locate_DevNode_ExA(ptr str long long)\r
+@ stdcall CM_Locate_DevNode_ExW(ptr wstr long long)\r
+@ stub CM_Merge_Range_List\r
+@ stub CM_Modify_Res_Des\r
+@ stub CM_Modify_Res_Des_Ex\r
+@ stub CM_Move_DevNode\r
+@ stub CM_Move_DevNode_Ex\r
+@ stub CM_Next_Range\r
+@ stub CM_Open_Class_KeyA\r
+@ stub CM_Open_Class_KeyW\r
+@ stub CM_Open_Class_Key_ExA\r
+@ stub CM_Open_Class_Key_ExW\r
+@ stub CM_Open_DevNode_Key\r
+@ stub CM_Open_DevNode_Key_Ex\r
+@ stub CM_Query_Arbitrator_Free_Data\r
+@ stub CM_Query_Arbitrator_Free_Data_Ex\r
+@ stub CM_Query_Arbitrator_Free_Size\r
+@ stub CM_Query_Arbitrator_Free_Size_Ex\r
+@ stub CM_Query_Remove_SubTree\r
+@ stub CM_Query_Remove_SubTree_Ex\r
+@ stub CM_Reenumerate_DevNode\r
+@ stub CM_Reenumerate_DevNode_Ex\r
+@ stub CM_Register_Device_Driver\r
+@ stub CM_Register_Device_Driver_Ex\r
+@ stub CM_Register_Device_InterfaceA\r
+@ stub CM_Register_Device_InterfaceW\r
+@ stub CM_Register_Device_Interface_ExA\r
+@ stub CM_Register_Device_Interface_ExW\r
+@ stub CM_Remove_SubTree\r
+@ stub CM_Remove_SubTree_Ex\r
+@ stub CM_Remove_Unmarked_Children\r
+@ stub CM_Remove_Unmarked_Children_Ex\r
+@ stub CM_Request_Device_EjectA\r
+@ stub CM_Request_Device_EjectW\r
+@ stub CM_Request_Eject_PC\r
+@ stub CM_Reset_Children_Marks\r
+@ stub CM_Reset_Children_Marks_Ex\r
+@ stub CM_Run_Detection\r
+@ stub CM_Run_Detection_Ex\r
+@ stub CM_Set_DevNode_Problem\r
+@ stub CM_Set_DevNode_Problem_Ex\r
+@ stub CM_Set_DevNode_Registry_PropertyA\r
+@ stub CM_Set_DevNode_Registry_PropertyW\r
+@ stub CM_Set_DevNode_Registry_Property_ExA\r
+@ stub CM_Set_DevNode_Registry_Property_ExW\r
+@ stub CM_Set_HW_Prof\r
+@ stub CM_Set_HW_Prof_Ex\r
+@ stub CM_Set_HW_Prof_FlagsA\r
+@ stub CM_Set_HW_Prof_FlagsW\r
+@ stub CM_Set_HW_Prof_Flags_ExA\r
+@ stub CM_Set_HW_Prof_Flags_ExW\r
+@ stub CM_Setup_DevNode\r
+@ stub CM_Setup_DevNode_Ex\r
+@ stub CM_Test_Range_Available\r
+@ stub CM_Uninstall_DevNode\r
+@ stub CM_Uninstall_DevNode_Ex\r
+@ stub CM_Unregister_Device_InterfaceA\r
+@ stub CM_Unregister_Device_InterfaceW\r
+@ stub CM_Unregister_Device_Interface_ExA\r
+@ stub CM_Unregister_Device_Interface_ExW\r
+@ stdcall CaptureAndConvertAnsiArg(str ptr)\r
+@ stdcall CaptureStringArg(wstr ptr)\r
+@ stub CenterWindowRelativeToParent\r
+@ stub ConcatenatePaths\r
+@ stdcall DelayedMove(wstr wstr)\r
+@ stub DelimStringToMultiSz\r
+@ stub DestroyTextFileReadBuffer\r
+@ stdcall DoesUserHavePrivilege(wstr)\r
+@ stdcall DuplicateString(wstr)\r
+@ stdcall EnablePrivilege(wstr long)\r
+@ stub ExtensionPropSheetPageProc\r
+@ stdcall FileExists(wstr ptr)\r
+@ stub FreeStringArray\r
+@ stub GetCurrentDriverSigningPolicy\r
+@ stub GetNewInfName\r
+@ stub GetSetFileTimestamp\r
+@ stub GetVersionInfoFromImage\r
+@ stub InfIsFromOemLocation\r
+@ stub InstallCatalog\r
+@ stdcall InstallHinfSection(long long str long) InstallHinfSectionA\r
+@ stdcall InstallHinfSectionA(long long str long)\r
+@ stdcall InstallHinfSectionW(long long wstr long)\r
+@ stub InstallStop\r
+@ stub InstallStopEx\r
+@ stdcall IsUserAdmin()\r
+@ stub LookUpStringInTable\r
+@ stub MemoryInitialize\r
+@ stdcall MultiByteToUnicode(str long)\r
+@ stub MultiSzFromSearchControl\r
+@ stdcall MyFree(ptr)\r
+@ stub MyGetFileTitle\r
+@ stdcall MyMalloc(long)\r
+@ stdcall MyRealloc(ptr long)\r
+@ stub OpenAndMapFileForRead\r
+@ stub OutOfMemory\r
+@ stub QueryMultiSzValueToArray\r
+@ stdcall QueryRegistryValue(long wstr ptr ptr ptr)\r
+@ stub ReadAsciiOrUnicodeTextFile\r
+@ stub RegistryDelnode\r
+@ stub RetreiveFileSecurity\r
+@ stub RetrieveServiceConfig\r
+@ stub SearchForInfFile\r
+@ stub SetArrayToMultiSzValue\r
+@ stdcall SetupAddInstallSectionToDiskSpaceListA(long long long str ptr long)\r
+@ stub SetupAddInstallSectionToDiskSpaceListW\r
+@ stub SetupAddSectionToDiskSpaceListA\r
+@ stub SetupAddSectionToDiskSpaceListW\r
+@ stub SetupAddToDiskSpaceListA\r
+@ stub SetupAddToDiskSpaceListW\r
+@ stub SetupAddToSourceListA\r
+@ stub SetupAddToSourceListW\r
+@ stub SetupAdjustDiskSpaceListA\r
+@ stub SetupAdjustDiskSpaceListW\r
+@ stub SetupCancelTemporarySourceList\r
+@ stdcall SetupCloseFileQueue(ptr)\r
+@ stdcall SetupCloseInfFile(long)\r
+@ stub SetupCloseLog\r
+@ stdcall SetupCommitFileQueue(long long ptr ptr) SetupCommitFileQueueW\r
+@ stdcall SetupCommitFileQueueA(long long ptr ptr)\r
+@ stdcall SetupCommitFileQueueW(long long ptr ptr)\r
+@ stub SetupCopyErrorA\r
+@ stub SetupCopyErrorW\r
+@ stdcall SetupCopyOEMInfA(str str long long ptr long ptr ptr)\r
+@ stub SetupCopyOEMInfW\r
+@ stdcall SetupCreateDiskSpaceListA(ptr long long)\r
+@ stdcall SetupCreateDiskSpaceListW(ptr long long)\r
+@ stub SetupDecompressOrCopyFileA\r
+@ stub SetupDecompressOrCopyFileW\r
+@ stub SetupDefaultQueueCallback\r
+@ stdcall SetupDefaultQueueCallbackA(ptr long long long)\r
+@ stdcall SetupDefaultQueueCallbackW(ptr long long long)\r
+@ stub SetupDeleteErrorA\r
+@ stub SetupDeleteErrorW\r
+@ stdcall SetupDestroyDiskSpaceList(long)\r
+@ stub SetupDiAskForOEMDisk\r
+@ stdcall SetupDiBuildClassInfoList(long ptr long ptr)\r
+@ stdcall SetupDiBuildClassInfoListExA(long ptr long ptr str ptr)\r
+@ stdcall SetupDiBuildClassInfoListExW(long ptr long ptr wstr ptr)\r
+@ stub SetupDiBuildDriverInfoList\r
+@ stdcall SetupDiCallClassInstaller(long ptr ptr)\r
+@ stub SetupDiCancelDriverInfoSearch\r
+@ stub SetupDiChangeState\r
+@ stdcall SetupDiClassGuidsFromNameA(str ptr long ptr)\r
+@ stdcall SetupDiClassGuidsFromNameExA(str ptr long ptr str ptr)\r
+@ stdcall SetupDiClassGuidsFromNameExW(wstr ptr long ptr wstr ptr)\r
+@ stdcall SetupDiClassGuidsFromNameW(wstr ptr long ptr)\r
+@ stdcall SetupDiClassNameFromGuidA(ptr str long ptr)\r
+@ stdcall SetupDiClassNameFromGuidExA(ptr str long ptr wstr ptr)\r
+@ stdcall SetupDiClassNameFromGuidExW(ptr wstr long ptr wstr ptr)\r
+@ stdcall SetupDiClassNameFromGuidW(ptr wstr long ptr)\r
+@ stub SetupDiCreateDevRegKeyA\r
+@ stub SetupDiCreateDevRegKeyW\r
+@ stub SetupDiCreateDeviceInfoA\r
+@ stdcall SetupDiCreateDeviceInfoList(ptr ptr)\r
+@ stdcall SetupDiCreateDeviceInfoListExA(ptr long str ptr)\r
+@ stdcall SetupDiCreateDeviceInfoListExW(ptr long str ptr)\r
+@ stub SetupDiCreateDeviceInfoW\r
+@ stub SetupDiDeleteDevRegKey\r
+@ stub SetupDiDeleteDeviceInfo\r
+@ stub SetupDiDeleteDeviceInterfaceData\r
+@ stub SetupDiDeleteDeviceRegKey\r
+@ stub SetupDiDestroyClassImageList\r
+@ stdcall SetupDiDestroyDeviceInfoList(long)\r
+@ stub SetupDiDestroyDriverInfoList\r
+@ stub SetupDiDrawMiniIcon\r
+@ stdcall SetupDiEnumDeviceInfo(long long ptr)\r
+@ stdcall SetupDiEnumDeviceInterfaces(long ptr ptr long ptr)\r
+@ stub SetupDiEnumDriverInfoA\r
+@ stub SetupDiEnumDriverInfoW\r
+@ stdcall SetupDiGetActualSectionToInstallA(long str str long ptr ptr)\r
+@ stdcall SetupDiGetActualSectionToInstallW(long wstr wstr long ptr ptr)\r
+@ stub SetupDiGetClassBitmapIndex\r
+@ stdcall SetupDiGetClassDescriptionA(ptr str long ptr)\r
+@ stdcall SetupDiGetClassDescriptionExA(ptr str long ptr str ptr)\r
+@ stdcall SetupDiGetClassDescriptionExW(ptr wstr long ptr wstr ptr)\r
+@ stdcall SetupDiGetClassDescriptionW(ptr wstr long ptr)\r
+@ stub SetupDiGetClassDevPropertySheetsA\r
+@ stub SetupDiGetClassDevPropertySheetsW\r
+@ stdcall SetupDiGetClassDevsA(ptr ptr long long)\r
+@ stdcall SetupDiGetClassDevsExA(ptr str ptr long ptr str ptr)\r
+@ stdcall SetupDiGetClassDevsExW(ptr wstr ptr long ptr wstr ptr)\r
+@ stdcall SetupDiGetClassDevsW(ptr ptr long long)\r
+@ stub SetupDiGetClassImageIndex\r
+@ stub SetupDiGetClassImageList\r
+@ stub SetupDiGetClassImageListExA\r
+@ stub SetupDiGetClassImageListExW\r
+@ stub SetupDiGetClassInstallParamsA\r
+@ stub SetupDiGetClassInstallParamsW\r
+@ stub SetupDiGetDeviceInfoListClass\r
+@ stdcall SetupDiGetDeviceInfoListDetailA(ptr ptr)\r
+@ stdcall SetupDiGetDeviceInfoListDetailW(ptr ptr)\r
+@ stdcall SetupDiGetDeviceInstallParamsA(ptr ptr ptr)\r
+@ stub SetupDiGetDeviceInstallParamsW\r
+@ stub SetupDiGetDeviceInstanceIdA\r
+@ stub SetupDiGetDeviceInstanceIdW\r
+@ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr)\r
+@ stub SetupDiGetDeviceRegistryPropertyW\r
+@ stub SetupDiGetDriverInfoDetailA\r
+@ stub SetupDiGetDriverInfoDetailW\r
+@ stub SetupDiGetDriverInstallParamsA\r
+@ stub SetupDiGetDriverInstallParamsW\r
+@ stub SetupDiGetDeviceInterfaceAlias\r
+@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr)\r
+@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr)\r
+@ stub SetupDiGetHwProfileFriendlyNameA\r
+@ stub SetupDiGetHwProfileFriendlyNameExA\r
+@ stub SetupDiGetHwProfileFriendlyNameExW\r
+@ stub SetupDiGetHwProfileFriendlyNameW\r
+@ stub SetupDiGetHwProfileList\r
+@ stub SetupDiGetHwProfileListExA\r
+@ stub SetupDiGetHwProfileListExW\r
+@ stub SetupDiGetINFClassA\r
+@ stub SetupDiGetINFClassW\r
+@ stub SetupDiGetSelectedDevice\r
+@ stub SetupDiGetSelectedDriverA\r
+@ stub SetupDiGetSelectedDriverW\r
+@ stub SetupDiGetWizardPage\r
+@ stdcall SetupDiInstallClassA(long str long ptr)\r
+@ stub SetupDiInstallClassExA\r
+@ stub SetupDiInstallClassExW\r
+@ stdcall SetupDiInstallClassW(long wstr long ptr)\r
+@ stub SetupDiInstallDevice\r
+@ stub SetupDiInstallDriverFiles\r
+@ stub SetupDiLoadClassIcon\r
+@ stub SetupDiMoveDuplicateDevice\r
+@ stdcall SetupDiOpenClassRegKey(ptr long)\r
+@ stdcall SetupDiOpenClassRegKeyExA(ptr long long str ptr)\r
+@ stdcall SetupDiOpenClassRegKeyExW(ptr long long wstr ptr)\r
+@ stdcall SetupDiOpenDevRegKey(ptr ptr long long long long)\r
+@ stub SetupDiOpenDeviceInfoA\r
+@ stub SetupDiOpenDeviceInfoW\r
+@ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr)\r
+@ stub SetupDiOpenDeviceInterfaceRegKey\r
+@ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr)\r
+@ stub SetupDiRegisterDeviceInfo\r
+@ stub SetupDiRemoveDevice\r
+@ stub SetupDiRemoveDeviceInterface\r
+@ stub SetupDiSelectDevice\r
+@ stub SetupDiSelectOEMDrv\r
+@ stdcall SetupDiSetClassInstallParamsA(ptr ptr ptr long)\r
+@ stub SetupDiSetClassInstallParamsW\r
+@ stub SetupDiSetDeviceInstallParamsA\r
+@ stub SetupDiSetDeviceInstallParamsW\r
+@ stub SetupDiSetDeviceRegistryPropertyA\r
+@ stub SetupDiSetDeviceRegistryPropertyW\r
+@ stub SetupDiSetDriverInstallParamsA\r
+@ stub SetupDiSetDriverInstallParamsW\r
+@ stub SetupDiSetSelectedDevice\r
+@ stub SetupDiSetSelectedDriverA\r
+@ stub SetupDiSetSelectedDriverW\r
+@ stub SetupDiUnremoveDevice\r
+@ stub SetupDuplicateDiskSpaceListA\r
+@ stub SetupDuplicateDiskSpaceListW\r
+@ stdcall SetupFindFirstLineA(long str str ptr)\r
+@ stdcall SetupFindFirstLineW(long wstr wstr ptr)\r
+@ stdcall SetupFindNextLine(ptr ptr)\r
+@ stdcall SetupFindNextMatchLineA(ptr str ptr)\r
+@ stdcall SetupFindNextMatchLineW(ptr wstr ptr)\r
+@ stub SetupFreeSourceListA\r
+@ stub SetupFreeSourceListW\r
+@ stub SetupGetBackupInformationA\r
+@ stub SetupGetBackupInformationW\r
+@ stdcall SetupGetBinaryField(ptr long ptr long ptr)\r
+@ stdcall SetupGetFieldCount(ptr)\r
+@ stub SetupGetFileCompressionInfoA\r
+@ stub SetupGetFileCompressionInfoW\r
+@ stdcall SetupGetFileQueueCount(long long ptr)\r
+@ stdcall SetupGetFileQueueFlags(long ptr)\r
+@ stub SetupGetInfFileListA\r
+@ stub SetupGetInfFileListW\r
+@ stdcall SetupGetInfInformationA(ptr long ptr long ptr)\r
+@ stub SetupGetInfInformationW\r
+@ stub SetupGetInfSections\r
+@ stdcall SetupGetIntField(ptr long ptr)\r
+@ stdcall SetupGetLineByIndexA(long str long ptr)\r
+@ stdcall SetupGetLineByIndexW(long wstr long ptr)\r
+@ stdcall SetupGetLineCountA(long str)\r
+@ stdcall SetupGetLineCountW(long wstr)\r
+@ stdcall SetupGetLineTextA(ptr long str str ptr long ptr)\r
+@ stdcall SetupGetLineTextW(ptr long wstr wstr ptr long ptr)\r
+@ stdcall SetupGetMultiSzFieldA(ptr long ptr long ptr)\r
+@ stdcall SetupGetMultiSzFieldW(ptr long ptr long ptr)\r
+@ stub SetupGetSourceFileLocationA\r
+@ stub SetupGetSourceFileLocationW\r
+@ stub SetupGetSourceFileSizeA\r
+@ stub SetupGetSourceFileSizeW\r
+@ stub SetupGetSourceInfoA\r
+@ stub SetupGetSourceInfoW\r
+@ stdcall SetupGetStringFieldA(ptr long ptr long ptr)\r
+@ stdcall SetupGetStringFieldW(ptr long ptr long ptr)\r
+@ stub SetupGetTargetPathA\r
+@ stub SetupGetTargetPathW\r
+@ stdcall SetupInitDefaultQueueCallback(long)\r
+@ stdcall SetupInitDefaultQueueCallbackEx(long long long long ptr)\r
+@ stdcall SetupInitializeFileLogA (str long)\r
+@ stdcall SetupInitializeFileLogW (wstr long)\r
+@ stub SetupInstallFileA\r
+@ stub SetupInstallFileExA\r
+@ stub SetupInstallFileExW\r
+@ stub SetupInstallFileW\r
+@ stdcall SetupInstallFilesFromInfSectionA(long long long str str long)\r
+@ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long)\r
+@ stdcall SetupInstallFromInfSectionA(long long str long long str long ptr ptr long ptr)\r
+@ stdcall SetupInstallFromInfSectionW(long long wstr long long wstr long ptr ptr long ptr)\r
+@ stub SetupInstallServicesFromInfSectionA\r
+@ stub SetupInstallServicesFromInfSectionExA\r
+@ stub SetupInstallServicesFromInfSectionExW\r
+@ stub SetupInstallServicesFromInfSectionW\r
+@ stdcall SetupIterateCabinetA(str long ptr ptr)\r
+@ stdcall SetupIterateCabinetW(wstr long ptr ptr)\r
+@ stub SetupLogErrorA\r
+@ stub SetupLogErrorW\r
+@ stub SetupLogFileA\r
+@ stub SetupLogFileW\r
+@ stdcall SetupOpenAppendInfFileA(str long ptr)\r
+@ stdcall SetupOpenAppendInfFileW(wstr long ptr)\r
+@ stdcall SetupOpenFileQueue()\r
+@ stdcall SetupOpenInfFileA(str str long ptr)\r
+@ stdcall SetupOpenInfFileW(wstr wstr long ptr)\r
+@ stdcall SetupOpenMasterInf()\r
+@ stub SetupPromptForDiskA\r
+@ stub SetupPromptForDiskW\r
+@ stub SetupPromptReboot\r
+@ stub SetupQueryDrivesInDiskSpaceListA\r
+@ stub SetupQueryDrivesInDiskSpaceListW\r
+@ stub SetupQueryFileLogA\r
+@ stub SetupQueryFileLogW\r
+@ stub SetupQueryInfFileInformationA\r
+@ stub SetupQueryInfFileInformationW\r
+@ stub SetupQueryInfOriginalFileInformationA\r
+@ stub SetupQueryInfOriginalFileInformationW\r
+@ stub SetupQueryInfVersionInformationA\r
+@ stub SetupQueryInfVersionInformationW\r
+@ stub SetupQuerySourceListA\r
+@ stub SetupQuerySourceListW\r
+@ stdcall SetupQuerySpaceRequiredOnDriveA(long str ptr ptr long)\r
+@ stub SetupQuerySpaceRequiredOnDriveW\r
+@ stdcall SetupQueueCopyA(long str str str str str str str long)\r
+@ stdcall SetupQueueCopyIndirectA(ptr)\r
+@ stdcall SetupQueueCopyIndirectW(ptr)\r
+@ stdcall SetupQueueCopySectionA(long str long long str long)\r
+@ stdcall SetupQueueCopySectionW(long wstr long long wstr long)\r
+@ stdcall SetupQueueCopyW(long wstr wstr wstr wstr wstr wstr wstr long)\r
+@ stdcall SetupQueueDefaultCopyA(long long str str str long)\r
+@ stdcall SetupQueueDefaultCopyW(long long wstr wstr wstr long)\r
+@ stdcall SetupQueueDeleteA(long str str)\r
+@ stdcall SetupQueueDeleteSectionA(long long long str)\r
+@ stdcall SetupQueueDeleteSectionW(long long long wstr)\r
+@ stdcall SetupQueueDeleteW(long wstr wstr)\r
+@ stdcall SetupQueueRenameA(long str str str str)\r
+@ stdcall SetupQueueRenameSectionA(long long long str)\r
+@ stdcall SetupQueueRenameSectionW(long long long wstr)\r
+@ stdcall SetupQueueRenameW(long wstr wstr wstr wstr)\r
+@ stub SetupRemoveFileLogEntryA\r
+@ stub SetupRemoveFileLogEntryW\r
+@ stub SetupRemoveFromDiskSpaceListA\r
+@ stub SetupRemoveFromDiskSpaceListW\r
+@ stub SetupRemoveFromSourceListA\r
+@ stub SetupRemoveFromSourceListW\r
+@ stub SetupRemoveInstallSectionFromDiskSpaceListA\r
+@ stub SetupRemoveInstallSectionFromDiskSpaceListW\r
+@ stub SetupRemoveSectionFromDiskSpaceListA\r
+@ stub SetupRemoveSectionFromDiskSpaceListW\r
+@ stub SetupRenameErrorA\r
+@ stub SetupRenameErrorW\r
+@ stub SetupScanFileQueue\r
+@ stdcall SetupScanFileQueueA(long long long ptr ptr ptr)\r
+@ stdcall SetupScanFileQueueW(long long long ptr ptr ptr)\r
+@ stdcall SetupSetDirectoryIdA(long long str)\r
+@ stub SetupSetDirectoryIdExA\r
+@ stub SetupSetDirectoryIdExW\r
+@ stdcall SetupSetDirectoryIdW(long long wstr)\r
+@ stub SetupFileQueueAlternatePlatformA\r
+@ stub SetupFileQueueAlternatePlatformW\r
+@ stdcall SetupSetFileQueueFlags(long long long)\r
+@ stub SetupSetPlatformPathOverrideA\r
+@ stub SetupSetPlatformPathOverrideW\r
+@ stub SetupSetSourceListA\r
+@ stub SetupSetSourceListW\r
+@ stdcall SetupTermDefaultQueueCallback(ptr)\r
+@ stdcall SetupTerminateFileLog(long)\r
+@ stub ShouldDeviceBeExcluded\r
+@ stub StampFileSecurity\r
+@ stub StringTableAddString\r
+@ stub StringTableAddStringEx\r
+@ stub StringTableDestroy\r
+@ stub StringTableDuplicate\r
+@ stub StringTableEnum\r
+@ stub StringTableGetExtraData\r
+@ stub StringTableInitialize\r
+@ stub StringTableInitializeEx\r
+@ stub StringTableLookUpString\r
+@ stub StringTableLookUpStringEx\r
+@ stub StringTableSetExtraData\r
+@ stub StringTableStringFromId\r
+@ stub StringTableTrim\r
+@ stub TakeOwnershipOfFile\r
+@ stdcall UnicodeToMultiByte(wstr long)\r
+@ stub UnmapAndCloseFile\r
+@ stub VerifyCatalogFile\r
+@ stub VerifyFile\r
+@ stub pSetupAccessRunOnceNodeList\r
+@ stub pSetupAddMiniIconToList\r
+@ stub pSetupAddTagToGroupOrderListEntry\r
+@ stub pSetupAppendStringToMultiSz\r
+@ stub pSetupDestroyRunOnceNodeList\r
+@ stub pSetupDirectoryIdToPath\r
+@ stub pSetupGetField\r
+@ stub pSetupGetGlobalFlags\r
+@ stub pSetupGetOsLoaderDriveAndPath\r
+@ stub pSetupGetQueueFlags\r
+@ stub pSetupGetVersionDatum\r
+@ stub pSetupGuidFromString\r
+@ stub pSetupIsGuidNull\r
+@ stub pSetupMakeSurePathExists\r
+@ stub pSetupSetGlobalFlags\r
+@ stub pSetupSetQueueFlags\r
+@ stub pSetupSetSystemSourceFlags\r
+@ stub pSetupStringFromGuid\r
+@ stub pSetupVerifyQueuedCatalogs\r
index cea0b8c..739d6c5 100644 (file)
@@ -2,6 +2,7 @@
        <importlibrary definition="setupapi.spec.def" />\r
        <include base="setupapi">.</include>\r
        <include base="ReactOS">include/wine</include>\r
+       <include base="pnp_client">.</include>\r
        <define name="UNICODE" />\r
        <define name="_UNICODE" />\r
        <define name="__REACTOS__" />\r
@@ -11,6 +12,7 @@
        <define name="WINVER">0x501</define>\r
        <define name="__WINESRC__" />\r
        <define name="_SETUPAPI_" />\r
+       <library>pnp_client</library>\r
        <library>wine</library>\r
        <library>ntdll</library>\r
        <library>kernel32</library>\r
@@ -28,6 +30,7 @@
        <file>queue.c</file>\r
        <file>setupcab.c</file>\r
        <file>stubs.c</file>\r
+       <file>rpc.c</file>\r
        <file>setupapi.rc</file>\r
        <file>setupapi.spec</file>\r
 </module>\r
index 80d1f55..96d9019 100644 (file)
@@ -1,59 +1,61 @@
-/*
- * Copyright 2001 Andreas Mohr
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __SETUPAPI_PRIVATE_H
-#define __SETUPAPI_PRIVATE_H
-
-#define COPYFILEDLGORD 1000
-#define SOURCESTRORD   500
-#define DESTSTRORD     501
-#define PROGRESSORD    502
-
-
-#define REG_INSTALLEDFILES "System\\CurrentControlSet\\Control\\InstalledFiles"
-#define REGPART_RENAME "\\Rename"
-#define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager"
-
-/* string substitutions */
-
-struct inf_file;
-extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );
-extern unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text,
-                                          char *buffer, unsigned int size );
-extern unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text,
-                                          WCHAR *buffer, unsigned int size );
-extern const WCHAR *PARSER_get_src_root( HINF hinf );
-extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context );
-
-/* support for Ascii queue callback functions */
-
-struct callback_WtoA_context
-{
-    void               *orig_context;
-    PSP_FILE_CALLBACK_A orig_handler;
-};
-
-UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification, UINT_PTR, UINT_PTR );
-
-/* from msvcrt/sys/stat.h */
-#define _S_IWRITE 0x0080
-#define _S_IREAD  0x0100
-
-extern OSVERSIONINFOW OsVersionInfo;
-
-#endif /* __SETUPAPI_PRIVATE_H */
+/*\r
+ * Copyright 2001 Andreas Mohr\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#ifndef __SETUPAPI_PRIVATE_H\r
+#define __SETUPAPI_PRIVATE_H\r
+\r
+#define COPYFILEDLGORD 1000\r
+#define SOURCESTRORD   500\r
+#define DESTSTRORD     501\r
+#define PROGRESSORD    502\r
+\r
+\r
+#define REG_INSTALLEDFILES "System\\CurrentControlSet\\Control\\InstalledFiles"\r
+#define REGPART_RENAME "\\Rename"\r
+#define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager"\r
+\r
+/* string substitutions */\r
+\r
+struct inf_file;\r
+extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );\r
+extern unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text,\r
+                                          char *buffer, unsigned int size );\r
+extern unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text,\r
+                                          WCHAR *buffer, unsigned int size );\r
+extern const WCHAR *PARSER_get_src_root( HINF hinf );\r
+extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context );\r
+\r
+/* support for Ascii queue callback functions */\r
+\r
+struct callback_WtoA_context\r
+{\r
+    void               *orig_context;\r
+    PSP_FILE_CALLBACK_A orig_handler;\r
+};\r
+\r
+UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification, UINT_PTR, UINT_PTR );\r
+\r
+/* from msvcrt/sys/stat.h */\r
+#define _S_IWRITE 0x0080\r
+#define _S_IREAD  0x0100\r
+\r
+extern OSVERSIONINFOW OsVersionInfo;\r
+\r
+DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst);\r
+\r
+#endif /* __SETUPAPI_PRIVATE_H */\r
index 9c10813..470f8aa 100644 (file)
-/* 
- * Setupapi cabinet routines
- *
- * Copyright 2003 Gregory M. Turner
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *
- * Many useful traces are commented in code, uncomment them if you have
- * trouble and run with WINEDEBUG=+setupapi
- * 
- */
-
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "wine/debug.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "setupapi.h"
-#include "setupapi_private.h"
-#include "fdi.h"
-#include "wine/unicode.h"
-
-#include "fcntl.h"
-#include "share.h"
-
-#include "wine/debug.h"
-
-OSVERSIONINFOW OsVersionInfo;
-
-static HINSTANCE CABINET_hInstance = 0;
-
-static HFDI (__cdecl *sc_FDICreate)(PFNALLOC, PFNFREE, PFNOPEN,
-                PFNREAD, PFNWRITE, PFNCLOSE, PFNSEEK, int, PERF);
-
-static BOOL (__cdecl *sc_FDICopy)(HFDI, char *, char *, int,
-                PFNFDINOTIFY, PFNFDIDECRYPT, void *);
-
-static BOOL (__cdecl *sc_FDIDestroy)(HFDI);
-
-#define SC_HSC_A_MAGIC 0xACABFEED
-typedef struct {
-  UINT magic;
-  HFDI hfdi;
-  PSP_FILE_CALLBACK_A msghandler;
-  PVOID context;
-  CHAR most_recent_cabinet_name[MAX_PATH];
-} SC_HSC_A, *PSC_HSC_A;
-
-#define SC_HSC_W_MAGIC 0x0CABFEED
-typedef struct {
-  UINT magic;
-  HFDI hfdi;
-  PSP_FILE_CALLBACK_W msghandler;
-  PVOID context;
-  WCHAR most_recent_cabinet_name[MAX_PATH];
-} SC_HSC_W, *PSC_HSC_W;
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-static BOOL LoadCABINETDll(void)
-{
-  if (!CABINET_hInstance) {
-    CABINET_hInstance = LoadLibraryA("cabinet.dll");
-    if (CABINET_hInstance)  {
-      sc_FDICreate = (void *)GetProcAddress(CABINET_hInstance, "FDICreate");
-      sc_FDICopy = (void *)GetProcAddress(CABINET_hInstance, "FDICopy");
-      sc_FDIDestroy = (void *)GetProcAddress(CABINET_hInstance, "FDIDestroy");
-      return TRUE;
-    } else {
-      ERR("load cabinet dll failed.\n");
-      return FALSE;
-    }
-  } else
-    return TRUE;
-}
-
-static void UnloadCABINETDll(void)
-{
-  if (CABINET_hInstance) {
-    FreeLibrary(CABINET_hInstance);
-    CABINET_hInstance = 0;
-  }
-}
-
-/* FDICreate callbacks */
-
-static void *sc_cb_alloc(ULONG cb)
-{
-  return malloc(cb);
-}
-
-static void sc_cb_free(void *pv)
-{
-  free(pv);
-}
-
-static INT_PTR sc_cb_open(char *pszFile, int oflag, int pmode)
-{
-  DWORD creation = 0, sharing = 0;
-  int ioflag = 0;
-  INT_PTR ret = 0;
-  SECURITY_ATTRIBUTES sa;
-
-  /* TRACE("(pszFile == %s, oflag == %d, pmode == %d)\n", debugstr_a(pszFile), oflag, pmode); */
-
-  switch(oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
-  case _O_RDONLY:
-    ioflag |= GENERIC_READ;
-    break;
-  case _O_WRONLY:
-    ioflag |= GENERIC_WRITE;
-    break;
-  case _O_RDWR:
-    ioflag |= GENERIC_READ & GENERIC_WRITE;
-    break;
-  case _O_WRONLY | _O_RDWR: /* hmmm.. */
-    ERR("_O_WRONLY & _O_RDWR in oflag?\n");
-    return -1;
-  }
-
-  if (oflag & _O_CREAT) {
-    if (oflag & _O_EXCL)
-      creation = CREATE_NEW;
-    else if (oflag & _O_TRUNC)
-      creation = CREATE_ALWAYS;
-    else
-      creation = OPEN_ALWAYS;
-  } else  /* no _O_CREAT */ {
-    if (oflag & _O_TRUNC)
-      creation = TRUNCATE_EXISTING;
-    else
-      creation = OPEN_EXISTING;
-  }
-
-  switch( pmode & 0x70 ) {
-    case _SH_DENYRW:
-      sharing = 0L;
-      break;
-    case _SH_DENYWR:
-      sharing = FILE_SHARE_READ;
-      break;
-    case _SH_DENYRD:
-      sharing = FILE_SHARE_WRITE;
-      break;
-    case _SH_COMPAT:
-    case _SH_DENYNO:
-      sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
-      break;
-    default:
-      ERR("<-- -1 (Unhandled pmode 0x%x)\n", pmode);
-      return -1;
-  }
-
-  if (oflag & ~(_O_BINARY | _O_TRUNC | _O_EXCL | _O_CREAT | _O_RDWR | _O_WRONLY | _O_NOINHERIT))
-    WARN("unsupported oflag 0x%04x\n",oflag);
-
-  sa.nLength              = sizeof( SECURITY_ATTRIBUTES );
-  sa.lpSecurityDescriptor = NULL;
-  sa.bInheritHandle       = (ioflag & _O_NOINHERIT) ? FALSE : TRUE;
-
-  ret = (INT_PTR) CreateFileA(pszFile, ioflag, sharing, &sa, creation, FILE_ATTRIBUTE_NORMAL, NULL);
-
-  /* TRACE("<-- %d\n", ret); */
-
-  return ret;
-}
-
-static UINT sc_cb_read(INT_PTR hf, void *pv, UINT cb)
-{
-  DWORD num_read;
-  BOOL rslt;
-
-  /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */
-
-  rslt = ReadFile((HANDLE) hf, pv, cb, &num_read, NULL);
-
-
-  /* eof and failure both give "-1" return */
-  if ((! rslt) || ((cb > 0) && (num_read == 0))) {
-    /* TRACE("<-- -1\n"); */
-    return -1;
-  }
-
-  /* TRACE("<-- %lu\n", num_read); */
-  return num_read;
-}
-
-static UINT sc_cb_write(INT_PTR hf, void *pv, UINT cb)
-{
-  DWORD num_written;
-  /* BOOL rv; */
-
-  /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */
-
-  if ( /* (rv = */ WriteFile((HANDLE) hf, pv, cb, &num_written, NULL) /* ) */
-       && (num_written == cb)) {
-    /* TRACE("<-- %lu\n", num_written); */
-    return num_written;
-  } else {
-    /* TRACE("rv == %d, num_written == %lu, cb == %u\n", rv, num_written,cb); */
-    /* TRACE("<-- -1\n"); */
-    return -1;
-  }
-}
-
-static int sc_cb_close(INT_PTR hf)
-{
-  /* TRACE("(hf == %d)\n", hf); */
-
-  if (CloseHandle((HANDLE) hf))
-    return 0;
-  else
-    return -1;
-}
-
-static long sc_cb_lseek(INT_PTR hf, long dist, int seektype)
-{
-  DWORD ret;
-
-  /* TRACE("(hf == %d, dist == %ld, seektype == %d)\n", hf, dist, seektype); */
-
-  if (seektype < 0 || seektype > 2)
-    return -1;
-
-  if (((ret = SetFilePointer((HANDLE) hf, dist, NULL, seektype)) != INVALID_SET_FILE_POINTER) || !GetLastError()) {
-    /* TRACE("<-- %lu\n", ret); */
-    return ret;
-  } else {
-    /* TRACE("<-- -1\n"); */
-    return -1;
-  }
-}
-
-#define SIZEOF_MYSTERIO (MAX_PATH*3)
-
-/* FDICopy callbacks */
-
-static INT_PTR sc_FNNOTIFY_A(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
-  FILE_IN_CABINET_INFO_A fici;
-  PSC_HSC_A phsc;
-  CABINET_INFO_A ci;
-  FILEPATHS_A fp;
-  UINT err;
-
-  CHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! probably 256... */
-
-  memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO);
-
-  TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
-
-  if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_A_MAGIC))
-    phsc = (PSC_HSC_A) pfdin->pv;
-  else {
-    ERR("pv %p is not an SC_HSC_A.\n", (pfdin) ? pfdin->pv : NULL);
-    return -1;
-  }
-
-  switch (fdint) {
-  case fdintCABINET_INFO:
-    TRACE("Cabinet info notification\n");
-    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
-    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
-    TRACE("  Cabinet Set#: %d\n", pfdin->setID);
-    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
-    WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");
-    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
-    ci.CabinetPath = pfdin->psz3;
-    ci.DiskName = pfdin->psz2;
-    ci.SetId = pfdin->setID;
-    ci.CabinetNumber = pfdin->iCabinet;
-    phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);
-    return 0;
-  case fdintPARTIAL_FILE:
-    TRACE("Partial file notification\n");
-    /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */
-    return 0;
-  case fdintCOPY_FILE:
-    TRACE("Copy file notification\n");
-    TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
-    /* TRACE("  File size: %ld\n", pfdin->cb);
-    TRACE("  File date: %u\n", pfdin->date);
-    TRACE("  File time: %u\n", pfdin->time);
-    TRACE("  File attr: %u\n", pfdin->attribs); */
-    fici.NameInCabinet = pfdin->psz1;
-    fici.FileSize = pfdin->cb;
-    fici.Win32Error = 0;
-    fici.DosDate = pfdin->date;
-    fici.DosTime = pfdin->time;
-    fici.DosAttribs = pfdin->attribs;
-    memset(&(fici.FullTargetName[0]), 0, MAX_PATH);
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
-                           (UINT) &fici, (UINT) pfdin->psz1);
-    if (err == FILEOP_DOIT) {
-      TRACE("  Callback specified filename: %s\n", debugstr_a(&(fici.FullTargetName[0])));
-      if (!fici.FullTargetName[0]) {
-        WARN("  Empty return string causing abort.\n");
-        SetLastError(ERROR_PATH_NOT_FOUND);
-        return -1;
-      }
-      return sc_cb_open(&(fici.FullTargetName[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);
-    } else {
-      TRACE("  Callback skipped file.\n");
-      return 0;
-    }
-  case fdintCLOSE_FILE_INFO:
-    TRACE("Close file notification\n");
-    /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");
-    TRACE("  File hndl: %d\n", pfdin->hf); */
-    fp.Source = &(phsc->most_recent_cabinet_name[0]);
-    fp.Target = pfdin->psz1;
-    fp.Win32Error = 0;
-    fp.Flags = 0;
-    /* the following should be a fixme -- but it occurs too many times */
-    WARN("Should set file date/time/attribs (and execute files?)\n");
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);
-    if (sc_cb_close(pfdin->hf))
-      WARN("_close failed.\n");
-    if (err) {
-      SetLastError(err);
-      return FALSE;
-    } else
-      return TRUE;
-  case fdintNEXT_CABINET:
-    TRACE("Next cabinet notification\n");
-    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
-    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
-    TRACE("  Cabinet Set#: %d\n", pfdin->setID);
-    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
-    ci.CabinetFile = pfdin->psz1;
-    ci.CabinetPath = pfdin->psz3;
-    ci.DiskName = pfdin->psz2;
-    ci.SetId = pfdin->setID;
-    ci.CabinetNumber = pfdin->iCabinet;
-    /* remember the new cabinet name */
-    strcpy(&(phsc->most_recent_cabinet_name[0]), pfdin->psz1);
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
-    if (err) {
-      SetLastError(err);
-      return -1;
-    } else {
-      if (mysterio[0]) {
-        /* some easy paranoia.  no such carefulness exists on the wide API IIRC */
-        mysterio[SIZEOF_MYSTERIO - 1] = '\0';
-        strncpy(pfdin->psz3, &(mysterio[0]), 255);
-        mysterio[255] = '\0';
-      }
-      return 0;
-    }
-  default:
-    FIXME("Unknown notification type %d.\n", fdint);
-    return 0;
-  }
-}
-
-static INT_PTR sc_FNNOTIFY_W(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
-  FILE_IN_CABINET_INFO_W fici;
-  PSC_HSC_W phsc;
-  CABINET_INFO_W ci;
-  FILEPATHS_W fp;
-  UINT err;
-  int len;
-
-  WCHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! */
-  WCHAR buf[MAX_PATH], buf2[MAX_PATH];
-  CHAR charbuf[MAX_PATH];
-
-  memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO * sizeof(WCHAR));
-  memset(&(buf[0]), 0, MAX_PATH * sizeof(WCHAR));
-  memset(&(buf2[0]), 0, MAX_PATH * sizeof(WCHAR));
-  memset(&(charbuf[0]), 0, MAX_PATH);
-
-  TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);
-
-  if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_W_MAGIC))
-    phsc = (PSC_HSC_W) pfdin->pv;
-  else {
-    ERR("pv %p is not an SC_HSC_W.\n", (pfdin) ? pfdin->pv : NULL);
-    return -1;
-  }
-
-  switch (fdint) {
-  case fdintCABINET_INFO:
-    TRACE("Cabinet info notification\n");
-    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
-    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
-    TRACE("  Cabinet Set#: %d\n", pfdin->setID);
-    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
-    WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");
-    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf[0] = '\0';
-    ci.CabinetPath = &(buf[0]);
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf2[0] = '\0';
-    ci.DiskName = &(buf2[0]);
-    ci.SetId = pfdin->setID;
-    ci.CabinetNumber = pfdin->iCabinet;
-    phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);
-    return 0;
-  case fdintPARTIAL_FILE:
-    TRACE("Partial file notification\n");
-    /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */
-    return 0;
-  case fdintCOPY_FILE:
-    TRACE("Copy file notification\n");
-    TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
-    /* TRACE("  File size: %ld\n", pfdin->cb);
-    TRACE("  File date: %u\n", pfdin->date);
-    TRACE("  File time: %u\n", pfdin->time);
-    TRACE("  File attr: %u\n", pfdin->attribs); */
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf2[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf2[0] = '\0';
-    fici.NameInCabinet = &(buf2[0]);
-    fici.FileSize = pfdin->cb;
-    fici.Win32Error = 0;
-    fici.DosDate = pfdin->date;
-    fici.DosTime = pfdin->time;
-    fici.DosAttribs = pfdin->attribs;
-    memset(&(fici.FullTargetName[0]), 0, MAX_PATH * sizeof(WCHAR));
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,
-                           (UINT) &fici, (UINT) pfdin->psz1);
-    if (err == FILEOP_DOIT) {
-      TRACE("  Callback specified filename: %s\n", debugstr_w(&(fici.FullTargetName[0])));
-      if (fici.FullTargetName[0]) {
-        len = strlenW(&(fici.FullTargetName[0])) + 1;
-        if ((len > MAX_PATH ) || (len <= 1))
-          return 0;
-        if (!WideCharToMultiByte(CP_ACP, 0, &(fici.FullTargetName[0]), len, &(charbuf[0]), MAX_PATH, 0, 0))
-          return 0;
-      } else {
-        WARN("Empty buffer string caused abort.\n");
-        SetLastError(ERROR_PATH_NOT_FOUND);
-        return -1;
-      }
-      return sc_cb_open(&(charbuf[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);
-    } else {
-      TRACE("  Callback skipped file.\n");
-      return 0;
-    }
-  case fdintCLOSE_FILE_INFO:
-    TRACE("Close file notification\n");
-    /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");
-    TRACE("  File hndl: %d\n", pfdin->hf); */
-    fp.Source = &(phsc->most_recent_cabinet_name[0]);
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf[0] = '\0';
-    fp.Target = &(buf[0]);
-    fp.Win32Error = 0;
-    fp.Flags = 0;
-    /* a valid fixme -- but occurs too many times */
-    /* FIXME("Should set file date/time/attribs (and execute files?)\n"); */
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);
-    if (sc_cb_close(pfdin->hf))
-      WARN("_close failed.\n");
-    if (err) {
-      SetLastError(err);
-      return FALSE;
-    } else
-      return TRUE;
-  case fdintNEXT_CABINET:
-    TRACE("Next cabinet notification\n");
-    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));
-    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));
-    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));
-    TRACE("  Cabinet Set#: %d\n", pfdin->setID);
-    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */
-    /* remember the new cabinet name */
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(phsc->most_recent_cabinet_name[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      phsc->most_recent_cabinet_name[0] = '\0';
-    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf[0] = '\0';
-    ci.CabinetPath = &(buf[0]);
-    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);
-    if ((len > MAX_PATH) || (len <= 1))
-      buf2[0] = '\0';
-    ci.DiskName = &(buf2[0]);
-    ci.SetId = pfdin->setID;
-    ci.CabinetNumber = pfdin->iCabinet;
-    err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));
-    if (err) {
-      SetLastError(err);
-      return -1;
-    } else {
-      if (mysterio[0]) {
-        len = strlenW(&(mysterio[0])) + 1;
-        if ((len > 255) || (len <= 1))
-          return 0;
-        if (!WideCharToMultiByte(CP_ACP, 0, &(mysterio[0]), len, pfdin->psz3, 255, 0, 0))
-          return 0;
-      }
-      return 0;
-    }
-  default:
-    FIXME("Unknown notification type %d.\n", fdint);
-    return 0;
-  }
-}
-
-/***********************************************************************
- *             SetupIterateCabinetA (SETUPAPI.@)
- */
-BOOL WINAPI SetupIterateCabinetA(PCSTR CabinetFile, DWORD Reserved,
-                                 PSP_FILE_CALLBACK_A MsgHandler, PVOID Context)
-{
-
-  SC_HSC_A my_hsc;
-  ERF erf;
-  CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH], *p;
-  DWORD fpnsize;
-  BOOL ret;
-
-
-  TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",
-        debugstr_a(CabinetFile), Reserved, MsgHandler, Context);
-
-  if (! LoadCABINETDll()) 
-    return FALSE;
-
-  memset(&my_hsc, 0, sizeof(SC_HSC_A));
-  pszCabinet[0] = '\0';
-  pszCabPath[0] = '\0';
-
-  fpnsize = strlen(CabinetFile);
-  if (fpnsize >= MAX_PATH) {
-    SetLastError(ERROR_BAD_PATHNAME);
-    return FALSE;
-  }
-
-  fpnsize = GetFullPathNameA(CabinetFile, MAX_PATH, &(pszCabPath[0]), &p);
-  if (fpnsize > MAX_PATH) {
-    SetLastError(ERROR_BAD_PATHNAME);
-    return FALSE;
-  }
-
-  if (p) {
-    strcpy(pszCabinet, p);
-    *p = '\0';
-  } else {
-    strcpy(pszCabinet, CabinetFile);
-    pszCabPath[0] = '\0';
-  }
-
-  TRACE("path: %s, cabfile: %s\n", debugstr_a(pszCabPath), debugstr_a(pszCabinet));
-
-  /* remember the cabinet name */
-  strcpy(&(my_hsc.most_recent_cabinet_name[0]), pszCabinet);
-
-  my_hsc.magic = SC_HSC_A_MAGIC;
-  my_hsc.msghandler = MsgHandler;
-  my_hsc.context = Context;
-  my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
-                           sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
-
-  if (!my_hsc.hfdi) return FALSE;
-
-  ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
-                     0, sc_FNNOTIFY_A, NULL, &my_hsc)     ) ? TRUE : FALSE;
-
-  sc_FDIDestroy(my_hsc.hfdi);
-  return ret;
-}
-
-
-/***********************************************************************
- *             SetupIterateCabinetW (SETUPAPI.@)
- */
-BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved,
-                                 PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)
-{
-  CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH];
-  UINT len;
-  SC_HSC_W my_hsc;
-  ERF erf;
-  WCHAR pszCabPathW[MAX_PATH], *p;
-  DWORD fpnsize;
-  BOOL ret;
-
-  TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",
-        debugstr_w(CabinetFile), Reserved, MsgHandler, Context);
-
-  if (!LoadCABINETDll())
-    return FALSE;
-
-  if (!CabinetFile) return FALSE;
-
-  memset(&my_hsc, 0, sizeof(SC_HSC_W));
-
-  fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p);
-  if (fpnsize > MAX_PATH) {
-    SetLastError(ERROR_BAD_PATHNAME);
-    return FALSE;
-  }
-
-  if (p) {
-    strcpyW(my_hsc.most_recent_cabinet_name, p);
-    *p = 0;
-    len = WideCharToMultiByte(CP_ACP, 0, pszCabPathW, -1, pszCabPath,
-                               MAX_PATH, 0, 0);
-    if (!len) return FALSE;
-  } else {
-    strcpyW(my_hsc.most_recent_cabinet_name, CabinetFile);
-    pszCabPath[0] = '\0';
-  }
-
-  len = WideCharToMultiByte(CP_ACP, 0, my_hsc.most_recent_cabinet_name, -1,
-                               pszCabinet, MAX_PATH, 0, 0);
-  if (!len) return FALSE;
-
-  TRACE("path: %s, cabfile: %s\n",
-       debugstr_a(pszCabPath), debugstr_a(pszCabinet));
-
-  my_hsc.magic = SC_HSC_W_MAGIC;
-  my_hsc.msghandler = MsgHandler;
-  my_hsc.context = Context;
-  my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,
-                              sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );
-
-  if (!my_hsc.hfdi) return FALSE;
-
-  ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,
-                     0, sc_FNNOTIFY_W, NULL, &my_hsc)     ) ? TRUE : FALSE;
-
-  sc_FDIDestroy(my_hsc.hfdi);
-  return ret;
-}
-
-
-/***********************************************************************
- * DllMain
- *
- * PARAMS
- *     hinstDLL    [I] handle to the DLL's instance
- *     fdwReason   [I]
- *     lpvReserved [I] reserved, must be NULL
- *
- * RETURNS
- *     Success: TRUE
- *     Failure: FALSE
- */
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
-    switch (fdwReason) {
-    case DLL_PROCESS_ATTACH:
-        DisableThreadLibraryCalls(hinstDLL);
-        OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
-        if (!GetVersionExW(&OsVersionInfo))
-            return FALSE;
-        break;
-    case DLL_PROCESS_DETACH:
-        UnloadCABINETDll();
-        break;
-    }
-
-    return TRUE;
-}
+/* \r
+ * Setupapi cabinet routines\r
+ *\r
+ * Copyright 2003 Gregory M. Turner\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ *\r
+ * Many useful traces are commented in code, uncomment them if you have\r
+ * trouble and run with WINEDEBUG=+setupapi\r
+ * \r
+ */\r
+\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#include "wine/debug.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "winreg.h"\r
+#include "setupapi.h"\r
+#include "setupapi_private.h"\r
+#include "fdi.h"\r
+#include "wine/unicode.h"\r
+\r
+#include "fcntl.h"\r
+#include "share.h"\r
+\r
+#include "wine/debug.h"\r
+\r
+OSVERSIONINFOW OsVersionInfo;\r
+\r
+static HINSTANCE CABINET_hInstance = 0;\r
+\r
+static HFDI (__cdecl *sc_FDICreate)(PFNALLOC, PFNFREE, PFNOPEN,\r
+                PFNREAD, PFNWRITE, PFNCLOSE, PFNSEEK, int, PERF);\r
+\r
+static BOOL (__cdecl *sc_FDICopy)(HFDI, char *, char *, int,\r
+                PFNFDINOTIFY, PFNFDIDECRYPT, void *);\r
+\r
+static BOOL (__cdecl *sc_FDIDestroy)(HFDI);\r
+\r
+#define SC_HSC_A_MAGIC 0xACABFEED\r
+typedef struct {\r
+  UINT magic;\r
+  HFDI hfdi;\r
+  PSP_FILE_CALLBACK_A msghandler;\r
+  PVOID context;\r
+  CHAR most_recent_cabinet_name[MAX_PATH];\r
+} SC_HSC_A, *PSC_HSC_A;\r
+\r
+#define SC_HSC_W_MAGIC 0x0CABFEED\r
+typedef struct {\r
+  UINT magic;\r
+  HFDI hfdi;\r
+  PSP_FILE_CALLBACK_W msghandler;\r
+  PVOID context;\r
+  WCHAR most_recent_cabinet_name[MAX_PATH];\r
+} SC_HSC_W, *PSC_HSC_W;\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+static BOOL LoadCABINETDll(void)\r
+{\r
+  if (!CABINET_hInstance) {\r
+    CABINET_hInstance = LoadLibraryA("cabinet.dll");\r
+    if (CABINET_hInstance)  {\r
+      sc_FDICreate = (void *)GetProcAddress(CABINET_hInstance, "FDICreate");\r
+      sc_FDICopy = (void *)GetProcAddress(CABINET_hInstance, "FDICopy");\r
+      sc_FDIDestroy = (void *)GetProcAddress(CABINET_hInstance, "FDIDestroy");\r
+      return TRUE;\r
+    } else {\r
+      ERR("load cabinet dll failed.\n");\r
+      return FALSE;\r
+    }\r
+  } else\r
+    return TRUE;\r
+}\r
+\r
+static void UnloadCABINETDll(void)\r
+{\r
+  if (CABINET_hInstance) {\r
+    FreeLibrary(CABINET_hInstance);\r
+    CABINET_hInstance = 0;\r
+  }\r
+}\r
+\r
+/* FDICreate callbacks */\r
+\r
+static void *sc_cb_alloc(ULONG cb)\r
+{\r
+  return malloc(cb);\r
+}\r
+\r
+static void sc_cb_free(void *pv)\r
+{\r
+  free(pv);\r
+}\r
+\r
+static INT_PTR sc_cb_open(char *pszFile, int oflag, int pmode)\r
+{\r
+  DWORD creation = 0, sharing = 0;\r
+  int ioflag = 0;\r
+  INT_PTR ret = 0;\r
+  SECURITY_ATTRIBUTES sa;\r
+\r
+  /* TRACE("(pszFile == %s, oflag == %d, pmode == %d)\n", debugstr_a(pszFile), oflag, pmode); */\r
+\r
+  switch(oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {\r
+  case _O_RDONLY:\r
+    ioflag |= GENERIC_READ;\r
+    break;\r
+  case _O_WRONLY:\r
+    ioflag |= GENERIC_WRITE;\r
+    break;\r
+  case _O_RDWR:\r
+    ioflag |= GENERIC_READ & GENERIC_WRITE;\r
+    break;\r
+  case _O_WRONLY | _O_RDWR: /* hmmm.. */\r
+    ERR("_O_WRONLY & _O_RDWR in oflag?\n");\r
+    return -1;\r
+  }\r
+\r
+  if (oflag & _O_CREAT) {\r
+    if (oflag & _O_EXCL)\r
+      creation = CREATE_NEW;\r
+    else if (oflag & _O_TRUNC)\r
+      creation = CREATE_ALWAYS;\r
+    else\r
+      creation = OPEN_ALWAYS;\r
+  } else  /* no _O_CREAT */ {\r
+    if (oflag & _O_TRUNC)\r
+      creation = TRUNCATE_EXISTING;\r
+    else\r
+      creation = OPEN_EXISTING;\r
+  }\r
+\r
+  switch( pmode & 0x70 ) {\r
+    case _SH_DENYRW:\r
+      sharing = 0L;\r
+      break;\r
+    case _SH_DENYWR:\r
+      sharing = FILE_SHARE_READ;\r
+      break;\r
+    case _SH_DENYRD:\r
+      sharing = FILE_SHARE_WRITE;\r
+      break;\r
+    case _SH_COMPAT:\r
+    case _SH_DENYNO:\r
+      sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;\r
+      break;\r
+    default:\r
+      ERR("<-- -1 (Unhandled pmode 0x%x)\n", pmode);\r
+      return -1;\r
+  }\r
+\r
+  if (oflag & ~(_O_BINARY | _O_TRUNC | _O_EXCL | _O_CREAT | _O_RDWR | _O_WRONLY | _O_NOINHERIT))\r
+    WARN("unsupported oflag 0x%04x\n",oflag);\r
+\r
+  sa.nLength              = sizeof( SECURITY_ATTRIBUTES );\r
+  sa.lpSecurityDescriptor = NULL;\r
+  sa.bInheritHandle       = (ioflag & _O_NOINHERIT) ? FALSE : TRUE;\r
+\r
+  ret = (INT_PTR) CreateFileA(pszFile, ioflag, sharing, &sa, creation, FILE_ATTRIBUTE_NORMAL, NULL);\r
+\r
+  /* TRACE("<-- %d\n", ret); */\r
+\r
+  return ret;\r
+}\r
+\r
+static UINT sc_cb_read(INT_PTR hf, void *pv, UINT cb)\r
+{\r
+  DWORD num_read;\r
+  BOOL rslt;\r
+\r
+  /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */\r
+\r
+  rslt = ReadFile((HANDLE) hf, pv, cb, &num_read, NULL);\r
+\r
+\r
+  /* eof and failure both give "-1" return */\r
+  if ((! rslt) || ((cb > 0) && (num_read == 0))) {\r
+    /* TRACE("<-- -1\n"); */\r
+    return -1;\r
+  }\r
+\r
+  /* TRACE("<-- %lu\n", num_read); */\r
+  return num_read;\r
+}\r
+\r
+static UINT sc_cb_write(INT_PTR hf, void *pv, UINT cb)\r
+{\r
+  DWORD num_written;\r
+  /* BOOL rv; */\r
+\r
+  /* TRACE("(hf == %d, pv == ^%p, cb == %u)\n", hf, pv, cb); */\r
+\r
+  if ( /* (rv = */ WriteFile((HANDLE) hf, pv, cb, &num_written, NULL) /* ) */\r
+       && (num_written == cb)) {\r
+    /* TRACE("<-- %lu\n", num_written); */\r
+    return num_written;\r
+  } else {\r
+    /* TRACE("rv == %d, num_written == %lu, cb == %u\n", rv, num_written,cb); */\r
+    /* TRACE("<-- -1\n"); */\r
+    return -1;\r
+  }\r
+}\r
+\r
+static int sc_cb_close(INT_PTR hf)\r
+{\r
+  /* TRACE("(hf == %d)\n", hf); */\r
+\r
+  if (CloseHandle((HANDLE) hf))\r
+    return 0;\r
+  else\r
+    return -1;\r
+}\r
+\r
+static long sc_cb_lseek(INT_PTR hf, long dist, int seektype)\r
+{\r
+  DWORD ret;\r
+\r
+  /* TRACE("(hf == %d, dist == %ld, seektype == %d)\n", hf, dist, seektype); */\r
+\r
+  if (seektype < 0 || seektype > 2)\r
+    return -1;\r
+\r
+  if (((ret = SetFilePointer((HANDLE) hf, dist, NULL, seektype)) != INVALID_SET_FILE_POINTER) || !GetLastError()) {\r
+    /* TRACE("<-- %lu\n", ret); */\r
+    return ret;\r
+  } else {\r
+    /* TRACE("<-- -1\n"); */\r
+    return -1;\r
+  }\r
+}\r
+\r
+#define SIZEOF_MYSTERIO (MAX_PATH*3)\r
+\r
+/* FDICopy callbacks */\r
+\r
+static INT_PTR sc_FNNOTIFY_A(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)\r
+{\r
+  FILE_IN_CABINET_INFO_A fici;\r
+  PSC_HSC_A phsc;\r
+  CABINET_INFO_A ci;\r
+  FILEPATHS_A fp;\r
+  UINT err;\r
+\r
+  CHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! probably 256... */\r
+\r
+  memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO);\r
+\r
+  TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);\r
+\r
+  if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_A_MAGIC))\r
+    phsc = (PSC_HSC_A) pfdin->pv;\r
+  else {\r
+    ERR("pv %p is not an SC_HSC_A.\n", (pfdin) ? pfdin->pv : NULL);\r
+    return -1;\r
+  }\r
+\r
+  switch (fdint) {\r
+  case fdintCABINET_INFO:\r
+    TRACE("Cabinet info notification\n");\r
+    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));\r
+    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));\r
+    TRACE("  Cabinet Set#: %d\n", pfdin->setID);\r
+    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */\r
+    WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");\r
+    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);\r
+    ci.CabinetPath = pfdin->psz3;\r
+    ci.DiskName = pfdin->psz2;\r
+    ci.SetId = pfdin->setID;\r
+    ci.CabinetNumber = pfdin->iCabinet;\r
+    phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);\r
+    return 0;\r
+  case fdintPARTIAL_FILE:\r
+    TRACE("Partial file notification\n");\r
+    /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */\r
+    return 0;\r
+  case fdintCOPY_FILE:\r
+    TRACE("Copy file notification\n");\r
+    TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));\r
+    /* TRACE("  File size: %ld\n", pfdin->cb);\r
+    TRACE("  File date: %u\n", pfdin->date);\r
+    TRACE("  File time: %u\n", pfdin->time);\r
+    TRACE("  File attr: %u\n", pfdin->attribs); */\r
+    fici.NameInCabinet = pfdin->psz1;\r
+    fici.FileSize = pfdin->cb;\r
+    fici.Win32Error = 0;\r
+    fici.DosDate = pfdin->date;\r
+    fici.DosTime = pfdin->time;\r
+    fici.DosAttribs = pfdin->attribs;\r
+    memset(&(fici.FullTargetName[0]), 0, MAX_PATH);\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,\r
+                           (UINT) &fici, (UINT) pfdin->psz1);\r
+    if (err == FILEOP_DOIT) {\r
+      TRACE("  Callback specified filename: %s\n", debugstr_a(&(fici.FullTargetName[0])));\r
+      if (!fici.FullTargetName[0]) {\r
+        WARN("  Empty return string causing abort.\n");\r
+        SetLastError(ERROR_PATH_NOT_FOUND);\r
+        return -1;\r
+      }\r
+      return sc_cb_open(&(fici.FullTargetName[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);\r
+    } else {\r
+      TRACE("  Callback skipped file.\n");\r
+      return 0;\r
+    }\r
+  case fdintCLOSE_FILE_INFO:\r
+    TRACE("Close file notification\n");\r
+    /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");\r
+    TRACE("  File hndl: %d\n", pfdin->hf); */\r
+    fp.Source = &(phsc->most_recent_cabinet_name[0]);\r
+    fp.Target = pfdin->psz1;\r
+    fp.Win32Error = 0;\r
+    fp.Flags = 0;\r
+    /* the following should be a fixme -- but it occurs too many times */\r
+    WARN("Should set file date/time/attribs (and execute files?)\n");\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);\r
+    if (sc_cb_close(pfdin->hf))\r
+      WARN("_close failed.\n");\r
+    if (err) {\r
+      SetLastError(err);\r
+      return FALSE;\r
+    } else\r
+      return TRUE;\r
+  case fdintNEXT_CABINET:\r
+    TRACE("Next cabinet notification\n");\r
+    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));\r
+    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));\r
+    TRACE("  Cabinet Set#: %d\n", pfdin->setID);\r
+    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */\r
+    ci.CabinetFile = pfdin->psz1;\r
+    ci.CabinetPath = pfdin->psz3;\r
+    ci.DiskName = pfdin->psz2;\r
+    ci.SetId = pfdin->setID;\r
+    ci.CabinetNumber = pfdin->iCabinet;\r
+    /* remember the new cabinet name */\r
+    strcpy(&(phsc->most_recent_cabinet_name[0]), pfdin->psz1);\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));\r
+    if (err) {\r
+      SetLastError(err);\r
+      return -1;\r
+    } else {\r
+      if (mysterio[0]) {\r
+        /* some easy paranoia.  no such carefulness exists on the wide API IIRC */\r
+        mysterio[SIZEOF_MYSTERIO - 1] = '\0';\r
+        strncpy(pfdin->psz3, &(mysterio[0]), 255);\r
+        mysterio[255] = '\0';\r
+      }\r
+      return 0;\r
+    }\r
+  default:\r
+    FIXME("Unknown notification type %d.\n", fdint);\r
+    return 0;\r
+  }\r
+}\r
+\r
+static INT_PTR sc_FNNOTIFY_W(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)\r
+{\r
+  FILE_IN_CABINET_INFO_W fici;\r
+  PSC_HSC_W phsc;\r
+  CABINET_INFO_W ci;\r
+  FILEPATHS_W fp;\r
+  UINT err;\r
+  int len;\r
+\r
+  WCHAR mysterio[SIZEOF_MYSTERIO]; /* how big? undocumented! */\r
+  WCHAR buf[MAX_PATH], buf2[MAX_PATH];\r
+  CHAR charbuf[MAX_PATH];\r
+\r
+  memset(&(mysterio[0]), 0, SIZEOF_MYSTERIO * sizeof(WCHAR));\r
+  memset(&(buf[0]), 0, MAX_PATH * sizeof(WCHAR));\r
+  memset(&(buf2[0]), 0, MAX_PATH * sizeof(WCHAR));\r
+  memset(&(charbuf[0]), 0, MAX_PATH);\r
+\r
+  TRACE("(fdint == %d, pfdin == ^%p)\n", fdint, pfdin);\r
+\r
+  if (pfdin && pfdin->pv && (*((void **) pfdin->pv) == (void *)SC_HSC_W_MAGIC))\r
+    phsc = (PSC_HSC_W) pfdin->pv;\r
+  else {\r
+    ERR("pv %p is not an SC_HSC_W.\n", (pfdin) ? pfdin->pv : NULL);\r
+    return -1;\r
+  }\r
+\r
+  switch (fdint) {\r
+  case fdintCABINET_INFO:\r
+    TRACE("Cabinet info notification\n");\r
+    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));\r
+    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));\r
+    TRACE("  Cabinet Set#: %d\n", pfdin->setID);\r
+    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */\r
+    WARN("SPFILENOTIFY_CABINETINFO undocumented: guess implementation.\n");\r
+    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf[0] = '\0';\r
+    ci.CabinetPath = &(buf[0]);\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf2[0] = '\0';\r
+    ci.DiskName = &(buf2[0]);\r
+    ci.SetId = pfdin->setID;\r
+    ci.CabinetNumber = pfdin->iCabinet;\r
+    phsc->msghandler(phsc->context, SPFILENOTIFY_CABINETINFO, (UINT) &ci, 0);\r
+    return 0;\r
+  case fdintPARTIAL_FILE:\r
+    TRACE("Partial file notification\n");\r
+    /* TRACE("  Partial file name: %s\n", debugstr_a(pfdin->psz1)); */\r
+    return 0;\r
+  case fdintCOPY_FILE:\r
+    TRACE("Copy file notification\n");\r
+    TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));\r
+    /* TRACE("  File size: %ld\n", pfdin->cb);\r
+    TRACE("  File date: %u\n", pfdin->date);\r
+    TRACE("  File time: %u\n", pfdin->time);\r
+    TRACE("  File attr: %u\n", pfdin->attribs); */\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf2[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf2[0] = '\0';\r
+    fici.NameInCabinet = &(buf2[0]);\r
+    fici.FileSize = pfdin->cb;\r
+    fici.Win32Error = 0;\r
+    fici.DosDate = pfdin->date;\r
+    fici.DosTime = pfdin->time;\r
+    fici.DosAttribs = pfdin->attribs;\r
+    memset(&(fici.FullTargetName[0]), 0, MAX_PATH * sizeof(WCHAR));\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEINCABINET,\r
+                           (UINT) &fici, (UINT) pfdin->psz1);\r
+    if (err == FILEOP_DOIT) {\r
+      TRACE("  Callback specified filename: %s\n", debugstr_w(&(fici.FullTargetName[0])));\r
+      if (fici.FullTargetName[0]) {\r
+        len = strlenW(&(fici.FullTargetName[0])) + 1;\r
+        if ((len > MAX_PATH ) || (len <= 1))\r
+          return 0;\r
+        if (!WideCharToMultiByte(CP_ACP, 0, &(fici.FullTargetName[0]), len, &(charbuf[0]), MAX_PATH, 0, 0))\r
+          return 0;\r
+      } else {\r
+        WARN("Empty buffer string caused abort.\n");\r
+        SetLastError(ERROR_PATH_NOT_FOUND);\r
+        return -1;\r
+      }\r
+      return sc_cb_open(&(charbuf[0]), _O_BINARY | _O_CREAT | _O_WRONLY,  _S_IREAD | _S_IWRITE);\r
+    } else {\r
+      TRACE("  Callback skipped file.\n");\r
+      return 0;\r
+    }\r
+  case fdintCLOSE_FILE_INFO:\r
+    TRACE("Close file notification\n");\r
+    /* TRACE("  File name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Exec file? %s\n", (pfdin->cb) ? "Yes" : "No");\r
+    TRACE("  File hndl: %d\n", pfdin->hf); */\r
+    fp.Source = &(phsc->most_recent_cabinet_name[0]);\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(buf[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf[0] = '\0';\r
+    fp.Target = &(buf[0]);\r
+    fp.Win32Error = 0;\r
+    fp.Flags = 0;\r
+    /* a valid fixme -- but occurs too many times */\r
+    /* FIXME("Should set file date/time/attribs (and execute files?)\n"); */\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_FILEEXTRACTED, (UINT) &fp, 0);\r
+    if (sc_cb_close(pfdin->hf))\r
+      WARN("_close failed.\n");\r
+    if (err) {\r
+      SetLastError(err);\r
+      return FALSE;\r
+    } else\r
+      return TRUE;\r
+  case fdintNEXT_CABINET:\r
+    TRACE("Next cabinet notification\n");\r
+    /* TRACE("  Cabinet name: %s\n", debugstr_a(pfdin->psz1));\r
+    TRACE("  Cabinet disk: %s\n", debugstr_a(pfdin->psz2));\r
+    TRACE("  Cabinet path: %s\n", debugstr_a(pfdin->psz3));\r
+    TRACE("  Cabinet Set#: %d\n", pfdin->setID);\r
+    TRACE("  Cabinet Cab#: %d\n", pfdin->iCabinet); */\r
+    /* remember the new cabinet name */\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz1, -1, &(phsc->most_recent_cabinet_name[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      phsc->most_recent_cabinet_name[0] = '\0';\r
+    ci.CabinetFile = &(phsc->most_recent_cabinet_name[0]);\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz3, -1, &(buf[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf[0] = '\0';\r
+    ci.CabinetPath = &(buf[0]);\r
+    len = 1 + MultiByteToWideChar(CP_ACP, 0, pfdin->psz2, -1, &(buf2[0]), MAX_PATH);\r
+    if ((len > MAX_PATH) || (len <= 1))\r
+      buf2[0] = '\0';\r
+    ci.DiskName = &(buf2[0]);\r
+    ci.SetId = pfdin->setID;\r
+    ci.CabinetNumber = pfdin->iCabinet;\r
+    err = phsc->msghandler(phsc->context, SPFILENOTIFY_NEEDNEWCABINET, (UINT) &ci, (UINT) &(mysterio[0]));\r
+    if (err) {\r
+      SetLastError(err);\r
+      return -1;\r
+    } else {\r
+      if (mysterio[0]) {\r
+        len = strlenW(&(mysterio[0])) + 1;\r
+        if ((len > 255) || (len <= 1))\r
+          return 0;\r
+        if (!WideCharToMultiByte(CP_ACP, 0, &(mysterio[0]), len, pfdin->psz3, 255, 0, 0))\r
+          return 0;\r
+      }\r
+      return 0;\r
+    }\r
+  default:\r
+    FIXME("Unknown notification type %d.\n", fdint);\r
+    return 0;\r
+  }\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupIterateCabinetA (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupIterateCabinetA(PCSTR CabinetFile, DWORD Reserved,\r
+                                 PSP_FILE_CALLBACK_A MsgHandler, PVOID Context)\r
+{\r
+\r
+  SC_HSC_A my_hsc;\r
+  ERF erf;\r
+  CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH], *p;\r
+  DWORD fpnsize;\r
+  BOOL ret;\r
+\r
+\r
+  TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",\r
+        debugstr_a(CabinetFile), Reserved, MsgHandler, Context);\r
+\r
+  if (! LoadCABINETDll()) \r
+    return FALSE;\r
+\r
+  memset(&my_hsc, 0, sizeof(SC_HSC_A));\r
+  pszCabinet[0] = '\0';\r
+  pszCabPath[0] = '\0';\r
+\r
+  fpnsize = strlen(CabinetFile);\r
+  if (fpnsize >= MAX_PATH) {\r
+    SetLastError(ERROR_BAD_PATHNAME);\r
+    return FALSE;\r
+  }\r
+\r
+  fpnsize = GetFullPathNameA(CabinetFile, MAX_PATH, &(pszCabPath[0]), &p);\r
+  if (fpnsize > MAX_PATH) {\r
+    SetLastError(ERROR_BAD_PATHNAME);\r
+    return FALSE;\r
+  }\r
+\r
+  if (p) {\r
+    strcpy(pszCabinet, p);\r
+    *p = '\0';\r
+  } else {\r
+    strcpy(pszCabinet, CabinetFile);\r
+    pszCabPath[0] = '\0';\r
+  }\r
+\r
+  TRACE("path: %s, cabfile: %s\n", debugstr_a(pszCabPath), debugstr_a(pszCabinet));\r
+\r
+  /* remember the cabinet name */\r
+  strcpy(&(my_hsc.most_recent_cabinet_name[0]), pszCabinet);\r
+\r
+  my_hsc.magic = SC_HSC_A_MAGIC;\r
+  my_hsc.msghandler = MsgHandler;\r
+  my_hsc.context = Context;\r
+  my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,\r
+                           sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );\r
+\r
+  if (!my_hsc.hfdi) return FALSE;\r
+\r
+  ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,\r
+                     0, sc_FNNOTIFY_A, NULL, &my_hsc)     ) ? TRUE : FALSE;\r
+\r
+  sc_FDIDestroy(my_hsc.hfdi);\r
+  return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupIterateCabinetW (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved,\r
+                                 PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)\r
+{\r
+  CHAR pszCabinet[MAX_PATH], pszCabPath[MAX_PATH];\r
+  UINT len;\r
+  SC_HSC_W my_hsc;\r
+  ERF erf;\r
+  WCHAR pszCabPathW[MAX_PATH], *p;\r
+  DWORD fpnsize;\r
+  BOOL ret;\r
+\r
+  TRACE("(CabinetFile == %s, Reserved == %lu, MsgHandler == ^%p, Context == ^%p)\n",\r
+        debugstr_w(CabinetFile), Reserved, MsgHandler, Context);\r
+\r
+  if (!LoadCABINETDll())\r
+    return FALSE;\r
+\r
+  if (!CabinetFile) return FALSE;\r
+\r
+  memset(&my_hsc, 0, sizeof(SC_HSC_W));\r
+\r
+  fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p);\r
+  if (fpnsize > MAX_PATH) {\r
+    SetLastError(ERROR_BAD_PATHNAME);\r
+    return FALSE;\r
+  }\r
+\r
+  if (p) {\r
+    strcpyW(my_hsc.most_recent_cabinet_name, p);\r
+    *p = 0;\r
+    len = WideCharToMultiByte(CP_ACP, 0, pszCabPathW, -1, pszCabPath,\r
+                               MAX_PATH, 0, 0);\r
+    if (!len) return FALSE;\r
+  } else {\r
+    strcpyW(my_hsc.most_recent_cabinet_name, CabinetFile);\r
+    pszCabPath[0] = '\0';\r
+  }\r
+\r
+  len = WideCharToMultiByte(CP_ACP, 0, my_hsc.most_recent_cabinet_name, -1,\r
+                               pszCabinet, MAX_PATH, 0, 0);\r
+  if (!len) return FALSE;\r
+\r
+  TRACE("path: %s, cabfile: %s\n",\r
+       debugstr_a(pszCabPath), debugstr_a(pszCabinet));\r
+\r
+  my_hsc.magic = SC_HSC_W_MAGIC;\r
+  my_hsc.msghandler = MsgHandler;\r
+  my_hsc.context = Context;\r
+  my_hsc.hfdi = sc_FDICreate( sc_cb_alloc, sc_cb_free, sc_cb_open, sc_cb_read,\r
+                              sc_cb_write, sc_cb_close, sc_cb_lseek, cpuUNKNOWN, &erf );\r
+\r
+  if (!my_hsc.hfdi) return FALSE;\r
+\r
+  ret = ( sc_FDICopy(my_hsc.hfdi, pszCabinet, pszCabPath,\r
+                     0, sc_FNNOTIFY_W, NULL, &my_hsc)     ) ? TRUE : FALSE;\r
+\r
+  sc_FDIDestroy(my_hsc.hfdi);\r
+  return ret;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * DllMain\r
+ *\r
+ * PARAMS\r
+ *     hinstDLL    [I] handle to the DLL's instance\r
+ *     fdwReason   [I]\r
+ *     lpvReserved [I] reserved, must be NULL\r
+ *\r
+ * RETURNS\r
+ *     Success: TRUE\r
+ *     Failure: FALSE\r
+ */\r
+\r
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
+{\r
+    switch (fdwReason) {\r
+    case DLL_PROCESS_ATTACH:\r
+        DisableThreadLibraryCalls(hinstDLL);\r
+        OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);\r
+        if (!GetVersionExW(&OsVersionInfo))\r
+            return FALSE;\r
+        break;\r
+    case DLL_PROCESS_DETACH:\r
+        UnloadCABINETDll();\r
+        break;\r
+    }\r
+\r
+    return TRUE;\r
+}\r
index be6bcfd..2c40e0e 100644 (file)
-1    stub     WEP
-2    pascal -ret16 IpOpen(str ptr) IpOpen16
-3    stub     IpOpenAppend #(str word)
-4    pascal -ret16 IpClose(word) IpClose16
-5    stub     IpGetLongField #(word ptr word ptr)
-6    stub     IpGetStringField #(word ptr word ptr word ptr)
-7    stub     IpFindFirstLine #(word str str ptr)
-8    stub     IpGetLineCount #(word str ptr)
-9    stub     IpGetFieldCount #(word ptr ptr)
-10   stub     IpGetIntField #(word ptr word ptr)
-11   stub     IpFindNextLine #(word ptr)
-12   stub     IpGetFileName #(word ptr word)
-13   pascal -ret16 VcpQueueCopy(str str str str word word ptr word long) VcpQueueCopy16
-14   stub     NOAUTORUNWNDPROC
-15   stub     __DEBUGMSG
-16   stub     __ASSERTMSG
-17   pascal -ret16 VcpQueueDelete(str str word long) VcpQueueDelete16
-18   stub     TpOpenFile #(str ptr word)
-19   stub     TpCloseFile #(word)
-20   stub     TpOpenSection #(word ptr str word)
-21   stub     TpCloseSection #(word)
-22   stub     TpCommitSection #(word word str word)
-23   stub     TpGetLine #(word str str word word ptr)
-24   stub     TpGetNextLine #(word str str ptr)
-25   stub     TpInsertLine #(word str str word word word)
-26   stub     TpReplaceLine #(word str str word word word)
-27   stub     TpDeleteLine #(word word word word)
-28   stub     TpMoveLine #(word word word word word word)
-29   stub     TpGetLineContents #(word ptr word ptr word word word)
-30   stub     TpGetPrivateProfileString #(str str str ptr word str)
-31   stub     TpWritePrivateProfileString #(str str str str)
-32   stub     TpGetProfileString #(str str str ptr word)
-33   pascal -ret16 CtlSetLdd(ptr) CtlSetLdd16
-34   pascal -ret16 CtlGetLdd(ptr) CtlGetLdd16
-35   pascal -ret16 CtlFindLdd(ptr) CtlFindLdd16
-36   pascal -ret16 CtlAddLdd(ptr) CtlAddLdd16
-37   pascal -ret16 CtlDelLdd(word) CtlDelLdd16
-38   pascal -ret16 CtlGetLddPath(word ptr) CtlGetLddPath16
-39   stub     SURegCloseKey #(word)
-40   stub     SURegCreateKey #(word)
-41   stub     SURegDeleteKey #(word str)
-42   stub     SURegDeleteValue #(word str)
-43   stub     SURegEnumKey #(word long ptr long)
-44   stub     SURegEnumValue #(word long str ptr ptr ptr ptr ptr)
-45   stub     SURegFlush #()
-46   stub     SURegInit #()
-47   pascal   SURegOpenKey(word str ptr) SURegOpenKey
-48   stub     SURegQueryValue
-49   stub     SURegQueryValue16 #(word str ptr ptr)
-50   pascal   SURegQueryValueEx(long str ptr ptr ptr ptr) SURegQueryValueEx
-51   stub     SURegSetValue
-52   stub     SURegSetValue16 #(word str long ptr long)
-53   stub     SURegSetValueEx #(word str long long ptr long)
-54   stub     SURegSaveKey #(word str ptr)
-55   stub     SURegLoadKey #(word str str)
-56   stub     SURegUnLoadKey #(word str)
-60   stub     DiskInfoFromLdid #(word ptr)
-61   pascal   suErrorToIds(word word) suErrorToIds16
-62   pascal -ret16 TPWriteProfileString(str str str) TPWriteProfileString16
-63   stub     SURPLSETUP
-# does SUSTORELDIDPATH set the path of an LDID in the registry ?
-64   stub     SUSTORELDIDPATH
-65   stub     WILDCARDSTRCMPI
-101  pascal -ret16 GenInstall(word str word) GenInstall16
-102  stub     GenWinInitRename #(str str word)
-103  pascal   GenFormStrWithoutPlaceHolders(str str word) GenFormStrWithoutPlaceHolders16
-104  stub     SETUPX
-105  stub     CfgSetupMerge #(word)
-106  stub     INITDEPENDANTLDIDS
-107  stub     CFGOBJFINDKEYCMD
-108  stub     GenSURegSetValueEx
-109  stub     GENINSTALLWITHQUEUE
-110  stub     GenInstallEx #(word str word word ptr long)
-111  stub     GenCopyLogConfig2Reg #(word word str)
-112  stub     SUGetSetSetupFlags #(ptr word)
-114  stub     CFGPARSELINE # returns array
-115  stub     CFGSETAUTOPROCESS
-116  stub     CFGOBJTOSTR
-117  stub     CFGLNTOOBJ
-118  stub     MATCHCMDEXT
-119  stub     IpFindNextMatchLine #(word str ptr)
-120  stub     P_SETDEFAULTOPTION
-121  stub     CFGCLEANBOOT
-122  stub     CFGMATCHCMDEXT
-123  stub     CFGWASFILEUPDATED
-124  stub     AUTOMATCHCMDEXT
-125  stub     P_VALIDATEOC
-126  stub     GENMAPROOTREGSTR2KEY
-127  stub     P_CDROMOC
-128  stub     P_MEDIAOC
-129  stub     CFGCLEAN1STBOOT
-130  stub     suFormatMessage
-131  stub     suvFormatMessage #(word str str word ptr)
-132  stub     suFormatMessageBox
-#133  stub     suHelp # W98SE conflict !!
-135  stub     suHelp #(word word)
-#135  stub     P_WEBTVOC # W98SE conflict !!
-136  stub     P_WBEMOC
-137  stub     P_THEMESOC
-138  stub     P_IMAGINGOC
-139  stub     P_SCHEMESOC
-140  stub     suVerConflict #(word ptr word ptr)
-141  stub     suVerConflictInit #(word)
-142  stub     suVerConflictTerm #(ptr)
-# Emergency Boot Disk
-143  stub     suCreateEBD #(word ptr long)
-144  stub     suCopyToEBD
-145  stub     sxIsMSDOS7Running #()
-150  stub     DS_INIT
-151  stub     DS_DESTROY
-152  stub     DS_SSYNCDRIVES
-153  stub     DS_GETDRIVEDATA
-154  stub     DS_ADDSECTION
-155  stub     DS_ENABLESECTION
-156  stub     DS_DISABLESECTION
-157  stub     DS_SETSWAPSIZE
-158  stub     DS_SETREQUIREDPAD
-159  stub     DS_SETAVAILABLEPAD
-160  stub     SXUPDATEDS
-170  stub     SUSETMEM
-171  stub     WriteDMFBootData #(word ptr word)
-200  pascal   VcpOpen(segptr ptr) VcpOpen16
-201  pascal   VcpClose(word str) VcpClose16
-202  pascal -ret16 vcpDefCallbackProc(ptr word word long long) vcpDefCallbackProc16
-203  stub     vcpEnumFiles #(ptr long)
-204  pascal -ret16 VcpQueueRename(str str str str word word long) VcpQueueRename16
-205  pascal -ret16 vsmGetStringName(word ptr word) vsmGetStringName16
-206  pascal -ret16 vsmStringDelete(word) vsmStringDelete16
-207  pascal -ret16 vsmStringAdd(str) vsmStringAdd16
-208  pascal   vsmGetStringRawName(word) vsmGetStringRawName16
-209  stub     IpSaveRestorePosition #(word word)
-210  pascal -ret16 IpGetProfileString(word str str ptr word) IpGetProfileString16
-211  stub     IpOpenEx #(str ptr word)
-212  stub     IpOpenAppendEx #(str word word)
-213  pascal -ret16 vcpUICallbackProc(ptr word word long long) vcpUICallbackProc16
-214  stub     VcpAddMRUPath #(str)
-300  pascal -ret16 DiBuildCompatDrvList (ptr) DiBuildCompatDrvList16
-301  pascal -ret16 DiBuildClassDrvList (ptr) DiBuildClassDrvList16
-302  stub     DiDestroyDriverNodeList #(ptr)
-303  pascal -ret16 DiCreateDeviceInfo (ptr str long long str str word) DiCreateDeviceInfo16
-304  pascal -ret16 DiGetClassDevs(ptr str word word) DiGetClassDevs16
-305  pascal -ret16 DiDestroyDeviceInfoList (ptr) DiDestroyDeviceInfoList16
-306  stub     DiRemoveDevice #(ptr)
-308  pascal -ret16 DiCallClassInstaller (word ptr) DiCallClassInstaller16
-309  stub     DiCreateDriverNode #(ptr word word word str str str str str str long)
-310  stub     DiDrawMiniIcon
-311  stub     DiGetClassBitmapIndex #(str ptr)
-312  stub     DiSelectDevice #(ptr)
-313  stub     DiInstallDevice #(ptr)
-314  stub     DiLoadClassIcon #(str ptr ptr)
-315  stub     DiAskForOEMDisk #(ptr)
-316  stub     Display_SetMode #(ptr word word word)
-317  stub     Display_ClassInstaller #(word ptr)
-318  pascal -ret16 DiCreateDevRegKey (ptr ptr word str word) DiCreateDevRegKey16
-319  pascal -ret16 DiOpenDevRegKey (ptr ptr word) DiOpenDevRegKey16
-320  stub     DiInstallDrvSection #(str str str str long)
-321  stub     DiInstallClass #(str long)
-322  stub     DiOpenClassRegKey #(ptr str)
-323  stub     Display_SetFontSize #(str)
-324  stub     Display_OpenFontSizeKey #(ptr)
-325  stub     DiBuildClassDrvListFromOldInf #(ptr str ptr long)
-326  stub     DiIsThereNeedToCopy #(word long)
-333  stub     DiChangeState #(ptr long long long)
-334  stub     WALKSUBTREE
-340  stub     GetFctn #(word str str ptr ptr)
-341  stub     DiBuildClassInfoList #(ptr)
-342  stub     DiDestroyClassInfoList #(ptr)
-343  stub     DiGetDeviceClassInfo #(ptr ptr)
-344  pascal -ret16 DiDeleteDevRegKey (ptr word) DiDeleteDevRegKey16
-350  stub     DiSelectOEMDrv #(word ptr)
-351  stub     DiGetINFClass #(str word str long)
-353  stub     DIPICKBESTDRIVER
-355  stub     COPYINFFILE
-360  stub     GenInfLCToDevNode #(word str  word word long)
-361  stub     GETDOSMESSAGE
-362  stub     Mouse_ClassInstaller #(word ptr)
-363  stub     sxCompareDosAppVer #(str str)
-364  stub     MONITOR_CLASSINSTALLER
-365  stub     FCEGETRESDESOFFSET
-366  stub     FCEGETALLOCVALUE
-367  stub     FCEADDRESDES
-368  stub     FCEDELETERESDES
-369  stub     FCEINIT
-370  stub     FCEGETRESDES
-371  stub     FCEGETFIRSTVALUE
-372  stub     FCEGETOTHERVALUE
-373  stub     FCEGETVALIDATEVALUE
-374  stub     FCEWRITETHISFORCEDCONFIGNOW
-375  stub     SUCreatePropertySheetPage #(ptr)
-376  stub     SUDestroyPropertySheetPage #(word)
-377  stub     SUPropertySheet #(ptr)
-380  stub     DiReadRegLogConf #(ptr str ptr ptr)
-381  stub     DiReadRegConf #(ptr ptr ptr long)
-390  stub     DiBuildPotentialDuplicatesList #(ptr ptr long ptr ptr)
-395  stub     InitSubstrData #(ptr str)
-396  stub     GetFirstSubstr #(ptr)
-397  stub     GetNextSubstr #(ptr)
-398  stub     INITSUBSTRDATAEX
-400  stub     bIsFileInVMM32 #(str)
-401  stub     DiInstallDriverFiles #(ptr)
-405  stub     DiBuildClassInfoListEx #(ptr long)
-406  stub     DiGetClassDevsEx #(ptr str str word word)
-407  stub     DiCopyRegSubKeyValue #(word str str str)
-408  stub     IPGETDRIVERDATE
-409  stub     IPGETDRIVERVERSION
-410  stub     IpGetVersionString #(str str ptr word str)
-411  pascal   VcpExplain(ptr long) VcpExplain16
-412  stub     DiBuildDriverIndex #(word)
-413  stub     DiAddSingleInfToDrvIdx #(str word word)
-414  stub     FCEGETFLAGS
-450  stub     UiMakeDlgNonBold #(word)
-451  stub     UiDeleteNonBoldFont #(word)
-500  stub     SUEBDPAGE
-501  stub     SUOCPAGE
-502  stub     SXLISTSUBPROC
-503  stub     SXFILLLB
-504  stub     SXOCPAGEDLG
-506  stub     SXOCBATCHSETTINGS
-507  stub     SXOCFIXNEEDS
-508  pascal -ret16 CtlSetLddPath(word str) CtlSetLddPath16
-509  stub     SXCALLOCPROC
-510  stub     BUILDINFOCS
-511  stub     BUILDREGOCS
-512  stub     DELETEOCS
-520  stub     DiBuildClassDrvInfoList #(ptr)
-521  stub     DiBuildCompatDrvInfoList #(ptr)
-522  stub     DiDestroyDrvInfoList #(ptr)
-523  stub     DiConvertDriverInfoToDriverNode #(ptr ptr)
-524  stub     DISELECTBESTCOMPATDRV
-525  stub     FirstBootMoveToDOSSTART #(str word)
-526  stub     DOSOptEnableCurCfg #(str)
-527  pascal -ret16 InstallHinfSection(word word str word) InstallHinfSection16
-528  stub     SXMAKEUNCPATH
-529  stub     SXISSBSSERVERFILE
-530  stub     SXFINDBATCHFILES
-531  stub     ISPANEUROPEAN
-532  stub     UPGRADENIGGLINGS
-533  stub     DISPLAY_ISSECONDDISPLAY
-534  stub     ISWINDOWSFILE
-540  stub     VERIFYSELECTEDDRIVER
-575  stub     SXCALLMIGRATIONDLLS
-576  stub     SXCALLMIGRATIONDLLS_RUNDLL
-600  stub     PidConstruct #(str str str word)
-601  stub     PidValidate #(str str)
-602  stub     GETJAPANESEKEYBOARDTYPE
-610  stub     CRC32COMPUTE
-621  stub     SXSAVEINFO
-622  stub     SXADDPAGEEX
-623  stub     OPKREMOVEINSTALLEDNETDEVICE
-640  stub     DOFIRSTRUNSCREENS
-700  stub     SXSHOWREBOOTDLG
-701  stub     SXSHOWREBOOTDLG_RUNDLL
-750  stub     UIPOSITIONDIALOG
-775  stub     ASPICLEAN
-800  stub     EXTRACTCABFILE
-825  stub     PIDGEN3
-826  stub     GETSETUPINFO
-827  stub     SETSETUPINFO
-828  stub     GETKEYBOARDOPTIONS
-829  stub     GETLOCALEOPTIONS
-830  stub     SETINTLOPTIONS
-831  stub     GETPRODUCTTYPE
-832  stub     ISOPKMODE
-833  stub     AUDITONETIMEINSTALL
-834  stub     DISKDUP
-835  stub     OPKPREINSTALL
-836  stub     ISAUDITMODE
-837  stub     ISAUDITAUTO
-838  stub     GETVALIDEULA
+1    stub     WEP\r
+2    pascal -ret16 IpOpen(str ptr) IpOpen16\r
+3    stub     IpOpenAppend #(str word)\r
+4    pascal -ret16 IpClose(word) IpClose16\r
+5    stub     IpGetLongField #(word ptr word ptr)\r
+6    stub     IpGetStringField #(word ptr word ptr word ptr)\r
+7    stub     IpFindFirstLine #(word str str ptr)\r
+8    stub     IpGetLineCount #(word str ptr)\r
+9    stub     IpGetFieldCount #(word ptr ptr)\r
+10   stub     IpGetIntField #(word ptr word ptr)\r
+11   stub     IpFindNextLine #(word ptr)\r
+12   stub     IpGetFileName #(word ptr word)\r
+13   pascal -ret16 VcpQueueCopy(str str str str word word ptr word long) VcpQueueCopy16\r
+14   stub     NOAUTORUNWNDPROC\r
+15   stub     __DEBUGMSG\r
+16   stub     __ASSERTMSG\r
+17   pascal -ret16 VcpQueueDelete(str str word long) VcpQueueDelete16\r
+18   stub     TpOpenFile #(str ptr word)\r
+19   stub     TpCloseFile #(word)\r
+20   stub     TpOpenSection #(word ptr str word)\r
+21   stub     TpCloseSection #(word)\r
+22   stub     TpCommitSection #(word word str word)\r
+23   stub     TpGetLine #(word str str word word ptr)\r
+24   stub     TpGetNextLine #(word str str ptr)\r
+25   stub     TpInsertLine #(word str str word word word)\r
+26   stub     TpReplaceLine #(word str str word word word)\r
+27   stub     TpDeleteLine #(word word word word)\r
+28   stub     TpMoveLine #(word word word word word word)\r
+29   stub     TpGetLineContents #(word ptr word ptr word word word)\r
+30   stub     TpGetPrivateProfileString #(str str str ptr word str)\r
+31   stub     TpWritePrivateProfileString #(str str str str)\r
+32   stub     TpGetProfileString #(str str str ptr word)\r
+33   pascal -ret16 CtlSetLdd(ptr) CtlSetLdd16\r
+34   pascal -ret16 CtlGetLdd(ptr) CtlGetLdd16\r
+35   pascal -ret16 CtlFindLdd(ptr) CtlFindLdd16\r
+36   pascal -ret16 CtlAddLdd(ptr) CtlAddLdd16\r
+37   pascal -ret16 CtlDelLdd(word) CtlDelLdd16\r
+38   pascal -ret16 CtlGetLddPath(word ptr) CtlGetLddPath16\r
+39   stub     SURegCloseKey #(word)\r
+40   stub     SURegCreateKey #(word)\r
+41   stub     SURegDeleteKey #(word str)\r
+42   stub     SURegDeleteValue #(word str)\r
+43   stub     SURegEnumKey #(word long ptr long)\r
+44   stub     SURegEnumValue #(word long str ptr ptr ptr ptr ptr)\r
+45   stub     SURegFlush #()\r
+46   stub     SURegInit #()\r
+47   pascal   SURegOpenKey(word str ptr) SURegOpenKey\r
+48   stub     SURegQueryValue\r
+49   stub     SURegQueryValue16 #(word str ptr ptr)\r
+50   pascal   SURegQueryValueEx(long str ptr ptr ptr ptr) SURegQueryValueEx\r
+51   stub     SURegSetValue\r
+52   stub     SURegSetValue16 #(word str long ptr long)\r
+53   stub     SURegSetValueEx #(word str long long ptr long)\r
+54   stub     SURegSaveKey #(word str ptr)\r
+55   stub     SURegLoadKey #(word str str)\r
+56   stub     SURegUnLoadKey #(word str)\r
+60   stub     DiskInfoFromLdid #(word ptr)\r
+61   pascal   suErrorToIds(word word) suErrorToIds16\r
+62   pascal -ret16 TPWriteProfileString(str str str) TPWriteProfileString16\r
+63   stub     SURPLSETUP\r
+# does SUSTORELDIDPATH set the path of an LDID in the registry ?\r
+64   stub     SUSTORELDIDPATH\r
+65   stub     WILDCARDSTRCMPI\r
+101  pascal -ret16 GenInstall(word str word) GenInstall16\r
+102  stub     GenWinInitRename #(str str word)\r
+103  pascal   GenFormStrWithoutPlaceHolders(str str word) GenFormStrWithoutPlaceHolders16\r
+104  stub     SETUPX\r
+105  stub     CfgSetupMerge #(word)\r
+106  stub     INITDEPENDANTLDIDS\r
+107  stub     CFGOBJFINDKEYCMD\r
+108  stub     GenSURegSetValueEx\r
+109  stub     GENINSTALLWITHQUEUE\r
+110  stub     GenInstallEx #(word str word word ptr long)\r
+111  stub     GenCopyLogConfig2Reg #(word word str)\r
+112  stub     SUGetSetSetupFlags #(ptr word)\r
+114  stub     CFGPARSELINE # returns array\r
+115  stub     CFGSETAUTOPROCESS\r
+116  stub     CFGOBJTOSTR\r
+117  stub     CFGLNTOOBJ\r
+118  stub     MATCHCMDEXT\r
+119  stub     IpFindNextMatchLine #(word str ptr)\r
+120  stub     P_SETDEFAULTOPTION\r
+121  stub     CFGCLEANBOOT\r
+122  stub     CFGMATCHCMDEXT\r
+123  stub     CFGWASFILEUPDATED\r
+124  stub     AUTOMATCHCMDEXT\r
+125  stub     P_VALIDATEOC\r
+126  stub     GENMAPROOTREGSTR2KEY\r
+127  stub     P_CDROMOC\r
+128  stub     P_MEDIAOC\r
+129  stub     CFGCLEAN1STBOOT\r
+130  stub     suFormatMessage\r
+131  stub     suvFormatMessage #(word str str word ptr)\r
+132  stub     suFormatMessageBox\r
+#133  stub     suHelp # W98SE conflict !!\r
+135  stub     suHelp #(word word)\r
+#135  stub     P_WEBTVOC # W98SE conflict !!\r
+136  stub     P_WBEMOC\r
+137  stub     P_THEMESOC\r
+138  stub     P_IMAGINGOC\r
+139  stub     P_SCHEMESOC\r
+140  stub     suVerConflict #(word ptr word ptr)\r
+141  stub     suVerConflictInit #(word)\r
+142  stub     suVerConflictTerm #(ptr)\r
+# Emergency Boot Disk\r
+143  stub     suCreateEBD #(word ptr long)\r
+144  stub     suCopyToEBD\r
+145  stub     sxIsMSDOS7Running #()\r
+150  stub     DS_INIT\r
+151  stub     DS_DESTROY\r
+152  stub     DS_SSYNCDRIVES\r
+153  stub     DS_GETDRIVEDATA\r
+154  stub     DS_ADDSECTION\r
+155  stub     DS_ENABLESECTION\r
+156  stub     DS_DISABLESECTION\r
+157  stub     DS_SETSWAPSIZE\r
+158  stub     DS_SETREQUIREDPAD\r
+159  stub     DS_SETAVAILABLEPAD\r
+160  stub     SXUPDATEDS\r
+170  stub     SUSETMEM\r
+171  stub     WriteDMFBootData #(word ptr word)\r
+200  pascal   VcpOpen(segptr ptr) VcpOpen16\r
+201  pascal   VcpClose(word str) VcpClose16\r
+202  pascal -ret16 vcpDefCallbackProc(ptr word word long long) vcpDefCallbackProc16\r
+203  stub     vcpEnumFiles #(ptr long)\r
+204  pascal -ret16 VcpQueueRename(str str str str word word long) VcpQueueRename16\r
+205  pascal -ret16 vsmGetStringName(word ptr word) vsmGetStringName16\r
+206  pascal -ret16 vsmStringDelete(word) vsmStringDelete16\r
+207  pascal -ret16 vsmStringAdd(str) vsmStringAdd16\r
+208  pascal   vsmGetStringRawName(word) vsmGetStringRawName16\r
+209  stub     IpSaveRestorePosition #(word word)\r
+210  pascal -ret16 IpGetProfileString(word str str ptr word) IpGetProfileString16\r
+211  stub     IpOpenEx #(str ptr word)\r
+212  stub     IpOpenAppendEx #(str word word)\r
+213  pascal -ret16 vcpUICallbackProc(ptr word word long long) vcpUICallbackProc16\r
+214  stub     VcpAddMRUPath #(str)\r
+300  pascal -ret16 DiBuildCompatDrvList (ptr) DiBuildCompatDrvList16\r
+301  pascal -ret16 DiBuildClassDrvList (ptr) DiBuildClassDrvList16\r
+302  stub     DiDestroyDriverNodeList #(ptr)\r
+303  pascal -ret16 DiCreateDeviceInfo (ptr str long long str str word) DiCreateDeviceInfo16\r
+304  pascal -ret16 DiGetClassDevs(ptr str word word) DiGetClassDevs16\r
+305  pascal -ret16 DiDestroyDeviceInfoList (ptr) DiDestroyDeviceInfoList16\r
+306  stub     DiRemoveDevice #(ptr)\r
+308  pascal -ret16 DiCallClassInstaller (word ptr) DiCallClassInstaller16\r
+309  stub     DiCreateDriverNode #(ptr word word word str str str str str str long)\r
+310  stub     DiDrawMiniIcon\r
+311  stub     DiGetClassBitmapIndex #(str ptr)\r
+312  stub     DiSelectDevice #(ptr)\r
+313  stub     DiInstallDevice #(ptr)\r
+314  stub     DiLoadClassIcon #(str ptr ptr)\r
+315  stub     DiAskForOEMDisk #(ptr)\r
+316  stub     Display_SetMode #(ptr word word word)\r
+317  stub     Display_ClassInstaller #(word ptr)\r
+318  pascal -ret16 DiCreateDevRegKey (ptr ptr word str word) DiCreateDevRegKey16\r
+319  pascal -ret16 DiOpenDevRegKey (ptr ptr word) DiOpenDevRegKey16\r
+320  stub     DiInstallDrvSection #(str str str str long)\r
+321  stub     DiInstallClass #(str long)\r
+322  stub     DiOpenClassRegKey #(ptr str)\r
+323  stub     Display_SetFontSize #(str)\r
+324  stub     Display_OpenFontSizeKey #(ptr)\r
+325  stub     DiBuildClassDrvListFromOldInf #(ptr str ptr long)\r
+326  stub     DiIsThereNeedToCopy #(word long)\r
+333  stub     DiChangeState #(ptr long long long)\r
+334  stub     WALKSUBTREE\r
+340  stub     GetFctn #(word str str ptr ptr)\r
+341  stub     DiBuildClassInfoList #(ptr)\r
+342  stub     DiDestroyClassInfoList #(ptr)\r
+343  stub     DiGetDeviceClassInfo #(ptr ptr)\r
+344  pascal -ret16 DiDeleteDevRegKey (ptr word) DiDeleteDevRegKey16\r
+350  stub     DiSelectOEMDrv #(word ptr)\r
+351  stub     DiGetINFClass #(str word str long)\r
+353  stub     DIPICKBESTDRIVER\r
+355  stub     COPYINFFILE\r
+360  stub     GenInfLCToDevNode #(word str  word word long)\r
+361  stub     GETDOSMESSAGE\r
+362  stub     Mouse_ClassInstaller #(word ptr)\r
+363  stub     sxCompareDosAppVer #(str str)\r
+364  stub     MONITOR_CLASSINSTALLER\r
+365  stub     FCEGETRESDESOFFSET\r
+366  stub     FCEGETALLOCVALUE\r
+367  stub     FCEADDRESDES\r
+368  stub     FCEDELETERESDES\r
+369  stub     FCEINIT\r
+370  stub     FCEGETRESDES\r
+371  stub     FCEGETFIRSTVALUE\r
+372  stub     FCEGETOTHERVALUE\r
+373  stub     FCEGETVALIDATEVALUE\r
+374  stub     FCEWRITETHISFORCEDCONFIGNOW\r
+375  stub     SUCreatePropertySheetPage #(ptr)\r
+376  stub     SUDestroyPropertySheetPage #(word)\r
+377  stub     SUPropertySheet #(ptr)\r
+380  stub     DiReadRegLogConf #(ptr str ptr ptr)\r
+381  stub     DiReadRegConf #(ptr ptr ptr long)\r
+390  stub     DiBuildPotentialDuplicatesList #(ptr ptr long ptr ptr)\r
+395  stub     InitSubstrData #(ptr str)\r
+396  stub     GetFirstSubstr #(ptr)\r
+397  stub     GetNextSubstr #(ptr)\r
+398  stub     INITSUBSTRDATAEX\r
+400  stub     bIsFileInVMM32 #(str)\r
+401  stub     DiInstallDriverFiles #(ptr)\r
+405  stub     DiBuildClassInfoListEx #(ptr long)\r
+406  stub     DiGetClassDevsEx #(ptr str str word word)\r
+407  stub     DiCopyRegSubKeyValue #(word str str str)\r
+408  stub     IPGETDRIVERDATE\r
+409  stub     IPGETDRIVERVERSION\r
+410  stub     IpGetVersionString #(str str ptr word str)\r
+411  pascal   VcpExplain(ptr long) VcpExplain16\r
+412  stub     DiBuildDriverIndex #(word)\r
+413  stub     DiAddSingleInfToDrvIdx #(str word word)\r
+414  stub     FCEGETFLAGS\r
+450  stub     UiMakeDlgNonBold #(word)\r
+451  stub     UiDeleteNonBoldFont #(word)\r
+500  stub     SUEBDPAGE\r
+501  stub     SUOCPAGE\r
+502  stub     SXLISTSUBPROC\r
+503  stub     SXFILLLB\r
+504  stub     SXOCPAGEDLG\r
+506  stub     SXOCBATCHSETTINGS\r
+507  stub     SXOCFIXNEEDS\r
+508  pascal -ret16 CtlSetLddPath(word str) CtlSetLddPath16\r
+509  stub     SXCALLOCPROC\r
+510  stub     BUILDINFOCS\r
+511  stub     BUILDREGOCS\r
+512  stub     DELETEOCS\r
+520  stub     DiBuildClassDrvInfoList #(ptr)\r
+521  stub     DiBuildCompatDrvInfoList #(ptr)\r
+522  stub     DiDestroyDrvInfoList #(ptr)\r
+523  stub     DiConvertDriverInfoToDriverNode #(ptr ptr)\r
+524  stub     DISELECTBESTCOMPATDRV\r
+525  stub     FirstBootMoveToDOSSTART #(str word)\r
+526  stub     DOSOptEnableCurCfg #(str)\r
+527  pascal -ret16 InstallHinfSection(word word str word) InstallHinfSection16\r
+528  stub     SXMAKEUNCPATH\r
+529  stub     SXISSBSSERVERFILE\r
+530  stub     SXFINDBATCHFILES\r
+531  stub     ISPANEUROPEAN\r
+532  stub     UPGRADENIGGLINGS\r
+533  stub     DISPLAY_ISSECONDDISPLAY\r
+534  stub     ISWINDOWSFILE\r
+540  stub     VERIFYSELECTEDDRIVER\r
+575  stub     SXCALLMIGRATIONDLLS\r
+576  stub     SXCALLMIGRATIONDLLS_RUNDLL\r
+600  stub     PidConstruct #(str str str word)\r
+601  stub     PidValidate #(str str)\r
+602  stub     GETJAPANESEKEYBOARDTYPE\r
+610  stub     CRC32COMPUTE\r
+621  stub     SXSAVEINFO\r
+622  stub     SXADDPAGEEX\r
+623  stub     OPKREMOVEINSTALLEDNETDEVICE\r
+640  stub     DOFIRSTRUNSCREENS\r
+700  stub     SXSHOWREBOOTDLG\r
+701  stub     SXSHOWREBOOTDLG_RUNDLL\r
+750  stub     UIPOSITIONDIALOG\r
+775  stub     ASPICLEAN\r
+800  stub     EXTRACTCABFILE\r
+825  stub     PIDGEN3\r
+826  stub     GETSETUPINFO\r
+827  stub     SETSETUPINFO\r
+828  stub     GETKEYBOARDOPTIONS\r
+829  stub     GETLOCALEOPTIONS\r
+830  stub     SETINTLOPTIONS\r
+831  stub     GETPRODUCTTYPE\r
+832  stub     ISOPKMODE\r
+833  stub     AUDITONETIMEINSTALL\r
+834  stub     DISKDUP\r
+835  stub     OPKPREINSTALL\r
+836  stub     ISAUDITMODE\r
+837  stub     ISAUDITAUTO\r
+838  stub     GETVALIDEULA\r
index 4b5468f..6fd50df 100644 (file)
-/*
- * Copyright 2000 Andreas Mohr 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __SETUPX16_H
-#define __SETUPX16_H
-
-#include "wine/windef16.h"
-
-typedef UINT16 DI_FUNCTION16;
-typedef UINT16 HINF16;
-typedef UINT16 LOGDISKID16;
-typedef UINT16 VHSTR;
-
-#define LINE_LEN       256
-
-/* error codes stuff */
-
-typedef UINT16 RETERR16;
-#define OK             0
-#define IP_ERROR       (UINT16)100
-#define TP_ERROR       (UINT16)200
-#define VCP_ERROR      (UINT16)300
-#define GEN_ERROR      (UINT16)400
-#define DI_ERROR       (UINT16)500
-
-enum {
-       ERR_IP_INVALID_FILENAME = IP_ERROR+1,
-       ERR_IP_ALLOC_ERR,
-       ERR_IP_INVALID_SECT_NAME,
-       ERR_IP_OUT_OF_HANDLES,
-       ERR_IP_INF_NOT_FOUND,
-       ERR_IP_INVALID_INFFILE,
-       ERR_IP_INVALID_HINF,
-       ERR_IP_INVALID_FIELD,
-       ERR_IP_SECT_NOT_FOUND,
-       ERR_IP_END_OF_SECTION,
-       ERR_IP_PROFILE_NOT_FOUND,
-       ERR_IP_LINE_NOT_FOUND,
-       ERR_IP_FILEREAD,
-       ERR_IP_TOOMANYINFFILES,
-       ERR_IP_INVALID_SAVERESTORE,
-       ERR_IP_INVALID_INFTYPE
-};
-
-/****** virtual copy operations ******/
-
-typedef DWORD LPEXPANDVTBL;
-
-typedef struct {
-       DWORD           dwSoFar;
-       DWORD           dwTotal;
-} VCPPROGRESS, *LPVCPPROGRESS;
-
-typedef struct {
-       WORD            cbSize;
-       LOGDISKID16     ldid;
-       VHSTR           vhstrRoot;
-       VHSTR           vhstrVolumeLabel;
-       VHSTR           vhstrDiskName;
-       WORD            wVolumeTime;
-       WORD            wVolumeDate;
-       DWORD           dwSerialNumber;
-       WORD            fl;
-       LPARAM          lparamRef;
-
-       VCPPROGRESS     prgFileRead;
-       VCPPROGRESS     prgByteRead;
-
-       VCPPROGRESS     prgFileWrite;
-       VCPPROGRESS     prgByteWrite;
-} VCPDISKINFO, *LPVCPDISKINFO;
-
-typedef struct {
-       LOGDISKID16     ldid;
-       VHSTR           vhstrDir;
-       VHSTR           vhstrFileName;
-} VCPFILESPEC, *LPVCPFILESPEC;
-
-typedef struct {
-       UINT16          uiMDate;
-       UINT16          uiMTime;
-       UINT16          uiADate;
-       UINT16          uiATime;
-       UINT16          uiAttr;
-       DWORD           llenIn;
-       DWORD           llenOut;
-} VCPFATTR, *LPVCPFATTR;
-
-typedef struct {
-       UINT16          uDate;
-       UINT16          uTime;
-       DWORD           dwSize;
-} VCPFILESTAT, *LPVCPFILESTAT;
-
-typedef struct
-{
-       HFILE16         hFileSrc;
-       HFILE16         hFileDst;
-       VCPFATTR        fAttr;
-       WORD            dosError;
-       VHSTR           vhstrFileName;
-       WPARAM          vcpm;
-} VIRTNODEEX, *LPVIRTNODEEX;
-
-typedef struct {
-       WORD            cbSize;
-       VCPFILESPEC     vfsSrc;
-       VCPFILESPEC     vfsDst;
-       WORD            fl;
-       LPARAM          lParam;
-       LPEXPANDVTBL    lpExpandVtbl;
-       LPVIRTNODEEX    lpvnex;
-       VHSTR           vhstrDstFinalName;
-       VCPFILESTAT     vFileStat;
-} VIRTNODE, *LPVIRTNODE;
-
-typedef struct {
-       WORD            cbSize;
-       VCPPROGRESS     prgDiskRead;
-       VCPPROGRESS     prgFileRead;
-       VCPPROGRESS     prgByteRead;
-
-       VCPPROGRESS     prgDiskWrite;
-       VCPPROGRESS     prgFileWrite;
-       VCPPROGRESS     prgByteWrite;
-
-       LPVCPDISKINFO   lpvdiIn;
-       LPVCPDISKINFO   lpvdiOut;
-       LPVIRTNODE      lpvn;
-} VCPSTATUS, *LPVCPSTATUS;
-
-#define CNFL_BACKUP            0x0001
-#define CNFL_DELETEONFAILURE   0x0002
-#define CNFL_RENAMEONSUCCESS   0x0004
-#define CNFL_CONTINUATION      0x0008
-#define CNFL_SKIPPED           0x0010
-#define CNFL_IGNOREERRORS      0x0020
-#define CNFL_RETRYFILE         0x0040
-#define CNFL_COPIED            0x0080
-#define VNFL_UNIQUE            0x0000
-#define VNFL_MULTIPLEOK                0x0100
-#define VNFL_DESTROYOLD                0x0200
-#define VNFL_COPY              0x0000
-#define VNFL_DELETE            0x0800
-#define VNFL_RENAME            0x1000
-#define VNFL_NODE_TYPE         (VNFL_RENAME|VNFL_DELETE|VNFL_COPY)
-#define VNFL_CREATED           0x2000
-#define VNFL_REJECTED          0x4000
-#define VNFL_DEVICEINSTALLER   0x8000
-
-enum {
-       ERR_VCP_IOFAIL = VCP_ERROR+1,
-       ERR_VCP_STRINGTOOLONG,
-       ERR_VCP_NOMEM,
-       ERR_VCP_QUEUEFULL,
-       ERR_VCP_NOVHSTR,
-       ERR_VCP_OVERFLOW,
-       ERR_VCP_BADARG,
-       ERR_VCP_UNINIT,
-       ERR_VCP_NOTFOUND,
-       ERR_VCP_BUSY,
-       ERR_VCP_INTERRUPTED,
-       ERR_VCP_BADDEST,
-       ERR_VCP_SKIPPED,
-       ERR_VCP_IO,
-       ERR_VCP_LOCKED,
-       ERR_VCP_WRONGDISK,
-       ERR_VCP_CHANGEMODE,
-       ERR_VCP_LDDINVALID,
-       ERR_VCP_LDDFIND,
-       ERR_VCP_LDDUNINIT,
-       ERR_VCP_LDDPATH_INVALID,
-       ERR_VCP_NOEXPANSION,
-       ERR_VCP_NOTOPEN,
-       ERR_VCP_NO_DIGITAL_SIGNATURE_CATALOG,
-       ERR_VCP_NO_DIGITAL_SIGNATURE_FILE
-};
-
-#define VCPN_OK                0
-#define VCPN_PROCEED   0
-#define VCPN_ABORT     -1
-#define VCPN_RETRY     -2
-#define VCPN_IGNORE    -3
-#define VCPN_SKIP      -4
-#define VCPN_FORCE     -5
-#define VCPN_DEFER     -6
-#define VCPN_FAIL      -7
-#define VCPN_RETRYFILE -8
-
-#define VCPFL_ABANDON          0x00
-#define VCPFL_BACKUP           0x01
-#define VCPFL_COPY             0x02
-#define VCPFL_BACKUPANDCOPY    (VCPFL_BACKUP|VCPFL_COPY)
-#define VCPFL_INSPECIFIEDORDER 0x04
-#define VCPFL_DELETE           0x08
-#define VCPFL_RENAME           0x10
-#define VCPFL_ALL              (VCPFL_COPY|VCPFL_DELETE|VCPFL_RENAME)
-
-#define CFNL_BACKUP            0x0001
-#define CFNL_DELETEONFAILURE   0x0002
-#define CFNL_RENAMEONSUCCESS   0x0004
-#define CFNL_CONTINUATION      0x0008
-#define CFNL_SKIPPED           0x0010
-#define CFNL_IGNOREERRORS      0x0020
-#define CFNL_RETRYFILE         0x0040
-#define CFNL_COPIED            0x0080
-#define VFNL_MULTIPLEOK                0x0100
-#define VFNL_DESTROYOLD                0x0200
-#define VFNL_NOW               0x0400
-#define VFNL_COPY              0x0000
-#define VFNL_DELETE            0x0800
-#define VFNL_RENAME            0x1000
-#define VFNL_CREATED           0x2000
-#define VFNL_REJECTED          0x4000
-#define VCPM_DISKCLASS         0x01
-#define VCPM_DISKFIRST         0x0100
-#define VCPM_DISKLAST          0x01ff
-
-enum {
-       VCPM_DISKCREATEINFO = VCPM_DISKFIRST,
-       VCPM_DISKGETINFO,
-       VCPM_DISKDESTROYINFO,
-       VCPM_DISKPREPINFO,
-       VCPM_DISKENSURE,
-       VCPM_DISKPROMPT,
-       VCPM_DISKFORMATBEGIN,
-       VCPM_DISKFORMATTING,
-       VCPM_DISKFORMATEND
-};
-
-#define VCPM_FILEINCLASS       0x02
-#define VCPM_FILEOUTCLASS      0x03
-#define VCPM_FILEFIRSTIN       0x0200
-#define VCPM_FILEFIRSTOUT      0x0300
-#define VCPM_FILELAST          0x03ff
-
-enum {
-       VCPM_FILEOPENIN = VCPM_FILEFIRSTIN,
-       VCPM_FILEGETFATTR,
-       VCPM_FILECLOSEIN,
-       VCPM_FILECOPY,
-       VCPM_FILENEEDED,
-
-       VCPM_FILEOPENOUT = VCPM_FILEFIRSTOUT,
-       VCPM_FILESETFATTR,
-       VCPM_FILECLOSEOUT,
-       VCPM_FILEFINALIZE,
-       VCPM_FILEDELETE,
-       VCPM_FILERENAME
-};
-
-#define VCPM_NODECLASS         0x04
-#define VCPM_NODEFIRST         0x0400
-#define VCPM_NODELAST          0x04ff
-
-enum {
-       VCPM_NODECREATE = VCPM_NODEFIRST,
-       VCPM_NODEACCEPT,
-       VCPM_NODEREJECT,
-       VCPM_NODEDESTROY,
-       VCPM_NODECHANGEDESTDIR,
-       VCPM_NODECOMPARE
-};
-
-#define VCPM_TALLYCLASS                0x05
-#define VCPM_TALLYFIRST                0x0500
-#define VCPM_TALLYLAST         0x05ff
-
-enum {
-       VCPM_TALLYSTART = VCPM_TALLYFIRST,
-       VCPM_TALLYEND,
-       VCPM_TALLYFILE,
-       VCPM_TALLYDISK
-};
-
-#define VCPM_VERCLASS          0x06
-#define VCPM_VERFIRST          0x0600
-#define VCPM_VERLAST           0x06ff
-
-enum {
-       VCPM_VERCHECK = VCPM_VERFIRST,
-       VCPM_VERCHECKDONE,
-       VCPM_VERRESOLVECONFLICT
-};
-
-#define VCPM_VSTATCLASS                0x07
-#define VCPM_VSTATFIRST                0x0700
-#define VCPM_VSTATLAST         0x07ff
-
-enum {
-       VCPM_VSTATSTART = VCPM_VSTATFIRST,
-       VCPM_VSTATEND,
-       VCPM_VSTATREAD,
-       VCPM_VSTATWRITE,
-       VCPM_VSTATNEWDISK,
-       VCPM_VSTATCLOSESTART,
-       VCPM_VSTATCLOSEEND,
-       VCPM_VSTATBACKUPSTART,
-       VCPM_VSTATBACKUPEND,
-       VCPM_VSTATRENAMESTART,
-       VCPM_VSTATRENAMEEND,
-       VCPM_VSTATCOPYSTART,
-       VCPM_VSTATCOPYEND,
-       VCPM_VSTATDELETESTART,
-       VCPM_VSTATDELETEEND,
-       VCPM_VSTATPATHCHECKSTART,
-       VCPM_VSTATPATHCHECKEND,
-       VCPM_VSTATCERTIFYSTART,
-       VCPM_VSTATCERTIFYEND,
-       VCPM_VSTATUSERABORT,
-       VCPM_VSTATYIELD
-};
-
-#define VCPM_PATHCLASS         0x08
-#define VCPM_PATHFIRST         0x0800
-#define VCPM_PATHLAST          0x08ff
-
-enum {
-       VCPM_BUILDPATH = VCPM_PATHFIRST,
-       VCPM_UNIQUEPATH,
-       VCPM_CHECKPATH
-};
-
-#define VCPM_PATCHCLASS                0x09
-#define VCPM_PATCHFIRST                0x0900
-#define VCPM_PATCHLAST         0x09ff
-
-enum {
-       VCPM_FILEPATCHBEFORECPY = VCPM_PATCHFIRST,
-       VCPM_FILEPATCHAFTERCPY,
-       VCPM_FILEPATCHINFOPEN,
-       VCPM_FILEPATCHINFCLOSE
-};
-
-#define VCPM_CERTCLASS         0x0a
-#define VCPM_CERTFIRST         0x0a00
-#define VCPM_CERTLAST          0x0aff
-
-enum {
-       VCPM_FILECERTIFY = VCPM_CERTFIRST,
-       VCPM_FILECERTIFYWARN
-};
-
-typedef LRESULT (CALLBACK *VIFPROC)(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam, LPARAM lParam, LPARAM lparamRef);
-
-typedef int (CALLBACK *VCPENUMPROC)(LPVIRTNODE lpvn, LPARAM lparamRef);
-
-RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef);
-
-/* VcpQueueCopy flags */
-#define VNLP_SYSCRITICAL       0x0001
-#define VNLP_SETUPCRITICAL     0x0002
-#define VNLP_NOVERCHECK                0x0004
-#define VNLP_FORCETEMP         0x0008
-#define VNLP_IFEXISTS          0x0010
-#define VNLP_KEEPNEWER         0x0020
-#define VNLP_PATCHIFEXIST      0x0040
-#define VNLP_NOPATCH           0x0080
-#define VNLP_CATALOGCERT       0x0100
-#define VNLP_NEEDCERTIFY       0x0200
-#define VNLP_COPYIFEXISTS      0x0400
-
-RETERR16 WINAPI VcpQueueCopy16(
-       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
-       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
-       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
-       LPEXPANDVTBL lpExpandVtbl,
-       WORD fl, LPARAM lParam
-);
-RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest);
-RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest);
-
-/* VcpExplain flags */
-enum {
-       VCPEX_SRC_DISK,
-       VCPEX_SRC_CABINET,
-       VCPEX_SRC_LOCN,
-       VCPEX_DST_LOCN,
-       VCPEX_SRC_FILE,
-       VCPEX_DST_FILE,
-       VCPEX_DST_FILE_FINAL,
-       VCPEX_DOS_ERROR,
-       VCPEX_MESSAGE,
-       VCPEX_DOS_SOLUTION,
-       VCPEX_SRC_FULL,
-       VCPEX_DST_FULL,
-       VCPEX_DST_FULL_FINAL
-};
-
-LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat);
-
-/****** logical disk management ******/
-
-typedef struct _LOGDISKDESC_S { /* ldd */
-       WORD        cbSize;       /* struct size */
-       LOGDISKID16 ldid;         /* logical disk ID */
-       LPSTR       pszPath;      /* path this descriptor points to */
-       LPSTR       pszVolLabel;  /* volume label of the disk related to it */
-       LPSTR       pszDiskName;  /* name of this disk */
-       WORD        wVolTime;     /* modification time of volume label */
-       WORD        wVolDate;     /* modification date */
-       DWORD       dwSerNum;     /* serial number of disk */
-       WORD        wFlags;
-} LOGDISKDESC_S, *LPLOGDISKDESC;
-
-/** logical disk identifiers (LDID) **/
-
-/* predefined LDIDs */
-#define LDID_PREDEF_START      0x0001
-#define LDID_PREDEF_END                0x7fff
-
-/* registry-assigned LDIDs */
-#define LDID_VAR_START         0x7000
-#define LDID_VAR_END           0x7fff
-
-/* dynamically assigned LDIDs */
-#define LDID_ASSIGN_START      0x8000
-#define LDID_ASSIGN_END                0xbfff
-
-#define LDID_NULL              0
-#define LDID_ABSOLUTE          ((UINT)-1)
-#define LDID_SRCPATH           1               /* setup source path */
-#define LDID_SETUPTEMP         2               /* setup temp dir */
-#define LDID_UNINSTALL         3               /* uninstall dir */
-#define LDID_BACKUP            4               /* backup dir */
-#define LDID_SETUPSCRATCH      5               /* setup scratch dir */
-#define LDID_WIN               10              /* win dir */
-#define LDID_SYS               11              /* win system dir */
-#define LDID_IOS               12              /* win Iosubsys dir */
-#define LDID_CMD               13              /* win command dir */
-#define LDID_CPL               14              /* win control panel dir */
-#define LDID_PRINT             15              /* win printer dir */
-#define LDID_MAIL              16              /* win mail dir */
-#define LDID_INF               17              /* win inf dir */
-#define LDID_HELP              18              /* win help dir */
-#define LDID_WINADMIN          19              /* admin dir */
-#define LDID_FONTS             20              /* win fonts dir */
-#define LDID_VIEWERS           21              /* win viewers dir */
-#define LDID_VMM32             22              /* win VMM32 dir */
-#define LDID_COLOR             23              /* win color mngment dir */
-#define LDID_APPS              24              /* win apps dir */
-#define LDID_SHARED            25              /* win shared dir */
-#define LDID_WINBOOT           26              /* guaranteed win boot drive */
-#define LDID_MACHINE           27              /* machine specific files */
-#define LDID_HOST_WINBOOT      28
-#define LDID_BOOT              30              /* boot drive root dir */
-#define LDID_BOOT_HOST         31              /* boot drive host root dir */
-#define LDID_OLD_WINBOOT       32              /* root subdir */
-#define LDID_OLD_WIN           33              /* old windows dir */
-
-/* flags for GenInstall() */
-#define GENINSTALL_DO_FILES            1
-#define GENINSTALL_DO_INI              2
-#define GENINSTALL_DO_REG              4
-#define GENINSTALL_DO_INI2REG          8
-#define GENINSTALL_DO_CFGAUTO          16
-#define GENINSTALL_DO_LOGCONFIG                32
-#define GENINSTALL_DO_REGSRCPATH       64
-#define GENINSTALL_DO_PERUSER          128
-
-#define GEINISTALL_DO_INIREG           14
-#define GENINSTALL_DO_ALL              255
-
-/*
- * flags for InstallHinfSection()
- * 128 can be added, too. This means that the .inf file is provided by you
- * instead of being a 32 bit file (i.e. Windows .inf file).
- * In this case all files you install must be in the same dir
- * as your .inf file on the install disk.
- */
-#define HOW_NEVER_REBOOT               0
-#define HOW_ALWAYS_SILENT_REBOOT       1
-#define HOW_ALWAYS_PROMPT_REBOOT       2
-#define HOW_SILENT_REBOOT              3
-#define HOW_PROMPT_REBOOT              4
-
-/****** device installation stuff ******/
-
-#define MAX_CLASS_NAME_LEN     32
-#define MAX_DEVNODE_ID_LEN     256
-#define MAX_GUID_STR           50
-
-typedef struct _DEVICE_INFO
-{
-       UINT16              cbSize;
-       struct _DEVICE_INFO *lpNextDi;
-       char                szDescription[LINE_LEN];
-       DWORD               dnDevnode;
-       HKEY                hRegKey;
-       char                szRegSubkey[MAX_DEVNODE_ID_LEN];
-       char                szClassName[MAX_CLASS_NAME_LEN];
-       DWORD               Flags;
-       HWND16              hwndParent;
-       /*LPDRIVER_NODE*/ LPVOID      lpCompatDrvList;
-       /*LPDRIVER_NODE*/ LPVOID      lpClassDrvList;
-       /*LPDRIVER_NODE*/ LPVOID      lpSelectedDriver;
-       ATOM                atDriverPath;
-       ATOM                atTempInfFile;
-       HINSTANCE16         hinstClassInstaller;
-       HINSTANCE16         hinstClassPropProvidor;
-       HINSTANCE16         hinstDevicePropProvidor;
-       HINSTANCE16         hinstBasicPropProvidor;
-       FARPROC16           fpClassInstaller;
-       FARPROC16           fpClassEnumPropPages;
-       FARPROC16           fpDeviceEnumPropPages;
-       FARPROC16           fpEnumBasicProperties;
-       DWORD               dwSetupReserved;
-       DWORD               dwClassInstallReserved;
-       /*GENCALLBACKPROC*/ LPVOID     gicpGenInstallCallBack;
-
-       LPARAM              gicplParam;
-       UINT16              InfType;
-
-       HINSTANCE16         hinstPrivateProblemHandler;
-       FARPROC16           fpPrivateProblemHandler;
-       LPARAM              lpClassInstallParams;
-       struct _DEVICE_INFO *lpdiChildList;
-       DWORD               dwFlagsEx;
-       /*LPDRIVER_INFO*/ LPVOID       lpCompatDrvInfoList;
-       /*LPDRIVER_INFO*/ LPVOID      lpClassDrvInfoList;
-       char                szClassGUID[MAX_GUID_STR];
-} DEVICE_INFO16, *LPDEVICE_INFO16, **LPLPDEVICE_INFO16;
-
-
-extern void WINAPI GenFormStrWithoutPlaceHolders16(LPSTR,LPCSTR,HINF16);
-extern RETERR16 WINAPI IpOpen16(LPCSTR,HINF16 *);
-extern RETERR16 WINAPI IpClose16(HINF16);
-extern RETERR16 WINAPI CtlSetLdd16(LPLOGDISKDESC);
-extern RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC);
-extern RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC);
-extern RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC);
-extern RETERR16 WINAPI CtlDelLdd16(LOGDISKID16);
-extern RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath);
-extern RETERR16 WINAPI GenInstall16(HINF16,LPCSTR,WORD);
-
-typedef struct tagLDD_LIST {
-        LPLOGDISKDESC pldd;
-        struct tagLDD_LIST *next;
-} LDD_LIST;
-
-#define INIT_LDD(ldd, LDID) \
-  do { \
-   memset(&(ldd), 0, sizeof(LOGDISKDESC_S)); \
-   (ldd).cbSize = sizeof(LOGDISKDESC_S); \
-   ldd.ldid = LDID; \
-  } while(0)
-
-#endif /* __SETUPX16_H */
+/*\r
+ * Copyright 2000 Andreas Mohr for CodeWeavers\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#ifndef __SETUPX16_H\r
+#define __SETUPX16_H\r
+\r
+#include "wine/windef16.h"\r
+\r
+typedef UINT16 DI_FUNCTION16;\r
+typedef UINT16 HINF16;\r
+typedef UINT16 LOGDISKID16;\r
+typedef UINT16 VHSTR;\r
+\r
+#define LINE_LEN       256\r
+\r
+/* error codes stuff */\r
+\r
+typedef UINT16 RETERR16;\r
+#define OK             0\r
+#define IP_ERROR       (UINT16)100\r
+#define TP_ERROR       (UINT16)200\r
+#define VCP_ERROR      (UINT16)300\r
+#define GEN_ERROR      (UINT16)400\r
+#define DI_ERROR       (UINT16)500\r
+\r
+enum {\r
+       ERR_IP_INVALID_FILENAME = IP_ERROR+1,\r
+       ERR_IP_ALLOC_ERR,\r
+       ERR_IP_INVALID_SECT_NAME,\r
+       ERR_IP_OUT_OF_HANDLES,\r
+       ERR_IP_INF_NOT_FOUND,\r
+       ERR_IP_INVALID_INFFILE,\r
+       ERR_IP_INVALID_HINF,\r
+       ERR_IP_INVALID_FIELD,\r
+       ERR_IP_SECT_NOT_FOUND,\r
+       ERR_IP_END_OF_SECTION,\r
+       ERR_IP_PROFILE_NOT_FOUND,\r
+       ERR_IP_LINE_NOT_FOUND,\r
+       ERR_IP_FILEREAD,\r
+       ERR_IP_TOOMANYINFFILES,\r
+       ERR_IP_INVALID_SAVERESTORE,\r
+       ERR_IP_INVALID_INFTYPE\r
+};\r
+\r
+/****** virtual copy operations ******/\r
+\r
+typedef DWORD LPEXPANDVTBL;\r
+\r
+typedef struct {\r
+       DWORD           dwSoFar;\r
+       DWORD           dwTotal;\r
+} VCPPROGRESS, *LPVCPPROGRESS;\r
+\r
+typedef struct {\r
+       WORD            cbSize;\r
+       LOGDISKID16     ldid;\r
+       VHSTR           vhstrRoot;\r
+       VHSTR           vhstrVolumeLabel;\r
+       VHSTR           vhstrDiskName;\r
+       WORD            wVolumeTime;\r
+       WORD            wVolumeDate;\r
+       DWORD           dwSerialNumber;\r
+       WORD            fl;\r
+       LPARAM          lparamRef;\r
+\r
+       VCPPROGRESS     prgFileRead;\r
+       VCPPROGRESS     prgByteRead;\r
+\r
+       VCPPROGRESS     prgFileWrite;\r
+       VCPPROGRESS     prgByteWrite;\r
+} VCPDISKINFO, *LPVCPDISKINFO;\r
+\r
+typedef struct {\r
+       LOGDISKID16     ldid;\r
+       VHSTR           vhstrDir;\r
+       VHSTR           vhstrFileName;\r
+} VCPFILESPEC, *LPVCPFILESPEC;\r
+\r
+typedef struct {\r
+       UINT16          uiMDate;\r
+       UINT16          uiMTime;\r
+       UINT16          uiADate;\r
+       UINT16          uiATime;\r
+       UINT16          uiAttr;\r
+       DWORD           llenIn;\r
+       DWORD           llenOut;\r
+} VCPFATTR, *LPVCPFATTR;\r
+\r
+typedef struct {\r
+       UINT16          uDate;\r
+       UINT16          uTime;\r
+       DWORD           dwSize;\r
+} VCPFILESTAT, *LPVCPFILESTAT;\r
+\r
+typedef struct\r
+{\r
+       HFILE16         hFileSrc;\r
+       HFILE16         hFileDst;\r
+       VCPFATTR        fAttr;\r
+       WORD            dosError;\r
+       VHSTR           vhstrFileName;\r
+       WPARAM          vcpm;\r
+} VIRTNODEEX, *LPVIRTNODEEX;\r
+\r
+typedef struct {\r
+       WORD            cbSize;\r
+       VCPFILESPEC     vfsSrc;\r
+       VCPFILESPEC     vfsDst;\r
+       WORD            fl;\r
+       LPARAM          lParam;\r
+       LPEXPANDVTBL    lpExpandVtbl;\r
+       LPVIRTNODEEX    lpvnex;\r
+       VHSTR           vhstrDstFinalName;\r
+       VCPFILESTAT     vFileStat;\r
+} VIRTNODE, *LPVIRTNODE;\r
+\r
+typedef struct {\r
+       WORD            cbSize;\r
+       VCPPROGRESS     prgDiskRead;\r
+       VCPPROGRESS     prgFileRead;\r
+       VCPPROGRESS     prgByteRead;\r
+\r
+       VCPPROGRESS     prgDiskWrite;\r
+       VCPPROGRESS     prgFileWrite;\r
+       VCPPROGRESS     prgByteWrite;\r
+\r
+       LPVCPDISKINFO   lpvdiIn;\r
+       LPVCPDISKINFO   lpvdiOut;\r
+       LPVIRTNODE      lpvn;\r
+} VCPSTATUS, *LPVCPSTATUS;\r
+\r
+#define CNFL_BACKUP            0x0001\r
+#define CNFL_DELETEONFAILURE   0x0002\r
+#define CNFL_RENAMEONSUCCESS   0x0004\r
+#define CNFL_CONTINUATION      0x0008\r
+#define CNFL_SKIPPED           0x0010\r
+#define CNFL_IGNOREERRORS      0x0020\r
+#define CNFL_RETRYFILE         0x0040\r
+#define CNFL_COPIED            0x0080\r
+#define VNFL_UNIQUE            0x0000\r
+#define VNFL_MULTIPLEOK                0x0100\r
+#define VNFL_DESTROYOLD                0x0200\r
+#define VNFL_COPY              0x0000\r
+#define VNFL_DELETE            0x0800\r
+#define VNFL_RENAME            0x1000\r
+#define VNFL_NODE_TYPE         (VNFL_RENAME|VNFL_DELETE|VNFL_COPY)\r
+#define VNFL_CREATED           0x2000\r
+#define VNFL_REJECTED          0x4000\r
+#define VNFL_DEVICEINSTALLER   0x8000\r
+\r
+enum {\r
+       ERR_VCP_IOFAIL = VCP_ERROR+1,\r
+       ERR_VCP_STRINGTOOLONG,\r
+       ERR_VCP_NOMEM,\r
+       ERR_VCP_QUEUEFULL,\r
+       ERR_VCP_NOVHSTR,\r
+       ERR_VCP_OVERFLOW,\r
+       ERR_VCP_BADARG,\r
+       ERR_VCP_UNINIT,\r
+       ERR_VCP_NOTFOUND,\r
+       ERR_VCP_BUSY,\r
+       ERR_VCP_INTERRUPTED,\r
+       ERR_VCP_BADDEST,\r
+       ERR_VCP_SKIPPED,\r
+       ERR_VCP_IO,\r
+       ERR_VCP_LOCKED,\r
+       ERR_VCP_WRONGDISK,\r
+       ERR_VCP_CHANGEMODE,\r
+       ERR_VCP_LDDINVALID,\r
+       ERR_VCP_LDDFIND,\r
+       ERR_VCP_LDDUNINIT,\r
+       ERR_VCP_LDDPATH_INVALID,\r
+       ERR_VCP_NOEXPANSION,\r
+       ERR_VCP_NOTOPEN,\r
+       ERR_VCP_NO_DIGITAL_SIGNATURE_CATALOG,\r
+       ERR_VCP_NO_DIGITAL_SIGNATURE_FILE\r
+};\r
+\r
+#define VCPN_OK                0\r
+#define VCPN_PROCEED   0\r
+#define VCPN_ABORT     -1\r
+#define VCPN_RETRY     -2\r
+#define VCPN_IGNORE    -3\r
+#define VCPN_SKIP      -4\r
+#define VCPN_FORCE     -5\r
+#define VCPN_DEFER     -6\r
+#define VCPN_FAIL      -7\r
+#define VCPN_RETRYFILE -8\r
+\r
+#define VCPFL_ABANDON          0x00\r
+#define VCPFL_BACKUP           0x01\r
+#define VCPFL_COPY             0x02\r
+#define VCPFL_BACKUPANDCOPY    (VCPFL_BACKUP|VCPFL_COPY)\r
+#define VCPFL_INSPECIFIEDORDER 0x04\r
+#define VCPFL_DELETE           0x08\r
+#define VCPFL_RENAME           0x10\r
+#define VCPFL_ALL              (VCPFL_COPY|VCPFL_DELETE|VCPFL_RENAME)\r
+\r
+#define CFNL_BACKUP            0x0001\r
+#define CFNL_DELETEONFAILURE   0x0002\r
+#define CFNL_RENAMEONSUCCESS   0x0004\r
+#define CFNL_CONTINUATION      0x0008\r
+#define CFNL_SKIPPED           0x0010\r
+#define CFNL_IGNOREERRORS      0x0020\r
+#define CFNL_RETRYFILE         0x0040\r
+#define CFNL_COPIED            0x0080\r
+#define VFNL_MULTIPLEOK                0x0100\r
+#define VFNL_DESTROYOLD                0x0200\r
+#define VFNL_NOW               0x0400\r
+#define VFNL_COPY              0x0000\r
+#define VFNL_DELETE            0x0800\r
+#define VFNL_RENAME            0x1000\r
+#define VFNL_CREATED           0x2000\r
+#define VFNL_REJECTED          0x4000\r
+#define VCPM_DISKCLASS         0x01\r
+#define VCPM_DISKFIRST         0x0100\r
+#define VCPM_DISKLAST          0x01ff\r
+\r
+enum {\r
+       VCPM_DISKCREATEINFO = VCPM_DISKFIRST,\r
+       VCPM_DISKGETINFO,\r
+       VCPM_DISKDESTROYINFO,\r
+       VCPM_DISKPREPINFO,\r
+       VCPM_DISKENSURE,\r
+       VCPM_DISKPROMPT,\r
+       VCPM_DISKFORMATBEGIN,\r
+       VCPM_DISKFORMATTING,\r
+       VCPM_DISKFORMATEND\r
+};\r
+\r
+#define VCPM_FILEINCLASS       0x02\r
+#define VCPM_FILEOUTCLASS      0x03\r
+#define VCPM_FILEFIRSTIN       0x0200\r
+#define VCPM_FILEFIRSTOUT      0x0300\r
+#define VCPM_FILELAST          0x03ff\r
+\r
+enum {\r
+       VCPM_FILEOPENIN = VCPM_FILEFIRSTIN,\r
+       VCPM_FILEGETFATTR,\r
+       VCPM_FILECLOSEIN,\r
+       VCPM_FILECOPY,\r
+       VCPM_FILENEEDED,\r
+\r
+       VCPM_FILEOPENOUT = VCPM_FILEFIRSTOUT,\r
+       VCPM_FILESETFATTR,\r
+       VCPM_FILECLOSEOUT,\r
+       VCPM_FILEFINALIZE,\r
+       VCPM_FILEDELETE,\r
+       VCPM_FILERENAME\r
+};\r
+\r
+#define VCPM_NODECLASS         0x04\r
+#define VCPM_NODEFIRST         0x0400\r
+#define VCPM_NODELAST          0x04ff\r
+\r
+enum {\r
+       VCPM_NODECREATE = VCPM_NODEFIRST,\r
+       VCPM_NODEACCEPT,\r
+       VCPM_NODEREJECT,\r
+       VCPM_NODEDESTROY,\r
+       VCPM_NODECHANGEDESTDIR,\r
+       VCPM_NODECOMPARE\r
+};\r
+\r
+#define VCPM_TALLYCLASS                0x05\r
+#define VCPM_TALLYFIRST                0x0500\r
+#define VCPM_TALLYLAST         0x05ff\r
+\r
+enum {\r
+       VCPM_TALLYSTART = VCPM_TALLYFIRST,\r
+       VCPM_TALLYEND,\r
+       VCPM_TALLYFILE,\r
+       VCPM_TALLYDISK\r
+};\r
+\r
+#define VCPM_VERCLASS          0x06\r
+#define VCPM_VERFIRST          0x0600\r
+#define VCPM_VERLAST           0x06ff\r
+\r
+enum {\r
+       VCPM_VERCHECK = VCPM_VERFIRST,\r
+       VCPM_VERCHECKDONE,\r
+       VCPM_VERRESOLVECONFLICT\r
+};\r
+\r
+#define VCPM_VSTATCLASS                0x07\r
+#define VCPM_VSTATFIRST                0x0700\r
+#define VCPM_VSTATLAST         0x07ff\r
+\r
+enum {\r
+       VCPM_VSTATSTART = VCPM_VSTATFIRST,\r
+       VCPM_VSTATEND,\r
+       VCPM_VSTATREAD,\r
+       VCPM_VSTATWRITE,\r
+       VCPM_VSTATNEWDISK,\r
+       VCPM_VSTATCLOSESTART,\r
+       VCPM_VSTATCLOSEEND,\r
+       VCPM_VSTATBACKUPSTART,\r
+       VCPM_VSTATBACKUPEND,\r
+       VCPM_VSTATRENAMESTART,\r
+       VCPM_VSTATRENAMEEND,\r
+       VCPM_VSTATCOPYSTART,\r
+       VCPM_VSTATCOPYEND,\r
+       VCPM_VSTATDELETESTART,\r
+       VCPM_VSTATDELETEEND,\r
+       VCPM_VSTATPATHCHECKSTART,\r
+       VCPM_VSTATPATHCHECKEND,\r
+       VCPM_VSTATCERTIFYSTART,\r
+       VCPM_VSTATCERTIFYEND,\r
+       VCPM_VSTATUSERABORT,\r
+       VCPM_VSTATYIELD\r
+};\r
+\r
+#define VCPM_PATHCLASS         0x08\r
+#define VCPM_PATHFIRST         0x0800\r
+#define VCPM_PATHLAST          0x08ff\r
+\r
+enum {\r
+       VCPM_BUILDPATH = VCPM_PATHFIRST,\r
+       VCPM_UNIQUEPATH,\r
+       VCPM_CHECKPATH\r
+};\r
+\r
+#define VCPM_PATCHCLASS                0x09\r
+#define VCPM_PATCHFIRST                0x0900\r
+#define VCPM_PATCHLAST         0x09ff\r
+\r
+enum {\r
+       VCPM_FILEPATCHBEFORECPY = VCPM_PATCHFIRST,\r
+       VCPM_FILEPATCHAFTERCPY,\r
+       VCPM_FILEPATCHINFOPEN,\r
+       VCPM_FILEPATCHINFCLOSE\r
+};\r
+\r
+#define VCPM_CERTCLASS         0x0a\r
+#define VCPM_CERTFIRST         0x0a00\r
+#define VCPM_CERTLAST          0x0aff\r
+\r
+enum {\r
+       VCPM_FILECERTIFY = VCPM_CERTFIRST,\r
+       VCPM_FILECERTIFYWARN\r
+};\r
+\r
+typedef LRESULT (CALLBACK *VIFPROC)(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam, LPARAM lParam, LPARAM lparamRef);\r
+\r
+typedef int (CALLBACK *VCPENUMPROC)(LPVIRTNODE lpvn, LPARAM lparamRef);\r
+\r
+RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef);\r
+\r
+/* VcpQueueCopy flags */\r
+#define VNLP_SYSCRITICAL       0x0001\r
+#define VNLP_SETUPCRITICAL     0x0002\r
+#define VNLP_NOVERCHECK                0x0004\r
+#define VNLP_FORCETEMP         0x0008\r
+#define VNLP_IFEXISTS          0x0010\r
+#define VNLP_KEEPNEWER         0x0020\r
+#define VNLP_PATCHIFEXIST      0x0040\r
+#define VNLP_NOPATCH           0x0080\r
+#define VNLP_CATALOGCERT       0x0100\r
+#define VNLP_NEEDCERTIFY       0x0200\r
+#define VNLP_COPYIFEXISTS      0x0400\r
+\r
+RETERR16 WINAPI VcpQueueCopy16(\r
+       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,\r
+       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,\r
+       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,\r
+       LPEXPANDVTBL lpExpandVtbl,\r
+       WORD fl, LPARAM lParam\r
+);\r
+RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest);\r
+RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest);\r
+\r
+/* VcpExplain flags */\r
+enum {\r
+       VCPEX_SRC_DISK,\r
+       VCPEX_SRC_CABINET,\r
+       VCPEX_SRC_LOCN,\r
+       VCPEX_DST_LOCN,\r
+       VCPEX_SRC_FILE,\r
+       VCPEX_DST_FILE,\r
+       VCPEX_DST_FILE_FINAL,\r
+       VCPEX_DOS_ERROR,\r
+       VCPEX_MESSAGE,\r
+       VCPEX_DOS_SOLUTION,\r
+       VCPEX_SRC_FULL,\r
+       VCPEX_DST_FULL,\r
+       VCPEX_DST_FULL_FINAL\r
+};\r
+\r
+LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat);\r
+\r
+/****** logical disk management ******/\r
+\r
+typedef struct _LOGDISKDESC_S { /* ldd */\r
+       WORD        cbSize;       /* struct size */\r
+       LOGDISKID16 ldid;         /* logical disk ID */\r
+       LPSTR       pszPath;      /* path this descriptor points to */\r
+       LPSTR       pszVolLabel;  /* volume label of the disk related to it */\r
+       LPSTR       pszDiskName;  /* name of this disk */\r
+       WORD        wVolTime;     /* modification time of volume label */\r
+       WORD        wVolDate;     /* modification date */\r
+       DWORD       dwSerNum;     /* serial number of disk */\r
+       WORD        wFlags;\r
+} LOGDISKDESC_S, *LPLOGDISKDESC;\r
+\r
+/** logical disk identifiers (LDID) **/\r
+\r
+/* predefined LDIDs */\r
+#define LDID_PREDEF_START      0x0001\r
+#define LDID_PREDEF_END                0x7fff\r
+\r
+/* registry-assigned LDIDs */\r
+#define LDID_VAR_START         0x7000\r
+#define LDID_VAR_END           0x7fff\r
+\r
+/* dynamically assigned LDIDs */\r
+#define LDID_ASSIGN_START      0x8000\r
+#define LDID_ASSIGN_END                0xbfff\r
+\r
+#define LDID_NULL              0\r
+#define LDID_ABSOLUTE          ((UINT)-1)\r
+#define LDID_SRCPATH           1               /* setup source path */\r
+#define LDID_SETUPTEMP         2               /* setup temp dir */\r
+#define LDID_UNINSTALL         3               /* uninstall dir */\r
+#define LDID_BACKUP            4               /* backup dir */\r
+#define LDID_SETUPSCRATCH      5               /* setup scratch dir */\r
+#define LDID_WIN               10              /* win dir */\r
+#define LDID_SYS               11              /* win system dir */\r
+#define LDID_IOS               12              /* win Iosubsys dir */\r
+#define LDID_CMD               13              /* win command dir */\r
+#define LDID_CPL               14              /* win control panel dir */\r
+#define LDID_PRINT             15              /* win printer dir */\r
+#define LDID_MAIL              16              /* win mail dir */\r
+#define LDID_INF               17              /* win inf dir */\r
+#define LDID_HELP              18              /* win help dir */\r
+#define LDID_WINADMIN          19              /* admin dir */\r
+#define LDID_FONTS             20              /* win fonts dir */\r
+#define LDID_VIEWERS           21              /* win viewers dir */\r
+#define LDID_VMM32             22              /* win VMM32 dir */\r
+#define LDID_COLOR             23              /* win color mngment dir */\r
+#define LDID_APPS              24              /* win apps dir */\r
+#define LDID_SHARED            25              /* win shared dir */\r
+#define LDID_WINBOOT           26              /* guaranteed win boot drive */\r
+#define LDID_MACHINE           27              /* machine specific files */\r
+#define LDID_HOST_WINBOOT      28\r
+#define LDID_BOOT              30              /* boot drive root dir */\r
+#define LDID_BOOT_HOST         31              /* boot drive host root dir */\r
+#define LDID_OLD_WINBOOT       32              /* root subdir */\r
+#define LDID_OLD_WIN           33              /* old windows dir */\r
+\r
+/* flags for GenInstall() */\r
+#define GENINSTALL_DO_FILES            1\r
+#define GENINSTALL_DO_INI              2\r
+#define GENINSTALL_DO_REG              4\r
+#define GENINSTALL_DO_INI2REG          8\r
+#define GENINSTALL_DO_CFGAUTO          16\r
+#define GENINSTALL_DO_LOGCONFIG                32\r
+#define GENINSTALL_DO_REGSRCPATH       64\r
+#define GENINSTALL_DO_PERUSER          128\r
+\r
+#define GEINISTALL_DO_INIREG           14\r
+#define GENINSTALL_DO_ALL              255\r
+\r
+/*\r
+ * flags for InstallHinfSection()\r
+ * 128 can be added, too. This means that the .inf file is provided by you\r
+ * instead of being a 32 bit file (i.e. Windows .inf file).\r
+ * In this case all files you install must be in the same dir\r
+ * as your .inf file on the install disk.\r
+ */\r
+#define HOW_NEVER_REBOOT               0\r
+#define HOW_ALWAYS_SILENT_REBOOT       1\r
+#define HOW_ALWAYS_PROMPT_REBOOT       2\r
+#define HOW_SILENT_REBOOT              3\r
+#define HOW_PROMPT_REBOOT              4\r
+\r
+/****** device installation stuff ******/\r
+\r
+#define MAX_CLASS_NAME_LEN     32\r
+#define MAX_DEVNODE_ID_LEN     256\r
+#define MAX_GUID_STR           50\r
+\r
+typedef struct _DEVICE_INFO\r
+{\r
+       UINT16              cbSize;\r
+       struct _DEVICE_INFO *lpNextDi;\r
+       char                szDescription[LINE_LEN];\r
+       DWORD               dnDevnode;\r
+       HKEY                hRegKey;\r
+       char                szRegSubkey[MAX_DEVNODE_ID_LEN];\r
+       char                szClassName[MAX_CLASS_NAME_LEN];\r
+       DWORD               Flags;\r
+       HWND16              hwndParent;\r
+       /*LPDRIVER_NODE*/ LPVOID      lpCompatDrvList;\r
+       /*LPDRIVER_NODE*/ LPVOID      lpClassDrvList;\r
+       /*LPDRIVER_NODE*/ LPVOID      lpSelectedDriver;\r
+       ATOM                atDriverPath;\r
+       ATOM                atTempInfFile;\r
+       HINSTANCE16         hinstClassInstaller;\r
+       HINSTANCE16         hinstClassPropProvidor;\r
+       HINSTANCE16         hinstDevicePropProvidor;\r
+       HINSTANCE16         hinstBasicPropProvidor;\r
+       FARPROC16           fpClassInstaller;\r
+       FARPROC16           fpClassEnumPropPages;\r
+       FARPROC16           fpDeviceEnumPropPages;\r
+       FARPROC16           fpEnumBasicProperties;\r
+       DWORD               dwSetupReserved;\r
+       DWORD               dwClassInstallReserved;\r
+       /*GENCALLBACKPROC*/ LPVOID     gicpGenInstallCallBack;\r
+\r
+       LPARAM              gicplParam;\r
+       UINT16              InfType;\r
+\r
+       HINSTANCE16         hinstPrivateProblemHandler;\r
+       FARPROC16           fpPrivateProblemHandler;\r
+       LPARAM              lpClassInstallParams;\r
+       struct _DEVICE_INFO *lpdiChildList;\r
+       DWORD               dwFlagsEx;\r
+       /*LPDRIVER_INFO*/ LPVOID       lpCompatDrvInfoList;\r
+       /*LPDRIVER_INFO*/ LPVOID      lpClassDrvInfoList;\r
+       char                szClassGUID[MAX_GUID_STR];\r
+} DEVICE_INFO16, *LPDEVICE_INFO16, **LPLPDEVICE_INFO16;\r
+\r
+\r
+extern void WINAPI GenFormStrWithoutPlaceHolders16(LPSTR,LPCSTR,HINF16);\r
+extern RETERR16 WINAPI IpOpen16(LPCSTR,HINF16 *);\r
+extern RETERR16 WINAPI IpClose16(HINF16);\r
+extern RETERR16 WINAPI CtlSetLdd16(LPLOGDISKDESC);\r
+extern RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC);\r
+extern RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC);\r
+extern RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC);\r
+extern RETERR16 WINAPI CtlDelLdd16(LOGDISKID16);\r
+extern RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath);\r
+extern RETERR16 WINAPI GenInstall16(HINF16,LPCSTR,WORD);\r
+\r
+typedef struct tagLDD_LIST {\r
+        LPLOGDISKDESC pldd;\r
+        struct tagLDD_LIST *next;\r
+} LDD_LIST;\r
+\r
+#define INIT_LDD(ldd, LDID) \\r
+  do { \\r
+   memset(&(ldd), 0, sizeof(LOGDISKDESC_S)); \\r
+   (ldd).cbSize = sizeof(LOGDISKDESC_S); \\r
+   ldd.ldid = LDID; \\r
+  } while(0)\r
+\r
+#endif /* __SETUPX16_H */\r
index 8610ce0..df1a5da 100644 (file)
-/*
- *      SETUPX library
- *
- *      Copyright 1998,2000  Andreas Mohr
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * FIXME: Rather non-functional functions for now.
- *
- * See:
- * http://www.geocities.com/SiliconValley/Network/5317/drivers.html
- * http://willemer.de/informatik/windows/inf_info.htm (German)
- * http://www.microsoft.com/ddk/ddkdocs/win98ddk/devinst_12uw.htm
- * DDK: setupx.h
- * http://mmatrix.tripod.com/customsystemfolder/infsysntaxfull.html
- * http://www.rdrop.com/~cary/html/inf_faq.html
- * http://support.microsoft.com/support/kb/articles/q194/6/40.asp
- *
- * Stuff tested with:
- * - rs405deu.exe (German Acroread 4.05 setup)
- * - ie5setup.exe
- * - Netmeeting
- *
- * FIXME:
- * - string handling is... weird ;) (buflen etc.)
- * - memory leaks ?
- * - separate that mess (but probably only when it's done completely)
- *
- * SETUPX consists of several parts with the following acronyms/prefixes:
- * Di  device installer (devinst.c ?)
- * Gen generic installer (geninst.c ?)
- * Ip  .INF parsing (infparse.c)
- * LDD logical device descriptor (ldd.c ?)
- * LDID        logical device ID
- * SU   setup (setup.c ?)
- * Tp  text processing (textproc.c ?)
- * Vcp virtual copy module (vcp.c ?)
- * ...
- *
- * The SETUPX DLL is NOT thread-safe. That's why many installers urge you to
- * "close all open applications".
- * All in all the design of it seems to be a bit weak.
- * Not sure whether my implementation of it is better, though ;-)
- */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winerror.h"
-#include "wine/winuser16.h"
-#include "wownt32.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "setupx16.h"
-#include "setupapi_private.h"
-#include "winerror.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
-
-/***********************************************************************
- *             SURegOpenKey (SETUPX.47)
- */
-DWORD WINAPI SURegOpenKey( HKEY hkey, LPCSTR lpszSubKey, PHKEY retkey )
-{
-    FIXME("(%p,%s,%p), semi-stub.\n",hkey,debugstr_a(lpszSubKey),retkey);
-    return RegOpenKeyA( hkey, lpszSubKey, retkey );
-}
-
-/***********************************************************************
- *             SURegQueryValueEx (SETUPX.50)
- */
-DWORD WINAPI SURegQueryValueEx( HKEY hkey, LPSTR lpszValueName,
-                                LPDWORD lpdwReserved, LPDWORD lpdwType,
-                                LPBYTE lpbData, LPDWORD lpcbData )
-{
-    FIXME("(%p,%s,%p,%p,%p,%ld), semi-stub.\n",hkey,debugstr_a(lpszValueName),
-          lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);
-    return RegQueryValueExA( hkey, lpszValueName, lpdwReserved, lpdwType,
-                               lpbData, lpcbData );
-}
-
-
-/***********************************************************************
- *             InstallHinfSection (SETUPX.527)
- *
- * hwnd = parent window
- * hinst = instance of SETUPX.DLL
- * lpszCmdLine = e.g. "DefaultInstall 132 C:\MYINSTALL\MYDEV.INF"
- * Here "DefaultInstall" is the .inf file section to be installed (optional).
- * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h).
- *
- * nCmdShow = nCmdShow of CreateProcess
- */
-RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCmdLine, INT16 nCmdShow)
-{
-    InstallHinfSectionA( HWND_32(hwnd), HINSTANCE_32(hinst), lpszCmdLine, nCmdShow );
-    return OK;
-}
-
-typedef struct
-{
-    LPCSTR RegValName;
-    LPCSTR StdString; /* fallback string; sub dir of windows directory */
-} LDID_DATA;
-
-static const LDID_DATA LDID_Data[34] =
-{
-    { /* 0 (LDID_NULL) -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */
-       "SourcePath", /* hmm, does SETUPX have to care about updating it ?? */
-       NULL
-    },
-    { /* 2 (LDID_SETUPTEMP) = setup temp dir */
-       "SetupTempDir",
-       NULL
-    },
-    { /* 3 (LDID_UNINSTALL) = uninstall backup dir */
-       "UninstallDir",
-       NULL
-    },
-    { /* 4 (LDID_BACKUP) = backup dir */
-       "BackupDir",
-       NULL
-    },
-    { /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */
-       "SetupScratchDir",
-       NULL
-    },
-    { /* 6 -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 7 -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 8 -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 9 -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 10 (LDID_WIN) = windows dir */
-       "WinDir",
-        ""
-    },
-    { /* 11 (LDID_SYS) = system dir */
-       "SysDir",
-       NULL /* call GetSystemDirectory() instead */
-    },
-    { /* 12 (LDID_IOS) = IOSubSys dir */
-        NULL, /* FIXME: registry string ? */
-       "SYSTEM\\IOSUBSYS"
-    },
-    { /* 13 (LDID_CMD) = COMMAND dir */
-       NULL, /* FIXME: registry string ? */
-       "COMMAND"
-    },
-    { /* 14 (LDID_CPL) = control panel dir */
-       NULL,
-       ""
-    },
-    { /* 15 (LDID_PRINT) = windows printer dir */
-       NULL,
-       "SYSTEM" /* correct ?? */
-    },
-    { /* 16 (LDID_MAIL) = destination mail dir */
-       NULL,
-       ""
-    },
-    { /* 17 (LDID_INF) = INF dir */
-       "SetupScratchDir", /* correct ? */
-       "INF"
-    },
-    { /* 18 (LDID_HELP) = HELP dir */
-       NULL, /* ??? */
-       "HELP"
-    },
-    { /* 19 (LDID_WINADMIN) = Admin dir */
-       "WinAdminDir",
-       ""
-    },
-    { /* 20 (LDID_FONTS) = Fonts dir */
-       NULL, /* ??? */
-       "FONTS"
-    },
-    { /* 21 (LDID_VIEWERS) = Viewers */
-       NULL, /* ??? */
-       "SYSTEM\\VIEWERS"
-    },
-    { /* 22 (LDID_VMM32) = VMM32 dir */
-       NULL, /* ??? */
-       "SYSTEM\\VMM32"
-    },
-    { /* 23 (LDID_COLOR) = ICM dir */
-       "ICMPath",
-       "SYSTEM\\COLOR"
-    },
-    { /* 24 (LDID_APPS) = root of boot drive ? */
-       "AppsDir",
-       "C:\\"
-    },
-    { /* 25 (LDID_SHARED) = shared dir */
-       "SharedDir",
-       ""
-    },
-    { /* 26 (LDID_WINBOOT) = Windows boot dir */
-       "WinBootDir",
-       ""
-    },
-    { /* 27 (LDID_MACHINE) = machine specific files */
-       "MachineDir",
-       NULL
-    },
-    { /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */
-       "HostWinBootDir",
-       NULL
-    },
-    { /* 29 -- not defined */
-       NULL,
-       NULL
-    },
-    { /* 30 (LDID_BOOT) = Root of boot drive */
-       "BootDir",
-       NULL
-    },
-    { /* 31 (LDID_BOOT_HOST) = Root of boot drive host */
-       "BootHost",
-       NULL
-    },
-    { /* 32 (LDID_OLD_WINBOOT) = subdir of root */
-       "OldWinBootDir",
-       NULL
-    },
-    { /* 33 (LDID_OLD_WIN) = old win dir */
-       "OldWinDir",
-       NULL
-    }
-    /* the rest (34-38) isn't too interesting, so I'll forget about it */
-};
-
-/*
- * LDD  == Logical Device Descriptor
- * LDID == Logical Device ID
- *
- * The whole LDD/LDID business might go into a separate file named
- * ldd.c.
- * At the moment I don't know what the hell these functions are really doing.
- * That's why I added reporting stubs.
- * The only thing I do know is that I need them for the LDD/LDID infrastructure.
- * That's why I implemented them in a way that's suitable for my purpose.
- */
-static LDD_LIST *pFirstLDD = NULL;
-
-static BOOL std_LDDs_done = FALSE;
-
-void SETUPX_CreateStandardLDDs(void)
-{
-    HKEY hKey = 0;
-    WORD n;
-    DWORD type, len;
-    LOGDISKDESC_S ldd;
-    char buffer[MAX_PATH];
-
-    /* has to be here, otherwise loop */
-    std_LDDs_done = TRUE;
-
-    RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", &hKey);
-
-    for (n=0; n < sizeof(LDID_Data)/sizeof(LDID_DATA); n++)
-    {
-       buffer[0] = '\0';
-
-       len = MAX_PATH;
-       if ( (hKey) && (LDID_Data[n].RegValName)
-       &&   (RegQueryValueExA(hKey, LDID_Data[n].RegValName,
-               NULL, &type, buffer, &len) == ERROR_SUCCESS)
-       &&   (type == REG_SZ) )
-       {
-           TRACE("found value '%s' for LDID %d\n", buffer, n);
-       }
-       else
-        switch(n)
-       {
-           case LDID_SRCPATH:
-               FIXME("LDID_SRCPATH: what exactly do we have to do here ?\n");
-               strcpy(buffer, "X:\\FIXME");
-               break;
-           case LDID_SYS:
-               GetSystemDirectoryA(buffer, MAX_PATH);
-               break;
-           case LDID_APPS:
-           case LDID_MACHINE:
-           case LDID_HOST_WINBOOT:
-           case LDID_BOOT:
-           case LDID_BOOT_HOST:
-               strcpy(buffer, "C:\\");
-               break;
-           default:
-               if (LDID_Data[n].StdString)
-               {
-                   DWORD len = GetWindowsDirectoryA(buffer, MAX_PATH);
-                   LPSTR p;
-                   p = buffer + len;
-                   *p++ = '\\';
-                   strcpy(p, LDID_Data[n].StdString);
-               }
-               break;
-        }
-       if (buffer[0])
-       {
-           INIT_LDD(ldd, n);
-           ldd.pszPath = buffer;
-           TRACE("LDID %d -> '%s'\n", ldd.ldid, ldd.pszPath);
-           CtlSetLdd16(&ldd);
-       }
-    }
-    if (hKey) RegCloseKey(hKey);
-}
-
-/***********************************************************************
- * CtlDelLdd           (SETUPX.37)
- *
- * RETURN
- *   ERR_VCP_LDDINVALID if ldid < LDID_ASSIGN_START.
- */
-RETERR16 SETUPX_DelLdd(LOGDISKID16 ldid)
-{
-    LDD_LIST *pCurr, *pPrev = NULL;
-
-    TRACE("(%d)\n", ldid);
-
-    if (!std_LDDs_done)
-       SETUPX_CreateStandardLDDs();
-
-    if (ldid < LDID_ASSIGN_START)
-       return ERR_VCP_LDDINVALID;
-
-    pCurr = pFirstLDD;
-    /* search until we find the appropriate LDD or hit the end */
-    while ((pCurr != NULL) && (ldid > pCurr->pldd->ldid))
-    {
-        pPrev = pCurr;
-        pCurr = pCurr->next;
-    }
-    if ( (pCurr == NULL) /* hit end of list */
-      || (ldid != pCurr->pldd->ldid) )
-       return ERR_VCP_LDDFIND; /* correct ? */
-
-    /* ok, found our victim: eliminate it */
-
-    if (pPrev)
-       pPrev->next = pCurr->next;
-
-    if (pCurr == pFirstLDD)
-       pFirstLDD = NULL;
-    HeapFree(GetProcessHeap(), 0, pCurr);
-
-    return OK;
-}
-
-/***********************************************************************
- *             CtlDelLdd (SETUPX.37)
- */
-RETERR16 WINAPI CtlDelLdd16(LOGDISKID16 ldid)
-{
-    FIXME("(%d); - please report this!\n", ldid);
-    return SETUPX_DelLdd(ldid);
-}
-
-/***********************************************************************
- * CtlFindLdd          (SETUPX.35)
- *
- * doesn't check pldd ptr validity: crash (W98SE)
- *
- * RETURN
- *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize
- *   1 in all other cases ??
- *
- */
-RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC pldd)
-{
-    LDD_LIST *pCurr, *pPrev = NULL;
-
-    TRACE("(%p)\n", pldd);
-
-    if (!std_LDDs_done)
-       SETUPX_CreateStandardLDDs();
-
-    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
-        return ERR_VCP_LDDINVALID;
-
-    pCurr = pFirstLDD;
-    /* search until we find the appropriate LDD or hit the end */
-    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
-    {
-       pPrev = pCurr;
-       pCurr = pCurr->next;
-    }
-    if ( (pCurr == NULL) /* hit end of list */
-      || (pldd->ldid != pCurr->pldd->ldid) )
-       return ERR_VCP_LDDFIND; /* correct ? */
-
-    memcpy(pldd, pCurr->pldd, pldd->cbSize);
-    /* hmm, we probably ought to strcpy() the string ptrs here */
-
-    return 1; /* what is this ?? */
-}
-
-/***********************************************************************
- * CtlSetLdd                   (SETUPX.33)
- *
- * Set an LDD entry.
- *
- * RETURN
- *   ERR_VCP_LDDINVALID if pldd.cbSize != sizeof(LOGDISKDESC_S)
- *
- */
-RETERR16 WINAPI CtlSetLdd16(LPLOGDISKDESC pldd)
-{
-    LDD_LIST *pCurr, *pPrev = NULL;
-    LPLOGDISKDESC pCurrLDD;
-    HANDLE heap;
-    BOOL is_new = FALSE;
-
-    TRACE("(%p)\n", pldd);
-
-    if (!std_LDDs_done)
-       SETUPX_CreateStandardLDDs();
-
-    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
-       return ERR_VCP_LDDINVALID;
-
-    heap = GetProcessHeap();
-    pCurr = pFirstLDD;
-    /* search until we find the appropriate LDD or hit the end */
-    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
-    {
-        pPrev = pCurr;
-        pCurr = pCurr->next;
-    }
-    if (!pCurr || pldd->ldid != pCurr->pldd->ldid)
-    {
-       is_new = TRUE;
-        pCurr = HeapAlloc(heap, 0, sizeof(LDD_LIST));
-        pCurr->pldd = HeapAlloc(heap, 0, sizeof(LOGDISKDESC_S));
-        pCurr->next = NULL;
-        pCurrLDD = pCurr->pldd;
-    }
-    else
-    {
-        pCurrLDD = pCurr->pldd;
-        HeapFree(heap, 0, pCurrLDD->pszPath);
-        HeapFree(heap, 0, pCurrLDD->pszVolLabel);
-        HeapFree(heap, 0, pCurrLDD->pszDiskName);
-    }
-
-    memcpy(pCurrLDD, pldd, sizeof(LOGDISKDESC_S));
-
-    if (pldd->pszPath)
-    {
-        pCurrLDD->pszPath = HeapAlloc( heap, 0, strlen(pldd->pszPath)+1 );
-        strcpy( pCurrLDD->pszPath, pldd->pszPath );
-    }
-    if (pldd->pszVolLabel)
-    {
-        pCurrLDD->pszVolLabel = HeapAlloc( heap, 0, strlen(pldd->pszVolLabel)+1 );
-        strcpy( pCurrLDD->pszVolLabel, pldd->pszVolLabel );
-    }
-    if (pldd->pszDiskName)
-    {
-        pCurrLDD->pszDiskName = HeapAlloc( heap, 0, strlen(pldd->pszDiskName)+1 );
-        strcpy( pCurrLDD->pszDiskName, pldd->pszDiskName );
-    }
-
-    if (is_new) /* link into list */
-    {
-        if (pPrev)
-       {
-           pCurr->next = pPrev->next;
-            pPrev->next = pCurr;
-       }
-       if (!pFirstLDD)
-           pFirstLDD = pCurr;
-    }
-
-    return OK;
-}
-
-
-/***********************************************************************
- * CtlAddLdd           (SETUPX.36)
- *
- * doesn't check pldd ptr validity: crash (W98SE)
- *
- */
-static LOGDISKID16 ldid_to_add = LDID_ASSIGN_START;
-RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC pldd)
-{
-    pldd->ldid = ldid_to_add++;
-    return CtlSetLdd16(pldd);
-}
-
-/***********************************************************************
- * CtlGetLdd           (SETUPX.34)
- *
- * doesn't check pldd ptr validity: crash (W98SE)
- * What the !@#$%&*( is the difference between CtlFindLdd() and CtlGetLdd() ??
- *
- * RETURN
- *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize
- *
- */
-static RETERR16 SETUPX_GetLdd(LPLOGDISKDESC pldd)
-{
-    LDD_LIST *pCurr, *pPrev = NULL;
-
-    if (!std_LDDs_done)
-       SETUPX_CreateStandardLDDs();
-
-    if (pldd->cbSize != sizeof(LOGDISKDESC_S))
-        return ERR_VCP_LDDINVALID;
-
-    pCurr = pFirstLDD;
-    /* search until we find the appropriate LDD or hit the end */
-    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))
-    {
-        pPrev = pCurr;
-        pCurr = pCurr->next;
-    }
-    if (pCurr == NULL) /* hit end of list */
-       return ERR_VCP_LDDFIND; /* correct ? */
-
-    memcpy(pldd, pCurr->pldd, pldd->cbSize);
-    /* hmm, we probably ought to strcpy() the string ptrs here */
-
-    return OK;
-}
-
-/**********************************************************************/
-
-RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC pldd)
-{
-    FIXME("(%p); - please report this!\n", pldd);
-    return SETUPX_GetLdd(pldd);
-}
-
-/***********************************************************************
- *             CtlGetLddPath           (SETUPX.38)
- *
- * Gets the path of an LDD.
- * No crash if szPath == NULL.
- * szPath has to be at least MAX_PATH_LEN bytes long.
- * RETURN
- *   ERR_VCP_LDDUNINIT if LDD for LDID not found.
- */
-RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath)
-{
-    TRACE("(%d, %p);\n", ldid, szPath);
-
-    if (szPath)
-    {
-       LOGDISKDESC_S ldd;
-       INIT_LDD(ldd, ldid);
-       if (CtlFindLdd16(&ldd) == ERR_VCP_LDDFIND)
-           return ERR_VCP_LDDUNINIT;
-       SETUPX_GetLdd(&ldd);
-        strcpy(szPath, ldd.pszPath);
-       TRACE("ret '%s' for LDID %d\n", szPath, ldid);
-    }
-    return OK;
-}
-
-/***********************************************************************
- *             CtlSetLddPath           (SETUPX.508)
- *
- * Sets the path of an LDD.
- * Creates LDD for LDID if not existing yet.
- */
-RETERR16 WINAPI CtlSetLddPath16(LOGDISKID16 ldid, LPSTR szPath)
-{
-    LOGDISKDESC_S ldd;
-    TRACE("(%d, '%s');\n", ldid, szPath);
-
-    SetupSetDirectoryIdA( 0, ldid, szPath );
-    INIT_LDD(ldd, ldid);
-    ldd.pszPath = szPath;
-    return CtlSetLdd16(&ldd);
-}
+/*\r
+ *      SETUPX library\r
+ *\r
+ *      Copyright 1998,2000  Andreas Mohr\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * FIXME: Rather non-functional functions for now.\r
+ *\r
+ * See:\r
+ * http://www.geocities.com/SiliconValley/Network/5317/drivers.html\r
+ * http://willemer.de/informatik/windows/inf_info.htm (German)\r
+ * http://www.microsoft.com/ddk/ddkdocs/win98ddk/devinst_12uw.htm\r
+ * DDK: setupx.h\r
+ * http://mmatrix.tripod.com/customsystemfolder/infsysntaxfull.html\r
+ * http://www.rdrop.com/~cary/html/inf_faq.html\r
+ * http://support.microsoft.com/support/kb/articles/q194/6/40.asp\r
+ *\r
+ * Stuff tested with:\r
+ * - rs405deu.exe (German Acroread 4.05 setup)\r
+ * - ie5setup.exe\r
+ * - Netmeeting\r
+ *\r
+ * FIXME:\r
+ * - string handling is... weird ;) (buflen etc.)\r
+ * - memory leaks ?\r
+ * - separate that mess (but probably only when it's done completely)\r
+ *\r
+ * SETUPX consists of several parts with the following acronyms/prefixes:\r
+ * Di  device installer (devinst.c ?)\r
+ * Gen generic installer (geninst.c ?)\r
+ * Ip  .INF parsing (infparse.c)\r
+ * LDD logical device descriptor (ldd.c ?)\r
+ * LDID        logical device ID\r
+ * SU   setup (setup.c ?)\r
+ * Tp  text processing (textproc.c ?)\r
+ * Vcp virtual copy module (vcp.c ?)\r
+ * ...\r
+ *\r
+ * The SETUPX DLL is NOT thread-safe. That's why many installers urge you to\r
+ * "close all open applications".\r
+ * All in all the design of it seems to be a bit weak.\r
+ * Not sure whether my implementation of it is better, though ;-)\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winreg.h"\r
+#include "winerror.h"\r
+#include "wine/winuser16.h"\r
+#include "wownt32.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "setupx16.h"\r
+#include "setupapi_private.h"\r
+#include "winerror.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))\r
+\r
+/***********************************************************************\r
+ *             SURegOpenKey (SETUPX.47)\r
+ */\r
+DWORD WINAPI SURegOpenKey( HKEY hkey, LPCSTR lpszSubKey, PHKEY retkey )\r
+{\r
+    FIXME("(%p,%s,%p), semi-stub.\n",hkey,debugstr_a(lpszSubKey),retkey);\r
+    return RegOpenKeyA( hkey, lpszSubKey, retkey );\r
+}\r
+\r
+/***********************************************************************\r
+ *             SURegQueryValueEx (SETUPX.50)\r
+ */\r
+DWORD WINAPI SURegQueryValueEx( HKEY hkey, LPSTR lpszValueName,\r
+                                LPDWORD lpdwReserved, LPDWORD lpdwType,\r
+                                LPBYTE lpbData, LPDWORD lpcbData )\r
+{\r
+    FIXME("(%p,%s,%p,%p,%p,%ld), semi-stub.\n",hkey,debugstr_a(lpszValueName),\r
+          lpdwReserved,lpdwType,lpbData,lpcbData?*lpcbData:0);\r
+    return RegQueryValueExA( hkey, lpszValueName, lpdwReserved, lpdwType,\r
+                               lpbData, lpcbData );\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             InstallHinfSection (SETUPX.527)\r
+ *\r
+ * hwnd = parent window\r
+ * hinst = instance of SETUPX.DLL\r
+ * lpszCmdLine = e.g. "DefaultInstall 132 C:\MYINSTALL\MYDEV.INF"\r
+ * Here "DefaultInstall" is the .inf file section to be installed (optional).\r
+ * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h).\r
+ *\r
+ * nCmdShow = nCmdShow of CreateProcess\r
+ */\r
+RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCmdLine, INT16 nCmdShow)\r
+{\r
+    InstallHinfSectionA( HWND_32(hwnd), HINSTANCE_32(hinst), lpszCmdLine, nCmdShow );\r
+    return OK;\r
+}\r
+\r
+typedef struct\r
+{\r
+    LPCSTR RegValName;\r
+    LPCSTR StdString; /* fallback string; sub dir of windows directory */\r
+} LDID_DATA;\r
+\r
+static const LDID_DATA LDID_Data[34] =\r
+{\r
+    { /* 0 (LDID_NULL) -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 1 (LDID_SRCPATH) = source of installation. hmm, what to do here ? */\r
+       "SourcePath", /* hmm, does SETUPX have to care about updating it ?? */\r
+       NULL\r
+    },\r
+    { /* 2 (LDID_SETUPTEMP) = setup temp dir */\r
+       "SetupTempDir",\r
+       NULL\r
+    },\r
+    { /* 3 (LDID_UNINSTALL) = uninstall backup dir */\r
+       "UninstallDir",\r
+       NULL\r
+    },\r
+    { /* 4 (LDID_BACKUP) = backup dir */\r
+       "BackupDir",\r
+       NULL\r
+    },\r
+    { /* 5 (LDID_SETUPSCRATCH) = setup scratch dir */\r
+       "SetupScratchDir",\r
+       NULL\r
+    },\r
+    { /* 6 -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 7 -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 8 -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 9 -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 10 (LDID_WIN) = windows dir */\r
+       "WinDir",\r
+        ""\r
+    },\r
+    { /* 11 (LDID_SYS) = system dir */\r
+       "SysDir",\r
+       NULL /* call GetSystemDirectory() instead */\r
+    },\r
+    { /* 12 (LDID_IOS) = IOSubSys dir */\r
+        NULL, /* FIXME: registry string ? */\r
+       "SYSTEM\\IOSUBSYS"\r
+    },\r
+    { /* 13 (LDID_CMD) = COMMAND dir */\r
+       NULL, /* FIXME: registry string ? */\r
+       "COMMAND"\r
+    },\r
+    { /* 14 (LDID_CPL) = control panel dir */\r
+       NULL,\r
+       ""\r
+    },\r
+    { /* 15 (LDID_PRINT) = windows printer dir */\r
+       NULL,\r
+       "SYSTEM" /* correct ?? */\r
+    },\r
+    { /* 16 (LDID_MAIL) = destination mail dir */\r
+       NULL,\r
+       ""\r
+    },\r
+    { /* 17 (LDID_INF) = INF dir */\r
+       "SetupScratchDir", /* correct ? */\r
+       "INF"\r
+    },\r
+    { /* 18 (LDID_HELP) = HELP dir */\r
+       NULL, /* ??? */\r
+       "HELP"\r
+    },\r
+    { /* 19 (LDID_WINADMIN) = Admin dir */\r
+       "WinAdminDir",\r
+       ""\r
+    },\r
+    { /* 20 (LDID_FONTS) = Fonts dir */\r
+       NULL, /* ??? */\r
+       "FONTS"\r
+    },\r
+    { /* 21 (LDID_VIEWERS) = Viewers */\r
+       NULL, /* ??? */\r
+       "SYSTEM\\VIEWERS"\r
+    },\r
+    { /* 22 (LDID_VMM32) = VMM32 dir */\r
+       NULL, /* ??? */\r
+       "SYSTEM\\VMM32"\r
+    },\r
+    { /* 23 (LDID_COLOR) = ICM dir */\r
+       "ICMPath",\r
+       "SYSTEM\\COLOR"\r
+    },\r
+    { /* 24 (LDID_APPS) = root of boot drive ? */\r
+       "AppsDir",\r
+       "C:\\"\r
+    },\r
+    { /* 25 (LDID_SHARED) = shared dir */\r
+       "SharedDir",\r
+       ""\r
+    },\r
+    { /* 26 (LDID_WINBOOT) = Windows boot dir */\r
+       "WinBootDir",\r
+       ""\r
+    },\r
+    { /* 27 (LDID_MACHINE) = machine specific files */\r
+       "MachineDir",\r
+       NULL\r
+    },\r
+    { /* 28 (LDID_HOST_WINBOOT) = Host Windows boot dir */\r
+       "HostWinBootDir",\r
+       NULL\r
+    },\r
+    { /* 29 -- not defined */\r
+       NULL,\r
+       NULL\r
+    },\r
+    { /* 30 (LDID_BOOT) = Root of boot drive */\r
+       "BootDir",\r
+       NULL\r
+    },\r
+    { /* 31 (LDID_BOOT_HOST) = Root of boot drive host */\r
+       "BootHost",\r
+       NULL\r
+    },\r
+    { /* 32 (LDID_OLD_WINBOOT) = subdir of root */\r
+       "OldWinBootDir",\r
+       NULL\r
+    },\r
+    { /* 33 (LDID_OLD_WIN) = old win dir */\r
+       "OldWinDir",\r
+       NULL\r
+    }\r
+    /* the rest (34-38) isn't too interesting, so I'll forget about it */\r
+};\r
+\r
+/*\r
+ * LDD  == Logical Device Descriptor\r
+ * LDID == Logical Device ID\r
+ *\r
+ * The whole LDD/LDID business might go into a separate file named\r
+ * ldd.c.\r
+ * At the moment I don't know what the hell these functions are really doing.\r
+ * That's why I added reporting stubs.\r
+ * The only thing I do know is that I need them for the LDD/LDID infrastructure.\r
+ * That's why I implemented them in a way that's suitable for my purpose.\r
+ */\r
+static LDD_LIST *pFirstLDD = NULL;\r
+\r
+static BOOL std_LDDs_done = FALSE;\r
+\r
+void SETUPX_CreateStandardLDDs(void)\r
+{\r
+    HKEY hKey = 0;\r
+    WORD n;\r
+    DWORD type, len;\r
+    LOGDISKDESC_S ldd;\r
+    char buffer[MAX_PATH];\r
+\r
+    /* has to be here, otherwise loop */\r
+    std_LDDs_done = TRUE;\r
+\r
+    RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", &hKey);\r
+\r
+    for (n=0; n < sizeof(LDID_Data)/sizeof(LDID_DATA); n++)\r
+    {\r
+       buffer[0] = '\0';\r
+\r
+       len = MAX_PATH;\r
+       if ( (hKey) && (LDID_Data[n].RegValName)\r
+       &&   (RegQueryValueExA(hKey, LDID_Data[n].RegValName,\r
+               NULL, &type, buffer, &len) == ERROR_SUCCESS)\r
+       &&   (type == REG_SZ) )\r
+       {\r
+           TRACE("found value '%s' for LDID %d\n", buffer, n);\r
+       }\r
+       else\r
+        switch(n)\r
+       {\r
+           case LDID_SRCPATH:\r
+               FIXME("LDID_SRCPATH: what exactly do we have to do here ?\n");\r
+               strcpy(buffer, "X:\\FIXME");\r
+               break;\r
+           case LDID_SYS:\r
+               GetSystemDirectoryA(buffer, MAX_PATH);\r
+               break;\r
+           case LDID_APPS:\r
+           case LDID_MACHINE:\r
+           case LDID_HOST_WINBOOT:\r
+           case LDID_BOOT:\r
+           case LDID_BOOT_HOST:\r
+               strcpy(buffer, "C:\\");\r
+               break;\r
+           default:\r
+               if (LDID_Data[n].StdString)\r
+               {\r
+                   DWORD len = GetWindowsDirectoryA(buffer, MAX_PATH);\r
+                   LPSTR p;\r
+                   p = buffer + len;\r
+                   *p++ = '\\';\r
+                   strcpy(p, LDID_Data[n].StdString);\r
+               }\r
+               break;\r
+        }\r
+       if (buffer[0])\r
+       {\r
+           INIT_LDD(ldd, n);\r
+           ldd.pszPath = buffer;\r
+           TRACE("LDID %d -> '%s'\n", ldd.ldid, ldd.pszPath);\r
+           CtlSetLdd16(&ldd);\r
+       }\r
+    }\r
+    if (hKey) RegCloseKey(hKey);\r
+}\r
+\r
+/***********************************************************************\r
+ * CtlDelLdd           (SETUPX.37)\r
+ *\r
+ * RETURN\r
+ *   ERR_VCP_LDDINVALID if ldid < LDID_ASSIGN_START.\r
+ */\r
+RETERR16 SETUPX_DelLdd(LOGDISKID16 ldid)\r
+{\r
+    LDD_LIST *pCurr, *pPrev = NULL;\r
+\r
+    TRACE("(%d)\n", ldid);\r
+\r
+    if (!std_LDDs_done)\r
+       SETUPX_CreateStandardLDDs();\r
+\r
+    if (ldid < LDID_ASSIGN_START)\r
+       return ERR_VCP_LDDINVALID;\r
+\r
+    pCurr = pFirstLDD;\r
+    /* search until we find the appropriate LDD or hit the end */\r
+    while ((pCurr != NULL) && (ldid > pCurr->pldd->ldid))\r
+    {\r
+        pPrev = pCurr;\r
+        pCurr = pCurr->next;\r
+    }\r
+    if ( (pCurr == NULL) /* hit end of list */\r
+      || (ldid != pCurr->pldd->ldid) )\r
+       return ERR_VCP_LDDFIND; /* correct ? */\r
+\r
+    /* ok, found our victim: eliminate it */\r
+\r
+    if (pPrev)\r
+       pPrev->next = pCurr->next;\r
+\r
+    if (pCurr == pFirstLDD)\r
+       pFirstLDD = NULL;\r
+    HeapFree(GetProcessHeap(), 0, pCurr);\r
+\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             CtlDelLdd (SETUPX.37)\r
+ */\r
+RETERR16 WINAPI CtlDelLdd16(LOGDISKID16 ldid)\r
+{\r
+    FIXME("(%d); - please report this!\n", ldid);\r
+    return SETUPX_DelLdd(ldid);\r
+}\r
+\r
+/***********************************************************************\r
+ * CtlFindLdd          (SETUPX.35)\r
+ *\r
+ * doesn't check pldd ptr validity: crash (W98SE)\r
+ *\r
+ * RETURN\r
+ *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize\r
+ *   1 in all other cases ??\r
+ *\r
+ */\r
+RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC pldd)\r
+{\r
+    LDD_LIST *pCurr, *pPrev = NULL;\r
+\r
+    TRACE("(%p)\n", pldd);\r
+\r
+    if (!std_LDDs_done)\r
+       SETUPX_CreateStandardLDDs();\r
+\r
+    if (pldd->cbSize != sizeof(LOGDISKDESC_S))\r
+        return ERR_VCP_LDDINVALID;\r
+\r
+    pCurr = pFirstLDD;\r
+    /* search until we find the appropriate LDD or hit the end */\r
+    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))\r
+    {\r
+       pPrev = pCurr;\r
+       pCurr = pCurr->next;\r
+    }\r
+    if ( (pCurr == NULL) /* hit end of list */\r
+      || (pldd->ldid != pCurr->pldd->ldid) )\r
+       return ERR_VCP_LDDFIND; /* correct ? */\r
+\r
+    memcpy(pldd, pCurr->pldd, pldd->cbSize);\r
+    /* hmm, we probably ought to strcpy() the string ptrs here */\r
+\r
+    return 1; /* what is this ?? */\r
+}\r
+\r
+/***********************************************************************\r
+ * CtlSetLdd                   (SETUPX.33)\r
+ *\r
+ * Set an LDD entry.\r
+ *\r
+ * RETURN\r
+ *   ERR_VCP_LDDINVALID if pldd.cbSize != sizeof(LOGDISKDESC_S)\r
+ *\r
+ */\r
+RETERR16 WINAPI CtlSetLdd16(LPLOGDISKDESC pldd)\r
+{\r
+    LDD_LIST *pCurr, *pPrev = NULL;\r
+    LPLOGDISKDESC pCurrLDD;\r
+    HANDLE heap;\r
+    BOOL is_new = FALSE;\r
+\r
+    TRACE("(%p)\n", pldd);\r
+\r
+    if (!std_LDDs_done)\r
+       SETUPX_CreateStandardLDDs();\r
+\r
+    if (pldd->cbSize != sizeof(LOGDISKDESC_S))\r
+       return ERR_VCP_LDDINVALID;\r
+\r
+    heap = GetProcessHeap();\r
+    pCurr = pFirstLDD;\r
+    /* search until we find the appropriate LDD or hit the end */\r
+    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))\r
+    {\r
+        pPrev = pCurr;\r
+        pCurr = pCurr->next;\r
+    }\r
+    if (!pCurr || pldd->ldid != pCurr->pldd->ldid)\r
+    {\r
+       is_new = TRUE;\r
+        pCurr = HeapAlloc(heap, 0, sizeof(LDD_LIST));\r
+        pCurr->pldd = HeapAlloc(heap, 0, sizeof(LOGDISKDESC_S));\r
+        pCurr->next = NULL;\r
+        pCurrLDD = pCurr->pldd;\r
+    }\r
+    else\r
+    {\r
+        pCurrLDD = pCurr->pldd;\r
+        HeapFree(heap, 0, pCurrLDD->pszPath);\r
+        HeapFree(heap, 0, pCurrLDD->pszVolLabel);\r
+        HeapFree(heap, 0, pCurrLDD->pszDiskName);\r
+    }\r
+\r
+    memcpy(pCurrLDD, pldd, sizeof(LOGDISKDESC_S));\r
+\r
+    if (pldd->pszPath)\r
+    {\r
+        pCurrLDD->pszPath = HeapAlloc( heap, 0, strlen(pldd->pszPath)+1 );\r
+        strcpy( pCurrLDD->pszPath, pldd->pszPath );\r
+    }\r
+    if (pldd->pszVolLabel)\r
+    {\r
+        pCurrLDD->pszVolLabel = HeapAlloc( heap, 0, strlen(pldd->pszVolLabel)+1 );\r
+        strcpy( pCurrLDD->pszVolLabel, pldd->pszVolLabel );\r
+    }\r
+    if (pldd->pszDiskName)\r
+    {\r
+        pCurrLDD->pszDiskName = HeapAlloc( heap, 0, strlen(pldd->pszDiskName)+1 );\r
+        strcpy( pCurrLDD->pszDiskName, pldd->pszDiskName );\r
+    }\r
+\r
+    if (is_new) /* link into list */\r
+    {\r
+        if (pPrev)\r
+       {\r
+           pCurr->next = pPrev->next;\r
+            pPrev->next = pCurr;\r
+       }\r
+       if (!pFirstLDD)\r
+           pFirstLDD = pCurr;\r
+    }\r
+\r
+    return OK;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * CtlAddLdd           (SETUPX.36)\r
+ *\r
+ * doesn't check pldd ptr validity: crash (W98SE)\r
+ *\r
+ */\r
+static LOGDISKID16 ldid_to_add = LDID_ASSIGN_START;\r
+RETERR16 WINAPI CtlAddLdd16(LPLOGDISKDESC pldd)\r
+{\r
+    pldd->ldid = ldid_to_add++;\r
+    return CtlSetLdd16(pldd);\r
+}\r
+\r
+/***********************************************************************\r
+ * CtlGetLdd           (SETUPX.34)\r
+ *\r
+ * doesn't check pldd ptr validity: crash (W98SE)\r
+ * What the !@#$%&*( is the difference between CtlFindLdd() and CtlGetLdd() ??\r
+ *\r
+ * RETURN\r
+ *   ERR_VCP_LDDINVALID if pldd->cbSize != structsize\r
+ *\r
+ */\r
+static RETERR16 SETUPX_GetLdd(LPLOGDISKDESC pldd)\r
+{\r
+    LDD_LIST *pCurr, *pPrev = NULL;\r
+\r
+    if (!std_LDDs_done)\r
+       SETUPX_CreateStandardLDDs();\r
+\r
+    if (pldd->cbSize != sizeof(LOGDISKDESC_S))\r
+        return ERR_VCP_LDDINVALID;\r
+\r
+    pCurr = pFirstLDD;\r
+    /* search until we find the appropriate LDD or hit the end */\r
+    while ((pCurr != NULL) && (pldd->ldid > pCurr->pldd->ldid))\r
+    {\r
+        pPrev = pCurr;\r
+        pCurr = pCurr->next;\r
+    }\r
+    if (pCurr == NULL) /* hit end of list */\r
+       return ERR_VCP_LDDFIND; /* correct ? */\r
+\r
+    memcpy(pldd, pCurr->pldd, pldd->cbSize);\r
+    /* hmm, we probably ought to strcpy() the string ptrs here */\r
+\r
+    return OK;\r
+}\r
+\r
+/**********************************************************************/\r
+\r
+RETERR16 WINAPI CtlGetLdd16(LPLOGDISKDESC pldd)\r
+{\r
+    FIXME("(%p); - please report this!\n", pldd);\r
+    return SETUPX_GetLdd(pldd);\r
+}\r
+\r
+/***********************************************************************\r
+ *             CtlGetLddPath           (SETUPX.38)\r
+ *\r
+ * Gets the path of an LDD.\r
+ * No crash if szPath == NULL.\r
+ * szPath has to be at least MAX_PATH_LEN bytes long.\r
+ * RETURN\r
+ *   ERR_VCP_LDDUNINIT if LDD for LDID not found.\r
+ */\r
+RETERR16 WINAPI CtlGetLddPath16(LOGDISKID16 ldid, LPSTR szPath)\r
+{\r
+    TRACE("(%d, %p);\n", ldid, szPath);\r
+\r
+    if (szPath)\r
+    {\r
+       LOGDISKDESC_S ldd;\r
+       INIT_LDD(ldd, ldid);\r
+       if (CtlFindLdd16(&ldd) == ERR_VCP_LDDFIND)\r
+           return ERR_VCP_LDDUNINIT;\r
+       SETUPX_GetLdd(&ldd);\r
+        strcpy(szPath, ldd.pszPath);\r
+       TRACE("ret '%s' for LDID %d\n", szPath, ldid);\r
+    }\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             CtlSetLddPath           (SETUPX.508)\r
+ *\r
+ * Sets the path of an LDD.\r
+ * Creates LDD for LDID if not existing yet.\r
+ */\r
+RETERR16 WINAPI CtlSetLddPath16(LOGDISKID16 ldid, LPSTR szPath)\r
+{\r
+    LOGDISKDESC_S ldd;\r
+    TRACE("(%d, '%s');\n", ldid, szPath);\r
+\r
+    SetupSetDirectoryIdA( 0, ldid, szPath );\r
+    INIT_LDD(ldd, ldid);\r
+    ldd.pszPath = szPath;\r
+    return CtlSetLdd16(&ldd);\r
+}\r
index f0ab6e2..fa0cbd8 100644 (file)
-/*
- * SetupAPI stubs
- *
- * Copyright 2000 James Hatheway
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdarg.h>
-
-#include "wine/debug.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "setupapi.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-/***********************************************************************
- *             TPWriteProfileString (SETUPX.62)
- */
-BOOL WINAPI TPWriteProfileString16( LPCSTR section, LPCSTR entry, LPCSTR string )
-{
-    FIXME( "%s %s %s: stub\n", debugstr_a(section), debugstr_a(entry), debugstr_a(string) );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *             suErrorToIds  (SETUPX.61)
- */
-DWORD WINAPI suErrorToIds16( WORD w1, WORD w2 )
-{
-    FIXME( "%x %x: stub\n", w1, w2 );
-    return 0;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInfoListDetailA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailA(HDEVINFO devinfo, PSP_DEVINFO_LIST_DETAIL_DATA_A devinfo_data )
-{
-  FIXME("\n");
-  return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInfoListDetailW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailW(HDEVINFO devinfo, PSP_DEVINFO_LIST_DETAIL_DATA_W devinfo_data )
-{
-  FIXME("\n");
-  return FALSE;
-}
-
-/***********************************************************************
- *               (SETUPAPI.@)
- *
- * NO WINAPI in description given
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExA(const GUID *class, PCSTR filter, HWND parent, DWORD flags, HDEVINFO deviceset, PCSTR machine, PVOID reserved)
-{
-  FIXME("filter %s machine %s\n",debugstr_a(filter),debugstr_a(machine));
-  return FALSE;
-}
-
-/***********************************************************************
- *               (SETUPAPI.@)
- *
- * NO WINAPI in description given
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExW(const GUID *class, PCWSTR filter, HWND parent, DWORD flags, HDEVINFO deviceset, PCWSTR machine, PVOID reserved)
-{
-  FIXME("\n");
-  return FALSE;
-}
-
-
-/***********************************************************************
- *             SetupCopyOEMInfA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupCopyOEMInfA(PCSTR sourceinffile, PCSTR sourcemedialoc,
-                           DWORD mediatype, DWORD copystyle, PSTR destinfname,
-                           DWORD destnamesize, PDWORD required,
-                           PSTR *destinfnamecomponent)
-{
-  FIXME("stub: source %s location %s ...\n",sourceinffile, sourcemedialoc);
-  return FALSE;
-}
-
-/***********************************************************************
- *             SetupGetInfInformationA    (SETUPAPI.@)
- */
-BOOL WINAPI SetupGetInfInformationA( LPCVOID InfSpec, DWORD SearchControl,
-                                     PSP_INF_INFORMATION ReturnBuffer,
-                                     DWORD ReturnBufferSize, PDWORD RequiredSize)
-{
-    FIXME("(%p, %ld, %p, %ld, %p) Stub!\n",
-          InfSpec, SearchControl, ReturnBuffer, ReturnBufferSize, RequiredSize );
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupInitializeFileLogW(SETUPAPI.@)
- */
-HANDLE WINAPI SetupInitializeFileLogW(LPWSTR LogFileName, DWORD Flags)
-{
-    FIXME("Stub %s, 0x%lx\n",debugstr_w(LogFileName),Flags);
-    return INVALID_HANDLE_VALUE;
-}
-
-/***********************************************************************
- *             SetupInitializeFileLogA(SETUPAPI.@)
- */
-HANDLE WINAPI SetupInitializeFileLogA(LPSTR LogFileName, DWORD Flags)
-{
-    FIXME("Stub %s, 0x%lx\n",debugstr_a(LogFileName),Flags);
-    return INVALID_HANDLE_VALUE;
-}
-
-/***********************************************************************
- *             SetupTerminateFileLog(SETUPAPI.@)
- */
-BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle)
-{
-    FIXME ("Stub %p\n",FileLogHandle);
-    return TRUE;
-}
+/*\r
+ * SetupAPI stubs\r
+ *\r
+ * Copyright 2000 James Hatheway\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include <stdarg.h>\r
+\r
+#include "wine/debug.h"\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "wingdi.h"\r
+#include "winuser.h"\r
+#include "winnls.h"\r
+#include "winreg.h"\r
+#include "setupapi.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+/***********************************************************************\r
+ *             TPWriteProfileString (SETUPX.62)\r
+ */\r
+BOOL WINAPI TPWriteProfileString16( LPCSTR section, LPCSTR entry, LPCSTR string )\r
+{\r
+    FIXME( "%s %s %s: stub\n", debugstr_a(section), debugstr_a(entry), debugstr_a(string) );\r
+    return TRUE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             suErrorToIds  (SETUPX.61)\r
+ */\r
+DWORD WINAPI suErrorToIds16( WORD w1, WORD w2 )\r
+{\r
+    FIXME( "%x %x: stub\n", w1, w2 );\r
+    return 0;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceInfoListDetailA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceInfoListDetailA(HDEVINFO devinfo, PSP_DEVINFO_LIST_DETAIL_DATA_A devinfo_data )\r
+{\r
+  FIXME("\n");\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupDiGetDeviceInfoListDetailW  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupDiGetDeviceInfoListDetailW(HDEVINFO devinfo, PSP_DEVINFO_LIST_DETAIL_DATA_W devinfo_data )\r
+{\r
+  FIXME("\n");\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *               (SETUPAPI.@)\r
+ *\r
+ * NO WINAPI in description given\r
+ */\r
+HDEVINFO WINAPI SetupDiGetClassDevsExA(const GUID *class, PCSTR filter, HWND parent, DWORD flags, HDEVINFO deviceset, PCSTR machine, PVOID reserved)\r
+{\r
+  FIXME("filter %s machine %s\n",debugstr_a(filter),debugstr_a(machine));\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *               (SETUPAPI.@)\r
+ *\r
+ * NO WINAPI in description given\r
+ */\r
+HDEVINFO WINAPI SetupDiGetClassDevsExW(const GUID *class, PCWSTR filter, HWND parent, DWORD flags, HDEVINFO deviceset, PCWSTR machine, PVOID reserved)\r
+{\r
+  FIXME("\n");\r
+  return FALSE;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ *             SetupCopyOEMInfA  (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupCopyOEMInfA(PCSTR sourceinffile, PCSTR sourcemedialoc,\r
+                           DWORD mediatype, DWORD copystyle, PSTR destinfname,\r
+                           DWORD destnamesize, PDWORD required,\r
+                           PSTR *destinfnamecomponent)\r
+{\r
+  FIXME("stub: source %s location %s ...\n",sourceinffile, sourcemedialoc);\r
+  return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupGetInfInformationA    (SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupGetInfInformationA( LPCVOID InfSpec, DWORD SearchControl,\r
+                                     PSP_INF_INFORMATION ReturnBuffer,\r
+                                     DWORD ReturnBufferSize, PDWORD RequiredSize)\r
+{\r
+    FIXME("(%p, %ld, %p, %ld, %p) Stub!\n",\r
+          InfSpec, SearchControl, ReturnBuffer, ReturnBufferSize, RequiredSize );\r
+    return TRUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupInitializeFileLogW(SETUPAPI.@)\r
+ */\r
+HANDLE WINAPI SetupInitializeFileLogW(LPWSTR LogFileName, DWORD Flags)\r
+{\r
+    FIXME("Stub %s, 0x%lx\n",debugstr_w(LogFileName),Flags);\r
+    return INVALID_HANDLE_VALUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupInitializeFileLogA(SETUPAPI.@)\r
+ */\r
+HANDLE WINAPI SetupInitializeFileLogA(LPSTR LogFileName, DWORD Flags)\r
+{\r
+    FIXME("Stub %s, 0x%lx\n",debugstr_a(LogFileName),Flags);\r
+    return INVALID_HANDLE_VALUE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             SetupTerminateFileLog(SETUPAPI.@)\r
+ */\r
+BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle)\r
+{\r
+    FIXME ("Stub %p\n",FileLogHandle);\r
+    return TRUE;\r
+}\r
index 8ffbfdd..b21692e 100644 (file)
-/*
- * SetupAPI virtual copy operations
- *
- * Copyright 2001 Andreas Mohr
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * FIXME: we now rely on builtin setupapi.dll for dialog resources.
- *        This is bad ! We ought to have 16bit resource handling working.
- */
-
-#include <stdarg.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "wownt32.h"
-#include "wingdi.h"
-#include "winnls.h"
-#include "setupapi.h"
-#include "setupx16.h"
-#include "setupapi_private.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
-
-static FARPROC16 VCP_Proc = NULL;
-static LPARAM VCP_MsgRef = 0;
-
-static BOOL VCP_opened = FALSE;
-
-static VCPSTATUS vcp_status;
-
-static HINSTANCE SETUPAPI_hInstance;
-
-static WORD VCP_Callback( LPVOID obj, UINT16 msg, WPARAM16 wParam, LPARAM lParam, LPARAM lParamRef )
-{
-    WORD args[8];
-    DWORD ret = OK;
-    if (VCP_Proc)
-    {
-        args[7] = HIWORD(obj);
-        args[6] = LOWORD(obj);
-        args[5] = msg;
-        args[4] = wParam;
-        args[3] = HIWORD(lParam);
-        args[2] = LOWORD(lParam);
-        args[1] = HIWORD(lParamRef);
-        args[0] = LOWORD(lParamRef);
-        WOWCallback16Ex( (DWORD)VCP_Proc, WCB16_PASCAL, sizeof(args), args, &ret );
-    }
-    return (WORD)ret;
-}
-
-/****************************** VHSTR management ******************************/
-
-/*
- * This is a totally braindead implementation for now;
- * I don't care about speed at all ! Size and implementation time
- * is much more important IMHO. I could have created some sophisticated
- * tree structure, but... what the hell ! :-)
- */
-typedef struct {
-    DWORD refcount;
-    LPCSTR pStr;
-} VHSTR_STRUCT;
-
-static VHSTR_STRUCT **vhstrlist = NULL;
-static VHSTR vhstr_alloc = 0;
-
-#define VALID_VHSTR(x)         ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))
-
-/***********************************************************************
- *             vsmStringAdd (SETUPX.207)
- */
-VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)
-{
-    VHSTR n;
-    VHSTR index = 0xffff;
-    HANDLE heap;
-
-    TRACE("add string '%s'\n", lpszName);
-    /* search whether string already inserted */
-    TRACE("searching for existing string...\n");
-    for (n = 0; n < vhstr_alloc; n++)
-    {
-       if ((vhstrlist[n]) && (vhstrlist[n]->refcount))
-       {
-               TRACE("checking item: %d\n", n);
-           if (!strcmp(vhstrlist[n]->pStr, lpszName))
-           {
-               TRACE("found\n");
-               vhstrlist[n]->refcount++;
-               return n;
-           }
-       }
-    }
-
-    /* hmm, not found yet, let's insert it */
-    TRACE("inserting item\n");
-    for (n = 0; n < vhstr_alloc; n++)
-    {
-       if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))
-       {
-           index = n;
-           break;
-       }
-    }
-    heap = GetProcessHeap();
-    if (n == vhstr_alloc) /* hmm, no free index found yet */
-    {
-       index = vhstr_alloc;
-       vhstr_alloc += 20;
-
-       if (vhstrlist)
-           vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,
-                                       sizeof(VHSTR_STRUCT *) * vhstr_alloc);
-       else
-           vhstrlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,
-                                       sizeof(VHSTR_STRUCT *) * vhstr_alloc);
-    }
-    if (index == 0xffff)
-       return 0xffff; /* failure */
-    if (!vhstrlist[index])
-       vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));
-    vhstrlist[index]->refcount = 1;
-    vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);
-    strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);
-    return index;
-}
-
-/***********************************************************************
- *             vsmStringDelete (SETUPX.206)
- */
-INT16 WINAPI vsmStringDelete16(VHSTR vhstr)
-{
-    if (VALID_VHSTR(vhstr))
-    {
-       vhstrlist[vhstr]->refcount--;
-       if (!vhstrlist[vhstr]->refcount)
-       {
-           HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);
-           vhstrlist[vhstr]->pStr = NULL;
-       }
-       return VCPN_OK;
-    }
-
-    /* string not found */
-    return VCPN_FAIL;
-}
-
-/*
- * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems
- */
-VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)
-{
-    WORD n;
-    for (n = 0; n < vhstr_alloc; n++)
-       if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))
-           return n;
-    return 0xffff;
-}
-
-/***********************************************************************
- *             vsmGetStringName (SETUPX.205)
- *
- * Pretty correct, I guess
- */
-INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)
-{
-    if (VALID_VHSTR(vhstr))
-    {
-       int len = strlen(vhstrlist[vhstr]->pStr)+1;
-       if (cbBuffer >= len)
-       {
-           if (lpszBuffer)
-               strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);
-           return len;
-       }
-    }
-    return VCPN_FAIL;
-}
-
-/***********************************************************************
- *             vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)
- */
-INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)
-{
-    if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))
-       return VCPN_FAIL; /* correct ? */
-    return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);
-}
-
-/***********************************************************************
- *             vsmGetStringRawName (SETUPX.208)
- */
-LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)
-{
-    return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;
-}
-
-
-/***************************** VIRTNODE management ****************************/
-static LPVIRTNODE *pvnlist = NULL;
-static DWORD vn_num = 0;
-static DWORD vn_last = 0;
-
-RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)
-{
-    HANDLE heap;
-    LPVIRTNODE lpvn;
-    RETERR16 cbres;
-
-    while (vn_last < vn_num)
-    {
-       if (pvnlist[vn_last] == NULL)
-           break;
-       vn_last++;
-    }
-    heap = GetProcessHeap();
-    if (vn_last == vn_num)
-    {
-       vn_num += 20;
-       if (pvnlist)
-           pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,
-                               sizeof(LPVIRTNODE *) * vn_num);
-       else
-           pvnlist = HeapAlloc(heap, HEAP_ZERO_MEMORY, 
-                               sizeof(LPVIRTNODE *) * vn_num);
-    }
-    pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));
-    lpvn = pvnlist[vn_last];
-    vn_last++;
-
-    lpvn->cbSize = sizeof(VIRTNODE);
-
-    if (vfsSrc)
-        memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));
-
-    if (vfsDst)
-        memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));
-
-    lpvn->fl = fl;
-    lpvn->lParam = lParam;
-    lpvn->lpExpandVtbl = lpExpandVtbl;
-
-    lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */
-
-    cbres = VCP_Callback(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);
-    lpvn->fl |= VFNL_CREATED;
-    cbres = VCP_Callback(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);
-
-    return OK;
-}
-
-BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)
-{
-    DWORD n;
-    RETERR16 cbres;
-
-    for (n = 0; n < vn_last; n++)
-    {
-       if (pvnlist[n] == lpvnDel)
-       {
-           cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);
-           HeapFree(GetProcessHeap(), 0, lpvnDel);
-           pvnlist[n] = NULL;
-           return TRUE;
-       }
-    }
-    return FALSE;
-}
-
-/***********************************************************************
- *             VcpOpen (SETUPX.200)
- *
- * Sets up a virtual copy operation.
- * This means that functions such as GenInstall()
- * create a VIRTNODE struct for every file to be touched in a .INF file
- * instead of actually touching the file.
- * The actual copy/move/rename gets started when VcpClose or
- * VcpFlush is called; several different callbacks are made
- * (copy, rename, open, close, version conflicts, ...) on every file copied.
- */
-RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)
-{
-    TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);
-    if (VCP_opened)
-       return ERR_VCP_BUSY;
-
-    VCP_Proc = (FARPROC16)vifproc;
-    VCP_MsgRef = lparamMsgRef;
-
-    /* load SETUPAPI needed for dialog resources etc. */
-    SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");
-    if (!SETUPAPI_hInstance)
-    {
-       ERR("Could not load sibling setupapi.dll\n");
-       return ERR_VCP_NOMEM;
-    }
-    VCP_opened = TRUE;
-    return OK;
-}
-
-/***********************************************************************
- *             VcpQueueCopy            [SETUPX.13]
- *
- * lpExpandVtbl seems to be deprecated.
- * fl are the CNFL_xxx and VNFL_xxx flags.
- * lParam are the VNLP_xxx flags.
- */
-RETERR16 WINAPI VcpQueueCopy16(
-       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
-       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
-       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
-       LPEXPANDVTBL lpExpandVtbl,
-       WORD fl, LPARAM lParam
-)
-{
-    VCPFILESPEC vfsSrc, vfsDst;
-
-    if (!VCP_opened)
-       return ERR_VCP_NOTOPEN;
-
-    TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",
-      lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);
-
-    TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);
-
-    vfsSrc.ldid = ldidSrc;
-    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
-    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
-
-    vfsDst.ldid = ldidDst;
-    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
-    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
-
-    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,
-                   lpExpandVtbl);
-}
-
-/***********************************************************************
- *             VcpQueueDelete          [SETUPX.17]
- *
- * Is lParamRef the same as lParam in VcpQueueCopy ?
- * Damn docu !! Err... which docu ?
- */
-RETERR16 WINAPI VcpQueueDelete16(
-       LPCSTR lpszDstFileName,
-       LPCSTR lpszDstDir,
-       LOGDISKID16 ldidDst,
-       LPARAM lParamRef
-)
-{
-    VCPFILESPEC vfsDst;
-
-    if (!VCP_opened)
-       return ERR_VCP_NOTOPEN;
-
-    vfsDst.ldid = ldidDst;
-    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
-    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
-
-    return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);
-}
-
-/***********************************************************************
- *             VcpQueueRename          [SETUPX.204]
- *
- */
-RETERR16 WINAPI VcpQueueRename16(
-       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,
-       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,
-       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,
-       LPARAM lParam
-)
-{
-    VCPFILESPEC vfsSrc, vfsDst;
-
-    if (!VCP_opened)
-       return ERR_VCP_NOTOPEN;
-
-    vfsSrc.ldid = ldidSrc;
-    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);
-    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);
-
-    vfsDst.ldid = ldidDst;
-    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);
-    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);
-
-    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,
-                   0);
-}
-
-/***********************************************************************
- *             VcpEnumFiles (SETUPX.@)
- */
-INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)
-{
-    WORD n;
-
-    for (n = 0; n < vn_last; n++)
-       vep(pvnlist[n], lParamRef);
-
-    return 0; /* FIXME: return value ? */
-}
-
-/***********************************************************************
- *             VcpExplain (SETUPX.411)
- */
-LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)
-{
-    static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */
-    buffer[0] = '\0';
-    switch (dwWhat)
-    {
-       case VCPEX_SRC_FULL:
-       case VCPEX_DST_FULL:
-           {
-               LPVCPFILESPEC lpvfs =
-                   (dwWhat == VCPEX_SRC_FULL) ?  &lpVn->vfsSrc : &lpVn->vfsDst;
-
-                /* if we have an ldid, use it, otherwise use the string */
-                /* from the vhstrlist array */
-               if (lpvfs->ldid != 0xffff)
-                  CtlGetLddPath16(lpvfs->ldid, buffer);
-                else
-                  strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));
-
-                strcat(buffer, "\\");
-                strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));
-           }
-           break;
-       default:
-           FIXME("%ld unimplemented !\n", dwWhat);
-           strcpy(buffer, "Unknown error");
-           break;
-    }
-    return buffer;
-}
-
-RETERR16 VCP_CheckPaths(void)
-{
-    DWORD n;
-    LPVIRTNODE lpvn;
-    RETERR16 cbres;
-
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);
-    for (n = 0; n < vn_num; n++)
-    {
-       lpvn = pvnlist[n];
-       if (!lpvn) continue;
-        /* FIXME: check paths of all VIRTNODEs here ! */
-       cbres = VCP_Callback(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);
-    }
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);
-    return OK;
-}
-
-RETERR16 VCP_CopyFiles(void)
-{
-    char fn_src[MAX_PATH], fn_dst[MAX_PATH];
-    RETERR16 res = OK, cbres;
-    DWORD n;
-    LPVIRTNODE lpvn;
-
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);
-    for (n = 0; n < vn_num; n++)
-    {
-       lpvn = pvnlist[n];
-       if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;
-       /* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */
-        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
-        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
-       /* FIXME: what is this VCPM_VSTATWRITE here for ?
-        * I guess it's to signal successful destination file creation */
-       cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
-
-       /* FIXME: need to do the file copy in small chunks for notifications */
-       TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);
-        /* perform the file copy */
-        if (!(CopyFileA(fn_src, fn_dst,
-              (lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))
-        {
-            ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);
-           res = ERR_VCP_IOFAIL;
-        }
-
-       vcp_status.prgFileRead.dwSoFar++;
-       cbres = VCP_Callback(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);
-       vcp_status.prgFileWrite.dwSoFar++;
-       cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);
-    }
-
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);
-    return res;
-}
-
-/***********************************************************************
- *             VcpFlush - internal (not exported), but documented
- *
- * VNFL_NOW is used for VcpFlush.
- */
-RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)
-{
-    return OK;
-}
-
-/***********************************************************************
- *             VcpClose (SETUPX.201)
- *
- * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,
- * VCPM_VSTATCLOSEEND.
- *
- * fl gets VCPFL_xxx flags to indicate what to do with the
- * VIRTNODEs (files to mess with) created by e.g. GenInstall()
- */
-RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)
-{
-    RETERR16 res = OK;
-    WORD cbres = VCPN_PROCEED;
-
-    TRACE("(%04x, '%s')\n", fl, lpszBackupDest);
-
-    /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER
-     * is not set. This is done by VCP_Callback(VCPM_NODECOMPARE) */
-
-    TRACE("#1\n");
-    memset(&vcp_status, 0, sizeof(VCPSTATUS));
-    /* yes, vcp_status.cbSize is 0 ! */
-    TRACE("#2\n");
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);
-    TRACE("#3\n");
-
-    res = VCP_CheckPaths();
-    TRACE("#4\n");
-    if (res != OK)
-       return res; /* is this ok ? */
-    VCP_CopyFiles();
-
-    TRACE("#5\n");
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);
-    TRACE("#6\n");
-    VCP_Proc = NULL;
-    FreeLibrary(SETUPAPI_hInstance);
-    VCP_opened = FALSE;
-    return OK;
-}
-
-RETERR16 VCP_RenameFiles(void)
-{
-    char fn_src[MAX_PATH], fn_dst[MAX_PATH];
-    RETERR16 res = OK, cbres;
-    DWORD n;
-    LPVIRTNODE lpvn;
-
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);
-    for (n = 0; n < vn_num; n++)
-    {
-       lpvn = pvnlist[n];
-       if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;
-        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));
-        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));
-       cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);
-        if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))
-           res = ERR_VCP_IOFAIL;
-       else
-           VCP_VirtnodeDelete(lpvn);
-    }
-    cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);
-    return res;
-}
-
-/***********************************************************************
- *             vcpDefCallbackProc (SETUPX.202)
- */
-RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
-                                       LPARAM lParam, LPARAM lParamRef)
-{
-    static int count = 0;
-    if (count < 10)
-        FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",
-               lpvObj, uMsg, wParam, lParam, lParamRef);
-    count++;
-    return OK;
-}
-
-/********************* point-and-click stuff from here ***********************/
-
-static HWND hDlgCopy = 0;
-static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;
-static char BackupDir[12];
-
-static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
-{
-    INT_PTR retval = FALSE;
-
-    if (iMsg == WM_INITDIALOG)
-    {
-        ShowWindow(hWndDlg, SW_SHOWNORMAL);
-        UpdateWindow(hWndDlg);
-       retval = TRUE;
-    }
-    return retval;
-}
-
-BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)
-{
-    HRSRC hResInfo;
-    HGLOBAL hDlgTmpl32;
-
-    if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))
-       return FALSE;
-    if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||
-        !(*template32 = LockResource( hDlgTmpl32 )))
-       return FALSE;
-    return TRUE;
-}
-
-static LRESULT WINAPI
-VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-    if (uMsg != WM_CREATE)
-        return DefWindowProcA (hwnd, uMsg, wParam, lParam);
-
-    switch (uMsg)
-    {
-       case WM_CREATE:
-           return 0;
-       default:
-           FIXME("%04x: unhandled.\n", uMsg);
-    }
-
-    return 0;
-}
-
-void VCP_UI_RegisterProgressClass(void)
-{
-    static BOOL registered = FALSE;
-    WNDCLASSA wndClass;
-
-    if (registered)
-       return;
-
-    registered = TRUE;
-    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
-    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
-    wndClass.lpfnWndProc   = VCP_UI_FileCopyWndProc;
-    wndClass.cbClsExtra    = 0;
-    wndClass.cbWndExtra    = 0;
-    wndClass.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROW);
-    wndClass.hbrBackground = NULL;
-    wndClass.lpszClassName = "setupx_progress";
-
-    RegisterClassA (&wndClass);
-}
-
-RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)
-{
-    LPCSTR file1, file2;
-    file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);
-    file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);
-    return (RETERR16)strcmp(file1, file2);
-}
-
-RETERR16 VCP_UI_CopyStart(void)
-{
-    LPCVOID template32;
-    char buf[256]; /* plenty */
-    BOOL dirty;
-    DWORD len;
-
-    /* FIXME: should be registered at DLL startup instead */
-    VCP_UI_RegisterProgressClass();
-    if (!(VCP_UI_GetDialogTemplate(&template32)))
-       return VCPN_FAIL;
-
-    if (vn_num > 10)  /* hack */
-    {
-        hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,
-                                              VCP_UI_FileCopyDlgProc, 0);
-        if (!hDlgCopy)
-            return VCPN_FAIL;
-        SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");
-        SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");
-    }
-    strcpy(buf, REG_INSTALLEDFILES);
-    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))
-       return VCPN_FAIL;
-    strcat(buf, REGPART_RENAME);
-    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))
-       return VCPN_FAIL;
-    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))
-       return VCPN_FAIL;
-    len = 1;
-    if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))
-    {
-       /* FIXME: what does SETUPX.DLL do in this case ? */
-       MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");
-       return VCPN_FAIL;
-    }
-    dirty = TRUE;
-    if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))
-       return VCPN_FAIL;
-    len = 12;
-    if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))
-       strcpy(BackupDir, "VCM");
-
-    /* create C:\WINDOWS\[BackupDir] and set registry key to it */
-    GetWindowsDirectoryA(buf, 256);
-    strcat(buf, "\\");
-    strcat(buf, BackupDir);
-    if (!(CreateDirectoryA(buf, NULL)))
-       return VCPN_FAIL;
-    if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))
-       return VCPN_FAIL;
-    RegCloseKey(hKeyConflict);
-
-    return VCPN_OK;
-}
-
-/***********************************************************************
- *             vcpUICallbackProc (SETUPX.213)
- */
-RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,
-                                       LPARAM lParam, LPARAM lParamRef)
-{
-    static int count = 0;
-    RETERR16 res = VCPN_OK, cbres;
-
-    if (count < 5)
-        FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",
-               lpvObj, uMsg, wParam, lParam, lParamRef);
-    count++;
-    switch (uMsg)
-    {
-       /* unused messages, it seems */
-       case VCPM_DISKPREPINFO:
-
-       case VCPM_FILENEEDED:
-
-       case VCPM_NODECREATE:
-       case VCPM_NODEACCEPT:
-
-       case VCPM_VSTATCLOSESTART:
-       case VCPM_VSTATPATHCHECKSTART:
-       case VCPM_VSTATPATHCHECKEND:
-
-       case VCPM_CHECKPATH:
-           break;
-
-       /* the real stuff */
-       case VCPM_NODECOMPARE:
-           res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);
-           break;
-       case VCPM_VSTATREAD:
-           break;
-       case VCPM_VSTATWRITE:
-           cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);
-           break;
-       case VCPM_VSTATCLOSEEND:
-           RegCloseKey(hKeyFiles);
-           RegCloseKey(hKeyRename);
-           RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);
-           break;
-       case VCPM_VSTATCOPYSTART:
-           res = VCP_UI_CopyStart();
-           break;
-       case VCPM_VSTATCOPYEND:
-           if (hDlgCopy) DestroyWindow(hDlgCopy);
-           break;
-       default:
-           FIXME("unhandled msg 0x%04x\n", uMsg);
-    }
-    return res;
-}
+/*\r
+ * SetupAPI virtual copy operations\r
+ *\r
+ * Copyright 2001 Andreas Mohr\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * FIXME: we now rely on builtin setupapi.dll for dialog resources.\r
+ *        This is bad ! We ought to have 16bit resource handling working.\r
+ */\r
+\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include "windef.h"\r
+#include "winbase.h"\r
+#include "winuser.h"\r
+#include "winreg.h"\r
+#include "wownt32.h"\r
+#include "wingdi.h"\r
+#include "winnls.h"\r
+#include "setupapi.h"\r
+#include "setupx16.h"\r
+#include "setupapi_private.h"\r
+#include "wine/debug.h"\r
+\r
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);\r
+\r
+static FARPROC16 VCP_Proc = NULL;\r
+static LPARAM VCP_MsgRef = 0;\r
+\r
+static BOOL VCP_opened = FALSE;\r
+\r
+static VCPSTATUS vcp_status;\r
+\r
+static HINSTANCE SETUPAPI_hInstance;\r
+\r
+static WORD VCP_Callback( LPVOID obj, UINT16 msg, WPARAM16 wParam, LPARAM lParam, LPARAM lParamRef )\r
+{\r
+    WORD args[8];\r
+    DWORD ret = OK;\r
+    if (VCP_Proc)\r
+    {\r
+        args[7] = HIWORD(obj);\r
+        args[6] = LOWORD(obj);\r
+        args[5] = msg;\r
+        args[4] = wParam;\r
+        args[3] = HIWORD(lParam);\r
+        args[2] = LOWORD(lParam);\r
+        args[1] = HIWORD(lParamRef);\r
+        args[0] = LOWORD(lParamRef);\r
+        WOWCallback16Ex( (DWORD)VCP_Proc, WCB16_PASCAL, sizeof(args), args, &ret );\r
+    }\r
+    return (WORD)ret;\r
+}\r
+\r
+/****************************** VHSTR management ******************************/\r
+\r
+/*\r
+ * This is a totally braindead implementation for now;\r
+ * I don't care about speed at all ! Size and implementation time\r
+ * is much more important IMHO. I could have created some sophisticated\r
+ * tree structure, but... what the hell ! :-)\r
+ */\r
+typedef struct {\r
+    DWORD refcount;\r
+    LPCSTR pStr;\r
+} VHSTR_STRUCT;\r
+\r
+static VHSTR_STRUCT **vhstrlist = NULL;\r
+static VHSTR vhstr_alloc = 0;\r
+\r
+#define VALID_VHSTR(x)         ((x < vhstr_alloc) && (vhstrlist[x]) && (vhstrlist[x]->refcount))\r
+\r
+/***********************************************************************\r
+ *             vsmStringAdd (SETUPX.207)\r
+ */\r
+VHSTR WINAPI vsmStringAdd16(LPCSTR lpszName)\r
+{\r
+    VHSTR n;\r
+    VHSTR index = 0xffff;\r
+    HANDLE heap;\r
+\r
+    TRACE("add string '%s'\n", lpszName);\r
+    /* search whether string already inserted */\r
+    TRACE("searching for existing string...\n");\r
+    for (n = 0; n < vhstr_alloc; n++)\r
+    {\r
+       if ((vhstrlist[n]) && (vhstrlist[n]->refcount))\r
+       {\r
+               TRACE("checking item: %d\n", n);\r
+           if (!strcmp(vhstrlist[n]->pStr, lpszName))\r
+           {\r
+               TRACE("found\n");\r
+               vhstrlist[n]->refcount++;\r
+               return n;\r
+           }\r
+       }\r
+    }\r
+\r
+    /* hmm, not found yet, let's insert it */\r
+    TRACE("inserting item\n");\r
+    for (n = 0; n < vhstr_alloc; n++)\r
+    {\r
+       if ((!(vhstrlist[n])) || (!(vhstrlist[n]->refcount)))\r
+       {\r
+           index = n;\r
+           break;\r
+       }\r
+    }\r
+    heap = GetProcessHeap();\r
+    if (n == vhstr_alloc) /* hmm, no free index found yet */\r
+    {\r
+       index = vhstr_alloc;\r
+       vhstr_alloc += 20;\r
+\r
+       if (vhstrlist)\r
+           vhstrlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, vhstrlist,\r
+                                       sizeof(VHSTR_STRUCT *) * vhstr_alloc);\r
+       else\r
+           vhstrlist = HeapAlloc(heap, HEAP_ZERO_MEMORY,\r
+                                       sizeof(VHSTR_STRUCT *) * vhstr_alloc);\r
+    }\r
+    if (index == 0xffff)\r
+       return 0xffff; /* failure */\r
+    if (!vhstrlist[index])\r
+       vhstrlist[index] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VHSTR_STRUCT));\r
+    vhstrlist[index]->refcount = 1;\r
+    vhstrlist[index]->pStr = HeapAlloc(heap, 0, strlen(lpszName)+1);\r
+    strcpy((LPSTR)vhstrlist[index]->pStr, lpszName);\r
+    return index;\r
+}\r
+\r
+/***********************************************************************\r
+ *             vsmStringDelete (SETUPX.206)\r
+ */\r
+INT16 WINAPI vsmStringDelete16(VHSTR vhstr)\r
+{\r
+    if (VALID_VHSTR(vhstr))\r
+    {\r
+       vhstrlist[vhstr]->refcount--;\r
+       if (!vhstrlist[vhstr]->refcount)\r
+       {\r
+           HeapFree(GetProcessHeap(), 0, (LPSTR)vhstrlist[vhstr]->pStr);\r
+           vhstrlist[vhstr]->pStr = NULL;\r
+       }\r
+       return VCPN_OK;\r
+    }\r
+\r
+    /* string not found */\r
+    return VCPN_FAIL;\r
+}\r
+\r
+/*\r
+ * vsmStringFind() - not exported from a standard SETUPX.DLL, it seems\r
+ */\r
+VHSTR WINAPI vsmStringFind16(LPCSTR lpszName)\r
+{\r
+    WORD n;\r
+    for (n = 0; n < vhstr_alloc; n++)\r
+       if ((vhstrlist[n]) && (vhstrlist[n]->refcount) && (!strcmp(vhstrlist[n]->pStr, lpszName)))\r
+           return n;\r
+    return 0xffff;\r
+}\r
+\r
+/***********************************************************************\r
+ *             vsmGetStringName (SETUPX.205)\r
+ *\r
+ * Pretty correct, I guess\r
+ */\r
+INT16 WINAPI vsmGetStringName16(VHSTR vhstr, LPSTR lpszBuffer, int cbBuffer)\r
+{\r
+    if (VALID_VHSTR(vhstr))\r
+    {\r
+       int len = strlen(vhstrlist[vhstr]->pStr)+1;\r
+       if (cbBuffer >= len)\r
+       {\r
+           if (lpszBuffer)\r
+               strcpy(lpszBuffer, vhstrlist[vhstr]->pStr);\r
+           return len;\r
+       }\r
+    }\r
+    return VCPN_FAIL;\r
+}\r
+\r
+/***********************************************************************\r
+ *             vsmStringCompare (not exported from a standard SETUPX.DLL, it seems)\r
+ */\r
+INT16 WINAPI vsmStringCompare16(VHSTR vhstrA, VHSTR vhstrB)\r
+{\r
+    if ((!VALID_VHSTR(vhstrA)) || (!VALID_VHSTR(vhstrB)))\r
+       return VCPN_FAIL; /* correct ? */\r
+    return strcmp(vhstrlist[vhstrA]->pStr, vhstrlist[vhstrB]->pStr);\r
+}\r
+\r
+/***********************************************************************\r
+ *             vsmGetStringRawName (SETUPX.208)\r
+ */\r
+LPCSTR WINAPI vsmGetStringRawName16(VHSTR vhstr)\r
+{\r
+    return (VALID_VHSTR(vhstr)) ? vhstrlist[vhstr]->pStr : NULL;\r
+}\r
+\r
+\r
+/***************************** VIRTNODE management ****************************/\r
+static LPVIRTNODE *pvnlist = NULL;\r
+static DWORD vn_num = 0;\r
+static DWORD vn_last = 0;\r
+\r
+RETERR16 VCP_VirtnodeCreate(LPVCPFILESPEC vfsSrc, LPVCPFILESPEC vfsDst, WORD fl, LPARAM lParam, LPEXPANDVTBL lpExpandVtbl)\r
+{\r
+    HANDLE heap;\r
+    LPVIRTNODE lpvn;\r
+    RETERR16 cbres;\r
+\r
+    while (vn_last < vn_num)\r
+    {\r
+       if (pvnlist[vn_last] == NULL)\r
+           break;\r
+       vn_last++;\r
+    }\r
+    heap = GetProcessHeap();\r
+    if (vn_last == vn_num)\r
+    {\r
+       vn_num += 20;\r
+       if (pvnlist)\r
+           pvnlist = HeapReAlloc(heap, HEAP_ZERO_MEMORY, pvnlist,\r
+                               sizeof(LPVIRTNODE *) * vn_num);\r
+       else\r
+           pvnlist = HeapAlloc(heap, HEAP_ZERO_MEMORY, \r
+                               sizeof(LPVIRTNODE *) * vn_num);\r
+    }\r
+    pvnlist[vn_last] = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(VIRTNODE));\r
+    lpvn = pvnlist[vn_last];\r
+    vn_last++;\r
+\r
+    lpvn->cbSize = sizeof(VIRTNODE);\r
+\r
+    if (vfsSrc)\r
+        memcpy(&lpvn->vfsSrc, vfsSrc, sizeof(VCPFILESPEC));\r
+\r
+    if (vfsDst)\r
+        memcpy(&lpvn->vfsDst, vfsDst, sizeof(VCPFILESPEC));\r
+\r
+    lpvn->fl = fl;\r
+    lpvn->lParam = lParam;\r
+    lpvn->lpExpandVtbl = lpExpandVtbl;\r
+\r
+    lpvn->vhstrDstFinalName = 0xffff; /* FIXME: what is this ? */\r
+\r
+    cbres = VCP_Callback(lpvn, VCPM_NODECREATE, 0, 0, VCP_MsgRef);\r
+    lpvn->fl |= VFNL_CREATED;\r
+    cbres = VCP_Callback(lpvn, VCPM_NODEACCEPT, 0, 0, VCP_MsgRef);\r
+\r
+    return OK;\r
+}\r
+\r
+BOOL VCP_VirtnodeDelete(LPVIRTNODE lpvnDel)\r
+{\r
+    DWORD n;\r
+    RETERR16 cbres;\r
+\r
+    for (n = 0; n < vn_last; n++)\r
+    {\r
+       if (pvnlist[n] == lpvnDel)\r
+       {\r
+           cbres = VCP_Callback(lpvnDel, VCPM_NODEDESTROY, 0, 0, VCP_MsgRef);\r
+           HeapFree(GetProcessHeap(), 0, lpvnDel);\r
+           pvnlist[n] = NULL;\r
+           return TRUE;\r
+       }\r
+    }\r
+    return FALSE;\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpOpen (SETUPX.200)\r
+ *\r
+ * Sets up a virtual copy operation.\r
+ * This means that functions such as GenInstall()\r
+ * create a VIRTNODE struct for every file to be touched in a .INF file\r
+ * instead of actually touching the file.\r
+ * The actual copy/move/rename gets started when VcpClose or\r
+ * VcpFlush is called; several different callbacks are made\r
+ * (copy, rename, open, close, version conflicts, ...) on every file copied.\r
+ */\r
+RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)\r
+{\r
+    TRACE("(%p, %08lx)\n", vifproc, lparamMsgRef);\r
+    if (VCP_opened)\r
+       return ERR_VCP_BUSY;\r
+\r
+    VCP_Proc = (FARPROC16)vifproc;\r
+    VCP_MsgRef = lparamMsgRef;\r
+\r
+    /* load SETUPAPI needed for dialog resources etc. */\r
+    SETUPAPI_hInstance = LoadLibraryA("setupapi.dll");\r
+    if (!SETUPAPI_hInstance)\r
+    {\r
+       ERR("Could not load sibling setupapi.dll\n");\r
+       return ERR_VCP_NOMEM;\r
+    }\r
+    VCP_opened = TRUE;\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpQueueCopy            [SETUPX.13]\r
+ *\r
+ * lpExpandVtbl seems to be deprecated.\r
+ * fl are the CNFL_xxx and VNFL_xxx flags.\r
+ * lParam are the VNLP_xxx flags.\r
+ */\r
+RETERR16 WINAPI VcpQueueCopy16(\r
+       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,\r
+       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,\r
+       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,\r
+       LPEXPANDVTBL lpExpandVtbl,\r
+       WORD fl, LPARAM lParam\r
+)\r
+{\r
+    VCPFILESPEC vfsSrc, vfsDst;\r
+\r
+    if (!VCP_opened)\r
+       return ERR_VCP_NOTOPEN;\r
+\r
+    TRACE("srcdir: %s, srcfile: %s, dstdir: %s, dstfile: %s\n",\r
+      lpszSrcDir, lpszSrcFileName, lpszDstDir, lpszDstFileName);\r
+\r
+    TRACE("ldidSrc == %d, ldidDst == %d\n", ldidSrc, ldidDst);\r
+\r
+    vfsSrc.ldid = ldidSrc;\r
+    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);\r
+    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);\r
+\r
+    vfsDst.ldid = ldidDst;\r
+    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);\r
+    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);\r
+\r
+    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, fl, lParam,\r
+                   lpExpandVtbl);\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpQueueDelete          [SETUPX.17]\r
+ *\r
+ * Is lParamRef the same as lParam in VcpQueueCopy ?\r
+ * Damn docu !! Err... which docu ?\r
+ */\r
+RETERR16 WINAPI VcpQueueDelete16(\r
+       LPCSTR lpszDstFileName,\r
+       LPCSTR lpszDstDir,\r
+       LOGDISKID16 ldidDst,\r
+       LPARAM lParamRef\r
+)\r
+{\r
+    VCPFILESPEC vfsDst;\r
+\r
+    if (!VCP_opened)\r
+       return ERR_VCP_NOTOPEN;\r
+\r
+    vfsDst.ldid = ldidDst;\r
+    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);\r
+    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);\r
+\r
+    return VCP_VirtnodeCreate(NULL, &vfsDst, VNFL_DELETE, lParamRef, 0);\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpQueueRename          [SETUPX.204]\r
+ *\r
+ */\r
+RETERR16 WINAPI VcpQueueRename16(\r
+       LPCSTR lpszSrcFileName, LPCSTR lpszDstFileName,\r
+       LPCSTR lpszSrcDir, LPCSTR lpszDstDir,\r
+       LOGDISKID16 ldidSrc, LOGDISKID16 ldidDst,\r
+       LPARAM lParam\r
+)\r
+{\r
+    VCPFILESPEC vfsSrc, vfsDst;\r
+\r
+    if (!VCP_opened)\r
+       return ERR_VCP_NOTOPEN;\r
+\r
+    vfsSrc.ldid = ldidSrc;\r
+    vfsSrc.vhstrDir = vsmStringAdd16(lpszSrcDir);\r
+    vfsSrc.vhstrFileName = vsmStringAdd16(lpszSrcFileName);\r
+\r
+    vfsDst.ldid = ldidDst;\r
+    vfsDst.vhstrDir = vsmStringAdd16(lpszDstDir);\r
+    vfsDst.vhstrFileName = vsmStringAdd16(lpszDstFileName);\r
+\r
+    return VCP_VirtnodeCreate(&vfsSrc, &vfsDst, VNFL_RENAME, lParam,\r
+                   0);\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpEnumFiles (SETUPX.@)\r
+ */\r
+INT16 WINAPI VcpEnumFiles(VCPENUMPROC vep, LPARAM lParamRef)\r
+{\r
+    WORD n;\r
+\r
+    for (n = 0; n < vn_last; n++)\r
+       vep(pvnlist[n], lParamRef);\r
+\r
+    return 0; /* FIXME: return value ? */\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpExplain (SETUPX.411)\r
+ */\r
+LPCSTR WINAPI VcpExplain16(LPVIRTNODE lpVn, DWORD dwWhat)\r
+{\r
+    static char buffer[MAX_PATH]; /* FIXME: is this how it's done ? */\r
+    buffer[0] = '\0';\r
+    switch (dwWhat)\r
+    {\r
+       case VCPEX_SRC_FULL:\r
+       case VCPEX_DST_FULL:\r
+           {\r
+               LPVCPFILESPEC lpvfs =\r
+                   (dwWhat == VCPEX_SRC_FULL) ?  &lpVn->vfsSrc : &lpVn->vfsDst;\r
+\r
+                /* if we have an ldid, use it, otherwise use the string */\r
+                /* from the vhstrlist array */\r
+               if (lpvfs->ldid != 0xffff)\r
+                  CtlGetLddPath16(lpvfs->ldid, buffer);\r
+                else\r
+                  strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrDir));\r
+\r
+                strcat(buffer, "\\");\r
+                strcat(buffer, vsmGetStringRawName16(lpvfs->vhstrFileName));\r
+           }\r
+           break;\r
+       default:\r
+           FIXME("%ld unimplemented !\n", dwWhat);\r
+           strcpy(buffer, "Unknown error");\r
+           break;\r
+    }\r
+    return buffer;\r
+}\r
+\r
+RETERR16 VCP_CheckPaths(void)\r
+{\r
+    DWORD n;\r
+    LPVIRTNODE lpvn;\r
+    RETERR16 cbres;\r
+\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKSTART, 0, 0, VCP_MsgRef);\r
+    for (n = 0; n < vn_num; n++)\r
+    {\r
+       lpvn = pvnlist[n];\r
+       if (!lpvn) continue;\r
+        /* FIXME: check paths of all VIRTNODEs here ! */\r
+       cbres = VCP_Callback(&lpvn->vfsDst, VCPM_CHECKPATH, 0, (DWORD)lpvn, VCP_MsgRef);\r
+    }\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATPATHCHECKEND, 0, 0, VCP_MsgRef);\r
+    return OK;\r
+}\r
+\r
+RETERR16 VCP_CopyFiles(void)\r
+{\r
+    char fn_src[MAX_PATH], fn_dst[MAX_PATH];\r
+    RETERR16 res = OK, cbres;\r
+    DWORD n;\r
+    LPVIRTNODE lpvn;\r
+\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYSTART, 0, 0, VCP_MsgRef);\r
+    for (n = 0; n < vn_num; n++)\r
+    {\r
+       lpvn = pvnlist[n];\r
+       if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_COPY)) continue;\r
+       /* FIXME: need to send VCPM_VSTATNEWDISK notification sometimes */\r
+        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));\r
+        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));\r
+       /* FIXME: what is this VCPM_VSTATWRITE here for ?\r
+        * I guess it's to signal successful destination file creation */\r
+       cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);\r
+\r
+       /* FIXME: need to do the file copy in small chunks for notifications */\r
+       TRACE("copying '%s' to '%s'\n", fn_src, fn_dst);\r
+        /* perform the file copy */\r
+        if (!(CopyFileA(fn_src, fn_dst,\r
+              (lpvn->fl & VNLP_COPYIFEXISTS) ? FALSE : TRUE )))\r
+        {\r
+            ERR("error copying, src: %s -> dst: %s\n", fn_src, fn_dst);\r
+           res = ERR_VCP_IOFAIL;\r
+        }\r
+\r
+       vcp_status.prgFileRead.dwSoFar++;\r
+       cbres = VCP_Callback(&vcp_status, VCPM_VSTATREAD, 0, 0, VCP_MsgRef);\r
+       vcp_status.prgFileWrite.dwSoFar++;\r
+       cbres = VCP_Callback(&vcp_status, VCPM_VSTATWRITE, 0, 0, VCP_MsgRef);\r
+    }\r
+\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCOPYEND, 0, 0, VCP_MsgRef);\r
+    return res;\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpFlush - internal (not exported), but documented\r
+ *\r
+ * VNFL_NOW is used for VcpFlush.\r
+ */\r
+RETERR16 VcpFlush16(WORD fl, LPCSTR lpszBackupDest)\r
+{\r
+    return OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             VcpClose (SETUPX.201)\r
+ *\r
+ * Does callbacks (-> vifproc) with VCPM_VSTATCLOSESTART,\r
+ * VCPM_VSTATCLOSEEND.\r
+ *\r
+ * fl gets VCPFL_xxx flags to indicate what to do with the\r
+ * VIRTNODEs (files to mess with) created by e.g. GenInstall()\r
+ */\r
+RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)\r
+{\r
+    RETERR16 res = OK;\r
+    WORD cbres = VCPN_PROCEED;\r
+\r
+    TRACE("(%04x, '%s')\n", fl, lpszBackupDest);\r
+\r
+    /* FIXME: needs to sort virtnodes in case VCPFL_INSPECIFIEDORDER\r
+     * is not set. This is done by VCP_Callback(VCPM_NODECOMPARE) */\r
+\r
+    TRACE("#1\n");\r
+    memset(&vcp_status, 0, sizeof(VCPSTATUS));\r
+    /* yes, vcp_status.cbSize is 0 ! */\r
+    TRACE("#2\n");\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSESTART, 0, 0, VCP_MsgRef);\r
+    TRACE("#3\n");\r
+\r
+    res = VCP_CheckPaths();\r
+    TRACE("#4\n");\r
+    if (res != OK)\r
+       return res; /* is this ok ? */\r
+    VCP_CopyFiles();\r
+\r
+    TRACE("#5\n");\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATCLOSEEND, 0, 0, VCP_MsgRef);\r
+    TRACE("#6\n");\r
+    VCP_Proc = NULL;\r
+    FreeLibrary(SETUPAPI_hInstance);\r
+    VCP_opened = FALSE;\r
+    return OK;\r
+}\r
+\r
+RETERR16 VCP_RenameFiles(void)\r
+{\r
+    char fn_src[MAX_PATH], fn_dst[MAX_PATH];\r
+    RETERR16 res = OK, cbres;\r
+    DWORD n;\r
+    LPVIRTNODE lpvn;\r
+\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMESTART, 0, 0, VCP_MsgRef);\r
+    for (n = 0; n < vn_num; n++)\r
+    {\r
+       lpvn = pvnlist[n];\r
+       if ((!lpvn) || ((lpvn->fl & VNFL_NODE_TYPE) != VNFL_RENAME)) continue;\r
+        strcpy(fn_src, VcpExplain16(lpvn, VCPEX_SRC_FULL));\r
+        strcpy(fn_dst, VcpExplain16(lpvn, VCPEX_DST_FULL));\r
+       cbres = VCP_Callback(&lpvn->vfsDst, VCPM_FILEOPENOUT, 0, (LPARAM)lpvn, VCP_MsgRef);\r
+        if (!(MoveFileExA(fn_src, fn_dst, MOVEFILE_REPLACE_EXISTING)))\r
+           res = ERR_VCP_IOFAIL;\r
+       else\r
+           VCP_VirtnodeDelete(lpvn);\r
+    }\r
+    cbres = VCP_Callback(&vcp_status, VCPM_VSTATRENAMEEND, 0, 0, VCP_MsgRef);\r
+    return res;\r
+}\r
+\r
+/***********************************************************************\r
+ *             vcpDefCallbackProc (SETUPX.202)\r
+ */\r
+RETERR16 WINAPI vcpDefCallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,\r
+                                       LPARAM lParam, LPARAM lParamRef)\r
+{\r
+    static int count = 0;\r
+    if (count < 10)\r
+        FIXME("(%p, %04x, %04x, %08lx, %08lx) - what to do here ?\n",\r
+               lpvObj, uMsg, wParam, lParam, lParamRef);\r
+    count++;\r
+    return OK;\r
+}\r
+\r
+/********************* point-and-click stuff from here ***********************/\r
+\r
+static HWND hDlgCopy = 0;\r
+static HKEY hKeyFiles = 0, hKeyRename = 0, hKeyConflict = 0;\r
+static char BackupDir[12];\r
+\r
+static INT_PTR CALLBACK VCP_UI_FileCopyDlgProc(HWND hWndDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    INT_PTR retval = FALSE;\r
+\r
+    if (iMsg == WM_INITDIALOG)\r
+    {\r
+        ShowWindow(hWndDlg, SW_SHOWNORMAL);\r
+        UpdateWindow(hWndDlg);\r
+       retval = TRUE;\r
+    }\r
+    return retval;\r
+}\r
+\r
+BOOL VCP_UI_GetDialogTemplate(LPCVOID *template32)\r
+{\r
+    HRSRC hResInfo;\r
+    HGLOBAL hDlgTmpl32;\r
+\r
+    if (!(hResInfo = FindResourceA(SETUPAPI_hInstance, MAKEINTRESOURCEA(COPYFILEDLGORD), (LPSTR)RT_DIALOG)))\r
+       return FALSE;\r
+    if (!(hDlgTmpl32 = LoadResource(SETUPAPI_hInstance, hResInfo )) ||\r
+        !(*template32 = LockResource( hDlgTmpl32 )))\r
+       return FALSE;\r
+    return TRUE;\r
+}\r
+\r
+static LRESULT WINAPI\r
+VCP_UI_FileCopyWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    if (uMsg != WM_CREATE)\r
+        return DefWindowProcA (hwnd, uMsg, wParam, lParam);\r
+\r
+    switch (uMsg)\r
+    {\r
+       case WM_CREATE:\r
+           return 0;\r
+       default:\r
+           FIXME("%04x: unhandled.\n", uMsg);\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+void VCP_UI_RegisterProgressClass(void)\r
+{\r
+    static BOOL registered = FALSE;\r
+    WNDCLASSA wndClass;\r
+\r
+    if (registered)\r
+       return;\r
+\r
+    registered = TRUE;\r
+    ZeroMemory (&wndClass, sizeof(WNDCLASSA));\r
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;\r
+    wndClass.lpfnWndProc   = VCP_UI_FileCopyWndProc;\r
+    wndClass.cbClsExtra    = 0;\r
+    wndClass.cbWndExtra    = 0;\r
+    wndClass.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROW);\r
+    wndClass.hbrBackground = NULL;\r
+    wndClass.lpszClassName = "setupx_progress";\r
+\r
+    RegisterClassA (&wndClass);\r
+}\r
+\r
+RETERR16 VCP_UI_NodeCompare(LPVIRTNODE vn1, LPVIRTNODE vn2)\r
+{\r
+    LPCSTR file1, file2;\r
+    file1 = vsmGetStringRawName16(vn1->vfsSrc.vhstrFileName);\r
+    file2 = vsmGetStringRawName16(vn2->vfsSrc.vhstrFileName);\r
+    return (RETERR16)strcmp(file1, file2);\r
+}\r
+\r
+RETERR16 VCP_UI_CopyStart(void)\r
+{\r
+    LPCVOID template32;\r
+    char buf[256]; /* plenty */\r
+    BOOL dirty;\r
+    DWORD len;\r
+\r
+    /* FIXME: should be registered at DLL startup instead */\r
+    VCP_UI_RegisterProgressClass();\r
+    if (!(VCP_UI_GetDialogTemplate(&template32)))\r
+       return VCPN_FAIL;\r
+\r
+    if (vn_num > 10)  /* hack */\r
+    {\r
+        hDlgCopy = CreateDialogIndirectParamA(SETUPAPI_hInstance, template32, 0,\r
+                                              VCP_UI_FileCopyDlgProc, 0);\r
+        if (!hDlgCopy)\r
+            return VCPN_FAIL;\r
+        SetDlgItemTextA(hDlgCopy, SOURCESTRORD, "Scanning ...");\r
+        SetDlgItemTextA(hDlgCopy, DESTSTRORD, "NOT_IMPLEMENTED_YET");\r
+    }\r
+    strcpy(buf, REG_INSTALLEDFILES);\r
+    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyFiles))\r
+       return VCPN_FAIL;\r
+    strcat(buf, REGPART_RENAME);\r
+    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, buf, &hKeyRename))\r
+       return VCPN_FAIL;\r
+    if (RegCreateKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT, &hKeyConflict))\r
+       return VCPN_FAIL;\r
+    len = 1;\r
+    if (!(RegQueryValueExA(hKeyConflict, "Dirty", NULL, 0, (LPBYTE)&dirty, &len)))\r
+    {\r
+       /* FIXME: what does SETUPX.DLL do in this case ? */\r
+       MESSAGE("Warning: another program using SETUPX is already running ! Failed.\n");\r
+       return VCPN_FAIL;\r
+    }\r
+    dirty = TRUE;\r
+    if (RegSetValueExA(hKeyConflict, "Dirty", 0, REG_BINARY, (LPBYTE)&dirty, 1))\r
+       return VCPN_FAIL;\r
+    len = 12;\r
+    if (!(RegQueryValueExA(hKeyConflict, "BackupDirectory", NULL, 0, BackupDir, &len)))\r
+       strcpy(BackupDir, "VCM");\r
+\r
+    /* create C:\WINDOWS\[BackupDir] and set registry key to it */\r
+    GetWindowsDirectoryA(buf, 256);\r
+    strcat(buf, "\\");\r
+    strcat(buf, BackupDir);\r
+    if (!(CreateDirectoryA(buf, NULL)))\r
+       return VCPN_FAIL;\r
+    if (RegSetValueExA(hKeyConflict, "BackupDirectory", 0, REG_SZ, (LPBYTE)buf, strlen(buf)+1))\r
+       return VCPN_FAIL;\r
+    RegCloseKey(hKeyConflict);\r
+\r
+    return VCPN_OK;\r
+}\r
+\r
+/***********************************************************************\r
+ *             vcpUICallbackProc (SETUPX.213)\r
+ */\r
+RETERR16 WINAPI vcpUICallbackProc16(LPVOID lpvObj, UINT16 uMsg, WPARAM wParam,\r
+                                       LPARAM lParam, LPARAM lParamRef)\r
+{\r
+    static int count = 0;\r
+    RETERR16 res = VCPN_OK, cbres;\r
+\r
+    if (count < 5)\r
+        FIXME("(%p, %04x, %04x, %08lx, %08lx) - semi-stub\n",\r
+               lpvObj, uMsg, wParam, lParam, lParamRef);\r
+    count++;\r
+    switch (uMsg)\r
+    {\r
+       /* unused messages, it seems */\r
+       case VCPM_DISKPREPINFO:\r
+\r
+       case VCPM_FILENEEDED:\r
+\r
+       case VCPM_NODECREATE:\r
+       case VCPM_NODEACCEPT:\r
+\r
+       case VCPM_VSTATCLOSESTART:\r
+       case VCPM_VSTATPATHCHECKSTART:\r
+       case VCPM_VSTATPATHCHECKEND:\r
+\r
+       case VCPM_CHECKPATH:\r
+           break;\r
+\r
+       /* the real stuff */\r
+       case VCPM_NODECOMPARE:\r
+           res = VCP_UI_NodeCompare((LPVIRTNODE)lpvObj, (LPVIRTNODE)lParam);\r
+           break;\r
+       case VCPM_VSTATREAD:\r
+           break;\r
+       case VCPM_VSTATWRITE:\r
+           cbres = VCP_Callback(&vcp_status, VCPM_DISKPREPINFO, 0, 0, VCP_MsgRef);\r
+           break;\r
+       case VCPM_VSTATCLOSEEND:\r
+           RegCloseKey(hKeyFiles);\r
+           RegCloseKey(hKeyRename);\r
+           RegDeleteKeyA(HKEY_LOCAL_MACHINE, REG_VERSIONCONFLICT);\r
+           break;\r
+       case VCPM_VSTATCOPYSTART:\r
+           res = VCP_UI_CopyStart();\r
+           break;\r
+       case VCPM_VSTATCOPYEND:\r
+           if (hDlgCopy) DestroyWindow(hDlgCopy);\r
+           break;\r
+       default:\r
+           FIXME("unhandled msg 0x%04x\n", uMsg);\r
+    }\r
+    return res;\r
+}\r
diff --git a/reactos/lib/shdocvw/De.rc b/reactos/lib/shdocvw/De.rc
new file mode 100644 (file)
index 0000000..564d998
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005 Henning Gerhardt
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
+
+100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Lade die Mozilla Active X Steuerung"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12
+ LTEXT "", 104, 10, 30, 200, 10, SS_CENTER
+ PUSHBUTTON "Abbrechen", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE
+BEGIN
+ 1001  "Diese Anwendung fordert ein ActiveX Browser Objekt an,\n" \
+        "aber die Mozilla Active X Steuerung ist nicht installiert." \
+        "Möchten Sie, dass es aus dem Internet geladen und installiert wird ?"
+END
diff --git a/reactos/lib/shdocvw/En.rc b/reactos/lib/shdocvw/En.rc
new file mode 100644 (file)
index 0000000..c6d5150
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 Mike McCormack 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Downloading the Mozilla Active X control"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12
+ LTEXT "", 104, 10, 30, 200, 10, SS_CENTER
+ PUSHBUTTON "Cancel", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE
+BEGIN
+ 1001  "This application is requesting an ActiveX browser object\n" \
+        "but the Mozilla Active X control is currently not installed." \
+        "Do you wish to download and install it?"
+END
diff --git a/reactos/lib/shdocvw/Fr.rc b/reactos/lib/shdocvw/Fr.rc
new file mode 100644 (file)
index 0000000..cab59b4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 Jonathan Ernst
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
+
+100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Téléchargement du contrôle ActiveX de Mozilla"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12
+ LTEXT "", 104, 10, 30, 200, 10, SS_CENTER
+ PUSHBUTTON "Annuler", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE
+BEGIN
+ 1001  "Cette application requiert un object navigateur ActiveX\n" \
+        "mais le contrôle Active X de Mozilla n'est pas installé." \
+        "Souhaitez-vous le télécharger et l'installer ?"
+END
diff --git a/reactos/lib/shdocvw/Pt.rc b/reactos/lib/shdocvw/Pt.rc
new file mode 100644 (file)
index 0000000..a0f3796
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2005 Marcelo Duarte
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
+
+100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Baixando o controle Mozilla ActiveX"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12
+ LTEXT "", 104, 10, 30, 200, 10, SS_CENTER
+ PUSHBUTTON "Cancelar", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE
+BEGIN
+ 1001  "Esta aplicação requer um objecto ActiveX do navegador\n" \
+        "mas o controle Mozilla ActiveX atualmente não está instalado." \
+        "Você deseja baixá-lo e instalá-lo?"
+END
index 6909c38..77a8d2d 100644 (file)
 \r
 #include "version.rc"\r
 \r
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
-\r
-100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62\r
-STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
-CAPTION "Downloading the Mozilla Active X control"\r
-FONT 8, "Helv"\r
-{\r
- CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12\r
- LTEXT "", 104, 10, 30, 200, 10, SS_CENTER\r
- PUSHBUTTON "Cancel", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP\r
-}\r
-\r
-STRINGTABLE\r
-BEGIN\r
- 1001  "This application is requesting an ActiveX browser object\n" \\r
-        "but the Mozilla Active X control is currently not installed." \\r
-        "Do you wish to download and install it?"\r
-END\r
+#include "De.rc"\r
+#include "En.rc"\r
+#include "Fr.rc"\r
+#include "Pt.rc"\r
index b5e1670..6d4cc4a 100644 (file)
@@ -130,17 +130,16 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
  */\r
 HRESULT WINAPI SHDOCVW_DllCanUnloadNow(void)\r
 {\r
-    HRESULT moz_can_unload = S_FALSE;\r
+    HRESULT moz_can_unload = S_OK;\r
     fnCanUnloadNow pCanUnloadNow;\r
 \r
     if (hMozCtl)\r
     {\r
         pCanUnloadNow = (fnCanUnloadNow)\r
             GetProcAddress(hMozCtl, "DllCanUnloadNow");\r
-        moz_can_unload = pCanUnloadNow();\r
+        if (pCanUnloadNow)\r
+            moz_can_unload = pCanUnloadNow();\r
     }\r
-    else\r
-        moz_can_unload = S_OK;\r
 \r
     if (moz_can_unload == S_OK && SHDOCVW_refCount == 0)\r
         return S_OK;\r
index 36b7140..9d74b96 100644 (file)
@@ -37,6 +37,7 @@ C_SRCS = \
        shfldr_desktop.c \
        shfldr_fs.c \
        shfldr_mycomp.c \
+       shfldr_unixfs.c \
        shlexec.c \
        shlfileop.c \
        shlfolder.c \
@@ -77,7 +78,7 @@ version16.res: version16.rc
        $(LDPATH) $(RC16) $(RC16FLAGS) -fo$@ $(SRCDIR)/version16.rc
 
 shell.spec.c: shell.spec version16.res
-       $(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --main-module $(MODULE) --res version16.res --dll $(SRCDIR)/shell.spec
+       $(WINEBUILD) $(DEFS) $(DLLFLAGS) --dll -o $@ --main-module $(MODULE) --res version16.res --export $(SRCDIR)/shell.spec
 
 authors.c: $(TOPSRCDIR)/AUTHORS
        (LC_ALL=C; export LC_ALL; echo 'const char * const SHELL_Authors[] = {' && \
index 198c18d..63be4a3 100644 (file)
@@ -55,68 +55,95 @@ static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
     return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ? SHCONTF_NONFOLDERS : 0);
 }
 
+/******************************************************************************
+ * InitializeTreeView [Internal]
+ *
+ * Called from WM_INITDIALOG handler.
+ * 
+ * PARAMS
+ *  hwndParent [I] The BrowseForFolder dialog
+ *  root       [I] ITEMIDLIST of the root shell folder
+ */
 static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
 {
-       HIMAGELIST      hImageList;
-       IShellFolder *  lpsf;
-       HRESULT hr;
-       IEnumIDList * pEnumIL = NULL;
-       LPITEMIDLIST parentofroot;
-       parentofroot = ILClone(root);
-       ILRemoveLastID(parentofroot);
-
-       hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
-       Shell_GetImageList(NULL, &hImageList);
-
-       TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
-
-       if (hImageList && hwndTreeView)
-         TreeView_SetImageList(hwndTreeView, hImageList, 0);
-
-       if (_ILIsDesktop (root)) {
-          hr = SHGetDesktopFolder(&lpsf);
-       } else {
-          IShellFolder *       lpsfdesktop;
-
-          hr = SHGetDesktopFolder(&lpsfdesktop);
-          if (SUCCEEDED(hr)) {
-             hr = IShellFolder_BindToObject(lpsfdesktop, parentofroot, 0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf);
-             IShellFolder_Release(lpsfdesktop);
-          }
-       }
-       if (SUCCEEDED(hr))
-       {
-           IShellFolder * pSFRoot;
-           if (_ILIsPidlSimple(root))
-           {
-               pSFRoot = lpsf;
-               IShellFolder_AddRef(pSFRoot);
-           }
-           else
-               hr = IShellFolder_BindToObject(lpsf,ILFindLastID(root),0,&IID_IShellFolder,(LPVOID *)&pSFRoot);
-           if (SUCCEEDED(hr))
-           {
-               hr = IShellFolder_EnumObjects(
-                   pSFRoot,
-                   hwndParent,
-                   BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags),
-                   &pEnumIL);
-               IShellFolder_Release(pSFRoot);
-           }
-       }
+    LPITEMIDLIST pidlParent, pidlChild;
+    HIMAGELIST hImageList;
+    HRESULT hr;
+    IShellFolder *lpsfParent, *lpsfRoot;
+    IEnumIDList * pEnumChildren = NULL;
+
+    TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+    
+    hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
+    if (!hwndTreeView) {
+        FIXME("Could not get handle to treeview control! Error: %08lx\n", GetLastError());
+        return;
+    }
+    Shell_GetImageList(NULL, &hImageList);
+
+    if (hImageList)
+        TreeView_SetImageList(hwndTreeView, hImageList, 0);
+
+    /* We want to call InsertTreeViewItem down the code, in order to insert
+     * the root item of the treeview. Due to InsertTreeViewItem's signature, 
+     * we need the following to do this:
+     *
+     * + An ITEMIDLIST corresponding to _the parent_ of root. 
+     * + An ITEMIDLIST, which is a relative path from root's parent to root 
+     *   (containing a single SHITEMID).
+     * + An IShellFolder interface pointer of root's parent folder.
+     *
+     * If root is 'Desktop', then root's parent is also 'Desktop'.
+     */
+
+    pidlParent = ILClone(root);
+    ILRemoveLastID(pidlParent);
+    pidlChild = ILClone(ILFindLastID(root));
+    
+    if (_ILIsDesktop(pidlParent)) {
+        hr = SHGetDesktopFolder(&lpsfParent);
+    } else {
+        IShellFolder *lpsfDesktop;
+        hr = SHGetDesktopFolder(&lpsfDesktop);
+        if (!SUCCEEDED(hr)) {
+            WARN("SHGetDesktopFolder failed! hr = %08lx\n", hr);
+            return;
+        }
+        hr = IShellFolder_BindToObject(lpsfDesktop, pidlParent, 0, &IID_IShellFolder, (LPVOID*)&lpsfParent);
+        IShellFolder_Release(lpsfDesktop);
+    }
+    
+    if (!SUCCEEDED(hr)) {
+        WARN("Could not bind to parent shell folder! hr = %08lx\n", hr);
+        return;
+    }
 
-       if (SUCCEEDED(hr) && hwndTreeView)
-       {
-         TreeView_DeleteAllItems(hwndTreeView);
-         TreeView_Expand(hwndTreeView,
-                         InsertTreeViewItem(lpsf, _ILIsPidlSimple(root) ? root : ILFindLastID(root), parentofroot, pEnumIL,  TVI_ROOT),
-                         TVE_EXPAND);
-       }
+    if (pidlChild && pidlChild->mkid.cb) {
+        hr = IShellFolder_BindToObject(lpsfParent, pidlChild, 0, &IID_IShellFolder, (LPVOID*)&lpsfRoot);
+    } else {
+        lpsfRoot = lpsfParent;
+        hr = IShellFolder_AddRef(lpsfParent);
+    }
+    
+    if (!SUCCEEDED(hr)) {
+        WARN("Could not bind to root shell folder! hr = %08lx\n", hr);
+        IShellFolder_Release(lpsfParent);
+        return;
+    }
+
+    hr = IShellFolder_EnumObjects(lpsfRoot, hwndParent, BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumChildren);
+    if (!SUCCEEDED(hr)) {
+        WARN("Could not get child iterator! hr = %08lx\n", hr);
+        IShellFolder_Release(lpsfParent);
+        IShellFolder_Release(lpsfRoot);
+        return;
+    }
 
-       if (SUCCEEDED(hr))
-         IShellFolder_Release(lpsf);
+    TreeView_DeleteAllItems(hwndTreeView);
+    TreeView_Expand(hwndTreeView, InsertTreeViewItem(lpsfParent, pidlChild, pidlParent, pEnumChildren,  TVI_ROOT), TVE_EXPAND);
 
-       TRACE("done\n");
+    IShellFolder_Release(lpsfRoot);
+    IShellFolder_Release(lpsfParent);
 }
 
 static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
@@ -149,12 +176,27 @@ static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW lpTV_ITEM)
 
 typedef struct tagID
 {
-   LPSHELLFOLDER lpsfParent;
-   LPITEMIDLIST  lpi;
-   LPITEMIDLIST  lpifq;
-   IEnumIDList*  pEnumIL;
+   LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
+   LPITEMIDLIST  lpi;        /* PIDL relativ to parent */
+   LPITEMIDLIST  lpifq;      /* Fully qualified PIDL */
+   IEnumIDList*  pEnumIL;    /* Children iterator */ 
 } TV_ITEMDATA, *LPTV_ITEMDATA;
 
+/******************************************************************************
+ * GetName [Internal]
+ *
+ * Query a shell folder for the display name of one of it's children
+ *
+ * PARAMS
+ *  lpsf           [I] IShellFolder interface of the folder to be queried.
+ *  lpi            [I] ITEMIDLIST of the child, relative to parent
+ *  dwFlags        [I] as in IShellFolder::GetDisplayNameOf
+ *  lpFriendlyName [O] The desired display name in unicode
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
 static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR lpFriendlyName)
 {
        BOOL   bSuccess=TRUE;
@@ -175,7 +217,22 @@ static BOOL GetName(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpi, DWORD dwFlags, LPWSTR
        return bSuccess;
 }
 
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
+/******************************************************************************
+ * InsertTreeViewItem [Internal]
+ *
+ * PARAMS
+ *  lpsf       [I] IShellFolder interface of the item's parent shell folder 
+ *  pidl       [I] ITEMIDLIST of the child to insert, relativ to parent 
+ *  pidlParent [I] ITEMIDLIST of the parent shell folder
+ *  pEnumIL    [I] Iterator for the children of the item to be inserted
+ *  hParent    [I] The treeview-item that represents the parent shell folder
+ *
+ * RETURNS
+ *  Success: Handle to the created and inserted treeview-item
+ *  Failure: NULL
+ */
+static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, 
+    LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
 {
        TVITEMW         tvi;
        TVINSERTSTRUCTW tvins;
@@ -211,6 +268,18 @@ static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST pidl, LPC
        return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
 }
 
+/******************************************************************************
+ * FillTreeView [Internal]
+ *
+ * For each child (given by lpe) of the parent shell folder, which is given by 
+ * lpsf and whose PIDL is pidl, insert a treeview-item right under hParent
+ *
+ * PARAMS
+ *  lpsf    [I] IShellFolder interface of the parent shell folder
+ *  pidl    [I] ITEMIDLIST of the parent shell folder
+ *  hParent [I] The treeview item that represents the parent shell folder
+ *  lpe     [I] An iterator for the children of the parent shell folder
+ */
 static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hParent, IEnumIDList* lpe)
 {
        HTREEITEM       hPrev = 0;
@@ -219,7 +288,11 @@ static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST  pidl, HTREEITEM hPar
        HRESULT         hr;
        HWND            hwnd=GetParent(hwndTreeView);
 
-       TRACE("%p %p %x\n",lpsf, pidl, (INT)hParent);
+       TRACE("%p %p %x %p\n",lpsf, pidl, (INT)hParent, lpe);
+
+       /* No IEnumIDList -> No children */
+       if (!lpe) return;
+       
        SetCapture(GetParent(hwndTreeView));
        SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
 
index 0e47f6f..f5e8c38 100644 (file)
@@ -116,7 +116,7 @@ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, DWORD len, BOOL b
 
 BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
 {
-        static const WCHAR swShell[] = {'\\','s','h','e','l','l','\\',0};
+        static const WCHAR swShell[] = {'s','h','e','l','l','\\',0};
         static const WCHAR swCommand[] = {'\\','c','o','m','m','a','n','d',0};
        BOOL    ret = FALSE;
 
index 71c9293..9f06d97 100644 (file)
@@ -26,7 +26,7 @@
  * - a right mousebutton-copy sets the following formats:
  *  classic:
  *     Shell IDList Array
- *     Prefered Drop Effect
+ *     Preferred Drop Effect
  *     Shell Object Offsets
  *     HDROP
  *     FileName
index 522e005..a243768 100644 (file)
@@ -127,9 +127,9 @@ INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
         case WM_INITDIALOG :
             prfdp = (RUNFILEDLGPARAMS *)lParam ;
             SetWindowTextA (hwnd, prfdp->lpstrTitle) ;
-            SetClassLongA (hwnd, GCL_HICON, (LPARAM)prfdp->hIcon) ;
-            SendMessageA (GetDlgItem (hwnd, 12297), STM_SETICON,
-                          (WPARAM)LoadIconA (NULL, (LPSTR)IDI_WINLOGO), 0);
+            SetClassLongPtrW (hwnd, GCLP_HICON, (LPARAM)prfdp->hIcon) ;
+            SendMessageW (GetDlgItem (hwnd, 12297), STM_SETICON,
+                          (WPARAM)LoadIconW (NULL, (LPCWSTR)IDI_WINLOGO), 0);
             FillList (GetDlgItem (hwnd, 12298), NULL) ;
             SetFocus (GetDlgItem (hwnd, 12298)) ;
             return TRUE ;
@@ -283,7 +283,7 @@ void FillList (HWND hCb, char *pszLatest)
 
         if (NULL != pszLatest)
             {
-            if (!strcasecmp (pszCmd, pszLatest))
+            if (!lstrcmpiA(pszCmd, pszLatest))
                 {
                 /*
                 sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ;
index 1d78e29..072e328 100644 (file)
@@ -25,6 +25,7 @@
 #define COBJMACROS
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 #include "windef.h"
 #include "winbase.h"
 #include "winreg.h"
@@ -103,24 +104,27 @@ BOOL AddToEnumList(
  */
 BOOL CreateFolderEnumList(
        IEnumIDList *list,
-       LPCSTR lpszPath,
+       LPCWSTR lpszPath,
        DWORD dwFlags)
 {
     LPITEMIDLIST pidl=NULL;
-    WIN32_FIND_DATAA stffile;
+    WIN32_FIND_DATAW stffile;
     HANDLE hFile;
-    CHAR  szPath[MAX_PATH];
+    WCHAR  szPath[MAX_PATH];
     BOOL succeeded = TRUE;
+    const static WCHAR stars[] = { '*','.','*',0 };
+    const static WCHAR dot[] = { '.',0 };
+    const static WCHAR dotdot[] = { '.','.',0 };
 
-    TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_a(lpszPath),dwFlags);
+    TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_w(lpszPath),dwFlags);
 
     if(!lpszPath || !lpszPath[0]) return FALSE;
 
-    strcpy(szPath, lpszPath);
-    PathAddBackslashA(szPath);
-    strcat(szPath,"*.*");
+    strcpyW(szPath, lpszPath);
+    PathAddBackslashW(szPath);
+    strcatW(szPath,stars);
 
-    hFile = FindFirstFileA(szPath,&stffile);
+    hFile = FindFirstFileW(szPath,&stffile);
     if ( hFile != INVALID_HANDLE_VALUE )
     {
         BOOL findFinished = FALSE;
@@ -132,21 +136,21 @@ BOOL CreateFolderEnumList(
             {
                 if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
                  dwFlags & SHCONTF_FOLDERS &&
-                 strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, ".."))
+                 strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot))
                 {
-                    pidl = _ILCreateFromFindDataA(&stffile);
+                    pidl = _ILCreateFromFindDataW(&stffile);
                     succeeded = succeeded && AddToEnumList(list, pidl);
                 }
                 else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                  && dwFlags & SHCONTF_NONFOLDERS)
                 {
-                    pidl = _ILCreateFromFindDataA(&stffile);
+                    pidl = _ILCreateFromFindDataW(&stffile);
                     succeeded = succeeded && AddToEnumList(list, pidl);
                 }
             }
             if (succeeded)
             {
-                if (!FindNextFileA(hFile, &stffile))
+                if (!FindNextFileW(hFile, &stffile))
                 {
                     if (GetLastError() == ERROR_NO_MORE_FILES)
                         findFinished = TRUE;
index 53b8b5f..26972aa 100644 (file)
@@ -25,6 +25,6 @@ BOOL AddToEnumList(IEnumIDList *list, LPITEMIDLIST pidl);
 /* Enumerates the folders and/or files (depending on dwFlags) in lpszPath and
  * adds them to the already-created list.
  */
-BOOL CreateFolderEnumList(IEnumIDList *list, LPCSTR lpszPath, DWORD dwFlags);
+BOOL CreateFolderEnumList(IEnumIDList *list, LPCWSTR lpszPath, DWORD dwFlags);
 
 #endif /* ndef __ENUMIDLIST_H__ */
index 12b6fe4..efa3b2b 100644 (file)
@@ -328,7 +328,7 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation(
 
              found = TRUE;
            }
-           else if (!strcasecmp(sTemp, "lnkfile"))
+           else if (!lstrcmpiA(sTemp, "lnkfile"))
            {
              /* extract icon from shell shortcut */
              IShellFolder* dsf;
index d0f4206..1c1cf1b 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *     pidl Handling
+ *    pidl Handling
  *
- *     Copyright 1998  Juergen Schmied
+ *    Copyright 1998    Juergen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -57,7 +57,7 @@ extern LPVOID WINAPI Alloc(INT);
 extern BOOL WINAPI Free(LPVOID);
 
 /*************************************************************************
- * ILGetDisplayNameEx          [SHELL32.186]
+ * ILGetDisplayNameEx        [SHELL32.186]
  *
  * Retrieves the display name of an ItemIDList
  *
@@ -75,106 +75,108 @@ extern BOOL WINAPI Free(LPVOID);
  */
 BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type)
 {
-       BOOL ret = FALSE;
-       WCHAR wPath[MAX_PATH];
+    BOOL ret = FALSE;
+    WCHAR wPath[MAX_PATH];
 
-       TRACE("%p %p %p %ld\n", psf, pidl, path, type);
+    TRACE("%p %p %p %ld\n", psf, pidl, path, type);
 
-       if (!pidl || !path)
-         return FALSE;
+    if (!pidl || !path)
+        return FALSE;
 
-       ret = ILGetDisplayNameExW(psf, pidl, wPath, type);
-       WideCharToMultiByte(CP_ACP, 0, wPath, -1, path, MAX_PATH, NULL, NULL);
-       TRACE("%p %p %s\n", psf, pidl, debugstr_a(path));
+    ret = ILGetDisplayNameExW(psf, pidl, wPath, type);
+    WideCharToMultiByte(CP_ACP, 0, wPath, -1, path, MAX_PATH, NULL, NULL);
+    TRACE("%p %p %s\n", psf, pidl, debugstr_a(path));
 
-       return ret;
+    return ret;
 }
 
 BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type)
 {
-       LPSHELLFOLDER psfParent, lsf = psf;
-       HRESULT ret = NO_ERROR;
-       LPCITEMIDLIST pidllast;
-       STRRET strret;
-       DWORD flag;
-
-       TRACE("%p %p %p %ld\n", psf, pidl, path, type);
-
-       if (!pidl || !path)
-         return FALSE;
-
-       if (!lsf)
-       {
-         ret = SHGetDesktopFolder(&lsf);
-         if (FAILED(ret))
-           return FALSE;
-       }
-
-       if (type >= 0 && type <= 2)
-       {
-         switch (type)
-         {
-           case ILGDN_FORPARSING:
-             flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
-             break;
-           case ILGDN_NORMAL:
-             flag = SHGDN_NORMAL;
-             break;
-           case ILGDN_INFOLDER:
-             flag = SHGDN_INFOLDER;
-             break;
-           default:
-             FIXME("Unknown type parameter = %lx\n", type);
-             flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
-             break;
-         }
-         if (!*(const WORD*)pidl || type == ILGDN_FORPARSING)
-         {
-           ret = IShellFolder_GetDisplayNameOf(lsf, pidl, flag, &strret);
-           if (SUCCEEDED(ret))
-           {
-             ret = StrRetToStrNW(path, MAX_PATH, &strret, pidl);
-           }
-         }
-         else
-         {
-           ret = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidllast);
-           if (SUCCEEDED(ret))
-           {
-             ret = IShellFolder_GetDisplayNameOf(psfParent, pidllast, flag, &strret);
-             if (SUCCEEDED(ret))
-             {
-               ret = StrRetToStrNW(path, MAX_PATH, &strret, pidllast);
-             }
-             IShellFolder_Release(psfParent);
-           }
-         }
-       }
-
-       TRACE("%p %p %s\n", psf, pidl, debugstr_w(path));
-
-       if (!psf)
-         IShellFolder_Release(lsf);
-       return SUCCEEDED(ret);
+    LPSHELLFOLDER psfParent, lsf = psf;
+    HRESULT ret = NO_ERROR;
+    LPCITEMIDLIST pidllast;
+    STRRET strret;
+    DWORD flag;
+
+    TRACE("%p %p %p %ld\n", psf, pidl, path, type);
+
+    if (!pidl || !path)
+        return FALSE;
+
+    if (!lsf)
+    {
+        ret = SHGetDesktopFolder(&lsf);
+        if (FAILED(ret))
+            return FALSE;
+    }
+
+    if (type >= 0 && type <= 2)
+    {
+        switch (type)
+        {
+        case ILGDN_FORPARSING:
+            flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
+            break;
+        case ILGDN_NORMAL:
+            flag = SHGDN_NORMAL;
+            break;
+        case ILGDN_INFOLDER:
+            flag = SHGDN_INFOLDER;
+            break;
+        default:
+            FIXME("Unknown type parameter = %lx\n", type);
+            flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR;
+            break;
+        }
+        if (!*(const WORD*)pidl || type == ILGDN_FORPARSING)
+        {
+            ret = IShellFolder_GetDisplayNameOf(lsf, pidl, flag, &strret);
+            if (SUCCEEDED(ret))
+            {
+                ret = StrRetToStrNW(path, MAX_PATH, &strret, pidl);
+            }
+        }
+        else
+        {
+            ret = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidllast);
+            if (SUCCEEDED(ret))
+            {
+                ret = IShellFolder_GetDisplayNameOf(psfParent, pidllast, flag, &strret);
+                if (SUCCEEDED(ret))
+                {
+                    ret = StrRetToStrNW(path, MAX_PATH, &strret, pidllast);
+                }
+                IShellFolder_Release(psfParent);
+            }
+        }
+    }
+
+    TRACE("%p %p %s\n", psf, pidl, debugstr_w(path));
+
+    if (!psf)
+        IShellFolder_Release(lsf);
+    return SUCCEEDED(ret);
 }
 
 BOOL WINAPI ILGetDisplayNameEx(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPVOID path, DWORD type)
 {
-       TRACE_(shell)("%p %p %p %ld\n", psf, pidl, path, type);
-       if (SHELL_OsIsUnicode())
-         return ILGetDisplayNameExW(psf, pidl, path, type);
-       return ILGetDisplayNameExA(psf, pidl, path, type);
+    TRACE_(shell)("%p %p %p %ld\n", psf, pidl, path, type);
+
+    if (SHELL_OsIsUnicode())
+        return ILGetDisplayNameExW(psf, pidl, path, type);
+    return ILGetDisplayNameExA(psf, pidl, path, type);
 }
 
 /*************************************************************************
- * ILGetDisplayName                    [SHELL32.15]
+ * ILGetDisplayName            [SHELL32.15]
  */
 BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl, LPVOID path)
 {
-       TRACE_(shell)("%p %p\n", pidl, path);
-       if (SHELL_OsIsUnicode())
-         return ILGetDisplayNameExW(NULL, pidl, path, ILGDN_FORPARSING);
-       return ILGetDisplayNameExA(NULL, pidl, path, ILGDN_FORPARSING);
+    TRACE_(shell)("%p %p\n", pidl, path);
+
+    if (SHELL_OsIsUnicode())
+        return ILGetDisplayNameExW(NULL, pidl, path, ILGDN_FORPARSING);
+    return ILGetDisplayNameExA(NULL, pidl, path, ILGDN_FORPARSING);
 }
 
 /*************************************************************************
@@ -185,20 +187,21 @@ BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl, LPVOID path)
  */
 LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
 {
-       LPCITEMIDLIST   pidlLast = pidl;
+    LPCITEMIDLIST   pidlLast = pidl;
 
-       TRACE("(pidl=%p)\n",pidl);
+    TRACE("(pidl=%p)\n",pidl);
 
-       if (!pidl)
-         return NULL;
+    if (!pidl)
+        return NULL;
 
-       while (pidl->mkid.cb)
-       {
-         pidlLast = pidl;
-         pidl = ILGetNext(pidl);
-       }
-       return (LPITEMIDLIST)pidlLast;
+    while (pidl->mkid.cb)
+    {
+        pidlLast = pidl;
+        pidl = ILGetNext(pidl);
+    }
+    return (LPITEMIDLIST)pidlLast;
 }
+
 /*************************************************************************
  * ILRemoveLastID [SHELL32.17]
  *
@@ -207,12 +210,12 @@ LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
  */
 BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
 {
-       TRACE_(shell)("pidl=%p\n",pidl);
+    TRACE_(shell)("pidl=%p\n",pidl);
 
-       if (!pidl || !pidl->mkid.cb)
-         return 0;
-       ILFindLastID(pidl)->mkid.cb = 0;
-       return 1;
+    if (!pidl || !pidl->mkid.cb)
+        return 0;
+    ILFindLastID(pidl)->mkid.cb = 0;
+    return 1;
 }
 
 /*************************************************************************
@@ -222,22 +225,24 @@ BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
  *    duplicate an idlist
  */
 LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
-{ DWORD    len;
-  LPITEMIDLIST  newpidl;
+{
+    DWORD    len;
+    LPITEMIDLIST  newpidl;
 
-  if (!pidl)
-    return NULL;
+    if (!pidl)
+        return NULL;
 
-  len = ILGetSize(pidl);
-  newpidl = (LPITEMIDLIST)SHAlloc(len);
-  if (newpidl)
-    memcpy(newpidl,pidl,len);
+    len = ILGetSize(pidl);
+    newpidl = (LPITEMIDLIST)SHAlloc(len);
+    if (newpidl)
+        memcpy(newpidl,pidl,len);
 
-  TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
-  pdump(pidl);
+    TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
+    pdump(pidl);
 
-  return newpidl;
+    return newpidl;
 }
+
 /*************************************************************************
  * ILCloneFirst [SHELL32.19]
  *
@@ -245,27 +250,28 @@ LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
  *  duplicates the first idlist of a complex pidl
  */
 LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
-{      DWORD len;
-       LPITEMIDLIST pidlNew = NULL;
+{
+    DWORD len;
+    LPITEMIDLIST pidlNew = NULL;
 
-       TRACE("pidl=%p \n",pidl);
-       pdump(pidl);
+    TRACE("pidl=%p \n",pidl);
+    pdump(pidl);
 
-       if (pidl)
-       {
-         len = pidl->mkid.cb;
-         pidlNew = (LPITEMIDLIST) SHAlloc (len+2);
-         if (pidlNew)
-         {
-           memcpy(pidlNew,pidl,len+2);         /* 2 -> mind a desktop pidl */
+    if (pidl)
+    {
+        len = pidl->mkid.cb;
+        pidlNew = (LPITEMIDLIST) SHAlloc (len+2);
+        if (pidlNew)
+        {
+            memcpy(pidlNew,pidl,len+2);        /* 2 -> mind a desktop pidl */
 
-           if (len)
-             ILGetNext(pidlNew)->mkid.cb = 0x00;
-         }
-       }
-       TRACE("-- newpidl=%p\n",pidlNew);
+            if (len)
+                ILGetNext(pidlNew)->mkid.cb = 0x00;
+        }
+    }
+    TRACE("-- newpidl=%p\n",pidlNew);
 
-       return pidlNew;
+    return pidlNew;
 }
 
 /*************************************************************************
@@ -275,51 +281,58 @@ LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
  *   the first two bytes are the len, the pidl is following then
  */
 HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl)
-{      WORD            wLen = 0;
-       DWORD           dwBytesRead;
-       HRESULT         ret = E_FAIL;
-
-
-       TRACE_(shell)("%p %p\n", pStream ,  ppPidl);
-
-       if (*ppPidl)
-       { SHFree(*ppPidl);
-         *ppPidl = NULL;
-       }
-
-       IStream_AddRef (pStream);
-
-       if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
-       {
-         TRACE("PIDL length is %d\n", wLen);
-         if (wLen != 0) {
-           *ppPidl = SHAlloc (wLen);
-           if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead))) {
-               TRACE("Stream read OK\n");
-               ret = S_OK;
-           } else {
-               WARN("reading pidl failed\n");
-               SHFree(*ppPidl);
-               *ppPidl = NULL;
-           }
-         } else {
-           *ppPidl = NULL;
-           ret = S_OK;
-         }
-       }
-
-       /* we are not yet fully compatible */
-       if (*ppPidl && !pcheck(*ppPidl))
-       {
-         WARN("Check failed\n");
-         SHFree(*ppPidl);
-         *ppPidl = NULL;
-       }
-
-       
-       IStream_Release (pStream);
-       TRACE("done\n");
-       return ret;
+{
+    WORD        wLen = 0;
+    DWORD       dwBytesRead;
+    HRESULT     ret = E_FAIL;
+
+
+    TRACE_(shell)("%p %p\n", pStream ,  ppPidl);
+
+    if (*ppPidl)
+    {
+        SHFree(*ppPidl);
+        *ppPidl = NULL;
+    }
+
+    IStream_AddRef (pStream);
+
+    if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
+    {
+        TRACE("PIDL length is %d\n", wLen);
+        if (wLen != 0)
+        {
+            *ppPidl = SHAlloc (wLen);
+            if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead)))
+            {
+                TRACE("Stream read OK\n");
+                ret = S_OK;
+            }
+            else
+            {
+                WARN("reading pidl failed\n");
+                SHFree(*ppPidl);
+                *ppPidl = NULL;
+            }
+        }
+        else
+        {
+            *ppPidl = NULL;
+            ret = S_OK;
+        }
+    }
+
+    /* we are not yet fully compatible */
+    if (*ppPidl && !pcheck(*ppPidl))
+    {
+        WARN("Check failed\n");
+        SHFree(*ppPidl);
+        *ppPidl = NULL;
+    }
+
+    IStream_Release (pStream);
+    TRACE("done\n");
+    return ret;
 }
 
 /*************************************************************************
@@ -330,30 +343,29 @@ HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl)
  */
 HRESULT WINAPI ILSaveToStream (IStream * pStream, LPCITEMIDLIST pPidl)
 {
-       LPCITEMIDLIST   pidl;
-       WORD            wLen = 0;
-       HRESULT         ret = E_FAIL;
+    LPCITEMIDLIST    pidl;
+    WORD        wLen = 0;
+    HRESULT        ret = E_FAIL;
 
-       TRACE_(shell)("%p %p\n", pStream, pPidl);
+    TRACE_(shell)("%p %p\n", pStream, pPidl);
 
-       IStream_AddRef (pStream);
+    IStream_AddRef (pStream);
 
-       pidl = pPidl;
-        while (pidl->mkid.cb)
-        {
-          wLen += sizeof(WORD) + pidl->mkid.cb;
-          pidl = ILGetNext(pidl);
-        }
+    pidl = pPidl;
+    while (pidl->mkid.cb)
+    {
+        wLen += sizeof(WORD) + pidl->mkid.cb;
+        pidl = ILGetNext(pidl);
+    }
 
-       if (SUCCEEDED(IStream_Write(pStream, (LPVOID)&wLen, 2, NULL)))
-       {
-         if (SUCCEEDED(IStream_Write(pStream, pPidl, wLen, NULL)))
-         { ret = S_OK;
-         }
-       }
-       IStream_Release (pStream);
+    if (SUCCEEDED(IStream_Write(pStream, (LPVOID)&wLen, 2, NULL)))
+    {
+        if (SUCCEEDED(IStream_Write(pStream, pPidl, wLen, NULL)))
+            ret = S_OK;
+    }
+    IStream_Release (pStream);
 
-       return ret;
+    return ret;
 }
 
 /*************************************************************************
@@ -375,45 +387,37 @@ HRESULT WINAPI ILSaveToStream (IStream * pStream, LPCITEMIDLIST pPidl)
  */
 HRESULT WINAPI SHILCreateFromPathA(LPCSTR path, LPITEMIDLIST * ppidl, DWORD * attributes)
 {
-       LPSHELLFOLDER sf;
-       WCHAR lpszDisplayName[MAX_PATH];
-       DWORD pchEaten;
-       HRESULT ret = E_FAIL;
+    WCHAR lpszDisplayName[MAX_PATH];
 
-       TRACE_(shell)("%s %p 0x%08lx\n", path, ppidl, attributes ? *attributes : 0);
+    TRACE_(shell)("%s %p 0x%08lx\n", path, ppidl, attributes ? *attributes : 0);
 
-       if (!MultiByteToWideChar(CP_ACP, 0, path, -1, lpszDisplayName, MAX_PATH))
-         lpszDisplayName[MAX_PATH-1] = 0;
+    if (!MultiByteToWideChar(CP_ACP, 0, path, -1, lpszDisplayName, MAX_PATH))
+        lpszDisplayName[MAX_PATH-1] = 0;
 
-       if (SUCCEEDED (SHGetDesktopFolder(&sf)))
-       {
-         ret = IShellFolder_ParseDisplayName(sf, 0, NULL, lpszDisplayName, &pchEaten, ppidl, attributes);
-         IShellFolder_Release(sf);
-       }
-       return ret;
+    return SHILCreateFromPathW(lpszDisplayName, ppidl, attributes);
 }
 
 HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST * ppidl, DWORD * attributes)
 {
-       LPSHELLFOLDER sf;
-       DWORD pchEaten;
-       HRESULT ret = E_FAIL;
+    LPSHELLFOLDER sf;
+    DWORD pchEaten;
+    HRESULT ret = E_FAIL;
 
-       TRACE_(shell)("%s %p 0x%08lx\n", debugstr_w(path), ppidl, attributes ? *attributes : 0);
+    TRACE_(shell)("%s %p 0x%08lx\n", debugstr_w(path), ppidl, attributes ? *attributes : 0);
 
-       if (SUCCEEDED (SHGetDesktopFolder(&sf)))
-       {
-         ret = IShellFolder_ParseDisplayName(sf, 0, NULL, (LPWSTR)path, &pchEaten, ppidl, attributes);
-         IShellFolder_Release(sf);
-       }
-       return ret;
+    if (SUCCEEDED (SHGetDesktopFolder(&sf)))
+    {
+        ret = IShellFolder_ParseDisplayName(sf, 0, NULL, (LPWSTR)path, &pchEaten, ppidl, attributes);
+        IShellFolder_Release(sf);
+    }
+    return ret;
 }
 
 HRESULT WINAPI SHILCreateFromPathAW (LPCVOID path, LPITEMIDLIST * ppidl, DWORD * attributes)
 {
-       if ( SHELL_OsIsUnicode())
-         return SHILCreateFromPathW (path, ppidl, attributes);
-       return SHILCreateFromPathA (path, ppidl, attributes);
+    if ( SHELL_OsIsUnicode())
+        return SHILCreateFromPathW (path, ppidl, attributes);
+    return SHILCreateFromPathA (path, ppidl, attributes);
 }
 
 /*************************************************************************
@@ -422,9 +426,9 @@ HRESULT WINAPI SHILCreateFromPathAW (LPCVOID path, LPITEMIDLIST * ppidl, DWORD *
  * Create an ItemIDList to one of the special folders.
 
  * PARAMS
- *  hwndOwner  [in]
- *  nFolder            [in]    CSIDL_xxxxx
- *  fCreate            [in]    Create folder if it does not exist
+ *  hwndOwner    [in]
+ *  nFolder      [in]    CSIDL_xxxxx
+ *  fCreate      [in]    Create folder if it does not exist
  *
  * RETURNS
  *  Success: The newly created pidl
@@ -436,14 +440,15 @@ HRESULT WINAPI SHILCreateFromPathAW (LPCVOID path, LPITEMIDLIST * ppidl, DWORD *
  *  shells IMalloc interface, aka ILFree.
  */
 LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, DWORD nFolder, BOOL fCreate)
-{      LPITEMIDLIST ppidl;
-       TRACE_(shell)("(hwnd=%p,csidl=0x%lx,%s).\n", hwndOwner, nFolder, fCreate ? "T" : "F");
+{
+    LPITEMIDLIST ppidl;
+    TRACE_(shell)("(hwnd=%p,csidl=0x%lx,%s).\n", hwndOwner, nFolder, fCreate ? "T" : "F");
 
-       if (fCreate)
-         nFolder |= CSIDL_FLAG_CREATE;
+    if (fCreate)
+        nFolder |= CSIDL_FLAG_CREATE;
 
-       SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
-       return ppidl;
+    SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
+    return ppidl;
 }
 
 /*************************************************************************
@@ -461,21 +466,22 @@ LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner, DWORD nFolder, BOOL fCr
  *  exported by ordinal.
  */
 LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl)
-{      DWORD    len;
-       LPITEMIDLIST  newpidl;
+{
+    DWORD    len;
+    LPITEMIDLIST  newpidl;
 
-       if (!pidl)
-         return NULL;
+    if (!pidl)
+        return NULL;
 
-       len = ILGetSize(pidl);
-       newpidl = (LPITEMIDLIST)Alloc(len);
-       if (newpidl)
-         memcpy(newpidl,pidl,len);
+    len = ILGetSize(pidl);
+    newpidl = (LPITEMIDLIST)Alloc(len);
+    if (newpidl)
+        memcpy(newpidl,pidl,len);
 
-       TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
-       pdump(pidl);
+    TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
+    pdump(pidl);
 
-       return newpidl;
+    return newpidl;
 }
 
 /*************************************************************************
@@ -484,42 +490,45 @@ LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl)
  */
 BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
-       char    szData1[MAX_PATH];
-       char    szData2[MAX_PATH];
+    char    szData1[MAX_PATH];
+    char    szData2[MAX_PATH];
 
-       LPCITEMIDLIST pidltemp1 = pidl1;
-       LPCITEMIDLIST pidltemp2 = pidl2;
+    LPCITEMIDLIST pidltemp1 = pidl1;
+    LPCITEMIDLIST pidltemp2 = pidl2;
 
-       TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
+    TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
 
-       /* explorer reads from registry directly (StreamMRU),
-          so we can only check here */
-       if ((!pcheck (pidl1)) || (!pcheck (pidl2))) return FALSE;
+    /*
+     * Explorer reads from registry directly (StreamMRU),
+     * so we can only check here
+     */
+    if (!pcheck(pidl1) || !pcheck (pidl2))
+        return FALSE;
 
-       pdump (pidl1);
-       pdump (pidl2);
+    pdump (pidl1);
+    pdump (pidl2);
 
-       if ( (!pidl1) || (!pidl2) ) return FALSE;
+    if (!pidl1 || !pidl2)
+        return FALSE;
 
-       while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
-       {
-           _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
-           _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
+    while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
+    {
+        _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
+        _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
 
-           if (strcasecmp ( szData1, szData2 )!=0 )
-             return FALSE;
+        if (strcasecmp( szData1, szData2 ))
+            return FALSE;
 
-           pidltemp1 = ILGetNext(pidltemp1);
-           pidltemp2 = ILGetNext(pidltemp2);
-       }
+        pidltemp1 = ILGetNext(pidltemp1);
+        pidltemp2 = ILGetNext(pidltemp2);
+    }
 
-       if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb)
-       {
-         return TRUE;
-       }
+    if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb)
+        return TRUE;
 
-       return FALSE;
+    return FALSE;
 }
+
 /*************************************************************************
  * ILIsParent                [SHELL32.23]
  *
@@ -542,35 +551,37 @@ BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
  */
 BOOL WINAPI ILIsParent(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL bImmediate)
 {
-       char    szData1[MAX_PATH];
-       char    szData2[MAX_PATH];
-
-       LPCITEMIDLIST pParent = pidlParent;
-       LPCITEMIDLIST pChild = pidlChild;
+    char    szData1[MAX_PATH];
+    char    szData2[MAX_PATH];
+    LPCITEMIDLIST pParent = pidlParent;
+    LPCITEMIDLIST pChild = pidlChild;
 
-       TRACE("%p %p %x\n", pidlParent, pidlChild, bImmediate);
+    TRACE("%p %p %x\n", pidlParent, pidlChild, bImmediate);
 
-       if (!pParent || !pChild) return FALSE;
+    if (!pParent || !pChild)
+        return FALSE;
 
-       while (pParent->mkid.cb && pChild->mkid.cb)
-       {
-         _ILSimpleGetText(pParent, szData1, MAX_PATH);
-         _ILSimpleGetText(pChild, szData2, MAX_PATH);
+    while (pParent->mkid.cb && pChild->mkid.cb)
+    {
+        _ILSimpleGetText(pParent, szData1, MAX_PATH);
+        _ILSimpleGetText(pChild, szData2, MAX_PATH);
 
-         if (strcasecmp ( szData1, szData2 )!=0 )
-           return FALSE;
+        if (strcasecmp( szData1, szData2 ))
+            return FALSE;
 
-         pParent = ILGetNext(pParent);
-         pChild = ILGetNext(pChild);
-       }
+        pParent = ILGetNext(pParent);
+        pChild = ILGetNext(pChild);
+    }
 
-       if ( pParent->mkid.cb || ! pChild->mkid.cb) /* child shorter or has equal length to parent */
-         return FALSE;
+    /* child shorter or has equal length to parent */
+    if (pParent->mkid.cb || !pChild->mkid.cb)
+        return FALSE;
 
-       if ( ILGetNext(pChild)->mkid.cb && bImmediate) /* not immediate descent */
-         return FALSE;
+    /* not immediate descent */
+    if ( ILGetNext(pChild)->mkid.cb && bImmediate)
+        return FALSE;
 
-       return TRUE;
+    return TRUE;
 }
 
 /*************************************************************************
@@ -594,49 +605,47 @@ BOOL WINAPI ILIsParent(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild, BOOL b
  */
 LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
-       char    szData1[MAX_PATH];
-       char    szData2[MAX_PATH];
+    char    szData1[MAX_PATH];
+    char    szData2[MAX_PATH];
 
-       LPCITEMIDLIST pidltemp1 = pidl1;
-       LPCITEMIDLIST pidltemp2 = pidl2;
-       LPCITEMIDLIST ret=NULL;
+    LPCITEMIDLIST pidltemp1 = pidl1;
+    LPCITEMIDLIST pidltemp2 = pidl2;
+    LPCITEMIDLIST ret=NULL;
 
-       TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
+    TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
 
-       /* explorer reads from registry directly (StreamMRU),
-          so we can only check here */
-       if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
-         return FALSE;
+    /* explorer reads from registry directly (StreamMRU),
+       so we can only check here */
+    if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
+        return FALSE;
 
-       pdump (pidl1);
-       pdump (pidl2);
+    pdump (pidl1);
+    pdump (pidl2);
 
-       if ( _ILIsDesktop(pidl1) )
-       {
-         ret = pidl2;
-       }
-       else
-       {
-         while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
-         {
-           _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
-           _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
+    if (_ILIsDesktop(pidl1))
+    {
+        ret = pidl2;
+    }
+    else
+    {
+        while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
+        {
+            _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
+            _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
 
-           if (strcasecmp(szData1,szData2))
-             break;
+            if (strcasecmp(szData1,szData2))
+                break;
 
-           pidltemp1 = ILGetNext(pidltemp1);
-           pidltemp2 = ILGetNext(pidltemp2);
-           ret = pidltemp2;
-         }
+            pidltemp1 = ILGetNext(pidltemp1);
+            pidltemp2 = ILGetNext(pidltemp2);
+            ret = pidltemp2;
+        }
 
-         if (pidltemp1->mkid.cb)
-         {
-           ret = NULL; /* elements of pidl1 left*/
-         }
-       }
-       TRACE_(shell)("--- %p\n", ret);
-       return (LPITEMIDLIST)ret; /* pidl 1 is shorter */
+        if (pidltemp1->mkid.cb)
+            ret = NULL; /* elements of pidl1 left*/
+    }
+    TRACE_(shell)("--- %p\n", ret);
+    return (LPITEMIDLIST)ret; /* pidl 1 is shorter */
 }
 
 /*************************************************************************
@@ -660,40 +669,40 @@ LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
  */
 LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
-       DWORD    len1,len2;
-       LPITEMIDLIST  pidlNew;
+    DWORD    len1,len2;
+    LPITEMIDLIST  pidlNew;
 
-       TRACE("pidl=%p pidl=%p\n",pidl1,pidl2);
+    TRACE("pidl=%p pidl=%p\n",pidl1,pidl2);
 
-       if(!pidl1 && !pidl2) return NULL;
+    if (!pidl1 && !pidl2) return NULL;
 
-       pdump (pidl1);
-       pdump (pidl2);
+    pdump (pidl1);
+    pdump (pidl2);
 
-       if(!pidl1)
-       {
-         pidlNew = ILClone(pidl2);
-         return pidlNew;
-       }
+    if (!pidl1)
+    {
+        pidlNew = ILClone(pidl2);
+        return pidlNew;
+    }
 
-       if(!pidl2)
-       {
-         pidlNew = ILClone(pidl1);
-         return pidlNew;
-       }
+    if (!pidl2)
+    {
+        pidlNew = ILClone(pidl1);
+        return pidlNew;
+    }
 
-       len1  = ILGetSize(pidl1)-2;
-       len2  = ILGetSize(pidl2);
-       pidlNew  = SHAlloc(len1+len2);
+    len1  = ILGetSize(pidl1)-2;
+    len2  = ILGetSize(pidl2);
+    pidlNew  = SHAlloc(len1+len2);
 
-       if (pidlNew)
-       {
-         memcpy(pidlNew,pidl1,len1);
-         memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
-       }
+    if (pidlNew)
+    {
+        memcpy(pidlNew,pidl1,len1);
+        memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
+    }
 
-       /*  TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
-       return pidlNew;
+    /*  TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
+    return pidlNew;
 }
 
 /*************************************************************************
@@ -703,57 +712,61 @@ LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
  */
 HRESULT WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPCITEMIDLIST pidlSimple, LPITEMIDLIST *pidlReal)
 {
-       IDataObject* pDataObj;
-       HRESULT hr = IShellFolder_GetUIObjectOf(lpsf, 0, 1, &pidlSimple, &IID_IDataObject, 0, (LPVOID*)&pDataObj);
+    IDataObject* pDataObj;
+    HRESULT hr;
 
-       if (SUCCEEDED(hr)) {
-            STGMEDIUM medium;
-            FORMATETC fmt;
+    hr = IShellFolder_GetUIObjectOf(lpsf, 0, 1, &pidlSimple,
+                             &IID_IDataObject, 0, (LPVOID*)&pDataObj);
+    if (SUCCEEDED(hr))
+    {
+        STGMEDIUM medium;
+        FORMATETC fmt;
 
-            fmt.cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
-            fmt.ptd = NULL;
-            fmt.dwAspect = DVASPECT_CONTENT;
-            fmt.lindex = -1;
-            fmt.tymed = TYMED_HGLOBAL;
+        fmt.cfFormat = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
+        fmt.ptd = NULL;
+        fmt.dwAspect = DVASPECT_CONTENT;
+        fmt.lindex = -1;
+        fmt.tymed = TYMED_HGLOBAL;
 
-           hr = IDataObject_GetData(pDataObj, &fmt, &medium);
+        hr = IDataObject_GetData(pDataObj, &fmt, &medium);
 
-           IDataObject_Release(pDataObj);
+        IDataObject_Release(pDataObj);
 
-           if (SUCCEEDED(hr)) {
-               /*assert(pida->cidl==1);*/
-               LPIDA pida = (LPIDA)GlobalLock(medium.u.hGlobal);
+        if (SUCCEEDED(hr))
+        {
+            /*assert(pida->cidl==1);*/
+            LPIDA pida = (LPIDA)GlobalLock(medium.u.hGlobal);
 
-               LPCITEMIDLIST pidl_folder = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
-               LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
+            LPCITEMIDLIST pidl_folder = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]);
+            LPCITEMIDLIST pidl_child = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1]);
 
-               *pidlReal = ILCombine(pidl_folder, pidl_child);
+            *pidlReal = ILCombine(pidl_folder, pidl_child);
 
-               if (!*pidlReal)
-                       hr = E_OUTOFMEMORY;
+            if (!*pidlReal)
+                hr = E_OUTOFMEMORY;
 
-               GlobalUnlock(medium.u.hGlobal);
-               GlobalFree(medium.u.hGlobal);
-           }
-       }
+            GlobalUnlock(medium.u.hGlobal);
+            GlobalFree(medium.u.hGlobal);
+        }
+    }
 
-       return hr;
+    return hr;
 }
 
 /*************************************************************************
  *  SHLogILFromFSIL [SHELL32.95]
  *
  * NOTES
- *  pild = CSIDL_DESKTOP       ret = 0
- *  pild = CSIDL_DRIVES                ret = 0
+ *  pild = CSIDL_DESKTOP    ret = 0
+ *  pild = CSIDL_DRIVES     ret = 0
  */
 LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
 {
-       FIXME("(pidl=%p)\n",pidl);
+    FIXME("(pidl=%p)\n",pidl);
 
-       pdump(pidl);
+    pdump(pidl);
 
-       return 0;
+    return 0;
 }
 
 /*************************************************************************
@@ -772,18 +785,20 @@ LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
  */
 UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
 {
-       LPCSHITEMID si = &(pidl->mkid);
-       UINT len=0;
+    LPCSHITEMID si = &(pidl->mkid);
+    UINT len=0;
 
-       if (pidl)
-       { while (si->cb)
-         { len += si->cb;
-           si  = (LPCSHITEMID)(((const BYTE*)si)+si->cb);
-         }
-         len += 2;
-       }
-       TRACE("pidl=%p size=%u\n",pidl, len);
-       return len;
+    if (pidl)
+    {
+        while (si->cb)
+        {
+            len += si->cb;
+            si  = (LPCSHITEMID)(((const BYTE*)si)+si->cb);
+        }
+        len += 2;
+    }
+    TRACE("pidl=%p size=%u\n",pidl, len);
+    return len;
 }
 
 /*************************************************************************
@@ -804,21 +819,21 @@ UINT WINAPI ILGetSize(LPCITEMIDLIST pidl)
  */
 LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
 {
-       WORD len;
+    WORD len;
 
-       TRACE("%p\n", pidl);
+    TRACE("%p\n", pidl);
 
-       if(pidl)
-       {
-         len =  pidl->mkid.cb;
-         if (len)
-         {
-           pidl = (LPCITEMIDLIST) (((const BYTE*)pidl)+len);
-           TRACE("-- %p\n", pidl);
-           return (LPITEMIDLIST)pidl;
-         }
-       }
-       return NULL;
+    if (pidl)
+    {
+        len =  pidl->mkid.cb;
+        if (len)
+        {
+            pidl = (LPCITEMIDLIST) (((const BYTE*)pidl)+len);
+            TRACE("-- %p\n", pidl);
+            return (LPITEMIDLIST)pidl;
+        }
+    }
+    return NULL;
 }
 
 /*************************************************************************
@@ -838,32 +853,28 @@ LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
  */
 LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
 {
-       LPITEMIDLIST idlRet;
+    LPITEMIDLIST idlRet;
 
-       WARN("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);
+    WARN("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);
 
-       pdump (pidl);
-       pdump (item);
+    pdump (pidl);
+    pdump (item);
 
-       if (_ILIsDesktop(pidl))
-       {
-          idlRet = ILClone(item);
-          if (pidl)
-            SHFree (pidl);
-          return idlRet;
-       }
+    if (_ILIsDesktop(pidl))
+    {
+        idlRet = ILClone(item);
+        if (pidl)
+            SHFree (pidl);
+        return idlRet;
+    }
 
-       if (bEnd)
-       {
-         idlRet = ILCombine(pidl, item);
-       }
-       else
-       {
-         idlRet = ILCombine(item, pidl);
-       }
+    if (bEnd)
+        idlRet = ILCombine(pidl, item);
+    else
+        idlRet = ILCombine(item, pidl);
 
-       SHFree(pidl);
-       return idlRet;
+    SHFree(pidl);
+    return idlRet;
 }
 
 /*************************************************************************
@@ -879,8 +890,9 @@ LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
  */
 void WINAPI ILFree(LPITEMIDLIST pidl)
 {
-       TRACE("(pidl=%p)\n",pidl);
-       if(pidl) SHFree(pidl);
+    TRACE("(pidl=%p)\n",pidl);
+    if (pidl)
+        SHFree(pidl);
 }
 
 /*************************************************************************
@@ -896,10 +908,10 @@ void WINAPI ILFree(LPITEMIDLIST pidl)
  */
 void WINAPI ILGlobalFree( LPITEMIDLIST pidl)
 {
-       TRACE("%p\n", pidl);
+    TRACE("%p\n", pidl);
 
-       if(!pidl) return;
-       Free(pidl);
+    if (pidl)
+        Free(pidl);
 }
 
 /*************************************************************************
@@ -916,16 +928,15 @@ void WINAPI ILGlobalFree( LPITEMIDLIST pidl)
  * NOTES
  *  exported by ordinal.
  */
-
 LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
 {
-       LPITEMIDLIST pidlnew = NULL;
+    LPITEMIDLIST pidlnew = NULL;
 
-       TRACE_(shell)("%s\n", debugstr_a(path));
+    TRACE_(shell)("%s\n", debugstr_a(path));
 
-       if (SUCCEEDED(SHILCreateFromPathA(path, &pidlnew, NULL)))
-         return pidlnew;
-       return NULL;
+    if (SUCCEEDED(SHILCreateFromPathA(path, &pidlnew, NULL)))
+        return pidlnew;
+    return NULL;
 }
 
 /*************************************************************************
@@ -933,13 +944,13 @@ LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
  */
 LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
 {
-       LPITEMIDLIST pidlnew = NULL;
+    LPITEMIDLIST pidlnew = NULL;
 
-       TRACE_(shell)("%s\n", debugstr_w(path));
+    TRACE_(shell)("%s\n", debugstr_w(path));
 
-       if (SUCCEEDED(SHILCreateFromPathW(path, &pidlnew, NULL)))
-         return pidlnew;
-       return NULL;
+    if (SUCCEEDED(SHILCreateFromPathW(path, &pidlnew, NULL)))
+        return pidlnew;
+    return NULL;
 }
 
 /*************************************************************************
@@ -947,9 +958,9 @@ LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
  */
 LPITEMIDLIST WINAPI ILCreateFromPathAW (LPCVOID path)
 {
-       if ( SHELL_OsIsUnicode())
-         return ILCreateFromPathW (path);
-       return ILCreateFromPathA (path);
+    if ( SHELL_OsIsUnicode())
+        return ILCreateFromPathW (path);
+    return ILCreateFromPathA (path);
 }
 
 /*************************************************************************
@@ -982,42 +993,40 @@ LPITEMIDLIST WINAPI ILCreateFromPathAW (LPCVOID path)
 static HRESULT WINAPI _ILParsePathW(LPCWSTR path, LPWIN32_FIND_DATAW lpFindFile,
                              BOOL bBindCtx, LPITEMIDLIST *ppidl, LPDWORD prgfInOut)
 {
-       LPSHELLFOLDER pSF = NULL;
-       LPBC pBC = NULL;
-       HRESULT ret;
+    LPSHELLFOLDER pSF = NULL;
+    LPBC pBC = NULL;
+    HRESULT ret;
 
-       TRACE("%s %p %d (%p)->%p (%p)->0x%lx\n", debugstr_w(path), lpFindFile, bBindCtx,
-                                                ppidl, ppidl ? *ppidl : NULL,
-                                                prgfInOut, prgfInOut ? *prgfInOut : 0);
+    TRACE("%s %p %d (%p)->%p (%p)->0x%lx\n", debugstr_w(path), lpFindFile, bBindCtx,
+                                             ppidl, ppidl ? *ppidl : NULL,
+                                             prgfInOut, prgfInOut ? *prgfInOut : 0);
 
-       ret = SHGetDesktopFolder(&pSF);
-       if (FAILED(ret))
-       {
-         return ret;
-       }
+    ret = SHGetDesktopFolder(&pSF);
+    if (FAILED(ret))
+        return ret;
 
-       if (lpFindFile || bBindCtx)
-         ret = IFileSystemBindData_Constructor(lpFindFile, &pBC);
+    if (lpFindFile || bBindCtx)
+        ret = IFileSystemBindData_Constructor(lpFindFile, &pBC);
 
-       if (SUCCEEDED(ret))
-       {
-         ret = IShellFolder_ParseDisplayName(pSF, 0, pBC, (LPOLESTR)path, NULL, ppidl, prgfInOut);
-       }
+    if (SUCCEEDED(ret))
+    {
+        ret = IShellFolder_ParseDisplayName(pSF, 0, pBC, (LPOLESTR)path, NULL, ppidl, prgfInOut);
+    }
 
-       if (pBC)
-       {
-         IBindCtx_Release(pBC);
-         pBC = NULL;
-       }
+    if (pBC)
+    {
+        IBindCtx_Release(pBC);
+        pBC = NULL;
+    }
 
-       IShellFolder_Release(pSF);
+    IShellFolder_Release(pSF);
 
-       if (!SUCCEEDED(ret) && ppidl)
-         *ppidl = NULL;
+    if (!SUCCEEDED(ret) && ppidl)
+        *ppidl = NULL;
 
-       TRACE("%s %p 0x%lx\n", debugstr_w(path), ppidl ? *ppidl : NULL, prgfInOut ? *prgfInOut : 0);
+    TRACE("%s %p 0x%lx\n", debugstr_w(path), ppidl ? *ppidl : NULL, prgfInOut ? *prgfInOut : 0);
 
-       return ret;
+    return ret;
 }
 
 /*************************************************************************
@@ -1064,20 +1073,20 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath)
 
 LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
 {
-       LPITEMIDLIST pidl = NULL;
+    LPITEMIDLIST pidl = NULL;
 
-       TRACE("%s\n", debugstr_w(lpszPath));
+    TRACE("%s\n", debugstr_w(lpszPath));
 
-       _ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
-       TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
-       return pidl;
+    _ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
+    TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
+    return pidl;
 }
 
 LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath)
 {
-       if ( SHELL_OsIsUnicode())
-         return SHSimpleIDListFromPathW (lpszPath);
-       return SHSimpleIDListFromPathA (lpszPath);
+    if ( SHELL_OsIsUnicode())
+        return SHSimpleIDListFromPathW (lpszPath);
+    return SHSimpleIDListFromPathA (lpszPath);
 }
 
 /*************************************************************************
@@ -1087,110 +1096,117 @@ LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath)
  *  the pidl can be a simple one. since we can't get the path out of the pidl
  *  we have to take all data from the pidl
  */
-HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
+HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl,
+                                    int nFormat, LPVOID dest, int len)
 {
-       TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
+    LPSTR filename, shortname;
+    WIN32_FIND_DATAA * pfd;
 
-       pdump(pidl);
-       if (!psf || !dest )  return E_INVALIDARG;
+    TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
 
-       switch (nFormat)
-       {
-         case SHGDFIL_FINDDATA:
-           {
-              LPSTR filename, shortname;
-              WIN32_FIND_DATAA * pfd = dest;
+    pdump(pidl);
+    if (!psf || !dest)
+        return E_INVALIDARG;
 
-              if (_ILIsDrive(pidl))
-                  return E_INVALIDARG;
+    switch (nFormat)
+    {
+    case SHGDFIL_FINDDATA:
+        pfd = dest;
 
-              if (len < (int)sizeof(WIN32_FIND_DATAA)) return E_INVALIDARG;
+        if (_ILIsDrive(pidl))
+            return E_INVALIDARG;
 
-              ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
-              _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
-              pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
-              pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
+        if (len < sizeof(WIN32_FIND_DATAA))
+            return E_INVALIDARG;
 
-              filename = _ILGetTextPointer(pidl);
-              shortname = _ILGetSTextPointer(pidl);
+        ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
+        _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
+        pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
+        pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
 
-              if (filename)
-                  lstrcpynA(pfd->cFileName, filename, MAX_PATH);
-              else
-                  pfd->cFileName[0] = '\0';
+        filename = _ILGetTextPointer(pidl);
+        shortname = _ILGetSTextPointer(pidl);
 
-              if (shortname)
-                  lstrcpynA(pfd->cAlternateFileName, shortname, MAX_PATH);
-              else
-                  pfd->cAlternateFileName[0] = '\0';
-           }
-           return NOERROR;
+        if (filename)
+            lstrcpynA(pfd->cFileName, filename, MAX_PATH);
+        else
+            pfd->cFileName[0] = '\0';
 
-         case SHGDFIL_NETRESOURCE:
-         case SHGDFIL_DESCRIPTIONID:
-           FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
-           break;
+        if (shortname)
+            lstrcpynA(pfd->cAlternateFileName, shortname, MAX_PATH);
+        else
+            pfd->cAlternateFileName[0] = '\0';
+        return NOERROR;
 
-         default:
-           ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
-       }
+    case SHGDFIL_NETRESOURCE:
+    case SHGDFIL_DESCRIPTIONID:
+        FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
+        break;
+
+    default:
+        ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
+    }
 
-       return E_INVALIDARG;
+    return E_INVALIDARG;
 }
 
 /*************************************************************************
  * SHGetDataFromIDListW [SHELL32.248]
  *
  */
-HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
+HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl,
+                                    int nFormat, LPVOID dest, int len)
 {
-       TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
+    LPSTR filename, shortname;
+    WIN32_FIND_DATAW * pfd = dest;
 
-       pdump(pidl);
+    TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
 
-       if (! psf || !dest )  return E_INVALIDARG;
+    pdump(pidl);
 
-       switch (nFormat)
-       {
-         case SHGDFIL_FINDDATA:
-           {
-              LPSTR filename, shortname;
-              WIN32_FIND_DATAW * pfd = dest;
+    if (!psf || !dest)
+        return E_INVALIDARG;
+
+    switch (nFormat)
+    {
+    case SHGDFIL_FINDDATA:
+        pfd = dest;
 
-              if (_ILIsDrive(pidl))
-                  return E_INVALIDARG;
+        if (_ILIsDrive(pidl))
+            return E_INVALIDARG;
 
-              if (len < (int)sizeof(WIN32_FIND_DATAW)) return E_INVALIDARG;
+        if (len < sizeof(WIN32_FIND_DATAW))
+            return E_INVALIDARG;
 
-              ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
-              _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
-              pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
-              pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
+        ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
+        _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
+        pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
+        pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
 
-              filename = _ILGetTextPointer(pidl);
-              shortname = _ILGetSTextPointer(pidl);
+        filename = _ILGetTextPointer(pidl);
+        shortname = _ILGetSTextPointer(pidl);
 
-              if (!filename)
-                  pfd->cFileName[0] = '\0';
-              else if (!MultiByteToWideChar(CP_ACP, 0, filename, -1, pfd->cFileName, MAX_PATH))
-                  pfd->cFileName[MAX_PATH-1] = 0;
+        if (!filename)
+            pfd->cFileName[0] = '\0';
+        else if (!MultiByteToWideChar(CP_ACP, 0, filename, -1, pfd->cFileName, MAX_PATH))
+            pfd->cFileName[MAX_PATH-1] = 0;
 
-              if (!shortname)
-                  pfd->cAlternateFileName[0] = '\0';
-              else if (!MultiByteToWideChar(CP_ACP, 0, shortname, -1, pfd->cAlternateFileName, 14))
-                  pfd->cAlternateFileName[13] = 0;
-           }
-           return NOERROR;
-         case SHGDFIL_NETRESOURCE:
-         case SHGDFIL_DESCRIPTIONID:
-           FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
-           break;
+        if (!shortname)
+            pfd->cAlternateFileName[0] = '\0';
+        else if (!MultiByteToWideChar(CP_ACP, 0, shortname, -1, pfd->cAlternateFileName, 14))
+            pfd->cAlternateFileName[13] = 0;
+        return NOERROR;
 
-         default:
-           ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
-       }
+    case SHGDFIL_NETRESOURCE:
+    case SHGDFIL_DESCRIPTIONID:
+        FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
+        break;
+
+    default:
+        ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
+    }
 
-       return E_INVALIDARG;
+    return E_INVALIDARG;
 }
 
 /*************************************************************************
@@ -1198,63 +1214,84 @@ HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int n
  */
 HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSize)
 {
-       HRESULT hr = S_OK;
-
-        pszPath[0]=0;
-
-       /* One case is a PIDL rooted at desktop level */
-       if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
-           hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE);
-
-           if (SUCCEEDED(hr))
-               PathAddBackslashA(pszPath);
-       }
-       /* The only other valid case is a item ID list beginning at "My Computer" */
-       else if (_ILIsMyComputer(pidl))
-           pidl = ILGetNext(pidl);
-
-        if (SUCCEEDED(hr)) {
-           LPSTR txt;
+    HRESULT hr = S_OK;
 
-           while(pidl && pidl->mkid.cb) {
-               if (_ILIsSpecialFolder(pidl))
-                   {hr = E_INVALIDARG; break;}
+    pszPath[0]=0;
 
-               txt = _ILGetTextPointer(pidl);
-               if (!txt)
-                   {hr = E_INVALIDARG; break;}
-
-                if (lstrlenA(txt) > pidl->mkid.cb)
-                    ERR("pidl %p is borked\n",pidl);
-
-                /* make sure there's enough space for the next segment */
-                if ( (lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize)
-                   {hr = E_INVALIDARG; break;}
-               lstrcatA( pszPath, txt );
+    /* One case is a PIDL rooted at desktop level */
+    if (_ILIsValue(pidl) || _ILIsFolder(pidl))
+    {
+        hr = SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOP, FALSE);
 
-               pidl = ILGetNext(pidl);
-               if (!pidl)
-                   {hr = E_INVALIDARG; break;}
+        if (SUCCEEDED(hr))
+            PathAddBackslashA(pszPath);
+    }
+    /* The only other valid case is a item ID list beginning at "My Computer" */
+    else if (_ILIsMyComputer(pidl))
+        pidl = ILGetNext(pidl);
 
-               if (!pidl->mkid.cb) {
-                   /* We are at the end and successfully converted the complete PIDL. */
-                   break;
-               }
+    if (SUCCEEDED(hr))
+    {
+        LPSTR txt;
 
-                if( (lstrlenA(pszPath) + 1) > uOutSize)
-                   {hr = E_INVALIDARG; break;}
-               if (!PathAddBackslashA(pszPath))
-                   {hr = E_INVALIDARG; break;}
-           }
-       } else
-           hr = E_INVALIDARG;
+        while(pidl && pidl->mkid.cb)
+        {
+            if (_ILIsSpecialFolder(pidl))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            txt = _ILGetTextPointer(pidl);
+            if (!txt)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            if (lstrlenA(txt) > pidl->mkid.cb)
+                ERR("pidl %p is borked\n",pidl);
+
+            /* make sure there's enough space for the next segment */
+            if ((lstrlenA(txt) + lstrlenA(pszPath)) > uOutSize)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            lstrcatA( pszPath, txt );
+
+            pidl = ILGetNext(pidl);
+            if (!pidl)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            /* Are we at the end and successfully converted the complete PIDL? */
+            if (!pidl->mkid.cb)
+                break;
+
+            if ((lstrlenA(pszPath) + 1) > uOutSize)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            if (!PathAddBackslashA(pszPath))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+        }
+    }
+    else
+        hr = E_INVALIDARG;
 
-       TRACE_(shell)("-- %s, 0x%08lx\n", pszPath, hr);
-       return hr;
+    TRACE_(shell)("-- %s, 0x%08lx\n", pszPath, hr);
+    return hr;
 }
 
 /*************************************************************************
- * SHGetPathFromIDListA                [SHELL32.@][NT 4.0: SHELL32.220]
+ * SHGetPathFromIDListA        [SHELL32.@][NT 4.0: SHELL32.220]
  *
  * PARAMETERS
  *  pidl,   [IN] pidl
@@ -1264,23 +1301,23 @@ HRESULT SHELL_GetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath, UINT uOutSiz
  *  path from a passed PIDL.
  *
  * NOTES
- *     NULL returns FALSE
- *     desktop pidl gives path to desktop directory back
- *     special pidls returning FALSE
+ *    NULL returns FALSE
+ *    desktop pidl gives path to desktop directory back
+ *    special pidls returning FALSE
  */
 BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
 {
-       HRESULT hr;
+    HRESULT hr;
 
-       TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
-       pdump(pidl);
+    TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
+    pdump(pidl);
 
-       if (!pidl)
-           return FALSE;
+    if (!pidl)
+        return FALSE;
 
-       hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH);
+    hr = SHELL_GetPathFromIDListA(pidl, pszPath, MAX_PATH);
 
-       return SUCCEEDED(hr);
+    return SUCCEEDED(hr);
 }
 
 /*************************************************************************
@@ -1288,144 +1325,166 @@ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
  */
 HRESULT SHELL_GetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath, UINT uOutSize)
 {
-       HRESULT hr = S_OK;
-       UINT len;
-
-        pszPath[0]=0;
-
-       /* One case is a PIDL rooted at desktop level */
-       if (_ILIsValue(pidl) || _ILIsFolder(pidl)) {
-           hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE);
-
-           if (SUCCEEDED(hr))
-               PathAddBackslashW(pszPath);
-       }
-       /* The only other valid case is a item ID list beginning at "My Computer" */
-       else if (_ILIsMyComputer(pidl))
-           pidl = ILGetNext(pidl);
-
-        if (SUCCEEDED(hr)) {
-           LPSTR txt;
+    HRESULT hr = S_OK;
+    UINT len;
 
-           while(pidl && pidl->mkid.cb) {
-               if (_ILIsSpecialFolder(pidl))
-                   {hr = E_INVALIDARG; break;}
+    pszPath[0]=0;
 
-               txt = _ILGetTextPointer(pidl);
-               if (!txt)
-                   {hr = E_INVALIDARG; break;}
-
-                if (lstrlenA(txt) > pidl->mkid.cb)
-                    ERR("pidl %p is borked\n",pidl);
-               len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0);
-                if ( (lstrlenW(pszPath) + len) > uOutSize )
-                   {hr = E_INVALIDARG; break;}
-
-               MultiByteToWideChar(CP_ACP, 0, txt, -1, 
-                                    &pszPath[lstrlenW(pszPath)], len);
+    /* One case is a PIDL rooted at desktop level */
+    if (_ILIsValue(pidl) || _ILIsFolder(pidl))
+    {
+        hr = SHGetSpecialFolderPathW(0, pszPath, CSIDL_DESKTOP, FALSE);
 
-               pidl = ILGetNext(pidl);
-               if (!pidl)
-                   {hr = E_INVALIDARG; break;}
+        if (SUCCEEDED(hr))
+            PathAddBackslashW(pszPath);
+    }
+    /* The only other valid case is a item ID list beginning at "My Computer" */
+    else if (_ILIsMyComputer(pidl))
+        pidl = ILGetNext(pidl);
 
-               if (!pidl->mkid.cb) {
-                   /* We are at the end and successfully converted the complete PIDL. */
-                   break;
-               }
+    if (SUCCEEDED(hr))
+    {
+        LPSTR txt;
 
-                if ( (lstrlenW(pszPath) + 1) > uOutSize )
-                   {hr = E_INVALIDARG; break;}
-               if (!PathAddBackslashW(pszPath))
-                   {hr = E_INVALIDARG; break;}
-           }
-       } else
-           hr = E_INVALIDARG;
+        while(pidl && pidl->mkid.cb)
+        {
+            if (_ILIsSpecialFolder(pidl))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            txt = _ILGetTextPointer(pidl);
+            if (!txt)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            if (lstrlenA(txt) > pidl->mkid.cb)
+                ERR("pidl %p is borked\n",pidl);
+            len = MultiByteToWideChar(CP_ACP, 0, txt, -1, NULL, 0);
+            if ( (lstrlenW(pszPath) + len) > uOutSize )
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            MultiByteToWideChar(CP_ACP, 0, txt, -1,
+                                &pszPath[lstrlenW(pszPath)], len);
+
+            pidl = ILGetNext(pidl);
+            if (!pidl)
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+
+            /* Are we at the end and successfully converted the complete PIDL? */
+            if (!pidl->mkid.cb)
+                break;
+
+            if ((lstrlenW(pszPath) + 1) > uOutSize )
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+            if (!PathAddBackslashW(pszPath))
+            {
+                hr = E_INVALIDARG;
+                break;
+            }
+        }
+    }
+    else
+        hr = E_INVALIDARG;
 
     TRACE_(shell)("-- %s, 0x%08lx\n", debugstr_w(pszPath), hr);
     return hr;
 }
 
 /*************************************************************************
- * SHGetPathFromIDListW                        [SHELL32.@]
+ * SHGetPathFromIDListW             [SHELL32.@]
  */
 BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
 {
-       HRESULT hr;
+    HRESULT hr;
 
-       TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
-       pdump(pidl);
+    TRACE_(shell)("(pidl=%p,%p)\n", pidl, debugstr_w(pszPath));
+    pdump(pidl);
 
-       if (!pidl)
-           return FALSE;
+    if (!pidl)
+        return FALSE;
 
-       hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH);
+    hr = SHELL_GetPathFromIDListW(pidl, pszPath, MAX_PATH);
 
-       TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
-       return SUCCEEDED(hr);
+    TRACE_(shell)("-- %s, 0x%08lx\n",debugstr_w(pszPath), hr);
+    return SUCCEEDED(hr);
 }
 
 /*************************************************************************
- *     SHBindToParent          [shell version 5.0]
+ *    SHBindToParent        [shell version 5.0]
  */
 HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
 {
-       IShellFolder    * psf;
-       LPITEMIDLIST    pidlChild, pidlParent;
-       HRESULT         hr=E_FAIL;
+    IShellFolder    * psf;
+    LPITEMIDLIST    pidlChild, pidlParent;
+    HRESULT         hr=E_FAIL;
 
-       TRACE_(shell)("pidl=%p\n", pidl);
-       pdump(pidl);
+    TRACE_(shell)("pidl=%p\n", pidl);
+    pdump(pidl);
 
-       *ppv = NULL;
-       if (ppidlLast) *ppidlLast = NULL;
+    *ppv = NULL;
+    if (ppidlLast)
+        *ppidlLast = NULL;
 
-       if (_ILIsPidlSimple(pidl))
-       {
-         IShellFolder* desktop;
-
-         /* we are on desktop level */
-         hr = SHGetDesktopFolder(&desktop);
+    if (_ILIsPidlSimple(pidl))
+    {
+        IShellFolder* desktop;
 
-         if (SUCCEEDED(hr))
-         {
-           hr = IShellFolder_QueryInterface(desktop, riid, ppv);
+        /* we are on desktop level */
+        hr = SHGetDesktopFolder(&desktop);
 
-           if (SUCCEEDED(hr) && ppidlLast)
-             *ppidlLast = ILClone(pidl);
+        if (SUCCEEDED(hr))
+        {
+            hr = IShellFolder_QueryInterface(desktop, riid, ppv);
 
-           IShellFolder_Release(desktop);
-         }
-       }
-       else
-       {
-         pidlChild =  ILClone(ILFindLastID(pidl));
-         pidlParent = ILClone(pidl);
-         ILRemoveLastID(pidlParent);
+            if (SUCCEEDED(hr) && ppidlLast)
+                *ppidlLast = ILClone(pidl);
 
-         hr = SHGetDesktopFolder(&psf);
+            IShellFolder_Release(desktop);
+        }
+    }
+    else
+    {
+        pidlChild =  ILClone(ILFindLastID(pidl));
+        pidlParent = ILClone(pidl);
+        ILRemoveLastID(pidlParent);
 
-         if (SUCCEEDED(hr))
-           hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
+        hr = SHGetDesktopFolder(&psf);
 
-         if (SUCCEEDED(hr) && ppidlLast)
-           *ppidlLast = pidlChild;
-         else
-           ILFree (pidlChild);
+        if (SUCCEEDED(hr))
+            hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
 
-         SHFree (pidlParent);
-         if (psf) IShellFolder_Release(psf);
-       }
+        if (SUCCEEDED(hr) && ppidlLast)
+            *ppidlLast = pidlChild;
+        else
+            ILFree (pidlChild);
 
+        SHFree (pidlParent);
+        if (psf)
+            IShellFolder_Release(psf);
+    }
 
-       TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
-       return hr;
+    TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
+    return hr;
 }
 
 /**************************************************************************
  *
- *             internal functions
+ *        internal functions
  *
- *     ### 1. section creating pidls ###
+ *    ### 1. section creating pidls ###
  *
  *************************************************************************
  */
@@ -1433,7 +1492,8 @@ LPITEMIDLIST _ILAlloc(PIDLTYPE type, size_t size)
 {
     LPITEMIDLIST pidlOut = NULL;
 
-    if((pidlOut = SHAlloc(size + 5)))
+    pidlOut = SHAlloc(size + 5);
+    if(pidlOut)
     {
         LPPIDLDATA pData;
         LPITEMIDLIST pidlNext;
@@ -1441,10 +1501,12 @@ LPITEMIDLIST _ILAlloc(PIDLTYPE type, size_t size)
         ZeroMemory(pidlOut, size + 5);
         pidlOut->mkid.cb = size + 3;
 
-        if ((pData = _ILGetDataPointer(pidlOut)))
+        pData = _ILGetDataPointer(pidlOut);
+        if (pData)
             pData->type = type;
 
-        if ((pidlNext = ILGetNext(pidlOut)))
+        pidlNext = ILGetNext(pidlOut);
+        if (pidlNext)
             pidlNext->mkid.cb = 0x00;
         TRACE("-- (pidl=%p, size=%u)\n", pidlOut, size);
     }
@@ -1464,13 +1526,15 @@ LPITEMIDLIST _ILCreateDesktop()
 }
 
 LPITEMIDLIST _ILCreateMyComputer()
-{      TRACE("()\n");
-       return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
+{
+    TRACE("()\n");
+    return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
 }
 
 LPITEMIDLIST _ILCreateIExplore()
-{      TRACE("()\n");
-       return _ILCreateGuid(PT_GUID, &CLSID_Internet);
+{
+    TRACE("()\n");
+    return _ILCreateGuid(PT_GUID, &CLSID_Internet);
 }
 
 LPITEMIDLIST _ILCreateControlPanel()
@@ -1512,13 +1576,15 @@ LPITEMIDLIST _ILCreatePrinters()
 }
 
 LPITEMIDLIST _ILCreateNetwork()
-{      TRACE("()\n");
-       return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
+{
+    TRACE("()\n");
+    return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
 }
 
 LPITEMIDLIST _ILCreateBitBucket()
-{      TRACE("()\n");
-       return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
+{
+    TRACE("()\n");
+    return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
 }
 
 LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
@@ -1534,7 +1600,7 @@ LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
 
             memcpy(&(pData->u.guid.guid), guid, sizeof(GUID));
             TRACE("-- create GUID-pidl %s\n",
-             debugstr_guid(&(pData->u.guid.guid)));
+                  debugstr_guid(&(pData->u.guid.guid)));
         }
     }
     else
@@ -1547,21 +1613,52 @@ LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
 
 LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID)
 {
-       IID iid;
+    IID iid;
 
-       if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid)))
-       {
-         ERR("%s is not a GUID\n", szGUID);
-         return NULL;
-       }
-       return _ILCreateGuid(PT_GUID, &iid);
+    if (!SUCCEEDED(SHCLSIDFromStringA(szGUID, &iid)))
+    {
+        ERR("%s is not a GUID\n", szGUID);
+        return NULL;
+    }
+    return _ILCreateGuid(PT_GUID, &iid);
+}
+
+LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID)
+{
+    IID iid;
+
+    if (!SUCCEEDED(SHCLSIDFromStringW(szGUID, &iid)))
+    {
+        ERR("%s is not a GUID\n", debugstr_w(szGUID));
+        return NULL;
+    }
+    return _ILCreateGuid(PT_GUID, &iid);
+}
+
+LPITEMIDLIST _ILCreateFromFindDataW( WIN32_FIND_DATAW *wfd )
+{
+    /* FIXME: should make unicode PIDLs */
+    WIN32_FIND_DATAA fda;
+
+    memset( &fda, 0, sizeof fda );
+    fda.dwFileAttributes = wfd->dwFileAttributes;
+    fda.ftCreationTime = wfd->ftCreationTime;
+    fda.ftLastAccessTime = wfd->ftLastAccessTime;
+    fda.ftLastWriteTime = wfd->ftLastWriteTime;
+    fda.nFileSizeHigh = wfd->nFileSizeHigh;
+    fda.nFileSizeLow = wfd->nFileSizeLow;
+    fda.dwReserved0 = wfd->dwReserved0;
+    fda.dwReserved1 = wfd->dwReserved1;
+    WideCharToMultiByte( CP_ACP, 0, wfd->cFileName, -1,
+                         fda.cFileName, MAX_PATH, NULL, NULL );
+    return _ILCreateFromFindDataA( &fda );
 }
 
 LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile )
 {
-    char       buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
-    char *     pbuff = buff;
-    size_t     len, len1;
+    char    buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
+    char *  pbuff = buff;
+    size_t  len, len1;
     LPITEMIDLIST pidl;
     PIDLTYPE type;
 
@@ -1578,25 +1675,30 @@ LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile )
     len1 = strlen (stffile->cAlternateFileName)+1;
     memcpy (pbuff, stffile->cAlternateFileName, len1);
 
-    type = (stffile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : 
-     PT_VALUE;
-    /* FileStruct already has one byte for the first name, so use len - 1 in
+    type = (stffile->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? PT_FOLDER : PT_VALUE;
+
+    /*
+     * FileStruct already has one byte for the first name, so use len - 1 in
      * size calculation
      */
-    if ((pidl = _ILAlloc(type, sizeof(FileStruct) + (len - 1) + len1)))
+    pidl = _ILAlloc(type, sizeof(FileStruct) + (len - 1) + len1);
+    if (pidl)
     {
         LPPIDLDATA pData;
         LPSTR pszDest;
 
         /* set attributes */
-        if ((pData = _ILGetDataPointer(pidl)))
+        pData = _ILGetDataPointer(pidl);
+        if (pData)
         {
             pData->type = type;
-            FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.file.uFileDate,&pData->u.file.uFileTime);
+            FileTimeToDosDateTime( &(stffile->ftLastWriteTime),
+                          &pData->u.file.uFileDate, &pData->u.file.uFileTime);
             pData->u.file.dwFileSize = stffile->nFileSizeLow;
             pData->u.file.uFileAttribs = (WORD)stffile->dwFileAttributes;
         }
-        if ((pszDest = _ILGetTextPointer(pidl)))
+        pszDest = _ILGetTextPointer(pidl);
+        if (pszDest)
         {
             memcpy(pszDest, buff, len + len1);
             TRACE("-- create Value: %s\n",debugstr_a(pszDest));
@@ -1607,42 +1709,58 @@ LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA * stffile )
 
 HRESULT _ILCreateFromPathA(LPCSTR szPath, LPITEMIDLIST* ppidl)
 {
-       HANDLE hFile;
-       WIN32_FIND_DATAA stffile;
+    HANDLE hFile;
+    WIN32_FIND_DATAA stffile;
 
     if (!ppidl)
         return E_INVALIDARG;
 
-       hFile = FindFirstFileA(szPath, &stffile);
+    hFile = FindFirstFileA(szPath, &stffile);
+    if (hFile == INVALID_HANDLE_VALUE)
+        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+
+    FindClose(hFile);
+
+    *ppidl = _ILCreateFromFindDataA(&stffile);
 
-       if (hFile == INVALID_HANDLE_VALUE)
-               return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+    return *ppidl ? S_OK : E_OUTOFMEMORY;
+}
+
+HRESULT _ILCreateFromPathW(LPCWSTR szPath, LPITEMIDLIST* ppidl)
+{
+    HANDLE hFile;
+    WIN32_FIND_DATAW stffile;
+
+    if (!ppidl)
+        return E_INVALIDARG;
+
+    hFile = FindFirstFileW(szPath, &stffile);
+    if (hFile == INVALID_HANDLE_VALUE)
+        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
 
-       FindClose(hFile);
+    FindClose(hFile);
 
-       *ppidl = _ILCreateFromFindDataA(&stffile);
+    *ppidl = _ILCreateFromFindDataW(&stffile);
 
-       return *ppidl ? S_OK : E_OUTOFMEMORY;
+    return *ppidl ? S_OK : E_OUTOFMEMORY;
 }
 
 LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
 {
-    WCHAR sTemp[4];
     LPITEMIDLIST pidlOut;
 
-    sTemp[0]=toupperW(lpszNew[0]);
-    sTemp[1]=':';
-    sTemp[2]='\\';
-    sTemp[3]=0x00;
-    TRACE("(%s)\n",debugstr_w(sTemp));
+    TRACE("(%s)\n",debugstr_w(lpszNew));
 
-    if ((pidlOut = _ILAlloc(PT_DRIVE, sizeof(DriveStruct))))
+    pidlOut = _ILAlloc(PT_DRIVE, sizeof(DriveStruct));
+    if (pidlOut)
     {
         LPSTR pszDest;
 
-        if ((pszDest = _ILGetTextPointer(pidlOut)))
+        pszDest = _ILGetTextPointer(pidlOut);
+        if (pszDest)
         {
-           WideCharToMultiByte(CP_ACP, 0, sTemp, sizeof(sTemp)/sizeof(WCHAR), pszDest, sizeof(sTemp)/sizeof(WCHAR), NULL, NULL);
+            strcpy(pszDest, "x:\\");
+            pszDest[0]=toupperW(lpszNew[0]);
             TRACE("-- create Drive: %s\n", debugstr_a(pszDest));
         }
     }
@@ -1658,20 +1776,21 @@ LPITEMIDLIST _ILCreateDrive(LPCWSTR lpszNew)
  *  strlen (lpszText)
  */
 DWORD _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT uSize)
-{      TRACE("(%p,%p,%u)\n",pidl,pOut,uSize);
+{
+    TRACE("(%p,%p,%u)\n",pidl,pOut,uSize);
 
-       if(_ILIsMyComputer(pidl))
-         pidl = ILGetNext(pidl);
+    if(_ILIsMyComputer(pidl))
+        pidl = ILGetNext(pidl);
 
-       if (pidl && _ILIsDrive(pidl))
-         return _ILSimpleGetText(pidl, pOut, uSize);
+    if (pidl && _ILIsDrive(pidl))
+        return _ILSimpleGetText(pidl, pOut, uSize);
 
-       return 0;
+    return 0;
 }
 
 /**************************************************************************
  *
- *     ### 2. section testing pidls ###
+ *    ### 2. section testing pidls ###
  *
  **************************************************************************
  *  _ILIsDesktop()
@@ -1683,79 +1802,96 @@ DWORD _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT uSize)
  *  _ILIsPidlSimple()
  */
 BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
-{      TRACE("(%p)\n",pidl);
-       return pidl && pidl->mkid.cb  ? 0 : 1;
+{
+    TRACE("(%p)\n",pidl);
+
+    return pidl && pidl->mkid.cb  ? 0 : 1;
 }
 
 BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
 {
-       REFIID iid = _ILGetGUIDPointer(pidl);
+    REFIID iid = _ILGetGUIDPointer(pidl);
 
-       TRACE("(%p)\n",pidl);
+    TRACE("(%p)\n",pidl);
 
-       if (iid)
-         return IsEqualIID(iid, &CLSID_MyComputer);
-       return FALSE;
+    if (iid)
+        return IsEqualIID(iid, &CLSID_MyComputer);
+    return FALSE;
 }
 
 BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl)
 {
-       LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
-       TRACE("(%p)\n",pidl);
-       return (pidl && ( (lpPData && (PT_GUID== lpPData->type || PT_SHELLEXT== lpPData->type)) ||
-                         (pidl && pidl->mkid.cb == 0x00)
-                       ));
+    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    return (pidl && ( (lpPData && (PT_GUID== lpPData->type || PT_SHELLEXT== lpPData->type)) ||
+              (pidl && pidl->mkid.cb == 0x00)
+            ));
 }
 
 BOOL _ILIsDrive(LPCITEMIDLIST pidl)
-{      LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
-       TRACE("(%p)\n",pidl);
-       return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
-                                   PT_DRIVE1 == lpPData->type ||
-                                   PT_DRIVE2 == lpPData->type ||
-                                   PT_DRIVE3 == lpPData->type));
+{
+    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
+                    PT_DRIVE1 == lpPData->type ||
+                    PT_DRIVE2 == lpPData->type ||
+                    PT_DRIVE3 == lpPData->type));
 }
 
 BOOL _ILIsFolder(LPCITEMIDLIST pidl)
-{      LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
-       TRACE("(%p)\n",pidl);
-       return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
+{
+    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
 }
 
 BOOL _ILIsValue(LPCITEMIDLIST pidl)
-{      LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
-       TRACE("(%p)\n",pidl);
-       return (pidl && lpPData && PT_VALUE == lpPData->type);
+{
+    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    return (pidl && lpPData && PT_VALUE == lpPData->type);
 }
 
 BOOL _ILIsCPanelStruct(LPCITEMIDLIST pidl)
-{      LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
-       TRACE("(%p)\n",pidl);
-       return (pidl && lpPData && (lpPData->type == 0));
+{
+    LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
+
+    TRACE("(%p)\n",pidl);
+
+    return (pidl && lpPData && (lpPData->type == 0));
 }
 
 /**************************************************************************
- *     _ILIsPidlSimple
+ *    _ILIsPidlSimple
  */
-BOOL _ILIsPidlSimple ( LPCITEMIDLIST pidl)
+BOOL _ILIsPidlSimple(LPCITEMIDLIST pidl)
 {
-       BOOL ret = TRUE;
+    BOOL ret = TRUE;
 
-       if(! _ILIsDesktop(pidl))        /* pidl=NULL or mkid.cb=0 */
-       {
-         WORD len = pidl->mkid.cb;
-         LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((const BYTE*)pidl) + len );
-         if (pidlnext->mkid.cb)
-           ret = FALSE;
-       }
+    if(! _ILIsDesktop(pidl))    /* pidl=NULL or mkid.cb=0 */
+    {
+        WORD len = pidl->mkid.cb;
+        LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((const BYTE*)pidl) + len );
+
+        if (pidlnext->mkid.cb)
+            ret = FALSE;
+    }
 
-       TRACE("%s\n", ret ? "Yes" : "No");
-       return ret;
+    TRACE("%s\n", ret ? "Yes" : "No");
+    return ret;
 }
 
 /**************************************************************************
  *
- *     ### 3. section getting values from pidls ###
+ *    ### 3. section getting values from pidls ###
  */
 
  /**************************************************************************
@@ -1767,55 +1903,56 @@ BOOL _ILIsPidlSimple ( LPCITEMIDLIST pidl)
  */
 DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
 {
-       DWORD           dwReturn=0;
-       LPSTR           szSrc;
-       GUID const *    riid;
-       char szTemp[MAX_PATH];
-
-       TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
-
-       if (!pidl) return 0;
-
-       if (szOut)
-         *szOut = 0;
-
-       if (_ILIsDesktop(pidl))
-       {
-        /* desktop */
-         if (HCR_GetClassNameA(&CLSID_ShellDesktop, szTemp, MAX_PATH))
-         {
-           if (szOut)
-             lstrcpynA(szOut, szTemp, uOutSize);
-
-           dwReturn = strlen (szTemp);
-         }
-       }
-       else if (( szSrc = _ILGetTextPointer(pidl) ))
-       {
-         /* filesystem */
-         if (szOut)
-           lstrcpynA(szOut, szSrc, uOutSize);
-
-         dwReturn = strlen(szSrc);
-       }
-       else if (( riid = _ILGetGUIDPointer(pidl) ))
-       {
-         /* special folder */
-         if ( HCR_GetClassNameA(riid, szTemp, MAX_PATH) )
-         {
-           if (szOut)
-             lstrcpynA(szOut, szTemp, uOutSize);
-
-           dwReturn = strlen (szTemp);
-         }
-       }
-       else
-       {
-         ERR("-- no text\n");
-       }
-
-       TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_a(szOut),dwReturn);
-       return dwReturn;
+    DWORD        dwReturn=0;
+    LPSTR        szSrc;
+    GUID const * riid;
+    char szTemp[MAX_PATH];
+
+    TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
+
+    if (!pidl)
+        return 0;
+
+    if (szOut)
+        *szOut = 0;
+
+    if (_ILIsDesktop(pidl))
+    {
+        /* desktop */
+        if (HCR_GetClassNameA(&CLSID_ShellDesktop, szTemp, MAX_PATH))
+        {
+            if (szOut)
+                lstrcpynA(szOut, szTemp, uOutSize);
+
+            dwReturn = strlen (szTemp);
+        }
+    }
+    else if (( szSrc = _ILGetTextPointer(pidl) ))
+    {
+        /* filesystem */
+        if (szOut)
+            lstrcpynA(szOut, szSrc, uOutSize);
+
+        dwReturn = strlen(szSrc);
+    }
+    else if (( riid = _ILGetGUIDPointer(pidl) ))
+    {
+        /* special folder */
+        if ( HCR_GetClassNameA(riid, szTemp, MAX_PATH) )
+        {
+            if (szOut)
+                lstrcpynA(szOut, szTemp, uOutSize);
+
+            dwReturn = strlen (szTemp);
+        }
+    }
+    else
+    {
+        ERR("-- no text\n");
+    }
+
+    TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_a(szOut),dwReturn);
+    return dwReturn;
 }
 
  /**************************************************************************
@@ -1827,32 +1964,32 @@ DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
  */
 DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR szOut, UINT uOutSize)
 {
-       DWORD   dwReturn;
-       char    szTemp[MAX_PATH];
+    DWORD    dwReturn;
+    char    szTemp[MAX_PATH];
 
-       TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
+    TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
 
-       dwReturn = _ILSimpleGetText(pidl, szTemp, uOutSize);
+    dwReturn = _ILSimpleGetText(pidl, szTemp, uOutSize);
 
-       if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, MAX_PATH))
-               *szOut = 0;
+    if (!MultiByteToWideChar(CP_ACP, 0, szTemp, -1, szOut, MAX_PATH))
+        *szOut = 0;
 
-       TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn);
-       return dwReturn;
+    TRACE("-- (%p=%s 0x%08lx)\n",szOut,debugstr_w(szOut),dwReturn);
+    return dwReturn;
 }
 
 /**************************************************************************
  *
- *     ### 4. getting pointers to parts of pidls ###
+ *    ### 4. getting pointers to parts of pidls ###
  *
  **************************************************************************
  *  _ILGetDataPointer()
  */
 LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
 {
-       if(pidl && pidl->mkid.cb != 0x00)
-         return (LPPIDLDATA) &(pidl->mkid.abID);
-       return NULL;
+    if(pidl && pidl->mkid.cb != 0x00)
+        return (LPPIDLDATA) &(pidl->mkid.abID);
+    return NULL;
 }
 
 /**************************************************************************
@@ -1860,41 +1997,42 @@ LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
  * gets a pointer to the long filename string stored in the pidl
  */
 LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl)
-{/*    TRACE(pidl,"(pidl%p)\n", pidl);*/
-
-       LPPIDLDATA pdata = _ILGetDataPointer(pidl);
-
-       if (pdata)
-       {
-         switch (pdata->type)
-         {
-           case PT_GUID:
-           case PT_SHELLEXT:
-           case PT_YAGUID:
-             return NULL;
-
-           case PT_DRIVE:
-           case PT_DRIVE1:
-           case PT_DRIVE2:
-           case PT_DRIVE3:
-             return (LPSTR)&(pdata->u.drive.szDriveName);
-
-           case PT_FOLDER:
-           case PT_FOLDER1:
-           case PT_VALUE:
-           case PT_IESPECIAL1:
-           case PT_IESPECIAL2:
-             return (LPSTR)&(pdata->u.file.szNames);
-
-           case PT_WORKGRP:
-           case PT_COMP:
-           case PT_NETWORK:
-           case PT_NETPROVIDER:
-           case PT_SHARE:
-             return (LPSTR)&(pdata->u.network.szNames);
-         }
-       }
-       return NULL;
+{
+    /* TRACE(pidl,"(pidl%p)\n", pidl);*/
+
+    LPPIDLDATA pdata = _ILGetDataPointer(pidl);
+
+    if (!pdata)
+        return NULL;
+
+    switch (pdata->type)
+    {
+    case PT_GUID:
+    case PT_SHELLEXT:
+    case PT_YAGUID:
+        return NULL;
+
+    case PT_DRIVE:
+    case PT_DRIVE1:
+    case PT_DRIVE2:
+    case PT_DRIVE3:
+        return (LPSTR)&(pdata->u.drive.szDriveName);
+
+    case PT_FOLDER:
+    case PT_FOLDER1:
+    case PT_VALUE:
+    case PT_IESPECIAL1:
+    case PT_IESPECIAL2:
+        return (LPSTR)&(pdata->u.file.szNames);
+
+    case PT_WORKGRP:
+    case PT_COMP:
+    case PT_NETWORK:
+    case PT_NETPROVIDER:
+    case PT_SHARE:
+        return (LPSTR)&(pdata->u.network.szNames);
+    }
+    return NULL;
 }
 
 /**************************************************************************
@@ -1902,25 +2040,26 @@ LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl)
  * gets a pointer to the short filename string stored in the pidl
  */
 LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl)
-{/*    TRACE(pidl,"(pidl%p)\n", pidl);*/
+{
+    /* TRACE(pidl,"(pidl%p)\n", pidl); */
 
-       LPPIDLDATA pdata =_ILGetDataPointer(pidl);
+    LPPIDLDATA pdata =_ILGetDataPointer(pidl);
 
-       if (pdata)
-       {
-         switch (pdata->type)
-         {
-           case PT_FOLDER:
-           case PT_VALUE:
-           case PT_IESPECIAL1:
-           case PT_IESPECIAL2:
-             return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);
+    if (!pdata)
+        return NULL;
 
-           case PT_WORKGRP:
-             return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
-         }
-       }
-       return NULL;
+    switch (pdata->type)
+    {
+    case PT_FOLDER:
+    case PT_VALUE:
+    case PT_IESPECIAL1:
+    case PT_IESPECIAL2:
+        return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);
+
+    case PT_WORKGRP:
+        return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
+    }
+    return NULL;
 }
 
 /**************************************************************************
@@ -1930,25 +2069,25 @@ LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl)
  */
 IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl)
 {
-       LPPIDLDATA pdata =_ILGetDataPointer(pidl);
+    LPPIDLDATA pdata =_ILGetDataPointer(pidl);
+
+    TRACE("%p\n", pidl);
 
-       TRACE("%p\n", pidl);
+    if (!pdata)
+        return NULL;
 
-       if (pdata)
-       {
-         TRACE("pdata->type 0x%04x\n", pdata->type);
-         switch (pdata->type)
-         {
-           case PT_SHELLEXT:
-           case PT_GUID:
-             return &(pdata->u.guid.guid);
+    TRACE("pdata->type 0x%04x\n", pdata->type);
+    switch (pdata->type)
+    {
+    case PT_SHELLEXT:
+    case PT_GUID:
+        return &(pdata->u.guid.guid);
 
-           default:
-               TRACE("Unknown pidl type 0x%04x\n", pdata->type);
-               break;
-         }
-       }
-       return NULL;
+    default:
+        TRACE("Unknown pidl type 0x%04x\n", pdata->type);
+        break;
+    }
+    return NULL;
 }
 
 /*************************************************************************
@@ -1970,36 +2109,39 @@ BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt)
 {
     LPPIDLDATA pdata = _ILGetDataPointer(pidl);
 
-    if(! pdata) return FALSE;
+    if (!pdata)
+        return FALSE;
 
     switch (pdata->type)
     {
-        case PT_FOLDER:
-        case PT_VALUE:
-            DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
-            break;
-        default:
-            return FALSE;
+    case PT_FOLDER:
+    case PT_VALUE:
+        DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
+        break;
+    default:
+        return FALSE;
     }
     return TRUE;
 }
 
 BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
 {
-       FILETIME ft,lft;
-       SYSTEMTIME time;
-       BOOL ret;
-
-       if (_ILGetFileDateTime( pidl, &ft )) {
-           FileTimeToLocalFileTime(&ft, &lft);
-           FileTimeToSystemTime (&lft, &time);
-           ret = GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
-       } else {
-           pOut[0] = '\0';
-           ret = FALSE;
-       }
-       return ret;
+    FILETIME ft,lft;
+    SYSTEMTIME time;
+    BOOL ret;
 
+    if (_ILGetFileDateTime( pidl, &ft ))
+    {
+        FileTimeToLocalFileTime(&ft, &lft);
+        FileTimeToSystemTime (&lft, &time);
+        ret = GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
+    }
+    else
+    {
+        pOut[0] = '\0';
+        ret = FALSE;
+    }
+    return ret;
 }
 
 /*************************************************************************
@@ -2008,59 +2150,66 @@ BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
  * Given the ItemIdList, get the FileSize
  *
  * PARAMS
- *      pidl    [I] The ItemIDList
- *     pOut    [I] The buffer to save the result
- *      uOutsize [I] The size of the buffer
+ *    pidl     [I] The ItemIDList
+ *    pOut     [I] The buffer to save the result
+ *    uOutsize [I] The size of the buffer
  *
  * RETURNS
- *     The FileSize
+ *    The FileSize
  *
  * NOTES
- *     pOut can be null when no string is needed
+ *    pOut can be null when no string is needed
  *
  */
 DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
 {
-       LPPIDLDATA pdata = _ILGetDataPointer(pidl);
-       DWORD dwSize;
+    LPPIDLDATA pdata = _ILGetDataPointer(pidl);
+    DWORD dwSize;
 
-       if(! pdata) return 0;
+    if (!pdata)
+        return 0;
 
-       switch (pdata->type)
-       {
-         case PT_VALUE:
-           dwSize = pdata->u.file.dwFileSize;
-           if (pOut) StrFormatByteSizeA(dwSize, pOut, uOutSize);
-           return dwSize;
-       }
-       if (pOut) *pOut = 0x00;
-       return 0;
+    switch (pdata->type)
+    {
+    case PT_VALUE:
+        dwSize = pdata->u.file.dwFileSize;
+        if (pOut)
+            StrFormatByteSizeA(dwSize, pOut, uOutSize);
+        return dwSize;
+    }
+    if (pOut)
+        *pOut = 0x00;
+    return 0;
 }
 
 BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
 {
-       char szTemp[MAX_PATH];
-       const char * pPoint;
-       LPCITEMIDLIST  pidlTemp=pidl;
+    char szTemp[MAX_PATH];
+    const char * pPoint;
+    LPCITEMIDLIST  pidlTemp=pidl;
 
-       TRACE("pidl=%p\n",pidl);
+    TRACE("pidl=%p\n",pidl);
 
-       if (!pidl) return FALSE;
+    if (!pidl)
+        return FALSE;
 
-       pidlTemp = ILFindLastID(pidl);
+    pidlTemp = ILFindLastID(pidl);
 
-       if (!_ILIsValue(pidlTemp)) return FALSE;
-       if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE;
+    if (!_ILIsValue(pidlTemp))
+        return FALSE;
+    if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH))
+        return FALSE;
 
-       pPoint = PathFindExtensionA(szTemp);
+    pPoint = PathFindExtensionA(szTemp);
 
-       if (! *pPoint) return FALSE;
+    if (!*pPoint)
+        return FALSE;
 
-       pPoint++;
-       lstrcpynA(pOut, pPoint, uOutSize);
-       TRACE("%s\n",pOut);
+    pPoint++;
+    lstrcpynA(pOut, pPoint, uOutSize);
+    TRACE("%s\n",pOut);
 
-       return TRUE;
+    return TRUE;
 }
 
 /*************************************************************************
@@ -2074,34 +2223,31 @@ BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
  *      uOutsize    [I] The size of the buffer
  *
  * RETURNS
- *     nothing
+ *    nothing
  *
  * NOTES
- *     This function copies as much as possible into the buffer.
+ *    This function copies as much as possible into the buffer.
  */
 void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
 {
-       if(_ILIsValue(pidl))
-       {
-         char sTemp[64];
-          if(uOutSize > 0)
-          {
+    if(_ILIsValue(pidl))
+    {
+        char sTemp[64];
+
+        if(uOutSize > 0)
             pOut[0] = 0;
-          }
-         if (_ILGetExtension (pidl, sTemp, 64))
-         {
-           if (!( HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE)
-               && HCR_MapTypeToValueA(sTemp, pOut, uOutSize, FALSE )))
-           {
-             lstrcpynA (pOut, sTemp, uOutSize - 6);
-             strcat (pOut, "-file");
-           }
-         }
-       }
-       else
-       {
-         lstrcpynA(pOut, "Folder", uOutSize);
-       }
+        if (_ILGetExtension (pidl, sTemp, 64))
+        {
+            if (!( HCR_MapTypeToValueA(sTemp, sTemp, 64, TRUE)
+                && HCR_MapTypeToValueA(sTemp, pOut, uOutSize, FALSE )))
+            {
+                lstrcpynA (pOut, sTemp, uOutSize - 6);
+                strcat (pOut, "-file");
+            }
+        }
+    }
+    else
+        lstrcpynA(pOut, "Folder", uOutSize);
 }
 
 /*************************************************************************
@@ -2123,98 +2269,95 @@ void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
  */
 DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
 {
-       LPPIDLDATA pData = _ILGetDataPointer(pidl);
-       WORD wAttrib = 0;
-       int i;
-
-       if(! pData) return 0;
-
-       switch(pData->type)
-       {
-         case PT_FOLDER:
-         case PT_VALUE:
-           wAttrib = pData->u.file.uFileAttribs;
-           break;
-       }
-
-       if(uOutSize >= 6)
-       {
-         i=0;
-         if(wAttrib & FILE_ATTRIBUTE_READONLY)
-         {
-           pOut[i++] = 'R';
-         }
-         if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
-         {
-           pOut[i++] = 'H';
-         }
-         if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
-         {
-           pOut[i++] = 'S';
-         }
-         if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
-         {
-           pOut[i++] = 'A';
-         }
-         if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
-         {
-           pOut[i++] = 'C';
-         }
-         pOut[i] = 0x00;
-       }
-       return wAttrib;
+    LPPIDLDATA pData = _ILGetDataPointer(pidl);
+    WORD wAttrib = 0;
+    int i;
+
+    if (!pData)
+        return 0;
+
+    switch(pData->type)
+    {
+    case PT_FOLDER:
+    case PT_VALUE:
+        wAttrib = pData->u.file.uFileAttribs;
+        break;
+    }
+
+    if(uOutSize >= 6)
+    {
+        i=0;
+        if(wAttrib & FILE_ATTRIBUTE_READONLY)
+            pOut[i++] = 'R';
+        if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
+            pOut[i++] = 'H';
+        if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
+            pOut[i++] = 'S';
+        if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
+            pOut[i++] = 'A';
+        if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
+            pOut[i++] = 'C';
+        pOut[i] = 0x00;
+    }
+    return wAttrib;
 }
 
 /*************************************************************************
-* ILFreeaPidl
-*
-* free a aPidl struct
-*/
+ * ILFreeaPidl
+ *
+ * free a aPidl struct
+ */
 void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl)
 {
-       UINT   i;
+    UINT   i;
 
-       if (apidl)
-       {
-         for (i = 0; i < cidl; i++) SHFree(apidl[i]);
-         SHFree(apidl);
-       }
+    if (apidl)
+    {
+        for (i = 0; i < cidl; i++)
+            SHFree(apidl[i]);
+        SHFree(apidl);
+    }
 }
 
 /*************************************************************************
-* ILCopyaPidl
-*
-* copies an aPidl struct
-*/
+ * ILCopyaPidl
+ *
+ * copies an aPidl struct
+ */
 LPITEMIDLIST* _ILCopyaPidl(LPCITEMIDLIST * apidlsrc, UINT cidl)
 {
-       UINT i;
-       LPITEMIDLIST * apidldest = (LPITEMIDLIST*)SHAlloc(cidl * sizeof(LPITEMIDLIST));
-       if(!apidlsrc) return NULL;
+    UINT i;
+    LPITEMIDLIST *apidldest;
 
-       for (i = 0; i < cidl; i++)
-         apidldest[i] = ILClone(apidlsrc[i]);
+    apidldest = SHAlloc(cidl * sizeof(LPITEMIDLIST));
+    if (!apidlsrc)
+        return NULL;
 
-       return apidldest;
+    for (i = 0; i < cidl; i++)
+        apidldest[i] = ILClone(apidlsrc[i]);
+
+    return apidldest;
 }
 
 /*************************************************************************
-* _ILCopyCidaToaPidl
-*
-* creates aPidl from CIDA
-*/
+ * _ILCopyCidaToaPidl
+ *
+ * creates aPidl from CIDA
+ */
 LPITEMIDLIST* _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida)
 {
-       UINT i;
-       LPITEMIDLIST * dst = (LPITEMIDLIST*)SHAlloc(cida->cidl * sizeof(LPITEMIDLIST));
+    UINT i;
+    LPITEMIDLIST *dst;
 
-       if(!dst) return NULL;
+    dst = SHAlloc(cida->cidl * sizeof(LPITEMIDLIST));
+    if (!dst)
+        return NULL;
 
-       if (pidl)
-         *pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[0]]));
+    if (pidl)
+        *pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[0]]));
 
-       for (i = 0; i < cida->cidl; i++)
-         dst[i] = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[i + 1]]));
+    for (i = 0; i < cida->cidl; i++)
+        dst[i] = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[i + 1]]));
 
-       return dst;
+    return dst;
 }
index b28d217..1bf1828 100644 (file)
@@ -208,11 +208,14 @@ LPITEMIDLIST      _ILCreateGuid(PIDLTYPE type, REFIID guid);
 
 /* Like _ILCreateGuid, but using the string szGUID. */
 LPITEMIDLIST   _ILCreateGuidFromStrA(LPCSTR szGUID);
+LPITEMIDLIST   _ILCreateGuidFromStrW(LPCWSTR szGUID);
 
 /* Commonly used PIDLs representing file system objects. */
 LPITEMIDLIST   _ILCreateDesktop        (void);
 LPITEMIDLIST   _ILCreateFromFindDataA(WIN32_FIND_DATAA *stffile);
+LPITEMIDLIST   _ILCreateFromFindDataW(WIN32_FIND_DATAW *stffile);
 HRESULT                _ILCreateFromPathA      (LPCSTR szPath, LPITEMIDLIST* ppidl);
+HRESULT                _ILCreateFromPathW      (LPCWSTR szPath, LPITEMIDLIST* ppidl);
 
 /* Other helpers */
 LPITEMIDLIST   _ILCreateMyComputer     (void);
index 17e7098..b038862 100644 (file)
 #  win95 and winNT dlls import shell32.dll by ordinal)
 # This list was updated to dll version 4.72
 
-   2 stdcall SHChangeNotifyRegister(long long long long long ptr)
-   4 stdcall SHChangeNotifyDeregister (long)
-   5 stdcall SHChangeNotifyUpdateEntryList (long long long long)
-   9 stub PifMgr_OpenProperties
-  10 stub PifMgr_GetProperties
-  11 stub PifMgr_SetProperties
-  13 stub PifMgr_CloseProperties
-  15 stdcall ILGetDisplayName(ptr ptr)
-  16 stdcall ILFindLastID(ptr)
-  17 stdcall ILRemoveLastID(ptr)
-  18 stdcall ILClone(ptr)
-  19 stdcall ILCloneFirst (ptr)
-  20 stdcall ILGlobalClone (ptr)
-  21 stdcall ILIsEqual (ptr ptr)
-  23 stdcall ILIsParent (ptr ptr long)
-  24 stdcall ILFindChild (ptr ptr)
-  25 stdcall ILCombine(ptr ptr)
-  26 stdcall ILLoadFromStream (ptr ptr)
-  27 stdcall ILSaveToStream(ptr ptr)
-  28 stdcall SHILCreateFromPath(ptr ptr ptr) SHILCreateFromPathAW
-  29 stdcall PathIsRoot(ptr) PathIsRootAW
-  30 stdcall PathBuildRoot(ptr long) PathBuildRootAW
-  31 stdcall PathFindExtension(ptr) PathFindExtensionAW
-  32 stdcall PathAddBackslash(ptr) PathAddBackslashAW
-  33 stdcall PathRemoveBlanks(ptr) PathRemoveBlanksAW
-  34 stdcall PathFindFileName(ptr) PathFindFileNameAW
-  35 stdcall PathRemoveFileSpec(ptr) PathRemoveFileSpecAW
-  36 stdcall PathAppend(ptr ptr) PathAppendAW
-  37 stdcall PathCombine(ptr ptr ptr) PathCombineAW
-  38 stdcall PathStripPath(ptr)PathStripPathAW
-  39 stdcall PathIsUNC (ptr) PathIsUNCAW
-  40 stdcall PathIsRelative (ptr) PathIsRelativeAW
-  41 stdcall IsLFNDriveA(str)
-  42 stdcall IsLFNDriveW(wstr)
-  43 stdcall PathIsExe (ptr) PathIsExeAW
-  45 stdcall PathFileExists(ptr) PathFileExistsAW
-  46 stdcall PathMatchSpec (ptr ptr) PathMatchSpecAW
-  47 stdcall PathMakeUniqueName (ptr long ptr ptr ptr)PathMakeUniqueNameAW
-  48 stdcall PathSetDlgItemPath (long long ptr) PathSetDlgItemPathAW
-  49 stdcall PathQualify (ptr) PathQualifyAW
-  50 stdcall PathStripToRoot (ptr) PathStripToRootAW
-  51 stdcall PathResolve(str long long) PathResolveAW
-  52 stdcall PathGetArgs(str) PathGetArgsAW
-  53 stdcall DoEnvironmentSubst (long long) DoEnvironmentSubstAW
-  54 stdcall DragAcceptFiles(long long)
-  55 stdcall PathQuoteSpaces (ptr) PathQuoteSpacesAW
-  56 stdcall PathUnquoteSpaces(str) PathUnquoteSpacesAW
-  57 stdcall PathGetDriveNumber (str) PathGetDriveNumberAW
-  58 stdcall ParseField(str long ptr long) ParseFieldAW
-  59 stdcall RestartDialog(long wstr long)
-  60 stdcall ExitWindowsDialog(long)
-  61 stdcall RunFileDlg(long long long str str long)
-  62 stdcall PickIconDlg(long long long long)
-  63 stdcall GetFileNameFromBrowse(long long long long str str str)
-  64 stdcall DriveType (long)
-  65 stub InvalidateDriveType
-  66 stdcall IsNetDrive(long)
-  67 stdcall Shell_MergeMenus (long long long long long long)
-  68 stdcall SHGetSetSettings(ptr long long)
-  69 stub SHGetNetResource
-  70 stdcall SHCreateDefClassObject(long long long long long)
-  71 stdcall Shell_GetImageList(ptr ptr)
-  72 stdcall Shell_GetCachedImageIndex(ptr ptr long) Shell_GetCachedImageIndexAW
-  73 stdcall SHShellFolderView_Message(long long long)
-  74 stdcall SHCreateStdEnumFmtEtc(long ptr ptr)
-  75 stdcall PathYetAnotherMakeUniqueName(ptr wstr wstr wstr)
+   2 stdcall -noname SHChangeNotifyRegister(long long long long long ptr)
+   4 stdcall -noname SHChangeNotifyDeregister(long)
+   5 stdcall -noname SHChangeNotifyUpdateEntryList(long long long long)
+   9 stub -noname PifMgr_OpenProperties
+  10 stub -noname PifMgr_GetProperties
+  11 stub -noname PifMgr_SetProperties
+  13 stub -noname PifMgr_CloseProperties
+  15 stdcall -noname ILGetDisplayName(ptr ptr)
+  16 stdcall -noname ILFindLastID(ptr)
+  17 stdcall -noname ILRemoveLastID(ptr)
+  18 stdcall -noname ILClone(ptr)
+  19 stdcall -noname ILCloneFirst(ptr)
+  20 stdcall -noname ILGlobalClone(ptr)
+  21 stdcall -noname ILIsEqual(ptr ptr)
+  23 stdcall -noname ILIsParent(ptr ptr long)
+  24 stdcall -noname ILFindChild(ptr ptr)
+  25 stdcall -noname ILCombine(ptr ptr)
+  26 stdcall -noname ILLoadFromStream(ptr ptr)
+  27 stdcall -noname ILSaveToStream(ptr ptr)
+  28 stdcall -noname SHILCreateFromPath(ptr ptr ptr) SHILCreateFromPathAW
+  29 stdcall -noname PathIsRoot(ptr) PathIsRootAW
+  30 stdcall -noname PathBuildRoot(ptr long) PathBuildRootAW
+  31 stdcall -noname PathFindExtension(ptr) PathFindExtensionAW
+  32 stdcall -noname PathAddBackslash(ptr) PathAddBackslashAW
+  33 stdcall -noname PathRemoveBlanks(ptr) PathRemoveBlanksAW
+  34 stdcall -noname PathFindFileName(ptr) PathFindFileNameAW
+  35 stdcall -noname PathRemoveFileSpec(ptr) PathRemoveFileSpecAW
+  36 stdcall -noname PathAppend(ptr ptr) PathAppendAW
+  37 stdcall -noname PathCombine(ptr ptr ptr) PathCombineAW
+  38 stdcall -noname PathStripPath(ptr)PathStripPathAW
+  39 stdcall -noname PathIsUNC(ptr) PathIsUNCAW
+  40 stdcall -noname PathIsRelative(ptr) PathIsRelativeAW
+  41 stdcall -noname IsLFNDriveA(str)
+  42 stdcall -noname IsLFNDriveW(wstr)
+  43 stdcall -noname PathIsExe(ptr) PathIsExeAW
+  45 stdcall -noname PathFileExists(ptr) PathFileExistsAW
+  46 stdcall -noname PathMatchSpec(ptr ptr) PathMatchSpecAW
+  47 stdcall -noname PathMakeUniqueName(ptr long ptr ptr ptr)PathMakeUniqueNameAW
+  48 stdcall -noname PathSetDlgItemPath(long long ptr) PathSetDlgItemPathAW
+  49 stdcall -noname PathQualify(ptr) PathQualifyAW
+  50 stdcall -noname PathStripToRoot(ptr) PathStripToRootAW
+  51 stdcall -noname PathResolve(str long long) PathResolveAW
+  52 stdcall -noname PathGetArgs(str) PathGetArgsAW
+  53 stdcall DoEnvironmentSubst(long long) DoEnvironmentSubstAW
+  55 stdcall -noname PathQuoteSpaces(ptr) PathQuoteSpacesAW
+  56 stdcall -noname PathUnquoteSpaces(str) PathUnquoteSpacesAW
+  57 stdcall -noname PathGetDriveNumber(str) PathGetDriveNumberAW
+  58 stdcall -noname ParseField(str long ptr long) ParseFieldAW
+  59 stdcall -noname RestartDialog(long wstr long)
+  60 stdcall -noname ExitWindowsDialog(long)
+  61 stdcall -noname RunFileDlg(long long long str str long)
+  62 stdcall -noname PickIconDlg(long long long long)
+  63 stdcall -noname GetFileNameFromBrowse(long long long long str str str)
+  64 stdcall -noname DriveType(long)
+  65 stub -noname InvalidateDriveType
+  66 stdcall -noname IsNetDrive(long)
+  67 stdcall -noname Shell_MergeMenus(long long long long long long)
+  68 stdcall -noname SHGetSetSettings(ptr long long)
+  69 stub -noname SHGetNetResource
+  70 stdcall -noname SHCreateDefClassObject(long long long long long)
+  71 stdcall -noname Shell_GetImageList(ptr ptr)
+  72 stdcall -noname Shell_GetCachedImageIndex(ptr ptr long) Shell_GetCachedImageIndexAW
+  73 stdcall -noname SHShellFolderView_Message(long long long)
+  74 stdcall -noname SHCreateStdEnumFmtEtc(long ptr ptr)
+  75 stdcall -noname PathYetAnotherMakeUniqueName(ptr wstr wstr wstr)
   76 stub DragQueryInfo
-  77 stdcall SHMapPIDLToSystemImageListIndex(ptr ptr ptr)
-  78 stdcall OleStrToStrN(str long wstr long) OleStrToStrNAW
-  79 stdcall StrToOleStrN(wstr long str long) StrToOleStrNAW
-  80 stdcall DragFinish(long)
-  81 stdcall DragQueryFile(long long ptr long) DragQueryFileA
-  82 stdcall DragQueryFileA(long long ptr long)
-  83 stdcall CIDLData_CreateFromIDArray(ptr long ptr ptr)
+  77 stdcall -noname SHMapPIDLToSystemImageListIndex(ptr ptr ptr)
+  78 stdcall -noname OleStrToStrN(str long wstr long) OleStrToStrNAW
+  79 stdcall -noname StrToOleStrN(wstr long str long) StrToOleStrNAW
+  83 stdcall -noname CIDLData_CreateFromIDArray(ptr long ptr ptr)
   84 stub SHIsBadInterfacePtr
-  85 stdcall OpenRegStream(long str str long) shlwapi.SHOpenRegStreamA
-  86 stdcall SHRegisterDragDrop(long ptr)
-  87 stdcall SHRevokeDragDrop(long)
-  88 stdcall SHDoDragDrop(long ptr ptr long ptr)
-  89 stdcall SHCloneSpecialIDList(long long long)
-  90 stdcall SHFindFiles(ptr ptr)
+  85 stdcall -noname OpenRegStream(long str str long) shlwapi.SHOpenRegStreamA
+  86 stdcall -noname SHRegisterDragDrop(long ptr)
+  87 stdcall -noname SHRevokeDragDrop(long)
+  88 stdcall -noname SHDoDragDrop(long ptr ptr long ptr)
+  89 stdcall -noname SHCloneSpecialIDList(long long long)
+  90 stdcall -noname SHFindFiles(ptr ptr)
   91 stub SHFindComputer
-  92 stdcall PathGetShortPath (ptr) PathGetShortPathAW
-  93 stdcall Win32CreateDirectory(wstr ptr) Win32CreateDirectoryAW
-  94 stdcall Win32RemoveDirectory(wstr) Win32RemoveDirectoryAW
-  95 stdcall SHLogILFromFSIL (ptr)
-  96 stdcall StrRetToStrN (ptr long ptr ptr) StrRetToStrNAW
-  97 stdcall SHWaitForFileToOpen (long long long)
-  98 stdcall SHGetRealIDL (ptr ptr ptr)
-  99 stdcall SetAppStartingCursor (long long)
- 100 stdcall SHRestricted(long)
+  92 stdcall -noname PathGetShortPath(ptr) PathGetShortPathAW
+  93 stdcall -noname Win32CreateDirectory(wstr ptr) Win32CreateDirectoryAW
+  94 stdcall -noname Win32RemoveDirectory(wstr) Win32RemoveDirectoryAW
+  95 stdcall -noname SHLogILFromFSIL(ptr)
+  96 stdcall -noname StrRetToStrN(ptr long ptr ptr) StrRetToStrNAW
+  97 stdcall -noname SHWaitForFileToOpen (long long long)
+  98 stdcall -noname SHGetRealIDL(ptr ptr ptr)
+  99 stdcall -noname SetAppStartingCursor(long long)
+ 100 stdcall -noname SHRestricted(long)
 
- 102 stdcall SHCoCreateInstance(wstr ptr long ptr ptr)
- 103 stdcall SignalFileOpen(long)
- 104 stdcall FileMenu_DeleteAllItems(long)
- 105 stdcall FileMenu_DrawItem(long ptr)
- 106 stdcall FileMenu_FindSubMenuByPidl(long ptr)
- 107 stdcall FileMenu_GetLastSelectedItemPidls(long ptr ptr)
- 108 stdcall FileMenu_HandleMenuChar(long long)
- 109 stdcall FileMenu_InitMenuPopup (long)
- 110 stdcall FileMenu_InsertUsingPidl (long long ptr long long ptr)
- 111 stdcall FileMenu_Invalidate (long)
- 112 stdcall FileMenu_MeasureItem(long ptr)
- 113 stdcall FileMenu_ReplaceUsingPidl (long long ptr long ptr)
- 114 stdcall FileMenu_Create (long long long long long)
- 115 stdcall FileMenu_AppendItem (long ptr long long long long) FileMenu_AppendItemAW
- 116 stdcall FileMenu_TrackPopupMenuEx (long long long long long long)
- 117 stdcall FileMenu_DeleteItemByCmd(long long)
- 118 stdcall FileMenu_Destroy (long)
- 119 stdcall IsLFNDrive(ptr) IsLFNDriveAW
- 120 stdcall FileMenu_AbortInitMenu ()
- 121 stdcall SHFlushClipboard ()
+ 102 stdcall -noname SHCoCreateInstance(wstr ptr long ptr ptr)
+ 103 stdcall -noname SignalFileOpen(long)
+ 104 stdcall -noname FileMenu_DeleteAllItems(long)
+ 105 stdcall -noname FileMenu_DrawItem(long ptr)
+ 106 stdcall -noname FileMenu_FindSubMenuByPidl(long ptr)
+ 107 stdcall -noname FileMenu_GetLastSelectedItemPidls(long ptr ptr)
+ 108 stdcall -noname FileMenu_HandleMenuChar(long long)
+ 109 stdcall -noname FileMenu_InitMenuPopup(long)
+ 110 stdcall -noname FileMenu_InsertUsingPidl (long long ptr long long ptr)
+ 111 stdcall -noname FileMenu_Invalidate(long)
+ 112 stdcall -noname FileMenu_MeasureItem(long ptr)
+ 113 stdcall -noname FileMenu_ReplaceUsingPidl(long long ptr long ptr)
+ 114 stdcall -noname FileMenu_Create(long long long long long)
+ 115 stdcall -noname FileMenu_AppendItem(long ptr long long long long) FileMenu_AppendItemAW
+ 116 stdcall -noname FileMenu_TrackPopupMenuEx(long long long long long long)
+ 117 stdcall -noname FileMenu_DeleteItemByCmd(long long)
+ 118 stdcall -noname FileMenu_Destroy(long)
+ 119 stdcall -noname IsLFNDrive(ptr) IsLFNDriveAW
+ 120 stdcall -noname FileMenu_AbortInitMenu()
+ 121 stdcall -noname SHFlushClipboard()
  122 stdcall -noname RunDLL_CallEntry16(long long long str long) #name wrong?
- 123 stdcall SHFreeUnusedLibraries ()
- 124 stdcall FileMenu_AppendFilesForPidl(long ptr long)
- 125 stdcall FileMenu_AddFilesForPidl(long long long ptr long long ptr)
- 126 stdcall SHOutOfMemoryMessageBox (long long long)
- 127 stdcall SHWinHelp (long long long long)
- 128 stdcall -private DllGetClassObject(long long ptr) SHELL32_DllGetClassObject
- 129 stdcall DAD_AutoScroll(long ptr ptr)
- 130 stdcall DAD_DragEnter(long)
- 131 stdcall DAD_DragEnterEx(long long long)
- 132 stdcall DAD_DragLeave()
- 133 stdcall DragQueryFileW(long long ptr long)
- 134 stdcall DAD_DragMove(long long)
- 135 stdcall DragQueryPoint(long ptr)
- 136 stdcall DAD_SetDragImage(long long)
- 137 stdcall DAD_ShowDragImage (long)
+ 123 stdcall -noname SHFreeUnusedLibraries()
+ 124 stdcall -noname FileMenu_AppendFilesForPidl(long ptr long)
+ 125 stdcall -noname FileMenu_AddFilesForPidl(long long long ptr long long ptr)
+ 126 stdcall -noname SHOutOfMemoryMessageBox(long long long)
+ 127 stdcall -noname SHWinHelp(long long long long)
+ 129 stdcall -noname DAD_AutoScroll(long ptr ptr)
+ 130 stdcall -noname DAD_DragEnter(long)
+ 131 stdcall -noname DAD_DragEnterEx(long long long)
+ 132 stdcall -noname DAD_DragLeave()
+ 134 stdcall -noname DAD_DragMove(long long)
+ 136 stdcall -noname DAD_SetDragImage(long long)
+ 137 stdcall -noname DAD_ShowDragImage(long)
  139 stub Desktop_UpdateBriefcaseOnEvent
- 140 stdcall FileMenu_DeleteItemByIndex(long long)
- 141 stdcall FileMenu_DeleteItemByFirstID(long long)
- 142 stdcall FileMenu_DeleteSeparator(long)
- 143 stdcall FileMenu_EnableItemByCmd(long long long)
- 144 stdcall FileMenu_GetItemExtent (long long)
- 145 stdcall PathFindOnPath (ptr ptr) PathFindOnPathAW
- 146 stdcall RLBuildListOfPaths()
- 147 stdcall SHCLSIDFromString(long long) SHCLSIDFromStringAW
- 149 stdcall SHFind_InitMenuPopup(long long long long)
+ 140 stdcall -noname FileMenu_DeleteItemByIndex(long long)
+ 141 stdcall -noname FileMenu_DeleteItemByFirstID(long long)
+ 142 stdcall -noname FileMenu_DeleteSeparator(long)
+ 143 stdcall -noname FileMenu_EnableItemByCmd(long long long)
+ 144 stdcall -noname FileMenu_GetItemExtent(long long)
+ 145 stdcall -noname PathFindOnPath(ptr ptr) PathFindOnPathAW
+ 146 stdcall -noname RLBuildListOfPaths()
+ 147 stdcall -noname SHCLSIDFromString(long long) SHCLSIDFromStringAW
+ 149 stdcall -noname SHFind_InitMenuPopup(long long long long)
 
- 151 stdcall SHLoadOLE (long)
- 152 stdcall ILGetSize(ptr)
- 153 stdcall ILGetNext(ptr)
- 154 stdcall ILAppend (long long long)
- 155 stdcall ILFree (ptr)
- 156 stdcall ILGlobalFree (ptr)
- 157 stdcall ILCreateFromPath (ptr) ILCreateFromPathAW
- 158 stdcall PathGetExtension(str long long) PathGetExtensionAW
- 159 stdcall PathIsDirectory(ptr)PathIsDirectoryAW
+ 151 stdcall -noname SHLoadOLE(long)
+ 152 stdcall -noname ILGetSize(ptr)
+ 153 stdcall -noname ILGetNext(ptr)
+ 154 stdcall -noname ILAppend(long long long)
+ 155 stdcall -noname ILFree(ptr)
+ 156 stdcall -noname ILGlobalFree(ptr)
+ 157 stdcall -noname ILCreateFromPath(ptr) ILCreateFromPathAW
+ 158 stdcall -noname PathGetExtension(str long long) PathGetExtensionAW
+ 159 stdcall -noname PathIsDirectory(ptr) PathIsDirectoryAW
  160 stub SHNetConnectionDialog
- 161 stdcall SHRunControlPanel (long long)
- 162 stdcall SHSimpleIDListFromPath (ptr) SHSimpleIDListFromPathAW
- 163 stdcall StrToOleStr (wstr str) StrToOleStrAW
- 164 stdcall Win32DeleteFile(str) Win32DeleteFileAW
- 165 stdcall SHCreateDirectory(long ptr)
- 166 stdcall CallCPLEntry16(long long long long long long)
- 167 stdcall SHAddFromPropSheetExtArray(long long long)
- 168 stdcall SHCreatePropSheetExtArray(long str long)
- 169 stdcall SHDestroyPropSheetExtArray(long)
- 170 stdcall SHReplaceFromPropSheetExtArray(long long long long)
- 171 stdcall PathCleanupSpec(ptr ptr)
- 172 stdcall SHCreateLinks(long str ptr long ptr)
- 173 stdcall SHValidateUNC(long long long)
- 174 stdcall SHCreateShellFolderViewEx (ptr ptr)
- 175 stdcall SHGetSpecialFolderPath(long long long long) SHGetSpecialFolderPathAW
- 176 stdcall SHSetInstanceExplorer (long)
+ 161 stdcall -noname SHRunControlPanel(long long)
+ 162 stdcall -noname SHSimpleIDListFromPath(ptr) SHSimpleIDListFromPathAW
+ 163 stdcall -noname StrToOleStr(wstr str) StrToOleStrAW
+ 164 stdcall -noname Win32DeleteFile(str) Win32DeleteFileAW
+ 165 stdcall -noname SHCreateDirectory(long ptr)
+ 166 stdcall -noname CallCPLEntry16(long long long long long long)
+ 167 stdcall -noname SHAddFromPropSheetExtArray(long long long)
+ 168 stdcall -noname SHCreatePropSheetExtArray(long str long)
+ 169 stdcall -noname SHDestroyPropSheetExtArray(long)
+ 170 stdcall -noname SHReplaceFromPropSheetExtArray(long long long long)
+ 171 stdcall -noname PathCleanupSpec(ptr ptr)
+ 172 stdcall -noname SHCreateLinks(long str ptr long ptr)
+ 173 stdcall -noname SHValidateUNC(long long long)
+ 174 stdcall -noname SHCreateShellFolderViewEx(ptr ptr)
+ 175 stdcall -noname SHGetSpecialFolderPath(long long long long) SHGetSpecialFolderPathAW
+ 176 stdcall -noname SHSetInstanceExplorer(long)
  177 stub DAD_SetDragImageFromListView
- 178 stdcall SHObjectProperties(long long wstr wstr)
- 179 stdcall SHGetNewLinkInfoA(str str ptr long long)
- 180 stdcall SHGetNewLinkInfoW(wstr wstr ptr long long)
- 181 stdcall RegisterShellHook(long long)
- 182 varargs ShellMessageBoxW(long long long str long)
- 183 varargs ShellMessageBoxA(long long long str long)
- 184 stdcall ArrangeWindows(long long long long long)
+ 178 stdcall -noname SHObjectProperties(long long wstr wstr)
+ 179 stdcall -noname SHGetNewLinkInfoA(str str ptr long long)
+ 180 stdcall -noname SHGetNewLinkInfoW(wstr wstr ptr long long)
+ 181 stdcall -noname RegisterShellHook(long long)
+ 182 varargs -noname ShellMessageBoxW(long long long str long)
+ 183 varargs -noname ShellMessageBoxA(long long long str long)
+ 184 stdcall -noname ArrangeWindows(long long long long long)
  185 stub SHHandleDiskFull
- 186 stdcall ILGetDisplayNameEx(ptr ptr ptr long)
+ 186 stdcall -noname ILGetDisplayNameEx(ptr ptr ptr long)
  187 stub ILGetPseudoNameW
- 188 stdcall ShellDDEInit(long)
- 189 stdcall ILCreateFromPathA(str)
- 190 stdcall ILCreateFromPathW(wstr)
- 191 stdcall SHUpdateImageA(str long long long)
- 192 stdcall SHUpdateImageW(wstr long long long)
- 193 stdcall SHHandleUpdateImage(ptr)
+ 188 stdcall -noname ShellDDEInit(long)
+ 189 stdcall -noname ILCreateFromPathA(str)
+ 190 stdcall -noname ILCreateFromPathW(wstr)
+ 191 stdcall -noname SHUpdateImageA(str long long long)
+ 192 stdcall -noname SHUpdateImageW(wstr long long long)
+ 193 stdcall -noname SHHandleUpdateImage(ptr)
  194 stub SHCreatePropSheetExtArrayEx
- 195 stdcall SHFree(ptr)
- 196 stdcall SHAlloc(long)
+ 195 stdcall -noname SHFree(ptr)
+ 196 stdcall -noname SHAlloc(long)
  197 stub SHGlobalDefect
- 198 stdcall SHAbortInvokeCommand ()
+ 198 stdcall -noname SHAbortInvokeCommand()
  199 stub SHGetFileIcon
  200 stub SHLocalAlloc
  201 stub SHLocalFree
  212 stub Printers_AddPrinterPropPages
  213 stub Printers_RegisterWindowW
  214 stub Printers_UnregisterWindow
- 215 stdcall SHStartNetConnectionDialog(long str long)
+ 215 stdcall -noname SHStartNetConnectionDialog(long str long)
  243 stdcall @(long long) shell32_243
- 244 stdcall SHInitRestricted(ptr ptr)
- 247 stdcall SHGetDataFromIDListA (ptr ptr long ptr long)
- 248 stdcall SHGetDataFromIDListW (ptr ptr long ptr long)
- 249 stdcall PathParseIconLocation (ptr) PathParseIconLocationAW
- 250 stdcall PathRemoveExtension (ptr) PathRemoveExtensionAW
- 251 stdcall PathRemoveArgs (ptr) PathRemoveArgsAW
+ 244 stdcall -noname SHInitRestricted(ptr ptr)
+ 249 stdcall -noname PathParseIconLocation(ptr) PathParseIconLocationAW
+ 250 stdcall -noname PathRemoveExtension(ptr) PathRemoveExtensionAW
+ 251 stdcall -noname PathRemoveArgs(ptr) PathRemoveArgsAW
  256 stdcall @(ptr ptr) SHELL32_256
- 271 stub SheChangeDirA
- 272 stub SheChangeDirExA
- 273 stub SheChangeDirExW
- 274 stdcall SheChangeDirW(wstr)
- 275 stub SheConvertPathW
- 276 stub SheFullPathA
- 277 stub SheFullPathW
- 278 stub SheGetCurDrive
- 279 stub SheGetDirA
- 280 stub SheGetDirExW
- 281 stdcall SheGetDirW (long long)
- 282 stub SheGetPathOffsetW
- 283 stub SheRemoveQuotesA
- 284 stub SheRemoveQuotesW
- 285 stub SheSetCurDrive
- 286 stub SheShortenPathA
- 287 stub SheShortenPathW
- 288 stdcall ShellAboutA(long str str long)
- 289 stdcall ShellAboutW(long wstr wstr long)
- 290 stdcall ShellExecuteA(long str str str str long)
- 291 stdcall ShellExecuteEx (long) ShellExecuteExA
- 292 stdcall ShellExecuteExA (long)
- 293 stdcall ShellExecuteExW (long)
- 294 stdcall ShellExecuteW (long wstr wstr wstr wstr long)
- 296 stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconA
- 297 stdcall Shell_NotifyIconA(long ptr)
- 298 stdcall Shell_NotifyIconW(long ptr)
 #299 stub Shl1632_ThunkData32
 #300 stub Shl3216_ThunkData32
- 301 stdcall StrChrA(str long) shlwapi.StrChrA
- 302 stdcall StrChrIA(str long) shlwapi.StrChrIA
- 303 stdcall StrChrIW(wstr long) shlwapi.StrChrIW
- 304 stdcall StrChrW(wstr long) shlwapi.StrChrW
- 305 stdcall StrCmpNA(str str long) shlwapi.StrCmpNA
- 306 stdcall StrCmpNIA(str str long) shlwapi.StrCmpNIA
- 307 stdcall StrCmpNIW(wstr wstr long) shlwapi.StrCmpNIW
- 308 stdcall StrCmpNW(wstr wstr long) shlwapi.StrCmpNW
- 309 stdcall StrCpyNA (ptr str long) lstrcpynA
- 310 stdcall StrCpyNW(wstr wstr long) shlwapi.StrCpyNW
- 311 stdcall StrNCmpA(str str long) shlwapi.StrCmpNA
- 312 stdcall StrNCmpIA(str str long) shlwapi.StrCmpNIA
- 313 stdcall StrNCmpIW(wstr wstr long) shlwapi.StrCmpNIW
- 314 stdcall StrNCmpW(wstr wstr long) shlwapi.StrCmpNW
- 315 stdcall StrNCpyA (ptr str long) lstrcpynA
- 316 stdcall StrNCpyW(wstr wstr long) shlwapi.StrCpyNW
- 317 stdcall StrRChrA(str str long) shlwapi.StrRChrA
- 318 stdcall StrRChrIA(str str long) shlwapi.StrRChrIA
- 319 stdcall StrRChrIW(str str long) shlwapi.StrRChrIW
- 320 stdcall StrRChrW(wstr wstr long) shlwapi.StrRChrW
- 321 stub StrRStrA
- 322 stdcall StrRStrIA(str str str) shlwapi.StrRStrIA
- 323 stdcall StrRStrIW(wstr wstr wstr) shlwapi.StrRStrIW
- 324 stub StrRStrW
- 325 stdcall StrStrA(str str) shlwapi.StrStrA
- 326 stdcall StrStrIA(str str) shlwapi.StrStrIA
- 327 stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW
- 328 stdcall StrStrW(wstr wstr) shlwapi.StrStrW
 
  505 stdcall SHRegCloseKey (long)
  506 stdcall SHRegOpenKeyA (long str long)
  511 stdcall SHRegQueryValueExW (long wstr ptr ptr ptr ptr)
  512 stdcall SHRegDeleteKeyW (long wstr)
 
- 520 stdcall -noname SHAllocShared (ptr long long)
- 521 stdcall -noname SHLockShared (long long)
- 522 stdcall -noname SHUnlockShared (ptr)
- 523 stdcall -noname SHFreeShared (long long)
- 524 stdcall RealDriveType (long long)
+ 520 stdcall -noname SHAllocShared(ptr long long)
+ 521 stdcall -noname SHLockShared(long long)
+ 522 stdcall -noname SHUnlockShared(ptr)
+ 523 stdcall -noname SHFreeShared(long long)
+ 524 stdcall -noname RealDriveType(long long)
  525 stub RealDriveTypeFlags
 
- 640 stdcall NTSHChangeNotifyRegister (long long long long long long)
- 641 stdcall NTSHChangeNotifyDeregister (long)
+ 640 stdcall -noname NTSHChangeNotifyRegister(long long long long long long)
+ 641 stdcall -noname NTSHChangeNotifyDeregister(long)
 
  643 stub SHChangeNotifyReceive
- 644 stdcall SHChangeNotification_Lock(long long ptr ptr)
- 645 stdcall SHChangeNotification_Unlock(long)
+ 644 stdcall -noname SHChangeNotification_Lock(long long ptr ptr)
+ 645 stdcall -noname SHChangeNotification_Unlock(long)
  646 stub SHChangeRegistrationReceive
  647 stub ReceiveAddToRecentDocs
  648 stub SHWaitOp_Operate
 
- 650 stdcall PathIsSameRoot(ptr ptr)PathIsSameRootAW
+ 650 stdcall -noname PathIsSameRoot(ptr ptr) PathIsSameRootAW
 
 # nt40/win98
- 651 stdcall ReadCabinetState (long long) # OldReadCabinetState
- 652 stdcall WriteCabinetState (long)
- 653 stdcall PathProcessCommand (long long long long) PathProcessCommandAW
+ 651 stdcall -noname ReadCabinetState(long long) # OldReadCabinetState
+ 652 stdcall -noname WriteCabinetState(long)
+ 653 stdcall -noname PathProcessCommand(long long long long) PathProcessCommandAW
 
 # win98
- 654 stdcall @(long long)shell32_654 # ReadCabinetState@8
- 660 stdcall FileIconInit(long)
- 680 stdcall IsUserAdmin()
+ 654 stdcall @(long long) shell32_654 # ReadCabinetState@8
+ 660 stdcall -noname FileIconInit(long)
+ 680 stdcall -noname IsUserAdmin()
 
 # >= NT5
- 714 stdcall @(ptr)SHELL32_714 # PathIsTemporaryW
- 730 stdcall RestartDialogEx(long wstr long long)
+ 714 stdcall @(ptr) SHELL32_714 # PathIsTemporaryW
+ 730 stdcall -noname RestartDialogEx(long wstr long long)
 
 1217 stub FOOBAR1217   # no joke! This is the real name!!
 
 @ stdcall Control_FillCache_RunDLLW(long long long long)
 @ stdcall Control_RunDLL(ptr ptr str long) Control_RunDLLA
 @ stdcall Control_RunDLLA(ptr ptr str long)
+@ stub Control_RunDLLAsUserW
 @ stdcall Control_RunDLLW(ptr ptr wstr long)
 @ stdcall -private DllCanUnloadNow() SHELL32_DllCanUnloadNow
+@ stdcall -private DllGetClassObject(long long ptr) SHELL32_DllGetClassObject
 @ stdcall DllInstall(long wstr)SHELL32_DllInstall
 @ stdcall -private DllRegisterServer() SHELL32_DllRegisterServer
 @ stdcall -private DllUnregisterServer() SHELL32_DllUnregisterServer
 @ stdcall DoEnvironmentSubstA(str str)
 @ stdcall DoEnvironmentSubstW(wstr wstr)
+@ stdcall DragAcceptFiles(long long)
+@ stdcall DragFinish(long)
+@ stdcall DragQueryFile(long long ptr long) DragQueryFileA
+@ stdcall DragQueryFileA(long long ptr long)
 @ stub DragQueryFileAorW
+@ stdcall DragQueryFileW(long long ptr long)
+@ stdcall DragQueryPoint(long ptr)
 @ stdcall DuplicateIcon(long long)
 @ stdcall ExtractAssociatedIconA(long str ptr)
 @ stdcall ExtractAssociatedIconExA(long str long long)
 @ stub FindExeDlgProc
 @ stdcall FindExecutableA(ptr ptr ptr)
 @ stdcall FindExecutableW(wstr wstr wstr)
+@ stub FixupOptionalComponents
 @ stdcall FreeIconList(long)
 @ stub InternalExtractIconListA
 @ stub InternalExtractIconListW
+@ stub OCInstall
 @ stub OpenAs_RunDLL
 @ stub OpenAs_RunDLLA
 @ stub OpenAs_RunDLLW
 @ stdcall SHBrowseForFolderA(ptr)
 @ stdcall SHBrowseForFolderW(ptr)
 @ stdcall SHChangeNotify (long long ptr ptr)
+@ stub SHChangeNotifySuspendResume
 @ stdcall SHCreateDirectoryExA(long str ptr)
 @ stdcall SHCreateDirectoryExW(long wstr ptr)
+@ stub SHCreateProcessAsUserW
+@ stdcall SheChangeDirA(str)
+@ stub SheChangeDirExA
+@ stub SheChangeDirExW
+@ stdcall SheChangeDirW(wstr)
+@ stub SheConvertPathW
+@ stub SheFullPathA
+@ stub SheFullPathW
+@ stub SheGetCurDrive
+@ stdcall SheGetDirA(long long)
+@ stub SheGetDirExW
+@ stdcall SheGetDirW (long long)
+@ stub SheGetPathOffsetW
+@ stdcall ShellAboutA(long str str long)
+@ stdcall ShellAboutW(long wstr wstr long)
+@ stdcall ShellExecuteA(long str str str str long)
+@ stdcall ShellExecuteEx (long) ShellExecuteExA
+@ stdcall ShellExecuteExA (long)
+@ stdcall ShellExecuteExW (long)
+@ stdcall ShellExecuteW (long wstr wstr wstr wstr long)
 @ stub ShellHookProc
+@ stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIconA
+@ stdcall Shell_NotifyIconA(long ptr)
+@ stdcall Shell_NotifyIconW(long ptr)
 @ stdcall SHEmptyRecycleBinA(long str long)
 @ stdcall SHEmptyRecycleBinW(long wstr long)
+@ stub SheRemoveQuotesA
+@ stub SheRemoveQuotesW
+@ stub SheSetCurDrive
+@ stub SheShortenPathA
+@ stub SheShortenPathW
+@ stub SHExtractIconsW
 @ stdcall SHFileOperation(ptr) SHFileOperationA
 @ stdcall SHFileOperationA(ptr)
 @ stdcall SHFileOperationW(ptr)
 @ stdcall SHFormatDrive(long long long long)
 @ stdcall SHFreeNameMappings(ptr)
+@ stdcall SHGetDataFromIDListA(ptr ptr long ptr long)
+@ stdcall SHGetDataFromIDListW(ptr ptr long ptr long)
 @ stdcall SHGetDesktopFolder(ptr)
 @ stdcall SHGetFileInfo(ptr long ptr long long) SHGetFileInfoA
 @ stdcall SHGetFileInfoA(ptr long ptr long long)
 @ stdcall SHGetPathFromIDListW(ptr ptr)
 @ stdcall SHGetSettings(ptr long)
 @ stdcall SHGetSpecialFolderLocation(long long ptr)
-@ stdcall SHHelpShortcuts_RunDLL(long long long long)
-@ stub SHHelpShortcuts_RunDLLA
-@ stub SHHelpShortcuts_RunDLLW
+@ stdcall SHHelpShortcuts_RunDLL(long long long long) SHHelpShortcuts_RunDLLA
+@ stdcall SHHelpShortcuts_RunDLLA(long long long long)
+@ stdcall SHHelpShortcuts_RunDLLW(long long long long)
+@ stub SHInvokePrinterCommandA
+@ stub SHInvokePrinterCommandW
+@ stub SHIsFileAvailableOffline
 @ stdcall SHLoadInProc(long)
+@ stub SHLoadNonloadedIconOverlayIdentifiers
+@ stub SHPathPrepareForWriteA
+@ stub SHPathPrepareForWriteW
 @ stdcall SHQueryRecycleBinA(str ptr)
 @ stdcall SHQueryRecycleBinW(wstr ptr)
 @ stub SHUpdateRecycleBinIcon
+@ stdcall StrChrA(str long) shlwapi.StrChrA
+@ stdcall StrChrIA(str long) shlwapi.StrChrIA
+@ stdcall StrChrIW(wstr long) shlwapi.StrChrIW
+@ stdcall StrChrW(wstr long) shlwapi.StrChrW
+@ stdcall StrCmpNA(str str long) shlwapi.StrCmpNA
+@ stdcall StrCmpNIA(str str long) shlwapi.StrCmpNIA
+@ stdcall StrCmpNIW(wstr wstr long) shlwapi.StrCmpNIW
+@ stdcall StrCmpNW(wstr wstr long) shlwapi.StrCmpNW
+@ stdcall StrCpyNA (ptr str long) kernel32.lstrcpynA
+@ stdcall StrCpyNW(wstr wstr long) shlwapi.StrCpyNW
+@ stdcall StrNCmpA(str str long) shlwapi.StrCmpNA
+@ stdcall StrNCmpIA(str str long) shlwapi.StrCmpNIA
+@ stdcall StrNCmpIW(wstr wstr long) shlwapi.StrCmpNIW
+@ stdcall StrNCmpW(wstr wstr long) shlwapi.StrCmpNW
+@ stdcall StrNCpyA (ptr str long) kernel32.lstrcpynA
+@ stdcall StrNCpyW(wstr wstr long) shlwapi.StrCpyNW
+@ stdcall StrRChrA(str str long) shlwapi.StrRChrA
+@ stdcall StrRChrIA(str str long) shlwapi.StrRChrIA
+@ stdcall StrRChrIW(str str long) shlwapi.StrRChrIW
+@ stdcall StrRChrW(wstr wstr long) shlwapi.StrRChrW
+@ stub StrRStrA
+@ stdcall StrRStrIA(str str str) shlwapi.StrRStrIA
+@ stdcall StrRStrIW(wstr wstr wstr) shlwapi.StrRStrIW
+@ stub StrRStrW
+@ stdcall StrStrA(str str) shlwapi.StrStrA
+@ stdcall StrStrIA(str str) shlwapi.StrStrIA
+@ stdcall StrStrIW(wstr wstr) shlwapi.StrStrIW
+@ stdcall StrStrW(wstr wstr) shlwapi.StrStrW
 @ stub WOWShellExecute
 
 #
 # version 5.00 (Win2K)
 # _WIN32_IE >= 0x0500
 #
+@ stub ShellExec_RunDLL
+@ stub ShellExec_RunDLLA
+@ stub ShellExec_RunDLLW
 @ stdcall SHBindToParent(ptr ptr ptr ptr)
 @ stdcall SHGetDiskFreeSpaceA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA
 @ stdcall SHGetDiskFreeSpaceExA(str ptr ptr ptr) kernel32.GetDiskFreeSpaceExA
 @ stdcall SHGetFolderPathA(long long long long ptr)
 @ stdcall SHGetFolderPathW(long long long long ptr)
 @ stdcall SHGetFolderLocation(long long long long ptr)
+@ stub SHGetIconOverlayIndexA
+@ stub SHGetIconOverlayIndexW
 
 # version 6.0 (WinXP)
 # _WIN32_IE >= 0x600
index ec7bd2d..3b4dbe8 100644 (file)
@@ -17,7 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
 
 MENU_001 MENU DISCARDABLE
 BEGIN
index 3ebdf5c..da16006 100644 (file)
@@ -188,3 +188,35 @@ STRINGTABLE DISCARDABLE
        IDS_SHUTDOWN_TITLE      "Desligar"
        IDS_SHUTDOWN_PROMPT     "Você quer finalizar a sessão no ReactOS?"
 }
+
+/* shell folder path default values - */
+STRINGTABLE DISCARDABLE
+{
+       IDS_PROGRAMS                "Menu Iniciar\\Programas"
+       IDS_PERSONAL                "Meus Documentos"
+       IDS_FAVORITES               "Favoritos"
+       IDS_STARTUP                 "Menu Iniciar\\Programas\\Iniciar"
+       IDS_RECENT                  "Recent"
+       IDS_SENDTO                  "SendTo"
+       IDS_STARTMENU               "Menu Iniciar"
+       IDS_MYMUSIC                 "Meus Documentos\\Minhas Músicas"
+       IDS_MYVIDEO                 "Meus Documentos\\Meus Vídeos"
+       IDS_DESKTOPDIRECTORY        "Desktop"
+       IDS_NETHOOD                 "NetHood"
+       IDS_TEMPLATES               "Templates"
+       IDS_APPDATA                 "Application Data"
+       IDS_PRINTHOOD               "PrintHood"
+       IDS_LOCAL_APPDATA           "Configurações locais\\Dados de aplicativos"
+       IDS_INTERNET_CACHE          "Temporary Internet Files"
+       IDS_COOKIES                 "Cookies"
+       IDS_HISTORY                 "Histórico"
+       IDS_PROGRAM_FILES           "Arquivos de programas"
+       IDS_MYPICTURES              "Meus Documentos\\Minhas Imagens"
+       IDS_PROGRAM_FILES_COMMON    "Arquivos de programas\\Arquivos comuns"
+       IDS_COMMON_DOCUMENTS        "Documentos"
+       IDS_ADMINTOOLS              "Menu Iniciar\\Programas\\Ferramentas Administrativas"
+       IDS_COMMON_MUSIC            "Documentos\\Minhas Músicas"
+       IDS_COMMON_PICTURES         "Documentos\\Minhas Imagens"
+       IDS_COMMON_VIDEO            "Documentos\\Meus Vídeos"
+       IDS_CDBURN_AREA             "Configurações locais\\Dados de aplicativos\\Microsoft\\CD Burning"
+}
index 86102cc..dd21543 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998 Juergen Schmied
+ * Copyright 2005 David Nordenberg
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT
 
+MENU_001 MENU DISCARDABLE
+BEGIN
+       MENUITEM "&Stora ikoner",       FCIDM_SHVIEW_BIGICON
+       MENUITEM "S&må ikoner", FCIDM_SHVIEW_SMALLICON
+       MENUITEM "&Lista",              FCIDM_SHVIEW_LISTVIEW
+       MENUITEM "&Detaljer",           FCIDM_SHVIEW_REPORTVIEW
+END
+
+/*
+ shellview background menu
+*/
+MENU_002 MENU DISCARDABLE
+BEGIN
+       POPUP ""
+       BEGIN
+         POPUP "&Visa"
+         BEGIN
+           MENUITEM "&Stora ikoner",   FCIDM_SHVIEW_BIGICON
+           MENUITEM "S&må ikoner",     FCIDM_SHVIEW_SMALLICON
+           MENUITEM "&Lista",          FCIDM_SHVIEW_LISTVIEW
+           MENUITEM "&Detaljer",       FCIDM_SHVIEW_REPORTVIEW
+         END
+         MENUITEM SEPARATOR
+         POPUP "Ordna &ikoner efter"
+         BEGIN
+           MENUITEM "&Namn",   0x30    /* column 0 */
+           MENUITEM "&Typ",    0x32    /* column 2 */
+           MENUITEM "&Storlek",        0x31    /* ... */
+           MENUITEM "&Datum",  0x33
+           MENUITEM SEPARATOR
+           MENUITEM "&Ordna automatiskt",      FCIDM_SHVIEW_AUTOARRANGE
+         END
+         MENUITEM "Rada upp ikoner",   FCIDM_SHVIEW_SNAPTOGRID
+         MENUITEM SEPARATOR
+         MENUITEM "&Uppdatera",                FCIDM_SHVIEW_REFRESH
+         MENUITEM SEPARATOR
+         MENUITEM "K&listra in",               FCIDM_SHVIEW_INSERT
+         MENUITEM "Klistra in som genväg",     FCIDM_SHVIEW_INSERTLINK
+         MENUITEM SEPARATOR
+         POPUP "&Ny"
+         BEGIN
+           MENUITEM "Ny &mapp",        FCIDM_SHVIEW_NEWFOLDER
+           MENUITEM "Ny &genväg",      FCIDM_SHVIEW_NEWLINK
+           MENUITEM SEPARATOR
+         END
+         MENUITEM SEPARATOR
+         MENUITEM "&Egenskaper",       FCIDM_SHVIEW_PROPERTIES
+       END
+END
+
+/*
+ shellview item menu
+*/
+MENU_SHV_FILE MENU DISCARDABLE
+BEGIN
+       POPUP ""
+       BEGIN
+         MENUITEM "&Utforska",         FCIDM_SHVIEW_EXPLORE
+         MENUITEM "&Öppna",            FCIDM_SHVIEW_OPEN
+         MENUITEM SEPARATOR
+         MENUITEM "&Klipp ut",         FCIDM_SHVIEW_CUT
+         MENUITEM "K&opiera",          FCIDM_SHVIEW_COPY
+         MENUITEM SEPARATOR
+         MENUITEM "Skapa &genväg",     FCIDM_SHVIEW_CREATELINK
+         MENUITEM "&Ta bort",          FCIDM_SHVIEW_DELETE
+         MENUITEM "&Byt namn",         FCIDM_SHVIEW_RENAME
+         MENUITEM SEPARATOR
+         MENUITEM "&Egenskaper",       FCIDM_SHVIEW_PROPERTIES
+       END
+END
+
+SHBRSFORFOLDER_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 188, 192
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_SETFONT | DS_3DLOOK
+CAPTION "Bläddra efter mapp"
+FONT 8, "MS Shell Dlg"
+{
+ DEFPUSHBUTTON "OK", 1, 80, 176, 50, 12, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 134, 176, 50, 12, 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
+}
+
 SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 210, 152
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 CAPTION "Om %s"
@@ -37,10 +123,99 @@ CAPTION ""
 FONT 8, "MS Shell Dlg"
 {
  ICON "", 12297, 7, 11, 18, 20, WS_VISIBLE
- LTEXT "Skriv namnet på ett program, en mapp eller ett dokument och ReactOS kommer att öppna det för dig.", 12289, 36, 11, 182, 18
+LTEXT "Skriv namnet på ett program, en mapp eller ett dokument för att öppna det.", 12289, 36, 11, 182, 18
  LTEXT "&Öppna:", 12305, 7, 39, 24, 10
  CONTROL "", 12298, "COMBOBOX", WS_TABSTOP | WS_GROUP | WS_VSCROLL | WS_VISIBLE | CBS_DISABLENOSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWN, 36, 37, 183, 100
  DEFPUSHBUTTON "OK", IDOK, 62, 63, 50, 14, WS_TABSTOP
  PUSHBUTTON "Avbryt", IDCANCEL, 116, 63, 50, 14, WS_TABSTOP
  PUSHBUTTON "&Bläddra...", 12288, 170, 63, 50, 14, WS_TABSTOP
 }
+
+/*
+       special folders
+*/
+STRINGTABLE DISCARDABLE
+{
+       IDS_DESKTOP             "Skrivbord"
+       IDS_MYCOMPUTER          "Den här datorn"
+}
+
+/*
+       context menus
+*/
+STRINGTABLE DISCARDABLE
+{
+       IDS_VIEW_LARGE          "&Stora ikoner"
+       IDS_VIEW_SMALL          "S&må ikoner"
+       IDS_VIEW_LIST           "&Lista"
+       IDS_VIEW_DETAILS        "&Detaljer"
+       IDS_SELECT              "Välj"
+       IDS_OPEN                "Öppna"
+}
+
+STRINGTABLE DISCARDABLE
+{
+       IDS_CREATEFOLDER_DENIED "Kan inte skapa ny mapp: Åtkomst nekad."
+       IDS_CREATEFOLDER_CAPTION "Fel vid försök att skapa ny mapp"
+       IDS_DELETEITEM_CAPTION "Bekräfta borttagning av fil"
+       IDS_DELETEFOLDER_CAPTION "Bekräfta borttagning av mapp"
+       IDS_DELETEITEM_TEXT "Är du säker på att du vill ta bort '%1'?"
+       IDS_DELETEMULTIPLE_TEXT "Är du säker på att du vill ta bort de här %1 objekten?"
+       IDS_OVERWRITEFILE_TEXT "Skriv över fil %1?"
+       IDS_OVERWRITEFILE_CAPTION "Bekräfta filöverskrivning"
+}
+
+/*     columns in the shellview        */
+STRINGTABLE
+BEGIN
+       IDS_SHV_COLUMN1         "Fil"
+       IDS_SHV_COLUMN2         "Storlek"
+       IDS_SHV_COLUMN3         "Typ"
+       IDS_SHV_COLUMN4         "Modifierad"
+       IDS_SHV_COLUMN5         "Attribut"
+       IDS_SHV_COLUMN6         "Storlek"
+       IDS_SHV_COLUMN7         "Storlek tillgänglig"
+       IDS_SHV_COLUMN8         "Namn"
+       IDS_SHV_COLUMN9         "Kommentarer"
+END
+
+/* message box strings */
+STRINGTABLE DISCARDABLE
+{
+       IDS_RESTART_TITLE       "Starta om"
+       IDS_RESTART_PROMPT      "Vill du starta om datorn?"
+       IDS_SHUTDOWN_TITLE      "Stäng av"
+       IDS_SHUTDOWN_PROMPT     "Vill du stänga av datorn?"
+}
+
+/* shell folder path default values */
+STRINGTABLE DISCARDABLE
+{
+       IDS_PROGRAMS                "Start-meny\\Program"
+       IDS_PERSONAL                "Mina dokument"
+       IDS_FAVORITES               "Favoriter"
+       IDS_STARTUP                 "Start-meny\\Program\\Autostart"
+       IDS_RECENT                  "Tidigare"
+       IDS_SENDTO                  "Skicka till"
+       IDS_STARTMENU               "Start-meny"
+       IDS_MYMUSIC                 "Mina dokument\\Min musik"
+       IDS_MYVIDEO                 "Mina dokument\\Mina videoklipp"
+       IDS_DESKTOPDIRECTORY        "Skrivbord"
+       IDS_NETHOOD                 "Nätverk"
+       IDS_TEMPLATES               "Mallar"
+       IDS_APPDATA                 "Application Data"
+       IDS_PRINTHOOD               "Skrivare"
+       IDS_LOCAL_APPDATA           "Lokala inställningar\\Application Data"
+       IDS_INTERNET_CACHE          "Temporary Internet Files"
+       IDS_COOKIES                 "Cookies"
+       IDS_HISTORY                 "Tidigare"
+       IDS_PROGRAM_FILES           "Program"
+       IDS_MYPICTURES              "Mina dokument\\Mina bilder"
+       IDS_PROGRAM_FILES_COMMON    "Program\\Delade filer"
+       IDS_COMMON_DOCUMENTS        "Delade dokument"
+       IDS_ADMINTOOLS              "Start-meny\\Program\\Administrativa verktyg"
+       IDS_COMMON_MUSIC            "Delade dokument\\Min musik"
+       IDS_COMMON_PICTURES         "Delade dokument\\Mina bilder"
+       IDS_COMMON_VIDEO            "Delade dokument\\Mina videoklipp"
+       IDS_CDBURN_AREA             "Lokala inställningar\\Application Data\\Microsoft\\CD Burning"
+}
index f107146..44d3e01 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *                             Shell basics
+ *                 Shell basics
  *
  * Copyright 1998 Marcus Meissner
  * Copyright 1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
@@ -54,7 +54,7 @@ extern const char * const SHELL_Authors[];
 
 #define MORE_DEBUG 1
 /*************************************************************************
- * CommandLineToArgvW                  [SHELL32.@]
+ * CommandLineToArgvW            [SHELL32.@]
  *
  * We must interpret the quotes in the command line to rebuild the argv
  * array correctly:
@@ -92,15 +92,18 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
     LPWSTR cmdline;
     int in_quotes,bcount;
 
-    if (*lpCmdline==0) {
+    if (*lpCmdline==0)
+    {
         /* Return the path to the executable */
         DWORD len, size=16;
 
         hargv=GlobalAlloc(size, 0);
-       argv=GlobalLock(hargv);
-       for (;;) {
+        argv=GlobalLock(hargv);
+        for (;;)
+        {
             len = GetModuleFileNameW(0, (LPWSTR)(argv+1), size-sizeof(LPWSTR));
-            if (!len) {
+            if (!len)
+            {
                 GlobalFree(hargv);
                 return NULL;
             }
@@ -121,8 +124,10 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
     bcount=0;
     in_quotes=0;
     cs=lpCmdline;
-    while (1) {
-        if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes)) {
+    while (1)
+    {
+        if (*cs==0 || ((*cs==0x0009 || *cs==0x0020) && !in_quotes))
+        {
             /* space */
             argc++;
             /* skip the remaining spaces */
@@ -133,14 +138,20 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
                 break;
             bcount=0;
             continue;
-        } else if (*cs==0x005c) {
+        }
+        else if (*cs==0x005c)
+        {
             /* '\', count them */
             bcount++;
-        } else if ((*cs==0x0022) && ((bcount & 1)==0)) {
+        }
+        else if ((*cs==0x0022) && ((bcount & 1)==0))
+        {
             /* unescaped '"' */
             in_quotes=!in_quotes;
             bcount=0;
-        } else {
+        }
+        else
+        {
             /* a regular character */
             bcount=0;
         }
@@ -160,8 +171,10 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
     bcount=0;
     in_quotes=0;
     arg=d=s=cmdline;
-    while (*s) {
-        if ((*s==0x0009 || *s==0x0020) && !in_quotes) {
+    while (*s)
+    {
+        if ((*s==0x0009 || *s==0x0020) && !in_quotes)
+        {
             /* Close the argument and copy it */
             *d=0;
             argv[argc++]=arg;
@@ -174,21 +187,28 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
             /* Start with a new argument */
             arg=d=s;
             bcount=0;
-        } else if (*s==0x005c) {
+        }
+        else if (*s==0x005c)
+        {
             /* '\\' */
             *d++=*s++;
             bcount++;
-        } else if (*s==0x0022) {
+        }
+        else if (*s==0x0022)
+        {
             /* '"' */
-            if ((bcount & 1)==0) {
-                /* Preceeded by an even number of '\', this is half that
+            if ((bcount & 1)==0)
+            {
+                /* Preceded by an even number of '\', this is half that
                  * number of '\', plus a quote which we erase.
                  */
                 d-=bcount/2;
                 in_quotes=!in_quotes;
                 s++;
-            } else {
-                /* Preceeded by an odd number of '\', this is half that
+            }
+            else
+            {
+                /* Preceded by an odd number of '\', this is half that
                  * number of '\' followed by a '"'
                  */
                 d=d-bcount/2-1;
@@ -196,13 +216,16 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
                 s++;
             }
             bcount=0;
-        } else {
+        }
+        else
+        {
             /* a regular character */
             *d++=*s++;
             bcount=0;
         }
     }
-    if (*arg) {
+    if (*arg)
+    {
         *d='\0';
         argv[argc++]=arg;
     }
@@ -212,347 +235,426 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
     return argv;
 }
 
+#define SHGFI_KNOWN_FLAGS \
+    (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \
+     SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \
+     SHGFI_ICON | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | \
+     SHGFI_ICONLOCATION | SHGFI_EXETYPE | SHGFI_SYSICONINDEX | \
+     SHGFI_LINKOVERLAY | SHGFI_SELECTED | SHGFI_ATTR_SPECIFIED)
+
 /*************************************************************************
- * SHGetFileInfoA                      [SHELL32.@]
+ * SHGetFileInfoW            [SHELL32.@]
  *
  */
-
 DWORD WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
-                              SHFILEINFOW *psfi, UINT sizeofpsfi,
-                              UINT flags )
+                            SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags )
 {
-       WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH];
-       int iIndex;
-       DWORD ret = TRUE, dwAttributes = 0;
-       IShellFolder * psfParent = NULL;
-       IExtractIconW * pei = NULL;
-       LPITEMIDLIST    pidlLast = NULL, pidl = NULL;
-       HRESULT hr = S_OK;
-       BOOL IconNotYetLoaded=TRUE;
-
-       TRACE("(%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x)\n",
-         (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags);
-
-       if ((flags & SHGFI_USEFILEATTRIBUTES) && (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL)))
-         return FALSE;
-
-       /* windows initializes this values regardless of the flags */
-        if (psfi != NULL) {
-           psfi->szDisplayName[0] = '\0';
-           psfi->szTypeName[0] = '\0';
-           psfi->iIcon = 0;
+    WCHAR szLocation[MAX_PATH], szFullPath[MAX_PATH];
+    int iIndex;
+    DWORD ret = TRUE, dwAttributes = 0;
+    IShellFolder * psfParent = NULL;
+    IExtractIconW * pei = NULL;
+    LPITEMIDLIST    pidlLast = NULL, pidl = NULL;
+    HRESULT hr = S_OK;
+    BOOL IconNotYetLoaded=TRUE;
+
+    TRACE("%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x\n",
+          (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes,
+          psfi, psfi->dwAttributes, sizeofpsfi, flags);
+
+    if ( (flags & SHGFI_USEFILEATTRIBUTES) && 
+         (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL)))
+        return FALSE;
+
+    /* windows initializes this values regardless of the flags */
+    if (psfi != NULL)
+    {
+        psfi->szDisplayName[0] = '\0';
+        psfi->szTypeName[0] = '\0';
+        psfi->iIcon = 0;
+    }
+
+    if (!(flags & SHGFI_PIDL))
+    {
+        /* SHGitFileInfo should work with absolute and relative paths */
+        if (PathIsRelativeW(path))
+        {
+            GetCurrentDirectoryW(MAX_PATH, szLocation);
+            PathCombineW(szFullPath, szLocation, path);
+        }
+        else
+        {
+            lstrcpynW(szFullPath, path, MAX_PATH);
         }
+    }
 
-       if (!(flags & SHGFI_PIDL)){
-            /* SHGitFileInfo should work with absolute and relative paths */
-            if (PathIsRelativeW(path)){
-                GetCurrentDirectoryW(MAX_PATH, szLocation);
-                PathCombineW(szFullPath, szLocation, path);
-            } else {
-                lstrcpynW(szFullPath, path, MAX_PATH);
+    if (flags & SHGFI_EXETYPE)
+    {
+        BOOL status = FALSE;
+        HANDLE hfile;
+        DWORD BinaryType;
+        IMAGE_DOS_HEADER mz_header;
+        IMAGE_NT_HEADERS nt;
+        DWORD len;
+        char magic[4];
+
+        if (flags != SHGFI_EXETYPE)
+            return 0;
+
+        status = GetBinaryTypeW (szFullPath, &BinaryType);
+        if (!status)
+            return 0;
+        if ((BinaryType == SCS_DOS_BINARY) || (BinaryType == SCS_PIF_BINARY))
+            return 0x4d5a;
+
+        hfile = CreateFileW( szFullPath, GENERIC_READ, FILE_SHARE_READ,
+                             NULL, OPEN_EXISTING, 0, 0 );
+        if ( hfile == INVALID_HANDLE_VALUE )
+            return 0;
+
+        /*
+         * The next section is adapted from MODULE_GetBinaryType, as we need
+         * to examine the image header to get OS and version information. We
+         * know from calling GetBinaryTypeA that the image is valid and either
+         * an NE or PE, so much error handling can be omitted.
+         * Seek to the start of the file and read the header information.
+         */
+
+        SetFilePointer( hfile, 0, NULL, SEEK_SET );
+        ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
+
+        SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+        ReadFile( hfile, magic, sizeof(magic), &len, NULL );
+        if ( *(DWORD*)magic      == IMAGE_NT_SIGNATURE )
+        {
+            SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+            ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
+            CloseHandle( hfile );
+            if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI)
+            {
+                 return IMAGE_NT_SIGNATURE | 
+                       (nt.OptionalHeader.MajorSubsystemVersion << 24) |
+                       (nt.OptionalHeader.MinorSubsystemVersion << 16);
             }
+            return IMAGE_NT_SIGNATURE;
+        }
+        else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
+        {
+            IMAGE_OS2_HEADER ne;
+            SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
+            ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
+            CloseHandle( hfile );
+            if (ne.ne_exetyp == 2)
+                return IMAGE_OS2_SIGNATURE | (ne.ne_expver << 16);
+            return 0;
         }
+        CloseHandle( hfile );
+        return 0;
+    }
 
-       if (flags & SHGFI_EXETYPE) {
-         BOOL status = FALSE;
-         HANDLE hfile;
-         DWORD BinaryType;
-         IMAGE_DOS_HEADER mz_header;
-         IMAGE_NT_HEADERS nt;
-         DWORD len;
-         char magic[4];
-
-         if (flags != SHGFI_EXETYPE) return 0;
-
-         status = GetBinaryTypeW (szFullPath, &BinaryType);
-         if (!status) return 0;
-         if ((BinaryType == SCS_DOS_BINARY)
-               || (BinaryType == SCS_PIF_BINARY)) return 0x4d5a;
-
-         hfile = CreateFileW( szFullPath, GENERIC_READ, FILE_SHARE_READ,
-               NULL, OPEN_EXISTING, 0, 0 );
-         if ( hfile == INVALID_HANDLE_VALUE ) return 0;
-
-       /* The next section is adapted from MODULE_GetBinaryType, as we need
-        * to examine the image header to get OS and version information. We
-        * know from calling GetBinaryTypeA that the image is valid and either
-        * an NE or PE, so much error handling can be omitted.
-        * Seek to the start of the file and read the header information.
-        */
-
-         SetFilePointer( hfile, 0, NULL, SEEK_SET );
-         ReadFile( hfile, &mz_header, sizeof(mz_header), &len, NULL );
-
-         SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-         ReadFile( hfile, magic, sizeof(magic), &len, NULL );
-         if ( *(DWORD*)magic      == IMAGE_NT_SIGNATURE )
-         {
-             SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-             ReadFile( hfile, &nt, sizeof(nt), &len, NULL );
-             CloseHandle( hfile );
-             if (nt.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
-                 return IMAGE_NT_SIGNATURE
-                       | (nt.OptionalHeader.MajorSubsystemVersion << 24)
-                       | (nt.OptionalHeader.MinorSubsystemVersion << 16);
-             }
-             return IMAGE_NT_SIGNATURE;
-         }
-         else if ( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
-         {
-             IMAGE_OS2_HEADER ne;
-             SetFilePointer( hfile, mz_header.e_lfanew, NULL, SEEK_SET );
-             ReadFile( hfile, &ne, sizeof(ne), &len, NULL );
-             CloseHandle( hfile );
-             if (ne.ne_exetyp == 2) return IMAGE_OS2_SIGNATURE
-                       | (ne.ne_expver << 16);
-             return 0;
-         }
-         CloseHandle( hfile );
-         return 0;
-      }
-
-      /* psfi is NULL normally to query EXE type. If it is NULL, none of the
-       * below makes sense anyway. Windows allows this and just returns FALSE */
-      if (psfi == NULL) return FALSE;
-
-       /* translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
-        * is not specified.
-          The pidl functions fail on not existing file names */
-
-       if (flags & SHGFI_PIDL) {
-           pidl = ILClone((LPCITEMIDLIST)path);
-       } else if (!(flags & SHGFI_USEFILEATTRIBUTES)) {
-           hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes);
-       }
-
-        if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES))
+    /*
+     * psfi is NULL normally to query EXE type. If it is NULL, none of the
+     * below makes sense anyway. Windows allows this and just returns FALSE
+     */
+    if (psfi == NULL)
+        return FALSE;
+
+    /*
+     * translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES
+     * is not specified.
+     * The pidl functions fail on not existing file names
+     */
+
+    if (flags & SHGFI_PIDL)
+    {
+        pidl = ILClone((LPCITEMIDLIST)path);
+    }
+    else if (!(flags & SHGFI_USEFILEATTRIBUTES))
+    {
+        hr = SHILCreateFromPathW(szFullPath, &pidl, &dwAttributes);
+    }
+
+    if ((flags & SHGFI_PIDL) || !(flags & SHGFI_USEFILEATTRIBUTES))
+    {
+        /* get the parent shellfolder */
+        if (pidl)
+        {
+            hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent,
+                                (LPCITEMIDLIST*)&pidlLast );
+            ILFree(pidl);
+        }
+        else
         {
-          /* get the parent shellfolder */
-          if (pidl) {
-             hr = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, (LPCITEMIDLIST*)&pidlLast);
-             ILFree(pidl);
-          } else {
-             ERR("pidl is null!\n");
-             return FALSE;
-          }
+            ERR("pidl is null!\n");
+            return FALSE;
         }
+    }
 
-       /* get the attributes of the child */
-       if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES))
-       {
-         if (!(flags & SHGFI_ATTR_SPECIFIED))
-         {
-           psfi->dwAttributes = 0xffffffff;
-         }
-         IShellFolder_GetAttributesOf(psfParent, 1, (LPCITEMIDLIST*)&pidlLast, &(psfi->dwAttributes));
-       }
-
-       /* get the displayname */
-       if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME))
-       {
-         if (flags & SHGFI_USEFILEATTRIBUTES)
-         {
-           lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath));
-         }
-         else
-         {
-           STRRET str;
-           hr = IShellFolder_GetDisplayNameOf(psfParent, pidlLast, SHGDN_INFOLDER, &str);
-           StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast);
-         }
-       }
-
-       /* get the type name */
-       if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME))
+    /* get the attributes of the child */
+    if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES))
+    {
+        if (!(flags & SHGFI_ATTR_SPECIFIED))
         {
-            static const WCHAR szFile[] = { 'F','i','l','e',0 };
-            static const WCHAR szDashFile[] = { '-','f','i','l','e',0 };
-            if (!(flags & SHGFI_USEFILEATTRIBUTES))
-            {
-                char ftype[80];
-                _ILGetFileType(pidlLast, ftype, 80);
-                MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 );
-            }
-            else
+            psfi->dwAttributes = 0xffffffff;
+        }
+        IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast,
+                                      &(psfi->dwAttributes) );
+    }
+
+    /* get the displayname */
+    if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME))
+    {
+        if (flags & SHGFI_USEFILEATTRIBUTES)
+        {
+            lstrcpyW (psfi->szDisplayName, PathFindFileNameW(szFullPath));
+        }
+        else
+        {
+            STRRET str;
+            hr = IShellFolder_GetDisplayNameOf( psfParent, pidlLast,
+                                                SHGDN_INFOLDER, &str);
+            StrRetToStrNW (psfi->szDisplayName, MAX_PATH, &str, pidlLast);
+        }
+    }
+
+    /* get the type name */
+    if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME))
+    {
+        static const WCHAR szFile[] = { 'F','i','l','e',0 };
+        static const WCHAR szDashFile[] = { '-','f','i','l','e',0 };
+
+        if (!(flags & SHGFI_USEFILEATTRIBUTES))
+        {
+            char ftype[80];
+
+            _ILGetFileType(pidlLast, ftype, 80);
+            MultiByteToWideChar(CP_ACP, 0, ftype, -1, psfi->szTypeName, 80 );
+        }
+        else
+        {
+            if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                strcatW (psfi->szTypeName, szFile);
+            else 
             {
-                if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                   strcatW (psfi->szTypeName, szFile);
-                else 
+                WCHAR sTemp[64];
+
+                lstrcpyW(sTemp,PathFindExtensionW(szFullPath));
+                if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE) &&
+                    HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE )))
                 {
-                   WCHAR sTemp[64];
-                   lstrcpyW(sTemp,PathFindExtensionW(szFullPath));
-                   if (!( HCR_MapTypeToValueW(sTemp, sTemp, 64, TRUE)
-                        && HCR_MapTypeToValueW(sTemp, psfi->szTypeName, 80, FALSE )))
-                   {
-                       lstrcpynW (psfi->szTypeName, sTemp, 64);
-                       strcatW (psfi->szTypeName, szDashFile);
-                   }
+                    lstrcpynW (psfi->szTypeName, sTemp, 64);
+                    strcatW (psfi->szTypeName, szDashFile);
                 }
             }
         }
+    }
 
-       /* ### icons ###*/
-       if (flags & SHGFI_LINKOVERLAY)
-         FIXME("set icon to link, stub\n");
+    /* ### icons ###*/
+    if (flags & SHGFI_ADDOVERLAYS)
+        FIXME("SHGFI_ADDOVERLAYS unhandled\n");
 
-       if (flags & SHGFI_SELECTED)
-         FIXME("set icon to selected, stub\n");
+    if (flags & SHGFI_OVERLAYINDEX)
+        FIXME("SHGFI_OVERLAYINDEX unhandled\n");
 
-       if (flags & SHGFI_SHELLICONSIZE)
-         FIXME("set icon to shell size, stub\n");
+    if (flags & SHGFI_LINKOVERLAY)
+        FIXME("set icon to link, stub\n");
 
-       /* get the iconlocation */
-       if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
-       {
-         UINT uDummy,uFlags;
-         hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconA, &uDummy, (LPVOID*)&pei);
+    if (flags & SHGFI_SELECTED)
+        FIXME("set icon to selected, stub\n");
 
-         if (SUCCEEDED(hr))
-         {
-           hr = IExtractIconW_GetIconLocation(pei, (flags & SHGFI_OPENICON)? GIL_OPENICON : 0,szLocation, MAX_PATH, &iIndex, &uFlags);
-           psfi->iIcon = iIndex;
+    if (flags & SHGFI_SHELLICONSIZE)
+        FIXME("set icon to shell size, stub\n");
+
+    /* get the iconlocation */
+    if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
+    {
+        UINT uDummy,uFlags;
 
-           if(uFlags != GIL_NOTFILENAME)
-             lstrcpyW (psfi->szDisplayName, szLocation);
-           else
-             ret = FALSE;
+        hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1,
+               (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconA,
+               &uDummy, (LPVOID*)&pei);
+        if (SUCCEEDED(hr))
+        {
+            hr = IExtractIconW_GetIconLocation(pei, 
+                    (flags & SHGFI_OPENICON)? GIL_OPENICON : 0,
+                    szLocation, MAX_PATH, &iIndex, &uFlags);
+            psfi->iIcon = iIndex;
 
-           IExtractIconA_Release(pei);
-         }
-       }
+            if (uFlags != GIL_NOTFILENAME)
+                lstrcpyW (psfi->szDisplayName, szLocation);
+            else
+                ret = FALSE;
 
-       /* get icon index (or load icon)*/
-       if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX)))
-       {
+            IExtractIconA_Release(pei);
+        }
+    }
 
-         if (flags & SHGFI_USEFILEATTRIBUTES)
-         {
-           WCHAR sTemp [MAX_PATH];
-           WCHAR * szExt;
-           DWORD dwNr=0;
+    /* get icon index (or load icon)*/
+    if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX)))
+    {
+        if (flags & SHGFI_USEFILEATTRIBUTES)
+        {
+            WCHAR sTemp [MAX_PATH];
+            WCHAR * szExt;
+            DWORD dwNr=0;
 
-           lstrcpynW(sTemp, szFullPath, MAX_PATH);
+            lstrcpynW(sTemp, szFullPath, MAX_PATH);
 
             if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-               psfi->iIcon = 2;
+                psfi->iIcon = 2;
             else
             {
-               static const WCHAR p1W[] = {'%','1',0};
-               psfi->iIcon = 0;
-               szExt = (LPWSTR) PathFindExtensionW(sTemp);
-               if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE)
-                   && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &dwNr))
-               {
-                  if (!lstrcmpW(p1W,sTemp))            /* icon is in the file */
-                     strcpyW(sTemp, szFullPath);
-
-                  if (flags & SHGFI_SYSICONINDEX) 
-                  {
-                      psfi->iIcon = SIC_GetIconIndex(sTemp,dwNr);
-                      if (psfi->iIcon == -1) psfi->iIcon = 0;
-                  }
-                  else 
-                  {
-                      IconNotYetLoaded=FALSE;
-                      PrivateExtractIconsW(sTemp,dwNr,(flags & SHGFI_SMALLICON) ? 
-                        GetSystemMetrics(SM_CXSMICON) : GetSystemMetrics(SM_CXICON),
-                        (flags & SHGFI_SMALLICON) ? GetSystemMetrics(SM_CYSMICON) :
-                        GetSystemMetrics(SM_CYICON), &psfi->hIcon,0,1,0);
-                      psfi->iIcon = dwNr;
-                  }
-               }
+                static const WCHAR p1W[] = {'%','1',0};
+
+                psfi->iIcon = 0;
+                szExt = (LPWSTR) PathFindExtensionW(sTemp);
+                if ( szExt &&
+                     HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) &&
+                     HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &dwNr))
+                {
+                    if (!lstrcmpW(p1W,sTemp))            /* icon is in the file */
+                        strcpyW(sTemp, szFullPath);
+
+                    if (flags & SHGFI_SYSICONINDEX) 
+                    {
+                        psfi->iIcon = SIC_GetIconIndex(sTemp,dwNr);
+                        if (psfi->iIcon == -1)
+                            psfi->iIcon = 0;
+                    }
+                    else 
+                    {
+                        IconNotYetLoaded=FALSE;
+                        if (flags & SHGFI_SMALLICON)
+                            PrivateExtractIconsW( sTemp,dwNr,
+                                GetSystemMetrics( SM_CXSMICON ),
+                                GetSystemMetrics( SM_CYSMICON ),
+                                &psfi->hIcon, 0, 1, 0);
+                        else
+                            PrivateExtractIconsW( sTemp, dwNr,
+                                GetSystemMetrics( SM_CXICON),
+                                GetSystemMetrics( SM_CYICON),
+                                &psfi->hIcon, 0, 1, 0);
+                        psfi->iIcon = dwNr;
+                    }
+                }
             }
-         }
-         else
-         {
-           if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
-             (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon))))
-           {
-             ret = FALSE;
-           }
-         }
-         if (ret)
-         {
-           ret = (DWORD) ((flags & SHGFI_SMALLICON) ? ShellSmallIconList : ShellBigIconList);
-         }
-       }
-
-       /* icon handle */
-       if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded)
-         psfi->hIcon = ImageList_GetIcon((flags & SHGFI_SMALLICON) ? ShellSmallIconList:ShellBigIconList, psfi->iIcon, ILD_NORMAL);
-
-       if (flags & (SHGFI_UNKNOWN1 | SHGFI_UNKNOWN2 | SHGFI_UNKNOWN3))
-         FIXME("unknown attribute!\n");
-
-       if (psfParent)
-         IShellFolder_Release(psfParent);
-
-       if (hr != S_OK)
-         ret = FALSE;
-
-       if(pidlLast) SHFree(pidlLast);
+        }
+        else
+        {
+            if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON),
+                (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon))))
+            {
+                ret = FALSE;
+            }
+        }
+        if (ret)
+        {
+            if (flags & SHGFI_SMALLICON)
+                ret = (DWORD) ShellSmallIconList;
+            else
+                ret = (DWORD) ShellBigIconList;
+        }
+    }
+
+    /* icon handle */
+    if (SUCCEEDED(hr) && (flags & SHGFI_ICON) && IconNotYetLoaded)
+    {
+        if (flags & SHGFI_SMALLICON)
+            psfi->hIcon = ImageList_GetIcon( ShellSmallIconList, psfi->iIcon, ILD_NORMAL);
+        else
+            psfi->hIcon = ImageList_GetIcon( ShellBigIconList, psfi->iIcon, ILD_NORMAL);
+    }
+
+    if (flags & ~SHGFI_KNOWN_FLAGS)
+        FIXME("unknown flags %08x\n", flags & ~SHGFI_KNOWN_FLAGS);
+
+    if (psfParent)
+        IShellFolder_Release(psfParent);
+
+    if (hr != S_OK)
+        ret = FALSE;
+
+    if (pidlLast)
+        SHFree(pidlLast);
+
 #ifdef MORE_DEBUG
-       TRACE ("icon=%p index=0x%08x attr=0x%08lx name=%s type=%s ret=0x%08lx\n",
-               psfi->hIcon, psfi->iIcon, psfi->dwAttributes, debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret);
+    TRACE ("icon=%p index=0x%08x attr=0x%08lx name=%s type=%s ret=0x%08lx\n",
+           psfi->hIcon, psfi->iIcon, psfi->dwAttributes,
+           debugstr_w(psfi->szDisplayName), debugstr_w(psfi->szTypeName), ret);
 #endif
-       return ret;
+
+    return ret;
 }
 
 /*************************************************************************
- * SHGetFileInfoW                      [SHELL32.@]
+ * SHGetFileInfoA            [SHELL32.@]
  */
-
 DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes,
                               SHFILEINFOA *psfi, UINT sizeofpsfi,
                               UINT flags )
 {
-       INT len;
-       LPWSTR temppath;
-       DWORD ret;
-       SHFILEINFOW temppsfi;
-
-       if (flags & SHGFI_PIDL) {
-         /* path contains a pidl */
-         temppath = (LPWSTR) path;
-       } else {
-         len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
-         temppath = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
-         MultiByteToWideChar(CP_ACP, 0, path, -1, temppath, len);
-       }
-
-       if(psfi && (flags & SHGFI_ATTR_SPECIFIED))
-               temppsfi.dwAttributes=psfi->dwAttributes;
-
-       ret = SHGetFileInfoW(temppath, dwFileAttributes, (psfi == NULL)? NULL : &temppsfi, sizeof(temppsfi), flags);
-
-        if (psfi)
+    INT len;
+    LPWSTR temppath;
+    DWORD ret;
+    SHFILEINFOW temppsfi;
+
+    if (flags & SHGFI_PIDL)
+    {
+        /* path contains a pidl */
+        temppath = (LPWSTR) path;
+    }
+    else
+    {
+        len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
+        temppath = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, path, -1, temppath, len);
+    }
+
+    if (psfi && (flags & SHGFI_ATTR_SPECIFIED))
+        temppsfi.dwAttributes=psfi->dwAttributes;
+
+    if (psfi == NULL)
+        ret = SHGetFileInfoW(temppath, dwFileAttributes, NULL, sizeof(temppsfi), flags);
+    else
+        ret = SHGetFileInfoW(temppath, dwFileAttributes, &temppsfi, sizeof(temppsfi), flags);
+
+    if (psfi)
+    {
+        if(flags & SHGFI_ICON)
+            psfi->hIcon=temppsfi.hIcon;
+        if(flags & (SHGFI_SYSICONINDEX|SHGFI_ICON|SHGFI_ICONLOCATION))
+            psfi->iIcon=temppsfi.iIcon;
+        if(flags & SHGFI_ATTRIBUTES)
+            psfi->dwAttributes=temppsfi.dwAttributes;
+        if(flags & (SHGFI_DISPLAYNAME|SHGFI_ICONLOCATION))
+        {
+            WideCharToMultiByte(CP_ACP, 0, temppsfi.szDisplayName, -1,
+                  psfi->szDisplayName, sizeof(psfi->szDisplayName), NULL, NULL);
+        }
+        if(flags & SHGFI_TYPENAME)
         {
-            if(flags & SHGFI_ICON)
-                psfi->hIcon=temppsfi.hIcon;
-            if(flags & (SHGFI_SYSICONINDEX|SHGFI_ICON|SHGFI_ICONLOCATION))
-                psfi->iIcon=temppsfi.iIcon;
-            if(flags & SHGFI_ATTRIBUTES)
-                psfi->dwAttributes=temppsfi.dwAttributes;
-            if(flags & (SHGFI_DISPLAYNAME|SHGFI_ICONLOCATION))
-                WideCharToMultiByte(CP_ACP, 0, temppsfi.szDisplayName, -1, psfi->szDisplayName, sizeof(psfi->szDisplayName), NULL, NULL);
-            if(flags & SHGFI_TYPENAME)
-                WideCharToMultiByte(CP_ACP, 0, temppsfi.szTypeName, -1, psfi->szTypeName, sizeof(psfi->szTypeName), NULL, NULL);
+            WideCharToMultiByte(CP_ACP, 0, temppsfi.szTypeName, -1,
+                  psfi->szTypeName, sizeof(psfi->szTypeName), NULL, NULL);
         }
-        if(!(flags & SHGFI_PIDL)) HeapFree(GetProcessHeap(), 0, temppath);
-       return ret;
+    }
+
+    if (!(flags & SHGFI_PIDL))
+        HeapFree(GetProcessHeap(), 0, temppath);
+
+    return ret;
 }
 
 /*************************************************************************
- * DuplicateIcon                       [SHELL32.@]
+ * DuplicateIcon            [SHELL32.@]
  */
 HICON WINAPI DuplicateIcon( HINSTANCE hInstance, HICON hIcon)
 {
     ICONINFO IconInfo;
     HICON hDupIcon = 0;
 
-    TRACE("(%p, %p)\n", hInstance, hIcon);
+    TRACE("%p %p\n", hInstance, hIcon);
 
-    if(GetIconInfo(hIcon, &IconInfo))
+    if (GetIconInfo(hIcon, &IconInfo))
     {
         hDupIcon = CreateIconIndirect(&IconInfo);
 
@@ -565,47 +667,50 @@ HICON WINAPI DuplicateIcon( HINSTANCE hInstance, HICON hIcon)
 }
 
 /*************************************************************************
- * ExtractIconA                                [SHELL32.@]
+ * ExtractIconA                [SHELL32.@]
  */
 HICON WINAPI ExtractIconA(HINSTANCE hInstance, LPCSTR lpszFile, UINT nIconIndex)
 {   
-  HICON ret;
-  INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
-  LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    HICON ret;
+    INT len = MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, NULL, 0);
+    LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+    TRACE("%p %s %d\n", hInstance, lpszFile, nIconIndex);
 
-  TRACE("%p %s %d\n", hInstance, lpszFile, nIconIndex);
+    MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
+    ret = ExtractIconW(hInstance, lpwstrFile, nIconIndex);
+    HeapFree(GetProcessHeap(), 0, lpwstrFile);
 
-  MultiByteToWideChar(CP_ACP, 0, lpszFile, -1, lpwstrFile, len);
-  ret = ExtractIconW(hInstance, lpwstrFile, nIconIndex);
-  HeapFree(GetProcessHeap(), 0, lpwstrFile);
-  return ret;
+    return ret;
 }
 
 /*************************************************************************
- * ExtractIconW                                [SHELL32.@]
+ * ExtractIconW                [SHELL32.@]
  */
 HICON WINAPI ExtractIconW(HINSTANCE hInstance, LPCWSTR lpszFile, UINT nIconIndex)
 {
-       HICON  hIcon = NULL;
-       UINT ret;
-       UINT cx = GetSystemMetrics(SM_CXICON), cy = GetSystemMetrics(SM_CYICON);
-
-       TRACE("%p %s %d\n", hInstance, debugstr_w(lpszFile), nIconIndex);
-
-       if (nIconIndex == 0xFFFFFFFF) {
-         ret = PrivateExtractIconsW(lpszFile, 0, cx, cy, NULL, NULL, 0, LR_DEFAULTCOLOR);
-         if (ret != 0xFFFFFFFF && ret)
-           return (HICON)ret;
-         return NULL;
-       }
-       else
-         ret = PrivateExtractIconsW(lpszFile, nIconIndex, cx, cy, &hIcon, NULL, 1, LR_DEFAULTCOLOR);
-
-       if (ret == 0xFFFFFFFF)
-         return (HICON)1;
-       else if (ret > 0 && hIcon)
-         return hIcon;
-       return NULL;
+    HICON  hIcon = NULL;
+    UINT ret;
+    UINT cx = GetSystemMetrics(SM_CXICON), cy = GetSystemMetrics(SM_CYICON);
+
+    TRACE("%p %s %d\n", hInstance, debugstr_w(lpszFile), nIconIndex);
+
+    if (nIconIndex == 0xFFFFFFFF)
+    {
+        ret = PrivateExtractIconsW(lpszFile, 0, cx, cy, NULL, NULL, 0, LR_DEFAULTCOLOR);
+        if (ret != 0xFFFFFFFF && ret)
+            return (HICON)ret;
+        return NULL;
+    }
+    else
+        ret = PrivateExtractIconsW(lpszFile, nIconIndex, cx, cy, &hIcon, NULL, 1, LR_DEFAULTCOLOR);
+
+    if (ret == 0xFFFFFFFF)
+        return (HICON)1;
+    else if (ret > 0 && hIcon)
+        return hIcon;
+
+    return NULL;
 }
 
 typedef struct
@@ -616,90 +721,103 @@ typedef struct
     HFONT hFont;
 } ABOUT_INFO;
 
-#define                IDC_STATIC_TEXT1        100
-#define                IDC_STATIC_TEXT2        101
-#define                IDC_LISTBOX             99
-#define                IDC_WINE_TEXT           98
+#define IDC_STATIC_TEXT1   100
+#define IDC_STATIC_TEXT2   101
+#define IDC_LISTBOX        99
+#define IDC_WINE_TEXT      98
 
-#define                DROP_FIELD_TOP          (-15)
-#define                DROP_FIELD_HEIGHT       15
+#define DROP_FIELD_TOP    (-15)
+#define DROP_FIELD_HEIGHT  15
 
 static BOOL __get_dropline( HWND hWnd, LPRECT lprect )
-{ HWND hWndCtl = GetDlgItem(hWnd, IDC_WINE_TEXT);
+{
+    HWND hWndCtl = GetDlgItem(hWnd, IDC_WINE_TEXT);
+
     if( hWndCtl )
-  { GetWindowRect( hWndCtl, lprect );
-       MapWindowPoints( 0, hWnd, (LPPOINT)lprect, 2 );
-       lprect->bottom = (lprect->top += DROP_FIELD_TOP);
-       return TRUE;
+    {
+        GetWindowRect( hWndCtl, lprect );
+        MapWindowPoints( 0, hWnd, (LPPOINT)lprect, 2 );
+        lprect->bottom = (lprect->top += DROP_FIELD_TOP);
+        return TRUE;
     }
     return FALSE;
 }
 
 /*************************************************************************
- * SHAppBarMessage                     [SHELL32.@]
+ * SHAppBarMessage            [SHELL32.@]
  */
 UINT WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
 {
-        int width=data->rc.right - data->rc.left;
-        int height=data->rc.bottom - data->rc.top;
-        RECT rec=data->rc;
-        switch (msg)
-        { case ABM_GETSTATE:
-               return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
-          case ABM_GETTASKBARPOS:
-               GetWindowRect(data->hWnd, &rec);
-               data->rc=rec;
-               return TRUE;
-          case ABM_ACTIVATE:
-               SetActiveWindow(data->hWnd);
-               return TRUE;
-          case ABM_GETAUTOHIDEBAR:
-               data->hWnd=GetActiveWindow();
-               return TRUE;
-          case ABM_NEW:
-               SetWindowPos(data->hWnd,HWND_TOP,rec.left,rec.top,
-                                        width,height,SWP_SHOWWINDOW);
-               return TRUE;
-          case ABM_QUERYPOS:
-               GetWindowRect(data->hWnd, &(data->rc));
-               return TRUE;
-          case ABM_REMOVE:
-               FIXME("ABM_REMOVE broken\n");
-               /* FIXME: this is wrong; should it be DestroyWindow instead? */
-               /*CloseHandle(data->hWnd);*/
-               return TRUE;
-          case ABM_SETAUTOHIDEBAR:
-               SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top,
-                                       width,height,SWP_SHOWWINDOW);
-               return TRUE;
-          case ABM_SETPOS:
-               data->uEdge=(ABE_RIGHT | ABE_LEFT);
-               SetWindowPos(data->hWnd,HWND_TOP,data->rc.left,data->rc.top,
-                                  width,height,SWP_SHOWWINDOW);
-               return TRUE;
-          case ABM_WINDOWPOSCHANGED:
-               return TRUE;
-          }
-      return FALSE;
+    int width=data->rc.right - data->rc.left;
+    int height=data->rc.bottom - data->rc.top;
+    RECT rec=data->rc;
+
+    switch (msg)
+    {
+    case ABM_GETSTATE:
+        return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
+    case ABM_GETTASKBARPOS:
+        GetWindowRect(data->hWnd, &rec);
+        data->rc=rec;
+        return TRUE;
+    case ABM_ACTIVATE:
+        SetActiveWindow(data->hWnd);
+        return TRUE;
+    case ABM_GETAUTOHIDEBAR:
+        data->hWnd=GetActiveWindow();
+        return TRUE;
+    case ABM_NEW:
+        SetWindowPos(data->hWnd,HWND_TOP,rec.left,rec.top,
+                          width,height,SWP_SHOWWINDOW);
+        return TRUE;
+    case ABM_QUERYPOS:
+        GetWindowRect(data->hWnd, &(data->rc));
+        return TRUE;
+    case ABM_REMOVE:
+        FIXME("ABM_REMOVE broken\n");
+        /* FIXME: this is wrong; should it be DestroyWindow instead? */
+        /*CloseHandle(data->hWnd);*/
+        return TRUE;
+    case ABM_SETAUTOHIDEBAR:
+        SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top,
+                         width,height,SWP_SHOWWINDOW);
+        return TRUE;
+    case ABM_SETPOS:
+        data->uEdge=(ABE_RIGHT | ABE_LEFT);
+        SetWindowPos(data->hWnd,HWND_TOP,data->rc.left,data->rc.top,
+                     width,height,SWP_SHOWWINDOW);
+        return TRUE;
+    case ABM_WINDOWPOSCHANGED:
+        return TRUE;
+    }
+    return FALSE;
 }
 
 /*************************************************************************
- * SHHelpShortcuts_RunDLL              [SHELL32.@]
+ * SHHelpShortcuts_RunDLLA        [SHELL32.@]
  *
  */
-DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
-{ FIXME("(%lx, %lx, %lx, %lx) empty stub!\n",
-       dwArg1, dwArg2, dwArg3, dwArg4);
+DWORD WINAPI SHHelpShortcuts_RunDLLA(DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
+{
+    FIXME("(%lx, %lx, %lx, %lx) stub!\n", dwArg1, dwArg2, dwArg3, dwArg4);
+    return 0;
+}
 
-  return 0;
+/*************************************************************************
+ * SHHelpShortcuts_RunDLLA        [SHELL32.@]
+ *
+ */
+DWORD WINAPI SHHelpShortcuts_RunDLLW(DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
+{
+    FIXME("(%lx, %lx, %lx, %lx) stub!\n", dwArg1, dwArg2, dwArg3, dwArg4);
+    return 0;
 }
 
 /*************************************************************************
- * SHLoadInProc                                [SHELL32.@]
+ * SHLoadInProc                [SHELL32.@]
  * Create an instance of specified object class from within
  * the shell process and release it immediately
  */
-
 HRESULT WINAPI SHLoadInProc (REFCLSID rclsid)
 {
     void *ptr = NULL;
@@ -717,7 +835,7 @@ HRESULT WINAPI SHLoadInProc (REFCLSID rclsid)
 }
 
 /*************************************************************************
- * AboutDlgProc                        (internal)
+ * AboutDlgProc            (internal)
  */
 INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
                               LPARAM lParam )
@@ -759,18 +877,20 @@ INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
         return 1;
 
     case WM_PAINT:
-      { RECT rect;
-           PAINTSTRUCT ps;
-           HDC hDC = BeginPaint( hWnd, &ps );
-
-           if( __get_dropline( hWnd, &rect ) ) {
-               SelectObject( hDC, GetStockObject( BLACK_PEN ) );
-               MoveToEx( hDC, rect.left, rect.top, NULL );
-               LineTo( hDC, rect.right, rect.bottom );
-           }
-           EndPaint( hWnd, &ps );
-       }
-       break;
+        {
+            RECT rect;
+            PAINTSTRUCT ps;
+            HDC hDC = BeginPaint( hWnd, &ps );
+
+            if (__get_dropline( hWnd, &rect ))
+            {
+                SelectObject( hDC, GetStockObject( BLACK_PEN ) );
+                MoveToEx( hDC, rect.left, rect.top, NULL );
+                LineTo( hDC, rect.right, rect.bottom );
+            }
+            EndPaint( hWnd, &ps );
+        }
+    break;
 
     case WM_COMMAND:
         if (wParam == IDOK || wParam == IDCANCEL)
@@ -789,7 +909,7 @@ INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
 
 
 /*************************************************************************
- * ShellAboutA                         [SHELL32.288]
+ * ShellAboutA                [SHELL32.288]
  */
 BOOL WINAPI ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon )
 {
@@ -819,7 +939,7 @@ BOOL WINAPI ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIc
 
 
 /*************************************************************************
- * ShellAboutW                         [SHELL32.289]
+ * ShellAboutW                [SHELL32.289]
  */
 BOOL WINAPI ShellAboutW( HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
                              HICON hIcon )
@@ -855,7 +975,8 @@ BOOL WINAPI ShellAboutW( HWND hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
  * FreeIconList (SHELL32.@)
  */
 void WINAPI FreeIconList( DWORD dw )
-{ FIXME("(%lx): stub\n",dw);
+{
+    FIXME("%lx: stub\n",dw);
 }
 
 
@@ -887,7 +1008,7 @@ HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi)
 {
     /* FIXME: shouldn't these values come from the version resource? */
     if (pdvi->cbSize == sizeof(DLLVERSIONINFO) ||
-     pdvi->cbSize == sizeof(DLLVERSIONINFO2))
+        pdvi->cbSize == sizeof(DLLVERSIONINFO2))
     {
         pdvi->dwMajorVersion = WINE_FILEVERSION_MAJOR;
         pdvi->dwMinorVersion = WINE_FILEVERSION_MINOR;
@@ -904,24 +1025,25 @@ HRESULT WINAPI SHELL32_DllGetVersion (DLLVERSIONINFO *pdvi)
                                               WINE_FILEVERSION_PLATFORMID);
         }
         TRACE("%lu.%lu.%lu.%lu\n",
-           pdvi->dwMajorVersion, pdvi->dwMinorVersion,
-           pdvi->dwBuildNumber, pdvi->dwPlatformID);
+              pdvi->dwMajorVersion, pdvi->dwMinorVersion,
+              pdvi->dwBuildNumber, pdvi->dwPlatformID);
         return S_OK;
     }
     else
-       {
+    {
         WARN("wrong DLLVERSIONINFO size from app\n");
         return E_INVALIDARG;
     }
 }
+
 /*************************************************************************
  * global variables of the shell32.dll
  * all are once per process
  *
  */
-HINSTANCE      shell32_hInstance = 0;
-HIMAGELIST     ShellSmallIconList = 0;
-HIMAGELIST     ShellBigIconList = 0;
+HINSTANCE    shell32_hInstance = 0;
+HIMAGELIST   ShellSmallIconList = 0;
+HIMAGELIST   ShellBigIconList = 0;
 
 
 /*************************************************************************
@@ -930,34 +1052,33 @@ HIMAGELIST       ShellBigIconList = 0;
  * NOTES
  *  calling oleinitialize here breaks sone apps.
  */
-
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
 {
-       TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
-
-       switch (fdwReason)
-       {
-         case DLL_PROCESS_ATTACH:
-           shell32_hInstance = hinstDLL;
-           DisableThreadLibraryCalls(shell32_hInstance);
-
-           /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
-           GetModuleFileNameW(hinstDLL, swShell32Name, MAX_PATH);
-            swShell32Name[MAX_PATH - 1] = '\0';
-
-           InitCommonControlsEx(NULL);
-
-           SIC_Initialize();
-           InitChangeNotifications();
-           break;
-
-         case DLL_PROCESS_DETACH:
-             shell32_hInstance = 0;
-             SIC_Destroy();
-             FreeChangeNotifications();
-              break;
-       }
-       return TRUE;
+    TRACE("%p 0x%lx %p\n", hinstDLL, fdwReason, fImpLoad);
+
+    switch (fdwReason)
+    {
+    case DLL_PROCESS_ATTACH:
+        shell32_hInstance = hinstDLL;
+        DisableThreadLibraryCalls(shell32_hInstance);
+
+        /* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
+        GetModuleFileNameW(hinstDLL, swShell32Name, MAX_PATH);
+        swShell32Name[MAX_PATH - 1] = '\0';
+
+        InitCommonControlsEx(NULL);
+
+        SIC_Initialize();
+        InitChangeNotifications();
+        break;
+
+    case DLL_PROCESS_DETACH:
+        shell32_hInstance = 0;
+        SIC_Destroy();
+        FreeChangeNotifications();
+        break;
+    }
+    return TRUE;
 }
 
 /*************************************************************************
@@ -971,9 +1092,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
 
 HRESULT WINAPI SHELL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
 {
-   FIXME("(%s, %s): stub!\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
-
-   return S_OK;                /* indicate success */
+    FIXME("%s %s: stub\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
+    return S_OK;        /* indicate success */
 }
 
 /***********************************************************************
@@ -981,7 +1101,6 @@ HRESULT WINAPI SHELL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
  */
 HRESULT WINAPI SHELL32_DllCanUnloadNow(void)
 {
-    FIXME("(void): stub\n");
-
+    FIXME("stub\n");
     return S_FALSE;
 }
index f2e013e..97ba2dc 100644 (file)
@@ -81,7 +81,7 @@ LPENUMFORMATETC       IEnumFORMATETC_Constructor(UINT, const FORMATETC []);
 
 LPCLASSFACTORY IClassFactory_Constructor(REFCLSID);
 IContextMenu2 *        ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *aPidls, UINT uItemCount);
-IContextMenu2 *        ISvBgCm_Constructor(LPSHELLFOLDER pSFParent);
+IContextMenu2 *        ISvBgCm_Constructor(LPSHELLFOLDER pSFParent, BOOL bDesktop);
 LPSHELLVIEW    IShellView_Constructor(LPSHELLFOLDER);
 
 HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
@@ -92,6 +92,7 @@ HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPV
 HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
 HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+HRESULT WINAPI UnixFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI CPanel_GetIconLocationA(LPITEMIDLIST pidl, LPSTR szIconFile, UINT cchMax, int* piIndex);
 HRESULT WINAPI CPanel_GetIconLocationW(LPITEMIDLIST pidl, LPWSTR szIconFile, UINT cchMax, int* piIndex);
 HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
@@ -220,6 +221,8 @@ UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
 
 extern WCHAR swShell32Name[MAX_PATH];
 
+extern const GUID CLSID_UnixFolder;
+
 /* Default shell folder value registration */
 HRESULT SHELL_RegisterShellFolders(void);
 
index b7b379f..70f2690 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *
- *     Copyright 1997  Marcus Meissner
- *     Copyright 1998  Juergen Schmied
+ *      Copyright 1997  Marcus Meissner
+ *      Copyright 1998  Juergen Schmied
+ *      Copyright 2005  Mike McCormack
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *   Nearly complete informations about the binary formats 
  *   of .lnk files available at http://www.wotsit.org
  *
+ *  You can use winedump to examine the contents of a link file:
+ *   winedump lnk sc.lnk
+ *
+ *  MSI advertised shortcuts are totally undocumented.  They provide an
+ *   icon for a program that is not yet installed, and invoke MSI to
+ *   install the program when the shortcut is clicked on.  They are
+ *   created by passing a special string to SetPath, and the information
+ *   in that string is parsed an stored.
  */
 
 #include "config.h"
 #include "shlguid.h"
 #include "shlwapi.h"
 
+#include "initguid.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+DEFINE_GUID( SHELL32_AdvtShortcutProduct,
+       0x9db1186f,0x40df,0x11d1,0xaa,0x8c,0x00,0xc0,0x4f,0xb6,0x78,0x63);
+DEFINE_GUID( SHELL32_AdvtShortcutComponent,
+       0x9db1186e,0x40df,0x11d1,0xaa,0x8c,0x00,0xc0,0x4f,0xb6,0x78,0x63);
+
 /* link file formats */
 
 /* flag1: lnk elements: simple link has 0x0B */
-#define SCF_PIDL   1
-#define SCF_NORMAL 2
+#define SCF_PIDL 1
+#define SCF_LOCATION 2
 #define SCF_DESCRIPTION 4
 #define SCF_RELATIVE 8
 #define SCF_WORKDIR 0x10
 #define SCF_ARGS 0x20
 #define SCF_CUSTOMICON 0x40
 #define SCF_UNICODE 0x80
+#define SCF_PRODUCT 0x800
+#define SCF_COMPONENT 0x1000
 
 #include "pshpack1.h"
 
@@ -113,6 +131,21 @@ typedef struct _LOCAL_VOLUME_INFO
     DWORD dwVolLabelOfs;
 } LOCAL_VOLUME_INFO;
 
+typedef struct tagLINK_ADVERTISEINFO
+{
+    DWORD size;
+    DWORD magic;
+    CHAR  bufA[MAX_PATH];
+    WCHAR bufW[MAX_PATH];
+} LINK_ADVERTISEINFO;
+
+typedef struct volume_info_t
+{
+    DWORD type;
+    DWORD serial;
+    WCHAR label[12];  /* assume 8.3 */
+} volume_info;
+
 #include "poppack.h"
 
 static IShellLinkAVtbl         slvt;
@@ -146,6 +179,9 @@ typedef struct
        LPWSTR        sWorkDir;
        LPWSTR        sDescription;
        LPWSTR        sPathRel;
+       LPWSTR        sProduct;
+       LPWSTR        sComponent;
+       volume_info   volume;
 
        BOOL            bDirty;
 } IShellLinkImpl;
@@ -172,7 +208,6 @@ inline static LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
     return p;
 }
 
-
 /**************************************************************************
  *  IPersistFile_QueryInterface
  */
@@ -251,8 +286,9 @@ static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFile
 
 static BOOL StartLinkProcessor( LPCOLESTR szLink )
 {
-    static const WCHAR szFormat[] = {'w','i','n','e','m','e','n','u','b','u','i','l','d','e','r','.','e','x','e',
-                              ' ','-','r',' ','"','%','s','"',0 };
+    static const WCHAR szFormat[] = {
+        'w','i','n','e','m','e','n','u','b','u','i','l','d','e','r','.','e','x','e',
+        ' ','-','r',' ','"','%','s','"',0 };
     LONG len;
     LPWSTR buffer;
     STARTUPINFOW si;
@@ -290,7 +326,7 @@ static HRESULT WINAPI IPersistFile_fnSave(IPersistFile* iface, LPCOLESTR pszFile
 
     TRACE("(%p)->(%s)\n",This,debugstr_w(pszFileName));
 
-    if (!pszFileName || !This->sPath)
+    if (!pszFileName)
         return E_FAIL;
 
     r = CreateStreamOnFile(pszFileName, STGM_READWRITE | STGM_CREATE, &stm);
@@ -469,44 +505,175 @@ static HRESULT Stream_LoadString( IStream* stm, BOOL unicode, LPWSTR *pstr )
     return S_OK;
 }
 
-static HRESULT Stream_LoadLocation( IStream* stm )
+static HRESULT Stream_ReadChunk( IStream* stm, LPVOID *data )
 {
     DWORD size;
     ULONG count;
     HRESULT r;
-    LOCATION_INFO *loc;
+    struct sized_chunk {
+        DWORD size;
+        unsigned char data[1];
+    } *chunk;
 
     TRACE("%p\n",stm);
 
     r = IStream_Read( stm, &size, sizeof(size), &count );
-    if( FAILED( r ) )
-        return r;
-    if( count != sizeof(loc->dwTotalSize) )
+    if( FAILED( r )  || count != sizeof(size) )
         return E_FAIL;
 
-    loc = HeapAlloc( GetProcessHeap(), 0, size );
-    if( ! loc )
+    chunk = HeapAlloc( GetProcessHeap(), 0, size );
+    if( !chunk )
         return E_OUTOFMEMORY;
 
-    r = IStream_Read( stm, &loc->dwHeaderSize, size-sizeof(size), &count );
+    chunk->size = size;
+    r = IStream_Read( stm, chunk->data, size - sizeof(size), &count );
+    if( FAILED( r ) || count != (size - sizeof(size)) )
+    {
+        HeapFree( GetProcessHeap(), 0, chunk );
+        return E_FAIL;
+    }
+
+    TRACE("Read %ld bytes\n",chunk->size);
+
+    *data = (LPVOID) chunk;
+
+    return S_OK;
+}
+
+static BOOL Stream_LoadVolume( LOCAL_VOLUME_INFO *vol, volume_info *volume )
+{
+    const int label_sz = sizeof volume->label/sizeof volume->label[0];
+    LPSTR label;
+    int len;
+
+    volume->serial = vol->dwVolSerial;
+    volume->type = vol->dwType;
+
+    if( !vol->dwVolLabelOfs )
+        return FALSE;
+    if( vol->dwSize <= vol->dwVolLabelOfs )
+        return FALSE;
+    len = vol->dwSize - vol->dwVolLabelOfs;
+
+    label = (LPSTR) vol;
+    label += vol->dwVolLabelOfs;
+    MultiByteToWideChar( CP_ACP, 0, label, len, volume->label, label_sz-1);
+
+    return TRUE;
+}
+
+static LPWSTR Stream_LoadPath( LPSTR p, DWORD maxlen )
+{
+    int len = 0, wlen;
+    LPWSTR path;
+
+    while( p[len] && (len < maxlen) )
+        len++;
+
+    wlen = MultiByteToWideChar(CP_ACP, 0, p, len, NULL, 0);
+    path = HeapAlloc(GetProcessHeap(), 0, (wlen+1)*sizeof(WCHAR));
+    MultiByteToWideChar(CP_ACP, 0, p, len, path, wlen);
+    path[wlen] = 0;
+
+    return path;
+}
+
+static HRESULT Stream_LoadLocation( IStream *stm,
+                volume_info *volume, LPWSTR *path )
+{
+    unsigned char *p = NULL;
+    LOCATION_INFO *loc;
+    HRESULT r;
+    int n;
+
+    r = Stream_ReadChunk( stm, (LPVOID*) &p );
+    if( FAILED(r) )
+        return r;
+
+    loc = (LOCATION_INFO*) p;
+    if (loc->dwTotalSize < sizeof(LOCATION_INFO) - sizeof(DWORD))
+    {
+        HeapFree( GetProcessHeap(), 0, p );
+        return E_FAIL;
+    }
+
+    /* if there's valid local volume information, load it */
+    if( loc->dwVolTableOfs && 
+       ((loc->dwVolTableOfs + sizeof(LOCAL_VOLUME_INFO)) <= loc->dwTotalSize) )
+    {
+        LOCAL_VOLUME_INFO *volume_info;
+
+        volume_info = (LOCAL_VOLUME_INFO*) &p[loc->dwVolTableOfs];
+        Stream_LoadVolume( volume_info, volume );
+    }
+
+    /* if there's a local path, load it */
+    n = loc->dwLocalPathOfs;
+    if( n && (n < loc->dwTotalSize) )
+        *path = Stream_LoadPath( &p[n], loc->dwTotalSize - n );
+
+    TRACE("type %ld serial %08lx name %s path %s\n", volume->type,
+          volume->serial, debugstr_w(volume->label), debugstr_w(*path));
+
+    HeapFree( GetProcessHeap(), 0, p );
+    return S_OK;
+}
+
+/*
+ *  The format of the advertised shortcut info seems to be:
+ *
+ *  Offset     Description
+ *  ------     -----------
+ *
+ *    0          Length of the block (4 bytes, usually 0x314)
+ *    4          tag (dword)
+ *    8          string data in ASCII
+ *    8+0x104    string data in UNICODE
+ *
+ * In the original Win32 implementation the buffers are not initialized
+ *  to zero, so data trailing the string is random garbage.
+ */
+static HRESULT Stream_LoadAdvertiseInfo( IStream* stm, LPWSTR *str )
+{
+    DWORD size;
+    ULONG count;
+    HRESULT r;
+    LINK_ADVERTISEINFO buffer;
+    
+    TRACE("%p\n",stm);
+
+    r = IStream_Read( stm, &buffer.size, sizeof (DWORD), &count );
     if( FAILED( r ) )
-        goto end;
-    if( count != (size - sizeof(size)) )
+        return r;
+
+    /* make sure that we read the size of the structure even on error */
+    size = sizeof buffer - sizeof (DWORD);
+    if( buffer.size != sizeof buffer )
     {
-        r = E_FAIL;
-        goto end;
+        ERR("Ooops.  This structure is not as expected...\n");
+        return E_FAIL;
     }
-    loc->dwTotalSize = size;
 
-    TRACE("Read %ld bytes\n",count);
+    r = IStream_Read( stm, &buffer.magic, size, &count );
+    if( FAILED( r ) )
+        return r;
+
+    if( count != size )
+        return E_FAIL;
 
-    /* FIXME: do something useful with it */
-    HeapFree( GetProcessHeap(), 0, loc );
+    TRACE("magic %08lx  string = %s\n", buffer.magic, debugstr_w(buffer.bufW));
+
+    if( (buffer.magic&0xffff0000) != 0xa0000000 )
+    {
+        ERR("Unknown magic number %08lx in advertised shortcut\n", buffer.magic);
+        return E_FAIL;
+    }
+
+    *str = HeapAlloc( GetProcessHeap(), 0, 
+                     (strlenW(buffer.bufW)+1) * sizeof(WCHAR) );
+    strcpyW( *str, buffer.bufW );
 
     return S_OK;
-end:
-    HeapFree( GetProcessHeap(), 0, loc );
-    return r;
 }
 
 /************************************************************************
@@ -519,12 +686,12 @@ static HRESULT WINAPI IPersistStream_fnLoad(
     LINK_HEADER hdr;
     ULONG    dwBytesRead;
     BOOL     unicode;
-    WCHAR    sTemp[MAX_PATH];
     HRESULT  r;
+    DWORD    zero;
 
     _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
 
-    TRACE("(%p)(%p)\n", This, stm);
+    TRACE("%p %p\n", This, stm);
 
     if( !stm )
          return STG_E_INVALIDPOINTER;
@@ -541,30 +708,61 @@ static HRESULT WINAPI IPersistStream_fnLoad(
     if( !IsEqualIID(&hdr.MagicGuid, &CLSID_ShellLink) )
         return E_FAIL;
 
-    /* if( hdr.dwFlags & SCF_PIDL ) */  /* FIXME: seems to always have a PIDL */
-    {
-        r = ILLoadFromStream( stm, &This->pPidl );
-        if( FAILED( r ) )
-            return r;
-    }
+    /* free all the old stuff */
+    ILFree(This->pPidl);
+    This->pPidl = NULL;
+    memset( &This->volume, 0, sizeof This->volume );
+    HeapFree(GetProcessHeap(), 0, This->sPath);
+    This->sPath = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sDescription);
+    This->sDescription = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sPathRel);
+    This->sPathRel = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sWorkDir);
+    This->sWorkDir = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sArgs);
+    This->sArgs = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sIcoPath);
+    This->sIcoPath = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sProduct);
+    This->sProduct = NULL;
+    HeapFree(GetProcessHeap(), 0, This->sComponent);
+    This->sComponent = NULL;
+        
     This->wHotKey = (WORD)hdr.wHotKey;
     This->iIcoNdx = hdr.nIcon;
     FileTimeToSystemTime (&hdr.Time1, &This->time1);
     FileTimeToSystemTime (&hdr.Time2, &This->time2);
     FileTimeToSystemTime (&hdr.Time3, &This->time3);
-#if 1
-    GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time1, NULL, sTemp, 256);
-    TRACE("-- time1: %s\n", debugstr_w(sTemp) );
-    GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time2, NULL, sTemp, 256);
-    TRACE("-- time1: %s\n", debugstr_w(sTemp) );
-    GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&This->time3, NULL, sTemp, 256);
-    TRACE("-- time1: %s\n", debugstr_w(sTemp) );
-    pdump (This->pPidl);
-#endif
-    if( hdr.dwFlags & SCF_NORMAL )
-        r = Stream_LoadLocation( stm );
+    if (TRACE_ON(shell))
+    {
+        WCHAR sTemp[MAX_PATH];
+        GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE, &This->time1,
+                       NULL, sTemp, sizeof(sTemp)/sizeof(*sTemp));
+        TRACE("-- time1: %s\n", debugstr_w(sTemp) );
+        GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE, &This->time2,
+                       NULL, sTemp, sizeof(sTemp)/sizeof(*sTemp));
+        TRACE("-- time2: %s\n", debugstr_w(sTemp) );
+        GetDateFormatW(LOCALE_USER_DEFAULT,DATE_SHORTDATE, &This->time3,
+                       NULL, sTemp, sizeof(sTemp)/sizeof(*sTemp));
+        TRACE("-- time3: %s\n", debugstr_w(sTemp) );
+    }
+
+    /* load all the new stuff */
+    if( hdr.dwFlags & SCF_PIDL )
+    {
+        r = ILLoadFromStream( stm, &This->pPidl );
+        if( FAILED( r ) )
+            return r;
+    }
+    pdump(This->pPidl);
+
+    /* load the location information */
+    if( hdr.dwFlags & SCF_LOCATION )
+        r = Stream_LoadLocation( stm, &This->volume, &This->sPath );
     if( FAILED( r ) )
         goto end;
+
     unicode = hdr.dwFlags & SCF_UNICODE;
     if( hdr.dwFlags & SCF_DESCRIPTION )
     {
@@ -583,7 +781,7 @@ static HRESULT WINAPI IPersistStream_fnLoad(
         goto end;
 
     if( hdr.dwFlags & SCF_WORKDIR )
-          {
+    {
         r = Stream_LoadString( stm, unicode, &This->sWorkDir );
         TRACE("Working Dir  -> %s\n",debugstr_w(This->sWorkDir));
     }
@@ -606,6 +804,26 @@ static HRESULT WINAPI IPersistStream_fnLoad(
     if( FAILED( r ) )
         goto end;
 
+    if( hdr.dwFlags & SCF_PRODUCT )
+    {
+        r = Stream_LoadAdvertiseInfo( stm, &This->sProduct );
+        TRACE("Product      -> %s\n",debugstr_w(This->sProduct));
+    }
+    if( FAILED( r ) )
+        goto end;
+
+    if( hdr.dwFlags & SCF_COMPONENT )
+    {
+        r = Stream_LoadAdvertiseInfo( stm, &This->sComponent );
+        TRACE("Component    -> %s\n",debugstr_w(This->sComponent));
+    }
+    if( FAILED( r ) )
+        goto end;
+
+    r = IStream_Read(stm, &zero, sizeof zero, &dwBytesRead);
+    if( FAILED( r ) || zero || dwBytesRead != sizeof zero )
+        ERR("Last word was not zero\n");
+
     TRACE("OK\n");
 
     pdump (This->pPidl);
@@ -640,19 +858,81 @@ static HRESULT Stream_WriteString( IStream* stm, LPCWSTR str )
     return S_OK;
 }
 
-static HRESULT Stream_WriteLocationInfo( IStream* stm, LPCWSTR filename )
+/************************************************************************
+ * Stream_WriteLocationInfo
+ *
+ * Writes the location info to a stream
+ *
+ * FIXME: One day we might want to write the network volume information
+ *        and the final path.
+ *        Figure out how Windows deals with unicode paths here.
+ */
+static HRESULT Stream_WriteLocationInfo( IStream* stm, LPCWSTR path,
+                                         volume_info *volume )
+{
+    DWORD total_size, path_size, volume_info_size, label_size, final_path_size;
+    LOCAL_VOLUME_INFO *vol;
+    LOCATION_INFO *loc;
+    LPSTR szLabel, szPath, szFinalPath;
+    ULONG count = 0;
+
+    TRACE("%p %s %p\n", stm, debugstr_w(path), volume);
+
+    /* figure out the size of everything */
+    label_size = WideCharToMultiByte( CP_ACP, 0, volume->label, -1,
+                                      NULL, 0, NULL, NULL );
+    path_size = WideCharToMultiByte( CP_ACP, 0, path, -1,
+                                     NULL, 0, NULL, NULL );
+    volume_info_size = sizeof *vol + label_size;
+    final_path_size = 1;
+    total_size = sizeof *loc + volume_info_size + path_size + final_path_size;
+
+    /* create pointers to everything */
+    loc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, total_size);
+    vol = (LOCAL_VOLUME_INFO*) &loc[1];
+    szLabel = (LPSTR) &vol[1];
+    szPath = &szLabel[label_size];
+    szFinalPath = &szPath[path_size];
+
+    /* fill in the location information header */
+    loc->dwTotalSize = total_size;
+    loc->dwHeaderSize = sizeof (*loc);
+    loc->dwFlags = 1;
+    loc->dwVolTableOfs = sizeof (*loc);
+    loc->dwLocalPathOfs = sizeof (*loc) + volume_info_size;
+    loc->dwNetworkVolTableOfs = 0;
+    loc->dwFinalPathOfs = sizeof (*loc) + volume_info_size + path_size;
+
+    /* fill in the volume information */
+    vol->dwSize = volume_info_size;
+    vol->dwType = volume->type;
+    vol->dwVolSerial = volume->serial;
+    vol->dwVolLabelOfs = sizeof (*vol);
+
+    /* copy in the strings */
+    WideCharToMultiByte( CP_ACP, 0, volume->label, -1,
+                         szLabel, label_size, NULL, NULL );
+    WideCharToMultiByte( CP_ACP, 0, path, -1,
+                         szPath, path_size, NULL, NULL );
+    szFinalPath[0] = 0;
+
+    return IStream_Write( stm, loc, total_size, &count );
+}
+
+static HRESULT Stream_WriteAdvertiseInfo( IStream* stm, LPCWSTR string, DWORD magic )
 {
-    LOCATION_INFO loc;
     ULONG count;
+    LINK_ADVERTISEINFO buffer;
+    
+    TRACE("%p\n",stm);
 
-    FIXME("writing empty location info\n");
-
-    memset( &loc, 0, sizeof(loc) );
-    loc.dwTotalSize = sizeof(loc) - sizeof(loc.dwTotalSize);
-
-    /* FIXME: fill this in */
+    memset( &buffer, 0, sizeof buffer );
+    buffer.size = sizeof buffer;
+    buffer.magic = magic;
+    strncpyW( buffer.bufW, string, MAX_PATH );
+    WideCharToMultiByte(CP_ACP, 0, string, -1, buffer.bufA, MAX_PATH, NULL, NULL );
 
-    return IStream_Write( stm, &loc, loc.dwTotalSize, &count );
+    return IStream_Write( stm, &buffer, buffer.size, &count );
 }
 
 /************************************************************************
@@ -670,38 +950,39 @@ static HRESULT WINAPI IPersistStream_fnSave(
     LINK_HEADER header;
     WCHAR   exePath[MAX_PATH];
     ULONG   count;
+    DWORD   zero;
     HRESULT r;
 
     _ICOM_THIS_From_IPersistStream(IShellLinkImpl, iface);
 
-    TRACE("(%p) %p %x\n", This, stm, fClearDirty);
+    TRACE("%p %p %x\n", This, stm, fClearDirty);
 
     *exePath = '\0';
 
     if (This->sPath)
     {
-        SHELL_FindExecutable(NULL, This->sPath, wOpen, exePath, MAX_PATH, NULL, NULL, NULL, NULL);
+        SHELL_FindExecutable(NULL, This->sPath, wOpen, exePath, MAX_PATH,
+                             NULL, NULL, NULL, NULL);
         /*
          * windows can create lnk files to executables that do not exist yet
          * so if the executable does not exist the just trust the path they
          * gave us
          */
-        if( !*exePath ) strcpyW(exePath,This->sPath);
+        if (!*exePath) strcpyW(exePath,This->sPath);
     }
 
-    /* if there's no PIDL, generate one */
-    if( ! This->pPidl ) This->pPidl = ILCreateFromPathW(exePath);
-
     memset(&header, 0, sizeof(header));
     header.dwSize = sizeof(header);
+    header.fStartup = This->iShowCmd;
     memcpy(&header.MagicGuid, &CLSID_ShellLink, sizeof(header.MagicGuid) );
 
     header.wHotKey = This->wHotKey;
     header.nIcon = This->iIcoNdx;
     header.dwFlags = SCF_UNICODE;   /* strings are in unicode */
-    header.dwFlags |= SCF_NORMAL;   /* how do we determine this ? */
     if( This->pPidl )
         header.dwFlags |= SCF_PIDL;
+    if( This->sPath )
+        header.dwFlags |= SCF_LOCATION;
     if( This->sDescription )
         header.dwFlags |= SCF_DESCRIPTION;
     if( This->sWorkDir )
@@ -710,6 +991,10 @@ static HRESULT WINAPI IPersistStream_fnSave(
         header.dwFlags |= SCF_ARGS;
     if( This->sIcoPath )
         header.dwFlags |= SCF_CUSTOMICON;
+    if( This->sProduct )
+        header.dwFlags |= SCF_PRODUCT;
+    if( This->sComponent )
+        header.dwFlags |= SCF_COMPONENT;
 
     SystemTimeToFileTime ( &This->time1, &header.Time1 );
     SystemTimeToFileTime ( &This->time2, &header.Time2 );
@@ -736,9 +1021,9 @@ static HRESULT WINAPI IPersistStream_fnSave(
         }
     }
 
-    Stream_WriteLocationInfo( stm, exePath );
+    if( This->sPath )
+        Stream_WriteLocationInfo( stm, exePath, &This->volume );
 
-    TRACE("Description = %s\n", debugstr_w(This->sDescription));
     if( This->sDescription )
         r = Stream_WriteString( stm, This->sDescription );
 
@@ -754,6 +1039,16 @@ static HRESULT WINAPI IPersistStream_fnSave(
     if( This->sIcoPath )
         r = Stream_WriteString( stm, This->sIcoPath );
 
+    if( This->sProduct )
+        r = Stream_WriteAdvertiseInfo( stm, This->sProduct, 0xa0000007 );
+
+    if( This->sComponent )
+        r = Stream_WriteAdvertiseInfo( stm, This->sComponent, 0xa0000006 );
+
+    /* the last field is a single zero dword */
+    zero = 0;
+    r = IStream_Write( stm, &zero, sizeof zero, &count );
+
     return S_OK;
 }
 
@@ -828,13 +1123,9 @@ HRESULT WINAPI IShellLink_Constructor (
 
 static BOOL SHELL_ExistsFileW(LPCWSTR path)
 {
-    HANDLE hfile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-
-    if (hfile != INVALID_HANDLE_VALUE) {
-       CloseHandle(hfile);
-       return TRUE;
-    } else
+    if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(path))
         return FALSE;
+    return TRUE;
 }
 
 /**************************************************************************
@@ -1017,7 +1308,10 @@ static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile,
     TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",
           This, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(This->sPath));
 
-    if( cchMaxPath )
+    if (This->sComponent || This->sProduct)
+        return S_FALSE;
+
+    if (cchMaxPath)
         pszFile[0] = 0;
     if (This->sPath)
         WideCharToMultiByte( CP_ACP, 0, This->sPath, -1,
@@ -1025,18 +1319,16 @@ static HRESULT WINAPI IShellLinkA_fnGetPath(IShellLinkA * iface, LPSTR pszFile,
 
     if (pfd) FIXME("(%p): WIN32_FIND_DATA is not yet filled.\n", This);
 
-    return NOERROR;
+    return S_OK;
 }
 
 static HRESULT WINAPI IShellLinkA_fnGetIDList(IShellLinkA * iface, LPITEMIDLIST * ppidl)
 {
-       IShellLinkImpl *This = (IShellLinkImpl *)iface;
-
-       TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
+    IShellLinkImpl *This = (IShellLinkImpl *)iface;
 
-       *ppidl = ILClone(This->pPidl);
+    TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
 
-       return NOERROR;
+    return IShellLinkW_GetIDList((IShellLinkW*)&(This->lpvtblw), ppidl);
 }
 
 static HRESULT WINAPI IShellLinkA_fnSetIDList(IShellLinkA * iface, LPCITEMIDLIST pidl)
@@ -1218,21 +1510,23 @@ static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR p
 
     TRACE("(%p)->(%p len=%u iicon=%p)\n", This, pszIconPath, cchIconPath, piIcon);
 
-    if (cchIconPath)
-        pszIconPath[0] = 0;
+    pszIconPath[0] = 0;
+    *piIcon = This->iIcoNdx;
 
-    if (This->sIcoPath) {
+    if (This->sIcoPath)
+    {
         WideCharToMultiByte(CP_ACP, 0, This->sIcoPath, -1, pszIconPath, cchIconPath, NULL, NULL);
-       *piIcon = This->iIcoNdx;
        return S_OK;
     }
 
-    if (This->pPidl || This->sPath) {
+    if (This->pPidl || This->sPath)
+    {
        IShellFolder* pdsk;
 
        HRESULT hr = SHGetDesktopFolder(&pdsk);
 
-       if (SUCCEEDED(hr)) {
+       if (SUCCEEDED(hr))
+        {
            /* first look for an icon using the PIDL (if present) */
            if (This->pPidl)
                hr = SHELL_PidlGeticonLocationA(pdsk, This->pPidl, pszIconPath, cchIconPath, piIcon);
@@ -1240,7 +1534,8 @@ static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR p
                hr = E_FAIL;
 
            /* if we couldn't find an icon yet, look for it using the file system path */
-           if (FAILED(hr) && This->sPath) {
+           if (FAILED(hr) && This->sPath)
+            {
                LPITEMIDLIST pidl;
 
                hr = IShellFolder_ParseDisplayName(pdsk, 0, NULL, This->sPath, NULL, &pidl, NULL);
@@ -1256,8 +1551,8 @@ static HRESULT WINAPI IShellLinkA_fnGetIconLocation(IShellLinkA * iface, LPSTR p
        }
 
        return hr;
-    } else
-        return E_FAIL;
+    }
+    return S_OK;
 }
 
 static HRESULT WINAPI IShellLinkA_fnSetIconLocation(IShellLinkA * iface, LPCSTR pszIconPath,INT iIcon)
@@ -1281,7 +1576,7 @@ static HRESULT WINAPI IShellLinkA_fnSetRelativePath(IShellLinkA * iface, LPCSTR
 {
     IShellLinkImpl *This = (IShellLinkImpl *)iface;
 
-    FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
+    TRACE("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
 
     HeapFree(GetProcessHeap(), 0, This->sPathRel);
     This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
@@ -1296,7 +1591,7 @@ static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWOR
 
     IShellLinkImpl *This = (IShellLinkImpl *)iface;
 
-    FIXME("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
+    TRACE("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
 
     /*FIXME: use IResolveShellLink interface */
 
@@ -1333,23 +1628,20 @@ static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWOR
 
 static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile)
 {
+    HRESULT r;
+    LPWSTR str;
     IShellLinkImpl *This = (IShellLinkImpl *)iface;
-    char buffer[MAX_PATH];
-    LPSTR fname;
 
     TRACE("(%p)->(path=%s)\n",This, pszFile);
 
-    if (!GetFullPathNameA(pszFile, MAX_PATH, buffer, &fname))
-       return E_FAIL;
-
-    HeapFree(GetProcessHeap(), 0, This->sPath);
-    This->sPath = HEAP_strdupAtoW(GetProcessHeap(), 0, buffer);
-    if( !This->sPath )
+    str = HEAP_strdupAtoW(GetProcessHeap(), 0, pszFile);
+    if( !str ) 
         return E_OUTOFMEMORY;
 
-    This->bDirty = TRUE;
+    r = IShellLinkW_SetPath((IShellLinkW*)&(This->lpvtblw), str);
+    HeapFree( GetProcessHeap(), 0, str );
 
-    return S_OK;
+    return r;
 }
 
 /**************************************************************************
@@ -1421,17 +1713,20 @@ static HRESULT WINAPI IShellLinkW_fnGetPath(IShellLinkW * iface, LPWSTR pszFile,
 {
     _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
 
-    TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)\n",
-                 This, pszFile, cchMaxPath, pfd, fFlags);
+    TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%lu)(%s)\n",
+          This, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(This->sPath));
+
+    if (This->sComponent || This->sProduct)
+        return S_FALSE;
 
-    if( cchMaxPath )
+    if (cchMaxPath)
         pszFile[0] = 0;
-    if( This->sPath )
+    if (This->sPath)
         lstrcpynW( pszFile, This->sPath, cchMaxPath );
 
     if (pfd) FIXME("(%p): WIN32_FIND_DATA is not yet filled.\n", This);
 
-    return NOERROR;
+    return S_OK;
 }
 
 static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST * ppidl)
@@ -1440,11 +1735,9 @@ static HRESULT WINAPI IShellLinkW_fnGetIDList(IShellLinkW * iface, LPITEMIDLIST
 
     TRACE("(%p)->(ppidl=%p)\n",This, ppidl);
 
-    if( This->pPidl)
-        *ppidl = ILClone( This->pPidl );
-    else
-        *ppidl = NULL;
-
+    if (!This->pPidl)
+        return S_FALSE;
+    *ppidl = ILClone(This->pPidl);
     return S_OK;
 }
 
@@ -1471,8 +1764,7 @@ static HRESULT WINAPI IShellLinkW_fnGetDescription(IShellLinkW * iface, LPWSTR p
 
     TRACE("(%p)->(%p len=%u)\n",This, pszName, cchMaxName);
 
-    if( cchMaxName )
-        pszName[0] = 0;
+    pszName[0] = 0;
     if( This->sDescription )
         lstrcpynW( pszName, This->sDescription, cchMaxName );
 
@@ -1632,21 +1924,23 @@ static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR
 
     TRACE("(%p)->(%p len=%u iicon=%p)\n", This, pszIconPath, cchIconPath, piIcon);
 
-    if (cchIconPath)
-        pszIconPath[0] = 0;
+    pszIconPath[0] = 0;
+    *piIcon = This->iIcoNdx;
 
-    if (This->sIcoPath) {
+    if (This->sIcoPath)
+    {
        lstrcpynW(pszIconPath, This->sIcoPath, cchIconPath);
-       *piIcon = This->iIcoNdx;
        return S_OK;
     }
 
-    if (This->pPidl || This->sPath) {
+    if (This->pPidl || This->sPath)
+    {
        IShellFolder* pdsk;
 
        HRESULT hr = SHGetDesktopFolder(&pdsk);
 
-       if (SUCCEEDED(hr)) {
+       if (SUCCEEDED(hr))
+        {
            /* first look for an icon using the PIDL (if present) */
            if (This->pPidl)
                hr = SHELL_PidlGeticonLocationW(pdsk, This->pPidl, pszIconPath, cchIconPath, piIcon);
@@ -1654,12 +1948,14 @@ static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR
                hr = E_FAIL;
 
            /* if we couldn't find an icon yet, look for it using the file system path */
-           if (FAILED(hr) && This->sPath) {
+           if (FAILED(hr) && This->sPath)
+            {
                LPITEMIDLIST pidl;
 
                hr = IShellFolder_ParseDisplayName(pdsk, 0, NULL, This->sPath, NULL, &pidl, NULL);
 
-               if (SUCCEEDED(hr)) {
+               if (SUCCEEDED(hr))
+                {
                    hr = SHELL_PidlGeticonLocationW(pdsk, pidl, pszIconPath, cchIconPath, piIcon);
 
                    SHFree(pidl);
@@ -1668,10 +1964,9 @@ static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR
 
            IShellFolder_Release(pdsk);
        }
-
        return hr;
-    } else
-        return E_FAIL;
+    }
+    return S_OK;
 }
 
 static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
@@ -1716,7 +2011,7 @@ static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWOR
 
     _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
 
-    FIXME("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
+    TRACE("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
 
     /*FIXME: use IResolveShellLink interface */
 
@@ -1751,27 +2046,141 @@ static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWOR
     return hr;
 }
 
+static LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str)
+{
+    LPWSTR ret;
+    LPCWSTR p;
+    DWORD len;
+
+    p = strchrW( str, ':' );
+    if( !p )
+        return NULL;
+    len = p - str;
+    ret = HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
+    if( !ret )
+        return ret;
+    memcpy( ret, str, sizeof(WCHAR)*len );
+    ret[len] = 0;
+    return ret;
+}
+
+static HRESULT ShellLink_SetAdvertiseInfo(IShellLinkImpl *This, LPCWSTR str)
+{
+    LPCWSTR szComponent = NULL, szProduct = NULL, p;
+    WCHAR szGuid[39];
+    HRESULT r;
+    GUID guid;
+    int len;
+
+    while( str[0] )
+    {
+        /* each segment must start with two colons */
+        if( str[0] != ':' || str[1] != ':' )
+            return E_FAIL;
+
+        /* the last segment is just two colons */
+        if( !str[2] )
+            break;
+        str += 2;
+
+        /* there must be a colon straight after a guid */
+        p = strchrW( str, ':' );
+        if( !p )
+            return E_FAIL;
+        len = p - str;
+        if( len != 38 )
+            return E_FAIL;
+
+        /* get the guid, and check it's validly formatted */
+        memcpy( szGuid, str, sizeof(WCHAR)*len );
+        szGuid[len] = 0;
+        r = CLSIDFromString( szGuid, &guid );
+        if( r != S_OK )
+            return r;
+        str = p + 1;
+
+        /* match it up to a guid that we care about */
+        if( IsEqualGUID( &guid, &SHELL32_AdvtShortcutComponent ) && !szComponent )
+            szComponent = str;
+        else if( IsEqualGUID( &guid, &SHELL32_AdvtShortcutProduct ) && !szProduct )
+            szProduct = str;
+        else
+            return E_FAIL;
+
+        /* skip to the next field */
+        str = strchrW( str, ':' );
+        if( !str )
+            return E_FAIL;
+    }
+
+    /* we have to have at least one of these two for an advertised shortcut */
+    if( !szComponent && !szProduct )
+        return E_FAIL;
+
+    This->sComponent = ShellLink_GetAdvertisedArg( szComponent );
+    This->sProduct = ShellLink_GetAdvertisedArg( szProduct );
+
+    TRACE("Component = %s\n", debugstr_w(This->sComponent));
+    TRACE("Product = %s\n", debugstr_w(This->sProduct));
+
+    return S_OK;
+}
+
+static BOOL ShellLink_GetVolumeInfo(LPWSTR path, volume_info *volume)
+{
+    const int label_sz = sizeof volume->label/sizeof volume->label[0];
+    WCHAR drive[4] = { path[0], ':', '\\', 0 };
+    BOOL r;
+
+    volume->type = GetDriveTypeW(drive);
+    r = GetVolumeInformationW(drive, volume->label, label_sz,
+                              &volume->serial, NULL, NULL, NULL, 0);
+    TRACE("r = %d type %ld serial %08lx name %s\n", r,
+          volume->type, volume->serial, debugstr_w(volume->label));
+    return r;
+}
+
 static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
 {
     _ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
     WCHAR buffer[MAX_PATH];
     LPWSTR fname;
+    HRESULT hr = S_OK;
 
     TRACE("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
 
-    if (!GetFullPathNameW(pszFile, MAX_PATH, buffer, &fname))
-       return E_FAIL;
-
     HeapFree(GetProcessHeap(), 0, This->sPath);
-    This->sPath = HeapAlloc( GetProcessHeap(), 0,
+    This->sPath = NULL;
+
+    HeapFree(GetProcessHeap(), 0, This->sComponent);
+    This->sComponent = NULL;
+
+    if (This->pPidl)
+        ILFree(This->pPidl);
+    This->pPidl = NULL;
+
+    if (S_OK != ShellLink_SetAdvertiseInfo( This, pszFile ))
+    {
+        if (*pszFile == '\0')
+            *buffer = '\0';
+        else if (!GetFullPathNameW(pszFile, MAX_PATH, buffer, &fname))
+           return E_FAIL;
+        else if(!PathFileExistsW(buffer))
+            hr = S_FALSE;
+
+        This->pPidl = SHSimpleIDListFromPathW(pszFile);
+        ShellLink_GetVolumeInfo(buffer, &This->volume);
+
+        This->sPath = HeapAlloc( GetProcessHeap(), 0,
                              (lstrlenW( buffer )+1) * sizeof (WCHAR) );
-    if (!This->sPath)
-        return E_OUTOFMEMORY;
+        if (!This->sPath)
+            return E_OUTOFMEMORY;
 
-    lstrcpyW(This->sPath, buffer);
+        lstrcpyW(This->sPath, buffer);
+    }
     This->bDirty = TRUE;
 
-    return S_OK;
+    return hr;
 }
 
 /**************************************************************************
index 718bfc2..3201c64 100644 (file)
@@ -365,7 +365,7 @@ static BOOL PathIsExeA (LPCSTR lpszPath)
        TRACE("path=%s\n",lpszPath);
 
        for(i=0; lpszExtensions[i]; i++)
-         if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
+         if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE;
 
        return FALSE;
 }
@@ -1267,7 +1267,7 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
         }
         else
         {
-            FIXME("LoadString failed, missing translation?\n");
+            FIXME("(%d,%s), LoadString failed, missing translation?\n", folder, debugstr_w(pszPath));
             hr = E_FAIL;
         }
     }
@@ -1522,7 +1522,7 @@ static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
  */
 static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
 {
-    HRESULT hr;
+    HRESULT hr = S_OK;
     WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
 
     TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
index 5666f0d..bc35caf 100644 (file)
@@ -46,6 +46,7 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
                             LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
 
 HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
+LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
 
 static inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
 {
@@ -55,4 +56,17 @@ static inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
             guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
 }
 
+static inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
+{
+    static const WCHAR fmtW[] =
+     { '{','%','0','8','l','x','-','%','0','4','x','-','%','0','4','x','-',
+     '%','0','2','x','%','0','2','x','-',
+     '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
+     '%','0','2','x','%','0','2','x','}',0 };
+    return sprintfW(str, fmtW,
+            guid->Data1, guid->Data2, guid->Data3,
+            guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+            guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+}
+
 void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags);
index e14dd08..5e8b13d 100644 (file)
@@ -1,9 +1,9 @@
 
 /*
- *     Virtual Desktop Folder
+ *    Virtual Desktop Folder
  *
- *     Copyright 1997                  Marcus Meissner
- *     Copyright 1998, 1999, 2002      Juergen Schmied
+ *    Copyright 1997            Marcus Meissner
+ *    Copyright 1998, 1999, 2002    Juergen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -56,7 +56,7 @@
 WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
 /***********************************************************************
-*      Desktopfolder implementation
+*     Desktopfolder implementation
 */
 
 typedef struct {
@@ -66,17 +66,17 @@ typedef struct {
     CLSID *pclsid;
 
     /* both paths are parsible from the desktop */
-    LPSTR sPathTarget;         /* complete path to target used for enumeration and ChangeNotify */
-    LPITEMIDLIST pidlRoot;     /* absolute pidl */
+    LPSTR sPathTarget;        /* complete path to target used for enumeration and ChangeNotify */
+    LPITEMIDLIST pidlRoot;    /* absolute pidl */
 
-    int dwAttributes;          /* attributes returned by GetAttributesOf FIXME: use it */
+    int dwAttributes;        /* attributes returned by GetAttributesOf FIXME: use it */
 
-    UINT cfShellIDList;                /* clipboardformat for IDropTarget */
-    BOOL fAcceptFmt;           /* flag for pending Drop */
+    UINT cfShellIDList;        /* clipboardformat for IDropTarget */
+    BOOL fAcceptFmt;        /* flag for pending Drop */
 } IGenericSFImpl;
 
-#define _IUnknown_(This)       (IShellFolder*)&(This->lpVtbl)
-#define _IShellFolder_(This)   (IShellFolder*)&(This->lpVtbl)
+#define _IUnknown_(This)    (IShellFolder*)&(This->lpVtbl)
+#define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
 
 static struct IShellFolder2Vtbl vt_MCFldr_ShellFolder2;
 
@@ -91,9 +91,10 @@ static shvheader DesktopSFHeader[] = {
 #define DESKTOPSHELLVIEWCOLUMNS 5
 
 /**************************************************************************
-*      ISF_Desktop_Constructor
-*/
-HRESULT WINAPI ISF_Desktop_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+ *    ISF_Desktop_Constructor
+ */
+HRESULT WINAPI ISF_Desktop_Constructor (
+                IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
 {
     IGenericSFImpl *sf;
     char szMyPath[MAX_PATH];
@@ -101,26 +102,27 @@ HRESULT WINAPI ISF_Desktop_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOI
     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
 
     if (!ppv)
-       return E_POINTER;
+        return E_POINTER;
     if (pUnkOuter)
-       return CLASS_E_NOAGGREGATION;
+        return CLASS_E_NOAGGREGATION;
 
     if (!SHGetSpecialFolderPathA (0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE))
-       return E_UNEXPECTED;
+        return E_UNEXPECTED;
 
     sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
     if (!sf)
-       return E_OUTOFMEMORY;
+        return E_OUTOFMEMORY;
 
     sf->ref = 0;
     sf->lpVtbl = &vt_MCFldr_ShellFolder2;
-    sf->pidlRoot = _ILCreateDesktop ();        /* my qualified pidl */
+    sf->pidlRoot = _ILCreateDesktop ();    /* my qualified pidl */
     sf->sPathTarget = SHAlloc (strlen (szMyPath) + 1);
     lstrcpyA (sf->sPathTarget, szMyPath);
 
-    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
-       IUnknown_Release (_IUnknown_ (sf));
-       return E_NOINTERFACE;
+    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv)))
+    {
+        IUnknown_Release (_IUnknown_ (sf));
+        return E_NOINTERFACE;
     }
 
     TRACE ("--(%p)\n", sf);
@@ -128,11 +130,12 @@ HRESULT WINAPI ISF_Desktop_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOI
 }
 
 /**************************************************************************
- *     ISF_Desktop_fnQueryInterface
+ *    ISF_Desktop_fnQueryInterface
  *
  * NOTES supports not IPersist/IPersistFolder
  */
-static HRESULT WINAPI ISF_Desktop_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
+                IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
@@ -140,15 +143,18 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface (IShellFolder2 * iface, REFII
 
     *ppvObj = NULL;
 
-    if (IsEqualIID (riid, &IID_IUnknown) || IsEqualIID (riid, &IID_IShellFolder)
-       || IsEqualIID (riid, &IID_IShellFolder2)) {
-       *ppvObj = This;
+    if (IsEqualIID (riid, &IID_IUnknown) ||
+        IsEqualIID (riid, &IID_IShellFolder) ||
+        IsEqualIID (riid, &IID_IShellFolder2))
+    {
+        *ppvObj = This;
     }
 
-    if (*ppvObj) {
-       IUnknown_AddRef ((IUnknown *) (*ppvObj));
-       TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
-       return S_OK;
+    if (*ppvObj)
+    {
+        IUnknown_AddRef ((IUnknown *) (*ppvObj));
+        TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
+        return S_OK;
     }
     TRACE ("-- Interface: E_NOINTERFACE\n");
     return E_NOINTERFACE;
@@ -171,89 +177,116 @@ static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface)
 
     TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
 
-    if (!refCount) {
-       TRACE ("-- destroying IShellFolder(%p)\n", This);
-       if (This->pidlRoot)
-           SHFree (This->pidlRoot);
-       if (This->sPathTarget)
-           SHFree (This->sPathTarget);
-       LocalFree ((HLOCAL) This);
+    if (!refCount)
+    {
+        TRACE ("-- destroying IShellFolder(%p)\n", This);
+        if (This->pidlRoot)
+            SHFree (This->pidlRoot);
+        if (This->sPathTarget)
+            SHFree (This->sPathTarget);
+        LocalFree ((HLOCAL) This);
         return 0;
     }
     return refCount;
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnParseDisplayName
-*
-* NOTES
-*      "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
-*      to MyComputer
-*/
+ *    ISF_Desktop_fnParseDisplayName
+ *
+ * NOTES
+ *    "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
+ *    to MyComputer
+ */
 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface,
-                                                     HWND hwndOwner,
-                                                     LPBC pbc,
-                                                     LPOLESTR lpszDisplayName,
-                                                     DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
+                HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
+                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     WCHAR szElement[MAX_PATH];
     LPCWSTR szNext = NULL;
     LPITEMIDLIST pidlTemp = NULL;
     HRESULT hr = S_OK;
-    char szPath[MAX_PATH];
-    DWORD len;
     CLSID clsid;
 
     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
-          This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes);
+           This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
+           pchEaten, ppidl, pdwAttributes);
 
     if (!lpszDisplayName || !ppidl)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     *ppidl = 0;
 
     if (pchEaten)
-       *pchEaten = 0;          /* strange but like the original */
-
-    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') {
-       szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
-       TRACE ("-- element: %s\n", debugstr_w (szElement));
-       SHCLSIDFromStringW (szElement + 2, &clsid);
-       pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
-    } else if (PathGetDriveNumberW (lpszDisplayName) >= 0) {
-       /* it's a filesystem path with a drive. Let MyComputer parse it */
-       pidlTemp = _ILCreateMyComputer ();
-       szNext = lpszDisplayName;
-    } else if (PathIsUNCW(lpszDisplayName)) {
-       pidlTemp = _ILCreateNetwork();
-       szNext = lpszDisplayName;
-    } else {
-       /* it's a filesystem path on the desktop. Let a FSFolder parse it */
-
-       if (*lpszDisplayName) {
-           /* build a complete path to create a simple pidl */
-           lstrcpyA(szPath, This->sPathTarget);
-           PathAddBackslashA(szPath);
-           len = lstrlenA(szPath);
-           WideCharToMultiByte(CP_ACP, 0, lpszDisplayName, -1, szPath + len, MAX_PATH - len, NULL, NULL);
-           hr = _ILCreateFromPathA(szPath, &pidlTemp);
-       } else {
-           pidlTemp = _ILCreateMyComputer();
-       }
-
-       szNext = NULL;
+        *pchEaten = 0;        /* strange but like the original */
+
+    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
+    {
+        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+        TRACE ("-- element: %s\n", debugstr_w (szElement));
+        SHCLSIDFromStringW (szElement + 2, &clsid);
+        pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
+    }
+    else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
+    {
+        /* it's a filesystem path with a drive. Let MyComputer parse it */
+        pidlTemp = _ILCreateMyComputer ();
+        szNext = lpszDisplayName;
+    }
+    else if (PathIsUNCW(lpszDisplayName))
+    {
+        pidlTemp = _ILCreateNetwork();
+        szNext = lpszDisplayName;
+    }
+    else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
+    {
+        *ppidl = pidlTemp;
+        return S_OK;
+    }
+    else
+    {
+        /* it's a filesystem path on the desktop. Let a FSFolder parse it */
+
+        if (*lpszDisplayName)
+        {
+            WCHAR szPath[MAX_PATH];
+            LPWSTR pathPtr;
+
+            /* build a complete path to create a simple pidl */
+            MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath,
+             sizeof(szPath) / sizeof(szPath[0]));
+            pathPtr = PathAddBackslashW(szPath);
+            if (pathPtr)
+            {
+                lstrcpynW(pathPtr, lpszDisplayName,
+                          sizeof(szPath)/sizeof(szPath[0]) - (pathPtr - szPath));
+                hr = _ILCreateFromPathW(szPath, &pidlTemp);
+            }
+            else
+            {
+                /* should never reach here, but for completeness */
+                hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+            }
+        }
+        else
+            pidlTemp = _ILCreateMyComputer();
+
+        szNext = NULL;
     }
 
-    if (SUCCEEDED(hr) && pidlTemp) {
-       if (szNext && *szNext) {
-           hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
-       } else {
-           if (pdwAttributes && *pdwAttributes) {
-               hr = SHELL32_GetItemAttributes (_IShellFolder_ (This), pidlTemp, pdwAttributes);
-           }
-       }
+    if (SUCCEEDED(hr) && pidlTemp)
+    {
+        if (szNext && *szNext)
+        {
+            hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc,
+                    &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
+        }
+        else
+        {
+            if (pdwAttributes && *pdwAttributes)
+                hr = SHELL32_GetItemAttributes(_IShellFolder_ (This),
+                                               pidlTemp, pdwAttributes);
+        }
     }
 
     *ppidl = pidlTemp;
@@ -266,41 +299,48 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface,
 /**************************************************************************
  *  CreateDesktopEnumList()
  */
+static const WCHAR Desktop_NameSpaceW[] = { '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','\\','E','x','p','l',
+ 'o','r','e','r','\\','D','e','s','k','t','o','p','\\','N','a','m','e','s','p',
+ 'a','c','e','\0' };
+
 static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
 {
     BOOL ret = TRUE;
-    char szPath[MAX_PATH];
+    WCHAR szPath[MAX_PATH];
 
     TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
 
-    /*enumerate the root folders */
-    if(dwFlags & SHCONTF_FOLDERS)
+    /* enumerate the root folders */
+    if (dwFlags & SHCONTF_FOLDERS)
     {
         HKEY hkey;
+        LONG r;
 
-        /*create the pidl for This item */
+        /* create the pidl for This item */
         ret = AddToEnumList(list, _ILCreateMyComputer());
 
-        if (ret && !RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-         "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\desktop\\NameSpace",
-         0, KEY_READ, &hkey))
+        r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW,
+                          0, KEY_READ, &hkey);
+        if (ret && ERROR_SUCCESS == r)
         {
-            char iid[50];
+            WCHAR iid[50];
             int i=0;
             BOOL moreKeys = TRUE;
 
             while (ret && moreKeys)
             {
-                DWORD size = sizeof (iid);
-                LONG apiRet = RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL,
-                 NULL);
+                DWORD size;
 
-                if (ERROR_SUCCESS == apiRet)
+                size = sizeof (iid);
+                r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
+                if (ERROR_SUCCESS == r)
                 {
-                    ret = AddToEnumList(list, _ILCreateGuidFromStrA(iid));
+                    ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
                     i++;
                 }
-                else if (ERROR_NO_MORE_ITEMS == apiRet)
+                else if (ERROR_NO_MORE_ITEMS == r)
                     moreKeys = FALSE;
                 else
                     ret = FALSE;
@@ -309,22 +349,23 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
         }
     }
 
-    /*enumerate the elements in %windir%\desktop */
-    SHGetSpecialFolderPathA(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);
+    /* enumerate the elements in %windir%\desktop */
+    SHGetSpecialFolderPathW(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);
     ret = ret && CreateFolderEnumList(list, szPath, dwFlags);
 
     return ret;
 }
 
 /**************************************************************************
-*              ISF_Desktop_fnEnumObjects
-*/
+ *        ISF_Desktop_fnEnumObjects
+ */
 static HRESULT WINAPI ISF_Desktop_fnEnumObjects (IShellFolder2 * iface,
-                                                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
+                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);
+    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n",
+           This, hwndOwner, dwFlags, ppEnumIDList);
 
     *ppEnumIDList = IEnumIDList_Constructor();
     if (*ppEnumIDList)
@@ -336,41 +377,41 @@ static HRESULT WINAPI ISF_Desktop_fnEnumObjects (IShellFolder2 * iface,
 }
 
 /**************************************************************************
-*              ISF_Desktop_fnBindToObject
-*/
+ *        ISF_Desktop_fnBindToObject
+ */
 static HRESULT WINAPI ISF_Desktop_fnBindToObject (IShellFolder2 * iface,
-                                                 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
+           This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
 
     return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut);
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnBindToStorage
-*/
+ *    ISF_Desktop_fnBindToStorage
+ */
 static HRESULT WINAPI ISF_Desktop_fnBindToStorage (IShellFolder2 * iface,
-                                                  LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+                LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
+           This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
 
     *ppvOut = NULL;
     return E_NOTIMPL;
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnCompareIDs
-*/
-
+ *     ISF_Desktop_fnCompareIDs
+ */
 static HRESULT WINAPI ISF_Desktop_fnCompareIDs (IShellFolder2 * iface,
-                                               LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+                        LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     int nReturn;
 
     TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
@@ -380,62 +421,70 @@ static HRESULT WINAPI ISF_Desktop_fnCompareIDs (IShellFolder2 * iface,
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnCreateViewObject
-*/
+ *    ISF_Desktop_fnCreateViewObject
+ */
 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject (IShellFolder2 * iface,
-                                                     HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+                              HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     LPSHELLVIEW pShellView;
     HRESULT hr = E_INVALIDARG;
 
-    TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
-
-    if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IDropTarget)) {
-           WARN ("IDropTarget not implemented\n");
-           hr = E_NOTIMPL;
-       } else if (IsEqualIID (riid, &IID_IContextMenu)) {
-           WARN ("IContextMenu not implemented\n");
-           hr = E_NOTIMPL;
-       } else if (IsEqualIID (riid, &IID_IShellView)) {
-           pShellView = IShellView_Constructor ((IShellFolder *) iface);
-           if (pShellView) {
-               hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
-               IShellView_Release (pShellView);
-           }
-       }
+    TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
+           This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    *ppvOut = NULL;
+
+    if (IsEqualIID (riid, &IID_IDropTarget))
+    {
+        WARN ("IDropTarget not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IContextMenu))
+    {
+        WARN ("IContextMenu not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IShellView))
+    {
+        pShellView = IShellView_Constructor ((IShellFolder *) iface);
+        if (pShellView)
+        {
+            hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
+            IShellView_Release (pShellView);
+        }
     }
     TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
     return hr;
 }
 
 /**************************************************************************
-*  ISF_Desktop_fnGetAttributesOf
-*/
+ *  ISF_Desktop_fnGetAttributesOf
+ */
 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
-                                                    UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+                UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",
+           This, cidl, apidl, *rgfInOut);
 
-    if ((!cidl) || (!apidl) || (!rgfInOut))
-       return E_INVALIDARG;
+    if (!cidl || !apidl || !rgfInOut)
+        return E_INVALIDARG;
 
     if (*rgfInOut == 0)
-       *rgfInOut = ~0;
+        *rgfInOut = ~0;
 
-    while (cidl > 0 && *apidl) {
-       pdump (*apidl);
-       SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
-       apidl++;
-       cidl--;
+    while (cidl > 0 && *apidl)
+    {
+        pdump (*apidl);
+        SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
+        apidl++;
+        cidl--;
     }
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
@@ -444,22 +493,20 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnGetUIObjectOf
-*
-* PARAMETERS
-*  HWND           hwndOwner, //[in ] Parent window for any output
-*  UINT           cidl,      //[in ] array size
-*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
-*  REFIID         riid,      //[in ] Requested Interface
-*  UINT*          prgfInOut, //[   ] reserved
-*  LPVOID*        ppvObject) //[out] Resulting Interface
-*
-*/
+ *    ISF_Desktop_fnGetUIObjectOf
+ *
+ * PARAMETERS
+ *  HWND           hwndOwner, //[in ] Parent window for any output
+ *  UINT           cidl,      //[in ] array size
+ *  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
+ *  REFIID         riid,      //[in ] Requested Interface
+ *  UINT*          prgfInOut, //[   ] reserved
+ *  LPVOID*        ppvObject) //[out] Resulting Interface
+ *
+ */
 static HRESULT WINAPI ISF_Desktop_fnGetUIObjectOf (IShellFolder2 * iface,
-                                                  HWND hwndOwner,
-                                                  UINT cidl,
-                                                  LPCITEMIDLIST * apidl,
-                                                  REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+                HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl,
+                REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
@@ -468,58 +515,72 @@ static HRESULT WINAPI ISF_Desktop_fnGetUIObjectOf (IShellFolder2 * iface,
     HRESULT hr = E_INVALIDARG;
 
     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
-          This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
-
-    if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IContextMenu)) {
-           pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
-           pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
-           hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
-       } else if ((IsEqualIID(riid,&IID_IShellLinkW) || IsEqualIID(riid,&IID_IShellLinkA))
-                               && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
-           SHFree (pidl);
-       } else {
-           hr = E_NOINTERFACE;
-       }
-
-       if (SUCCEEDED(hr) && !pObj)
-           hr = E_OUTOFMEMORY;
-
-       *ppvOut = pObj;
+       This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
+    {
+        pObj = (LPUNKNOWN) IDataObject_Constructor( hwndOwner,
+                                                  This->pidlRoot, apidl, cidl);
+        hr = S_OK;
+    }
+    else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
+              IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
+        SHFree (pidl);
+    }
+    else if (IsEqualIID (riid, &IID_IContextMenu))
+    {
+        if (cidl > 0)
+            pObj = (LPUNKNOWN) ISvItemCm_Constructor( (IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+        else
+            pObj = (LPUNKNOWN) ISvBgCm_Constructor( (IShellFolder *) iface, TRUE);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
+    {
+        hr = IShellFolder_QueryInterface (iface,
+                                          &IID_IDropTarget, (LPVOID *) & pObj);
     }
+    else
+        hr = E_NOINTERFACE;
+
+    if (SUCCEEDED(hr) && !pObj)
+        hr = E_OUTOFMEMORY;
+
+    *ppvOut = pObj;
     TRACE ("(%p)->hr=0x%08lx\n", This, hr);
     return hr;
 }
 
 /**************************************************************************
-*      ISF_Desktop_fnGetDisplayNameOf
-*
-* NOTES
-*      special case: pidl = null gives desktop-name back
-*/
+ *    ISF_Desktop_fnGetDisplayNameOf
+ *
+ * NOTES
+ *    special case: pidl = null gives desktop-name back
+ */
 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
-                                                     LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+                LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     CHAR szPath[MAX_PATH];
     GUID const *clsid;
     HRESULT hr = S_OK;
@@ -530,66 +591,103 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
     pdump (pidl);
 
     if (!strRet)
-       return E_INVALIDARG;
-
-    if (_ILIsDesktop (pidl)) {
-       if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)) {
-           lstrcpyA (szPath, This->sPathTarget);
-       } else {
-           HCR_GetClassNameA(&CLSID_ShellDesktop, szPath, MAX_PATH);
-       }
-    } else if (_ILIsPidlSimple (pidl)) {
-       if ((clsid = _ILGetGUIDPointer (pidl))) {
-           if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) {
-               int bWantsForParsing;
-
-               /*
-                * we can only get a filesystem path from a shellfolder if the value WantsFORPARSING in
-                * CLSID\\{...}\\shellfolder exists
-                * exception: the MyComputer folder has this keys not but like any filesystem backed
-                *            folder it needs these behaviour
-                */
-               if (IsEqualIID (clsid, &CLSID_MyComputer)) {
-                   bWantsForParsing = 1;
-               } else {
-                   /* get the "WantsFORPARSING" flag from the registry */
-                   char szRegPath[100];
-
-                   lstrcpyA (szRegPath, "CLSID\\");
-                   SHELL32_GUIDToStringA (clsid, &szRegPath[6]);
-                   lstrcatA (szRegPath, "\\shellfolder");
-                   bWantsForParsing =
-                       (ERROR_SUCCESS ==
-                        SHGetValueA (HKEY_CLASSES_ROOT, szRegPath, "WantsFORPARSING", NULL, NULL, NULL));
-               }
-
-               if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && bWantsForParsing) {
-                   /* we need the filesystem path to the destination folder. Only the folder itself can know it */
-                   hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
-               } else {
-                   /* parsing name like ::{...} */
-                   lstrcpyA (szPath, "::");
-                   SHELL32_GUIDToStringA (clsid, &szPath[2]);
-               }
-           } else {
-               /* user friendly name */
-               HCR_GetClassNameA (clsid, szPath, MAX_PATH);
-           }
-       } else {
-           /* file system folder */
-           _ILSimpleGetText (pidl, szPath, MAX_PATH);
-
-           if (!_ILIsFolder(pidl))
-               SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
-       }
-    } else {
-       /* a complex pidl, let the subfolder do the work */
-       hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
+        return E_INVALIDARG;
+
+    if (_ILIsDesktop (pidl))
+    {
+        if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
+            (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING))
+        {
+            lstrcpyA (szPath, This->sPathTarget);
+        }
+        else
+            HCR_GetClassNameA(&CLSID_ShellDesktop, szPath, MAX_PATH);
+    }
+    else if (_ILIsPidlSimple (pidl))
+    {
+        if ((clsid = _ILGetGUIDPointer (pidl)))
+        {
+            if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
+            {
+                int bWantsForParsing;
+
+                /*
+                 * We can only get a filesystem path from a shellfolder if the
+                 *  value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
+                 *
+                 * Exception: The MyComputer folder doesn't have this key,
+                 *   but any other filesystem backed folder it needs it.
+                 */
+                if (IsEqualIID (clsid, &CLSID_MyComputer))
+                {
+                    bWantsForParsing = 1;
+                }
+                else
+                {
+                    /* get the "WantsFORPARSING" flag from the registry */
+                    static const WCHAR clsidW[] =
+                     { 'C','L','S','I','D','\\',0 };
+                    static const WCHAR shellfolderW[] =
+                     { '\\','s','h','e','l','l','f','o','l','d','e','r',0 };
+                    static const WCHAR wantsForParsingW[] =
+                     { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n',
+                     'g',0 };
+                    WCHAR szRegPath[100];
+                    LONG r;
+
+                    lstrcpyW (szRegPath, clsidW);
+                    SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
+                    lstrcatW (szRegPath, shellfolderW);
+                    r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
+                                    wantsForParsingW, NULL, NULL, NULL);
+                    if (r == ERROR_SUCCESS)
+                        bWantsForParsing = TRUE;
+                    else
+                        bWantsForParsing = FALSE;
+                }
+
+                if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
+                     bWantsForParsing)
+                {
+                    /*
+                     * we need the filesystem path to the destination folder.
+                     * Only the folder itself can know it
+                     */
+                    hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags,
+                                                        szPath, MAX_PATH);
+                }
+                else
+                {
+                    /* parsing name like ::{...} */
+                    lstrcpyA (szPath, "::");
+                    SHELL32_GUIDToStringA (clsid, &szPath[2]);
+                }
+            }
+            else
+            {
+                /* user friendly name */
+                HCR_GetClassNameA (clsid, szPath, MAX_PATH);
+            }
+        }
+        else
+        {
+            /* file system folder */
+            _ILSimpleGetText (pidl, szPath, MAX_PATH);
+
+            if (!_ILIsFolder(pidl))
+            SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
+        }
+    }
+    else
+    {
+        /* a complex pidl, let the subfolder do the work */
+        hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
     }
 
-    if (SUCCEEDED (hr)) {
-       strRet->uType = STRRET_CSTR;
-       lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+    if (SUCCEEDED (hr))
+    {
+        strRet->uType = STRRET_CSTR;
+        lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
     }
 
     TRACE ("-- (%p)->(%s,0x%08lx)\n", This, szPath, hr);
@@ -597,77 +695,86 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
 }
 
 /**************************************************************************
-*  ISF_Desktop_fnSetNameOf
-*  Changes the name of a file object or subfolder, possibly changing its item
-*  identifier in the process.
-*
-* PARAMETERS
-*  HWND          hwndOwner,  //[in ] Owner window for output
-*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
-*  LPCOLESTR     lpszName,   //[in ] the items new display name
-*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
-*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
-*/
-static HRESULT WINAPI ISF_Desktop_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,      /*simple pidl */
-                                              LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+ *  ISF_Desktop_fnSetNameOf
+ *  Changes the name of a file object or subfolder, possibly changing its item
+ *  identifier in the process.
+ *
+ * PARAMETERS
+ *  HWND          hwndOwner,  //[in ] Owner window for output
+ *  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
+ *  LPCOLESTR     lpszName,   //[in ] the items new display name
+ *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
+ *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
+ */
+static HRESULT WINAPI ISF_Desktop_fnSetNameOf (IShellFolder2 * iface,
+                HWND hwndOwner, LPCITEMIDLIST pidl,    /* simple pidl */
+                LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+    FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl,
+           debugstr_w (lpName), dwFlags, pPidlOut);
 
     return E_FAIL;
 }
 
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(IShellFolder2 *iface,
+                GUID * pguid)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
-static HRESULT WINAPI ISF_Desktop_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+
+static HRESULT WINAPI ISF_Desktop_fnEnumSearches (IShellFolder2 *iface,
+                IEnumExtraSearch ** ppenum)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
+
 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn (IShellFolder2 * iface,
-                                                     DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
+                DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
     TRACE ("(%p)\n", This);
 
     if (pSort)
-       *pSort = 0;
+        *pSort = 0;
     if (pDisplay)
-       *pDisplay = 0;
+        *pDisplay = 0;
 
     return S_OK;
 }
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
+static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState (
+                IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
     TRACE ("(%p)\n", This);
 
     if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
-       return E_INVALIDARG;
+    return E_INVALIDARG;
 
     *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
 
     return S_OK;
 }
+
 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx (IShellFolder2 * iface,
-                                                 LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
+                LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
 
     return E_NOTIMPL;
 }
+
 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf (IShellFolder2 * iface,
-                                                 LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+                LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
@@ -676,40 +783,46 @@ static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf (IShellFolder2 * iface,
     TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
 
     if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
-       return E_INVALIDARG;
-
-    if (!pidl) {
-       psd->fmt = DesktopSFHeader[iColumn].fmt;
-       psd->cxChar = DesktopSFHeader[iColumn].cxChar;
-       psd->str.uType = STRRET_CSTR;
-       LoadStringA (shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
-       return S_OK;
-    } else {
-       /* the data from the pidl */
-       switch (iColumn) {
-       case 0:         /* name */
-           hr = IShellFolder_GetDisplayNameOf (iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
-           break;
-       case 1:         /* size */
-           _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 2:         /* type */
-           _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 3:         /* date */
-           _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 4:         /* attributes */
-           _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       }
-       hr = S_OK;
-       psd->str.uType = STRRET_CSTR;
+        return E_INVALIDARG;
+
+    if (!pidl)
+    {
+        psd->fmt = DesktopSFHeader[iColumn].fmt;
+        psd->cxChar = DesktopSFHeader[iColumn].cxChar;
+        psd->str.uType = STRRET_CSTR;
+        LoadStringA (shell32_hInstance, DesktopSFHeader[iColumn].colnameid,
+                     psd->str.u.cStr, MAX_PATH);
+        return S_OK;
+    }
+
+    /* the data from the pidl */
+    switch (iColumn)
+    {
+    case 0:        /* name */
+        hr = IShellFolder_GetDisplayNameOf(iface, pidl,
+                   SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+        break;
+    case 1:        /* size */
+        _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 2:        /* type */
+        _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 3:        /* date */
+        _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
+    case 4:        /* attributes */
+        _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
+        break;
     }
+    hr = S_OK;
+    psd->str.uType = STRRET_CSTR;
 
     return hr;
 }
-static HRESULT WINAPI ISF_Desktop_fnMapColumnToSCID (IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
+
+static HRESULT WINAPI ISF_Desktop_fnMapColumnToSCID (
+                IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
@@ -718,24 +831,25 @@ static HRESULT WINAPI ISF_Desktop_fnMapColumnToSCID (IShellFolder2 * iface, UINT
 
 static IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
 {
-       ISF_Desktop_fnQueryInterface,
-       ISF_Desktop_fnAddRef,
-       ISF_Desktop_fnRelease,
-       ISF_Desktop_fnParseDisplayName,
-       ISF_Desktop_fnEnumObjects,
-       ISF_Desktop_fnBindToObject,
-       ISF_Desktop_fnBindToStorage,
-       ISF_Desktop_fnCompareIDs,
-       ISF_Desktop_fnCreateViewObject,
-       ISF_Desktop_fnGetAttributesOf,
-       ISF_Desktop_fnGetUIObjectOf,
-       ISF_Desktop_fnGetDisplayNameOf,
-       ISF_Desktop_fnSetNameOf,
-       /* ShellFolder2 */
-        ISF_Desktop_fnGetDefaultSearchGUID,
-       ISF_Desktop_fnEnumSearches,
-       ISF_Desktop_fnGetDefaultColumn,
-       ISF_Desktop_fnGetDefaultColumnState,
-       ISF_Desktop_fnGetDetailsEx,
-       ISF_Desktop_fnGetDetailsOf,
-       ISF_Desktop_fnMapColumnToSCID};
+    ISF_Desktop_fnQueryInterface,
+    ISF_Desktop_fnAddRef,
+    ISF_Desktop_fnRelease,
+    ISF_Desktop_fnParseDisplayName,
+    ISF_Desktop_fnEnumObjects,
+    ISF_Desktop_fnBindToObject,
+    ISF_Desktop_fnBindToStorage,
+    ISF_Desktop_fnCompareIDs,
+    ISF_Desktop_fnCreateViewObject,
+    ISF_Desktop_fnGetAttributesOf,
+    ISF_Desktop_fnGetUIObjectOf,
+    ISF_Desktop_fnGetDisplayNameOf,
+    ISF_Desktop_fnSetNameOf,
+    /* ShellFolder2 */
+    ISF_Desktop_fnGetDefaultSearchGUID,
+    ISF_Desktop_fnEnumSearches,
+    ISF_Desktop_fnGetDefaultColumn,
+    ISF_Desktop_fnGetDefaultColumnState,
+    ISF_Desktop_fnGetDetailsEx,
+    ISF_Desktop_fnGetDetailsOf,
+    ISF_Desktop_fnMapColumnToSCID
+};
index e8fdca7..41c6e1d 100644 (file)
@@ -1,9 +1,9 @@
 
 /*
- *     file system folder
+ * file system folder
  *
- *     Copyright 1997                  Marcus Meissner
- *     Copyright 1998, 1999, 2002      Juergen Schmied
+ * Copyright 1997             Marcus Meissner
+ * Copyright 1998, 1999, 2002 Juergen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -67,24 +67,24 @@ typedef struct {
     IDropTargetVtbl     *lpvtblDropTarget;
     ISFHelperVtbl       *lpvtblSFHelper;
 
-    IUnknown *pUnkOuter;       /* used for aggregation */
+    IUnknown *pUnkOuter; /* used for aggregation */
 
     CLSID *pclsid;
 
     /* both paths are parsible from the desktop */
-    LPSTR sPathTarget;         /* complete path to target used for enumeration and ChangeNotify */
+    LPSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */
 
-    LPITEMIDLIST pidlRoot;     /* absolute pidl */
+    LPITEMIDLIST pidlRoot; /* absolute pidl */
 
-    int dwAttributes;          /* attributes returned by GetAttributesOf FIXME: use it */
+    int dwAttributes;      /* attributes returned by GetAttributesOf FIXME: use it */
 
-    UINT cfShellIDList;                /* clipboardformat for IDropTarget */
-    BOOL fAcceptFmt;           /* flag for pending Drop */
+    UINT cfShellIDList;    /* clipboardformat for IDropTarget */
+    BOOL fAcceptFmt;       /* flag for pending Drop */
 } IGenericSFImpl;
 
 static struct IUnknownVtbl unkvt;
 static struct IShellFolder2Vtbl sfvt;
-static struct IPersistFolder3Vtbl vt_FSFldr_PersistFolder3;    /* IPersistFolder3 for a FS_Folder */
+static struct IPersistFolder3Vtbl vt_FSFldr_PersistFolder3; /* IPersistFolder3 for a FS_Folder */
 static struct IDropTargetVtbl dtvt;
 static struct ISFHelperVtbl shvt;
 
@@ -106,31 +106,31 @@ static struct ISFHelperVtbl shvt;
 /*
   converts This to a interface pointer
 */
-#define _IUnknown_(This)       (IUnknown*)&(This->lpVtbl)
-#define _IShellFolder_(This)   (IShellFolder*)&(This->lpvtblShellFolder)
-#define _IShellFolder2_(This)  (IShellFolder2*)&(This->lpvtblShellFolder)
-#define _IPersist_(This)       (IPersist*)&(This->lpvtblPersistFolder3)
-#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder3)
-#define _IPersistFolder2_(This)        (IPersistFolder2*)&(This->lpvtblPersistFolder3)
-#define _IPersistFolder3_(This)        (IPersistFolder3*)&(This->lpvtblPersistFolder3)
-#define _IDropTarget_(This)    (IDropTarget*)&(This->lpvtblDropTarget)
-#define _ISFHelper_(This)      (ISFHelper*)&(This->lpvtblSFHelper)
+#define _IUnknown_(This)        (IUnknown*)&(This->lpVtbl)
+#define _IShellFolder_(This)    (IShellFolder*)&(This->lpvtblShellFolder)
+#define _IShellFolder2_(This)   (IShellFolder2*)&(This->lpvtblShellFolder)
+#define _IPersist_(This)        (IPersist*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder_(This)  (IPersistFolder*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder3_(This) (IPersistFolder3*)&(This->lpvtblPersistFolder3)
+#define _IDropTarget_(This)     (IDropTarget*)&(This->lpvtblDropTarget)
+#define _ISFHelper_(This)       (ISFHelper*)&(This->lpvtblSFHelper)
 
 /**************************************************************************
-*      registers clipboardformat once
+* registers clipboardformat once
 */
 static void SF_RegisterClipFmt (IGenericSFImpl * This)
 {
     TRACE ("(%p)\n", This);
 
     if (!This->cfShellIDList) {
-       This->cfShellIDList = RegisterClipboardFormatA (CFSTR_SHELLIDLIST);
+        This->cfShellIDList = RegisterClipboardFormatA (CFSTR_SHELLIDLIST);
     }
 }
 
 /**************************************************************************
-*      we need a separate IUnknown to handle aggregation
-*      (inner IUnknown)
+* we need a separate IUnknown to handle aggregation
+* (inner IUnknown)
 */
 static HRESULT WINAPI IUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppvObj)
 {
@@ -141,30 +141,30 @@ static HRESULT WINAPI IUnknown_fnQueryInterface (IUnknown * iface, REFIID riid,
     *ppvObj = NULL;
 
     if (IsEqualIID (riid, &IID_IUnknown))
-       *ppvObj = _IUnknown_ (This);
+        *ppvObj = _IUnknown_ (This);
     else if (IsEqualIID (riid, &IID_IShellFolder))
-       *ppvObj = _IShellFolder_ (This);
+        *ppvObj = _IShellFolder_ (This);
     else if (IsEqualIID (riid, &IID_IShellFolder2))
-       *ppvObj = _IShellFolder_ (This);
+        *ppvObj = _IShellFolder_ (This);
     else if (IsEqualIID (riid, &IID_IPersist))
-       *ppvObj = _IPersist_ (This);
+        *ppvObj = _IPersist_ (This);
     else if (IsEqualIID (riid, &IID_IPersistFolder))
-       *ppvObj = _IPersistFolder_ (This);
+        *ppvObj = _IPersistFolder_ (This);
     else if (IsEqualIID (riid, &IID_IPersistFolder2))
-       *ppvObj = _IPersistFolder2_ (This);
+        *ppvObj = _IPersistFolder2_ (This);
     else if (IsEqualIID (riid, &IID_IPersistFolder3))
-       *ppvObj = _IPersistFolder3_ (This);
+        *ppvObj = _IPersistFolder3_ (This);
     else if (IsEqualIID (riid, &IID_ISFHelper))
-       *ppvObj = _ISFHelper_ (This);
+        *ppvObj = _ISFHelper_ (This);
     else if (IsEqualIID (riid, &IID_IDropTarget)) {
-       *ppvObj = _IDropTarget_ (This);
-       SF_RegisterClipFmt (This);
+        *ppvObj = _IDropTarget_ (This);
+        SF_RegisterClipFmt (This);
     }
 
     if (*ppvObj) {
-       IUnknown_AddRef ((IUnknown *) (*ppvObj));
-       TRACE ("-- Interface = %p\n", *ppvObj);
-       return S_OK;
+        IUnknown_AddRef ((IUnknown *) (*ppvObj));
+        TRACE ("-- Interface = %p\n", *ppvObj);
+        return S_OK;
     }
     TRACE ("-- Interface: E_NOINTERFACE\n");
     return E_NOINTERFACE;
@@ -188,13 +188,13 @@ static ULONG WINAPI IUnknown_fnRelease (IUnknown * iface)
     TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
 
     if (!refCount) {
-       TRACE ("-- destroying IShellFolder(%p)\n", This);
+        TRACE ("-- destroying IShellFolder(%p)\n", This);
 
-       if (This->pidlRoot)
-           SHFree (This->pidlRoot);
-       if (This->sPathTarget)
-           SHFree (This->sPathTarget);
-       LocalFree ((HLOCAL) This);
+        if (This->pidlRoot)
+            SHFree (This->pidlRoot);
+        if (This->sPathTarget)
+            SHFree (This->sPathTarget);
+        LocalFree ((HLOCAL) This);
     }
     return refCount;
 }
@@ -217,24 +217,25 @@ static shvheader GenericSFHeader[] = {
 #define GENERICSHELLVIEWCOLUMNS 5
 
 /**************************************************************************
-*      IFSFolder_Constructor
+* IFSFolder_Constructor
 *
 * NOTES
 *  creating undocumented ShellFS_Folder as part of an aggregation
 *  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
 *
 */
-HRESULT WINAPI IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+HRESULT WINAPI
+IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
 {
     IGenericSFImpl *sf;
 
     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
 
     if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
-       return CLASS_E_NOAGGREGATION;
+        return CLASS_E_NOAGGREGATION;
     sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
     if (!sf)
-       return E_OUTOFMEMORY;
+        return E_OUTOFMEMORY;
 
     sf->ref = 0;
     sf->lpVtbl = &unkvt;
@@ -246,8 +247,8 @@ HRESULT WINAPI IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID
     sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_ (sf);
 
     if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
-       IUnknown_Release (_IUnknown_ (sf));
-       return E_NOINTERFACE;
+        IUnknown_Release (_IUnknown_ (sf));
+        return E_NOINTERFACE;
     }
 
     TRACE ("--%p\n", *ppv);
@@ -258,14 +259,16 @@ HRESULT WINAPI IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID
  *  IShellFolder_fnQueryInterface
  *
  * PARAMETERS
- *  REFIID riid                [in ] Requested InterfaceID
- *  LPVOID* ppvObject  [out] Interface* to hold the result
+ *  REFIID riid       [in ] Requested InterfaceID
+ *  LPVOID* ppvObject [out] Interface* to hold the result
  */
-static HRESULT WINAPI IShellFolder_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+static HRESULT WINAPI
+IShellFolder_fnQueryInterface (IShellFolder2 * iface, REFIID riid,
+                               LPVOID * ppvObj)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-       TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
 
     return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
 }
@@ -295,6 +298,50 @@ static ULONG WINAPI IShellFolder_fnRelease (IShellFolder2 * iface)
     return IUnknown_Release (This->pUnkOuter);
 }
 
+/**************************************************************************
+ *  SHELL32_CreatePidlFromBindCtx  [internal]
+ *
+ *  If the caller bound File System Bind Data, assume it is the 
+ *   find data for the path.
+ *  This allows binding of paths that don't exist.
+ */
+LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path)
+{
+    static const WCHAR szfsbc[] = {
+        'F','i','l','e',' ','S','y','s','t','e','m',' ',
+        'B','i','n','d',' ','D','a','t','a',0 };
+    IFileSystemBindData *fsbd = NULL;
+    LPITEMIDLIST pidl = NULL;
+    IUnknown *param = NULL;
+    WIN32_FIND_DATAW wfd;
+    HRESULT r;
+
+    TRACE("%p %s\n", pbc, debugstr_w(path));
+
+    if (!pbc)
+        return NULL;
+
+    /* see if the caller bound File System Bind Data */
+    r = IBindCtx_GetObjectParam( pbc, (LPOLESTR) szfsbc, &param );
+    if (FAILED(r))
+        return NULL;
+
+    r = IUnknown_QueryInterface( param, &IID_IFileSystemBindData,
+                                 (LPVOID*) &fsbd );
+    if (SUCCEEDED(r))
+    {
+        r = IFileSystemBindData_GetFindData( fsbd, &wfd );
+        if (SUCCEEDED(r))
+        {
+            lstrcpynW( &wfd.cFileName[0], path, MAX_PATH );
+            pidl = _ILCreateFromFindDataW( &wfd );
+        }
+        IFileSystemBindData_Release( fsbd );
+    }
+    
+    return pidl;
+}
+
 /**************************************************************************
 * IShellFolder_ParseDisplayName {SHELL32}
 *
@@ -313,8 +360,8 @@ static ULONG WINAPI IShellFolder_fnRelease (IShellFolder2 * iface)
 *  subfolder to evaluate the remaining parts.
 *  Now we can parse into namespaces implemented by shell extensions
 *
-*  Behaviour on win98: lpszDisplayName=NULL -> crash
-*                      lpszDisplayName="" -> returns mycoputer-pidl
+*  Behaviour on win98: lpszDisplayName=NULL -> crash
+*                      lpszDisplayName="" -> returns mycoputer-pidl
 *
 * FIXME
 *    pdwAttributes is not set
@@ -322,59 +369,66 @@ static ULONG WINAPI IShellFolder_fnRelease (IShellFolder2 * iface)
 */
 static HRESULT WINAPI
 IShellFolder_fnParseDisplayName (IShellFolder2 * iface,
-                                HWND hwndOwner,
-                                LPBC pbc,
-                                LPOLESTR lpszDisplayName,
-                                DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
+                                 HWND hwndOwner,
+                                 LPBC pbc,
+                                 LPOLESTR lpszDisplayName,
+                                 DWORD * pchEaten, LPITEMIDLIST * ppidl,
+                                 DWORD * pdwAttributes)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
     HRESULT hr = E_INVALIDARG;
     LPCWSTR szNext = NULL;
     WCHAR szElement[MAX_PATH];
-    CHAR szPath[MAX_PATH];
+    WCHAR szPath[MAX_PATH];
     LPITEMIDLIST pidlTemp = NULL;
     DWORD len;
 
     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
-          This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes);
+     This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
+     pchEaten, ppidl, pdwAttributes);
 
     if (!lpszDisplayName || !ppidl)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     if (pchEaten)
-       *pchEaten = 0;          /* strange but like the original */
-
-    if (*lpszDisplayName) {
-       /* get the next element */
-       szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
-
-       /* build the full pathname to the element */
-       lstrcpyA(szPath, This->sPathTarget);
-       PathAddBackslashA(szPath);
-       len = lstrlenA(szPath);
-       WideCharToMultiByte(CP_ACP, 0, szElement, -1, szPath + len, MAX_PATH - len, NULL, NULL);
-
-       /* get the pidl */
-       hr = _ILCreateFromPathA(szPath, &pidlTemp);
-
-       if (SUCCEEDED(hr)) {
-           if (szNext && *szNext) {
-               /* try to analyse the next element */
-               hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
-           } else {
-               /* it's the last element */
-               if (pdwAttributes && *pdwAttributes) {
-                   hr = SHELL32_GetItemAttributes (_IShellFolder_ (This), pidlTemp, pdwAttributes);
-               }
-           }
-       }
+        *pchEaten = 0; /* strange but like the original */
+
+    pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName);
+    if (!pidlTemp && *lpszDisplayName)
+    {
+        /* get the next element */
+        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+
+        /* build the full pathname to the element */
+        /* lstrcpyW(szPath, This->sPathTarget); */
+        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
+        PathAddBackslashW(szPath);
+        len = lstrlenW(szPath);
+        lstrcpynW(szPath + len, szElement, MAX_PATH - len);
+
+        /* get the pidl */
+        hr = _ILCreateFromPathW(szPath, &pidlTemp);
+
+        if (SUCCEEDED(hr)) {
+            if (szNext && *szNext) {
+                /* try to analyse the next element */
+                hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc,
+                 &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
+            } else {
+                /* it's the last element */
+                if (pdwAttributes && *pdwAttributes) {
+                    hr = SHELL32_GetItemAttributes (_IShellFolder_ (This),
+                     pidlTemp, pdwAttributes);
+                }
+            }
+        }
     }
 
     if (SUCCEEDED(hr))
-       *ppidl = pidlTemp;
+        *ppidl = pidlTemp;
     else
-       *ppidl = NULL;
+        *ppidl = NULL;
 
     TRACE ("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl ? *ppidl : 0, hr);
 
@@ -382,22 +436,28 @@ IShellFolder_fnParseDisplayName (IShellFolder2 * iface,
 }
 
 /**************************************************************************
-*              IShellFolder_fnEnumObjects
+* IShellFolder_fnEnumObjects
 * PARAMETERS
 *  HWND          hwndOwner,    //[in ] Parent Window
 *  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
 *  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
 */
 static HRESULT WINAPI
-IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
+IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner,
+                            DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);
+    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner,
+     dwFlags, ppEnumIDList);
 
     *ppEnumIDList = IEnumIDList_Constructor();
     if (*ppEnumIDList)
-        CreateFolderEnumList(*ppEnumIDList, This->sPathTarget, dwFlags);
+    {
+        WCHAR path[MAX_PATH];
+        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, path, MAX_PATH);
+        CreateFolderEnumList(*ppEnumIDList, path, dwFlags);
+    }
 
     TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
 
@@ -405,7 +465,7 @@ IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags
 }
 
 /**************************************************************************
-*              IShellFolder_fnBindToObject
+* IShellFolder_fnBindToObject
 * PARAMETERS
 *  LPCITEMIDLIST pidl,       //[in ] relative pidl to open
 *  LPBC          pbc,        //[in ] optional FileSystemBindData context
@@ -413,13 +473,16 @@ IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags
 *  LPVOID*       ppvObject   //[out] Interface*
 */
 static HRESULT WINAPI
-IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, LPVOID * ppvOut)
+IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+                             LPBC pbc, REFIID riid, LPVOID * ppvOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc, shdebugstr_guid (riid), ppvOut);
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc,
+     shdebugstr_guid (riid), ppvOut);
 
-    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut);
+    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid,
+     ppvOut);
 }
 
 /**************************************************************************
@@ -431,11 +494,13 @@ IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbc
 *  LPVOID*       ppvObject   //[out] Interface* returned
 */
 static HRESULT WINAPI
-IShellFolder_fnBindToStorage (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+IShellFolder_fnBindToStorage (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+                              LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved,
+     shdebugstr_guid (riid), ppvOut);
 
     *ppvOut = NULL;
     return E_NOTIMPL;
@@ -446,7 +511,8 @@ IShellFolder_fnBindToStorage (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pb
 */
 
 static HRESULT WINAPI
-IShellFolder_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+IShellFolder_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam,
+                           LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
@@ -459,33 +525,35 @@ IShellFolder_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST p
 }
 
 /**************************************************************************
-*      IShellFolder_fnCreateViewObject
+* IShellFolder_fnCreateViewObject
 */
 static HRESULT WINAPI
-IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner,
+                                 REFIID riid, LPVOID * ppvOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
     LPSHELLVIEW pShellView;
     HRESULT hr = E_INVALIDARG;
 
-    TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+    TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid),
+     ppvOut);
 
     if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IDropTarget)) {
-           hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, ppvOut);
-       } else if (IsEqualIID (riid, &IID_IContextMenu)) {
-           FIXME ("IContextMenu not implemented\n");
-           hr = E_NOTIMPL;
-       } else if (IsEqualIID (riid, &IID_IShellView)) {
-           pShellView = IShellView_Constructor ((IShellFolder *) iface);
-           if (pShellView) {
-               hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
-               IShellView_Release (pShellView);
-           }
-       }
+        *ppvOut = NULL;
+
+        if (IsEqualIID (riid, &IID_IDropTarget)) {
+            hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, ppvOut);
+        } else if (IsEqualIID (riid, &IID_IContextMenu)) {
+            FIXME ("IContextMenu not implemented\n");
+            hr = E_NOTIMPL;
+        } else if (IsEqualIID (riid, &IID_IShellView)) {
+            pShellView = IShellView_Constructor ((IShellFolder *) iface);
+            if (pShellView) {
+                hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
+                IShellView_Release (pShellView);
+            }
+        }
     }
     TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
     return hr;
@@ -501,25 +569,27 @@ IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID r
 *
 */
 static HRESULT WINAPI
-IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl,
+                                LPCITEMIDLIST * apidl, DWORD * rgfInOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
     HRESULT hr = S_OK;
 
-    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl,
+     *rgfInOut);
 
     if ((!cidl) || (!apidl) || (!rgfInOut))
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     if (*rgfInOut == 0)
-       *rgfInOut = ~0;
+        *rgfInOut = ~0;
 
     while (cidl > 0 && *apidl) {
-       pdump (*apidl);
-       SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
-       apidl++;
-       cidl--;
+        pdump (*apidl);
+        SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
+        apidl++;
+        cidl--;
     }
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
@@ -539,19 +609,22 @@ IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST
 *  LPVOID*        ppvObject) //[out] Resulting Interface
 *
 * NOTES
-*  This function gets asked to return "view objects" for one or more (multiple select)
-*  items:
-*  The viewobject typically is an COM object with one of the following interfaces:
+*  This function gets asked to return "view objects" for one or more (multiple
+*  select) items:
+*  The viewobject typically is an COM object with one of the following
+*  interfaces:
 *  IExtractIcon,IDataObject,IContextMenu
 *  In order to support icon positions in the default Listview your DataObject
-*  must implement the SetData method (in addition to GetData :) - the shell passes
-*  a barely documented "Icon positions" structure to SetData when the drag starts,
-*  and GetData's it if the drop is in another explorer window that needs the positions.
+*  must implement the SetData method (in addition to GetData :) - the shell
+*  passes a barely documented "Icon positions" structure to SetData when the
+*  drag starts, and GetData's it if the drop is in another explorer window that
+*  needs the positions.
 */
 static HRESULT WINAPI
 IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
-                             HWND hwndOwner,
-                             UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+                              HWND hwndOwner,
+                              UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
+                              UINT * prgfInOut, LPVOID * ppvOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
@@ -560,86 +633,99 @@ IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
     HRESULT hr = E_INVALIDARG;
 
     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
-          This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+     This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
 
     if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
-           pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
-           pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
-           hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
-       } else if ((IsEqualIID(riid,&IID_IShellLinkW) || IsEqualIID(riid,&IID_IShellLinkA))
-                               && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
-           SHFree (pidl);
-       } else {
-           hr = E_NOINTERFACE;
-       }
-
-       if (SUCCEEDED(hr) && !pObj)
-           hr = E_OUTOFMEMORY;
-
-       *ppvOut = pObj;
+        *ppvOut = NULL;
+
+        if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
+            pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
+             This->pidlRoot, apidl, cidl);
+            hr = S_OK;
+        } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+            pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
+             This->pidlRoot, apidl, cidl);
+            hr = S_OK;
+        } else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
+            pidl = ILCombine (This->pidlRoot, apidl[0]);
+            pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+            SHFree (pidl);
+            hr = S_OK;
+        } else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1)) {
+            pidl = ILCombine (This->pidlRoot, apidl[0]);
+            pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
+            SHFree (pidl);
+            hr = S_OK;
+        } else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
+            hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget,
+             (LPVOID *) & pObj);
+        } else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
+         IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1)) {
+            pidl = ILCombine (This->pidlRoot, apidl[0]);
+            hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
+            SHFree (pidl);
+        } else {
+            hr = E_NOINTERFACE;
+        }
+
+        if (SUCCEEDED(hr) && !pObj)
+            hr = E_OUTOFMEMORY;
+
+        *ppvOut = pObj;
     }
     TRACE ("(%p)->hr=0x%08lx\n", This, hr);
     return hr;
 }
 
+static const WCHAR AdvancedW[] = { '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','\\','E','x','p','l',
+ 'o','r','e','r','\\','A','d','v','a','n','c','e','d',0 };
+static const WCHAR HideFileExtW[] = { 'H','i','d','e','F','i','l','e','E','x',
+ 't',0 };
+static const WCHAR NeverShowExtW[] = { 'N','e','v','e','r','S','h','o','w','E',
+ 'x','t',0 };
+
 void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags)
 {
     /*FIXME: MSDN also mentions SHGDN_FOREDITING which is not yet handled. */
     if (!(dwFlags & SHGDN_FORPARSING) &&
-       ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
-       HKEY hKey;
-       DWORD dwData;
-       DWORD dwDataSize = sizeof (DWORD);
-       BOOL doHide = FALSE;    /* The default value is FALSE (win98 at least) */
-
-       if (!RegCreateKeyExA (HKEY_CURRENT_USER,
-                             "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
-                             0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
-           if (!RegQueryValueExA (hKey, "HideFileExt", 0, 0, (LPBYTE) & dwData, &dwDataSize))
-               doHide = dwData;
-
-           RegCloseKey (hKey);
-       }
-
-       if (!doHide) {
-           LPSTR ext = PathFindExtensionA(szPath);
-
-           if (ext) {
-               HKEY hkey;
-               char classname[MAX_PATH];
-               LONG classlen = MAX_PATH;
-
-               if (!RegQueryValueA(HKEY_CLASSES_ROOT, ext, classname, &classlen))
-                   if (!RegOpenKeyA(HKEY_CLASSES_ROOT, classname, &hkey)) {
-                       if (!RegQueryValueExA(hkey, "NeverShowExt", 0, NULL, NULL, NULL))
-                           doHide = TRUE;
-
-                       RegCloseKey(hkey);
-                   }
-           }
-       }
-
-       if (doHide && szPath[0] != '.')
-           PathRemoveExtensionA (szPath);
+        ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
+        HKEY hKey;
+        DWORD dwData;
+        DWORD dwDataSize = sizeof (DWORD);
+        BOOL doHide = FALSE; /* The default value is FALSE (win98 at least) */
+
+        if (!RegCreateKeyExW (HKEY_CURRENT_USER, AdvancedW,
+         0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
+            if (!RegQueryValueExW (hKey, HideFileExtW, 0, 0, (LPBYTE) &dwData,
+             &dwDataSize))
+                doHide = dwData;
+
+            RegCloseKey (hKey);
+        }
+
+        if (!doHide) {
+            LPSTR ext = PathFindExtensionA(szPath);
+
+            if (ext) {
+                char classname[MAX_PATH];
+                LONG classlen = MAX_PATH;
+
+                if (!RegQueryValueA(HKEY_CLASSES_ROOT, ext, classname,
+                 &classlen))
+                    if (!RegOpenKeyA(HKEY_CLASSES_ROOT, classname, &hKey)) {
+                        if (!RegQueryValueExW(hKey, NeverShowExtW, 0, NULL,
+                         NULL, NULL))
+                            doHide = TRUE;
+
+                        RegCloseKey(hKey);
+                    }
+            }
+        }
+
+        if (doHide && szPath[0] != '.')
+            PathRemoveExtensionA (szPath);
     }
 }
 
@@ -657,7 +743,8 @@ void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags)
 */
 
 static HRESULT WINAPI
-IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+                                 DWORD dwFlags, LPSTRRET strRet)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
@@ -671,36 +758,40 @@ IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWOR
     pdump (pidl);
 
     if (!pidl || !strRet)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     bSimplePidl = _ILIsPidlSimple (pidl);
 
     /* take names of special folders only if its only this folder */
     if (_ILIsSpecialFolder (pidl)) {
-       if (bSimplePidl) {
-           _ILSimpleGetText (pidl, szPath, MAX_PATH);  /* append my own path */
-       } else {
-           FIXME ("special pidl\n");
-       }
+        if (bSimplePidl) {
+            _ILSimpleGetText (pidl, szPath, MAX_PATH); /* append my own path */
+        } else {
+            FIXME ("special pidl\n");
+        }
     } else {
-       if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sPathTarget) {
-           lstrcpyA (szPath, This->sPathTarget);       /* get path to root */
-           PathAddBackslashA (szPath);
-           len = lstrlenA (szPath);
-       }
-       _ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);  /* append my own path */
-
-       if (!_ILIsFolder(pidl))
-           SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
+        if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) &&
+         This->sPathTarget) {
+            /* get path to root */
+            lstrcpyA (szPath, This->sPathTarget);
+            PathAddBackslashA (szPath);
+            len = lstrlenA (szPath);
+        }
+        /* append my own path */
+        _ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);
+
+        if (!_ILIsFolder(pidl))
+            SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
     }
 
-    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {        /* go deeper if needed */
-       PathAddBackslashA (szPath);
-       len = lstrlenA (szPath);
+    /* go deeper if needed */
+    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {
+        PathAddBackslashA (szPath);
+        len = lstrlenA (szPath);
 
-       if (!SUCCEEDED
-           (SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len)))
-           return E_OUTOFMEMORY;
+        if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild (iface, pidl,
+         dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len)))
+            return E_OUTOFMEMORY;
     }
     strRet->uType = STRRET_CSTR;
     lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
@@ -721,98 +812,113 @@ IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWOR
 *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
 *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
 */
-static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,     /*simple pidl */
-                                               LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface,
+                                                HWND hwndOwner,
+                                                LPCITEMIDLIST pidl,
+                                                LPCOLESTR lpName,
+                                                DWORD dwFlags,
+                                                LPITEMIDLIST * pPidlOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
-    char szSrc[MAX_PATH],
-      szDest[MAX_PATH];
-    int len;
+    WCHAR szSrc[MAX_PATH], szDest[MAX_PATH];
+    LPWSTR ptr;
     BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));
 
-    TRACE ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+    TRACE ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl,
+     debugstr_w (lpName), dwFlags, pPidlOut);
 
     /* build source path */
     if (dwFlags & SHGDN_INFOLDER) {
-       strcpy (szSrc, This->sPathTarget);
-       PathAddBackslashA (szSrc);
-       len = strlen (szSrc);
-       _ILSimpleGetText (pidl, szSrc + len, MAX_PATH - len);
+        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szSrc, MAX_PATH);
+        ptr = PathAddBackslashW (szSrc);
+        if (ptr)
+            _ILSimpleGetTextW (pidl, ptr, MAX_PATH - (ptr - szSrc));
     } else {
-       /* FIXME: Can this work with a simple PIDL? */
-       SHGetPathFromIDListA (pidl, szSrc);
+        /* FIXME: Can this work with a simple PIDL? */
+        SHGetPathFromIDListW (pidl, szSrc);
     }
 
     /* build destination path */
-    strcpy (szDest, This->sPathTarget);
-    PathAddBackslashA (szDest);
-    len = strlen (szDest);
-    WideCharToMultiByte (CP_ACP, 0, lpName, -1, szDest + len, MAX_PATH - len, NULL, NULL);
-    szDest[MAX_PATH - 1] = 0;
-    TRACE ("src=%s dest=%s\n", szSrc, szDest);
-    if (MoveFileA (szSrc, szDest)) {
-       HRESULT hr = S_OK;
+    MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szDest, MAX_PATH);
+    ptr = PathAddBackslashW (szDest);
+    if (ptr)
+        lstrcpynW(ptr, lpName, MAX_PATH - (ptr - szDest));
+    TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
+    if (MoveFileW (szSrc, szDest)) {
+        HRESULT hr = S_OK;
 
-       if (pPidlOut)
-           hr = _ILCreateFromPathA(szDest, pPidlOut);
+        if (pPidlOut)
+            hr = _ILCreateFromPathW(szDest, pPidlOut);
 
-       SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
+        SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM,
+         SHCNF_PATHW, szSrc, szDest);
 
-       return hr;
+        return hr;
     }
 
     return E_FAIL;
 }
 
-static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID (IShellFolder2 *iface,
+                                                           GUID * pguid)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
-       FIXME ("(%p)\n", This);
+    FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
-static HRESULT WINAPI IShellFolder_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+static HRESULT WINAPI IShellFolder_fnEnumSearches (IShellFolder2 * iface,
+                                                   IEnumExtraSearch ** ppenum)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
-       FIXME ("(%p)\n", This);
+    FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
+
 static HRESULT WINAPI
-IShellFolder_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
+IShellFolder_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes,
+                                 ULONG * pSort, ULONG * pDisplay)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-       TRACE ("(%p)\n", This);
+    TRACE ("(%p)\n", This);
 
     if (pSort)
-       *pSort = 0;
+        *pSort = 0;
     if (pDisplay)
-       *pDisplay = 0;
+        *pDisplay = 0;
 
     return S_OK;
 }
-static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
+
+static HRESULT WINAPI
+IShellFolder_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn,
+                                      DWORD * pcsFlags)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-       TRACE ("(%p)\n", This);
+    TRACE ("(%p)\n", This);
 
     if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
 
     return S_OK;
 }
+
 static HRESULT WINAPI
-IShellFolder_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
+IShellFolder_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+                             const SHCOLUMNID * pscid, VARIANT * pv)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
-       FIXME ("(%p)\n", This);
+    FIXME ("(%p)\n", This);
 
     return E_NOTIMPL;
 }
+
 static HRESULT WINAPI
-IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+                             UINT iColumn, SHELLDETAILS * psd)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
     HRESULT hr = E_FAIL;
@@ -820,41 +926,46 @@ IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iCo
     TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
 
     if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     if (!pidl) {
-       /* the header titles */
-       psd->fmt = GenericSFHeader[iColumn].fmt;
-       psd->cxChar = GenericSFHeader[iColumn].cxChar;
-       psd->str.uType = STRRET_CSTR;
-       LoadStringA (shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
-       return S_OK;
+        /* the header titles */
+        psd->fmt = GenericSFHeader[iColumn].fmt;
+        psd->cxChar = GenericSFHeader[iColumn].cxChar;
+        psd->str.uType = STRRET_CSTR;
+        LoadStringA (shell32_hInstance, GenericSFHeader[iColumn].colnameid,
+         psd->str.u.cStr, MAX_PATH);
+        return S_OK;
     } else {
-       /* the data from the pidl */
-       switch (iColumn) {
-       case 0:         /* name */
-           hr = IShellFolder_GetDisplayNameOf (iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
-           break;
-       case 1:         /* size */
-           _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 2:         /* type */
-           _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 3:         /* date */
-           _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 4:         /* attributes */
-           _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       }
-       hr = S_OK;
-       psd->str.uType = STRRET_CSTR;
+        /* the data from the pidl */
+        switch (iColumn) {
+        case 0:                /* name */
+            hr = IShellFolder_GetDisplayNameOf (iface, pidl,
+             SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+            break;
+        case 1:                /* size */
+            _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
+            break;
+        case 2:                /* type */
+            _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
+            break;
+        case 3:                /* date */
+            _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
+            break;
+        case 4:                /* attributes */
+            _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
+            break;
+        }
+        hr = S_OK;
+        psd->str.uType = STRRET_CSTR;
     }
 
     return hr;
 }
-static HRESULT WINAPI IShellFolder_fnMapColumnToSCID (IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
+
+static HRESULT WINAPI
+IShellFolder_fnMapColumnToSCID (IShellFolder2 * iface, UINT column,
+                                SHCOLUMNID * pscid)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
     FIXME ("(%p)\n", This);
@@ -863,34 +974,35 @@ static HRESULT WINAPI IShellFolder_fnMapColumnToSCID (IShellFolder2 * iface, UIN
 
 static IShellFolder2Vtbl sfvt =
 {
-       IShellFolder_fnQueryInterface,
-       IShellFolder_fnAddRef,
-       IShellFolder_fnRelease,
-       IShellFolder_fnParseDisplayName,
-       IShellFolder_fnEnumObjects,
-       IShellFolder_fnBindToObject,
-       IShellFolder_fnBindToStorage,
-       IShellFolder_fnCompareIDs,
-       IShellFolder_fnCreateViewObject,
-       IShellFolder_fnGetAttributesOf,
-       IShellFolder_fnGetUIObjectOf,
-       IShellFolder_fnGetDisplayNameOf,
-       IShellFolder_fnSetNameOf,
-       /* ShellFolder2 */
-        IShellFolder_fnGetDefaultSearchGUID,
-       IShellFolder_fnEnumSearches,
-       IShellFolder_fnGetDefaultColumn,
-       IShellFolder_fnGetDefaultColumnState,
-       IShellFolder_fnGetDetailsEx,
-       IShellFolder_fnGetDetailsOf,
-       IShellFolder_fnMapColumnToSCID
+    IShellFolder_fnQueryInterface,
+    IShellFolder_fnAddRef,
+    IShellFolder_fnRelease,
+    IShellFolder_fnParseDisplayName,
+    IShellFolder_fnEnumObjects,
+    IShellFolder_fnBindToObject,
+    IShellFolder_fnBindToStorage,
+    IShellFolder_fnCompareIDs,
+    IShellFolder_fnCreateViewObject,
+    IShellFolder_fnGetAttributesOf,
+    IShellFolder_fnGetUIObjectOf,
+    IShellFolder_fnGetDisplayNameOf,
+    IShellFolder_fnSetNameOf,
+    /* ShellFolder2 */
+    IShellFolder_fnGetDefaultSearchGUID,
+    IShellFolder_fnEnumSearches,
+    IShellFolder_fnGetDefaultColumn,
+    IShellFolder_fnGetDefaultColumnState,
+    IShellFolder_fnGetDetailsEx,
+    IShellFolder_fnGetDetailsOf,
+    IShellFolder_fnMapColumnToSCID
 };
 
 /****************************************************************************
  * ISFHelper for IShellFolder implementation
  */
 
-static HRESULT WINAPI ISFHelper_fnQueryInterface (ISFHelper * iface, REFIID riid, LPVOID * ppvObj)
+static HRESULT WINAPI
+ISFHelper_fnQueryInterface (ISFHelper * iface, REFIID riid, LPVOID * ppvObj)
 {
     _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);
 
@@ -923,7 +1035,8 @@ static ULONG WINAPI ISFHelper_fnRelease (ISFHelper * iface)
  * creates a unique folder name
  */
 
-static HRESULT WINAPI ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen)
+static HRESULT WINAPI
+ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen)
 {
     _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
     IEnumIDList *penum;
@@ -934,31 +1047,33 @@ static HRESULT WINAPI ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName
     TRACE ("(%p)(%s %u)\n", This, lpName, uLen);
 
     if (uLen < strlen (szNewFolder) + 4)
-       return E_POINTER;
+        return E_POINTER;
 
     strcpy (lpName, szNewFolder);
 
     hr = IShellFolder_fnEnumObjects (_IShellFolder2_ (This), 0,
-                                    SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
+     SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
     if (penum) {
-       LPITEMIDLIST pidl;
-       DWORD dwFetched;
-       int i = 1;
-
-      next:IEnumIDList_Reset (penum);
-       while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) && dwFetched) {
-           _ILSimpleGetText (pidl, szText, MAX_PATH);
-           if (0 == strcasecmp (szText, lpName)) {
-               sprintf (lpName, "%s %d", szNewFolder, i++);
-               if (i > 99) {
-                   hr = E_FAIL;
-                   break;
-               }
-               goto next;
-           }
-       }
-
-       IEnumIDList_Release (penum);
+        LPITEMIDLIST pidl;
+        DWORD dwFetched;
+        int i = 1;
+
+next:
+        IEnumIDList_Reset (penum);
+        while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) &&
+         dwFetched) {
+            _ILSimpleGetText (pidl, szText, MAX_PATH);
+            if (0 == strcasecmp (szText, lpName)) {
+                sprintf (lpName, "%s %d", szNewFolder, i++);
+                if (i > 99) {
+                    hr = E_FAIL;
+                    break;
+                }
+                goto next;
+            }
+        }
+
+        IEnumIDList_Release (penum);
     }
     return hr;
 }
@@ -969,7 +1084,9 @@ static HRESULT WINAPI ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName
  * adds a new folder.
  */
 
-static HRESULT WINAPI ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName, LPITEMIDLIST * ppidlOut)
+static HRESULT WINAPI
+ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName,
+                       LPITEMIDLIST * ppidlOut)
 {
     _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
     char lpstrNewDir[MAX_PATH];
@@ -983,22 +1100,24 @@ static HRESULT WINAPI ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCST
 
     bRes = CreateDirectoryA (lpstrNewDir, NULL);
     if (bRes) {
-       SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHA, lpstrNewDir, NULL);
+        SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHA, lpstrNewDir, NULL);
 
-       hres = S_OK;
+        hres = S_OK;
 
-       if (ppidlOut)
-           hres = _ILCreateFromPathA(lpstrNewDir, ppidlOut);
+        if (ppidlOut)
+                hres = _ILCreateFromPathA(lpstrNewDir, ppidlOut);
     } else {
-       char lpstrText[128 + MAX_PATH];
-       char lpstrTempText[128];
-       char lpstrCaption[256];
-
-       /* Cannot Create folder because of permissions */
-       LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof (lpstrTempText));
-       LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof (lpstrCaption));
-       sprintf (lpstrText, lpstrTempText, lpstrNewDir);
-       MessageBoxA (hwnd, lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
+        char lpstrText[128 + MAX_PATH];
+        char lpstrTempText[128];
+        char lpstrCaption[256];
+
+        /* Cannot Create folder because of permissions */
+        LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText,
+         sizeof (lpstrTempText));
+        LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption,
+         sizeof (lpstrCaption));
+        sprintf (lpstrText, lpstrTempText, lpstrNewDir);
+        MessageBoxA (hwnd, lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
     }
 
     return hres;
@@ -1009,7 +1128,8 @@ static HRESULT WINAPI ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCST
  *
  * deletes items in folder
  */
-static HRESULT WINAPI ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
+static HRESULT WINAPI
+ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
 {
     _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
     UINT i;
@@ -1020,42 +1140,42 @@ static HRESULT WINAPI ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPC
 
     /* deleting multiple items so give a slightly different warning */
     if (cidl != 1) {
-       char tmp[8];
+        char tmp[8];
 
-       snprintf (tmp, sizeof (tmp), "%d", cidl);
-       if (!SHELL_ConfirmDialog(ASK_DELETE_MULTIPLE_ITEM, tmp))
-           return E_FAIL;
-       bConfirm = FALSE;
+        snprintf (tmp, sizeof (tmp), "%d", cidl);
+        if (!SHELL_ConfirmDialog(ASK_DELETE_MULTIPLE_ITEM, tmp))
+            return E_FAIL;
+        bConfirm = FALSE;
     }
 
     for (i = 0; i < cidl; i++) {
-       strcpy (szPath, This->sPathTarget);
-       PathAddBackslashA (szPath);
-       _ILSimpleGetText (apidl[i], szPath + strlen (szPath), MAX_PATH);
-
-       if (_ILIsFolder (apidl[i])) {
-           LPITEMIDLIST pidl;
-
-           TRACE ("delete %s\n", szPath);
-           if (!SHELL_DeleteDirectoryA (szPath, bConfirm)) {
-               TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
-               return E_FAIL;
-           }
-           pidl = ILCombine (This->pidlRoot, apidl[i]);
-           SHChangeNotify (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
-           SHFree (pidl);
-       } else if (_ILIsValue (apidl[i])) {
-           LPITEMIDLIST pidl;
-
-           TRACE ("delete %s\n", szPath);
-           if (!SHELL_DeleteFileA (szPath, bConfirm)) {
-               TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
-               return E_FAIL;
-           }
-           pidl = ILCombine (This->pidlRoot, apidl[i]);
-           SHChangeNotify (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
-           SHFree (pidl);
-       }
+        strcpy (szPath, This->sPathTarget);
+        PathAddBackslashA (szPath);
+        _ILSimpleGetText (apidl[i], szPath + strlen (szPath), MAX_PATH);
+
+        if (_ILIsFolder (apidl[i])) {
+            LPITEMIDLIST pidl;
+
+            TRACE ("delete %s\n", szPath);
+            if (!SHELL_DeleteDirectoryA (szPath, bConfirm)) {
+                TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
+                return E_FAIL;
+            }
+            pidl = ILCombine (This->pidlRoot, apidl[i]);
+            SHChangeNotify (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
+            SHFree (pidl);
+        } else if (_ILIsValue (apidl[i])) {
+            LPITEMIDLIST pidl;
+
+            TRACE ("delete %s\n", szPath);
+            if (!SHELL_DeleteFileA (szPath, bConfirm)) {
+                TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
+                return E_FAIL;
+            }
+            pidl = ILCombine (This->pidlRoot, apidl[i]);
+            SHChangeNotify (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
+            SHFree (pidl);
+        }
 
     }
     return S_OK;
@@ -1067,7 +1187,8 @@ static HRESULT WINAPI ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPC
  * copies items to this folder
  */
 static HRESULT WINAPI
-ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl)
+ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
+                       LPCITEMIDLIST * apidl)
 {
     UINT i;
     IPersistFolder2 *ppf2 = NULL;
@@ -1078,44 +1199,49 @@ ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPC
 
     TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
 
-    IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2);
+    IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2,
+     (LPVOID *) & ppf2);
     if (ppf2) {
-       LPITEMIDLIST pidl;
-
-       if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
-           for (i = 0; i < cidl; i++) {
-               SHGetPathFromIDListA (pidl, szSrcPath);
-               PathAddBackslashA (szSrcPath);
-               _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath), MAX_PATH);
-
-               strcpy (szDstPath, This->sPathTarget);
-               PathAddBackslashA (szDstPath);
-               _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH);
-               MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
-           }
-           SHFree (pidl);
-       }
-       IPersistFolder2_Release (ppf2);
+        LPITEMIDLIST pidl;
+
+        if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
+            for (i = 0; i < cidl; i++) {
+                SHGetPathFromIDListA (pidl, szSrcPath);
+                PathAddBackslashA (szSrcPath);
+                _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
+                 MAX_PATH);
+
+                strcpy (szDstPath, This->sPathTarget);
+                PathAddBackslashA (szDstPath);
+                _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath),
+                 MAX_PATH);
+                MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
+            }
+            SHFree (pidl);
+        }
+        IPersistFolder2_Release (ppf2);
     }
     return S_OK;
 }
 
 static ISFHelperVtbl shvt =
 {
-       ISFHelper_fnQueryInterface,
-       ISFHelper_fnAddRef,
-       ISFHelper_fnRelease,
-       ISFHelper_fnGetUniqueName,
-       ISFHelper_fnAddFolder,
-       ISFHelper_fnDeleteItems,
-        ISFHelper_fnCopyItems
+    ISFHelper_fnQueryInterface,
+    ISFHelper_fnAddRef,
+    ISFHelper_fnRelease,
+    ISFHelper_fnGetUniqueName,
+    ISFHelper_fnAddFolder,
+    ISFHelper_fnDeleteItems,
+    ISFHelper_fnCopyItems
 };
 
 /************************************************************************
- *     IFSFldr_PersistFolder3_QueryInterface
+ * IFSFldr_PersistFolder3_QueryInterface
  *
  */
-static HRESULT WINAPI IFSFldr_PersistFolder3_QueryInterface (IPersistFolder3 * iface, REFIID iid, LPVOID * ppvObj)
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_QueryInterface (IPersistFolder3 * iface, REFIID iid,
+                                       LPVOID * ppvObj)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
 
@@ -1125,10 +1251,11 @@ static HRESULT WINAPI IFSFldr_PersistFolder3_QueryInterface (IPersistFolder3 * i
 }
 
 /************************************************************************
- *     IFSFldr_PersistFolder3_AddRef
+ * IFSFldr_PersistFolder3_AddRef
  *
  */
-static ULONG WINAPI IFSFldr_PersistFolder3_AddRef (IPersistFolder3 * iface)
+static ULONG WINAPI
+IFSFldr_PersistFolder3_AddRef (IPersistFolder3 * iface)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
 
@@ -1138,10 +1265,11 @@ static ULONG WINAPI IFSFldr_PersistFolder3_AddRef (IPersistFolder3 * iface)
 }
 
 /************************************************************************
- *     IFSFldr_PersistFolder3_Release
+ * IFSFldr_PersistFolder3_Release
  *
  */
-static ULONG WINAPI IFSFldr_PersistFolder3_Release (IPersistFolder3 * iface)
+static ULONG WINAPI
+IFSFldr_PersistFolder3_Release (IPersistFolder3 * iface)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
 
@@ -1151,28 +1279,30 @@ static ULONG WINAPI IFSFldr_PersistFolder3_Release (IPersistFolder3 * iface)
 }
 
 /************************************************************************
- *     IFSFldr_PersistFolder3_GetClassID
+ * IFSFldr_PersistFolder3_GetClassID
  */
-static HRESULT WINAPI IFSFldr_PersistFolder3_GetClassID (IPersistFolder3 * iface, CLSID * lpClassId)
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_GetClassID (IPersistFolder3 * iface, CLSID * lpClassId)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
 
     TRACE ("(%p)\n", This);
 
     if (!lpClassId)
-       return E_POINTER;
+        return E_POINTER;
     *lpClassId = *This->pclsid;
 
     return S_OK;
 }
 
 /************************************************************************
- *     IFSFldr_PersistFolder3_Initialize
+ * IFSFldr_PersistFolder3_Initialize
  *
  * NOTES
  *  sPathTarget is not set. Don't know how to handle in a non rooted environment.
  */
-static HRESULT WINAPI IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface, LPCITEMIDLIST pidl)
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface, LPCITEMIDLIST pidl)
 {
     char sTemp[MAX_PATH];
 
@@ -1181,16 +1311,16 @@ static HRESULT WINAPI IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface
     TRACE ("(%p)->(%p)\n", This, pidl);
 
     if (This->pidlRoot)
-       SHFree (This->pidlRoot);        /* free the old pidl */
-    This->pidlRoot = ILClone (pidl);   /* set my pidl */
+        SHFree (This->pidlRoot);     /* free the old pidl */
+    This->pidlRoot = ILClone (pidl); /* set my pidl */
 
     if (This->sPathTarget)
-       SHFree (This->sPathTarget);
+        SHFree (This->sPathTarget);
 
     /* set my path */
     if (SHGetPathFromIDListA (pidl, sTemp)) {
-       This->sPathTarget = SHAlloc (strlen (sTemp) + 1);
-       strcpy (This->sPathTarget, sTemp);
+        This->sPathTarget = SHAlloc (strlen (sTemp) + 1);
+        strcpy (This->sPathTarget, sTemp);
     }
 
     TRACE ("--(%p)->(%s)\n", This, This->sPathTarget);
@@ -1198,9 +1328,11 @@ static HRESULT WINAPI IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface
 }
 
 /**************************************************************************
- *     IFSFldr_PersistFolder3_GetCurFolder
+ * IFSFldr_PersistFolder3_GetCurFolder
  */
-static HRESULT WINAPI IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * iface, LPITEMIDLIST * pidl)
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * iface,
+                                       LPITEMIDLIST * pidl)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
 
@@ -1212,13 +1344,14 @@ static HRESULT WINAPI IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * i
 }
 
 /**************************************************************************
- *     IFSFldr_PersistFolder3_InitializeEx
+ * IFSFldr_PersistFolder3_InitializeEx
  *
- * FIXME: errorhandling
+ * FIXME: error handling
  */
 static HRESULT WINAPI
 IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
-                                    IBindCtx * pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO * ppfti)
+                                     IBindCtx * pbc, LPCITEMIDLIST pidlRoot,
+                                     const PERSIST_FOLDER_TARGET_INFO * ppfti)
 {
     char sTemp[MAX_PATH];
 
@@ -1226,18 +1359,19 @@ IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
 
     TRACE ("(%p)->(%p,%p,%p)\n", This, pbc, pidlRoot, ppfti);
     if (ppfti)
-       TRACE ("--%p %s %s 0x%08lx 0x%08x\n",
-              ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName),
-              debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes, ppfti->csidl);
+        TRACE ("--%p %s %s 0x%08lx 0x%08x\n",
+         ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName),
+         debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes,
+         ppfti->csidl);
 
     pdump (pidlRoot);
     if (ppfti && ppfti->pidlTargetFolder)
-       pdump (ppfti->pidlTargetFolder);
+        pdump (ppfti->pidlTargetFolder);
 
     if (This->pidlRoot)
-       __SHFreeAndNil (&This->pidlRoot);       /* free the old */
+        __SHFreeAndNil (&This->pidlRoot);    /* free the old */
     if (This->sPathTarget)
-       __SHFreeAndNil (&This->sPathTarget);
+        __SHFreeAndNil (&This->sPathTarget);
 
     /*
      * Root path and pidl
@@ -1245,20 +1379,22 @@ IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
     This->pidlRoot = ILClone (pidlRoot);
 
     /*
-     *  the target folder is spezified in csidl OR pidlTargetFolder OR szTargetParsingName
+     *  the target folder is spezified in csidl OR pidlTargetFolder OR
+     *  szTargetParsingName
      */
     if (ppfti) {
-       if (ppfti->csidl != -1) {
-           if (SHGetSpecialFolderPathA (0, sTemp, ppfti->csidl, ppfti->csidl & CSIDL_FLAG_CREATE)) {
-               __SHCloneStrA (&This->sPathTarget, sTemp);
-           }
-       } else if (ppfti->szTargetParsingName[0]) {
-           __SHCloneStrWtoA (&This->sPathTarget, ppfti->szTargetParsingName);
-       } else if (ppfti->pidlTargetFolder) {
-           if (SHGetPathFromIDListA (ppfti->pidlTargetFolder, sTemp)) {
-               __SHCloneStrA (&This->sPathTarget, sTemp);
-           }
-       }
+        if (ppfti->csidl != -1) {
+            if (SHGetSpecialFolderPathA (0, sTemp, ppfti->csidl,
+             ppfti->csidl & CSIDL_FLAG_CREATE)) {
+                __SHCloneStrA (&This->sPathTarget, sTemp);
+            }
+        } else if (ppfti->szTargetParsingName[0]) {
+            __SHCloneStrWtoA (&This->sPathTarget, ppfti->szTargetParsingName);
+        } else if (ppfti->pidlTargetFolder) {
+            if (SHGetPathFromIDListA (ppfti->pidlTargetFolder, sTemp)) {
+                __SHCloneStrA (&This->sPathTarget, sTemp);
+            }
+        }
     }
 
     TRACE ("--(%p)->(target=%s)\n", This, debugstr_a (This->sPathTarget));
@@ -1267,7 +1403,8 @@ IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
 }
 
 static HRESULT WINAPI
-IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface, PERSIST_FOLDER_TARGET_INFO * ppfti)
+IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface,
+                                            PERSIST_FOLDER_TARGET_INFO * ppfti)
 {
     _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
     FIXME ("(%p)->(%p)\n", This, ppfti);
@@ -1277,20 +1414,22 @@ IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface, PERSIST_FOL
 
 static IPersistFolder3Vtbl vt_FSFldr_PersistFolder3 =
 {
-       IFSFldr_PersistFolder3_QueryInterface,
-       IFSFldr_PersistFolder3_AddRef,
-       IFSFldr_PersistFolder3_Release,
-       IFSFldr_PersistFolder3_GetClassID,
-       IFSFldr_PersistFolder3_Initialize,
-       IFSFldr_PersistFolder3_fnGetCurFolder,
-       IFSFldr_PersistFolder3_InitializeEx,
-       IFSFldr_PersistFolder3_GetFolderTargetInfo
+    IFSFldr_PersistFolder3_QueryInterface,
+    IFSFldr_PersistFolder3_AddRef,
+    IFSFldr_PersistFolder3_Release,
+    IFSFldr_PersistFolder3_GetClassID,
+    IFSFldr_PersistFolder3_Initialize,
+    IFSFldr_PersistFolder3_fnGetCurFolder,
+    IFSFldr_PersistFolder3_InitializeEx,
+    IFSFldr_PersistFolder3_GetFolderTargetInfo
 };
 
 /****************************************************************************
  * ISFDropTarget implementation
  */
-static BOOL ISFDropTarget_QueryDrop (IDropTarget * iface, DWORD dwKeyState, LPDWORD pdwEffect)
+static BOOL
+ISFDropTarget_QueryDrop (IDropTarget * iface, DWORD dwKeyState,
+                         LPDWORD pdwEffect)
 {
     DWORD dwEffect = *pdwEffect;
 
@@ -1298,18 +1437,19 @@ static BOOL ISFDropTarget_QueryDrop (IDropTarget * iface, DWORD dwKeyState, LPDW
 
     *pdwEffect = DROPEFFECT_NONE;
 
-    if (This->fAcceptFmt) {    /* Does our interpretation of the keystate ... */
-       *pdwEffect = KeyStateToDropEffect (dwKeyState);
+    if (This->fAcceptFmt) { /* Does our interpretation of the keystate ... */
+        *pdwEffect = KeyStateToDropEffect (dwKeyState);
 
-       /* ... matches the desired effect ? */
-       if (dwEffect & *pdwEffect) {
-           return TRUE;
-       }
+        /* ... matches the desired effect ? */
+        if (dwEffect & *pdwEffect) {
+            return TRUE;
+        }
     }
     return FALSE;
 }
 
-static HRESULT WINAPI ISFDropTarget_QueryInterface (IDropTarget * iface, REFIID riid, LPVOID * ppvObj)
+static HRESULT WINAPI
+ISFDropTarget_QueryInterface (IDropTarget * iface, REFIID riid, LPVOID * ppvObj)
 {
     _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
 
@@ -1337,7 +1477,8 @@ static ULONG WINAPI ISFDropTarget_Release (IDropTarget * iface)
 }
 
 static HRESULT WINAPI
-ISFDropTarget_DragEnter (IDropTarget * iface, IDataObject * pDataObject, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+ISFDropTarget_DragEnter (IDropTarget * iface, IDataObject * pDataObject,
+                         DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
 {
     FORMATETC fmt;
 
@@ -1347,21 +1488,24 @@ ISFDropTarget_DragEnter (IDropTarget * iface, IDataObject * pDataObject, DWORD d
 
     InitFormatEtc (fmt, This->cfShellIDList, TYMED_HGLOBAL);
 
-    This->fAcceptFmt = (S_OK == IDataObject_QueryGetData (pDataObject, &fmt)) ? TRUE : FALSE;
+    This->fAcceptFmt = (S_OK == IDataObject_QueryGetData (pDataObject, &fmt)) ?
+     TRUE : FALSE;
 
     ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);
 
     return S_OK;
 }
 
-static HRESULT WINAPI ISFDropTarget_DragOver (IDropTarget * iface, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+static HRESULT WINAPI
+ISFDropTarget_DragOver (IDropTarget * iface, DWORD dwKeyState, POINTL pt,
+                        DWORD * pdwEffect)
 {
     _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
 
     TRACE ("(%p)\n", This);
 
     if (!pdwEffect)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);
 
@@ -1380,7 +1524,8 @@ static HRESULT WINAPI ISFDropTarget_DragLeave (IDropTarget * iface)
 }
 
 static HRESULT WINAPI
-ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject,
+                    DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
 {
     _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
 
@@ -1390,11 +1535,11 @@ ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject, DWORD dwKeyS
 }
 
 static struct IDropTargetVtbl dtvt = {
-       ISFDropTarget_QueryInterface,
-       ISFDropTarget_AddRef,
-       ISFDropTarget_Release,
-       ISFDropTarget_DragEnter,
-       ISFDropTarget_DragOver,
-       ISFDropTarget_DragLeave,
-       ISFDropTarget_Drop
+    ISFDropTarget_QueryInterface,
+    ISFDropTarget_AddRef,
+    ISFDropTarget_Release,
+    ISFDropTarget_DragEnter,
+    ISFDropTarget_DragOver,
+    ISFDropTarget_DragLeave,
+    ISFDropTarget_Drop
 };
index cacfcfb..ef6a23e 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
- *     Virtual Workplace folder
+ *    Virtual Workplace folder
  *
- *     Copyright 1997                  Marcus Meissner
- *     Copyright 1998, 1999, 2002      Juergen Schmied
+ *    Copyright 1997            Marcus Meissner
+ *    Copyright 1998, 1999, 2002    Juergen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -61,8 +60,8 @@ typedef struct {
     IPersistFolder2Vtbl *lpVtblPersistFolder2;
 
     /* both paths are parsible from the desktop */
-    LPITEMIDLIST pidlRoot;     /* absolute pidl */
-    int dwAttributes;          /* attributes returned by GetAttributesOf FIXME: use it */
+    LPITEMIDLIST pidlRoot;    /* absolute pidl */
+    int dwAttributes;        /* attributes returned by GetAttributesOf FIXME: use it */
 } IGenericSFImpl;
 
 static struct IShellFolder2Vtbl vt_ShellFolder2;
@@ -74,13 +73,13 @@ static struct IPersistFolder2Vtbl vt_PersistFolder2;
 /*
   converts This to a interface pointer
 */
-#define _IUnknown_(This)       (IUnknown*)&(This->lpVtbl)
-#define _IShellFolder_(This)   (IShellFolder*)&(This->lpVtbl)
-#define _IShellFolder2_(This)  (IShellFolder2*)&(This->lpVtbl)
+#define _IUnknown_(This)    (IUnknown*)&(This->lpVtbl)
+#define _IShellFolder_(This)    (IShellFolder*)&(This->lpVtbl)
+#define _IShellFolder2_(This)    (IShellFolder2*)&(This->lpVtbl)
 
-#define _IPersist_(This)       (IPersist*)&(This->lpVtblPersistFolder2)
-#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpVtblPersistFolder2)
-#define _IPersistFolder2_(This)        (IPersistFolder2*)&(This->lpVtblPersistFolder2)
+#define _IPersist_(This)    (IPersist*)&(This->lpVtblPersistFolder2)
+#define _IPersistFolder_(This)    (IPersistFolder*)&(This->lpVtblPersistFolder2)
+#define _IPersistFolder2_(This)    (IPersistFolder2*)&(This->lpVtblPersistFolder2)
 
 /***********************************************************************
 *   IShellFolder [MyComputer] implementation
@@ -96,7 +95,7 @@ static shvheader MyComputerSFHeader[] = {
 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
 
 /**************************************************************************
-*      ISF_MyComputer_Constructor
+*    ISF_MyComputer_Constructor
 */
 HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
 {
@@ -105,22 +104,23 @@ HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LP
     TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
 
     if (!ppv)
-       return E_POINTER;
+        return E_POINTER;
     if (pUnkOuter)
-       return CLASS_E_NOAGGREGATION;
+        return CLASS_E_NOAGGREGATION;
 
-    sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
+    sf = LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
     if (!sf)
-       return E_OUTOFMEMORY;
+        return E_OUTOFMEMORY;
 
     sf->ref = 0;
     sf->lpVtbl = &vt_ShellFolder2;
     sf->lpVtblPersistFolder2 = &vt_PersistFolder2;
-    sf->pidlRoot = _ILCreateMyComputer ();     /* my qualified pidl */
+    sf->pidlRoot = _ILCreateMyComputer ();    /* my qualified pidl */
 
-    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
-       IUnknown_Release (_IUnknown_ (sf));
-       return E_NOINTERFACE;
+    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv)))
+    {
+        IUnknown_Release (_IUnknown_ (sf));
+        return E_NOINTERFACE;
     }
 
     TRACE ("--(%p)\n", sf);
@@ -128,11 +128,12 @@ HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LP
 }
 
 /**************************************************************************
- *     ISF_MyComputer_fnQueryInterface
+ *    ISF_MyComputer_fnQueryInterface
  *
  * NOTES supports not IPersist/IPersistFolder
  */
-static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 *iface,
+               REFIID riid, LPVOID *ppvObj)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
@@ -141,17 +142,23 @@ static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 * iface, RE
     *ppvObj = NULL;
 
     if (IsEqualIID (riid, &IID_IUnknown) ||
-       IsEqualIID (riid, &IID_IShellFolder) || IsEqualIID (riid, &IID_IShellFolder2)) {
-       *ppvObj = This;
-    } else if (IsEqualIID (riid, &IID_IPersist) ||
-              IsEqualIID (riid, &IID_IPersistFolder) || IsEqualIID (riid, &IID_IPersistFolder2)) {
-       *ppvObj = _IPersistFolder2_ (This);
+        IsEqualIID (riid, &IID_IShellFolder) ||
+        IsEqualIID (riid, &IID_IShellFolder2))
+    {
+        *ppvObj = This;
+    }
+    else if (IsEqualIID (riid, &IID_IPersist) ||
+             IsEqualIID (riid, &IID_IPersistFolder) ||
+             IsEqualIID (riid, &IID_IPersistFolder2))
+    {
+        *ppvObj = _IPersistFolder2_ (This);
     }
 
-    if (*ppvObj) {
-       IUnknown_AddRef ((IUnknown *) (*ppvObj));
-       TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
-       return S_OK;
+    if (*ppvObj)
+    {
+        IUnknown_AddRef ((IUnknown *) (*ppvObj));
+        TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
+        return S_OK;
     }
     TRACE ("-- Interface: E_NOINTERFACE\n");
     return E_NOINTERFACE;
@@ -174,7 +181,8 @@ static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
 
     TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
 
-    if (!refCount) {
+    if (!refCount)
+    {
         TRACE ("-- destroying IShellFolder(%p)\n", This);
         if (This->pidlRoot)
             SHFree (This->pidlRoot);
@@ -184,51 +192,56 @@ static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnParseDisplayName
+*    ISF_MyComputer_fnParseDisplayName
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnParseDisplayName (IShellFolder2 * iface,
-                                  HWND hwndOwner,
-                                  LPBC pbc,
-                                  LPOLESTR lpszDisplayName,
-                                  DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
+static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
+               HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
+               DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     HRESULT hr = E_INVALIDARG;
     LPCWSTR szNext = NULL;
     WCHAR szElement[MAX_PATH];
     LPITEMIDLIST pidlTemp = NULL;
     CLSID clsid;
 
-    TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
-          This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes);
+    TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This,
+          hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
+          pchEaten, ppidl, pdwAttributes);
 
     *ppidl = 0;
     if (pchEaten)
-       *pchEaten = 0;          /* strange but like the original */
+        *pchEaten = 0;        /* strange but like the original */
 
     /* handle CLSID paths */
-    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') {
-       szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
-       TRACE ("-- element: %s\n", debugstr_w (szElement));
-       SHCLSIDFromStringW (szElement + 2, &clsid);
-       pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
+    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
+    {
+        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+        TRACE ("-- element: %s\n", debugstr_w (szElement));
+        SHCLSIDFromStringW (szElement + 2, &clsid);
+        pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
     }
     /* do we have an absolute path name ? */
-    else if (PathGetDriveNumberW (lpszDisplayName) >= 0 && lpszDisplayName[2] == (WCHAR) '\\') {
-       szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
-       szElement[0] = toupper(szElement[0]); /* make drive letter uppercase to enable PIDL comparison */
-       pidlTemp = _ILCreateDrive (szElement);
+    else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
+              lpszDisplayName[2] == (WCHAR) '\\')
+    {
+        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+        /* make drive letter uppercase to enable PIDL comparison */
+        szElement[0] = toupper(szElement[0]);
+        pidlTemp = _ILCreateDrive (szElement);
     }
 
-    if (szNext && *szNext) {
-       hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
-    } else {
-       if (pdwAttributes && *pdwAttributes) {
-           SHELL32_GetItemAttributes (_IShellFolder_ (This), pidlTemp, pdwAttributes);
-       }
-       hr = S_OK;
+    if (szNext && *szNext)
+    {
+        hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc, &pidlTemp,
+                              (LPOLESTR) szNext, pchEaten, pdwAttributes);
+    }
+    else
+    {
+        if (pdwAttributes && *pdwAttributes)
+            SHELL32_GetItemAttributes (_IShellFolder_ (This),
+                                       pidlTemp, pdwAttributes);
+        hr = S_OK;
     }
 
     *ppidl = pidlTemp;
@@ -241,14 +254,20 @@ ISF_MyComputer_fnParseDisplayName (IShellFolder2 * iface,
 /**************************************************************************
  *  CreateMyCompEnumList()
  */
+static const WCHAR MyComputer_NameSpaceW[] = { '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','\\','E','x','p','l',
+ 'o','r','e','r','\\','M','y','C','o','m','p','u','t','e','r','\\','N','a','m',
+ 'e','s','p','a','c','e','\0' };
+
 static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
 {
     BOOL ret = TRUE;
 
     TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
 
-    /*enumerate the folders*/
-    if(dwFlags & SHCONTF_FOLDERS)
+    /* enumerate the folders */
+    if (dwFlags & SHCONTF_FOLDERS)
     {
         WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
         DWORD dwDrivemap = GetLogicalDrives();
@@ -263,27 +282,27 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
         }
 
         TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list);
-        if (ret && !RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-         "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\explorer\\mycomputer\\NameSpace",
+        if (ret && !RegOpenKeyExW(HKEY_LOCAL_MACHINE, MyComputer_NameSpaceW,
          0, KEY_READ, &hkey))
         {
-            char iid[50];
+            WCHAR iid[50];
             int i=0;
 
             while (ret)
             {
-                DWORD size = sizeof (iid);
-                LONG apiRet = RegEnumKeyExA(hkey, i, iid, &size, 0, NULL, NULL,
-                 NULL);
+                DWORD size;
+                LONG r;
 
-                if (ERROR_SUCCESS == apiRet)
+                size = sizeof(iid) / sizeof(iid[0]);
+                r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
+                if (ERROR_SUCCESS == r)
                 {
                     /* FIXME: shell extensions, shouldn't the type be
                      * PT_SHELLEXT? */
-                    ret = AddToEnumList(list, _ILCreateGuidFromStrA(iid));
+                    ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid));
                     i++;
                 }
-                else if (ERROR_NO_MORE_ITEMS == apiRet)
+                else if (ERROR_NO_MORE_ITEMS == r)
                     break;
                 else
                     ret = FALSE;
@@ -295,14 +314,15 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
 }
 
 /**************************************************************************
-*              ISF_MyComputer_fnEnumObjects
+*        ISF_MyComputer_fnEnumObjects
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
+static HRESULT WINAPI ISF_MyComputer_fnEnumObjects (IShellFolder2 *iface,
+               HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);
+    TRACE("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This,
+          hwndOwner, dwFlags, ppEnumIDList);
 
     *ppEnumIDList = IEnumIDList_Constructor();
     if (*ppEnumIDList)
@@ -314,43 +334,42 @@ ISF_MyComputer_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFla
 }
 
 /**************************************************************************
-*              ISF_MyComputer_fnBindToObject
+*        ISF_MyComputer_fnBindToObject
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
-                              LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+static HRESULT WINAPI ISF_MyComputer_fnBindToObject (IShellFolder2 *iface,
+               LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", This,
+          pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
 
     return SHELL32_BindToChild (This->pidlRoot, NULL, pidl, riid, ppvOut);
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnBindToStorage
+*    ISF_MyComputer_fnBindToStorage
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
-                               LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+static HRESULT WINAPI ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
+               LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This,
+          pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
 
     *ppvOut = NULL;
     return E_NOTIMPL;
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnCompareIDs
+*     ISF_MyComputer_fnCompareIDs
 */
 
-static HRESULT WINAPI
-ISF_MyComputer_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+static HRESULT WINAPI ISF_MyComputer_fnCompareIDs (IShellFolder2 *iface,
+               LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     int nReturn;
 
     TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
@@ -360,34 +379,41 @@ ISF_MyComputer_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnCreateViewObject
+*    ISF_MyComputer_fnCreateViewObject
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject (IShellFolder2 *iface,
+               HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     LPSHELLVIEW pShellView;
     HRESULT hr = E_INVALIDARG;
 
-    TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
-
-    if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IDropTarget)) {
-           WARN ("IDropTarget not implemented\n");
-           hr = E_NOTIMPL;
-       } else if (IsEqualIID (riid, &IID_IContextMenu)) {
-           WARN ("IContextMenu not implemented\n");
-           hr = E_NOTIMPL;
-       } else if (IsEqualIID (riid, &IID_IShellView)) {
-           pShellView = IShellView_Constructor ((IShellFolder *) iface);
-           if (pShellView) {
-               hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
-               IShellView_Release (pShellView);
-           }
-       }
+    TRACE("(%p)->(hwnd=%p,%s,%p)\n", This,
+          hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    *ppvOut = NULL;
+
+    if (IsEqualIID (riid, &IID_IDropTarget))
+    {
+        WARN ("IDropTarget not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IContextMenu))
+    {
+        WARN ("IContextMenu not implemented\n");
+        hr = E_NOTIMPL;
+    }
+    else if (IsEqualIID (riid, &IID_IShellView))
+    {
+        pShellView = IShellView_Constructor ((IShellFolder *) iface);
+        if (pShellView)
+        {
+            hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
+            IShellView_Release (pShellView);
+        }
     }
     TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
     return hr;
@@ -396,26 +422,26 @@ ISF_MyComputer_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID
 /**************************************************************************
 *  ISF_MyComputer_fnGetAttributesOf
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface,
+                UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-
     HRESULT hr = S_OK;
 
     TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
 
-    if ((!cidl) || (!apidl) || (!rgfInOut))
-       return E_INVALIDARG;
+    if (!cidl || !apidl || !rgfInOut)
+        return E_INVALIDARG;
 
     if (*rgfInOut == 0)
-       *rgfInOut = ~0;
+        *rgfInOut = ~0;
 
-    while (cidl > 0 && *apidl) {
-       pdump (*apidl);
-       SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
-       apidl++;
-       cidl--;
+    while (cidl > 0 && *apidl)
+    {
+        pdump (*apidl);
+        SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
+        apidl++;
+        cidl--;
     }
 
     TRACE ("-- result=0x%08lx\n", *rgfInOut);
@@ -423,21 +449,20 @@ ISF_MyComputer_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIS
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnGetUIObjectOf
+*    ISF_MyComputer_fnGetUIObjectOf
 *
 * PARAMETERS
-*  HWND           hwndOwner, //[in ] Parent window for any output
-*  UINT           cidl,      //[in ] array size
-*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
-*  REFIID         riid,      //[in ] Requested Interface
-*  UINT*          prgfInOut, //[   ] reserved
-*  LPVOID*        ppvObject) //[out] Resulting Interface
+*  hwndOwner [in]  Parent window for any output
+*  cidl      [in]  array size
+*  apidl     [in]  simple pidl array
+*  riid      [in]  Requested Interface
+*  prgfInOut [   ] reserved
+*  ppvObject [out] Resulting Interface
 *
 */
-static HRESULT WINAPI
-ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
-                               HWND hwndOwner,
-                               UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+static HRESULT WINAPI ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
+                HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
+                UINT * prgfInOut, LPVOID * ppvOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
@@ -445,57 +470,72 @@ ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
     IUnknown *pObj = NULL;
     HRESULT hr = E_INVALIDARG;
 
-    TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
-          This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
-
-    if (ppvOut) {
-       *ppvOut = NULL;
-
-       if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
-           pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
-           pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
-           SHFree (pidl);
-           hr = S_OK;
-       } else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
-           hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
-       } else if ((IsEqualIID(riid,&IID_IShellLinkW) || IsEqualIID(riid,&IID_IShellLinkA))
-                               && (cidl == 1)) {
-           pidl = ILCombine (This->pidlRoot, apidl[0]);
-           hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
-           SHFree (pidl);
-       } else {
-           hr = E_NOINTERFACE;
-       }
-
-       if (SUCCEEDED(hr) && !pObj)
-           hr = E_OUTOFMEMORY;
-
-       *ppvOut = pObj;
+    TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", This,
+          hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (!ppvOut)
+        return hr;
+
+    *ppvOut = NULL;
+
+    if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1))
+    {
+        pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
+                                              This->pidlRoot, apidl, cidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1))
+    {
+        pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
+                                              This->pidlRoot, apidl, cidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
     }
+    else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
+        SHFree (pidl);
+        hr = S_OK;
+    }
+    else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1))
+    {
+        hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget,
+                                          (LPVOID *) &pObj);
+    }
+    else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
+              IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1))
+    {
+        pidl = ILCombine (This->pidlRoot, apidl[0]);
+        hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*) &pObj);
+        SHFree (pidl);
+    }
+    else 
+        hr = E_NOINTERFACE;
+
+    if (SUCCEEDED(hr) && !pObj)
+        hr = E_OUTOFMEMORY;
+
+    *ppvOut = pObj;
     TRACE ("(%p)->hr=0x%08lx\n", This, hr);
     return hr;
 }
 
 /**************************************************************************
-*      ISF_MyComputer_fnGetDisplayNameOf
+*    ISF_MyComputer_fnGetDisplayNameOf
 */
-static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 *iface,
+               LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
-    char szPath[MAX_PATH],
-      szDrive[18];
+    char szPath[MAX_PATH], szDrive[18];
     int len = 0;
     BOOL bSimplePidl;
     HRESULT hr = S_OK;
@@ -504,98 +544,138 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 * iface,
     pdump (pidl);
 
     if (!strRet)
-       return E_INVALIDARG;
+        return E_INVALIDARG;
 
     szPath[0] = 0x00;
     szDrive[0] = 0x00;
 
     bSimplePidl = _ILIsPidlSimple (pidl);
 
-    if (!pidl->mkid.cb) {
-       /* parsing name like ::{...} */
-       lstrcpyA (szPath, "::");
-       SHELL32_GUIDToStringA(&CLSID_MyComputer, &szPath[2]);
-    } else if (_ILIsSpecialFolder (pidl)) {
-       /* take names of special folders only if its only this folder */
-       if (bSimplePidl) {
-           GUID const *clsid;
-
-           if ((clsid = _ILGetGUIDPointer (pidl))) {
-               if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) {
-                   int bWantsForParsing;
-
-                   /*
-                    * we can only get a filesystem path from a shellfolder if the value WantsFORPARSING in
-                    * CLSID\\{...}\\shellfolder exists
-                    * exception: the MyComputer folder has this keys not but like any filesystem backed
-                    *            folder it needs these behaviour
-                    */
-                   /* get the "WantsFORPARSING" flag from the registry */
-                   char szRegPath[100];
-
-                   lstrcpyA (szRegPath, "CLSID\\");
-                   SHELL32_GUIDToStringA (clsid, &szRegPath[6]);
-                   lstrcatA (szRegPath, "\\shellfolder");
-                   bWantsForParsing =
-                       (ERROR_SUCCESS ==
-                        SHGetValueA (HKEY_CLASSES_ROOT, szRegPath, "WantsFORPARSING", NULL, NULL, NULL));
-
-                   if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && bWantsForParsing) {
-                       /* we need the filesystem path to the destination folder. Only the folder itself can know it */
-                       hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
-                   } else {
-                       LPSTR p;
-
-                       /* parsing name like ::{...} */
-                       p = lstrcpyA(szPath, "::") + 2;
-                       p += SHELL32_GUIDToStringA(&CLSID_MyComputer, p);
-
-                       lstrcatA(p, "\\::");
-                       p += 3;
-                       SHELL32_GUIDToStringA(clsid, p);
-                   }
-               } else {
-                   /* user friendly name */
-                   HCR_GetClassNameA (clsid, szPath, MAX_PATH);
-               }
-           } else
-               _ILSimpleGetText (pidl, szPath, MAX_PATH);      /* append my own path */
-       } else {
-           FIXME ("special folder\n");
-       }
-    } else {
-       if (!_ILIsDrive (pidl)) {
-           ERR ("Wrong pidl type\n");
-           return E_INVALIDARG;
-       }
-
-       _ILSimpleGetText (pidl, szPath, MAX_PATH);      /* append my own path */
-
-       /* long view "lw_name (C:)" */
-       if (bSimplePidl && !(dwFlags & SHGDN_FORPARSING)) {
-           DWORD dwVolumeSerialNumber,
-             dwMaximumComponetLength,
-             dwFileSystemFlags;
-
-           GetVolumeInformationA (szPath, szDrive, sizeof (szDrive) - 6, &dwVolumeSerialNumber,
-                                  &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
-           strcat (szDrive, " (");
-           strncat (szDrive, szPath, 2);
-           strcat (szDrive, ")");
-           strcpy (szPath, szDrive);
-       }
+    if (!pidl->mkid.cb)
+    {
+        /* parsing name like ::{...} */
+        lstrcpyA (szPath, "::");
+        SHELL32_GUIDToStringA(&CLSID_MyComputer, &szPath[2]);
+    }
+    else if (_ILIsSpecialFolder (pidl))
+    {
+        /* take names of special folders only if its only this folder */
+        if (bSimplePidl)
+        {
+            GUID const *clsid;
+
+            clsid = _ILGetGUIDPointer (pidl);
+            if (clsid)
+            {
+                if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)
+                {
+                    static const WCHAR clsidW[] =
+                     { 'C','L','S','I','D','\\',0 };
+                    static const WCHAR shellfolderW[] =
+                     { '\\','s','h','e','l','l','f','o','l','d','e','r',0 };
+                    static const WCHAR wantsForParsingW[] =
+                     { 'W','a','n','t','s','F','o','r','P','a','r','s','i','n',
+                     'g',0 };
+                    int bWantsForParsing = FALSE;
+                    WCHAR szRegPath[100];
+                    LONG r;
+
+                    /*
+                     * We can only get a filesystem path from a shellfolder
+                     * if the value WantsFORPARSING exists in
+                     *      CLSID\\{...}\\shellfolder 
+                     * exception: the MyComputer folder has this keys not
+                     *            but like any filesystem backed
+                     *            folder it needs these behaviour
+                     *
+                     * Get the "WantsFORPARSING" flag from the registry
+                     */
+
+                    lstrcpyW (szRegPath, clsidW);
+                    SHELL32_GUIDToStringW (clsid, &szRegPath[6]);
+                    lstrcatW (szRegPath, shellfolderW);
+                    r = SHGetValueW (HKEY_CLASSES_ROOT, szRegPath, 
+                                     wantsForParsingW, NULL, NULL, NULL);
+                    if (r == ERROR_SUCCESS)
+                        bWantsForParsing = TRUE;
+
+                    if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
+                        bWantsForParsing)
+                    {
+                        /*
+                         * We need the filesystem path to the destination folder
+                         * Only the folder itself can know it
+                         */
+                        hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
+                                                dwFlags, szPath, MAX_PATH);
+                    }
+                    else
+                    {
+                        LPSTR p;
+
+                        /* parsing name like ::{...} */
+                        p = lstrcpyA(szPath, "::") + 2;
+                        p += SHELL32_GUIDToStringA(&CLSID_MyComputer, p);
+
+                        lstrcatA(p, "\\::");
+                        p += 3;
+                        SHELL32_GUIDToStringA(clsid, p);
+                    }
+                }
+                else
+                {
+                    /* user friendly name */
+                    HCR_GetClassNameA (clsid, szPath, MAX_PATH);
+                }
+            }
+            else
+            {
+                /* append my own path */
+                _ILSimpleGetText (pidl, szPath, MAX_PATH);
+            }
+        }
+        else
+            FIXME ("special folder\n");
+    }
+    else
+    {
+        if (!_ILIsDrive (pidl))
+        {
+            ERR ("Wrong pidl type\n");
+            return E_INVALIDARG;
+        }
+
+        _ILSimpleGetText (pidl, szPath, MAX_PATH);    /* append my own path */
+
+        /* long view "lw_name (C:)" */
+        if (bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
+        {
+            DWORD dwVolumeSerialNumber, dwMaximumComponetLength, dwFileSystemFlags;
+
+            GetVolumeInformationA (szPath, szDrive, sizeof (szDrive) - 6,
+                       &dwVolumeSerialNumber,
+                       &dwMaximumComponetLength, &dwFileSystemFlags, NULL, 0);
+            strcat (szDrive, " (");
+            strncat (szDrive, szPath, 2);
+            strcat (szDrive, ")");
+            strcpy (szPath, szDrive);
+        }
     }
 
-    if (!bSimplePidl) {                /* go deeper if needed */
-       PathAddBackslashA (szPath);
-       len = strlen (szPath);
+    if (!bSimplePidl)
+    {
+        /* go deeper if needed */
+        PathAddBackslashA (szPath);
+        len = strlen (szPath);
 
-       hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len);
+        hr = SHELL32_GetDisplayNameOfChild (iface, pidl,
+                  dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len);
     }
 
-    if (SUCCEEDED (hr)) {
-       strRet->uType = STRRET_CSTR;
-       lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+    if (SUCCEEDED (hr))
+    {
+        strRet->uType = STRRET_CSTR;
+        lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
     }
 
     TRACE ("-- (%p)->(%s)\n", This, szPath);
@@ -608,53 +688,64 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf (IShellFolder2 * iface,
 *  identifier in the process.
 *
 * PARAMETERS
-*  HWND          hwndOwner,  //[in ] Owner window for output
-*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
-*  LPCOLESTR     lpszName,   //[in ] the items new display name
-*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
-*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
+*  hwndOwner  [in]   Owner window for output
+*  pidl       [in]   simple pidl of item to change
+*  lpszName   [in]   the items new display name
+*  dwFlags    [in]   SHGNO formatting flags
+*  ppidlOut   [out]  simple pidl returned
 */
-static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,   /*simple pidl */
-                                                 LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+static HRESULT WINAPI ISF_MyComputer_fnSetNameOf (
+               IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,
+               LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
-    FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+    FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This,
+           hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
     return E_FAIL;
 }
 
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID (
+               IShellFolder2 * iface, GUID * pguid)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
-static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (
+               IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
     return E_NOTIMPL;
 }
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
+static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn (
+               IShellFolder2 *iface, DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
     TRACE ("(%p)\n", This);
 
-    if (pSort) *pSort = 0;
-    if (pDisplay) *pDisplay = 0;
+    if (pSort)
+         *pSort = 0;
+    if (pDisplay)
+        *pDisplay = 0;
     return S_OK;
 }
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
+static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState (
+               IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
 
     TRACE ("(%p)\n", This);
 
-    if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS) return E_INVALIDARG;
+    if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
+        return E_INVALIDARG;
     *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
     return S_OK;
 }
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
+
+static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface,
+               LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
@@ -662,7 +753,8 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx (IShellFolder2 * iface, LPCI
 }
 
 /* FIXME: drive size >4GB is rolling over */
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface,
+               LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     HRESULT hr;
@@ -670,48 +762,58 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf (IShellFolder2 * iface, LPCI
     TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
 
     if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
-       return E_INVALIDARG;
-
-    if (!pidl) {
-       psd->fmt = MyComputerSFHeader[iColumn].fmt;
-       psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
-       psd->str.uType = STRRET_CSTR;
-       LoadStringA (shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
-       return S_OK;
-    } else {
-       char szPath[MAX_PATH];
-       ULARGE_INTEGER ulBytes;
-
-       psd->str.u.cStr[0] = 0x00;
-       psd->str.uType = STRRET_CSTR;
-       switch (iColumn) {
-       case 0:         /* name */
-           hr = IShellFolder_GetDisplayNameOf (iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
-           break;
-       case 1:         /* type */
-           _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
-           break;
-       case 2:         /* total size */
-           if (_ILIsDrive (pidl)) {
-               _ILSimpleGetText (pidl, szPath, MAX_PATH);
-               GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
-               StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
-           }
-           break;
-       case 3:         /* free size */
-           if (_ILIsDrive (pidl)) {
-               _ILSimpleGetText (pidl, szPath, MAX_PATH);
-               GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
-               StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
-           }
-           break;
-       }
-       hr = S_OK;
+        return E_INVALIDARG;
+
+    if (!pidl)
+    {
+        psd->fmt = MyComputerSFHeader[iColumn].fmt;
+        psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
+        psd->str.uType = STRRET_CSTR;
+        LoadStringA (shell32_hInstance, MyComputerSFHeader[iColumn].colnameid,
+                     psd->str.u.cStr, MAX_PATH);
+        return S_OK;
+    }
+    else
+    {
+        char szPath[MAX_PATH];
+        ULARGE_INTEGER ulBytes;
+
+        psd->str.u.cStr[0] = 0x00;
+        psd->str.uType = STRRET_CSTR;
+        switch (iColumn)
+        {
+        case 0:        /* name */
+            hr = IShellFolder_GetDisplayNameOf (iface, pidl,
+                       SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+            break;
+        case 1:        /* type */
+            _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
+            break;
+        case 2:        /* total size */
+            if (_ILIsDrive (pidl))
+            {
+                _ILSimpleGetText (pidl, szPath, MAX_PATH);
+                GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
+                StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
+            }
+            break;
+        case 3:        /* free size */
+            if (_ILIsDrive (pidl))
+            {
+                _ILSimpleGetText (pidl, szPath, MAX_PATH);
+                GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
+                StrFormatByteSizeA (ulBytes.u.LowPart, psd->str.u.cStr, MAX_PATH);
+            }
+            break;
+        }
+        hr = S_OK;
     }
 
     return hr;
 }
-static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
+
+static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (
+               IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
 {
     IGenericSFImpl *This = (IGenericSFImpl *)iface;
     FIXME ("(%p)\n", This);
@@ -720,33 +822,34 @@ static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (IShellFolder2 * iface, U
 
 static IShellFolder2Vtbl vt_ShellFolder2 =
 {
-       ISF_MyComputer_fnQueryInterface,
-       ISF_MyComputer_fnAddRef,
-       ISF_MyComputer_fnRelease,
-       ISF_MyComputer_fnParseDisplayName,
-       ISF_MyComputer_fnEnumObjects,
-       ISF_MyComputer_fnBindToObject,
-       ISF_MyComputer_fnBindToStorage,
-       ISF_MyComputer_fnCompareIDs,
-       ISF_MyComputer_fnCreateViewObject,
-       ISF_MyComputer_fnGetAttributesOf,
-       ISF_MyComputer_fnGetUIObjectOf,
-       ISF_MyComputer_fnGetDisplayNameOf,
-       ISF_MyComputer_fnSetNameOf,
-       /* ShellFolder2 */
-        ISF_MyComputer_fnGetDefaultSearchGUID,
-       ISF_MyComputer_fnEnumSearches,
-       ISF_MyComputer_fnGetDefaultColumn,
-       ISF_MyComputer_fnGetDefaultColumnState,
-       ISF_MyComputer_fnGetDetailsEx,
-       ISF_MyComputer_fnGetDetailsOf,
-       ISF_MyComputer_fnMapColumnToSCID
+    ISF_MyComputer_fnQueryInterface,
+    ISF_MyComputer_fnAddRef,
+    ISF_MyComputer_fnRelease,
+    ISF_MyComputer_fnParseDisplayName,
+    ISF_MyComputer_fnEnumObjects,
+    ISF_MyComputer_fnBindToObject,
+    ISF_MyComputer_fnBindToStorage,
+    ISF_MyComputer_fnCompareIDs,
+    ISF_MyComputer_fnCreateViewObject,
+    ISF_MyComputer_fnGetAttributesOf,
+    ISF_MyComputer_fnGetUIObjectOf,
+    ISF_MyComputer_fnGetDisplayNameOf,
+    ISF_MyComputer_fnSetNameOf,
+    /* ShellFolder2 */
+    ISF_MyComputer_fnGetDefaultSearchGUID,
+    ISF_MyComputer_fnEnumSearches,
+    ISF_MyComputer_fnGetDefaultColumn,
+    ISF_MyComputer_fnGetDefaultColumnState,
+    ISF_MyComputer_fnGetDetailsEx,
+    ISF_MyComputer_fnGetDetailsOf,
+    ISF_MyComputer_fnMapColumnToSCID
 };
 
 /************************************************************************
- *     IMCFldr_PersistFolder2_QueryInterface
+ *    IMCFldr_PersistFolder2_QueryInterface
  */
-static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
+static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (
+               IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
 {
     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
 
@@ -756,7 +859,7 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (IPersistFolder2 * i
 }
 
 /************************************************************************
- *     IMCFldr_PersistFolder2_AddRef
+ *    IMCFldr_PersistFolder2_AddRef
  */
 static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
 {
@@ -768,7 +871,7 @@ static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
 }
 
 /************************************************************************
- *     ISFPersistFolder_Release
+ *    ISFPersistFolder_Release
  */
 static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
 {
@@ -780,27 +883,29 @@ static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
 }
 
 /************************************************************************
- *     IMCFldr_PersistFolder2_GetClassID
+ *    IMCFldr_PersistFolder2_GetClassID
  */
-static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (IPersistFolder2 * iface, CLSID * lpClassId)
+static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (
+               IPersistFolder2 * iface, CLSID * lpClassId)
 {
     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
 
     TRACE ("(%p)\n", This);
 
     if (!lpClassId)
-       return E_POINTER;
+    return E_POINTER;
     *lpClassId = CLSID_MyComputer;
 
     return S_OK;
 }
 
 /************************************************************************
- *     IMCFldr_PersistFolder2_Initialize
+ *    IMCFldr_PersistFolder2_Initialize
  *
  * NOTES: it makes no sense to change the pidl
  */
-static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (IPersistFolder2 * iface, LPCITEMIDLIST pidl)
+static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (
+               IPersistFolder2 * iface, LPCITEMIDLIST pidl)
 {
     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
     TRACE ("(%p)->(%p)\n", This, pidl);
@@ -808,26 +913,27 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (IPersistFolder2 * iface
 }
 
 /**************************************************************************
- *     IPersistFolder2_fnGetCurFolder
+ *    IPersistFolder2_fnGetCurFolder
  */
-static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (IPersistFolder2 * iface, LPITEMIDLIST * pidl)
+static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (
+               IPersistFolder2 * iface, LPITEMIDLIST * pidl)
 {
     _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
 
     TRACE ("(%p)->(%p)\n", This, pidl);
 
     if (!pidl)
-       return E_POINTER;
+        return E_POINTER;
     *pidl = ILClone (This->pidlRoot);
     return S_OK;
 }
 
 static IPersistFolder2Vtbl vt_PersistFolder2 =
 {
-       IMCFldr_PersistFolder2_QueryInterface,
-       IMCFldr_PersistFolder2_AddRef,
-       IMCFldr_PersistFolder2_Release,
-       IMCFldr_PersistFolder2_GetClassID,
-       IMCFldr_PersistFolder2_Initialize,
-       IMCFldr_PersistFolder2_GetCurFolder
+    IMCFldr_PersistFolder2_QueryInterface,
+    IMCFldr_PersistFolder2_AddRef,
+    IMCFldr_PersistFolder2_Release,
+    IMCFldr_PersistFolder2_GetClassID,
+    IMCFldr_PersistFolder2_Initialize,
+    IMCFldr_PersistFolder2_GetCurFolder
 };
diff --git a/reactos/lib/shell32/shfldr_unixfs.c b/reactos/lib/shell32/shfldr_unixfs.c
new file mode 100644 (file)
index 0000000..7a49b5e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * UNIXFS - Shell namespace extension for the unix filesystem
+ *
+ * Copyright (C) 2005 Michael Jung
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* Placeholder in ReactOS, we don't need this */
index 14bab16..8385b12 100644 (file)
@@ -365,7 +365,7 @@ static UINT SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
     }
     else if ((retval = GetLastError()) >= 32)
     {
-        FIXME("Strange error set by CreateProcess: %d\n", retval);
+        TRACE("CreateProcess returned error %d\n", retval);
         retval = ERROR_BAD_FORMAT;
     }
 
index 811a5a9..dfa6fb3 100644 (file)
@@ -861,7 +861,8 @@ static const char * debug_shfileops_action( DWORD op )
 #define ERROR_SHELL_INTERNAL_FILE_NOT_FOUND 1026
 #define HIGH_ADR (LPWSTR)0xffffffff
 
-static int file_operation_delete( WIN32_FIND_DATAW *wfd,SHFILEOPSTRUCTW nFileOp, LPWSTR pFromFile,LPWSTR pTempFrom,HANDLE *hFind)
+/* handle the complete deletion of `pTempFrom` */
+static int shfileops_delete(WIN32_FIND_DATAW *wfd,SHFILEOPSTRUCTW nFileOp, LPWSTR pFromFile,LPWSTR pTempFrom,HANDLE *hFind)
 
 {
     LPWSTR lpFileName;
@@ -914,7 +915,7 @@ static int file_operation_delete( WIN32_FIND_DATAW *wfd,SHFILEOPSTRUCTW nFileOp,
  * FOF_ALLOWUNDO, FOF_WANTMAPPINGHANDLE
  */
 
-static int file_operation_checkFlags(SHFILEOPSTRUCTW nFileOp)
+static int shfileops_check_flags(SHFILEOPSTRUCTW nFileOp)
 {
     FILEOP_FLAGS OFl = ((FILEOP_FLAGS)nFileOp.fFlags & 0xfff);
     long FuncSwitch = (nFileOp.wFunc & FO_MASK);
@@ -945,6 +946,53 @@ static int file_operation_checkFlags(SHFILEOPSTRUCTW nFileOp)
     return 0;
 }
 
+static int shfileops_do_operation(WIN32_FIND_DATAW wfd,SHFILEOPSTRUCTW *nFileOp, LPWSTR pToFile, LPWSTR pFromFile)
+{
+    LPWSTR lpFileName = wfd.cAlternateFileName;
+    if (!lpFileName[0])
+        lpFileName = wfd.cFileName;
+    if (IsDotDir(lpFileName) ||
+            (IsAttribDir(wfd.dwFileAttributes) && (nFileOp->fFlags & FOF_FILESONLY)))
+        return 0; /* next name in pTempFrom(dir) */
+    SHFileStrCpyCatW(&pToFile[1], lpFileName, NULL);
+    SHFileStrCpyCatW(&pFromFile[1], lpFileName, NULL);
+    return SHFileOperationW (nFileOp);
+}
+
+/* get attributes of the parent dir of pTemp and create the directory if it does not exists */
+static DWORD shfileops_get_parent_attr2(LPWSTR pFile,LPWSTR pTemp,int flag,int *retCode)
+{
+    DWORD PathAttr;
+    pFile[0] = '\0';
+    PathAttr = GetFileAttributesW(pTemp);
+    if ((PathAttr == INVALID_FILE_ATTRIBUTES) && flag)
+    {
+        /* create dir must be here, sample target D:\y\ *.* create with RC=10003 */
+        if (SHNotifyCreateDirectoryW(pTemp, NULL))
+        {
+            *retCode = 0x73;/* value unknown */
+            /*goto shfileop_end;*/
+            return PathAttr;
+        }
+        PathAttr = GetFileAttributesW(pTemp);
+    }
+    pFile[0] = '\\';
+    return PathAttr;
+}
+
+/* get attributes of the parent dir of pTemp without creating the directory if it does not exists */
+static DWORD shfileops_get_parent_attr(LPWSTR pFile,LPWSTR pTemp)
+{
+    /* less efficient: 
+    return shfileops_get_parent_attr2(pFile,pTemp,0,NULL);
+    */
+    DWORD PathAttr;
+    pFile[0] = '\0';
+    PathAttr = GetFileAttributesW(pTemp);
+    pFile[0] = '\\';
+    return PathAttr;
+}
+
 /*************************************************************************
  * SHFileOperationW          [SHELL32.@]
  *
@@ -964,7 +1012,6 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
        LPWSTR pTempTo = NULL;
        LPWSTR pFromFile;
        LPWSTR pToFile = NULL;
-       LPWSTR lpFileName;
        int retCode = 0;
        DWORD ToAttr;
        DWORD ToPathAttr;
@@ -986,8 +1033,6 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
        long FuncSwitch = (nFileOp.wFunc & FO_MASK);
        long level= nFileOp.wFunc>>4;
 
-        int ret;
-
        /*  default no error */
        nFileOp.fAnyOperationsAborted = FALSE;
 
@@ -1016,12 +1061,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
          * create dir              0 0 0 0 0 0 1 0
          */
 
-        ret = file_operation_checkFlags(nFileOp);
-        if (ret != 0)
-        {
-            retCode = ret;
+        retCode = shfileops_check_flags(nFileOp);
+        if (retCode)
             goto shfileop_end;
-        }
 
         if ((pNextFrom) && (!(b_MultiTo) || (pNextTo)))
         {
@@ -1108,17 +1150,10 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
            hFind = FindFirstFileW(pFrom, &wfd);
            if (INVALID_HANDLE_VALUE == hFind)
            {
-                if ((FO_DELETE == FuncSwitch) && (b_Mask))
+                if ((FO_DELETE == FuncSwitch) && (b_Mask) && IsAttribDir(shfileops_get_parent_attr(pFromFile,pTempFrom)))
                 {
-                    DWORD FromPathAttr;
-                    pFromFile[0] = '\0';
-                    FromPathAttr = GetFileAttributesW(pTempFrom);
-                    pFromFile[0] = '\\';
-                    if (IsAttribDir(FromPathAttr))
-                    {
-                        /* FO_DELETE with mask and without found is valid */
-                        goto shfileop_end;
-                    }
+                    /* FO_DELETE with mask and without found is valid */
+                    goto shfileop_end;
                 }
                 /* root (without mask) is also not allowed as source, tested in W98 */
                 retCode = ERROR_SHELL_INTERNAL_FILE_NOT_FOUND;
@@ -1130,13 +1165,8 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
             /* ??? b_Mask = (!SHFileStrICmpA(&pFromFile[1], &wfd.cFileName[0], HIGH_ADR, HIGH_ADR)); */
            if (!pTo) /* FO_DELETE */
            {
-                ret = file_operation_delete(&wfd,nFileOp,pFromFile,pTempFrom,&hFind);
-                /* if ret is not 0, nFileOp.fAnyOperationsAborted is TRUE */
-                if (ret != 0)
-                {
-                  retCode = ret;
-                  goto shfileop_end;
-                }
+                retCode = shfileops_delete(&wfd,nFileOp,pFromFile,pTempFrom,&hFind);
+                /* if ret is not 0, nFileOp.fAnyOperationsAborted is TRUE and the loop will end */
                 continue;
            } /* FO_DELETE ends, pTo must be always valid from here */
 
@@ -1146,9 +1176,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
            ToPathAttr = ToAttr = GetFileAttributesW(pTempTo);
            if (!b_Mask && (ToAttr == INVALID_FILE_ATTRIBUTES) && (pToFile))
            {
-                pToFile[0] = '\0';
-                ToPathAttr = GetFileAttributesW(pTempTo);
-                pToFile[0] = '\\';
+                ToPathAttr = shfileops_get_parent_attr(pToFile,pTempTo);
            }
 
            if (FO_RENAME == FuncSwitch)
@@ -1202,15 +1230,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
                 nFileOp.fFlags = (nFileOp.fFlags | FOF_MULTIDESTFILES);
                 do
                 {
-                    lpFileName = wfd.cAlternateFileName;
-                    if (!lpFileName[0])
-                        lpFileName = wfd.cFileName;
-                    if (IsDotDir(lpFileName) ||
-                        (IsAttribDir(wfd.dwFileAttributes) && (nFileOp.fFlags & FOF_FILESONLY)))
-                        continue; /* next name in pTempFrom(dir) */
-                    SHFileStrCpyCatW(&pToFile[1], lpFileName, NULL);
-                    SHFileStrCpyCatW(&pFromFile[1], lpFileName, NULL);
-                    retCode = SHFileOperationW (&nFileOp);
+                    retCode = shfileops_do_operation(wfd,&nFileOp,pToFile,pFromFile);
                 } while(!nFileOp.fAnyOperationsAborted && FindNextFileW(hFind, &wfd));
            }
            FindClose(hFind);
@@ -1224,19 +1244,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
            {
                 if (pToFile)
                 {
-                    pToFile[0] = '\0';
-                    ToPathAttr = GetFileAttributesW(pTempTo);
-                    if ((ToPathAttr == INVALID_FILE_ATTRIBUTES) && b_ToValid)
-                    {
-                        /* create dir must be here, sample target D:\y\ *.* create with RC=10003 */
-                        if (SHNotifyCreateDirectoryW(pTempTo, NULL))
-                        {
-                            retCode = 0x73;/* value unknown */
-                            goto shfileop_end;
-                        }
-                        ToPathAttr = GetFileAttributesW(pTempTo);
-                    }
-                    pToFile[0] = '\\';
+                    ToPathAttr = shfileops_get_parent_attr2(pToFile,pTempTo,b_ToValid,&retCode);
+                    if (retCode)
+                        goto shfileop_end;
                     if (b_ToInvalidTail)
                     {
                         retCode = 0x10003;
@@ -1270,9 +1280,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
            }
            else
            {
-                pToFile[0] = '\0';
-                ToPathAttr = GetFileAttributesW(pTempTo);
-                pToFile[0] = '\\';
+                ToPathAttr = shfileops_get_parent_attr(pToFile,pTempTo);
                 if (IsAttribFile(ToPathAttr))
                 {
                     /* error, is this tested ? */
@@ -1403,7 +1411,16 @@ void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
 }
 
 /*************************************************************************
- * SheGetDirW [SHELL32.281]
+ * SheGetDirA [SHELL32.@]
+ *
+ */
+HRESULT WINAPI SheGetDirA(LPSTR u, LPSTR v)
+{   FIXME("%p %p stub\n",u,v);
+    return 0;
+}
+
+/*************************************************************************
+ * SheGetDirW [SHELL32.@]
  *
  */
 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
@@ -1412,7 +1429,16 @@ HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
 }
 
 /*************************************************************************
- * SheChangeDirW [SHELL32.274]
+ * SheChangeDirA [SHELL32.@]
+ *
+ */
+HRESULT WINAPI SheChangeDirA(LPSTR u)
+{   FIXME("(%s),stub\n",debugstr_a(u));
+    return 0;
+}
+
+/*************************************************************************
+ * SheChangeDirW [SHELL32.@]
  *
  */
 HRESULT WINAPI SheChangeDirW(LPWSTR u)
index 1f58419..e6734eb 100644 (file)
@@ -422,7 +422,7 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO
        if (SFGAO_LINK & *pdwAttributes) {
            char ext[MAX_PATH];
 
-           if (!_ILGetExtension(pidl, ext, MAX_PATH) || strcasecmp(ext, "lnk"))
+           if (!_ILGetExtension(pidl, ext, MAX_PATH) || lstrcmpiA(ext, "lnk"))
                *pdwAttributes &= ~SFGAO_LINK;
        }
     } else {
@@ -469,7 +469,7 @@ HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST p
     /* test for name of pidl */
     _ILSimpleGetText (pidl1, szTemp1, MAX_PATH);
     _ILSimpleGetText (pidl2, szTemp2, MAX_PATH);
-    nReturn = strcasecmp (szTemp1, szTemp2);
+    nReturn = lstrcmpiA (szTemp1, szTemp2);
     if (nReturn < 0)
         return MAKE_HRESULT( SEVERITY_SUCCESS, 0, (WORD)-1 );
     else if (nReturn > 0)
index b558aea..17ff230 100644 (file)
@@ -42,16 +42,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(pidl);
  */
 typedef struct
 {
-       IFileSystemBindDataVtbl *lpVtbl;
-       DWORD              ref;
-       WIN32_FIND_DATAW findFile;
+    IFileSystemBindDataVtbl *lpVtbl;
+    DWORD              ref;
+    WIN32_FIND_DATAW findFile;
 } IFileSystemBindDataImpl;
 
-static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *iface, REFIID riid, LPVOID* ppvObj);
-static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *iface);
-static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *iface);
-static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd);
-static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd);
+static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *, REFIID, LPVOID*);
+static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *);
+static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *);
+static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *, WIN32_FIND_DATAW *);
+static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *, const WIN32_FIND_DATAW *);
 
 static struct IFileSystemBindDataVtbl sbvt =
 {
@@ -62,165 +62,165 @@ static struct IFileSystemBindDataVtbl sbvt =
     IFileSystemBindData_fnGetFindData,
 };
 
-static const WCHAR wFileSystemBindData[] = {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0};
+static const WCHAR wFileSystemBindData[] = {
+    'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0};
 
 HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
 {
-       IFileSystemBindDataImpl *sb;
-       HRESULT ret = E_OUTOFMEMORY;
-
-       TRACE("%p, %p\n", pfd, ppV);
-
-       if (!ppV)
-         return E_INVALIDARG;
-
-       *ppV = NULL;
-
-       sb = (IFileSystemBindDataImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileSystemBindDataImpl));
-       if (!sb)
-         return ret;
-
-       sb->lpVtbl = &sbvt;
-       sb->ref = 1;
-       IFileSystemBindData_fnSetFindData((IFileSystemBindData*)sb, pfd);
-
-       ret = CreateBindCtx(0, ppV);
-       if (SUCCEEDED(ret))
-       {
-         BIND_OPTS bindOpts;
-         bindOpts.cbStruct = sizeof(BIND_OPTS);
-         bindOpts.grfFlags = 0;
-         bindOpts.grfMode = STGM_CREATE;
-         bindOpts.dwTickCountDeadline = 0;
-         IBindCtx_SetBindOptions(*ppV, &bindOpts);
-         IBindCtx_RegisterObjectParam(*ppV, (LPOLESTR)wFileSystemBindData, (LPUNKNOWN)sb);
-
-         IFileSystemBindData_Release((IFileSystemBindData*)sb);
-       }
-       else
-         HeapFree(GetProcessHeap(), 0, sb);
-       return ret;
+    IFileSystemBindDataImpl *sb;
+    HRESULT ret = E_OUTOFMEMORY;
+
+    TRACE("%p, %p\n", pfd, ppV);
+
+    if (!ppV)
+       return E_INVALIDARG;
+
+    *ppV = NULL;
+
+    sb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IFileSystemBindDataImpl));
+    if (!sb)
+        return ret;
+
+    sb->lpVtbl = &sbvt;
+    sb->ref = 1;
+    IFileSystemBindData_fnSetFindData((IFileSystemBindData*)sb, pfd);
+
+    ret = CreateBindCtx(0, ppV);
+    if (SUCCEEDED(ret))
+    {
+        BIND_OPTS bindOpts;
+
+        bindOpts.cbStruct = sizeof(BIND_OPTS);
+        bindOpts.grfFlags = 0;
+        bindOpts.grfMode = STGM_CREATE;
+        bindOpts.dwTickCountDeadline = 0;
+        IBindCtx_SetBindOptions(*ppV, &bindOpts);
+        IBindCtx_RegisterObjectParam(*ppV, (LPOLESTR)wFileSystemBindData, (LPUNKNOWN)sb);
+
+        IFileSystemBindData_Release((IFileSystemBindData*)sb);
+    }
+    else
+        HeapFree(GetProcessHeap(), 0, sb);
+    return ret;
 }
 
 HRESULT WINAPI FileSystemBindData_GetFindData(LPBC pbc, WIN32_FIND_DATAW *pfd)
 {
-       LPUNKNOWN pUnk;
-       IFileSystemBindData *pfsbd = NULL;
-       HRESULT ret;
-
-       TRACE("%p, %p\n", pbc, pfd);
-
-       if (!pfd)
-         return E_INVALIDARG;
-
-       ret = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &pUnk);
-       if (SUCCEEDED(ret))
-       {
-         ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd);
-         if (SUCCEEDED(ret))
-         {
-           ret = IFileSystemBindData_GetFindData(pfsbd, pfd);
-           IFileSystemBindData_Release(pfsbd);
-         }
-         IUnknown_Release(pUnk);
-       }
-       return ret;
+    LPUNKNOWN pUnk;
+    IFileSystemBindData *pfsbd = NULL;
+    HRESULT ret;
+
+    TRACE("%p, %p\n", pbc, pfd);
+
+    if (!pfd)
+        return E_INVALIDARG;
+
+    ret = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &pUnk);
+    if (SUCCEEDED(ret))
+    {
+        ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd);
+        if (SUCCEEDED(ret))
+        {
+            ret = IFileSystemBindData_GetFindData(pfsbd, pfd);
+            IFileSystemBindData_Release(pfsbd);
+        }
+        IUnknown_Release(pUnk);
+    }
+    return ret;
 }
 
 HRESULT WINAPI FileSystemBindData_SetFindData(LPBC pbc, const WIN32_FIND_DATAW *pfd)
 {
-       LPUNKNOWN pUnk;
-       IFileSystemBindData *pfsbd = NULL;
-       HRESULT ret;
-       
-       TRACE("%p, %p\n", pbc, pfd);
-
-       ret = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &pUnk);
-       if (SUCCEEDED(ret))
-       {
-         ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd);
-         if (SUCCEEDED(ret))
-         {
-           ret = IFileSystemBindData_SetFindData(pfsbd, pfd);
-           IFileSystemBindData_Release(pfsbd);
-         }
-         IUnknown_Release(pUnk);
-       }
-       return ret;}
-
-
-
-static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(IFileSystemBindData *iface, REFIID riid, LPVOID *ppV)
+    LPUNKNOWN pUnk;
+    IFileSystemBindData *pfsbd = NULL;
+    HRESULT ret;
+    
+    TRACE("%p, %p\n", pbc, pfd);
+
+    ret = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &pUnk);
+    if (SUCCEEDED(ret))
+    {
+        ret = IUnknown_QueryInterface(pUnk, &IID_IFileSystemBindData, (LPVOID *)&pfsbd);
+        if (SUCCEEDED(ret))
+        {
+            ret = IFileSystemBindData_SetFindData(pfsbd, pfd);
+            IFileSystemBindData_Release(pfsbd);
+        }
+        IUnknown_Release(pUnk);
+    }
+    return ret;
+}
+
+static HRESULT WINAPI IFileSystemBindData_fnQueryInterface(
+                IFileSystemBindData *iface, REFIID riid, LPVOID *ppV)
 {
-       IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
-       TRACE("(%p)->(\n\tIID:\t%s, %p)\n", This, debugstr_guid(riid), ppV);
-
-       *ppV = NULL;
-
-       if (IsEqualIID(riid, &IID_IUnknown))
-       {
-         *ppV = This;
-       }
-       else if (IsEqualIID(riid, &IID_IFileSystemBindData))
-       {
-         *ppV = (IFileSystemBindData*)This;
-       }
-
-       if (*ppV)
-       {
-         IUnknown_AddRef((IUnknown*)(*ppV));
-         TRACE("-- Interface: (%p)->(%p)\n", ppV, *ppV);
-         return S_OK;
-       }
-       TRACE("-- Interface: E_NOINTERFACE\n");
-       return E_NOINTERFACE;
+    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
+    TRACE("(%p)->(\n\tIID:\t%s, %p)\n", This, debugstr_guid(riid), ppV);
+
+    *ppV = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppV = This;
+    else if (IsEqualIID(riid, &IID_IFileSystemBindData))
+        *ppV = (IFileSystemBindData*)This;
+
+    if (*ppV)
+    {
+        IUnknown_AddRef((IUnknown*)(*ppV));
+        TRACE("-- Interface: (%p)->(%p)\n", ppV, *ppV);
+        return S_OK;
+    }
+    TRACE("-- Interface: E_NOINTERFACE\n");
+    return E_NOINTERFACE;
 }
 
 static ULONG WINAPI IFileSystemBindData_fnAddRef(IFileSystemBindData *iface)
 {
-       IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
-       ULONG refCount = InterlockedIncrement(&This->ref);
+    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->ref);
 
-       TRACE("(%p)->(count=%li)\n", This, refCount - 1);
+    TRACE("(%p)->(count=%li)\n", This, refCount - 1);
 
-       return refCount;
+    return refCount;
 }
 
 static ULONG WINAPI IFileSystemBindData_fnRelease(IFileSystemBindData *iface)
 {
-       IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
-       ULONG refCount = InterlockedDecrement(&This->ref);
-       
-       TRACE("(%p)->(count=%li)\n", This, refCount + 1);
-
-       if (!refCount)
-       {
-         TRACE(" destroying ISFBindPidl(%p)\n",This);
-         HeapFree(GetProcessHeap(), 0, This);
-       }
-       return refCount;
+    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->ref);
+    
+    TRACE("(%p)->(count=%li)\n", This, refCount + 1);
+
+    if (!refCount)
+    {
+        TRACE(" destroying ISFBindPidl(%p)\n",This);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return refCount;
 }
 
-static HRESULT WINAPI IFileSystemBindData_fnGetFindData(IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd)
+static HRESULT WINAPI IFileSystemBindData_fnGetFindData(
+               IFileSystemBindData *iface, WIN32_FIND_DATAW *pfd)
 {
-       IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
-       TRACE("(%p), %p\n", This, pfd);
+    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
+    TRACE("(%p), %p\n", This, pfd);
 
-       if (!pfd)
-         return E_INVALIDARG;
+    if (!pfd)
+        return E_INVALIDARG;
 
-       memcpy(pfd, &This->findFile, sizeof(WIN32_FIND_DATAW));
-       return NOERROR;
+    memcpy(pfd, &This->findFile, sizeof(WIN32_FIND_DATAW));
+    return NOERROR;
 }
 
-static HRESULT WINAPI IFileSystemBindData_fnSetFindData(IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd)
+static HRESULT WINAPI IFileSystemBindData_fnSetFindData(
+               IFileSystemBindData *iface, const WIN32_FIND_DATAW *pfd)
 {
-       IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
-       TRACE("(%p), %p\n", This, pfd);
-
-       if (pfd)
-         memcpy(&This->findFile, pfd, sizeof(WIN32_FIND_DATAW));
-       else
-         memset(&This->findFile, 0, sizeof(WIN32_FIND_DATAW));
-       return NOERROR;
+    IFileSystemBindDataImpl *This = (IFileSystemBindDataImpl *)iface;
+    TRACE("(%p), %p\n", This, pfd);
+
+    if (pfd)
+        memcpy(&This->findFile, pfd, sizeof(WIN32_FIND_DATAW));
+    else
+        memset(&This->findFile, 0, sizeof(WIN32_FIND_DATAW));
+    return NOERROR;
 }
index 6dc5e5f..06f30c6 100644 (file)
@@ -454,7 +454,7 @@ static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam
         {
             _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
             _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
-            nDiff = strcasecmp(strName1, strName2);
+            nDiff = lstrcmpiA(strName1, strName2);
         }
         /* Sort by FileName: Folder or Files can be sorted */
         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
@@ -462,7 +462,7 @@ static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam
             /* Sort by Text */
             _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
             _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
-            nDiff = strcasecmp(strName1, strName2);
+            nDiff = lstrcmpiA(strName1, strName2);
         }
         /* Sort by File Size, Only valid for Files */
         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
@@ -475,7 +475,7 @@ static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam
             /* Sort by Type */
             _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
             _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
-            nDiff = strcasecmp(strName1, strName2);
+            nDiff = lstrcmpiA(strName1, strName2);
         }
     }
     /*  If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
@@ -484,7 +484,7 @@ static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam
     {
         _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
         _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
-        nDiff = strcasecmp(strName1, strName2);
+        nDiff = lstrcmpiA(strName1, strName2);
     }
 
     if(!pSortInfo->bIsAscending)
@@ -988,7 +988,7 @@ static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL
        {
          hMenu = CreatePopupMenu();
 
-         pCM = ISvBgCm_Constructor(This->pSFParent);
+         pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
          IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
 
          uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
@@ -1977,7 +1977,7 @@ static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem,
        switch(uItem)
        {
          case SVGIO_BACKGROUND:
-           *ppvOut = ISvBgCm_Constructor(This->pSFParent);
+           *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
            break;
 
          case SVGIO_SELECTION:
index 66a6f3b..81ce377 100644 (file)
@@ -38,23 +38,57 @@ END
 /* BINRES document.ico */
 1 ICON document.ico
 /* {
- '00 00 01 00 08 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 86 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 2E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 96 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 7E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 A6 12 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 4E 21 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 F6 46 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 9E 57 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 01 00 0C 00 10 10 10 00 01 00 04 00 28 01'
+ '00 00 C6 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 EE 01 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 56 07 00 00 20 20 10 00 01 00 04 00 E8 02'
+ '00 00 BE 0B 00 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 A6 0E 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 4E 17 00 00 30 30 10 00 01 00 04 00 68 06'
+ '00 00 F6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 5E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 06 3D 00 00 40 40 10 00 01 00 04 00 68 0A'
+ '00 00 AE 62 00 00 40 40 00 00 01 00 08 00 28 16'
+ '00 00 16 6D 00 00 40 40 00 00 01 00 20 00 28 42'
+ '00 00 3E 83 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 11 11 11 00 22 22 22 00 33 33 33 00 55 55'
- '55 00 66 66 66 00 77 77 77 00 7F 7F 7F 00 88 88'
- '88 00 99 99 99 00 AA AA AA 00 BB BB BB 00 CC CC'
- 'CC 00 DD DD DD 00 EE EE EE 00 FF FF FF 00 00 00'
- '00 00 33 00 32 00 5C 00 64 00 6F 00 63 00 75 00'
- '6D 00 65 00 6E 00 74 00 2E 00 69 00 63 00 6F 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 88'
+ '88 88 88 88 88 00 00 8F FF FF FF FF F8 00 00 8F'
+ 'FF FF FF FF F8 00 00 8F FF FF FF FF F8 00 00 8F'
+ 'FF FF FF FF F8 00 00 8F FF FF FF FF F8 00 00 8F'
+ 'FF FF FF FF F8 00 00 8F FF FF FF FF F8 00 00 8F'
+ 'FF FF FF FF F8 00 00 8F FF FF FF FF F8 00 00 8F'
+ 'FF FF FF F8 88 00 00 8F FF FF F8 77 80 00 00 8F'
+ 'FF FF F8 F8 80 00 00 8F FF FF F8 F8 00 00 00 8F'
+ 'FF FF F8 80 00 00 00 88 88 88 88 00 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 07 00 00 C0 07'
+ '00 00 C0 0F 00 00 C0 1F 00 00 C0 3F 00 00 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 FF 00'
+ 'FF 00 8C 8C 8C 00 A5 A5 A5 00 A9 A9 A9 00 B5 B5'
+ 'B5 00 BA BA BA 00 C0 C0 C0 00 C2 C2 C2 00 C6 C6'
+ 'C6 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CC CC'
+ 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DE DE DE 00 E0 E0'
+ 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
+ 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
+ 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
+ 'F9 00 FA FA FA 00 FB FB FB 00 FC FC FC 00 FD FD'
+ 'FD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -69,131 +103,10 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 5A 00 5C 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 5A 00'
- '00 00 00 00 00 00 03 00 00 00 62 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 64 6F 63 75 6D 65 6E 74 2E'
- '69 63 6F 00 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 00 00 00 00 00 00 00 00 00 00 00 00'
- '10 01 08 09 09 09 09 09 09 08 09 09 08 09 09 08'
- '06 03 10 10 10 00 00 00 00 00 00 00 00 00 00 00'
- '10 02 0C 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0F'
- '0B 08 03 10 10 10 00 00 00 00 00 00 00 00 00 00'
- '10 01 0C 0E 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0A 0C 0A 02 10 10 10 00 00 00 00 00 00 00 00 00'
- '10 02 0B 0E 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0E'
- '0A 0D 0D 0A 02 10 10 10 00 00 00 00 00 00 00 00'
- '10 01 0C 0E 0D 0D 0D 0D 0D 0D 0E 0D 0D 0E 0D 0D'
- '0B 0D 0E 0E 0A 03 10 10 10 00 00 00 00 00 00 00'
- '10 02 0C 0E 0D 0D 0D 0E 0D 0D 0D 0D 0E 0D 0E 0D'
- '0A 0D 0F 0E 0E 09 02 10 10 00 00 00 00 00 00 00'
- '10 01 0C 0E 0D 0E 0D 0D 0D 0E 0D 0E 0D 0D 0E 0D'
- '0B 0D 0E 0F 0E 0F 0A 02 10 10 00 00 00 00 00 00'
- '10 02 0C 0E 0D 0D 0E 0D 0E 0D 0D 0E 0E 0D 0D 0E'
- '0A 0E 0F 0E 0F 0F 0F 0A 02 10 10 10 00 00 00 00'
- '10 01 0C 0E 0D 0E 0E 0D 0D 0E 0E 0D 0D 0E 0E 0E'
- '0A 0D 0E 0E 0E 0E 0E 0E 09 03 10 10 00 00 00 00'
- '10 02 0C 0E 0E 0D 0D 0E 0E 0D 0E 0E 0E 0D 0E 0E'
- '0C 0A 0B 0B 0B 0A 0B 0B 0B 06 10 10 00 00 00 00'
- '10 01 0C 0F 0D 0E 0E 0D 0E 0E 0D 0E 0D 0E 0D 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0F 09 10 10 00 00 00 00'
- '10 02 0C 0E 0E 0E 0E 0E 0D 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0E 08 10 10 00 00 00 00'
- '10 01 0C 0F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0F 0E 0E 0E 0E 0E 0F 0E 09 10 10 00 00 00 00'
- '10 01 0C 0F 0E 0E 0E 0E 0F 0E 0F 0E 0E 0E 0F 0E'
- '0E 0E 0E 0E 0F 0E 0F 0E 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0E 0F 0E 0F 0E 0F 0E 0F 0F 0F 0E 0F'
- '0F 0E 0F 0E 0E 0E 0E 0F 0F 08 10 10 00 00 00 00'
- '10 02 0C 0F 0E 0E 0F 0E 0F 0E 0F 0F 0F 0E 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0E 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0F 0E 0E 0F 0E 0F 0E 0F 0E 0F 0F 0E'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0E 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0F 0E 0F 0F 0E 0F 0F 0E 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0F 0F 0E 0F 0F 0E 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0D 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0C 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 01 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0A 10 10 00 00 00 00'
- '10 02 0C 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 09 10 10 00 00 00 00'
- '10 02 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0A 10 10 00 00 00 00'
- '10 01 06 08 06 06 06 06 06 06 06 06 06 06 06 06'
- '06 06 05 06 05 06 05 05 06 04 10 10 00 00 00 00'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 00 00 E0 00'
- '07 FF C0 00 03 FF C0 00 01 FF C0 00 00 FF C0 00'
- '00 7F C0 00 00 3F C0 00 00 1F C0 00 00 1F C0 00'
- '00 0F C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 11 11 11 00 33 33'
- '33 00 44 44 44 00 77 77 77 00 7F 7F 7F 00 99 99'
- '99 00 AA AA AA 00 BB BB BB 00 CC CC CC 00 DD DD'
- 'DD 00 EE EE EE 00 FF FF FF 00 00 00 00 00 EE EE'
- 'EE 00 FF FF FF 00 00 00 00 00 33 00 32 00 5C 00'
- '64 00 6F 00 63 00 75 00 6D 00 65 00 6E 00 74 00'
- '2E 00 69 00 63 00 6F 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -207,148 +120,183 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
- '95 00 00 00 38 00 A8 44 F9 77 13 00 00 00 18 0A'
- '38 00 00 00 38 00 18 6C 38 00 98 17 95 00 00 00'
- '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
- 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 86 00'
- '00 00 86 00 00 00 08 00 00 00 B0 18 95 00 00 00'
- '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
- '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 5A 00'
- '5C 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
- '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
- '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
- 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
- '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 5A 00 00 00 00 00 00 00 03 00'
- '00 00 62 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 64'
- '6F 63 75 6D 65 6E 74 2E 69 63 6F 00 4B 00 14 1A'
- '95 00 1F 3B D4 77 13 00 00 00 98 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 18 6C 38 00 86 00 00 00 00 00'
- '00 00 C9 F1 E7 77 86 00 00 00 A4 1A 95 00 08 00'
- '00 00 00 00 00 00 86 00 00 00 86 00 00 00 08 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 18 6C 38 00 86 00 00 00 58 1A'
- '95 00 00 00 00 00 00 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0D 00 00 00 00 00 00 01 07 08 08 07 08 07 08 04'
- '0D 0D 00 00 00 00 00 01 09 0B 0A 0B 0B 0B 0A 09'
- '06 0D 0D 00 00 00 00 01 0A 0A 0A 0A 0A 0B 0A 09'
- '0C 06 0D 0D 00 00 00 01 09 0A 0B 0A 0B 0A 0A 09'
- '0C 0C 06 01 0D 00 00 01 0A 0B 0A 0B 0A 0B 0A 09'
- '0A 09 0A 04 0D 00 00 01 09 0B 0B 0A 0B 0B 0B 0B'
- '0A 0B 0B 08 0D 00 00 01 0A 0C 0B 0B 0B 0B 0B 0B'
- '0B 0B 0C 08 0D 00 00 01 0A 0B 0B 0C 0B 0C 0B 0B'
- '0C 0B 0C 09 0D 00 00 01 0B 0C 0B 0C 0B 0C 0C 0C'
- '0C 0C 0C 08 0D 00 00 01 09 0C 0C 0B 0C 0C 0C 0C'
- '0C 0C 0C 09 0D 00 00 01 0B 0C 0C 0C 0C 0C 0C 0C'
- '0C 0C 0C 08 0D 00 00 01 0A 0C 0C 0C 0C 0C 0C 0C'
- '0C 0C 0C 09 0D 00 00 01 0B 0C 0C 0C 0C 0C 0C 0C'
- '0C 0C 0C 09 0D 00 00 01 0B 0C 0C 0C 0C 0C 0C 0C'
- '0C 0C 0C 09 0D 00 00 0D 03 03 03 03 03 03 03 02'
- '03 02 03 02 0D 00 80 1F 00 00 80 0F 00 00 80 07'
- '00 00 80 03 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08'
- '88 87 88 78 88 78 88 88 00 00 00 00 00 00 00 00'
- '7F F7 FF 7F FF 7F F7 78 80 00 00 00 00 00 00 04'
- '7F 7F 77 F7 F7 F7 FF 8F 88 00 00 00 00 00 00 00'
- '7F F7 FF 7F 7F 7F 7F 77 F8 80 00 00 00 00 00 08'
- '7F 77 F7 F7 F7 F7 F7 77 FF 88 00 00 00 00 00 00'
- '7F F7 7F 7F 7F 7F 7F 7F 7F F8 80 00 00 00 00 08'
- '7F 7F F7 F7 F7 F7 F7 77 FF FF 88 00 00 00 00 00'
- '7F F7 FF 7F 7F F7 FF 8F FF FF F8 80 00 00 00 08'
- '7F 7F 77 F7 FF 7F F7 77 F7 F7 FF 84 00 00 00 00'
- '7F F7 FF 7F 7F F7 FF 77 77 77 87 78 00 00 00 08'
- '7F 7F F7 FF F7 FF 7F FF 7F F7 FF F7 00 00 00 00'
- '7F F7 FF 7F 7F 7F F7 FF F7 FF F7 F8 00 00 00 08'
- '7F FF F7 F7 FF F7 FF 7F 7F FF 7F F8 00 00 00 00'
- '7F 7F FF FF 7F FF 7F FF F7 FF FF F8 00 00 00 04'
- '7F FF 7F F7 FF 7F FF F7 FF FF F7 F7 00 00 00 00'
- 'FF FF FF FF FF F7 FF FF 7F F7 FF F8 00 00 00 08'
- '7F 7F F7 FF FF FF FF FF FF FF FF F8 00 00 00 00'
- '7F FF FF F7 FF FF FF FF FF FF FF F8 00 00 00 08'
- '7F FF FF FF FF 7F FF FF FF FF FF F7 00 00 00 00'
- 'FF F7 FF FF FF FF FF FF FF FF FF F8 00 00 00 08'
- '7F FF FF 7F FF FF FF FF FF FF FF F7 00 00 00 00'
- '7F FF FF FF FF FF FF FF FF FF FF F8 00 00 00 08'
- '7F FF FF FF FF FF FF FF FF FF FF F8 00 00 00 00'
- 'FF FF FF FF FF FF FF FF FF FF FF F7 00 00 00 08'
- '7F FF FF FF FF FF FF FF FF FF FF F8 00 00 00 00'
- 'FF FF FF FF FF FF FF FF FF FF FF F7 00 00 00 04'
- '7F FF FF FF FF FF FF FF FF FF FF F8 00 00 00 08'
- '7F FF FF FF FF FF FF F7 FF FF FF F7 00 00 00 00'
- '88 88 88 88 88 88 88 88 88 88 88 88 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 00'
- '07 FF C0 00 03 FF C0 00 01 FF C0 00 00 FF C0 00'
- '00 7F C0 00 00 3F C0 00 00 1F C0 00 00 1F C0 00'
- '00 0F C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 77'
- '77 77 78 00 00 00 00 7F F7 FF 7F 80 00 00 04 7F'
- '7F 7F 77 F8 00 00 00 77 F7 F7 F7 FF 70 00 00 FF'
- '7F 7F 7F 7F 78 00 08 77 FF 7F F7 F7 F7 00 00 FF'
- '7F FF 7F 7F F7 00 00 7F FF F7 FF FF F7 00 04 7F'
- 'FF FF FF FF F7 00 00 FF FF FF FF FF F7 00 00 7F'
- 'FF FF FF FF F7 00 00 FF FF FF FF FF F7 00 04 7F'
- 'FF FF FF FF F7 00 00 FF FF FF FF FF F7 00 00 88'
- '88 88 88 88 88 00 80 1F 00 00 80 0F 00 00 80 07'
- '00 00 80 03 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 11 11 11 00 22 22 22 00 33 33 33 00 44 44'
- '44 00 66 66 66 00 77 77 77 00 7F 7F 7F 00 88 88'
- '88 00 99 99 99 00 AA AA AA 00 BB BB BB 00 CC CC'
- 'CC 00 DD DD DD 00 EE EE EE 00 FF FF FF 00 00 00'
- '00 00 33 00 32 00 5C 00 64 00 6F 00 63 00 75 00'
- '6D 00 65 00 6E 00 74 00 2E 00 69 00 63 00 6F 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 21 21 20 1F 1F 1D 1C 1B'
+ '19 17 16 1F 00 00 00 00 21 35 34 32 31 30 2E 2B'
+ '29 26 25 17 00 00 00 00 22 36 34 33 32 31 2F 2D'
+ '2A 29 27 18 00 00 00 00 23 37 34 34 33 32 31 2F'
+ '2E 2A 29 19 00 00 00 00 23 38 36 35 34 33 32 31'
+ '2F 2E 2C 1C 00 00 00 00 23 39 36 36 35 34 33 32'
+ '31 2F 2F 1D 00 00 00 00 23 39 38 37 36 35 34 33'
+ '32 31 31 1E 00 00 00 00 23 3B 38 38 37 36 35 34'
+ '33 32 32 1F 00 00 00 00 23 3C 3A 39 38 37 36 35'
+ '34 33 30 13 00 00 00 00 23 3C 3B 3A 39 38 37 36'
+ '35 35 13 1E 00 00 00 00 23 3D 3C 3B 3A 39 38 38'
+ '38 1B 0D 1B 00 00 00 00 23 3F 3D 3C 3B 3A 36 12'
+ '0B 0C 0F 00 00 00 00 00 23 40 3E 3D 3C 3C 1A 1A'
+ '2B 07 18 00 00 00 00 00 23 41 40 3E 3D 3C 28 15'
+ '14 18 00 00 00 00 00 00 24 42 41 40 3E 3D 29 0E'
+ '11 00 00 00 00 00 00 00 1F 21 20 20 20 1E 21 17'
+ '00 00 00 00 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 07 00 00 C0 07 00 00 C0 0F 00 00 C0 1F'
+ '00 00 C0 3F 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A1 A1 A1 6C BF BF BF 9F BE BE'
+ 'BE A0 BC BC BC A0 BC BC BC A0 B9 B9 B9 A0 B7 B7'
+ 'B7 A0 B5 B5 B5 A0 B3 B3 B3 A0 B0 B0 B0 A0 AE AE'
+ 'AE 9F 94 94 94 64 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C4 C4 C4 AD F0 F0 F0 FF EF EF'
+ 'EF FF ED ED ED FF EC EC EC FF EB EB EB FF E9 E9'
+ 'E9 FF E6 E6 E6 FF E3 E3 E3 FF E0 E0 E0 FF DE DE'
+ 'DE FE AE AE AE 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C6 C6 C6 AD F1 F1 F1 FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EC EC EC FF EA EA'
+ 'EA FF E8 E8 E8 FF E5 E5 E5 FF E3 E3 E3 FF E1 E1'
+ 'E1 FE B0 B0 B0 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F2 F2 F2 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF ED ED ED FF EC EC'
+ 'EC FF EA EA EA FF E9 E9 E9 FF E5 E5 E5 FF E3 E3'
+ 'E3 FE B2 B2 B2 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F3 F3 F3 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF EE EE EE FF ED ED'
+ 'ED FF EC EC EC FF EA EA EA FF E9 E9 E9 FF E7 E7'
+ 'E7 FE B6 B6 B6 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F4 F4 F4 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF EF EF EF FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EA EA EA FF EA EA'
+ 'EA FE B8 B8 B8 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F4 F4 F4 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FE B9 B9 B9 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F6 F6 F6 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FE BB BB BB 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F7 F7 F7 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF EE EE EE FF EB EB'
+ 'EB FE A8 A8 A8 9E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F4 F4 F4 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF C9 C9'
+ 'C9 FE B2 B2 B2 8F 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD F8 F8 F8 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F3 F3 F3 FF D1 D1 D1 FE A7 A7'
+ 'A7 F9 87 87 87 62 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD FA FA FA FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F1 F1'
+ 'F1 FF C6 C6 C6 FF 8C 8C 8C FF A4 A4 A4 FD 9A 9A'
+ '9A AD 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD FB FB FB FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF E6 E6 E6 FE B3 B3 B3 D5 37 37'
+ '37 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C7 C7 C7 AD FC FC FC FF FB FB'
+ 'FB FF F9 F9 F9 FF F8 F8 F8 FF F7 F7 F7 FF E2 E2'
+ 'E2 FF CB CB CB FE C6 C6 C6 ED 5C 5C 5C 4D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C9 C9 C9 AD FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF F9 F9 F9 FF F8 F8 F8 FF E3 E3'
+ 'E3 FF B3 B3 B3 F8 89 89 89 83 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A6 A6 A6 77 C5 C5 C5 AF C3 C3'
+ 'C3 B0 C3 C3 C3 B0 C3 C3 C3 B0 C1 C1 C1 B0 C2 C2'
+ 'C2 A6 9D 9D 9D 81 0F 0F 0F 10 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 07 00 00 C0 07'
+ '00 00 C0 0F 00 00 C0 1F 00 00 C0 1F 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 88 88 88 88 88 88 88'
+ '88 88 88 88 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF F8 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF 88 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF 88 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF FF 88 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF F8 88 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF FF F8 78 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'FF 88 87 80 00 00 00 00 00 8F FF FF FF FF FF FF'
+ '87 87 88 00 00 00 00 00 00 8F FF FF FF FF FF FF'
+ '7F 8F 88 00 00 00 00 00 00 8F FF FF FF FF FF FF'
+ '88 F8 80 00 00 00 00 00 00 8F FF FF FF FF FF FF'
+ 'F7 F7 00 00 00 00 00 00 00 8F FF FF FF FF FF FF'
+ '88 88 00 00 00 00 00 00 00 88 88 88 88 88 88 88'
+ '88 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 1F FC 00 00 3F FC 00'
+ '00 3F FC 00 00 7F FC 00 00 FF FC 00 00 FF FC 00'
+ '01 FF FF FF FF FF 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 77 77 77 00 FF 00 FF 00 82 82'
+ '82 00 A0 A0 A0 00 A1 A1 A1 00 A3 A3 A3 00 A7 A7'
+ 'A7 00 A9 A9 A9 00 AE AE AE 00 B2 B2 B2 00 B3 B3'
+ 'B3 00 B4 B4 B4 00 B5 B5 B5 00 B8 B8 B8 00 BA BA'
+ 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 C0 C0 C0 00 C5 C5 C5 00 C6 C6'
+ 'C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9 C9 00 CB CB'
+ 'CB 00 CD CD CD 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
+ 'D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9'
+ 'D9 00 DA DA DA 00 DB DB DB 00 DC DC DC 00 DD DD'
+ 'DD 00 DE DE DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1'
+ 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
+ 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
+ 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
+ 'F9 00 FA FA FA 00 FB FB FB 00 FC FC FC 00 FD FD'
+ 'FD 00 FE FE FE 00 FF FF FF 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -359,1477 +307,526 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 5A 00 5C 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 5A 00'
- '00 00 00 00 00 00 03 00 00 00 62 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 64 6F 63 75 6D 65 6E 74 2E'
- '69 63 6F 00 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 08 08 06 08 08 06 08 06 06 08 06 08'
- '06 06 06 06 06 06 06 05 06 05 05 01 10 10 10 10'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0E 0E 0E 0D 0E 0E 0E 0E 0E 0E 0D'
- '0E 0E 0E 0E 0E 0E 0E 0E 0E 0C 08 05 01 10 10 10'
- '10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0D 0D 0D 0D 0D 0D 0E 0D'
- '0D 0D 0D 0E 0D 0D 0D 0E 0E 0B 09 0A 05 01 10 10'
- '10 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0B 0F 0C 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0D 0D 0D 0D 0D 0D 0D 0D 0D 0B 0A 0D 0A 05 02 10'
- '10 10 10 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0E 0D 0D 0D 0D 0E 0D 0D 0E 0A 0A 0E 0D 09 06 01'
- '10 10 10 10 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0E 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0D 0D 0D 0D 0D 0D 0D 0E 0D 0B 0A 0E 0D 0E 0A 06'
- '01 10 10 10 10 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D'
- '0D 0D 0D 0E 0D 0D 0D 0D 0E 0B 0A 0E 0E 0E 0E 0A'
- '05 01 10 10 10 10 00 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0D 0D 0D 0D 0D 0D 0E 0D'
- '0D 0E 0D 0D 0D 0D 0E 0D 0E 0B 0A 0E 0E 0E 0E 0F'
- '0A 06 01 10 10 10 10 00 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0E 0D 0D 0D 0E 0D 0D 0D 0D'
- '0E 0D 0E 0D 0E 0D 0D 0E 0D 0B 0A 0E 0F 0E 0E 0E'
- '0F 0A 05 01 10 10 10 10 00 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0D 0E 0D 0D 0D 0E 0D 0E'
- '0D 0D 0D 0E 0D 0D 0E 0D 0E 0B 0A 0F 0E 0E 0F 0E'
- '0F 0E 0B 05 02 10 10 10 10 00 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0D 0E 0D 0D 0E 0D 0D 0E 0D'
- '0E 0D 0E 0D 0E 0E 0D 0E 0E 0B 0B 0E 0F 0E 0E 0F'
- '0E 0F 0F 0B 05 01 10 10 10 10 00 00 00 00 00 00'
- '00 10 10 03 0C 0F 0E 0D 0D 0D 0E 0D 0E 0D 0D 0E'
- '0D 0E 0D 0E 0D 0D 0E 0D 0E 0B 0A 0F 0E 0F 0F 0F'
- '0F 0F 0F 0F 0B 06 01 10 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0E 0D 0E 0D 0D 0E 0E 0D 0E'
- '0D 0D 0E 0D 0E 0E 0D 0E 0E 0B 0B 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0B 05 02 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0E 0D 0E 0D 0E 0E 0D 0D 0E 0D'
- '0E 0E 0D 0E 0E 0D 0E 0E 0E 0B 09 0B 0B 0B 0A 0B'
- '0B 0A 0B 0A 0B 0B 09 05 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0E 0D 0D 0E 0D 0D 0E 0E 0D 0E'
- '0D 0E 0E 0D 0E 0E 0E 0D 0E 0D 0C 0C 0C 0C 0C 0C'
- '0C 0C 0C 0C 0B 0C 0C 06 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0E 0E 0D 0E 0E 0E 0D 0E 0E'
- '0E 0E 0D 0E 0E 0E 0D 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0F 0E 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0E 0D 0E 0E 0D 0E 0E 0E 0D 0E'
- '0E 0D 0E 0E 0D 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0F 0D 06 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0D 0E 0E 0E 0E 0D 0E 0D 0E 0E'
- '0D 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0F 0E 0E 0E 0E 0E 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0F 0D 06 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0E 0E 0E 0E 0E 0F 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0F 0E'
- '0E 0E 0E 0F 0E 0E 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E'
- '0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0F 0E 0E 0E 0E'
- '0E 0F 0E 0E 0E 0F 0E 06 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0F 0E 0E 0E 0F 0E 0F 0E 0F 0E'
- '0F 0E 0E 0E 0E 0E 0E 0F 0E 0E 0E 0E 0E 0E 0E 0F'
- '0E 0E 0F 0E 0F 0E 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0E 0E 0E 0F 0E 0E 0E 0F 0E 0F'
- '0E 0F 0E 0F 0F 0E 0F 0E 0F 0E 0F 0E 0F 0E 0E 0E'
- '0F 0E 0E 0E 0E 0F 0E 06 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0E 0E 0F 0E 0E 0E 0F 0E 0F 0E'
- '0F 0E 0F 0F 0E 0F 0F 0F 0E 0F 0F 0F 0E 0F 0E 0F'
- '0E 0F 0E 0F 0F 0E 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0E 0E 0E 0F 0E 0F 0E 0E 0F 0F'
- '0E 0F 0F 0E 0F 0E 0F 0F 0F 0F 0E 0F 0F 0F 0F 0E'
- '0F 0E 0E 0E 0F 0F 0E 06 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0E 0F 0E 0F 0E 0F 0F 0F 0E'
- '0F 0F 0E 0F 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0E 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0E 0F 0E 0F 0E 0F 0E 0F 0E 0F'
- '0F 0E 0F 0E 0F 0F 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 06 01 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0E 0E 0F 0F 0E 0F 0E 0F 0E'
- '0F 0F 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0E 0F 0F 0E 0E 0F 0F 0F 0F 0F'
- '0E 0F 0F 0F 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 06 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0F 0E 0F 0F 0F 0E 0F 0F 0E'
- '0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0E 0F 0F 0E 0F 0F 0F 0E 0F 0F'
- '0F 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0C 0F 0F 0E 0F 0F 0F 0E 0F 0F 0F 0F'
- '0F 0E 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0F 0F 0E 0F 0F 0F 0F 0F 0E 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0F 0E 0F 0F 0F 0F 0E 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0F 0F 0F 0E 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0F 0F 0E 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 03 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0C 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0E 08 10 10 10 00 00 00 00 00'
- '00 10 10 04 0D 0F 0F 0F 0F 0F 0F 0F 0F 0E 0F 0F'
- '0E 0F 0E 0F 0E 0F 0F 0E 0F 0E 0F 0F 0F 0F 0E 0F'
- '0F 0F 0E 0F 0E 0F 0E 09 10 10 10 00 00 00 00 00'
- '00 10 10 02 0A 09 09 09 09 09 09 09 09 09 09 09'
- '09 09 09 08 09 09 08 09 08 09 08 08 08 08 08 08'
- '08 08 08 08 08 08 08 05 10 10 10 00 00 00 00 00'
- '00 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 00 00 00 00 00'
- '00 00 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10'
- '10 10 10 10 10 10 10 10 10 10 00 00 00 00 F0 00'
- '00 01 FF FF 00 00 E0 00 00 00 FF FF 00 00 E0 00'
- '00 00 7F FF 00 00 E0 00 00 00 3F FF 00 00 E0 00'
- '00 00 1F FF 00 00 E0 00 00 00 0F FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 03 FF 00 00 E0 00'
- '00 00 01 FF 00 00 E0 00 00 00 00 FF 00 00 E0 00'
- '00 00 00 7F 00 00 E0 00 00 00 00 3F 00 00 E0 00'
- '00 00 00 1F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 F0 00 00 00 00 0F 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 20 00 00 00'
- '00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 04 00 00 00 29 00 00'
- '00 38 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 38 00 00 00 34 00 00 00 19 00 00'
- '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 01 00 00 00 76 00 00 00 F1 00 00'
- '00 F9 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F8 00 00 00 F2 00 00 00 B2 00 00'
- '00 49 00 00 00 05 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 5A 00 00 00 FF 01 01 01 FF 06 06'
- '06 FF 05 05 05 FF 05 05 05 FF 05 05 05 FF 05 05'
- '05 FF 05 05 05 FF 05 05 05 FF 05 05 05 FF 05 05'
- '05 FF 05 05 05 FF 05 05 05 FF 05 05 05 FF 05 05'
- '05 FF 05 05 05 FF 05 05 05 FF 05 05 05 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 03 03 03 FF 02 02'
- '02 FF 03 03 03 FF 02 02 02 FF 00 00 00 FF 00 00'
- '00 D9 00 00 00 39 00 00 00 06 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 2E 2E 2E FF 88 88'
- '88 FF 87 87 87 FF 86 86 86 FF 86 86 86 FF 85 85'
- '85 FF 84 84 84 FF 84 84 84 FF 83 83 83 FF 82 82'
- '82 FF 82 82 82 FF 81 81 81 FF 80 80 80 FF 7F 7F'
- '7F FF 7F 7F 7F FF 7E 7E 7E FF 7D 7D 7D FF 7C 7C'
- '7C FF 7C 7C 7C FF 7B 7B 7B FF 74 74 74 FF 72 72'
- '72 FF 73 73 73 FF 67 67 67 FF 18 18 18 FF 00 00'
- '00 FF 00 00 00 D9 00 00 00 58 00 00 00 03 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 38 38 38 FF C1 C1'
- 'C1 FF F2 F2 F2 FF EA EA EA FF EA EA EA FF EA EA'
- 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E9 E9'
- 'E9 FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E9 E9 E9 FF EB EB EB FF EA EA'
- 'EA FF EA EA EA FF EA EA EA FF EB EB EB FF F1 F1'
- 'F1 FF C4 C4 C4 FF 8C 8C 8C FF 67 67 67 FF 15 15'
- '15 FF 00 00 00 FF 00 00 00 DC 00 00 00 4C 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 35 35 35 FF C8 C8'
- 'C8 FF FA FA FA FF DD DD DD FF DE DE DE FF DE DE'
- 'DE FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E2 E2 E2 FF E3 E3 E3 FF E8 E8'
- 'E8 FF BA BA BA FF A3 A3 A3 FF A6 A6 A6 FF 6B 6B'
- '6B FF 0B 0B 0B FF 00 00 00 FF 00 00 00 EB 00 00'
- '00 4B 00 00 00 03 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 35 35 35 FF C7 C7'
- 'C7 FF F9 F9 F9 FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DB DB DB FF DB DB DB FF DB DB'
- 'DB FF DC DC DC FF DC DC DC FF DC DC DC FF DC DC'
- 'DC FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DE DE DE FF E3 E3'
- 'E3 FF B7 B7 B7 FF A8 A8 A8 FF DE DE DE FF A8 A8'
- 'A8 FF 6C 6C 6C FF 25 25 25 FF 00 00 00 FF 00 00'
- '00 DE 00 00 00 57 00 00 00 03 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 22 1B 1B 1B 1B 1B 1B 1B 1B 1B 1B 1B'
+ '1B 1B 1B 1B 1B 1B 1B 1B 20 21 00 00 00 00 00 00'
+ '00 00 00 00 26 35 35 35 35 35 35 35 35 35 35 33'
+ '32 31 30 2D 2C 2B 2A 28 29 1F 00 00 00 00 00 00'
+ '00 00 00 00 34 43 42 42 41 40 3F 3F 3D 3D 3B 39'
+ '38 36 35 33 30 2F 2E 2C 2A 1A 00 00 00 00 00 00'
+ '00 00 00 00 34 44 43 42 42 41 40 3F 3F 3D 3C 3A'
+ '39 38 36 35 32 30 2F 2E 2A 1A 00 00 00 00 00 00'
+ '00 00 00 00 35 44 44 43 42 42 41 40 3F 3F 3E 3C'
+ '3B 39 38 36 35 32 30 2F 2B 1A 00 00 00 00 00 00'
+ '00 00 00 00 35 45 44 44 43 42 42 41 40 3F 3F 3E'
+ '3C 3B 39 38 36 35 32 30 2D 1A 00 00 00 00 00 00'
+ '00 00 00 00 35 46 45 44 44 43 42 42 41 40 3F 3F'
+ '3E 3C 3B 39 38 36 35 33 2F 1A 00 00 00 00 00 00'
+ '00 00 00 00 36 46 46 45 44 44 43 42 42 41 40 3F'
+ '3F 3E 3C 3B 39 38 36 35 30 1A 00 00 00 00 00 00'
+ '00 00 00 00 37 47 46 46 45 44 43 43 42 42 41 40'
+ '3F 3E 3E 3C 3B 39 38 36 30 1A 00 00 00 00 00 00'
+ '00 00 00 00 37 48 47 46 46 45 44 43 43 42 42 41'
+ '40 3F 3E 3E 3C 3B 39 38 33 1B 00 00 00 00 00 00'
+ '00 00 00 00 37 49 48 47 46 46 45 44 43 43 42 42'
+ '41 40 3F 3E 3E 3C 3B 39 34 1A 00 00 00 00 00 00'
+ '00 00 00 00 37 49 49 48 47 46 46 45 44 43 43 42'
+ '42 41 40 3F 3E 3E 3C 3A 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 37 4A 49 49 48 47 46 46 45 44 43 43'
+ '42 42 41 40 3F 3E 3D 3C 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 38 4C 4A 49 49 48 47 46 46 45 44 43'
+ '43 42 42 41 40 3F 3E 3D 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 38 4C 4C 4A 49 49 48 47 46 46 45 44'
+ '43 43 42 42 41 40 3F 3E 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 38 4D 4C 4C 4A 49 49 48 47 46 46 45'
+ '44 43 43 42 42 41 40 3F 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 39 4E 4D 4C 4C 4A 49 49 48 47 46 46'
+ '45 44 43 43 42 42 41 40 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 39 4E 4E 4D 4C 4C 4A 49 49 48 47 46'
+ '46 45 44 43 43 42 42 41 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 38 4F 4E 4E 4D 4C 4C 4A 49 49 48 47'
+ '46 46 45 44 43 43 42 42 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 39 51 4F 4E 4E 4D 4C 4C 4A 49 49 48'
+ '47 46 46 45 44 43 43 42 36 1B 00 00 00 00 00 00'
+ '00 00 00 00 39 51 51 4F 4E 4E 4D 4C 4C 4A 49 49'
+ '48 47 46 46 45 44 43 43 35 1B 00 00 00 00 00 00'
+ '00 00 00 00 3A 52 52 51 4F 4E 4E 4D 4C 4C 4A 49'
+ '49 48 47 46 46 45 44 41 28 19 00 00 00 00 00 00'
+ '00 00 00 00 3A 54 53 52 51 4F 4E 4E 4D 4C 4B 4A'
+ '49 49 48 47 46 46 47 31 16 1C 00 00 00 00 00 00'
+ '00 00 00 00 3A 54 54 52 52 51 4F 4E 4E 4D 4C 4B'
+ '4A 49 49 48 47 47 45 14 17 07 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 55 54 53 52 51 4F 4E 4E 4D 4C'
+ '4B 4A 4A 4A 4A 3F 11 0D 17 00 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 55 54 54 52 51 51 4F 4E 4E 4D'
+ '4C 4B 4B 42 16 0A 0E 15 00 00 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 56 56 55 54 53 51 51 4F 4E 4E'
+ '4D 4E 27 0C 10 31 07 18 00 00 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 56 56 55 54 54 53 51 51 4F 4E'
+ '4E 4E 29 23 3B 24 16 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 56 56 56 56 54 54 53 51 51 4F'
+ '4E 4F 3C 12 26 13 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 3A 56 56 56 56 56 55 54 54 53 51 50'
+ '4F 50 3F 0F 1B 07 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 3D 39 39 39 39 39 39 39 39 39 39 39'
+ '38 33 25 1A 1D 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 35 35 35 FF C7 C7'
- 'C7 FF F9 F9 F9 FF DC DC DC FF DB DB DB FF DB DB'
- 'DB FF DC DC DC FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DF DF DF FF DE DE'
- 'DE FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E5 E5'
- 'E5 FF B8 B8 B8 FF A7 A7 A7 FF EB EB EB FF DE DE'
- 'DE FF A4 A4 A4 FF 72 72 72 FF 17 17 17 FF 00 00'
- '00 FF 00 00 00 DC 00 00 00 4C 00 00 00 06 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 0F FC 00 00 0F FC 00 00 0F FC 00 00 0F FC 00'
+ '00 1F FC 00 00 3F FC 00 00 3F FC 00 00 7F FC 00'
+ '00 FF FC 00 00 FF FC 00 01 FF FF FF FF FF 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 2C 2C'
+ '2C 43 26 26 26 4D 26 26 26 4D 26 26 26 4D 26 26'
+ '26 4D 26 26 26 4D 26 26 26 4D 26 26 26 4D 26 26'
+ '26 4D 26 26 26 4D 26 26 26 4D 26 26 26 4D 26 26'
+ '26 4D 26 26 26 4D 26 26 26 4D 23 23 23 4D 26 26'
+ '26 4D 23 23 23 4D 23 23 23 4D 23 23 23 4D 23 23'
+ '23 42 00 00 00 38 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 1F C2 C2'
+ 'C2 C9 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8'
+ 'D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D8'
+ 'D8 D8 D8 D8 D8 D8 D8 D8 D8 D8 D6 D6 D6 D8 D4 D4'
+ 'D4 D8 D3 D3 D3 D8 D2 D2 D2 D8 CF CF CF D8 CE CE'
+ 'CE D8 CC CC CC D8 CB CB CB D8 C9 C9 C9 D8 BF BF'
+ 'BF B4 20 20 20 42 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DA DA'
+ 'DA ED EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DF DF DF FF DE DE DE FF DC DC DC FF D9 D9'
+ 'D9 FF D8 D8 D8 FF D7 D7 D7 FF D5 D5 D5 FF CB CB'
+ 'CB DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DA DA'
+ 'DA ED ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E6 E6 E6 FF E5 E5 E5 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF DF DF DF FF DE DE DE FF DB DB'
+ 'DB FF D9 D9 D9 FF D8 D8 D8 FF D7 D7 D7 FF CB CB'
+ 'CB DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DB DB'
+ 'DB ED ED ED ED FF ED ED ED FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF DF FF DE DE'
+ 'DE FF DB DB DB FF D9 D9 D9 FF D8 D8 D8 FF CD CD'
+ 'CD DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DC DC'
+ 'DC ED EE EE EE FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF'
+ 'DF FF DE DE DE FF DB DB DB FF D9 D9 D9 FF CF CF'
+ 'CF DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DC DC'
+ 'DC ED EF EF EF FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E5 E5 E5 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DF DF DF FF DE DE DE FF DC DC DC FF D1 D1'
+ 'D1 DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 27 DD DD'
+ 'DD ED EF EF EF FF EF EF EF FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E5 E5 E5 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF DF DF DF FF DE DE DE FF D2 D2'
+ 'D2 DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 27 DE DE'
+ 'DE ED F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF DF FF D3 D3'
+ 'D3 DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 27 DE DE'
+ 'DE ED F1 F1 F1 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF D6 D6'
+ 'D6 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 27 DE DE'
+ 'DE ED F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E5 E5 E5 FF E4 E4 E4 FF E2 E2 E2 FF D7 D7'
+ 'D7 DA 23 23 23 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 27 DE DE'
+ 'DE ED F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E5 E5 E5 FF E3 E3 E3 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C4 C4 C4 27 DE DE'
+ 'DE ED F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 DF DF'
+ 'DF ED F5 F5 F5 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 DF DF'
+ 'DF ED F5 F5 F5 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E7 E7 E7 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 DF DF'
+ 'DF ED F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 E0 E0'
+ 'E0 ED F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF E9 E9 E9 FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CA CA CA 27 E0 E0'
+ 'E0 ED F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 DF DF'
+ 'DF ED F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C7 C7 C7 27 E0 E0'
+ 'E0 ED FA FA FA FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF D9 D9'
+ 'D9 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CA CA CA 27 E0 E0'
+ 'E0 ED FA FA FA FF FA FA FA FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EC EC EC FF D8 D8'
+ 'D8 DA 26 26 26 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CA CA CA 27 E1 E1'
+ 'E1 ED FB FB FB FF FB FB FB FF FA FA FA FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF ED ED ED FF EA EA EA FF C9 C9'
+ 'C9 DA 20 20 20 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FD FD FD FF FC FC FC FF FB FB FB FF FA FA'
+ 'FA FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F4 F4 F4 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF F0 F0 F0 FF DA DA DA FF A8 A8'
+ 'A8 D9 24 24 24 4C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FD FD FD FF FD FD FD FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EE EE EE FF B3 B3 B3 FF A9 A9'
+ 'A9 D3 1D 1D 1D 47 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FA FA FA FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF E8 E8 E8 FF A9 A9 A9 FE 9E 9E 9E FB 8B 8B'
+ '8B 9B 00 00 00 2D 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FB FB FB FF FA FA FA FF FA FA FA FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF EB EB EB FF B5 B5'
+ 'B5 FF 77 77 77 FF A0 A0 A0 FD A9 A9 A9 DD 3B 3B'
+ '3B 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FD FD FD FF FC FC FC FF FA FA FA FF FA FA'
+ 'FA FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F7 F7 F7 FF D0 D0 D0 FF 82 82 82 FF A7 A7'
+ 'A7 FF DA DA DA FE B9 B9 B9 E5 57 57 57 69 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FD FD FD FF FD FD FD FF FC FC FC FF FA FA'
+ 'FA FF FA FA FA FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF D2 D2 D2 FF C9 C9 C9 FF E4 E4'
+ 'E4 FE CA CA CA FB 86 86 86 9C 1B 1B 1B 1C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FD FD FD FF FD FD FD FF FC FC'
+ 'FC FF FA FA FA FF FA FA FA FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F8 F8 F8 FF E5 E5 E5 FF AE AE AE FF CE CE'
+ 'CE FC 9C 9C 9C C7 18 18 18 29 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CD CD CD 27 E1 E1'
+ 'E1 ED FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FA FA FA FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F9 F9 F9 FF E8 E8 E8 FF A3 A3 A3 FE B5 B5'
+ 'B5 E4 5E 5E 5E 64 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 DC DC DC 22 E2 E2'
+ 'E2 DA E0 E0 E0 ED E0 E0 E0 ED E0 E0 E0 ED E0 E0'
+ 'E0 ED E0 E0 E0 ED E0 E0 E0 ED E0 E0 E0 ED E0 E0'
+ 'E0 ED E0 E0 E0 ED E0 E0 E0 ED E0 E0 E0 EC DF DF'
+ 'DF EC D9 D9 D9 ED C8 C8 C8 EA B3 B3 B3 E2 7A 7A'
+ '7A 7B 00 00 00 10 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 D8'
+ 'D8 22 CA CA CA 27 CA CA CA 27 CA CA CA 27 CA CA'
+ 'CA 27 CA CA CA 27 CA CA CA 27 CA CA CA 27 CA CA'
+ 'CA 27 CA CA CA 27 CA CA CA 27 C9 C9 C9 26 C5 C5'
+ 'C5 26 BC BC BC 27 A7 A7 A7 26 99 99 99 22 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FC 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 0F F8 00'
+ '00 0F F8 00 00 0F F8 00 00 0F F8 00 00 1F F8 00'
+ '00 3F F8 00 00 3F F8 00 00 7F F8 00 00 FF F8 00'
+ '00 FF FC 00 03 FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF F8 80 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF F8 70 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF F8 F8 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF 8F 70 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF F8 F8 F7 80 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF FF 8F'
+ '8F 78 00 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF F8 F8 FF 77 87 00 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF FF 8F 77'
+ '88 80 00 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF 87 77 8F 87 00 00 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF FF F7 F8 F8'
+ '80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF 87 8F 88 70 00 00 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF F8 F7 F8 88'
+ '00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF 87 88 70 00 00 00 00 00 00 00 00'
+ '00 00 8F FF FF FF FF FF FF FF FF FF F8 F7 88 80'
+ '00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF FF'
+ 'FF FF FF FF FF 87 87 00 00 00 00 00 00 00 00 00'
+ '00 00 88 88 88 88 88 88 88 88 88 88 88 87 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 36 36 36 FF C8 C8'
- 'C8 FF FA FA FA FF DC DC DC FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1 E1 FF E6 E6'
- 'E6 FF B9 B9 B9 FF A9 A9 A9 FF EA EA EA FF EA EA'
- 'EA FF E9 E9 E9 FF B1 B1 B1 FF 72 72 72 FF 14 14'
- '14 FF 00 00 00 FF 00 00 00 EB 00 00 00 4B 00 00'
- '00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 00 00 00 03 FF 00 00 FF 00'
+ '00 00 07 FF 00 00 FF 00 00 00 07 FF 00 00 FF 00'
+ '00 00 0F FF 00 00 FF 00 00 00 1F FF 00 00 FF 00'
+ '00 00 1F FF 00 00 FF 00 00 00 3F FF 00 00 FF 00'
+ '00 00 FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 6C 6C'
+ '6C 00 6F 6F 6F 00 78 78 78 00 7E 7E 7E 00 FF 00'
+ 'FF 00 8A 8A 8A 00 96 96 96 00 99 99 99 00 9B 9B'
+ '9B 00 9D 9D 9D 00 A1 A1 A1 00 A2 A2 A2 00 A3 A3'
+ 'A3 00 A4 A4 A4 00 A5 A5 A5 00 A7 A7 A7 00 A8 A8'
+ 'A8 00 A9 A9 A9 00 AA AA AA 00 AB AB AB 00 AC AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B5 B5'
+ 'B5 00 B6 B6 B6 00 B9 B9 B9 00 BA BA BA 00 BC BC'
+ 'BC 00 BD BD BD 00 BF BF BF 00 C0 C0 C0 00 C5 C5'
+ 'C5 00 C6 C6 C6 00 C8 C8 C8 00 CA CA CA 00 CC CC'
+ 'CC 00 CE CE CE 00 CF CF CF 00 D0 D0 D0 00 D3 D3'
+ 'D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7'
+ 'D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA DA 00 DB DB'
+ 'DB 00 DC DC DC 00 DD DD DD 00 DE DE DE 00 DF DF'
+ 'DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3'
+ 'E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7'
+ 'E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
+ 'EB 00 EC EC EC 00 ED ED ED 00 EE EE EE 00 EF EF'
+ 'EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2 F2 00 F3 F3'
+ 'F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7'
+ 'F7 00 F8 F8 F8 00 F9 F9 F9 00 FA FA FA 00 FB FB'
+ 'FB 00 FC FC FC 00 FD FD FD 00 FE FE FE 00 FF FF'
+ 'FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 37 37 37 FF C9 C9'
- 'C9 FF FA FA FA FF DD DD DD FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1'
- 'E1 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2 E2 FF E7 E7'
- 'E7 FF BA BA BA FF AA AA AA FF EC EC EC FF EA EA'
- 'EA FF ED ED ED FF EA EA EA FF B2 B2 B2 FF 6A 6A'
- '6A FF 1C 1C 1C FF 00 00 00 FF 00 00 00 DE 00 00'
- '00 57 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 37 37 37 FF C9 C9'
- 'C9 FF FA FA FA FF DF DF DF FF DE DE DE FF DF DF'
- 'DF FF DF DF DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E1 E1'
- 'E1 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3 E3 FF E8 E8'
- 'E8 FF BA BA BA FF AC AC AC FF EF EF EF FF ED ED'
- 'ED FF ED ED ED FF F1 F1 F1 FF F1 F1 F1 FF B1 B1'
- 'B1 FF 6B 6B 6B FF 13 13 13 FF 00 00 00 FF 00 00'
- '00 DC 00 00 00 46 00 00 00 05 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 37 37 37 FF C9 C9'
- 'C9 FF FA FA FA FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E1 E1'
- 'E1 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF E9 E9'
- 'E9 FF BB BB BB FF AD AD AD FF F3 F3 F3 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F4 F4 F4 FF F5 F5'
- 'F5 FF B5 B5 B5 FF 70 70 70 FF 14 14 14 FF 00 00'
- '00 FF 00 00 00 E0 00 00 00 3F 00 00 00 02 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 37 37 37 FF CA CA'
- 'CA FF FB FB FB FF E1 E1 E1 FF E1 E1 E1 FF E1 E1'
- 'E1 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5 E5 FF EA EA'
- 'EA FF BC BC BC FF AF AF AF FF F5 F5 F5 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F3 F3 F3 FF F4 F4 F4 FF F8 F8'
- 'F8 FF F4 F4 F4 FF B6 B6 B6 FF 6C 6C 6C FF 22 22'
- '22 FF 00 00 00 FF 00 00 00 D4 00 00 00 49 00 00'
- '00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 38 38 38 FF CA CA'
- 'CA FF FB FB FB FF E2 E2 E2 FF E1 E1 E1 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6 E6 FF EB EB'
- 'EB FF BC BC BC FF B1 B1 B1 FF F8 F8 F8 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F7 F7 F7 FF F8 F8 F8 FF F8 F8'
- 'F8 FF FC FC FC FF FC FC FC FF B5 B5 B5 FF 70 70'
- '70 FF 18 18 18 FF 00 00 00 FF 00 00 00 D4 00 00'
- '00 3F 00 00 00 05 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 38 38 38 FF CB CB'
- 'CB FF FC FC FC FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E6 E6 E6 FF E6 E6 E6 FF EC EC'
- 'EC FF BD BD BD FF B3 B3 B3 FF FC FC FC FF F9 F9'
- 'F9 FF FA FA FA FF FA FA FA FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FF FF FF FF FF FF FF FF BA BA'
- 'BA FF 75 75 75 FF 18 18 18 FF 00 00 00 FF 00 00'
- '00 E0 00 00 00 3E 00 00 00 03 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 38 38 38 FF CB CB'
- 'CB FF FC FC FC FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF ED ED'
- 'ED FF BE BE BE FF B5 B5 B5 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FB FB'
- 'FB FF BE BE BE FF 6E 6E 6E FF 1C 1C 1C FF 00 00'
- '00 FF 00 00 00 BB 00 00 00 1F 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 38 38 38 FF CC CC'
- 'CC FF FC FC FC FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E6 E6 E6 FF E7 E7 E7 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9 E9 FF EE EE'
- 'EE FF C3 C3 C3 FF 9A 9A 9A FF B9 B9 B9 FF B8 B8'
- 'B8 FF B7 B7 B7 FF B7 B7 B7 FF B7 B7 B7 FF B7 B7'
- 'B7 FF B6 B6 B6 FF B5 B5 B5 FF B5 B5 B5 FF B8 B8'
- 'B8 FF B5 B5 B5 FF 91 91 91 FF 67 67 67 FF 01 01'
- '01 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 39 39 39 FF CC CC'
- 'CC FF FC FC FC FF E6 E6 E6 FF E7 E7 E7 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9 E9 FF E9 E9'
- 'E9 FF E9 E9 E9 FF E9 E9 E9 FF EA EA EA FF EB EB'
- 'EB FF E2 E2 E2 FF CD CD CD FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF C9 C9 C9 FF C9 C9'
- 'C9 FF C9 C9 C9 FF C9 C9 C9 FF C9 C9 C9 FF C9 C9'
- 'C9 FF CD CD CD FF CC CC CC FF 7A 7A 7A FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 39 39 39 FF CC CC'
- 'CC FF FC FC FC FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9 E9 FF E9 E9'
- 'E9 FF E9 E9 E9 FF E9 E9 E9 FF EA EA EA FF EA EA'
- 'EA FF EA EA EA FF EA EA EA FF EB EB EB FF EB EB'
- 'EB FF ED ED ED FF EF EF EF FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F6 F6 F6 FF EC EC EC FF 7A 7A 7A FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3A 3A 3A FF CE CE'
- 'CE FF FD FD FD FF E9 E9 E9 FF E9 E9 E9 FF EA EA'
- 'EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9'
- 'E9 FF E9 E9 E9 FF EA EA EA FF EA EA EA FF EA EA'
- 'EA FF EA EA EA FF EB EB EB FF EB EB EB FF EA EA'
- 'EA FF EB EB EB FF EC EC EC FF EC EC EC FF EC EC'
- 'EC FF EC EC EC FF EC EC EC FF ED ED ED FF ED ED'
- 'ED FF ED ED ED FF ED ED ED FF EE EE EE FF ED ED'
- 'ED FF ED ED ED FF EE EE EE FF EF EF EF FF EF EF'
- 'EF FF F2 F2 F2 FF E9 E9 E9 FF 7B 7B 7B FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3A 3A 3A FF CD CD'
- 'CD FF FD FD FD FF EA EA EA FF EB EB EB FF EC EC'
- 'EC FF ED ED ED FF EC EC EC FF E9 E9 E9 FF EA EA'
- 'EA FF EA EA EA FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EC EC'
- 'EC FF EC EC EC FF EC EC EC FF ED ED ED FF ED ED'
- 'ED FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF EE EE EE FF EE EE EE FF EF EF EF FF EF EF'
- 'EF FF EF EF EF FF EF EF EF FF F0 F0 F0 FF F0 F0'
- 'F0 FF F4 F4 F4 FF E9 E9 E9 FF 7B 7B 7B FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3A 3A 3A FF CE CE'
- 'CE FF FE FE FE FF EC EC EC FF EC EC EC FF ED ED'
- 'ED FF EE EE EE FF EF EF EF FF EE EE EE FF EB EB'
- 'EB FF EB EB EB FF EC EC EC FF EC EC EC FF EC EC'
- 'EC FF EC EC EC FF EC EC EC FF ED ED ED FF ED ED'
- 'ED FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF EE EE EE FF EE EE EE FF EF EF EF FF EF EF'
- 'EF FF EF EF EF FF EF EF EF FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F4 F4 F4 FF EA EA EA FF 7C 7C 7C FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3B 3B 3B FF CE CE'
- 'CE FF FE FE FE FF ED ED ED FF ED ED ED FF EE EE'
- 'EE FF EF EF EF FF F0 F0 F0 FF F1 F1 F1 FF F0 F0'
- 'F0 FF EE EE EE FF EC EC EC FF EC EC EC FF ED ED'
- 'ED FF ED ED ED FF EE EE EE FF EE EE EE FF EE EE'
- 'EE FF EE EE EE FF EF EF EF FF EF EF EF FF EF EF'
- 'EF FF EF EF EF FF EF EF EF FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F2 F2 F2 FF F1 F1'
- 'F1 FF F5 F5 F5 FF EA EA EA FF 7D 7D 7D FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3B 3B 3B FF CF CF'
- 'CF FF FE FE FE FF EE EE EE FF EF EF EF FF F0 F0'
- 'F0 FF F0 F0 F0 FF F1 F1 F1 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F3 F3 F3 FF F1 F1 F1 FF EE EE EE FF EE EE'
- 'EE FF EE EE EE FF EE EE EE FF EE EE EE FF EF EF'
- 'EF FF EF EF EF FF EF EF EF FF EF EF EF FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F6 F6 F6 FF EB EB EB FF 7D 7D 7D FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3B 3B 3B FF CF CF'
- 'CF FF FF FF FF FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F1 F1 F1 FF F2 F2 F2 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1 F1 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F3 F3 F3 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F7 F7 F7 FF EB EB EB FF 7E 7E 7E FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3C 3C 3C FF D0 D0'
- 'D0 FF FF FF FF FF F1 F1 F1 FF F1 F1 F1 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F3 F3 F3 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F5 F5 F5 FF F6 F6 F6 FF F6 F6 F6 FF F7 F7'
- 'F7 FF F7 F7 F7 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
- 'F8 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F4 F4'
- 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F8 F8 F8 FF EB EB EB FF 7E 7E 7E FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3D 3D 3D FF D1 D1'
- 'D1 FF FF FF FF FF F2 F2 F2 FF F2 F2 F2 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F6 F6 F6 FF F7 F7 F7 FF F7 F7 F7 FF F8 F8'
- 'F8 FF F8 F8 F8 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF FA FA FA FF FB FB FB FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FA FA FA FF F7 F7 F7 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F5 F5 F5 FF F5 F5 F5 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F9 F9 F9 FF EC EC EC FF 7F 7F 7F FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3D 3D 3D FF D1 D1'
- 'D1 FF FF FF FF FF F3 F3 F3 FF F3 F3 F3 FF F4 F4'
- 'F4 FF F4 F4 F4 FF F5 F5 F5 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F7 F7 F7 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F9 F9 F9 FF F9 F9 F9 FF FA FA FA FF FA FA'
- 'FA FF FA FA FA FF FA FA FA FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FE FE FE FF FD FD FD FF FA FA'
- 'FA FF F7 F7 F7 FF F5 F5 F5 FF F6 F6 F6 FF F7 F7'
- 'F7 FF FA FA FA FF EC EC EC FF 80 80 80 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3E 3E 3E FF D2 D2'
- 'D2 FF FF FF FF FF F4 F4 F4 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F5 F5 F5 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF FA FA FA FF FA FA FA FF FB FB FB FF FB FB'
- 'FB FF FB FB FB FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FD FD FD FF FD FD FD FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FE FE FE FF FB FB FB FF F8 F8 F8 FF F7 F7'
- 'F7 FF FB FB FB FF ED ED ED FF 81 81 81 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3E 3E 3E FF D2 D2'
- 'D2 FF FF FF FF FF F5 F5 F5 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F7 F7 F7 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F9 F9 F9 FF FA FA'
- 'FA FF FA FA FA FF FA FA FA FF FB FB FB FF FB FB'
- 'FB FF FC FC FC FF FC FC FC FF FC FC FC FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FA FA'
- 'FA FF FC FC FC FF ED ED ED FF 80 80 80 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3E 3E 3E FF D3 D3'
- 'D3 FF FF FF FF FF F6 F6 F6 FF F7 F7 F7 FF F7 F7'
- 'F7 FF F7 F7 F7 FF F8 F8 F8 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF FA FA FA FF FA FA'
- 'FA FF FB FB FB FF FB FB FB FF FC FC FC FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF EE EE EE FF 82 82 82 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3E 3E 3E FF D3 D3'
- 'D3 FF FF FF FF FF F7 F7 F7 FF F7 F7 F7 FF F8 F8'
- 'F8 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF FA FA'
- 'FA FF FA FA FA FF FB FB FB FF FB FB FB FF FB FB'
- 'FB FF FC FC FC FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 82 82 82 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3F 3F 3F FF D4 D4'
- 'D4 FF FF FF FF FF F8 F8 F8 FF F8 F8 F8 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF FA FA FA FF FA FA'
- 'FA FF FA FA FA FF FB FB FB FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FC FC FC FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF EF EF EF FF 82 82 82 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3F 3F 3F FF D5 D5'
- 'D5 FF FF FF FF FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF FA FA FA FF FB FB FB FF FB FB FB FF FB FB'
- 'FB FF FC FC FC FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 83 83 83 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 3F 3F 3F FF D5 D5'
- 'D5 FF FF FF FF FF FA FA FA FF FA FA FA FF FB FB'
- 'FB FF FB FB FB FF FB FB FB FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FC FC FC FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 84 84 84 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 40 40 40 FF D5 D5'
- 'D5 FF FF FF FF FF FB FB FB FF FB FB FB FF FB FB'
- 'FB FF FC FC FC FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 85 85 85 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 40 40 40 FF D6 D6'
- 'D6 FF FF FF FF FF FB FB FB FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 85 85 85 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 41 41 41 FF D6 D6'
- 'D6 FF FF FF FF FF FB FB FB FF FC FC FC FF FD FD'
- 'FD FF FD FD FD FF FC FC FC FF FD FD FD FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F0 F0 F0 FF 86 86 86 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 41 41 41 FF D6 D6'
- 'D6 FF FF FF FF FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F1 F1 F1 FF 87 87 87 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 41 41 41 FF D7 D7'
- 'D7 FF FF FF FF FF FD FD FD FF FD FD FD FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F1 F1 F1 FF 87 87 87 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 41 41 41 FF D7 D7'
- 'D7 FF FF FF FF FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F1 F1 F1 FF 88 88 88 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 41 41 41 FF D7 D7'
- 'D7 FF FF FF FF FF FE FE FE FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F1 F1 F1 FF 88 88 88 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 42 42 42 FF D8 D8'
- 'D8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F1 F1 F1 FF 89 89 89 FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 42 42 42 FF D9 D9'
- 'D9 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F2 F2 F2 FF 8A 8A 8A FF 05 05'
- '05 FF 00 00 00 F7 00 00 00 37 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 84 00 00 00 FF 47 47 47 FF D9 D9'
- 'D9 FF FB FB FB FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
- 'F7 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
- 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F6 F6 F6 FF E8 E8 E8 FF 8F 8F 8F FF 06 06'
- '06 FF 00 00 00 F7 00 00 00 38 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 83 00 00 00 FF 2D 2D 2D FF 98 98'
- '98 FF 98 98 98 FF 97 97 97 FF 97 97 97 FF 97 97'
- '97 FF 96 96 96 FF 95 95 95 FF 95 95 95 FF 95 95'
- '95 FF 93 93 93 FF 93 93 93 FF 93 93 93 FF 92 92'
- '92 FF 91 91 91 FF 90 90 90 FF 90 90 90 FF 90 90'
- '90 FF 8F 8F 8F FF 8F 8F 8F FF 8E 8E 8E FF 8C 8C'
- '8C FF 8C 8C 8C FF 8C 8C 8C FF 8B 8B 8B FF 89 89'
- '89 FF 89 89 89 FF 88 88 88 FF 88 88 88 FF 86 86'
- '86 FF 86 86 86 FF 86 86 86 FF 86 86 86 FF 84 84'
- '84 FF 84 84 84 FF 87 87 87 FF 6C 6C 6C FF 04 04'
- '04 FF 00 00 00 F7 00 00 00 33 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 47 00 00 00 F5 00 00 00 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 04 04 04 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 04 04 04 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 04 04 04 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 04 04 04 FF 04 04'
- '04 FF 04 04 04 FF 04 04 04 FF 04 04 04 FF 04 04'
- '04 FF 03 03 03 FF 03 03 03 FF 03 03 03 FF 03 03'
- '03 FF 03 03 03 FF 03 03 03 FF 03 03 03 FF 03 03'
- '03 FF 03 03 03 FF 03 03 03 FF 03 03 03 FF 03 03'
- '03 FF 03 03 03 FF 03 03 03 FF 03 03 03 FF 00 00'
- '00 FF 00 00 00 C1 00 00 00 14 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 52 00 00 00 EA 00 00'
- '00 F3 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F4 00 00'
- '00 C7 00 00 00 29 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 F0 00 00 01 FF FF 00 00 E0 00'
- '00 00 FF FF 00 00 E0 00 00 00 7F FF 00 00 E0 00'
- '00 00 3F FF 00 00 E0 00 00 00 1F FF 00 00 E0 00'
- '00 00 0F FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 03 FF 00 00 E0 00 00 00 01 FF 00 00 E0 00'
- '00 00 00 FF 00 00 E0 00 00 00 00 7F 00 00 E0 00'
- '00 00 00 3F 00 00 E0 00 00 00 00 1F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 F0 00'
- '00 00 00 0F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 00'
- '00 64 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 62 00 00 00 41 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4D 01 01 01 FB 05 05'
- '05 FF 03 03 03 FF 03 03 03 FF 02 02 02 FF 02 02'
- '02 FF 02 02 02 FF 02 02 02 FF 02 02 02 FF 02 02'
- '02 FF 02 02 02 FF 02 02 02 FF 02 02 02 FF 01 01'
- '01 FF 00 00 00 FF 03 03 03 FF 01 01 01 FD 00 00'
- '00 7F 00 00 00 02 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1A 1A 1A FF 8C 8C'
- '8C FF 9F 9F 9F FF 9C 9C 9C FF 9A 9A 9A FF 9A 9A'
- '9A FF 99 99 99 FF 99 99 99 FF 97 97 97 FF 97 97'
- '97 FF 96 96 96 FF 96 96 96 FF 95 95 95 FF 93 93'
- '93 FF 8E 8E 8E FF 7D 7D 7D FF 33 33 33 FF 00 00'
- '00 FD 00 00 00 79 00 00 00 02 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1D 1D 1D FF C6 C6'
- 'C6 FF F7 F7 F7 FF EA EA EA FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EC EC'
- 'EC FF ED ED ED FF EE EE EE FF EE EE EE FF EF EF'
- 'EF FF F3 F3 F3 FF B7 B7 B7 FF 94 94 94 FF 34 34'
- '34 FF 00 00 00 FD 00 00 00 7A 00 00 00 02 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1C 1C 1C FF C4 C4'
- 'C4 FF EB EB EB FF D8 D8 D8 FF DA DA DA FF DB DB'
- 'DB FF DB DB DB FF DC DC DC FF DC DC DC FF DC DC'
- 'DC FF DD DD DD FF DD DD DD FF DD DD DD FF DE DE'
- 'DE FF E0 E0 E0 FF AE AE AE FF D1 D1 D1 FF A4 A4'
- 'A4 FF 32 32 32 FF 00 00 00 FD 00 00 00 7A 00 00'
- '00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1C 1C 1C FF C4 C4'
- 'C4 FF ED ED ED FF DB DB DB FF DD DD DD FF DD DD'
- 'DD FF DE DE DE FF DE DE DE FF DE DE DE FF DF DF'
- 'DF FF DF DF DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E2 E2 E2 FF AE AE AE FF D9 D9 D9 FF E9 E9'
- 'E9 FF A3 A3 A3 FF 2E 2E 2E FF 00 00 00 FD 00 00'
- '00 7A 00 00 00 02 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1D 1D 1D FF C6 C6'
- 'C6 FF EF EF EF FF DD DD DD FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E1 E1 E1 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2'
- 'E2 FF E4 E4 E4 FF B0 B0 B0 FF DA DA DA FF F1 F1'
- 'F1 FF EC EC EC FF A3 A3 A3 FF 2B 2B 2B FF 00 00'
- '00 FD 00 00 00 79 00 00 00 01 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1D 1D 1D FF C6 C6'
- 'C6 FF EF EF EF FF DE DE DE FF E0 E0 E0 FF E0 E0'
- 'E0 FF E1 E1 E1 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E5 E5 E5 FF B1 B1 B1 FF DE DE DE FF F2 F2'
- 'F2 FF F4 F4 F4 FF F1 F1 F1 FF A4 A4 A4 FF 2B 2B'
- '2B FF 00 00 00 FC 00 00 00 72 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1D 1D 1D FF C7 C7'
- 'C7 FF F1 F1 F1 FF E0 E0 E0 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E7 E7 E7 FF B3 B3 B3 FF E1 E1 E1 FF F6 F6'
- 'F6 FF F4 F4 F4 FF F9 F9 F9 FF F6 F6 F6 FF A6 A6'
- 'A6 FF 2D 2D 2D FF 00 00 00 F9 00 00 00 6F 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1E 1E 1E FF C7 C7'
- 'C7 FF F1 F1 F1 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E8 E8 E8 FF B5 B5 B5 FF E8 E8 E8 FF FE FE'
- 'FE FF FC FC FC FF FD FD FD FF FF FF FF FF FC FC'
- 'FC FF AD AD AD FF 31 31 31 FF 00 00 00 F9 00 00'
- '00 6F 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1E 1E 1E FF C8 C8'
- 'C8 FF F3 F3 F3 FF E3 E3 E3 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8'
- 'E8 FF EA EA EA FF B2 B2 B2 FF D8 D8 D8 FF EC EC'
- 'EC FF EA EA EA FF EB EB EB FF EB EB EB FF EF EF'
- 'EF FF EA EA EA FF 98 98 98 FF 2C 2C 2C FF 00 00'
- '00 F5 00 00 00 42 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1E 1E 1E FF C8 C8'
- 'C8 FF F3 F3 F3 FF E5 E5 E5 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9 E9 FF E9 E9'
- 'E9 FF EC EC EC FF C9 C9 C9 FF B3 B3 B3 FF B6 B6'
- 'B6 FF B5 B5 B5 FF B5 B5 B5 FF B5 B5 B5 FF B4 B4'
- 'B4 FF B6 B6 B6 FF BA BA BA FF 80 80 80 FF 03 03'
- '03 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1F 1F 1F FF C9 C9'
- 'C9 FF F5 F5 F5 FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF E9 E9 E9 FF E9 E9 E9 FF E9 E9'
- 'E9 FF EA EA EA FF EA EA EA FF EA EA EA FF EB EB'
- 'EB FF EB EB EB FF EE EE EE FF EE EE EE FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF EF EF EF FF EF EF'
- 'EF FF F0 F0 F0 FF F7 F7 F7 FF 93 93 93 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1F 1F 1F FF CA CA'
- 'CA FF F7 F7 F7 FF EA EA EA FF EC EC EC FF EA EA'
- 'EA FF E9 E9 E9 FF EA EA EA FF EA EA EA FF EB EB'
- 'EB FF EB EB EB FF EC EC EC FF EC EC EC FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF EE EE EE FF EF EF EF FF EF EF EF FF EF EF'
- 'EF FF F1 F1 F1 FF F6 F6 F6 FF 93 93 93 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 1F 1F 1F FF CA CA'
- 'CA FF F8 F8 F8 FF EC EC EC FF EE EE EE FF EF EF'
- 'EF FF EE EE EE FF EB EB EB FF EB EB EB FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF ED ED ED FF EE EE'
- 'EE FF EE EE EE FF EF EF EF FF EF EF EF FF EF EF'
- 'EF FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F1 F1'
- 'F1 FF F2 F2 F2 FF F7 F7 F7 FF 93 93 93 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 20 20 20 FF CB CB'
- 'CB FF F9 F9 F9 FF EE EE EE FF F0 F0 F0 FF F1 F1'
- 'F1 FF F2 F2 F2 FF F1 F1 F1 FF EE EE EE FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF EE EE EE FF EF EF'
- 'EF FF EF EF EF FF EF EF EF FF F0 F0 F0 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F3 F3 F3 FF F8 F8 F8 FF 94 94 94 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 20 20 20 FF CC CC'
- 'CC FF FB FB FB FF F0 F0 F0 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F3 F3 F3 FF F4 F4'
- 'F4 FF F5 F5 F5 FF F9 F9 F9 FF 94 94 94 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 20 20 20 FF CD CD'
- 'CD FF FB FB FB FF F2 F2 F2 FF F3 F3 F3 FF F4 F4'
- 'F4 FF F5 F5 F5 FF F6 F6 F6 FF F7 F7 F7 FF F8 F8'
- 'F8 FF F9 F9 F9 FF F9 F9 F9 FF FA FA FA FF FB FB'
- 'FB FF FB FB FB FF FB FB FB FF FA FA FA FF F8 F8'
- 'F8 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F5 F5'
- 'F5 FF F6 F6 F6 FF FA FA FA FF 95 95 95 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 21 21 21 FF CE CE'
- 'CE FF FD FD FD FF F4 F4 F4 FF F4 F4 F4 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F7 F7 F7 FF F8 F8 F8 FF F8 F8'
- 'F8 FF FA FA FA FF FA FA FA FF FB FB FB FF FB FB'
- 'FB FF FC FC FC FF FD FD FD FF FD FD FD FF FE FE'
- 'FE FF FE FE FE FF FC FC FC FF F9 F9 F9 FF F6 F6'
- 'F6 FF F7 F7 F7 FF FB FB FB FF 96 96 96 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 21 21 21 FF CE CE'
- 'CE FF FE FE FE FF F5 F5 F5 FF F6 F6 F6 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
- 'FA FF FB FB FB FF FB FB FB FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FF FF FF FF FF FF FF FF FD FD'
- 'FD FF FB FB FB FF FC FC FC FF 97 97 97 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 21 21 21 FF CF CF'
- 'CF FF FF FF FF FF F7 F7 F7 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F9 F9 F9 FF FA FA FA FF FA FA FA FF FB FB'
- 'FB FF FB FB FB FF FC FC FC FF FC FC FC FF FD FD'
- 'FD FF FD FD FD FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 98 98 98 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 22 22 22 FF CF CF'
- 'CF FF FF FF FF FF F8 F8 F8 FF F9 F9 F9 FF FA FA'
- 'FA FF FA FA FA FF FA FA FA FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FD FD FD FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 99 99 99 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 22 22 22 FF D0 D0'
- 'D0 FF FF FF FF FF F9 F9 F9 FF FA FA FA FF FB FB'
- 'FB FF FB FB FB FF FB FB FB FF FC FC FC FF FD FD'
- 'FD FF FD FD FD FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 99 99 99 FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 23 23 23 FF D1 D1'
- 'D1 FF FF FF FF FF FA FA FA FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9A 9A 9A FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 23 23 23 FF D1 D1'
- 'D1 FF FF FF FF FF FC FC FC FF FC FC FC FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9B 9B 9B FF 02 02'
- '02 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 23 23 23 FF D2 D2'
- 'D2 FF FF FF FF FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FE FE FE FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9C 9C 9C FF 03 03'
- '03 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 23 23 23 FF D3 D3'
- 'D3 FF FF FF FF FF FE FE FE FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9D 9D 9D FF 03 03'
- '03 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 23 23 23 FF D3 D3'
- 'D3 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9D 9D 9D FF 03 03'
- '03 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 24 24 24 FF D4 D4'
- 'D4 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 9E 9E 9E FF 03 03'
- '03 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 84 27 27 27 FF D8 D8'
- 'D8 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
- 'FE FF FE FE FE FF FE FE FE FF FE FE FE FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FC FC FC FF FC FC FC FF FC FC'
- 'FC FF FD FD FD FF FF FF FF FF A3 A3 A3 FF 04 04'
- '04 FF 00 00 00 61 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 7F 18 18 18 FF 77 77'
- '77 FF 7D 7D 7D FF 7B 7B 7B FF 7A 7A 7A FF 79 79'
- '79 FF 79 79 79 FF 78 78 78 FF 78 78 78 FF 77 77'
- '77 FF 76 76 76 FF 75 75 75 FF 75 75 75 FF 74 74'
- '74 FF 73 73 73 FF 72 72 72 FF 71 71 71 FF 70 70'
- '70 FF 70 70 70 FF 6F 6F 6F FF 6E 6E 6E FF 6E 6E'
- '6E FF 6D 6D 6D FF 6E 6E 6E FF 59 59 59 FF 03 03'
- '03 FF 00 00 00 59 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2A 00 00 00 D3 00 00'
- '00 F5 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F6 00 00'
- '00 B6 00 00 00 14 00 00 00 00 00 00 00 00 E0 00'
- '07 FF C0 00 03 FF C0 00 01 FF C0 00 00 FF C0 00'
- '00 7F C0 00 00 3F C0 00 00 1F C0 00 00 1F C0 00'
- '00 0F C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 01 01 63 05 05'
- '05 AF 04 04 04 A8 04 04 04 A8 04 04 04 A8 04 04'
- '04 A8 03 03 03 A8 03 03 03 AA 02 02 02 A0 00 00'
- '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 13 13 13 CB A8 A8'
- 'A8 FF BC BC BC FF B7 B7 B7 FF B7 B7 B7 FF B6 B6'
- 'B6 FF B7 B7 B7 FF B6 B6 B6 FF 7A 7A 7A FF 0F 0F'
- '0F D5 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 17 17 17 CC D1 D1'
- 'D1 FF EA EA EA FF E5 E5 E5 FF E6 E6 E6 FF E7 E7'
- 'E7 FF E9 E9 E9 FF E3 E3 E3 FF D0 D0 D0 FF 95 95'
- '95 FF 0B 0B 0B D5 00 00 00 28 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 17 17 17 CC CD CD'
- 'CD FF E4 E4 E4 FF DF DF DF FF E0 E0 E0 FF E1 E1'
- 'E1 FF E2 E2 E2 FF DA DA DA FF CE CE CE FF F9 F9'
- 'F9 FF 95 95 95 FF 0A 0A 0A D4 00 00 00 25 00 00'
- '00 00 00 00 00 00 00 00 00 00 17 17 17 CC D0 D0'
- 'D0 FF E7 E7 E7 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E6 E6 E6 FF DD DD DD FF D2 D2 D2 FF FF FF'
- 'FF FF FF FF FF FF 9E 9E 9E FF 0D 0D 0D D1 00 00'
- '00 24 00 00 00 00 00 00 00 00 17 17 17 CC D1 D1'
- 'D1 FF EB EB EB FF E5 E5 E5 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E9 E9 E9 FF E4 E4 E4 FF CB CB CB FF D7 D7'
- 'D7 FF D9 D9 D9 FF DF DF DF FF 7C 7C 7C FF 00 00'
- '00 9D 00 00 00 00 00 00 00 00 17 17 17 CC D4 D4'
- 'D4 FF F0 F0 F0 FF E9 E9 E9 FF E9 E9 E9 FF EA EA'
- 'EA FF EB EB EB FF EC EC EC FF E8 E8 E8 FF E4 E4'
- 'E4 FF E5 E5 E5 FF EF EF EF FF BC BC BC FF 03 03'
- '03 A8 00 00 00 00 00 00 00 00 17 17 17 CC D6 D6'
- 'D6 FF F4 F4 F4 FF EF EF EF FF EE EE EE FF ED ED'
- 'ED FF ED ED ED FF EE EE EE FF F0 F0 F0 FF F1 F1'
- 'F1 FF F1 F1 F1 FF FC FC FC FF BD BD BD FF 02 02'
- '02 A8 00 00 00 00 00 00 00 00 18 18 18 CC D8 D8'
- 'D8 FF F8 F8 F8 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
- 'F5 FF F4 F4 F4 FF FE FE FE FF BE BE BE FF 03 03'
- '03 A8 00 00 00 00 00 00 00 00 18 18 18 CC DB DB'
- 'DB FF FB FB FB FF F6 F6 F6 FF F8 F8 F8 FF FA FA'
- 'FA FF FB FB FB FF FC FC FC FF FD FD FD FF FE FE'
- 'FE FF FD FD FD FF FF FF FF FF C0 C0 C0 FF 02 02'
- '02 A8 00 00 00 00 00 00 00 00 18 18 18 CC DC DC'
- 'DC FF FE FE FE FF F9 F9 F9 FF FB FB FB FF FC FC'
- 'FC FF FC FC FC FF FD FD FD FF FE FE FE FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF C3 C3 C3 FF 02 02'
- '02 A8 00 00 00 00 00 00 00 00 18 18 18 CC DE DE'
- 'DE FF FF FF FF FF FC FC FC FF FC FC FC FF FD FD'
- 'FD FF FE FE FE FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF C4 C4 C4 FF 03 03'
- '03 A8 00 00 00 00 00 00 00 00 18 18 18 CC DF DF'
- 'DF FF FF FF FF FF FD FD FD FF FE FE FE FF FE FE'
- 'FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF C5 C5 C5 FF 03 03'
- '03 A8 00 00 00 00 00 00 00 00 19 19 19 CC E2 E2'
- 'E2 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF C7 C7 C7 FF 03 03'
- '03 A8 00 00 00 00 00 00 00 00 19 19 19 CC E2 E2'
- 'E2 FF FF FF FF FF FD FD FD FF FD FD FD FF FD FD'
- 'FD FF FD FD FD FF FD FD FD FF FC FC FC FF FC FC'
- 'FC FF FB FB FB FF FF FF FF FF C6 C6 C6 FF 04 04'
- '04 A8 00 00 00 00 00 00 00 00 09 09 09 A0 41 41'
- '41 F9 46 46 46 F0 44 44 44 F0 44 44 44 F0 43 43'
- '43 F0 42 42 42 F0 42 42 42 F0 41 41 41 F0 3F 3F'
- '3F F0 3F 3F 3F F0 40 40 40 F0 36 36 36 FB 02 02'
- '02 82 00 00 00 00 80 1F 00 00 80 0F 00 00 80 07'
- '00 00 80 03 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00'
-} */
-
-
-/* BINRES folder.ico */
-3 ICON folder.ico
-/* {
- '00 00 01 00 08 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 86 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 2E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 96 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 7E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 A6 12 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 4E 21 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 F6 46 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 9E 57 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 11 00 00 00 00 11 00 00 00 00 11 00 22 00'
- '00 00 33 00 00 00 33 33 00 00 33 33 33 00 44 00'
- '00 00 66 33 00 00 66 33 33 00 66 66 33 00 7F 7F'
- '7F 00 99 33 00 00 99 33 33 00 99 66 33 00 99 66'
- '66 00 CC 66 66 00 FF 99 33 00 FF CC 33 00 99 99'
- '66 00 CC 99 66 00 FF 99 66 00 CC CC 66 00 FF CC'
- '66 00 BB BB BB 00 CC 99 99 00 FF 99 99 00 CC CC'
- '99 00 FF CC 99 00 FF FF 99 00 CC 99 CC 00 CC CC'
- 'CC 00 DD DD DD 00 FF CC CC 00 FF FF CC 00 FF CC'
- 'FF 00 EE EE EE 00 FF FF FF 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 56 00 58 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 56 00'
- '00 00 00 00 00 00 03 00 00 00 5E 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 66 6F 6C 64 65 72 2E 69 63'
- '6F 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 27 27 27 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 27 02 03 27 27'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 27 03 04 0D 06 27'
- '27 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 27 27 27 09 11 22 1A 06'
- '27 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 27 27 27 0F 1B 22 26 26 1A'
- '05 27 27 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 27 02 08 15 1B 1C 26 26 26 26'
- '1A 04 27 27 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 27 27 27 08 1A 1D 1A 26 26 26 26 26'
- '25 15 04 27 27 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 27 27 27 0A 1D 1D 1A 1D 1D 26 26 26 26'
- '26 25 10 04 27 27 00 00 00 00 00 00 00 00 00 00'
- '00 00 27 01 01 10 23 1D 15 23 16 12 18 26 26 26'
- '26 26 25 10 01 27 27 00 00 00 00 00 00 00 00 00'
- '27 27 02 06 1B 23 1D 1A 22 12 12 16 12 1D 26 26'
- '26 25 25 25 10 01 27 27 00 00 00 00 00 00 00 27'
- '27 27 0E 22 23 1D 1A 22 18 12 16 12 16 12 18 25'
- '26 24 25 23 25 10 01 27 27 00 00 00 00 00 27 01'
- '04 15 23 22 22 1C 1D 1B 12 16 12 12 18 16 16 1D'
- '23 25 25 21 25 22 10 01 27 27 00 00 00 00 03 06'
- '1D 25 25 23 1C 1B 1D 13 16 12 18 16 12 16 18 16'
- '1D 25 25 25 22 21 21 0F 01 27 27 00 00 00 27 09'
- '22 23 22 22 17 1D 16 12 16 16 12 16 16 18 16 18'
- '1B 1D 25 21 21 21 20 22 09 02 27 27 00 00 27 27'
- '06 22 23 15 1D 16 12 16 16 13 16 18 12 16 18 1B'
- '18 1D 1D 21 21 20 22 20 22 0A 27 27 27 00 00 27'
- '27 09 16 1D 16 13 16 16 12 16 12 16 16 18 16 18'
- '1D 1D 1E 22 20 22 19 20 19 22 0F 27 27 27 00 00'
- '27 27 09 16 12 16 16 12 18 16 16 12 18 16 18 1D'
- '1D 1D 22 22 23 20 22 19 22 19 1C 0E 27 27 00 00'
- '00 27 27 09 16 16 16 18 16 12 18 16 16 1D 1D 1D'
- '22 1E 22 23 22 23 20 19 19 22 1F 14 01 27 00 00'
- '00 00 27 27 09 12 18 16 12 16 16 1D 1D 1D 1D 23'
- '1D 22 23 22 23 23 25 22 19 19 14 02 27 27 00 00'
- '00 00 00 27 27 09 16 18 16 18 1D 1D 1D 1D 22 1D'
- '23 22 23 23 23 24 23 25 20 1A 04 27 27 00 00 00'
- '00 00 00 00 27 27 09 16 18 1D 22 1D 1D 22 1D 23'
- '22 23 22 23 24 23 26 26 1D 07 27 27 00 00 00 00'
- '00 00 00 00 00 27 27 09 1D 22 1D 22 1D 22 23 22'
- '23 22 26 23 25 23 25 22 0A 27 27 00 00 00 00 00'
- '00 00 00 00 00 00 27 27 10 1D 22 1E 22 23 22 23'
- '22 23 23 24 23 26 25 0B 27 27 00 00 00 00 00 00'
- '00 00 00 00 00 00 27 27 15 23 22 22 23 22 23 24'
- '23 25 25 23 26 26 0F 27 27 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 27 27 05 1C 23 22 22 23 24 23'
- '25 25 23 26 26 10 27 27 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 27 27 04 17 22 23 23 25 25'
- '23 25 26 26 15 27 27 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 27 27 04 1D 26 26 25 23'
- '26 26 25 22 04 27 27 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 27 27 06 22 25 26 26'
- '25 26 22 06 27 27 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 27 27 04 1C 26 26'
- '26 23 07 27 27 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 27 27 01 1A 26'
- '23 0A 27 27 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 27 27 27 06'
- '04 27 27 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 27'
- '27 27 00 00 00 00 00 00 00 00 00 00 00 00 FF FC'
- '7F FF FF F8 3F FF FF F0 1F FF FF C0 0F FF FF 80'
- '07 FF FF 00 03 FF FC 00 01 FF F8 00 00 FF F0 00'
- '00 7F C0 00 00 3F 80 00 00 1F 00 00 00 0F 00 00'
- '00 07 00 00 00 03 00 00 00 01 80 00 00 00 C0 00'
- '00 00 E0 00 00 00 F0 00 00 00 F8 00 00 01 FC 00'
- '00 03 FE 00 00 07 FF 00 00 0F FF 00 00 1F FF 00'
- '00 3F FF 80 00 7F FF C0 00 7F FF E0 00 FF FF F0'
- '01 FF FF F8 03 FF FF FC 07 FF FF FF 0F FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 11 00 00 00 00 11'
- '00 00 00 00 11 00 11 11 11 00 22 00 00 00 33 00'
- '00 00 33 33 00 00 33 00 33 00 22 22 22 00 33 33'
- '33 00 66 33 00 00 66 33 33 00 66 66 33 00 44 44'
- '44 00 66 66 66 00 77 77 77 00 7F 7F 7F 00 99 66'
- '66 00 FF 99 33 00 99 99 66 00 CC 99 66 00 FF 99'
- '66 00 FF CC 66 00 CC 99 99 00 CC CC 99 00 FF CC'
- '99 00 FF FF 99 00 CC 99 CC 00 CC CC CC 00 DD DD'
- 'DD 00 FF CC CC 00 FF FF CC 00 EE EE EE 00 FF FF'
- 'FF 00 00 00 00 00 FF CC FF 00 EE EE EE 00 FF FF'
- 'FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
- '95 00 00 00 38 00 A8 44 F9 77 13 00 00 00 18 0A'
- '38 00 00 00 38 00 18 6C 38 00 98 17 95 00 00 00'
- '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
- 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 86 00'
- '00 00 86 00 00 00 08 00 00 00 B0 18 95 00 00 00'
- '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
- '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 56 00'
- '58 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
- '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
- '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
- 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
- '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 56 00 00 00 00 00 00 00 03 00'
- '00 00 5E 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 66'
- '6F 6C 64 65 72 2E 69 63 6F 00 1A 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 13 00 00 00 98 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 18 6C 38 00 86 00 00 00 00 00'
- '00 00 C9 F1 E7 77 86 00 00 00 A4 1A 95 00 08 00'
- '00 00 00 00 00 00 86 00 00 00 86 00 00 00 08 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 18 6C 38 00 86 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 01 23 23 00'
- '00 00 00 00 00 00 00 00 00 00 00 02 03 12 0C 23'
- '00 00 00 00 00 00 00 00 00 00 02 08 15 22 20 0A'
- '03 00 00 00 00 00 00 00 23 23 0C 1A 1F 22 22 1F'
- '07 03 00 00 00 00 00 01 01 10 1A 1A 13 1A 22 22'
- '1D 07 23 00 00 00 23 09 1A 1F 1A 13 16 13 1A 21'
- '22 1C 06 02 00 00 05 1F 20 1A 16 16 13 17 16 1A'
- '1E 21 19 05 23 00 23 0D 1A 16 13 17 16 16 17 1A'
- '1A 1E 1D 18 04 01 00 23 0B 17 16 16 13 16 1A 1A'
- '20 1F 1D 1F 14 23 00 00 23 0B 17 16 1A 1A 1F 20'
- '1F 21 20 1C 0A 23 00 00 00 23 0C 17 1F 1B 1F 1F'
- '20 20 21 0D 23 00 00 00 00 00 23 18 20 1F 20 1F'
- '22 22 0F 23 00 00 00 00 00 00 23 0E 1A 21 20 22'
- '22 14 23 00 00 00 00 00 00 00 00 23 0C 20 22 22'
- '18 02 23 00 00 00 00 00 00 00 00 00 23 0E 1F 1D'
- '02 23 00 00 00 00 00 00 00 00 00 00 00 23 02 01'
- '23 00 00 00 00 00 FC 7F 00 00 F8 3F 00 00 F0 1F'
- '00 00 C0 0F 00 00 80 07 00 00 00 03 00 00 00 01'
- '00 00 00 00 00 00 80 00 00 00 C0 00 00 00 E0 01'
- '00 00 F0 03 00 00 F0 07 00 00 F8 07 00 00 FC 0F'
- '00 00 FE 1F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 08 10 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 08 BF 81 00 00 00 00 00 00 00 00 00'
- '00 00 00 04 1B 7F F8 00 00 00 00 00 00 00 00 00'
- '00 00 00 9B 77 FF FF 89 00 00 00 00 00 00 00 00'
- '00 00 00 78 7F FF FF F8 20 00 00 00 00 00 00 00'
- '00 00 1F B7 78 FF FF F7 10 00 00 00 00 00 00 00'
- '00 81 77 8F B7 BF FF FF F8 20 00 00 00 00 00 00'
- '08 BF FB FB 8B 8B FF FF F7 18 00 00 00 00 00 00'
- '17 7F B7 88 B1 B7 BF FF 7F F8 00 00 00 00 00 0B'
- 'FF F8 77 BB 7B 7B 78 FF F7 F7 B0 00 00 00 09 7F'
- '7F B7 7B 88 B7 B8 BF BF 7F 77 7B 00 00 00 08 7F'
- '7F 87 B8 B7 B8 B8 7B FB F7 F7 F7 90 00 00 00 97'
- 'FB 7B 7B 7B 7B 8F B7 BF BF 7F 77 78 00 00 00 08'
- 'B7 B8 B7 B8 B8 BB 7B 7B F7 77 77 7F 90 00 00 00'
- '1B 7B 8B 7B 87 B7 BF BF 7F F7 77 FB F1 00 00 00'
- '08 B8 B7 B7 BB 7B 77 F7 FB FF 77 77 78 00 00 00'
- '00 8B 7B 7B B7 77 7F BF BF FF 77 77 80 00 00 00'
- '00 08 B8 B7 7B FB F7 F7 F7 FF FF B7 00 00 00 00'
- '00 00 1B FB 77 7F BF 7F BF FF FF 78 00 00 00 00'
- '00 00 08 BF 7F BF 7F F7 FF BF FF 80 00 00 00 00'
- '00 00 00 87 FB F7 FF BF FF FF F8 00 00 00 00 00'
- '00 00 00 BF 77 FF BF FF 7F FF 80 00 00 00 00 00'
- '00 00 00 07 F7 F7 FF F7 FF F8 00 00 00 00 00 00'
- '00 00 00 00 BF 7F 7F FF FF B0 00 00 00 00 00 00'
- '00 00 00 00 8B FF FF FF F7 00 00 00 00 00 00 00'
- '00 00 00 00 08 7F FF FF 78 00 00 00 00 00 00 00'
- '00 00 00 00 00 07 FF F7 80 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 8F F8 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FC'
- '7F FF FF F8 3F FF FF F0 1F FF FF C0 0F FF FF 80'
- '07 FF FF 00 03 FF FC 00 01 FF F8 00 00 FF F0 00'
- '00 7F C0 00 00 3F 80 00 00 1F 00 00 00 0F 00 00'
- '00 07 00 00 00 03 00 00 00 01 80 00 00 00 C0 00'
- '00 00 E0 00 00 00 F0 00 00 00 F8 00 00 01 FC 00'
- '00 03 FE 00 00 07 FF 00 00 0F FF 00 00 1F FF 00'
- '00 3F FF 80 00 7F FF C0 00 7F FF E0 00 FF FF F0'
- '01 FF FF F8 03 FF FF FC 07 FF FF FF 0F FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- '00 01 80 00 00 00 00 00 01 8F 78 00 00 00 00 00'
- '1B FF F7 10 00 00 00 4B 8F B7 FF 70 00 00 08 BF'
- '7B 8B FF F7 90 00 07 F7 7B 87 B7 F7 70 00 08 7B'
- 'B7 BB 7B 7F 77 00 00 8B 7B B7 BF F7 77 B0 00 08'
- 'B7 B7 FB FF F7 00 00 00 17 7F BF 7F F8 00 00 00'
- '0B F7 FF FF 80 00 00 00 08 7F 7F F8 00 00 00 00'
- '00 8F FF 70 00 00 00 00 00 08 F7 00 00 00 00 00'
- '00 00 00 00 00 00 FC 7F 00 00 F8 3F 00 00 F0 1F'
- '00 00 C0 0F 00 00 80 07 00 00 00 03 00 00 00 01'
- '00 00 00 00 00 00 80 00 00 00 C0 00 00 00 E0 01'
- '00 00 F0 03 00 00 F0 07 00 00 F8 07 00 00 FC 0F'
- '00 00 FE 1F 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 11 00 00 00 00 11 00 00 00 00 11 00 22 00'
- '00 00 33 00 00 00 00 22 00 00 33 33 00 00 22 22'
- '22 00 44 00 00 00 55 00 00 00 66 00 00 00 66 33'
- '00 00 66 33 33 00 66 66 33 00 7F 7F 7F 00 99 33'
- '00 00 99 33 33 00 99 66 00 00 99 66 33 00 CC 66'
- '00 00 CC 66 33 00 99 66 66 00 CC 66 66 00 CC 99'
- '33 00 FF 99 33 00 FF CC 33 00 99 99 66 00 CC 99'
- '66 00 FF 99 66 00 CC CC 66 00 FF CC 66 00 BB BB'
- 'BB 00 CC 99 99 00 FF 99 99 00 CC CC 99 00 FF CC'
- '99 00 FF FF 99 00 CC 99 CC 00 CC CC CC 00 DD DD'
- 'DD 00 FF CC CC 00 CC FF CC 00 FF FF CC 00 FF CC'
- 'FF 00 EE EE EE 00 FF FF FF 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -1838,276 +835,751 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 56 00 58 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 56 00'
- '00 00 00 00 00 00 03 00 00 00 5E 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 66 6F 6C 64 65 72 2E 69 63'
- '6F 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 2F 2F 2F 2F 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 2F 2F 2F 2F 2F 2F 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 2F 2F 2F 01 2F 2F 2F 2F 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '2F 2F 2F 2F 09 10 0C 02 2F 2F 2F 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2F'
- '2F 2F 04 11 15 1C 17 09 02 2F 2F 2F 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 2F 2F'
- '2F 05 13 1C 23 2E 2D 1C 0B 2F 2F 2F 2F 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 2F 2F 2F 2F'
- '0B 23 22 21 2E 2E 2E 28 1C 0A 2F 2F 2F 2F 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 2F 2F 2F 01 0C'
- '23 22 18 2E 2E 2E 2E 2E 28 1C 05 2F 2F 2F 2F 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2F 2F 2F 2F 04 13 29'
- '24 17 2D 2E 2E 2E 2E 2E 2E 28 17 05 02 2F 2F 2F'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 2F 2F 2F 01 05 1C 2D 24'
- '15 2D 2E 2E 2E 2E 2E 2E 2E 2E 27 1C 04 01 2F 2F'
- '2F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 2F 2F 2F 01 0C 24 29 1F 17'
- '2D 24 24 2E 2E 2E 2E 2E 2E 2E 2E 28 17 06 2F 2F'
- '2F 2F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2F 2F 2F 2F 05 16 29 29 24 17 29'
- '29 19 1D 24 2E 2E 2E 2E 2E 2E 2E 2D 28 17 09 2F'
- '2F 2F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 2F 2F 2F 2F 0C 21 2B 24 24 1D 27 2B'
- '19 19 19 1D 29 2E 2E 2E 2E 2E 2D 2E 2E 28 1B 05'
- '2F 2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 2F 2F 2F 03 10 29 2B 24 29 1D 20 2B 19'
- '19 1D 19 19 19 29 2E 2E 2E 2E 2E 2D 2D 2D 29 17'
- '04 2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 2F 2F 2F 2F 05 13 29 2B 24 29 1C 1C 2E 1D 19'
- '19 19 1D 19 1D 19 2D 2E 2E 2E 2D 2E 2D 2D 2D 27'
- '13 04 2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00'
- '2F 2F 2F 2F 0A 21 2B 2B 24 29 24 21 2E 1D 19 1D'
- '19 1D 19 1D 19 1F 19 29 2E 2D 2E 2D 29 2D 28 2D'
- '28 15 2F 2F 2F 2F 00 00 00 00 00 00 00 00 00 2F'
- '2F 2F 04 13 24 28 29 2B 29 24 1C 2B 24 19 1D 19'
- '1D 19 1D 1A 1D 1D 1F 1D 2B 2C 2E 2D 2D 2D 2D 28'
- '29 27 15 04 2F 2F 2F 00 00 00 00 00 00 00 2F 2F'
- '2F 05 13 29 2E 2B 2B 29 24 1C 2D 24 19 1D 1A 1D'
- '19 1D 19 1D 19 1D 1D 1F 1D 25 28 2D 2D 2D 29 28'
- '28 28 29 13 01 2F 2F 2F 00 00 00 00 00 00 2F 2F'
- '0C 22 2E 2B 29 29 2D 2B 1C 29 1F 1D 1D 19 1D 19'
- '1D 1A 1D 19 1D 1F 1D 1D 1F 22 2B 2D 2D 28 28 28'
- '28 27 28 27 15 2F 2F 2F 2F 00 00 00 00 00 2F 2F'
- '0C 2B 29 2B 29 2B 2B 17 24 24 1D 1D 19 1D 1D 1A'
- '1D 1D 19 1D 1F 1D 1D 1F 22 1F 1F 29 28 2D 29 28'
- '28 28 27 29 20 15 04 2F 2F 2F 2F 00 00 00 2F 2F'
- '2F 10 2B 2D 2B 2D 1D 23 24 1D 19 1D 1F 19 1D 1D'
- '1A 1D 1D 19 1D 1F 1F 1D 1F 24 22 1F 29 28 2D 28'
- '29 28 29 27 29 20 10 2F 2F 2F 2F 00 00 00 2F 2F'
- '2F 2F 10 24 2E 1D 1C 24 19 1D 1F 19 1D 1F 19 1D'
- '1D 1D 19 1D 1F 1D 1D 1F 22 1F 1F 24 24 29 2A 29'
- '28 27 27 27 27 20 29 13 2F 2F 2F 2F 00 00 00 00'
- '2F 2F 2F 11 24 1C 24 1D 1D 19 1D 1D 19 1D 1D 1A'
- '1D 19 1F 1D 19 1F 1D 24 1F 22 24 24 24 24 29 28'
- '27 29 27 29 20 27 28 24 11 02 2F 2F 2F 2F 00 00'
- '00 2F 2F 01 12 1D 1F 1D 1A 1D 19 1D 1F 19 1F 1D'
- '19 1D 1D 1A 1D 1D 1D 1F 1D 24 24 24 25 29 2B 29'
- '28 27 27 27 27 27 21 27 28 10 2F 2F 2F 2F 00 00'
- '00 00 2F 2F 04 14 1D 1D 1D 1D 1F 1D 19 1D 19 1D'
- '1F 1D 19 1D 1F 1D 1F 24 24 24 25 29 29 25 29 2B'
- '29 28 29 20 29 23 27 26 23 29 13 01 2F 2F 00 00'
- '00 00 2F 2F 2F 08 10 19 1D 1F 19 1F 1D 1D 1D 1F'
- '1D 19 1D 1D 1D 24 24 24 24 24 29 2B 24 29 2B 2B'
- '29 2B 20 20 27 27 26 23 26 27 1C 02 2F 2F 00 00'
- '00 00 00 2F 2F 2F 01 14 1D 1D 1D 19 1D 1F 1D 19'
- '1D 1F 1D 1F 24 24 24 24 2B 24 24 29 2B 29 29 2B'
- '2B 29 2E 27 23 26 23 20 20 21 05 2F 2F 2F 00 00'
- '00 00 00 00 2F 2F 2F 03 12 19 1D 1D 1F 19 1F 1D'
- '1F 1D 24 24 24 24 29 24 24 29 29 2B 29 2B 2B 29'
- '2B 2E 2B 29 27 23 26 27 21 07 2F 2F 2F 00 00 00'
- '00 00 00 00 00 00 2F 2F 2F 12 1D 1F 1D 1D 1D 1D'
- '24 24 24 24 24 24 24 2B 29 24 2B 29 2B 29 2B 2B'
- '2C 2B 2D 2E 28 26 23 21 0D 2F 2F 2F 00 00 00 00'
- '00 00 00 00 00 00 2F 2F 2F 03 10 18 1D 1D 1F 24'
- '24 29 24 24 2B 24 29 29 24 2B 29 2B 29 2B 2B 2C'
- '2B 2D 2D 2E 2B 2B 27 0D 2F 2F 2F 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 2F 2F 2F 10 1D 1F 24 29'
- '24 24 29 24 24 29 25 29 2B 29 2B 29 2E 29 2B 2D'
- '2B 2E 2B 29 2E 2B 13 2F 2F 2F 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2F 2F 2F 0C 24 29 24'
- '25 29 24 2B 29 25 29 29 2B 29 2B 2B 29 2B 2D 2B'
- '2E 29 2B 2E 2E 13 2F 2F 2F 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 2F 2F 2F 0D 1F 29'
- '29 24 29 24 29 29 2B 29 29 2B 29 2D 2B 2D 2D 2B'
- '2D 2B 2E 2E 13 01 2F 2F 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 2F 2F 0C 1E 24'
- '29 2B 29 2B 29 2B 29 2B 2B 2C 2B 2B 2D 2D 2B 2C'
- '2B 2E 2E 1C 01 2F 2F 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 2F 2F 15 2D 29'
- '1E 29 2B 29 2B 29 2B 29 2D 2B 2C 2B 2D 2B 2C 2B'
- '2E 2D 22 02 01 2F 2F 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 2F 2F 07 22 2B'
- '29 24 29 2B 29 2B 2C 2B 2B 2D 2B 2C 2B 2D 2B 2E'
- '2E 29 07 2F 2F 2F 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 2F 2F 2F 07 1C'
- '2E 23 24 2C 2B 2D 2B 2C 2B 2D 2D 2B 2D 2D 2E 2E'
- '24 07 2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 2F 2F 2F 04'
- '1B 1D 29 2B 2D 2B 2C 2B 2E 2D 2B 2E 2D 2E 2E 29'
- '0C 2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2F 2F 2F'
- '01 18 2B 2D 2B 2C 2B 2E 2C 2B 2E 2D 2E 2E 29 0E'
- '2F 2F 2F 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2F'
- '2F 04 1C 2E 2E 2B 2E 2D 2B 2E 2D 2E 2E 2B 13 2F'
- '2F 2F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2F'
- '2F 2F 04 1C 2D 2E 2D 2E 2E 2E 2E 2E 2E 1B 01 2F'
- '2F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '2F 2F 2F 2F 1C 2D 2E 2E 2E 2E 2E 2E 1C 01 2F 2F'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 2F 2F 2F 2F 13 2B 2E 2E 2E 2E 1E 01 2F 2F 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 2F 2F 2F 0E 29 2E 2D 23 05 2F 2F 2F 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 2F 2F 2F 07 13 07 04 2F 2F 2F 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2F 2F 2F 2F 2F 2F 2F 2F 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 2F 2F 2F 2F 2F 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FC 3F FF FF 00 00 FF FF'
- 'F8 1F FF FF 00 00 FF FF F0 0F FF FF 00 00 FF FF'
- 'C0 07 FF FF 00 00 FF FF 80 03 FF FF 00 00 FF FF'
- '00 01 FF FF 00 00 FF FC 00 00 FF FF 00 00 FF F8'
- '00 00 7F FF 00 00 FF E0 00 00 3F FF 00 00 FF C0'
- '00 00 1F FF 00 00 FF 80 00 00 0F FF 00 00 FE 00'
- '00 00 0F FF 00 00 FC 00 00 00 03 FF 00 00 F8 00'
- '00 00 03 FF 00 00 E0 00 00 00 01 FF 00 00 C0 00'
- '00 00 00 FF 00 00 80 00 00 00 00 7F 00 00 00 00'
- '00 00 00 3F 00 00 00 00 00 00 00 1F 00 00 00 00'
- '00 00 00 07 00 00 00 00 00 00 00 07 00 00 00 00'
- '00 00 00 03 00 00 C0 00 00 00 00 00 00 00 E0 00'
- '00 00 00 00 00 00 F0 00 00 00 00 00 00 00 F0 00'
- '00 00 00 00 00 00 F8 00 00 00 00 00 00 00 FC 00'
- '00 00 00 01 00 00 FF 00 00 00 00 03 00 00 FF 00'
- '00 00 00 07 00 00 FF C0 00 00 00 0F 00 00 FF E0'
- '00 00 00 1F 00 00 FF F0 00 00 00 3F 00 00 FF F8'
- '00 00 00 7F 00 00 FF F8 00 00 00 7F 00 00 FF F8'
- '00 00 00 FF 00 00 FF F8 00 00 01 FF 00 00 FF FC'
- '00 00 03 FF 00 00 FF FE 00 00 07 FF 00 00 FF FF'
- '80 00 0F FF 00 00 FF FF 80 00 1F FF 00 00 FF FF'
- 'C0 00 3F FF 00 00 FF FF E0 00 7F FF 00 00 FF FF'
- 'F8 00 7F FF 00 00 FF FF FC 00 FF FF 00 00 FF FF'
- 'FE 01 FF FF 00 00 FF FF FF 07 FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 20 00 00 00'
- '00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 39 28'
+ '23 23 23 23 23 23 23 23 23 22 22 22 22 22 21 21'
+ '21 20 20 20 20 1F 1F 1F 1F 1E 1E 1E 1D 25 33 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 50'
+ '50 50 4F 4F 4E 4E 4D 4D 4C 4B 4B 4A 49 48 47 46'
+ '45 43 42 41 40 3F 3E 3D 3B 3A 39 38 37 36 24 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 51'
+ '50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 4A 4A 49 48 47'
+ '45 44 43 42 41 40 3F 3D 3C 3B 3A 39 38 37 1D 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 51'
+ '51 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 4A 49 48 47'
+ '46 45 44 43 42 41 40 3E 3D 3C 3B 3A 39 38 1D 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 51'
+ '51 51 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 4A 49 48'
+ '47 46 45 44 43 42 41 40 3E 3D 3C 3B 3A 39 1D 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 52'
+ '51 51 51 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 4A 49'
+ '48 47 46 45 44 43 42 41 40 3E 3D 3C 3B 3A 1E 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 52'
+ '52 51 51 51 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 4A'
+ '49 48 47 46 45 44 43 42 41 40 3E 3D 3C 3B 1E 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 53'
+ '52 52 51 51 51 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B'
+ '4A 49 48 47 46 45 44 43 42 41 40 3E 3D 3C 1E 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 53'
+ '53 52 52 51 51 51 50 50 4F 4F 4E 4E 4D 4D 4C 4C'
+ '4B 4A 49 48 47 46 45 44 43 42 41 40 3F 3E 1E 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 54'
+ '53 53 52 52 51 51 51 50 50 4F 4F 4E 4E 4D 4D 4C'
+ '4C 4B 4A 49 48 47 46 45 44 43 42 41 40 3F 1F 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 54'
+ '54 53 53 52 52 51 51 51 50 50 4F 4F 4E 4E 4D 4D'
+ '4C 4C 4B 4A 49 48 47 46 45 44 43 42 41 40 1F 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 55'
+ '54 54 53 53 52 52 51 51 50 50 50 4F 4F 4E 4E 4D'
+ '4D 4C 4B 4B 4A 49 48 47 46 45 44 43 42 41 1F 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 55'
+ '55 54 54 53 53 52 52 51 51 50 50 50 4F 4F 4E 4E'
+ '4D 4D 4C 4B 4B 4A 49 48 47 46 45 44 43 42 20 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 56'
+ '55 55 54 54 53 53 52 52 51 51 50 50 50 4F 4F 4E'
+ '4E 4D 4D 4C 4B 4B 4A 49 48 47 46 45 44 43 20 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 56'
+ '56 55 55 54 54 53 53 52 52 51 51 50 50 50 4F 4F'
+ '4E 4E 4D 4D 4C 4B 4B 4A 49 48 47 46 45 44 20 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 57'
+ '56 56 55 55 54 54 53 53 52 52 51 51 50 50 50 4F'
+ '4F 4E 4E 4D 4D 4C 4B 4B 4A 49 48 47 46 46 20 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 57'
+ '57 56 56 55 55 54 54 53 53 52 52 51 51 50 50 50'
+ '4F 4F 4E 4E 4D 4D 4C 4B 4B 4A 49 48 47 47 21 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 58'
+ '57 57 56 56 55 55 54 54 53 53 52 52 51 51 50 50'
+ '50 4F 4F 4E 4E 4D 4D 4C 4B 4B 4A 49 49 48 21 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 58'
+ '58 57 57 56 56 55 55 54 54 53 53 52 52 51 51 50'
+ '50 50 4F 4F 4E 4E 4D 4D 4C 4B 4B 4A 49 49 21 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 59'
+ '59 58 57 57 56 56 55 55 54 54 53 53 52 52 51 51'
+ '50 50 50 4F 4F 4E 4E 4D 4D 4C 4B 4B 4A 4A 21 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 5A'
+ '59 59 58 57 57 56 56 55 55 54 54 53 53 52 52 51'
+ '51 50 50 50 4F 4F 4E 4E 4D 4D 4C 4B 4B 4B 21 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 5A'
+ '5A 59 59 58 57 57 56 56 55 55 54 54 53 53 52 52'
+ '51 51 50 50 50 4F 4F 4E 4E 4D 4D 4C 4C 4B 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 5B'
+ '5A 5A 59 59 58 57 57 56 56 55 55 54 54 53 53 52'
+ '52 51 51 50 50 50 4F 4F 4E 4E 4D 4D 4C 4C 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 5B'
+ '5B 5A 5A 59 59 58 57 57 56 56 55 55 54 54 53 53'
+ '52 52 51 51 50 50 50 4F 4F 4E 4E 4D 4D 4C 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 5C'
+ '5B 5B 5A 5A 59 59 58 57 57 56 56 55 55 54 54 53'
+ '53 52 52 51 51 50 50 50 4F 4F 4E 4E 4D 4D 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 5C'
+ '5C 5B 5B 5A 5A 59 59 58 57 57 56 56 55 55 54 54'
+ '53 53 52 52 51 51 50 50 50 4F 4F 4E 4E 4D 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 5D'
+ '5C 5C 5B 5B 5A 5A 59 59 58 57 57 56 56 55 55 54'
+ '54 53 53 52 52 51 51 50 50 50 4F 4F 4E 4E 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 5E'
+ '5D 5C 5C 5B 5B 5A 5A 59 59 58 57 57 56 56 55 55'
+ '54 54 53 53 52 52 51 51 50 50 50 4F 4F 4F 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 5E'
+ '5E 5D 5C 5C 5B 5B 5A 5A 59 59 58 57 57 56 56 55'
+ '55 54 54 53 53 52 52 51 51 50 50 50 4F 4F 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4A 5F'
+ '5E 5E 5D 5C 5C 5B 5B 5A 5A 59 59 58 57 57 56 56'
+ '55 55 54 54 53 53 52 52 51 51 50 50 4F 4D 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4A 60'
+ '5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59 59 58 57 57 56'
+ '56 55 55 54 54 53 53 52 52 51 51 50 4D 43 1E 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 61'
+ '60 5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59 59 58 57 57'
+ '56 56 55 55 54 54 53 53 52 52 51 51 47 33 1B 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 61'
+ '61 60 5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59 58 58 57'
+ '57 56 56 55 55 54 54 53 53 52 52 51 38 27 1A 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '61 61 60 5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59 58 58'
+ '57 57 56 56 55 55 54 54 53 53 52 4C 29 1B 1C 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 61 61 60 5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59 58'
+ '58 57 57 56 56 55 55 54 54 53 50 36 11 20 22 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 61 61 60 5F 5F 5E 5D 5C 5C 5B 5B 5A 5A 59'
+ '58 58 57 57 56 56 55 55 54 4E 35 12 13 18 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 61 61 60 5F 5E 5E 5D 5C 5C 5B 5B 5A 5A'
+ '59 58 58 57 57 56 55 50 3E 25 0D 10 1D 20 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 61 61 60 5F 5E 5E 5D 5C 5C 5B 5B 5A'
+ '5A 59 58 58 55 49 34 1C 0C 0B 1F 26 18 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 61 61 60 5F 5E 5E 5D 5C 5C 5B 5B'
+ '5A 5A 59 58 43 12 0A 0F 2A 37 07 15 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 62 61 61 60 5F 5E 5E 5D 5C 5C 5B'
+ '5B 5A 5A 59 3A 18 56 4B 3C 30 1B 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 62 62 61 61 60 5F 5E 5E 5D 5C 5C'
+ '5B 5B 5A 59 49 11 50 41 33 24 1A 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 62 62 62 61 61 60 5F 5E 5E 5D 5C'
+ '5C 5B 5B 5A 53 16 31 36 2B 16 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 62 62 62 62 61 61 60 5F 5E 5E 5D'
+ '5C 5C 5B 5B 57 27 1A 2E 18 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4B 62'
+ '62 62 62 62 62 62 62 62 62 62 61 61 60 5F 5E 5E'
+ '5D 5C 5C 5A 50 22 17 21 1E 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4C 62'
+ '62 62 62 62 62 62 62 62 62 62 62 61 61 60 5F 5E'
+ '5D 5C 59 4D 32 14 22 19 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 4E 4D'
+ '4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 4A 49'
+ '47 47 43 39 2F 2C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 00'
+ '00 00 03 FF 00 00 FF 00 00 00 07 FF 00 00 FF 00'
+ '00 00 07 FF 00 00 FF 00 00 00 0F FF 00 00 FF 00'
+ '00 00 1F FF 00 00 FF 00 00 00 1F FF 00 00 FF 00'
+ '00 00 3F FF 00 00 FF 00 00 00 FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 80 25 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 10 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E 0E 12 0E 0E'
+ '0E 12 0E 0E 0E 12 0E 0E 0E 12 00 00 00 10 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 7D 7D'
+ '7D 51 76 76 76 83 6F 6F 6F 8B 6F 6F 6F 8B 6F 6F'
+ '6F 8B 6F 6F 6F 8B 6F 6F 6F 8B 6F 6F 6F 8B 6F 6F'
+ '6F 8B 6F 6F 6F 8B 6F 6F 6F 8B 6E 6E 6E 8B 6E 6E'
+ '6E 8B 6E 6E 6E 8B 6E 6E 6E 8B 6E 6E 6E 8B 6C 6C'
+ '6C 8B 6C 6C 6C 8B 6C 6C 6C 8B 6A 6A 6A 8B 6A 6A'
+ '6A 8B 6A 6A 6A 8B 6A 6A 6A 8B 68 68 68 8B 68 68'
+ '68 8B 68 68 68 8B 68 68 68 8B 66 66 66 8B 66 66'
+ '66 8B 66 66 66 8B 64 64 64 8B 6B 6B 6B 83 38 38'
+ '38 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D4 D4'
+ 'D4 BF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E0 E0 E0 FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF DA DA DA FF D8 D8 D8 FF D7 D7 D7 FF D6 D6'
+ 'D6 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF 67 67'
+ '67 82 00 00 00 10 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 D2'
+ 'D2 C1 EE EE EE FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF DC DC'
+ 'DC FF DA DA DA FF D9 D9 D9 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D6 D6 D6 FF D5 D5 D5 FF D4 D4 D4 FF 63 63'
+ '63 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 D2'
+ 'D2 C1 EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF DF DF DF FF DE DE DE FF DD DD'
+ 'DD FF DB DB DB FF DA DA DA FF D9 D9 D9 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF 63 63'
+ '63 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D3 D3'
+ 'D3 C1 EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF DE DE'
+ 'DE FF DD DD DD FF DB DB DB FF DA DA DA FF D9 D9'
+ 'D9 FF D8 D8 D8 FF D7 D7 D7 FF D6 D6 D6 FF 63 63'
+ '63 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D3 D3'
+ 'D3 C1 EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DB DB DB FF DA DA'
+ 'DA FF D9 D9 D9 FF D8 D8 D8 FF D7 D7 D7 FF 65 65'
+ '65 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D3 D3'
+ 'D3 C1 EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF DB DB'
+ 'DB FF DA DA DA FF D9 D9 D9 FF D8 D8 D8 FF 65 65'
+ '65 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D4 D4'
+ 'D4 C1 F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF DF DF DF FF DE DE DE FF DD DD'
+ 'DD FF DB DB DB FF DA DA DA FF D9 D9 D9 FF 65 65'
+ '65 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D4 D4'
+ 'D4 C1 F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF DE DE'
+ 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF 65 65'
+ '65 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D4 D4'
+ 'D4 C1 F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DC DC DC FF 67 67'
+ '67 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 D6'
+ 'D6 C1 F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF 67 67'
+ '67 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 D6'
+ 'D6 C1 F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF DF DF DF FF DE DE DE FF 67 67'
+ '67 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 D6'
+ 'D6 C1 F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF 69 69'
+ '69 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D7 D7'
+ 'D7 C1 F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF 69 69'
+ '69 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D7 D7'
+ 'D7 C1 F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF 69 69'
+ '69 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D7 D7'
+ 'D7 C1 F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3 E3 FF 69 69'
+ '69 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 D8'
+ 'D8 C1 F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF 6B 6B'
+ '6B 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 D8'
+ 'D8 C1 F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E6 E6 E6 FF E5 E5 E5 FF 6B 6B'
+ '6B 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 D8'
+ 'D8 C1 F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E6 E6 E6 FF E6 E6 E6 FF 6B 6B'
+ '6B 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DA DA'
+ 'DA C1 F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF 6B 6B'
+ '6B 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DA DA'
+ 'DA C1 F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E8 E8 E8 FF 6B 6B'
+ '6B 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DB DB'
+ 'DB C1 F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DB DB'
+ 'DB C1 F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DB DB'
+ 'DB C1 F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DC DC'
+ 'DC C1 F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DC DC'
+ 'DC C1 F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DC DC'
+ 'DC C1 FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DD DD'
+ 'DD C1 FB FB FB FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DD DD'
+ 'DD C1 FB FB FB FF FB FB FB FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ 'DF C1 FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EA EA EA FF 6D 6D'
+ '6D 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ 'DF C1 FD FD FD FF FC FC FC FF FC FC FC FF FB FB'
+ 'FB FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EA EA EA FF E0 E0 E0 FF 65 65'
+ '65 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FE FE FE FF FD FD FD FF FC FC FC FF FC FC'
+ 'FC FF FB FB FB FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF E4 E4 E4 FF CE CE CE FF 60 60'
+ '60 8A 0E 0E 0E 12 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0E 00 00 00 32 00 00 00 2D 00 00 00 0B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FE FE FE FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FC FC FC FF FB FB FB FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF D5 D5 D5 FF B6 B6 B6 FF 5D 5D'
+ '5D 89 0F 0F 0F 11 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FC FC FC FF FC FC FC FF FB FB FB FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF E9 E9 E9 FF BA BA BA FF A9 A9 A9 FE 5D 5D'
+ '5D 86 00 00 00 10 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FD FD FD FF FC FC FC FF FC FC FC FF FB FB'
+ 'FB FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF ED ED'
+ 'ED FF D3 D3 D3 FF 99 99 99 FF AD AD AD FB 52 52'
+ '52 75 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FE FE FE FF FD FD FD FF FC FC FC FF FC FC'
+ 'FC FF FB FB FB FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF EB EB EB FF D0 D0'
+ 'D0 FF 9B 9B 9B FF 9D 9D 9D FE 9A 9A 9A E2 40 40'
+ '40 4B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF ED ED ED FF DB DB DB FF B3 B3 B3 FF 7E 7E'
+ '7E FF 96 96 96 FE A7 A7 A7 F2 6C 6C 6C 8D 0A 0A'
+ '0A 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F2 F2 F2 FF E6 E6 E6 FF CF CF'
+ 'CF FF AA AA AA FF 78 78 78 FF 6F 6F 6F FF AD AD'
+ 'AD FE B4 B4 B4 FA 82 82 82 B8 21 21 21 2E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF E0 E0 E0 FF 9B 9B 9B FF 6C 6C'
+ '6C FF 8A 8A 8A FF BC BC BC FF D4 D4 D4 FF C0 C0'
+ 'C0 FD 92 92 92 D9 43 43 43 4F 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FE FE FE FF FD FD FD FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF D7 D7 D7 FF A5 A5 A5 FF F3 F3'
+ 'F3 FF E8 E8 E8 FF D9 D9 D9 FF C8 C8 C8 FE A2 A2'
+ 'A2 EC 60 60 60 79 0D 0D 0D 13 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF E6 E6 E6 FF 99 99 99 FF ED ED'
+ 'ED FF DE DE DE FF CE CE CE FE B0 B0 B0 F7 79 79'
+ '79 A6 15 15 15 23 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 31 00 00'
- '00 B1 00 00 00 F6 00 00 00 DF 00 00 00 65 00 00'
- '00 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F0 F0 F0 FF A3 A3 A3 FF CA CA'
+ 'CA FF D3 D3 D3 FF BC BC BC FC 8C 8C 8C CC 35 35'
+ '35 3E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F4 F4 F4 FF B6 B6 B6 FF A8 A8'
+ 'A8 FF C5 C5 C5 FE 9B 9B 9B E5 55 55 55 65 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 E0'
+ 'E0 C1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FE FE FE FF FD FD FD FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F7 F7 F7 FF ED ED ED FF B0 B0 B0 FF A4 A4'
+ 'A4 FE AB AB AB F3 6F 6F 6F 93 12 12 12 1B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 58 00 00 00 F2 00 00'
- '00 FF 12 04 00 FF 02 00 00 FF 00 00 00 F6 00 00'
- '00 71 00 00 00 08 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E2 E2'
+ 'E2 BF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FA FA FA FF F9 F9 F9 FF F6 F6'
+ 'F6 FF EA EA EA FF CC CC CC FF A1 A1 A1 FE AE AE'
+ 'AE F9 86 86 86 BA 24 24 24 31 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 D8'
+ 'D8 86 E3 E3 E3 C1 E0 E0 E0 C3 E0 E0 E0 C3 E0 E0'
+ 'E0 C3 E0 E0 E0 C3 E0 E0 E0 C3 E0 E0 E0 C3 E0 E0'
+ 'E0 C3 E0 E0 E0 C3 E0 E0 E0 C3 E0 E0 E0 C3 E0 E0'
+ 'E0 C3 E0 E0 E0 C3 E0 E0 E0 C3 DF DF DF C3 DF DF'
+ 'DF C3 DE DE DE C3 DC DC DC C2 DB DB DB C2 D6 D6'
+ 'D6 C3 CA CA CA C3 B4 B4 B4 C3 AB AB AB C1 96 96'
+ '96 A3 51 51 51 42 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 12 00 00 00 9D 00 00 00 F6 00 00 00 FF 59 17'
- '00 FF 97 2E 01 FF 6E 20 00 FF 06 00 00 FF 00 00'
- '00 F0 00 00 00 65 00 00 00 08 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -2116,23 +1588,239 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3A 00 00'
- '00 C2 00 00 00 FF 17 03 00 FF 7A 37 1A FF BE 59'
- '2D FF CF 9C 89 FF BF 81 6D FF 5A 1E 08 FF 06 00'
- '00 FF 00 00 00 EE 00 00 00 5C 00 00 00 08 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 80'
+ '00 00 00 FF 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 3F 00 00 FF 00'
+ '00 00 00 3F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 00 00 00 03 FF 00 00 FF 00'
+ '00 00 07 FF 00 00 FF 00 00 00 0F FF 00 00 FF 00'
+ '00 00 0F FF 00 00 FF 00 00 00 1F FF 00 00 FF 00'
+ '00 00 3F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 04 00 00 00'
+ '00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 08 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 00 00 00 00 00 00 00 00 00 00 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ '88 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ '88 80 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 88'
+ '88 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF F8 F8'
+ '78 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 87'
+ '88 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 88 87'
+ '80 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF 8F F8 78'
+ '80 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF F8 87 87'
+ '80 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF 8F 88 77 88'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F8 F8 F8 77 78 78'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 8F 88 77 77 88 80'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F7 77 77 88 87 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 87 88 F8 F8 88 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F7 FF 88 87 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 87 F8 F8 88 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F7 8F 88 70 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 87 88 88 80 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F7 88 87 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 88 78 70 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 87 88 80 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 8F FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 88 87 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 08 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF E0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 01 FF FF C0 00 00 00 00 01 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 07 FF FF C0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 0F FF FF C0 00 00 00 00 0F FF FF C0'
+ '00 00 00 00 1F FF FF C0 00 00 00 00 3F FF FF C0'
+ '00 00 00 00 3F FF FF C0 00 00 00 00 7F FF FF C0'
+ '00 00 00 00 FF FF FF C0 00 00 00 01 FF FF FF C0'
+ '00 00 00 01 FF FF FF C0 00 00 00 03 FF FF FF C0'
+ '00 00 00 07 FF FF FF C0 00 00 00 07 FF FF FF C0'
+ '00 00 00 0F FF FF FF E0 00 00 00 3F FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 40 00 00 00 80 00'
+ '00 00 01 00 08 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 5B 5B 5B 00 5D 5D 5D 00 65 65'
+ '65 00 6B 6B 6B 00 72 72 72 00 FF 00 FF 00 82 82'
+ '82 00 83 83 83 00 85 85 85 00 88 88 88 00 8B 8B'
+ '8B 00 90 90 90 00 91 91 91 00 92 92 92 00 93 93'
+ '93 00 96 96 96 00 97 97 97 00 9A 9A 9A 00 9D 9D'
+ '9D 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2 A2 00 A3 A3'
+ 'A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6 A6 00 A7 A7'
+ 'A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA AA 00 AB AB'
+ 'AB 00 AC AC AC 00 AD AD AD 00 AE AE AE 00 AF AF'
+ 'AF 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3'
+ 'B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7'
+ 'B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BB BB'
+ 'BB 00 BC BC BC 00 BD BD BD 00 BE BE BE 00 BF BF'
+ 'BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2 C2 00 C3 C3'
+ 'C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6 C6 00 C7 C7'
+ 'C7 00 C8 C8 C8 00 C9 C9 C9 00 CB CB CB 00 CC CC'
+ 'CC 00 CD CD CD 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
+ 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
+ 'DA 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
+ 'DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
+ 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
+ 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
+ 'EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2'
+ 'F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
+ 'F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9 F9 00 FA FA'
+ 'FA 00 FB FB FB 00 FC FC FC 00 FD FD FD 00 FE FE'
+ 'FE 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 70 00 00 00 F3 00 00'
- '00 FF 32 07 00 FF B1 63 41 FF D5 8F 70 FF E3 BF'
- 'AF FF FF FF FF FF EA E7 EA FF C0 82 6C FF 64 1B'
- '01 FF 00 00 00 FF 00 00 00 EE 00 00 00 5E 00 00'
- '00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 20 00 00 00 AC 00 00 00 FD 06 00 00 FF 61 1B'
- '00 FF D5 9F 86 FF E2 A3 84 FF DB AE 9A FF FD FB'
- 'FA FF FF FF FF FF FF FF FF FF E9 E3 E4 FF BD 87'
- '77 FF 5A 1A 01 FF 02 00 00 FF 00 00 00 E6 00 00'
- '00 52 00 00 00 08 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2A 00 00'
- '00 C4 00 00 00 FF 08 00 00 FF 73 29 0F FF EE BD'
- 'A5 FF EB AE 8B FF CA 7F 5C FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF E6 DF'
- 'E1 FF BE 7A 63 FF 3D 0E 00 FF 00 00 00 FF 00 00'
- '00 E2 00 00 00 3D 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 01 00 00 00 6C 00 00 00 E3 00 00'
- '00 FF 2F 01 00 FF A7 66 50 FF F5 D0 B8 FF F3 B6'
- '8D FF CF 89 67 FF F5 EB E8 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FD FD'
- 'FE FF E4 DA DC FF B6 78 61 FF 44 11 00 FF 00 00'
- '00 FF 00 00 00 CB 00 00 00 3C 00 00 00 01 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1C 00 00 00 8D 00 00 00 FF 07 00 00 FF 4D 1A'
- '07 FF C9 81 63 FF FF E3 CD FF F7 BC 91 FF C7 71'
- '47 FF F1 E5 E0 FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF E5 D8 DA FF B3 77 61 FF 33 0E'
- '00 FF 00 00 00 FF 00 00 00 C8 00 00 00 33 00 00'
- '00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00'
- '00 D3 00 00 00 FF 0B 00 00 FF 85 36 19 FF E9 B7'
- '9F FF FF E6 CB FF F9 B8 88 FF CE 7B 50 FF F2 EE'
- 'EF FF FF C8 98 FF FF D7 B6 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FD FE FF FF E5 DA DB FF BE 7D'
- '65 FF 30 0B 00 FF 00 00 00 FF 00 00 00 D2 00 00'
- '00 33 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 3F 3F 3B 3B 3B 3B 3B'
+ '3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B'
+ '3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B 3B'
+ '3B 3F 3F 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 50 46 43 43 43 43 43'
+ '42 42 42 41 41 41 41 40 40 40 40 40 3E 3E 07 07'
+ '3C 3B 3B 3B 3B 39 39 38 37 37 36 36 36 34 34 33'
+ '33 34 35 3E 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 68 67 67 67 67 66 66'
+ '65 65 65 64 64 63 63 62 62 61 61 60 5F 5E 5E 5D'
+ '5C 5B 5A 59 58 58 57 56 55 54 53 52 51 50 4F 4F'
+ '4E 4D 36 3E 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 68 68 67 67 67 66 66'
+ '66 65 65 64 64 64 63 63 62 62 61 60 60 5F 5E 5D'
+ '5C 5C 5B 5A 59 58 57 56 55 55 54 53 52 51 50 4F'
+ '4E 4E 35 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 68 68 68 67 67 67 66'
+ '66 66 65 65 64 64 63 63 63 62 61 61 60 60 5F 5E'
+ '5D 5C 5B 5B 5A 59 58 57 56 55 54 53 52 52 51 50'
+ '4F 4F 35 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 68 68 68 68 67 67 67'
+ '66 66 65 65 65 64 64 63 63 63 62 61 61 60 5F 5F'
+ '5E 5D 5C 5B 5A 5A 59 58 57 56 55 54 53 52 52 51'
+ '50 4F 35 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 69 68 68 68 67 67 67'
+ '67 66 66 65 65 65 64 64 63 63 62 62 61 61 60 5F'
+ '5F 5E 5D 5C 5B 5A 5A 59 58 57 56 55 54 53 52 52'
+ '51 50 36 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 69 69 68 68 68 67 67'
+ '67 67 66 66 65 65 65 64 64 63 63 62 62 61 61 60'
+ '5F 5F 5E 5D 5C 5B 5A 5A 59 58 57 56 55 54 53 52'
+ '52 51 37 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 69 69 69 68 68 68 67'
+ '67 67 67 66 66 65 65 65 64 64 63 63 62 62 61 61'
+ '60 5F 5F 5E 5D 5C 5B 5A 5A 59 58 57 56 55 54 53'
+ '53 52 37 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6A 69 69 69 68 68 68'
+ '67 67 67 67 66 66 65 65 65 64 64 63 63 62 62 61'
+ '61 60 5F 5F 5E 5D 5C 5B 5A 59 59 58 57 56 55 54'
+ '53 53 38 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6A 6A 69 69 69 68 68'
+ '68 67 67 67 67 66 66 65 65 65 64 64 63 63 62 62'
+ '61 61 60 5F 5F 5E 5D 5C 5B 5A 59 59 58 57 56 55'
+ '54 54 38 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6B 6A 6A 69 69 69 68'
+ '68 68 67 67 67 67 66 66 65 65 65 64 64 63 63 62'
+ '62 61 61 60 5F 5F 5E 5D 5C 5B 5A 59 59 58 57 56'
+ '55 55 3A 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6B 6B 6A 6A 69 69 69'
+ '68 68 68 67 67 67 67 66 66 65 65 65 64 64 63 63'
+ '62 62 61 61 60 5F 5F 5E 5D 5C 5B 5A 59 59 58 57'
+ '56 56 3A 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6B 6B 6B 6A 6A 69 69'
+ '69 68 68 68 67 67 67 66 66 66 65 65 65 64 64 63'
+ '63 62 62 61 61 60 5F 5F 5E 5D 5C 5B 5A 59 59 58'
+ '57 56 3A 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4A 6C 6B 6B 6B 6A 6A 69'
+ '69 69 68 68 68 67 67 67 66 66 66 65 65 65 64 64'
+ '63 63 62 62 61 61 60 5F 5F 5E 5D 5C 5B 5A 59 59'
+ '58 57 3B 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6C 6C 6B 6B 6B 6A 6A'
+ '69 69 69 68 68 68 67 67 67 66 66 66 65 65 65 64'
+ '64 63 63 62 62 61 61 60 5F 5E 5E 5D 5C 5B 5A 59'
+ '59 58 3B 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6C 6C 6C 6B 6B 6B 6A'
+ '6A 69 69 69 68 68 68 67 67 67 66 66 66 65 65 65'
+ '64 64 63 63 62 62 61 61 60 5F 5E 5E 5D 5C 5B 5A'
+ '5A 59 3C 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6D 6C 6C 6C 6B 6B 6B'
+ '6A 6A 69 69 69 68 68 68 67 67 67 66 66 66 65 65'
+ '65 64 64 63 63 62 62 61 61 60 5F 5E 5E 5D 5C 5B'
+ '5A 5A 07 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6D 6D 6D 6C 6C 6B 6B'
+ '6B 6A 6A 69 69 69 68 68 68 67 67 67 66 66 66 65'
+ '65 65 64 64 63 63 62 62 61 61 60 5F 5E 5E 5D 5C'
+ '5B 5B 07 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6E 6D 6D 6D 6C 6C 6B'
+ '6B 6B 6A 6A 69 69 69 68 68 68 67 67 67 66 66 66'
+ '65 65 65 64 64 63 63 62 62 61 61 60 5F 5E 5E 5D'
+ '5C 5B 3F 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6E 6E 6D 6D 6D 6C 6C'
+ '6B 6B 6B 6A 6A 69 69 69 68 68 68 67 67 67 66 66'
+ '66 65 65 65 64 64 63 63 62 62 61 61 60 5F 5E 5E'
+ '5D 5C 3F 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6E 6E 6E 6D 6D 6D 6C'
+ '6C 6B 6B 6B 6A 6A 69 69 69 68 68 68 67 67 67 66'
+ '66 66 65 65 64 64 64 63 63 62 62 61 61 60 5F 5E'
+ '5E 5D 40 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6F 6E 6E 6E 6D 6D 6D'
+ '6C 6C 6B 6B 6B 6A 6A 69 69 69 68 68 68 67 67 67'
+ '66 66 66 65 65 64 64 64 63 63 62 62 61 61 60 5F'
+ '5F 5E 40 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 6F 6F 6F 6E 6E 6D 6D'
+ '6D 6C 6C 6B 6B 6B 6A 6A 69 69 69 68 68 68 67 67'
+ '67 66 66 66 65 65 64 64 64 63 63 62 62 61 61 60'
+ '5F 5F 40 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4B 70 6F 6F 6F 6E 6E 6D'
+ '6D 6D 6C 6C 6B 6B 6B 6A 6A 69 69 69 68 68 68 67'
+ '67 67 66 66 66 65 65 64 64 64 63 63 62 62 61 61'
+ '60 60 41 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 70 70 6F 6F 6F 6E 6E'
+ '6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69 69 69 68 68 68'
+ '67 67 67 66 66 66 65 65 64 64 64 63 63 62 62 61'
+ '61 60 41 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 70 70 70 6F 6F 6F 6E'
+ '6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69 69 69 68 68'
+ '68 67 67 67 66 66 66 65 65 64 64 64 63 63 62 62'
+ '61 61 41 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 71 71 70 70 6F 6F 6F'
+ '6E 6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69 69 69 68'
+ '68 68 67 67 67 66 66 66 65 65 64 64 64 63 63 62'
+ '62 62 42 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 71 71 71 70 70 6F 6F'
+ '6F 6E 6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69 69 69'
+ '68 68 68 67 67 67 66 66 66 65 65 64 64 64 63 63'
+ '62 62 42 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 72 71 71 71 70 70 6F'
+ '6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69 69'
+ '69 68 68 68 67 67 67 66 66 66 65 65 64 64 64 63'
+ '63 63 43 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 72 72 71 71 71 70 70'
+ '6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A 69'
+ '69 69 68 68 68 67 67 67 66 66 66 65 65 64 64 64'
+ '63 63 43 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 72 72 72 71 71 71 70'
+ '70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6B 6A 6A'
+ '69 69 69 68 68 68 67 67 67 66 66 66 65 65 64 64'
+ '64 63 43 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 73 73 72 72 71 71 71'
+ '70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6A 6A'
+ '6A 69 69 69 68 68 68 67 67 67 66 66 66 65 65 64'
+ '64 64 43 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 73 73 73 72 72 71 71'
+ '71 70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6A'
+ '6A 6A 69 69 69 68 68 68 67 67 67 66 66 66 65 65'
+ '64 64 45 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4C 74 73 73 73 72 72 71'
+ '71 71 70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B'
+ '6A 6A 6A 69 69 69 68 68 68 67 67 67 66 66 66 65'
+ '65 65 45 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 74 74 73 73 73 72 72'
+ '71 71 71 70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C 6B'
+ '6B 6A 6A 6A 69 69 69 68 68 68 67 67 67 66 66 66'
+ '65 65 45 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 75 74 74 73 73 73 72'
+ '72 71 71 70 70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C 6C'
+ '6B 6B 6A 6A 6A 69 69 69 68 68 68 67 67 67 66 66'
+ '66 65 46 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 75 75 74 74 73 73 73'
+ '72 72 71 71 71 70 70 6F 6F 6E 6E 6E 6D 6D 6C 6C'
+ '6C 6B 6B 6A 6A 6A 69 69 69 68 68 68 67 67 67 66'
+ '66 66 46 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 76 75 75 74 74 73 73'
+ '73 72 72 71 71 70 70 70 6F 6F 6E 6E 6E 6D 6D 6C'
+ '6C 6C 6B 6B 6A 6A 6A 69 69 69 68 68 68 67 67 67'
+ '66 66 46 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 76 76 75 75 74 74 73'
+ '73 73 72 72 71 71 70 70 70 6F 6F 6E 6E 6E 6D 6D'
+ '6C 6C 6C 6B 6B 6A 6A 6A 69 69 69 68 68 68 67 67'
+ '66 65 45 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 77 76 76 75 75 74 74'
+ '73 73 73 72 72 71 71 70 70 70 6F 6F 6E 6E 6E 6D'
+ '6D 6C 6C 6C 6B 6B 6A 6A 6A 69 69 69 68 68 68 67'
+ '65 5F 40 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4D 77 77 77 76 75 75 74'
+ '74 73 73 73 72 72 71 71 70 70 70 6F 6F 6E 6E 6E'
+ '6D 6D 6C 6C 6C 6B 6B 6A 6A 6A 69 69 68 68 68 67'
+ '62 55 37 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 78 78 77 77 76 75 75'
+ '74 74 73 73 73 72 72 71 71 70 70 70 6F 6F 6E 6E'
+ '6E 6D 6D 6C 6C 6C 6B 6B 6A 6A 6A 69 69 68 68 67'
+ '5B 48 2F 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 79 78 78 77 77 76 75'
+ '75 74 74 73 73 72 72 72 71 71 70 70 70 6F 6F 6E'
+ '6E 6E 6D 6D 6C 6C 6C 6B 6B 6A 6A 6A 69 69 68 66'
+ '4E 33 29 39 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 79 79 79 78 77 77 76'
+ '75 75 74 74 73 73 72 72 72 71 71 70 70 70 6F 6F'
+ '6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6A 6A 6A 69 68 62'
+ '3E 1E 29 3B 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 79 79 79 79 78 77 77'
+ '76 75 75 74 74 73 73 72 72 72 71 71 70 70 70 6F'
+ '6F 6E 6E 6E 6D 6D 6C 6C 6C 6B 6B 6A 6A 6A 68 53'
+ '24 1E 28 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 79 79 79 79 79 78 77'
+ '77 76 75 75 74 74 73 73 72 72 72 71 71 70 70 70'
+ '6F 6F 6E 6E 6D 6D 6D 6C 6C 6C 6B 6B 6A 69 5D 38'
+ '16 2C 22 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4E 79 79 79 79 79 79 78'
+ '77 77 76 75 75 74 74 73 73 72 72 72 71 71 70 70'
+ '70 6F 6F 6E 6E 6D 6D 6D 6C 6C 6C 6B 68 5B 3A 17'
+ '1C 27 26 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '78 77 77 76 75 75 74 74 73 73 72 72 72 71 71 70'
+ '70 70 6F 6F 6E 6E 6D 6D 6D 6C 6A 62 4D 29 11 15'
+ '2D 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '79 78 77 77 76 75 75 74 74 73 73 72 72 72 71 71'
+ '70 70 70 6F 6F 6E 6E 6D 69 60 4E 31 13 0C 18 38'
+ '1E 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '79 79 78 77 77 76 75 75 74 74 73 73 72 72 72 71'
+ '71 70 70 70 6F 6E 67 57 44 25 10 0A 0E 34 3F 24'
+ '23 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '79 79 78 78 77 77 76 75 75 74 74 73 73 72 72 72'
+ '71 71 70 70 6F 68 47 1A 0D 0B 14 42 4F 46 2D 1F'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '79 79 79 78 78 77 77 76 75 75 74 74 73 73 72 72'
+ '72 71 71 70 70 63 27 18 42 67 5E 53 49 35 1E 32'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 4F 79 79 79 79 79 79 79'
+ '79 79 79 79 78 78 77 77 76 75 75 74 74 73 73 72'
+ '72 72 71 71 70 66 2D 3C 6D 62 56 4B 07 22 27 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 50 79 79 79 79 79 79 79'
+ '79 79 79 79 79 78 78 77 77 76 75 75 74 74 73 73'
+ '72 72 72 71 71 6D 45 19 66 5A 4F 45 2B 20 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 50 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 78 78 77 76 76 75 75 74 74 73'
+ '73 72 72 72 71 6F 54 12 55 52 49 32 1E 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 50 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 79 78 78 77 76 76 75 75 74 74'
+ '73 73 72 72 72 71 5E 19 32 4B 07 21 2A 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 50 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 79 79 78 78 77 76 76 75 75 74'
+ '74 73 73 72 72 71 60 1D 1E 43 28 20 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 50 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 79 79 79 78 78 77 76 76 75 75'
+ '74 74 73 72 71 6B 51 1B 21 31 1F 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 53 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 79 79 79 79 78 77 77 76 76 75'
+ '75 74 73 6F 67 55 34 19 2F 21 2E 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 53 79 79 79 79 79 79 79'
+ '79 79 79 79 79 79 79 79 79 79 78 78 77 77 76 75'
+ '75 74 72 6D 61 4D 39 38 30 2F 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 52 52 4F 4F 4F 4F 4F'
+ '4E 4E 4E 4E 4E 4E 4E 4D 4D 4D 4D 4D 4D 4C 4C 4C'
+ '4B 4B 4B 4A 48 45 45 45 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 04 00 00 00 72 00 00 00 EA 00 00'
- '00 FF 37 0B 00 FF B1 71 56 FF F7 D4 BE FF FF DF'
- 'C0 FF FD C3 95 FF D0 80 56 FF E9 D4 CC FF FF D4'
- 'AD FF FF 92 39 FF FF 98 44 FF FF D6 B4 FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FE FE FE FF FC FC FB FF F8 F6 F7 FF E4 D9'
- 'DA FF B5 80 6B FF 3A 12 02 FF 00 00 00 FF 00 00'
- '00 C8 00 00 00 39 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF E0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 07 FF FF C0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 07 FF FF C0 00 00 00 00 0F FF FF C0'
+ '00 00 00 00 0F FF FF C0 00 00 00 00 1F FF FF C0'
+ '00 00 00 00 3F FF FF C0 00 00 00 00 3F FF FF C0'
+ '00 00 00 00 7F FF FF C0 00 00 00 00 FF FF FF C0'
+ '00 00 00 01 FF FF FF C0 00 00 00 01 FF FF FF C0'
+ '00 00 00 03 FF FF FF C0 00 00 00 07 FF FF FF C0'
+ '00 00 00 07 FF FF FF C0 00 00 00 0F FF FF FF E0'
+ '00 00 00 3F FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 20 00 00 00'
+ '00 00 00 42 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1F 00 00 00 9F 00 00 00 FF 08 00 00 FF 5F 28'
- '11 FF D3 93 74 FF FF EF DE FF FF D9 B5 FF FC C5'
- '9B FF D5 83 56 FF E6 CE C4 FF FF EB D2 FF FF 93'
- '3A FF FF 94 3D FF FF 93 3B FF FF 95 3E FF FF DD'
- 'BF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FD FB FB FF FA F8 F8 FF F8 F6 F6 FF F5 F3'
- 'F4 FF E7 DA DA FF B6 82 6C FF 2A 0D 00 FF 00 00'
- '00 FF 00 00 00 BF 00 00 00 29 00 00 00 02 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3D 00 00'
- '00 E1 00 00 00 FF 12 00 00 FF 94 3F 15 FF F3 CF'
- 'BC FF FF EC D7 FF FF D1 AC FF FF D8 B4 FF DC 91'
- '64 FF E0 C0 B3 FF FF E9 D3 FF FF 99 44 FF FF 96'
- '40 FF FF 98 44 FF FF 98 43 FF FF 97 42 FF FF 9B'
- '46 FF FF D3 AE FF FF FF FF FF FF FF FF FF FE FD'
- 'FD FF FC FA FA FF F9 F6 F6 FF F6 F3 F3 FF F4 F0'
- 'F0 FF F1 ED EF FF E3 D6 D6 FF BD 77 57 FF 27 08'
- '00 FF 00 00 00 FF 00 00 00 C4 00 00 00 28 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 02 00 00 00 60 00 00 00 DD 00 00'
- '00 FF 2F 0C 00 FF A1 5E 3C FF F7 D5 C0 FF FF EA'
- 'D2 FF FF D4 B0 FF FF DB B8 FF E3 A2 76 FF D6 9E'
- '83 FF FF F8 F1 FF FF AB 64 FF FF 95 3D FF FF 9A'
- '46 FF FF 99 46 FF FF 99 45 FF FF 9A 47 FF FF 9C'
- '49 FF FF A8 5D FF FF E3 CA FF FF FF FF FF FD FC'
- 'FD FF FA F8 F8 FF F7 F5 F5 FF F4 F1 F1 FF F2 EE'
- 'EE FF F1 EC EC FF EB E6 E8 FF E1 CF CC FF A2 62'
- '43 FF 24 0A 00 FF 00 00 00 FF 00 00 00 A1 00 00'
- '00 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 12 00 00 00 9E 00 00 00 FF 00 00 00 FF 59 1E'
- '00 FF D5 99 7A FF FF F5 E8 FF FF E4 C7 FF FF D9'
- 'B8 FF FF E0 C1 FF ED B6 8E FF D7 A1 86 FF FD FA'
- 'F6 FF FF AC 66 FF FF 98 41 FF FF 9C 49 FF FF 9C'
- '49 FF FF 9C 49 FF FF 9C 48 FF FF 9C 49 FF FF A0'
- '51 FF FF A3 54 FF FF A7 59 FF FE DF C3 FF FB FF'
- 'FF FF F9 F7 F8 FF F6 F3 F3 FF F4 F0 F0 FF F1 EC'
- 'EC FF EF E9 E8 FF EC E6 E6 FF E9 E3 E5 FF E4 D0'
- 'CA FF AE 6B 48 FF 16 02 00 FF 00 00 00 FF 00 00'
- '00 B0 00 00 00 1C 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 48 00 00'
- '00 C8 00 00 00 FF 21 04 00 FF 8E 4B 25 FF EF C7'
- 'B0 FF FF F0 DE FF FF E3 C9 FF FF DE C0 FF FF E8'
- 'CC FF EF BF 99 FF D2 93 71 FF F9 F0 E9 FF FF BF'
- '86 FF FF 98 43 FF FF 9D 4C FF FF 9E 4C FF FF 9D'
- '4B FF FF 9D 4B FF FF 9D 4B FF FF 9E 4B FF FF A2'
- '53 FF FF A7 59 FF FF AA 5E FF FF B0 6A FF FD D7'
- 'B5 FF F7 F8 FC FF F5 F3 F3 FF F2 ED ED FF F0 EA'
- 'EA FF ED E7 E7 FF EA E3 E3 FF E9 E1 E1 FF E5 DE'
- 'E1 FF E0 CA C3 FF B0 6B 44 FF 23 09 00 FF 00 00'
- '00 FE 00 00 00 B1 00 00 00 24 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4C 00 00 00 EB 00 00'
- '00 FF 37 11 00 FF B5 72 4C FF FC DD C8 FF FF F8'
- 'E8 FF FF E4 C8 FF FF E3 C8 FF FF E9 CF FF F2 CA'
- 'A9 FF D4 92 69 FF F8 EC E3 FF FF C4 8E FF FF 98'
- '42 FF FF 9F 4F FF FF A0 4F FF FF A0 4E FF FF 9F'
- '4E FF FF 9F 4E FF FF 9F 4D FF FF 9F 4E FF FF A3'
- '54 FF FF A8 5C FF FF AD 64 FF FF B0 67 FF FF B4'
- '6F FF FA D9 BC FF F4 F0 F1 FF F1 ED EE FF EF E9'
- 'E9 FF EC E5 E5 FF E9 E2 E2 FF E7 DE DE FF E5 DC'
- 'DC FF E2 DA DD FF E3 CC C3 FF A4 5F 37 FF 25 0B'
- '00 FF 00 00 00 FF 00 00 00 A1 00 00 00 25 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 EB 02 00 00 FF 6A 2F'
- '0C FF E4 AC 8B FF FF FA EF FF FF F1 DC FF FF E7'
- 'CE FF FF E8 D0 FF FF EC D5 FF FC E3 C8 FF D2 8B'
- '5F FF F0 D2 BD FF FF C9 96 FF FF 9E 4A FF FF A1'
- '51 FF FF A2 52 FF FF A1 51 FF FF A1 51 FF FF A1'
- '51 FF FF A1 51 FF FF A1 50 FF FF A1 50 FF FF A5'
- '57 FF FF AA 5E FF FF AE 66 FF FF B3 6D FF FF B7'
- '72 FF FF B9 74 FF F8 D6 B7 FF EF EC EF FF ED E8'
- 'E9 FF EB E4 E4 FF E8 E0 E0 FF E6 DD DD FF E3 DA'
- 'D9 FF E0 D6 D6 FF DE D5 D8 FF E2 C7 BD FF AF 63'
- '36 FF 16 03 00 FF 00 00 00 FF 00 00 00 B0 00 00'
- '00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 ED 06 01 00 FF 7A 3C'
- '16 FF F7 CA AA FF FF F4 E0 FF FF E9 D2 FF FF E9'
- 'D2 FF FF ED D7 FF FA E1 C7 FF D1 87 58 FF EF C6'
- 'A8 FF FF CD 9E FF FF A0 4D FF FF A2 53 FF FF A3'
- '54 FF FF A3 54 FF FF A3 54 FF FF A3 53 FF FF A3'
- '53 FF FF A3 53 FF FF A3 53 FF FF A3 53 FF FF A7'
- '59 FF FF AC 60 FF FF B0 68 FF FF B4 6F FF FF B9'
- '76 FF FF BD 7C FF FF C1 81 FF F9 D4 B1 FF EC E6'
- 'E8 FF E9 E3 E3 FF E7 DE DE FF E4 DB DB FF E2 D7'
- 'D7 FF DF D4 D4 FF DD D1 D0 FF DB D2 D5 FF DF C3'
- 'B8 FF A9 5E 30 FF 1D 08 00 FF 00 00 00 FE 00 00'
- '00 B1 00 00 00 26 00 00 00 01 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 7D 00 00 00 FF 08 01'
- '00 FF 96 46 13 FF FB CF AC FF FF F4 E1 FF FF EB'
- 'D6 FF FF F1 DE FF DF A6 7E FF E2 A8 7F FF FF CF'
- 'A1 FF FF A2 52 FF FF A2 52 FF FF A3 54 FF FF A3'
- '54 FF FF A3 54 FF FF A3 54 FF FF A3 54 FF FF A3'
- '54 FF FF A3 54 FF FF A3 54 FF FF A3 54 FF FF A7'
- '5A FF FF AC 62 FF FF B1 69 FF FF B5 71 FF FF BA'
- '78 FF FF BF 7F FF FF C3 85 FF FF C6 89 FF F5 D7'
- 'B9 FF E8 E1 E3 FF E5 DD DE FF E4 DA DA FF E1 D6'
- 'D6 FF DD D3 D3 FF DB CF CF FF D8 CB CB FF D9 CF'
- 'D3 FF E6 C9 BA FF 95 50 23 FF 0C 00 00 FF 00 00'
- '00 FF 00 00 00 91 00 00 00 17 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 01 00 00 00 7C 00 00'
- '00 FF 0B 03 00 FF 89 49 1D FF F7 C4 9A FF FF FC'
- 'EC FF DF A8 7F FF DE 98 67 FF FF CC 9D FF FF A8'
- '5C FF FF A2 52 FF FF A4 56 FF FF A4 55 FF FF A4'
- '55 FF FF A4 55 FF FF A4 55 FF FF A4 55 FF FF A3'
- '55 FF FF A3 55 FF FF A3 54 FF FF A3 54 FF FF A7'
- '5B FF FF AC 62 FF FF B0 69 FF FF B5 71 FF FF BA'
- '78 FF FF BF 80 FF FF C4 87 FF FF C8 8C FF FF CC'
- '91 FF F4 D7 B9 FF E4 DB DB FF E1 D8 D9 FF DF D5'
- 'D5 FF DD D1 D1 FF DB CE CE FF D8 CA CA FF D4 C6'
- 'C6 FF D5 CA CE FF E5 C3 B1 FF 9D 5D 34 FF 0A 00'
- '00 FF 00 00 00 FA 00 00 00 99 00 00 00 13 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 76 00 00 00 FC 09 00 00 FF 87 4B 20 FF E7 AE'
- '83 FF DF 95 60 FF FD C1 8C FF FF A9 5F FF FF A2'
- '53 FF FF A4 57 FF FF A4 57 FF FF A4 57 FF FF A4'
- '56 FF FF A4 56 FF FF A4 56 FF FF A4 56 FF FF A4'
- '56 FF FF A4 56 FF FF A4 55 FF FF A3 55 FF FF A7'
- '5B FF FF AC 62 FF FF B1 6A FF FF B5 71 FF FF BA'
- '78 FF FF BE 7E FF FF C4 86 FF FF CA 92 FF FF D2'
- '9E FF FF D9 A9 FF F4 DE C6 FF E0 D6 D7 FF DD D2'
- 'D3 FF DB CF CF FF D9 CC CC FF D6 C8 C8 FF D3 C4'
- 'C4 FF D0 BF BF FF D6 CC D0 FF E6 C5 B3 FF 96 54'
- '29 FF 11 05 00 FF 00 00 00 F9 00 00 00 82 00 00'
- '00 16 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 5F 00 00 00 FB 0D 03 00 FF B1 50'
- '0F FF FD AB 6A FF FF B3 6D FF FF A3 55 FF FF A5'
- '58 FF FF A5 58 FF FF A5 58 FF FF A4 58 FF FF A4'
- '58 FF FF A4 58 FF FF A4 58 FF FF A4 57 FF FF A4'
- '57 FF FF A4 57 FF FF A4 57 FF FF A4 57 FF FF A8'
- '5C FF FF AC 63 FF FF B0 69 FF FF B5 70 FF FF BA'
- '7A FF FF C3 88 FF FF CF 9D FF FF D7 AB FF FF DB'
- 'B4 FF FF E0 BA FF FF E3 BE FF F4 E0 CA FF DD D1'
- 'D1 FF D9 CD CE FF D8 CA CA FF D5 C6 C6 FF D2 C3'
- 'C3 FF D0 C0 C0 FF CC BA BA FF D0 C3 C6 FF EA CC'
- 'BD FF 97 55 26 FF 0D 02 00 FF 00 00 00 FF 00 00'
- '00 7D 00 00 00 0E 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9E 00 00 00 FF 26 12'
- '04 FF B2 5F 23 FF FB 98 48 FF FF AA 5F FF FF A6'
- '5A FF FF A6 59 FF FF A6 59 FF FF A6 59 FF FF A6'
- '59 FF FF A5 59 FF FF A5 59 FF FF A5 59 FF FF A5'
- '58 FF FF A5 58 FF FF A5 58 FF FF A5 58 FF FF A7'
- '5B FF FF AC 62 FF FF B5 72 FF FF C2 89 FF FF CB'
- '99 FF FF D2 A6 FF FF D7 AD FF FF DA B2 FF FF DD'
- 'B8 FF FF E1 BD FF FF E4 C3 FF FF E9 C8 FF F4 E3'
- 'CE FF DB CD CC FF D5 C7 C8 FF D4 C5 C5 FF D1 C2'
- 'C2 FF CF BE BE FF CC BA BA FF C9 B5 B6 FF CC BD'
- 'C0 FF E2 BE AD FF A2 65 3A FF 0E 05 00 FF 00 00'
- '00 EC 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 14 00 00 00 AC 00 00'
- '00 FF 27 12 03 FF A7 53 15 FF F9 93 40 FF FF A7'
- '5B FF FF A7 5C FF FF A6 5B FF FF A6 5B FF FF A6'
- '5B FF FF A6 5B FF FF A6 5B FF FF A6 5A FF FF A6'
- '5A FF FF A6 5A FF FF A5 58 FF FF A5 58 FF FF AE'
- '69 FF FF BB 7F FF FF C9 97 FF FF CF A2 FF FF D2'
- 'A7 FF FF D5 AC FF FF D9 B1 FF FF DC B8 FF FF E0'
- 'BD FF FF E3 C2 FF FF E7 C8 FF FF EA CD FF FF EF'
- 'D2 FF F4 E5 D3 FF D7 C9 C8 FF D1 C2 C2 FF D0 C0'
- 'C0 FF CE BD BD FF CB B9 B9 FF C8 B5 B5 FF C3 B0'
- 'B0 FF D6 C7 CA FF BF 94 78 FF 18 09 00 FF 00 00'
- '00 F4 00 00 00 2C 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00'
- '00 A6 00 00 00 FF 11 08 02 FF A1 4F 12 FF FA 93'
- '3F FF FF AC 61 FF FF A7 5D FF FF A7 5C FF FF A6'
- '5C FF FF A6 5C FF FF A6 5C FF FF A7 5B FF FF A6'
- '5B FF FF A4 57 FF FF A9 60 FF FF BA 7F FF FF C5'
- '94 FF FF CB 9C FF FF CE A1 FF FF D1 A6 FF FF D4'
- 'AC FF FF D8 B1 FF FF DC B7 FF FF DF BD FF FF E3'
- 'C2 FF FF E5 C7 FF FF E8 CC FF FF EC D1 FF FF EE'
- 'D6 FF FF F3 DB FF F6 EB D9 FF D3 C3 C3 FF CD BC'
- 'BC FF CD BB BB FF CA B7 B7 FF C6 B3 B4 FF CB B9'
- 'BC FF BD 92 7B FF 31 19 0B FF 00 00 00 FF 00 00'
- '00 8D 00 00 00 03 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 05 00 00 00 A6 00 00 00 FF 16 0B 03 FF A6 54'
- '16 FF FA 94 41 FF FF AB 61 FF FF A9 5F FF FF A8'
- '5D FF FF A8 5E FF FF A8 5D FF FF A6 5B FF FF A7'
- '5D FF FF B2 71 FF FF C2 8E FF FF C8 9A FF FF C9'
- '9B FF FF CD A0 FF FF D0 A6 FF FF D4 AC FF FF D7'
- 'B1 FF FF DB B7 FF FF DE BC FF FF E1 C1 FF FF E4'
- 'C6 FF FF E7 CB FF FF EA D0 FF FF ED D4 FF FF EF'
- 'D9 FF FF F2 DD FF FF F8 E3 FF EE E5 D9 FF D1 C1'
- 'C0 FF CA B7 B8 FF C8 B5 B5 FF CA B7 B8 FF CB A8'
- '9A FF 46 2D 1D FF 00 00 00 FF 00 00 00 C8 00 00'
- '00 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 87 00 00 00 FF 0D 06'
- '02 FF 92 4B 14 FF FD 96 41 FF FF AB 63 FF FF A9'
- '60 FF FF A8 5F FF FF A6 5B FF FF AB 64 FF FF C1'
- '8C FF FF CB A0 FF FF CC A0 FF FF CB 9F FF FF CD'
- 'A2 FF FF D1 A8 FF FF D4 AD FF FF D7 B2 FF FF DA'
- 'B8 FF FF DE BD FF FF E1 C2 FF FF E4 C7 FF FF E7'
- 'CB FF FF E9 D0 FF FF EC D4 FF FF EF D8 FF FF F1'
- 'DD FF FF F4 E1 FF FF F7 E5 FF FF FD EC FF F2 EA'
- 'E0 FF CA B8 B6 FF C8 B6 B9 FF CD AD A1 FF 57 35'
- '1B FF 00 00 00 FF 00 00 00 D6 00 00 00 18 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 75 00 00'
- '00 FD 0C 06 02 FF 7E 42 11 FF F3 91 3F FF FF AC'
- '63 FF FF A7 5D FF FF B5 77 FF FF C8 9A FF FF CF'
- 'A7 FF FF CE A5 FF FF CF A6 FF FF CF A7 FF FF D1'
- 'AA FF FF D4 AF FF FF D8 B4 FF FF DA B9 FF FF DD'
- 'BE FF FF E0 C2 FF FF E3 C7 FF FF E6 CC FF FF E9'
- 'D0 FF FF EB D4 FF FF EE D8 FF FF F0 DC FF FF F2'
- 'E0 FF FF F5 E4 FF FF F8 E9 FF FF F9 EB FF FD F3'
- 'E0 FF F3 EC E4 FF DB BD B0 FF 68 46 30 FF 00 00'
- '00 FF 00 00 00 D1 00 00 00 32 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 78 00 00 00 F1 00 00 00 FF 7F 43 12 FF EF 90'
- '40 FF FF BC 80 FF FF D0 A8 FF FF D3 AD FF FF D2'
- 'AC FF FF D2 AD FF FF D3 AD FF FF D3 AE FF FF D5'
- 'B1 FF FF D8 B5 FF FF DB BA FF FF DD BF FF FF E0'
- 'C4 FF FF E3 C8 FF FF E6 CC FF FF E8 D1 FF FF EB'
- 'D5 FF FF ED D8 FF FF EF DC FF FF F2 E0 FF FF F4'
- 'E3 FF FF F7 E8 FF FE F5 E6 FF FC EF DC FF FD F7'
- 'EA FF FF F0 DA FF 83 5C 3B FF 00 00 00 FF 00 00'
- '00 EB 00 00 00 3F 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F 0F'
+ '0F 13 0F 0F 0F 2F 0F 0F 0F 41 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F 0F 45 0F 0F'
+ '0F 45 0F 0F 0F 41 0F 0F 0F 2F 0F 0F 0F 13 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 54 00 00 00 FD 00 00 00 FF 66 3A'
- '14 FF F4 B8 85 FF FF D9 B8 FF FF D6 B3 FF FF D5'
- 'B3 FF FF D6 B4 FF FF D6 B5 FF FF D7 B5 FF FF D9'
- 'B8 FF FF DC BC FF FF DF C1 FF FF E1 C5 FF FF E4'
- 'C9 FF FF E7 CE FF FF E8 D1 FF FF EB D5 FF FF EE'
- 'D9 FF FF F0 DD FF FF F1 E0 FF FF F4 E4 FF FF F6'
- 'E8 FF FE F2 E1 FF FB EB D7 FF FF FD F6 FF FF F6'
- 'E4 FF 9C 66 38 FF 03 00 00 FF 00 00 00 F5 00 00'
- '00 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 86'
+ '86 4B CA CA CA C7 BE BE BE D4 BB BB BB D6 BB BB'
+ 'BB D6 BB BB BB D6 BB BB BB D6 BB BB BB D6 BA BA'
+ 'BA D6 BA BA BA D6 BA BA BA D6 B9 B9 B9 D6 B9 B9'
+ 'B9 D6 B9 B9 B9 D6 B9 B9 B9 D6 B8 B8 B8 D6 B8 B8'
+ 'B8 D6 B8 B8 B8 D6 B7 B7 B7 D6 B7 B7 B7 D6 B5 B5'
+ 'B5 D6 B5 B5 B5 D6 B4 B4 B4 D6 B4 B4 B4 D6 B3 B3'
+ 'B3 D6 B2 B2 B2 D6 B2 B2 B2 D6 B1 B1 B1 D6 B1 B1'
+ 'B1 D6 AF AF AF D6 AF AF AF D6 AE AE AE D6 AD AD'
+ 'AD D6 AD AD AD D6 AC AC AC D6 AC AC AC D6 AB AB'
+ 'AB D6 A9 A9 A9 D6 A9 A9 A9 D6 A8 A8 A8 D6 A8 A8'
+ 'A8 D6 A8 A8 A8 D4 93 93 93 A7 0F 0F 0F 2F 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 45 00 00 00 E0 01 00'
- '00 FF 78 47 1B FF F2 B5 7F FF FF DC BE FF FF DA'
- 'BB FF FF DA BB FF FF DB BC FF FF DB BD FF FF DC'
- 'BF FF FF DF C3 FF FF E2 C7 FF FF E4 CB FF FF E6'
- 'CF FF FF E9 D4 FF FF EB D6 FF FF ED DA FF FF F0'
- 'DE FF FF F2 E1 FF FF F3 E5 FF FF F4 E6 FF FC EE'
- 'DB FF FD F1 E0 FF FF FC F5 FF FF F5 E3 FF A7 7A'
- '51 FF 07 00 00 FF 00 00 00 F3 00 00 00 60 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 93 93'
+ '93 68 EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF DE DE'
+ 'DE FF DE DE DE FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF DA DA DA FF D9 D9 D9 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D6 D6 D6 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
+ 'D4 FF D3 D3 D3 FF AC AC AC D7 0F 0F 0F 42 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 8B 00 00'
- '00 FF 69 42 1C FF ED AC 6F FF EE BC 90 FF FF E2'
- 'C7 FF FF DE C2 FF FF DE C2 FF FF DF C4 FF FF E0'
- 'C5 FF FF E2 C9 FF FF E5 CD FF FF E7 D1 FF FF E9'
- 'D4 FF FF EC D8 FF FF EE DB FF FF F0 DF FF FF F1'
- 'E2 FF FF F4 E6 FF FE F3 E5 FF FC EB D9 FF FD F2'
- 'E2 FF FF FC F4 FF FF FF FE FF CB 9A 6C FF 1A 09'
- '00 FF 00 00 00 FF 00 00 00 7D 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF DB DB DB FF DA DA DA FF D9 D9 D9 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF D4 D4'
+ 'D4 FF D4 D4 D4 FF AB AB AB D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 02 00'
- '00 FF AA 6B 2D FF FF FA EA FF F1 D6 BF FF EC B8'
- '88 FF FF E1 C9 FF FF E3 CB FF FF E2 CA FF FF E3'
- 'CB FF FF E5 CF FF FF E8 D3 FF FF EA D6 FF FF EC'
- 'D9 FF FF ED DD FF FF EF E0 FF FF F2 E3 FF FF F4'
- 'E6 FF FD F0 E0 FF FD EF DE FF FE F4 E8 FF FF FB'
- 'F4 FF FF FF F7 FF DC B0 84 FF 29 17 09 FF 00 00'
- '00 FF 00 00 00 94 00 00 00 0B 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF DC DC'
+ 'DC FF DB DB DB FF DA DA DA FF D9 D9 D9 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF AC AC AC D9 0F 0F 0F 47 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 94 01 00'
- '00 FF 51 30 0F FF DF B0 7F FF FF FB F0 FF EF D0'
- 'B3 FF F0 C5 9D FF FD E4 CD FF FF E6 D1 FF FF E7'
- 'D2 FF FF E8 D5 FF FF EB D9 FF FF ED DC FF FF EF'
- 'DF FF FF F0 E2 FF FF F2 E5 FF FF F3 E6 FF FE F0'
- 'E1 FF FE F0 E1 FF FE F6 ED FF FF FA F3 FF FF FF'
- 'FC FF E5 C3 A0 FF 3B 20 06 FF 00 00 00 FF 00 00'
- '00 B0 00 00 00 07 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EE EE EE FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF DF DF DF FF DE DE DE FF DD DD'
+ 'DD FF DC DC DC FF DB DB DB FF DA DA DA FF D9 D9'
+ 'D9 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D6 D6'
+ 'D6 FF D5 D5 D5 FF AC AC AC D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 1F 00 00'
- '00 CC 00 00 00 FF 35 1B 00 FF D4 99 5A FF FF FF'
- 'FE FF EC C3 9B FF F4 CE AA FF FF ED DC FF FF EA'
- 'D8 FF FF EC DB FF FF EE DF FF FF F0 E1 FF FF F1'
- 'E4 FF FF F3 E7 FF FE F2 E6 FF FE EF E0 FF FE F3'
- 'E7 FF FF F8 F0 FF FF FA F3 FF FF FF FF FF F3 CD'
- 'A6 FF 52 2F 0D FF 00 00 00 FF 00 00 00 B8 00 00'
- '00 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF E0 E0 E0 FF DF DF DF FF DE DE'
+ 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DA DA'
+ 'DA FF D9 D9 D9 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D6 D6 D6 FF AD AD AD D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1A 00 00 00 AE 00 00 00 FF 23 13 01 FF BF 8D'
- '56 FF F3 B6 77 FF F6 D4 B6 FF FF F0 E3 FF FF ED'
- 'DF FF FF EF E1 FF FF F1 E4 FF FF F3 E7 FF FF F3'
- 'E9 FF FE F2 E5 FF FE F2 E6 FF FF F6 ED FF FF F9'
- 'F2 FF FF F9 F4 FF FF FF FF FF FB DE BE FF 55 37'
- '1A FF 00 00 00 FF 00 00 00 CB 00 00 00 1E 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF E0 E0 E0 FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF DA DA DA FF D9 D9 D9 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF AE AE AE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF DC DC'
+ 'DC FF DB DB DB FF DA DA DA FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D8 D8 D8 FF AE AE AE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 04 00 00 00 A1 00 00 00 FF 11 07'
- '00 FF B5 72 2D FF FF EB CF FF FF F4 EA FF FF F1'
- 'E5 FF FF F2 E7 FF FF F4 EA FF FF F4 EB FF FE F3'
- 'E9 FF FE F4 EA FF FF F8 F2 FF FF FA F5 FF FF FB'
- 'F6 FF FF FF FF FF F7 E5 D0 FF 76 4D 25 FF 00 00'
- '00 FF 00 00 00 DB 00 00 00 25 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DF DF DF FF DE DE DE FF DD DD'
+ 'DD FF DC DC DC FF DB DB DB FF DA DA DA FF D9 D9'
+ 'D9 FF D9 D9 D9 FF AF AF AF D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00'
- '00 FF 23 14 04 FF C7 99 68 FF FF FF F2 FF FF F8'
- 'F1 FF FF F5 ED FF FE F6 ED FF FE F4 EC FF FE F8'
- 'F1 FF FF FA F6 FF FF FB F6 FF FF FC F8 FF FF FF'
- 'FF FF FF F4 DE FF 8C 61 34 FF 00 00 00 FF 00 00'
- '00 EA 00 00 00 3B 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DE DE'
+ 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DA DA'
+ 'DA FF DA DA DA FF AF AF AF D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF DF DF'
+ 'DF FF DE DE DE FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF DB DB DB FF B1 B1 B1 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00'
- '00 BB 00 00 00 FF 28 17 05 FF C1 9C 74 FF FF F6'
- 'E7 FF FF FB F8 FF FE F8 F1 FF FF FA F6 FF FF FC'
- 'F8 FF FF FC FA FF FF FD FB FF FF FF FF FF FF FD'
- 'F5 FF AA 82 56 FF 0E 05 00 FF 00 00 00 F9 00 00'
- '00 5A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF'
+ 'DF FF DF DF DF FF DE DE DE FF DD DD DD FF DC DC'
+ 'DC FF DC DC DC FF B2 B2 B2 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 04 00 00 00 A8 00 00 00 FF 06 00 00 FF AB 84'
- '58 FF FF FA EB FF FF FF FF FF FF FE FD FF FF FF'
- 'FD FF FF FF FF FF FF FF FF FF FF FF FC FF C9 9B'
- '66 FF 0F 05 00 FF 00 00 00 FF 00 00 00 68 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F1 F1 F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF DF DF DF FF DF DF DF FF DE DE DE FF DD DD'
+ 'DD FF DC DC DC FF B2 B2 B2 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8F 8F'
+ '8F 6B F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DE DE'
+ 'DE FF DD DD DD FF B3 B3 B3 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0A 00 00 00 74 00 00 00 FF 0E 05'
- '00 FF 79 5C 3A FF FF ED D6 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FE FF C9 A5 7A FF 19 0D'
- '00 FF 00 00 00 FF 00 00 00 82 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF E0 E0 E0 FF DF DF DF FF DF DF'
+ 'DF FF DE DE DE FF B3 B3 B3 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF DF DF DF FF B4 B4 B4 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 67 00 00'
- '00 EE 00 00 00 FF 6E 4E 29 FF F0 DD C5 FF FF FF'
- 'F4 FF FF F1 DC FF D1 AC 80 FF 36 1D 02 FF 00 00'
- '00 FF 00 00 00 8F 00 00 00 03 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1 E1 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF B5 B5 B5 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF E1 E1 E1 FF B5 B5 B5 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3 E3 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF B7 B7 B7 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 3F 00 00 00 E0 00 00 00 FF 48 2F 12 FF 87 5D'
- '2D FF 53 38 19 FF 12 0A 00 FF 00 00 00 FF 00 00'
- '00 AD 00 00 00 08 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E2 E2 E2 FF B7 B7 B7 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF B8 B8 B8 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 26 00 00 00 BF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 EC 00 00 00 83 00 00'
- '00 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5 E5 FF E5 E5'
+ 'E5 FF E4 E4 E4 FF B8 B8 B8 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F5 F5 F5 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF B9 B9 B9 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0A 00 00 00 75 00 00'
- '00 84 00 00 00 60 00 00 00 24 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 92'
+ '92 6B F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF BA BA BA D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FC 3F FF FF 00 00 FF FF F8 1F FF FF 00 00 FF FF'
- 'F0 0F FF FF 00 00 FF FF C0 07 FF FF 00 00 FF FF'
- '80 03 FF FF 00 00 FF FF 00 01 FF FF 00 00 FF FC'
- '00 00 FF FF 00 00 FF F8 00 00 7F FF 00 00 FF E0'
- '00 00 3F FF 00 00 FF C0 00 00 1F FF 00 00 FF 80'
- '00 00 0F FF 00 00 FE 00 00 00 0F FF 00 00 FC 00'
- '00 00 03 FF 00 00 F8 00 00 00 03 FF 00 00 E0 00'
- '00 00 01 FF 00 00 C0 00 00 00 00 FF 00 00 80 00'
- '00 00 00 7F 00 00 00 00 00 00 00 3F 00 00 00 00'
- '00 00 00 1F 00 00 00 00 00 00 00 07 00 00 00 00'
- '00 00 00 07 00 00 00 00 00 00 00 03 00 00 C0 00'
- '00 00 00 00 00 00 E0 00 00 00 00 00 00 00 F0 00'
- '00 00 00 00 00 00 F0 00 00 00 00 00 00 00 F8 00'
- '00 00 00 00 00 00 FC 00 00 00 00 01 00 00 FF 00'
- '00 00 00 03 00 00 FF 00 00 00 00 07 00 00 FF C0'
- '00 00 00 0F 00 00 FF E0 00 00 00 1F 00 00 FF F0'
- '00 00 00 3F 00 00 FF F8 00 00 00 7F 00 00 FF F8'
- '00 00 00 7F 00 00 FF F8 00 00 00 FF 00 00 FF F8'
- '00 00 01 FF 00 00 FF FC 00 00 03 FF 00 00 FF FE'
- '00 00 07 FF 00 00 FF FF 80 00 0F FF 00 00 FF FF'
- '80 00 1F FF 00 00 FF FF C0 00 3F FF 00 00 FF FF'
- 'E0 00 7F FF 00 00 FF FF F8 00 7F FF 00 00 FF FF'
- 'FC 00 FF FF 00 00 FF FF FE 01 FF FF 00 00 FF FF'
- 'FF 07 FF FF 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E6 E6 E6 FF BA BA BA D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0E 00 00 00 58 00 00'
- '00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF BA BA BA D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF BB BB BB D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 30 00 00 00 C1 09 00 00 FF 00 00'
- '00 ED 00 00 00 59 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F7 F7 F7 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF EA EA EA FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF BB BB BB D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 61 00 00 00 E9 33 0D 00 FF 97 3E 19 FF 4D 1D'
- '0A FF 00 00 00 F0 00 00 00 52 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF EA EA EA FF E9 E9 E9 FF E9 E9'
+ 'E9 FF E9 E9 E9 FF BC BC BC D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 14 00 00 00 9A 02 00'
- '00 FF 63 32 1D FF C6 78 55 FF F2 DA D2 FF CC A1'
- '95 FF 44 17 07 FF 00 00 00 EB 00 00 00 4C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF BC BC BC D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF EA EA EA FF EA EA EA FF EA EA'
+ 'EA FF E9 E9 E9 FF BC BC BC D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3B 00 00 00 CD 18 03 00 FF 9A 62'
- '4A FF E0 9D 7D FF F1 DB D2 FF FF FF FF FF FD FD'
- 'FE FF CA 9D 8F FF 3D 15 08 FF 00 00 00 E5 00 00'
- '00 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EA EA EA FF EA EA'
+ 'EA FF EA EA EA FF BC BC BC D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 6F 00 00 00 F1 3B 15 09 FF CB 95 7B FF EE AA'
- '83 FF E9 C8 B8 FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FD FC FE FF C8 9B 8D FF 39 14 07 FF 00 00'
- '00 E2 00 00 00 3C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 03 00 00 00 80 00 00'
- '00 FF 45 1B 0D FF E1 AC 91 FF FC BD 95 FF DB A5'
- '8B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FA F7 F9 FF B5 80 6E FF 1A 05'
- '00 FF 00 00 00 CA 00 00 00 1E 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF EB EB EB FF EB EB EB FF EA EA'
+ 'EA FF EA EA EA FF BE BE BE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1F 00 00 00 AC 07 00 00 FF 74 43'
- '2F FF EF C3 A7 FF FC C4 9B FF DB A2 86 FF FA D0'
- 'AF FF FF BE 87 FF FF FC FA FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F4 EB EB FF A8 78'
- '67 FF 16 05 00 FF 00 00 00 BB 00 00 00 1B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 6B FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF BE BE BE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4A 00 00 00 DA 24 0A 00 FF AB 76 5E FF FF DE'
- 'C1 FF FE CB A2 FF DC A0 80 FF F7 D7 BD FF FF 9D'
- '49 FF FF 8E 31 FF FF BB 82 FF FF FB F8 FF FF FF'
- 'FF FF FF FF FF FF FD FB FB FF FA FA FB FF F3 EA'
- 'E9 FF A6 7B 6A FF 16 05 00 FF 00 00 00 B5 00 00'
- '00 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 07 00 00 00 82 00 00'
- '00 F9 50 28 15 FF D8 A9 8F FF FF E9 CE FF FE D1'
- 'AA FF DE A2 81 FF F4 D5 C0 FF FF A6 58 FF FF 96'
- '3E FF FF 98 44 FF FF 96 3E FF FF BD 85 FF FF FA'
- 'F6 FF FE FF FF FF FA F8 F8 FF F6 F3 F3 FF F4 F2'
- 'F3 FF F0 E4 E3 FF A5 74 5E FF 16 05 00 FF 00 00'
- '00 B1 00 00 00 16 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 28 00 00 00 B8 0E 00 00 FF 86 55'
- '3D FF F6 D3 BA FF FF EB D1 FF FE D9 B7 FF E2 A9'
- '88 FF F1 D4 C1 FF FF B0 69 FF FF 98 40 FF FF 9C'
- '49 FF FF 9C 48 FF FF 9D 4C FF FF A0 4E FF FF C1'
- '89 FF FD F6 F1 FF F8 F9 FB FF F5 F0 F0 FF F1 EB'
- 'EB FF EE EA EB FF ED E0 DD FF A6 74 5B FF 16 05'
- '00 FF 00 00 00 B1 00 00 00 16 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4F 00 00 00 E2 30 13 04 FF BB 8B 70 FF FF ED'
- 'D8 FF FF EB D1 FF FF E3 C7 FF E5 B0 8C FF ED CB'
- 'B6 FF FF B9 7A FF FF 99 44 FF FF 9F 4D FF FF 9E'
- '4D FF FF 9E 4C FF FF A0 4F FF FF A6 5A FF FF AA'
- '5D FF FE C3 8D FF F7 EE E8 FF F2 F0 F2 FF EE E8'
- 'E8 FF EB E3 E3 FF E8 E2 E3 FF EA DA D7 FF A7 72'
- '56 FF 18 06 00 FF 00 00 00 B1 00 00 00 17 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 EA 53 27 0F FF E8 BF A3 FF FF F9 E7 FF FF EB'
- 'D2 FF FF EF D8 FF EA BC 9B FF E7 BB 9E FF FF C0'
- '86 FF FF 9C 47 FF FF A2 51 FF FF A1 51 FF FF A1'
- '51 FF FF A1 50 FF FF A2 53 FF FF A9 5D FF FF B0'
- '68 FF FF B3 6B FF FD C8 94 FF F1 EA E7 FF EC E8'
- 'EA FF E9 E1 E1 FF E5 DC DB FF E2 DA DB FF E7 D4'
- 'D0 FF A2 65 42 FF 08 00 00 FF 00 00 00 A8 00 00'
- '00 0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 EB 5F 32 18 FF F9 D2 B3 FF FF F4 DE FF FF EF'
- 'DA FF F4 D4 B9 FF E1 A8 82 FF FD C5 93 FF FF A1'
- '50 FF FF A2 53 FF FF A3 54 FF FF A3 54 FF FF A3'
- '53 FF FF A3 53 FF FF A3 55 FF FF AB 60 FF FF B2'
- '6B FF FF B9 76 FF FF BE 7A FF FA D1 A8 FF EC E4'
- 'E2 FF E7 DF E2 FF E4 DA DA FF DF D4 D4 FF DD D4'
- 'D6 FF E2 C5 B9 FF 7D 4A 2C FF 01 00 00 FF 00 00'
- '00 86 00 00 00 05 00 00 00 00 00 00 00 00 00 00'
- '00 51 00 00 00 F3 5A 2F 15 FF F1 C8 A5 FF FC E5'
- 'CD FF E1 A2 77 FF FB BB 85 FF FF A5 56 FF FF A3'
- '53 FF FF A4 55 FF FF A4 55 FF FF A4 55 FF FF A3'
- '55 FF FF A3 55 FF FF A4 57 FF FF AB 61 FF FF B3'
- '6C FF FF BA 77 FF FF C0 81 FF FF C6 87 FF F9 D4'
- 'AC FF E7 DC DA FF E1 D7 D9 FF DE D2 D2 FF DA CD'
- 'CD FF D8 CD D0 FF E1 C4 B8 FF 7F 4F 31 FF 01 00'
- '00 FF 00 00 00 83 00 00 00 03 00 00 00 00 00 00'
- '00 00 00 00 00 48 00 00 00 EB 56 2F 16 FF E3 94'
- '5B FF FB B5 79 FF FF A8 5C FF FF A3 55 FF FF A4'
- '58 FF FF A4 56 FF FF A4 56 FF FF A4 56 FF FF A4'
- '56 FF FF A4 56 FF FF A5 58 FF FF AB 62 FF FF B2'
- '6B FF FF B9 76 FF FF C2 85 FF FF CD 97 FF FF D7'
- 'A7 FF F8 DF C1 FF E2 D6 D4 FF DB CF D0 FF D9 CB'
- 'CB FF D4 C5 C4 FF D3 C6 C8 FF E2 C5 B8 FF 80 51'
- '31 FF 02 00 00 FE 00 00 00 79 00 00 00 06 00 00'
- '00 00 00 00 00 00 00 00 00 4E 00 00 00 FF 7A 40'
- '16 FF FB 9E 51 FF FF AA 5C FF FF A6 5A FF FF A5'
- '59 FF FF A5 59 FF FF A5 58 FF FF A5 59 FF FF A5'
- '59 FF FF A4 57 FF FF A4 57 FF FF AB 62 FF FF B8'
- '76 FF FF C6 8F FF FF D2 A3 FF FF DA B1 FF FF E0'
- 'BA FF FF E5 C1 FF F8 E5 CB FF DE D0 CD FF D4 C6'
- 'C7 FF D3 C3 C3 FF CE BC BC FF CD BE C0 FF DE C0'
- 'B3 FF 85 56 37 FF 06 01 00 FE 00 00 00 4C 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 6B 00 00'
- '00 FB 6D 37 0D FF F5 92 41 FF FF AC 5F FF FF A7'
- '5C FF FF A6 5B FF FF A6 5B FF FF A6 5B FF FF A5'
- '59 FF FF A5 58 FF FF AE 68 FF FF C0 87 FF FF CC'
- '9D FF FF D3 A9 FF FF D8 B0 FF FF DD B8 FF FF E2'
- 'C0 FF FF E7 C8 FF FF EE D0 FF F8 EA D5 FF DA CB'
- 'C8 FF CF BE BF FF CD BB BB FF C8 B5 B5 FF D3 C0'
- 'C1 FF 9B 77 61 FF 09 03 00 FF 00 00 00 4B 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 5B 00 00 00 F7 5D 2F 0C FF F1 90 41 FF FF AD'
- '62 FF FF A8 5E FF FF A7 5D FF FF A6 5A FF FF AB'
- '64 FF FF BC 83 FF FF C8 98 FF FF CE A1 FF FF D2'
- 'A8 FF FF D7 B0 FF FF DC B8 FF FF E1 C0 FF FF E5'
- 'C8 FF FF EA CF FF FF EE D6 FF FF F4 DE FF F8 EF'
- 'DE FF D6 C6 C4 FF C8 B6 B7 FF D0 BC BD FF A0 80'
- '70 FF 10 09 04 FF 00 00 00 8E 00 00 00 04 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 6B 00 00 00 FF 70 3A 0F FF FB 9C'
- '4B FF FF AE 64 FF FF A6 5B FF FF AE 6A FF FF C6'
- '95 FF FF CD A3 FF FF CD A1 FF FF D1 A8 FF FF D6'
- 'B0 FF FF DB B8 FF FF DF C0 FF FF E4 C6 FF FF E8'
- 'CD FF FF EC D4 FF FF F0 DB FF FF F3 E1 FF FF FC'
- 'EA FF F5 EC E0 FF D3 C2 C3 FF BF A0 95 FF 29 19'
- '0C FF 00 00 00 C7 00 00 00 0B 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 69 00 00 00 FB 6F 3C'
- '12 FF F7 9B 4C FF FF BC 7F FF FF CD A3 FF FF D1'
- 'AB FF FF D0 AA FF FF D2 AC FF FF D6 B1 FF FF DB'
- 'B9 FF FF DF C0 FF FF E3 C7 FF FF E7 CD FF FF EB'
- 'D4 FF FF EF DA FF FF F3 E0 FF FF F6 E6 FF FE F5'
- 'E5 FF FF FF EF FF E9 D0 BA FF 43 2D 20 FF 00 00'
- '00 D9 00 00 00 25 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
- '00 F2 60 36 14 FF ED BA 8B FF FF DB B9 FF FF D7'
- 'B4 FF FF D6 B5 FF FF D8 B7 FF FF DC BC FF FF E0'
- 'C2 FF FF E4 C9 FF FF E8 CF FF FF EB D5 FF FF EF'
- 'DB FF FF F2 E1 FF FF F4 E5 FF FE F2 E1 FF FF FA'
- 'EE FF F9 EA D3 FF 5B 41 2A FF 00 00 00 E4 00 00'
- '00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
+ 'ED FF EC EC EC FF EC EC EC FF EC EC EC FF EB EB'
+ 'EB FF EB EB EB FF BE BE BE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4F 00 00 00 F9 A5 74 48 FF FB CF A6 FF FF DE'
- 'C1 FF FF DD C0 FF FF DD C1 FF FF E1 C6 FF FF E5'
- 'CD FF FF E8 D2 FF FF EC D7 FF FF EE DD FF FF F2'
- 'E2 FF FF F3 E4 FF FE F0 DF FF FF F9 EF FF FF F3'
- 'E2 FF 70 52 37 FF 00 00 00 F0 00 00 00 42 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF ED ED'
+ 'ED FF ED ED ED FF EC EC EC FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF BF BF BF D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 23 03 00 00 FD BF 97 6F FF FF EA D3 FF F4 CC'
- 'A9 FF FF E3 CB FF FF E3 CC FF FF E6 CF FF FF EA'
- 'D5 FF FF EC DA FF FF EF DF FF FF F2 E4 FF FE F2'
- 'E3 FF FE F0 E1 FF FF FA F3 FF FF FA ED FF 83 65'
- '48 FF 00 00 00 F6 00 00 00 52 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 12 00 00 00 CD 37 23 0E FF D6 B6 91 FF FD E7'
- 'D0 FF F6 D3 B4 FF FF EB D9 FF FF EB D9 FF FF EE'
- 'DE FF FF F0 E2 FF FF F2 E6 FF FF F1 E4 FF FE F3'
- 'E6 FF FF FA F4 FF FF FE F4 FF 98 79 5A FF 01 00'
- '00 FC 00 00 00 65 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EC EC EC FF BF BF BF D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1C 00 00 00 D4 24 13 01 FF D7 A8'
- '74 FF FE D8 B5 FF FF F1 E5 FF FF EF E1 FF FF F2'
- 'E6 FF FF F4 E9 FF FE F2 E5 FF FF F6 EC FF FF FA'
- 'F4 FF FF FF FF FF BB 9C 7B FF 06 01 00 FF 00 00'
- '00 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EC EC EC FF BF BF BF D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2A 00 00 00 D3 36 1F'
- '07 FF EB C5 9C FF FF FF F6 FF FF F4 EA FF FF F5'
- 'EB FF FF F4 EB FF FF F7 F0 FF FF FB F7 FF FF FF'
- 'FF FF E0 C8 AD FF 29 1A 0B FF 00 00 00 B7 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FC FC FC FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EF EF EF FF EE EE EE FF EE EE'
+ 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF EC EC'
+ 'EC FF EB EB EB FF BE BE BE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 22 00 00'
- '00 DA 3E 2D 1A FF DE C5 A8 FF FF FF FD FF FF FA'
- 'F5 FF FF FB F7 FF FF FD FB FF FF FF FF FF EC D9'
- 'C2 FF 3A 27 14 FF 00 00 00 C7 00 00 00 16 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FD FD FD FF FC FC FC FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF EB EB'
+ 'EB FF E5 E5 E5 FF B8 B8 B8 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 22 00 00 00 C4 25 18 0A FF C6 B0 95 FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F4 E5 D3 FF 4B 36'
- '20 FF 00 00 00 D6 00 00 00 22 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 6B FD FD FD FF FD FD FD FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
+ 'EE FF EE EE EE FF EE EE EE FF ED ED ED FF E8 E8'
+ 'E8 FF DB DB DB FF AE AE AE D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 10 00 00 00 A6 12 09 01 FF AA 94'
- '7A FF FF F6 EA FF F0 DE C8 FF 5E 46 2B FF 00 00'
- '00 E3 00 00 00 2E 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FE FE FE FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF EF FF EF EF'
+ 'EF FF EE EE EE FF EE EE EE FF ED ED ED FF E1 E1'
+ 'E1 FF CC CC CC FF A5 A5 A5 D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 84 05 01'
- '00 FF 44 31 1A FF 26 19 0A FF 00 00 00 E1 00 00'
- '00 3D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EC EC EC FF D4 D4'
+ 'D4 FF B6 B6 B6 FF 9D 9D 9D D9 0F 0F 0F 47 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FD FD FD FF FD FD FD FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF EF EF EF FF EE EE EE FF E8 E8 E8 FF C1 C1'
+ 'C1 FF A1 A1 A1 FF 9E 9E 9E D9 0F 0F 0F 45 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 54 00 00 00 84 00 00 00 67 00 00 00 1F 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FC'
- '7F FF FF F8 3F FF FF F0 1F FF FF C0 0F FF FF 80'
- '07 FF FF 00 03 FF FC 00 01 FF F8 00 00 FF F0 00'
- '00 7F C0 00 00 3F 80 00 00 1F 00 00 00 0F 00 00'
- '00 07 00 00 00 03 00 00 00 01 80 00 00 00 C0 00'
- '00 00 E0 00 00 00 F0 00 00 00 F8 00 00 01 FC 00'
- '00 03 FE 00 00 07 FF 00 00 0F FF 00 00 1F FF 00'
- '00 3F FF 80 00 7F FF C0 00 7F FF E0 00 FF FF F0'
- '01 FF FF F8 03 FF FF FC 07 FF FF FF 0F FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FD FD FD FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF EE EE EE FF D9 D9 D9 FF A7 A7'
+ 'A7 FF A1 A1 A1 FE 99 99 99 D3 0F 0F 0F 40 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 10 00 00 00 8A 00 00 00 67 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 36 1E 0B'
- '04 C9 9D 6B 56 FF 5D 3E 32 FE 00 00 00 67 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 69 4C 2F 21 EF CE 9D'
- '87 FF FF FF FE FF F0 E3 DF FF 50 36 2D F9 00 00'
- '00 5D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0A 00 00 00 90 71 4F 3D FF EE B2 90 FF FD D2'
- 'B5 FF FF FF FD FF FF FF FF FF E8 D7 D1 FF 3C 27'
- '1F F3 00 00 00 47 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 1A 0D'
- '07 BF A6 83 6D FF FB CC AC FF F7 BA 8F FF FF 9A'
- '44 FF FF C3 91 FF FF FD FC FF FF FF FF FF DC C7'
- 'C1 FF 38 26 1D E9 00 00 00 40 00 00 00 00 00 00'
- '00 00 00 00 00 00 02 01 00 5C 47 33 27 E8 D6 B9'
- 'A1 FF FF E0 C2 FF F3 BF 98 FF FF A3 55 FF FF 9A'
- '44 FF FF 9D 4A FF FF CB 9D FF F5 F2 F2 FF F6 F2'
- 'F5 FF D5 BD B4 FF 39 24 19 E9 00 00 00 3E 00 00'
- '00 00 00 00 00 00 29 16 0B F2 F3 D0 B4 FF FF F3'
- 'DC FF EF BC 94 FF FE A9 60 FF FF 9F 4D FF FF A1'
- '51 FF FF A5 57 FF FF B1 67 FF F9 D1 AA FF E9 E2'
- 'E3 FF EA E2 E5 FF CA AB 9D FF 28 17 0D E2 00 00'
- '00 2D 00 00 00 00 06 03 02 67 6D 53 3F FB F7 B8'
- '88 FF FF AD 65 FF FF A3 52 FF FF A4 56 FF FF A3'
- '54 FF FF A7 5A FF FF B5 6F FF FF C5 88 FF F5 D9'
- 'BD FF DE D4 D4 FF DE D1 D3 FF BD 9F 92 FF 2D 1E'
- '13 D8 00 00 00 2D 00 00 00 00 00 00 00 6E 76 43'
- '1B FF FD A4 53 FF FF AA 5D FF FF A5 57 FF FF A4'
- '56 FF FF B0 6C FF FF C6 91 FF FF D7 AE FF FF E4'
- 'C0 FF F3 E2 D0 FF D3 C5 C5 FF D9 C7 C9 FF A5 85'
- '75 FF 06 03 01 9C 00 00 00 00 00 00 00 00 00 00'
- '00 6D 6E 3E 18 FF FF A6 58 FF FF AE 65 FF FF BD'
- '85 FF FF CC A0 FF FF D7 B2 FF FF E0 C0 FF FF E9'
- 'CE FF FF F3 DC FF F3 EA DF FF CB B4 AF FF 3C 30'
- '2A EB 01 01 00 32 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 6F 71 43 1E F6 F7 C2 90 FF FF D8'
- 'B5 FF FF D7 B4 FF FF DF C1 FF FF E7 CE FF FF EE'
- 'DA FF FF F8 E8 FF FF F7 E4 FF 61 51 44 F8 00 00'
- '00 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9F D0 AA 86 FF FF E6'
- 'CA FF FF E1 C9 FF FF E8 D3 FF FF EE DD FF FF F4'
- 'E7 FF FF FC ED FF 7C 6B 5A FD 00 00 00 64 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 43 53 43 32 F4 F3 D2'
- 'B0 FF FF F1 E0 FF FF F0 E3 FF FF F4 E8 FF FF FF'
- 'FB FF 98 86 75 FF 00 00 00 7D 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 4E 59 47'
- '34 F4 F5 EA D9 FF FF FF FC FF FF FF FF FF BA AC'
- '9C FF 0C 07 03 A2 00 00 00 03 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 45 47 3C 31 E3 E3 DC D4 FF C9 BE B0 FF 16 10'
- '09 B4 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2B 19 12 0A BB 0D 09 03 A0 00 00'
- '00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FC 7F 00 00 F8 3F 00 00 F0 1F'
- '00 00 C0 0F 00 00 80 07 00 00 00 03 00 00 00 01'
- '00 00 00 00 00 00 80 00 00 00 C0 00 00 00 E0 01'
- '00 00 F0 03 00 00 F0 07 00 00 F8 07 00 00 FC 0F'
- '00 00 FE 1F 00 00'
-} */
-
-/* BINRES folder_open.ico */
-4 ICON folder_open.ico
-/* {
- '00 00 01 00 06 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 66 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 0E 09 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 76 0E 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 1E 34 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 C6 44 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 2E 49 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 B7 35 09 00 C4 3D 06 00 B5 44 16 00 B5 48'
- '23 00 BE 50 2B 00 CE 48 0F 00 CC 4A 15 00 CB 53'
- '1B 00 D4 58 1A 00 DC 66 1F 00 C5 53 26 00 D0 5A'
- '22 00 D0 59 31 00 DE 69 20 00 DA 72 2B 00 CE 63'
- '3C 00 D5 67 31 00 DF 6F 37 00 DC 72 30 00 E4 6C'
- '24 00 EA 78 27 00 EB 6D 31 00 E8 75 36 00 F1 76'
- '30 00 BB 6C 4F 00 C4 6D 55 00 C4 76 5D 00 CE 7D'
- '5F 00 D2 74 50 00 D4 7A 5B 00 E6 72 41 00 C5 7F'
- '6B 00 C8 7B 68 00 DB 7E 65 00 F8 8A 29 00 EF 88'
- '35 00 F2 8A 34 00 FD 99 35 00 FC 9B 3B 00 FF A3'
- '3A 00 BC 89 79 00 E9 88 46 00 E5 85 4B 00 F5 9A'
- '44 00 FD 9D 45 00 F0 95 49 00 FA 9C 4D 00 EA 81'
- '5B 00 FF A6 40 00 FF A9 45 00 F4 A0 49 00 FF AD'
- '4E 00 FA A0 53 00 FE A9 53 00 FD A6 58 00 FA AA'
- '5B 00 FF B2 55 00 FF B3 5C 00 C5 80 6C 00 CB 82'
- '6C 00 D5 84 69 00 C3 85 77 00 CA 8B 77 00 D4 89'
- '78 00 CD 90 7C 00 DA 9B 7E 00 EF 9D 65 00 ED 97'
- '6F 00 F4 9E 63 00 F5 9C 6F 00 E3 8C 78 00 E0 9D'
- '7E 00 E8 9A 7D 00 F0 9B 79 00 FA AF 65 00 F6 AB'
- '6C 00 FD B2 62 00 FF BA 65 00 FE B6 6E 00 FF BF'
- '6D 00 EC A1 76 00 EB A2 7A 00 F2 A6 75 00 F7 AC'
- '70 00 F0 A3 7D 00 F5 AC 7F 00 FE B7 71 00 FC BC'
- '72 00 F9 BA 7F 00 FE C4 78 00 92 8F 8D 00 91 90'
- '8E 00 9F 93 8F 00 93 91 91 00 9B 96 94 00 9C 9B'
- '9B 00 BC 8F 82 00 A1 93 8D 00 BC 92 85 00 B1 96'
- '8A 00 A3 95 91 00 A5 98 94 00 A0 9E 9F 00 BC 9A'
- '93 00 BE 9E 98 00 A8 A0 9C 00 B6 A1 9D 00 B9 A3'
- '9F 00 A4 A2 A2 00 A9 A6 A6 00 AD AA A6 00 A9 A5'
- 'A8 00 AE AB AC 00 B7 A7 A1 00 B9 A3 A0 00 B6 A8'
- 'A3 00 BA AA A5 00 B3 AB AB 00 B5 B1 AD 00 B4 AE'
- 'B0 00 BB B3 B7 00 C1 93 84 00 C2 93 89 00 CE 97'
- '8B 00 C2 9A 8D 00 CF 99 8A 00 D6 98 87 00 C3 9F'
- '92 00 CB 9D 92 00 DF 9D 90 00 E4 9A 88 00 C2 A1'
- '97 00 CB A0 92 00 C3 A6 9C 00 C8 A4 99 00 DC A4'
- '91 00 DB A9 91 00 D0 A3 99 00 E8 A7 80 00 EC AD'
- '83 00 F0 AA 82 00 F3 AB 89 00 F0 B7 80 00 FF BF'
- '85 00 F3 B2 8C 00 F8 B1 88 00 F5 BB 8C 00 F8 BE'
- '8E 00 F1 AE 9A 00 EE B2 95 00 F7 B8 96 00 C1 AC'
- 'A5 00 D7 AA A4 00 C4 B1 AD 00 D7 B0 A1 00 DA B5'
- 'A6 00 DA B4 AA 00 D9 BB AF 00 C2 BC BD 00 D0 B3'
- 'B2 00 DA BD B4 00 D0 BB BB 00 E0 B2 A5 00 EE BD'
- 'A2 00 E3 B4 AA 00 E4 BB AF 00 F1 B6 A7 00 F6 BE'
- 'A2 00 F0 BA AB 00 E5 BE B3 00 EC BC B0 00 E2 BF'
- 'BB 00 FD C9 86 00 F4 C4 97 00 FF CB 95 00 FB C4'
- '9C 00 FE CC 9D 00 FD D1 93 00 FE D5 9C 00 FE DB'
- '9E 00 EC C5 AF 00 F4 C2 A5 00 FD CD A1 00 F5 C8'
- 'AA 00 F9 CB AB 00 FD D4 A3 00 FF DE A4 00 FD D3'
- 'AC 00 FD DB A9 00 E9 C2 B7 00 F1 C2 B5 00 F3 CA'
- 'B3 00 FA D2 B3 00 FD DC B5 00 FB D6 BB 00 FB DC'
- 'BC 00 FF E0 A5 00 FF E2 AE 00 FF E3 B2 00 FE E6'
- 'BE 00 FF E8 BF 00 C3 BF C0 00 D0 C1 C1 00 DB C5'
- 'C0 00 DD C6 CC 00 DF CA CB 00 DF CF D0 00 EB C5'
- 'C0 00 EB CF CA 00 F9 CD C6 00 FC D3 C5 00 FC DC'
- 'C5 00 F0 D3 CA 00 FF D7 CB 00 FA DD CA 00 E0 CF'
- 'D0 00 E5 D7 DA 00 FA D8 D1 00 F0 DC D9 00 FE E4'
- 'C1 00 FF E9 C3 00 FF EE CE 00 F0 E0 D4 00 FC E2'
- 'D3 00 FF EE D0 00 F0 E1 DF 00 FD E5 DA 00 FE EB'
- 'DC 00 FF F0 D5 00 FE F2 DD 00 ED DE E0 00 F0 DF'
- 'E2 00 F1 E3 E3 00 FD E9 E5 00 F0 E7 EF 00 F1 EB'
- 'EC 00 FE F5 E3 00 FF F3 EB 00 FF FA EE 00 F3 EE'
- 'F0 00 FE F3 F2 00 FF FA F1 00 FF F7 FF 00 FF F9'
- 'FC 00 7F 7F 7F 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 40 B4'
- '0C 01 66 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 5F 5F 5F 5C 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 A5 99 98 76 70 60 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 7F 83 88 7E 68 74 71 67 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 65 47 A7 E3 A9 83 7E 68 75 71 6D 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 9D 8E 95 F4 F4 EA BF 82 7C 68 73 71 6D'
- '5C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 9B B1 95 F4 F4 F3 F1 E9 D0 83 7F 7A 6B'
- '76 6E 5E 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 89 BA 91 F1 F4 F3 F1 F1 EC E8 AB 83 41'
- '63 69 76 70 5E 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 62 89 C5 93 E0 E3 F1 F1 F0 F0 EB E9 E2 AA'
- '83 40 3E 68 6B 71 6D 00 00 00 00 00 00 00 00 00'
- '00 00 BE B6 B4 93 B0 90 B7 C3 DF EC EB E9 E2 E7'
- 'E7 AC 83 40 3E 7B 6C 71 70 5C 00 00 00 00 00 00'
- '00 00 AB C1 C5 94 97 4F 36 37 8F C0 D5 DB E7 E7'
- 'E7 D9 D8 AC 82 3D 20 63 6B 77 6D 00 00 00 00 00'
- '00 00 95 C2 C7 B0 91 5A 4D 36 2C 2E 43 96 BE D1'
- 'D9 D9 D8 CF CF A1 7E 3C 1B 69 CA 00 00 00 00 00'
- '00 66 95 C2 C7 B7 8D AD 4E 3A 36 2C 24 18 2B 48'
- 'A5 AC D8 CF CF CD CB A0 3D 3E 9F 60 00 00 00 00'
- '00 9E C0 C4 C7 BD 55 B2 5A 4E 3A 36 2C 24 15 14'
- '12 3D 88 9D CE CD CB A2 8A 20 9F 6D 00 00 00 00'
- '00 9E D4 C8 C9 BD 4A BA AD 5A 4E 3A 34 2C 24 15'
- '0E 0C 0C 1D 7F 99 A0 A2 A0 21 79 70 00 00 00 00'
- '00 9C E1 DD C9 C2 8E BC AD AD 5A 4E 39 36 2C 25'
- '15 0E 0C 08 07 10 3C 7B 8A 21 73 6E 00 00 00 00'
- '5D A6 E5 DE DD C4 95 B9 B3 B2 AD 5A 4E 3A 36 2D'
- '25 15 14 09 08 06 02 04 19 1A 63 6F 00 00 00 00'
- 'D0 D3 E5 E1 DE DC B8 A8 B0 B0 AF AD 5A 4E 3A 39'
- '32 26 25 15 0A 09 06 01 03 05 20 76 00 00 00 00'
- 'D0 E0 E6 E5 E1 DE DD BC 97 97 B0 94 94 90 50 3A'
- '34 32 31 26 23 14 09 01 08 0B 1A 76 00 00 00 00'
- 'AB E4 E6 E6 E5 E1 DE DD C9 C2 B7 91 8E 97 AF 50'
- '39 34 32 31 28 23 14 08 0C 0B 10 75 60 00 00 66'
- 'BF ED ED ED E6 E5 E1 DE DD C9 C9 C7 BA 92 97 AD'
- '50 39 34 32 31 26 18 17 0F 0C 0D 69 67 00 00 A1'
- 'D6 EE F2 ED E6 E6 E5 E1 DE DD C9 C8 C7 B7 52 91'
- '59 57 4D 39 32 27 16 2F 33 13 0D 61 6D 00 00 CC'
- 'EA F2 F2 EF ED ED E6 E5 DE DE DD C9 C9 C7 B1 8D'
- '8E 92 56 4C 38 35 1F 4B 4E 2E 11 3B 70 00 00 A1'
- 'F1 F4 F2 F2 F2 ED E6 E6 E5 E1 DE DD C9 C8 C7 C6'
- 'BA 94 52 51 53 46 30 54 58 4B 2A 1C 78 00 00 A1'
- 'EA EA F1 EE F2 EF ED E6 D7 C3 C4 DC DC C9 C9 C7'
- 'C7 C6 C5 B3 93 44 22 49 8E 53 45 1E 77 00 00 74'
- '98 9D D2 DA E0 E3 E4 D4 A9 87 86 B5 C1 B9 C1 C2'
- 'C7 C7 C7 C5 B4 8C 81 98 84 61 29 3F 00 00 00 00'
- '00 5B 98 98 86 A5 A6 A3 98 00 00 72 86 80 86 A4'
- 'B9 B7 BA BD BB 8B 9A 00 00 00 00 6A 00 00 00 00'
- '00 00 00 00 00 66 5D 66 00 00 00 00 00 00 00 6B'
- '7D 85 B6 B0 AE 42 76 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 9A 84 63 64 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF E3 E3 E3 FF BB BB BB FF 91 91'
+ '91 FF AE AE AE FD 89 89 89 C3 0F 0F 0F 35 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FC 3F FF FF FC 0F FF FF FC 03 FF FF F8 00'
- 'FF FF F8 00 1F FF F8 00 07 FF F8 00 01 FF F0 00'
- '00 7F F0 00 00 0F F0 00 00 07 F0 00 00 07 E0 00'
- '00 03 E0 00 00 03 E0 00 00 03 E0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 01 80 00'
- '00 01 80 00 00 01 80 00 00 01 80 00 00 01 80 00'
- '00 01 80 00 00 03 E0 18 00 7B FE 3F 80 7F FF FF'
- 'F0 FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 B8 47 1D 00 C9 45'
- '0E 00 CB 55 1F 00 D7 5F 1F 00 DE 65 1E 00 D0 59'
- '28 00 CE 68 3F 00 E2 69 24 00 E7 77 27 00 EB 7B'
- '2F 00 F0 7F 39 00 C7 6B 4E 00 DE 7A 45 00 C9 7B'
- '60 00 F3 8B 32 00 FD 9C 35 00 BE 80 70 00 BF 91'
- '7F 00 F0 96 46 00 F6 99 44 00 F7 99 44 00 E8 8D'
- '51 00 ED 8A 5E 00 FD A4 44 00 FF AA 46 00 FF AA'
- '49 00 F7 A2 52 00 FF B2 59 00 FF B5 59 00 FF B2'
- '5D 00 FF B3 5E 00 C4 84 72 00 EF A1 6B 00 FF B4'
- '62 00 FF B5 68 00 F2 A7 73 00 F8 B3 71 00 F8 B5'
- '7E 00 FF C3 73 00 FF C5 7A 00 FF C7 7A 00 96 8A'
- '85 00 96 90 8E 00 99 91 8E 00 92 91 90 00 96 95'
- '94 00 9F 97 94 00 9A 98 97 00 9C 99 98 00 9E 9C'
- '9C 00 A6 96 91 00 AD 9C 95 00 B6 9D 93 00 A6 A0'
- '9F 00 BB A0 94 00 B7 A0 9B 00 B1 A2 9F 00 BB A0'
- '9A 00 A6 A2 A3 00 AE A7 A5 00 AC A7 A8 00 B3 A3'
- 'A3 00 BF AB A6 00 BF AE AB 00 B7 AF B0 00 C9 8E'
- '82 00 C4 95 8B 00 C9 94 88 00 CD 9A 8E 00 D9 9C'
- '85 00 C3 9C 95 00 C2 9E 95 00 CE 9D 91 00 D1 9F'
- '94 00 CD A0 90 00 C6 AA 9F 00 DA A3 98 00 DF AA'
- '98 00 DF A9 9A 00 DC AB 9F 00 EC B5 8D 00 F1 B2'
- '83 00 F3 B3 8B 00 F5 B6 8A 00 F7 B5 8E 00 F7 B8'
- '8A 00 EE AC 93 00 F6 BB 99 00 CF B3 A9 00 D9 B0'
- 'A0 00 D1 B7 B1 00 D9 BD B2 00 E9 BC A3 00 E5 BE'
- 'AF 00 EA BC A8 00 FD C3 8C 00 FF D1 8F 00 FE C7'
- '92 00 F8 C3 98 00 F9 C2 9B 00 FC C1 99 00 FF C8'
- '9B 00 FA CF 9C 00 FB D0 97 00 FD CD A3 00 F8 CE'
- 'AE 00 FC D0 A1 00 F7 D0 AE 00 FF DD AC 00 F4 CB'
- 'B0 00 F2 CA B5 00 FF DF B2 00 FF E2 AD 00 FE E0'
- 'B3 00 FF E1 B3 00 FF E4 B6 00 FE E0 BA 00 D3 C0'
- 'C2 00 DE C1 C1 00 DF C4 C3 00 EF CA C3 00 EA D0'
- 'CF 00 F6 D7 CE 00 F6 DA CF 00 F3 DD CD 00 E0 D0'
- 'D1 00 EE D6 D4 00 E3 D4 D8 00 FA DF DB 00 FB E2'
- 'C7 00 FF E8 C0 00 FF E8 C1 00 FF ED CB 00 FF EC'
- 'CC 00 FF ED CC 00 EF E0 DF 00 FB E2 D3 00 FF EB'
- 'D2 00 FF F0 D5 00 FF F1 D6 00 FC E5 E0 00 FC E7'
- 'E4 00 F0 E6 EA 00 F7 ED ED 00 FB EB EA 00 FF F4'
- 'E0 00 FF F9 ED 00 FF FA F6 00 FF F6 FB 00 7F 7F'
- '7F 00 F7 B8 96 00 C1 AC A5 00 D7 AA A4 00 C4 B1'
- 'AD 00 D7 B0 A1 00 DA B5 A6 00 DA B4 AA 00 D9 BB'
- 'AF 00 C2 BC BD 00 D0 B3 B2 00 DA BD B4 00 D0 BB'
- 'BB 00 E0 B2 A5 00 EE BD A2 00 E3 B4 AA 00 E4 BB'
- 'AF 00 F1 B6 A7 00 F6 BE A2 00 F0 BA AB 00 E5 BE'
- 'B3 00 EC BC B0 00 E2 BF BB 00 FD C9 86 00 F4 C4'
- '97 00 FF CB 95 00 FB C4 9C 00 FE CC 9D 00 FD D1'
- '93 00 FE D5 9C 00 FE DB 9E 00 EC C5 AF 00 F4 C2'
- 'A5 00 FD CD A1 00 F5 C8 AA 00 F9 CB AB 00 FD D4'
- 'A3 00 FF DE A4 00 FD D3 AC 00 FD DB A9 00 E9 C2'
- 'B7 00 F1 C2 B5 00 F3 CA B3 00 FA D2 B3 00 FD DC'
- 'B5 00 FB D6 BB 00 FB DC BC 00 FF E0 A5 00 FF E2'
- 'AE 00 FF E3 B2 00 FE E6 BE 00 FF E8 BF 00 C3 BF'
- 'C0 00 D0 C1 C1 00 DB C5 C0 00 DD C6 CC 00 DF CA'
- 'CB 00 DF CF D0 00 EB C5 C0 00 EB CF CA 00 F9 CD'
- 'C6 00 FC D3 C5 00 FC DC C5 00 F0 D3 CA 00 FF D7'
- 'CB 00 FA DD CA 00 E0 CF D0 00 E5 D7 DA 00 FA D8'
- 'D1 00 F0 DC D9 00 FE E4 C1 00 FF E9 C3 00 FF EE'
- 'CE 00 F0 E0 D4 00 FC E2 D3 00 FF EE D0 00 F0 E1'
- 'DF 00 FD E5 DA 00 FE EB DC 00 FF F0 D5 00 FE F2'
- 'DD 00 ED DE E0 00 F0 DF E2 00 F1 E3 E3 00 FD E9'
- 'E5 00 F0 E7 EF 00 F1 EB EC 00 FE F5 E3 00 FF F3'
- 'EB 00 FF FA EE 00 F3 EE F0 00 FE F3 F2 00 FF FA'
- 'F1 00 FF F7 FF 00 FF F9 FC 00 7F 7F 7F 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 40 B4 0C 01 66 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 2F 31 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 45 4F 48 3D 2D 00 00'
- '00 00 00 00 00 00 00 00 00 57 8E 81 50 47 3C 2E'
- '00 00 00 00 00 00 00 00 00 63 8D 95 90 7F 4E 43'
- '3E 30 00 00 00 00 00 00 59 67 65 66 7D 8F 88 7A'
- '4D 42 38 3B 00 00 00 00 5A 6D 56 22 1B 21 5F 80'
- '7E 78 4A 20 41 00 00 00 6F 74 54 29 1E 14 0A 0D'
- '46 77 76 49 40 00 00 00 82 83 58 61 27 1C 15 09'
- '04 06 0E 44 3A 00 00 5B 8A 87 6A 64 62 28 1F 18'
- '0F 05 02 01 11 00 00 5C 92 8C 86 75 69 55 60 1D'
- '19 10 08 03 0C 32 2B 7B 93 92 8C 87 84 70 53 26'
- '23 1A 0B 13 07 36 2C 91 94 93 92 8B 85 84 72 6B'
- '52 24 17 25 16 39 00 3F 79 7C 89 5E 4C 6E 6C 73'
- '71 68 4B 35 12 2A 00 00 00 00 33 00 00 00 00 37'
- '5D 51 34 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E7 FF 00 00 E0 FF 00 00 E0 3F'
- '00 00 E0 0F 00 00 C0 03 00 00 C0 01 00 00 C0 01'
- '00 00 C0 01 00 00 80 01 00 00 80 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 F7 87 00 00 FF FF'
- '00 00 FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 99'
+ '99 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FD FD'
+ 'FD FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1 F1 FF EE EE'
+ 'EE FF E1 E1 E1 FF BD BD BD FF 92 92 92 FF 9D 9D'
+ '9D FE A5 A5 A5 F2 72 72 72 9C 0F 0F 0F 23 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FD FD FD FF FD FD FD FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F0 F0 F0 FF E8 E8 E8 FF D3 D3'
+ 'D3 FF AC AC AC FF 83 83 83 FF 90 90 90 FE AE AE'
+ 'AE F9 89 89 89 CE 42 42 42 54 0F 0F 0F 11 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FD FD FD FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF EF EF'
+ 'EF FF E6 E6 E6 FF D4 D4 D4 FF B4 B4 B4 FF 88 88'
+ '88 FF 65 65 65 FF 93 93 93 FF BA BA BA FC 95 95'
+ '95 E3 5E 5E 5E 7D 0F 0F 0F 1F 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF ED ED ED FF DD DD DD FF C7 C7'
+ 'C7 FF A8 A8 A8 FF 82 82 82 FF 5B 5B 5B FF 72 72'
+ '72 FF B7 B7 B7 FF C2 C2 C2 FE A1 A1 A1 F0 74 74'
+ '74 A4 19 19 19 30 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF EE EE EE FF CB CB CB FF 97 97 97 FF 6B 6B'
+ '6B FF 5D 5D 5D FF 8B 8B 8B FF C5 C5 C5 FF D5 D5'
+ 'D5 FF C9 C9 C9 FE AD AD AD F7 86 86 86 C5 37 37'
+ '37 4B 0F 0F 0F 10 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FD FD FD FF FD FD FD FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF E9 E9 E9 FF AA AA AA FF 93 93 93 FF C5 C5'
+ 'C5 FF ED ED ED FF E4 E4 E4 FF D9 D9 D9 FF CD CD'
+ 'CD FE B7 B7 B7 FC 92 92 92 DD 56 56 56 6F 0F 0F'
+ '0F 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FE FE FE FF FD FD FD FF FD FD FD FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
+ 'F6 FF EC EC EC FF B0 B0 B0 FF BF BF BF FF F3 F3'
+ 'F3 FF E8 E8 E8 FF DC DC DC FF D1 D1 D1 FF C0 C0'
+ 'C0 FE 9E 9E 9E EC 6F 6F 6F 97 15 15 15 29 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D'
+ '9D 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8'
+ 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7'
+ 'F7 FF F3 F3 F3 FF C8 C8 C8 FF 96 96 96 FF EC EC'
+ 'EC FF E0 E0 E0 FF D5 D5 D5 FF C8 C8 C8 FE AB AB'
+ 'AB F5 81 81 81 BB 2E 2E 2E 41 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D'
+ '9D 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FC FC FC FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF FA FA FA FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F5 F5 F5 FF DA DA DA FF 85 85 85 FF DB DB'
+ 'DB FF D8 D8 D8 FF CD CD CD FE B4 B4 B4 FB 8F 8F'
+ '8F D6 4D 4D 4D 62 0F 0F 0F 17 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D5 C9'
- 'BE 1C DC C8 BE 54 D4 C6 BE 54 CF C4 BF 54 CB C4'
- 'BF 54 CF C7 C2 41 D2 CA C6 2E D6 CE C9 1B DA D3'
- 'CD 0C D8 D2 C9 03 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D'
+ '9D 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FD FD FD FF FC FC FC FF FC FC FC FF FB FB'
+ 'FB FF FB FB FB FF FA FA FA FF FA FA FA FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF E4 E4 E4 FF 96 96 96 FF B5 B5'
+ 'B5 FF D1 D1 D1 FF BF BF BF FD 9B 9B 9B E8 67 67'
+ '67 8A 0F 0F 0F 24 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D'
+ '9D 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FE'
+ 'FE FF FE FE FE FF FD FD FD FF FC FC FC FF FC FC'
+ 'FC FF FB FB FB FF FB FB FB FF FA FA FA FF FA FA'
+ 'FA FF F9 F9 F9 FF F9 F9 F9 FF F8 F8 F8 FF F8 F8'
+ 'F8 FF F7 F7 F7 FF E6 E6 E6 FF A0 A0 A0 FF A1 A1'
+ 'A1 FF C6 C6 C6 FE A7 A7 A7 F3 7B 7B 7B B1 25 25'
+ '25 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DC C8'
- 'BE 54 F0 C5 BC FF DA BF BE FF CA BA BF FF BF B8'
- 'BF FF C9 C2 C9 C3 D4 CC D4 8A DF D8 DF 54 EA E7'
- 'EA 26 E6 E2 DF 0A 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D'
+ '9D 6B FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FE FE FE FF FD FD FD FF FC FC'
+ 'FC FF FC FC FC FF FB FB FB FF FB FB FB FF FA FA'
+ 'FA FF FA FA FA FF F9 F9 F9 FF F8 F8 F8 FF F7 F7'
+ 'F7 FF F1 F1 F1 FF D7 D7 D7 FF 9A 9A 9A FF A4 A4'
+ 'A4 FE B2 B2 B2 F9 8C 8C 8C CE 40 40 40 57 0F 0F'
+ '0F 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A2 A2'
+ 'A2 68 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FD FD FD FF FD FD'
+ 'FD FF FC FC FC FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF F9 F9 F9 FF F5 F5 F5 FF ED ED'
+ 'ED FF DB DB DB FF B7 B7 B7 FF 96 96 96 FE B1 B1'
+ 'B1 FC 98 98 98 E2 5F 5F 5F 7C 0F 0F 0F 1F 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 BE'
- 'B4 54 E5 A7 9E FF DE 9C 90 FF D5 96 89 FF CA 95'
- '89 FF C6 A1 9B EB C2 AE AD D8 BF BD BF C6 CA C9'
- 'CA 96 D3 D0 D1 6B DA D2 D4 43 E1 DA DB 24 DE D7'
- 'D4 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 B5 B5'
+ 'B5 5C FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FE FE FE FF FD FD'
+ 'FD FF FD FD FD FF FC FC FC FF FB FB FB FF FB FB'
+ 'FB FF FA FA FA FF F8 F8 F8 FF F3 F3 F3 FF E7 E7'
+ 'E7 FF D3 D3 D3 FF BC BC BC FF BA BA BA FD AB AB'
+ 'AB E7 7E 7E 7E 99 1A 1A 1A 2C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 B7'
- 'AB 54 E0 91 84 FF E3 95 84 FF E3 9B 88 FF DF A2'
- '8F FF D4 9B 8C FF C9 99 8E FF BF 9D 95 FF BF A9'
- 'A3 DF C4 B8 B6 BD CF C9 CF 98 DA D4 DA 6C DA D5'
- 'D6 47 D1 CC C4 27 D8 D1 CB 17 D8 D0 C9 0A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 7D 7D'
+ '7D 1E AE AE AE 58 9B 9B 9B 64 97 97 97 67 97 97'
+ '97 67 97 97 97 67 97 97 97 67 97 97 97 67 94 94'
+ '94 67 94 94 94 67 94 94 94 67 94 94 94 67 94 94'
+ '94 67 94 94 94 67 94 94 94 67 92 92 92 67 92 92'
+ '92 67 92 92 92 67 92 92 92 67 92 92 92 67 92 92'
+ '92 67 8F 8F 8F 67 8F 8F 8F 67 8F 8F 8F 67 8C 8C'
+ '8C 66 8C 8C 8C 66 8C 8C 8C 66 89 89 89 66 80 80'
+ '80 67 76 76 76 67 75 75 75 66 71 71 71 62 62 62'
+ '62 4F 36 36 36 27 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 B2'
- 'A4 54 E0 84 6F FF EA AB 9A FF F5 C9 BA FF FF DF'
- 'D0 FF F4 AF 9A FF E9 8C 75 FF DF 78 5F FF C9 88'
- '74 FF BA 9A 8F FF B0 AF B0 FF BA B9 BA DB C5 C4'
- 'C5 AE D0 D0 D0 78 E4 DF E4 46 E5 DD DF 1E 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3314,423 +3154,138 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 DF C7 BD 71 E7 B4'
- 'A6 C6 EA 90 79 FF ED A1 8F FF F4 C1 B6 FF FF F2'
- 'EF FF FB E2 DD FF F7 D2 CA FF F4 C1 B4 FF E6 AA'
- '98 FF D6 98 84 FF C5 89 7A FF C1 94 8B F3 BD A4'
- 'A1 E4 BA BA BA D1 C8 C3 C8 B1 CF C9 CD 89 D0 CD'
- 'CA 5B D7 D4 D1 39 D8 D3 CD 1A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 C4 BA A9 F1 B9'
- 'A8 FF F4 A9 8A FF F0 A0 8A FF F4 BC B0 FF FF FC'
- 'FF FF FF FC FF FF FF F6 F8 FF FF EC EA FF F8 CE'
- 'C3 FF EC B3 A2 FF DA 99 89 FF D2 96 89 FF C9 97'
- '8D FF BF 9C 95 FF BF A3 9F EF C1 AF AD D5 C5 C1'
- 'C0 B0 CF CC CD 8A D3 CF CF 60 D1 C9 C4 33 D4 CE'
- 'C8 22 D5 CE C6 10 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 0F FF FF C0 00 00 00 00 0F FF FF C0'
+ '00 00 00 00 1F FF FF C0 00 00 00 00 3F FF FF C0'
+ '00 00 00 00 7F FF FF C0 00 00 00 00 7F FF FF C0'
+ '00 00 00 00 FF FF FF C0 00 00 00 01 FF FF FF C0'
+ '00 00 00 01 FF FF FF C0 00 00 00 03 FF FF FF C0'
+ '00 00 00 07 FF FF FF C0 00 00 00 0F FF FF FF FF'
+ 'FF FF FF FF FF FF'
+} */
+
+
+/* BINRES folder.ico */
+3 ICON folder.ico
+ /* {
+ '00 00 01 00 0C 00 10 10 10 00 01 00 04 00 28 01'
+ '00 00 C6 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 EE 01 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 56 07 00 00 20 20 10 00 01 00 04 00 E8 02'
+ '00 00 BE 0B 00 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 A6 0E 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 4E 17 00 00 30 30 10 00 01 00 04 00 68 06'
+ '00 00 F6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 5E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 06 3D 00 00 40 40 10 00 01 00 04 00 68 0A'
+ '00 00 AE 62 00 00 40 40 00 00 01 00 08 00 28 16'
+ '00 00 16 6D 00 00 40 40 00 00 01 00 20 00 28 42'
+ '00 00 3E 83 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 C2 B5 A9 F4 C3'
- 'AA FF FF CD A0 FF F4 A9 8A FF F4 B8 AA FF FF FC'
- 'FF FF FF FC FF FF FF FA FF FF FF F7 FF FF FF F3'
- 'F5 FF FA EB EA FF F0 DF DF FF EF BD B4 FF E9 9B'
- '89 FF DF 77 5F FF CA 7F 6A FF BA 8F 7F FF B0 A7'
- 'A0 FF B9 B1 B4 F3 C4 BC C4 D2 CF C8 CF 9C DA D7'
- 'DA 66 DB D8 D5 32 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 78'
+ '78 78 78 78 78 00 F8 FF FF FF FF F8 88 70 FF F4'
+ 'F4 F4 FF FF 88 70 FF 4F 4F 4F 4F FF 88 70 F8 FF'
+ 'FF FF FF F8 88 70 F8 88 88 88 88 88 88 70 F8 88'
+ '88 88 88 88 88 70 F8 88 88 88 88 88 88 70 F8 88'
+ '88 88 88 88 88 70 86 66 66 66 87 87 87 00 0E FE'
+ 'FE FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 80 03 00 00 00 01 00 00 00 01'
+ '00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01'
+ '00 00 00 01 00 00 00 01 00 00 00 03 00 00 80 FF'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 75 72'
+ '6D 00 7A 75 6C 00 6F 70 70 00 74 74 75 00 7B 79'
+ '7B 00 7A 7B 7B 00 7D 7E 7E 00 8A 84 78 00 B7 97'
+ '7C 00 BD A5 77 00 FF 00 FF 00 82 81 85 00 84 84'
+ '84 00 8A 8A 8A 00 8C 8B 8C 00 8C 8C 8C 00 8D 8D'
+ '8D 00 8E 8E 8E 00 8F 8F 8F 00 90 90 90 00 90 90'
+ '91 00 92 92 92 00 93 93 93 00 96 96 96 00 97 97'
+ '97 00 98 98 98 00 99 99 99 00 9A 9A 9A 00 9A 9A'
+ '9E 00 9B 9C 9C 00 9C 9C 9C 00 9C 9D 9E 00 9E 9E'
+ '9E 00 9F 9F 9F 00 A0 99 8C 00 BD 9D 85 00 A0 A0'
+ 'A0 00 A1 A1 A1 00 A2 A3 A3 00 A3 A3 A3 00 A2 A3'
+ 'A4 00 A3 A4 A5 00 A5 A5 A5 00 A4 A5 A7 00 A6 A6'
+ 'A6 00 A7 A7 A7 00 A6 A7 A9 00 A7 A8 AA 00 A9 A9'
+ 'A9 00 A8 A9 AA 00 A9 A9 AA 00 AB AB AB 00 AA AB'
+ 'AC 00 AC AC AC 00 AC AE AF 00 AE AE AE 00 AF AF'
+ 'AF 00 AC AF B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3'
+ 'B3 00 B0 B2 B4 00 B1 B3 B5 00 B3 B5 B6 00 B5 B7'
+ 'B7 00 B6 B6 B6 00 B7 B7 B7 00 B6 B7 B9 00 B7 B9'
+ 'BA 00 BA BA BA 00 BB BC BB 00 BA BC BC 00 BB BC'
+ 'BE 00 BC BC BC 00 BE BE BE 00 C7 B2 89 00 DF CC'
+ 'A6 00 D1 C5 B0 00 E4 D0 BE 00 F2 DE B8 00 FB E6'
+ 'BF 00 BE BF C0 00 C1 C1 C1 00 C1 C3 C5 00 C4 C4'
+ 'C4 00 C4 C6 C7 00 DA CA C2 00 DC D9 D2 00 D8 D8'
+ 'D9 00 DF DF DF 00 E3 D4 C6 00 FE EE C7 00 E1 E1'
+ 'E1 00 E4 E4 E4 00 F1 E9 E1 00 F0 F1 F1 00 F2 F2'
+ 'F2 00 F4 F4 F5 00 F5 F5 F6 00 F5 F6 F6 00 F6 F6'
+ 'F7 00 F6 F7 F8 00 F7 F7 F8 00 F6 F8 F9 00 F7 F8'
+ 'F9 00 F8 F8 F9 00 F9 FA FA 00 FB FC FD 00 FC FC'
+ 'FD 00 FF FF FD 00 FD FE FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 B8 A6 A9 F4 BA'
- '9C FF FF D1 A0 FF F4 A7 83 FF F4 B5 A2 FF FF FC'
- 'FF FF FF FC FF FF FF FA FF FF FF F7 FF FF FF F3'
- 'F5 FF FD EE EE FF FA E9 EA FF F3 DE DC FF ED CF'
- 'CA FF EA BC B4 FF E3 A9 9B FF DA 97 83 FF CF 87'
- '6A FF C4 8B 78 FB BD 97 8F F0 BA AC AF DD C4 BC'
- 'C0 CB CC C5 C9 A8 D0 C8 C9 73 D7 CF D0 50 D7 D0'
- 'CD 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 AF 9C A9 F4 B4'
- '93 FF FF D9 A5 FF F4 AB 81 FF F4 B5 9D FF FF F8'
- 'FA FF FF F9 FD FF FF F9 FF FF FF F7 FF FF FF F3'
- 'F5 FF FD F0 F0 FF FA EF F0 FF F3 EF F0 FF F0 EA'
- 'EC FF F0 E1 E5 FF EF CA C4 FF EB B2 A3 FF E4 9A'
- '7F FF D3 8F 78 FF C7 8C 7C FF BF 91 89 FF C2 9A'
- '94 FE C4 A6 A4 EC C4 B4 B9 C9 CB C3 C8 A5 CE C9'
- 'CA 77 CC C6 BF 3F D2 CB C6 2E D8 D0 CB 1C DB D3'
- 'CF 0C D5 CD C4 04 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 AA 95 A9 F4 B2'
- '90 FF FF E4 B0 FF F5 B6 85 FF F5 BA 9A FF FF F1'
- 'F0 FF FF F5 FA FF FF F7 FF FF FF F7 FF FF FF F3'
- 'F5 FF FA F0 F0 FF F0 EF F0 FF F0 EF F0 FF F0 EC'
- 'EF FF F0 E7 EF FF F0 E3 E5 FF F0 E2 E0 FF F0 E2'
- 'E0 FF E5 C0 B5 FF DF 9C 8A FF DF 77 5F FF D4 71'
- '55 FF C4 79 64 FF B0 90 8F FF B0 A5 A4 FF B5 B5'
- 'B5 EA C0 C0 C0 C0 D4 CF D4 8A E4 DC E4 56 EF E8'
- 'EF 26 DB D4 CF 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 D8 C8 BE 38 E6 C6 BD A9 EC B6 A2 E2 F4 BE'
- '9A FF FF E0 A5 FF F5 BA 88 FF F5 B6 90 FF FF D3'
- 'BA FF FF D2 AF FF FF D9 BB FF FF E7 DF FF FF ED'
- 'EA FF FA F0 F0 FF F0 EF F0 FF F0 EF F0 FF F0 EC'
- 'EF FF F0 E7 EF FF F0 E3 E5 FF F0 E2 E0 FF F0 E2'
- 'E0 FF EC D5 D1 FF E9 C8 C3 FF E9 BC B4 FF DF A8'
- '9C FF D6 94 85 FF CF 80 6F FF C8 7F 6F FF C2 88'
- '7B F8 BF 9A 94 E9 BF B0 B1 D8 C5 C1 C5 BC CF CC'
- 'CF 98 D0 CD CC 6C D7 D3 D1 45 E5 DD DE 23 D8 D0'
- 'C9 0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DC C8 BE 54 F0 C5 BD FF F3 C0 AD FF F8 C9'
- 'A3 FF FF DE A0 FF F5 BD 8A FF F5 B4 8A FF FF C3'
- '9F FF FF BD 83 FF FF C0 84 FF FF CB A4 FF FF D2'
- 'B3 FF FA D9 C3 FF F0 E1 D5 FF F0 EA E7 FF F0 EC'
- 'EF FF F0 E7 EF FF F0 E3 E5 FF EF E1 E0 FF EF E1'
- 'E0 FF EF DF E0 FF EF DF E0 FF EF DF E0 FF E5 CB'
- 'CA FF DF B2 AC FF DF 95 84 FF D8 89 79 FF D0 84'
- '76 FF C9 86 79 FF BF 8F 84 FF BC 9B 93 F5 BF A9'
- 'A5 E0 C3 BA B7 BD CD C9 CA 97 DF D7 DF 6F D5 CF'
- 'CD 45 D4 CF C8 25 DB D6 CF 0E D5 CE C4 04 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DC C9 BF 54 F0 C7 BF FF FA CA B5 FF FF D2'
- 'AA FF FF DE A0 FF F5 BF 8A FF F5 B5 8A FF FF BF'
- '9F FF FF B5 74 FF FF AD 59 FF FF A5 4F FF FF A1'
- '4F FF FA AC 6A FF F0 C7 A0 FF F0 E1 D5 FF F0 EC'
- 'EF FF F0 E7 EF FF F0 E3 E5 FF EF E1 E0 FF EF DF'
- 'E0 FF EF DF E0 FF EF DF E0 FF EF DF E0 FF E5 D9'
- 'DF FF E0 D4 DA FF E0 D0 D0 FF DF C4 C4 FF DF AB'
- 'A4 FF E0 84 6F FF D5 6A 4F FF CA 68 4F FF BF 7F'
- '70 FF B5 99 8F FF B5 AC AA F6 BF B8 BF E4 CA C7'
- 'CA AE DA DA DA 70 F0 EF F0 2C DC D6 CF 0E 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DB C3 B7 54 EF B5 A9 FF F9 D0 B4 FF FF DE'
- 'B4 FF FF E2 AA FF FB C7 95 FF F8 BA 8E FF F5 B9'
- '95 FF FB BD 7F FF FF B9 6B FF FF AD 59 FF FF A6'
- '52 FF FA A4 54 FF F0 A7 60 FF F0 AC 71 FF F0 B5'
- '88 FF F0 BF A5 FF F0 D0 C4 FF EF DA D8 FF EF DF'
- 'E0 FF EF DF E0 FF EB DD DF FF E5 D9 DF FF E1 D7'
- 'DF FF E0 D4 DA FF E0 D0 D0 FF DF CB CC FF DF C3'
- 'C1 FF DF B5 AF FF DB A2 96 FF D4 92 81 FF CA 85'
- '70 FF C7 7A 64 FF C3 7D 6A FC BF 8C 7F F6 C2 AA'
- 'A6 E4 CF C6 C8 C0 E4 DF E4 8A D8 D1 CB 2E 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DB BF B2 54 EF AB 9A FF F9 D2 B2 FF FF E5'
- 'BA FF FF E4 B0 FF FF CE 9E FF FA BD 91 FF F0 B1'
- '8A FF FA C1 83 FF FF C1 74 FF FF B3 5F FF FF AC'
- '57 FF FB A4 4F FF F5 9B 44 FF F1 95 41 FF EF 96'
- '4B FF EF 9D 65 FF EF AB 84 FF ED B8 9F FF EA C4'
- 'B5 FF EA CD C6 FF E6 D3 D4 FF E0 D7 DF FF E0 D5'
- 'DB FF E0 D3 D6 FF E0 CF D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF CF D0 FF DF C2 C1 FF DA B1 AA FF D0 9A'
- '8A FF D0 85 74 FF CC 78 64 FF C4 74 5A FF C0 90'
- '84 FF C7 B0 AF EB D9 D2 D9 C5 DB D5 D2 4C D8 D2'
- 'C9 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DC BE AF 54 F0 A8 90 FF FA D2 AF FF FF E6'
- 'BA FF FF E4 B0 FF FF D4 A4 FF FA BF 94 FF F0 A7'
- '80 FF FA BF 80 FF FF C5 75 FF FF B8 60 FF FF B3'
- '5F FF FF AD 59 FF FF A5 4F FF F5 9B 45 FF EF 8F'
- '3A FF EF 80 30 FF EF 75 25 FF EA 7A 35 FF E0 90'
- '60 FF E0 AA 94 FF E0 C2 BE FF E0 D7 DF FF E0 D2'
- 'D5 FF E0 CF D0 FF E0 CF D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF CF D0 FF DF C9 CF FF DA C4 CA FF D0 C0'
- 'C0 FF D0 BA BF FF D0 9F 9A FF D0 6F 50 FF C4 79'
- '65 FF C4 97 8F F3 CF C8 CF DD E4 E2 E4 69 E6 E3'
- 'DF 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 C7'
- 'BD 71 EB C1 B4 C6 F0 B8 A4 FF FA D7 B6 FF FF E5'
- 'BA FF FF E4 B0 FF FF DE AC FF FA CA 9C FF F0 A7'
- '80 FF FA C7 8E FF FF CF 86 FF FF BD 69 FF FF B8'
- '63 FF FF B2 5D FF FF AD 59 FF FB A4 4F FF F6 9A'
- '44 FF EF 8F 3A FF EF 81 30 FF ED 7A 2E FF EA 7A'
- '35 FF E2 7F 46 FF DF 87 5B FF DF 92 74 FF DF A6'
- '94 FF DF BA B3 FF E0 CF D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF CF D0 FF DF C9 CF FF DA C4 CA FF D0 C0'
- 'C0 FF D0 BD BF FF D0 AD A8 FF D0 8E 7A FF C5 7D'
- '65 FF C1 8E 7E F9 C5 C2 C5 EF E1 E0 E1 79 E6 E2'
- 'DF 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E7 C8'
- 'BD A9 F3 C7 BA FF F5 C7 B4 FF FB DC BB FF FF E6'
- 'BB FF FF E4 B5 FF FF E4 B1 FF F9 CD 9E FF EF 9F'
- '7A FF F9 CA 97 FF FF D6 95 FF FF C4 74 FF FF BD'
- '6A FF FF B8 63 FF FF B3 5F FF FF AC 57 FF FB A4'
- '4F FF F5 9B 44 FF F1 8E 3A FF EF 81 30 FF EF 75'
- '25 FF E4 6D 21 FF DF 6B 26 FF DF 6D 34 FF DB 7F'
- '57 FF DA 92 78 FF DA A7 95 FF DA B1 A6 FF DB BC'
- 'B8 FF DF C9 CA FF DF C7 CD FF DA C4 CA FF D0 C0'
- 'C0 FF D0 BF C0 FF D0 B6 B3 FF D0 A4 9A FF C8 7C'
- '65 FF C3 84 71 FD BF BD BF FB DF DC DF 88 E5 E1'
- 'DF 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 CC'
- 'BF A9 F5 D0 BF FF FF D7 BF FF FF E2 BF FF FF E7'
- 'BF FF FF E6 BF FF FF E4 B5 FF F9 C7 9A FF EF 8F'
- '70 FF F9 C7 9A FF FF DC A0 FF FF CC 80 FF FF C4'
- '74 FF FF BD 6A FF FF B8 60 FF FF B3 5F FF FF AD'
- '59 FF FF A5 4F FF F5 9B 45 FF EF 8F 3A FF EF 80'
- '30 FF E5 75 25 FF DF 6D 1F FF DF 67 1F FF D5 5D'
- '1F FF D0 57 1F FF D0 57 1F FF D0 74 54 FF D5 97'
- '89 FF DF BF BF FF DF C4 C9 FF DA C4 CA FF D0 C0'
- 'C0 FF D0 BF C0 FF D0 BA BA FF D0 B0 B0 FF D0 78'
- '64 FF CA 7A 69 FF BF B7 BF FF DE D7 DE 95 E5 DE'
- 'DF 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 C0'
- 'B1 A9 F4 CA B5 FF FF E6 CA FF FF E7 C3 FF FF E7'
- 'BF FF FF E7 BF FF FF E6 BB FF F9 CD A4 FF EF 9E'
- '7A FF F9 CE A5 FF FF DD A7 FF FF CC 80 FF FF C9'
- '7C FF FF C4 74 FF FF BD 69 FF FF B8 63 FF FF B2'
- '5A FF FF AC 4F FF FB A4 4B FF F6 9A 44 FF EF 8F'
- '3A FF EB 81 2F FF E6 76 26 FF DF 6D 1F FF DB 65'
- '1F FF D6 5E 1F FF D0 57 1F FF CF 5D 2A FF D1 65'
- '38 FF D4 6D 4A FF D4 82 69 FF D2 97 89 FF D0 AF'
- 'AA FF D0 B9 B8 FF D0 BC BE FF D0 B8 BA FF D0 7B'
- '68 FF C7 79 66 FF B5 B2 B5 FF D4 D2 D4 A1 DE DA'
- 'D8 4C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 BB'
- 'AA A9 F4 C7 B1 FF FF EF D5 FF FF EC CA FF FF E9'
- 'C3 FF FF E8 C0 FF FF E7 BF FF FA D1 AB FF F0 A7'
- '85 FF FA CE AC FF FF DB AC FF FF CE 85 FF FF CC'
- '81 FF FF C9 7C FF FF C4 74 FF FF BD 6A FF FF B8'
- '5F FF FF B2 55 FF FF AC 54 FF FB A4 4F FF F5 9B'
- '44 FF F4 8E 39 FF EF 81 2F FF E5 75 24 FF E1 6D'
- '21 FF DB 65 1F FF D5 5C 1F FF D1 55 18 FF CF 4E'
- '13 FF CF 48 10 FF CF 58 2B FF CD 6C 4A FF CA 82'
- '6A FF C7 91 83 FF C7 9E 96 FF CA A9 A4 FF CE 7C'
- '68 FF C7 7B 68 FF B5 A7 A5 FF CE C9 C8 AD D7 D4'
- 'D1 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 BB'
- 'AA A9 F5 C9 B5 FF FF F3 DF FF FF F0 D4 FF FF EC'
- 'CA FF FF E8 C0 FF FF E8 C0 FF FA D2 AF FF F0 A7'
- '8F FF FA C6 AE FF FF D6 AF FF FF D4 90 FF FF CE'
- '85 FF FF CC 80 FF FF CC 80 FF FF C4 74 FF FF BD'
- '6A FF FF B8 60 FF FF B3 5F FF FF AD 59 FF FF A5'
- '4F FF FF 9B 44 FF F9 8F 39 FF EF 80 2F FF E5 75'
- '25 FF DF 6D 1F FF DF 67 1F FF D5 5D 1F FF CF 55'
- '1A FF CF 4F 10 FF CF 48 10 FF CA 40 0A FF C0 38'
- '00 FF B5 47 1F FF B5 60 45 FF C0 84 70 FF CA 7B'
- '64 FF CA 81 6E FF BF 97 8F FF CA BC BA BA D0 CE'
- 'CA 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 D9 C9 BE 38 E8 C7 BD A9 F4 C3'
- 'B7 E2 FB D1 BF FF FF F1 D5 FF FF EF D1 FF FF ED'
- 'CD FF FF EC C9 FF FF E9 C3 FF FA D6 B3 FF F0 B2'
- '99 FF F3 BB A4 FF F8 C7 A8 FF FF D6 A5 FF FF D7'
- 'A1 FF FF D5 98 FF FF CE 89 FF FF C7 7F FF FF C2'
- '74 FF FF BD 69 FF FF B8 63 FF FF B2 5D FF FF AC'
- '59 FF FF A8 4F FF FD A2 44 FF F9 99 3A FF F6 8D'
- '2F FF F0 82 2A FF E9 77 29 FF DF 69 22 FF D6 5D'
- '1D FF CF 54 19 FF CF 4E 13 FF CD 47 0E FF C9 40'
- '0A FF B8 38 0E FF B1 3F 1A FF B5 56 30 FF C0 56'
- '32 FF C3 68 4B FF BF 8A 7A FF CA B5 B2 C6 D6 D2'
- 'D4 73 E5 E3 DF 07 D8 D2 C9 02 00 00 00 00 00 00'
- '00 00 00 00 00 00 DC C9 C0 54 F2 C9 C2 FF FA CD'
- 'C3 FF FF DA C9 FF FF F1 D5 FF FF EF D1 FF FF EE'
- 'CF FF FF EE CF FF FF EB C8 FF FB DE BC FF F5 C7'
- 'A9 FF F5 BE A3 FF F6 BE A0 FF FA C7 A0 FF F9 C7'
- '9F FF FB C8 9B FF FF C9 94 FF FF CA 8D FF FF C9'
- '84 FF FF C6 79 FF FF BE 6B FF FF B8 63 FF FF B3'
- '5F FF FF B0 58 FF FF AD 4F FF FF A9 44 FF FF 9F'
- '3A FF FB 95 35 FF F4 8C 34 FF ED 7D 2A FF E4 6F'
- '22 FF DA 62 1F FF D6 59 18 FF D2 50 13 FF CF 48'
- '10 FF B9 32 05 FF B1 30 06 FF B5 44 14 FF BC 46'
- '1B FF C0 58 38 FF C0 7D 6A FF C6 AD AA D2 D6 D3'
- 'D6 83 F0 EF F0 12 DC D6 CF 06 00 00 00 00 00 00'
- '00 00 00 00 00 00 DC CB C4 54 F0 CF CF FF FA D9'
- 'CF FF FF E5 D4 FF FF F3 DF FF FF F1 D5 FF FF EF'
- 'D0 FF FF EE D0 FF FF EE CF FF FF EC CA FF FF E7'
- 'C0 FF FF D0 AA FF FA BB 95 FF F0 A7 80 FF EF 9E'
- '80 FF F4 A6 8A FF FF BF A0 FF FF CC A0 FF FF D4'
- '9A FF FF D4 90 FF FF C6 7A FF FF BD 6A FF FF B8'
- '60 FF FF B3 5F FF FF B0 59 FF FF AF 4F FF FF A9'
- '45 FF FF A6 40 FF FF A6 40 FF FF 9A 35 FF FA 8A'
- '2A FF F0 78 20 FF E4 67 1F FF D9 59 1A FF CF 4F'
- '10 FF B9 34 05 FF B4 34 0A FF C0 4F 1F FF C0 49'
- '1F FF C0 54 34 FF C0 6F 5F FF C0 A4 9F DF CF CF'
- 'CF 95 F0 EF F0 23 DC D6 CF 0B 00 00 00 00 00 00'
- '00 00 00 00 00 00 DC C8 BD 54 F0 C4 BA FF FA E0'
- 'CF FF FF EF DB FF FF F3 DF FF FF F2 DB FF FF F1'
- 'D6 FF FF EF D0 FF FF EE CF FF FF ED CD FF FF EC'
- 'C9 FF FF E1 BC FF FD D8 B1 FF F9 D2 AA FF F9 C8'
- 'A3 FF FB C2 9C FF FF BF 95 FF F7 AE 86 FF F4 A8'
- '81 FF F4 AD 85 FF FB BC 8C FF FF C4 8A FF FF C7'
- '7F FF FF BB 6A FF FF B3 5A FF FF AF 4F FF FF AD'
- '4B FF FF AA 46 FF FF A6 40 FF FF A1 3C FF FD 9B'
- '35 FF F9 91 2A FF F6 85 29 FF EB 72 24 FF D9 59'
- '19 FF BD 3F 0F FF B8 3D 11 FF C9 54 1F FF C3 4F'
- '1F FF C3 54 2D FF C9 65 4A FF C2 9D 98 EB CF CA'
- 'CF A7 EF EA EF 32 DB D4 CF 11 00 00 00 00 00 00'
- '00 00 00 00 00 00 DC C5 B9 54 F0 BD AF FF FA E3'
- 'D3 FF FF F6 E3 FF FF F4 DF FF FF F3 DF FF FF F2'
- 'DB FF FF F1 D5 FF FF EF D1 FF FF EE CF FF FF EE'
- 'CF FF FF EB C8 FF FF E9 C3 FF FF E8 C0 FF FF E0'
- 'B8 FF FF D7 AE FF FF CC 9F FF F7 B6 8D FF F4 AB'
- '86 FF F4 AA 8A FF F7 B0 8E FF FB BC 93 FF FF CE'
- '99 FF FF C3 7A FF FF BA 63 FF FF B2 55 FF FF B0'
- '51 FF FF AD 4B FF FF A9 44 FF FF A7 41 FF FF A4'
- '3C FF FF A1 35 FF FF 98 31 FF F6 85 2B FF E4 67'
- '24 FF CC 50 1D FF C4 4B 1B FF CF 59 1F FF C8 54'
- '1F FF C8 55 28 FF CF 5C 3A FF C1 97 8F F6 C9 C4'
- 'C9 B7 EA E5 EA 42 DA D3 CD 16 00 00 00 00 00 00'
- '00 00 00 00 00 00 DC C4 B9 54 F0 BA AF FF FA E4'
- 'DA FF FF F8 EA FF FF F6 E0 FF FF F4 DF FF FF F3'
- 'DF FF FF F3 DF FF FF F1 D5 FF FF EF D0 FF FF EE'
- 'D0 FF FF EE CF FF FF EC CA FF FF E8 C0 FF FF E8'
- 'C0 FF FF E7 BF FF FF E6 BF FF FF E4 B5 FF FF DC'
- 'AA FF FF CD A0 FF F4 A3 7F FF F4 A3 84 FF FF CC'
- 'B0 FF FF CC 90 FF FF C5 75 FF FF B8 60 FF FF B2'
- '55 FF FF AF 4F FF FF AF 4F FF FF A9 45 FF FF A6'
- '40 FF FF A6 40 FF FF A1 35 FF FA 92 2F FF F0 78'
- '2F FF E4 68 2F FF D9 60 2A FF CF 60 20 FF CF 5A'
- '1F FF CF 56 24 FF D0 54 2F FF BA 91 84 FF BF BF'
- 'BF C5 E0 DF E0 52 D6 D1 CA 1B 00 00 00 00 00 00'
- '00 00 E1 C8 BD 71 EE C7 BC C6 F9 C8 BA FF FD E9'
- 'DE FF FF F9 EE FF FF F8 EA FF FF F6 E3 FF FF F4'
- 'DF FF FF F3 DF FF FF F2 DB FF FF F1 D6 FF FF EF'
- 'D0 FF FF EE CF FF FF ED CD FF FF EC C9 FF FF E9'
- 'C3 FF FF E7 BF FF FF E7 BF FF FF E6 BB FF FF E2'
- 'B4 FF FF DC AA FF FB C4 98 FF F4 B1 8C FF EA A3'
- '85 FF F8 C3 97 FF FF CF 91 FF FF C5 75 FF FF BA'
- '63 FF FF B3 56 FF FF AF 4F FF FF AD 4B FF FF AA'
- '46 FF FF A6 40 FF FF A4 3C FF FA 93 36 FF F0 72'
- '2F FF F2 81 3D FF EF 88 3F FF E4 84 35 FF D6 6A'
- '26 FF CF 5A 24 FF D0 54 2F FF C1 86 76 FF C3 B1'
- 'AD CB D5 D5 D5 64 D3 CD C6 21 00 00 00 00 00 00'
- '00 00 E7 CA C1 AA F6 CE C5 FF FF D6 CA FF FF EE'
- 'E3 FF FF FA F0 FF FF FA F0 FF FF F8 E8 FF FF F6'
- 'E3 FF FF F4 DF FF FF F3 DF FF FF F2 DB FF FF F1'
- 'D5 FF FF EF D1 FF FF EE CF FF FF EF CF FF FF EB'
- 'C8 FF FF E9 C3 FF FF E8 C0 FF FF E7 BF FF FF E6'
- 'BB FF FF E4 B5 FF FF DA AA FF F8 C2 97 FF EA 9F'
- '7A FF F1 B1 8C FF F6 BB 8E FF F9 BB 80 FF FD B8'
- '75 FF FF B6 6C FF FF B5 64 FF FF B4 5D FF FF B0'
- '53 FF FF A9 45 FF FF A7 41 FF F8 92 3A FF EA 6A'
- '2F FF F8 92 48 FF FB A5 51 FF F5 A1 4A FF E2 7E'
- '35 FF D6 65 2B FF D0 57 2F FF C4 7D 68 FF C4 A4'
- '9D D1 CF CD CF 77 D7 D3 CF 2C DB D6 CF 07 00 00'
- '00 00 E6 D0 C9 AA F5 D9 D4 FF FF E4 DF FF FF F2'
- 'EA FF FF FA F0 FF FF FA F0 FF FF FA F0 FF FF F8'
- 'EA FF FF F6 E0 FF FF F4 DF FF FF F3 DF FF FF F3'
- 'DF FF FF F1 D5 FF FF EF CF FF FF EF CF FF FF EF'
- 'CF FF FF EC CA FF FF E8 C0 FF FF E8 C0 FF FF E7'
- 'BF FF FF E6 BF FF FF E4 B5 FF FF D8 A5 FF FF C0'
- '90 FF EA 96 70 FF E5 89 6A FF EF 9A 80 FF F9 AD'
- '89 FF FF BA 8F FF FF C0 8F FF FF C0 7A FF FF BA'
- '65 FF FF B0 50 FF FF A9 45 FF F4 8E 3A FF E0 60'
- '2F FF F4 9A 4F FF FF B8 60 FF FF B8 60 FF F4 97'
- '4A FF E4 79 39 FF D0 5F 2F FF C5 77 5A FF C5 9A'
- '8F D8 CF C7 CF 8A E4 E2 E4 3C F0 F0 F0 16 00 00'
- '00 00 E6 CA C2 AA F5 D6 D1 FF FF EC EA FF FF F6'
- 'F4 FF FF FA F6 FF FF FA F0 FF FF FA F0 FF FF F9'
- 'EE FF FF F8 EA FF FF F6 E3 FF FF F4 DF FF FF F3'
- 'DF FF FF F2 DB FF FF F1 D6 FF FF EF CF FF FF EF'
- 'CF FF FF EE CD FF FF EC C9 FF FF E9 C3 FF FF E7'
- 'BF FF FF E7 BF FF FF E6 BB FF FF E0 B3 FF FF D7'
- 'A5 FF F8 CA 9A FF F6 C0 95 FF F9 BB 94 FF F6 B3'
- '89 FF F1 A7 7D FF EA 96 6F FF EA 96 68 FF ED 9B'
- '65 FF F5 A4 65 FF FB A9 68 FF F8 9C 61 FF E9 7A'
- '4F FF F7 AC 68 FF FF C2 71 FF FF BD 69 FF FB AB'
- '5B FF EF 90 48 FF D9 6A 2F FF CF 72 4C FF C8 8F'
- '7E DE C5 C1 C5 9B D4 CF CB 38 DC D6 CF 07 00 00'
- '00 00 E6 C6 BB AA F5 D4 CD FF FF F4 F5 FF FF F9'
- 'FB FF FF FB FB FF FF FA F5 FF FF FA F1 FF FF FA'
- 'F0 FF FF FA F0 FF FF F8 E8 FF FF F6 E3 FF FF F4'
- 'DF FF FF F3 DF FF FF F2 DB FF FF F1 D5 FF FF EF'
- 'D1 FF FF EF CF FF FF EF CF FF FF EB C8 FF FF E9'
- 'C3 FF FF E8 C0 FF FF E7 BF FF FF E6 BB FF FF E4'
- 'B5 FF FF E4 B1 FF FF DE AC FF FF D3 A4 FF F8 C5'
- '96 FF F1 B4 86 FF EA A0 75 FF EA 9E 75 FF EC 9F'
- '75 FF F0 A4 74 FF F6 A3 74 FF F4 97 6B FF E9 7F'
- '5A FF F4 A3 6C FF F9 B6 75 FF FA B9 74 FF FD B7'
- '6D FF F7 A6 5D FF E9 87 44 FF D8 73 48 FF CB 87'
- '73 EB C5 C1 C5 C2 CD C7 C1 41 00 00 00 00 00 00'
- '00 00 E6 C3 B5 AA F5 D4 CA FF FF FC FF FF FF FC'
- 'FF FF FF FC FF FF FF FC FF FF FF FA F5 FF FF FA'
- 'F0 FF FF FA F0 FF FF FA F0 FF FF F8 EA FF FF F6'
- 'E0 FF FF F4 DF FF FF F3 DF FF FF F3 DF FF FF F1'
- 'D5 FF FF EF CF FF FF EF CF FF FF EF CF FF FF EC'
- 'CA FF FF E8 C0 FF FF E8 BF FF FF E7 BF FF FF E6'
- 'BF FF FF E4 B5 FF FF E4 B0 FF FF E4 B0 FF FF E4'
- 'B0 FF FF E2 AA FF FF DE A0 FF FF D7 A0 FF FA C8'
- '95 FF F0 B0 7F FF EF 95 6A FF E9 7F 5A FF DF 6F'
- '4F FF E9 7F 5A FF EF 93 6A FF F0 AC 80 FF F9 B9'
- '80 FF FF BD 7A FF FF B7 6F FF DF 7D 4F FF CF 82'
- '6F FF CF C7 CF FF D0 C8 C4 55 00 00 00 00 00 00'
- '00 00 EA CB C3 AA F6 D0 CA FF F5 D8 D4 FF F5 D5'
- 'CD FF F8 D8 D1 FF FF E1 DF FF FF E8 E2 FF FF F0'
- 'E8 FF FF FA F0 FF FF FA F0 FF FF F9 EE FF FF F8'
- 'EA FF FF F4 E2 FF FB E3 D0 FF F5 C5 B4 FF F4 BD'
- 'A9 FF F4 BD A8 FF F5 C4 AF FF FB D1 B6 FF FF DB'
- 'BC FF FF E2 BF FF FF E6 BF FF FF E7 BF FF FF E7'
- 'BF FF FF E6 BB FF FF E4 B6 FF FF E4 B0 FF FF E4'
- 'B0 FF FF E3 AE FF FF E2 AA FF FF DD A3 FF FD D6'
- '9C FF F9 CE 94 FF F3 AF 7F FF E6 98 76 FF D4 89'
- '79 FF DF A4 93 FF E8 B0 9C FF EF AC 94 FF EC 99'
- '78 FF EA 8D 65 FF EA 87 59 FF DF 69 41 FF D7 7F'
- '64 C6 D0 C8 C4 55 D1 C9 C0 1C 00 00 00 00 00 00'
- '00 00 E3 CE C6 71 EA CD C6 AA E6 C8 BF AA EC C0'
- 'B4 BB F3 C2 B7 D7 FA CE C7 FF FA D4 CE FF FA DB'
- 'D3 FF FA E2 D5 FF FA E4 D8 FF FB E7 DC FF FF EC'
- 'E0 FF FB E2 D1 FF F6 D1 BF FF F0 B8 A9 FF E8 B1'
- 'A2 C6 E5 B0 A2 AA E6 B7 A9 AA F3 C5 B1 E2 F9 CD'
- 'B5 FF F9 D0 B4 FF F9 CE AE FF F9 D0 AE FF FA D6'
- 'B4 FF FD D9 B4 FF FF DE B4 FF FF E4 B5 FF FF E4'
- 'B1 FF FF E4 B0 FF FF E4 B0 FF FF E1 A8 FF FF DF'
- 'A3 FF FF DE A0 FF F5 B9 86 FF E3 A3 82 FF CA 9C'
- '94 FF D5 B9 B1 C6 DE C2 B8 AA E5 B6 A9 AA DE 9F'
- '8D AA DB 91 7B AA DB 8D 74 AA E1 83 66 E2 DE 97'
- '7F AA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 BF'
- 'B4 33 F0 BC B2 88 F2 C2 B8 FF F0 C1 B8 FF F0 BC'
- 'B0 FF F0 B4 A0 FF F0 B8 AA FF F5 C1 B4 FF FF D0'
- 'C0 FF F5 BD AA FF F0 BC AA FF F0 CD C0 FF DC CB'
- 'BF 55 00 00 00 00 00 00 00 00 E6 CC BF A9 EF C4'
- 'B5 FF EF B4 A0 FF EF A2 8A FF EF A2 8A FF F0 B4'
- 'A0 FF F9 BF A0 FF FF CF AA FF FF E6 BF FF FF E4'
- 'B5 FF FF E4 B0 FF FF E4 B0 FF FF E4 B0 FF FF E2'
- 'AA FF FF DE A0 FF F5 B4 80 FF E0 A1 7F FF C0 A7'
- 'A0 FF CB BE B4 55 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 E5 CC BF A9 E6 CC'
- 'BF AA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 C6'
- 'BB 11 DC C5 BA 2D DC C7 BC 55 DC C7 BC 55 DC C5'
- 'B9 55 DC C2 B4 55 E9 BC B0 A6 F1 BC B0 C1 F5 C1'
- 'B4 A5 F1 BA AD C2 E8 BD B0 A7 DC CB BF 55 D5 CA'
- 'BF 1C 00 00 00 00 00 00 00 00 D8 CA BF 38 DB C8'
- 'BB 55 DB C2 B4 55 DB BC AD 55 DB BC AD 55 DC C2'
- 'B4 55 EC BF AD C6 F4 BA A3 FF F4 B3 95 FF F4 B2'
- '91 FF F4 B9 93 FF F5 C6 9A FF FB CF A1 FF FF D9'
- 'A7 FF FF E2 AA FF ED A8 7C FF DC 9D 83 FF CA C1'
- 'BF FF CF C7 BF 55 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 D8 CA BF 38 D8 CA'
- 'BF 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 DF C2 B7 51 E6 BF B4 6C E6 BF'
- 'B4 50 E5 BE B3 6D DE C2 B7 52 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 DF C2 B7 71 E5 B8 A9 AA E5 A9 94 AA E5 A9'
- '94 AA EA B1 9A C6 F5 C0 A4 FF F8 C0 9E FF F8 C2'
- '9A FF F4 C7 9A FF E6 9C 77 FF DA 9D 86 E2 D0 CD'
- 'CA AA D1 CB C2 38 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3740,24 +3295,88 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 E0 CD C4 54 FF D4 CF FF F4 B6 A5 FF EA 9F'
- '85 FF E0 8F 70 FF E0 8F 70 FF DB A2 8A AA 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 4C 4C 4C 4A 48 40 3E 38 3B'
+ '35 32 3C 42 00 00 71 76 79 79 78 75 74 73 6E 70'
+ '6C 6B 29 1E 44 00 79 2D 60 12 60 68 12 60 2D 79'
+ '79 79 51 0C 28 00 79 79 58 79 64 79 79 64 79 79'
+ '79 77 5B 0D 2B 00 69 6F 74 73 72 72 72 72 72 6D'
+ '6B 6A 30 0F 34 00 62 5F 5D 52 4D 4E 49 47 43 39'
+ '33 29 10 16 3F 00 63 53 45 3D 31 2E 2E 23 22 1F'
+ '1C 1A 19 17 4C 00 66 5C 4B 41 37 34 2F 2B 28 25'
+ '21 1F 1F 18 50 00 67 5E 4F 46 3A 36 31 2E 2A 28'
+ '24 21 20 1D 54 00 61 2C 11 0B 0A 0E 15 26 27 25'
+ '24 21 1F 1B 00 00 00 65 5A 59 56 55 13 57 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF 00 00 FF FF 00 00 80 03'
+ '00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01'
+ '00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01'
+ '00 00 00 03 00 00 80 FF 00 00 FF FF 00 00 FF FF'
+ '00 00 FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 D7 CB C0 1C E1 CD C4 55 DD C3 B6 55 DA BB'
- 'AB 55 D6 B6 A4 55 D6 B6 A4 55 D5 BC AD 38 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 C1'
+ 'C1 84 B0 B0 B0 92 B0 B0 B0 92 B0 B0 B0 92 AC B0'
+ 'B0 92 A5 A9 AC 92 9D A0 A2 92 99 9B 9D 92 92 94'
+ '97 92 96 97 99 92 8F 90 94 92 8B 8D 8F 92 97 97'
+ '99 91 A2 A2 A2 90 A1 A1 A1 91 81 81 81 45 F6 F8'
+ 'F9 FE FC FC FD FF FF FF FF FF FF FF FF FF FD FE'
+ 'FF FF FB FC FD FF F9 FA FA FF F8 F8 F9 FF F6 F6'
+ 'F7 FF F7 F7 F8 FF F5 F5 F6 FF F4 F4 F5 FF 9C 9D'
+ '9E FF 90 90 91 FF B1 B1 B1 FB 94 94 94 7D FF FF'
+ 'FF FF BD 9D 85 FF DA CA C2 FF B7 97 7C FF DA CA'
+ 'C2 FF F1 E9 E1 FF B7 97 7C FF DA CA C2 FF BD 9D'
+ '85 FF FF FF FF FF FF FF FF FF FF FF FF FF BA BC'
+ 'BC FF 6F 70 70 FF 9B 9B 9B FB 82 82 82 81 FF FF'
+ 'FF FF FF FF FF FF E4 D0 BE FF FF FF FF FF E3 D4'
+ 'C6 FF FF FF FF FF FF FF FF FF E3 D4 C6 FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FD FF BE BF'
+ 'C0 FF 74 74 75 FF 9F 9F 9F FC 84 84 84 85 F0 F1'
+ 'F1 FF F6 F7 F8 FF F9 FA FA FF F8 F8 F9 FF F7 F8'
+ 'F9 FF F7 F8 F9 FF F7 F8 F9 FF F7 F8 F9 FF F7 F8'
+ 'F9 FF F5 F6 F6 FF F4 F4 F5 FF F2 F2 F2 FF A2 A3'
+ 'A3 FF 7A 7B 7B FF A5 A5 A5 FC 88 88 88 88 D8 D8'
+ 'D9 FF C4 C6 C7 FF C1 C3 C5 FF BB BC BE FF B6 B7'
+ 'B9 FF B7 B9 BA FF B3 B5 B6 FF B0 B2 B4 FF AC AF'
+ 'B0 FF A7 A8 AA FF A3 A4 A5 FF 9C 9D 9E FF 7D 7E'
+ '7E FF 84 84 84 FF AC AC AC FD 8F 8F 8F 8B DF DF'
+ 'DF FF BC BC BC FF B2 B2 B2 FF AB AB AB FF A3 A3'
+ 'A3 FF A0 A0 A0 FF A0 A0 A0 FF 98 98 98 FF 97 97'
+ '97 FF 92 92 92 FF 8F 8F 8F FF 8D 8D 8D FF 8C 8C'
+ '8C FF 8A 8A 8A FF B7 B7 B7 FD 95 95 95 8E E1 E1'
+ 'E1 FF C1 C1 C1 FF B6 B6 B6 FF AE AE AE FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A1 A1 A1 FF 9F 9F 9F FF 9C 9C'
+ '9C FF 9A 9A 9A FF 96 96 96 FF 92 92 92 FF 92 92'
+ '92 FF 8C 8B 8C FF BB BC BB FD 98 98 98 90 E4 E4'
+ 'E4 FF C4 C4 C4 FF BA BA BA FF B3 B3 B3 FF A9 A9'
+ 'A9 FF A6 A6 A6 FF A3 A3 A3 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9C 9C 9C FF 99 99 99 FF 96 96 96 FF 93 93'
+ '93 FF 90 90 90 FF BE BE BE FD 99 99 99 92 DC D9'
+ 'D2 FF A0 99 8C FF 8A 84 78 FF 7A 75 6C FF 75 72'
+ '6D FF 7B 79 7B FF 82 81 85 FF 9A 9A 9E FF 9B 9C'
+ '9C FF 9A 9A 9A FF 99 99 99 FF 96 96 96 FF 92 92'
+ '92 FF 8E 8E 8E FF C1 C1 C1 FE 9D 9D 9D 93 F8 F7'
+ 'E9 7F FE EE C7 FF FB E6 BF FF F2 DE B8 FF DF CC'
+ 'A6 FF C7 B2 89 FF BD A5 77 FF D1 C5 B0 FE E9 E9'
+ 'E9 40 E9 E9 E9 40 E8 E8 E8 40 E8 E8 E8 40 E7 E7'
+ 'E7 40 E7 E7 E7 40 EE EE EE 3F B3 B3 B3 1E 00 00'
+ '00 00 FE EE C7 40 FB E6 BF 40 F2 DE B8 40 DF CC'
+ 'A6 40 C7 B2 89 40 BD A5 77 40 C4 B0 87 2C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3767,19 +3386,124 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 08 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 70 00 0F 88 88 88 88 87 88 78 78 78'
+ '78 78 78 78 78 00 0F 88 FF FF FF FF FF FF FF FF'
+ 'FF F8 88 88 87 00 0F 8F 4F F4 44 44 44 4F FF F4'
+ '4F FF 88 88 87 00 0F 8F F4 4F F4 F4 FF F4 4F 4F'
+ 'FF FF 88 88 87 00 0F 8F F4 F4 4F 4F FF 4F F4 4F'
+ 'FF FF 88 88 87 00 0F 8F F4 4F FF 44 4F F4 4F FF'
+ 'FF FF 88 88 87 00 0F 88 FF FF FF FF FF FF FF FF'
+ 'FF F8 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 0F 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 00 00 F6 66 66 66 66 66 88 88 88'
+ '88 88 88 88 80 00 00 FE 6E 6E 6E 6E 6E 80 00 00'
+ '00 00 00 00 00 00 00 0F EF EF EF EF EF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 80 00'
+ '00 07 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 C0 00 00 07 C0 01 FF FF E0 03 FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 73 73 73 00 76 76 76 00 79 79'
+ '79 00 7A 7A 7A 00 7C 7C 7C 00 7E 7E 7E 00 7F 7F'
+ '7F 00 90 67 4E 00 92 79 6A 00 9C 8A 66 00 A9 86'
+ '70 00 A8 9A 7E 00 B4 91 78 00 FF 00 FF 00 80 80'
+ '80 00 82 82 82 00 84 84 84 00 86 86 86 00 87 87'
+ '87 00 87 88 87 00 88 88 88 00 8A 8A 8A 00 8B 8B'
+ '8B 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
+ '8F 00 9F 83 82 00 96 92 8B 00 93 90 8C 00 95 92'
+ '8D 00 98 94 8A 00 98 94 8E 00 9C 97 8C 00 90 90'
+ '90 00 92 92 92 00 93 93 93 00 94 94 94 00 95 95'
+ '95 00 95 96 95 00 96 96 96 00 97 97 97 00 98 98'
+ '98 00 99 99 99 00 9A 9A 9A 00 9B 9A 9A 00 9B 9B'
+ '9B 00 9C 9C 9C 00 9D 9D 9D 00 9E 9E 9E 00 9F 9F'
+ '9E 00 9E 9F 9F 00 9F 9F 9F 00 AD 9F 83 00 BD 9E'
+ '8F 00 A2 9C 92 00 B2 A5 89 00 BF A0 88 00 AA A0'
+ '96 00 A9 A3 97 00 BD A7 94 00 BB AE 94 00 B1 AB'
+ '9F 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2 A1 00 A2 A2'
+ 'A2 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6 A6 00 A7 A7'
+ 'A6 00 A7 A7 A7 00 A8 A8 A8 00 AA AA AA 00 AC AB'
+ 'AA 00 AC AC AC 00 AE AE AE 00 B5 AE A6 00 B7 B1'
+ 'A6 00 B8 B2 A6 00 B1 B0 AF 00 AF AF B0 00 B1 B1'
+ 'B1 00 B2 B2 B2 00 B3 B4 B4 00 B4 B4 B4 00 B5 B5'
+ 'B5 00 B5 B6 B6 00 B6 B6 B6 00 B8 B8 B8 00 B8 B9'
+ 'BA 00 BA BA BA 00 BB BB BB 00 BB BC BC 00 BC BC'
+ 'BC 00 BC BD BE 00 BF BF BE 00 BF BF BF 00 C0 9F'
+ '80 00 C3 A4 8F 00 C3 A7 92 00 C5 AA 93 00 C5 A9'
+ '99 00 C6 AB 9E 00 C8 B0 9C 00 C5 B9 9F 00 C9 AD'
+ 'A7 00 C2 AA A8 00 CC B5 A2 00 C9 B0 A4 00 CC B7'
+ 'A4 00 CE B7 A4 00 CD B8 A5 00 CC BF A5 00 C6 B2'
+ 'AD 00 C9 B4 AE 00 CE B9 A8 00 CE BA A8 00 CE BA'
+ 'AB 00 D1 B8 A2 00 D0 B8 A6 00 D1 BA A7 00 D0 BC'
+ 'A7 00 D2 BE AB 00 D0 C3 AA 00 D3 C0 AE 00 D5 C8'
+ 'AE 00 D3 C2 B2 00 D5 C3 B2 00 D1 C0 B5 00 D6 C7'
+ 'B7 00 D7 CA B1 00 DA CC B3 00 DD CE B4 00 D7 C7'
+ 'B8 00 D5 C5 BD 00 D8 C6 BB 00 DB C9 BA 00 DC CA'
+ 'B9 00 D9 CB BC 00 DB C9 BE 00 EB DF BE 00 C0 C0'
+ 'C0 00 C2 C2 C1 00 C0 C1 C2 00 C2 C2 C2 00 C3 C3'
+ 'C3 00 C4 C3 C2 00 C3 C4 C5 00 C4 C4 C4 00 C5 C6'
+ 'C6 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C7 00 C8 C8'
+ 'C8 00 C9 C9 C9 00 C9 C9 CA 00 CA CA CA 00 CB CB'
+ 'CB 00 CC CC CC 00 CC CD CC 00 CD CD CD 00 CE CE'
+ 'CE 00 DF D0 C1 00 D0 D0 D0 00 D1 D2 D2 00 D2 D2'
+ 'D2 00 D4 D4 D4 00 D7 D6 D5 00 D5 D6 D6 00 D6 D6'
+ 'D6 00 D8 D5 D0 00 D8 D8 D8 00 DA DA DA 00 DE DE'
+ 'DE 00 DF DF DF 00 E1 D2 C7 00 E5 D6 C9 00 E5 D7'
+ 'CC 00 E4 D6 CF 00 E5 DA D0 00 E7 DB D0 00 E8 D9'
+ 'D3 00 EE E5 C6 00 F2 E8 CB 00 F5 EC CE 00 ED E2'
+ 'D6 00 E2 E1 DF 00 EC E1 D9 00 F7 EE D5 00 FA F2'
+ 'DA 00 E0 E0 E0 00 E1 E1 E1 00 E2 E1 E1 00 E4 E3'
+ 'E3 00 E7 E5 E3 00 E8 E6 E4 00 EA E7 E5 00 EA E8'
+ 'E5 00 EC E8 E6 00 ED EA E7 00 EA EA EA 00 ED EA'
+ 'E8 00 EE EB E8 00 F1 EA E2 00 F2 EA E2 00 F6 ED'
+ 'E6 00 F6 EE E7 00 F6 EE E8 00 F5 F0 E4 00 FD F5'
+ 'E0 00 FD F8 E6 00 F6 F0 E9 00 F6 F0 EA 00 F1 F1'
+ 'EF 00 F7 F1 EC 00 F9 F0 EA 00 F8 F1 EC 00 F8 F2'
+ 'EC 00 F9 F2 EE 00 FB F4 EE 00 FD FA E8 00 FD FD'
+ 'ED 00 F9 F3 F0 00 F9 F4 F0 00 FA F5 F0 00 FA F6'
+ 'F1 00 F9 F5 F2 00 FA F5 F2 00 F9 F6 F2 00 FA F6'
+ 'F2 00 FA F6 F4 00 FD FD F3 00 FC F9 F5 00 FE FC'
+ 'F7 00 FC FB F9 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3791,7 +3515,46 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
+ '4C 1F 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E'
+ '1E 1E 1E 1E 1E 1E 1F 20 20 1A 23 00 00 00 00 6B'
+ 'D3 B3 AC A6 A0 9E 9A 69 67 64 5E 5E 56 5B 53 53'
+ '53 52 4E 3B 3A 39 39 3B 36 31 32 49 00 00 00 6B'
+ 'B3 07 CF D5 D4 D4 D4 D2 D1 D2 D1 D0 D0 D0 D1 CF'
+ 'CF CE CE CD B2 2C 0E 0E 0D 0A 1B 38 00 00 00 6B'
+ 'B7 E0 77 81 81 94 78 7F 8C 8A 7F AD D6 DF E2 C6'
+ '87 7A 90 80 BB B8 18 0F 0F 0B 19 36 00 00 00 07'
+ 'CB DE 7D C0 44 57 8B 79 92 BE 93 EA 80 6F 70 96'
+ '71 D6 F5 F1 E4 F0 1D 10 0E 0B 19 35 00 00 00 6B'
+ 'CC E9 EF 12 F4 74 75 6D 76 43 89 EB 16 85 84 6C'
+ '7C BA BF DF DF F1 23 18 0F 0B 19 33 00 00 00 AB'
+ 'AC F0 C4 14 82 EE DE D8 72 11 40 EB 83 46 6E 25'
+ 'F0 DA DE D9 D9 E6 1F 19 18 0C 19 30 00 00 00 B6'
+ '9C C5 EB BD 91 E2 E2 DF DF E6 E4 E3 E4 95 BC D7'
+ 'E2 E3 E2 DE F3 9D 1F 19 19 0C 1B 2E 00 00 00 B7'
+ '99 66 AF B7 B6 B3 B1 B3 B0 B0 AE AE AB AC AB A8'
+ 'A7 A4 A1 A2 62 21 20 1E 19 0F 1F 2C 00 00 00 B9'
+ '99 68 63 62 5D 56 55 52 52 4F 4D 4A 4A 49 3A 35'
+ '34 30 2F 2E 2D 23 21 1E 1B 0E 21 2C 00 00 00 B8'
+ '07 99 68 65 62 5C 56 53 51 4D 4F 4D 4A 39 3B 36'
+ '34 30 30 2D 2D 23 22 20 1F 10 2D 23 00 00 00 C9'
+ '9B 9F 68 63 5F 5C 56 54 4F 4F 4F 4C 4A 3B 3A 39'
+ '35 35 2F 2F 2D 2C 23 1F 1E 19 2F 23 00 00 00 B8'
+ '9B A1 99 66 63 5D 56 53 52 4F 4D 49 4A 3E 3B 39'
+ '38 34 34 2F 2E 2E 2D 20 20 1A 30 22 00 00 00 B8'
+ 'A0 A1 9C 69 63 60 5C 55 53 52 4F 4C 4B 3E 3A 3B'
+ '39 36 34 34 30 2F 2C 2D 21 1C 32 21 00 00 00 B9'
+ 'A2 A8 9F 07 68 62 5F 55 52 4F 4E 4D 4A 4A 49 3B'
+ '3A 39 37 34 32 32 2D 2C 23 1B 33 20 00 00 00 CA'
+ 'A5 A9 A1 9C 6B 63 5C 56 54 4F 4D 4C 4C 3B 3E 3B'
+ '3A 3A 39 34 34 30 2F 2D 21 1C 34 20 00 00 00 B8'
+ 'A8 AA A3 99 6A 65 5F 5A 54 50 4D 4B 3C 49 3E 3A'
+ '3B 3A 38 38 34 32 2E 24 23 1B 35 1F 00 00 00 00'
+ 'B5 59 58 48 45 41 2B 29 26 2A 28 27 37 3D 38 39'
+ '35 36 35 33 30 2D 24 21 1C 10 60 00 00 00 00 00'
+ 'DB 8F 8E 8D 88 86 7B 73 47 42 3F 15 13 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F2 E8 E7 DD DC C8 C7 C3 C2 C1 97 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3805,32 +3568,16 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF 00'
- '3F FF FF FF 00 00 FF 00 3F FF FF FF 00 00 FF 00'
- '07 FF FF FF 00 00 FF 00 00 FF FF FF 00 00 FF 00'
- '00 FF FF FF 00 00 FE 00 00 1F FF FF 00 00 FE 00'
- '00 03 FF FF 00 00 FE 00 00 03 FF FF 00 00 FE 00'
- '00 00 7F FF 00 00 FE 00 00 00 03 FF 00 00 FE 00'
- '00 00 03 FF 00 00 F8 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 0F 00 00 F8 00 00 00 00 0F 00 00 F8 00'
- '00 00 00 0F 00 00 F8 00 00 00 00 07 00 00 F8 00'
- '00 00 00 07 00 00 F0 00 00 00 00 07 00 00 F0 00'
- '00 00 00 07 00 00 F0 00 00 00 00 07 00 00 F0 00'
- '00 00 00 07 00 00 F0 00 00 00 00 07 00 00 F0 00'
- '00 00 00 07 00 00 C0 00 00 00 00 01 00 00 C0 00'
- '00 00 00 01 00 00 C0 00 00 00 00 01 00 00 C0 00'
- '00 00 00 01 00 00 C0 00 00 00 00 01 00 00 C0 00'
- '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
- '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
- '00 00 00 07 00 00 F0 00 60 00 03 E7 00 00 F0 00'
- '60 00 03 E7 00 00 FF C1 FF 80 03 FF 00 00 FF FF'
- 'FF F8 0F FF 00 00 FF FF FF F8 0F FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 80 00 00 07 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 C0 00 00 07 C0 01'
+ 'FF FF E0 03 FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
  '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
- '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -3848,220 +3595,200 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 C5'
- 'BC FF D0 BC BF FF BF B8 BF FF CF C7 CF A5 DF D8'
- 'DF 54 F0 EF F0 0F 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 98'
- '8F FF E0 84 6F FF D0 84 6F FF BF 98 90 FF B0 B0'
- 'B0 FF C0 C0 C0 B7 DF D7 DF 66 EF E8 EF 1E 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 84'
- '6F FF F0 BF B0 FF FF DF D0 FF EF 97 80 FF DF 78'
- '5F FF BF 90 80 FF B0 AF B0 FF C0 BF C0 C9 D0 D0'
- 'D0 78 EF E7 EF 2D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F0 C4 BC FF EF 97'
- '7F FF EF 9F 8F FF FF FC FF FF FF FC FF FF FF E7'
- 'E0 FF F0 A7 8F FF D0 77 5F FF BF 88 7F FF B0 AF'
- 'B0 FF BF B8 BF DB D0 CF D0 8A E0 E0 E0 3C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 EF BF B0 FF FF CD'
- 'A0 FF EF 97 80 FF FF FC FF FF FF FC FF FF FF F7'
- 'FF FF FF F1 F0 FF F0 DF DF FF EF AD 9F FF DF 77'
- '5F FF C0 84 70 FF B0 A7 A0 FF BF B7 BF ED CF C8'
- 'CF 9C E0 E0 E0 4B 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 EF A7 90 FF FF D4'
- 'A0 FF EF 8F 6F FF FF FC FF FF FF FC FF FF FF F7'
- 'FF FF FF F1 F0 FF FF EF F0 FF F0 EF F0 FF F0 DF'
- 'E0 FF EF AD 9F FF DF 77 50 FF C0 78 60 FF B0 9F'
- '9F FF BF B7 BF FE CF C7 CF AE DF D8 DF 5D 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 EF 9A 80 FF FF E4'
- 'B0 FF F0 9F 70 FF FF F1 F0 FF FF F7 FF FF FF F7'
- 'FF FF FF F1 F0 FF F0 EF F0 FF F0 EF F0 FF F0 E7'
- 'EF FF F0 E2 E0 FF F0 E2 E0 FF E0 AF A0 FF DF 77'
- '5F FF CF 6F 50 FF B0 90 8F FF B0 B0 B0 FF C0 C0'
- 'C0 C0 DF D7 DF 6F EF E8 EF 26 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 F0 C4 BC FF F0 B8 A0 FF FF DE'
- 'A0 FF F0 AC 80 FF FF C5 A0 FF FF C0 80 FF FF DF'
- 'CF FF FF F1 F0 FF F0 EF F0 FF F0 EF F0 FF F0 E7'
- 'EF FF F0 E2 E0 FF F0 E2 E0 FF EF DF E0 FF EF DF'
- 'E0 FF E0 B7 B0 FF DF 78 5F FF CF 67 4F FF BF 87'
- '7F FF B0 AF B0 FF C0 BF C0 D2 D0 D0 D0 81 EF E7'
- 'EF 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 F0 C7 BF FF FF CC B0 FF FF DE'
- 'A0 FF F0 B0 80 FF FF BF 9F FF FF B1 5F FF FF A5'
- '4F FF FF 9F 50 FF F0 C7 A0 FF F0 EF F0 FF F0 E7'
- 'EF FF F0 E2 E0 FF EF DF E0 FF EF DF E0 FF EF DF'
- 'E0 FF E0 D7 DF FF E0 D0 D0 FF DF BF BF FF E0 84'
- '6F FF D0 5D 3F FF BF 7F 70 FF B0 A7 A0 FF BF B8'
- 'BF E4 D0 D0 D0 93 F0 EF F0 2C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 EF AD 9F FF FF E6 BF FF FF E4'
- 'B0 FF FF C0 90 FF F0 B7 90 FF FF C7 7F FF FF B1'
- '5F FF FF A5 4F FF F0 97 40 FF F0 90 3F FF F0 AC'
- '80 FF F0 D4 CF FF EF DF E0 FF EF DF E0 FF E0 D7'
- 'DF FF E0 D7 DF FF E0 D0 D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF B7 B0 FF D0 88 70 FF D0 5D 3F FF BF 77'
- '60 FF BF AF AF FF DF D8 DF BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 F0 A8 90 FF FF E8 C0 FF FF E4'
- 'B0 FF FF CC 9F FF F0 A7 80 FF FF CC 80 FF FF B8'
- '60 FF FF B1 5F FF FF A5 4F FF F0 97 40 FF EF 80'
- '30 FF EF 70 20 FF E0 90 60 FF E0 B8 AF FF E0 D7'
- 'DF FF E0 D0 D0 FF E0 CF D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF C7 CF FF D0 C0 C0 FF D0 B7 BF FF D0 6F'
- '50 FF BF 7F 70 FF CF C8 CF DD F0 F0 F0 2F 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F4 C5 BC FF F0 C0 AF FF FF E6 BF FF FF E4'
- 'B0 FF FF E4 B0 FF F0 A7 80 FF FF DE A0 FF FF C0'
- '6F FF FF B8 60 FF FF B1 5F FF FF A5 4F FF F0 97'
- '40 FF EF 80 30 FF EF 70 20 FF DF 67 1F FF DF 70'
- '3F FF DF A0 8F FF E0 CF D0 FF DF CF D0 FF DF CF'
- 'D0 FF DF C7 CF FF D0 C0 C0 FF D0 BF C0 FF D0 9F'
- '90 FF C0 6F 50 FF C0 C0 C0 F9 F0 EF F0 46 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F0 CD C0 FF FF D7 BF FF FF E8 C0 FF FF E6'
- 'BF FF FF E4 B0 FF EF 8F 70 FF FF E4 B0 FF FF CC'
- '80 FF FF C0 6F FF FF B8 60 FF FF B1 5F FF FF A5'
- '4F FF F0 97 40 FF EF 80 30 FF E0 70 20 FF DF 67'
- '1F FF D0 58 1F FF D0 57 1F FF D0 84 6F FF DF BF'
- 'BF FF DF C7 CF FF D0 C0 C0 FF D0 BF C0 FF D0 B0'
- 'B0 FF D0 5D 3F FF BF B7 BF FF EF E8 EF 60 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 EF B4 A0 FF FF EE D0 FF FF E8 C0 FF FF E8'
- 'C0 FF FF E6 BF FF F0 A7 80 FF FF E8 C0 FF FF CC'
- '80 FF FF CC 80 FF FF C0 6F FF FF B8 60 FF FF B0'
- '50 FF FF A5 4F FF F0 97 40 FF EF 80 2F FF E0 70'
- '20 FF DF 67 1F FF D0 58 1F FF CF 4F 10 FF CF 45'
- '10 FF CF 6F 4F FF D0 A7 9F FF D0 BF C0 FF D0 BC'
- 'BF FF D0 5D 3F FF B0 B0 B0 FF E0 DF E0 7C 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F0 B4 A0 FF FF F3 DF FF FF EF CF FF FF E8'
- 'C0 FF FF E8 C0 FF F0 A7 8F FF FF D7 BF FF FF D4'
- '90 FF FF CC 80 FF FF CC 80 FF FF C0 6F FF FF B8'
- '60 FF FF B1 5F FF FF A5 4F FF FF 97 3F FF EF 80'
- '2F FF E0 70 20 FF DF 67 1F FF D0 58 1F FF CF 4F'
- '10 FF CF 45 10 FF C0 38 00 FF B0 4F 30 FF C0 84'
- '70 FF D0 77 5F FF BF 97 8F FF D0 D0 D0 98 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F4 C6'
- 'BC FF FF C8 BF FF FF F0 D0 FF FF EE D0 FF FF EF'
- 'CF FF FF E8 C0 FF F0 B8 9F FF F0 B4 A0 FF FF D7'
- 'B0 FF FF DF AF FF FF CF 8F FF FF C7 7F FF FF C0'
- '6F FF FF B8 60 FF FF B1 5F FF FF AF 4F FF FF A6'
- '40 FF FF 94 30 FF EF 80 2F FF DF 67 1F FF D0 58'
- '1F FF CF 4F 10 FF CF 45 10 FF AF 27 00 FF B0 3F'
- '10 FF C0 47 1F FF C0 84 70 FF CF C8 CF B3 F0 F0'
- 'F0 0B 00 00 00 00 00 00 00 00 00 00 00 00 F0 CF'
- 'CF FF FF DF CF FF FF F3 DF FF FF F0 D0 FF FF EE'
- 'D0 FF FF EF CF FF FF E7 C0 FF FF C5 A0 FF F0 A7'
- '80 FF EF 9A 80 FF FF BF A0 FF FF D4 A0 FF FF D4'
- '90 FF FF C0 6F FF FF B8 60 FF FF B1 5F FF FF AF'
- '4F FF FF A6 40 FF FF A6 40 FF FF 94 30 FF F0 78'
- '20 FF DF 5F 1F FF CF 4F 10 FF AF 27 00 FF C0 4F'
- '1F FF C0 47 1F FF C0 6F 5F FF C0 C0 C0 CF F0 EF'
- 'F0 23 00 00 00 00 00 00 00 00 00 00 00 00 F0 BF'
- 'B0 FF FF F6 E0 FF FF F3 DF FF FF F3 DF FF FF F0'
- 'D0 FF FF EE D0 FF FF EF CF FF FF E8 C0 FF FF E8'
- 'C0 FF FF D8 B0 FF FF C0 90 FF EF 8F 6F FF EF 9A'
- '80 FF FF C5 A0 FF FF CF 8F FF FF B8 60 FF FF B0'
- '50 FF FF AF 4F FF FF A6 40 FF FF A6 40 FF FF 9F'
- '30 FF FF 8F 2F FF DF 5F 1F FF B0 37 10 FF CF 57'
- '1F FF C0 4F 1F FF CF 60 40 FF BF B7 BF EB EF E8'
- 'EF 3B 00 00 00 00 00 00 00 00 00 00 00 00 F0 BA'
- 'AF FF FF FA F0 FF FF F6 E0 FF FF F3 DF FF FF F3'
- 'DF FF FF F0 D0 FF FF EE D0 FF FF EF CF FF FF E8'
- 'C0 FF FF E8 C0 FF FF E6 BF FF FF E4 B0 FF FF CD'
- 'A0 FF EF 8F 6F FF FF CC B0 FF FF CC 80 FF FF B8'
- '60 FF FF B0 50 FF FF AF 4F FF FF A6 40 FF FF A6'
- '40 FF FF 9F 30 FF F0 78 2F FF DF 60 2F FF CF 60'
- '20 FF CF 57 1F FF D0 54 2F FF B0 B0 B0 FF E0 DF'
- 'E0 52 00 00 00 00 00 00 00 00 F4 C6 BC FF FF D0'
- 'C0 FF FF FA F0 FF FF FA F0 FF FF F6 E0 FF FF F3'
- 'DF FF FF F3 DF FF FF F0 D0 FF FF EE D0 FF FF EF'
- 'CF FF FF E8 C0 FF FF E8 C0 FF FF E6 BF FF FF E4'
- 'B0 FF FF CD A0 FF E0 8F 70 FF FF D8 B0 FF FF CC'
- '80 FF FF B8 60 FF FF B0 50 FF FF AF 4F FF FF A6'
- '40 FF FF A6 40 FF F0 6F 2F FF FF 9F 4F FF F0 97'
- '40 FF CF 60 20 FF D0 54 2F FF BF 97 8F FF D0 D0'
- 'D0 6E 00 00 00 00 00 00 00 00 F0 D4 CF FF FF E4'
- 'DF FF FF FA F0 FF FF FA F0 FF FF FA F0 FF FF F6'
- 'E0 FF FF F3 DF FF FF F3 DF FF FF F0 D0 FF FF EF'
- 'CF FF FF EF CF FF FF E8 C0 FF FF E8 C0 FF FF E6'
- 'BF FF FF E4 B0 FF FF C0 90 FF E0 82 60 FF EF 9A'
- '80 FF FF B7 8F FF FF C0 8F FF FF C0 70 FF FF B0'
- '50 FF FF A6 40 FF E0 60 2F FF FF B8 60 FF FF B8'
- '60 FF EF 87 3F FF D0 5F 2F FF C0 84 70 FF CF C7'
- 'CF 8A F0 F0 F0 16 00 00 00 00 F0 C7 BF FF FF F1'
- 'F0 FF FF FC FF FF FF FA F0 FF FF FA F0 FF FF FA'
- 'F0 FF FF F6 E0 FF FF F3 DF FF FF F3 DF FF FF F0'
- 'D0 FF FF EF CF FF FF EF CF FF FF E8 C0 FF FF E8'
- 'C0 FF FF E6 BF FF FF E4 B0 FF FF E4 B0 FF FF CC'
- '9F FF F0 AC 7F FF E0 82 60 FF E0 82 60 FF F0 9F'
- '70 FF FF B0 7F FF EF 88 60 FF FF CC 80 FF FF C0'
- '6F FF FF B1 5F FF DF 70 30 FF CF 6F 50 FF C0 BF'
- 'C0 A5 00 00 00 00 00 00 00 00 F0 C0 B0 FF FF FC'
- 'FF FF FF FC FF FF FF FC FF FF FF FA F0 FF FF FA'
- 'F0 FF FF FA F0 FF FF F6 E0 FF FF F3 DF FF FF F3'
- 'DF FF FF F0 D0 FF FF EF CF FF FF EF CF FF FF E8'
- 'C0 FF FF E8 BF FF FF E6 BF FF FF E4 B0 FF FF E4'
- 'B0 FF FF E4 B0 FF FF DE A0 FF FF D4 A0 FF F0 B0'
- '7F FF EF 88 60 FF DF 6F 4F FF EF 88 60 FF F0 AC'
- '80 FF FF C0 80 FF FF B7 6F FF D0 60 40 FF CF C7'
- 'CF FF 00 00 00 00 00 00 00 00 FA D3 D0 FF F0 C7'
- 'BF FF F0 BF B0 FF FF D4 CF FF FF E4 DF FF FF FA'
- 'F0 FF FF FA F0 FF FF FA F0 FF FF F3 DF FF F0 AF'
- '9F FF EF 9F 8F FF F0 AF 9F FF FF CC B0 FF FF DF'
- 'BF FF FF E8 C0 FF FF E8 BF FF FF E6 BF FF FF E4'
- 'B0 FF FF E4 B0 FF FF E4 B0 FF FF DE A0 FF FF DE'
- 'A0 FF F0 AC 7F FF CF 97 8F FF E0 C7 C0 FF EF AD'
- '9F FF E0 78 60 FF E0 70 4F FF DF 58 30 FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F0 BA AF 4D F2 C2 B8 FF F0 C1 B8 FF F0 B4'
- 'A0 FF F0 BA AF FF FF D0 C0 FF F0 B4 A0 FF F0 CD'
- 'C0 FF 00 00 00 00 00 00 00 00 F0 CD C0 FF EF B4'
- 'A0 FF EF 9A 80 FF F0 B4 A0 FF FF C5 A0 FF FF E6'
- 'BF FF FF E4 B0 FF FF E4 B0 FF FF E4 B0 FF FF DE'
- 'A0 FF F0 9F 70 FF C0 A7 A0 FF 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F0 CD C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F0 BA AF B7 F0 BA AF 79 EF B9 AE B9 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F0 BA AF FF EF 9A'
- '80 FF EF 9A 80 FF F0 B7 90 FF FF CD A0 FF FF E4'
- 'B0 FF E0 82 60 FF D0 CF D0 FF 00 00 00 00 00 00'
+ '00 27 00 00 00 49 00 00 00 4A 00 00 00 4A 00 00'
+ '00 4A 00 00 00 4A 00 00 00 4A 00 00 00 4A 00 00'
+ '00 4A 00 00 00 4A 00 00 00 4A 00 00 00 4A 00 00'
+ '00 4A 00 00 00 4A 00 00 00 4A 00 00 00 4A 00 00'
+ '00 4A 00 00 00 4A 00 00 00 4A 00 00 00 4A 00 00'
+ '00 4A 00 00 00 4A 00 00 00 48 00 00 00 47 00 00'
+ '00 47 00 00 00 50 00 00 00 43 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 EB EB'
+ 'EB F8 D5 D6 D6 FF CE CF CF FF C9 C9 CA FF C5 C6'
+ 'C6 FF C3 C4 C5 FF C0 C1 C2 FF BC BD BE FF BB BC'
+ 'BC FF B8 B9 BA FF B3 B4 B4 FF B2 B2 B3 FF AE AF'
+ 'AF FF AF AF B0 FF AA AA AB FF AA AA AA FF AB AB'
+ 'AB FF A8 A8 A8 FF A4 A4 A4 FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9C 9C 9C FF 9E 9E 9E FF 9A 9A'
+ '9A FF 96 96 96 FF 90 90 90 E0 00 00 00 2B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D5 D5'
+ 'D5 FF C1 C1 C2 FF E9 E7 E5 FF EE EB E8 FF ED EB'
+ 'E8 FF ED EA E7 FF ED EA E8 FF ED E9 E7 FF EC E9'
+ 'E7 FF EC E9 E6 FF EC E8 E6 FF EB E8 E5 FF EA E8'
+ 'E5 FF EB E8 E5 FF EB E8 E5 FF EA E7 E5 FF E9 E7'
+ 'E5 FF E9 E6 E4 FF E8 E6 E4 FF E7 E5 E3 FF D7 D6'
+ 'D5 FF 90 90 90 FF 7C 7C 7C FF 7C 7C 7C FF 7A 7A'
+ '7A FF 73 73 73 FF 7F 7F 7F E6 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DA DA'
+ 'DA FF F1 F1 EF FF C9 B0 A4 FF D1 B8 A2 FF D1 B8'
+ 'A2 FF DC CA B9 FF CC B7 A4 FF CE BB A8 FF D6 C7'
+ 'B7 FF D5 C3 B2 FF CE B9 A8 FF DF D0 C1 FF F1 EA'
+ 'E2 FF F7 F0 EA FF F7 F0 EB FF EC E1 D9 FF D3 C0'
+ 'AE FF CD B8 A5 FF D7 C7 B8 FF CE BA A9 FF E5 D6'
+ 'C9 FF DF DF DF FF 80 80 80 FF 7E 7E 7E FF 7D 7D'
+ '7D FF 76 76 76 FF 7D 7D 7D E8 00 00 00 32 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E2 E1'
+ 'E1 FF F6 F0 E9 FF C9 B4 AE FF E8 D9 D3 FF AA A0'
+ '96 FF B5 AE A6 FF D1 C0 B5 FF CE B7 A4 FF D8 C6'
+ 'BB FF E5 DA D0 FF DB C9 BA FF F9 F4 F0 FF CE BA'
+ 'AB FF C5 AA 93 FF C5 A9 99 FF DB C9 BE FF C6 AB'
+ '9E FF F1 EB E2 FF FC FB F9 FF FA F6 F4 FF F8 F2'
+ 'ED FF FA F6 F2 FF 87 88 87 FF 7E 7E 7E FF 7C 7C'
+ '7C FF 76 76 76 FF 7C 7C 7C EA 00 00 00 34 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E4 E3'
+ 'E3 FF F9 F3 F0 FF F9 F6 F2 FF 92 79 6A FF FE FC'
+ 'F7 FF C9 AD A7 FF C2 AA A8 FF C3 A4 8F FF CC B5'
+ 'A2 FF BF A0 88 FF D3 C2 B2 FF FA F5 F0 FF B4 91'
+ '78 FF D2 BE AB FF D0 BC A7 FF C0 9F 80 FF C6 B2'
+ 'AD FF E1 D2 C7 FF E7 DB D0 FF F7 F0 EA FF F6 F0'
+ 'EA FF FB F7 F4 FF 8D 8D 8D FF 80 80 80 FF 7E 7E'
+ '7E FF 76 76 76 FF 7E 7E 7E EC 00 00 00 38 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F0 F0 F0 47 CF CF'
+ 'CF FF F9 F5 F2 FF ED E2 D6 FF A9 86 70 FF D0 B8'
+ 'A6 FF FA F5 F2 FF F7 EF E8 FF F6 ED E6 FF C8 B0'
+ '9C FF 90 67 4E FF BD 9E 8F FF FA F6 F1 FF D1 BA'
+ 'A7 FF BD A7 94 FF C3 A7 92 FF 9F 83 82 FF FB F7'
+ 'F1 FF F6 EE E8 FF F7 EF E8 FF F7 EF E8 FF F6 EE'
+ 'E7 FF F9 F2 EE FF 8A 8A 8A FF 83 83 83 FF 80 80'
+ '80 FF 77 77 77 FF 80 80 80 EE 00 00 00 3A 00 00'
+ '00 00 00 00 00 00 00 00 00 00 FA FA FA 6F C2 C2'
+ 'C2 FF E2 E1 DF FF FB F5 F0 FF E4 D6 CF FF D5 C5'
+ 'BD FF F9 F0 EA FF F7 F1 EA FF F7 F1 EA FF F7 F0'
+ 'EA FF FB F4 EE FF F7 F1 EC FF F8 F1 EC FF F8 F2'
+ 'EC FF D9 CB BC FF E5 D7 CC FF F2 EA E2 FF F9 F1'
+ 'EB FF F7 F0 EA FF F7 F0 EA FF F7 F0 EA FF FC F9'
+ 'F5 FF C4 C3 C2 FF 89 89 89 FF 83 83 83 FF 81 81'
+ '81 FF 79 79 79 FF 83 83 83 EF 00 00 00 3C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F6 F6 F6 79 C1 C1'
+ 'C1 FF BC BC BC FF D1 D2 D2 FF D9 D9 D9 FF D8 D8'
+ 'D8 FF D6 D6 D6 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3'
+ 'D3 FF D2 D2 D2 FF D0 D0 D0 FF CF CF CF FF CE CE'
+ 'CE FF CE CE CE FF CD CD CD FF CB CB CB FF CA CA'
+ 'CA FF C8 C8 C8 FF C6 C6 C6 FF C7 C7 C7 FF B5 B6'
+ 'B6 FF 8C 8C 8C FF 8B 8B 8B FF 88 88 88 FF 83 83'
+ '83 FF 7D 7D 7D FF 87 87 87 F1 00 00 00 3E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 FB FB FB 84 C1 C1'
+ 'C1 FF BD BD BD FF B8 B8 B8 FF B6 B6 B6 FF B2 B2'
+ 'B2 FF AE AE AE FF AB AB AB FF A9 A9 A9 FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF 9D 9D 9D FF 99 99 99 FF 98 98'
+ '98 FF 95 95 95 FF 94 94 94 FF 93 93 93 FF 92 92'
+ '92 FF 8E 8E 8E FF 8C 8C 8C FF 88 88 88 FF 85 85'
+ '85 FF 7D 7D 7D FF 89 89 89 F3 00 00 00 40 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F9 F9 F9 88 C0 C0'
+ 'C0 FF C1 C1 C1 FF BD BD BD FF BA BA BA FF B6 B6'
+ 'B6 FF B1 B1 B1 FF AE AE AE FF AA AA AA FF A7 A7'
+ 'A7 FF A4 A4 A4 FF A6 A6 A6 FF A4 A4 A4 FF A1 A1'
+ 'A1 FF 9C 9C 9C FF 9E 9E 9E FF 9A 9A 9A FF 98 98'
+ '98 FF 95 95 95 FF 95 95 95 FF 92 92 92 FF 91 91'
+ '91 FF 8F 8F 8F FF 8D 8D 8D FF 8B 8B 8B FF 89 89'
+ '89 FF 80 80 80 FF 8F 8F 8F F4 00 00 00 41 00 00'
+ '00 00 00 00 00 00 00 00 00 00 FB FB FB 89 C2 C2'
+ 'C2 FF C4 C4 C4 FF BC BC BC FF B8 B8 B8 FF B4 B4'
+ 'B4 FF B1 B1 B1 FF AE AE AE FF AB AB AB FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A6 A6 A6 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C 9C FF 99 99'
+ '99 FF 99 99 99 FF 94 94 94 FF 94 94 94 FF 92 92'
+ '92 FF 90 90 90 FF 8E 8E 8E FF 8A 8A 8A FF 89 89'
+ '89 FF 82 82 82 FF 91 91 91 F5 00 00 00 43 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F6 F6 F6 8F C2 C2'
+ 'C2 FF C6 C6 C6 FF C1 C1 C1 FF BC BC BC FF B8 B8'
+ 'B8 FF B2 B2 B2 FF AE AE AE FF AA AA AA FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A3 A3 A3 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF 9F 9F 9F FF 9E 9E 9E FF 9C 9C 9C FF 9B 9B'
+ '9B FF 98 98 98 FF 98 98 98 FF 94 94 94 FF 93 93'
+ '93 FF 93 93 93 FF 91 91 91 FF 8C 8C 8C FF 8A 8A'
+ '8A FF 84 84 84 FF 93 94 93 F6 00 00 00 44 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F1 F1 F1 9C C5 C5'
+ 'C5 FF C7 C7 C7 FF C3 C3 C3 FF BD BD BD FF B9 B9'
+ 'B9 FF B4 B4 B4 FF B1 B1 B1 FF AC AC AC FF AA AA'
+ 'AA FF A8 A8 A8 FF A6 A6 A6 FF A3 A3 A3 FF A1 A1'
+ 'A1 FF 9F 9F 9F FF 9D 9D 9D FF 9E 9E 9E FF 9C 9C'
+ '9C FF 9A 9A 9A FF 98 98 98 FF 98 98 98 FF 95 95'
+ '95 FF 94 94 94 FF 91 91 91 FF 91 91 91 FF 8C 8C'
+ '8C FF 87 87 87 FF 95 95 95 F7 00 00 00 45 00 00'
+ '00 00 00 00 00 00 00 00 00 00 EF EF EF A8 C7 C7'
+ 'C7 FF CB CB CB FF C4 C4 C4 FF C0 C0 C0 FF BB BB'
+ 'BB FF B7 B7 B7 FF B3 B3 B3 FF AD AD AD FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF A1 A1 A1 FF A0 A0 A0 FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9A 9A 9A FF 98 98 98 FF 96 96'
+ '96 FF 96 96 96 FF 92 92 92 FF 91 91 91 FF 8D 8D'
+ '8D FF 86 86 86 FF 96 96 96 F8 00 00 00 47 00 00'
+ '00 00 00 00 00 00 00 00 00 00 EF EF EF B4 C9 C9'
+ 'C9 FF CC CC CC FF C6 C6 C6 FF C3 C3 C3 FF BF BF'
+ 'BF FF B7 B7 B7 FF B2 B2 B2 FF AE AE AE FF AB AB'
+ 'AB FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF A2 A2'
+ 'A2 FF 9E 9E 9E FF 9F 9F 9F FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9C 9C 9C FF 98 98 98 FF 98 98'
+ '98 FF 95 95 95 FF 94 94 94 FF 91 91 91 FF 8D 8D'
+ '8D FF 87 87 87 FF 97 97 97 F9 00 00 00 47 00 00'
+ '00 00 00 00 00 00 00 00 00 00 ED ED ED AB CB CB'
+ 'CB FF CC CD CC FF C8 C8 C7 FF C2 C2 C1 FF BF BF'
+ 'BE FF BA BA BA FF B4 B4 B4 FF B1 B0 AF FF AC AB'
+ 'AA FF A7 A7 A6 FF A4 A4 A4 FF A2 A2 A1 FF 9F 9F'
+ '9E FF A0 A0 A0 FF 9F 9F 9F FF 9D 9D 9D FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9B 9B 9B FF 9B 9B 9B FF 98 98'
+ '98 FF 96 96 96 FF 93 93 93 FF 8F 8F 8F FF 8E 8E'
+ '8E FF 86 86 86 FF 99 99 99 FC 00 00 00 48 00 00'
+ '00 00 00 00 00 00 00 00 00 00 BE BE B9 3B D8 D5'
+ 'D0 FF B8 B2 A6 FF B7 B1 A6 FF B1 AB 9F FF A9 A3'
+ '97 FF A2 9C 92 FF 9C 97 8C FF 98 94 8A FF 96 92'
+ '8B FF 98 94 8E FF 95 92 8D FF 93 90 8C FF 9B 9A'
+ '9A FF 9E 9F 9F FF 9B 9B 9B FF 9C 9C 9C FF 99 99'
+ '99 FF 9A 9A 9A FF 99 99 99 FF 97 97 97 FF 95 95'
+ '95 FF 92 92 92 FF 8F 8F 8F FF 8C 8C 8C FF 87 87'
+ '87 FF 7F 7F 7F FF B5 B5 B5 FC 00 00 00 29 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F5 F0'
+ 'E4 FD DD CE B4 FF DA CC B3 FF D7 CA B1 FF D5 C8'
+ 'AE FF D0 C3 AA FF CC BF A5 FF C5 B9 9F FF BB AE'
+ '94 FF B2 A5 89 FF AD 9F 83 FF A8 9A 7E FF 9C 8A'
+ '66 FF BF BD BC FE D1 D1 D1 FC D0 D0 D0 FC D1 D1'
+ 'D1 FD D2 D2 D2 FD CE CE CE FD CD CD CD FD C8 C8'
+ 'C8 FD C4 C5 C4 FD BD BC BD FD B6 B6 B6 FE B0 B0'
+ 'B0 FD C2 C2 C2 FC 42 42 42 38 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E6'
+ 'E3 53 FF FF F5 F6 FF FF EE F8 FF FC E9 F8 FF FA'
+ 'E7 F8 FF F6 E1 F8 FC F3 DB F8 F9 EF D6 F8 F6 ED'
+ 'CE F8 F3 E9 CB F8 EF E6 C6 F8 EC E0 BE F8 E5 DD'
+ 'CB E2 0B 0B 0B 17 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF D4 CF FF EF A7 90 FF E0 8F'
- '70 FF E0 8F 70 FF 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4087,815 +3814,373 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FC 0F'
- 'FF FF FC 03 FF FF FC 00 FF FF F8 00 3F FF F8 00'
- '0F FF F8 00 03 FF F8 00 00 7F F0 00 00 1F F0 00'
- '00 07 F0 00 00 07 F0 00 00 03 E0 00 00 03 E0 00'
- '00 03 E0 00 00 03 E0 00 00 03 C0 00 00 01 C0 00'
- '00 01 C0 00 00 01 C0 00 00 01 80 00 00 01 80 00'
- '00 00 80 00 00 01 80 00 00 01 80 00 00 03 E0 18'
- '00 7B FE 3F 80 7F FF FF F0 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 D7 C8 BE 01 DD C6 BD 57 CA C1'
- 'BF 65 D8 D1 D0 27 DD D7 D1 03 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 D7 B8 AC 03 DF A0 92 D1 E0 AA'
- '9B FD CA A2 98 E7 CC C3 C4 98 D6 D1 CF 38 DC D4'
- 'D0 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E4 C3 B7 2A F2 AE 94 F8 FC E7'
- 'E4 FF FA DF DB FF DD AC A0 FE C9 9F 97 ED C6 BB'
- 'B8 AC D2 CC CA 49 D7 D1 CB 08 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E6 B1 9D 31 F9 C4 99 FD FC E5'
- 'E0 FF FF F6 FB FF F7 ED ED FF EE D6 D4 FF DF AA'
- '98 FF C8 96 8C F4 C5 B0 B0 BF CD C7 C5 59 DD D5'
- 'D3 15 DE D7 D5 01 00 00 00 00 00 00 00 00 00 00'
- '00 00 DB C8 BE 02 EA C5 B8 BF FA CF 9C FF FC C1'
- '99 FF FF C8 9B FF F3 DD CD FF F0 E6 EA FF EF E0'
- 'DF FF EA D0 CF FF DA A3 98 FF CC 8F 83 F8 C4 A8'
- 'A2 D0 D3 CB CC 78 DC D8 D2 19 00 00 00 00 00 00'
- '00 00 DB C0 B3 03 ED BC A8 D1 FF DD AC FF F7 B8'
- '8A FF FF B4 62 FF F7 A2 52 FF EF A1 6B FF EA BC'
- 'A8 FF E3 D4 D8 FF E0 D0 D1 FF DF C4 C3 FF D1 9F'
- '94 FF C6 85 72 FB D6 CA CB A6 DC D6 D0 05 00 00'
- '00 00 E6 C8 BD 2A F6 CD B7 F8 FF E4 B6 FF F5 B6'
- '8A FF FF C7 7A FF FF B2 5D FF F6 99 44 FF EB 7B'
- '2F FF DE 7A 45 FF D9 9C 85 FF DE C1 C1 FF D3 C0'
- 'C2 FF CE 9D 91 FF CA B6 B3 DA E5 E0 DF 10 00 00'
- '00 00 E6 BE AD 31 FC E3 C8 FD FF E8 C0 FF F6 BB'
- '99 FF FF D1 8F FF FF C3 73 FF FF B2 59 FF F7 99'
- '44 FF E7 77 27 FF D7 5F 1F FF D0 59 28 FF C9 7B'
- '60 FF C9 94 88 FF C2 A4 9D E7 D7 D3 D1 19 DB C9'
- 'C0 03 ED CB C2 BF FF EB D2 FF FF ED CC FF F8 CE'
- 'AE FF F9 C2 9B FF FE C7 92 FF FF C5 7A FF FF B3'
- '5E FF FD A4 44 FF F3 8B 32 FF DE 65 1E FF C9 45'
- '0E FF B8 47 1D FF C2 81 70 F1 E1 DE DC 30 DC C6'
- 'BA 04 EE CB BE D1 FF F4 E0 FF FF F1 D6 FF FF EC'
- 'CC FF FE E0 BA FF FD CD A3 FF F7 B5 8E FF FD C3'
- '8C FF FF B5 59 FF FF AA 46 FF FD 9C 35 FF E2 69'
- '24 FF CB 55 1F FF C9 6B 4E FB DC D6 D7 56 E6 CB'
- 'C2 3A FA DA D1 F8 FF F9 ED FF FF F4 E0 FF FF F1'
- 'D6 FF FF ED CC FF FF E8 C1 FF FF DF B2 FF F3 B3'
- '8B FF F8 B5 7E FF FF B5 68 FF FF AA 49 FF F0 7F'
- '39 FF F0 96 46 FF CF 68 3F FE D0 C4 C2 7B E7 C8'
- 'BD 40 FC EC EB FD FF FA F6 FF FF F9 ED FF FF F4'
- 'E0 FF FF F0 D5 FF FF ED CB FF FF E8 C1 FF FE E0'
- 'B3 FF FC D0 A1 FF F1 B2 83 FF F2 A7 73 FF ED 8A'
- '5E FF F8 B3 71 FF E8 8D 51 FF CB B4 B0 AB E6 CD'
- 'C5 25 EB C9 C1 98 F7 D0 C8 EE F8 DC D0 FC FC E3'
- 'D4 FD F0 C5 B4 E8 EC C2 B1 A7 F7 CD B1 FA F9 D1'
- 'AF FC FF E1 B3 FF FF E2 AD FF FB D0 97 FF D4 A3'
- '92 EB DE B3 A3 94 E2 9B 80 A5 DD AC 9A 3F 00 00'
- '00 00 D9 C5 BA 02 DE C6 BB 17 E0 C1 B6 2A EA BF'
- 'B3 5D DF C4 B8 25 D9 CA BF 05 DD C1 B2 1A E1 C0'
- 'B3 30 E8 B9 A5 93 F4 C3 A7 E8 EF B7 8E FA D4 B5'
- 'A8 8B D0 C9 C1 01 D9 CA BF 05 D9 CA BF 05 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 DF CA BF 15 D8 B5 A2 1A D6 BA'
- 'A9 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 FF'
- '00 00 C0 7F 00 00 C0 1F 00 00 C0 03 00 00 80 01'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 FF C7 00 00 FF FF 00 00 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 7F 7F 7F 00 00 99'
- '99 00 66 CC CC 00 99 CC FF 00 99 FF FF 00 F8 F8'
- 'F8 00 00 00 00 00 E2 69 24 00 E7 77 27 00 EB 7B'
- '2F 00 F0 7F 39 00 C7 6B 4E 00 DE 7A 45 00 C9 7B'
- '60 00 F3 8B 32 00 FD 9C 35 00 BE 80 70 00 BF 91'
- '7F 00 F0 96 46 00 F6 99 44 00 F7 99 44 00 E8 8D'
- '51 00 ED 8A 5E 00 FD A4 44 00 FF AA 46 00 FF AA'
- '49 00 F7 A2 52 00 FF B2 59 00 FF B5 59 00 FF B2'
- '5D 00 FF B3 5E 00 C4 84 72 00 EF A1 6B 00 FF B4'
- '62 00 FF B5 68 00 F2 A7 73 00 F8 B3 71 00 F8 B5'
- '7E 00 FF C3 73 00 FF C5 7A 00 FF C7 7A 00 96 8A'
- '85 00 96 90 8E 00 99 91 8E 00 92 91 90 00 96 95'
- '94 00 9F 97 94 00 9A 98 97 00 3C 17 95 00 00 00'
- '38 00 A8 44 F9 77 21 00 00 00 B8 0C 38 00 00 00'
- '38 00 30 7E 0D 01 14 17 95 00 B1 A2 9F 00 5C 19'
- '95 00 00 40 0D 01 68 19 95 00 77 82 F5 77 98 7F'
- 'F5 77 3A 8A F5 77 00 04 00 00 C4 A2 AF 00 10 00'
- '00 00 10 00 00 00 C9 94 88 00 CD 9A 8E 00 D9 9C'
- '85 00 C3 9C 95 00 C2 9E 95 00 CE 9D 91 00 D1 9F'
- '94 00 CD A0 90 00 C6 AA 9F 00 DA A3 98 00 DF AA'
- '98 00 DF A9 9A 00 DC AB 9F 00 EC B5 8D 00 F1 B2'
- '83 00 F3 B3 8B 00 F5 B6 8A 00 F7 B5 8E 00 F7 B8'
- '8A 00 EE AC 93 00 F6 BB 99 00 CF B3 A9 00 D9 B0'
- 'A0 00 D1 B7 B1 00 D9 BD B2 00 E9 BC A3 00 E5 BE'
- 'AF 00 EA BC A8 00 FD C3 8C 00 FF D1 8F 00 FE C7'
- '92 00 F8 C3 98 00 F9 C2 9B 00 FC C1 99 00 FF C8'
- '9B 00 FA CF 9C 00 FB D0 97 00 FD CD A3 00 F8 CE'
- 'AE 00 FC D0 A1 00 F7 D0 AE 00 FF DD AC 00 F4 CB'
- 'B0 00 F2 CA B5 00 FF DF B2 00 FF E2 AD 00 FE E0'
- 'B3 00 FF E1 B3 00 FF E4 B6 00 FE E0 BA 00 D3 C0'
- 'C2 00 A8 01 38 00 10 44 0D 01 40 00 00 00 00 00'
- '00 00 A8 01 38 00 38 44 0D 01 38 44 0D 01 E0 D0'
- 'D1 00 EE D6 D4 00 E3 D4 D8 00 FA DF DB 00 FB E2'
- 'C7 00 FF E8 C0 00 FF E8 C1 00 FF ED CB 00 FF EC'
- 'CC 00 08 44 0D 01 08 44 0D 01 FB E2 D3 00 FF EB'
- 'D2 00 FF F0 D5 00 FF F1 D6 00 FC E5 E0 00 FC E7'
- 'E4 00 F0 E6 EA 00 00 40 0D 01 A4 18 95 00 E5 3A'
- 'F8 77 06 00 00 00 08 44 0D 01 00 00 38 00 00 40'
- '0D 01 00 00 00 00 78 19 95 00 CA 8C F5 77 78 01'
- '38 00 BE 8E F5 77 08 06 38 00 37 90 F5 77 08 40'
- '0D 01 08 40 0D 01 40 00 00 00 40 00 00 00 D0 BB'
- 'BB 00 E0 B2 A5 00 EE BD A2 00 E3 B4 AA 00 E4 BB'
- 'AF 00 F1 B6 A7 00 F6 BE A2 00 F0 BA AB 00 E5 BE'
- 'B3 00 EC BC B0 00 00 40 0D 01 00 40 0D 01 F4 C4'
- '97 00 78 01 38 00 08 40 0D 01 E0 07 0D 01 E8 07'
- '0D 01 78 01 38 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 F5 C8 AA 00 00 40 0D 01 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 C2'
- 'B7 00 08 04 00 00 87 00 00 00 08 04 00 00 08 01'
- '00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00'
- '38 00 BC 18 95 00 C0 18 95 00 B0 19 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 81 E9'
- '49 00 00 00 38 00 00 00 00 00 08 40 0D 01 08 40'
- '0D 01 A4 1A 95 00 40 00 00 00 40 00 00 00 B8 10'
- 'E9 77 FF FF FF FF C9 F1 E7 77 16 EA 4B 00 F8 00'
- '00 00 B4 1A 95 00 DC E3 49 00 E0 A3 4E 00 FF FF'
- 'FF FF 10 00 00 00 10 DA 4B 00 08 40 0D 01 71 CC'
- '43 00 08 40 0D 01 30 7E 0D 01 A4 1A 95 00 C4 A2'
- 'AF 00 C4 F5 AF 00 02 00 00 00 30 7E 0D 01 0F 02'
- '00 00 48 40 0D 01 10 00 00 00 00 00 00 00 20 00'
- '00 00 08 40 0D 01 40 00 00 00 10 00 00 00 00 01'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 10 00 00 00 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 07 07 07 07 07 07 07'
- '07 07 07 07 07 07 00 00 02 02 02 02 02 02 02 02'
- '02 02 02 02 07 07 00 00 02 06 04 05 04 05 04 04'
- '04 04 03 02 07 07 00 02 06 05 05 04 05 04 05 04'
- '04 04 03 07 02 07 00 02 06 05 05 05 05 05 04 05'
- '04 04 02 07 02 07 02 06 05 05 05 05 04 05 05 04'
- '05 03 07 03 03 07 02 06 05 05 05 05 05 05 04 05'
- '04 03 07 03 03 07 02 02 02 02 02 02 02 02 02 02'
- '02 02 03 05 03 07 00 02 06 05 05 05 05 05 05 05'
- '05 05 05 05 03 07 00 02 06 05 05 05 05 05 05 05'
- '06 06 06 06 03 07 00 02 06 05 05 05 05 05 06 02'
- '02 02 02 02 02 00 00 00 02 06 06 06 06 06 02 00'
- '00 00 00 00 00 00 00 00 00 02 02 02 02 02 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF 00 00 FF FF 00 00 E0 00'
- '00 00 C0 00 00 00 C0 00 00 00 80 00 00 00 80 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 00 00 00 80 01 00 00 C0 7F 00 00 E0 FF'
- '00 00 FF FF 00 00'
-} */
-
-/* BINRES floppy.ico */
-5 ICON floppy.ico
-/* {
- '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 3E 09 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 A6 0E 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 CE 0F 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 5E 21 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 C6 27 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 6E 4D 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 01 01 00 02 02 02 00 04 04 04 00 05 05'
- '05 00 07 07 07 00 09 09 09 00 0A 0A 0A 00 0C 0C'
- '0C 00 0D 0D 0D 00 10 10 10 00 12 12 12 00 13 13'
- '13 00 15 15 15 00 16 16 16 00 17 17 17 00 18 18'
- '18 00 19 19 19 00 1B 1B 1B 00 1C 1C 1C 00 1E 1E'
- '1E 00 1F 1F 1F 00 20 20 20 00 21 21 21 00 23 23'
- '23 00 24 24 24 00 25 25 25 00 26 26 26 00 27 27'
- '27 00 28 28 24 00 2A 2A 25 00 28 28 28 00 2A 2A'
- '2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E 2E 00 32 32'
- '32 00 33 33 33 00 34 34 34 00 35 35 35 00 37 37'
- '37 00 3B 3B 3B 00 3C 3C 3C 00 3D 3D 3D 00 3F 3F'
- '3F 00 40 40 40 00 44 44 44 00 45 45 45 00 46 46'
- '46 00 47 47 47 00 48 48 48 00 49 49 49 00 4B 4B'
- '4B 00 4C 4C 4C 00 4E 4E 4E 00 50 50 50 00 52 52'
- '52 00 57 57 57 00 59 59 59 00 5E 5E 5E 00 61 61'
- '61 00 64 64 64 00 65 65 65 00 6A 6A 6A 00 7F 60'
- '60 00 71 71 71 00 77 77 77 00 79 79 79 00 7F 7F'
- '7F 00 D5 40 40 00 00 C0 00 00 00 FF 00 00 87 80'
- '7D 00 8B 86 84 00 8A 8A 8A 00 8C 8C 8C 00 8D 8D'
- '8D 00 8E 8E 8E 00 97 97 97 00 99 99 99 00 9A 9A'
- '9A 00 9E 9E 9E 00 A3 A3 9E 00 A4 A4 A4 00 A7 A7'
- 'A7 00 AA AA AA 00 AB AB AB 00 AD A8 AB 00 AE AE'
- 'AE 00 AF AF AF 00 B0 B0 B0 00 B2 B2 B2 00 B5 B5'
- 'B5 00 B6 B6 B6 00 B7 B7 B7 00 BB BB BB 00 BC BC'
- 'BC 00 BD BD BD 00 BF BF BF 00 EA 80 80 00 CA A8'
- '94 00 CC AF 9D 00 E9 B6 99 00 E9 B8 9C 00 CE B6'
- 'A6 00 D0 B3 A3 00 EB BE A5 00 D2 C3 B9 00 EC C0'
- 'A7 00 EF CC B8 00 C2 C2 C2 00 C4 C4 C4 00 C5 C5'
- 'C5 00 C6 C6 C6 00 C8 C9 C9 00 C9 C9 C9 00 CA CA'
- 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CF CF'
- 'CF 00 D5 CB C4 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
- 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
- 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
- 'D8 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
- 'DE 00 DF DF DF 00 F1 D2 C2 00 F2 D6 C7 00 F4 DD'
- 'D0 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3'
- 'E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7'
- 'E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
- 'EB 00 EC EC EC 00 ED ED ED 00 F0 F0 F0 00 F2 F2'
- 'F2 00 F3 F3 F3 00 F9 F9 F9 00 FA FA FA 00 FF FF'
- 'FF 00 00 00 00 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 56 00'
- '00 00 00 00 00 00 03 00 00 00 5E 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 66 6C 6F 70 70 79 2E 69 63'
- '6F 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 2A 2A 2A 2A 40 40 40 40 40 40 40 40 40 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4B 4B 4B 4B A1 A1 A1 A1 A1 A1 A1 A1 A1 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1D 00 4B 08 45 45 45 45 45 45 45 45 45 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1E A1 A1 08 63 63 63 63 63 63 63 63 63 00 A1'
- 'A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
- 'A1 03 08 0A 10 9A 94 94 94 94 94 94 94 94 00 A1'
- 'A1 17 22 22 21 21 21 21 21 21 21 20 20 20 20 20'
- '20 08 08 10 0F 99 94 4F 4F 4F 4F 4F 4F 4F A1 01'
- '4A 98 95 95 7E 46 94 95 90 82 7C 77 77 77 72 55'
- '23 A1 A1 15 10 97 93 95 95 97 97 98 98 99 A1 11'
- '57 98 95 95 47 47 46 89 7F 7C 75 77 77 77 77 2D'
- '23 A1 A1 0D 0C 96 94 4F 4F 4F 4F 4F 4F 4F A1 1F'
- '7B 98 98 95 95 47 5C 5D 29 29 29 29 29 29 29 5D'
- '5D A1 A1 07 09 95 94 90 90 91 91 93 93 94 A1 1F'
- '7B 95 98 95 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
- 'A1 19 15 05 07 92 94 4F 4F 4F 4F 4F 4F 4F A1 1C'
- '7C 97 98 98 54 56 58 59 59 59 59 56 56 56 56 56'
- '56 24 08 A1 A1 92 92 94 94 96 96 97 97 98 A1 1B'
- '7D 98 9A 96 95 91 8F 86 82 7C 7C 7A 7A 7A 7A 7A'
- '7A 28 02 03 03 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 19'
- '80 96 8E 8F 8D 89 89 89 8D 8D 8D 8D 8D 8D 8D 8D'
- '8D 2C 09 0B 0E 17 1B 2A 2E 30 30 22 22 22 A1 19'
- '88 83 6F 62 82 83 83 83 83 83 83 83 83 83 83 83'
- '83 2E 18 12 16 21 27 2E 31 30 30 22 22 22 A1 04'
- '6E 60 5B 56 5F 7F 7F 7E 7D 7F 81 82 81 7D 7D 7E'
- '7F 34 35 23 25 2F 2E 34 34 2A 24 1A 13 0E 00 A1'
- '53 78 70 62 73 7C 7A 7A 7A 7F 7F 7F 7F 7F 7A 7E'
- '7A 38 39 27 2C 4B 4B 4B 4B 4B 4B 4B 4B 4B 00 A1'
- '3A 7A 77 77 74 7D 7D 7E 7F 80 80 80 80 80 7F 85'
- '91 3B 3B 3F 2E 4D A0 49 48 69 6C 66 66 66 00 A1'
- '2D 7C 74 74 7E 7D 7D 7C 7C 7C 7C 7D 7C 7D 7C 7B'
- '7A 3B 3B 3F 2E 4D A0 49 48 69 6C 66 66 66 00 A1'
- '05 87 76 7D 7D 7A 7A 7A 7A 7D 7D 7D 7D 7D 7D 7D'
- '7D 3E 3F 41 43 51 A0 38 36 8B 6D 67 66 66 00 A1'
- 'A1 87 78 7D 7D 7A 7A 7A 7A 7A 78 7D 7D 7D 7D 7D'
- '7D 2A 3F 41 43 55 A0 37 35 8C 8A 6A 66 66 00 A1'
- 'A1 82 7E 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D'
- '7D A1 A1 A1 A1 52 84 84 84 79 6B 68 65 64 00 A1'
- 'A1 76 80 7D 7D 80 80 80 80 80 80 80 7D 7D 7D 76'
- '73 6F 6E 61 7A 06 A1 00 00 00 00 00 00 00 00 A1'
- 'A1 4E 86 86 88 88 87 87 87 87 87 87 87 87 87 87'
- '87 94 94 86 71 A1 A1 00 00 00 00 00 00 00 00 00'
- 'A1 42 7D 8E 88 88 88 8D 8D 8D 8D 8D 8D 8D 8D 8E'
- '8E 94 94 83 5F A1 A1 00 00 00 00 00 00 00 00 00'
- 'A1 27 61 93 93 94 98 98 98 98 98 98 98 98 98 94'
- '94 94 93 7E 50 A1 A1 00 00 00 00 00 00 00 00 00'
- 'A1 14 56 9A 94 99 98 9A 98 98 98 98 98 98 98 98'
- '99 92 98 80 4A A1 A1 00 00 00 00 00 00 00 00 00'
- '00 A1 4C 6F 5B 5B 98 9B 9B 9B 9B 9B 9B 9B 9B 9D'
- '7F 5D 5E 77 3C A1 A1 00 00 00 00 00 00 00 00 00'
- '00 A1 3D 87 86 91 9E 9E 9E 9E 9E 9E 9E 9E 9E 9F'
- '9C 82 86 5A 26 A1 00 00 00 00 00 00 00 00 00 00'
- '00 A1 A1 2B 33 32 32 32 32 32 32 32 32 32 32 32'
- '32 33 33 02 A1 00 00 00 00 00 00 00 00 00 00 00'
- '00 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
- 'A1 A1 A1 A1 A1 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF E0 00 FF FF E0 00 FF FF E8 00 FF FF'
- 'E0 00 80 00 00 00 80 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 7F 80 00 00 7F C0 00'
- '00 7F C0 00 00 7F C0 00 00 7F E0 00 00 7F E0 00'
- '00 FF E0 00 01 FF E0 00 01 FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01'
- '01 00 03 06 04 00 05 05 05 00 09 09 09 00 0A 0C'
- '0C 00 08 0D 0F 00 13 13 13 00 15 15 15 00 16 16'
- '15 00 17 17 17 00 18 18 18 00 19 19 19 00 1D 1D'
- '1D 00 1E 1E 1E 00 31 0A 0B 00 1A 1E 20 00 35 19'
- '35 00 21 21 21 00 29 23 23 00 30 2A 30 00 31 31'
- '31 00 32 33 33 00 34 34 34 00 35 35 35 00 36 36'
- '36 00 39 39 39 00 3A 3A 3B 00 3B 3B 3B 00 7A 00'
- '00 00 4E 3E 3E 00 3F 41 42 00 44 44 44 00 46 46'
- '46 00 4B 4B 4B 00 50 52 52 00 57 57 57 00 59 59'
- '59 00 5C 5C 5C 00 5E 5E 5E 00 65 6A 68 00 69 69'
- '69 00 6E 6E 6E 00 6F 6E 6E 00 77 6E 69 00 7E 69'
- '69 00 72 72 72 00 75 75 75 00 79 73 79 00 79 79'
- '79 00 7B 7B 7B 00 7F 7F 7F 00 83 00 00 00 88 70'
- '70 00 00 FF 00 00 75 99 75 00 97 97 97 00 9B 9B'
- '9B 00 A5 A5 A5 00 A6 A6 A6 00 A8 A2 A8 00 A8 A8'
- 'A8 00 A9 A9 A9 00 AF AF AF 00 B8 AC B8 00 B2 B2'
- 'B2 00 ED B7 97 00 C0 AE A4 00 DB B7 A2 00 DC B7'
- 'A2 00 B7 E6 B7 00 FB C6 A8 00 F9 C7 AB 00 C0 C0'
- 'C0 00 C1 C2 C2 00 C2 C2 C2 00 C3 C3 C3 00 C6 CD'
- 'CD 00 C7 CE CE 00 C9 C9 C9 00 CA CA CA 00 C8 CF'
- 'CF 00 CC CC CC 00 CE CE CE 00 D0 D0 D0 00 D1 D1'
- 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
- 'D5 00 D6 D6 D6 00 D7 D7 D7 00 DE D8 D3 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DE DE DE 00 FF C9'
- 'C9 00 FF D7 D7 00 FF E3 D0 00 DF E6 E6 00 E0 E0'
- 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E4 E4 E4 00 E5 E5'
- 'E5 00 E6 E6 E6 00 E8 E3 E1 00 E8 E8 E8 00 E9 E9'
- 'E9 00 EA EA EA 00 EB EB EB 00 ED ED ED 00 F3 F3'
- 'F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6 F6 00 FF F2'
- 'FF 00 F9 F9 F9 00 FA FA FA 00 FB FB FB 00 FB FC'
- 'FC 00 FC FC FC 00 FF FD FE 00 FE FE FE 00 FF FF'
- 'FF 00 00 00 00 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA D8 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 F1 D2'
- 'C2 00 F2 D6 C7 00 F4 DD D0 00 E0 E0 E0 00 E1 E1'
- 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
- 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
- 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
- 'ED 00 F0 F0 F0 00 F2 F2 F2 00 F3 F3 F3 00 F9 F9'
- 'F9 00 FA FA FA 00 FF FF FF 00 00 00 00 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 56 00 00 00 00 00 00 00 03 00'
- '00 00 5E 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 66'
- '6C 6F 70 70 79 2E 69 63 6F 00 1A 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
- '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
- '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '06 14 36 2E 2E 2E 00 00 00 00 00 00 00 00 00 0A'
- '29 10 35 1E 1E 1E 00 7F 7F 7F 7F 7F 7F 7F 7F 01'
- '03 1F 63 62 62 62 7F 2C 3D 38 41 40 3E 3C 3F 0D'
- '05 24 65 4E 4F 52 7F 7C 76 37 47 31 33 32 42 08'
- '7F 23 6B 51 53 53 7F 7D 7D 12 15 19 19 18 19 13'
- '7F 23 7D 66 68 69 7F 7E 72 7D 77 75 72 72 7E 28'
- '7F 02 7F 0B 0C 04 7F 7B 3B 58 5B 5A 5C 5B 69 25'
- '0F 16 1C 20 11 07 7F 5C 54 54 57 59 5A 5A 67 27'
- '25 17 6C 44 46 45 7F 3A 57 58 55 55 56 57 66 26'
- '2F 22 4B 2D 48 43 00 2A 61 55 55 55 56 57 67 1D'
- '0E 21 7A 5D 64 49 00 1B 71 60 5E 5F 5F 5E 5E 6A'
- '71 30 7F 00 00 00 00 04 72 6F 6D 6B 6A 6A 69 70'
- '75 1A 00 00 00 00 00 7F 6E 50 77 75 73 74 78 54'
- '79 09 00 00 00 00 00 7F 2B 4A 4D 4C 4C 4C 4C 4A'
- '39 7F 00 00 00 00 00 00 7F 7F 7F 7F 7F 7F 7F 7F'
- '7F 00 00 00 00 00 FF C0 00 00 FF 80 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 80 0F'
- '00 00 C0 1F 00 00 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00'
- '00 00 00 09 99 99 00 00 00 00 00 0F FF FF 0F FA'
- '77 77 00 0F 88 88 0F F0 00 00 00 0F FF FF 0F F7'
- '77 77 70 00 00 00 07 77 77 77 70 00 00 00 07 77'
- '77 77 70 08 88 88 07 77 77 77 70 08 87 77 07 77'
- '77 77 70 07 8F 77 07 77 77 77 77 70 00 00 08 77'
- '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 77'
- '77 77 77 70 00 00 00 00 00 00 00 00 00 00 FF 80'
- '00 00 FF 80 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 07 00 00 80 07'
- '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 28 00'
- '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
- '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 08 88 88 88 88 00 00 00 00 00 00 00 00 00 08'
- '88 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '08 09 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
- '00 07 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
- '00 0F FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
- '00 0F F8 88 88 88 00 8F FF 7A FF F7 77 77 77 00'
- '00 0F FF FF FF FF 00 7F FF AA A7 77 77 77 70 00'
- '00 0F F8 88 88 88 00 7F FF FA 77 00 00 00 07 70'
- '00 0F FF FF FF FF 00 7F FF 00 00 00 00 00 00 00'
- '00 0F F8 88 88 88 00 7F FF 77 77 77 77 77 77 70'
- '00 0F FF FF FF FF 00 7F FF 77 77 77 77 77 77 70'
- '00 00 00 00 00 00 00 7F FF FF FF FF FF FF FF F0'
- '00 00 00 88 80 00 00 77 77 77 77 77 77 77 77 78'
- '00 00 08 88 80 00 00 77 77 77 77 77 77 77 77 78'
- '80 08 88 80 00 00 00 77 77 77 77 77 77 77 77 78'
- '80 08 88 88 88 88 00 87 77 77 77 77 77 77 77 78'
- '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 78'
- '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 78'
- '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 70'
- '88 87 F8 8F 77 77 00 07 77 77 77 77 77 77 77 70'
- '00 07 77 77 77 77 00 07 77 77 77 77 77 77 77 77'
- '77 70 00 00 00 00 00 08 77 77 77 77 77 77 77 77'
- '77 70 00 00 00 00 00 08 77 77 77 77 77 77 77 77'
- '77 70 00 00 00 00 00 00 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
- '77 00 00 00 00 00 00 00 00 88 88 88 88 88 88 88'
- '80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF E0 00 FF FF E0 00 FF FF'
- 'E0 00 FF FF E8 00 E0 00 00 00 80 00 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 3F 80 00 00 7F C0 00 00 7F C0 00 00 7F C0 00'
- '00 7F E0 00 00 7F E0 00 00 FF E0 00 00 FF E0 00'
- '01 FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 01 01 00 02 02 02 00 03 03 03 00 04 04'
- '04 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
- '08 00 09 09 09 00 0A 0A 0A 00 0B 0B 0B 00 0C 0C'
- '0C 00 0D 0D 0D 00 0E 0E 0E 00 10 10 10 00 11 11'
- '11 00 12 12 10 00 12 12 12 00 13 13 13 00 14 14'
- '14 00 15 15 15 00 16 16 14 00 16 16 16 00 17 17'
- '17 00 18 18 18 00 19 19 19 00 1B 1B 1B 00 1C 1C'
- '1C 00 1E 1E 1E 00 1F 1F 1F 00 22 22 1F 00 20 20'
- '20 00 21 21 21 00 22 22 22 00 23 23 23 00 24 24'
- '24 00 25 25 25 00 26 26 26 00 27 27 27 00 28 28'
- '24 00 2A 2A 25 00 2B 2B 26 00 28 28 28 00 29 29'
- '29 00 2A 2A 2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E'
- '2E 00 2F 2F 2F 00 30 30 2C 00 30 30 30 00 32 32'
- '32 00 33 33 33 00 36 36 30 00 34 34 34 00 35 35'
- '35 00 36 36 36 00 37 37 37 00 39 39 39 00 3B 3B'
- '3B 00 3C 3C 3C 00 3D 3D 3D 00 3F 3F 3F 00 40 40'
- '40 00 41 41 41 00 42 42 42 00 43 43 43 00 44 44'
- '44 00 45 45 45 00 46 46 46 00 47 47 47 00 48 48'
- '48 00 49 49 49 00 4A 4A 4A 00 4B 4B 4B 00 4C 4C'
- '4C 00 4E 4E 4E 00 4F 4F 4F 00 50 50 50 00 52 52'
- '52 00 53 53 53 00 54 54 54 00 57 57 57 00 5B 58'
- '57 00 59 59 59 00 5D 5D 5D 00 5E 5E 5E 00 5F 5F'
- '5F 00 61 61 61 00 64 64 64 00 65 65 65 00 66 66'
- '66 00 6D 6A 67 00 6A 6A 6A 00 7F 60 60 00 71 71'
- '71 00 75 75 75 00 77 77 77 00 7B 77 75 00 79 79'
- '79 00 7A 7A 7A 00 7E 7E 7E 00 7F 7F 7F 00 C0 00'
- '00 00 83 7A 75 00 D5 40 40 00 00 C0 00 00 00 FF'
- '00 00 87 80 7D 00 80 80 80 00 83 83 83 00 84 84'
- '84 00 8B 86 84 00 8A 8A 8A 00 8C 8C 8C 00 8D 8D'
- '8D 00 8E 8E 8E 00 90 90 90 00 93 93 93 00 97 97'
- '97 00 99 99 99 00 9A 9A 9A 00 9E 9E 9E 00 9F 9F'
- '9F 00 A3 A3 9E 00 A4 A4 A4 00 A6 A6 A6 00 A7 A7'
- 'A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA AA 00 AB AB'
- 'AB 00 AD A8 AB 00 AB AC AC 00 AD AD AD 00 AE AE'
- 'AE 00 AF AF AF 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
- 'B2 00 B3 B3 B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7'
- 'B7 00 B8 B4 B6 00 B8 B6 B6 00 B8 B8 B8 00 BA BA'
- 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
- 'BE 00 BF BF BF 00 EA 80 80 00 CA A8 94 00 CC AF'
- '9D 00 E9 B6 99 00 E9 B8 9C 00 CE B6 A6 00 D0 B3'
- 'A3 00 D0 BC B0 00 EA BB A0 00 EA BC A1 00 EB BE'
- 'A5 00 D2 C3 B9 00 EC C0 A7 00 EC C2 AA 00 ED C5'
- 'AE 00 ED C6 AF 00 EE C8 B3 00 EF CC B8 00 F0 CF'
- 'BC 00 F0 D0 BE 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2'
- 'C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6'
- 'C6 00 C8 C8 C8 00 C8 C9 C9 00 C9 C9 C9 00 CA CA'
- 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
- 'CE 00 CF CF CF 00 D5 CB C4 00 D0 CB C8 00 D7 D2'
- 'CE 00 D9 D1 CC 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
- 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
- 'D6 00 D7 D7 D7 00 DC D9 D7 00 D8 D8 D8 00 D9 D9'
- 'D9 00 DA DA D8 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 FF C0'
- 'C0 00 F1 D2 C2 00 F2 D6 C7 00 F3 D9 CB 00 F4 DD'
- 'D0 00 F6 E4 D9 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
- 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
- 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
- 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
- 'EE 00 EF EF EF 00 F9 EE E8 00 F0 F0 F0 00 F1 F1'
- 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
- 'F5 00 F6 F6 F6 00 F7 F7 F7 00 FD F9 F7 00 F8 F8'
- 'F8 00 F9 F9 F9 00 FA FA FA 00 FF FF FF 00 00 00'
- '00 00 C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF C0 00'
+ '00 07 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
+ '00 03 C0 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 C0 00 00 07 C0 00 FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 00 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 80 00 00 F8 88 88 88 88 88 88 88 88'
+ '87 78 77 77 77 77 77 77 77 77 77 77 70 00 00 F8'
+ '88 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 88'
+ '88 88 88 88 70 00 00 F8 8F 44 44 4F FF FF FF FF'
+ 'FF FF FF FF FF FF FF F8 88 88 88 88 70 00 00 F8'
+ 'FF 4F FF F4 44 44 44 44 4F FF FF 44 44 44 4F FF'
+ '88 88 88 88 70 00 00 F8 FF 4F F4 FF FF FF FF FF'
+ 'F4 44 44 FF FF FF FF FF 88 88 88 88 70 00 00 F8'
+ 'FF F4 F4 4F 44 4F 44 4F FF 4F F4 44 4F FF FF FF'
+ '88 88 88 88 70 00 00 F8 FF F4 4F F4 FF F4 4F 4F'
+ 'F4 FF FF 4F FF FF FF FF 88 88 88 88 70 00 00 F8'
+ 'FF F4 F4 FF FF F4 F4 FF F4 F4 F4 4F FF FF FF FF'
+ '88 88 88 88 70 00 00 F8 FF F4 44 FF FF FF 44 44'
+ 'F4 44 FF 4F FF FF FF FF 88 88 88 88 70 00 00 F8'
+ '8F FF FF FF FF FF FF FF FF FF FF FF FF FF FF F8'
+ '88 88 88 88 70 00 00 F8 88 FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F8'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 70 00 00 F7'
+ '77 77 77 77 77 77 77 77 77 78 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 F6 66 66 66 66 66 66 66 66'
+ '66 67 77 77 77 77 77 77 77 77 77 77 00 00 00 FE'
+ '6E 6E 6E 6E 6E 6E 6E 6E 6E 68 88 88 88 88 88 88'
+ '88 88 88 80 00 00 00 0F EF EF EF EF EF EF EF EF'
+ 'EF 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '88 88 88 88 88 88 88 88 88 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 F8 F8 F8 F8 F8'
- 'F8 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 3D 3D 3D 3D 3D'
- 'F8 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 73 73 73 73 73'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 16 36 36 1F 04'
- 'F8 68 68 68 68 68 68 68 68 68 68 68 68 68 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 28 00 00 73 0C'
- 'F8 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 F8 29 F8 F8 F8 0C'
- 'F8 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 00 00'
- '00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 11 2A 32 1F 0F'
- 'F8 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 00 00'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 04 0C 0C 0F 19'
- 'F8 E7 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 00 F8'
- 'F8 F8 F8 21 2F 2E 2F 2E 2E 2E 2E 2E 2E 2E 2E 2E'
- '2E 2E 2D 2D 2D 2D 2D 2D 2D 2D F8 0C 0C 0F 19 18'
- 'F8 E6 E1 79 79 79 79 79 79 79 79 79 79 79 00 F8'
- 'F8 26 76 91 87 86 85 BB BA B9 B7 B2 B1 B0 B0 B1'
- 'AE AF 99 99 96 97 94 97 97 97 F8 0C 0F 19 19 1D'
- 'F8 E5 CF DA DA DA DB DB DB DC DD DD DD DE F8 F8'
- '01 72 85 E5 E2 E2 E2 C6 6B 6B E1 E2 E2 DD D1 CB'
- 'C4 BB BB BB BB BB B6 BB 83 30 F8 F8 F8 19 1E 19'
- 'F8 E4 E0 E1 E2 E2 E3 E4 E4 E4 E5 E5 E5 E6 F8 F8'
- '1A 85 E5 E5 E2 E2 E2 6C 6C 6C 6B DB D3 C7 BA C4'
- 'B9 BB BB BB BB BB BB BB 40 30 F8 F8 F8 1E 15 13'
- 'F8 E3 E1 79 79 79 79 79 79 79 79 79 79 79 F8 F8'
- '2C 85 E4 E5 E5 E2 E2 6C 6C 6C 6C B9 B5 5C 5C 5C'
- '5C 5C 5C 5C 5C 5C 5C BB 77 40 F8 F8 F8 F8 0E 0F'
- 'F8 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 F8 F8'
- '2B C3 E6 E5 E5 E2 E2 E2 6C 6C 8E 8E 8F 3C 3C 3C'
- '3C 3C 3C 3C 3C 3C 3C 8F 8F 8F F8 F8 F8 F8 0A 0D'
- 'F8 E2 E1 DD DD DD DD DE DE DF E0 E0 E0 E1 F8 F8'
- '2B C3 E8 E2 E5 E2 E2 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 24 1E 05 07 0A'
- 'F8 DF E1 79 79 79 79 79 79 79 79 79 79 79 F8 F8'
- '27 C3 E9 E5 E5 E5 E5 6E 3C 3C 3C 3C 3C 3C 3C 3C'
- '3C 3C 3C 3C 3C 3C 3C 3C 3C 3C F8 2E 10 02 03 03'
- 'F8 D0 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 F8 F8'
- '27 C4 ED E4 E5 E5 E5 80 80 84 88 8A 89 89 89 89'
- '89 89 84 84 84 84 84 84 84 84 F8 34 0C F8 F8 F8'
- 'F8 DF DF E0 E1 E1 E2 E3 E3 E3 E4 E4 E4 E5 F8 F8'
- '26 C5 EE E5 E7 E5 E3 E2 E0 DE DC CF D0 CB CC C4'
- 'C4 BD C2 C2 C2 C2 C2 C2 C2 C2 F8 3A 02 03 04 04'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- '26 C5 F2 F4 F1 F1 F1 F0 F0 EF EF EE EE EE ED ED'
- 'EC EC EC EB EB EB E9 E9 E8 E8 F8 3A 07 09 0B 0D'
- '0F 13 1A 1D 27 37 42 46 46 46 46 2F 2F 2F F8 F8'
- '24 C8 F7 E3 DB DC DC DA D3 D3 D3 D3 D3 DA DA DA'
- 'DA DA DA DA DA DA DA DA DA DA F8 3F 0D 10 12 17'
- '1B 21 26 33 3D 44 47 46 46 46 2F 2F 2F 2F F8 F8'
- '24 D2 F4 CC B2 95 99 CB CE CC CC CC CC CC CC CC'
- 'CC CC CC CC CC CC CC CC CC CC F8 44 23 18 1B 20'
- '27 2E 38 40 44 47 4A 46 46 2F 2F 2F 2F 2F F8 F8'
- '1E CE EE B4 82 90 8A B1 CE CB CB CB CB CB C9 C9'
- 'C9 C9 C9 C9 C9 C9 CB CB CB CB F8 4B 30 1E 25 2E'
- '31 3B 43 44 47 4B 49 42 39 2F 23 1C 1C 14 F8 F8'
- '05 B0 F1 96 8C B1 84 95 CB C7 C7 C7 C6 C5 C5 C7'
- 'C9 CB CB C9 C7 C5 C5 C5 C6 C7 F8 4B 4C 27 30 35'
- '3D 45 44 47 4B 4B 45 3D 34 2D 25 1C 1C 17 00 F8'
- 'F8 7E EF BD B3 C4 99 B7 C5 C4 C2 C5 C2 C2 C7 C7'
- 'C7 C7 C7 C7 C7 C7 C2 C2 C6 C2 F8 50 53 3D 38 3F'
- 'F8 73 73 73 73 73 73 73 73 73 73 73 73 73 00 F8'
- 'F8 66 E9 C3 BD B9 BD C3 BC BD C7 C7 C7 C7 C7 C7'
- 'C7 C7 C7 C7 C7 C7 C7 C7 C7 DB F8 53 57 56 49 45'
- 'F8 70 F3 EA D9 D7 AC A8 A2 9D 9D 9D 9D 9D 00 F8'
- 'F8 55 E3 C2 BB BB BB B8 C5 C5 C5 C5 C6 C7 C8 C8'
- 'C8 C8 C8 C8 C8 C8 C7 C7 CF DE F8 57 57 5B 5E 44'
- 'F8 75 F7 BF 71 6D 69 A0 A6 9D 9D 9D 9D 9D 00 F8'
- 'F8 40 C9 C4 B8 B9 B8 C6 C5 C5 C5 C3 C4 C4 C4 C4'
- 'C4 C4 C5 C4 C5 C5 C4 C4 C3 C2 F8 57 57 5B 5E 44'
- 'F8 75 F7 BF 71 6D 69 A0 A6 9D 9D 9D 9D 9D 00 F8'
- 'F8 22 90 CF B8 B9 BC C5 C5 BD C3 C2 C2 C2 C2 BD'
- 'C5 C5 BC C5 C5 C5 C5 C5 C5 BC F8 57 5B 5E 5E 60'
- 'F8 78 F7 92 52 4E 54 AD A9 A3 9D 9D 9D 9D 00 F8'
- 'F8 07 7C D1 BA BB C5 C5 C5 C2 C2 C2 C2 C2 C2 C5'
- 'C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5B 5B 5E 60 64'
- 'F8 7B F7 89 50 4D 5D D6 AB A7 9E 9D 9D 9D 00 00'
- 'F8 F8 6F D1 BD C3 C5 C5 C2 C2 C2 C2 C2 C2 C2 C2'
- 'BD C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5B 5B 5E 64 64'
- '3D 83 F7 7F 4F 4C 63 D8 D5 AA A4 9D 9D 9D 00 00'
- 'F8 F8 58 D0 C3 C4 C5 C5 C3 C3 C3 C3 C3 C3 C3 C3'
- 'C3 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5E 60 64 66 66'
- 'F8 8B F7 DA D3 CA C1 D9 D7 AC A8 A2 A2 9D 00 00'
- 'F8 F8 41 CB C6 C4 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5'
- 'C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 F8 F8 F8 F8 F8'
- 'F8 7D CD CD CD CD C0 BE A5 A1 9F 9C 9C 9B 00 00'
- 'F8 F8 2F BA C8 C7 C5 C5 C8 C8 C8 C8 C8 C8 C8 C8'
- 'C8 C8 C8 C5 C5 C5 C5 C5 BA B7 B4 B2 B0 8D 97 C2'
- '79 09 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00'
- 'F8 F8 19 8A CF CF D2 D2 D2 CC CE CE CE CE CE CE'
- 'CE CE CE CE D1 D1 D1 D1 D1 CE D1 D1 E1 CC BA B8'
- '65 02 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00'
- 'F8 F8 08 78 D0 D3 D0 D2 D2 D2 D1 D1 D1 D1 D1 D1'
- 'D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 E1 E1 E1 D1 D0 B4'
- '51 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 F8 F8 62 C5 DC DB D2 D2 D2 D2 D2 DA DA DA DA'
- 'DA DA DA DA DA DA DA DA DB DB E1 E1 E1 DD CC 95'
- '3B F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 F8 F8 4B B7 DF DD DE E5 E5 E5 E5 E5 E5 DE DE'
- 'DE DE DE DE DE DE DF DF E1 E1 E1 E1 DE E0 C8 81'
- '20 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 F8 F8 38 97 E0 E0 E0 E1 E1 E5 E5 E5 E5 E5 E5'
- 'E5 E5 E5 E5 E5 E5 E5 E1 E1 E1 E1 E1 E0 E2 C6 7A'
- '0B F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 F8 F8 1D 84 DE E7 E1 E0 E6 E5 E4 E7 E5 E5 E5'
- 'E5 E5 E5 E5 E5 E5 E5 E5 E5 E6 E4 DF E5 E5 C8 72'
- 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 F8 F8 08 79 DE D3 97 AF C8 E6 E7 E7 E8 E8 E7'
- 'E6 E5 E5 E6 E7 E8 E8 E7 E8 DE B0 98 C3 E6 C6 61'
- 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F8 F8 74 DA B2 8C 93 8C E5 EC EB EB EB EB'
- 'EB EB EB EB EB EB EB EB EE C7 8A 8F 90 E5 BB 59'
- 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F8 F8 5A BC D1 D0 C7 DE F5 F5 F5 F5 F5 F5'
- 'F5 F5 F5 F5 F5 F5 F5 F5 F6 ED D3 CB D0 C9 8A 37'
- 'F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F8 F8 1A 6E 98 C5 C9 CF CB CB CB CB CB CB'
- 'CB CB CB CB CB CB CB CB CB CC CC C9 BB 8A 56 06'
- 'F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 F8 F8 F8 0C 3E 49 48 48 48 48 48 48 48 48'
- '48 48 48 48 48 48 48 48 48 48 48 49 49 31 02 F8'
- 'F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
- 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F3 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 C0 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 1F 00 00 E0 00 01 FF FF FF 00 00 F0 00'
+ '03 FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 66 66'
+ '66 00 69 69 69 00 6D 6D 6D 00 72 72 72 00 75 75'
+ '75 00 79 79 79 00 7D 7D 7D 00 9F 73 58 00 91 6B'
+ '63 00 9E 77 6A 00 9D 76 6D 00 A1 7A 71 00 9B 8A'
+ '69 00 8E 88 7A 00 8F 89 7D 00 91 88 76 00 94 8B'
+ '77 00 92 8A 78 00 95 8C 78 00 92 8B 7D 00 95 8D'
+ '7D 00 99 8E 7A 00 A7 84 6F 00 AE 89 6D 00 AD 8C'
+ '7D 00 A2 93 75 00 AA 9C 7F 00 B6 96 7C 00 FF 00'
+ 'FF 00 81 81 81 00 83 83 84 00 85 85 85 00 89 89'
+ '89 00 8D 8D 8D 00 9F 95 80 00 96 93 8D 00 91 91'
+ '91 00 95 95 95 00 98 97 97 00 99 99 99 00 9D 9D'
+ '9D 00 A2 98 82 00 A6 9C 86 00 AC 9E 82 00 BE 9E'
+ '85 00 B7 99 8E 00 BA 9B 89 00 A4 9F 97 00 B6 9A'
+ '95 00 AD A0 84 00 AA A0 8A 00 AF A5 8F 00 BF A1'
+ '87 00 B3 A5 89 00 BF A2 8A 00 B8 AA 8F 00 AF A5'
+ '90 00 B0 A6 90 00 BC A3 93 00 BE B0 96 00 9F A0'
+ 'A3 00 A1 A1 A1 00 A2 A3 A4 00 A4 A3 A4 00 A3 A4'
+ 'A7 00 A5 A5 A5 00 A3 A6 A9 00 A5 A6 A9 00 A9 A9'
+ 'A9 00 A9 AB AF 00 AB AC AD 00 AD AD AD 00 BC B3'
+ 'A0 00 AC AE B2 00 B1 B1 B1 00 B1 B2 B4 00 B5 B5'
+ 'B5 00 B3 B5 B9 00 B6 B8 BC 00 B9 B9 B9 00 BB BB'
+ 'BC 00 BA BC BD 00 BD BD BD 00 C1 A4 8F 00 C2 A6'
+ '92 00 C1 A6 96 00 C6 AC 96 00 C3 AD 99 00 C6 AF'
+ '98 00 C0 AC 9E 00 C8 AF 9A 00 C0 B2 96 00 C7 B0'
+ '9A 00 C3 B5 99 00 C5 B7 9B 00 C9 B1 9B 00 C5 B8'
+ '9D 00 C9 BB 9F 00 C6 AF A4 00 CA B1 A0 00 CB B5'
+ 'A1 00 CD B6 A3 00 CA B3 A7 00 CD B7 A4 00 CA BC'
+ 'A2 00 CE BF A3 00 CF BA A7 00 CC BF A5 00 C8 B4'
+ 'AB 00 D0 BA A8 00 D0 BC AA 00 D3 BD B0 00 CE C3'
+ 'A3 00 CF C2 A7 00 D2 C4 A9 00 D6 C7 AB 00 D4 C1'
+ 'AF 00 D4 C6 AC 00 D6 C9 AF 00 D9 CB AF 00 CB C4'
+ 'B0 00 D4 C0 B0 00 D6 C3 B4 00 D6 C4 B5 00 D9 C6'
+ 'B5 00 D6 CD B5 00 D9 CB B2 00 DB CD B3 00 DC CD'
+ 'B2 00 D4 C2 B9 00 D6 C4 BC 00 D8 C7 B9 00 D9 C8'
+ 'B9 00 DD CB BB 00 DA C9 BC 00 DD CC BF 00 E0 D2'
+ 'B6 00 E0 D2 B8 00 E3 D5 B9 00 E7 D7 BE 00 E8 D9'
+ 'BD 00 BD BF C3 00 C1 C1 C1 00 C5 C5 C5 00 C8 C6'
+ 'C3 00 CB C7 C6 00 C3 C5 C8 00 C6 C8 CB 00 C9 C9'
+ 'C9 00 CD CC CB 00 CA CB CE 00 CD CD CD 00 D9 CB'
+ 'C3 00 DC CC C1 00 D9 C8 C6 00 DB CC C7 00 D0 CF'
+ 'CE 00 DF D1 C5 00 CC CE D2 00 CF D1 D4 00 D1 D2'
+ 'D2 00 D1 D3 D6 00 D6 D6 D6 00 DB D7 D4 00 DC D9'
+ 'D6 00 DA DA DA 00 DE DB D8 00 DF DC D9 00 D8 D9'
+ 'DD 00 DD DD DD 00 E1 D2 C6 00 EA DD C1 00 ED DF'
+ 'C3 00 E2 D5 CA 00 E5 D8 CC 00 E6 DB D1 00 E6 DD'
+ 'D2 00 E6 DA D5 00 E6 DC D6 00 EA DE D3 00 E9 DD'
+ 'D6 00 E0 DD DA 00 ED E2 C6 00 EE E6 C9 00 EB E3'
+ 'CF 00 EE E8 CC 00 F0 EA CF 00 E0 E0 D7 00 EA E0'
+ 'D7 00 EC E1 D7 00 E4 E1 DE 00 EA E1 DA 00 ED E2'
+ 'D9 00 EA E3 DC 00 EC E3 DD 00 EC E5 DD 00 F0 EA'
+ 'D2 00 F1 ED D6 00 F2 EF D8 00 F2 F0 DD 00 E2 E2'
+ 'E2 00 E7 E4 E2 00 E5 E5 E5 00 EB E4 E2 00 ED E6'
+ 'E0 00 EF E8 E2 00 EF EE E0 00 EA E8 E5 00 EC EA'
+ 'E6 00 E9 E9 E9 00 EB EC EC 00 ED ED EC 00 F0 E7'
+ 'E0 00 F2 E8 E1 00 F1 EA E5 00 F4 EB E4 00 F2 EC'
+ 'E6 00 F5 ED E6 00 F2 ED E8 00 F6 EE E8 00 F8 EF'
+ 'E9 00 F3 F3 E7 00 F7 F1 EB 00 F5 F1 EE 00 F8 F0'
+ 'EA 00 F8 F2 EE 00 F9 F4 EF 00 F4 F2 F1 00 F9 F5'
+ 'F1 00 F9 F6 F4 00 FB F8 F2 00 FB F8 F5 00 FC F9'
+ 'F6 00 FC FB F9 00 FE FC F9 00 FE FE FC 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 C0 00 00 00 03 FF 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
- '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
- '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
- '77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 08 88 88 88 88 88 88 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 08 88 88 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 09 99 99 99 99 99 99 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 09'
- '99 99 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 07 77 77 77 77 77 77 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
- '77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 0F FF FF FF FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F'
- 'F8 88 88 88 88 88 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 00 00 00 0F 7F FF FF FF FF FF 00 08'
- '7F FF F7 AA FF FF 77 77 77 77 77 70 00 00 00 0F'
- 'FF FF FF FF FF FF 00 07 FF FF FA AA AF 77 77 77'
- '77 77 77 00 00 00 00 0F F8 88 88 88 88 88 00 07'
- 'FF FF FA AA A7 78 88 88 88 88 87 80 00 00 00 0F'
- 'FF FF FF FF FF FF 00 07 FF FF FF AA 77 70 00 00'
- '00 00 07 77 00 00 00 0F FF FF FF FF FF FF 00 07'
- 'FF FF F0 00 00 00 00 00 00 00 00 00 00 00 00 0F'
- 'F8 88 88 88 88 88 00 07 FF FF F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 07 FF FF FF FF FF FF 00 07'
- 'FF FF F7 77 77 77 77 77 77 77 77 77 00 00 00 0F'
- 'FF FF FF FF FF FF 00 07 FF FF FF FF F7 77 77 77'
- '77 77 77 77 00 00 00 00 00 00 00 00 00 00 00 07'
- 'FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00'
- '00 00 88 88 80 00 00 07 F7 7F FF 77 77 7F FF FF'
- 'FF FF FF FF 00 00 00 00 00 08 88 88 00 00 00 07'
- '77 77 77 77 77 77 77 77 77 7F 77 F7 08 00 00 00'
- '00 88 88 80 00 00 00 07 F7 77 77 77 77 77 77 77'
- '77 77 77 77 08 00 00 00 88 88 88 00 00 00 00 07'
- '77 77 77 77 77 77 77 77 77 77 77 77 08 80 00 08'
- '88 88 80 00 00 00 00 07 77 77 77 77 77 77 77 77'
- '77 77 77 77 08 80 00 08 88 88 88 88 88 88 00 08'
- '77 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
- 'FF F7 77 77 77 77 00 08 77 77 77 77 77 77 77 77'
- '77 77 77 77 08 88 88 08 F7 88 87 77 77 77 00 00'
- '77 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
- 'F7 88 87 77 77 77 00 00 77 77 77 77 77 77 77 77'
- '77 77 77 77 08 88 88 08 F7 88 87 77 77 77 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
- 'F7 88 87 77 77 77 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 08 88 88 07 F7 88 8F 77 77 77 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 08 88 88 07'
- 'FF 77 7F 77 77 77 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 00 00 00 07 77 77 77 77 77 77 00 00'
- '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '00 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
- '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
- '00 00 00 00 00 00 00 00 00 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
- '00 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
- '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
- '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
- '00 87 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
- '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
- '77 77 77 77 77 77 70 00 00 00 00 00 00 00 00 00'
- '00 08 77 77 77 77 77 77 77 77 77 77 77 77 80 00'
- '00 00 00 00 00 00 00 00 00 00 08 88 88 88 88 88'
- '88 88 88 88 88 80 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F3 00 00 00 00 FF FF FF F0 00 00 00 00 F0 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 03 FF 00 00 C0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
- '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
- '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 5A 4E 32 32 32 32 32 32'
+ '32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32'
+ '32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32'
+ '47 50 00 00 00 00 00 00 99 50 30 2F 2F 2F 2F 2E'
+ '2F 2E 2B 2B 2B 2B 2B 2B 2A 2B 2A 2A 2A 2A 2A 29'
+ '2A 29 29 29 27 27 F8 10 F8 10 10 F8 10 10 10 0F'
+ 'F8 0F 55 00 00 00 00 00 AF AC 99 98 07 5A 59 56'
+ '57 56 55 54 54 51 51 50 4D 4B 48 48 48 47 32 32'
+ '32 32 30 2F 2F 2F 2E 2B 2E 2B 2B 2E 2B 2B 2B 2B'
+ '31 0C 51 00 00 00 00 00 B3 9E 56 9F BF C8 C8 C8'
+ 'C8 C8 C8 C8 C8 BF BF BF BF BF BF BF BF BF B1 B1'
+ 'B0 B0 B0 AE AE AE AD 9A 32 29 F8 10 10 10 10 0F'
+ '2A 0B 50 00 00 00 00 00 AF 99 A6 D5 85 8D 8F 8F'
+ 'B8 EE F5 F5 F4 F4 F2 F4 F2 F2 F0 EC EC EC EC EC'
+ 'F0 F1 F2 F2 F2 F4 F4 EC D3 30 27 10 10 10 10 0F'
+ '2B 0B 4E 00 00 00 00 00 AC 9E DD EE C9 C9 CD CD'
+ 'CC 85 66 62 71 78 71 69 69 77 B7 DE EB EF EB D7'
+ 'A7 71 64 64 77 6F 6E B7 F5 A1 F8 F8 10 F8 0F 0F'
+ '2A 0A 50 00 00 00 00 00 AA A6 E9 EB 44 C9 E1 A5'
+ 'BB A4 CC CA C9 E0 C6 B9 E2 EC B9 8E 71 7E 77 8F'
+ 'B4 BE D7 F3 F5 F4 F3 EC E5 E2 2A 10 F8 10 10 0F'
+ '2A 0A 4D 00 00 00 00 00 A6 A6 EF F3 E2 12 86 22'
+ '11 15 20 40 21 6D B8 B4 60 E4 E9 8B 40 85 6D 5E'
+ '38 37 8B A3 D6 F1 EF F1 F1 ED 2B 28 10 F8 0F 10'
+ '2A 0A 4E 00 00 00 00 00 A1 A6 EC E3 EF 3A 8C EE'
+ '79 DE BC 90 3E 8F 6D 60 BA E0 DF 3E 91 84 8D 77'
+ '64 8B E3 CA DF E3 E3 E3 E6 E2 2E 28 F8 10 10 0F'
+ '2A 0B 4B 00 00 00 00 00 AA 99 F1 F3 E4 A2 25 B7'
+ 'F3 F1 F2 F2 E4 78 90 13 BB EE EF 83 61 74 78 D7'
+ '14 F2 F2 F2 F2 F2 F2 F2 F2 DD 2B 29 28 F8 10 0F'
+ '2A 0A 4B 00 00 00 00 00 B3 07 D9 F1 C7 76 5F 5D'
+ 'E8 EB EB EB F0 B9 6E 6F 70 DE EE BD 63 8D 90 CB'
+ '6C EB EB EB EC EB EB EB EE 9B 2A 29 29 F8 F8 0F'
+ '2A 0B 4D 00 00 00 00 00 D2 5A 9F EB EA EA D7 D6'
+ 'E5 E6 E3 E6 E3 E6 E6 E5 E5 E6 E5 E6 E3 CB E1 E6'
+ 'EA E6 E3 E5 E3 E5 E6 EC E0 32 2A 29 28 27 27 10'
+ '2A 0B 4B 00 00 00 00 00 D2 5C 5A 9E D4 DD DC DB'
+ 'DC DB DB DB DB DB DB DB D4 DB D4 DB D4 D4 D4 D4'
+ 'D4 D4 D4 D2 D4 D2 D3 A1 31 2B 2A 2B 29 29 28 F8'
+ '2B 0B 4B 00 00 00 00 00 D2 07 59 59 59 56 54 54'
+ '54 50 50 4E 4E 4E 4B 4B 4B 48 47 47 47 32 32 32'
+ '31 30 2F 2E 2E 2F 2E 2E 2B 2B 2B 2A 29 29 28 F8'
+ '2B 0C F7 00 00 00 00 00 D2 98 07 5A 59 59 54 54'
+ '51 50 50 4E 4E 4B 4B 4B 48 49 47 47 32 47 32 31'
+ '31 31 30 2F 2F 2F 2E 2E 2E 2B 2B 2A 2A 29 27 27'
+ '2E 0D 47 00 00 00 00 00 D2 99 98 98 5A 5A 59 56'
+ '54 51 51 51 4E 4E 4B 4B 4B 4B 48 F7 32 32 32 32'
+ '31 30 2F 2F 2F 2F 2E 2E 2E 2E 2B 2B 2A 2A 29 29'
+ '2F 0C F7 00 00 00 00 00 D2 99 99 07 5A 5A 56 56'
+ '56 54 51 51 4E 4B 4B 4B 4B 4B 4B 47 32 47 32 32'
+ '31 31 31 2F 2F 2F 2E 2E 2E 2E 2B 2B 2A 2A 2A 29'
+ '2E 0D 47 00 00 00 00 00 D2 9E 99 98 5C 59 59 56'
+ '54 54 54 4E 4E 4E 4B 4B 4B 49 48 47 47 32 32 32'
+ '31 31 31 30 2F 2F 2F 2E 2E 2B 2E 2B 2A 2A 2A 29'
+ '2F 0E 47 00 00 00 00 00 D4 99 9E 98 98 5C 59 59'
+ '56 51 51 50 4E 4E 4B 4B 4B 47 4B 47 47 32 32 47'
+ '31 31 31 31 30 2F 2F 2E 2F 2E 2E 2B 2B 2A 2A 29'
+ '2F 0E 32 00 00 00 00 00 D4 9E 99 99 99 5C 5A 59'
+ '56 56 54 50 4E 4E 4E 4B 49 47 48 47 47 47 32 47'
+ '32 32 31 31 31 30 2F 2F 2F 2E 2E 2E 2B 2B 2A 2A'
+ '30 0E 47 00 00 00 00 00 D4 9E 9E 99 98 07 5A 59'
+ '56 54 54 51 51 4E 4E 4E 4B 4B F7 48 47 32 32 32'
+ '32 32 31 32 31 31 30 2F 2F 2F 2E 2E 2E 2B 2B 29'
+ '31 0F 32 00 00 00 00 00 D4 9F A0 9A 99 07 5C 5A'
+ '59 56 54 54 4E 4E 4E 4B 4B 4B 48 49 47 F7 47 32'
+ '47 32 32 31 32 31 30 2F 2F 2F 2F 2E 2E 2B 2A 2A'
+ '30 0F 32 00 00 00 00 00 D4 9F A0 9E 99 98 98 5C'
+ '59 56 54 54 50 4E 4B 4B 4B 49 47 47 47 47 47 32'
+ '32 32 32 32 31 31 31 30 30 2F 2F 2E 2E 2B 2B 2A'
+ '2F 0F 32 00 00 00 00 00 D4 A1 A1 9E 99 99 98 07'
+ '59 56 55 54 51 51 4E 4B 49 47 49 47 47 32 47 32'
+ '32 32 32 32 32 31 31 31 30 2F 2F 2E 2E 2B 2B 29'
+ '31 0F 32 00 00 00 00 00 DB A1 A6 A0 9E 98 98 07'
+ '59 59 56 54 51 50 4B 4B 4B 4B 48 47 47 47 32 32'
+ '47 32 32 32 32 32 31 30 30 2F 2F 2E 2B 2B 2A 2A'
+ '2F 0F 47 00 00 00 00 00 DB B2 A9 A9 A8 A1 9D 9C'
+ '97 5B 58 57 55 53 4F 4E 4C 4A 4C 48 47 32 47 32'
+ '32 32 32 32 31 32 31 31 30 2E 2F 2E 2B 2B 2A 28'
+ '2F 28 47 00 00 00 00 00 C5 82 43 3D 42 3C 34 33'
+ '2C 1F 1C 1A 19 1B 1E 1E 1D 17 18 2D 46 32 32 32'
+ '32 32 32 31 31 31 30 30 2F 2E 2B 2E 2A 2A 28 29'
+ '4B 32 00 00 00 00 00 00 B3 C2 8A 88 80 7F 7F 7C'
+ '7B 75 72 6A 45 41 3F 3B 35 24 23 16 39 57 5A 59'
+ '56 59 56 56 56 54 54 51 50 4B 4B 47 32 31 30 4E'
+ '4E 00 00 00 00 00 00 00 00 E7 CE C1 C0 B6 B5 96'
+ '94 92 8A 81 7D 7C 73 72 68 67 65 7A 52 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D8 D1 D1 D0 D0 CF'
+ 'C4 C4 C3 C3 B6 B6 B5 95 94 93 93 87 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 C0 00'
+ '00 00 00 0F 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 0F 00 00 C0 00 00 00 00 1F 00 00 E0 00'
+ '01 FF FF FF 00 00 F0 00 03 FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
  'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 01 00 20 00 00 00 00 00 80 25 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4904,11 +4189,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 24 00 00 00 6C 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4916,11 +4196,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4928,11 +4203,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C'
- '3C FF 3C 3C 3C FF 00 00 00 FF 7F 60 60 FF 7F 60'
- '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
- '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
- '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4940,11 +4210,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4952,11 +4217,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 16 16 14 FF 36 36 30 FF 36 36 30 FF 22 22'
- '1F FF 04 04 04 FF 00 00 00 FF C0 00 00 FF C0 00'
- '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF C0 00'
- '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF C0 00'
- '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4964,11 +4224,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 28 28 24 FF 00 00 00 B4 00 00 00 9C 8C 8C'
- '8C FF 0C 0C 0C FF 00 00 00 FF D5 40 40 FF D5 40'
- '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
- '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
- '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -4976,488 +4231,443 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 FF 2A 2A 25 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 0C 0C 0C FF 00 00 00 FF EA 80 80 FF EA 80'
- '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
- '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
- '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 FF 12 12 10 FF 2B 2B 26 FF 30 30 2C FF 22 22'
- '1F FF 10 10 10 FF 00 00 00 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
- '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 FF 04 04 04 FF 0C 0C 0C FF 0C 0C 0C FF 10 10'
- '10 FF 18 18 18 FF 00 00 00 FF ED ED ED FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
- '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
- '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
- '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 00 00'
- '00 FF 0C 0C 0C FF 0C 0C 0C FF 10 10 10 FF 18 18'
- '18 FF 17 17 17 FF 00 00 00 FF EC EC EC FF E7 E7'
- 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
- '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
- '90 FF B8 B4 B6 FF AD AD AD FF AB AC AC FF AD A8'
- 'AB FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
- 'C9 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2'
- 'C2 FF C3 C3 C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF'
- 'BF FF BF BF BF FF BC BC BC FF BD BD BD FF BA BA'
- 'BA FF BD BD BD FF BD BD BD FF BD BD BD FF 00 00'
- '00 FF 0C 0C 0C FF 10 10 10 FF 18 18 18 FF 18 18'
- '18 FF 1E 1E 1E FF 00 00 00 FF EB EB EB FF DB DB'
- 'DB FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
- 'E1 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2 E2 FF E3 E3'
- 'E3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF 00 00'
- '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF AD A8'
- 'AB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
- 'E8 FF D4 D4 D4 FF 00 C0 00 FF 00 C0 00 FF E7 E7'
- 'E7 FF E8 E8 E8 FF E8 E8 E8 FF E3 E3 E3 FF DD DD'
- 'DD FF D8 D8 D8 FF D2 D2 D2 FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF CD CD CD FF C8 C9'
- 'C9 FF CD CD CD FF AA AA AA FF 2E 2E 2E FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 18 18 18 FF 1F 1F'
- '1F FF 18 18 18 FF 00 00 00 FF EA EA EA FF E6 E6'
- 'E6 FF E7 E7 E7 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9'
- 'E9 FF EA EA EA FF EA EA EA FF EA EA EA FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF 00 00'
- '00 15 00 00 00 F0 19 19 19 FF AD A8 AB FF EB EB'
- 'EB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
- 'E8 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 C0'
- '00 FF E1 E1 E1 FF DF DF DF FF D5 D5 D5 FF CC CC'
- 'CC FF D2 D2 D2 FF CB CB CB FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF 40 40 40 FF 2E 2E 2E FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 1F 1F 1F FF 15 15'
- '15 FF 13 13 13 FF 00 00 00 FF E9 E9 E9 FF E7 E7'
- 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
- '00 30 00 00 00 FA 29 29 29 FF AD A8 AB FF EA EA'
- 'EA FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
- 'E8 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF'
- '00 FF CB CB CB FF C8 C8 C8 FF 66 66 66 FF 66 66'
- '66 FF 66 66 66 FF 66 66 66 FF 66 66 66 FF 66 66'
- '66 FF 66 66 66 FF 66 66 66 FF 66 66 66 FF 66 66'
- '66 FF CD CD CD FF 93 93 93 FF 40 40 40 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 0E 0E'
- '0E FF 10 10 10 FF 00 00 00 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
- '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
- 'EC FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
- 'E8 FF E8 E8 E8 FF 00 FF 00 FF 00 FF 00 FF B5 B5'
- 'B5 FF B5 B5 B5 FF B6 B6 B6 FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 0A 0A'
- '0A FF 0D 0D 0D FF 00 00 00 FF E8 E8 E8 FF E7 E7'
- 'E7 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5 E5 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF 00 00'
- '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
- 'EE FF E8 E8 E8 FF EB EB EB FF E8 E8 E8 FF E8 E8'
- 'E8 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 24 24 24 FF 1F 1F 1F FF 05 05 05 FF 07 07'
- '07 FF 0A 0A 0A FF 00 00 00 FF E5 E5 E5 FF E7 E7'
- 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
- 'EF FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF 80 80 80 FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 00 00'
- '00 FF 2B 2B 2B FF 11 11 11 FF 02 02 02 FF 03 03'
- '03 FF 03 03 03 FF 00 00 00 FF DC DC DC FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
- 'F2 FF EA EA EA FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF A7 A7 A7 FF A7 A7 A7 FF AB AB AB FF AE AE'
- 'AE FF B0 B0 B0 FF AF AF AF FF AF AF AF FF AF AF'
- 'AF FF AF AF AF FF AF AF AF FF AF AF AF FF AB AB'
- 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
- 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF 00 00'
- '00 FF 32 32 32 FF 0C 0C 0C FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF E5 E5 E5 FF E5 E5'
- 'E5 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8'
- 'E8 FF E9 E9 E9 FF E9 E9 E9 FF E9 E9 E9 FF EA EA'
- 'EA FF EA EA EA FF EA EA EA FF EB EB EB FF 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
- 'F3 FF EB EB EB FF ED ED ED FF EB EB EB FF E9 E9'
- 'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
- 'E2 FF DB DB DB FF DC DC DC FF D8 D8 D8 FF D9 D9'
- 'D9 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF 00 00'
- '00 FF 37 37 37 FF 02 02 02 FF 03 03 03 FF 04 04'
- '04 FF 04 04 04 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
- 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF 00 00'
- '00 FF 37 37 37 FF 07 07 07 FF 09 09 09 FF 0B 0B'
- '0B FF 0D 0D 0D FF 10 10 10 FF 13 13 13 FF 19 19'
- '19 FF 1E 1E 1E FF 27 27 27 FF 34 34 34 FF 42 42'
- '42 FF 46 46 46 FF 46 46 46 FF 46 46 46 FF 46 46'
- '46 FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
- '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
- 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF 00 00'
- '00 FF 3F 3F 3F FF 0D 0D 0D FF 11 11 11 FF 12 12'
- '12 FF 16 16 16 FF 1B 1B 1B FF 21 21 21 FF 26 26'
- '26 FF 30 30 30 FF 3C 3C 3C FF 44 44 44 FF 47 47'
- '47 FF 46 46 46 FF 46 46 46 FF 46 46 46 FF 2C 2C'
- '2C FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
- '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
- 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
- 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF 00 00'
- '00 FF 44 44 44 FF 23 23 23 FF 17 17 17 FF 1B 1B'
- '1B FF 20 20 20 FF 27 27 27 FF 2B 2B 2B FF 35 35'
- '35 FF 40 40 40 FF 44 44 44 FF 47 47 47 FF 4A 4A'
- '4A FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
- '2C FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
- '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
- 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
- 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF 00 00'
- '00 FF 4B 4B 4B FF 2E 2E 2E FF 1F 1F 1F FF 25 25'
- '25 FF 2B 2B 2B FF 2F 2F 2F FF 39 39 39 FF 43 43'
- '43 FF 44 44 44 FF 47 47 47 FF 4B 4B 4B FF 49 49'
- '49 FF 42 42 42 FF 36 36 36 FF 2C 2C 2C FF 23 23'
- '23 FF 1C 1C 1C FF 1C 1C 1C FF 14 14 14 FF 00 00'
- '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
- 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
- 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF 00 00'
- '00 FF 4B 4B 4B FF 4C 4C 4C FF 27 27 27 FF 2E 2E'
- '2E FF 33 33 33 FF 3C 3C 3C FF 45 45 45 FF 44 44'
- '44 FF 47 47 47 FF 4B 4B 4B FF 4B 4B 4B FF 45 45'
- '45 FF 3C 3C 3C FF 32 32 32 FF 2A 2A 2A FF 25 25'
- '25 FF 1C 1C 1C FF 1C 1C 1C FF 16 16 16 FF 00 00'
- '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
- 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
- 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0 D0 FF 00 00'
- '00 FF 52 52 52 FF 57 57 57 FF 3C 3C 3C FF 35 35'
- '35 FF 3F 3F 3F FF 00 00 00 FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 00 00'
- '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
- 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
- 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF E1 E1 E1 FF 00 00'
- '00 FF 57 57 57 FF 5E 5E 5E FF 5D 5D 5D FF 49 49'
- '49 FF 45 45 45 FF 00 00 00 FF 84 84 84 FF FD F9'
- 'F7 FF F9 EE E8 FF F6 E4 D9 FF F3 D9 CB FF F0 CF'
- 'BC FF ED C5 AE FF EA BB A0 FF E9 B6 99 FF E9 B6'
- '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
- 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CA CA CA FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF 00 00'
- '00 FF 5E 5E 5E FF 5E 5E 5E FF 65 65 65 FF 6A 6A'
- '6A FF 44 44 44 FF 00 00 00 FF 8E 8E 8E FF FF FF'
- 'FF FF D0 CB C8 FF 8B 86 84 FF 87 80 7D FF 83 7A'
- '75 FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
- '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
- 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
- 'CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D2 D2 D2 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF 00 00'
- '00 FF 5E 5E 5E FF 5E 5E 5E FF 65 65 65 FF 6A 6A'
- '6A FF 44 44 44 FF 00 00 00 FF 8E 8E 8E FF FF FF'
- 'FF FF D0 CB C8 FF 8B 86 84 FF 87 80 7D FF 83 7A'
- '75 FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
- '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
- 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
- 'CE FF D3 D3 D3 FF D3 D3 D3 FF CF CF CF FF D1 D1'
- 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF D3 D3 D3 FF D3 D3 D3 FF CE CE'
- 'CE FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CE CE CE FF 00 00'
- '00 FF 5E 5E 5E FF 65 65 65 FF 6A 6A 6A FF 6A 6A'
- '6A FF 71 71 71 FF 00 00 00 FF 97 97 97 FF FF FF'
- 'FF FF B8 B6 B6 FF 54 54 54 FF 4F 4F 4F FF 5B 58'
- '57 FF F0 D0 BE FF ED C6 AF FF EA BC A1 FF E9 B6'
- '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
- '9F FF DD DD DD FF CC CC CC FF CD CD CD FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
- '00 FF 65 65 65 FF 6A 6A 6A FF 6A 6A 6A FF 71 71'
- '71 FF 79 79 79 FF 00 00 00 FF 9E 9E 9E FF FF FF'
- 'FF FF AF AF AF FF 52 52 52 FF 4E 4E 4E FF 6D 6A'
- '67 FF F2 D6 C7 FF EF CC B8 FF EC C2 AA FF E9 B8'
- '9C FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
- '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
- '00 FF 65 65 65 FF 6A 6A 6A FF 71 71 71 FF 7E 7E'
- '7E FF 79 79 79 FF 00 00 00 FF AA AA AA FF FF FF'
- 'FF FF A6 A6 A6 FF 50 50 50 FF 4C 4C 4C FF 7B 77'
- '75 FF F4 DD D0 FF F1 D2 C2 FF EE C8 B3 FF EB BE'
- 'A5 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
- '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
- '00 FF 65 65 65 FF 71 71 71 FF 79 79 79 FF 7E 7E'
- '7E FF 7E 7E 7E FF 00 00 00 FF B1 B1 B1 FF FF FF'
- 'FF FF E0 E0 E0 FF DF DF DF FF DC D9 D7 FF D9 D1'
- 'CC FF F6 E4 D9 FF F3 D9 CB FF F0 CF BC FF ED C5'
- 'AE FF EA BB A0 FF EA BB A0 FF E9 B6 99 FF 00 00'
- '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
- '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF A3 A3 9E FF DA DA'
- 'D8 FF DA DA D8 FF DA DA D8 FF DA DA D8 FF D7 D2'
- 'CE FF D5 CB C4 FF D2 C3 B9 FF D0 BC B0 FF CE B6'
- 'A6 FF CC AF 9D FF CC AF 9D FF CA A8 94 FF 00 00'
- '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
- '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF CC CC CC FF C9 C9 C9 FF C6 C6'
- 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
- 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
- '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
- '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF D9 D9 D9 FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DA DA DA FF DD DD'
- 'DD FF DD DD DD FF E7 E7 E7 FF D9 D9 D9 FF CC CC'
- 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
- '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
- '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
- 'DC FF DE DE DE FF DE DE DE FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF DD DD DD FF DC DC'
- 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
- '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
- '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
- 'E1 FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E3 E3 E3 FF D9 D9'
- 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
- '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
- '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
- 'E3 FF E4 E4 E4 FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
- 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
- '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
- '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 1F 00 00'
+ '00 2D 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2E 00 00 00 2E 00 00'
+ '00 2E 00 00 00 2E 00 00 00 2C 00 00 00 1A 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 DA DA DA 31 9E 9E 9E 97 86 86'
+ '86 B4 84 84 84 B5 84 84 84 B5 83 83 83 B5 81 81'
+ '81 B5 80 80 80 B5 80 80 80 B5 7E 7E 7E B5 7D 7D'
+ '7D B5 7A 7A 7A B5 7A 7A 7A B5 7A 7A 7A B5 7A 7A'
+ '7A B5 79 79 79 B5 74 74 74 B5 76 76 76 B5 74 74'
+ '74 B5 74 74 74 B5 74 74 74 B5 73 73 73 B5 70 70'
+ '70 B5 70 70 70 B5 70 70 70 B5 6F 6F 6F B5 6D 6D'
+ '6D B5 6B 6B 6B B5 69 69 69 B5 66 66 66 B5 65 65'
+ '65 B5 65 65 65 B5 65 65 65 B5 62 62 62 B5 62 62'
+ '62 B5 64 64 64 B5 62 62 62 B5 61 61 61 B5 61 61'
+ '61 B5 5F 5F 5F B5 5E 5E 5E AA 0F 0F 0F 63 00 00'
+ '00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FA FA FA 73 D6 D6 D6 F6 C5 C5'
+ 'C5 FC C2 C2 C2 FC BE BF BF FC BB BC BC FC B8 B9'
+ 'B9 FC B7 B7 B7 FC B5 B6 B7 FC B4 B4 B5 FC B2 B3'
+ 'B4 FC B0 B1 B2 FC AE AF AF FC AD AE AE FC AB AC'
+ 'AD FC AA AA AB FC A6 A7 A8 FC A6 A6 A6 FC A2 A3'
+ 'A4 FC A1 A2 A2 FC A2 A2 A2 FC A1 A1 A1 FC 9F 9F'
+ '9F FC 9E 9E 9E FC 9D 9D 9D FC 9B 9B 9B FC 98 98'
+ '98 FC 96 96 96 FC 94 94 94 FC 92 92 92 FC 90 90'
+ '90 FC 8E 8E 8E FC 8F 8F 8F FC 8C 8C 8C FC 8E 8E'
+ '8E FC 8F 8F 8F FC 8E 8E 8E FC 8D 8D 8D FC 8D 8D'
+ '8D FC 8B 8B 8B FC 96 96 96 EC 22 22 22 87 00 00'
+ '00 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FA FA FA 7D C9 C9 C9 FF B7 B7'
+ 'B7 FF CB CA CA FF E0 DD DB FF E5 E2 DF FF E5 E2'
+ 'DF FF E4 E1 DE FF E4 E1 DE FF E4 E1 DE FF E4 E0'
+ 'DE FF E3 E0 DD FF E2 DF DC FF E2 DF DC FF E1 DE'
+ 'DB FF E1 DE DB FF E1 DD DB FF E0 DD DA FF E0 DD'
+ 'DA FF DF DC D9 FF E0 DD DA FF E0 DC D9 FF DF DC'
+ 'D9 FF DF DB D8 FF DE DB D8 FF DE DB D8 FF DE DB'
+ 'D8 FF DD DA D7 FF DC D9 D6 FF DC D9 D6 FF DB D7'
+ 'D4 FF C8 C6 C3 FF 9D 9E 9D FF 84 84 84 FF 7F 7F'
+ '7F FF 7D 7D 7D FF 7D 7D 7D FF 7C 7C 7C FF 7B 7B'
+ '7B FF 79 79 79 FF 89 89 89 F0 24 24 24 8D 00 00'
+ '00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F6 F6 F6 7D C7 C7 C7 FF CE CD'
+ 'CC FF EB E4 E2 FF D6 C4 B7 FF DA C6 B6 FF DD CB'
+ 'BB FF DD CB BB FF E6 D9 CC FF F9 F4 F0 FF FF FF'
+ 'FD FF FF FE FC FF FF FC F9 FF FE FA F7 FF FD F9'
+ 'F6 FF FD FA F6 FF FD FA F6 FF FC F9 F5 FF FB F7'
+ 'F2 FF FA F5 F0 FF F9 F4 EF FF F9 F3 EF FF F9 F4'
+ 'EF FF FA F4 F0 FF FB F6 F3 FF FC F8 F5 FF FD F9'
+ 'F6 FF FD F9 F6 FF FE FA F7 FF FF FC FA FF FE FD'
+ 'FA FF F9 F3 EF FF E7 E4 E2 FF 98 97 97 FF 80 80'
+ '80 FF 7E 7E 7E FF 7D 7D 7D FF 7D 7D 7D FF 7C 7C'
+ '7C FF 7A 7A 7A FF 88 88 88 F1 23 23 23 90 00 00'
+ '00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 EE EE EE 7E C7 C7 C7 FF ED ED'
+ 'EC FF F8 F4 F3 FF EA E1 DB FF EC E2 DA FF ED E5'
+ 'DD FF ED E5 DD FF EC E3 DD FF D5 C5 B4 FF C7 B0'
+ '9A FF C6 AF 98 FF CD B7 A4 FF D0 BC AA FF CE B7'
+ 'A4 FF C9 B1 9B FF C8 AF 99 FF D0 BB A8 FF E2 D5'
+ 'CA FF EE E7 E0 FF F6 F3 F1 FF FA F7 F5 FF F6 F2'
+ 'EF FF EF E8 E2 FF DF D1 C5 FF CE B7 A4 FF C7 AD'
+ '97 FF C8 B0 99 FF D0 BC A9 FF CC B6 A3 FF CB B5'
+ 'A1 FF E3 D6 CB FF FD FC FB FF CD CE CE FF 80 80'
+ '80 FF 7F 7F 7F FF 7F 7F 7F FF 7E 7E 7E FF 7C 7C'
+ '7C FF 79 79 79 FF 86 86 86 F1 22 22 22 92 00 00'
+ '00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E4 E6 E6 7E CE CD CC FF F6 F1'
+ 'ED FF F9 F3 ED FF BC A3 93 FF E9 E0 DB FF F4 EB'
+ 'E4 FF DB CC C7 FF E6 DA D5 FF D9 C8 C6 FF EC E4'
+ 'DF FF EB E2 DA FF EA E1 DA FF F1 EA E6 FF EA E0'
+ 'D7 FF E6 DB D1 FF F1 EB E5 FF F8 F4 F0 FF E7 DB'
+ 'D0 FF D9 C8 B9 FF CE B7 A3 FF D4 C1 AF FF D0 BA'
+ 'A8 FF DB C9 BC FF E3 D3 C6 FF E9 DD D6 FF ED E6'
+ 'E2 FF FC FB FB FF FE FD FD FF FD FC F9 FF FD FB'
+ 'F8 FF FA F3 EF FF F7 EF E7 FF F1 ED E8 FF 88 88'
+ '88 FF 7F 7F 7F FF 7E 7E 7E FF 7E 7E 7E FF 7C 7C'
+ '7C FF 7A 7A 7A FF 84 84 84 F2 25 25 25 95 00 00'
+ '00 1F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 DE DE DE 7F D0 CF CE FF F9 F7'
+ 'F5 FF FC FA F7 FF F2 EC E6 FF 91 6B 63 FF D8 C6'
+ 'B5 FF AD 8C 7D FF 9F 73 58 FF A1 7A 71 FF A7 84'
+ '6F FF BF A2 8C FF AE 89 6D FF CA B3 9F FF E4 D8'
+ 'CD FF E0 D2 C6 FF C6 AD 95 FF F2 ED E7 FF F4 F0'
+ 'EF FF D4 C3 BB FF BF A2 89 FF D6 C3 B4 FF C9 B0'
+ 'A0 FF C2 A6 92 FF BA 9B 89 FF B7 99 8E FF D5 C3'
+ 'B8 FF DC CC C1 FF ED E6 DE FF FB F7 F5 FF FA F6'
+ 'F4 FF FA F7 F4 FF FB F8 F5 FF F3 F2 F1 FF 8F 8F'
+ '8F FF 81 81 81 FF 7F 7F 7F FF 7E 7E 7E FF 7C 7C'
+ '7C FF 7A 7A 7A FF 86 86 86 F3 2A 2A 2A 97 00 00'
+ '00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 DB DB DB 80 CF CE CD FF F8 F3'
+ 'EF FF F5 ED E6 FF FB F8 F2 FF B6 9A 95 FF D6 C4'
+ 'BC FF F8 F6 F2 FF D3 BD B0 FF F0 E7 E0 FF E6 DC'
+ 'D6 FF DB C8 B9 FF BF A1 87 FF DA CA BC FF CB B2'
+ 'A0 FF C5 AA 96 FF E6 DD D2 FF F3 EB E4 FF F3 E9'
+ 'E2 FF BE 9E 85 FF DD CC BF FF D7 C4 B4 FF D8 C7'
+ 'B8 FF D0 BB A8 FF C9 AF 9B FF D4 C2 BA FF F5 ED'
+ 'E6 FF EE E2 D8 FF F2 E8 E0 FF F5 EE E7 FF F5 ED'
+ 'E6 FF F5 ED E6 FF F7 ED E7 FF F2 ED E9 FF 91 90'
+ '90 FF 84 84 84 FF 7F 7F 7F FF 7D 7D 7D FF 7D 7D'
+ '7D FF 7A 7A 7A FF 86 86 86 F4 2C 2C 2C 9A 00 00'
+ '00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E1 E1 E1 1A D8 D9 D9 B3 C7 C7 C7 FF F8 F7'
+ 'F6 FF FD FB F9 FF F2 EE E8 FF D9 CB C3 FF B6 96'
+ '7C FF E3 D6 CA FF FC FA F7 FF FB F8 F6 FF FC F9'
+ 'F6 FF FC F8 F6 FF F3 EE E9 FF D0 BC AB FF D8 C7'
+ 'BB FF 9E 77 6A FF E7 DC D6 FF F8 F4 F1 FF FA F7'
+ 'F4 FF D4 C0 B0 FF C3 AD 99 FF CF BA A7 FF D0 BC'
+ 'AB FF EF E8 E2 FF 9D 76 6D FF FB F9 F6 FF FC F9'
+ 'F6 FF FC F8 F6 FF FC F9 F6 FF FC F9 F6 FF FC F9'
+ 'F6 FF FB F8 F6 FF FD F9 F7 FF EE ED EC FF 8D 8D'
+ '8D FF 85 85 85 FF 82 82 82 FF 80 80 80 FF 7D 7D'
+ '7D FF 7B 7B 7B FF 87 87 87 F4 2C 2C 2D 9C 00 00'
+ '00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 FA FA FA 34 E2 E2 E2 EA BE BE BE FF EA E8'
+ 'E5 FF FB F7 F3 FF EC E1 D7 FF C8 B4 AB FF C1 A6'
+ '96 FF C1 A4 8F FF F7 F1 EB FF F8 F2 ED FF F9 F3'
+ 'EE FF F9 F2 EE FF FB F7 F3 FF E7 DB D2 FF CA B3'
+ 'A2 FF CE B7 A4 FF CA B3 A7 FF EF E6 E0 FF FA F5'
+ 'F1 FF EA DE D3 FF C0 AC 9E FF D8 C8 B8 FF D9 C9'
+ 'BB FF EA E3 DC FF C6 AF A4 FF F7 F2 EE FF F9 F3'
+ 'EE FF F9 F2 EE FF F9 F3 EE FF F9 F3 EE FF F9 F3'
+ 'EE FF F8 F2 EE FF FB F4 F0 FF CB C7 C6 FF 88 88'
+ '88 FF 86 86 86 FF 84 84 84 FF 81 81 81 FF 7F 7F'
+ '7F FF 7B 7B 7B FF 88 88 88 F5 34 34 34 9F 00 00'
+ '00 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 FA FA FA 36 E3 E3 E3 EE BC BC BC FF CD CC'
+ 'CB FF F8 F2 EE FF FA F1 EB FF F8 F0 EA FF ED E6'
+ 'E1 FF EE E6 E0 FF F7 EF E9 FF F7 EE E7 FF F6 EF'
+ 'E7 FF F6 EF E7 FF F6 EF E7 FF F7 EF E8 FF F7 EF'
+ 'E8 FF F7 EF E8 FF F6 EE E8 FF F7 EF E8 FF F7 EF'
+ 'E9 FF F7 EF E9 FF F5 EE E7 FF EB E3 DA FF F4 EC'
+ 'E5 FF F7 EF E7 FF F8 F1 EB FF F8 EF E9 FF F7 EF'
+ 'E7 FF F6 EE E7 FF F6 EE E7 FF F6 EE E7 FF F7 EF'
+ 'E8 FF FB F5 EF FF EC EA E6 FF 9F 9E 9D FF 8A 8A'
+ '8A FF 86 86 86 FF 83 83 83 FF 82 82 82 FF 80 80'
+ '80 FF 7C 7C 7C FF 89 89 89 F6 37 37 37 A1 00 00'
+ '00 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F2 F2 F2 3B E2 E2 E2 F3 C0 C0 C0 FF BB BB'
+ 'BB FF C8 C8 C9 FF E5 E5 E5 FF EB EC EC FF EA EB'
+ 'EB FF EA EB EB FF EA EA EA FF EA EA EA FF E9 E9'
+ 'E9 FF E9 E9 E9 FF E9 E9 E9 FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF E8 E8 E8 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6 E6 FF E5 E6'
+ 'E6 FF E5 E5 E5 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF CD CE CF FF 99 9A 9A FF 8B 8B 8B FF 8B 8B'
+ '8B FF 8A 8A 8A FF 88 88 88 FF 85 85 85 FF 82 82'
+ '82 FF 80 80 80 FF 8B 8B 8B F6 38 38 38 A3 00 00'
+ '00 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 EE EE EE 3F E3 E3 E3 F6 BF BF BF FF BB BB'
+ 'BB FF B9 B9 B9 FF B7 B7 B7 FF B5 B5 B5 FF B3 B3'
+ 'B3 FF B1 B1 B1 FF AF AF AF FF AD AD AD FF AB AB'
+ 'AB FF AA AA AA FF A9 A9 A9 FF A8 A8 A8 FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3 A3 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F 9F FF 9D 9D'
+ '9D FF 9B 9B 9B FF 99 99 99 FF 97 97 97 FF 95 95'
+ '95 FF 93 93 93 FF 92 92 92 FF 92 92 92 FF 92 92'
+ '92 FF 90 90 90 FF 8E 8E 8E FF 8D 8D 8D FF 8B 8B'
+ '8B FF 89 89 89 FF 87 87 87 FF 84 84 84 FF 82 82'
+ '82 FF 7F 7F 7F FF 8D 8D 8D F7 3D 3D 3D A5 00 00'
+ '00 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 EB EB EB 43 E3 E3 E3 FA C2 C2 C2 FF BF BF'
+ 'BF FF BC BC BC FF B9 B9 B9 FF B7 B7 B7 FF B3 B3'
+ 'B3 FF B1 B1 B1 FF AE AE AE FF AB AB AB FF AB AB'
+ 'AB FF A9 A9 A9 FF A8 A8 A8 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A4 A4 A4 FF A3 A3 A3 FF A4 A4 A4 FF A1 A1'
+ 'A1 FF A1 A1 A1 FF 9F 9F 9F FF 9F 9F 9F FF 9D 9D'
+ '9D FF 9B 9B 9B FF 98 98 98 FF 99 99 99 FF 97 97'
+ '97 FF 95 95 95 FF 95 95 95 FF 94 94 94 FF 92 92'
+ '92 FF 92 92 92 FF 90 90 90 FF 8E 8E 8E FF 8C 8C'
+ '8C FF 8A 8A 8A FF 87 87 87 FF 85 85 85 FF 83 83'
+ '83 FF 81 81 81 FF 8F 8F 8F F7 43 43 43 A6 00 00'
+ '00 27 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F4 F4 F4 48 E3 E3 E3 FE C5 C5 C5 FF C1 C1'
+ 'C1 FF C0 C0 C0 FF BC BC BC FF BB BB BB FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B0 B0 B0 FF B0 B0 B0 FF AD AD'
+ 'AD FF AB AB AB FF A9 A9 A9 FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A6 A6 A6 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9A 9A 9A FF 98 98 98 FF 96 96'
+ '96 FF 95 95 95 FF 95 95 95 FF 93 93 93 FF 92 92'
+ '92 FF 92 92 92 FF 90 90 90 FF 90 90 90 FF 8E 8E'
+ '8E FF 8B 8B 8B FF 8B 8B 8B FF 89 89 89 FF 86 86'
+ '86 FF 83 83 83 FF 93 93 93 F8 44 44 44 A8 00 00'
+ '00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 F8 4A E3 E3 E3 FF C5 C5 C5 FF C3 C3'
+ 'C3 FF C0 C0 C0 FF BD BD BD FF BA BA BA FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B3 B3 B3 FF B1 B1 B1 FF AE AE'
+ 'AE FF AC AC AC FF A9 A9 A9 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A1 A1 A1 FF 9E 9E 9E FF 9E 9E 9E FF 9F 9F'
+ '9F FF 9C 9C 9C FF 9A 9A 9A FF 99 99 99 FF 98 98'
+ '98 FF 96 96 96 FF 94 94 94 FF 94 94 94 FF 93 93'
+ '93 FF 92 92 92 FF 90 90 90 FF 90 90 90 FF 8D 8D'
+ '8D FF 8D 8D 8D FF 8A 8A 8A FF 8A 8A 8A FF 87 87'
+ '87 FF 85 85 85 FF 93 93 93 F8 48 48 48 A9 00 00'
+ '00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 F8 4B E3 E3 E3 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF C2 C2 C2 FF BD BD BD FF B9 B9 B9 FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B4 B4 B4 FF B1 B1 B1 FF AE AE'
+ 'AE FF AB AB AB FF A9 A9 A9 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A5 A5 A5 FF A3 A3 A3 FF A3 A3'
+ 'A3 FF A1 A1 A1 FF A0 A0 A0 FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9D 9D 9D FF 9B 9B 9B FF 99 99 99 FF 98 98'
+ '98 FF 98 98 98 FF 95 95 95 FF 94 94 94 FF 94 94'
+ '94 FF 92 92 92 FF 91 91 91 FF 8F 8F 8F FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8B 8B 8B FF 8A 8A 8A FF 88 88'
+ '88 FF 85 85 85 FF 94 94 94 F9 4D 4D 4D AB 00 00'
+ '00 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 EF EF EF 51 E4 E4 E4 FF C7 C7 C7 FF C7 C7'
+ 'C7 FF C3 C3 C3 FF C0 C0 C0 FF BD BD BD FF BA BA'
+ 'BA FF B7 B7 B7 FF B4 B4 B4 FF B0 B0 B0 FF AE AE'
+ 'AE FF AB AB AB FF A9 A9 A9 FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A4 A4 A4 FF A1 A1 A1 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A1 A1 A1 FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9F 9F 9F FF 9A 9A 9A FF 9B 9B 9B FF 98 98'
+ '98 FF 99 99 99 FF 97 97 97 FF 96 96 96 FF 94 94'
+ '94 FF 93 93 93 FF 93 93 93 FF 92 92 92 FF 90 90'
+ '90 FF 8E 8E 8E FF 8B 8B 8B FF 89 89 89 FF 89 89'
+ '89 FF 87 87 87 FF 94 94 94 F9 4E 4E 4E AC 00 00'
+ '00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 EB EB EB 5C E4 E4 E4 FF C9 C9 C9 FF C8 C8'
+ 'C8 FF C5 C5 C5 FF C3 C3 C3 FF BE BE BE FF BB BB'
+ 'BB FF B9 B9 B9 FF B5 B5 B5 FF B3 B3 B3 FF B0 B0'
+ 'B0 FF AD AD AD FF AB AB AB FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF A2 A2'
+ 'A2 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9D 9D 9D FF 9C 9C 9C FF 99 99'
+ '99 FF 9A 9A 9A FF 99 99 99 FF 98 98 98 FF 95 95'
+ '95 FF 94 94 94 FF 94 94 94 FF 93 93 93 FF 91 91'
+ '91 FF 90 90 90 FF 8F 8F 8F FF 8C 8C 8C FF 8A 8A'
+ '8A FF 88 88 88 FF 95 96 95 FA 52 52 52 AE 00 00'
+ '00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E6 E6 E6 68 E4 E4 E4 FF CA CA CA FF C8 C8'
+ 'C8 FF C5 C5 C5 FF C2 C2 C2 FF BE BE BE FF BC BC'
+ 'BC FF B9 B9 B9 FF B5 B5 B5 FF B3 B3 B3 FF B0 B0'
+ 'B0 FF AC AC AC FF AB AB AB FF AA AA AA FF A9 A9'
+ 'A9 FF A8 A8 A8 FF A6 A6 A6 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A1 A1 A1 FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9E 9E 9E FF 9C 9C 9C FF 9B 9B'
+ '9B FF 9B 9B 9B FF 99 99 99 FF 99 99 99 FF 98 98'
+ '98 FF 96 96 96 FF 94 94 94 FF 94 94 94 FF 92 92'
+ '92 FF 92 92 92 FF 91 91 91 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 88 88 88 FF 96 96 96 FA 57 57 57 AF 00 00'
+ '00 2B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E2 E2 E2 76 E5 E5 E5 FF CC CC CC FF CB CB'
+ 'CB FF C7 C7 C7 FF C4 C4 C4 FF C1 C1 C1 FF BE BE'
+ 'BE FF BB BB BB FF B8 B8 B8 FF B5 B5 B5 FF B2 B2'
+ 'B2 FF AF AF AF FF AC AC AC FF A9 A9 A9 FF A8 A8'
+ 'A8 FF A5 A5 A5 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9C 9C 9C FF 9A 9A 9A FF 9A 9A 9A FF 97 97'
+ '97 FF 96 96 96 FF 96 96 96 FF 95 95 95 FF 93 93'
+ '93 FF 92 92 92 FF 90 90 90 FF 8D 8D 8D FF 8B 8B'
+ '8B FF 88 88 88 FF 96 96 96 FA 58 58 58 B0 00 00'
  '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E3 E3 E3 81 E5 E5 E5 FF CC CC CC FF CC CC'
+ 'CC FF C8 C8 C8 FF C6 C6 C6 FF C1 C1 C1 FF C0 C0'
+ 'C0 FF BC BC BC FF B9 B9 B9 FF B5 B5 B5 FF B2 B2'
+ 'B2 FF AF AF AF FF AC AC AC FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF A1 A1 A1 FF A1 A1 A1 FF A0 A0 A0 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9D 9D 9D FF 9E 9E 9E FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9B 9B 9B FF 99 99 99 FF 98 98'
+ '98 FF 98 98 98 FF 97 97 97 FF 95 95 95 FF 94 94'
+ '94 FF 92 92 92 FF 90 90 90 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 89 89 89 FF 95 95 95 FB 59 59 59 B1 00 00'
+ '00 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E3 E3 E3 8C E7 E7 E7 FF CD CD CD FF CD CD'
+ 'CD FF C9 C9 C9 FF C6 C6 C6 FF C5 C5 C5 FF C1 C1'
+ 'C1 FF BE BE BE FF BA BA BA FF B5 B5 B5 FF B3 B3'
+ 'B3 FF B0 B0 B0 FF AE AE AE FF AB AB AB FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A0 A0 A0 FF 9E 9E 9E FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9C 9C 9C FF 9A 9A 9A FF 9A 9A'
+ '9A FF 99 99 99 FF 97 97 97 FF 95 95 95 FF 94 94'
+ '94 FF 92 92 92 FF 90 90 90 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 88 88 88 FF 96 96 96 FB 5B 5B 5B B2 00 00'
+ '00 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 E9 E9 E9 81 E7 E7 E7 FE CF CF CF FF CE CE'
+ 'CE FF CB CB CB FF C8 C8 C8 FF C3 C3 C3 FF C1 C1'
+ 'C1 FF BE BE BE FF BB BB BC FF B7 B7 B7 FF B4 B4'
+ 'B4 FF B2 B2 B2 FF AE AD AD FF AB AB AB FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A5 A5 A5 FF A4 A4 A4 FF A2 A2'
+ 'A2 FF A0 A0 A0 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9D 9D 9D FF 9F 9F 9F FF 9D 9D 9D FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9B 9B 9B FF 9C 9C 9C FF 99 99'
+ '99 FF 98 98 98 FF 97 97 97 FF 95 95 95 FF 94 94'
+ '94 FF 92 92 92 FF 8E 8E 8E FF 8E 8E 8E FF 8A 8A'
+ '8A FF 88 88 88 FF 93 93 93 FB 5D 5D 5D B2 00 00'
+ '00 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 EC EC EC 36 EE EE EE DD D8 D9 DD FF D1 D3'
+ 'D6 FF CF D1 D4 FF CC CE D2 FF CA CB CE FF C6 C8'
+ 'CB FF C3 C5 C8 FF BD BF C3 FF BA BC BF FF B6 B8'
+ 'BC FF B3 B5 B9 FF B0 B2 B5 FF AC AE B2 FF A9 AB'
+ 'AF FF A5 A6 AA FF A3 A6 A9 FF A3 A4 A7 FF A4 A6'
+ 'A9 FF A2 A3 A5 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9B 9B 9B FF 9B 9B 9B FF 9A 9A'
+ '9A FF 98 98 98 FF 97 97 97 FF 93 93 93 FF 93 93'
+ '93 FF 91 91 91 FF 8E 8E 8E FF 8C 8C 8C FF 88 88'
+ '88 FF 85 85 85 FF 93 93 94 FB 64 64 66 AA 00 00'
+ '00 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F6 F6 E6 99 CB C4 B0 FF B0 A6'
+ '90 FF AF A5 8F FF AF A5 90 FF AA A0 8A FF A6 9C'
+ '86 FF A2 98 82 FF 9F 95 80 FF 99 8E 7A FF 95 8C'
+ '78 FF 94 8B 77 FF 91 88 76 FF 92 8A 78 FF 95 8D'
+ '7D FF 95 8E 7E FF 92 8B 7D FF 8E 88 7A FF 8F 89'
+ '7D FF 96 93 8D FF 9F A0 A3 FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9D 9D 9D FF 9B 9B 9B FF 9C 9C'
+ '9C FF 9B 9B 9B FF 9A 9A 9A FF 99 99 99 FF 97 97'
+ '97 FF 96 96 96 FF 94 94 94 FF 92 92 92 FF 8F 8F'
+ '8F FF 8E 8E 8E FF 8B 8B 8B FF 88 88 88 FF 84 84'
+ '84 FF 85 85 85 FF A4 A4 A4 F4 7C 7C 7C 83 00 00'
+ '00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F9 F9 F5 86 EC E3 CF FC DB CD'
+ 'B3 FF D9 CB B2 FF D6 C9 AF FF D4 C6 AC FF D2 C5'
+ 'AB FF D2 C5 AA FF CF C2 A7 FF CC BF A5 FF CA BC'
+ 'A2 FF C5 B8 9D FF BE B0 96 FF B8 AA 8F FF B3 A5'
+ '89 FF AD A0 84 FF AC 9E 82 FF AA 9C 7F FF A2 93'
+ '75 FF 9B 8A 69 FF A4 9F 97 FE B5 B6 B7 F7 BA BA'
+ 'BA F6 B9 B9 B9 F6 B7 B7 B7 F6 B7 B7 B7 F6 B7 B7'
+ 'B7 F6 B5 B5 B5 F7 B3 B3 B3 F7 B0 B0 B0 F7 AF AF'
+ 'AF F7 AD AD AD F7 AA AA AA F7 A6 A6 A6 F7 A3 A2'
+ 'A3 F8 A0 A0 A0 F8 9D 9D 9D F8 98 98 98 F8 96 96'
+ '96 F7 A8 A8 A8 F1 63 63 63 42 00 00 00 15 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 EF EB E7 40 FC FC EE D9 F0 E9'
+ 'D3 FE EF E6 C8 FF EE E3 C6 FF ED DF C3 FF EB DD'
+ 'C1 FF E8 D9 BD FF E3 D5 B8 FF E0 D2 B6 FF DC CD'
+ 'B2 FF D9 CB AF FF D6 C7 AB FF D2 C4 A8 FF CE BF'
+ 'A3 FF C9 BB 9F FF C5 B7 9B FF C3 B5 99 FF C0 B2'
+ '96 FF CE C3 A3 FF BA AD 91 AC AE B0 B5 72 C9 C9'
+ 'C9 6E CE CE CE 6E D2 D2 D2 6E D1 D1 D1 6F D3 D3'
+ 'D3 6F D7 D7 D7 6F D5 D5 D5 6F D5 D5 D5 6F D7 D7'
+ 'D7 6F CF CF CF 70 CB CB CB 72 CB CB CB 72 C5 C0'
+ 'C5 73 BD BD BD 74 B9 B9 B9 75 B5 B5 B5 73 B2 B2'
+ 'B2 71 BA BA BA 68 19 19 19 14 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
- '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
- 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
- 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EA EA'
- 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
- 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 DE DE D6 46 FC FB'
+ 'E9 C6 FC FB E5 D4 FC FA E2 D4 FC F8 DD D4 FC F7'
+ 'DC D4 FB F6 D9 D4 FA F4 D4 D4 FA F2 D2 D4 F7 F0'
+ 'CE D4 F6 EF CC D4 F5 E8 C7 D4 F4 E5 C2 D4 F1 E2'
+ 'C0 D4 EF DC BE D4 EA DA BA D4 E8 D6 B5 D4 E6 D6'
+ 'B6 D4 DE D2 B1 BB A8 9E 84 32 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
- 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
- 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
- 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
- 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
- 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
- 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
- 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
- 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
- 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
- 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
- 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
- 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
- '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
- '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
- '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
- '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
- '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -5472,281 +4682,27 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
- 'FF F0 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 C0 00 00 00 03 FF 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
- '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
- '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 24 00 00 00 6C 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 3C 3C 3C FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C'
- '3C FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
- '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
- '60 FF 7F 60 60 FF 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
- '00 04 00 00 00 14 00 00 00 26 00 00 00 2D 00 00'
- '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
- '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
- '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
- '00 2D 28 28 24 FF 00 00 00 8F 8C 8C 8C FF 0C 0C'
- '0C FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
- '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
- '40 FF D5 40 40 FF 00 00 00 00 00 00 00 07 00 00'
- '00 23 00 00 00 55 00 00 00 7E 00 00 00 8C 00 00'
- '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
- '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
- '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
- '00 8C 2A 2A 25 FF 00 00 00 FF 00 00 00 FF 0C 0C'
- '0C FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
- '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
- '80 FF EA 80 80 FF 00 00 00 00 00 00 00 1F 00 00'
- '00 C2 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 04 04 04 FF 0C 0C 0C FF 10 10 10 FF 18 18'
- '18 FF ED ED ED FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF 00 00 00 00 00 00 00 C0 00 00'
- '00 FF 21 21 21 FF 2C 2C 2C FF 2C 2C 2C FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 0C 0C 0C FF 0C 0C 0C FF 18 18 18 FF 17 17'
- '17 FF EC EC EC FF E7 E7 E7 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 00 00 00 06 01 01 01 FF 8A 8A'
- '8A FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 00 C0 00 FF E7 E7 E7 FF E8 E8 E8 FF E3 E3'
- 'E3 FF D8 D8 D8 FF D2 D2 D2 FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF C8 C9 C9 FF AA AA AA FF 2E 2E'
- '2E FF 00 00 00 FF 00 00 00 FF 1F 1F 1F FF 18 18'
- '18 FF EA EA EA FF E6 E6 E6 FF E8 E8 E8 FF E8 E8'
- 'E8 FF EA EA EA FF EA EA EA FF EB EB EB FF EB EB'
- 'EB FF EC EC EC FF 00 00 00 1B 19 19 19 FF AD A8'
- 'AB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF 00 FF'
- '00 FF 00 FF 00 FF 00 C0 00 FF DF DF DF FF D5 D5'
- 'D5 FF D2 D2 D2 FF CB CB CB FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF 40 40 40 FF 2E 2E'
- '2E FF 00 00 00 FF 00 00 00 FF 15 15 15 FF 13 13'
- '13 FF E9 E9 E9 FF E7 E7 E7 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 00 00 00 3A 28 28 28 FF D1 D1'
- 'D1 FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
- 'E8 FF 00 FF 00 FF B5 B5 B5 FF B6 B6 B6 FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF B6 B6 B6 FF B6 B6'
- 'B6 FF 00 00 00 FF 00 00 00 FF 0A 0A 0A FF 0D 0D'
- '0D FF E8 E8 E8 FF E7 E7 E7 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF 00 00 00 39 28 28 28 FF D1 D1'
- 'D1 FF E8 E8 E8 FF EB EB EB FF E8 E8 E8 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 24 24 24 FF 1F 1F 1F FF 07 07 07 FF 0A 0A'
- '0A FF E5 E5 E5 FF E7 E7 E7 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
- '99 FF 99 99 99 FF 00 00 00 39 27 27 27 FF D2 D2'
- 'D2 FF EA EA EA FF EB EB EB FF EB EB EB FF A7 A7'
- 'A7 FF AB AB AB FF AE AE AE FF AF AF AF FF AF AF'
- 'AF FF AF AF AF FF AF AF AF FF AB AB AB FF AB AB'
- 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
- 'AB FF 32 32 32 FF 0C 0C 0C FF 00 00 00 FF 00 00'
- '00 FF E5 E5 E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E9 E9 E9 FF E9 E9 E9 FF EA EA EA FF EA EA'
- 'EA FF EB EB EB FF 00 00 00 39 26 26 26 FF D3 D3'
- 'D3 FF EB EB EB FF ED ED ED FF E9 E9 E9 FF E8 E8'
- 'E8 FF E4 E4 E4 FF E2 E2 E2 FF DC DC DC FF D8 D8'
- 'D8 FF D2 D2 D2 FF D2 D2 D2 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF 37 37 37 FF 02 02 02 FF 04 04 04 FF 04 04'
- '04 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 37 24 24 24 FF D6 D6'
- 'D6 FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E0 E0'
- 'E0 FF DF DF DF FF DF DF DF FF DF DF DF FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF 3F 3F 3F FF 0D 0D 0D FF 12 12 12 FF 16 16'
- '16 FF 21 21 21 FF 26 26 26 FF 3C 3C 3C FF 44 44'
- '44 FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
- '2C FF 2C 2C 2C FF 00 00 00 34 24 24 24 FF DE DE'
- 'DE FF D9 D9 D9 FF C4 C4 C4 FF BF BF BF FF D8 D8'
- 'D8 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF 44 44 44 FF 23 23 23 FF 1B 1B 1B FF 20 20'
- '20 FF 2B 2B 2B FF 35 35 35 FF 44 44 44 FF 47 47'
- '47 FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
- '2C FF 2C 2C 2C FF 00 00 00 07 05 05 05 FF C2 C2'
- 'C2 FF BC BC BC FF B2 B2 B2 FF AB AB AB FF BB BB'
- 'BB FF D5 D5 D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3'
- 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D7 D7'
- 'D7 FF D3 D3 D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5'
- 'D5 FF 4B 4B 4B FF 4C 4C 4C FF 2E 2E 2E FF 33 33'
- '33 FF 45 45 45 FF 44 44 44 FF 4B 4B 4B FF 4B 4B'
- '4B FF 3C 3C 3C FF 32 32 32 FF 25 25 25 FF 1C 1C'
- '1C FF 16 16 16 FF 00 00 00 00 00 00 00 FF A4 A4'
- 'A4 FF CF CF CF FF C5 C5 C5 FF BF BF BF FF C9 C9'
- 'C9 FF D2 D2 D2 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0'
- 'D0 FF 52 52 52 FF 57 57 57 FF 35 35 35 FF 3F 3F'
- '3F FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
- '8C FF 8C 8C 8C FF 00 00 00 00 00 00 00 FF 59 59'
- '59 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CA CA'
- 'CA FF D3 D3 D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5'
- 'D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D5 D5 D5 FF DB DB DB FF E4 E4'
- 'E4 FF 5E 5E 5E FF 5E 5E 5E FF 6A 6A 6A FF 44 44'
- '44 FF 8E 8E 8E FF FF FF FF FF 8B 86 84 FF 87 80'
- '7D FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
- '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 FF 40 40'
- '40 FF D2 D2 D2 FF CA CA CA FF CA CA CA FF D4 D4'
- 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3 D3 FF D2 D2'
- 'D2 FF D3 D3 D3 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0'
- 'D0 FF 5E 5E 5E FF 5E 5E 5E FF 6A 6A 6A FF 44 44'
- '44 FF 8E 8E 8E FF FF FF FF FF 8B 86 84 FF 87 80'
- '7D FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
- '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 F4 07 07'
- '07 FF DD DD DD FF CC CC CC FF D3 D3 D3 FF D3 D3'
- 'D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 65 65 65 FF 6A 6A 6A FF 71 71 71 FF 79 79'
- '79 FF 9E 9E 9E FF FF FF FF FF 52 52 52 FF 4E 4E'
- '4E FF F2 D6 C7 FF EF CC B8 FF E9 B8 9C FF E9 B6'
- '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 BA 00 00'
- '00 FF DD DD DD FF CF CF CF FF D3 D3 D3 FF D3 D3'
- 'D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 3C 3C 3C FF 6A 6A 6A FF 71 71 71 FF 79 79'
- '79 FF AA AA AA FF FF FF FF FF 50 50 50 FF 4C 4C'
- '4C FF F4 DD D0 FF F1 D2 C2 FF EB BE A5 FF E9 B6'
- '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 4D 00 00'
- '00 FF D8 D8 D8 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF A3 A3 9E FF DA DA D8 FF DA DA D8 FF DA DA'
- 'D8 FF D5 CB C4 FF D2 C3 B9 FF CE B6 A6 FF CC AF'
- '9D FF CA A8 94 FF 00 00 00 00 00 00 00 1A 00 00'
- '00 FF CC CC CC FF D6 D6 D6 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CC CC CC FF C9 C9'
- 'C9 FF C4 C4 C4 FF C2 C2 C2 FF BD BD BD FF D0 D0'
- 'D0 FF 09 09 09 FF 00 00 00 FF 00 00 00 6C 00 00'
- '00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00'
- '00 D2 97 97 97 FF DC DC DC FF DC DC DC FF DE DE'
- 'DE FF DE DE DE FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF E7 E7 E7 FF E7 E7 E7 FF DC DC DC FF C6 C6'
- 'C6 FF 00 00 00 FF 00 00 00 FF 00 00 00 59 00 00'
- '00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 AF 77 77 77 FF D3 D3 D3 FF E1 E1 E1 FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1'
- 'E1 FF E7 E7 E7 FF E7 E7 E7 FF D9 D9 D9 FF BB BB'
- 'BB FF 00 00 00 FF 00 00 00 FF 00 00 00 40 00 00'
- '00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 66 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E6 E6 E6 FF D4 D4 D4 FF 9A 9A'
- '9A FF 00 00 00 FF 00 00 00 A4 00 00 00 2B 00 00'
- '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 2D 1E 1E 1E FF AB AB AB FF ED ED ED FF E7 E7'
- 'E7 FF EC EC EC FF EB EB EB FF ED ED ED FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EC EC'
- 'EC FF E5 E5 E5 FF EB EB EB FF D6 D6 D6 FF 8A 8A'
- '8A FF 00 00 00 FF 00 00 00 7B 00 00 00 1B 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 8D 8D 8D FF C4 C4 C4 FF B2 B2'
- 'B2 FF B2 B2 B2 FF EB EB EB FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5'
- 'D5 FF B6 B6 B6 FF B7 B7 B7 FF CD CD CD FF 61 61'
- '61 FF 00 00 00 FF 00 00 00 50 00 00 00 0F 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 64 64 64 FF DD DD DD FF DC DC'
- 'DC FF E4 E4 E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA FA FF F2 F2'
- 'F2 FF D8 D8 D8 FF DC DC DC FF B0 B0 B0 FF 34 34'
- '34 FF 00 00 00 E5 00 00 00 31 00 00 00 04 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9C 00 00 00 FF 3D 3D 3D FF 49 49'
- '49 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 49 49 49 FF 49 49 49 FF 02 02 02 FF 00 00'
- '00 FF 00 00 00 49 00 00 00 14 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 00 00 00 7F 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FA 00 00'
- '00 7C 00 00 00 12 00 00 00 04 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -5755,108 +4711,18 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF E0 00 FF FF E0 00 FF FF'
- 'E0 00 C0 00 00 00 80 00 00 00 80 00 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 1F 80 00 00 1F C0 00 00 1F C0 00 00 1F C0 00'
- '00 1F E0 00 00 3F E0 00 00 3F E0 00 00 7F E0 00'
- '00 7F FF FF FF FF 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 00 00 00 FF 00 00 00 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 36 36 30 FF 00 00 00 FF C0 00'
- '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF 00 00'
- '00 00 00 00 00 16 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 FF 30 30 2C FF 00 00 00 FF FF C0'
- 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
- '00 54 90 90 90 FF AB AC AC FF CC CC CC FF C4 C4'
- 'C4 FF C2 C2 C2 FF C1 C1 C1 FF BC BC BC FF BD BD'
- 'BD FF 00 00 00 FF 18 18 18 FF 00 00 00 FF E0 E0'
- 'E0 FF E1 E1 E1 FF E2 E2 E2 FF E3 E3 E3 FF 00 00'
- '00 FA EA EA EA FF E8 E8 E8 FF 00 FF 00 FF CB CB'
- 'CB FF 66 66 66 FF 66 66 66 FF 66 66 66 FF CD CD'
- 'CD FF 00 00 00 FF 00 00 00 FF 00 00 00 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
- '00 F9 EF EF EF FF EB EB EB FF 3B 3B 3B FF 3B 3B'
- '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
- '3B FF 00 00 00 FF 02 02 02 FF 00 00 00 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
- '00 F9 F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F3 F3'
- 'F3 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
- 'EF FF 00 00 00 FF 09 09 09 FF 10 10 10 FF 1E 1E'
- '1E FF 42 42 42 FF 46 46 46 FF 2C 2C 2C FF 00 00'
- '00 F7 F3 F3 F3 FF B7 B7 B7 FF DA DA DA FF D8 D8'
- 'D8 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
- 'D8 FF 00 00 00 FF 1F 1F 1F FF 2F 2F 2F FF 44 44'
- '44 FF 49 49 49 FF 2C 2C 2C FF 1C 1C 1C FF 00 00'
- '00 73 EF EF EF FF CB CB CB FF CE CE CE FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF 00 00 00 FF 5D 5D 5D FF 00 00 00 FF F9 EE'
- 'E8 FF F0 CF BC FF E9 B6 99 FF E9 B6 99 FF 00 00'
- '00 25 B7 B7 B7 FF CB CB CB FF D3 D3 D3 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 00 00 00 FF 6A 6A 6A FF 00 00 00 FF B8 B6'
- 'B6 FF 5B 58 57 FF EA BC A1 FF E9 B6 99 FF 00 00'
- '00 00 5F 5F 5F FF D2 D2 D2 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 00 00 00 FF 79 79 79 FF 00 00 00 FF E0 E0'
- 'E0 FF D9 D1 CC FF F0 CF BC FF EA BB A0 FF 00 00'
- '00 00 18 18 18 FF DB DB DB FF DE DE DE FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF D9 D9 D9 FF 7A 7A 7A FF 00 00'
- '00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF E5 E5 E5 FF EB EB EB FF EB EB'
- 'EB FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E7 E7 E7 FF E6 E6 E6 FF 20 20 20 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 DD E4 E4 E4 FF C1 C1 C1 FF ED ED'
- 'ED FF EE EE EE FF EB EB EB FF ED ED ED FF ED ED'
- 'ED FF C2 C2 C2 FF EC EC EC FF 00 00 00 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 44 80 80 80 FF D7 D7 D7 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D9 D9 D9 FF B0 B0 B0 FF 00 00 00 ED 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2C 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 70 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 80'
- '00 00 FF 80 00 00 80 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 80 07 00 00 80 0F'
- '00 00 80 0F 00 00 80 0F 00 00 C0 1F 00 00'
-} */
-
-
-/* BINRES drive.ico */
-8 ICON drive.ico
-/* {
- '00 00 01 00 08 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 86 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 2E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 96 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 7E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 A6 12 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 4E 21 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 F6 46 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 9E 57 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 11 00 00 00 00 11 00 00 11 11 11 00 22 22'
- '22 00 33 33 33 00 44 44 44 00 55 55 55 00 66 66'
- '66 00 77 77 77 00 7F 7F 7F 00 00 CC 66 00 66 99'
- '99 00 33 CC 99 00 66 CC 99 00 88 88 88 00 99 99'
- '99 00 AA AA AA 00 BB BB BB 00 99 CC 99 00 CC CC'
- 'CC 00 DD DD DD 00 EE EE EE 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -5871,131 +4737,13 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 54 00 56 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 54 00'
- '00 00 00 00 00 00 03 00 00 00 5C 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 50 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 64 72 69 76 65 2E 69 63 6F'
- '00 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 18 18 18 18 18 18 18 18 18 18 18 18 18 18'
- '18 18 18 18 18 02 18 18 18 18 00 00 00 00 00 00'
- '00 18 18 03 03 04 03 04 03 03 04 03 03 04 03 03'
- '04 03 03 04 03 03 03 04 01 18 18 00 00 00 00 00'
- '18 18 06 12 14 12 12 12 12 11 12 12 12 12 12 12'
- '12 12 12 12 12 11 0F 10 0C 04 18 18 00 00 00 00'
- '18 18 12 16 16 11 07 08 0F 10 11 12 12 11 12 12'
- '12 12 12 12 12 12 0D 0B 10 0F 18 18 00 00 00 00'
- '18 03 14 16 16 11 06 0F 0F 10 11 11 11 11 10 10'
- '11 11 10 11 11 12 13 0E 12 0F 18 18 00 00 00 00'
- '18 03 14 16 16 12 09 09 0F 10 10 11 12 0F 0F 10'
- '0F 10 0F 10 11 14 12 12 14 10 18 18 00 00 00 00'
- '18 03 15 16 16 12 08 0F 0F 10 11 11 12 10 09 0F'
- '10 0F 0F 0F 11 14 14 12 14 0F 18 18 00 00 00 00'
- '18 03 14 17 15 16 15 15 15 15 15 14 15 14 15 14'
- '14 14 14 14 14 14 14 12 14 0F 18 18 00 00 00 00'
- '18 03 14 17 17 16 17 17 16 17 16 17 16 17 16 17'
- '16 17 16 17 16 16 16 17 15 10 18 18 00 00 00 00'
- '18 03 15 16 15 15 15 15 15 15 15 15 15 15 15 15'
- '15 15 15 15 15 15 15 15 17 10 18 18 00 00 00 00'
- '18 03 15 15 11 11 14 15 15 14 15 15 14 15 14 15'
- '14 15 14 15 14 12 11 12 16 10 18 18 00 00 00 00'
- '18 18 11 15 12 12 12 14 14 15 15 15 15 16 15 16'
- '15 15 15 14 15 11 12 12 16 09 18 18 00 00 00 00'
- '18 18 0F 16 14 14 14 15 15 15 16 15 15 15 15 15'
- '15 16 15 15 14 15 14 14 16 07 18 18 00 00 00 00'
- '00 18 08 16 14 14 14 15 15 15 14 15 15 14 15 14'
- '15 14 15 15 16 14 14 14 15 05 18 00 00 00 00 00'
- '00 18 05 15 14 14 15 15 14 14 14 14 14 14 14 14'
- '14 14 14 14 14 15 14 14 14 03 18 00 00 00 00 00'
- '00 18 04 14 14 14 15 14 14 14 15 14 14 14 14 14'
- '12 14 14 14 14 14 14 14 11 18 18 00 00 00 00 00'
- '00 18 18 12 15 14 15 14 15 14 14 14 15 14 14 12'
- '14 12 12 14 14 14 12 15 0F 18 18 00 00 00 00 00'
- '00 18 18 10 15 14 14 15 14 15 14 15 14 14 15 15'
- '14 12 14 12 12 12 12 14 08 18 18 00 00 00 00 00'
- '00 18 18 09 15 15 14 15 14 15 15 15 15 15 14 15'
- '15 15 15 15 15 12 14 14 06 18 18 00 00 00 00 00'
- '00 00 18 06 15 15 15 14 16 15 15 15 15 15 15 15'
- '15 15 15 15 14 15 15 14 05 18 00 00 00 00 00 00'
- '00 00 18 05 14 16 15 15 14 15 15 16 15 16 16 15'
- '16 15 15 15 15 15 15 11 03 18 00 00 00 00 00 00'
- '00 00 18 04 11 15 16 16 16 15 15 15 15 15 15 15'
- '15 15 15 15 16 16 15 10 18 18 00 00 00 00 00 00'
- '00 00 18 18 11 16 14 14 15 16 16 15 16 15 15 16'
- '15 16 16 15 12 15 15 09 18 18 00 00 00 00 00 00'
- '00 00 18 18 0F 15 14 12 16 17 17 17 17 17 17 17'
- '17 17 17 15 14 14 15 07 18 18 00 00 00 00 00 00'
- '00 00 00 18 04 10 15 15 15 15 15 15 15 15 15 15'
- '15 15 15 15 15 14 09 03 18 00 00 00 00 00 00 00'
- '00 00 00 18 18 03 04 04 04 04 04 04 04 04 04 04'
- '04 04 04 04 04 04 18 18 18 00 00 00 00 00 00 00'
- '00 00 00 00 18 18 18 18 18 18 18 18 18 18 18 18'
- '18 18 18 18 18 18 18 18 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F0 00 00 0F E0 00'
- '00 07 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 F0 00 00 0F F0 00 00 0F F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F8 00 00 1F F8 00'
- '00 1F FC 00 00 3F FF FF FF FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 11 00 11 11'
- '11 00 22 00 00 00 22 22 22 00 44 44 44 00 55 55'
- '55 00 66 66 66 00 77 77 77 00 7F 7F 7F 00 33 CC'
- '99 00 88 88 88 00 99 99 99 00 AA AA AA 00 BB BB'
- 'BB 00 99 CC 99 00 CC CC CC 00 DD DD DD 00 EE EE'
- 'EE 00 00 00 00 00 CC CC CC 00 DD DD DD 00 EE EE'
- 'EE 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -6009,145 +4757,56 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
- '95 00 00 00 38 00 A8 44 F9 77 13 00 00 00 18 0A'
- '38 00 00 00 38 00 18 6C 38 00 98 17 95 00 00 00'
- '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
- 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 86 00'
- '00 00 86 00 00 00 08 00 00 00 B0 18 95 00 00 00'
- '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
- '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 E0 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 0F 00 00 C0 00 00 00 00 1F 00 00 E0 00'
+ '01 FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 04 00 00 00'
+ '00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 54 00'
- '56 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
- '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
- '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
- 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
- '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 54 00 00 00 00 00 00 00 03 00'
- '00 00 5C 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 50 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 64'
- '72 69 76 65 2E 69 63 6F 00 00 1A 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 13 00 00 00 98 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 18 6C 38 00 86 00 00 00 00 00'
- '00 00 C9 F1 E7 77 86 00 00 00 A4 1A 95 00 08 00'
- '00 00 00 00 00 00 86 00 00 00 86 00 00 00 08 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 18 6C 38 00 86 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 13 13 02 02 02 02 02 02 02'
- '02 02 03 01 13 00 00 13 0C 0E 0B 0C 0D 0E 0D 0E'
- '0E 0D 0A 07 13 00 00 02 11 10 07 0B 0D 0D 0C 0C'
- '0C 0E 0F 0C 13 00 00 02 11 11 0C 0D 0E 0E 0C 0D'
- '0C 0E 10 0D 13 00 00 02 11 12 12 12 11 11 12 11'
- '11 11 11 0E 13 00 00 13 10 0E 10 10 11 11 11 11'
- '11 10 10 0E 13 00 00 13 0D 10 10 11 11 11 11 11'
- '11 10 11 0B 13 00 00 13 0B 11 11 11 10 10 10 11'
- '10 10 11 07 13 00 00 13 07 11 10 10 11 10 10 0E'
- '10 10 10 06 13 00 00 13 05 10 11 11 10 11 11 10'
- '11 10 10 04 13 00 00 13 04 11 11 11 11 11 11 11'
- '11 11 0E 02 13 00 00 00 13 0E 11 12 12 12 12 12'
- '11 12 0D 13 00 00 00 00 13 08 10 11 11 12 11 12'
- '10 10 07 13 00 00 00 00 13 13 04 02 04 02 04 02'
- '04 02 13 13 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 FF FF 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 80 00 00 00 00 80 82 00 00 00 00 00'
- '87 77 77 77 77 77 77 77 77 87 88 88 00 00 00 00'
- '7F F7 88 87 87 77 77 77 77 77 2E 88 00 00 00 00'
- '7F F8 88 88 78 78 77 88 77 77 77 78 00 00 00 00'
- 'F7 F7 88 78 77 77 88 87 88 77 77 78 00 00 00 08'
- '7F 77 88 88 87 78 88 78 88 77 77 77 00 00 00 00'
- '7F FF 77 77 F7 77 77 77 77 77 77 78 00 00 00 00'
- '7F FF FF FF FF FF FF FF FF 7F FF F8 00 00 00 04'
- '7F 77 F7 FF 7F 7F 77 F7 F7 FF 77 F8 00 00 00 00'
- 'F7 77 7F 77 7F 77 F7 F7 7F 77 77 77 00 00 00 00'
- '77 77 77 77 F7 FF 7F 77 F7 77 77 F8 00 00 00 00'
- '8F 77 77 FF 7F 77 F7 FF 7F 77 77 F8 00 00 00 00'
- '8F 77 7F F7 F7 7F 7F 77 F7 7F 7F 78 00 00 00 00'
- '8F 77 F7 77 7F 77 77 F7 7F 77 77 70 00 00 00 00'
- '87 7F 77 7F 77 F7 7F 77 77 7F 77 70 00 00 00 00'
- '07 77 F7 77 F7 77 77 77 77 77 7F 80 00 00 00 00'
- '08 7F 77 F7 77 7F 77 77 77 77 77 80 00 00 00 00'
- '08 F7 7F 7F 7F 77 F7 F7 F7 77 77 80 00 00 00 00'
- '08 7F 77 F7 F7 FF 7F 7F 7F 77 F7 80 00 00 00 00'
- '04 7F 7F 7F 7F 7F F7 F7 F7 F7 77 00 00 00 00 00'
- '08 8F FF 77 F7 F7 7F 7F 7F 7F F8 00 00 00 00 00'
- '00 77 77 FF 7F 7F F7 F7 FF 77 F8 00 00 00 00 00'
- '00 8F 77 FF FF FF FF FF F7 7F 78 00 00 00 00 00'
- '00 48 7F 77 F7 F7 7F 7F 77 F7 80 00 00 00 00 00'
- '00 00 80 48 08 04 80 80 48 04 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F0 00 00 0F E0 00'
- '00 07 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 F0 00 00 0F F0 00 00 0F F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F8 00 00 1F F8 00'
- '00 1F FC 00 00 3F FF FF FF FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- '80 00 00 02 00 00 00 87 88 77 77 77 68 00 00 F7'
- '88 87 87 87 78 00 08 77 87 77 87 87 77 00 00 FF'
- 'F7 FF 7F 7F 77 00 00 77 77 F7 F7 F7 77 00 00 77'
- '7F 77 F7 7F 78 00 00 87 F7 7F 77 F7 F8 00 00 8F'
- '77 F7 77 77 78 00 00 87 7F 77 7F 77 78 00 00 47'
- 'F7 F7 F7 F7 70 00 00 07 F7 FF 7F 7F 70 00 00 08'
- '7F 7F F7 F7 80 00 00 00 04 08 00 40 00 00 00 00'
- '00 00 00 00 00 00 FF FF 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 11 00 11 11 11 00 22 22 22 00 33 33'
- '33 00 44 44 44 00 55 55 55 00 66 66 66 00 77 77'
- '77 00 7F 7F 7F 00 00 99 66 00 33 99 66 00 00 CC'
- '66 00 33 CC 66 00 66 99 99 00 88 88 88 00 99 99'
- '99 00 AA AA AA 00 BB BB BB 00 99 CC 99 00 99 FF'
- '99 00 99 CC CC 00 CC CC CC 00 DD DD DD 00 EE EE'
- 'EE 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -6155,188 +4814,94 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 70 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 87 78 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 8F 44 44 44 FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF F8 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 FF FF FF FF 44 44 44'
+ '44 44 44 44 FF FF FF 44 44 44 44 44 FF 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 FF 4F FF FF FF FF FF'
+ 'FF FF FF FF 44 44 44 4F FF FF FF FF FF 88 88 88'
+ '88 88 87 00 00 00 00 F8 8F FF F4 FF 4F 4F 44 44'
+ 'FF 44 FF F4 4F F4 FF 44 4F FF FF FF FF F8 88 88'
+ '88 88 87 00 00 00 00 F8 8F FF F4 F4 4F 44 4F 44'
+ '44 FF 4F FF 4F 44 44 F4 F4 4F FF FF FF F8 88 88'
+ '88 88 87 00 00 00 00 F8 8F FF FF 4F F4 FF FF F4'
+ 'FF 4F FF FF 4F FF FF 4F FF FF FF FF FF F8 88 88'
+ '88 88 87 00 00 00 00 F8 8F FF FF 44 FF FF FF FF'
+ '4F 4F FF FF 44 44 FF 4F FF FF FF FF FF F8 88 88'
+ '88 88 87 00 00 00 00 F8 88 FF FF 4F 4F FF FF FF'
+ '44 44 4F FF F4 FF FF 4F FF FF FF FF FF 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 FF FF 44 4F FF FF FF'
+ 'FF FF FF FF F4 44 FF FF FF FF FF FF FF 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 8F FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF F8 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 8F 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 78 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 00 00 00 00 0F 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 67 77 77 77 77 77 77 77 77 77 77'
+ '77 77 70 00 00 00 00 0F 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 68 88 88 88 88 88 88 88 88 88 88'
+ '88 88 00 00 00 00 00 08 FE 6E 6E 6E 6E 6E 6E 6E'
+ '6E 6E 6E 6E 6E 80 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 8F EF EF EF EF EF EF EF'
+ 'EF EF EF EF EF 80 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 08 88 88 88 88 88 88 88'
+ '88 88 88 88 88 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 13 00 00 00 18 0A 38 00 00 00 38 00 18 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 86 00 00 00 86 00 00 00 08 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 54 00 56 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 54 00'
- '00 00 00 00 00 00 03 00 00 00 5C 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 50 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 64 72 69 76 65 2E 69 63 6F'
- '00 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 13 00'
- '00 00 98 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 18 6C'
- '38 00 86 00 00 00 00 00 00 00 C9 F1 E7 77 86 00'
- '00 00 A4 1A 95 00 08 00 00 00 00 00 00 00 86 00'
- '00 00 86 00 00 00 08 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 18 6C'
- '38 00 86 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 1A 1A 02 03 03 04 03 03 04 03 03'
- '04 03 03 04 03 03 03 04 03 03 03 03 04 03 03 04'
- '03 03 03 04 01 1A 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 03 10 16 16 16 16 16 16 16 16 16'
- '12 16 12 12 16 12 12 12 16 12 12 12 12 12 12 11'
- '12 12 11 11 11 07 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 1A 1A 1A 0F 17 18 18 17 0F 0F 10 10 10 11'
- '12 16 12 16 16 16 16 17 16 16 16 17 16 16 16 16'
- '16 11 0B 0B 13 12 06 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 02 16 18 17 17 16 04 05 06 08 0F 0F'
- '11 10 11 11 12 11 10 12 10 12 10 16 10 12 10 16'
- '12 0D 0C 0A 0B 16 08 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 16 18 17 18 17 05 06 08 0F 10 10'
- '10 11 11 12 12 10 10 12 0F 12 10 12 10 12 0F 12'
- '16 10 15 14 0E 16 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 04 17 18 18 17 16 07 08 08 0F 0F 10'
- '10 11 11 11 12 11 08 12 08 11 0F 12 0F 12 08 16'
- '16 12 11 10 16 12 10 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 16 18 17 18 17 07 08 08 0F 0F 10'
- '11 11 11 11 12 10 08 11 07 10 08 11 0F 11 07 12'
- '12 16 12 16 12 16 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 17 18 18 17 17 07 07 08 0F 0F 0F'
- '10 11 10 11 12 0F 07 11 06 10 07 12 07 11 06 16'
- '16 12 16 12 12 16 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 16 18 18 18 17 11 11 11 11 11 12'
- '11 12 12 12 12 12 11 12 11 12 12 12 11 12 11 12'
- '16 12 16 12 16 12 10 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 17 18 18 18 18 17 18 18 18 17 17'
- '18 17 17 17 17 17 17 17 17 17 16 17 16 16 16 16'
- '16 16 12 16 12 16 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 16 18 19 19 18 19 19 18 18 18 19'
- '18 19 18 19 18 18 18 18 18 18 18 18 18 18 18 18'
- '18 18 18 18 17 17 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 17 19 17 17 18 17 17 18 17 17 17'
- '17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17'
- '18 17 18 17 19 18 0F 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 17 19 17 16 12 12 17 16 17 17 16'
- '17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17'
- '16 12 12 16 17 19 10 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 03 17 18 16 11 11 11 16 17 17 16 17'
- '17 16 17 16 17 17 16 17 16 17 16 17 16 17 17 16'
- '11 12 11 12 16 19 10 1A 1A 1A 00 00 00 00 00 00'
- '00 00 1A 1A 1A 12 19 12 11 16 11 12 17 16 17 17'
- '16 17 16 17 16 16 17 16 17 16 17 16 17 17 16 16'
- '11 12 12 11 17 19 08 1A 1A 1A 00 00 00 00 00 00'
- '00 00 00 1A 1A 11 18 16 16 16 16 16 16 17 16 16'
- '17 17 17 18 18 18 18 18 17 18 17 17 16 16 17 16'
- '16 16 12 16 16 18 06 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 08 18 17 16 16 16 16 16 16 17 18'
- '18 17 17 17 17 17 17 17 17 17 17 18 18 18 16 16'
- '16 16 16 16 17 17 04 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 06 18 16 16 16 16 16 17 18 18 17'
- '16 17 17 17 16 17 17 16 17 17 16 17 17 17 18 17'
- '16 16 16 16 17 12 03 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 05 17 16 16 16 16 16 18 17 16 16'
- '16 17 16 16 16 17 16 16 17 16 16 17 16 16 17 18'
- '16 16 16 16 17 11 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 03 12 17 16 16 16 18 16 16 17 16'
- '17 16 17 16 16 16 16 16 16 16 16 16 16 16 16 16'
- '18 16 16 16 17 0F 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 1A 1A 1A 10 17 16 16 17 16 17 16 16 16'
- '16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16'
- '16 17 12 16 17 06 1A 1A 1A 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 0F 17 17 16 17 16 16 17 16 17'
- '16 17 16 16 16 16 16 16 12 16 12 16 16 16 12 16'
- '16 16 16 16 17 05 1A 1A 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 06 17 16 16 16 17 16 16 16 16'
- '16 16 16 16 17 16 16 12 16 12 16 12 16 12 16 12'
- '16 12 16 16 17 03 1A 1A 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 05 17 16 17 16 16 17 16 17 16'
- '17 16 17 16 16 17 16 16 16 12 16 12 12 12 16 12'
- '12 16 12 16 11 03 1A 1A 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 03 16 17 16 16 17 16 17 16 17'
- '16 17 16 16 17 16 16 17 16 17 16 16 16 16 12 16'
- '16 11 12 16 11 1A 1A 1A 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 02 12 17 17 16 16 17 17 17 17'
- '17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 16'
- '16 16 16 16 08 1A 1A 1A 00 00 00 00 00 00 00 00'
- '00 00 00 00 1A 1A 1A 10 17 17 17 16 17 17 17 17'
- '17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17'
- '16 17 17 16 06 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 1A 08 17 17 18 17 16 17 17 17'
- '17 17 18 17 17 18 17 17 17 17 17 17 18 17 17 16'
- '17 17 17 12 04 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 1A 06 16 17 17 18 17 17 16 17'
- '17 18 17 18 17 17 18 17 17 18 18 17 17 16 16 18'
- '17 18 16 11 03 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 1A 04 12 18 17 17 18 17 17 16'
- '17 17 17 17 18 17 17 18 17 17 17 17 16 17 18 17'
- '18 17 17 10 1A 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 1A 02 11 18 18 18 18 18 18 18'
- '17 17 17 17 17 17 17 17 17 17 17 17 18 18 17 18'
- '17 18 17 0F 1A 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 1A 1A 11 17 17 12 12 17 18 18'
- '18 18 18 18 18 17 18 18 18 18 18 18 18 17 16 12'
- '17 18 16 08 1A 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 1A 1A 0F 17 16 11 12 11 18 18'
- '18 18 18 18 18 18 18 18 18 18 18 18 18 17 11 12'
- '11 18 16 07 1A 1A 1A 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 1A 1A 07 16 17 17 17 17 19 19'
- '19 19 19 19 19 19 19 19 19 19 19 19 19 18 17 17'
- '17 17 11 04 1A 1A 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 1A 1A 02 0F 12 17 17 17 17 17'
- '17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17'
- '17 11 07 1A 1A 1A 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 1A 1A 1A 1A 05 05 05 05 05 05'
- '05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05'
- '05 04 1A 1A 1A 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A'
- '1A 1A 1A 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -6348,36 +4913,398 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF 00'
- '00 00 00 7F 00 00 FC 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
- '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 20 00 00 00'
- '00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF C0 00'
+ '00 00 00 00 00 7F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F E0 00'
+ '00 00 00 00 00 7F E0 00 00 00 00 00 00 FF E0 00'
+ '00 01 FF FF FF FF F0 00 00 01 FF FF FF FF F8 00'
+ '00 03 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 40 00 00 00 80 00'
+ '00 00 01 00 08 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 78 3C'
+ '25 00 77 77 77 00 7A 7A 7A 00 7D 7D 7D 00 83 49'
+ '25 00 83 50 32 00 A7 7E 5E 00 97 6F 64 00 9F 75'
+ '62 00 9E 79 68 00 96 88 6B 00 8E 86 75 00 92 87'
+ '70 00 96 8A 72 00 91 88 76 00 95 8A 74 00 97 8C'
+ '77 00 99 8C 73 00 9C 8D 70 00 9C 8F 76 00 90 88'
+ '78 00 96 8C 78 00 A9 82 67 00 AB 84 69 00 A5 82'
+ '7A 00 B2 8E 74 00 A0 92 76 00 A1 94 7A 00 A3 96'
+ '7C 00 A4 97 7C 00 A6 98 7C 00 A8 9B 7F 00 B3 90'
+ '74 00 BA 99 7F 00 FF 00 FF 00 81 81 81 00 85 85'
+ '85 00 89 89 89 00 8D 8D 8D 00 91 91 91 00 95 95'
+ '95 00 9A 97 93 00 98 97 96 00 99 99 99 00 9D 9D'
+ '9D 00 AD 89 81 00 A9 9C 82 00 AB 9E 84 00 AD 90'
+ '88 00 B8 96 82 00 BB 9B 82 00 B2 96 8C 00 B5 9A'
+ '8A 00 BB 9C 89 00 AE A0 86 00 AE A2 88 00 B4 A5'
+ '87 00 B0 A3 89 00 B2 A5 8A 00 B4 A7 8D 00 BD A0'
+ '8A 00 B5 A8 8E 00 AD A2 91 00 A2 A0 9C 00 BA AC'
+ '92 00 BC AF 95 00 BE B2 98 00 9F 9F A0 00 9F A0'
+ 'A0 00 A1 A1 A1 00 A1 A2 A5 00 A4 A3 A4 00 A3 A4'
+ 'A7 00 A5 A5 A5 00 A3 A4 A8 00 A6 A7 A8 00 A7 A8'
+ 'A9 00 A7 A9 AC 00 A9 A9 A9 00 A8 AA AD 00 AB AC'
+ 'AC 00 AD AD AD 00 AB AD B0 00 AE AF B2 00 AF B0'
+ 'B1 00 B1 B1 B1 00 B1 B2 B5 00 B3 B4 B5 00 B5 B5'
+ 'B5 00 B6 B7 B8 00 B7 B8 B9 00 B9 B9 B9 00 BC BB'
+ 'BB 00 BD BC BB 00 B8 B9 BC 00 BB BC BE 00 BD BD'
+ 'BD 00 C2 A4 8C 00 C1 A4 93 00 C3 A8 92 00 C4 A9'
+ '92 00 C5 AB 95 00 C6 AD 96 00 C8 AA 91 00 C1 A5'
+ '99 00 C0 A9 9F 00 C8 AF 9A 00 C0 B2 98 00 C4 B6'
+ '9A 00 C4 B6 9C 00 CB B2 9C 00 C6 B8 9B 00 C6 B8'
+ '9D 00 C8 BA 9E 00 C6 AB A1 00 C7 AF A1 00 C5 AE'
+ 'A5 00 CC B5 A1 00 C7 BA A0 00 C8 BA A0 00 C9 BC'
+ 'A1 00 CD BF A3 00 CF B9 A6 00 CB BE A4 00 CC BF'
+ 'A4 00 CB B7 AC 00 CE B9 A9 00 D1 BA A4 00 D1 BC'
+ 'AA 00 C2 BD B5 00 D2 BE B3 00 D4 BE B8 00 CD C0'
+ 'A6 00 D1 C2 A6 00 D1 C3 A9 00 D2 C4 A9 00 D5 C7'
+ 'AA 00 D4 C0 AE 00 D3 C6 AC 00 D5 C7 AD 00 D8 C3'
+ 'AF 00 D6 C8 A9 00 D6 C8 AD 00 C8 C3 BF 00 D5 C2'
+ 'B1 00 D7 C4 B2 00 D7 C5 B5 00 D9 C7 B7 00 D9 CC'
+ 'B1 00 DC CE B1 00 DB CE B4 00 D7 C4 B9 00 D8 C7'
+ 'B8 00 D3 CA B9 00 D4 CB BA 00 D6 CE BD 00 D9 C8'
+ 'B9 00 DC CB BD 00 D9 CF BF 00 DE D0 B6 00 E0 D3'
+ 'B9 00 E2 D4 B9 00 E4 D6 B9 00 E6 D8 BD 00 E9 DC'
+ 'BF 00 C1 C1 C1 00 C4 C3 C2 00 C3 C4 C5 00 C5 C5'
+ 'C5 00 C6 C7 C9 00 C9 C9 C9 00 CC CC CB 00 C9 CA'
+ 'CC 00 CD CD CD 00 DA C9 C1 00 DE CE C1 00 D9 CD'
+ 'C4 00 D1 CD C9 00 D4 CF CB 00 DA D2 C0 00 DB D4'
+ 'C3 00 DF D2 C6 00 DB D5 C5 00 DC D8 C6 00 D5 D1'
+ 'CD 00 D8 D3 CF 00 D9 D7 CD 00 DC DA CA 00 DD DB'
+ 'CD 00 DD DC CE 00 CD CE D0 00 CF D0 D0 00 D1 D1'
+ 'D1 00 D4 D2 D0 00 D2 D3 D6 00 D5 D5 D5 00 DA D6'
+ 'D2 00 DD DD D2 00 DC D8 D4 00 DA DA DA 00 DD DD'
+ 'DD 00 E0 D1 C4 00 EB DE C2 00 E2 D4 CA 00 E6 D8'
+ 'CC 00 E6 DC D3 00 E8 DE D5 00 EE E3 C7 00 EE E5'
+ 'C8 00 F0 E8 CB 00 E1 E0 D7 00 EC E0 D4 00 EA E1'
+ 'D9 00 EB E3 DD 00 ED E6 DF 00 F4 EB D0 00 F6 EE'
+ 'D6 00 F0 E5 DD 00 F6 F3 D8 00 E2 E2 E2 00 E5 E5'
+ 'E5 00 EB E4 E1 00 EE E7 E0 00 EF E8 E2 00 EC E8'
+ 'E4 00 E9 E9 E9 00 ED ED ED 00 F2 E9 E0 00 F4 EB'
+ 'E2 00 F1 ED E0 00 F1 EA E5 00 F1 EC E6 00 F6 ED'
+ 'E6 00 F0 EB E8 00 F2 ED E9 00 F6 EE E8 00 F2 EF'
+ 'ED 00 F4 EF EC 00 F8 EF E8 00 F5 F0 EC 00 F8 F0'
+ 'EA 00 F9 F2 ED 00 FA F4 EE 00 F2 F2 F1 00 F4 F3'
+ 'F2 00 F6 F4 F1 00 F4 F4 F4 00 F9 F5 F0 00 FC F6'
+ 'F2 00 F8 F6 F4 00 FB F8 F5 00 FA F9 F8 00 FC FA'
+ 'F8 00 FE FD FB 00 FE FE FE 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ '60 54 28 26 26 25 26 26 25 26 26 25 26 26 25 26'
+ '26 25 26 26 25 26 26 25 26 26 25 26 26 25 26 26'
+ '25 26 26 25 26 26 25 26 26 25 26 26 25 26 26 25'
+ '26 26 25 26 26 25 28 FF FF FF FF FF FF FF FF FF'
+ 'A6 C3 60 5C 5B 5B 59 58 58 57 55 58 55 54 55 50'
+ '50 51 51 50 51 4E 49 4E 4B 49 49 49 49 47 45 45'
+ '45 45 43 2C 2C 2C 2B 2A 2A 2A 28 28 27 27 27 2A'
+ '27 27 27 27 27 2B 23 45 FF FF FF FF FF FF FF FF'
+ 'A8 DC A9 A6 A5 A5 5F 5B 5A 58 58 57 57 56 54 54'
+ '51 50 50 4E 4C 4B 49 49 46 43 44 3F 43 2C 2C 2C'
+ '2B 2B 2B 28 28 28 27 27 26 26 26 26 25 25 25 25'
+ '25 24 25 24 24 2B 03 43 FF FF FF FF FF FF FF FF'
+ 'A8 C8 59 58 58 AA C4 C5 C6 C6 C6 C6 C4 C6 C4 C4'
+ 'C4 C4 B9 B9 B9 B9 B9 B9 B8 B8 B8 C1 B8 B8 B8 B8'
+ 'B8 B8 B2 B2 B1 B1 B1 B1 B1 8F 45 24 23 23 03 23'
+ '23 03 03 03 03 27 02 2C FF FF FF FF FF FF FF FF'
+ 'A7 C7 58 5B DB FD FE FE FE FE FE FE FE FE FE FE'
+ 'FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE'
+ 'FE FE FE FE FE FE FE FE FE FE FC 5F 24 23 03 23'
+ '03 03 03 03 02 27 02 2C FF FF FF FF FF FF FF FF'
+ 'A6 C3 58 C1 F2 83 61 64 6A 6E 6E 8C D3 F2 F2 F2'
+ 'F2 F0 EE EB E8 E8 E8 E8 E8 E8 E8 E8 E8 E8 E8 E8'
+ 'E8 E8 E8 E8 E8 EE F0 F2 F2 E4 E4 F1 2C 23 23 03'
+ '23 03 03 03 03 26 02 2C FF FF FF FF FF FF FF FF'
+ 'A5 C3 5B F3 FE FE FE FD F2 F2 F7 EA B5 75 66 66'
+ '75 80 7E 75 6A 6A 6E 80 B3 CE E6 EF F5 EF EA D4'
+ 'B5 89 6A 66 6A 80 84 6E 75 97 F9 FE C3 23 23 23'
+ '23 03 03 03 02 26 01 2B FF FF FF FF FF FF FF FF'
+ 'A5 C0 A6 F7 EB F0 34 F1 EE EB E8 EB EF F2 F8 F8'
+ 'F8 F2 FD CC CD F8 FA E8 D3 AF 9C 89 89 91 92 AF'
+ 'CC E3 F8 FC FC F8 F8 F8 F2 F1 F0 EE DF 26 23 03'
+ '23 03 23 02 03 25 01 2C FF FF FF FF FF FF FF FF'
+ 'A5 AB AA FA F7 FA 9D 68 DE 65 05 19 04 09 6A 32'
+ '32 32 B5 FD AF 61 CB F8 F9 7D CC 64 E9 97 68 AF'
+ '62 63 2D 91 E8 FA F8 F7 F7 F5 F7 F7 EC 28 23 23'
+ '23 03 03 03 02 26 02 2A FF FF FF FF FF FF FF FF'
+ 'A5 AA AD FC FC FC F9 00 21 CE 89 06 9C 69 17 82'
+ '16 90 75 9C ED CB 63 FC FC E7 35 66 61 7F 6E 20'
+ '61 30 E6 CD 7A 93 FC FC FC FA FC FA F4 2A 24 23'
+ '23 03 23 02 03 25 02 2B FF FF FF FF FF FF FF FF'
+ 'A5 AA AA F2 F0 E8 F2 83 72 F8 F7 B5 D9 F8 F1 AF'
+ '7F 67 F8 7A 19 CB F2 EE F0 91 20 EF CB 6E F1 90'
+ '6E 7D E6 EE F0 F0 EE EB E8 EE E8 F0 E9 2A 24 24'
+ '23 03 03 03 03 25 02 2B FF FF FF FF FF FF FF FF'
+ 'AA AA A8 FE FE FE F9 FB 20 91 FA FE FE FE FE FE'
+ 'FC B5 91 FB 07 D5 FE FE FE DF 3C 90 75 80 92 F9'
+ '18 FE FE FE FE FE FE FE FE FE FE FE F3 28 24 24'
+ '23 23 23 03 03 26 02 28 FF FF FF FF FF FF FF FF'
+ 'C7 A8 5C EA F1 EB 91 33 63 7D 6E F0 E8 E8 E8 E8'
+ 'E8 F2 61 19 17 31 35 E4 EB E8 61 34 FD E7 66 EB'
+ '08 D4 E8 E8 E8 E8 E8 E8 E8 E8 E8 EE C6 25 25 24'
+ '24 23 23 03 03 26 02 28 FF FF FF FF FF FF FF FF'
+ 'C8 A8 58 DB FD FE FE E9 73 74 80 FD FE FE FE FE'
+ 'FE FE FD E6 DF FB DD F9 FE FE E7 B0 66 80 E7 D6'
+ 'E9 F9 FE FE FE FE FE FE FE FE FE FE 54 25 25 24'
+ '24 24 03 23 03 25 03 28 FF FF FF FF FF FF FF FF'
+ 'C8 A8 5A 5D E0 F1 EE EE F2 F8 F2 F0 EE E8 EB E8'
+ 'EB EB E8 EE E8 EE EB EE EE EB EB F1 F2 F2 F0 F0'
+ 'F0 EB EE E8 EB E8 EB E8 EB EE F1 B1 26 26 25 24'
+ '24 24 23 23 03 26 03 28 FF FF FF FF FF FF FF FF'
+ 'C8 A8 60 5C 60 DB F3 F4 F6 F6 F6 F6 F9 F6 F6 F6'
+ 'F6 F6 F6 F6 F4 F6 F4 F6 F3 F3 F4 F6 F3 F3 F4 F3'
+ 'F3 F3 F3 F6 F9 FB F6 FB E2 E1 60 27 25 26 25 25'
+ '25 24 24 23 23 27 03 27 FF FF FF FF FF FF FF FF'
+ 'C8 A8 5C 60 5F 5B 5B 58 58 57 55 54 51 51 50 50'
+ '4E 4E 4E 49 49 49 49 47 45 45 44 45 44 2C 2C 2C'
+ '2B 2B 28 2A 27 27 27 27 28 27 27 26 26 26 25 25'
+ '25 24 23 23 23 27 03 28 FF FF FF FF FF FF FF FF'
+ 'C8 A8 A5 5C 60 5B 5B 59 58 58 55 55 51 51 51 50'
+ '4E 4E 4E 4E 49 49 49 49 45 47 45 45 45 2C 2C 2C'
+ '2B 2B 2A 28 2A 28 28 28 27 27 27 26 27 26 25 25'
+ '25 24 24 24 23 27 23 27 FF FF FF FF FF FF FF FF'
+ 'C8 AA A5 A5 A5 5C 5C 5A 58 58 55 54 51 50 50 4E'
+ '4E 4E 49 4B 49 49 49 49 45 45 45 45 44 44 2C 2B'
+ '2B 2B 2B 2B 28 28 28 28 28 27 28 27 26 26 26 26'
+ '25 24 24 24 24 26 24 27 FF FF FF FF FF FF FF FF'
+ 'DC AB A8 A5 A6 60 60 5C 5B 59 58 55 54 51 51 50'
+ '4E 4E 4E 4E 49 49 4B 47 47 47 45 44 2C 2C 43 2B'
+ '2C 2B 2B 2A 28 2B 28 28 27 28 27 27 27 27 26 25'
+ '26 25 25 24 24 27 24 27 FF FF FF FF FF FF FF FF'
+ 'E1 AB A7 A8 A5 A5 60 5F 5B 5B 58 55 57 55 51 51'
+ '50 4E 4E 49 49 49 49 49 49 47 45 2C 3F 44 43 2C'
+ '2C 2B 2A 2A 28 28 28 28 28 27 27 27 27 26 26 26'
+ '26 25 25 24 25 27 24 27 FF FF FF FF FF FF FF FF'
+ 'E2 AB AA A8 A7 60 60 5C 5B 5A 58 58 55 55 51 51'
+ '50 4B 4E 4E 49 4E 49 49 47 45 45 45 44 3F 2C 2C'
+ '2C 2B 2B 2C 2B 28 28 28 28 28 27 27 27 27 26 26'
+ '25 26 25 25 24 27 25 26 FF FF FF FF FF FF FF FF'
+ 'F3 AC AA A8 A8 A6 5F 5C 5B 59 58 58 55 57 51 51'
+ '4E 4E 49 4E 49 49 49 47 49 47 44 3F 43 2C 2C 2C'
+ '2C 2B 2C 28 2B 2A 28 28 28 28 27 27 27 27 26 26'
+ '26 26 25 24 25 27 25 26 FF FF FF FF FF FF FF FF'
+ 'F3 AD A9 AA A6 A6 A5 5F 60 5B 59 58 55 55 51 51'
+ '4E 4E 4E 4E 49 49 49 45 49 45 45 45 45 2C 44 43'
+ '2B 2C 2B 2B 2B 2B 2A 28 28 28 28 28 27 27 27 26'
+ '25 25 25 25 25 28 25 26 FF FF FF FF FF FF FF FF'
+ 'E2 AD AB AA A8 A8 A5 A5 5C 5B 5B 58 58 55 55 51'
+ '4E 4E 4E 49 4E 49 49 47 47 45 47 45 3F 44 44 43'
+ '2C 2C 2C 2B 2B 2B 2B 2B 2A 28 28 27 28 27 27 27'
+ '27 26 26 25 25 28 25 26 FF FF FF FF FF FF FF FF'
+ 'F3 AD AB AC A8 A8 A8 A5 60 5C 5B 58 58 58 55 54'
+ '51 4E 50 4E 4E 47 49 47 49 47 45 3F 45 43 43 2C'
+ '44 2C 2C 2B 2C 2B 2B 2B 2A 2A 28 28 28 27 27 27'
+ '27 26 26 25 25 28 26 26 FF FF FF FF FF FF FF FF'
+ 'E2 AD AD AA AA A8 A5 A5 5D 5F 5B 59 58 55 54 51'
+ '51 51 4E 4E 4E 4E 49 47 49 47 45 47 44 44 3F 2C'
+ '44 2C 2C 2C 2B 2C 2B 2B 2B 2A 28 28 28 28 27 28'
+ '27 27 26 26 25 28 27 26 FF FF FF FF FF FF FF FF'
+ 'E1 BF AD AD AA A8 A8 A5 A5 60 5C 5B 58 58 55 55'
+ '51 51 4E 4E 49 49 49 49 49 49 45 47 44 45 3F 44'
+ '44 2C 43 2C 2C 2B 2C 2B 2B 28 2A 2A 28 28 28 27'
+ '27 26 26 25 25 28 27 26 FF FF FF FF FF FF FF FF'
+ 'E2 BF AD AD AA AA A8 A5 A5 A5 5B 5B 5B 58 55 55'
+ '51 50 4E 4E 49 49 49 49 47 47 45 45 45 45 45 44'
+ '2C 43 2C 2C 2C 2C 2C 2B 2B 2B 2B 2B 28 28 27 27'
+ '27 27 26 26 25 27 26 26 FF FF FF FF FF FF FF FF'
+ 'E1 BF BF AD AB AA A8 A6 A5 A5 60 5C 58 58 55 55'
+ '51 51 50 4E 49 49 47 47 47 47 45 45 44 3F 44 43'
+ '2C 44 43 3F 43 2C 2B 2B 2B 2B 2B 2B 28 2A 28 27'
+ '27 27 26 25 25 28 26 26 FF FF FF FF FF FF FF FF'
+ 'E1 C0 BF BF AA AA A9 A8 A6 A5 60 5C 5A 58 57 55'
+ '51 51 50 4E 4E 49 47 47 47 47 47 45 44 44 3F 44'
+ '44 43 2C 2C 2C 43 2C 2B 2C 2B 2B 2A 28 28 28 27'
+ '27 26 26 26 25 27 27 26 FF FF FF FF FF FF FF FF'
+ 'E2 C0 C0 BF AD AB AA A6 A6 A5 60 60 5B 58 58 57'
+ '51 51 51 4E 49 49 49 49 47 45 45 45 3F 45 43 2C'
+ '44 43 2C 44 2C 2C 2C 2C 2B 2B 2B 2A 2A 28 28 27'
+ '27 27 25 26 25 26 27 26 FF FF FF FF FF FF FF FF'
+ 'E2 C7 C0 BF AD AB AA A9 A8 A6 A5 5F 5B 5A 58 58'
+ '55 51 50 4E 4E 49 49 47 49 45 45 45 45 45 44 44'
+ '3F 43 2C 2C 2C 2C 2C 2B 2C 2B 2B 2B 28 28 28 27'
+ '26 27 26 25 24 26 27 26 FF FF FF FF FF FF FF FF'
+ 'C0 E1 C2 C0 C0 BE BE AC A9 A7 A5 5F 5E 5A 56 56'
+ '53 53 4F 4E 4A 4A 46 48 48 4B 46 44 3F 44 44 44'
+ '43 2C 43 2C 2C 2B 2C 2C 2B 2B 2A 28 28 27 27 27'
+ '26 26 25 25 24 26 2B 2B FF FF FF FF FF FF FF FF'
+ 'FF D1 42 3A 39 39 37 2F 2E 1D 1C 1B 13 11 10 0D'
+ '0C 0C 0D 15 10 10 0E 0B 0B 14 29 46 45 44 45 43'
+ '2C 43 2C 2C 2C 2C 2C 2B 2B 2A 2A 28 28 27 27 26'
+ '26 25 25 24 24 2B 46 FF FF FF FF FF FF FF FF FF'
+ 'FF DA 9F 8E 8E 8A 86 84 84 84 7C 7B 77 70 6D 6B'
+ '40 3D 3A 36 2F 2E 1F 1E 1A 12 0A 46 50 50 50 4E'
+ '4E 49 4B 49 49 49 45 45 43 2C 2C 2B 2A 28 28 27'
+ '27 25 26 25 28 2B FF FF FF FF FF FF FF FF FF FF'
+ 'FF D2 D7 A3 A1 A0 9F 9F 96 94 8B 8A 86 84 7B 78'
+ '76 6D 42 41 40 3D 3D 3A 39 36 38 3E 56 FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF E5 D8 D1 D0 D0 CA CA A4 A4 A1 A2 9F 95 94'
+ '94 88 87 85 79 78 71 6F 6C 6F 8D 3F 5B FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF BA C5 C5 C5 BD BD BD BC BC BB BB B7 B7'
+ 'B6 B4 B3 B3 9E 9E 9B 99 9A 9A 81 5C FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF C0 00 00 00 00 00 00 7F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F E0 00 00 00 00 00 00 7F E0 00'
+ '00 00 00 00 00 FF E0 00 00 01 FF FF FF FF F0 00'
+ '00 01 FF FF FF FF F8 00 00 03 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 20 00 00 00'
+ '00 00 00 42 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -6425,482 +5352,77 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 16 00 00 00 34 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 35 00 00 00 18 00 00 00 04 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 05 00 00 00 69 00 00 00 C5 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F1 00 00 00 B1 00 00 00 5C 00 00 00 0D 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00'
- '00 9B 00 00 00 FF 00 00 00 FF 21 21 21 FF 2C 2C'
- '2C FF 2B 2B 2B FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2E 2C 2D FF 2E 2C 2D FF 13 13'
- '13 FF 00 00 00 FF 00 00 00 F6 00 00 00 69 00 00'
- '00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 54 00 00'
- '00 FF 26 26 26 FF 90 90 90 FF CA CA CA FF CD CD'
- 'CD FF CB CB CB FF CE CE CE FF CD CD CD FF CC CC'
- 'CC FF CB CB CB FF C9 C9 C9 FF C7 C7 C7 FF C6 C6'
- 'C6 FF C5 C5 C5 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2'
- 'C2 FF C2 C2 C2 FF C3 C3 C3 FF C0 C0 C0 FF C1 C1'
- 'C1 FF BF BF BF FF BF BF BF FF BC BC BC FF BD BD'
- 'BD FF BA BA BA FF BB BB BB FF B5 B5 B5 FF B3 B4'
- 'B3 FF B8 B4 B6 FF AD AD AD FF AB AC AC FF AD A8'
- 'AB FF 63 63 63 FF 09 09 09 FF 00 00 00 EF 00 00'
- '00 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 03 00 00 00 AD 01 01'
- '01 FF 8A 8A 8A FF EB EB EB FF E8 E8 E8 FF E7 E7'
- 'E7 FF D5 D5 D5 FF 85 85 85 FF 88 88 88 FF 92 92'
- '92 FF 98 98 98 FF A2 A2 A2 FF AD AD AD FF BA BA'
- 'BA FF C0 C0 C0 FF C3 C3 C3 FF C6 C6 C6 FF CB CB'
- 'CB FF CA CA CA FF CA CA CA FF D6 D6 D6 FF CA CA'
- 'CA FF D3 D3 D3 FF CB CB CB FF D7 D7 D7 FF CC CC'
- 'CC FF D4 D4 D4 FF C7 C7 C7 FF C8 C9 C9 FF C6 C2'
- 'C4 FF 9D B3 A8 FF 20 A8 63 FF 1C A8 60 FF 90 AF'
- 'A0 FF BF BB BD FF 4F 4F 4F FF 00 00 00 FF 00 00'
- '00 81 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 15 00 00 00 F0 19 19'
- '19 FF C7 C7 C7 FF EC EC EC FF E2 E2 E2 FF E6 E6'
- 'E6 FF CB CB CB FF 3B 3B 3B FF 3F 3F 3F FF 56 56'
- '56 FF 72 72 72 FF 87 87 87 FF 92 92 92 FF 9D 9D'
- '9D FF A5 A5 A5 FF A8 A8 A8 FF AC AC AC FF B7 B7'
- 'B7 FF A9 A9 A9 FF 9C 9C 9C FF BD BD BD FF 99 99'
- '99 FF B7 B7 B7 FF A1 A1 A1 FF C3 C3 C3 FF A3 A3'
- 'A3 FF BD BD BD FF 98 98 98 FF C5 C4 C4 FF C7 BF'
- 'C3 FF 51 A7 7C FF 17 CE 71 FF 0A BF 61 FF 2F 99'
- '64 FF C3 BD C0 FF 84 83 84 FF 01 01 01 FF 00 00'
- '00 A3 00 00 00 0B 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 30 00 00 00 FA 29 29'
- '29 FF D1 D1 D1 FF EA EA EA FF E4 E4 E4 FF E7 E7'
- 'E7 FF CD CD CD FF 47 47 47 FF 5F 5F 5F FF 79 79'
- '79 FF 87 87 87 FF 8F 8F 8F FF 97 97 97 FF A0 A0'
- 'A0 FF A7 A7 A7 FF AA AA AA FF AE AE AE FF B9 B9'
- 'B9 FF A4 A4 A4 FF 90 90 90 FF B8 B8 B8 FF 8A 8A'
- '8A FF AF AF AF FF 94 94 94 FF BF BF BF FF 97 97'
- '97 FF B7 B7 B7 FF 88 88 88 FF C4 C3 C3 FF C6 C3'
- 'C5 FF 95 B2 A3 FF 91 D6 B4 FF 91 D8 B5 FF 83 AB'
- '97 FF C4 C1 C3 FF 8E 8E 8E FF 01 01 01 FF 00 00'
- '00 B7 00 00 00 13 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 34 00 00 00 F9 28 28'
- '28 FF D1 D1 D1 FF EC EC EC FF E6 E6 E6 FF E7 E7'
- 'E7 FF D1 D1 D1 FF 68 68 68 FF 74 74 74 FF 7E 7E'
- '7E FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
- 'A0 FF A7 A7 A7 FF AA AA AA FF AE AE AE FF BA BA'
- 'BA FF 9F 9F 9F FF 83 83 83 FF B3 B3 B3 FF 7C 7C'
- '7C FF A8 A8 A8 FF 87 87 87 FF BB BB BB FF 8A 8A'
- '8A FF B2 B2 B2 FF 79 79 79 FF C2 C2 C2 FF C4 C4'
- 'C4 FF C6 C3 C4 FF 99 AC A2 FF 96 AB A0 FF C2 BE'
- 'C0 FF C4 C4 C4 FF 8D 8D 8D FF 01 01 01 FF 00 00'
- '00 BA 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 28 28'
- '28 FF D1 D1 D1 FF EE EE EE FF E7 E7 E7 FF E8 E8'
- 'E8 FF D6 D6 D6 FF 70 70 70 FF 71 71 71 FF 7D 7D'
- '7D FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
- 'A0 FF A7 A7 A7 FF AA AA AA FF AE AE AE FF BB BB'
- 'BB FF 98 98 98 FF 73 73 73 FF AD AD AD FF 6A 6A'
- '6A FF A0 A0 A0 FF 78 78 78 FF B7 B7 B7 FF 7C 7C'
- '7C FF AB AB AB FF 67 67 67 FF C2 C2 C2 FF C6 C6'
- 'C6 FF C4 C3 C4 FF C7 C4 C5 FF C6 C2 C4 FF BF BF'
- 'BF FF C5 C5 C5 FF 8D 8D 8D FF 01 01 01 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 27 27'
- '27 FF D1 D1 D1 FF EF EF EF FF E9 E9 E9 FF EB EB'
- 'EB FF D6 D6 D6 FF 6A 6A 6A FF 6C 6C 6C FF 78 78'
- '78 FF 81 81 81 FF 8A 8A 8A FF 93 93 93 FF 9C 9C'
- '9C FF A3 A3 A3 FF A6 A6 A6 FF AB AB AB FF B9 B9'
- 'B9 FF 90 90 90 FF 66 66 66 FF A5 A5 A5 FF 5B 5B'
- '5B FF 98 98 98 FF 6B 6B 6B FF B1 B1 B1 FF 70 70'
- '70 FF A4 A4 A4 FF 58 58 58 FF C1 C1 C1 FF C8 C8'
- 'C8 FF C5 C5 C5 FF C3 C3 C3 FF C2 C2 C2 FF C1 C1'
- 'C1 FF C6 C6 C6 FF 8E 8E 8E FF 01 01 01 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 27 27'
- '27 FF D2 D2 D2 FF F2 F2 F2 FF EB EB EB FF EA EA'
- 'EA FF DF DF DF FF A7 A7 A7 FF A7 A7 A7 FF AB AB'
- 'AB FF AE AE AE FF B0 B0 B0 FF B3 B3 B3 FF B6 B6'
- 'B6 FF B9 B9 B9 FF B9 B9 B9 FF BA BA BA FF BD BD'
- 'BD FF B7 B7 B7 FF B1 B1 B1 FF BE BE BE FF AF AF'
- 'AF FF BA BA BA FF B1 B1 B1 FF BE BE BE FF B0 B0'
- 'B0 FF BA BA BA FF AB AB AB FF C5 C5 C5 FF C8 C8'
- 'C8 FF C6 C6 C6 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2'
- 'C2 FF C9 C9 C9 FF 8E 8E 8E FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 26 26'
- '26 FF D3 D3 D3 FF F3 F3 F3 FF EB EB EB FF EB EB'
- 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF E9 E9'
- 'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
- 'E2 FF E1 E1 E1 FF DF DF DF FF DE DE DE FF DB DB'
- 'DB FF DB DB DB FF DC DC DC FF D8 D8 D8 FF D9 D9'
- 'D9 FF D6 D6 D6 FF D6 D6 D6 FF D2 D2 D2 FF D2 D2'
- 'D2 FF CF CF CF FF D0 D0 D0 FF CB CB CB FF CA CA'
- 'CA FF C9 C9 C9 FF C7 C7 C7 FF C4 C4 C4 FF C0 C0'
- 'C0 FF CA CA CA FF 8E 8E 8E FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 26 26'
- '26 FF D3 D3 D3 FF F7 F7 F7 FF F8 F8 F8 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
- 'F1 FF F1 F1 F1 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF EF EF EF FF EF EF EF FF EE EE'
- 'EE FF EE EE EE FF ED ED ED FF ED ED ED FF ED ED'
- 'ED FF EC EC EC FF EC EC EC FF EB EB EB FF E0 E0'
- 'E0 FF D0 D0 D0 FF 8D 8D 8D FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 33 00 00 00 F9 24 24'
- '24 FF D6 D6 D6 FF FF FF FF FF E9 E9 E9 FF E1 E1'
- 'E1 FF E2 E2 E2 FF E2 E2 E2 FF E0 E0 E0 FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E2 E2'
- 'E2 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3 E3 FF F8 F8'
- 'F8 FF EF EF EF FF 8C 8C 8C FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 34 00 00 00 FA 24 24'
- '24 FF DE DE DE FF F8 F8 F8 FF D9 D9 D9 FF C4 C4'
- 'C4 FF BB BB BB FF BF BF BF FF D8 D8 D8 FF DA DA'
- 'DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF DB DB DB FF CF CF'
- 'CF FF BC BC BC FF BB BB BB FF D1 D1 D1 FF DE DE'
- 'DE FF FF FF FF FF 9A 9A 9A FF 00 00 00 FF 00 00'
- '00 BA 00 00 00 14 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 00 00 00 F7 1F 1F'
- '1F FF DA DA DA FF F3 F3 F3 FF C6 C6 C6 FF A9 A9'
- 'A9 FF B7 B7 B7 FF B0 B0 B0 FF C3 C3 C3 FF DA DA'
- 'DA FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D9 D9 D9 FF D2 D2 D2 FF A8 A8'
- 'A8 FF B6 B6 B6 FF B1 B1 B1 FF B5 B5 B5 FF D8 D8'
- 'D8 FF FC FC FC FF 9C 9C 9C FF 00 00 00 FF 00 00'
- '00 AE 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 07 00 00 00 D0 05 05'
- '05 FF C2 C2 C2 FF F6 F6 F6 FF BC BC BC FF B2 B2'
- 'B2 FF C3 C3 C3 FF AB AB AB FF BB BB BB FF D8 D8'
- 'D8 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
- 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D5 D5 D5 FF D7 D7'
- 'D7 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D5 D5'
- 'D5 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D4 D4'
- 'D4 FF D5 D5 D5 FF D7 D7 D7 FF C9 C9 C9 FF A6 A6'
- 'A6 FF C3 C3 C3 FF B3 B3 B3 FF AD AD AD FF D6 D6'
- 'D6 FF F5 F5 F5 FF 76 76 76 FF 00 00 00 FF 00 00'
- '00 8C 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 00 00'
- '00 FF A4 A4 A4 FF F4 F4 F4 FF CF CF CF FF C5 C5'
- 'C5 FF D2 D2 D2 FF BF BF BF FF C9 C9 C9 FF D3 D3'
- 'D3 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF DD DD'
- 'DD FF E1 E1 E1 FF E3 E3 E3 FF E6 E6 E6 FF EA EA'
- 'EA FF ED ED ED FF ED ED ED FF EB EB EB FF E7 E7'
- 'E7 FF E4 E4 E4 FF E2 E2 E2 FF DE DE DE FF D4 D4'
- 'D4 FF D0 D0 D0 FF D2 D2 D2 FF D3 D3 D3 FF C5 C5'
- 'C5 FF D0 D0 D0 FF C2 C2 C2 FF BF BF BF FF D9 D9'
- 'D9 FF E8 E8 E8 FF 56 56 56 FF 00 00 00 FF 00 00'
- '00 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 73 00 00'
- '00 FF 7E 7E 7E FF EF EF EF FF D1 D1 D1 FF CF CF'
- 'CF FF CB CB CB FF CF CF CF FF D1 D1 D1 FF CE CE'
- 'CE FF CF CF CF FF DF DF DF FF F0 F0 F0 FF EC EC'
- 'EC FF E1 E1 E1 FF DE DE DE FF DD DD DD FF DC DC'
- 'DC FF DB DB DB FF DB DB DB FF DC DC DC FF DD DD'
- 'DD FF DE DE DE FF E1 E1 E1 FF EC EC EC FF F1 F1'
- 'F1 FF E1 E1 E1 FF D1 D1 D1 FF CE CE CE FF D0 D0'
- 'D0 FF CB CB CB FF CE CE CE FF D1 D1 D1 FF D9 D9'
- 'D9 FF D4 D4 D4 FF 3F 3F 3F FF 00 00 00 FF 00 00'
- '00 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
- '00 FF 59 59 59 FF E9 E9 E9 FF D0 D0 D0 FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF CA CA CA FF D6 D6'
- 'D6 FF ED ED ED FF E6 E6 E6 FF DC DC DC FF D4 D4'
- 'D4 FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D5 D5 D5 FF D5 D5 D5 FF DB DB'
- 'DB FF E4 E4 E4 FF ED ED ED FF DA DA DA FF CA CA'
- 'CA FF CD CD CD FF CD CD CD FF CB CB CB FF DF DF'
- 'DF FF B8 B8 B8 FF 22 22 22 FF 00 00 00 FB 00 00'
- '00 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
- '00 FE 40 40 40 FF D7 D7 D7 FF D2 D2 D2 FF CA CA'
- 'CA FF CB CB CB FF CA CA CA FF D4 D4 D4 FF E9 E9'
- 'E9 FF DC DC DC FF D0 D0 D0 FF D1 D1 D1 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D1 D1'
- 'D1 FF D0 D0 D0 FF D8 D8 D8 FF EA EA EA FF D8 D8'
- 'D8 FF C9 C9 C9 FF CA CA CA FF C9 C9 C9 FF E0 E0'
- 'E0 FF A0 A0 A0 FF 08 08 08 FF 00 00 00 EB 00 00'
- '00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 25 00 00'
- '00 F8 22 22 22 FF B7 B7 B7 FF DB DB DB FF CA CA'
- 'CA FF CB CB CB FF CE CE CE FF E4 E4 E4 FF D4 D4'
- 'D4 FF CF CF CF FF D1 D1 D1 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CD CD'
- 'CD FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CC CC CC FF D0 D0 D0 FF E2 E2'
- 'E2 FF CF CF CF FF C7 C7 C7 FF C9 C9 C9 FF E2 E2'
- 'E2 FF 80 80 80 FF 00 00 00 FF 00 00 00 C2 00 00'
- '00 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 E1 07 07 07 FF 9F 9F 9F FF DD DD DD FF CC CC'
- 'CC FF CD CD CD FF DB DB DB FF D6 D6 D6 FF CE CE'
- 'CE FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CC CC'
- 'CC FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF C8 C8 C8 FF CF CF'
- 'CF FF DA DA DA FF C7 C7 C7 FF C9 C9 C9 FF E2 E2'
- 'E2 FF 5A 5A 5A FF 00 00 00 FF 00 00 00 94 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 B2 00 00 00 FF 83 83 83 FF DD DD DD FF CF CF'
- 'CF FF D1 D1 D1 FF DB DB DB FF D1 D1 D1 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
- 'CF FF C9 C9 C9 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C7 C7'
- 'C7 FF D3 D3 D3 FF C8 C8 C8 FF C9 C9 C9 FF DE DE'
- 'DE FF 42 42 42 FF 00 00 00 FF 00 00 00 6C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 5F 5F 5F FF DC DC DC FF D1 D1'
- 'D1 FF D2 D2 D2 FF D4 D4 D4 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D0 D0 D0 FF C8 C8 C8 FF C3 C3 C3 FF C3 C3'
- 'C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C7 C7 C7 FF C5 C5 C5 FF CB CB CB FF CC CC'
- 'CC FF 2D 2D 2D FF 00 00 00 F8 00 00 00 40 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4B 00 00 00 FE 41 41 41 FF D8 D8 D8 FF D4 D4'
- 'D4 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CD CD CD FF C7 C7'
- 'C7 FF C4 C4 C4 FF C2 C2 C2 FF C1 C1 C1 FF C0 C0'
- 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2'
- 'C2 FF BF BF BF FF C0 C0 C0 FF CE CE CE FF B2 B2'
- 'B2 FF 1A 1A 1A FF 00 00 00 E5 00 00 00 28 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1A 00 00 00 F2 2C 2C 2C FF CC CC CC FF D6 D6'
- 'D6 FF D5 D5 D5 FF CC CC CC FF D5 D5 D5 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D7 D7 D7 FF D6 D6'
- 'D6 FF D5 D5 D5 FF D3 D3 D3 FF CF CF CF FF CC CC'
- 'CC FF C9 C9 C9 FF C6 C6 C6 FF C4 C4 C4 FF C2 C2'
- 'C2 FF B3 B3 B3 FF BD BD BD FF D0 D0 D0 FF 99 99'
- '99 FF 09 09 09 FF 00 00 00 CF 00 00 00 19 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 09 00 00 00 D8 18 18 18 FF B0 B0 B0 FF DB DB'
- 'DB FF DB DB DB FF D0 D0 D0 FF D2 D2 D2 FF DB DB'
- 'DB FF D9 D9 D9 FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DB DB DB FF DB DB'
- 'DB FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF CF CF'
- 'CF FF C5 C5 C5 FF CC CC CC FF CA CA CA FF 7A 7A'
- '7A FF 02 02 02 FF 00 00 00 B8 00 00 00 0A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 BF 08 08 08 FF 97 97 97 FF DC DC'
- 'DC FF DF DF DF FF DC DC DC FF CE CE CE FF D6 D6'
- 'D6 FF DE DE DE FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DE DE DE FF D8 D8 D8 FF CE CE'
- 'CE FF DD DD DD FF DC DC DC FF C6 C6 C6 FF 53 53'
- '53 FF 00 00 00 FF 00 00 00 A0 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 A4 00 00 00 FF 77 77 77 FF D3 D3'
- 'D3 FF E2 E2 E2 FF E1 E1 E1 FF DE DE DE FF CE CE'
- 'CE FF D7 D7 D7 FF E1 E1 E1 FF E2 E2 E2 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
- 'E1 FF E1 E1 E1 FF D9 D9 D9 FF CD CD CD FF DA DA'
- 'DA FF E3 E3 E3 FF D9 D9 D9 FF BB BB BB FF 39 39'
- '39 FF 00 00 00 FF 00 00 00 7E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 89 00 00 00 FF 4B 4B 4B FF C9 C9'
- 'C9 FF E5 E5 E5 FF E3 E3 E3 FF E4 E4 E4 FF E1 E1'
- 'E1 FF D7 D7 D7 FF D2 D2 D2 FF DA DA DA FF E4 E4'
- 'E4 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF DC DC'
- 'DC FF D2 D2 D2 FF D6 D6 D6 FF E0 E0 E0 FF E4 E4'
- 'E4 FF E6 E6 E6 FF D6 D6 D6 FF A8 A8 A8 FF 20 20'
- '20 FF 00 00 00 FD 00 00 00 4E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 62 00 00 00 FF 35 35 35 FF BD BD'
- 'BD FF E6 E6 E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7'
- 'E7 FF E7 E7 E7 FF DF DF DF FF D2 D2 D2 FF D3 D3'
- 'D3 FF DE DE DE FF E3 E3 E3 FF E3 E3 E3 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3'
- 'E3 FF E3 E3 E3 FF DE DE DE FF D4 D4 D4 FF D1 D1'
- 'D1 FF DD DD DD FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
- 'E6 FF E8 E8 E8 FF D4 D4 D4 FF 9A 9A 9A FF 0B 0B'
- '0B FF 00 00 00 ED 00 00 00 2C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2D 00 00 00 F9 1E 1E 1E FF AB AB'
- 'AB FF E4 E4 E4 FF ED ED ED FF E7 E7 E7 FF E6 E6'
- 'E6 FF EC EC EC FF EB EB EB FF EA EA EA FF E4 E4'
- 'E4 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DD DD'
- 'DD FF DC DC DC FF DC DC DC FF DD DD DD FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E2 E2 E2 FF E9 E9'
- 'E9 FF EC EC EC FF EA EA EA FF E5 E5 E5 FF EB EB'
- 'EB FF EB EB EB FF D6 D6 D6 FF 8A 8A 8A FF 00 00'
- '00 FF 00 00 00 C3 00 00 00 17 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 09 00 00 00 DD 08 08 08 FF 99 99'
- '99 FF E4 E4 E4 FF DF DF DF FF BD BD BD FF C1 C1'
- 'C1 FF D6 D6 D6 FF EC EC EC FF ED ED ED FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EC EC'
- 'EC FF EB EB EB FF EB EB EB FF EC EC EC FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EE EE'
- 'EE FF E4 E4 E4 FF C2 C2 C2 FF BE BE BE FF D1 D1'
- 'D1 FF EC EC EC FF D4 D4 D4 FF 75 75 75 FF 00 00'
- '00 FF 00 00 00 9C 00 00 00 06 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 AE 00 00 00 FF 8D 8D'
- '8D FF E0 E0 E0 FF C4 C4 C4 FF B2 B2 B2 FF B8 B8'
- 'B8 FF B2 B2 B2 FF EB EB EB FF F1 F1 F1 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3'
- 'F3 FF D5 D5 D5 FF B0 B0 B0 FF B6 B6 B6 FF B7 B7'
- 'B7 FF EB EB EB FF CD CD CD FF 61 61 61 FF 00 00'
- '00 FF 00 00 00 85 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 64 64'
- '64 FF CE CE CE FF DD DD DD FF DC DC DC FF D5 D5'
- 'D5 FF E4 E4 E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
- 'FA FF F2 F2 F2 FF DF DF DF FF D8 D8 D8 FF DC DC'
- 'DC FF D7 D7 D7 FF B0 B0 B0 FF 34 34 34 FF 00 00'
- '00 FF 00 00 00 67 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 44 00 00 00 FF 19 19'
- '19 FF 80 80 80 FF BE BE BE FF D3 D3 D3 FF D7 D7'
- 'D7 FF DB DB DB FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D9 D9 D9 FF D9 D9 D9 FF D7 D7 D7 FF CD CD'
- 'CD FF B0 B0 B0 FF 5D 5D 5D FF 06 06 06 FF 00 00'
- '00 ED 00 00 00 2B 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 9C 00 00'
- '00 FF 0C 0C 0C FF 3D 3D 3D FF 49 49 49 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 49 49 49 FF 49 49'
- '49 FF 2F 2F 2F FF 02 02 02 FF 00 00 00 FF 00 00'
- '00 5C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00'
- '00 7F 00 00 00 F1 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 D6 00 00 00 5C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2C 00 00 00 7E 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 70 00 00 00 1A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -6951,32 +5473,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF 00 00 00 00 7F 00 00 FC 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -7003,229 +5499,620 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 15 00 00 00 54 00 00 00 63 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 63 00 00 00 50 00 00 00 14 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 33 00 00'
- '00 D7 0D 0D 0D FF 1B 1B 1B FF 1C 1C 1C FF 1E 1E'
- '1E FF 1D 1D 1D FF 1D 1D 1D FF 1C 1C 1C FF 1B 1B'
- '1B FF 1B 1B 1B FF 1B 1B 1B FF 1A 1A 1A FF 1A 1A'
- '1A FF 1A 1A 1A FF 1A 1A 1A FF 1A 1A 1A FF 1A 1A'
- '1A FF 1A 1A 1A FF 1A 1A 1A FF 1A 1A 1A FF 20 1C'
- '1E FF 22 1B 1F FF 09 09 09 FF 00 00 00 C3 00 00'
- '00 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 07 00 00 00 C9 40 40'
- '40 FF BA BA BA FF CB CB CB FF BE BE BE FF B3 B3'
- 'B3 FF B4 B4 B4 FF B4 B4 B4 FF B7 B7 B7 FF BB BB'
- 'BB FF BB BB BB FF BB BB BB FF BC BC BC FF BE BE'
- 'BE FF BD BD BD FF BC BC BC FF BB BB BB FF BA BA'
- 'BA FF BA BA BA FF B4 B4 B4 FF B1 AE AF FF 8C A4'
- '98 FF 80 A5 93 FF 90 91 91 FF 21 21 21 FF 00 00'
- '00 AB 00 00 00 07 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 3D 08 08 08 FD B7 B7'
- 'B7 FF F2 F2 F2 FF EE EE EE FF AF AF AF FF 51 51'
- '51 FF 6E 6E 6E FF 89 89 89 FF 9A 9A 9A FF AB AB'
- 'AB FF B3 B3 B3 FF BC BC BC FF B5 B5 B5 FF B5 B5'
- 'B5 FF BC BC BC FF BD BD BD FF BE BE BE FF B7 B7'
- 'B7 FF C0 C0 C0 FF C4 C1 C3 FF B7 BF BA FF 2A BF'
- '75 FF 0E C0 67 FF 8C B8 A2 FF 80 79 7C FF 00 00'
- '00 EC 00 00 00 25 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 58 19 19 19 FF CE CE'
- 'CE FF EB EB EB FF EB EB EB FF AA AA AA FF 56 56'
- '56 FF 7A 7A 7A FF 8C 8C 8C FF 96 96 96 FF A2 A2'
- 'A2 FF A9 A9 A9 FF B4 B4 B4 FF A1 A1 A1 FF 97 97'
- '97 FF A1 A1 A1 FF A5 A5 A5 FF A5 A5 A5 FF 9B 9B'
- '9B FF A7 A7 A7 FF B3 B1 B2 FF BC C1 BE FF 87 C6'
- 'A6 FF 85 CC A8 FF A6 BC B1 FF 94 90 92 FF 02 02'
- '02 F9 00 00 00 36 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 5A 18 18 18 FF CC CC'
- 'CC FF ED ED ED FF EC EC EC FF B9 B9 B9 FF 6D 6D'
- '6D FF 7D 7D 7D FF 8B 8B 8B FF 96 96 96 FF A2 A2'
- 'A2 FF A9 A9 A9 FF B6 B6 B6 FF 96 96 96 FF 82 82'
- '82 FF 8E 8E 8E FF 93 93 93 FF 94 94 94 FF 86 86'
- '86 FF 95 95 95 FF A6 A6 A6 FF C8 C8 C8 FF C2 C0'
- 'C1 FF BF BD BE FF C9 C6 C7 FF 8E 8E 8E FF 01 01'
- '01 FA 00 00 00 37 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 5A 17 17 17 FF CD CD'
- 'CD FF F0 F0 F0 FF ED ED ED FF BF BF BF FF 77 77'
- '77 FF 85 85 85 FF 91 91 91 FF 9A 9A 9A FF A4 A4'
- 'A4 FF AA AA AA FF B5 B5 B5 FF 97 97 97 FF 83 83'
- '83 FF 8D 8D 8D FF 92 92 92 FF 93 93 93 FF 86 86'
- '86 FF 93 93 93 FF A7 A7 A7 FF CA CA CA FF C4 C3'
- 'C4 FF C3 C2 C2 FF C8 C8 C8 FF 8E 8E 8E FF 00 00'
- '00 FA 00 00 00 37 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 5A 17 17 17 FF CE CE'
- 'CE FF F2 F2 F2 FF EC EC EC FF E6 E6 E6 FF DC DC'
- 'DC FF DB DB DB FF DA DA DA FF DA DA DA FF D9 D9'
- 'D9 FF D8 D8 D8 FF D7 D7 D7 FF D4 D4 D4 FF D4 D4'
- 'D4 FF D2 D2 D2 FF D0 D0 D0 FF CF CF CF FF CC CC'
- 'CC FF CB CB CB FF CB CB CB FF CC CC CC FF CA CA'
- 'CA FF C7 C7 C7 FF C9 C9 C9 FF 8D 8D 8D FF 00 00'
- '00 FA 00 00 00 37 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 5A 17 17 17 FF D0 D0'
- 'D0 FF FF FF FF FF F8 F8 F8 FF F8 F8 F8 FF F9 F9'
- 'F9 FF F8 F8 F8 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1 F1 FF F2 F2'
- 'F2 FF F3 F3 F3 FF E8 E8 E8 FF 8D 8D 8D FF 00 00'
- '00 FA 00 00 00 37 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 5B 17 17 17 FF D7 D7'
- 'D7 FF F4 F4 F4 FF DB DB DB FF D8 D8 D8 FF DD DD'
- 'DD FF DF DF DF FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DE DE DE FF DF DF'
- 'DF FF DF DF DF FF E0 E0 E0 FF DD DD DD FF D8 D8'
- 'D8 FF E0 E0 E0 FF FB FB FB FF 9C 9C 9C FF 00 00'
- '00 FA 00 00 00 38 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 51 11 11 11 FF D3 D3'
- 'D3 FF D9 D9 D9 FF AD AD AD FF B0 B0 B0 FF BE BE'
- 'BE FF D9 D9 D9 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D9 D9 D9 FF D3 D3 D3 FF AF AF AF FF B1 B1'
- 'B1 FF B8 B8 B8 FF ED ED ED FF A0 A0 A0 FF 00 00'
- '00 F7 00 00 00 2E 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2B 00 00 00 F8 B3 B3'
- 'B3 FF DC DC DC FF B9 B9 B9 FF BA BA BA FF BC BC'
- 'BC FF D5 D5 D5 FF D3 D3 D3 FF D4 D4 D4 FF D8 D8'
- 'D8 FF DF DF DF FF E3 E3 E3 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E3 E3 E3 FF DF DF DF FF D9 D9 D9 FF D4 D4'
- 'D4 FF D3 D3 D3 FF CF CF CF FF BA BA BA FF B8 B8'
- 'B8 FF B8 B8 B8 FF E9 E9 E9 FF 7C 7C 7C FF 00 00'
- '00 DE 00 00 00 17 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0C 00 00 00 E2 89 89'
- '89 FF E5 E5 E5 FF CE CE CE FF D0 D0 D0 FF D0 D0'
- 'D0 FF D1 D1 D1 FF DE DE DE FF E5 E5 E5 FF E5 E5'
- 'E5 FF E2 E2 E2 FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF E2 E2 E2 FF E6 E6 E6 FF E5 E5'
- 'E5 FF DF DF DF FF D2 D2 D2 FF CF CF CF FF CF CF'
- 'CF FF D0 D0 D0 FF E6 E6 E6 FF 54 54 54 FF 00 00'
- '00 BC 00 00 00 07 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 BB 64 64'
- '64 FF E2 E2 E2 FF CB CB CB FF CB CB CB FF CE CE'
- 'CE FF E2 E2 E2 FF E0 E0 E0 FF D7 D7 D7 FF D3 D3'
- 'D3 FF D4 D4 D4 FF D4 D4 D4 FF D4 D4 D4 FF D4 D4'
- 'D4 FF D4 D4 D4 FF D4 D4 D4 FF D3 D3 D3 FF D7 D7'
- 'D7 FF DF DF DF FF E4 E4 E4 FF D1 D1 D1 FF CB CB'
- 'CB FF CF CF CF FF D7 D7 D7 FF 34 34 34 FF 00 00'
- '00 99 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 93 3E 3E'
- '3E FF DB DB DB FF CC CC CC FF CC CC CC FF DC DC'
- 'DC FF D7 D7 D7 FF CF CF CF FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF CD CD CD FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CC CC CC FF D3 D3 D3 FF DC DC DC FF C9 C9'
- 'C9 FF CF CF CF FF C2 C2 C2 FF 1A 1A 1A FF 00 00'
- '00 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 6B 21 21'
- '21 FF C9 C9 C9 FF D2 D2 D2 FF D3 D3 D3 FF D7 D7'
- 'D7 FF CF CF CF FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF CA CA CA FF C7 C7'
- 'C7 FF C8 C8 C8 FF C8 C8 C8 FF C8 C8 C8 FF C8 C8'
- 'C8 FF C8 C8 C8 FF C7 C7 C7 FF CF CF CF FF CC CC'
- 'CC FF D0 D0 D0 FF A9 A9 A9 FF 04 04 04 FF 00 00'
- '00 4D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 44 0B 0B'
- '0B FF B1 B1 B1 FF D8 D8 D8 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D2 D2 D2 FF D1 D1 D1 FF C9 C9'
- 'C9 FF C4 C4 C4 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C5 C5 C5 FF C5 C5'
- 'C5 FF D2 D2 D2 FF 86 86 86 FF 00 00 00 F3 00 00'
- '00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00'
- '00 F4 93 93 93 FF DF DF DF FF D2 D2 D2 FF D2 D2'
- 'D2 FF D5 D5 D5 FF D4 D4 D4 FF D4 D4 D4 FF D4 D4'
- 'D4 FF D4 D4 D4 FF D4 D4 D4 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D2 D2 D2 FF CD CD CD FF C7 C7 C7 FF C3 C3'
- 'C3 FF C2 C2 C2 FF C2 C2 C2 FF BE BE BE FF BC BC'
- 'BC FF D0 D0 D0 FF 67 67 67 FF 00 00 00 D9 00 00'
- '00 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0B 00 00'
- '00 DE 75 75 75 FF DE DE DE FF D7 D7 D7 FF D1 D1'
- 'D1 FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF DA DA DA FF DA DA DA FF DA DA DA FF D8 D8'
- 'D8 FF D6 D6 D6 FF D5 D5 D5 FF C7 C7 C7 FF C5 C5'
- 'C5 FF CD CD CD FF 4B 4B 4B FF 00 00 00 BD 00 00'
- '00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 B7 53 53 53 FF D9 D9 D9 FF E1 E1 E1 FF D5 D5'
- 'D5 FF D5 D5 D5 FF DF DF DF FF DF DF DF FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF DE DE DE FF DF DF'
- 'DF FF E0 E0 E0 FF D7 D7 D7 FF D6 D6 D6 FF DE DE'
- 'DE FF C3 C3 C3 FF 2C 2C 2C FF 00 00 00 9A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 90 31 31 31 FF CB CB CB FF E5 E5 E5 FF E4 E4'
- 'E4 FF DA DA DA FF D7 D7 D7 FF DD DD DD FF E2 E2'
- 'E2 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E2 E2 E2 FF DE DE'
- 'DE FF D7 D7 D7 FF D9 D9 D9 FF E4 E4 E4 FF DF DF'
- 'DF FF AB AB AB FF 17 17 17 FF 00 00 00 73 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 67 1A 1A 1A FF B3 B3 B3 FF E8 E8 E8 FF EA EA'
- 'EA FF EA EA EA FF E5 E5 E5 FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF DD DD DD FF DC DC DC FF DD DD'
- 'DD FF E5 E5 E5 FF E9 E9 E9 FF EC EC EC FF DF DF'
- 'DF FF 95 95 95 FF 04 04 04 FF 00 00 00 4D 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 41 07 07 07 FE 9F 9F 9F FF E8 E8 E8 FF CD CD'
- 'CD FF CB CB CB FF E7 E7 E7 FF EF EF EF FF ED ED'
- 'ED FF EA EA EA FF E9 E9 E9 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E8 E8 E8 FF EA EA EA FF EC EC EC FF F0 F0'
- 'F0 FF DB DB DB FF C6 C6 C6 FF DC DC DC FF E1 E1'
- 'E1 FF 78 78 78 FF 00 00 00 F4 00 00 00 29 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1E 00 00 00 F4 83 83 83 FF E0 E0 E0 FF C9 C9'
- 'C9 FF C6 C6 C6 FF EA EA EA FF FA FA FA FF F8 F8'
- 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8'
- 'F8 FF F8 F8 F8 FF F8 F8 F8 FF F8 F8 F8 FF FB FB'
- 'FB FF D9 D9 D9 FF C4 C4 C4 FF D1 D1 D1 FF D2 D2'
- 'D2 FF 50 50 50 FF 00 00 00 DA 00 00 00 15 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 BB 24 24 24 FF 98 98 98 FF CF CF'
- 'CF FF D2 D2 D2 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D2 D2 D2 FF C8 C8 C8 FF 7C 7C'
- '7C FF 0D 0D 0D FF 00 00 00 9A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 31 00 00 00 DF 0F 0F 0F FF 29 29'
- '29 FF 29 29 29 FF 28 28 28 FF 28 28 28 FF 28 28'
- '28 FF 28 28 28 FF 28 28 28 FF 28 28 28 FF 28 28'
- '28 FF 28 28 28 FF 28 28 28 FF 28 28 28 FF 28 28'
- '28 FF 28 28 28 FF 2A 2A 2A FF 26 26 26 FF 08 08'
- '08 FF 00 00 00 C8 00 00 00 1D 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 14 00 00 00 62 00 00'
- '00 87 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 86 00 00'
- '00 55 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 16 00 00 00 39 00 00 00 44 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 45 00 00 00 45 00 00'
+ '00 45 00 00 00 45 00 00 00 3A 00 00 00 17 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DC DC'
+ 'DC 16 DF DF DF AC BE BE BE C3 B9 B9 B9 C9 B7 B7'
+ 'B7 C9 B6 B6 B6 C9 B5 B5 B5 C9 B4 B4 B4 C9 B1 B1'
+ 'B1 C9 B0 B0 B0 C9 AF AF AF C9 AF AF AF C9 AD AD'
+ 'AD C9 AC AC AC C9 AA AA AA C9 A8 A8 A8 C9 A7 A7'
+ 'A7 C9 A7 A7 A7 C9 A8 A8 A8 C9 A6 A6 A6 C9 A6 A6'
+ 'A6 C9 A2 A2 A2 C9 A1 A1 A1 C9 A1 A1 A1 C9 9F 9F'
+ '9F C9 9F 9F 9F C9 9E 9E 9E C9 9E 9E 9E C9 9D 9D'
+ '9D C9 9A 9A 9A C9 9A 9A 9A C9 99 99 99 C9 99 99'
+ '99 C9 98 98 98 C9 96 96 96 C9 94 94 94 C9 93 93'
+ '93 C9 91 91 91 C9 90 90 90 C9 8C 8C 8C C9 8C 8C'
+ '8C C9 8B 8B 8B C9 8A 8A 8A C9 8A 8A 8A C9 86 86'
+ '86 C9 86 86 86 C9 86 86 86 C9 89 89 89 C9 87 87'
+ '87 C9 85 85 85 C9 83 83 83 C9 85 85 85 C9 83 83'
+ '83 C9 8E 8E 8E C9 36 36 36 76 00 00 00 29 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 F0'
+ 'F0 22 E5 E5 E5 FE C5 C5 C5 FF C4 C4 C4 FF C1 C2'
+ 'C2 FF C0 C0 C0 FF BB BC BD FF B9 BA BB FF B6 B7'
+ 'B8 FF B5 B6 B6 FF B4 B5 B5 FF B3 B4 B5 FF B2 B3'
+ 'B4 FF B1 B2 B3 FF B0 B0 B1 FF AF B0 B1 FF AC AD'
+ 'AE FF AB AC AD FF AA AB AB FF A8 A9 AA FF A7 A8'
+ 'A9 FF A6 A7 A8 FF A4 A5 A6 FF A4 A4 A5 FF A1 A2'
+ 'A3 FF 9F A0 A0 FF 9E 9F 9F FF A0 A0 A0 FF 9F 9F'
+ 'A0 FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C 9C FF 9B 9B'
+ '9B FF 9A 9A 9A FF 98 98 98 FF 96 96 96 FF 95 95'
+ '95 FF 93 93 93 FF 91 91 92 FF 90 90 90 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8C 8C 8C FF 8C 8C 8C FF 89 89'
+ '89 FF 89 89 89 FF 88 88 88 FF 89 89 89 FF 88 88'
+ '88 FF 87 87 87 FF 87 87 87 FF 86 86 86 FF 86 86'
+ '86 FF 99 99 99 FF 45 45 45 88 00 00 00 2D 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ 'DF 28 DD DD DD FF B7 B7 B7 FF B4 B4 B4 FF B6 B6'
+ 'B6 FF CB C9 C8 FF DC D7 D3 FF DD D9 D5 FF DD D9'
+ 'D5 FF DC D8 D4 FF DC D8 D4 FF DC D7 D3 FF DB D7'
+ 'D3 FF DB D7 D3 FF DB D6 D3 FF DB D6 D3 FF DA D5'
+ 'D2 FF D9 D5 D1 FF D9 D5 D1 FF D8 D4 D0 FF D8 D3'
+ 'CF FF D8 D3 CF FF D7 D2 CF FF D7 D2 CE FF D6 D2'
+ 'CE FF D5 D1 CD FF D5 D1 CD FF D6 D2 CE FF D6 D1'
+ 'CD FF D6 D1 CD FF D5 D0 CD FF D5 D0 CC FF D4 D0'
+ 'CC FF D4 D0 CC FF D4 CF CB FF D3 CF CB FF D3 CE'
+ 'CA FF D2 CD C9 FF D1 CD C9 FF D1 CC C8 FF D0 CC'
+ 'C8 FF C8 C3 BF FF A3 A3 A2 FF 85 85 85 FF 82 82'
+ '82 FF 81 81 81 FF 7E 7E 7E FF 80 80 80 FF 7F 7F'
+ '7F FF 7E 7E 7E FF 7D 7D 7D FF 7D 7D 7D FF 7C 7C'
+ '7C FF 90 90 90 FF 43 43 43 8B 00 00 00 2E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D6 D6'
+ 'D6 32 DA DA DA FF B6 B6 B6 FF B8 B8 B8 FF E2 E2'
+ 'E2 FF FD FD FD FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FE FE FE FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FE FE'
+ 'FE FF FF FF FF FF F9 F9 F9 FF BC BC BC FF 83 83'
+ '83 FF 81 81 81 FF 7F 7F 7F FF 80 80 80 FF 7D 7D'
+ '7D FF 7E 7E 7E FF 7D 7D 7D FF 7C 7C 7C FF 7B 7B'
+ '7B FF 8F 8F 8F FF 44 44 44 8D 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD CD'
+ 'CD 3E D6 D6 D6 FF B5 B5 B5 FF D4 D2 D0 FF F9 F3'
+ 'ED FF D4 BE B8 FF C0 A2 8B FF C8 AA 91 FF CC B1'
+ '98 FF CC B1 98 FF CD B2 9A FF D8 C3 AF FF EC E0'
+ 'D4 FF FA F4 EF FF FB F5 EF FF FB F4 EF FF FA F3'
+ 'ED FF F9 F1 EB FF F7 EF E8 FF F6 EE E7 FF F6 EE'
+ 'E6 FF F6 EE E6 FF F6 EE E6 FF F6 EE E6 FF F6 EE'
+ 'E6 FF F6 EE E6 FF F6 EE E6 FF F6 ED E6 FF F6 ED'
+ 'E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED'
+ 'E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED E6 FF F6 EE'
+ 'E6 FF F7 EF E8 FF F9 F2 EB FF FA F3 EE FF FA F4'
+ 'EE FF F4 EB E3 FF F3 EA E1 FF F8 F4 ED FF 9F 9D'
+ '9C FF 81 81 81 FF 80 80 80 FF 7E 7E 7E FF 7F 7F'
+ '7F FF 7E 7E 7E FF 7D 7D 7D FF 7D 7D 7D FF 7C 7C'
+ '7C FF 8E 8E 8E FF 43 43 43 8F 00 00 00 31 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C7 C7'
+ 'C7 4A D3 D3 D3 FF BA BA BA FF F2 F2 F2 FF FF FF'
+ 'FF FF FF FF FF FF FE FE FE FF FB FA F9 FF F8 F5'
+ 'F2 FF F7 F4 F1 FF F7 F4 F1 FF F4 EF EC FF DF D2'
+ 'C6 FF CB B5 A0 FF C6 AD 97 FF C6 AE 97 FF CB B4'
+ 'A0 FF CF BB A9 FF D0 BC AA FF CC B4 A0 FF C8 AF'
+ '99 FF C8 AF 9A FF C9 B1 9B FF D1 BD AB FF DE CF'
+ 'C2 FF E8 DE D6 FF EF E9 E3 FF F5 F1 EE FF F8 F4'
+ 'F1 FF F4 F1 ED FF F2 EC E7 FF EB E2 DA FF E0 D3'
+ 'C7 FF D3 BF AD FF C9 B0 9A FF C7 AE 97 FF C8 AF'
+ '99 FF CF BA A7 FF D0 BC A9 FF CA B3 9E FF CB B4'
+ '9F FF D8 C7 B8 FF F9 F8 F6 FF FE FE FE FF D5 D5'
+ 'D5 FF 82 82 82 FF 81 81 81 FF 80 80 80 FF 80 80'
+ '80 FF 7F 7F 7F FF 7E 7E 7E FF 7C 7C 7C FF 7B 7B'
+ '7B FF 8C 8C 8C FF 42 42 42 91 00 00 00 32 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 C6'
+ 'C6 55 D0 D0 D0 FF C4 C3 C2 FF F8 F3 EF FF F7 EF'
+ 'E9 FF F9 F1 EB FF B4 98 88 FF FA F3 ED FF F8 EF'
+ 'E9 FF F6 EE E7 FF F5 EC E5 FF F6 EE E9 FF F7 F1'
+ 'EC FF FA F4 EF FF FC F6 F2 FF FD F7 F3 FF FB F6'
+ 'F1 FF F9 F4 EF FF FF FB F8 FF E5 D8 CC FF E6 DB'
+ 'D2 FF FB F9 F5 FF FD F8 F4 FF F4 EC E5 FF EA DE'
+ 'D3 FF E0 D0 C2 FF DA CA B9 FF D5 C1 AF FF D4 C0'
+ 'AE FF D5 C2 B0 FF D9 C7 B7 FF DF CF C1 FF E7 D9'
+ 'CD FF F2 E8 E0 FF FC F7 F2 FF FE FA F6 FF FE F9'
+ 'F6 FF FE F8 F4 FF FC F7 F2 FF FB F5 F0 FF FB F5'
+ 'EF FF F9 F2 ED FF F8 F0 E9 FF F8 F0 E9 FF ED E9'
+ 'E4 FF 8B 8B 8B FF 81 81 81 FF 7F 7F 7F FF 7F 7F'
+ '7F FF 7F 7F 7F FF 7E 7E 7E FF 7C 7C 7C FF 7C 7C'
+ '7C FF 8B 8B 8B FF 43 43 43 94 00 00 00 33 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C2 C2'
+ 'C2 61 CC CC CC FF CA C9 C8 FF FB F8 F5 FF F9 F5'
+ 'F0 FF FB F7 F3 FF DC CB BD FF C1 A5 99 FF EF E7'
+ 'E1 FF C5 AB 95 FF 83 50 32 FF B1 8C 74 FF 83 49'
+ '25 FF 9E 79 68 FF C9 AF 9C FF BC 9C 83 FF BB 9B'
+ '81 FF BC 9C 84 FF E0 D1 C7 FF FD FD FC FF DD CE'
+ 'C0 FF C3 A6 8C FF E2 D4 C7 FF FB F8 F5 FF FA F6'
+ 'F3 FF CB B7 AE FF E3 D7 CF FF C4 A8 91 FF F2 EB'
+ 'E7 FF D7 C4 B9 FF C2 A5 99 FF DA C9 C1 FF C1 A4'
+ '94 FF C4 A7 8E FF AD 89 81 FF D7 C5 B5 FF F2 EB'
+ 'E7 FF FB F8 F5 FF FA F6 F2 FF F9 F4 F0 FF F9 F4'
+ 'F0 FF F9 F4 F0 FF F9 F4 F0 FF F9 F5 F0 FF F2 EF'
+ 'ED FF 95 95 94 FF 82 82 82 FF 80 80 80 FF 80 80'
+ '80 FF 7E 7E 7E FF 7D 7D 7D FF 7C 7C 7C FF 7B 7B'
+ '7B FF 8B 8B 8B FF 49 49 49 96 00 00 00 34 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 BF BF'
+ 'BF 6D CB CB CB FF CC CC CB FF FD FB F9 FF FC F9'
+ 'F7 FF FC FA F8 FF F8 F5 F4 FF 78 3C 25 FF BA 99'
+ '7F FF E8 DF D6 FF D4 C0 AE FF A7 7E 5E FF D9 C8'
+ 'BA FF C0 A9 9F FF A8 82 6A FF D3 BF B1 FF A9 82'
+ '67 FF D5 C2 B0 FF CD B6 A1 FF D9 C8 B8 FF F3 EE'
+ 'EA FF E2 D6 CA FF C2 A7 8E FF FD FB FA FF FC FA'
+ 'F8 FF F1 EA E5 FF BC 9D 8A FF C6 AC 94 FF C1 A3'
+ '8B FF CF B9 A5 FF CB B3 9D FF B3 90 71 FF C2 A5'
+ '92 FF AD 90 88 FF EF E8 E3 FF E7 DD D4 FF D0 B9'
+ 'A8 FF D9 C7 B7 FF FD FA F8 FF FC F9 F7 FF FC F9'
+ 'F7 FF FC F9 F7 FF FC F9 F7 FF FC F9 F7 FF F4 F3'
+ 'F1 FF 98 98 98 FF 84 84 84 FF 82 82 82 FF 7F 7F'
+ '7F FF 7F 7F 7F FF 7F 7F 7F FF 7C 7C 7C FF 7B 7B'
+ '7B FF 8B 8B 8B FF 4B 4B 4B 98 00 00 00 35 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 BF BF'
+ 'BF 79 C9 C9 C9 FF CB C9 C8 FF FA F5 F1 FF F7 EF'
+ 'E9 FF F6 EE E7 FF FA F4 EE FF D2 BD B6 FF C6 AB'
+ 'A1 FF FC F8 F4 FF FB F4 EF FF E1 D0 C8 FF F0 E5'
+ 'DD FF FB F4 EF FF F9 F2 EC FF E1 D0 C1 FF D1 BA'
+ 'A4 FF C5 AA 93 FF FC F7 F2 FF CE B6 A4 FF B2 8F'
+ '77 FF E2 D5 C8 FF FA F3 EE FF F7 EF E9 FF F8 F0'
+ 'EA FF D7 C4 B2 FF B4 8F 73 FF F5 F0 ED FF E4 D5'
+ 'CA FF CB B3 9E FF F6 F1 EB FF D5 C2 B1 FF CC B2'
+ '9F FF CC B7 AB FF F3 EA E4 FF F7 EE E8 FF F8 F0'
+ 'EA FF F8 F0 EA FF F7 EF E9 FF F6 EE E7 FF F6 EE'
+ 'E7 FF F6 EE E7 FF F6 EE E7 FF F7 EE E8 FF F1 EC'
+ 'E7 FF 98 97 96 FF 85 85 85 FF 84 84 84 FF 80 80'
+ '80 FF 7E 7E 7E FF 7E 7E 7E FF 7D 7D 7D FF 7C 7C'
+ '7C FF 8C 8C 8C FF 4D 4D 4D 9B 00 00 00 37 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 D2'
+ 'D2 8B C7 C7 C7 FF C6 C6 C7 FF FD FD FD FF FF FF'
+ 'FF FF FF FF FF FF F7 F5 F2 FF FB F9 F8 FF B3 91'
+ '77 FF D5 C2 B1 FF FA F8 F6 FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FB FA'
+ 'F8 FF DF D2 C6 FF D5 C2 B2 FF FB FA F8 FF 97 6F'
+ '64 FF EB E3 DD FF FF FF FF FF FF FF FF FF FE FF'
+ 'FF FF EE E7 E0 FF BD A0 8A FF D4 C3 B3 FF CB B4'
+ '9F FF D2 BE AD FF D7 C5 B5 FF F8 F6 F4 FF A5 82'
+ '7A FF FD FD FC FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF F1 F1'
+ 'F1 FF 93 93 93 FF 87 87 87 FF 85 85 85 FF 82 82'
+ '82 FF 81 81 81 FF 7F 7F 7F FF 7D 7D 7D FF 7D 7D'
+ '7D FF 8D 8D 8D FF 4D 4D 4D 9D 00 00 00 38 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 EE EE'
+ 'EE 98 C4 C4 C4 FF BC BB BB FF F1 ED E9 FF F9 F3'
+ 'EE FF F6 EE E7 FF D7 C3 B2 FF B2 96 8C FF C3 A8'
+ '92 FF CE B8 AA FF CD B2 9B FF F9 F2 EB FF F6 ED'
+ 'E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED E6 FF F6 EE'
+ 'E6 FF F9 F3 ED FF C2 A3 8D FF B2 8E 74 FF AE 87'
+ '68 FF B8 96 82 FF BB 9B 89 FF F4 EB E2 FF F6 EE'
+ 'E6 FF F6 EE E7 FF C4 A5 8B FF B6 9D 8D FF FE FD'
+ 'FB FF F2 EC E4 FF C6 AB 96 FF F6 EF E9 FF 9F 75'
+ '62 FF EA E0 D8 FF F6 EE E6 FF F6 ED E6 FF F6 ED'
+ 'E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED E6 FF F6 ED'
+ 'E6 FF F6 ED E6 FF F6 ED E6 FF F8 EF E8 FF DB D7'
+ 'D4 FF 8A 8A 8A FF 87 87 87 FF 86 86 86 FF 84 84'
+ '84 FF 82 82 82 FF 81 81 81 FF 7F 7F 7F FF 7C 7C'
+ '7C FF 8B 8B 8B FF 54 54 56 A0 00 00 00 39 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 F0'
+ 'F0 9D C4 C4 C4 FF B6 B6 B6 FF DF DF DF FF FE FE'
+ 'FE FF FF FF FF FF FE FE FE FF F1 EB E7 FF C7 AF'
+ 'A1 FF C5 AE A5 FF CF BA A9 FF FD FD FD FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FC FB FB FF F0 EA E5 FF EF E8'
+ 'E2 FF FB F9 F8 FF EB E4 E1 FF F9 F6 F4 FF FF FF'
+ 'FF FF FE FE FE FF F0 EA E5 FF D9 CD C4 FF C6 AD'
+ '96 FF CF BA A7 FF F1 EC E6 FF ED E6 DF FF F0 EB'
+ 'E8 FF F9 F7 F6 FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FC FC FC FF B1 B1'
+ 'B1 FF 8A 8A 8A FF 87 87 87 FF 87 87 87 FF 85 85'
+ '85 FF 83 83 83 FF 80 80 80 FF 7F 7F 7F FF 7D 7D'
+ '7D FF 8B 8B 8B FF 56 56 56 A3 00 00 00 3A 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 EE EE'
+ 'EE A6 C5 C5 C5 FF B7 B7 B7 FF BD BC BB FF EC E8'
+ 'E4 FF F9 F2 ED FF F7 EE E8 FF F8 F0 EA FF FB F4'
+ 'EF FF FC F6 F2 FF FA F3 EE FF F8 F0 EA FF F7 EE'
+ 'E7 FF F6 EE E7 FF F6 EE E7 FF F6 EE E7 FF F6 EE'
+ 'E7 FF F6 EE E7 FF F6 EE E7 FF F7 EE E7 FF F7 EE'
+ 'E7 FF F7 EE E8 FF F7 EF E8 FF F7 EF E8 FF F7 EE'
+ 'E8 FF F6 EE E7 FF F7 EF E8 FF F9 F2 EC FF FB F5'
+ 'F0 FF FA F3 EE FF F9 F1 EB FF F8 F0 E9 FF F7 EF'
+ 'E9 FF F7 EE E8 FF F7 EE E7 FF F6 EE E7 FF F6 EE'
+ 'E7 FF F6 EE E7 FF F6 EE E7 FF F6 EE E7 FF F6 EE'
+ 'E7 FF F7 EE E8 FF FA F3 ED FF D0 CC C9 FF 8F 8E'
+ '8E FF 8C 8C 8C FF 89 89 89 FF 86 86 86 FF 84 84'
+ '84 FF 84 84 84 FF 82 82 82 FF 81 81 81 FF 7E 7E'
+ '7E FF 8D 8D 8D FF 59 59 59 A5 00 00 00 3B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E9'
+ 'E9 B1 C6 C6 C6 FF BD BD BD FF BB BB BB FF BF BF'
+ 'BF FF DF DF DF FF F3 F2 F2 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F5 F5 F5 FF F5 F5 F5 FF F5 F5'
+ 'F4 FF F5 F4 F4 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F4 F4 F4 FF F4 F4 F4 FF F4 F4 F3 FF F4 F3'
+ 'F3 FF F4 F3 F3 FF F4 F3 F3 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F3 F3 F2 FF F3 F3 F2 FF F3 F3 F2 FF F3 F3'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F1 F1 FF F2 F2 F1 FF F4 F4 F4 FF F7 F7'
+ 'F7 FF F7 F7 F7 FF F7 F7 F7 FF F6 F6 F6 FF F1 F1'
+ 'F1 FF E8 E8 E8 FF BF BF BF FF 8F 8F 8F FF 8C 8C'
+ '8C FF 8B 8B 8B FF 8C 8C 8C FF 89 89 89 FF 88 88'
+ '88 FF 87 87 87 FF 84 84 84 FF 82 82 82 FF 81 81'
+ '81 FF 8F 8F 8F FF 5A 5A 5A A7 00 00 00 3C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 E6'
+ 'E6 BC C6 C6 C6 FF BC BC BC FF BC BC BC FF BB BB'
+ 'BB FF BA BA BA FF B9 B9 B9 FF B6 B6 B6 FF B4 B4'
+ 'B4 FF B3 B3 B3 FF B1 B1 B1 FF AF AF AF FF AF AF'
+ 'AF FF AD AD AD FF AB AB AB FF AB AB AB FF AA AA'
+ 'AA FF A9 A9 A9 FF A8 A8 A8 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3 A3 FF A1 A1'
+ 'A1 FF A1 A1 A1 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9D 9D 9D FF 9B 9B 9B FF 9A 9A'
+ '9A FF 98 98 98 FF 97 97 97 FF 96 96 96 FF 92 92'
+ '92 FF 91 91 91 FF 91 91 91 FF 92 92 92 FF 93 93'
+ '93 FF 92 92 92 FF 8F 8F 8F FF 8E 8E 8E FF 8D 8D'
+ '8D FF 8B 8B 8B FF 8B 8B 8B FF 8A 8A 8A FF 88 88'
+ '88 FF 84 84 84 FF 83 83 83 FF 82 82 82 FF 81 81'
+ '81 FF 8F 8F 8F FF 60 60 60 AA 00 00 00 3D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 E5'
+ 'E5 C6 C6 C6 C6 FF BF BF BF FF BD BD BD FF BD BD'
+ 'BD FF B9 B9 B9 FF B8 B8 B8 FF B7 B7 B7 FF B6 B6'
+ 'B6 FF B4 B4 B4 FF B2 B2 B2 FF B0 B0 B0 FF AE AE'
+ 'AE FF AD AD AD FF AD AD AD FF AB AB AB FF AA AA'
+ 'AA FF A9 A9 A9 FF A9 A9 A9 FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A5 A5 A5 FF A4 A4 A4 FF A2 A2'
+ 'A2 FF A2 A2 A2 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C 9C FF 9A 9A'
+ '9A FF 98 98 98 FF 97 97 97 FF 96 96 96 FF 96 96'
+ '96 FF 94 94 94 FF 94 94 94 FF 94 94 94 FF 93 93'
+ '93 FF 92 92 92 FF 90 90 90 FF 8F 8F 8F FF 8F 8F'
+ '8F FF 8E 8E 8E FF 8A 8A 8A FF 89 89 89 FF 88 88'
+ '88 FF 87 87 87 FF 85 85 85 FF 84 84 84 FF 81 81'
+ '81 FF 8F 8F 8F FF 64 64 64 AC 00 00 00 3D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E4 E4'
+ 'E4 D1 C9 C9 C9 FF C1 C1 C1 FF C1 C1 C1 FF BF BF'
+ 'BF FF BD BD BD FF BA BA BA FF B9 B9 B9 FF B5 B5'
+ 'B5 FF B4 B4 B4 FF B2 B2 B2 FF AF AF AF FF AD AD'
+ 'AD FF AB AB AB FF AC AC AC FF AA AA AA FF A9 A9'
+ 'A9 FF A8 A8 A8 FF A8 A8 A8 FF A6 A6 A6 FF A6 A6'
+ 'A6 FF A4 A4 A4 FF A5 A5 A5 FF A5 A5 A5 FF A2 A2'
+ 'A2 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0 A0 FF A0 A0'
+ 'A0 FF 9F 9F 9F FF 9C 9C 9C FF 9B 9B 9B FF 99 99'
+ '99 FF 9A 9A 9A FF 99 99 99 FF 97 97 97 FF 96 96'
+ '96 FF 96 96 96 FF 95 95 95 FF 95 95 95 FF 93 93'
+ '93 FF 93 93 93 FF 93 93 93 FF 90 90 90 FF 8F 8F'
+ '8F FF 8E 8E 8E FF 8D 8D 8D FF 8B 8B 8B FF 88 88'
+ '88 FF 87 87 87 FF 85 85 85 FF 84 84 84 FF 83 83'
+ '83 FF 90 90 90 FF 67 67 67 AF 00 00 00 3E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E9'
+ 'E9 EB CB CB CB FF C5 C5 C5 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF BF BF BF FF BC BC BC FF BC BC BC FF B8 B8'
+ 'B8 FF B7 B7 B7 FF B4 B4 B4 FF B1 B1 B1 FF B0 B0'
+ 'B0 FF AE AE AE FF AD AD AD FF AB AB AB FF AA AA'
+ 'AA FF A9 A9 A9 FF A9 A9 A9 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A6 A6 A6 FF A4 A4 A4 FF A4 A4'
+ 'A4 FF A2 A2 A2 FF A3 A3 A3 FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9E 9E 9E FF 9E 9E 9E FF 9B 9B 9B FF 9B 9B'
+ '9B FF 9A 9A 9A FF 98 98 98 FF 97 97 97 FF 96 96'
+ '96 FF 97 97 97 FF 95 95 95 FF 94 94 94 FF 93 93'
+ '93 FF 94 94 94 FF 92 92 92 FF 91 91 91 FF 90 90'
+ '90 FF 8F 8F 8F FF 8E 8E 8E FF 8B 8B 8B FF 8B 8B'
+ '8B FF 8A 8A 8A FF 87 87 87 FF 86 86 86 FF 84 84'
+ '84 FF 93 93 93 FF 69 69 69 B1 00 00 00 3F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CF CF CF 10 ED ED'
+ 'ED F6 CB CB CB FF C4 C4 C4 FF C4 C4 C4 FF C1 C1'
+ 'C1 FF C0 C0 C0 FF BE BE BE FF BC BC BC FF B9 B9'
+ 'B9 FF B8 B8 B8 FF B5 B5 B5 FF B3 B3 B3 FF B3 B3'
+ 'B3 FF B0 B0 B0 FF AE AE AE FF AD AD AD FF AB AB'
+ 'AB FF A8 A8 A8 FF A8 A8 A8 FF A6 A6 A6 FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A6 A6 A6 FF A5 A5 A5 FF A5 A5'
+ 'A5 FF A3 A3 A3 FF A1 A1 A1 FF 9E 9E 9E FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9F 9F 9F FF 9D 9D 9D FF 9B 9B'
+ '9B FF 9A 9A 9A FF 98 98 98 FF 97 97 97 FF 96 96'
+ '96 FF 95 95 95 FF 95 95 95 FF 94 94 94 FF 93 93'
+ '93 FF 93 93 93 FF 92 92 92 FF 90 90 90 FF 91 91'
+ '91 FF 8F 8F 8F FF 8D 8D 8D FF 8D 8D 8D FF 8C 8C'
+ '8C FF 8B 8B 8B FF 89 89 89 FF 86 86 86 FF 87 87'
+ '87 FF 93 93 93 FF 6C 6C 6C B3 00 00 00 3F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 E1 E1 E1 11 EE EE'
+ 'EE FB CB CB CB FF C9 C9 C9 FF C5 C5 C5 FF C3 C3'
+ 'C3 FF BF BF BF FF BD BD BD FF BB BB BB FF B9 B9'
+ 'B9 FF B7 B7 B7 FF B5 B5 B5 FF B4 B4 B4 FF B1 B1'
+ 'B1 FF B0 B0 B0 FF AE AE AE FF AD AD AD FF AC AC'
+ 'AC FF A8 A8 A8 FF A9 A9 A9 FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A3 A3 A3 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F'
+ '9F FF A0 A0 A0 FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9A 9A 9A FF 9A 9A 9A FF 9A 9A 9A FF 99 99'
+ '99 FF 96 96 96 FF 95 95 95 FF 94 94 94 FF 95 95'
+ '95 FF 94 94 94 FF 92 92 92 FF 92 92 92 FF 91 91'
+ '91 FF 8F 8F 8F FF 8E 8E 8E FF 8D 8D 8D FF 8A 8A'
+ '8A FF 8B 8B 8B FF 89 89 89 FF 88 88 88 FF 86 86'
+ '86 FF 92 92 92 FF 70 70 70 B6 00 00 00 40 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 E2 E2 E2 12 F0 F0'
+ 'F0 FE CC CC CC FF C8 C8 C8 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF C1 C1 C1 FF BD BD BD FF BB BB BB FF B9 B9'
+ 'B9 FF B7 B7 B7 FF B6 B6 B6 FF B5 B5 B5 FF B2 B2'
+ 'B2 FF B2 B2 B2 FF AE AE AE FF AC AC AC FF AB AB'
+ 'AB FF A8 A8 A8 FF A7 A7 A7 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A1 A1 A1 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9D 9D 9D FF 9E 9E 9E FF 9C 9C'
+ '9C FF 9A 9A 9A FF 9A 9A 9A FF 98 98 98 FF 99 99'
+ '99 FF 97 97 97 FF 95 95 95 FF 95 95 95 FF 95 95'
+ '95 FF 93 93 93 FF 93 93 93 FF 92 92 92 FF 90 90'
+ '90 FF 90 90 90 FF 8F 8F 8F FF 8D 8D 8D FF 8C 8C'
+ '8C FF 8B 8B 8B FF 89 89 89 FF 88 88 88 FF 86 86'
+ '86 FF 93 93 93 FF 73 73 73 B8 00 00 00 41 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 DA DA DA 15 F1 F1'
+ 'F1 FF CD CD CD FF C8 C8 C8 FF C8 C8 C8 FF C5 C5'
+ 'C5 FF C2 C2 C2 FF C0 C0 C0 FF BE BE BE FF BC BC'
+ 'BC FF B9 B9 B9 FF B7 B7 B7 FF B5 B5 B5 FF B1 B1'
+ 'B1 FF B1 B1 B1 FF AE AE AE FF AC AC AC FF AA AA'
+ 'AA FF A9 A9 A9 FF A8 A8 A8 FF A7 A7 A7 FF A7 A7'
+ 'A7 FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9F 9F 9F FF 9F 9F 9F FF 9A 9A'
+ '9A FF 9B 9B 9B FF 9B 9B 9B FF 98 98 98 FF 99 99'
+ '99 FF 98 98 98 FF 98 98 98 FF 96 96 96 FF 95 95'
+ '95 FF 95 95 95 FF 93 93 93 FF 94 94 94 FF 92 92'
+ '92 FF 91 91 91 FF 90 90 90 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 8A 8A 8A FF 89 89 89 FF 89 89 89 FF 88 88'
+ '88 FF 93 93 93 FF 74 73 74 BA 00 00 00 41 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CF CF CF 20 EF EF'
+ 'EF FF CD CD CD FF CA CA CA FF C9 C9 C9 FF C6 C6'
+ 'C6 FF C4 C4 C4 FF C2 C2 C2 FF BF BF BF FF BC BC'
+ 'BC FF BA BA BA FF B8 B8 B8 FF B6 B6 B6 FF B3 B3'
+ 'B3 FF B1 B1 B1 FF AF AF AF FF AD AD AD FF AB AB'
+ 'AB FF AA AA AA FF A8 A8 A8 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3 A3 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A2 A2 A2 FF A1 A1 A1 FF 9F 9F'
+ '9F FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9C 9C 9C FF 9C 9C 9C FF 9A 9A 9A FF 9B 9B'
+ '9B FF 9A 9A 9A FF 99 99 99 FF 98 98 98 FF 96 96'
+ '96 FF 95 95 95 FF 94 94 94 FF 94 94 94 FF 93 93'
+ '93 FF 93 93 93 FF 91 91 91 FF 8F 8F 8F FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8C 8C 8C FF 8A 8A 8A FF 89 89'
+ '89 FF 95 96 95 FF 77 77 77 BC 00 00 00 42 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D0 D0 D0 2C EF EF'
+ 'EF FF CE CE CE FF CC CC CC FF CA CA CA FF C7 C7'
+ 'C7 FF C5 C5 C5 FF C4 C4 C4 FF C0 C0 C0 FF BE BE'
+ 'BE FF BB BB BB FF B9 B9 B9 FF B6 B6 B6 FF B5 B5'
+ 'B5 FF B4 B4 B4 FF B1 B1 B1 FF AE AE AE FF AD AD'
+ 'AD FF AB AB AB FF AA AA AA FF A9 A9 A9 FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A5 A5 A5 FF A4 A4 A4 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9F 9F 9F FF 9F 9F 9F FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9D 9D 9D FF 9C 9C 9C FF 9A 9A 9A FF 9B 9B'
+ '9B FF 9A 9A 9A FF 99 99 99 FF 99 99 99 FF 97 97'
+ '97 FF 96 96 96 FF 94 94 94 FF 95 95 95 FF 94 94'
+ '94 FF 92 92 92 FF 92 92 92 FF 91 91 91 FF 90 90'
+ '90 FF 8E 8E 8E FF 8C 8C 8C FF 8B 8B 8B FF 8A 8A'
+ '8A FF 94 94 94 FF 7B 7B 7B BE 00 00 00 42 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CC CC CC 38 ED ED'
+ 'ED FF CE CE CE FF CC CC CC FF CA CA CA FF C7 C7'
+ 'C7 FF C5 C5 C5 FF C2 C2 C2 FF C0 C0 C0 FF BD BD'
+ 'BD FF BC BC BC FF B9 B9 B9 FF B7 B7 B7 FF B5 B5'
+ 'B5 FF B3 B3 B3 FF AF AF AF FF AE AE AE FF AC AC'
+ 'AC FF AB AB AB FF AA AA AA FF AA AA AA FF A8 A8'
+ 'A8 FF A8 A8 A8 FF A6 A6 A6 FF A5 A5 A5 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A3 A3 A3 FF A2 A2 A2 FF A0 A0'
+ 'A0 FF A0 A0 A0 FF 9F 9F 9F FF 9E 9E 9E FF 9F 9F'
+ '9F FF 9D 9D 9D FF 9D 9D 9D FF 9C 9C 9C FF 9C 9C'
+ '9C FF 9A 9A 9A FF 9A 9A 9A FF 9A 9A 9A FF 99 99'
+ '99 FF 97 97 97 FF 96 96 96 FF 95 95 95 FF 95 95'
+ '95 FF 93 93 93 FF 93 93 93 FF 92 92 92 FF 92 92'
+ '92 FF 90 90 90 FF 8D 8D 8D FF 8C 8C 8C FF 89 89'
+ '89 FF 94 94 94 FF 7F 7F 7F C0 00 00 00 43 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CE CE CE 44 EB EB'
+ 'EB FF CF CF CF FF CE CE CE FF CC CC CC FF CA CA'
+ 'CA FF C5 C5 C5 FF C4 C4 C4 FF C2 C2 C2 FF C0 C0'
+ 'C0 FF BD BD BD FF BB BB BB FF B9 B9 B9 FF B6 B6'
+ 'B6 FF B4 B4 B4 FF B1 B1 B1 FF B0 B0 B0 FF AD AD'
+ 'AD FF AC AC AC FF A9 A9 A9 FF A9 A9 A9 FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A6 A6 A6 FF A5 A5 A5 FF A4 A4'
+ 'A4 FF A4 A4 A4 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9B 9B 9B FF 9A 9A 9A FF 98 98'
+ '98 FF 97 97 97 FF 96 96 96 FF 97 97 97 FF 96 96'
+ '96 FF 94 94 94 FF 93 93 93 FF 92 92 92 FF 91 91'
+ '91 FF 8F 8F 8F FF 8D 8D 8D FF 8B 8B 8B FF 89 89'
+ '89 FF 94 94 94 FF 80 80 80 C1 00 00 00 43 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CE CE CE 4F EC EC'
+ 'EC FF CF CF CF FF CE CE CE FF CD CD CD FF CA CA'
+ 'CA FF C7 C7 C7 FF C6 C6 C6 FF C2 C2 C2 FF C1 C1'
+ 'C1 FF BF BF BF FF BB BB BB FF B9 B9 B9 FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B3 B3 B3 FF B0 B0 B0 FF AC AC'
+ 'AC FF AB AB AB FF A9 A9 A9 FF A8 A8 A8 FF A7 A7'
+ 'A7 FF A6 A6 A6 FF A5 A5 A5 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A3 A3 A3 FF A2 A2 A2 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A1 A1 A1 FF A0 A0 A0 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9E 9E 9E FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9B 9B 9B FF 9B 9B 9B FF 99 99'
+ '99 FF 99 99 99 FF 98 98 98 FF 97 97 97 FF 96 96'
+ '96 FF 94 94 94 FF 94 94 94 FF 92 92 92 FF 91 91'
+ '91 FF 8F 8F 8F FF 8E 8E 8E FF 8B 8B 8B FF 8A 8A'
+ '8A FF 92 92 92 FF 7E 7E 7E C3 00 00 00 44 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D1 D1 D1 5A E9 E9'
+ 'E9 FF D0 D0 D0 FF CE CE CE FF CE CE CE FF CB CB'
+ 'CB FF C8 C8 C8 FF C6 C6 C6 FF C3 C3 C3 FF C2 C2'
+ 'C2 FF C0 C0 C0 FF BD BD BD FF BB BB BB FF B6 B6'
+ 'B6 FF B4 B4 B4 FF B2 B2 B2 FF B0 B0 B0 FF AE AE'
+ 'AE FF AD AD AD FF AA AA AA FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A4 A4 A4 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF A0 A0 A0 FF A0 A0 A0 FF 9E 9E 9E FF 9E 9E'
+ '9E FF 9F 9F 9F FF 9F 9F 9F FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9C 9C 9C FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 98 98 98 FF 98 98 98 FF 96 96'
+ '96 FF 96 96 96 FF 94 94 94 FF 93 93 93 FF 91 91'
+ '91 FF 8F 8F 8F FF 8E 8E 8E FF 8B 8B 8B FF 8A 8A'
+ '8A FF 92 92 92 FF 81 81 81 C5 00 00 00 44 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D2 D2 D2 66 E9 E9'
+ 'E9 FF D2 D2 D2 FF CF CF CF FF CE CE CE FF CB CB'
+ 'CB FF C9 C9 C9 FF C7 C7 C7 FF C6 C6 C6 FF C3 C3'
+ 'C3 FF C1 C1 C1 FF BE BE BE FF BB BB BB FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B3 B3 B3 FF B1 B1 B1 FF AF AF'
+ 'AF FF AD AD AD FF AB AB AB FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A3 A3 A3 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9F 9F 9F FF A0 A0 A0 FF A0 A0 A0 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9C 9C 9C FF 9B 9B 9B FF 9B 9B'
+ '9B FF 9A 9A 9A FF 99 99 99 FF 97 97 97 FF 96 96'
+ '96 FF 95 95 95 FF 93 93 93 FF 93 93 93 FF 90 90'
+ '90 FF 8F 8F 8F FF 8D 8D 8D FF 8C 8C 8C FF 89 89'
+ '89 FF 91 91 91 FF 83 83 83 C6 00 00 00 45 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D8 D8 D8 6B ED ED'
+ 'ED FE D2 D2 D2 FF D0 D0 D0 FF CF CF CF FF CD CD'
+ 'CD FF CB CB CB FF C8 C8 C8 FF C4 C4 C4 FF C3 C3'
+ 'C3 FF C1 C1 C1 FF BE BE BE FF BC BC BC FF B9 B9'
+ 'B9 FF B6 B6 B6 FF B4 B4 B4 FF B3 B3 B3 FF AF AF'
+ 'AF FF AD AD AD FF AB AB AB FF A8 A8 A8 FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF 9F 9F 9F FF 9E 9E 9E FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9E 9E 9E FF 9F 9F 9F FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9C 9C 9C FF 9D 9D 9D FF 9A 9A'
+ '9A FF 99 99 99 FF 98 98 98 FF 98 98 98 FF 96 96'
+ '96 FF 95 95 95 FF 94 94 94 FF 92 92 92 FF 8F 8F'
+ '8F FF 90 90 90 FF 8C 8C 8C FF 8B 8B 8B FF 89 89'
+ '89 FF 8F 8F 8F FF 83 83 83 C8 00 00 00 45 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CE CE CE 15 F0 F0'
+ 'F0 EB DA DA DB FF D2 D2 D2 FF CF D0 D0 FF CD CD'
+ 'CD FF CB CB CB FF C9 C9 C9 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF C3 C3 C3 FF C0 C0 C0 FF BD BD BE FF BA BA'
+ 'BA FF B7 B8 B8 FF B5 B5 B6 FF B3 B3 B3 FF B1 B1'
+ 'B1 FF AE AE AE FF AC AC AC FF AA AA AA FF A7 A7'
+ 'A7 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9F 9F 9F FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9C 9C 9C FF 9C 9C 9C FF 9B 9B'
+ '9B FF 9A 9A 9A FF 99 99 99 FF 98 98 98 FF 95 95'
+ '95 FF 94 94 94 FF 94 94 94 FF 92 92 92 FF 8F 8F'
+ '8F FF 8F 8F 8F FF 8C 8C 8C FF 89 89 89 FF 87 87'
+ '87 FF 8E 8E 8E FF 83 83 84 C8 00 00 00 43 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E7 E7'
+ 'E5 6C EB EB E9 FE D2 D3 D6 FF D0 D1 D3 FF D0 D1'
+ 'D2 FF CD CE D0 FF CC CD CF FF C9 CA CC FF C6 C7'
+ 'C9 FF C3 C4 C5 FF C0 C1 C3 FF BB BC BF FF B8 B9'
+ 'BC FF B7 B8 BA FF B2 B3 B6 FF B0 B2 B5 FF AE AF'
+ 'B2 FF AB AD B0 FF A8 AA AD FF A7 A9 AC FF A3 A4'
+ 'A8 FF A2 A3 A7 FF A1 A3 A6 FF A2 A3 A6 FF A3 A4'
+ 'A7 FF A4 A5 A7 FF A2 A2 A4 FF A0 A0 A0 FF A0 A0'
+ 'A0 FF A0 A0 A0 FF 9F 9F 9F FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9D 9D 9D FF 9E 9E 9E FF 9E 9E 9E FF 9C 9C'
+ '9C FF 9C 9C 9C FF 9C 9C 9C FF 9B 9B 9B FF 9A 9A'
+ '9A FF 99 99 99 FF 97 97 97 FF 96 96 96 FF 94 94'
+ '94 FF 93 93 93 FF 92 92 92 FF 90 90 90 FF 8E 8E'
+ '8E FF 8C 8C 8C FF 89 89 89 FF 88 88 88 FF 86 86'
+ '86 FF 8D 8D 8D FF 8A 8A 8A C3 00 00 00 34 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E7 E7'
+ 'C8 21 F2 E9 CB FB BE B2 98 FF B2 A5 8B FF AF A2'
+ '88 FF B0 A3 89 FF AE A2 88 FF AB 9E 84 FF A9 9C'
+ '82 FF A4 97 7C FF A3 96 7C FF A1 94 7A FF 9C 8F'
+ '76 FF 99 8C 73 FF 97 8B 73 FF 96 8A 72 FF 93 87'
+ '70 FF 92 87 71 FF 95 8A 74 FF 97 8C 77 FF 96 8D'
+ '78 FF 96 8C 78 FF 91 88 76 FF 8E 86 74 FF 8F 86'
+ '76 FF 90 88 78 FF 9A 97 93 FF A1 A2 A4 FF A1 A1'
+ 'A1 FF 9F 9F 9F FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9D 9D 9D FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9C 9C 9C FF 9A 9A 9A FF 99 99'
+ '99 FF 98 98 98 FF 97 97 97 FF 95 95 95 FF 94 94'
+ '94 FF 91 91 91 FF 90 90 90 FF 8E 8E 8E FF 8C 8C'
+ '8C FF 8A 8A 8A FF 87 87 87 FF 85 85 85 FF 87 87'
+ '87 FF 96 96 96 F7 8F 8E 8F 93 00 00 00 14 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 EE EE'
+ 'D5 1F F8 F4 D9 F8 DE D1 B6 FF D6 C9 AE FF D5 C7'
+ 'AD FF D2 C5 AB FF D1 C3 A9 FF CF C1 A7 FF CD C0'
+ 'A6 FF CD C0 A5 FF CC BF A4 FF CA BD A2 FF C8 BA'
+ 'A0 FF C6 B8 9E FF C4 B6 9C FF C0 B2 98 FF BB AD'
+ '93 FF B5 A7 8D FF B2 A5 8A FF AF A1 86 FF AB 9E'
+ '83 FF A9 9C 81 FF A8 9B 7F FF A6 98 7C FF A0 92'
+ '76 FF 9C 8D 70 FF 96 88 6B FF A1 A2 A3 FF AB AC'
+ 'AC FF AB AB AB FF AC AC AC FF A9 A9 A9 FF A8 A8'
+ 'A8 FF A8 A8 A8 FF A6 A6 A6 FF A7 A7 A7 FF A5 A5'
+ 'A5 FF A4 A4 A4 FF A2 A2 A2 FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9C 9C 9C FF 9A 9A 9A FF 97 97'
+ '97 FF 95 95 95 FF 94 94 94 FF 92 92 92 FF 8F 8F'
+ '8F FF 8B 8B 8B FF 8B 8B 8B FF 89 89 89 FF 93 93'
+ '93 FC 7A 7A 7A 8D 12 12 12 1B 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F5 F2 E4 A1 F4 EB D0 FE E5 D8 BE FF E2 D5'
+ 'BB FF E0 D3 B9 FF DE D1 B7 FF DD D0 B6 FF DB CE'
+ 'B4 FF D9 CC B2 FF D5 C8 AE FF D3 C6 AC FF D1 C4'
+ 'AA FF CE C1 A7 FF CB BE A4 FF C9 BC A2 FF C7 BA'
+ 'A0 FF C4 B7 9D FF C0 B3 99 FF BC AF 95 FF B9 AC'
+ '92 FF B5 A8 8E FF B4 A7 8D FF B2 A5 8B FF AF A2'
+ '88 FF AD A0 86 FF B4 A5 87 FF AA 9E 8A DF AB AC'
+ 'AC A7 BD BD BD A0 C0 C0 C0 A0 C1 C1 C1 A1 C3 C3'
+ 'C3 A2 C3 C3 C3 A3 C5 C5 C5 A3 C5 C5 C5 A4 C7 C7'
+ 'C7 A4 C4 C4 C4 A5 C7 C7 C7 A5 C5 C5 C5 A5 C4 C4'
+ 'C4 A6 C0 C0 C0 A6 BE BE BE A7 BE BE BE A9 BA BA'
+ 'BA AB B6 B4 B6 AC B2 B2 B2 AE AE AE AE AF AB AB'
+ 'AB B1 A9 A9 A9 AF A6 A6 A6 A8 A5 A5 A5 A8 A7 A7'
+ 'A7 94 51 51 51 1C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 D7 CD BA 1A F9 F4 E5 DC F6 EE D6 FF F0 E8'
+ 'CB FF EE E5 C8 FF EE E3 C7 FF EB DF C3 FF EB DE'
+ 'C2 FF E9 DC BF FF E7 D9 BD FF E4 D6 B9 FF E3 D4'
+ 'B8 FF DF D1 B5 FF DC CE B1 FF DA CC B0 FF D7 C9'
+ 'AD FF D5 C7 AA FF D3 C5 A8 FF D1 C2 A6 FF CD BF'
+ 'A3 FF CA BC A0 FF C8 BA 9E FF C6 B8 9B FF C4 B6'
+ '9A FF C7 B9 9C FF D7 C8 A8 F7 5A 53 46 4C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -7233,729 +6120,52 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F0 00 00 0F E0 00'
- '00 07 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 F0 00 00 0F F0 00 00 0F F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F8 00 00 1F F8 00'
- '00 1F FC 00 00 3F FF FF FF FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 D9 D2 C3 22 F6 F2 DC 76 F9 F7'
+ 'E4 86 F9 F7 E2 86 F7 F7 E0 86 F7 F5 DC 86 F7 F5'
+ 'DA 86 F7 F5 DA 86 F7 F3 D8 86 F7 F3 D5 86 F5 F3'
+ 'D3 86 F5 F1 D1 86 F5 EF CD 86 F5 ED CB 86 F3 E8'
+ 'C9 86 F3 E6 C5 86 F1 E4 C2 86 F1 E0 C0 86 EF DC'
+ 'BE 86 EB DA BC 86 EA DA BA 86 E6 D5 B4 86 E4 D3'
+ 'B4 86 E4 D5 B2 86 C5 B8 9C 50 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 11 04 04'
- '04 8A 16 16 16 A8 1B 1B 1B A8 18 18 18 A8 16 16'
- '16 A8 15 15 15 A8 16 16 16 A8 15 15 15 A8 15 15'
- '15 A8 14 13 14 A8 19 12 16 A8 05 03 04 84 00 00'
- '00 0F 00 00 00 00 00 00 00 00 05 05 05 83 9B 9B'
- '9B FF C1 C1 C1 FF 83 83 83 FF 9A 9A 9A FF AD AD'
- 'AD FF B2 B2 B2 FF B3 B3 B3 FF B5 B5 B5 FF B2 B1'
- 'B2 FF AC B2 AF FF 59 B0 84 FF 5B 6C 64 FF 04 01'
- '03 71 00 00 00 00 00 00 00 00 13 13 13 B3 DC DC'
- 'DC FF CB CB CB FF 65 65 65 FF 8A 8A 8A FF A7 A7'
- 'A7 FF AB AB AB FF 95 95 95 FF A2 A2 A2 FF 95 94'
- '95 FF BA BF BC FF 8F CC AD FF 93 A1 9A FF 09 06'
- '07 95 00 00 00 00 00 00 00 00 13 13 13 B2 D7 D7'
- 'D7 FF DE DE DE FF A1 A1 A1 FF AC AC AC FF BA BA'
- 'BA FF B7 B7 B7 FF A2 A2 A2 FF A9 A9 A9 FF 9D 9D'
- '9D FF C2 C1 C1 FF CF C9 CC FF A2 A0 A1 FF 06 06'
- '06 93 00 00 00 00 00 00 00 00 14 14 14 B3 D9 D9'
- 'D9 FF ED ED ED FF EA EA EA FF E8 E8 E8 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E6 E6 E6 FF E4 E4 E4 FF E4 E4'
- 'E4 FF DF DF DF FF E3 E3 E3 FF B2 B2 B2 FF 04 05'
- '05 94 00 00 00 00 00 00 00 00 11 11 11 A5 C6 C6'
- 'C6 FF BC BC BC FF CA CA CA FF D9 D9 D9 FF DA DA'
- 'DA FF DA DA DA FF DB DB DB FF DA DA DA FF DA DA'
- 'DA FF C6 C6 C6 FF C5 C5 C5 FF B4 B4 B4 FF 04 04'
- '04 8B 00 00 00 00 00 00 00 00 04 04 04 7B A8 A8'
- 'A8 FF CE CE CE FF CF CF CF FF DC DC DC FF DD DD'
- 'DD FF DE DE DE FF DE DE DE FF DE DE DE FF DC DC'
- 'DC FF CF CF CF FF D4 D4 D4 FF 91 91 91 FF 00 00'
- '00 69 00 00 00 00 00 00 00 00 00 00 00 53 85 85'
- '85 FF DB DB DB FF D7 D7 D7 FF D3 D3 D3 FF D0 D0'
- 'D0 FF CE CE CE FF CD CD CD FF CE CE CE FF D0 D0'
- 'D0 FF D6 D6 D6 FF D9 D9 D9 FF 6E 6E 6E FE 00 00'
- '00 43 00 00 00 00 00 00 00 00 00 00 00 2E 64 64'
- '64 FA DD DD DD FF D3 D3 D3 FF D0 D0 D0 FF D1 D1'
- 'D1 FF CF CF CF FF C8 C8 C8 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C5 C5 C5 FF CF CF CF FF 4D 4D 4D F3 00 00'
- '00 20 00 00 00 00 00 00 00 00 00 00 00 0E 42 42'
- '42 E8 D7 D7 D7 FF D6 D6 D6 FF D9 D9 D9 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D7 D7 D7 FF D4 D4 D4 FF D3 D3'
- 'D3 FF CD CD CD FF C5 C5 C5 FF 2C 2C 2C D8 00 00'
- '00 0A 00 00 00 00 00 00 00 00 00 00 00 02 22 22'
- '22 C5 D1 D1 D1 FF E3 E3 E3 FF DC DC DC FF DF DF'
- 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF DE DE'
- 'DE FF E5 E5 E5 FF C0 C0 C0 FF 11 11 11 B6 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 08 08'
- '08 A1 BE BE BE FF E1 E1 E1 FF EA EA EA FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF E5 E5'
- 'E5 FF E5 E5 E5 FF A3 A3 A3 FF 01 01 01 93 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 74 78 78 78 FF C7 C7 C7 FF D9 D9 D9 FF DE DE'
- 'DE FF DD DD DD FF DD DD DD FF DF DF DF FF D4 D4'
- 'D4 FF C7 C7 C7 FF 60 60 60 FF 00 00 00 65 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 11 04 04 04 94 1D 1D 1D CC 1C 1C 1C CC 1C 1C'
- '1C CC 1C 1C 1C CC 1C 1C 1C CC 1C 1C 1C CC 1D 1D'
- '1D CC 1B 1B 1B CB 02 02 02 88 00 00 00 0C 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 FF FF 00 00'
-} */
-
-/* BINRES netdrive.ico */
-9 ICON netdrive.ico
-/* {
- '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 3E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 8E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 5E 21 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 C6 27 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 6E 4D 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 02 02 02 00 04 04 04 00 05 06 06 00 06 06'
- '06 00 09 09 09 00 0A 0A 0A 00 0C 0C 0C 00 12 12'
- '12 00 14 14 14 00 15 15 15 00 16 16 16 00 1D 1D'
- '1D 00 1F 1F 1F 00 21 21 21 00 22 22 22 00 23 23'
- '23 00 24 24 24 00 25 25 25 00 26 26 26 00 38 38'
- '38 00 39 39 39 00 3B 3B 3B 00 00 67 67 00 43 43'
- '43 00 46 46 46 00 4A 4A 4A 00 54 4C 50 00 53 53'
- '53 00 55 55 55 00 56 56 56 00 58 58 58 00 59 59'
- '59 00 5A 58 59 00 5A 5A 5A 00 5B 5B 5B 00 5C 5C'
- '5C 00 5D 5D 5D 00 5E 5E 5E 00 65 58 5F 00 60 60'
- '60 00 61 61 61 00 62 62 62 00 64 64 64 00 67 67'
- '67 00 69 69 69 00 71 71 71 00 72 72 72 00 73 73'
- '73 00 75 75 75 00 78 78 78 00 7A 7A 7A 00 7B 7B'
- '7B 00 7C 7C 7C 00 7F 7F 7F 00 24 A7 64 00 3C AD'
- '74 00 25 DC 7F 00 7D AA 94 00 18 FF FF 00 56 D8'
- 'D8 00 81 81 81 00 83 83 83 00 89 89 89 00 8A 8A'
- '8A 00 8B 8B 8B 00 8F 8F 8F 00 91 89 8C 00 90 90'
- '90 00 91 91 91 00 94 94 94 00 95 95 95 00 97 97'
- '97 00 99 99 99 00 9A 9A 9A 00 9C 9C 9C 00 9D 9D'
- '9D 00 9E 9E 9E 00 9F 9F 9F 00 A0 91 91 00 94 B6'
- 'A4 00 93 BD A9 00 A0 A0 A0 00 A1 A1 A1 00 A3 A3'
- 'A3 00 A4 A4 A4 00 A5 A5 A5 00 A8 A8 A8 00 A9 A9'
- 'A9 00 AA AA AA 00 AC AC AC 00 AD AD AD 00 AE AE'
- 'AE 00 AF AF AF 00 B7 AF AF 00 AD B9 B3 00 B0 B0'
- 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
- 'B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B9 B9'
- 'B9 00 BC BC BC 00 BD BD BD 00 BE BE BE 00 BF BF'
- 'BF 00 89 CF CF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C0'
- 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C2 00 C5 C2'
- 'C4 00 C4 C4 C4 00 C5 C5 C5 00 C6 C5 C6 00 C6 C6'
- 'C6 00 C8 C3 C5 00 CC C4 C8 00 C8 C8 C8 00 C9 C9'
- 'C9 00 CB C9 CA 00 CA CA CA 00 CB CB CB 00 CC CC'
- 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D2 C1'
- 'CA 00 D3 C8 CD 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
- 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
- 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
- 'DA 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
- 'DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
- 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
- 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
- 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
- 'EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2'
- 'F2 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7'
- 'F7 00 F8 F8 F8 00 F9 F9 F9 00 FC FC FC 00 FD FD'
- 'FD 00 FF FF FF 00 00 00 00 00 62 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 6E 65 74 64 72 69 76 65 2E'
- '69 63 6F 00 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 B2 B2'
- 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 17 17 B2'
- 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 62 62'
- '62 62 62 62 62 62 62 62 62 62 62 5E 6D 3B 3B 6D'
- '5E 62 62 62 62 62 62 62 62 62 62 62 62 62 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 3C 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 4F 4F 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 0D 0D B2'
- 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 00 00 00 00 00 00'
- '00 B2 B2 09 26 26 2C 2B 2A 28 26 25 24 1E 1D 22'
- '20 1F 1F 1F 1E 21 27 1B 05 B2 B2 00 00 00 00 00'
- '00 B2 09 6E AA A0 58 64 68 6F 86 88 8C 8D 92 92'
- '91 93 90 8E 82 79 38 51 43 03 B2 00 00 00 00 00'
- '00 B2 1E AC 9C 9A 0C 1A 33 41 4C 54 5D 59 4E 4B'
- '59 66 56 48 85 3A 39 37 84 13 B2 00 00 00 00 00'
- '00 B2 25 A8 9D 99 1C 34 40 46 54 58 64 59 47 44'
- '52 60 4A 3F 7D 70 50 5F 73 13 B2 00 00 00 00 00'
- '00 B2 23 A9 9F 9E 24 2F 3E 42 4E 56 63 53 32 2E'
- '41 52 3D 2C 7F 77 7A 74 6E 12 B2 00 00 00 00 00'
- '00 B2 23 AB A2 9E 3D 44 4A 52 58 5B 64 5A 4B 49'
- '54 5C 4C 45 7B 76 6F 6F 72 11 B2 00 00 00 00 00'
- '00 B2 22 AD A6 A5 AF AE AA A8 A4 A2 9F 9D A0 9E'
- '9A 96 96 96 8C 8A 88 7F 75 10 B2 00 00 00 00 00'
- '00 B2 20 B1 A5 A3 A2 9D 9D 9C 9D 9D 9E 9D 9D 9D'
- '9D 9D 9D 9C 9F A3 A2 AE 8B 0E B2 00 00 00 00 00'
- '00 B2 25 B1 78 61 69 8E 8D 8D 8D 8D 8C 8C 8C 8C'
- '8D 8D 8D 8E 87 65 65 8C AB 13 B2 00 00 00 00 00'
- '00 B2 18 B1 5D 67 57 87 8D 8B 89 87 8A 8B 8B 8A'
- '87 88 8A 90 68 62 58 7B 9E 0C B2 00 00 00 00 00'
- '00 B2 10 9E 82 86 78 86 82 8F 9A 99 9C A0 A0 9D'
- '9A 9B 91 83 83 83 75 8E 6B 06 B2 00 00 00 00 00'
- '00 B2 08 87 87 80 81 81 9F 9C 90 8E 8D 8C 8C 8D'
- '8E 91 9C 9F 86 7E 81 98 48 B2 B2 00 00 00 00 00'
- '00 B2 01 55 8E 7C 81 9B 89 82 86 86 83 86 86 86'
- '86 86 81 83 9C 83 78 9F 29 B2 B2 00 00 00 00 00'
- '00 B2 B2 31 9A 7C 90 88 82 86 83 86 81 7E 7F 7F'
- '7F 7F 7F 7E 80 90 72 A5 15 B2 B2 00 00 00 00 00'
- '00 00 B2 19 A0 83 8E 82 86 86 86 86 86 80 71 72'
- '75 76 76 76 72 81 76 A1 0A B2 00 00 00 00 00 00'
- '00 00 B2 0F A4 87 87 88 87 87 87 87 87 88 81 75'
- '6E 6C 6B 6E 6E 6E 78 8C 01 B2 00 00 00 00 00 00'
- '00 00 B2 02 94 8F 80 8E 8C 8D 8D 8D 8D 8D 8D 8E'
- '8D 8A 86 80 7C 67 7C 63 B2 B2 00 00 00 00 00 00'
- '00 00 B2 B2 76 99 89 89 94 92 91 91 91 91 91 91'
- '92 92 93 95 8C 89 93 3F B2 B2 00 00 00 00 00 00'
- '00 00 00 B2 45 9C 99 8B 8C 96 99 97 97 97 97 97'
- '97 99 95 8E 88 9D 8E 1F B2 00 00 00 00 00 00 00'
- '00 00 00 B2 2C 9C 9D 9D 95 87 8F 98 99 9A 9A 99'
- '98 8F 87 95 9E A1 82 14 B2 00 00 00 00 00 00 00'
- '00 00 00 B2 16 93 A0 8F A2 A4 9C 98 97 94 94 97'
- '98 9A A4 9A 91 A7 78 0C B2 00 00 00 00 00 00 00'
- '00 00 00 B2 13 94 6F 5B 76 A8 A6 A6 A6 A5 A5 A6'
- 'A6 A6 A3 65 5B 9D 6A 0B B2 00 00 00 00 00 00 00'
- '00 00 00 B2 07 4D A2 9A AB B0 AF AF AF AF AF AF'
- 'AF AF AF A7 9C 9B 30 B2 B2 00 00 00 00 00 00 00'
- '00 00 00 B2 B2 0B 31 34 33 32 32 32 32 32 32 32'
- '32 32 32 33 35 2D 04 B2 00 00 00 00 00 00 00 00'
- '00 00 00 00 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2'
- 'B2 B2 B2 B2 B2 B2 B2 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF 00 00 00 00 00 00 00 00 FF FE 7F FF FF FE'
- '7F FF F0 00 00 0F E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 0C 0C 0C 00 15 15'
- '15 00 1F 12 12 00 19 19 19 00 25 20 22 00 29 29'
- '29 00 35 35 35 00 3E 3E 3E 00 40 40 40 00 57 57'
- '57 00 6D 6D 6D 00 73 73 73 00 75 75 75 00 78 78'
- '78 00 7B 7B 7B 00 7D 7D 7D 00 7F 7F 7F 00 89 7D'
- '7D 00 66 8E 7A 00 86 7B 81 00 5E CA 93 00 4F D8'
- 'D8 00 85 85 85 00 8C 8C 8C 00 8F 8F 8F 00 90 90'
- '90 00 91 91 91 00 97 97 97 00 98 95 97 00 99 99'
- '99 00 9B 9A 9B 00 9B 9B 9B 00 9F 9F 9F 00 A1 A1'
- 'A1 00 A3 A3 A3 00 A5 A5 A5 00 A9 A9 A9 00 AC AC'
- 'AC 00 AE AE AE 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
- 'B4 00 B6 B6 B6 00 B8 B8 B8 00 BA BA BA 00 BF BF'
- 'BF 00 C1 C1 C1 00 C2 C2 C2 00 C0 C7 C4 00 C4 C4'
- 'C4 00 C7 C7 C7 00 CB C9 CA 00 CA CA CA 00 CC CC'
- 'CC 00 CD CD CD 00 CF CF CF 00 D4 C9 CF 00 D0 D0'
- 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
- 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DF DF'
- 'DF 00 E0 E0 E0 00 E1 E1 E1 00 E3 E3 E3 00 E4 E4'
- 'E4 00 E6 E6 E6 00 E7 E7 E7 00 E9 E9 E9 00 EA EA'
- 'EA 00 EC EC EC 00 ED ED ED 00 EF EF EF 00 F0 F0'
- 'F0 00 F3 F3 F3 00 F4 F4 F4 00 F7 F7 F7 00 FC FC'
- 'FC 00 00 00 00 00 A9 A9 A9 00 AA AA AA 00 AC AC'
- 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B7 AF'
- 'AF 00 AD B9 B3 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
- 'B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6'
- 'B6 00 B7 B7 B7 00 B9 B9 B9 00 BC BC BC 00 BD BD'
- 'BD 00 BE BE BE 00 BF BF BF 00 89 CF CF 00 C0 C0'
- 'C0 00 C1 C1 C1 00 C2 C0 C1 00 C2 C2 C2 00 C3 C3'
- 'C3 00 C4 C1 C2 00 C5 C2 C4 00 C4 C4 C4 00 C5 C5'
- 'C5 00 C6 C5 C6 00 C6 C6 C6 00 C8 C3 C5 00 CC C4'
- 'C8 00 C8 C8 C8 00 C9 C9 C9 00 CB C9 CA 00 CA CA'
- 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
- 'CE 00 CF CF CF 00 D2 C1 CA 00 D3 C8 CD 00 D0 D0'
- 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
- 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
- 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
- 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
- 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
- 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
- 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F4 F4 F4 00 F5 F5'
- 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
- 'F9 00 FC FC FC 00 FD FD FD 00 FF FF FF 00 00 00'
- '00 00 62 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 6E'
- '65 74 64 72 69 76 65 2E 69 63 6F 00 4B 00 14 1A'
- '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
- '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
- '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 17 17 17 17 17 17 12 16 16 12'
- '17 17 17 17 17 17 00 00 00 57 57 57 57 03 03 57'
- '57 57 57 57 00 00 00 00 07 2B 1A 1C 21 20 21 23'
- '22 1D 13 05 00 00 00 57 2B 56 08 18 25 2A 1E 29'
- '1F 31 15 14 00 00 00 57 27 55 0B 19 24 26 10 20'
- '0F 34 39 0D 00 00 00 57 28 56 56 54 52 4F 51 4E'
- '4E 4A 51 0E 00 00 00 57 2A 2C 2E 40 3D 3F 3F 3E'
- '42 2C 33 1B 00 00 00 00 11 43 35 47 47 48 48 47'
- '48 37 46 0A 00 00 00 00 09 46 43 38 38 36 36 37'
- '36 43 4B 04 00 00 00 00 01 50 3B 3A 3A 3A 32 2E'
- '2E 30 48 57 00 00 00 00 57 4C 3C 45 43 43 44 44'
- '41 36 30 57 00 00 00 00 57 2C 4F 42 46 49 49 47'
- '43 52 1B 57 00 00 00 00 57 19 43 4F 53 51 51 53'
- '49 4D 0C 57 00 00 00 00 00 06 2E 30 30 30 30 30'
- '2F 2D 02 00 00 00 00 00 00 00 57 57 57 57 57 57'
- '57 57 00 00 00 00 FF FF 00 00 00 00 00 00 E0 03'
- '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
- '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
- '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 60 00 00 00 00 00 00 00 77 77'
- '77 77 77 77 77 7E E7 77 77 77 77 77 77 77 00 00'
- '00 00 00 00 00 0E E0 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 08 80 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 88 88 88 88 88 88 88 88 88 88 00 00 00 00 00'
- '07 FF 77 77 77 77 77 77 77 77 67 80 00 00 00 00'
- '8F FF 08 88 87 77 88 77 78 78 66 70 00 00 00 00'
- '8F FF 88 88 77 77 88 77 88 77 77 70 00 00 00 00'
- '8F FF 88 88 87 77 88 87 88 77 77 70 00 00 00 00'
- '8F FF 88 87 77 77 88 77 88 77 77 70 00 00 00 00'
- '8F FF FF FF FF FF FF FF FF 77 77 70 00 00 00 00'
- '8F FF FF FF FF FF FF FF FF FF FF 70 00 00 00 00'
- '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
- '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
- '0F 77 77 77 FF FF FF FF 77 77 77 70 00 00 00 00'
- '07 77 77 FF 77 77 77 77 FF 77 7F 80 00 00 00 00'
- '07 77 7F 77 77 77 77 77 77 F7 7F 80 00 00 00 00'
- '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
- '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
- '00 F7 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
- '00 77 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
- '00 7F 77 77 77 77 77 77 77 77 78 00 00 00 00 00'
- '00 8F F7 7F FF FF FF FF 77 7F 78 00 00 00 00 00'
- '00 8F FF 77 7F FF FF F7 77 FF 70 00 00 00 00 00'
- '00 07 F7 FF FF F7 7F FF FF 7F 70 00 00 00 00 00'
- '00 07 77 7F FF FF FF FF F7 7F 70 00 00 00 00 00'
- '00 08 FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
- '00 00 88 88 88 88 88 88 88 88 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF 00 00 00 00 00 00 00 00 FF FE 7F FF FF FE'
- '7F FF F0 00 00 0F E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 88 88'
- '88 8E E8 88 88 88 00 00 00 00 00 00 00 00 00 07'
- '88 88 87 78 80 00 00 7F 08 77 87 87 88 00 00 7F'
- '88 77 88 87 78 00 00 7F FF FF FF FF F8 00 00 77'
- '77 77 77 77 78 00 00 87 7F FF FF F7 78 00 00 07'
- '77 77 77 77 F0 00 00 0F 77 77 77 77 F0 00 00 0F'
- '77 77 77 77 70 00 00 07 F7 7F FF 7F 80 00 00 08'
- '7F FF FF FF 80 00 00 00 77 77 77 77 00 00 00 00'
- '00 00 00 00 00 00 FF FF 00 00 00 00 00 00 E0 03'
- '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
- '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
- '00 00 F0 0F 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 01 01 00 02 02 02 00 05 05 05 00 06 06'
- '06 00 07 07 07 00 08 08 08 00 09 09 09 00 0B 0B'
- '0B 00 0C 0C 0C 00 13 13 13 00 18 18 18 00 19 19'
- '19 00 1A 1A 1A 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
- '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
- '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2A 2A'
- '2A 00 2B 2B 2B 00 2C 2C 2C 00 2D 2D 2D 00 2E 2C'
- '2D 00 2F 2F 2F 00 34 34 34 00 35 35 35 00 39 39'
- '39 00 3B 3B 3B 00 3D 3D 3D 00 3F 3F 3F 00 40 40'
- '40 00 41 41 41 00 42 42 42 00 47 47 47 00 48 48'
- '48 00 49 49 49 00 4B 4B 4B 00 4F 4F 4F 00 53 53'
- '53 00 56 56 56 00 58 58 58 00 59 59 59 00 5A 5A'
- '5A 00 5B 5B 5B 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
- '61 00 63 63 63 00 64 64 64 00 66 66 66 00 67 67'
- '67 00 68 68 68 00 6A 6A 6A 00 6B 6B 6B 00 6C 6C'
- '6C 00 70 70 70 00 71 71 71 00 72 72 72 00 73 73'
- '73 00 74 74 74 00 75 75 75 00 76 76 76 00 77 77'
- '77 00 78 78 78 00 79 79 79 00 7A 7A 7A 00 7C 7C'
- '7C 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F 7F 00 2F 99'
- '64 00 1C A8 60 00 0A BF 61 00 20 A8 63 00 51 A7'
- '7C 00 17 CE 71 00 00 DC DC 00 00 FF FF 00 6B FF'
- 'FF 00 80 80 80 00 81 81 81 00 83 83 83 00 84 83'
- '84 00 85 85 85 00 87 87 87 00 88 88 88 00 8A 8A'
- '8A 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
- '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 94 94'
- '94 00 97 97 97 00 98 98 98 00 99 99 99 00 9A 9A'
- '9A 00 9C 9C 9C 00 9D 9D 9D 00 9F 9F 9F 00 83 AB'
- '97 00 96 AB A0 00 90 AF A0 00 99 AC A2 00 95 B2'
- 'A3 00 9D B3 A8 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2'
- 'A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6'
- 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
- 'AA 00 AB AB AB 00 AD A8 AB 00 AB AC AC 00 AC AC'
- 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
- 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B3 B4'
- 'B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B4'
- 'B6 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BB BB'
- 'BB 00 BF BB BD 00 BC BC BC 00 BD BD BD 00 BE BE'
- 'BE 00 BF BF BF 00 91 D6 B4 00 91 D8 B5 00 C3 BD'
- 'C0 00 C2 BE C0 00 C7 BF C3 00 C0 C0 C0 00 C1 C1'
- 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C3 00 C4 C3'
- 'C3 00 C4 C3 C4 00 C6 C2 C4 00 C6 C3 C4 00 C6 C3'
- 'C5 00 C4 C4 C4 00 C5 C4 C4 00 C5 C5 C5 00 C7 C4'
- 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C8 C9'
- 'C9 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CC CC'
- 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
- 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
- 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
- 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
- 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
- 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
- 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
- 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4'
- 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
- 'F8 00 F9 F9 F9 00 FA FA FA 00 FC FC FC 00 FF FF'
- 'FF 00 00 00 00 00 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 52 52 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 55 55'
- '55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55'
- '55 55 55 55 52 53 53 52 55 55 55 55 55 55 55 55'
- '55 55 55 55 55 55 55 55 55 55 55 55 55 55 9B 9B'
- '9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B'
- '9B 9B 9B 9B 54 54 54 54 9B 9B 9B 9B 9B 9B 9B 9B'
- '9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 54 54 E1 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9B 9B E1 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9B 9B E1 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 E1 E1 11 1A 19 1A 19 19 19 19 19'
- '19 19 19 19 19 19 18 18 18 18 18 18 18 18 18 19'
- '19 19 1C 1C 0A E1 E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 14 61 AE B1 AF B2 B1 B0 AF AD AA'
- 'A9 A7 A5 9E 9D 9D 9E 9B 9C 95 95 92 93 8F 90 89'
- '88 8C 81 7F 7E 35 07 E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 01 5C CF CC CB B9 59 5B 62 66 74 81'
- '8F 9B 9E A9 AF AE AE BA AE B7 AF BB B0 B8 AA AC'
- 'A2 71 4F 4D 6E 91 2B E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 0C AA D0 C6 CA AF 21 23 2D 3F 5A 62'
- '6A 77 7A 80 8B 7B 69 93 67 8B 73 9E 75 93 66 A6'
- '9A 50 51 4E 4C 98 58 01 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 17 B5 CE C8 CB B1 27 33 46 5A 60 65'
- '72 79 7C 82 8E 76 61 8D 5C 83 64 95 65 8B 5B A0'
- 'A4 70 96 97 6C 9F 5F 01 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 16 B5 D0 CA CB B5 39 41 4A 59 5F 65'
- '72 79 7C 82 8F 6B 57 87 48 7A 5A 90 5C 86 46 9D'
- 'A5 A3 6F 6D 99 A5 5E 01 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 16 B5 D2 CB CC BA 3D 3E 49 59 5F 65'
- '72 79 7C 82 90 66 40 81 3A 72 45 8B 48 7D 38 9D'
- 'A9 A1 A8 A2 95 A7 5E 01 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 15 B5 D3 CD CF BA 3A 3C 45 56 5C 63'
- '69 75 78 7D 8E 61 37 77 31 66 3B 85 3D 76 2E 9C'
- 'AB A7 9E 9D 9C A9 5F 01 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 15 B6 D6 CF CE C3 79 79 7D 82 84 87'
- '8A 8E 8E 8F 93 8B 85 94 83 8F 85 94 84 8F 7D A7'
- 'AB A9 A5 9E 9D AD 5F E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 14 B7 D7 CF CF CE D1 CF CD CC CA C8'
- 'C6 C5 C3 C2 BF BF C0 BC BD BA BA B6 B6 B3 B4 AF'
- 'AE AD AA A5 9B AE 5F E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 14 B7 DB DC DA DA DA D9 D9 D8 D8 D7'
- 'D7 D7 D6 D6 D5 D5 D5 D4 D4 D4 D3 D3 D2 D2 D1 D1'
- 'D1 D0 D0 CF C4 B4 5E E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 13 BA E0 CD C5 C6 C6 C4 C3 C3 C3 C3'
- 'C3 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4'
- 'C6 C7 C7 C7 DC D3 5D E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 13 C2 DC BD A5 90 95 BC BE BD BD BD'
- 'BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BF'
- 'B3 92 90 B5 C2 E0 68 E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 0F BE D7 A9 7B 8B 84 9E BE BC BC BC'
- 'BC BC BB BB BB BB BB BB BB BB BC BC BC BC BD B6'
- '7A 8A 85 89 BC DF 69 E1 E1 00 00 00 00 00 00 00'
- '00 00 E1 E1 03 9D DA 92 86 9E 7D 90 BC B9 B9 B9'
- 'B8 B7 B7 B9 BB BC BC BB B9 B7 B7 B7 B8 B9 BB AD'
- '78 9E 87 81 BA D9 43 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 76 D8 B3 A7 B6 95 AD B7 B6 B4 B7'
- 'C1 C5 C7 CA CE D1 D1 CF CB C8 C6 C2 B8 B4 B6 B7'
- 'A7 B4 9D 95 BD CC 2D E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 4A D3 B5 B3 AF B3 B5 B2 B3 C3 D4'
- 'D0 C5 C2 C1 C0 BF BF C0 C1 C2 C5 D0 D5 C5 B5 B2'
- 'B4 AF B2 B5 BD B8 23 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 2F CD B4 B1 B1 B1 AE BA D1 CA C0'
- 'B8 B9 BA BA BA BA BA BA BA BA B9 B9 BF C8 D1 BE'
- 'AE B1 B1 AF C3 8D 12 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 24 BB B6 AE AF AE B8 CD C0 B4 B5'
- 'B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B5 B4 BC CE'
- 'BC AD AE AD C4 72 06 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 12 8B BF AE AF B2 C8 B8 B3 B5 B4'
- 'B4 B4 B4 B3 B1 B2 B2 B2 B2 B2 B2 B2 B2 B2 B0 B4'
- 'C6 B3 AA AD C6 55 E1 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 E1 E1 05 6B C1 B0 B1 BF BA B2 B4 B4 B4'
- 'B4 B4 B4 B3 B0 AD AE AE AE AE AE AE AE AE AE AB'
- 'B3 BE AA AD C6 30 E1 E1 E1 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 57 C1 B3 B5 BF B5 B4 B4 B4 B4'
- 'B4 B4 B4 B4 B3 AD A7 A9 A9 A9 A9 A9 A9 A9 A9 A9'
- 'AA B7 AB AD C2 26 E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 33 C0 B5 B6 B8 B5 B5 B5 B5 B5'
- 'B5 B5 B5 B5 B5 B4 AB 9E 9E 9E A5 A5 A5 A5 A5 A5'
- 'A5 AA A7 AF B0 1B E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 25 BC B8 B6 B4 B7 B7 B7 B7 B7'
- 'B7 B7 B7 B7 B7 B7 B7 B1 AA A5 9D 9C 9B 9C 9C 9C'
- '9D 95 9B B2 86 0D E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 1A B0 BA B9 B0 B9 BA BA BA BA'
- 'BA BA BA BA BA BA BA BB BA B9 B7 B3 B0 AD A9 A5'
- '9D 87 93 B4 67 07 E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 0B 84 BF BF B4 B6 BF BD BE BE'
- 'BE BE BE BE BE BE BE BE BE BE BE BF BF BE BD BD'
- 'B3 A7 B0 AE 47 02 E1 E1 00 00 00 00 00 00 00 00'
- '00 00 00 00 E1 E1 06 65 C0 C3 C0 B2 BA C2 C1 C1'
- 'C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C2 BC'
- 'B2 C1 C0 A9 2C E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 E1 E1 44 B7 C6 C5 C2 B2 BB C5 C6'
- 'C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C5 C5 BD B1'
- 'BE C7 BD 90 20 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 E1 E1 2A AD C9 C7 C8 C5 BB B6 BE'
- 'C8 C9 C8 C8 C8 C8 C8 C8 C8 C8 C9 C9 C0 B6 BA C4'
- 'C8 CA BA 7A 10 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 E1 E1 1F 93 CA CA CA CB CB C3 B6'
- 'B7 C2 C7 C7 C8 C8 C8 C8 C7 C7 C2 B8 B5 C1 CB CB'
- 'CA CC B8 68 08 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 E1 E1 0E 7D C8 D1 CB CA D0 CF CE'
- 'C8 C4 C3 C3 C1 C0 C0 C1 C3 C3 C3 C6 CD D0 CE C9'
- 'CF CF BA 5C E1 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 E1 E1 06 67 C8 C3 93 9C BA D0 D1'
- 'D1 D2 D2 D1 D0 CF CF D0 D1 D2 D2 D1 D2 C8 9D 94'
- 'B5 D0 B8 42 E1 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E1 E1 5E C4 A5 86 8D 86 CF D5'
- 'D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D7 B9 84 8A'
- '8B CF B1 34 E1 E1 E1 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E1 E1 36 B2 C1 C0 B9 C8 DD DD'
- 'DD DD DD DD DD DD DD DD DD DD DD DD DE D6 C3 BC'
- 'C0 BB 84 1E E1 E1 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E1 E1 0C 55 94 B7 BB BF BC BC'
- 'BC BC BC BC BC BC BC BC BC BC BC BC BC BD BD BB'
- 'B1 84 32 04 E1 E1 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E1 E1 E1 09 22 29 28 28 28 28'
- '28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 29'
- '29 1D 02 E1 E1 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
- 'E1 E1 E1 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FE 3F FF FF 00 00 FF FF'
- 'FE 3F FF FF 00 00 FF FF FE 3F FF FF 00 00 FC 00'
- '00 00 00 7F 00 00 F8 00 00 00 00 3F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
- '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0E E0 00 00 00 00 00 00 00 00 00 00 00 88 88'
- '88 88 88 88 88 88 88 88 88 EE EE 88 88 88 88 88'
- '88 88 88 88 88 88 77 77 77 77 77 77 77 77 77 77'
- '77 EE EE 77 77 77 77 77 77 77 77 77 77 77 00 00'
- '00 00 00 00 00 00 00 00 00 0E E0 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 07 70 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 07 70 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
- '00 08 FF F7 88 88 77 77 77 77 77 77 77 77 77 77'
- '66 87 80 00 00 00 00 00 00 07 FF F7 00 88 88 87'
- '77 77 87 87 77 77 87 78 66 67 80 00 00 00 00 00'
- '00 07 FF F7 88 88 88 77 77 77 87 87 87 87 87 77'
- '77 87 80 00 00 00 00 00 00 07 FF F7 88 88 88 77'
- '77 78 87 87 87 87 87 77 77 77 80 00 00 00 00 00'
- '00 07 FF F7 88 88 88 77 77 78 87 87 87 87 87 77'
- '77 77 80 00 00 00 00 00 00 07 FF F7 88 88 88 87'
- '77 78 87 88 87 87 87 77 77 77 80 00 00 00 00 00'
- '00 07 FF F7 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 77 80 00 00 00 00 00 00 07 FF FF FF FF FF FF'
- '77 77 77 77 77 77 77 77 77 77 80 00 00 00 00 00'
- '00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF F7 80 00 00 00 00 00 00 07 FF FF FF 77 77 7F'
- 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
- '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 7F 80 00 00 00 00 00'
- '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 7F'
- 'FF FF FF FF F7 77 77 77 77 7F 80 00 00 00 00 00'
- '00 08 F7 77 77 77 7F FF 77 77 77 77 FF FF 77 77'
- '77 77 00 00 00 00 00 00 00 08 F7 77 77 7F F7 77'
- '77 77 77 77 77 7F F7 77 77 77 00 00 00 00 00 00'
- '00 00 77 77 77 F7 77 77 77 77 77 77 77 77 7F 77'
- '77 F7 00 00 00 00 00 00 00 00 77 77 7F 77 77 77'
- '77 77 77 77 77 77 77 F7 77 F8 00 00 00 00 00 00'
- '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 F8 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
- '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 70 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
- '00 00 07 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 00 00 07 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
- '00 00 08 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 00 00 08 7F F7 77 77 77'
- '77 77 77 77 77 77 77 7F 77 00 00 00 00 00 00 00'
- '00 00 08 7F FF F7 77 77 77 77 77 77 77 77 7F FF'
- '77 00 00 00 00 00 00 00 00 00 00 7F FF FF 77 77'
- '77 77 77 77 77 77 FF FF 78 00 00 00 00 00 00 00'
- '00 00 00 7F FF FF FF FF 77 77 77 77 7F FF FF FF'
- '78 00 00 00 00 00 00 00 00 00 00 8F 77 77 FF FF'
- 'FF FF FF FF FF FF 77 7F 78 00 00 00 00 00 00 00'
- '00 00 00 8F 77 77 FF FF FF FF FF FF FF F7 77 7F'
- '78 00 00 00 00 00 00 00 00 00 00 87 77 7F FF FF'
- 'FF FF FF FF FF FF 77 77 70 00 00 00 00 00 00 00'
- '00 00 00 08 77 77 77 77 77 77 77 77 77 77 77 77'
- '80 00 00 00 00 00 00 00 00 00 00 00 08 88 88 88'
- '88 88 88 88 88 88 88 80 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
- 'FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FE 3F FF FF 00 00 FF FF FE 3F FF FF 00 00 FF FF'
- 'FE 3F FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
- '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -7969,61 +6179,11 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 48 00 00'
- '00 78 00 00 00 78 00 00 00 48 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 DC DC FF 00 DC'
- 'DC FF 00 00 00 B4 00 00 00 9C 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 00 DC DC FF 00 FF FF FF 00 FF'
- 'FF FF 00 DC DC FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF 6B FF FF FF 6B FF FF FF 6B FF'
- 'FF FF 6B FF FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 6B FF FF FF 6B FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -8034,8 +6194,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 FF C0 C0'
- 'C0 FF 00 00 00 92 00 00 00 37 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -8043,482 +6201,94 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 C0 C0 C0 FF C0 C0'
- 'C0 FF 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 35 00 00 00 18 00 00'
- '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
- '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F1 00 00 00 B1 00 00'
- '00 5C 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
- '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
- '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
- '2D FF 2E 2C 2D FF 13 13 13 FF 00 00 00 FF 00 00'
- '00 F6 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
- '90 FF CA CA CA FF CD CD CD FF CB CB CB FF CE CE'
- 'CE FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
- 'C9 FF C7 C7 C7 FF C6 C6 C6 FF C5 C5 C5 FF C4 C4'
- 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3'
- 'C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF BF FF BF BF'
- 'BF FF BC BC BC FF BD BD BD FF BA BA BA FF BB BB'
- 'BB FF B5 B5 B5 FF B3 B4 B3 FF B8 B4 B6 FF AD AD'
- 'AD FF AB AC AC FF AD A8 AB FF 63 63 63 FF 09 09'
- '09 FF 00 00 00 EF 00 00 00 42 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF EB EB'
- 'EB FF E8 E8 E8 FF E7 E7 E7 FF D5 D5 D5 FF 85 85'
- '85 FF 88 88 88 FF 92 92 92 FF 98 98 98 FF A2 A2'
- 'A2 FF AD AD AD FF BA BA BA FF C0 C0 C0 FF C3 C3'
- 'C3 FF C6 C6 C6 FF CB CB CB FF CA CA CA FF CA CA'
- 'CA FF D6 D6 D6 FF CA CA CA FF D3 D3 D3 FF CB CB'
- 'CB FF D7 D7 D7 FF CC CC CC FF D4 D4 D4 FF C7 C7'
- 'C7 FF C8 C9 C9 FF C6 C2 C4 FF 9D B3 A8 FF 20 A8'
- '63 FF 1C A8 60 FF 90 AF A0 FF BF BB BD FF 4F 4F'
- '4F FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 15 00 00 00 F0 19 19 19 FF C7 C7 C7 FF EC EC'
- 'EC FF E2 E2 E2 FF E6 E6 E6 FF CB CB CB FF 3B 3B'
- '3B FF 3F 3F 3F FF 56 56 56 FF 72 72 72 FF 87 87'
- '87 FF 92 92 92 FF 9D 9D 9D FF A5 A5 A5 FF A8 A8'
- 'A8 FF AC AC AC FF B7 B7 B7 FF A9 A9 A9 FF 9C 9C'
- '9C FF BD BD BD FF 99 99 99 FF B7 B7 B7 FF A1 A1'
- 'A1 FF C3 C3 C3 FF A3 A3 A3 FF BD BD BD FF 98 98'
- '98 FF C5 C4 C4 FF C7 BF C3 FF 51 A7 7C FF 17 CE'
- '71 FF 0A BF 61 FF 2F 99 64 FF C3 BD C0 FF 84 83'
- '84 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 30 00 00 00 FA 29 29 29 FF D1 D1 D1 FF EA EA'
- 'EA FF E4 E4 E4 FF E7 E7 E7 FF CD CD CD FF 47 47'
- '47 FF 5F 5F 5F FF 79 79 79 FF 87 87 87 FF 8F 8F'
- '8F FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF B9 B9 B9 FF A4 A4 A4 FF 90 90'
- '90 FF B8 B8 B8 FF 8A 8A 8A FF AF AF AF FF 94 94'
- '94 FF BF BF BF FF 97 97 97 FF B7 B7 B7 FF 88 88'
- '88 FF C4 C3 C3 FF C6 C3 C5 FF 95 B2 A3 FF 91 D6'
- 'B4 FF 91 D8 B5 FF 83 AB 97 FF C4 C1 C3 FF 8E 8E'
- '8E FF 01 01 01 FF 00 00 00 B7 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
- 'EC FF E6 E6 E6 FF E7 E7 E7 FF D1 D1 D1 FF 68 68'
- '68 FF 74 74 74 FF 7E 7E 7E FF 85 85 85 FF 8E 8E'
- '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF BA BA BA FF 9F 9F 9F FF 83 83'
- '83 FF B3 B3 B3 FF 7C 7C 7C FF A8 A8 A8 FF 87 87'
- '87 FF BB BB BB FF 8A 8A 8A FF B2 B2 B2 FF 79 79'
- '79 FF C2 C2 C2 FF C4 C4 C4 FF C6 C3 C4 FF 99 AC'
- 'A2 FF 96 AB A0 FF C2 BE C0 FF C4 C4 C4 FF 8D 8D'
- '8D FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
- 'EE FF E7 E7 E7 FF E8 E8 E8 FF D6 D6 D6 FF 70 70'
- '70 FF 71 71 71 FF 7D 7D 7D FF 85 85 85 FF 8E 8E'
- '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF BB BB BB FF 98 98 98 FF 73 73'
- '73 FF AD AD AD FF 6A 6A 6A FF A0 A0 A0 FF 78 78'
- '78 FF B7 B7 B7 FF 7C 7C 7C FF AB AB AB FF 67 67'
- '67 FF C2 C2 C2 FF C6 C6 C6 FF C4 C3 C4 FF C7 C4'
- 'C5 FF C6 C2 C4 FF BF BF BF FF C5 C5 C5 FF 8D 8D'
- '8D FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
- 'EF FF E9 E9 E9 FF EB EB EB FF D6 D6 D6 FF 6A 6A'
- '6A FF 6C 6C 6C FF 78 78 78 FF 81 81 81 FF 8A 8A'
- '8A FF 93 93 93 FF 9C 9C 9C FF A3 A3 A3 FF A6 A6'
- 'A6 FF AB AB AB FF B9 B9 B9 FF 90 90 90 FF 66 66'
- '66 FF A5 A5 A5 FF 5B 5B 5B FF 98 98 98 FF 6B 6B'
- '6B FF B1 B1 B1 FF 70 70 70 FF A4 A4 A4 FF 58 58'
- '58 FF C1 C1 C1 FF C8 C8 C8 FF C5 C5 C5 FF C3 C3'
- 'C3 FF C2 C2 C2 FF C1 C1 C1 FF C6 C6 C6 FF 8E 8E'
- '8E FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
- 'F2 FF EB EB EB FF EA EA EA FF DF DF DF FF A7 A7'
- 'A7 FF A7 A7 A7 FF AB AB AB FF AE AE AE FF B0 B0'
- 'B0 FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF B9 B9'
- 'B9 FF BA BA BA FF BD BD BD FF B7 B7 B7 FF B1 B1'
- 'B1 FF BE BE BE FF AF AF AF FF BA BA BA FF B1 B1'
- 'B1 FF BE BE BE FF B0 B0 B0 FF BA BA BA FF AB AB'
- 'AB FF C5 C5 C5 FF C8 C8 C8 FF C6 C6 C6 FF C4 C4'
- 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C9 C9 C9 FF 8E 8E'
- '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
- 'F3 FF EB EB EB FF EB EB EB FF EA EA EA FF ED ED'
- 'ED FF EB EB EB FF E9 E9 E9 FF E8 E8 E8 FF E6 E6'
- 'E6 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF'
- 'DF FF DE DE DE FF DB DB DB FF DB DB DB FF DC DC'
- 'DC FF D8 D8 D8 FF D9 D9 D9 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
- 'D0 FF CB CB CB FF CA CA CA FF C9 C9 C9 FF C7 C7'
- 'C7 FF C4 C4 C4 FF C0 C0 C0 FF CA CA CA FF 8E 8E'
- '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
- 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
- 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
- 'EC FF EB EB EB FF E0 E0 E0 FF D0 D0 D0 FF 8D 8D'
- '8D FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
- 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF EF FF 8C 8C'
- '8C FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
- 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
- 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF DB DB DB FF CF CF CF FF BC BC BC FF BB BB'
- 'BB FF D1 D1 D1 FF DE DE DE FF FF FF FF FF 9A 9A'
- '9A FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
- 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
- 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9'
- 'D9 FF D2 D2 D2 FF A8 A8 A8 FF B6 B6 B6 FF B1 B1'
- 'B1 FF B5 B5 B5 FF D8 D8 D8 FF FC FC FC FF 9C 9C'
- '9C FF 00 00 00 FF 00 00 00 AE 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
- 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
- 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D7 D7'
- 'D7 FF C9 C9 C9 FF A6 A6 A6 FF C3 C3 C3 FF B3 B3'
- 'B3 FF AD AD AD FF D6 D6 D6 FF F5 F5 F5 FF 76 76'
- '76 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
- 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
- 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF DD DD DD FF E1 E1 E1 FF E3 E3'
- 'E3 FF E6 E6 E6 FF EA EA EA FF ED ED ED FF ED ED'
- 'ED FF EB EB EB FF E7 E7 E7 FF E4 E4 E4 FF E2 E2'
- 'E2 FF DE DE DE FF D4 D4 D4 FF D0 D0 D0 FF D2 D2'
- 'D2 FF D3 D3 D3 FF C5 C5 C5 FF D0 D0 D0 FF C2 C2'
- 'C2 FF BF BF BF FF D9 D9 D9 FF E8 E8 E8 FF 56 56'
- '56 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
- 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
- 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF DF DF'
- 'DF FF F0 F0 F0 FF EC EC EC FF E1 E1 E1 FF DE DE'
- 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DB DB'
- 'DB FF DC DC DC FF DD DD DD FF DE DE DE FF E1 E1'
- 'E1 FF EC EC EC FF F1 F1 F1 FF E1 E1 E1 FF D1 D1'
- 'D1 FF CE CE CE FF D0 D0 D0 FF CB CB CB FF CE CE'
- 'CE FF D1 D1 D1 FF D9 D9 D9 FF D4 D4 D4 FF 3F 3F'
- '3F FF 00 00 00 FF 00 00 00 55 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
- 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CA CA CA FF D6 D6 D6 FF ED ED ED FF E6 E6'
- 'E6 FF DC DC DC FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF ED ED'
- 'ED FF DA DA DA FF CA CA CA FF CD CD CD FF CD CD'
- 'CD FF CB CB CB FF DF DF DF FF B8 B8 B8 FF 22 22'
- '22 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
- 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
- 'CA FF D4 D4 D4 FF E9 E9 E9 FF DC DC DC FF D0 D0'
- 'D0 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D8 D8'
- 'D8 FF EA EA EA FF D8 D8 D8 FF C9 C9 C9 FF CA CA'
- 'CA FF C9 C9 C9 FF E0 E0 E0 FF A0 A0 A0 FF 08 08'
- '08 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
- 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
- 'CE FF E4 E4 E4 FF D4 D4 D4 FF CF CF CF FF D1 D1'
- 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF CD CD CD FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CC CC'
- 'CC FF D0 D0 D0 FF E2 E2 E2 FF CF CF CF FF C7 C7'
- 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 C2 00 00 00 0E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
- '9F FF DD DD DD FF CC CC CC FF CD CD CD FF DB DB'
- 'DB FF D6 D6 D6 FF CE CE CE FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF C8 C8 C8 FF CF CF CF FF DA DA DA FF C7 C7'
- 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 5A 5A 5A FF 00 00'
- '00 FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
- '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF DB DB'
- 'DB FF D1 D1 D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF C5 C5'
- 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C7 C7 C7 FF D3 D3 D3 FF C8 C8'
- 'C8 FF C9 C9 C9 FF DE DE DE FF 42 42 42 FF 00 00'
- '00 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
- '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D4 D4'
- 'D4 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D0 D0 D0 FF C8 C8'
- 'C8 FF C3 C3 C3 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C7 C7 C7 FF C5 C5'
- 'C5 FF CB CB CB FF CC CC CC FF 2D 2D 2D FF 00 00'
- '00 F8 00 00 00 40 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
- '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF CD CD CD FF C7 C7 C7 FF C4 C4 C4 FF C2 C2'
- 'C2 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
- 'C1 FF C1 C1 C1 FF C2 C2 C2 FF BF BF BF FF C0 C0'
- 'C0 FF CE CE CE FF B2 B2 B2 FF 1A 1A 1A FF 00 00'
- '00 E5 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
- '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF CC CC'
- 'CC FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
- 'D3 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF C6 C6'
- 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
- 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
- '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
- '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF D0 D0'
- 'D0 FF D2 D2 D2 FF DB DB DB FF D9 D9 D9 FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DB DB DB FF DB DB DB FF DA DA DA FF D9 D9'
- 'D9 FF D9 D9 D9 FF CF CF CF FF C5 C5 C5 FF CC CC'
- 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
- '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
- '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
- 'DC FF CE CE CE FF D6 D6 D6 FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DE DE'
- 'DE FF D8 D8 D8 FF CE CE CE FF DD DD DD FF DC DC'
- 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
- '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
- '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
- 'E1 FF DE DE DE FF CE CE CE FF D7 D7 D7 FF E1 E1'
- 'E1 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF D9 D9'
- 'D9 FF CD CD CD FF DA DA DA FF E3 E3 E3 FF D9 D9'
- 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
- '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
- '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E1 E1 E1 FF D7 D7 D7 FF D2 D2'
- 'D2 FF DA DA DA FF E4 E4 E4 FF E5 E5 E5 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E5 E5 E5 FF DC DC DC FF D2 D2 D2 FF D6 D6'
- 'D6 FF E0 E0 E0 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
- 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
- '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
- '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF DF DF'
- 'DF FF D2 D2 D2 FF D3 D3 D3 FF DE DE DE FF E3 E3'
- 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3 E3 FF DE DE'
- 'DE FF D4 D4 D4 FF D1 D1 D1 FF DD DD DD FF E7 E7'
- 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
- '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
- '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
- 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
- 'EB FF EA EA EA FF E4 E4 E4 FF E0 E0 E0 FF DF DF'
- 'DF FF DF DF DF FF DD DD DD FF DC DC DC FF DC DC'
- 'DC FF DD DD DD FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E2 E2 E2 FF E9 E9 E9 FF EC EC EC FF EA EA'
- 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
- 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
- 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
- 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
- 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
- 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
- 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
- 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
- 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
- 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
- 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
- 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
- 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
- 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
- '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
- '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
- '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
- '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
- '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -8532,33 +6302,7 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FE 1F FF FF 00 00 FF FF'
- 'FE 1F FF FF 00 00 FF 00 00 00 00 7F 00 00 FC 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
- '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -8567,27 +6311,9 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 DC DC FF 00 DC DC FF 00 00 00 9C 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 00 FF FF FF 00 FF FF FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 6B FF FF FF 6B FF FF FF 00 00 00 30 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -8595,859 +6321,460 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 C0 C0 C0 FF C0 C0 C0 FF 00 00 00 37 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 C5 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F1 00 00'
- '00 B1 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 21 21'
- '21 FF 2B 2B 2B FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B'
- '2B FF 2B 2B 2B FF 2E 2C 2D FF 13 13 13 FF 00 00'
- '00 FF 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 AD 01 01 01 FF EB EB EB FF E8 E8'
- 'E8 FF D5 D5 D5 FF 85 85 85 FF 92 92 92 FF 98 98'
- '98 FF AD AD AD FF BA BA BA FF C3 C3 C3 FF C6 C6'
- 'C6 FF CA CA CA FF CA CA CA FF CA CA CA FF D3 D3'
- 'D3 FF D7 D7 D7 FF CC CC CC FF C7 C7 C7 FF C8 C9'
- 'C9 FF 9D B3 A8 FF 20 A8 63 FF 90 AF A0 FF BF BB'
- 'BD FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F0 19 19 19 FF EC EC EC FF E2 E2'
- 'E2 FF CB CB CB FF 3B 3B 3B FF 56 56 56 FF 72 72'
- '72 FF 92 92 92 FF 9D 9D 9D FF A8 A8 A8 FF AC AC'
- 'AC FF A9 A9 A9 FF 9C 9C 9C FF 99 99 99 FF B7 B7'
- 'B7 FF C3 C3 C3 FF A3 A3 A3 FF 98 98 98 FF C5 C4'
- 'C4 FF 51 A7 7C FF 17 CE 71 FF 2F 99 64 FF C3 BD'
- 'C0 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 28 28 28 FF EC EC EC FF E6 E6'
- 'E6 FF D1 D1 D1 FF 68 68 68 FF 7E 7E 7E FF 85 85'
- '85 FF 97 97 97 FF A0 A0 A0 FF AA AA AA FF AE AE'
- 'AE FF 9F 9F 9F FF 83 83 83 FF 7C 7C 7C FF A8 A8'
- 'A8 FF BB BB BB FF 8A 8A 8A FF 79 79 79 FF C2 C2'
- 'C2 FF C6 C3 C4 FF 99 AC A2 FF C2 BE C0 FF C4 C4'
- 'C4 FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF E0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F 80 00 00 00 00 00 00 3F 80 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 7F E0 00'
+ '00 00 00 00 00 FF E0 00 00 03 FF FF FF FF F0 00'
+ '00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF'
+} */
+
+
+
+/* BINRES folder_open.ico */
+4 ICON folder_open.ico
+/*{
+ '00 00 01 00 0B 00 10 10 10 00 01 00 04 00 28 01'
+ '00 00 B6 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 DE 01 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 46 07 00 00 20 20 10 00 01 00 04 00 E8 02'
+ '00 00 AE 0B 00 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 96 0E 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 3E 17 00 00 30 30 10 00 01 00 04 00 68 06'
+ '00 00 E6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 4E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 F6 3C 00 00 40 40 10 00 01 00 04 00 68 0A'
+ '00 00 9E 62 00 00 40 40 00 00 01 00 08 00 28 16'
+ '00 00 06 6D 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 28 28 28 FF EE EE EE FF E7 E7'
- 'E7 FF D6 D6 D6 FF 70 70 70 FF 7D 7D 7D FF 85 85'
- '85 FF 97 97 97 FF A0 A0 A0 FF AA AA AA FF AE AE'
- 'AE FF 98 98 98 FF 73 73 73 FF 6A 6A 6A FF A0 A0'
- 'A0 FF B7 B7 B7 FF 7C 7C 7C FF 67 67 67 FF C2 C2'
- 'C2 FF C4 C3 C4 FF C7 C4 C5 FF BF BF BF FF C5 C5'
- 'C5 FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 87'
+ '87 87 87 87 87 00 78 8F FF FF FF F8 88 70 88 FF'
+ '4F 4F 4F FF 88 70 78 F4 F4 F4 F4 FF 88 70 88 8F'
+ 'FF FF FF F8 88 70 77 88 88 88 88 88 88 87 87 88'
+ '88 88 88 88 88 87 77 77 77 77 88 88 88 87 87 77'
+ '77 77 77 77 77 77 86 66 66 66 87 77 77 70 0E FE'
+ 'FE FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 00 03 00 00 00 01 00 00 00 01'
+ '00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 01 00 00 80 FF'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 66 66'
+ '66 00 68 68 68 00 6C 6C 6C 00 6F 6F 6F 00 75 72'
+ '6D 00 7A 75 6C 00 6F 70 72 00 6F 71 74 00 71 71'
+ '71 00 72 72 72 00 73 73 73 00 76 76 76 00 73 75'
+ '78 00 78 79 79 00 7B 79 7B 00 7A 7A 7A 00 7B 7B'
+ '7B 00 79 7B 7E 00 7B 7D 7D 00 7C 7C 7C 00 7E 7E'
+ '7E 00 7F 7F 7F 00 8A 84 78 00 BD A5 77 00 7F 7F'
+ '80 00 FF 00 FF 00 80 80 80 00 80 80 82 00 82 82'
+ '82 00 83 83 83 00 82 81 85 00 80 82 85 00 84 84'
+ '84 00 85 85 85 00 86 86 86 00 87 87 89 00 86 88'
+ '8C 00 88 88 88 00 89 89 89 00 8A 8A 8A 00 8B 8B'
+ '8A 00 8B 8B 8B 00 8B 8C 8B 00 8C 8C 8C 00 8E 8E'
+ '8E 00 8E 8E 8F 00 8F 8F 8F 00 90 90 90 00 91 91'
+ '91 00 92 92 92 00 93 93 93 00 91 92 94 00 94 94'
+ '94 00 95 95 95 00 96 96 96 00 98 97 98 00 98 98'
+ '98 00 99 99 99 00 9A 99 99 00 9A 9A 9A 00 9B 9B'
+ '9B 00 9C 9C 9C 00 9D 9D 9D 00 9E 9E 9D 00 9E 9E'
+ '9E 00 A0 99 8C 00 A0 A0 A0 00 A0 A0 A1 00 A1 A1'
+ 'A1 00 A2 A2 A2 00 A3 A3 A3 00 A4 A4 A4 00 A6 A6'
+ 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
+ 'AA 00 AD AD AD 00 AD AE AE 00 B0 B0 B0 00 B2 B2'
+ 'B1 00 B3 B3 B3 00 B6 B7 B7 00 B7 B7 B7 00 B9 BA'
+ 'BA 00 BB BB BB 00 BC BC BB 00 BE BD BB 00 C0 A4'
+ '8D 00 C7 B2 89 00 C4 A8 94 00 C5 AB 95 00 CD B5'
+ 'A3 00 D1 BD B1 00 D3 BF B3 00 DF CC A6 00 D1 C5'
+ 'B0 00 F2 DE B8 00 FB E6 BF 00 C1 C1 C1 00 C5 C5'
+ 'C5 00 CF CF CF 00 DC D9 D2 00 D8 D8 D7 00 EB DC'
+ 'CE 00 E5 DC D5 00 EA DF D4 00 FE EE C7 00 EB E1'
+ 'D9 00 EA E3 DE 00 EF E7 E1 00 EF E8 E1 00 ED E8'
+ 'E2 00 ED E9 E5 00 EA E9 E8 00 F0 EC E7 00 F1 ED'
+ 'E9 00 F3 EE EB 00 F1 F0 EE 00 F3 F1 EF 00 F8 F3'
+ 'EF 00 F8 F4 F1 00 FF FF FF 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 27 27 27 FF F2 F2 F2 FF EB EB'
- 'EB FF DF DF DF FF A7 A7 A7 FF AB AB AB FF AE AE'
- 'AE FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF BA BA'
- 'BA FF B7 B7 B7 FF B1 B1 B1 FF AF AF AF FF BA BA'
- 'BA FF BE BE BE FF B0 B0 B0 FF AB AB AB FF C5 C5'
- 'C5 FF C6 C6 C6 FF C4 C4 C4 FF C2 C2 C2 FF C9 C9'
- 'C9 FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 26 26 26 FF F3 F3 F3 FF EB EB'
- 'EB FF EA EA EA FF ED ED ED FF E9 E9 E9 FF E8 E8'
- 'E8 FF E4 E4 E4 FF E2 E2 E2 FF DF DF DF FF DE DE'
- 'DE FF DB DB DB FF DC DC DC FF D9 D9 D9 FF D6 D6'
- 'D6 FF D2 D2 D2 FF D2 D2 D2 FF D0 D0 D0 FF CB CB'
- 'CB FF C9 C9 C9 FF C7 C7 C7 FF C0 C0 C0 FF CA CA'
- 'CA FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 24 24 24 FF FF FF FF FF E9 E9'
- 'E9 FF E2 E2 E2 FF E2 E2 E2 FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E3 E3 E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF'
- 'EF FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FA 24 24 24 FF F8 F8 F8 FF D9 D9'
- 'D9 FF BB BB BB FF BF BF BF FF DA DA DA FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF DB DB'
- 'DB FF BC BC BC FF BB BB BB FF DE DE DE FF FF FF'
- 'FF FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 D0 05 05 05 FF F6 F6 F6 FF BC BC'
- 'BC FF C3 C3 C3 FF AB AB AB FF D8 D8 D8 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D5 D5'
- 'D5 FF D8 D8 D8 FF D8 D8 D8 FF D5 D5 D5 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D7 D7 D7 FF C9 C9'
- 'C9 FF C3 C3 C3 FF B3 B3 B3 FF D6 D6 D6 FF F5 F5'
- 'F5 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9C 00 00 00 FF F4 F4 F4 FF CF CF'
- 'CF FF D2 D2 D2 FF BF BF BF FF D3 D3 D3 FF D2 D2'
- 'D2 FF D3 D3 D3 FF DD DD DD FF E3 E3 E3 FF E6 E6'
- 'E6 FF ED ED ED FF ED ED ED FF E7 E7 E7 FF E4 E4'
- 'E4 FF DE DE DE FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D0 D0 D0 FF C2 C2 C2 FF D9 D9 D9 FF E8 E8'
- 'E8 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 59 00 00 00 FF E9 E9 E9 FF D0 D0'
- 'D0 FF CD CD CD FF CD CD CD FF D6 D6 D6 FF ED ED'
- 'ED FF DC DC DC FF D4 D4 D4 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D5 D5 D5 FF DB DB DB FF ED ED ED FF DA DA'
- 'DA FF CD CD CD FF CD CD CD FF DF DF DF FF B8 B8'
- 'B8 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3E 00 00 00 FE D7 D7 D7 FF D2 D2'
- 'D2 FF CB CB CB FF CA CA CA FF E9 E9 E9 FF DC DC'
- 'DC FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D8 D8 D8 FF EA EA'
- 'EA FF C9 C9 C9 FF CA CA CA FF E0 E0 E0 FF A0 A0'
- 'A0 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 E1 9F 9F 9F FF DD DD'
- 'DD FF CD CD CD FF DB DB DB FF CE CE CE FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
- 'CF FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF C8 C8'
- 'C8 FF DA DA DA FF C7 C7 C7 FF E2 E2 E2 FF 5A 5A'
- '5A FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 B2 83 83 83 FF DD DD'
- 'DD FF D1 D1 D1 FF DB DB DB FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF C9 C9 C9 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF D3 D3 D3 FF C8 C8 C8 FF DE DE DE FF 42 42'
- '42 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4B 41 41 41 FF D8 D8'
- 'D8 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C7 C7 C7 FF C4 C4'
- 'C4 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
- 'C1 FF BF BF BF FF C0 C0 C0 FF B2 B2 B2 FF 1A 1A'
- '1A FF 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1A 2C 2C 2C FF CC CC'
- 'CC FF D5 D5 D5 FF CC CC CC FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF CF CF CF FF CC CC CC FF C6 C6 C6 FF C4 C4'
- 'C4 FF B3 B3 B3 FF BD BD BD FF 99 99 99 FF 09 09'
- '09 FF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 08 08 08 FF 97 97'
- '97 FF DF DF DF FF DC DC DC FF D6 D6 D6 FF DE DE'
- 'DE FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DE DE DE FF D8 D8'
- 'D8 FF DD DD DD FF DC DC DC FF 53 53 53 FF 00 00'
- '00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 77 77'
- '77 FF E2 E2 E2 FF E1 E1 E1 FF CE CE CE FF D7 D7'
- 'D7 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF D9 D9 D9 FF CD CD'
- 'CD FF E3 E3 E3 FF D9 D9 D9 FF 39 39 39 FF 00 00'
- '00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 35 35'
- '35 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7'
- 'E7 FF D2 D2 D2 FF D3 D3 D3 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3'
- 'E3 FF D4 D4 D4 FF D1 D1 D1 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E8 E8 E8 FF D4 D4 D4 FF 0B 0B 0B FF 00 00'
- '00 ED 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 1E 1E'
- '1E FF E4 E4 E4 FF ED ED ED FF E6 E6 E6 FF EC EC'
- 'EC FF EA EA EA FF E4 E4 E4 FF DF DF DF FF DF DF'
- 'DF FF DC DC DC FF DC DC DC FF DF DF DF FF DF DF'
- 'DF FF E2 E2 E2 FF E9 E9 E9 FF EA EA EA FF E5 E5'
- 'E5 FF EB EB EB FF D6 D6 D6 FF 00 00 00 FF 00 00'
- '00 C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 AE 00 00'
- '00 FF E0 E0 E0 FF C4 C4 C4 FF B8 B8 B8 FF B2 B2'
- 'B2 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F3 F3 F3 FF B0 B0 B0 FF B6 B6'
- 'B6 FF EB EB EB FF CD CD CD FF 00 00 00 FF 00 00'
- '00 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00'
- '00 FF CE CE CE FF DD DD DD FF D5 D5 D5 FF E4 E4'
- 'E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF DF DF DF FF D8 D8'
- 'D8 FF D7 D7 D7 FF B0 B0 B0 FF 00 00 00 FF 00 00'
- '00 67 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00'
- '00 9C 0C 0C 0C FF 3D 3D 3D FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 49 49'
- '49 FF 2F 2F 2F FF 02 02 02 FF 00 00 00 5C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 06 00 00 00 F1 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 D6 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 54 3B 37 34 31 2D 2A 25 1F 1C'
+ '17 1A 24 2A 00 00 5E 73 79 7F 7E 7A 7B 80 81 7D'
+ '77 61 19 1A 30 00 5A 84 66 68 62 67 76 65 67 64'
+ '78 7C 2F 1A 1E 00 4F 84 84 72 82 74 83 84 74 83'
+ '84 71 2F 1F 26 00 4A 5F 5C 58 56 52 50 4D 47 41'
+ '3F 38 2F 27 35 00 46 6D 5D 59 55 50 4C 48 43 3F'
+ '3C 36 35 2C 4E 3B 40 6F 6E 60 5B 57 53 51 4C 45'
+ '42 3E 39 35 3C 3A 1E 49 44 3B 32 2B 26 2C 48 48'
+ '46 42 3C 38 33 46 3D 2E 29 1B 16 11 10 12 13 12'
+ '0D 0C 0B 0A 3B 56 70 4B 20 0F 0E 18 28 22 1E 1D'
+ '19 15 12 14 56 00 00 75 6C 6B 69 63 21 6A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00'
- '00 00 FF FE 3F FF FF FE 3F FF F0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 F0 00 00 0F F0 00 00 0F F0 00'
- '00 0F F0 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 3F FC 00'
- '00 7F FF FF FF FF 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 FF FF 00 00 FF FF 00 00 00 03'
+ '00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 78 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF 6B FF FF FF 6B FF'
- 'FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 26 26 26 FF CD CD CD FF CD CD'
- 'CD FF C9 C9 C9 FF C5 C5 C5 FF C2 C2 C2 FF C0 C0'
- 'C0 FF BF BF BF FF BA BA BA FF B3 B4 B3 FF AB AC'
- 'AC FF 09 09 09 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 30 D1 D1 D1 FF E7 E7 E7 FF 5F 5F'
- '5F FF 8F 8F 8F FF A7 A7 A7 FF B9 B9 B9 FF B8 B8'
- 'B8 FF 94 94 94 FF B7 B7 B7 FF C6 C3 C5 FF 91 D8'
- 'B5 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 33 D1 D1 D1 FF EB EB EB FF 6C 6C'
- '6C FF 8A 8A 8A FF A3 A3 A3 FF B9 B9 B9 FF A5 A5'
- 'A5 FF 6B 6B 6B FF A4 A4 A4 FF C8 C8 C8 FF C2 C2'
- 'C2 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 33 D3 D3 D3 FF F6 F6 F6 FF F5 F5'
- 'F5 FF F4 F4 F4 FF F3 F3 F3 FF F1 F1 F1 FF F0 F0'
- 'F0 FF EF EF EF FF EE EE EE FF ED ED ED FF EB EB'
- 'EB FF 8D 8D 8D FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 DA DA DA FF A9 A9 A9 FF C3 C3'
- 'C3 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D8 D8 D8 FF D8 D8 D8 FF A8 A8 A8 FF B5 B5'
- 'B5 FF 9C 9C 9C FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 7E 7E 7E FF CF CF CF FF D1 D1'
- 'D1 FF DF DF DF FF E1 E1 E1 FF DC DC DC FF DC DC'
- 'DC FF E1 E1 E1 FF E1 E1 E1 FF D0 D0 D0 FF D1 D1'
- 'D1 FF 3F 3F 3F FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 22 22 FF CA CA CA FF E4 E4'
- 'E4 FF D1 D1 D1 FF D0 D0 D0 FF CD CD CD FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF E2 E2 E2 FF C9 C9'
- 'C9 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF C3 C3'
- 'C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF CB CB'
- 'CB FF 00 00 00 F8 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 D8 DB DB DB FF D2 D2'
- 'D2 FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF CF CF CF FF CA CA'
- 'CA FF 00 00 00 B8 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 89 C9 C9 C9 FF E4 E4'
- 'E4 FF D2 D2 D2 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E5 E5 E5 FF D2 D2 D2 FF E4 E4 E4 FF A8 A8'
- 'A8 FF 00 00 00 4E 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 99 99 99 FF BD BD'
- 'BD FF EC EC EC FF EE EE EE FF EC EC EC FF EC EC'
- 'EC FF EE EE EE FF E4 E4 E4 FF D1 D1 D1 FF 75 75'
- '75 FF 00 00 00 06 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 19 19 19 FF D3 D3'
- 'D3 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D9 D9 D9 FF CD CD CD FF 06 06'
- '06 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 01 00 00 80 FF 00 00 FF FF 00 00 FF FF'
+ '00 00 FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E0 03 00 00 C0 03 00 00 80 03'
- '00 00 80 03 00 00 80 03 00 00 80 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 E0 07 00 00 F0 0F 00 00'
-} */
-
-/* BINRES netdrive2.ico */
-10 ICON netdrive2.ico
-/* {
- '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 3E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 8E 11 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 5E 23 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 C6 29 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 6E 4F 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A8 A8'
+ 'A8 A6 7F 80 80 B6 7A 7A 7B B5 76 77 76 B5 74 74'
+ '74 B5 70 70 72 B5 6B 6B 6B B5 66 66 68 B5 65 65'
+ '65 B5 5F 61 62 B5 5B 5C 5C B5 5F 5F 60 B6 67 67'
+ '67 B6 6A 6A 6A B2 4B 4B 4B 51 00 00 00 00 CC CD'
+ 'CD F9 E5 DC D5 FE EF E8 E1 FD F3 EE EB FD F1 ED'
+ 'E9 FD ED E8 E2 FD ED E9 E5 FD F1 F0 EE FD F3 F1'
+ 'EF FD F0 EC E7 FD EA E3 DE FE BE BD BB FE 7A 7A'
+ '7A FE 7A 7A 7A FB 62 62 62 96 00 00 00 00 C4 C4'
+ 'C3 FD FF FF FF FF CD B5 A3 FF D3 BF B3 FF C0 A4'
+ '8D FF D1 BD B1 FF EB E1 D9 FF C5 AB 95 FF D1 BD'
+ 'B1 FF C4 A8 94 FF EF E7 E1 FF EA E9 E8 FF 88 88'
+ '88 FF 7B 7B 7B FE 67 67 67 BC 00 00 00 00 B2 B2'
+ 'B2 FE FF FF FF FF FF FF FF FF EB DC CE FF F8 F3'
+ 'EF FF EA DF D4 FF F8 F4 F1 FF FF FF FF FF EA DF'
+ 'D4 FF F8 F4 F1 FF FF FF FF FF D8 D8 D7 FF 88 88'
+ '88 FF 7F 7F 7F FE 76 76 76 D5 00 00 00 00 AE AE'
+ 'AE FE BB BB BB FF B6 B7 B7 FF AD AE AE FF AA AA'
+ 'AA FF A6 A6 A6 FF A3 A3 A3 FF A0 A0 A1 FF 9C 9C'
+ '9C FF 98 97 98 FF 95 95 95 FF 8F 8F 8F FF 88 88'
+ '88 FF 83 83 83 FF 88 88 88 EC 00 00 00 20 AB AB'
+ 'AB FF C1 C1 C1 FF B7 B7 B7 FF B0 B0 B0 FF A9 A9'
+ 'A9 FF A3 A3 A3 FF A0 A0 A0 FF 9D 9D 9D FF 99 99'
+ '99 FF 95 95 95 FF 93 93 93 FF 8E 8E 8E FF 8C 8C'
+ '8C FF 86 86 86 FF A0 A0 A0 F5 00 00 00 3D A5 A5'
+ 'A5 FF CF CF CF FF C5 C5 C5 FF BC BC BB FF B3 B3'
+ 'B3 FF AD AD AD FF A7 A7 A7 FF A4 A4 A4 FF A0 A0'
+ 'A0 FF 9A 9A 9A FF 98 98 98 FF 94 94 94 FF 90 90'
+ '90 FF 8C 8C 8C FF 92 92 92 FA 4C 4C 4C 67 8A 8A'
+ '8A FF 9E 9E 9D FF 9A 99 99 FF 92 92 92 FF 8B 8B'
+ '8A FF 85 85 85 FF 82 82 82 FF 86 86 86 FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9B 9B 9B FF 98 98 98 FF 93 93'
+ '93 FF 8F 8F 8F FF 8A 8A 8A FC 77 77 77 82 98 99'
+ '9B FE 86 88 8C FF 80 82 85 FF 79 7B 7E FF 73 75'
+ '78 FF 6F 71 74 FF 6F 70 72 FF 71 71 71 FF 72 72'
+ '72 FF 71 71 71 FF 6F 6F 6F FF 6C 6C 6C FF 68 68'
+ '68 FF 65 65 65 FD 89 89 89 D5 6C 6C 6C 42 DC D9'
+ 'D2 FF A0 99 8C FF 8A 84 78 FF 7A 75 6C FF 75 72'
+ '6D FF 7B 79 7B FF 82 81 85 FF 7E 7E 7F FC 7D 7D'
+ '7D FA 7B 7B 7B FA 79 79 79 FA 75 75 75 FA 6F 6F'
+ '6F FA 6F 6F 6F F3 83 83 83 5B 00 00 00 00 F8 F7'
+ 'E9 7F FE EE C7 FF FB E6 BF FF F2 DE B8 FF DF CC'
+ 'A6 FF C7 B2 89 FF BD A5 77 FF D1 C5 B0 FE E9 E9'
+ 'E9 40 E9 E9 E9 40 E8 E8 E8 40 E8 E8 E8 40 E7 E7'
+ 'E7 40 E7 E7 E7 40 EE EE EE 3F B3 B3 B3 1E 00 00'
+ '00 00 FE EE C7 40 FB E6 BF 40 F2 DE B8 40 DF CC'
+ 'A6 40 C7 B2 89 40 BD A5 77 40 C4 B0 87 2C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 00 01 00 00 00 01 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00'
+ '00 00 80 FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 08 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 70 00 07 88 88 88 88 88 78 87 87 87'
+ '87 87 87 87 80 00 07 88 8F FF FF FF FF FF FF FF'
+ 'FF F8 88 88 70 00 07 88 FF F4 FF F4 F4 FF FF FF'
+ 'FF FF 88 88 87 00 07 88 FF F4 F4 4F 44 FF 44 4F'
+ '4F FF 88 88 87 00 08 78 FF FF 4F FF FF 4F 4F F4'
+ 'FF FF 88 88 87 00 08 78 8F FF FF FF FF FF FF FF'
+ 'FF F8 88 88 87 00 08 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 08 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 87 08 77 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 87 08 77 77 77 77 77 77 77 78 88'
+ '88 88 88 88 88 87 08 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 70 08 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 78 00 00 F6 66 66 66 66 66 88 88 88'
+ '88 88 88 88 80 00 00 FE 6E 6E 6E 6E 6E 80 00 00'
+ '00 00 00 00 00 00 00 0F EF EF EF EF EF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 80 00'
+ '00 07 80 00 00 07 80 00 00 07 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 01 80 00 00 01 80 00 00 01 80 00 00 01 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 01 80 00'
+ '00 03 C0 00 00 07 C0 01 FF FF E0 03 FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 20 00 00 00 40 00'
  '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 64 64 64 00 66 66 66 00 69 69'
+ '69 00 6A 6A 6A 00 6C 6C 6C 00 6F 6F 6F 00 70 70'
+ '70 00 70 71 71 00 71 71 71 00 72 72 72 00 73 73'
+ '73 00 74 74 74 00 76 76 76 00 77 77 77 00 78 78'
+ '78 00 79 79 79 00 79 7A 7B 00 7A 7A 7A 00 7B 7B'
+ '7B 00 7B 7B 7D 00 7A 7B 7E 00 7B 7C 7C 00 7C 7C'
+ '7C 00 7C 7D 7D 00 7D 7D 7D 00 7C 7C 7F 00 7C 7D'
+ '7F 00 7D 7E 7E 00 7E 7E 7E 00 7F 7F 7F 00 81 7F'
+ '7D 00 A5 7C 61 00 8B 87 7E 00 8D 88 7F 00 A8 82'
+ '68 00 B0 8C 6F 00 B1 8E 6F 00 B2 90 70 00 B8 97'
+ '7B 00 B8 98 7E 00 7F 7F 80 00 FF 00 FF 00 7F 80'
+ '80 00 80 80 80 00 81 81 81 00 80 81 83 00 81 82'
+ '82 00 82 82 82 00 82 82 83 00 83 83 83 00 83 83'
+ '84 00 83 84 84 00 84 84 84 00 85 85 84 00 85 85'
+ '85 00 86 86 85 00 85 85 86 00 84 85 87 00 86 85'
+ '86 00 86 86 86 00 87 87 87 00 87 88 8A 00 88 88'
+ '88 00 88 88 89 00 89 89 89 00 8A 8A 8A 00 8B 8B'
+ '8B 00 8B 8D 8F 00 8C 8C 8C 00 8E 8E 8E 00 93 8E'
+ '84 00 99 94 8A 00 9D 97 8C 00 8F 90 93 00 90 90'
+ '90 00 92 90 90 00 93 92 91 00 92 92 92 00 93 93'
+ '93 00 93 94 96 00 94 94 94 00 95 94 94 00 95 95'
+ '95 00 96 96 96 00 98 98 98 00 9B 99 99 00 98 99'
+ '9B 00 9A 9A 9A 00 9C 9B 9B 00 9A 9B 9D 00 9C 9C'
+ '9C 00 9D 9D 9D 00 9E 9E 9E 00 BB 9C 81 00 A0 9D'
+ '98 00 A0 9F 9F 00 B1 A3 86 00 B9 AB 8E 00 BE AD'
+ '8C 00 A6 A1 93 00 AA A3 96 00 B0 A9 9B 00 9F 9F'
+ 'A0 00 A0 A0 A0 00 A2 A2 A1 00 A2 A2 A2 00 A4 A4'
+ 'A3 00 A3 A3 A4 00 A4 A4 A4 00 A6 A6 A6 00 A8 A8'
+ 'A8 00 AA AA A9 00 AA AA AA 00 AC AB AB 00 AB AB'
+ 'AD 00 AB AC AC 00 AC AC AC 00 AE AE AE 00 B7 B1'
+ 'A2 00 B0 B0 B0 00 B2 B2 B2 00 B3 B3 B4 00 B4 B4'
+ 'B4 00 B7 B7 B7 00 B9 B9 B7 00 B8 B8 B8 00 BA BA'
+ 'BA 00 BC BC BC 00 BD BD BD 00 BE BD BC 00 BE BE'
+ 'BE 00 C1 A6 8C 00 C4 A8 91 00 C5 AA 93 00 C1 B2'
+ '96 00 C5 B7 99 00 CB B2 9E 00 CB BD A0 00 CF BA'
+ 'A7 00 C0 B7 A9 00 C0 B8 A9 00 CE B9 A8 00 D0 BB'
+ 'A7 00 D2 BF AD 00 D0 C2 A7 00 D5 C7 AB 00 D6 C3'
+ 'B3 00 DB CC B1 00 DE D0 B4 00 E5 DA B7 00 E1 D3'
+ 'B8 00 E4 D6 BB 00 E3 DB BC 00 E8 DF BE 00 C0 C0'
+ 'C0 00 C2 C1 C0 00 C2 C2 C2 00 C4 C4 C4 00 C7 C6'
+ 'C6 00 C7 C7 C8 00 CA CA CA 00 CC CC CC 00 CF CD'
+ 'CF 00 DD CF C2 00 D9 D5 CA 00 D3 D2 D0 00 D2 D2'
+ 'D2 00 D5 D5 D5 00 D6 D6 D6 00 D9 D9 D9 00 DF DD'
+ 'DA 00 DE DE DD 00 DE DE DE 00 E0 D2 C5 00 E1 D3'
+ 'C7 00 E3 D7 CC 00 E5 D8 CE 00 E2 D9 D1 00 E4 D9'
+ 'D0 00 E7 DB D1 00 E7 DE D5 00 E6 DE D7 00 E8 DE'
+ 'D5 00 E5 DE D9 00 E6 DF DC 00 EB E2 C1 00 EC E6'
+ 'C7 00 EF E8 CF 00 E9 E0 D7 00 E1 E0 DF 00 E6 E2'
+ 'DD 00 EB E3 DB 00 ED E5 DE 00 ED E6 DF 00 EF E6'
+ 'DF 00 F1 EB D6 00 F3 ED D9 00 E1 E1 E1 00 E7 E6'
+ 'E6 00 EC E6 E1 00 EE E6 E0 00 ED E7 E2 00 EE E7'
+ 'E2 00 EF E8 E1 00 EE E8 E2 00 EF EA E3 00 EE E8'
+ 'E4 00 EC E9 E6 00 F0 EA E5 00 F1 EC E6 00 F3 ED'
+ 'E6 00 F1 EC E8 00 F2 ED E8 00 F2 EE E9 00 F3 EE'
+ 'EA 00 F0 EF EC 00 F0 EF EE 00 F6 F0 E0 00 F5 F2'
+ 'E5 00 F7 F2 E4 00 F5 F0 EB 00 F0 F0 EE 00 F2 F0'
+ 'EE 00 F5 F0 EC 00 F6 F2 EE 00 F8 F3 E8 00 F9 F6'
+ 'EB 00 F1 F1 F1 00 F2 F1 F0 00 F3 F3 F3 00 F4 F4'
+ 'F4 00 F8 F4 F1 00 F8 F5 F2 00 F9 F7 F5 00 FB F8'
+ 'F5 00 FB F8 F6 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 89'
+ '77 45 40 3D 3E 3A 39 39 39 38 36 35 34 32 27 27'
+ '26 25 21 1F 20 1C 1B 1B 1C 1C 46 00 00 00 00 07'
+ 'B6 88 81 7A 79 74 74 72 69 66 62 5F 5D 5B 56 55'
+ '4F 4E 4A 41 36 3B 48 48 46 44 49 00 00 00 00 69'
+ '88 A8 C1 C6 C6 CB D8 D8 DA DB DE DF E6 E0 E8 DF'
+ 'DC D7 D3 D1 C8 86 35 19 17 42 3C 00 00 00 00 4F'
+ '7D C7 E9 98 E6 DF D7 E0 D4 B9 C0 CA BE E0 D7 DE'
+ 'F1 E9 D4 C9 D5 EE 5F 1A 20 4A 35 26 00 00 00 39'
+ '70 B4 F5 97 8E 29 2C 2D 2F B8 9C BD CC 67 99 8D'
+ '2E 92 BA F1 F1 F4 8B 26 1B 41 3D 19 00 00 00 3B'
+ '75 AF F2 AD 31 D5 F1 F3 CB 94 2F B7 DC 8F BC B7'
+ '30 F1 EA EA EA F5 A5 39 22 3E 57 1B 00 00 00 39'
+ '61 88 B6 F0 C2 BF E8 E8 EA EF EF E7 ED E1 BB D9'
+ 'ED E2 E1 E2 E7 D0 66 40 39 26 5D 19 00 00 00 45'
+ '57 A6 89 A7 A6 8C 89 89 89 88 88 86 84 83 82 81'
+ '81 7F 7A 7A 7A 71 4C 46 3C 36 54 13 00 00 00 57'
+ '44 B0 8C 88 85 81 7E 7A 77 76 75 69 71 66 64 61'
+ '5D 5D 58 54 54 4F 4F 4B 46 3A 4C 49 22 00 00 5E'
+ '26 B3 A5 89 85 82 81 7C 79 76 75 73 72 66 64 61'
+ '5E 5D 5C 57 54 54 4E 4E 4B 42 3E 57 20 00 00 72'
+ '16 CF A7 07 89 85 83 7F 7A 77 76 75 66 66 66 61'
+ '62 5E 5E 5C 58 57 4F 54 4B 4A 3E 5E 12 00 00 76'
+ '17 B6 A9 A6 07 86 84 81 7E 79 77 75 72 70 66 64'
+ '64 62 5E 5E 5D 5C 54 54 4F 4F 42 4F 22 00 00 7B'
+ '21 B2 AB A9 A6 8C 88 84 7F 7B 76 73 73 70 66 65'
+ '65 61 62 61 5D 5D 5D 58 4F 4F 49 4B 61 22 00 7B'
+ '4B AA B1 AA A9 A6 8C 87 82 7F 78 77 73 70 66 65'
+ '64 62 64 61 61 5D 5D 5A 54 4E 4C 4C 70 22 00 81'
+ '62 4C 7E 7F 7B 77 75 66 62 5D 5A 54 4F 4F 58 66'
+ '69 66 66 66 64 61 5D 58 54 4F 46 54 7D 26 00 8A'
+ '65 58 4C 48 3F 27 20 19 17 15 14 14 14 11 10 35'
+ '46 46 41 40 3E 3B 36 27 1C 18 1C 5C 66 00 00 AC'
+ '7C 63 60 59 53 4D 47 43 37 24 23 1D 1A 1C 1C 19'
+ '18 17 16 16 14 12 0F 0E 0C 0A 14 57 00 00 00 00'
+ 'AE 96 95 80 6F 6E 6D 52 51 50 2B 2A 28 1E 1C 1C'
+ '1C 1B 19 18 16 15 12 0F 0D 0B 58 00 00 00 00 00'
+ 'E4 A1 A0 9E 9D 9B 9A 93 91 90 6B 6A 6C 68 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 EC EB E5 E3 CE CD C5 C4 C3 A3 9F A2 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 02 02 02 00 04 04 04 00 05 06 06 00 06 06'
- '06 00 00 00 0D 00 09 09 09 00 0A 0A 0A 00 0C 0C'
- '0C 00 12 12 12 00 14 14 14 00 15 15 15 00 16 16'
- '16 00 1F 1F 10 00 1D 1D 1D 00 00 00 20 00 00 00'
- '2C 00 00 00 2D 00 21 21 21 00 22 22 22 00 23 23'
- '23 00 24 24 24 00 25 25 25 00 26 26 26 00 38 38'
- '38 00 39 39 39 00 3B 3B 3B 00 43 43 43 00 46 46'
- '46 00 4A 4A 4A 00 54 4C 50 00 53 53 53 00 55 55'
- '55 00 56 56 56 00 59 59 52 00 5A 5A 53 00 5C 5C'
- '55 00 5D 5D 56 00 58 58 58 00 59 59 59 00 5A 58'
- '59 00 5A 5A 5A 00 5B 5B 5B 00 5C 5C 5C 00 5D 5D'
- '5D 00 5E 5E 5E 00 65 58 5F 00 60 60 60 00 61 61'
- '61 00 62 62 62 00 64 64 64 00 67 67 67 00 69 69'
- '69 00 71 71 71 00 72 72 72 00 73 73 73 00 75 75'
- '75 00 78 78 78 00 7A 7A 7A 00 7B 7B 7B 00 7C 7C'
- '7C 00 7F 7F 7F 00 24 A7 64 00 3C AD 74 00 25 DC'
- '7F 00 7C 7C A3 00 00 00 C9 00 00 00 CD 00 00 00'
- 'D3 00 00 00 D8 00 00 00 FF 00 2B 2B FF 00 7D AA'
- '94 00 81 81 81 00 83 83 83 00 89 89 89 00 8A 8A'
- '8A 00 8B 8B 8B 00 8F 8F 8F 00 91 89 8C 00 90 90'
- '90 00 91 91 91 00 94 94 94 00 95 95 95 00 97 97'
- '97 00 99 99 99 00 9A 9A 9A 00 9C 9C 9C 00 9D 9D'
- '9D 00 9E 9E 9E 00 9F 9F 9F 00 94 B6 A4 00 93 BD'
- 'A9 00 A0 A0 A0 00 A1 A1 A1 00 A3 A3 A3 00 A4 A4'
- 'A4 00 A5 A5 A5 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
- 'AA 00 AC AC AC 00 AD AD AD 00 AE AE AE 00 AF AF'
- 'AF 00 B8 B8 A7 00 AA AA BC 00 AD B9 B3 00 B0 B0'
- 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
- 'B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B9 B9'
- 'B9 00 BC BC BC 00 BD BD BD 00 BE BE BE 00 BF BF'
- 'BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C0 C1 00 C2 C2'
- 'C2 00 C3 C3 C3 00 C4 C1 C2 00 C5 C2 C4 00 C4 C4'
- 'C4 00 C5 C5 C5 00 C6 C5 C6 00 C6 C6 C6 00 C8 C3'
- 'C5 00 CC C4 C8 00 C8 C8 C8 00 C9 C9 C9 00 CB C9'
- 'CA 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
- 'CD 00 CE CE CE 00 CF CF CF 00 D2 C1 CA 00 D3 C8'
- 'CD 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3'
- 'D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7'
- 'D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA DA 00 DB DB'
- 'DB 00 DC DC DC 00 DD DD DD 00 DE DE DE 00 DF DF'
- 'DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3'
- 'E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7'
- 'E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
- 'EB 00 EC EC EC 00 ED ED ED 00 EE EE EE 00 EF EF'
- 'EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2 F2 00 F4 F4'
- 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
- 'F8 00 F9 F9 F9 00 FC FC FC 00 FD FD FD 00 FF FF'
- 'FF 00 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 6E 65 74 64 72 69 76 65 32'
- '2E 69 63 6F 00 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 42 45 BD 00 45'
- '42 BD 00 00 00 00 00 00 00 00 00 00 00 00 BD BD'
- 'BD BD BD BD BD BD BD BD BD BD BD 05 46 43 43 46'
- '05 BD BD BD BD BD BD BD BD BD BD BD BD BD 6E 6E'
- '6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 69 41 46 46 41'
- '69 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 47 46 46 47'
- 'BD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 44 46 6A 6A 46'
- '44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 BD BD BD BD BD BD BD BD BD 10 0F 0D 0D 0F'
- '11 BD BD BD BD BD BD BD BD 00 00 00 00 00 00 00'
- '00 BD BD 0A 2D 2D 33 32 31 2F 2D 25 24 21 20 23'
- '22 26 26 26 21 28 2E 1E 06 BD 00 00 00 00 00 00'
- '00 BD 0A 79 B5 AB 63 70 74 7A 91 93 97 98 9D 9D'
- '9C 9E 9B 99 8D 84 3F 5C 4F 03 BD 00 00 00 00 00'
- '00 BD 21 B7 A7 A5 0E 1D 3A 4D 58 5F 68 64 5A 57'
- '64 72 61 54 90 48 40 3E 8F 17 BD 00 00 00 00 00'
- '00 BD 2C B3 A8 A4 1F 3B 4C 52 5F 63 70 64 53 50'
- '5D 6C 56 4B 88 7B 5B 6B 7E 17 BD 00 00 00 00 00'
- '00 BD 2A B4 AA A9 2B 36 4A 4E 5A 61 6F 5E 39 35'
- '4D 5D 49 33 8A 82 85 7F 79 16 BD 00 00 00 00 00'
- '00 BD 2A B6 AD A9 49 50 56 5D 63 66 70 65 57 55'
- '5F 67 58 51 86 81 7A 7A 7D 15 BD 00 00 00 00 00'
- '00 BD 29 B8 B1 B0 BA B9 B5 B3 AF AD AA A8 AB A9'
- 'A5 A1 A1 A1 97 95 93 8A 80 14 BD 00 00 00 00 00'
- '00 BD 27 BC B0 AE AD A8 A8 A7 A8 A8 A9 A8 A8 A8'
- 'A8 A8 A8 A7 AA AE AD B9 96 12 BD 00 00 00 00 00'
- '00 BD 2C BC 83 6D 75 99 98 98 98 98 97 97 97 97'
- '98 98 98 99 92 71 71 97 B6 17 BD 00 00 00 00 00'
- '00 BD 1B BC 68 73 62 92 98 96 94 92 95 96 96 95'
- '92 93 95 9B 74 6E 63 86 A9 0E BD 00 00 00 00 00'
- '00 BD 14 A9 8D 91 83 91 8D 9A A5 A4 A7 AB AB A8'
- 'A5 A6 9C 8E 8E 8E 80 99 77 07 BD 00 00 00 00 00'
- '00 BD 09 92 92 8B 8C 8C AA A7 9B 99 98 97 97 98'
- '99 9C A7 AA 91 89 8C A3 54 BD BD 00 00 00 00 00'
- '00 BD 01 60 99 87 8C A6 94 8D 91 91 8E 91 91 91'
- '91 91 8C 8E A7 8E 83 AA 30 BD BD 00 00 00 00 00'
- '00 BD BD 38 A5 87 9B 93 8D 91 8E 91 8C 89 8A 8A'
- '8A 8A 8A 89 8B 9B 7D B0 19 BD BD 00 00 00 00 00'
- '00 00 BD 1C AB 8E 99 8D 91 91 91 91 91 8B 7C 7D'
- '80 81 81 81 7D 8C 81 AC 0B BD 00 00 00 00 00 00'
- '00 00 BD 13 AF 92 92 93 92 92 92 92 92 93 8C 80'
- '79 78 77 79 79 79 83 97 01 BD 00 00 00 00 00 00'
- '00 00 BD 02 9F 9A 8B 99 97 98 98 98 98 98 98 99'
- '98 95 91 8B 87 73 87 6F BD BD 00 00 00 00 00 00'
- '00 00 BD BD 81 A4 94 94 9F 9D 9C 9C 9C 9C 9C 9C'
- '9D 9D 9E A0 97 94 9E 4B BD BD 00 00 00 00 00 00'
- '00 00 00 BD 51 A7 A4 96 97 A1 A4 A2 A2 A2 A2 A2'
- 'A2 A4 A0 99 93 A8 99 26 BD 00 00 00 00 00 00 00'
- '00 00 00 BD 33 A7 A8 A8 A0 92 9A A3 A4 A5 A5 A4'
- 'A3 9A 92 A0 A9 AC 8D 18 BD 00 00 00 00 00 00 00'
- '00 00 00 BD 1A 9E AB 9A AD AF A7 A3 A2 9F 9F A2'
- 'A3 A5 AF A5 9C B2 83 0E BD 00 00 00 00 00 00 00'
- '00 00 00 BD 17 9F 7A 66 81 B3 B1 B1 B1 B0 B0 B1'
- 'B1 B1 AE 71 66 A8 76 0C BD 00 00 00 00 00 00 00'
- '00 00 00 BD 08 59 AD A5 B6 BB BA BA BA BA BA BA'
- 'BA BA BA B2 A7 A6 37 BD BD 00 00 00 00 00 00 00'
- '00 00 00 BD BD 0C 38 3B 3A 39 39 39 39 39 39 39'
- '39 39 39 3A 3C 34 04 BD 00 00 00 00 00 00 00 00'
- '00 00 00 00 BD BD BD BD BD BD BD BD BD BD BD BD'
- 'BD BD BD BD BD BD BD 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
- '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF FF F8'
- '1F FF F0 00 00 1F E0 00 00 0F E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 06 06 06 00 09 09'
- '09 00 19 19 19 00 22 22 22 00 26 26 26 00 3F 3F'
- '3F 00 5F 5F 5F 00 6B 6B 6B 00 6C 6C 6C 00 75 75'
- '75 00 7E 7E 7E 00 7F 7F 7F 00 00 00 FF 00 8A 8A'
- '8A 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F 8F 00 94 94'
- '94 00 99 99 99 00 9C 9C 9C 00 A3 A3 A3 00 A4 A4'
- 'A4 00 A5 A5 A5 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
- 'A9 00 AB AC AC 00 B3 B4 B3 00 B5 B5 B5 00 B7 B7'
- 'B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BD BD'
- 'BD 00 BF BF BF 00 91 D8 B5 00 C0 C0 C0 00 C2 C2'
- 'C2 00 C3 C3 C3 00 C6 C3 C5 00 C4 C4 C4 00 C5 C5'
- 'C5 00 C8 C8 C8 00 C9 C9 C9 00 CA CA CA 00 CB CB'
- 'CB 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
- 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D7 D7'
- 'D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA DA 00 DB DB'
- 'DB 00 DC DC DC 00 DF DF DF 00 E1 E1 E1 00 E2 E2'
- 'E2 00 E4 E4 E4 00 E5 E5 E5 00 E7 E7 E7 00 EB EB'
- 'EB 00 EC EC EC 00 ED ED ED 00 EE EE EE 00 EF EF'
- 'EF 00 F0 F0 F0 00 F1 F1 F1 00 F3 F3 F3 00 F4 F4'
- 'F4 00 F5 F5 F5 00 F6 F6 F6 00 00 00 00 00 8F 8F'
- '8F 00 91 89 8C 00 90 90 90 00 91 91 91 00 94 94'
- '94 00 95 95 95 00 97 97 97 00 99 99 99 00 9A 9A'
- '9A 00 9C 9C 9C 00 9D 9D 9D 00 9E 9E 9E 00 9F 9F'
- '9F 00 94 B6 A4 00 93 BD A9 00 A0 A0 A0 00 A1 A1'
- 'A1 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A8 A8'
- 'A8 00 A9 A9 A9 00 AA AA AA 00 AC AC AC 00 AD AD'
- 'AD 00 AE AE AE 00 AF AF AF 00 B8 B8 A7 00 AA AA'
- 'BC 00 AD B9 B3 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
- 'B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6'
- 'B6 00 B7 B7 B7 00 B9 B9 B9 00 BC BC BC 00 BD BD'
- 'BD 00 BE BE BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1'
- 'C1 00 C2 C0 C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1'
- 'C2 00 C5 C2 C4 00 C4 C4 C4 00 C5 C5 C5 00 C6 C5'
- 'C6 00 C6 C6 C6 00 C8 C3 C5 00 CC C4 C8 00 C8 C8'
- 'C8 00 C9 C9 C9 00 CB C9 CA 00 CA CA CA 00 CB CB'
- 'CB 00 CC CC CC 00 CD CD CD 00 CE CE CE 00 CF CF'
- 'CF 00 D2 C1 CA 00 D3 C8 CD 00 D0 D0 D0 00 D1 D1'
- 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
- 'D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9'
- 'D9 00 DA DA DA 00 DB DB DB 00 DC DC DC 00 DD DD'
- 'DD 00 DE DE DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1'
- 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
- 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
- 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
- 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
- 'F1 00 F2 F2 F2 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
- 'F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9 F9 00 FC FC'
- 'FC 00 FD FD FD 00 FF FF FF 00 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 6E'
- '65 74 64 72 69 76 65 32 2E 69 63 6F 00 00 14 1A'
- '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
- '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
- '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
- '95 00 00 00 00 00 4D 4D 4D 4D 4D 4D 4D 0D 0D 4D'
- '4D 4D 4D 4D 4D 4D 25 25 25 25 25 25 25 0D 0D 25'
- '25 25 25 25 25 25 00 00 00 4D 4D 4D 4D 4D 4D 4D'
- '4D 4D 4D 4D 00 00 00 00 05 2F 2F 2C 2A 26 25 23'
- '21 1C 1B 02 00 00 00 4D 33 41 07 11 18 20 1F 12'
- '1E 28 24 10 00 00 00 4D 33 42 09 0E 15 20 17 08'
- '16 2B 26 10 00 00 00 4D 35 4C 4B 4A 49 48 47 46'
- '45 44 42 0F 00 00 00 4D 39 1A 27 37 37 36 36 37'
- '37 19 1D 14 00 00 00 00 0B 31 33 3C 3D 3B 3B 3D'
- '3D 32 33 06 00 00 00 00 04 2D 3F 33 32 2F 30 30'
- '30 3E 2C 4D 00 00 00 00 4D 33 33 33 33 33 27 29'
- '29 29 2E 4D 00 00 00 00 4D 3A 34 39 39 39 39 39'
- '39 31 2D 4D 00 00 00 00 4D 2C 3F 34 40 3F 3F 40'
- '34 3F 19 4D 00 00 00 00 4D 13 22 43 45 43 43 45'
- '3F 33 0A 4D 00 00 00 00 00 03 35 37 37 37 37 37'
- '38 2F 01 00 00 00 00 00 00 00 4D 4D 4D 4D 4D 4D'
- '4D 4D 00 00 00 00 00 00 00 00 00 00 00 00 E0 03'
- '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
- '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
- '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
- '00 00 00 00 0C C0 0C C0 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 CC CC 00 00 00 00 00 00 00 77 77'
- '77 77 77 77 77 8C C8 77 77 77 77 77 77 77 00 00'
- '00 00 00 00 00 CC CC 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 0C C7 7C C0 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 88 88 88 88 88 88 88 88 88 88 00 00 00 00 00'
- '07 FF 77 77 77 77 77 77 77 77 67 80 00 00 00 00'
- '8F FF 08 88 87 77 88 77 78 78 66 70 00 00 00 00'
- '8F FF 88 88 77 77 88 77 88 77 77 70 00 00 00 00'
- '8F FF 88 88 87 77 88 87 88 77 77 70 00 00 00 00'
- '8F FF 88 87 77 77 88 77 88 77 77 70 00 00 00 00'
- '8F FF FF FF FF FF FF FF FF 77 77 70 00 00 00 00'
- '8F FF FF FF FF FF FF FF FF FF FF 70 00 00 00 00'
- '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
- '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
- '0F 77 77 77 FF FF FF FF 77 77 77 70 00 00 00 00'
- '07 77 77 FF 77 77 77 77 FF 77 7F 80 00 00 00 00'
- '07 77 7F 77 77 77 77 77 77 F7 7F 80 00 00 00 00'
- '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
- '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
- '00 F7 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
- '00 77 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
- '00 7F 77 77 77 77 77 77 77 77 78 00 00 00 00 00'
- '00 8F F7 7F FF FF FF FF 77 7F 78 00 00 00 00 00'
- '00 8F FF 77 7F FF FF F7 77 FF 70 00 00 00 00 00'
- '00 07 F7 FF FF F7 7F FF FF 7F 70 00 00 00 00 00'
- '00 07 77 7F FF FF FF FF F7 7F 70 00 00 00 00 00'
- '00 08 FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
- '00 00 88 88 88 88 88 88 88 88 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
- '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF FF F8'
- '1F FF F0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 0C C0 00 00 00 77 77'
- '77 7C C7 77 77 77 00 00 00 00 00 00 00 00 00 07'
- '77 77 77 77 70 00 00 7F 88 77 78 77 78 00 00 7F'
- '88 77 78 77 78 00 00 7F FF FF FF FF F8 00 00 77'
- '77 77 77 77 78 00 00 87 77 F7 7F F7 70 00 00 07'
- 'F7 77 77 7F 70 00 00 07 77 77 77 77 70 00 00 07'
- '77 77 77 77 70 00 00 07 F7 FF FF 7F 70 00 00 08'
- '7F FF FF F7 80 00 00 00 77 77 77 77 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 03'
- '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
- '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
- '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
- '00 00 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF 00 00 00 9C 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 00 00 FF FF 00 00'
- 'FF FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 80 00 00 07 80 00 00 07 80 00'
+ '00 07 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 01 80 00 00 01 80 00'
+ '00 01 80 00 00 01 80 00 00 00 80 00 00 00 80 00'
+ '00 00 80 00 00 01 80 00 00 03 C0 00 00 07 C0 00'
+ 'FF FF E0 01 FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF 00 00 00 3C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 01 00 00 00 04 00 00 00 09 00 00'
- '00 09 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
- '00 09 00 00 FF FF 00 00 FF FF C0 C0 C0 FF C0 C0'
- 'C0 FF 00 00 FF FF 00 00 FF FF 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 05 00 00 00 C5 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F1 00 00 00 B1 00 00 00 0D 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00'
- '00 9B 00 00 00 FF 21 21 21 FF 2B 2B 2B FF 2C 2C'
- '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
- '2D FF 13 13 13 FF 00 00 00 FF 00 00 00 69 00 00'
- '00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 AD 01 01'
- '01 FF EB EB EB FF E8 E8 E8 FF D5 D5 D5 FF 85 85'
- '85 FF 92 92 92 FF 98 98 98 FF AD AD AD FF BA BA'
- 'BA FF C3 C3 C3 FF C6 C6 C6 FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF D3 D3 D3 FF D7 D7 D7 FF CC CC'
- 'CC FF C7 C7 C7 FF C8 C9 C9 FF 9D B3 A8 FF 20 A8'
- '63 FF 90 AF A0 FF BF BB BD FF 00 00 00 FF 00 00'
- '00 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F0 19 19'
- '19 FF EC EC EC FF E2 E2 E2 FF CB CB CB FF 3B 3B'
- '3B FF 56 56 56 FF 72 72 72 FF 92 92 92 FF 9D 9D'
- '9D FF A8 A8 A8 FF AC AC AC FF A9 A9 A9 FF 9C 9C'
- '9C FF 99 99 99 FF B7 B7 B7 FF C3 C3 C3 FF A3 A3'
- 'A3 FF 98 98 98 FF C5 C4 C4 FF 51 A7 7C FF 17 CE'
- '71 FF 2F 99 64 FF C3 BD C0 FF 01 01 01 FF 00 00'
- '00 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 28 28'
- '28 FF EC EC EC FF E6 E6 E6 FF D1 D1 D1 FF 68 68'
- '68 FF 7E 7E 7E FF 85 85 85 FF 97 97 97 FF A0 A0'
- 'A0 FF AA AA AA FF AE AE AE FF 9F 9F 9F FF 83 83'
- '83 FF 7C 7C 7C FF A8 A8 A8 FF BB BB BB FF 8A 8A'
- '8A FF 79 79 79 FF C2 C2 C2 FF C6 C3 C4 FF 99 AC'
- 'A2 FF C2 BE C0 FF C4 C4 C4 FF 01 01 01 FF 00 00'
- '00 BA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 28 28'
- '28 FF EE EE EE FF E7 E7 E7 FF D6 D6 D6 FF 70 70'
- '70 FF 7D 7D 7D FF 85 85 85 FF 97 97 97 FF A0 A0'
- 'A0 FF AA AA AA FF AE AE AE FF 98 98 98 FF 73 73'
- '73 FF 6A 6A 6A FF A0 A0 A0 FF B7 B7 B7 FF 7C 7C'
- '7C FF 67 67 67 FF C2 C2 C2 FF C4 C3 C4 FF C7 C4'
- 'C5 FF BF BF BF FF C5 C5 C5 FF 01 01 01 FF 00 00'
- '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 27 27'
- '27 FF F2 F2 F2 FF EB EB EB FF DF DF DF FF A7 A7'
- 'A7 FF AB AB AB FF AE AE AE FF B3 B3 B3 FF B6 B6'
- 'B6 FF B9 B9 B9 FF BA BA BA FF B7 B7 B7 FF B1 B1'
- 'B1 FF AF AF AF FF BA BA BA FF BE BE BE FF B0 B0'
- 'B0 FF AB AB AB FF C5 C5 C5 FF C6 C6 C6 FF C4 C4'
- 'C4 FF C2 C2 C2 FF C9 C9 C9 FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 26 26'
- '26 FF F3 F3 F3 FF EB EB EB FF EA EA EA FF ED ED'
- 'ED FF E9 E9 E9 FF E8 E8 E8 FF E4 E4 E4 FF E2 E2'
- 'E2 FF DF DF DF FF DE DE DE FF DB DB DB FF DC DC'
- 'DC FF D9 D9 D9 FF D6 D6 D6 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D0 D0 D0 FF CB CB CB FF C9 C9 C9 FF C7 C7'
- 'C7 FF C0 C0 C0 FF CA CA CA FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 24 24'
- '24 FF FF FF FF FF E9 E9 E9 FF E2 E2 E2 FF E2 E2'
- 'E2 FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E3 E3 E3 FF E3 E3'
- 'E3 FF F8 F8 F8 FF EF EF EF FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FA 24 24'
- '24 FF F8 F8 F8 FF D9 D9 D9 FF BB BB BB FF BF BF'
- 'BF FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF DB DB DB FF BC BC BC FF BB BB'
- 'BB FF DE DE DE FF FF FF FF FF 00 00 00 FF 00 00'
- '00 BA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 D0 05 05'
- '05 FF F6 F6 F6 FF BC BC BC FF C3 C3 C3 FF AB AB'
- 'AB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
- 'D4 FF D3 D3 D3 FF D5 D5 D5 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3 D3 FF D4 D4'
- 'D4 FF D7 D7 D7 FF C9 C9 C9 FF C3 C3 C3 FF B3 B3'
- 'B3 FF D6 D6 D6 FF F5 F5 F5 FF 00 00 00 FF 00 00'
- '00 8C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 00 00'
- '00 FF F4 F4 F4 FF CF CF CF FF D2 D2 D2 FF BF BF'
- 'BF FF D3 D3 D3 FF D2 D2 D2 FF D3 D3 D3 FF DD DD'
- 'DD FF E3 E3 E3 FF E6 E6 E6 FF ED ED ED FF ED ED'
- 'ED FF E7 E7 E7 FF E4 E4 E4 FF DE DE DE FF D4 D4'
- 'D4 FF D2 D2 D2 FF D3 D3 D3 FF D0 D0 D0 FF C2 C2'
- 'C2 FF D9 D9 D9 FF E8 E8 E8 FF 00 00 00 FF 00 00'
- '00 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
- '00 FF E9 E9 E9 FF D0 D0 D0 FF CD CD CD FF CD CD'
- 'CD FF D6 D6 D6 FF ED ED ED FF DC DC DC FF D4 D4'
- 'D4 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5 D5 FF DB DB'
- 'DB FF ED ED ED FF DA DA DA FF CD CD CD FF CD CD'
- 'CD FF DF DF DF FF B8 B8 B8 FF 00 00 00 FB 00 00'
- '00 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
- '00 FE D7 D7 D7 FF D2 D2 D2 FF CB CB CB FF CA CA'
- 'CA FF E9 E9 E9 FF DC DC DC FF D1 D1 D1 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D1 D1'
- 'D1 FF D8 D8 D8 FF EA EA EA FF C9 C9 C9 FF CA CA'
- 'CA FF E0 E0 E0 FF A0 A0 A0 FF 00 00 00 EB 00 00'
- '00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 E1 9F 9F 9F FF DD DD DD FF CD CD CD FF DB DB'
- 'DB FF CE CE CE FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF C8 C8 C8 FF DA DA DA FF C7 C7'
- 'C7 FF E2 E2 E2 FF 5A 5A 5A FF 00 00 00 94 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 B2 83 83 83 FF DD DD DD FF D1 D1 D1 FF DB DB'
- 'DB FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF C9 C9 C9 FF C5 C5'
- 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF D3 D3 D3 FF C8 C8'
- 'C8 FF DE DE DE FF 42 42 42 FF 00 00 00 6C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4B 41 41 41 FF D8 D8 D8 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF C7 C7 C7 FF C4 C4 C4 FF C1 C1 C1 FF C0 C0'
- 'C0 FF C1 C1 C1 FF C1 C1 C1 FF BF BF BF FF C0 C0'
- 'C0 FF B2 B2 B2 FF 1A 1A 1A FF 00 00 00 28 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1A 2C 2C 2C FF CC CC CC FF D5 D5 D5 FF CC CC'
- 'CC FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D5 D5 D5 FF CF CF CF FF CC CC'
- 'CC FF C6 C6 C6 FF C4 C4 C4 FF B3 B3 B3 FF BD BD'
- 'BD FF 99 99 99 FF 09 09 09 FF 00 00 00 19 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 08 08 08 FF 97 97 97 FF DF DF DF FF DC DC'
- 'DC FF D6 D6 D6 FF DE DE DE FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DE DE DE FF D8 D8 D8 FF DD DD DD FF DC DC'
- 'DC FF 53 53 53 FF 00 00 00 FF 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 77 77 77 FF E2 E2 E2 FF E1 E1'
- 'E1 FF CE CE CE FF D7 D7 D7 FF E2 E2 E2 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
- 'E1 FF D9 D9 D9 FF CD CD CD FF E3 E3 E3 FF D9 D9'
- 'D9 FF 39 39 39 FF 00 00 00 FF 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF 35 35 35 FF E6 E6 E6 FF E6 E6'
- 'E6 FF E7 E7 E7 FF E7 E7 E7 FF D2 D2 D2 FF D3 D3'
- 'D3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E3 E3 E3 FF E3 E3 E3 FF D4 D4 D4 FF D1 D1'
- 'D1 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 0B 0B 0B FF 00 00 00 ED 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 F9 1E 1E 1E FF E4 E4 E4 FF ED ED'
- 'ED FF E6 E6 E6 FF EC EC EC FF EA EA EA FF E4 E4'
- 'E4 FF DF DF DF FF DF DF DF FF DC DC DC FF DC DC'
- 'DC FF DF DF DF FF DF DF DF FF E2 E2 E2 FF E9 E9'
- 'E9 FF EA EA EA FF E5 E5 E5 FF EB EB EB FF D6 D6'
- 'D6 FF 00 00 00 FF 00 00 00 C3 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 AE 00 00 00 FF E0 E0 E0 FF C4 C4'
- 'C4 FF B8 B8 B8 FF B2 B2 B2 FF F1 F1 F1 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3'
- 'F3 FF B0 B0 B0 FF B6 B6 B6 FF EB EB EB FF CD CD'
- 'CD FF 00 00 00 FF 00 00 00 85 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 80 00 00 00 FF CE CE CE FF DD DD'
- 'DD FF D5 D5 D5 FF E4 E4 E4 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
- 'FA FF DF DF DF FF D8 D8 D8 FF D7 D7 D7 FF B0 B0'
- 'B0 FF 00 00 00 FF 00 00 00 67 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 02 00 00 00 9C 0C 0C 0C FF 3D 3D'
- '3D FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 49 49 49 FF 2F 2F 2F FF 02 02'
- '02 FF 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 06 00 00 00 F1 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -9456,188 +6783,190 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
- '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF F8 00'
- '1F FF F0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
- '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
- '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 1F F8 00'
- '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
- '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
- '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- 'CC 00 00 CC 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 CC C0 0C CC 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '0C CC CC C0 00 00 00 00 00 00 00 00 00 00 88 88'
- '88 88 88 88 88 88 88 88 88 CC CC 88 88 88 88 88'
- '88 88 88 88 88 88 77 77 77 77 77 77 77 77 77 77'
- '77 CC CC 77 77 77 77 77 77 77 77 77 77 77 00 00'
- '00 00 00 00 00 00 00 00 0C CC CC C0 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- 'CC C7 7C CC 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 CC 07 70 CC 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
- '00 08 FF F7 88 88 77 77 77 77 77 77 77 77 77 77'
- '66 87 80 00 00 00 00 00 00 07 FF F7 00 88 88 87'
- '77 77 87 87 77 77 87 78 66 67 80 00 00 00 00 00'
- '00 07 FF F7 88 88 88 77 77 77 87 87 87 87 87 77'
- '77 87 80 00 00 00 00 00 00 07 FF F7 88 88 88 77'
- '77 78 87 87 87 87 87 77 77 77 80 00 00 00 00 00'
- '00 07 FF F7 88 88 88 77 77 78 87 87 87 87 87 77'
- '77 77 80 00 00 00 00 00 00 07 FF F7 88 88 88 87'
- '77 78 87 88 87 87 87 77 77 77 80 00 00 00 00 00'
- '00 07 FF F7 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 77 80 00 00 00 00 00 00 07 FF FF FF FF FF FF'
- '77 77 77 77 77 77 77 77 77 77 80 00 00 00 00 00'
- '00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF F7 80 00 00 00 00 00 00 07 FF FF FF 77 77 7F'
- 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
- '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 7F 80 00 00 00 00 00'
- '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 7F'
- 'FF FF FF FF F7 77 77 77 77 7F 80 00 00 00 00 00'
- '00 08 F7 77 77 77 7F FF 77 77 77 77 FF FF 77 77'
- '77 77 00 00 00 00 00 00 00 08 F7 77 77 7F F7 77'
- '77 77 77 77 77 7F F7 77 77 77 00 00 00 00 00 00'
- '00 00 77 77 77 F7 77 77 77 77 77 77 77 77 7F 77'
- '77 F7 00 00 00 00 00 00 00 00 77 77 7F 77 77 77'
- '77 77 77 77 77 77 77 F7 77 F8 00 00 00 00 00 00'
- '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 F8 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
- '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 70 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
- '00 00 07 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 00 00 07 77 77 77 77 77'
- '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
- '00 00 08 77 77 77 77 77 77 77 77 77 77 77 77 77'
- '77 80 00 00 00 00 00 00 00 00 08 7F F7 77 FF FF'
- 'FF FF FF FF FF FF 77 7F 77 00 00 00 00 00 00 00'
- '00 00 08 7F FF F7 77 FF FF FF FF FF FF 77 7F FF'
- '77 00 00 00 00 00 00 00 00 00 00 7F FF FF 77 77'
- 'FF FF FF FF 77 77 FF FF 78 00 00 00 00 00 00 00'
- '00 00 00 7F FF FF FF FF 77 77 77 77 7F FF FF FF'
- '78 00 00 00 00 00 00 00 00 00 00 8F 77 77 FF FF'
- 'FF FF FF FF FF FF 77 7F 78 00 00 00 00 00 00 00'
- '00 00 00 8F 77 77 FF FF FF FF FF FF FF F7 77 7F'
- '78 00 00 00 00 00 00 00 00 00 00 87 77 7F FF FF'
- 'FF FF FF FF FF FF 77 77 70 00 00 00 00 00 00 00'
- '00 00 00 08 77 77 77 77 77 77 77 77 77 77 77 77'
- '80 00 00 00 00 00 00 00 00 00 00 00 08 88 88 88'
- '88 88 88 88 88 88 88 80 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 8C 8C 8C 14 77 77'
+ '77 5C 4E 4E 4E 82 4C 4C 4C 82 48 4A 4A 82 4A 4A'
+ '4A 82 46 46 48 82 46 46 46 82 46 46 46 82 46 46'
+ '46 82 44 46 46 82 44 44 44 82 42 42 42 82 40 42'
+ '42 82 40 40 42 82 40 40 40 82 40 40 40 82 3E 3E'
+ '3E 82 3C 3E 3E 82 3A 3C 3C 82 38 3A 3A 82 3A 3A'
+ '3A 82 38 38 38 82 36 36 36 82 36 36 36 82 38 38'
+ '38 82 38 38 38 82 2F 2F 2F 65 00 00 00 16 00 00'
+ '00 00 00 00 00 00 00 00 00 00 BC BC BC 50 E3 E3'
+ 'E3 E1 BB BB BB F7 AF AF AF F6 A9 A9 A8 F5 A8 A7'
+ 'A7 F5 A4 A3 A3 F5 A3 A3 A2 F5 A1 A1 A0 F5 9F 9E'
+ '9E F5 9D 9D 9D F5 9B 9A 9A F5 99 97 97 F5 95 94'
+ '94 F5 93 92 92 F5 91 90 8F F5 90 8E 8E F5 8D 8C'
+ '8C F5 8A 8A 8A F5 87 87 87 F5 84 84 83 F5 7F 7F'
+ '7F F6 81 81 81 F7 86 86 86 F7 86 86 86 F7 85 85'
+ '85 F7 84 84 85 FA 7D 7D 7D D1 0C 0C 0C 3F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 73 73 73 6E BA BB'
+ 'BA F7 C7 C6 C6 FF E5 DE D9 FF E9 E0 D7 FF E9 E0'
+ 'D7 FF EE E6 E0 FF EE E8 E4 FF EE E8 E3 FF F0 EA'
+ 'E5 FF F1 EC E6 FF F2 ED E8 FF F2 EE E9 FF F3 EF'
+ 'EB FF F3 EF EB FF F3 EF EB FF F3 EF EA FF F1 EC'
+ 'E8 FF EF EA E3 FF ED E7 E2 FF EC E6 E1 FF E6 E2'
+ 'DD FF B9 B9 B7 FF 80 80 80 FF 79 79 79 FF 77 77'
+ '77 FF 85 85 85 FF 7E 7E 7F EA 2C 2C 2C 62 00 00'
+ '00 00 00 00 00 00 00 00 00 00 55 55 55 78 AB AC'
+ 'AC F9 E1 E0 DF FF F5 F0 EC FF D0 BB A7 FF F5 F0'
+ 'EB FF F2 EE E9 FF EF E9 E3 FF F3 EE EA FF EE E8'
+ 'E2 FF E3 D7 CC FF E8 DE D5 FF ED E5 DE FF E7 DE'
+ 'D5 FF F3 EE EA FF EF E9 E3 FF F3 ED E9 FF F8 F4'
+ 'F1 FF F5 F0 EB FF EE E7 E2 FF EB E3 DB FF EF E8'
+ 'E2 FF F2 F1 F0 FF 99 99 98 FF 7B 7B 7B FF 7C 7C'
+ '7C FF 89 89 89 FF 7E 7E 7E F7 3D 3D 3D 80 00 00'
+ '00 00 00 00 00 00 00 00 00 00 4C 4C 4C 88 9F 9F'
+ 'A0 FC DF DD DA FF FB F8 F6 FF CE B9 A8 FF C4 A8'
+ '91 FF A5 7C 61 FF A8 82 68 FF B0 8C 6F FF B2 91'
+ '70 FF E1 D3 C7 FF D6 C3 B3 FF E7 DB D1 FF EF E6'
+ 'DF FF BB 9C 81 FF D2 BF AD FF C1 A6 8C FF B1 8E'
+ '6F FF CB B2 9E FF E5 D8 CE FF F9 F4 F1 FF F6 F3'
+ 'EF FF FB F9 F5 FF BE BD BC FF 7F 7F 7F FF 7A 7A'
+ '7A FF 86 86 86 FF 83 83 84 FE 45 45 45 A5 00 00'
+ '00 00 00 00 00 00 00 00 00 00 54 54 54 91 A3 A3'
+ 'A4 FD D3 D2 D0 FF F8 F5 F2 FF DD CF C2 FF B8 98'
+ '7E FF EF E8 E1 FF F8 F4 F1 FF F9 F7 F5 FF ED E6'
+ 'DF FF CF BA A7 FF B3 90 71 FF E0 D2 C5 FF F3 ED'
+ 'E6 FF C5 AA 93 FF E4 D9 D0 FF E0 D2 C5 FF B8 97'
+ '7B FF F7 F3 EF FF F6 F2 EF FF F6 F3 EF FF F6 F2'
+ 'EE FF FB F8 F5 FF C2 C1 C0 FF 82 82 82 FF 7D 7D'
+ '7D FF 84 84 84 FF 92 92 92 FE 55 55 55 BA 00 00'
+ '00 00 00 00 00 00 00 00 00 00 58 58 58 99 9A 9A'
+ '9A FE BB BB BB FF DE DE DD FF F4 F4 F4 FF E6 DF'
+ 'DC FF E6 DE D7 FF F2 F1 EE FF F3 F0 EE FF F3 F1'
+ 'EE FF F3 F3 F3 FF F3 F3 F3 FF F1 F0 EF FF F1 F0'
+ 'EF FF F0 EF EE FF E2 D9 D1 FF EC E9 E6 FF F1 F1'
+ 'F1 FF F0 F0 EE FF F0 EF EC FF F0 EF ED FF F1 F0'
+ 'EE FF E7 E6 E6 FF 9E 9E 9E FF 85 85 85 FF 82 82'
+ '82 FF 7E 7E 7E FF 97 97 97 FF 63 63 63 D3 00 00'
+ '00 1F 00 00 00 00 00 00 00 00 61 61 61 9D 92 92'
+ '92 FE C2 C2 C2 FF BC BC BC FF C4 C4 C4 FF C2 C2'
+ 'C2 FF BE BE BE FF BC BC BC FF BB BB BB FF BC BC'
+ 'BC FF BB BB BB FF BA BA BA FF B8 B8 B8 FF B5 B4'
+ 'B5 FF B3 B3 B4 FF B2 B2 B2 FF B0 B0 B0 FF B0 B0'
+ 'B0 FF AC AD AD FF AA AA AA FF AB AB AB FF AA AA'
+ 'AA FF A0 A0 A0 FF 8B 8B 8B FF 87 87 87 FF 83 83'
+ '83 FF 81 81 81 FF 91 91 91 FF 69 69 69 E7 05 05'
+ '05 2F 00 00 00 00 00 00 00 00 77 77 77 A0 86 85'
+ '86 FF D2 D2 D2 FF BE BE BE FF BA BA BA FF B7 B7'
+ 'B7 FF B1 B1 B1 FF AC AC AC FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A4 A4 A4 FF A2 A2 A2 FF A0 A0 A0 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9B 9B 9B FF 9A 9A 9A FF 97 97'
+ '97 FF 95 95 95 FF 93 93 93 FF 91 91 91 FF 8F 8F'
+ '8F FF 8F 8F 8F FF 8D 8D 8D FF 8A 8A 8A FF 87 87'
+ '87 FF 83 83 83 FF 8B 8B 8B FF 88 88 89 FE 09 09'
+ '09 4D 00 00 00 00 00 00 00 00 84 84 84 A4 7D 7D'
+ '7D FF D9 D9 D9 FF C1 C1 C1 FF BC BC BC FF B7 B7'
+ 'B7 FF B2 B2 B2 FF B0 B0 B0 FF AC AC AC FF A9 A9'
+ 'A9 FF A5 A5 A5 FF A3 A3 A3 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF 9F 9F 9F FF 9B 9B 9B FF 9A 9A 9A FF 99 99'
+ '99 FF 96 96 96 FF 94 94 94 FF 92 92 92 FF 91 91'
+ '91 FF 8F 8F 8F FF 8D 8D 8D FF 8C 8C 8C FF 89 89'
+ '89 FF 86 86 86 FF 84 84 84 FF 91 91 91 FF 0F 0F'
+ '0F 61 00 00 00 00 00 00 00 00 92 92 92 AC 76 76'
+ '76 FF E1 E1 E1 FF C5 C5 C5 FF C0 C0 C0 FF BC BC'
+ 'BC FF B7 B7 B7 FF B3 B3 B3 FF AE AE AE FF AA AA'
+ 'AA FF A6 A6 A6 FF A4 A4 A4 FF A3 A3 A3 FF 9E 9E'
+ '9E FF 9F 9F 9F FF 9D 9D 9D FF 9B 9B 9B FF 9B 9B'
+ '9B FF 98 98 98 FF 97 97 97 FF 96 96 96 FF 93 93'
+ '93 FF 91 91 91 FF 8F 8F 8F FF 8F 8F 8F FF 8B 8B'
+ '8B FF 89 89 89 FF 84 84 84 FF 97 97 97 FF 2D 2D'
+ '2D 88 00 00 00 12 00 00 00 00 98 98 98 B1 77 77'
+ '77 FF DE DE DE FF C7 C7 C7 FF C3 C3 C3 FF BF BF'
+ 'BF FF B9 B9 B9 FF B5 B5 B5 FF B0 B0 B0 FF AC AC'
+ 'AC FF A8 A8 A8 FF A6 A6 A6 FF A4 A4 A4 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF 9E 9E 9E FF 9C 9C 9C FF 9C 9C'
+ '9C FF 9B 9B 9B FF 99 99 99 FF 98 98 98 FF 96 96'
+ '96 FF 94 94 94 FF 91 91 91 FF 90 90 90 FF 8E 8E'
+ '8E FF 8D 8D 8D FF 86 86 86 FF 8D 8D 8D FF 5E 5E'
+ '5E AB 00 00 00 1B 00 00 00 00 A3 A3 A3 B7 7D 7D'
+ '7D FF D6 D6 D6 FF CC CC CC FF C7 C7 C7 FF C3 C3'
+ 'C3 FF BE BE BE FF B9 B9 B9 FF B4 B4 B4 FF AF AF'
+ 'AF FF AA AA AA FF A5 A5 A5 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9A 9A 9A FF 9B 9B 9B FF 9A 9A 9A FF 97 97'
+ '97 FF 96 96 96 FF 95 95 95 FF 93 93 93 FF 8F 8F'
+ '8F FF 8E 8E 8E FF 88 88 88 FF 8A 8A 8A FF 93 93'
+ '93 D7 00 00 00 2F 00 00 00 00 A4 A4 A4 BF 8A 8A'
+ '8A FF CA CA CA FF D5 D5 D5 FF CB CB CB FF C7 C7'
+ 'C8 FF C2 C2 C2 FF BE BE BE FF B7 B7 B7 FF B2 B2'
+ 'B2 FF AE AE AE FF A9 A9 A9 FF A5 A5 A5 FF A2 A2'
+ 'A2 FF A0 A0 A0 FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9B 9B 9B FF 9C 9C 9C FF 9B 9B 9B FF 99 99'
+ '99 FF 97 97 97 FF 96 96 96 FF 93 93 93 FF 90 90'
+ '90 FF 8D 8D 8D FF 8A 8A 8A FF 8B 8B 8B FF 9C 9C'
+ '9C E1 0F 0F 0F 40 00 00 00 00 AD AD AD D5 9B 9B'
+ '9B FF 8B 8B 8B FF AD AD AD FF AD AD AD FF AC AB'
+ 'AB FF A7 A7 A7 FF A3 A3 A3 FF 9E 9E 9E FF 9B 9B'
+ '9A FF 96 96 96 FF 94 94 94 FF 91 91 91 FF 8F 8F'
+ '8E FF 8F 8E 8E FF 92 92 92 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9A 9A 9A FF 97 97 97 FF 93 93 93 FF 90 90'
+ '90 FF 8D 8D 8D FF 88 88 88 FF 90 90 90 FF A7 A7'
+ 'A7 D6 43 43 43 35 00 00 00 00 BD BD BD EC 9D 9D'
+ '9D FF 93 93 93 FF 8B 8B 8B FF 88 88 88 FF 85 85'
+ '84 FF 7F 7F 7F FF 7C 7C 7C FF 79 79 79 FF 77 77'
+ '77 FF 74 74 74 FF 73 73 73 FF 73 73 73 FF 72 72'
+ '72 FF 70 71 71 FF 70 70 70 FF 80 80 80 FF 87 87'
+ '87 FF 87 87 87 FF 86 86 86 FF 85 85 85 FF 84 84'
+ '84 FF 82 82 82 FF 81 81 81 FF 7F 7F 7F FF 7B 7B'
+ '7B FF 78 78 78 FF 7A 7A 7A FA 90 90 90 E2 7F 7F'
+ '7F 85 00 00 00 00 00 00 00 00 D4 D2 D4 B9 AB AB'
+ 'AD FE 9A 9B 9D FF 98 99 9B FF 93 94 96 FF 8F 90'
+ '93 FF 8B 8D 8F FF 87 88 8A FF 84 85 87 FF 80 81'
+ '83 FF 7C 7D 7F FF 7C 7C 7F FF 7B 7B 7D FF 79 7A'
+ '7B FF 7B 7B 7B FF 7B 7B 7B FF 79 79 79 FF 78 78'
+ '78 FF 77 77 77 FF 76 76 76 FF 76 76 76 FF 73 73'
+ '73 FF 71 71 71 FF 6F 6F 6F FF 6C 6C 6C FF 69 69'
+ '69 FF 64 64 64 FF 68 68 68 DF 19 19 19 47 00 00'
+ '00 00 00 00 00 00 00 00 00 00 DE DB D6 65 DA D6'
+ 'CA F7 C0 B8 A9 FF C0 B7 A9 FF B7 B1 A2 FF B0 A9'
+ '9B FF AA A3 96 FF A6 A1 93 FF 9D 97 8C FF 99 94'
+ '8A FF 93 8E 84 FF 8D 88 7F FF 8B 87 7E FF 81 7F'
+ '7D FF 7A 7B 7E FF 7B 7B 7B FF 7B 7B 7B FF 7B 7B'
+ '7B FF 7A 7A 7A FF 79 79 79 FF 78 78 78 FF 76 76'
+ '76 FF 74 74 74 FF 71 71 71 FF 6F 6F 6F FF 6A 6A'
+ '6A FF 66 66 66 FF 8A 8A 8A D5 28 28 28 33 00 00'
+ '00 00 00 00 00 00 00 00 00 00 ED ED E9 3B FC F9'
+ 'EA E0 E4 D6 BB FF E1 D3 B8 FF DE D0 B4 FF DB CC'
+ 'B1 FF D5 C7 AB FF D0 C2 A7 FF CB BD A0 FF C5 B7'
+ '99 FF C1 B2 96 FF B9 AB 8E FF B1 A3 86 FF BE AD'
+ '8C FE 9E 9B 96 F1 A8 A8 A9 D7 AA AA AA D0 A9 A9'
+ 'A9 D0 A7 A7 A7 D0 A5 A5 A5 D1 A2 A2 A2 D1 9D 9D'
+ '9D D2 98 98 98 D3 92 92 92 D4 8D 8D 8D D5 83 83'
+ '83 D7 9B 9B 9B D5 2D 2D 2D 44 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 DD'
+ 'DA 69 FB F8 EC F8 F9 F4 E9 FA F8 F3 E5 FA F7 F1'
+ 'E1 FA F4 EE DA FA F2 EC D6 FA F0 E9 CF FA ED E7'
+ 'C7 FA EC E3 C1 FA E9 E0 BE FA E6 DB B7 FA E8 DF'
+ 'BC E1 8E 86 75 5D 9E 9E 9E 2D AE AE AE 26 B5 B5'
+ 'B5 26 B5 B5 B5 26 B7 B7 B7 27 B0 B0 B0 27 AC AC'
+ 'AC 28 9D 9D 9D 2A 8B 8B 8B 2C 85 85 85 2E 74 74'
+ '74 30 7C 7C 7C 2D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF F1 C7 FF FF 00 00 FF FF'
- 'F0 07 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'F8 0F FF FF 00 00 FF FF F0 07 FF FF 00 00 FF FF'
- 'F2 07 FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
- '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- 'FF FF 00 00 FF FF 00 00 00 30 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 FF FF 00 00 FF FF 00 00'
- '00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 30 00 00 00 24 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
- '00 30 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
- '00 3C 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 9C 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
- 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 3C 00 00'
- '00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -9646,492 +6975,388 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- 'FF FF 00 00 FF FF 00 00 FF FF C0 C0 C0 FF C0 C0'
- 'C0 FF 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
- '00 15 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
- '00 09 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
- '00 09 00 00 00 09 00 00 00 09 00 00 00 07 00 00'
- '00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- 'FF FF 00 00 FF FF 00 00 00 37 C0 C0 C0 FF C0 C0'
- 'C0 FF 00 00 00 37 00 00 FF FF 00 00 FF FF 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 35 00 00 00 18 00 00'
- '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
- '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F1 00 00 00 B1 00 00'
- '00 5C 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
- '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
- '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
- '2D FF 2E 2C 2D FF 13 13 13 FF 00 00 00 FF 00 00'
- '00 F6 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
- '90 FF CA CA CA FF CD CD CD FF CB CB CB FF CE CE'
- 'CE FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
- 'C9 FF C7 C7 C7 FF C6 C6 C6 FF C5 C5 C5 FF C4 C4'
- 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3'
- 'C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF BF FF BF BF'
- 'BF FF BC BC BC FF BD BD BD FF BA BA BA FF BB BB'
- 'BB FF B5 B5 B5 FF B3 B4 B3 FF B8 B4 B6 FF AD AD'
- 'AD FF AB AC AC FF AD A8 AB FF 63 63 63 FF 09 09'
- '09 FF 00 00 00 EF 00 00 00 42 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF EB EB'
- 'EB FF E8 E8 E8 FF E7 E7 E7 FF D5 D5 D5 FF 85 85'
- '85 FF 88 88 88 FF 92 92 92 FF 98 98 98 FF A2 A2'
- 'A2 FF AD AD AD FF BA BA BA FF C0 C0 C0 FF C3 C3'
- 'C3 FF C6 C6 C6 FF CB CB CB FF CA CA CA FF CA CA'
- 'CA FF D6 D6 D6 FF CA CA CA FF D3 D3 D3 FF CB CB'
- 'CB FF D7 D7 D7 FF CC CC CC FF D4 D4 D4 FF C7 C7'
- 'C7 FF C8 C9 C9 FF C6 C2 C4 FF 9D B3 A8 FF 20 A8'
- '63 FF 1C A8 60 FF 90 AF A0 FF BF BB BD FF 4F 4F'
- '4F FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 15 00 00 00 F0 19 19 19 FF C7 C7 C7 FF EC EC'
- 'EC FF E2 E2 E2 FF E6 E6 E6 FF CB CB CB FF 3B 3B'
- '3B FF 3F 3F 3F FF 56 56 56 FF 72 72 72 FF 87 87'
- '87 FF 92 92 92 FF 9D 9D 9D FF A5 A5 A5 FF A8 A8'
- 'A8 FF AC AC AC FF B7 B7 B7 FF A9 A9 A9 FF 9C 9C'
- '9C FF BD BD BD FF 99 99 99 FF B7 B7 B7 FF A1 A1'
- 'A1 FF C3 C3 C3 FF A3 A3 A3 FF BD BD BD FF 98 98'
- '98 FF C5 C4 C4 FF C7 BF C3 FF 51 A7 7C FF 17 CE'
- '71 FF 0A BF 61 FF 2F 99 64 FF C3 BD C0 FF 84 83'
- '84 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 30 00 00 00 FA 29 29 29 FF D1 D1 D1 FF EA EA'
- 'EA FF E4 E4 E4 FF E7 E7 E7 FF CD CD CD FF 47 47'
- '47 FF 5F 5F 5F FF 79 79 79 FF 87 87 87 FF 8F 8F'
- '8F FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF B9 B9 B9 FF A4 A4 A4 FF 90 90'
- '90 FF B8 B8 B8 FF 8A 8A 8A FF AF AF AF FF 94 94'
- '94 FF BF BF BF FF 97 97 97 FF B7 B7 B7 FF 88 88'
- '88 FF C4 C3 C3 FF C6 C3 C5 FF 95 B2 A3 FF 91 D6'
- 'B4 FF 91 D8 B5 FF 83 AB 97 FF C4 C1 C3 FF 8E 8E'
- '8E FF 01 01 01 FF 00 00 00 B7 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
- 'EC FF E6 E6 E6 FF E7 E7 E7 FF D1 D1 D1 FF 68 68'
- '68 FF 74 74 74 FF 7E 7E 7E FF 85 85 85 FF 8E 8E'
- '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF BA BA BA FF 9F 9F 9F FF 83 83'
- '83 FF B3 B3 B3 FF 7C 7C 7C FF A8 A8 A8 FF 87 87'
- '87 FF BB BB BB FF 8A 8A 8A FF B2 B2 B2 FF 79 79'
- '79 FF C2 C2 C2 FF C4 C4 C4 FF C6 C3 C4 FF 99 AC'
- 'A2 FF 96 AB A0 FF C2 BE C0 FF C4 C4 C4 FF 8D 8D'
- '8D FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
- 'EE FF E7 E7 E7 FF E8 E8 E8 FF D6 D6 D6 FF 70 70'
- '70 FF 71 71 71 FF 7D 7D 7D FF 85 85 85 FF 8E 8E'
- '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
- 'AA FF AE AE AE FF BB BB BB FF 98 98 98 FF 73 73'
- '73 FF AD AD AD FF 6A 6A 6A FF A0 A0 A0 FF 78 78'
- '78 FF B7 B7 B7 FF 7C 7C 7C FF AB AB AB FF 67 67'
- '67 FF C2 C2 C2 FF C6 C6 C6 FF C4 C3 C4 FF C7 C4'
- 'C5 FF C6 C2 C4 FF BF BF BF FF C5 C5 C5 FF 8D 8D'
- '8D FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
- 'EF FF E9 E9 E9 FF EB EB EB FF D6 D6 D6 FF 6A 6A'
- '6A FF 6C 6C 6C FF 78 78 78 FF 81 81 81 FF 8A 8A'
- '8A FF 93 93 93 FF 9C 9C 9C FF A3 A3 A3 FF A6 A6'
- 'A6 FF AB AB AB FF B9 B9 B9 FF 90 90 90 FF 66 66'
- '66 FF A5 A5 A5 FF 5B 5B 5B FF 98 98 98 FF 6B 6B'
- '6B FF B1 B1 B1 FF 70 70 70 FF A4 A4 A4 FF 58 58'
- '58 FF C1 C1 C1 FF C8 C8 C8 FF C5 C5 C5 FF C3 C3'
- 'C3 FF C2 C2 C2 FF C1 C1 C1 FF C6 C6 C6 FF 8E 8E'
- '8E FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
- 'F2 FF EB EB EB FF EA EA EA FF DF DF DF FF A7 A7'
- 'A7 FF A7 A7 A7 FF AB AB AB FF AE AE AE FF B0 B0'
- 'B0 FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF B9 B9'
- 'B9 FF BA BA BA FF BD BD BD FF B7 B7 B7 FF B1 B1'
- 'B1 FF BE BE BE FF AF AF AF FF BA BA BA FF B1 B1'
- 'B1 FF BE BE BE FF B0 B0 B0 FF BA BA BA FF AB AB'
- 'AB FF C5 C5 C5 FF C8 C8 C8 FF C6 C6 C6 FF C4 C4'
- 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C9 C9 C9 FF 8E 8E'
- '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 80 00'
+ '00 03 80 00 00 03 80 00 00 03 80 00 00 03 80 00'
+ '00 03 80 00 00 03 80 00 00 01 80 00 00 01 80 00'
+ '00 01 80 00 00 01 80 00 00 00 80 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 01 80 00'
+ '00 03 80 00 00 03 80 00 00 07 C0 00 00 0F FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
- 'F3 FF EB EB EB FF EB EB EB FF EA EA EA FF ED ED'
- 'ED FF EB EB EB FF E9 E9 E9 FF E8 E8 E8 FF E6 E6'
- 'E6 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF'
- 'DF FF DE DE DE FF DB DB DB FF DB DB DB FF DC DC'
- 'DC FF D8 D8 D8 FF D9 D9 D9 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
- 'D0 FF CB CB CB FF CA CA CA FF C9 C9 C9 FF C7 C7'
- 'C7 FF C4 C4 C4 FF C0 C0 C0 FF CA CA CA FF 8E 8E'
- '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
- 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
- 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
- 'EC FF EB EB EB FF E0 E0 E0 FF D0 D0 D0 FF 8D 8D'
- '8D FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
- 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
- 'E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF EF FF 8C 8C'
- '8C FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
- 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
- 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF DB DB DB FF CF CF CF FF BC BC BC FF BB BB'
- 'BB FF D1 D1 D1 FF DE DE DE FF FF FF FF FF 9A 9A'
- '9A FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
- 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
- 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9'
- 'D9 FF D2 D2 D2 FF A8 A8 A8 FF B6 B6 B6 FF B1 B1'
- 'B1 FF B5 B5 B5 FF D8 D8 D8 FF FC FC FC FF 9C 9C'
- '9C FF 00 00 00 FF 00 00 00 AE 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
- 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
- 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D7 D7'
- 'D7 FF C9 C9 C9 FF A6 A6 A6 FF C3 C3 C3 FF B3 B3'
- 'B3 FF AD AD AD FF D6 D6 D6 FF F5 F5 F5 FF 76 76'
- '76 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
- 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
- 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF DD DD DD FF E1 E1 E1 FF E3 E3'
- 'E3 FF E6 E6 E6 FF EA EA EA FF ED ED ED FF ED ED'
- 'ED FF EB EB EB FF E7 E7 E7 FF E4 E4 E4 FF E2 E2'
- 'E2 FF DE DE DE FF D4 D4 D4 FF D0 D0 D0 FF D2 D2'
- 'D2 FF D3 D3 D3 FF C5 C5 C5 FF D0 D0 D0 FF C2 C2'
- 'C2 FF BF BF BF FF D9 D9 D9 FF E8 E8 E8 FF 56 56'
- '56 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 08 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 00 00 07 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 00 00 07 88 88 88 88 88 88 88 88 88'
+ '77 87 77 77 77 77 77 77 77 77 77 77 00 00 07 88'
+ '88 FF FF FF FF FF FF FF FF FF FF FF FF FF FF 88'
+ '88 88 88 88 70 00 08 78 8F F4 44 44 44 44 4F F4'
+ 'F4 F4 F4 44 44 44 4F F8 88 88 88 88 70 00 08 78'
+ '8F F4 FF FF FF FF F4 4F 4F 4F 4F FF FF FF FF FF'
+ '88 88 88 88 70 00 08 78 8F F4 F4 F4 4F 44 F4 F4'
+ 'FF 44 F4 4F 44 4F FF FF 88 88 88 88 70 00 08 78'
+ '8F FF 4F 4F F4 FF 4F 4F FF 4F FF F4 FF FF FF FF'
+ '88 88 88 88 70 00 08 78 88 F4 44 FF FF FF 44 44'
+ '4F F4 4F F4 4F FF FF FF 88 88 88 88 70 00 08 77'
+ '88 8F FF FF FF FF FF FF FF FF FF FF FF FF FF F8'
+ '88 88 88 88 70 00 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 87 00 08 77'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 87 00 08 77'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 08 77 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 87 00 08 77'
+ '78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 08 77 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 70 08 77'
+ '78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 70 08 77'
+ '78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 70 08 77'
+ '77 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 08 77 77 77 77 77 77 77 77 77'
+ '77 77 77 88 88 88 88 88 88 88 88 88 88 70 08 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 00 08 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 78 00 00 00 87'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 78 00 00 00 86 66 66 66 66 66 66 66 66'
+ '66 67 77 77 77 77 77 77 77 77 77 80 00 00 00 8E'
+ '6E 6E 6E 6E 6E 6E 6E 6E 6E 68 88 88 88 88 88 88'
+ '88 88 88 00 00 00 00 0F EF EF EF EF EF EF EF EF'
+ 'EF 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '88 88 88 88 88 88 88 88 88 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
- 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
- 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF DF DF'
- 'DF FF F0 F0 F0 FF EC EC EC FF E1 E1 E1 FF DE DE'
- 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DB DB'
- 'DB FF DC DC DC FF DD DD DD FF DE DE DE FF E1 E1'
- 'E1 FF EC EC EC FF F1 F1 F1 FF E1 E1 E1 FF D1 D1'
- 'D1 FF CE CE CE FF D0 D0 D0 FF CB CB CB FF CE CE'
- 'CE FF D1 D1 D1 FF D9 D9 D9 FF D4 D4 D4 FF 3F 3F'
- '3F FF 00 00 00 FF 00 00 00 55 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
- 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CA CA CA FF D6 D6 D6 FF ED ED ED FF E6 E6'
- 'E6 FF DC DC DC FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF ED ED'
- 'ED FF DA DA DA FF CA CA CA FF CD CD CD FF CD CD'
- 'CD FF CB CB CB FF DF DF DF FF B8 B8 B8 FF 22 22'
- '22 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
- 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
- 'CA FF D4 D4 D4 FF E9 E9 E9 FF DC DC DC FF D0 D0'
- 'D0 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D8 D8'
- 'D8 FF EA EA EA FF D8 D8 D8 FF C9 C9 C9 FF CA CA'
- 'CA FF C9 C9 C9 FF E0 E0 E0 FF A0 A0 A0 FF 08 08'
- '08 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
- 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
- 'CE FF E4 E4 E4 FF D4 D4 D4 FF CF CF CF FF D1 D1'
- 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF CD CD CD FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CC CC'
- 'CC FF D0 D0 D0 FF E2 E2 E2 FF CF CF CF FF C7 C7'
- 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 C2 00 00 00 0E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
- '9F FF DD DD DD FF CC CC CC FF CD CD CD FF DB DB'
- 'DB FF D6 D6 D6 FF CE CE CE FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF C8 C8 C8 FF CF CF CF FF DA DA DA FF C7 C7'
- 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 5A 5A 5A FF 00 00'
- '00 FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
- '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF DB DB'
- 'DB FF D1 D1 D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF C5 C5'
- 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C7 C7 C7 FF D3 D3 D3 FF C8 C8'
- 'C8 FF C9 C9 C9 FF DE DE DE FF 42 42 42 FF 00 00'
- '00 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
- '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D4 D4'
- 'D4 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D0 D0 D0 FF C8 C8'
- 'C8 FF C3 C3 C3 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C7 C7 C7 FF C5 C5'
- 'C5 FF CB CB CB FF CC CC CC FF 2D 2D 2D FF 00 00'
- '00 F8 00 00 00 40 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 80 00 00 00 00 0F 00 00 80 00'
+ '00 00 00 0F 00 00 80 00 00 00 00 0F 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 0F 00 00 C0 00 00 00 00 1F 00 00 C0 00'
+ '00 00 00 3F 00 00 E0 00 01 FF FF FF 00 00 F0 00'
+ '03 FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 58 58'
+ '58 00 5C 5C 5C 00 61 61 61 00 65 65 65 00 69 69'
+ '69 00 6D 6D 6D 00 71 71 71 00 75 75 75 00 79 79'
+ '79 00 7A 7C 7F 00 7D 7D 7D 00 98 69 4E 00 99 6C'
+ '4F 00 A5 7A 5A 00 A6 7D 58 00 89 85 7E 00 95 8E'
+ '7E 00 AB 84 61 00 AF 89 6A 00 B2 8E 6F 00 B1 8D'
+ '71 00 B3 91 70 00 B4 92 74 00 B5 94 75 00 7B 7D'
+ '80 00 7C 7E 82 00 FF 00 FF 00 7F 80 80 00 7F 81'
+ '84 00 81 81 81 00 82 83 86 00 85 85 85 00 85 86'
+ '88 00 87 89 8C 00 89 89 89 00 8C 8C 8B 00 89 8B'
+ '8E 00 8B 8C 8C 00 8C 8C 8C 00 8D 8D 8E 00 8D 8E'
+ '8E 00 8E 8E 8E 00 90 8F 8F 00 9A 91 81 00 9D 95'
+ '85 00 9A 96 8D 00 8D 8E 91 00 90 8F 90 00 90 90'
+ '90 00 92 91 92 00 92 92 92 00 95 94 93 00 91 92'
+ '95 00 94 94 94 00 96 95 95 00 96 96 96 00 98 97'
+ '97 00 93 95 98 00 96 97 99 00 97 98 9B 00 98 98'
+ '98 00 99 99 9A 00 9A 9A 9A 00 9C 9B 9B 00 99 9A'
+ '9D 00 9B 9C 9F 00 9C 9C 9C 00 9E 9D 9D 00 9E 9E'
+ '9D 00 9E 9E 9E 00 AA 9C 81 00 A4 9C 8B 00 A8 9F'
+ '8E 00 BD 9F 85 00 A0 9E 9E 00 AE A0 84 00 AA A0'
+ '8F 00 B2 A2 82 00 B2 A4 89 00 B7 AA 8F 00 AF A5'
+ '91 00 AE A5 93 00 BC AE 92 00 B6 AD 98 00 BE B1'
+ '94 00 BA B0 9C 00 9E 9E A0 00 A1 A1 A1 00 A4 A2'
+ 'A2 00 A3 A3 A4 00 A5 A5 A5 00 A6 A7 A9 00 A9 A9'
+ 'A9 00 AC AB AA 00 AD AC AB 00 AD AD AD 00 BF B4'
+ 'A0 00 B1 B1 B1 00 B5 B5 B5 00 B9 B7 B7 00 B9 B9'
+ 'B9 00 BD BC BB 00 BB BB BC 00 BD BD BD 00 C2 A5'
+ '8B 00 C1 A6 8D 00 C7 AD 96 00 C3 B5 99 00 CA B2'
+ '9D 00 CC B5 9F 00 C6 B9 9E 00 C8 B9 9D 00 CE BE'
+ '9F 00 CD B6 A2 00 CB B5 A6 00 C4 BA A4 00 CB BD'
+ 'A1 00 C9 BC A2 00 CF B9 A6 00 D0 B9 A5 00 D1 BD'
+ 'AA 00 D3 BF AD 00 C0 BF BE 00 CE C0 A3 00 CD C0'
+ 'A5 00 CB C0 AA 00 D0 C3 A8 00 D2 C4 A8 00 D5 C7'
+ 'AB 00 D3 C6 AC 00 D0 C4 AE 00 D7 C9 AE 00 D9 CB'
+ 'AF 00 D5 C2 B2 00 D2 C7 B0 00 D7 C5 B6 00 D9 C7'
+ 'B7 00 D7 C9 B3 00 D8 CB B0 00 DA CD B3 00 DD CF'
+ 'B3 00 DB CE B4 00 DA C9 B9 00 DB CC BE 00 DE D1'
+ 'B3 00 DF D0 B4 00 DE D0 B6 00 E0 D2 B5 00 E1 D4'
+ 'B9 00 E2 D5 BA 00 E4 D5 B9 00 E6 D8 BC 00 E8 DA'
+ 'BE 00 E9 DC BF 00 C1 C1 C1 00 C5 C5 C5 00 C8 C8'
+ 'C6 00 C7 C7 C8 00 C9 C9 C9 00 CC CB CB 00 CD CD'
+ 'CD 00 DD CF C3 00 D0 CF CE 00 DE D5 C1 00 D2 D0'
+ 'CE 00 DF D2 CA 00 D2 D2 D1 00 D6 D4 D3 00 D6 D5'
+ 'D5 00 D8 D7 D7 00 D9 D8 D3 00 D9 D9 D9 00 DD DD'
+ 'D9 00 DD DD DD 00 E0 D1 C4 00 E9 DB C1 00 EB DF'
+ 'C4 00 E2 D6 CA 00 E4 D7 CA 00 E3 D6 CC 00 E4 D7'
+ 'CC 00 E3 D8 CD 00 E4 D9 CE 00 E6 DA D0 00 E7 DC'
+ 'D2 00 E7 DE D5 00 E8 DD D2 00 E9 DF D6 00 EA E0'
+ 'C2 00 EC E2 C5 00 EC E1 C8 00 ED E4 CB 00 EE E5'
+ 'CF 00 EE E6 CF 00 EF E8 CE 00 EA E0 D7 00 E6 E0'
+ 'DB 00 E9 E1 DA 00 EC E2 D9 00 EC E4 DB 00 EA E3'
+ 'DC 00 EB E4 DD 00 ED E5 DE 00 F0 EA D0 00 F0 EC'
+ 'D3 00 F2 ED D5 00 F2 ED D8 00 F0 E8 DF 00 F0 EE'
+ 'DC 00 F2 F0 DB 00 F2 F1 DF 00 E0 E0 E0 00 ED E6'
+ 'E0 00 EF E8 E2 00 EB EA E9 00 ED EB E8 00 F1 E9'
+ 'E2 00 F1 EA E4 00 F1 EC E7 00 F2 EC E8 00 F5 EF'
+ 'EA 00 F4 F3 E4 00 F3 F0 EB 00 F3 F1 EE 00 F5 F1'
+ 'ED 00 F8 F4 EF 00 F2 F1 F0 00 F5 F2 F0 00 F6 F4'
+ 'F2 00 F8 F5 F1 00 FA F6 F4 00 FA F8 F5 00 FC F8'
+ 'F5 00 FA F9 F8 00 FC FA F8 00 FD FC FB 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 07 70 66 54 60 54 60 54 60'
+ '54 60 54 60 54 60 54 60 54 60 54 60 54 60 54 60'
+ '54 60 54 60 54 60 54 60 54 60 54 60 54 60 54 61'
+ '61 6B 00 00 00 00 00 71 A4 69 49 41 41 3C 3F 3C'
+ '3A 3A 32 3A 32 32 32 2F 2D 2C 2F 2C 2C 2A 29 29'
+ '2A 29 29 27 27 25 25 25 25 14 14 14 14 14 14 14'
+ '14 14 00 00 00 00 00 6D AA B5 A8 A4 71 71 6F 6F'
+ '6C 6D 6C 6C 6B 6B 6B 69 68 68 66 64 64 62 F7 54'
+ '54 4E 49 48 42 3D 3D 34 2D 32 2D 32 2D 2D 2D 2C'
+ '3C 0D 00 00 00 00 00 6B 69 71 6D B0 CE D2 D3 DE'
+ 'E8 ED EE EE EE EF EE EE EA ED ED ED EA E9 E9 E9'
+ 'E9 ED E9 E9 E9 EC EC E0 A5 3A 14 14 12 12 12 11'
+ '33 0D 4F 00 00 00 00 69 48 6E A8 ED CD C0 BC C1'
+ 'C1 C1 C0 BB C1 C3 C1 D0 D1 D4 D9 E3 E3 E7 E3 E4'
+ 'E2 D9 CD C4 C1 C0 BF C1 E8 AE 29 14 14 12 12 12'
+ '3B 11 3F 00 00 00 00 66 2C 6C B3 F4 F3 73 F4 F1'
+ 'ED D4 CF E3 E4 CF DF 8F CD E4 C2 C2 DE D3 D2 D3'
+ 'DF E5 EA E6 E4 E4 E3 E5 F1 F3 63 14 14 14 14 11'
+ '34 11 2A 00 00 00 00 67 13 6B AE EF F0 AB 1C 77'
+ '15 17 16 17 18 1F 83 D1 98 80 F4 E5 20 7B 82 77'
+ '21 1B 53 81 B8 E6 EB EA EA F2 A6 F8 14 14 12 12'
+ '2D 12 11 00 00 00 00 68 10 6C A8 F0 F1 E5 7C 99'
+ 'E6 C3 F0 E3 DF 82 BD 8F 76 E4 F5 E4 81 8F BE 99'
+ '92 8F C0 F3 EA F0 F1 F1 F4 F2 B2 29 F8 14 14 12'
+ '27 14 0F 00 00 00 00 68 0F 6C 07 E1 EB CD 76 1E'
+ 'BB E4 EB EF EF EB 98 74 1D 76 D1 EB 92 72 DE 98'
+ 'C4 18 F4 ED EB EA EA EB EA F0 AE 29 27 27 14 14'
+ '14 29 0E 00 00 00 00 68 0E 69 6E A9 EC F3 F0 AF'
+ 'BB E5 F2 F1 F0 F0 F5 F4 EA EF EB F1 F4 E3 BD D1'
+ 'EE F2 F4 F0 F0 F0 F2 F2 F2 ED 66 29 29 27 27 14'
+ '14 2C 0C 00 00 00 00 67 0F 65 71 6E A8 B7 DD DD'
+ 'B7 B7 B7 B6 B7 DD B7 B7 B7 B5 B7 B2 B5 B2 B3 B2'
+ 'B2 B2 B2 B0 B0 B0 B2 B2 B0 6B 32 2C 2A 29 29 F8'
+ '14 3C 0B 48 00 00 00 69 0F 4D A4 70 6E 70 6C 6C'
+ '69 6B 69 67 69 69 67 66 67 66 65 63 63 63 61 61'
+ '4F 4F 4F 4A 44 46 46 46 41 32 2F 2C 2C 29 27 28'
+ 'F8 2D 0C 2D 00 00 00 6B 11 3C AC 07 71 70 6E 6C'
+ '6C 6B 67 66 66 65 65 64 62 63 61 61 61 4F 4E 4C'
+ '48 46 46 41 3F 3C 3C 3C 3A 3A 33 30 2F 29 2A 27'
+ '27 2D 10 14 00 00 00 6B 14 2A B2 A4 A4 71 6E 6E'
+ '6C 6B 69 69 68 66 65 64 64 62 61 63 61 4E 48 4C'
+ '4C 48 46 3F 40 3F 3A 3A 3A 3A 33 32 2D 2C 2C 29'
+ '29 2C 2C 0F 00 00 00 6B 29 14 B5 A5 A4 07 6E 6E'
+ '6C 6C 6B 69 69 66 65 63 64 62 63 61 61 4E 4C 48'
+ '4C 47 46 46 41 3F 3C 3C 3C 34 33 32 31 2C 2C 2C'
+ '29 29 2D 0C 00 00 00 6B 3A 11 B7 A6 A7 A4 71 70'
+ '6D 6C 6C 69 69 67 65 64 64 64 61 4F 61 61 4E 4C'
+ '4C 4C 46 46 46 41 41 3F 3C 3A 3A 3A 34 2F 2C 2C'
+ '29 29 3C 0A 00 00 00 6B 3F 10 B5 A9 A7 A5 07 71'
+ '70 6C 6C 6B 6B 66 66 66 64 64 63 61 61 61 4E 4C'
+ '4C 4C 4C 49 46 46 46 41 3F 3F 3A 3C 3A 32 32 2D'
+ '2C 29 34 0C 3F 00 00 6C 47 10 B2 AA A8 A5 A4 A4'
+ '71 6E 6C 6C 69 69 67 65 66 63 64 61 61 61 54 4F'
+ '4E 4C 4F 48 48 48 46 46 41 41 3C 3C 3A 3A 33 32'
+ '2C 2A 3D 11 2C 00 00 6C 61 10 AC AC A9 A7 A5 A4'
+ '07 70 6E 6C 6B 69 68 66 64 64 63 61 61 61 4F 61'
+ '4C 4F 49 4C 48 4C 47 46 41 41 41 3F 3C 3A 33 33'
+ '2C 2C 33 27 11 00 00 6B 65 12 A6 B0 AA A8 A7 A5'
+ '07 71 70 6D 6C 6B 67 66 65 64 63 62 61 61 4F 4F'
+ '4E 4C 4C 4C 4C 4C 48 48 46 44 41 40 3C 3C 33 33'
+ '2C 2C 2C 34 0E 00 00 6C 64 29 69 B7 AC AA A8 A7'
+ 'A5 07 71 6E 6C 6B 6B 69 66 65 64 62 61 61 4E 4F'
+ '4F 4E 4A 4C 4C 4C 49 48 46 46 41 41 3C 3C 33 32'
+ '2D 2A 29 3A 0C 00 00 6C 65 34 2C 67 A5 A4 A4 71'
+ '71 6D 6C 6B 6B 66 65 64 63 54 4E 4E 48 4C 4E 61'
+ '4C 4E 4E 48 4C 48 48 47 46 41 41 3F 3C 32 33 2D'
+ '2A 29 27 49 29 00 00 6B 66 3F 3C 2C 2A 29 27 27'
+ '14 14 12 12 11 11 11 11 11 11 10 10 11 10 11 33'
+ '61 61 61 61 61 4E 61 4E 4C 48 47 46 3F 3A 3A 32'
+ '2D 3B 48 46 65 00 00 70 69 42 46 40 3F 3A 3A 2D'
+ '2C 29 29 27 27 F8 12 14 12 11 12 12 11 11 10 11'
+ '12 14 14 14 14 12 14 12 12 12 12 11 11 11 10 0F'
+ '11 0F 3A 64 00 00 00 AA 70 4F 60 4C 49 41 41 3C'
+ '3A 32 2F 2C 29 27 27 F8 25 14 14 12 12 14 12 12'
+ '12 12 12 11 11 12 11 11 10 10 10 0F 0F 0E 0E 0D'
+ '10 0D 00 00 00 00 00 00 A5 65 60 4B 4A 45 43 3E'
+ '38 2E 2B 2A 28 26 23 22 22 13 22 14 25 14 25 14'
+ '14 14 14 12 12 12 12 12 12 11 10 11 0F 10 0E 0E'
+ '12 0F 00 00 00 00 00 00 B4 AD 90 90 8C 87 7D 6A'
+ '5F 5F 5D 5B 56 56 51 36 35 1A 1A 19 22 27 14 25'
+ '25 14 25 14 14 14 12 12 12 11 11 10 10 0F 0F 0E'
+ '31 00 00 00 00 00 00 00 B6 CA 9C 97 95 94 8D 8B'
+ '88 86 7F 78 75 5E 5C 59 58 55 50 57 37 44 4F 4C'
+ '48 47 47 46 42 3D 3C 3C 33 2C 2C 29 27 14 14 3A'
+ '00 00 00 00 00 00 00 00 00 E7 CB C7 BA A3 A2 A0'
+ '9D 96 8E 8A 89 85 7E 79 75 5E 5C 7A 5A 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 DA DC DB D8 D7 D6'
+ 'D5 CC C9 C8 C6 B9 A1 9F 9E 9B 9A 93 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
- '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF CD CD CD FF C7 C7 C7 FF C4 C4 C4 FF C2 C2'
- 'C2 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
- 'C1 FF C1 C1 C1 FF C2 C2 C2 FF BF BF BF FF C0 C0'
- 'C0 FF CE CE CE FF B2 B2 B2 FF 1A 1A 1A FF 00 00'
- '00 E5 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
- '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF CC CC'
- 'CC FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
- 'D3 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF C6 C6'
- 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
- 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
- '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
- '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF D0 D0'
- 'D0 FF D2 D2 D2 FF DB DB DB FF D9 D9 D9 FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DB DB DB FF DB DB DB FF DA DA DA FF D9 D9'
- 'D9 FF D9 D9 D9 FF CF CF CF FF C5 C5 C5 FF CC CC'
- 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
- '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
- '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
- 'DC FF CE CE CE FF D6 D6 D6 FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DE DE'
- 'DE FF D8 D8 D8 FF CE CE CE FF DD DD DD FF DC DC'
- 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
- '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
- '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
- 'E1 FF DE DE DE FF CE CE CE FF D7 D7 D7 FF E1 E1'
- 'E1 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF D9 D9'
- 'D9 FF CD CD CD FF DA DA DA FF E3 E3 E3 FF D9 D9'
- 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
- '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
- '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
- 'E3 FF E4 E4 E4 FF E1 E1 E1 FF D7 D7 D7 FF D2 D2'
- 'D2 FF DA DA DA FF E4 E4 E4 FF E5 E5 E5 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E5 E5 E5 FF DC DC DC FF D2 D2 D2 FF D6 D6'
- 'D6 FF E0 E0 E0 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
- 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
- '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
- '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF DF DF'
- 'DF FF D2 D2 D2 FF D3 D3 D3 FF DE DE DE FF E3 E3'
- 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3 E3 FF DE DE'
- 'DE FF D4 D4 D4 FF D1 D1 D1 FF DD DD DD FF E7 E7'
- 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
- '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
- '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
- 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
- 'EB FF EA EA EA FF E4 E4 E4 FF E0 E0 E0 FF DF DF'
- 'DF FF DF DF DF FF DD DD DD FF DC DC DC FF DC DC'
- 'DC FF DD DD DD FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E2 E2 E2 FF E9 E9 E9 FF EC EC EC FF EA EA'
- 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
- 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
- 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
- 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
- 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
- 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
- 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
- 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
- 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
- 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
- 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
- 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
- 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
- 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
- '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 80 00'
+ '00 00 00 0F 00 00 80 00 00 00 00 0F 00 00 80 00'
+ '00 00 00 0F 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 0F 00 00 C0 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 E0 00'
+ '01 FF FF FF 00 00 F0 00 03 FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 80 25 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
- '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
- '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
- '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
- '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -10145,577 +7370,26 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'F1 C7 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF F8 07 FF FF 00 00 FF FF'
- 'E0 00 00 3F 00 00 FF 00 00 00 00 7F 00 00 FC 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
- '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
- '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
- '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 13 13'
- '13 00 18 18 18 00 19 19 19 00 1A 1A 1A 00 1E 1E'
- '1E 00 1F 1F 1F 00 20 20 20 00 21 21 21 00 22 22'
- '22 00 24 24 24 00 26 26 26 00 27 27 27 00 28 28'
- '28 00 29 29 29 00 2A 2A 2A 00 2B 2B 2B 00 2C 2C'
- '2C 00 2D 2D 2D 00 2E 2C 2D 00 2F 2F 2F 00 34 34'
- '34 00 35 35 35 00 39 39 39 00 3B 3B 3B 00 3D 3D'
- '3D 00 3F 3F 3F 00 40 40 40 00 41 41 41 00 42 42'
- '42 00 47 47 47 00 48 48 48 00 49 49 49 00 4B 4B'
- '4B 00 4F 4F 4F 00 53 53 53 00 56 56 56 00 58 58'
- '58 00 59 59 59 00 5A 5A 5A 00 5B 5B 5B 00 5D 5D'
- '5D 00 5F 5F 5F 00 61 61 61 00 63 63 63 00 64 64'
- '64 00 66 66 66 00 67 67 67 00 68 68 68 00 6A 6A'
- '6A 00 6B 6B 6B 00 6C 6C 6C 00 70 70 70 00 71 71'
- '71 00 72 72 72 00 73 73 73 00 74 74 74 00 75 75'
- '75 00 76 76 76 00 77 77 77 00 78 78 78 00 79 79'
- '79 00 7A 7A 7A 00 7C 7C 7C 00 7D 7D 7D 00 7E 7E'
- '7E 00 7F 7F 7F 00 2F 99 64 00 1C A8 60 00 0A BF'
- '61 00 20 A8 63 00 51 A7 7C 00 17 CE 71 00 00 00'
- 'FF 00 80 80 80 00 81 81 81 00 83 83 83 00 84 83'
- '84 00 85 85 85 00 87 87 87 00 88 88 88 00 8A 8A'
- '8A 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
- '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 94 94'
- '94 00 97 97 97 00 98 98 98 00 99 99 99 00 9A 9A'
- '9A 00 9C 9C 9C 00 9D 9D 9D 00 9F 9F 9F 00 83 AB'
- '97 00 96 AB A0 00 90 AF A0 00 99 AC A2 00 95 B2'
- 'A3 00 9D B3 A8 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2'
- 'A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6'
- 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
- 'AA 00 AB AB AB 00 AD A8 AB 00 AB AC AC 00 AC AC'
- 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
- 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B3 B4'
- 'B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B4'
- 'B6 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BB BB'
- 'BB 00 BF BB BD 00 BC BC BC 00 BD BD BD 00 BE BE'
- 'BE 00 BF BF BF 00 91 D6 B4 00 91 D8 B5 00 C3 BD'
- 'C0 00 C2 BE C0 00 C7 BF C3 00 C0 C0 C0 00 C1 C1'
- 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C3 00 C4 C3'
- 'C3 00 C4 C3 C4 00 C6 C2 C4 00 C6 C3 C4 00 C6 C3'
- 'C5 00 C4 C4 C4 00 C5 C4 C4 00 C5 C5 C5 00 C7 C4'
- 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C8 C9'
- 'C9 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CC CC'
- 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
- 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
- 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
- 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
- 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
- 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
- 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
- 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4'
- 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
- 'F8 00 F9 F9 F9 00 FA FA FA 00 FC FC FC 00 FF FF'
- 'FF 00 00 00 00 00 10 DA 4B 00 F8 0F 0D 01 71 CC'
- '43 00 F8 0F 0D 01 40 E3 0C 01 A4 1A 95 00 2C A3'
- 'AF 00 C4 F5 AF 00 03 00 00 00 40 E3 0C 01 2F 0C'
- '00 00 B8 10 0D 01 30 00 00 00 00 00 00 00 40 00'
- '00 00 F8 0F 0D 01 C0 00 00 00 30 00 00 00 00 09'
- '00 00 00 24 00 00 00 00 00 00 00 00 00 00 30 00'
- '00 00 30 00 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 52 52 DF 00 00 00'
- '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 52 52 52 DF 00 52'
- '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 DF DF DF DF DF DF DF DF DF DF'
- 'DF DF DF DF DF DF DF DF DF DF DF 52 52 52 52 52'
- '52 DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
- 'DF DF DF DF DF DF 53 53 53 53 53 53 53 53 53 53'
- '53 53 53 53 53 53 53 53 53 53 53 53 52 52 52 52'
- '53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53'
- '53 53 53 53 53 53 99 99 99 99 99 99 99 99 99 99'
- '99 99 99 99 99 99 99 99 99 99 99 99 52 52 52 52'
- '99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
- '99 99 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 52 52 52 52 52'
- '52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 52 52 52 99 99 52'
- '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 52 52 00 99 99 DF'
- '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF DF DF'
- 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
- 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 DF DF DF DF 11'
- '1A 19 1A 19 19 19 19 19 19 19 19 19 19 19 18 18'
- '18 18 18 18 18 18 18 19 19 19 1C 1C 0A DF DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 DF DF 14 5F AC'
- 'AF AD B0 AF AE AD AB A8 A7 A5 A3 9C 9B 9B 9C 99'
- '9A 93 93 90 91 8D 8E 87 86 8A 7F 7D 7C 35 07 DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 01 5A CD CA'
- 'C9 B7 57 59 60 64 72 7F 8D 99 9C A7 AD AC AC B8'
- 'AC B5 AD B9 AE B6 A8 AA A0 6F 4F 4D 6C 8F 2B DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 0C A8 CE C4'
- 'C8 AD 21 23 2D 3F 58 60 68 75 78 7E 89 79 67 91'
- '65 89 71 9C 73 91 64 A4 98 50 51 4E 4C 96 56 01'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 17 B3 CC C6'
- 'C9 AF 27 33 46 58 5E 63 70 77 7A 80 8C 74 5F 8B'
- '5A 81 62 93 63 89 59 9E A2 6E 94 95 6A 9D 5D 01'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 16 B3 CE C8'
- 'C9 B3 39 41 4A 57 5D 63 70 77 7A 80 8D 69 55 85'
- '48 78 58 8E 5A 84 46 9B A3 A1 6D 6B 97 A3 5C 01'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 16 B3 D0 C9'
- 'CA B8 3D 3E 49 57 5D 63 70 77 7A 80 8E 64 40 7F'
- '3A 70 45 89 48 7B 38 9B A7 9F A6 A0 93 A5 5C 01'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 15 B3 D1 CB'
- 'CD B8 3A 3C 45 54 5A 61 67 73 76 7B 8C 5F 37 75'
- '31 64 3B 83 3D 74 2E 9A A9 A5 9C 9B 9A A7 5D 01'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 15 B4 D4 CD'
- 'CC C1 77 77 7B 80 82 85 88 8C 8C 8D 91 89 83 92'
- '81 8D 83 92 82 8D 7B A5 A9 A7 A3 9C 9B AB 5D DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 14 B5 D5 CD'
- 'CD CC CF CD CB CA C8 C6 C4 C3 C1 C0 BD BD BE BA'
- 'BB B8 B8 B4 B4 B1 B2 AD AC AB A8 A3 99 AC 5D DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 14 B5 D9 DA'
- 'D8 D8 D8 D7 D7 D6 D6 D5 D5 D5 D4 D4 D3 D3 D3 D2'
- 'D2 D2 D1 D1 D0 D0 CF CF CF CE CE CD C2 B2 5C DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 13 B8 DE CB'
- 'C3 C4 C4 C2 C1 C1 C1 C1 C1 C2 C2 C2 C2 C2 C2 C2'
- 'C2 C2 C2 C2 C2 C2 C2 C2 C4 C5 C5 C5 DA D1 5B DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 13 C0 DA BB'
- 'A3 8E 93 BA BC BB BB BB BB BB BB BB BB BB BB BB'
- 'BB BB BB BB BB BB BB BD B1 90 8E B3 C0 DE 66 DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 0F BC D5 A7'
- '79 89 82 9C BC BA BA BA BA BA B9 B9 B9 B9 B9 B9'
- 'B9 B9 BA BA BA BA BB B4 78 88 83 87 BA DD 67 DF'
- 'DF 00 00 00 00 00 00 00 00 00 DF DF 03 9B D8 90'
- '84 9C 7B 8E BA B7 B7 B7 B6 B5 B5 B7 B9 BA BA B9'
- 'B7 B5 B5 B5 B6 B7 B9 AB 76 9C 85 7F B8 D7 43 DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 74 D6 B1'
- 'A5 B4 93 AB B5 B4 B2 B5 BF C3 C5 C8 CC CF CF CD'
- 'C9 C6 C4 C0 B6 B2 B4 B5 A5 B2 9B 93 BB CA 2D DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 4A D1 B3'
- 'B1 AD B1 B3 B0 B1 C1 D2 CE C3 C0 BF BE BD BD BE'
- 'BF C0 C3 CE D3 C3 B3 B0 B2 AD B0 B3 BB B6 23 DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 2F CB B2'
- 'AF AF AF AC B8 CF C8 BE B6 B7 B8 B8 B8 B8 B8 B8'
- 'B8 B8 B7 B7 BD C6 CF BC AC AF AF AD C1 8B 12 DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 24 B9 B4'
- 'AC AD AC B6 CB BE B2 B3 B4 B4 B4 B4 B4 B4 B4 B4'
- 'B4 B4 B4 B4 B3 B2 BA CC BA AB AC AB C2 70 06 DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 12 89 BD'
- 'AC AD B0 C6 B6 B1 B3 B2 B2 B2 B2 B1 AF B0 B0 B0'
- 'B0 B0 B0 B0 B0 B0 AE B2 C4 B1 A8 AB C4 53 DF DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 05 69 BF'
- 'AE AF BD B8 B0 B2 B2 B2 B2 B2 B2 B1 AE AB AC AC'
- 'AC AC AC AC AC AC AC A9 B1 BC A8 AB C4 30 DF DF'
- 'DF 00 00 00 00 00 00 00 00 00 00 00 DF DF 55 BF'
- 'B1 B3 BD B3 B2 B2 B2 B2 B2 B2 B2 B2 B1 AB A5 A7'
- 'A7 A7 A7 A7 A7 A7 A7 A7 A8 B5 A9 AB C0 26 DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 33 BE'
- 'B3 B4 B6 B3 B3 B3 B3 B3 B3 B3 B3 B3 B3 B2 A9 9C'
- '9C 9C A3 A3 A3 A3 A3 A3 A3 A8 A5 AD AE 1B DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 25 BA'
- 'B6 B4 B2 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 AF'
- 'A8 A3 9B 9A 99 9A 9A 9A 9B 93 99 B0 84 0D DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 1A AE'
- 'B8 B7 AE B7 B8 B8 B8 B8 B8 B8 B8 B8 B8 B8 B8 B9'
- 'B8 B7 B5 B1 AE AB A7 A3 9B 85 91 B2 65 07 DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 0B 82'
- 'BD BD B2 B4 BD BB BC BC BC BC BC BC BC BC BC BC'
- 'BC BC BC BD BD BC BB BB B1 A5 AE AC 47 02 DF DF'
- '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 06 63'
- 'BE C1 BE B0 B8 C0 BF BF BF BF BF BF BF BF BF BF'
- 'BF BF BF BF BF BF C0 BA B0 BF BE A7 2C DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 44'
- 'B5 C4 C3 C0 B0 B9 C3 C4 C2 C2 C2 C2 C2 C2 C2 C2'
- 'C2 C2 C2 C2 C3 C3 BB AF BC C5 BB 8E 20 DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 2A'
- 'AB C7 C5 C6 C3 B9 B4 BC C6 C7 C6 C6 C6 C6 C6 C6'
- 'C6 C6 C7 C7 BE B4 B8 C2 C6 C8 B8 78 10 DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 1F'
- '91 C8 C8 C8 C9 C9 C1 B4 B5 C0 C5 C5 C6 C6 C6 C6'
- 'C5 C5 C0 B6 B3 BF C9 C9 C8 CA B6 66 08 DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 0E'
- '7B C6 CF C9 C8 CE CD CC C6 C2 C1 C1 BF BE BE BF'
- 'C1 C1 C1 C4 CB CE CC C7 CD CD B8 5A DF DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 06'
- '65 C6 C1 91 9A B8 CE CF CF D0 D0 CF CE CD CD CE'
- 'CF D0 D0 CF D0 C6 9B 92 B3 CE B6 42 DF DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
- '5C C2 A3 84 8B 84 CD D3 D2 D2 D2 D2 D2 D2 D2 D2'
- 'D2 D2 D2 D2 D5 B7 82 88 89 CD AF 34 DF DF DF 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
- '36 B0 BF BE B7 C6 DB DB DB DB DB DB DB DB DB DB'
- 'DB DB DB DB DC D4 C1 BA BE B9 82 1E DF DF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
- '0C 53 92 B5 B9 BD BA BA BA BA BA BA BA BA BA BA'
- 'BA BA BA BA BA BB BB B9 AF 82 32 04 DF DF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
- 'DF 09 22 29 28 28 28 28 28 28 28 28 28 28 28 28'
- '28 28 28 28 28 28 28 29 29 1D 02 DF DF 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF'
- 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
- 'DF DF DF DF DF DF DF DF DF DF DF DF 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
- 'DF DF DF DF DF DF DF DF DF DF DF 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF F1 C7 FF FF 00 00 FF FF'
- 'F0 87 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'F8 0F FF FF 00 00 FF FF F0 07 FF FF 00 00 FF FF'
- 'F2 07 FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
- '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
- '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
- '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
- '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 24 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 FF FF 00 00'
- 'FF FF 00 00 00 3C 00 00 00 30 00 00 00 30 00 00'
- '00 30 00 00 00 30 00 00 00 30 00 00 00 30 C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00 FF FF 00 00'
- 'FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
- 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 26 26 26 FF CD CD CD FF CD CD'
- 'CD FF C9 C9 C9 FF C5 C5 C5 FF C2 C2 C2 FF C0 C0'
- 'C0 FF BF BF BF FF BA BA BA FF B3 B4 B3 FF AB AC'
- 'AC FF 09 09 09 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 30 D1 D1 D1 FF E7 E7 E7 FF 5F 5F'
- '5F FF 8F 8F 8F FF A7 A7 A7 FF B9 B9 B9 FF B8 B8'
- 'B8 FF 94 94 94 FF B7 B7 B7 FF C6 C3 C5 FF 91 D8'
- 'B5 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 33 D1 D1 D1 FF EB EB EB FF 6C 6C'
- '6C FF 8A 8A 8A FF A3 A3 A3 FF B9 B9 B9 FF A5 A5'
- 'A5 FF 6B 6B 6B FF A4 A4 A4 FF C8 C8 C8 FF C2 C2'
- 'C2 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 33 D3 D3 D3 FF F6 F6 F6 FF F5 F5'
- 'F5 FF F4 F4 F4 FF F3 F3 F3 FF F1 F1 F1 FF F0 F0'
- 'F0 FF EF EF EF FF EE EE EE FF ED ED ED FF EB EB'
- 'EB FF 8D 8D 8D FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 DA DA DA FF A9 A9 A9 FF C3 C3'
- 'C3 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D8 D8 D8 FF D8 D8 D8 FF A8 A8 A8 FF B5 B5'
- 'B5 FF 9C 9C 9C FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 7E 7E 7E FF CF CF CF FF D1 D1'
- 'D1 FF DF DF DF FF E1 E1 E1 FF DC DC DC FF DC DC'
- 'DC FF E1 E1 E1 FF E1 E1 E1 FF D0 D0 D0 FF D1 D1'
- 'D1 FF 3F 3F 3F FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 22 22 FF CA CA CA FF E4 E4'
- 'E4 FF D1 D1 D1 FF D0 D0 D0 FF CD CD CD FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF E2 E2 E2 FF C9 C9'
- 'C9 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF C3 C3'
- 'C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF CB CB'
- 'CB FF 00 00 00 F8 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 D8 DB DB DB FF D2 D2'
- 'D2 FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF CF CF CF FF CA CA'
- 'CA FF 00 00 00 B8 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 89 C9 C9 C9 FF E4 E4'
- 'E4 FF D2 D2 D2 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E5 E5 E5 FF D2 D2 D2 FF E4 E4 E4 FF A8 A8'
- 'A8 FF 00 00 00 4E 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 99 99 99 FF BD BD'
- 'BD FF EC EC EC FF EE EE EE FF EC EC EC FF EC EC'
- 'EC FF EE EE EE FF E4 E4 E4 FF D1 D1 D1 FF 75 75'
- '75 FF 00 00 00 06 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 19 19 19 FF D3 D3'
- 'D3 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D9 D9 D9 FF CD CD CD FF 06 06'
- '06 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 E0 03 00 00 C0 03 00 00 80 03'
- '00 00 80 03 00 00 80 03 00 00 80 03 00 00 C0 03'
- '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
- '00 00 C0 03 00 00 E0 07 00 00 F0 0F 00 00'
-} */
-
-/* BINRES cdrom.ico */
-11 ICON cdrom.ico
-/* {
- '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 3E 09 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 4E 1F 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 76 20 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 5E 23 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 C6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 2E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 D6 3C 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 01 01 00 01 02 02 00 02 03 03 00 05 05'
- '05 00 06 06 06 00 07 07 07 00 09 09 09 00 0B 0B'
- '0B 00 10 10 10 00 13 13 13 00 18 18 18 00 1B 1C'
- '1B 00 1E 1E 1E 00 22 26 23 00 23 29 24 00 24 2E'
- '25 00 3B 40 3C 00 3E 40 3F 00 40 41 40 00 41 43'
- '42 00 42 44 43 00 46 48 47 00 4E 50 4F 00 50 52'
- '51 00 54 55 55 00 56 56 56 00 57 57 57 00 57 58'
- '58 00 59 59 59 00 5A 5A 5A 00 5A 5B 5B 00 5B 5C'
- '5C 00 5D 5E 5E 00 5F 68 5F 00 71 71 72 00 72 72'
- '73 00 74 74 74 00 77 76 77 00 78 76 77 00 72 78'
- '72 00 79 76 78 00 7A 76 78 00 7B 77 79 00 7D 78'
- '7A 00 7F 78 7B 00 7F 7F 7F 00 80 7A 7D 00 81 7C'
- '7F 00 0E CE 0E 00 14 C2 15 00 10 CE 10 00 6D 90'
- '6D 00 82 7D 80 00 84 80 83 00 86 83 85 00 8D 8B'
- '8C 00 90 8F 90 00 95 96 95 00 97 97 97 00 98 98'
- '98 00 98 99 99 00 99 9A 9A 00 9B 9C 9B 00 9F A0'
- '9F 00 A7 A7 A7 00 A9 A8 A9 00 AB AA AA 00 AD AC'
- 'AC 00 AE AE AE 00 B1 B0 B1 00 B3 B2 B3 00 B4 B3'
- 'B4 00 B6 B6 B6 00 B8 B8 B8 00 B9 B9 B9 00 BB BB'
- 'BB 00 BE BE BE 00 C0 C0 C0 00 C2 C3 C2 00 C3 C3'
- 'C2 00 C5 C2 C3 00 C7 C1 C4 00 C9 C3 C5 00 CA C6'
- 'C7 00 CA C8 C8 00 CA C9 C9 00 CB CA CA 00 CC CB'
- 'CB 00 CD CB CB 00 CD CC CC 00 CD CD CD 00 CE CE'
- 'CE 00 CE CF CF 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
- 'D1 00 D2 D2 D2 00 D4 D3 D3 00 D4 D4 D4 00 D5 D4'
- 'D4 00 D7 D4 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DD DD DD 00 DE DE DE 00 FB D6 D7 00 FD D4'
- 'D5 00 FE D4 D6 00 FE D4 DF 00 F7 D9 DA 00 F0 DE'
- 'DF 00 EA DB E2 00 FE D3 E9 00 FE D3 ED 00 FE D4'
- 'EF 00 F2 DA E8 00 F9 DA EF 00 FE D4 F1 00 FE D5'
- 'F4 00 FE D6 F6 00 FC DB F4 00 FE D8 F9 00 FE DB'
- 'F9 00 FE DC F8 00 E1 E0 E0 00 E7 E5 E6 00 E7 E6'
- 'E6 00 E7 E7 E7 00 EA E3 E3 00 E8 E8 E8 00 E9 E9'
- 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
- 'ED 00 EF EE EE 00 F0 EE EF 00 F0 EF F0 00 F1 F0'
- 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F2 F3 F3 00 F3 F5'
- 'F5 00 F7 F6 F8 00 FA F7 FA 00 FB FA FB 00 FC F8'
- 'FC 00 00 00 00 00 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 54 00'
- '00 00 00 00 00 00 03 00 00 00 5C 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 88 36'
- '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 63 64 72 6F 6D 2E 69 63 6F'
- '00 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 99 99 0D 09 08 0C 99 99 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 99 21 11 45 4C 5D 55 21 14 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 99 23 4D 97 7F 7F 76 71 72 74 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 99 23 75 80 7B 7B 72 71 71 71 94 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 10 28 98 7C 78 7B 72 71 71 6F 94 92 00 00'
- '99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
- '99 10 1F 59 7D 78 78 7B 71 71 6F 93 92 92 00 99'
- '08 15 19 17 21 23 1F 1D 1D 1E 1E 1D 1D 1C 1C 1F'
- '1F 12 40 81 78 78 78 7B 71 71 8E 91 92 92 99 99'
- '37 6A 82 83 50 32 98 8B 84 82 67 64 64 64 61 63'
- '1B 17 75 7C 78 7B 78 78 7B 7F 7F 7B 93 92 99 03'
- '65 94 89 81 31 31 33 79 5C 5E 5A 5B 5B 5B 67 24'
- '0E 23 97 7A 92 77 7B 78 7F 53 6F 7F 8E 8F 99 07'
- '83 8D 89 98 34 31 41 52 4E 4E 4E 4E 4E 4E 50 4E'
- '2F 27 97 93 93 8C 7A 7F 48 40 23 70 7E 90 99 05'
- '92 8B 93 3A 2B 38 2A 25 25 25 25 25 25 25 25 26'
- '23 3A 97 92 92 93 92 7E 10 00 00 3A 81 93 99 04'
- '92 8F 91 44 39 3A 3F 3F 3F 3F 3F 3D 3C 3C 3C 3E'
- '35 40 97 92 92 93 76 7E 11 99 00 52 7E 8D 99 03'
- '90 8F 89 90 8A 89 87 86 82 82 82 82 82 82 82 83'
- '47 3D 97 92 92 93 8E 7C 53 38 52 81 7E 76 99 02'
- '96 96 8A 8D 88 87 87 87 88 88 87 87 87 87 85 8B'
- '4B 23 97 92 92 92 8F 8D 7F 81 7F 7F 77 7B 99 01'
- '97 82 46 46 66 68 67 67 67 67 66 66 66 67 67 6A'
- '50 22 95 93 92 92 92 94 72 71 71 76 7B 78 99 99'
- '94 5F 44 44 51 69 66 64 63 63 67 68 66 63 63 64'
- '82 23 49 97 92 92 92 94 6F 71 71 76 7B 78 00 99'
- '55 86 58 55 5C 5F 60 60 61 64 63 63 63 64 5F 62'
- '62 84 20 65 94 92 92 71 71 71 71 76 78 78 00 99'
- '3F 86 5A 5C 5B 60 63 63 64 66 66 66 66 66 64 68'
- '82 68 3B 2D 97 95 6F 71 71 71 77 7B 7B 7C 00 99'
- '22 82 55 56 64 61 60 60 60 5F 61 60 60 61 60 5F'
- '5C 62 69 3A 38 73 6F 71 71 77 7B 7B 81 75 00 99'
- '11 6C 57 5F 62 5F 5F 5E 5E 5F 62 60 62 62 62 62'
- '60 62 5C 5B 39 36 57 72 81 81 98 98 48 3A 00 99'
- '0B 57 62 61 60 5E 5F 5F 5F 5E 5E 62 62 62 62 62'
- '62 62 66 4D 4A 0C 02 13 19 18 16 15 99 00 00 99'
- '08 4A 66 61 61 60 60 60 60 60 61 61 61 61 61 61'
- '61 61 64 4C 48 0F 99 00 00 00 00 00 00 00 00 99'
- '99 3A 82 66 67 67 67 67 67 67 67 67 63 64 64 64'
- '63 64 5E 54 5A 10 99 00 00 00 00 00 00 00 00 99'
- '99 23 8A 6D 6E 6D 6B 6B 6B 6B 6B 6B 6C 6D 6D 6C'
- '6E 83 84 6E 46 0A 99 00 00 00 00 00 00 00 00 00'
- '99 11 84 86 82 82 82 82 86 82 82 82 82 82 82 82'
- '83 85 84 83 38 02 99 00 00 00 00 00 00 00 00 00'
- '99 0B 82 87 85 88 8B 8A 8A 87 88 88 88 88 87 84'
- '85 87 85 84 23 99 99 00 00 00 00 00 00 00 00 00'
- '99 99 56 90 69 83 8B 8B 8A 8A 8A 89 8A 8B 8B 8B'
- '87 69 89 8B 17 99 99 00 00 00 00 00 00 00 00 00'
- '99 99 4F 6B 43 45 92 8F 8F 8F 8F 8D 8F 8F 8F 94'
- '54 42 5A 92 12 99 99 00 00 00 00 00 00 00 00 00'
- '00 99 24 6E 88 8B 97 97 97 97 97 97 97 97 97 97'
- '95 87 83 4C 06 99 00 00 00 00 00 00 00 00 00 00'
- '00 99 07 1A 30 2C 29 29 29 29 29 29 29 29 29 29'
- '2B 2F 23 10 99 99 00 00 00 00 00 00 00 00 00 00'
- '00 00 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
- '99 99 99 99 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF 00 FF FF FE 00 FF FF FC 00 FF FF F8 00 FF FF'
- 'F0 00 C0 00 00 00 80 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
- '00 7F C0 00 00 7F C0 00 00 7F C0 00 00 7F E0 00'
- '00 FF E0 00 00 FF F0 00 03 FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 05 05 05 00 0C 0F'
- '0F 00 0D 11 0E 00 15 15 15 00 36 36 36 00 39 39'
- '39 00 40 43 41 00 44 47 45 00 53 53 53 00 5B 60'
- '5D 00 67 68 68 00 64 6A 69 00 69 69 69 00 6B 6C'
- '6B 00 6E 6E 6E 00 6F 6E 6E 00 6F 70 70 00 72 72'
- '72 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F 7F 00 00 FF'
- '00 00 75 99 75 00 88 6C 88 00 84 7E 84 00 8B 7E'
- '82 00 80 80 80 00 84 84 84 00 93 93 93 00 97 97'
- '97 00 9A 98 98 00 9B 9B 9B 00 9D 9D 9D 00 9F 9F'
- '9F 00 A0 A0 A0 00 A5 A5 A5 00 A6 A6 A6 00 A8 A2'
- 'A8 00 B8 AC B8 00 BB BB BB 00 A6 D4 A6 00 D8 AE'
- 'C6 00 CB BD C9 00 C0 C0 C0 00 C2 C2 C2 00 C2 C3'
- 'C3 00 C3 C3 C3 00 C8 C8 C8 00 C9 C9 C9 00 CE CE'
- 'CE 00 CF CF CF 00 D3 C2 CD 00 D0 D0 D0 00 D1 D1'
- 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D6 D0 D6 00 D4 D4'
- 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
- 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
- 'DC 00 DE DE DE 00 FF D2 CD 00 FF D2 CE 00 E2 C2'
- 'DA 00 FF D8 D7 00 FF D4 D8 00 FA DD DA 00 FD DC'
- 'DC 00 FF DE DF 00 F4 D7 EA 00 FF D3 E8 00 FF D6'
- 'E8 00 FF D7 EF 00 FF D3 F1 00 FF D3 F2 00 FF D3'
- 'F3 00 FF D4 F5 00 FF D7 F7 00 FF D9 F7 00 FD D9'
- 'FB 00 E1 E1 E1 00 E3 E4 E3 00 E4 E4 E4 00 E5 E5'
- 'E5 00 E6 E6 E6 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
- 'EA 00 EA EB EB 00 EB EB EB 00 ED ED ED 00 FF E3'
- 'E1 00 F5 EA EF 00 FF EF EF 00 FD E7 F4 00 FB ED'
- 'F4 00 FE E7 FA 00 FF E2 FF 00 FF E9 FF 00 FF ED'
- 'FE 00 FF EE FF 00 EE F9 F7 00 F1 F1 F1 00 F1 F3'
- 'F2 00 F2 F2 F2 00 F3 F3 F3 00 F0 F5 F2 00 F0 F6'
- 'F3 00 F0 F7 F7 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
- 'F6 00 FF F0 FF 00 FF F3 FF 00 FF F6 FF 00 F9 F9'
- 'F9 00 FA FA FA 00 FB FB FB 00 FC FC FC 00 FD FD'
- 'FD 00 FF FD FE 00 FE FE FE 00 FF FF FF 00 00 00'
- '00 00 E7 E5 E6 00 E7 E6 E6 00 E7 E7 E7 00 EA E3'
- 'E3 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
- 'EB 00 EC EC EC 00 ED ED ED 00 EF EE EE 00 F0 EE'
- 'EF 00 F0 EF F0 00 F1 F0 F0 00 F1 F1 F1 00 F2 F2'
- 'F2 00 F2 F3 F3 00 F3 F5 F5 00 F7 F6 F8 00 FA F7'
- 'FA 00 FB FA FB 00 FC F8 FC 00 00 00 00 00 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 54 00 00 00 00 00 00 00 03 00'
- '00 00 5C 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 63'
- '64 72 6F 6D 2E 69 63 6F 00 00 1A 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
- '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
- '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 03 0A 0C 02 00 00 00 00 00 00 00 00 00 00'
- '00 0E 6B 68 4B 64 00 82 82 82 82 82 82 82 82 82'
- '11 77 53 45 49 73 82 10 26 17 27 25 22 21 23 08'
- '4C 52 50 4E 67 71 82 7F 79 16 29 39 33 38 28 09'
- '81 63 55 2B 2A 66 82 81 30 18 19 14 14 13 1B 1C'
- '80 72 6A 82 07 79 82 81 74 6D 61 60 60 60 6F 1E'
- '7E 6E 65 46 56 4F 82 7D 24 38 3D 3B 3D 3C 41 1D'
- '5F 74 6C 47 48 51 82 3D 32 32 37 3A 3B 3B 38 58'
- '1A 81 4A 44 4D 54 82 20 37 38 35 35 36 37 37 38'
- '2E 1F 62 69 78 34 00 0D 43 35 35 35 36 37 37 38'
- '36 0B 00 00 00 00 00 06 61 40 3E 3F 3F 3E 3E 42'
- '57 12 00 00 00 00 00 01 70 5E 5C 5B 5A 5A 59 60'
- '75 05 00 00 00 00 00 82 5D 31 7A 76 74 75 7B 32'
- '7C 04 00 00 00 00 00 82 0F 2C 2F 2D 2D 2D 2D 2C'
- '1E 82 00 00 00 00 00 00 82 82 82 82 82 82 82 82'
- '82 00 00 00 00 00 FF F0 00 00 FF E0 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 0F'
- '00 00 80 0F 00 00 80 0F 00 00 80 0F 00 00 80 0F'
- '00 00 C0 1F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -10723,246 +7397,36 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0C 00 00 00 30 00 00 00 48 00 00 00 90 00 00'
- '00 90 00 00 00 90 00 00 00 78 00 00 00 30 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 86 86'
- '86 FF 7A 7A 7A FF AA AA AA FF DA DA DA FF F2 F2'
- 'F2 FF CE CE CE FF AA AA AA FF 6E 6E 6E FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0C 7A 7A 7A FF 80 80'
- '80 FF FF FF FF FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 D4 FF FF D4 D4 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- '00 13 00 00 00 78 6E 6E 6E FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 56 62 62 62 FF E6 E6 E6 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 00 00 00 00 05 00 00 00 69 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 62 62 62 FF 56 56'
- '56 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 00 00 00 00 9B 00 00 00 FF 21 21 21 FF 2C 2C'
- '2C FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 4A 4A 4A FF 62 62'
- '62 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 03 01 01 01 FF 8A 8A 8A FF EB EB EB FF E8 E8'
- 'E8 FF E8 E8 E8 FF D4 D4 D4 FF 00 C0 00 FF E7 E7'
- 'E7 FF E8 E8 E8 FF E3 E3 E3 FF D8 D8 D8 FF D2 D2'
- 'D2 FF CD CD CD FF CD CD CD FF CD CD CD FF C8 C9'
- 'C9 FF AA AA AA FF 2E 2E 2E FF 62 62 62 FF DA DA'
- 'DA FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 FF FF FF D4 FF FF FF D4'
- 'FF FF FF D4 F0 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 15 19 19 19 FF AD A8 AB FF EB EB EB FF E8 E8'
- 'E8 FF E8 E8 E8 FF 00 FF 00 FF 00 FF 00 FF 00 C0'
- '00 FF DF DF DF FF D5 D5 D5 FF D2 D2 D2 FF CB CB'
- 'CB FF CD CD CD FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF 40 40 40 FF 2E 2E 2E FF 7A 7A 7A FF F2 F2'
- 'F2 FF FF D4 E3 FF F2 F2 F2 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 FF FF FF D4 E3 FF FF D4'
- 'E3 FF FF D4 FF FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 34 28 28 28 FF D1 D1 D1 FF EB EB EB FF EB EB'
- 'EB FF E8 E8 E8 FF E8 E8 E8 FF 00 FF 00 FF B5 B5'
- 'B5 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6'
- 'B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6'
- 'B6 FF B6 B6 B6 FF B6 B6 B6 FF A4 A0 A0 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 F0 FF B6 B6 B6 FF AA AA AA FF 62 62'
- '62 FF FF D4 E3 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
- '00 33 28 28 28 FF D1 D1 D1 FF E8 E8 E8 FF EB EB'
- 'EB FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF B6 B6 B6 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 E3 FF 6E 6E 6E FF 00 00 00 00 00 00'
- '00 00 B6 B6 B6 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
- '00 33 27 27 27 FF D2 D2 D2 FF EA EA EA FF EB EB'
- 'EB FF A7 A7 A7 FF A7 A7 A7 FF AB AB AB FF AE AE'
- 'AE FF AF AF AF FF AF AF AF FF AF AF AF FF AF AF'
- 'AF FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
- 'AB FF AB AB AB FF AB AB AB FF CE CE CE FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
- 'E3 FF FF D4 E3 FF 80 80 80 FF 00 00 00 78 00 00'
- '00 00 FF D4 F0 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
- '00 33 26 26 26 FF D3 D3 D3 FF E8 E8 E8 FF E6 E6'
- 'E6 FF E2 E2 E2 FF DB DB DB FF D8 D8 D8 FF D9 D9'
- 'D9 FF D2 D2 D2 FF CF CF CF FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CE CE CE FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 F0 FF C0 C0 C0 FF 62 62 62 FF 80 80'
- '80 FF FF D4 F0 FF FF D4 F0 FF FF D4 E3 FF 00 00'
- '00 33 24 24 24 FF D6 D6 D6 FF E9 E9 E9 FF E1 E1'
- 'E1 FF E2 E2 E2 FF E0 E0 E0 FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF 92 92 92 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 FF FF FF D4 FF FF FF D4'
- 'FF FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 34 24 24 24 FF DE DE DE FF D9 D9 D9 FF C4 C4'
- 'C4 FF BF BF BF FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF 7A 7A 7A FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 07 05 05 05 FF C2 C2 C2 FF BC BC BC FF B2 B2'
- 'B2 FF AB AB AB FF BB BB BB FF D5 D5 D5 FF D5 D5'
- 'D5 FF D4 D4 D4 FF D3 D3 D3 FF D5 D5 D5 FF D7 D7'
- 'D7 FF D8 D8 D8 FF D7 D7 D7 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D4 D4 D4 FF D5 D5 D5 FF 62 62 62 FF 86 86'
- '86 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 FF A4 A4 A4 FF CF CF CF FF C5 C5'
- 'C5 FF BF BF BF FF C9 C9 C9 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
- 'D0 FF D4 D4 D4 FF D0 D0 D0 FF D3 D3 D3 FF 62 62'
- '62 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 FF 59 59 59 FF D0 D0 D0 FF CD CD'
- 'CD FF CD CD CD FF CA CA CA FF D3 D3 D3 FF D3 D3'
- 'D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF DB DB DB FF E4 E4 E4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 92 92 92 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 FE 40 40 40 FF D2 D2 D2 FF CA CA'
- 'CA FF CA CA CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D3 D3 D3 FF D2 D2 D2 FF D3 D3 D3 FF D2 D2'
- 'D2 FF D1 D1 D1 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 6E 6E 6E FF 92 92 92 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 E1 07 07 07 FF DD DD DD FF CC CC'
- 'CC FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF C4 C4 C4 FF B3 B3 B3 FF 62 62 62 FF 9E 9E'
- '9E FF FF D4 D4 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF CE CE CE FF 9E 9E 9E FF 92 92 92 FF 00 00'
- '00 00 00 00 00 B2 00 00 00 FF DD DD DD FF CF CF'
- 'CF FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
- 'CF FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF B3 B3 B3 FF B3 B3 B3 FF 00 00 00 FF 00 00'
- '00 FF 62 62 62 FF 86 86 86 FF 86 86 86 FF 86 86'
- '86 FF 6E 6E 6E FF 00 00 00 24 00 00 00 00 00 00'
- '00 00 00 00 00 4B 00 00 00 FE D8 D8 D8 FF D4 D4'
- 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF B3 B3 B3 FF B3 B3 B3 FF 00 00 00 CF 00 00'
- '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 00 00 00 F2 CC CC CC FF D6 D6'
- 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4'
- 'C4 FF BD BD BD FF D0 D0 D0 FF 09 09 09 FF 00 00'
- '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 02 00 00 00 BF 97 97 97 FF DC DC'
- 'DC FF DC DC DC FF DE DE DE FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF E7 E7 E7 FF E7 E7'
- 'E7 FF DC DC DC FF C6 C6 C6 FF 00 00 00 FF 00 00'
- '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 77 77 77 FF D3 D3'
- 'D3 FF E1 E1 E1 FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7 E7 FF E7 E7'
- 'E7 FF D9 D9 D9 FF BB BB BB FF 00 00 00 FF 00 00'
- '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 62 35 35 35 FF BD BD'
- 'BD FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
- 'E6 FF D4 D4 D4 FF 9A 9A 9A FF 00 00 00 ED 00 00'
- '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 2D 1E 1E 1E FF AB AB'
- 'AB FF ED ED ED FF E7 E7 E7 FF EC EC EC FF EB EB'
- 'EB FF ED ED ED FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EC EC EC FF E5 E5 E5 FF EB EB'
- 'EB FF D6 D6 D6 FF 8A 8A 8A FF 00 00 00 C3 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 8D 8D'
- '8D FF C4 C4 C4 FF B2 B2 B2 FF B2 B2 B2 FF EB EB'
- 'EB FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F3 F3 F3 FF D5 D5 D5 FF B6 B6 B6 FF B7 B7'
- 'B7 FF CD CD CD FF 61 61 61 FF 00 00 00 85 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 64 64'
- '64 FF DD DD DD FF DC DC DC FF E4 E4 E4 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF FA FA FA FF F2 F2 F2 FF D8 D8 D8 FF DC DC'
- 'DC FF B0 B0 B0 FF 34 34 34 FF 00 00 00 67 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 00 00'
- '00 FF 3D 3D 3D FF 49 49 49 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 49 49 49 FF 49 49'
- '49 FF 02 02 02 FF 00 00 00 FF 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00'
- '00 7F 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 D6 00 00 00 5C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF 00 FF FF FE 00 FF FF FC 00 FF FF E0 00 FF FF'
- 'F0 00 80 00 00 00 80 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
- '00 7F C0 00 00 7F C0 00 00 7F E0 00 00 7F E0 00'
- '00 FF E0 00 01 FF E0 00 01 FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 08 FF FF 00 00 00 00 00 8F FF FF 08 88'
- '88 88 80 FF FF FF 0F FA F7 77 88 FF F7 FF 0F 88'
- '88 88 88 FF F0 8F 0F FF FF FF F8 FF F8 FF 0F 77'
- '77 77 78 FF FF FF 07 77 77 77 77 7F FF FF 07 77'
- '77 77 77 8F FF FF 07 77 77 77 77 70 28 80 08 77'
- '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 77'
- '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 00'
- '00 00 00 00 00 00 FF E0 00 00 FF C0 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01'
- '00 00 00 07 00 00 80 07 00 00 80 07 00 00 80 0F'
- '00 00 C0 1F 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 77 77 88 00 00'
- '00 00 00 00 00 00 00 00 00 08 7F FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 00 8F FF FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 08 FF FF FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 87 FF FF FF FF FF 00 08'
- '88 88 88 88 88 88 88 80 8F FF FF FF FF FF 00 87'
- 'FF 7A FF FF 77 77 77 88 FF FF FF FF FF FF 00 7F'
- 'FF AA AF 77 77 77 78 08 FF FF FF F7 FF FF 00 FF'
- 'FF 8A 77 77 77 77 77 88 FF FF FF 78 8F FF 00 FF'
- 'F8 88 88 88 88 88 88 88 FF FF FF 00 08 FF 00 FF'
- 'F7 88 88 88 88 88 88 88 FF FF FF 00 07 FF 00 FF'
- 'FF FF FF FF FF FF FF 78 FF FF FF 78 7F FF 00 FF'
- 'FF FF FF FF FF FF FF 78 FF FF FF FF FF FF 00 FF'
- '77 77 77 77 77 77 77 78 FF FF FF FF FF FF 00 F7'
- '77 77 77 77 77 77 77 78 7F FF FF FF FF FF 00 77'
- '77 77 77 77 77 77 77 77 87 FF FF FF FF FF 00 87'
- '77 77 77 77 77 77 77 77 88 FF FF FF FF FF 00 87'
- '77 77 77 77 77 77 77 77 78 8F FF FF FF FF 00 07'
- '77 77 77 77 77 77 77 77 77 88 7F FF FF 78 00 07'
- '77 77 77 77 77 77 77 77 77 70 02 88 88 70 00 07'
- '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 08'
- '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 08'
- '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
- '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
- '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
- '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
- '77 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00'
- '87 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00'
- '08 88 88 88 88 88 88 88 80 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF 00 FF FF FE 00 FF FF FC 00 FF FF F8 00 FF FF'
- 'F0 00 C0 00 00 00 80 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
- '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
- '00 7F C0 00 00 7F C0 00 00 7F C0 00 00 7F E0 00'
- '00 FF E0 00 00 FF F0 00 03 FF FF FF FF FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 78 6E 6E 6E FF 62 62'
- '62 FF 00 00 00 9C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 62 62 62 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'D4 FF FF D4 D4 FF 00 00 00 00 00 00 00 16 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 42 62 62'
- '62 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF F2 F2 F2 FF 00 00 00 54 90 90 90 FF AB AC'
- 'AC FF CC CC CC FF C4 C4 C4 FF C2 C2 C2 FF C1 C1'
- 'C1 FF BC BC BC FF BD BD BD FF 6E 6E 6E FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'E3 FF F2 F2 F2 FF 00 00 00 FA EA EA EA FF E8 E8'
- 'E8 FF 00 FF 00 FF CB CB CB FF C8 C8 C8 FF C8 C8'
- 'C8 FF C8 C8 C8 FF C8 C8 C8 FF 56 56 56 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 F0 FF B6 B6 B6 FF FF B1'
- 'C7 FF FF D4 E3 FF 00 00 00 F9 EF EF EF FF EB EB'
- 'EB FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 80 80 80 FF 80 80 80 FF 62 62 62 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 F0 FF 00 00 00 78 62 62'
- '62 FF F2 F2 F2 FF 00 00 00 F9 F7 F7 F7 FF F6 F6'
- 'F6 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1'
- 'F1 FF F0 F0 F0 FF EF EF EF FF 62 62 62 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4 E3 FF FF D4'
- 'FF FF FF D4 F0 FF 00 00 00 F7 F3 F3 F3 FF B7 B7'
- 'B7 FF DA DA DA FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D8 D8 D8 FF D3 D3 D3 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 F0 FF 00 00 00 73 EF EF EF FF CB CB'
- 'CB FF CE CE CE FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D3 D3 D3 FF 7A 7A'
- '7A FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF 00 00 00 25 B7 B7 B7 FF CB CB'
- 'CB FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4'
- 'C4 FF 80 80 80 FF FF D4 D4 FF FF D4 F0 FF FF D4'
- 'F0 FF E6 E6 E6 FF 00 00 00 00 5F 5F 5F FF D2 D2'
- 'D2 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF 99 99 99 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 18 18 18 FF DB DB'
- 'DB FF DE DE DE FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DD DD DD FF DD DD DD FF DD DD DD FF D9 D9'
- 'D9 FF 7A 7A 7A FF 00 00 00 0A 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 FF E5 E5'
- 'E5 FF EB EB EB FF EB EB EB FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E7 E7 E7 FF E6 E6'
- 'E6 FF 20 20 20 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 DD E4 E4'
- 'E4 FF C1 C1 C1 FF ED ED ED FF EE EE EE FF EB EB'
- 'EB FF ED ED ED FF ED ED ED FF C2 C2 C2 FF EC EC'
- 'EC FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 44 80 80'
- '80 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF B0 B0'
- 'B0 FF 00 00 00 ED 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 2C 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF F0 00 00 FF E0 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 0F'
- '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 80 0F'
- '00 00 C0 1F 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 08 88 88 80 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '88 87 77 F7 77 88 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 08 87 FF FF FF FF F7 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87'
- 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 08 FF FF FF FF FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 08 8F FF'
- 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 88 7F FF FF FF FF FF FF FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 08 88 FF FF'
- 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 08 8F FF FF FF FF FF FF FF FF 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 88 8F FF FF'
- 'FF FF FF FF FF FF 00 08 7F FF F7 AA FF FF 77 77'
- '77 77 77 70 88 7F FF FF FF FF FF FF FF FF 00 07'
- 'FF FF FA AA AF 77 77 77 77 77 77 00 88 FF FF FF'
- 'FF FF FF FF FF FF 00 07 FF FF FA AA A7 77 77 77'
- '77 77 77 80 88 FF FF FF FF FF 78 87 FF FF 00 07'
- 'FF FF FF AA 77 77 77 77 77 77 77 77 87 FF FF FF'
- 'FF F7 87 88 FF FF 00 07 FF FF 88 88 88 88 88 88'
- '88 88 88 88 87 FF FF FF FF F8 00 08 7F FF 00 07'
- 'FF FF 88 88 88 88 88 88 88 88 88 88 87 FF FF FF'
- 'FF F8 00 08 7F FF 00 07 FF FF 77 77 77 77 77 77'
- '77 77 77 77 87 FF FF FF FF F8 00 08 FF FF 00 07'
- 'FF FF F7 77 77 77 77 77 77 77 77 77 87 FF FF FF'
- 'FF F7 88 8F FF FF 00 07 FF FF FF FF FF FF FF FF'
- 'FF FF FF FF 87 FF FF FF FF FF FF FF FF FF 00 07'
- 'FF FF FF 77 77 7F FF FF FF FF FF FF 88 FF FF FF'
- 'FF FF FF FF FF FF 00 07 77 77 77 77 77 77 77 77'
- '77 77 77 77 88 FF FF FF FF FF FF FF FF FF 00 07'
- '77 77 77 77 77 77 77 77 77 77 77 77 78 7F FF FF'
- 'FF FF FF FF FF FF 00 07 77 77 77 77 77 77 77 77'
- '77 77 77 77 78 8F FF FF FF FF FF FF FF FF 00 07'
- '77 77 77 77 77 77 77 77 77 77 77 77 77 87 FF FF'
- 'FF FF FF FF FF FF 00 08 77 77 77 77 77 77 77 77'
- '77 77 77 77 77 88 7F FF FF FF FF FF FF FF 00 08'
- '77 77 77 77 77 77 77 77 77 77 77 77 77 78 8F FF'
- 'FF FF FF FF FF FF 00 00 77 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 88 FF FF FF FF FF FF FF 00 00'
- '77 77 77 77 77 77 77 77 77 77 77 77 77 77 78 87'
- 'FF FF FF FF FF F8 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 88 87 FF FF FF 78 88 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '08 88 88 88 80 00 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '00 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
- '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
- '00 77 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
- '00 00 00 00 00 00 00 00 00 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
- '00 87 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
- '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
- '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
- '00 87 77 77 77 77 77 77 77 77 77 77 77 77 70 00'
- '00 00 00 00 00 00 00 00 00 08 77 77 77 77 77 77'
- '77 77 77 77 77 77 80 00 00 00 00 00 00 00 00 00'
- '00 00 08 88 88 88 88 88 88 88 88 88 88 80 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF F0 00 00 00 FF FF FF FF E0 00 00 00 FF FF'
- 'FF FF C0 00 00 00 FF FF FF FF 80 00 00 00 FF FF'
- 'FF FE 00 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
- 'FF FC 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 1E 00 00'
+ '00 2B 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2C 00 00 00 2C 00 00 00 2C 00 00'
+ '00 2C 00 00 00 2B 00 00 00 28 00 00 00 16 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C3 C3 C3 4D A4 A4 A4 9E 89 89'
+ '89 B2 85 85 85 B4 83 83 83 B4 80 80 80 B4 80 80'
+ '80 B4 80 7F 80 B4 7C 7B 7C B4 7B 7B 7B B4 7B 7B'
+ '7B B4 7B 7B 7B B4 78 78 79 B4 78 78 79 B4 78 79'
+ '79 B4 75 77 77 B4 75 75 75 B4 74 74 74 B4 74 74'
+ '74 B4 72 72 72 B4 72 72 72 B4 6F 6F 71 B4 6E 6E'
+ '6E B4 6E 6E 6E B4 6E 6E 6E B4 6B 6B 6D B4 6B 6B'
+ '6B B4 68 6A 6A B4 67 67 68 B4 64 66 66 B4 64 64'
+ '64 B4 64 64 64 B4 64 64 64 B4 61 61 61 B4 61 61'
+ '61 B4 61 61 61 B4 61 61 61 B4 60 60 60 B4 60 60'
+ '60 B4 60 60 60 B3 5A 5A 5A A6 05 05 05 5B 00 00'
+ '00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 2F 2F 2F 10 D5 D5 D5 9E D9 D9 D9 FA C8 C8'
+ 'C8 FC C1 C1 C1 FC BE BD BD FC BE BD BD FC BD BC'
+ 'BB FC BB BA B9 FC B9 B7 B7 FC B7 B7 B6 FC B7 B6'
+ 'B5 FC B5 B5 B4 FC B3 B2 B2 FC B2 B1 B1 FC B1 B0'
+ 'B0 FC AF AE AE FC AD AC AB FC AC AB AA FC AB A8'
+ 'A8 FC A7 A6 A6 FC A6 A5 A4 FC A4 A2 A2 FC A2 A1'
+ 'A0 FC A1 9F 9F FC A0 9E 9E FC 9E 9D 9D FC 9C 9B'
+ '9B FC 99 99 98 FC 98 97 97 FC 95 94 94 FC 94 93'
+ '92 FC 8F 8E 8E FC 8B 8B 8B FC 8B 8B 8B FC 8C 8C'
+ '8C FC 8B 8B 8B FC 8C 8C 8C FC 8A 8A 8A FC 8A 8A'
+ '8A FC 89 89 89 FC 90 90 90 EE 1C 1C 1B 8D 00 00'
+ '00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 16 16 16 17 A4 A4 A4 AF BE BE BE FF B6 B6'
+ 'B6 FF D3 D2 D1 FF E6 E0 DB FF EA E3 DC FF EB E4'
+ 'DD FF ED E6 E0 FF F2 ED E9 FF F5 F3 F1 FF F6 F4'
+ 'F3 FF F6 F4 F3 FF F6 F4 F3 FF F6 F4 F2 FF F5 F3'
+ 'F1 FF F5 F3 F0 FF F5 F2 F0 FF F4 F2 F0 FF F4 F2'
+ 'EF FF F4 F1 EF FF F3 F1 EE FF F3 F1 EE FF F3 F1'
+ 'EE FF F3 F1 EE FF F4 F1 EE FF F3 F1 EF FF F3 F1'
+ 'EE FF F3 F1 EF FF F3 F2 EF FF F3 F1 F0 FF F3 F1'
+ 'F0 FF EB EA E9 FF C6 C5 C4 FF 90 90 90 FF 7D 7D'
+ '7D FF 7B 7B 7B FF 7B 7B 7B FF 79 79 79 FF 78 78'
+ '78 FF 76 76 76 FF 8C 8C 8D F9 3A 3A 3B AB 00 00'
+ '00 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 12 12 12 1C 8B 8B 8B B9 BA BA BA FF C9 C8'
+ 'C8 FF F5 F3 F0 FF E9 DF D6 FF E5 D9 CD FF E4 D7'
+ 'CA FF E7 DB D0 FF E7 DB D1 FF E5 DA D0 FF E3 D8'
+ 'CE FF E3 D6 CC FF E4 D9 CF FF E7 DD D2 FF E7 DC'
+ 'D1 FF EC E2 D9 FF ED E3 DA FF ED E5 DD FF F0 E8'
+ 'DF FF F1 EB E4 FF F2 EB E5 FF F2 EB E5 FF F2 EB'
+ 'E5 FF F2 EB E4 FF F1 E9 E2 FF EF E6 DE FF EC E3'
+ 'D9 FF E8 DD D2 FF E5 DA CF FF E4 D9 CF FF E3 D8'
+ 'CC FF E6 DB D1 FF F3 F0 EB FF D0 CF CE FF 87 87'
+ '86 FF 7D 7D 7D FF 7C 7C 7C FF 7B 7B 7B FF 7A 7A'
+ '7A FF 78 78 78 FF 90 90 90 FC 5D 5D 5D BF 00 00'
+ '00 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 17 17 17 21 76 76 76 C1 B5 B5 B6 FF D7 D6'
+ 'D6 FF FD FB FA FF FB F8 F7 FF C1 A6 8D FF FC FB'
+ 'FA FF F8 F6 F4 FF F5 F2 EF FF EB E5 DE FF EA E1'
+ 'DA FF F1 EA E5 FF F1 EC E7 FF E9 E1 D9 FF EF E8'
+ 'E2 FF D4 C2 B0 FF EA E1 DA FF F1 EB E6 FF E7 DC'
+ 'D3 FF E5 DA D1 FF ED E6 E0 FF EC E5 DF FF EA E3'
+ 'DB FF EC E5 DE FF EF E8 E2 FF F3 ED E8 FF F5 EF'
+ 'EB FF F3 EE E9 FF F2 EC E8 FF F1 EC E7 FF F1 EB'
+ 'E5 FF F2 ED E8 FF FA F8 F6 FF F9 F8 F8 FF A3 A3'
+ 'A3 FF 7D 7D 7D FF 7C 7C 7C FF 7D 7D 7D FF 7B 7B'
+ '7B FF 78 78 78 FF 8E 8E 8E FE 63 63 63 CA 00 00'
+ '00 4D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 39 39 39 28 6B 6B 6B CE B1 B1 B1 FF D3 D1'
+ 'CF FF FA F6 F1 FF FA F6 F3 FF DD CF C3 FF AF 89'
+ '6A FF CC B5 A1 FF 98 69 4E FF A6 7B 5B FF 99 6C'
+ '4F FF A4 79 5A FF A6 7D 58 FF B3 91 70 FF D3 BF'
+ 'AD FF EC E3 DB FF D9 C8 B8 FF D0 B9 A5 FF FD FB'
+ 'F9 FF F3 EB E6 FF B4 92 74 FF CE B7 A3 FF D2 BE'
+ 'AB FF CC B5 9F FF B5 94 75 FF AB 84 61 FF BD 9F'
+ '85 FF CF B7 A3 FF E0 D1 C4 FF F6 EF EA FF F7 F2'
+ 'ED FF F6 F1 ED FF F6 F2 ED FF FC F8 F4 FF C9 C8'
+ 'C6 FF 80 80 80 FF 7E 7E 7E FF 7C 7C 7C FF 7B 7B'
+ '7B FF 7A 7A 7A FF 8B 8B 8B FE 6E 6E 6E E1 09 09'
+ '09 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 55 55 55 30 66 66 66 DF B4 B4 B4 FF CB CA'
+ 'C9 FF F8 F6 F4 FF FB F8 F6 FF F2 EC E9 FF CB B5'
+ 'A6 FF DB CA BB FF F4 F0 EC FF E7 DE D5 FF F9 F5'
+ 'F2 FF F0 EB E5 FF EF E8 E2 FF D1 BD AA FF E3 D7'
+ 'CC FF D6 C3 B3 FF C9 B1 9D FF F1 EC E7 FF FD FC'
+ 'FB FF F2 EB E5 FF CF B9 A6 FF D5 C3 B3 FF E3 D6'
+ 'CC FF DB CC BE FF D7 C5 B6 FF D5 C3 B3 FF E4 D8'
+ 'CD FF FC F9 F8 FF F5 F0 EC FF FA F7 F5 FF FA F8'
+ 'F6 FF FA F8 F6 FF FA F7 F6 FF FC F9 F8 FF D6 D4'
+ 'D3 FF 84 84 84 FF 80 80 80 FF 7C 7C 7C FF 7C 7C'
+ '7C FF 7B 7B 7B FF 80 80 80 FF 79 79 79 ED 1D 1D'
+ '1D 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 5D 5D 5D 34 65 65 65 E5 B5 B5 B5 FF C0 BF'
+ 'BE FF ED EB E8 FF F8 F4 F0 FF EA E0 D7 FF CA B2'
+ '9C FF B1 8D 71 FF E2 D6 C9 FF F3 EC E7 FF F8 F4'
+ 'F0 FF F7 F4 F1 FF F8 F5 F1 FF F8 F4 F0 FF DA C8'
+ 'B9 FF C7 AD 96 FF B2 8E 6F FF CB B3 9E FF EC E3'
+ 'DA FF F8 F4 EF FF D9 C7 B7 FF C2 A5 8B FF ED E6'
+ 'E0 FF DA CA BA FF E7 DC D2 FF A6 7D 59 FF FB FA'
+ 'F8 FF F7 F3 EE FF F7 F2 EF FF F6 F2 EE FF F6 F2'
+ 'EE FF F6 F2 EE FF F6 F1 ED FF FB F7 F3 FF D1 D0'
+ 'CE FF 85 85 85 FF 83 83 83 FF 80 80 80 FF 7E 7E'
+ '7E FF 7C 7C 7C FF 7D 7D 7D FF 83 83 83 F6 2C 2C'
+ '2C 96 00 00 00 16 00 00 00 00 00 00 00 00 00 00'
+ '00 00 64 64 64 38 63 63 63 EB AD AD AD FF B8 B8'
+ 'B8 FF CC CB CB FF F1 F1 F0 FF FC FA F8 FF F8 F6'
+ 'F3 FF DF D2 CA FF E3 D6 CB FF F3 ED E8 FF FB F8'
+ 'F5 FF FB F7 F4 FF FA F7 F4 FF FA F7 F3 FF FD FC'
+ 'FB FF FB FA F8 FF F6 F2 EE FF F8 F5 F2 FF F6 F2'
+ 'EE FF FB F8 F6 FF FC FB F9 FF F0 E9 E4 FF E4 D7'
+ 'CC FF EC E4 DB FF F7 F3 F0 FF FB F8 F5 FF FC F9'
+ 'F8 FF FA F7 F4 FF FA F7 F4 FF FB F7 F4 FF FB F7'
+ 'F4 FF FB F7 F4 FF FC F9 F6 FF F4 F3 F2 FF A8 A8'
+ 'A8 FF 86 86 86 FF 84 84 84 FF 82 82 82 FF 81 81'
+ '81 FF 7D 7D 7D FF 7D 7D 7D FF 87 87 87 FC 37 37'
+ '37 B0 00 00 00 24 00 00 00 00 00 00 00 00 00 00'
+ '00 00 66 66 66 3C 66 66 66 EF A7 A7 A7 FF BE BE'
+ 'BE FF BA BA BA FF C8 C8 C7 FF DE DD DD FF E0 E0'
+ 'E0 FF DF DF DF FF DE DE DE FF DD DD DD FF DD DD'
+ 'DD FF DC DC DC FF DD DD DD FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DC DC DC FF DB DB'
+ 'DB FF D8 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D6 D6'
+ 'D6 FF D5 D5 D5 FF D6 D5 D5 FF D7 D7 D7 FF D5 D6'
+ 'D6 FF D3 D3 D3 FF D2 D2 D2 FF D3 D3 D3 FF D6 D5'
+ 'D5 FF D6 D6 D6 FF D1 D1 D1 FF B3 B3 B3 FF 8D 8D'
+ '8D FF 89 89 89 FF 87 87 87 FF 85 85 85 FF 83 83'
+ '83 FF 81 81 81 FF 7E 7E 7E FF 91 91 91 FE 3F 3F'
+ '3F C5 00 00 00 33 00 00 00 00 00 00 00 00 00 00'
+ '00 00 6F 6F 6F 3E 6B 6B 6B F2 9C 9C 9C FF C3 C3'
+ 'C3 FF BA BA BA FF BA BA BA FF BA BA BA FF B7 B7'
+ 'B7 FF B4 B4 B4 FF AF AF AF FF B0 B0 B0 FF AD AD'
+ 'AD FF AB AB AB FF AC AC AC FF AD AD AD FF AC AC'
+ 'AC FF AB AB AB FF AA AA AA FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A4 A4 A4 FF A3 A3 A4 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF A0 A0 A0 FF 9F 9F 9F FF 9E 9E 9E FF 9C 9C'
+ '9C FF 99 99 9A FF 98 98 98 FF 97 97 97 FF 98 98'
+ '98 FF 97 97 97 FF 95 95 95 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 8A 8A 8A FF 87 87 87 FF 85 85 85 FF 83 83'
+ '83 FF 82 82 82 FF 7F 7F 7F FF 8C 8C 8B FE 50 50'
+ '50 DA 00 00 00 45 00 00 00 00 00 00 00 00 00 00'
+ '00 00 81 81 81 3F 74 74 74 F5 92 91 92 FF CE CE'
+ 'CE FF BF BF BF FF BE BE BE FF BB BB BB FF B9 B9'
+ 'B9 FF B6 B6 B6 FF B3 B3 B3 FF B0 B0 B0 FF AC AC'
+ 'AC FF AA AA AA FF A9 A9 A9 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A3 A3 A3 FF A2 A2 A2 FF A2 A2'
+ 'A2 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F 9F FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9A 9A 9A FF 98 98 98 FF 98 98'
+ '98 FF 96 96 96 FF 94 94 94 FF 93 93 93 FF 92 92'
+ '92 FF 91 91 91 FF 91 91 91 FF 90 90 90 FF 8E 8E'
+ '8E FF 8C 8C 8C FF 8A 8A 8A FF 87 87 87 FF 86 86'
+ '86 FF 82 82 82 FF 81 81 81 FF 8C 8C 8C FF 6C 6C'
+ '6C EC 02 02 02 5B 00 00 00 00 00 00 00 00 00 00'
+ '00 00 89 89 89 41 7A 7B 7A F7 87 86 87 FF D4 D4'
+ 'D4 FF C2 C2 C2 FF C0 C0 C0 FF BD BD BD FF BA BA'
+ 'BA FF B8 B8 B8 FF B4 B4 B4 FF B1 B1 B1 FF B0 B0'
+ 'B0 FF AD AD AD FF AB AB AB FF AA AA AA FF A6 A6'
+ 'A6 FF A6 A6 A6 FF A4 A4 A4 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF A2 A2 A2 FF A1 A1 A1 FF 9E 9E 9E FF 9B 9B'
+ '9B FF 9C 9C 9C FF 9C 9C 9C FF 99 99 99 FF 98 98'
+ '98 FF 95 95 95 FF 95 95 95 FF 93 93 93 FF 91 91'
+ '91 FF 91 91 91 FF 90 90 90 FF 90 90 90 FF 8E 8E'
+ '8E FF 8D 8D 8D FF 8B 8B 8B FF 8A 8A 8A FF 88 88'
+ '88 FF 86 86 86 FF 84 84 84 FF 89 89 89 FF 86 86'
+ '86 F8 04 04 04 6E 00 00 00 12 00 00 00 00 00 00'
+ '00 00 90 90 90 45 84 84 84 F9 7D 7D 7D FF D8 D8'
+ 'D8 FF C5 C5 C5 FF C3 C3 C3 FF BF BF BF FF BA BA'
+ 'BA FF B8 B8 B8 FF B5 B5 B5 FF B3 B3 B3 FF B1 B1'
+ 'B1 FF AE AE AE FF AC AC AC FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A4 A4 A4 FF A4 A4 A4 FF A3 A3 A3 FF A3 A3'
+ 'A3 FF A1 A1 A1 FF A1 A1 A1 FF 9E 9E 9E FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9B 9B 9B FF 9A 9A 9A FF 98 98'
+ '98 FF 97 97 97 FF 96 96 96 FF 95 95 95 FF 92 92'
+ '92 FF 92 92 92 FF 91 91 91 FF 90 90 90 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8D 8D 8D FF 8A 8A 8A FF 89 89'
+ '89 FF 86 86 86 FF 85 85 85 FF 86 86 86 FF 8A 8A'
+ '8A FC 09 09 09 86 00 00 00 1C 00 00 00 00 00 00'
+ '00 00 92 92 92 4B 8E 8E 8E FB 75 75 75 FF DD DD'
+ 'DD FF C7 C7 C7 FF C6 C6 C6 FF C1 C1 C1 FF BE BE'
+ 'BE FF BB BB BB FF B8 B8 B8 FF B6 B6 B6 FF B3 B3'
+ 'B3 FF AF AF AF FF AD AD AD FF AA AA AA FF A8 A8'
+ 'A8 FF A5 A5 A5 FF A4 A4 A4 FF A4 A4 A4 FF A2 A2'
+ 'A2 FF 9F 9F 9F FF A0 A0 A0 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9C 9C 9C FF 9C 9C 9C FF 9C 9C 9C FF 99 99'
+ '99 FF 98 98 98 FF 98 98 98 FF 96 96 96 FF 96 96'
+ '96 FF 93 93 93 FF 92 92 92 FF 91 91 91 FF 90 90'
+ '90 FF 90 90 90 FF 8F 8F 8F FF 8C 8C 8C FF 89 89'
+ '89 FF 88 88 88 FF 86 86 86 FF 85 85 85 FF 91 91'
+ '91 FF 21 21 21 A6 00 00 00 2C 00 00 00 00 00 00'
+ '00 00 94 94 94 4F 93 93 93 FD 71 71 71 FF DA DA'
+ 'DA FF CA CA CA FF C7 C7 C7 FF C4 C4 C4 FF C1 C1'
+ 'C1 FF BE BE BE FF BA BA BA FF B7 B7 B7 FF B4 B4'
+ 'B4 FF B2 B2 B2 FF AF AF AF FF AB AB AB FF A9 A9'
+ 'A9 FF A7 A7 A7 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A1 A1 A1 FF A1 A1 A1 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9D 9D 9D FF 9C 9C 9C FF 9C 9C 9C FF 9C 9C'
+ '9C FF 9B 9B 9B FF 98 98 98 FF 98 98 98 FF 97 97'
+ '97 FF 96 96 96 FF 95 95 95 FF 93 93 93 FF 91 91'
+ '91 FF 92 92 92 FF 90 90 90 FF 8E 8E 8E FF 8D 8D'
+ '8D FF 8C 8C 8C FF 88 88 88 FF 86 86 86 FF 8F 8F'
+ '8F FF 42 42 42 BF 00 00 00 3B 00 00 00 00 00 00'
+ '00 00 99 99 99 53 9A 9A 9A FD 71 71 71 FF D6 D6'
+ 'D6 FF CD CD CD FF C8 C8 C8 FF C6 C6 C6 FF C2 C2'
+ 'C2 FF C0 C0 C0 FF BC BC BC FF B9 B9 B9 FF B6 B6'
+ 'B6 FF B3 B3 B3 FF B0 B0 B0 FF AD AD AD FF AA AA'
+ 'AA FF A8 A8 A8 FF A7 A7 A7 FF A5 A5 A5 FF A4 A4'
+ 'A4 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1 A1 FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9A 9A 9A FF 9A 9A 9A FF 98 98'
+ '98 FF 97 97 97 FF 96 96 96 FF 95 95 95 FF 93 93'
+ '93 FF 93 93 93 FF 90 90 90 FF 90 90 90 FF 8E 8E'
+ '8E FF 8D 8D 8D FF 8A 8A 8A FF 86 86 86 FF 94 94'
+ '94 FF 67 67 67 D4 00 00 00 4C 00 00 00 00 00 00'
+ '00 00 9E 9E 9E 57 A1 A1 A1 FE 72 72 72 FF CF CF'
+ 'CF FF CF CF CF FF CB CB CB FF C8 C8 C8 FF C5 C5'
+ 'C5 FF C2 C2 C2 FF BF BF BF FF BC BC BC FF B8 B8'
+ 'B8 FF B5 B5 B5 FF B2 B2 B2 FF AF AF AF FF AB AB'
+ 'AB FF A9 A9 A9 FF A6 A6 A6 FF A4 A4 A4 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9F 9F 9F FF 9E 9E 9E FF 9E 9E 9E FF 9B 9B'
+ '9B FF 9B 9B 9B FF 9B 9B 9B FF 9B 9B 9B FF 9A 9A'
+ '9A FF 98 98 98 FF 97 97 97 FF 96 96 96 FF 95 95'
+ '95 FF 94 94 94 FF 92 92 92 FF 90 90 90 FF 8F 8F'
+ '8F FF 8E 8E 8E FF 89 89 89 FF 88 88 88 FF 8E 8E'
+ '8E FF 7A 7A 7A E3 02 02 02 65 00 00 00 00 00 00'
+ '00 00 9D 9D 9D 5C A6 A6 A6 FF 7A 7A 7A FF C6 C6'
+ 'C6 FF D3 D3 D3 FF CC CC CC FF C9 C9 C9 FF C7 C7'
+ 'C7 FF C4 C4 C4 FF C1 C1 C1 FF BE BE BE FF BB BB'
+ 'BB FF B7 B7 B7 FF B3 B3 B3 FF B0 B0 B0 FF AC AC'
+ 'AC FF AB AB AB FF A7 A7 A7 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1 A1 FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9D 9D 9D FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9B 9B 9B FF 9C 9C 9C FF 9D 9D 9D FF 9A 9A'
+ '9A FF 9A 9A 9A FF 98 98 98 FF 97 97 97 FF 96 96'
+ '96 FF 95 95 95 FF 93 93 93 FF 91 91 91 FF 8F 8F'
+ '8F FF 8E 8E 8E FF 8A 8A 8A FF 89 89 89 FF 88 88'
+ '88 FF 8B 8B 8B EC 0C 0C 0C 7C 00 00 00 15 00 00'
+ '00 00 9F 9F 9F 65 A6 A6 A6 FF 84 84 84 FF AE AE'
+ 'AE FF DB DB DB FF D0 D0 D0 FF CD CD CD FF CA CA'
+ 'CA FF C7 C7 C8 FF C3 C3 C3 FF C1 C1 C1 FF BE BE'
+ 'BE FF B9 B9 B9 FF B6 B6 B6 FF B2 B2 B2 FF B0 B0'
+ 'B0 FF AC AC AC FF AA AA AA FF A7 A7 A7 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A1 A1 A1 FF A0 A0 A0 FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9E 9E 9E FF 9D 9D 9D FF 9C 9C'
+ '9C FF 9C 9C 9C FF 9C 9C 9C FF 9C 9C 9C FF 9B 9B'
+ '9B FF 9A 9A 9A FF 99 99 99 FF 97 97 97 FF 97 97'
+ '97 FF 95 95 95 FF 93 93 93 FF 91 91 91 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8B 8B 8B FF 88 88 88 FF 84 84'
+ '84 FF 8F 8F 8F F2 1A 1A 1A 91 00 00 00 1C 00 00'
+ '00 00 A8 A8 A8 76 A7 A7 A7 FF 8F 8F 8F FF 88 88'
+ '88 FF AD AD AD FF C5 C5 C5 FF C1 C1 C1 FF C0 C0'
+ 'C0 FF BF BE BE FF BB BB BC FF B9 B9 B8 FF B5 B5'
+ 'B5 FF B1 B0 B1 FF AF AF AE FF AB AB AB FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A3 A3 A3 FF A0 A0 A0 FF 9D 9D'
+ '9D FF 9D 9D 9C FF 9B 9B 9B FF 9D 9C 9C FF 9E 9E'
+ '9D FF A0 A0 A0 FF 9D 9D 9D FF 9D 9D 9D FF 9D 9D'
+ '9D FF 9B 9B 9B FF 9B 9B 9B FF 9B 9B 9B FF 9A 9A'
+ '9A FF 99 99 99 FF 98 98 98 FF 97 97 97 FF 96 96'
+ '96 FF 93 93 93 FF 91 91 91 FF 8F 8F 8F FF 8E 8E'
+ '8E FF 8B 8B 8B FF 87 87 87 FF 84 84 84 FF 81 81'
+ '81 FF 99 99 99 F5 58 58 58 8D 00 00 00 16 00 00'
+ '00 00 AA AA AA 99 A9 A9 A9 FF 93 93 93 FF 92 92'
+ '92 FF 89 89 89 FF 87 87 87 FF 84 84 84 FF 83 83'
+ '83 FF 81 81 80 FF 7E 7E 7E FF 7C 7C 7C FF 7A 7A'
+ '7A FF 79 78 78 FF 77 77 76 FF 76 76 75 FF 74 74'
+ '74 FF 74 74 74 FF 74 74 74 FF 74 74 74 FF 73 73'
+ '73 FF 73 73 73 FF 72 72 72 FF 73 72 72 FF 75 75'
+ '75 FF 8E 8E 8E FF A2 A2 A2 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9E 9E 9E FF 9C 9C 9C FF 9B 9B 9B FF 99 99'
+ '99 FF 98 98 98 FF 94 94 94 FF 91 91 91 FF 90 90'
+ '90 FF 8D 8D 8D FF 8B 8B 8B FF 92 92 92 FF 9B 9B'
+ '9B FF 8E 8E 8E CE 62 62 62 46 00 00 00 00 00 00'
+ '00 00 B7 B7 B7 B6 AD AD AD FF 98 98 98 FF 98 98'
+ '98 FF 95 95 95 FF 93 93 93 FF 91 91 91 FF 8F 8F'
+ '8F FF 8C 8C 8C FF 88 88 88 FF 86 86 86 FF 84 84'
+ '84 FF 81 81 81 FF 80 80 80 FF 7E 7E 7E FF 7B 7B'
+ '7B FF 7B 7B 7B FF 79 79 79 FF 78 78 78 FF 78 78'
+ '78 FF 77 77 77 FF 76 76 76 FF 74 74 74 FF 73 73'
+ '73 FF 74 74 74 FF 7B 7B 7B FF 7D 7D 7D FF 7D 7D'
+ '7D FF 7D 7D 7D FF 7C 7C 7C FF 7B 7B 7B FF 7C 7C'
+ '7C FF 7A 7A 7A FF 79 79 79 FF 78 78 78 FF 78 78'
+ '78 FF 77 77 77 FF 75 75 75 FF 73 73 73 FF 71 71'
+ '71 FF 6E 6E 6E FF 73 73 73 FB 62 62 62 DF 7E 7E'
+ '7E B9 55 55 55 42 00 00 00 00 00 00 00 00 00 00'
+ '00 00 D5 D5 D5 AD B9 B9 BA FE 9F 9F A0 FF 9E 9F'
+ '9F FF 9C 9C 9C FF 9B 9B 9B FF 97 97 97 FF 95 95'
+ '95 FF 92 92 92 FF 91 91 91 FF 8D 8D 8E FF 8A 8A'
+ '8A FF 89 89 89 FF 86 86 86 FF 83 83 83 FF 81 81'
+ '81 FF 7F 7F 7F FF 7F 7F 7F FF 7E 7D 7D FF 7D 7D'
+ '7D FF 7A 7A 7A FF 7A 7A 7A FF 7B 7B 7B FF 7A 7A'
+ '7A FF 78 78 78 FF 79 79 79 FF 79 79 79 FF 78 78'
+ '78 FF 77 77 77 FF 76 76 76 FF 77 77 77 FF 75 75'
+ '75 FF 74 74 74 FF 73 73 73 FF 71 71 71 FF 70 70'
+ '70 FF 6E 6E 6E FF 6C 6C 6C FF 6B 6B 6B FF 68 68'
+ '68 FF 65 65 65 FF 6C 6C 6C F4 22 22 22 92 00 00'
+ '00 1B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 BB BB BB 44 C7 C5 C5 E4 A6 A7 A9 FF 9D 9E'
+ 'A1 FF 9B 9C 9F FF 99 9A 9D FF 97 98 9B FF 93 95'
+ '98 FF 91 92 95 FF 8D 8E 91 FF 89 8B 8E FF 87 89'
+ '8C FF 84 86 88 FF 82 83 86 FF 7F 81 84 FF 7C 7E'
+ '82 FF 7B 7D 80 FF 7A 7C 7F FF 7A 7C 7F FF 7B 7D'
+ '80 FF 7B 7C 7F FF 7E 7E 7E FF 7E 7E 7E FF 7E 7E'
+ '7E FF 7D 7D 7D FF 7D 7D 7D FF 7D 7D 7D FF 7C 7C'
+ '7C FF 7B 7B 7B FF 7A 7A 7A FF 7A 7A 7A FF 79 79'
+ '79 FF 78 78 78 FF 77 77 77 FF 75 75 75 FF 74 74'
+ '74 FF 72 72 72 FF 70 70 70 FF 6E 6E 6E FF 6B 6B'
+ '6B FF 68 68 68 FF 75 75 75 F4 2D 2D 2D 8B 00 00'
+ '00 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 AF AF 9F 10 E8 E7 DF A0 DE D5 C1 FF D2 C7'
+ 'B0 FF D2 C7 B0 FF D0 C4 AE FF CB C0 AA FF C4 BA'
+ 'A4 FF BF B4 A0 FF BB B1 9C FF BA B0 9C FF B6 AD'
+ '98 FF AE A5 93 FF AA A0 8F FF A8 9F 8E FF A4 9C'
+ '8B FF 9D 95 85 FF 9A 91 81 FF 95 8E 7F FF 96 8E'
+ '7E FF 89 85 7E FF 7B 7D 81 FF 80 80 80 FF 7E 7E'
+ '7E FF 7F 7F 7F FF 7F 7F 7F FF 7E 7E 7E FF 7E 7E'
+ '7E FF 7E 7E 7E FF 7D 7D 7D FF 7C 7C 7C FF 7A 7A'
+ '7A FF 7A 7A 7A FF 78 78 78 FF 76 76 76 FF 74 74'
+ '74 FF 72 72 72 FF 71 71 71 FF 6D 6D 6D FF 6B 6B'
+ '6B FF 6C 6C 6C FF 87 87 87 EA 3D 3D 3D 64 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F5 F4 EE 8C EE E5 CF FD DE D0'
+ 'B6 FF DB CE B4 FF DA CD B3 FF D8 CB B0 FF D7 C9'
+ 'AE FF D3 C6 AC FF D0 C3 A8 FF CD C0 A5 FF C9 BC'
+ 'A2 FF C6 B9 9E FF C3 B5 99 FF BE B1 94 FF BC AE'
+ '93 FF B7 AA 8F FF B2 A4 89 FF AE A0 84 FF AA 9C'
+ '81 FF B2 A2 82 FF 9A 95 8C FC 95 96 98 F7 9D 9D'
+ '9D F6 9A 9A 9A F6 9A 9A 9A F6 98 98 98 F7 98 98'
+ '98 F7 97 97 97 F7 96 96 96 F7 93 93 93 F7 91 91'
+ '91 F7 90 90 90 F7 8C 8C 8C F8 89 89 89 F9 87 87'
+ '87 F9 84 84 84 FA 81 81 81 FA 7B 7B 7B FB 7B 7B'
+ '7B FB 8F 8F 8F F3 26 26 26 69 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 00'
- '00 00 00 60 00 00 00 00 00 00 00 20 00 00 00 00'
+ '00 00 00 00 00 00 E1 DA CE 45 FB FA E9 DF EE E6'
+ 'CF FF EC E2 C5 FF EB DF C4 FF E9 DC BF FF E8 DA'
+ 'BE FF E4 D5 B9 FF E0 D2 B5 FF DD CF B3 FF D9 CB'
+ 'AF FF D5 C7 AB FF D2 C4 A8 FF CE C0 A3 FF CB BD'
+ 'A1 FF C8 B9 9D FF C3 B5 99 FF BF B1 95 FF BC AE'
+ '92 FF CE BE 9F FC AA 9D 84 C6 90 90 90 7A AB AB'
+ 'AB 6E AD AD AD 6E B0 B0 B0 6F B5 B5 B5 6F B5 B5'
+ 'B5 6F B5 B5 B5 6F B6 B6 B6 70 B8 B8 B8 70 B0 B0'
+ 'B0 71 AE AE AE 72 A4 A4 A4 76 9E 9E 9E 79 95 95'
+ '95 7B 8F 8F 8F 7C 8A 8A 8A 7F 81 81 81 82 82 82'
+ '82 83 85 85 85 6D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 D4 D0 CC 42 FC FA'
+ 'E3 CC FD FB E5 D3 FC FA E0 D4 FC F6 DD D4 FC F6'
+ 'D9 D4 FA F5 D7 D4 FA F2 D3 D4 F8 F0 D1 D4 F6 EB'
+ 'CD D4 F5 E8 CA D4 F2 E6 C2 D4 F1 E0 C1 D4 EE DD'
+ 'BB D4 E9 D9 B9 D4 E8 D8 B8 D4 E5 D3 B2 D4 E4 D4'
+ 'B0 D4 E0 CD AE BA 64 5B 48 38 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
- '00 00 00 07 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
- '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
- '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
- '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
- '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 18 18'
- '18 00 19 19 19 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
- '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
- '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2A 2A'
- '2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E 2E 00 2F 2F'
- '2F 00 34 34 34 00 35 35 35 00 39 39 39 00 3D 3D'
- '3D 00 40 40 40 00 41 41 41 00 48 48 48 00 49 49'
- '49 00 4A 4A 4A 00 4B 4B 4B 00 53 53 53 00 56 56'
- '56 00 59 59 59 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
- '61 00 62 62 62 00 64 64 64 00 6E 6E 6E 00 75 75'
- '75 00 77 77 77 00 7A 7A 7A 00 7E 7E 7E 00 7F 7F'
- '7F 00 00 C0 00 00 00 FF 00 00 80 80 80 00 83 83'
- '83 00 86 86 86 00 8A 8A 8A 00 8D 8D 8D 00 90 90'
- '90 00 92 92 92 00 93 93 93 00 97 97 97 00 99 99'
- '99 00 9A 9A 9A 00 9E 9E 9E 00 9F 9F 9F 00 A4 A0'
- 'A0 00 A4 A4 A4 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
- 'A9 00 AA AA AA 00 AB AB AB 00 AD A8 AB 00 AB AC'
- 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
- 'B0 00 B2 B2 B2 00 B3 B3 B3 00 B5 B5 B5 00 B6 B6'
- 'B6 00 B7 B7 B7 00 B8 B4 B6 00 B8 B8 B8 00 BA BA'
- 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
- 'BE 00 BF BF BF 00 FF B1 C7 00 C0 C0 C0 00 C1 C1'
- 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5'
- 'C5 00 C6 C6 C6 00 C8 C8 C8 00 C8 C9 C9 00 C9 C9'
- 'C9 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
- 'CD 00 CE CE CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
- 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
- 'D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9'
- 'D9 00 DA DA DA 00 DB DB DB 00 DC DC DC 00 DD DD'
- 'DD 00 DE DE DE 00 DF DF DF 00 FF D4 D4 00 FF D4'
- 'E3 00 FF D4 F0 00 FF D4 FF 00 E0 E0 E0 00 E1 E1'
- 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
- 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
- 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
- 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
- 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
- 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
- 'F9 00 FA FA FA 00 FF FF FF 00 00 00 00 00 78 EE'
- '0C 01 78 EE 0C 01 40 00 00 00 40 00 00 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 70 EE 0C 01 00 24 0D 01 01 01'
- 'F5 77 78 01 38 00 78 EE 0C 01 E0 19 0D 01 E8 19'
- '0D 01 78 01 38 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 BE B3 E7 77 70 EE 0C 01 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 08 04 00 00 E4 00 00 00 08 04 00 00 08 01'
- '00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00'
- '38 00 BC 18 95 00 C0 18 95 00 B0 19 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 81 E9'
- '49 00 00 00 38 00 00 00 00 00 78 EE 0C 01 78 EE'
- '0C 01 A4 1A 95 00 40 00 00 00 40 00 00 00 B8 10'
- 'E9 77 FF FF FF FF C9 F1 E7 77 16 EA 4B 00 F8 00'
- '00 00 B4 1A 95 00 DC E3 49 00 E0 A3 4E 00 FF FF'
- 'FF FF 10 00 00 00 10 DA 4B 00 78 EE 0C 01 71 CC'
- '43 00 78 EE 0C 01 50 7E 0D 01 A4 1A 95 00 F8 A2'
- 'AF 00 C4 F5 AF 00 04 00 00 00 50 7E 0D 01 0F 02'
- '00 00 B8 EE 0C 01 10 00 00 00 00 00 00 00 20 00'
- '00 00 78 EE 0C 01 40 00 00 00 10 00 00 00 00 01'
- '00 00 00 04 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 10 00 00 00 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 35 2D 2B'
- '2B 2B 35 9D 9D 9D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 9D 9D 37 2D 30 47 6B 77'
- '93 77 6B 47 35 2D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 9D 9D 30 35 6B 9C 7F 7F 7F'
- '7F 7D 7D 7D 7D 5D 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 9D 9D 9D 2B 5D 7F 7F 7F 7F 7F 7F'
- '7D 7D 7D 7D 7D 93 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 9D 9D 9D 2D 87 7F 7F 7F 7F 7F 7F 7D'
- '7D 7D 7D 7D 93 93 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 9D 26 2B 87 7F 7F 7F 7F 7F 7F 7D 7D'
- '7D 7D 7D 93 93 93 00 00 00 00 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 23 2B 5F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
- '7D 7D 93 93 93 93 00 00 9D 9D 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 2B 26 3B 7F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
- '7D 93 93 93 93 93 00 9D 9D 9D 9D 0F 18 17 18 17'
- '17 17 17 17 17 17 17 17 17 17 16 16 16 16 16 16'
- '16 16 16 23 2B 93 7F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
- '93 93 93 93 93 93 00 9D 9D 12 3A 54 4B 4A 49 6A'
- '69 68 66 61 60 5F 5F 60 5D 5E 5B 5B 58 59 56 59'
- '59 59 2D 26 40 7F 7F 7F 7F 7F 7F 7F 7F 7D 7D 7F'
- '7E 7E 93 93 93 93 9D 9D 01 38 49 8C 89 89 89 71'
- '33 33 88 89 89 84 7A 75 6F 6A 6A 6A 6A 6A 65 6A'
- '47 19 26 2B 77 7F 7F 7F 7F 7F 7F 7F 7F 80 80 80'
- '80 80 7F 93 93 93 9D 9D 0B 49 8C 8C 89 89 89 34'
- '34 34 33 82 7C 72 69 6F 68 6A 6A 6A 6A 6A 6A 6A'
- '1F 19 26 30 93 93 7E 93 7F 7F 7F 7F 7F 80 7F 7E'
- '7E 80 80 93 93 93 9D 9D 15 49 8B 8C 8C 89 89 34'
- '34 34 34 68 64 64 64 64 64 64 64 64 64 64 64 64'
- '3C 1F 26 3B 93 93 93 93 93 7E 7F 7F 7F 7F 52 35'
- '3B 5C 7F 7F 7E 93 9D 9D 14 6E 8D 8C 8C 89 89 89'
- '34 34 51 51 52 52 52 52 52 52 52 52 52 52 52 52'
- '52 52 26 42 93 93 93 93 93 93 93 7F 7F 52 2D 47'
- '2B 30 7E 7F 93 93 9D 9D 14 6E 8F 89 8C 89 35 35'
- '35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35'
- '35 35 2B 52 93 93 93 93 93 93 93 7F 7E 2D 00 00'
- '00 2B 52 7F 93 93 9D 9D 13 6E 90 8C 8C 8C 35 35'
- '35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35'
- '35 35 2B 52 93 93 93 93 93 93 93 7F 7D 2B 9D 00'
- '00 2B 52 7F 93 93 9D 9D 13 6F 93 8B 8C 8C 44 44'
- '44 48 4C 4E 4D 4D 4D 4D 4D 4D 48 48 48 48 48 48'
- '48 48 2B 6B 93 93 93 93 93 93 7E 7F 7E 35 9D 9D'
- '00 30 7F 7F 7E 93 9D 9D 12 70 8A 89 87 85 83 78'
- '79 75 76 6F 6F 6C 6D 6D 6D 6D 6D 6D 6D 6D 6D 6D'
- '6D 6D 2B 6B 93 93 93 93 93 93 93 7F 7F 5D 30 2B'
- '35 87 7F 7F 93 7E 9D 9D 12 70 98 99 97 97 97 96'
- '96 95 95 94 94 94 93 93 92 92 92 91 91 91 90 90'
- '8F 8F 2B 47 93 93 93 93 93 93 93 7E 7F 7F 7E 7D'
- '7E 80 80 7F 7F 7F 9D 9D 11 73 9C 8A 82 83 83 81'
- '7C 7C 7C 7C 7C 81 81 81 81 81 81 81 81 81 81 81'
- '81 81 2B 3B 93 93 93 93 93 93 93 93 93 80 80 80'
- '80 80 7F 7F 7F 7F 9D 9D 11 7B 99 76 61 57 5B 75'
- '77 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76'
- '76 76 2D 30 93 93 93 93 93 93 93 93 93 7E 7D 7D'
- '7D 7D 7F 7F 7F 7F 9D 9D 0D 77 94 63 46 53 4E 60'
- '77 75 75 75 75 75 74 74 74 74 74 74 74 74 75 75'
- '75 75 70 2B 5D 93 93 93 93 93 93 93 93 93 7D 7D'
- '7D 7D 7F 7F 7F 7F 9D 9D 03 5F 97 58 4F 60 48 57'
- '75 72 72 72 71 70 70 72 74 75 75 74 72 70 70 70'
- '71 72 70 2B 37 93 93 93 93 93 93 93 93 7D 7D 7D'
- '7D 7D 7F 7F 7F 7F 00 9D 9D 43 95 6C 62 6F 5B 66'
- '70 6F 6D 70 6D 6D 72 72 72 72 72 72 72 72 6D 6D'
- '71 6D 70 70 2B 52 93 93 93 93 93 93 7D 7D 7D 7D'
- '7D 7D 7F 7F 7F 7F 00 9D 9D 31 90 6E 6C 68 6C 6E'
- '6B 6C 72 72 72 72 72 72 72 72 72 72 72 72 72 72'
- '72 82 70 70 30 30 5C 93 93 93 93 7D 7D 7D 7D 7D'
- '7D 7F 7F 7F 7F 7F 00 9D 9D 27 8A 6D 6A 6A 6A 67'
- '70 70 70 70 71 72 73 73 73 73 73 73 73 73 72 72'
- '78 85 70 70 70 2D 3B 93 93 93 7D 7D 7D 7D 7D 7D'
- '7F 7F 7F 7F 7F 7F 00 9D 9D 1F 74 6F 67 68 67 71'
- '70 70 70 6E 6F 6F 6F 6F 6F 6F 70 6F 70 70 6F 6F'
- '6E 6D 70 70 70 61 2D 3B 93 7D 7D 7D 7D 7D 7D 7F'
- '7F 7F 7F 7F 7F 7F 00 9D 9D 10 53 78 67 68 6B 70'
- '70 6C 6E 6D 6D 6D 6D 6C 70 70 6B 70 70 70 70 70'
- '70 6B 70 70 70 61 61 2D 35 6B 7D 7D 7D 7D 7F 7F'
- '7F 7F 7F 7F 87 3B 00 9D 9D 05 41 7A 69 6A 70 70'
- '70 6D 6D 6D 6D 6D 6D 70 70 70 70 70 70 70 70 70'
- '70 70 70 70 70 61 61 50 3E 2B 40 5D 7D 7F 7F 7F'
- '7F 9C 6B 40 2B 3B 00 00 9D 9D 36 7A 6C 6E 70 70'
- '6D 6D 6D 6D 6D 6D 6D 6D 6C 70 70 70 70 70 70 70'
- '70 70 70 70 70 70 50 50 3E 9D 9D 30 2B 37 37 37'
- '37 2B 2D 00 00 00 00 00 9D 9D 29 79 6E 6F 70 70'
- '6E 6E 6E 6E 6E 6E 6E 6E 6E 70 70 70 70 70 70 70'
- '70 70 70 70 70 70 50 50 3E 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 9D 9D 20 75 71 6F 70 70'
- '70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70'
- '70 70 70 70 70 70 50 50 3E 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 9D 9D 18 69 73 72 70 70'
- '73 73 73 73 73 73 73 73 73 73 73 70 70 70 70 70'
- '70 70 70 70 61 70 59 6D 3E 07 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 9D 9D 0A 4E 78 78 7B 7B'
- '7B 76 77 77 77 77 77 77 77 77 77 77 7A 7A 7A 7A'
- '7A 77 7A 7A 88 76 69 67 30 02 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 9D 9D 06 3D 79 7C 79 7B'
- '7B 7B 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A'
- '7A 7A 88 88 88 7A 79 63 25 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 2F 70 83 82 7B'
- '7B 7B 7B 7B 81 81 81 81 81 81 81 81 81 81 81 81'
- '82 82 88 88 88 84 76 57 1D 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 24 66 86 84 85'
- '8C 8C 8C 8C 8C 8C 85 85 85 85 85 85 85 85 86 86'
- '88 88 88 88 85 87 73 45 0E 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 1C 59 87 87 87'
- '88 88 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 88'
- '88 88 88 88 87 89 71 3F 08 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 0C 48 85 8E 88'
- '87 8D 8C 8B 8E 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C'
- '8C 8D 8B 86 8C 8C 73 38 9D 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 9D 9D 06 3E 85 7C 59'
- '5E 73 8D 8E 8E 8F 8F 8E 8D 8C 8C 8D 8E 8F 8F 8E'
- '8F 85 5F 5A 6E 8D 71 2E 9D 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 9D 9D 39 81 61 4F'
- '55 4F 8C 92 91 91 91 91 91 91 91 91 91 91 91 91'
- '94 72 4E 52 53 8C 6A 2A 9D 9D 9D 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 9D 9D 2C 6B 7A 79'
- '72 85 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A'
- '9B 93 7C 75 79 74 4E 1B 9D 9D 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 9D 9D 0B 35 5A 70'
- '74 78 75 75 75 75 75 75 75 75 75 75 75 75 75 75'
- '75 76 76 74 6A 4E 28 04 9D 9D 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 9D 9D 9D 09 1E 22'
- '21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21'
- '21 21 21 22 22 1A 02 9D 9D 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
- '9D 9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF F0 00 00 00 FF FF'
- 'FF FF E0 00 00 00 FF FF FF FF C0 00 00 00 FF FF'
- 'FF FF 80 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
- 'FF FC 00 00 00 00 FF FF FF FC 00 00 00 00 F0 00'
- '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 E0 00 00 00 00 00 00 00 60 00 00 00 00'
- '00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 C0 00 00 00 00 07 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
- '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
- '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11465,9 +7836,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0C 00 00 00 24 00 00 00 30 00 00 00 48 00 00'
- '00 78 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
- '00 90 00 00 00 78 00 00 00 48 00 00 00 30 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11476,10 +7844,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 3C 00 00 00 78 00 00 00 90 80 80 80 FF 6E 6E'
- '6E FF 62 62 62 FF 62 62 62 FF 62 62 62 FF 80 80'
- '80 FF 00 00 00 B4 00 00 00 9C 00 00 00 90 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11488,10 +7852,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 86 86'
- '86 FF 6E 6E 6E FF 7A 7A 7A FF AA AA AA FF CE CE'
- 'CE FF DA DA DA FF F2 F2 F2 FF DA DA DA FF CE CE'
- 'CE FF AA AA AA FF 80 80 80 FF 6E 6E 6E FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11500,10 +7860,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 3C 7A 7A 7A FF 80 80'
- '80 FF CE CE CE FF FF FF FF FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11512,10 +7868,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 24 00 00 00 48 62 62 62 FF C0 C0 C0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -11523,11 +7875,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
- '00 78 6E 6E 6E FF E6 E6 E6 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 56 56 56 56 FF 62 62'
- '62 FF E6 E6 E6 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 42 00 00 00 42 4A 4A 4A FF 62 62 62 FF C2 C2'
- 'C2 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
- '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 FF 62 62 62 FF 56 56 56 FF 92 92 92 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
- '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
- '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
- '2A FF 4A 4A 4A FF 62 62 62 FF F2 F2 F2 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
- '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
- '90 FF B8 B4 B6 FF AD AD AD FF AB AC AC FF AD A8'
- 'AB FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
- 'C9 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2'
- 'C2 FF C3 C3 C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF'
- 'BF FF BF BF BF FF BC BC BC FF BD BD BD FF BA BA'
- 'BA FF BD BD BD FF BD BD BD FF BD BD BD FF 6E 6E'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 E0 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 0F 00 00 C0 00'
+ '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 E0 00'
+ '01 FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 04 00 00 00'
+ '00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 00 00 00 00 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 00 00 00 00 78 88 88 88 88 88 88 88 88'
+ '88 88 88 87 78 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 70 00 00 00 78 88 88 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF 88 88 88'
+ '88 88 88 70 00 00 00 78 88 8F 44 44 4F FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF F8 88 88'
+ '88 88 88 70 00 00 00 78 88 FF FF FF F4 44 44 44'
+ '44 44 44 44 FF FF FF F4 44 44 44 44 4F FF 88 88'
+ '88 88 88 70 00 00 00 87 88 FF F4 FF FF 4F 4F FF'
+ '4F F4 FF 4F 44 44 44 4F FF FF FF FF FF FF 88 88'
+ '88 88 88 70 00 00 00 87 88 FF FF 4F 44 FF 4F 44'
+ 'F4 4F 44 FF F4 F4 F4 F4 4F 44 FF FF FF FF F8 88'
+ '88 88 88 87 00 00 00 87 88 FF FF 44 FF 44 F4 F4'
+ '44 44 F4 FF F4 FF 44 44 F4 FF FF FF FF FF F8 88'
+ '88 88 88 87 00 00 00 87 88 8F FF 4F 44 FF FF FF'
+ 'F4 F4 F4 FF F4 44 F4 FF 4F FF FF FF FF FF F8 88'
+ '88 88 88 87 00 00 00 87 88 8F FF F4 F4 FF FF FF'
+ 'FF F4 44 4F FF 4F FF 4F FF FF FF FF FF FF F8 88'
+ '88 88 88 87 00 00 00 87 88 88 FF F4 44 FF FF FF'
+ 'FF FF FF FF FF F4 4F FF FF FF FF FF FF FF 88 88'
+ '88 88 88 87 00 00 00 87 88 88 8F FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF F8 88 88'
+ '88 88 88 87 00 00 00 87 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 77 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 77 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 77 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 00 87 77 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 00 87 77 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 00 87 77 78 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 70 00 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 00 00 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 70 00 00 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 00 00 00 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 80 00 00 00 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 80 00 00 00 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 80 00 00 00 08 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 67 77 77 77 77 77 77 77 77 77 77'
+ '77 77 88 00 00 00 00 08 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 68 88 88 88 88 88 88 88 88 88 88'
+ '88 88 00 00 00 00 00 08 FE 6E 6E 6E 6E 6E 6E 6E'
+ '6E 6E 6E 6E 6E 80 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 8F EF EF EF EF EF EF EF'
+ 'EF EF EF EF EF 80 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 08 88 88 88 88 88 88 88'
+ '88 88 88 88 88 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 01 C0 00 00 00 00 00 00 01 C0 00'
+ '00 00 00 00 00 01 C0 00 00 00 00 00 00 01 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F E0 00'
+ '00 00 00 00 00 3F E0 00 00 00 00 00 00 FF E0 00'
+ '00 01 FF FF FF FF F0 00 00 01 FF FF FF FF F8 00'
+ '00 03 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 40 00 00 00 80 00'
+ '00 00 01 00 08 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 67 67 67 00 69 69 69 00 6D 6D'
+ '6D 00 71 71 71 00 74 74 73 00 75 75 75 00 79 79'
+ '79 00 7C 7B 7B 00 7C 7C 7B 00 7D 7D 7D 00 95 66'
+ '4D 00 97 69 4B 00 9F 73 4B 00 9E 70 51 00 A1 75'
+ '59 00 A6 7D 59 00 AB 83 5E 00 90 8A 7F 00 9D 93'
+ '7F 00 B1 8B 6A 00 B1 8D 72 00 B5 93 74 00 B7 95'
+ '77 00 B8 98 7B 00 BA 9A 7E 00 BB 9C 7F 00 7C 7E'
+ '80 00 FF 00 FF 00 7F 80 82 00 81 81 81 00 80 81'
+ '84 00 83 84 86 00 85 85 85 00 85 86 88 00 87 88'
+ '8A 00 89 89 89 00 89 8A 8D 00 8D 8D 8D 00 95 8F'
+ '84 00 90 8F 8E 00 9F 95 82 00 8F 90 92 00 91 91'
+ '91 00 95 94 93 00 95 95 95 00 98 97 96 00 98 97'
+ '98 00 97 98 99 00 99 99 99 00 9C 9B 9A 00 9A 9B'
+ '9C 00 9D 9D 9D 00 A3 98 84 00 A6 9C 87 00 AA 9C'
+ '81 00 AC 9E 83 00 AB 9E 84 00 AA 9F 8A 00 BE 9F'
+ '84 00 A0 9F 9E 00 AF A0 82 00 AE A0 86 00 BE A1'
+ '87 00 B0 A3 89 00 B2 A4 89 00 B3 A6 8C 00 B5 A8'
+ '8D 00 AB A4 95 00 A2 A0 9F 00 B1 A7 91 00 B3 A8'
+ '92 00 B7 AA 90 00 B7 AB 95 00 BA AD 92 00 BC AF'
+ '94 00 BF A5 99 00 BB AF 98 00 BE B1 96 00 9F 9F'
+ 'A1 00 A1 A1 A1 00 A4 A3 A1 00 A6 A5 A3 00 A3 A3'
+ 'A4 00 A5 A5 A5 00 A8 A7 A6 00 AA A8 A7 00 A9 A9'
+ 'A9 00 AC AB AA 00 AD AC AB 00 AB AB AC 00 AD AD'
+ 'AD 00 B0 AE AE 00 B1 B0 AF 00 B0 AF B0 00 B1 B1'
+ 'B1 00 B5 B4 B3 00 B3 B4 B4 00 B5 B5 B5 00 B8 B7'
+ 'B6 00 BA B8 B7 00 B7 B7 B8 00 B9 B9 B9 00 BC BA'
+ 'B9 00 BD BC BB 00 BD BD BD 00 C1 A4 89 00 C2 A5'
+ '8D 00 C4 AA 91 00 C2 B4 99 00 C5 B7 9A 00 C1 B5'
+ '9C 00 C4 B7 9C 00 C9 B1 9B 00 C6 B9 9E 00 CA BB'
+ '9F 00 CD B6 A2 00 C6 BA A0 00 C9 BC A2 00 CC BE'
+ 'A1 00 CC BF A4 00 D0 B7 A2 00 D2 BC AA 00 CE C1'
+ 'A7 00 CF C2 A8 00 D0 C0 A1 00 D0 C2 A5 00 D0 C3'
+ 'A9 00 D1 C4 AA 00 D4 C6 AA 00 D4 C0 AD 00 D3 C6'
+ 'AC 00 D6 C9 AE 00 D9 CB AF 00 C8 C0 B3 00 D4 C1'
+ 'B1 00 D6 C4 B3 00 D5 C2 B5 00 D6 C4 B4 00 D8 C6'
+ 'B5 00 D8 CB B1 00 DA CC B2 00 DC CE B1 00 DB CE'
+ 'B4 00 DC CF B4 00 D8 C7 B8 00 D2 CA B8 00 D4 CB'
+ 'B9 00 D5 CD BC 00 DA C9 B9 00 DD CC BB 00 DA CB'
+ 'BC 00 DC CD BE 00 DD D0 B5 00 DF D2 B8 00 D8 D0'
+ 'BE 00 E1 D3 B7 00 E0 D3 B8 00 E3 D5 B9 00 E4 D6'
+ 'BA 00 E6 D8 BD 00 E9 DB BF 00 C1 C1 C1 00 C5 C4'
+ 'C1 00 C5 C5 C5 00 C9 C9 C9 00 CD CD CD 00 DC CD'
+ 'C0 00 DA D2 C1 00 DF D0 C3 00 DB D4 C2 00 DF D1'
+ 'C6 00 DB D5 C6 00 DC D8 C7 00 D7 D5 C9 00 D2 D1'
+ 'CF 00 DA D6 CB 00 DC DA CA 00 DD DB CD 00 D1 D1'
+ 'D1 00 D5 D4 D2 00 D4 D4 D4 00 DD DC D1 00 D9 D9'
+ 'D9 00 DD DB DA 00 DF DC DA 00 DE DE DC 00 E0 D1'
+ 'C4 00 EA DE C1 00 E2 D4 C9 00 E4 D7 CB 00 E5 D8'
+ 'CD 00 E5 DA D0 00 E6 DC D2 00 E7 DD D5 00 E8 DE'
+ 'D4 00 ED E2 C6 00 EE E4 C7 00 F0 E7 CA 00 F4 E9'
+ 'CD 00 E9 E0 D6 00 EC E7 D7 00 EA E1 D9 00 EC E2'
+ 'DA 00 EC E3 DC 00 ED E5 DE 00 F5 EE D2 00 F6 EE'
+ 'D4 00 F6 F3 D6 00 E3 E2 E1 00 E7 E6 E5 00 EA E6'
+ 'E3 00 ED E8 E4 00 EE EC EA 00 F0 E8 E1 00 F1 EA'
+ 'E4 00 F2 EC E7 00 F2 ED E9 00 F4 EE E9 00 F0 EE'
+ 'EC 00 F6 F0 E9 00 F2 F0 EE 00 F6 F2 EE 00 F8 F2'
+ 'EE 00 F8 F4 EE 00 F6 F3 F0 00 F6 F5 F4 00 F9 F5'
+ 'F1 00 FA F6 F4 00 FA F8 F5 00 FC F9 F6 00 FE FC'
+ 'F7 00 FB F9 F8 00 FC FA F9 00 FD FC FA 00 FE FD'
+ 'FC 00 00 00 00 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '07 68 3A 31 2F 31 2F 2F 31 2F 2F 31 2F 2F 31 2F'
+ '2F 31 2F 2F 31 2F 2F 31 2F 2F 31 2F 2F 31 2F 2F'
+ '31 2F 2F 31 2F 2F 31 2F 2F 31 2F 2F 31 2F 2F 31'
+ '2F 2F 31 2F 2F 31 33 3A 00 00 00 00 00 00 00 00'
+ '07 BE AB 71 6F 6B 6E 6A 6A 6A 6A 67 67 64 64 67'
+ '63 63 63 63 63 5E 60 5D 5D 5E 5C 5C 5C 58 58 59'
+ '58 58 3D 3D 3C 3C 3C 38 36 36 36 36 33 34 33 34'
+ '34 34 34 33 31 33 36 13 00 00 00 00 00 00 00 00'
+ '6B BE AD 07 72 6F 72 72 71 70 70 6D 6C 6C 6C 6B'
+ '69 68 66 66 65 65 61 64 60 5F 5F 5D 5B 5B 5A 5A'
+ '45 4E 45 45 3B 3A 3A 37 35 35 31 2D 2D 2A 2B 2A'
+ '2A 2A 2A 2A 27 2A 34 10 3B 00 00 00 00 00 00 00'
+ '60 72 6E 6A 6F C1 E4 EA E6 E6 E6 E6 E6 E6 E6 E6'
+ 'E6 E6 E6 E6 E6 E4 E6 E4 E6 E6 E4 E4 E4 E4 E4 E4'
+ 'E4 E4 E4 DE E4 DE E4 E4 E2 DE DB AF 37 F8 F8 13'
+ '13 13 11 11 10 11 2C 10 36 00 00 00 00 00 00 00'
+ '3D 68 6F 6A C2 E8 8B 94 94 9F C4 D1 E5 EF EF F0'
+ 'EE ED EC EC EC EC EC EC E9 EC E9 E9 EC E9 E9 E9'
+ 'EC E8 EC EC EC EC EC EC EE EF F0 F0 DC 3A 27 13'
+ '13 13 11 11 10 10 2A 13 2F 00 00 00 00 00 00 00'
+ '37 59 6F AC EB F2 EC E7 E3 E3 E2 D1 B0 92 8B 90'
+ '91 9A 9E 9F B0 C4 C6 C7 CA CC D1 D4 D5 D5 D4 D5'
+ 'D3 CC C9 C7 C4 9E 9E 9E 91 91 9A D6 F0 DA 2F 13'
+ '13 F8 12 12 11 10 F8 2B 27 00 00 00 00 00 00 00'
+ '37 36 6F AF F1 EE F4 21 EB F4 E1 E0 D6 CB D1 F3'
+ 'F4 EA D3 EE D4 83 DD E3 D6 D1 CA CC D3 D3 D1 D3'
+ 'D3 D4 D6 E1 EC EE EE EF F4 F4 F4 F3 F2 F2 67 13'
+ '13 13 24 13 12 10 12 2F 12 00 00 00 00 00 00 00'
+ '38 2A 72 AD E9 E8 EC DF 19 82 7A 14 1D 18 15 17'
+ '22 16 73 7A D3 F3 A1 75 E8 EC E0 1F 7A 83 8B 82'
+ '75 1F 1A 75 74 8B C4 E1 E8 E8 E7 E8 E5 ED B8 27'
+ '27 13 F8 11 12 10 11 2D 10 59 00 00 00 00 00 00'
+ '34 0F AB AB EB F4 F3 F4 55 7D EC F2 92 93 EA C7'
+ 'B0 A0 48 E3 A0 83 90 B0 EF F3 ED 83 C7 90 C6 C9'
+ 'B4 75 A1 75 F2 ED E0 EC F3 F2 F3 F2 F3 F4 DA 2A'
+ '27 F8 12 13 12 11 10 2E 12 3B 00 00 00 00 00 00'
+ '2F 0D AB 70 DE EC EC ED E3 7A 7A E1 F3 F0 EF EF'
+ 'F2 F2 CA 90 E1 83 74 EC ED ED D6 94 23 B2 CA 75'
+ 'E3 A0 7A F0 ED ED EC ED E8 ED E8 ED E8 ED DC 2F'
+ '27 27 F8 13 13 12 13 2B 0F 35 00 00 00 00 00 00'
+ '2F 0C 72 6E BD EC EC E9 74 9E 1E 9E C7 EC E9 EA'
+ 'E8 EC EF E0 22 8B 20 75 8B EC ED E5 44 83 DF D3'
+ '83 E7 19 ED EC E9 E8 E9 EA EA EA E8 EA EE C1 2D'
+ '2A 2A 27 F8 F8 12 10 2A 27 2D 00 00 00 00 00 00'
+ '2D 0B 71 6B 6F DB F3 EF F0 D6 92 B2 C7 EF EC ED'
+ 'EC ED EC EF EF E3 DF EF D3 ED ED EF E1 C9 C6 C7'
+ 'E3 E5 E0 EF EC ED EC EC ED EC EC ED EF EE 6B 2D'
+ '2A 2A 27 27 F8 13 12 27 2A 27 00 00 00 00 00 00'
+ '2D 0A 6B 72 6F 72 C3 EB F2 F3 F4 F2 F2 F3 F3 F2'
+ 'F3 F3 F3 F4 F2 F4 F4 F4 F4 F4 F3 F3 F4 FF F4 F4'
+ 'F4 F4 F4 F3 F4 F3 F3 F3 F3 F4 F0 F2 E6 AB 31 2C'
+ '2D 2A 2A 2A 2A 13 F8 F8 2D 10 00 00 00 00 00 00'
+ '2D 0A 64 AB 71 6F 6F AB AD AD AD AD AD AB AC AB'
+ '07 07 72 07 72 72 71 71 6F 6F 6F 6E 6E 6D 6E 6A'
+ '6B 6B 69 68 68 67 67 65 65 64 67 64 3D 2F 2D 2E'
+ '2D 2D 2A 2A 27 27 F8 F8 31 10 5A 00 00 00 00 00'
+ '2D 0B 5E AB 72 71 6F 6F 6E 6A 6A 67 67 67 63 63'
+ '63 60 60 5E 5D 5E 5D 5C 5C 5C 45 58 58 45 45 3D'
+ '3C 3C 3A 37 37 36 36 33 35 33 34 34 31 2F 2F 2F'
+ '2D 2B 2A 2A 2A 27 27 F8 31 0F 3B 00 00 00 00 00'
+ '2F 0B 59 AE AB 07 72 72 6F 6E 6B 6A 68 67 64 63'
+ '60 60 60 5D 5E 5D 5C 5C 5C 5A 59 58 59 3D 45 3D'
+ '3C 3A 3A 3A 39 36 36 36 35 35 33 34 34 34 2F 2F'
+ '2F 2D 2D 2D 27 27 29 F8 31 10 34 00 00 00 00 00'
+ '31 0C 39 AF AD AB 07 07 71 6F 6F 6B 6B 68 67 64'
+ '63 63 60 5E 60 5D 5C 5D 5C 5A 59 5C 45 58 3C 3D'
+ '3D 3B 3A 3A 39 37 36 35 36 33 35 33 34 31 31 33'
+ '2D 2F 2D 2D 2D 2D 2A 27 31 2B 2D 00 00 00 00 00'
+ '35 0D 2F BC AD AD 07 07 72 6F 6F 6B 6A 6A 67 67'
+ '64 64 61 60 5D 5D 5D 5D 5D 5C 5C 59 59 45 3D 3D'
+ '3D 3C 3B 3C 37 36 39 36 34 34 35 33 34 34 31 31'
+ '2F 2F 2E 2D 2D 2A 2A 2A 2D 35 F8 00 00 00 00 00'
+ '36 0F 2C BD AE AD AD 07 72 71 6E 6E 6B 6A 68 68'
+ '65 64 60 60 5E 5D 5D 5C 5D 5C 59 59 59 58 3D 3D'
+ '3D 3D 3A 3A 3A 37 39 37 36 36 34 35 33 34 33 2F'
+ '31 2F 2F 2D 2D 2B 2A 2A 2D 34 12 00 00 00 00 00'
+ '37 10 27 BE AE AE AD AB AB 72 72 6E 6E 6B 6A 67'
+ '67 62 60 60 5E 5D 5D 5D 5D 5C 45 59 59 58 45 3D'
+ '3D 3D 3D 3A 39 3A 3A 37 39 36 36 34 35 33 34 34'
+ '31 33 2F 2D 2D 2D 2D 2A 2A 37 13 59 00 00 00 00'
+ '3A 24 11 BE AF AE AE AD AC 07 72 71 6F 6B 6A 6A'
+ '67 65 63 60 60 60 5D 5D 5D 5C 59 5C 59 45 58 3D'
+ '3D 3D 45 3C 3C 3B 3A 3A 39 37 39 35 36 34 35 33'
+ '34 34 2F 2F 2F 2D 2D 2D 2D 3A 10 3B 00 00 00 00'
+ '3B 27 11 AF AF AE AE AD AD AB 07 6F 71 6E 6B 6A'
+ '68 68 62 63 60 60 5E 5E 5D 5D 59 5C 59 59 58 45'
+ '3D 3D 3D 3D 3D 3C 3A 3A 3A 3A 37 39 35 36 35 34'
+ '34 34 34 34 2F 2F 2E 2D 2A 37 27 34 00 00 00 00'
+ '58 2A 10 AF AF AF AE AE AD AD 07 72 72 6F 6E 6B'
+ '6A 67 65 63 60 60 5E 5D 5D 5D 5C 59 59 5C 59 3D'
+ '45 3D 58 3D 3D 3B 3D 3C 3B 39 3A 37 39 36 35 36'
+ '36 33 34 31 2F 2F 2E 2D 2D 34 2D 2D 00 00 00 00'
+ '5C 2D 10 AD BC AF AE AE AE AC AB 07 72 71 6E 6E'
+ '6A 68 66 64 60 60 60 5C 5D 5D 5C 59 59 59 59 59'
+ '3D 58 45 3D 3C 3D 3D 3B 3C 3B 39 3A 37 39 36 36'
+ '35 33 34 34 33 31 2D 2D 2D 2F 2D F8 00 00 00 00'
+ '5E 2E 12 72 BE AF AF AF AE AD AD AB 07 72 6F 6F'
+ '6A 69 67 67 63 61 5E 5D 5D 5C 5C 59 59 59 59 58'
+ '3D 45 3D 3D 3C 3D 3D 3D 3D 3B 3A 39 37 39 39 37'
+ '35 34 35 33 31 2F 2F 2D 2D 2E 35 12 60 00 00 00'
+ '60 2E 27 6B C0 B8 AF AF AE AD AD AD 07 07 72 6E'
+ '6E 6A 66 67 64 63 60 5E 5D 5C 5C 59 59 59 59 58'
+ '45 3D 3D 3D 3D 3C 3D 3D 3B 3C 3B 3C 3A 37 39 36'
+ '36 36 34 34 31 2F 2F 2D 2C 2D 36 0F 59 00 00 00'
+ '60 31 2D 3A BE BE BC B8 AE AF AE AD AB AB 07 6F'
+ '6F 6E 68 6A 65 63 62 60 5D 5D 5D 5C 59 59 59 3D'
+ '59 3D 45 3D 3D 3D 3C 3D 3D 3C 3B 3C 3A 37 3A 36'
+ '36 36 34 34 31 2F 2F 2C 2D 2A 37 0F 3C 00 00 00'
+ '60 34 31 2C 5A AE BE AF AF AF AE AE AD AC 07 72'
+ '71 6E 6B 68 67 64 63 60 5D 5D 5C 5C 5A 5D 5C 59'
+ '3D 45 3D 58 3C 3D 3B 3C 3D 3A 3B 3A 3A 39 37 36'
+ '36 34 34 34 2F 2F 2D 2B 2A 2A 34 2D 59 00 00 00'
+ '63 35 34 34 2F 2C 2F 2D 2D 2A 2A 2A 2A 27 27 26'
+ '13 12 12 13 12 12 10 12 12 12 12 10 12 12 27 39'
+ '59 58 3D 3D 45 3C 3D 3B 3C 3B 3A 3A 39 39 37 36'
+ '34 34 31 2F 2F 2D 2D 2B 27 2B 36 3D 00 00 00 00'
+ '62 39 37 39 35 33 34 2F 2F 2F 2D 2D 2A 27 27 F8'
+ '13 13 11 10 10 0F 10 0F 10 0E 0E 0E 0E 0E 0D 0E'
+ '36 59 58 59 3D 45 58 3D 45 3D 3D 3C 3C 3A 37 39'
+ '36 35 34 31 2F 2E 2D 34 36 3B 36 00 00 00 00 00'
+ '67 3D 3B 3A 39 37 36 36 33 31 2F 2F 2C 2D 2A 2A'
+ 'F8 27 27 13 13 13 12 12 10 10 10 10 10 0E 0F 0F'
+ '0F 10 0F 10 0F 10 0F 0F 0F 0F 0E 0F 0E 0D 0D 0D'
+ '0D 0C 0D 0B 0C 0B 0D 0D 31 5D 00 00 00 00 00 00'
+ '6F 59 59 45 3D 3C 3B 39 36 36 34 34 31 2F 2D 2D'
+ '2B 2A 27 27 27 F8 F8 13 13 13 12 10 12 12 12 10'
+ '10 10 10 10 10 0F 10 0F 0F 0F 0F 0E 0E 0D 0D 0C'
+ '0C 0C 0C 0B 0B 0A 0D 0E 58 00 00 00 00 00 00 00'
+ '07 63 5C 59 59 45 3D 3C 3A 3A 36 36 33 31 31 2E'
+ '2D 2D 2D 2A 27 27 27 27 F8 27 13 13 13 13 13 13'
+ '12 13 12 12 10 12 10 12 10 10 10 0F 0F 0F 0E 0E'
+ '0D 0D 0C 0C 0B 0B 0F 0F 59 00 00 00 00 00 00 00'
+ '72 AC 5F 5D 5C 59 58 3D 3C 39 39 33 33 2F 2E 2C'
+ '2B 29 28 28 26 24 13 24 24 24 26 F8 F8 F8 F8 F8'
+ 'F8 F8 24 F8 13 13 13 12 12 12 10 10 10 0F 0F 0F'
+ '0E 0D 0D 0C 0B 0C 0F 24 60 00 00 00 00 00 00 00'
+ 'AB D7 A8 99 A2 97 96 95 89 84 7F 7E 7E 7E 78 56'
+ '52 50 50 4F 43 3F 3E 32 1C 1C 1B 26 2B 2C 2D 2A'
+ '2A 2D 2A 2A 2A 27 2A 27 F8 24 F8 12 12 10 10 0F'
+ '0F 0E 0D 0D 0D 0D 27 39 00 00 00 00 00 00 00 00'
+ 'AC D9 A9 A6 A3 98 98 96 8E 8D 8C 89 85 81 80 7E'
+ '79 76 54 54 53 4C 4A 47 41 40 46 30 2E 3D 3D 3D'
+ '3D 3D 3D 3D 3D 3D 3B 3C 37 39 36 35 33 2F 2F 2D'
+ '2D 2A 26 F8 F8 27 34 00 00 00 00 00 00 00 00 00'
+ '00 B9 D0 A8 A3 A2 98 96 95 8D 89 88 85 81 7F 7E'
+ '7B 78 57 54 53 51 4B 49 47 42 4A 53 3B 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 D2 D8 CF CE CD C5 C5 AA A9 A8 A5 A2 97 8E'
+ '8D 8A 87 87 80 7C 7B 77 77 76 86 4D 66 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 B7 BF BF BF BF BB BB BA BA BA B6 B6 B5'
+ 'B1 B3 B1 A4 9D 9D 9D 9C 9B 9B 8F 6C 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 3F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 0F C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 01 C0 00'
+ '00 00 00 00 00 01 C0 00 00 00 00 00 00 01 C0 00'
+ '00 00 00 00 00 01 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 0F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 1F C0 00'
+ '00 00 00 00 00 1F C0 00 00 00 00 00 00 3F C0 00'
+ '00 00 00 00 00 7F E0 00 00 01 FF FF FF FF F0 00'
+ '00 01 FF FF FF FF F8 00 00 03 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+}*/ 
+
+
+
+/* BINRES floppy.ico */
+5 ICON floppy.ico
+/* {
+ '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 3E 09 00 00 10 10 00 00 01 00 04 00 28 01'
+ '00 00 A6 0E 00 00 20 20 00 00 01 00 04 00 E8 02'
+ '00 00 CE 0F 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
+ '00 00 5E 21 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 C6 27 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 6E 4D 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 01 01 01 00 02 02 02 00 04 04 04 00 05 05'
+ '05 00 07 07 07 00 09 09 09 00 0A 0A 0A 00 0C 0C'
+ '0C 00 0D 0D 0D 00 10 10 10 00 12 12 12 00 13 13'
+ '13 00 15 15 15 00 16 16 16 00 17 17 17 00 18 18'
+ '18 00 19 19 19 00 1B 1B 1B 00 1C 1C 1C 00 1E 1E'
+ '1E 00 1F 1F 1F 00 20 20 20 00 21 21 21 00 23 23'
+ '23 00 24 24 24 00 25 25 25 00 26 26 26 00 27 27'
+ '27 00 28 28 24 00 2A 2A 25 00 28 28 28 00 2A 2A'
+ '2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E 2E 00 32 32'
+ '32 00 33 33 33 00 34 34 34 00 35 35 35 00 37 37'
+ '37 00 3B 3B 3B 00 3C 3C 3C 00 3D 3D 3D 00 3F 3F'
+ '3F 00 40 40 40 00 44 44 44 00 45 45 45 00 46 46'
+ '46 00 47 47 47 00 48 48 48 00 49 49 49 00 4B 4B'
+ '4B 00 4C 4C 4C 00 4E 4E 4E 00 50 50 50 00 52 52'
+ '52 00 57 57 57 00 59 59 59 00 5E 5E 5E 00 61 61'
+ '61 00 64 64 64 00 65 65 65 00 6A 6A 6A 00 7F 60'
+ '60 00 71 71 71 00 77 77 77 00 79 79 79 00 7F 7F'
+ '7F 00 D5 40 40 00 00 C0 00 00 00 FF 00 00 87 80'
+ '7D 00 8B 86 84 00 8A 8A 8A 00 8C 8C 8C 00 8D 8D'
+ '8D 00 8E 8E 8E 00 97 97 97 00 99 99 99 00 9A 9A'
+ '9A 00 9E 9E 9E 00 A3 A3 9E 00 A4 A4 A4 00 A7 A7'
+ 'A7 00 AA AA AA 00 AB AB AB 00 AD A8 AB 00 AE AE'
+ 'AE 00 AF AF AF 00 B0 B0 B0 00 B2 B2 B2 00 B5 B5'
+ 'B5 00 B6 B6 B6 00 B7 B7 B7 00 BB BB BB 00 BC BC'
+ 'BC 00 BD BD BD 00 BF BF BF 00 EA 80 80 00 CA A8'
+ '94 00 CC AF 9D 00 E9 B6 99 00 E9 B8 9C 00 CE B6'
+ 'A6 00 D0 B3 A3 00 EB BE A5 00 D2 C3 B9 00 EC C0'
+ 'A7 00 EF CC B8 00 C2 C2 C2 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C6 C6 C6 00 C8 C9 C9 00 C9 C9 C9 00 CA CA'
+ 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CF CF'
+ 'CF 00 D5 CB C4 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
+ 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
+ 'D8 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
+ 'DE 00 DF DF DF 00 F1 D2 C2 00 F2 D6 C7 00 F4 DD'
+ 'D0 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3'
+ 'E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7'
+ 'E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
+ 'EB 00 EC EC EC 00 ED ED ED 00 F0 F0 F0 00 F2 F2'
+ 'F2 00 F3 F3 F3 00 F9 F9 F9 00 FA FA FA 00 FF FF'
+ 'FF 00 00 00 00 00 01 00 00 00 18 00 00 00 00 00'
+ '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
+ '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 56 00'
+ '00 00 00 00 00 00 03 00 00 00 5E 00 1A 02 40 9F'
+ '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
+ 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
+ '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
+ '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
+ '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
+ '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
+ 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
+ '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
+ '68 65 6C 6C 33 32 5C 66 6C 6F 70 70 79 2E 69 63'
+ '6F 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
+ '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
+ 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
+ '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
+ '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
+ '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
+ 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
+ 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 2A 2A 2A 2A 40 40 40 40 40 40 40 40 40 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 4B 4B 4B 4B A1 A1 A1 A1 A1 A1 A1 A1 A1 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 1D 00 4B 08 45 45 45 45 45 45 45 45 45 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 1E A1 A1 08 63 63 63 63 63 63 63 63 63 00 A1'
+ 'A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
+ 'A1 03 08 0A 10 9A 94 94 94 94 94 94 94 94 00 A1'
+ 'A1 17 22 22 21 21 21 21 21 21 21 20 20 20 20 20'
+ '20 08 08 10 0F 99 94 4F 4F 4F 4F 4F 4F 4F A1 01'
+ '4A 98 95 95 7E 46 94 95 90 82 7C 77 77 77 72 55'
+ '23 A1 A1 15 10 97 93 95 95 97 97 98 98 99 A1 11'
+ '57 98 95 95 47 47 46 89 7F 7C 75 77 77 77 77 2D'
+ '23 A1 A1 0D 0C 96 94 4F 4F 4F 4F 4F 4F 4F A1 1F'
+ '7B 98 98 95 95 47 5C 5D 29 29 29 29 29 29 29 5D'
+ '5D A1 A1 07 09 95 94 90 90 91 91 93 93 94 A1 1F'
+ '7B 95 98 95 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
+ 'A1 19 15 05 07 92 94 4F 4F 4F 4F 4F 4F 4F A1 1C'
+ '7C 97 98 98 54 56 58 59 59 59 59 56 56 56 56 56'
+ '56 24 08 A1 A1 92 92 94 94 96 96 97 97 98 A1 1B'
+ '7D 98 9A 96 95 91 8F 86 82 7C 7C 7A 7A 7A 7A 7A'
+ '7A 28 02 03 03 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 19'
+ '80 96 8E 8F 8D 89 89 89 8D 8D 8D 8D 8D 8D 8D 8D'
+ '8D 2C 09 0B 0E 17 1B 2A 2E 30 30 22 22 22 A1 19'
+ '88 83 6F 62 82 83 83 83 83 83 83 83 83 83 83 83'
+ '83 2E 18 12 16 21 27 2E 31 30 30 22 22 22 A1 04'
+ '6E 60 5B 56 5F 7F 7F 7E 7D 7F 81 82 81 7D 7D 7E'
+ '7F 34 35 23 25 2F 2E 34 34 2A 24 1A 13 0E 00 A1'
+ '53 78 70 62 73 7C 7A 7A 7A 7F 7F 7F 7F 7F 7A 7E'
+ '7A 38 39 27 2C 4B 4B 4B 4B 4B 4B 4B 4B 4B 00 A1'
+ '3A 7A 77 77 74 7D 7D 7E 7F 80 80 80 80 80 7F 85'
+ '91 3B 3B 3F 2E 4D A0 49 48 69 6C 66 66 66 00 A1'
+ '2D 7C 74 74 7E 7D 7D 7C 7C 7C 7C 7D 7C 7D 7C 7B'
+ '7A 3B 3B 3F 2E 4D A0 49 48 69 6C 66 66 66 00 A1'
+ '05 87 76 7D 7D 7A 7A 7A 7A 7D 7D 7D 7D 7D 7D 7D'
+ '7D 3E 3F 41 43 51 A0 38 36 8B 6D 67 66 66 00 A1'
+ 'A1 87 78 7D 7D 7A 7A 7A 7A 7A 78 7D 7D 7D 7D 7D'
+ '7D 2A 3F 41 43 55 A0 37 35 8C 8A 6A 66 66 00 A1'
+ 'A1 82 7E 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D 7D'
+ '7D A1 A1 A1 A1 52 84 84 84 79 6B 68 65 64 00 A1'
+ 'A1 76 80 7D 7D 80 80 80 80 80 80 80 7D 7D 7D 76'
+ '73 6F 6E 61 7A 06 A1 00 00 00 00 00 00 00 00 A1'
+ 'A1 4E 86 86 88 88 87 87 87 87 87 87 87 87 87 87'
+ '87 94 94 86 71 A1 A1 00 00 00 00 00 00 00 00 00'
+ 'A1 42 7D 8E 88 88 88 8D 8D 8D 8D 8D 8D 8D 8D 8E'
+ '8E 94 94 83 5F A1 A1 00 00 00 00 00 00 00 00 00'
+ 'A1 27 61 93 93 94 98 98 98 98 98 98 98 98 98 94'
+ '94 94 93 7E 50 A1 A1 00 00 00 00 00 00 00 00 00'
+ 'A1 14 56 9A 94 99 98 9A 98 98 98 98 98 98 98 98'
+ '99 92 98 80 4A A1 A1 00 00 00 00 00 00 00 00 00'
+ '00 A1 4C 6F 5B 5B 98 9B 9B 9B 9B 9B 9B 9B 9B 9D'
+ '7F 5D 5E 77 3C A1 A1 00 00 00 00 00 00 00 00 00'
+ '00 A1 3D 87 86 91 9E 9E 9E 9E 9E 9E 9E 9E 9E 9F'
+ '9C 82 86 5A 26 A1 00 00 00 00 00 00 00 00 00 00'
+ '00 A1 A1 2B 33 32 32 32 32 32 32 32 32 32 32 32'
+ '32 33 33 02 A1 00 00 00 00 00 00 00 00 00 00 00'
+ '00 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
+ 'A1 A1 A1 A1 A1 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF E0 00 FF FF E0 00 FF FF E8 00 FF FF'
+ 'E0 00 80 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 7F 80 00 00 7F C0 00'
+ '00 7F C0 00 00 7F C0 00 00 7F E0 00 00 7F E0 00'
+ '00 FF E0 00 01 FF E0 00 01 FF FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 01 01 00 00 01 01'
+ '01 00 03 06 04 00 05 05 05 00 09 09 09 00 0A 0C'
+ '0C 00 08 0D 0F 00 13 13 13 00 15 15 15 00 16 16'
+ '15 00 17 17 17 00 18 18 18 00 19 19 19 00 1D 1D'
+ '1D 00 1E 1E 1E 00 31 0A 0B 00 1A 1E 20 00 35 19'
+ '35 00 21 21 21 00 29 23 23 00 30 2A 30 00 31 31'
+ '31 00 32 33 33 00 34 34 34 00 35 35 35 00 36 36'
+ '36 00 39 39 39 00 3A 3A 3B 00 3B 3B 3B 00 7A 00'
+ '00 00 4E 3E 3E 00 3F 41 42 00 44 44 44 00 46 46'
+ '46 00 4B 4B 4B 00 50 52 52 00 57 57 57 00 59 59'
+ '59 00 5C 5C 5C 00 5E 5E 5E 00 65 6A 68 00 69 69'
+ '69 00 6E 6E 6E 00 6F 6E 6E 00 77 6E 69 00 7E 69'
+ '69 00 72 72 72 00 75 75 75 00 79 73 79 00 79 79'
+ '79 00 7B 7B 7B 00 7F 7F 7F 00 83 00 00 00 88 70'
+ '70 00 00 FF 00 00 75 99 75 00 97 97 97 00 9B 9B'
+ '9B 00 A5 A5 A5 00 A6 A6 A6 00 A8 A2 A8 00 A8 A8'
+ 'A8 00 A9 A9 A9 00 AF AF AF 00 B8 AC B8 00 B2 B2'
+ 'B2 00 ED B7 97 00 C0 AE A4 00 DB B7 A2 00 DC B7'
+ 'A2 00 B7 E6 B7 00 FB C6 A8 00 F9 C7 AB 00 C0 C0'
+ 'C0 00 C1 C2 C2 00 C2 C2 C2 00 C3 C3 C3 00 C6 CD'
+ 'CD 00 C7 CE CE 00 C9 C9 C9 00 CA CA CA 00 C8 CF'
+ 'CF 00 CC CC CC 00 CE CE CE 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
+ 'D5 00 D6 D6 D6 00 D7 D7 D7 00 DE D8 D3 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DE DE DE 00 FF C9'
+ 'C9 00 FF D7 D7 00 FF E3 D0 00 DF E6 E6 00 E0 E0'
+ 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E8 E3 E1 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 ED ED ED 00 F3 F3'
+ 'F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6 F6 00 FF F2'
+ 'FF 00 F9 F9 F9 00 FA FA FA 00 FB FB FB 00 FB FC'
+ 'FC 00 FC FC FC 00 FF FD FE 00 FE FE FE 00 FF FF'
+ 'FF 00 00 00 00 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA D8 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 F1 D2'
+ 'C2 00 F2 D6 C7 00 F4 DD D0 00 E0 E0 E0 00 E1 E1'
+ 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 F0 F0 F0 00 F2 F2 F2 00 F3 F3 F3 00 F9 F9'
+ 'F9 00 FA FA FA 00 FF FF FF 00 00 00 00 00 01 00'
+ '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
+ '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
+ 'F5 77 00 EC FD 7F 56 00 00 00 00 00 00 00 03 00'
+ '00 00 5E 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
+ '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
+ 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 66'
+ '6C 6F 70 70 79 2E 69 63 6F 00 1A 93 4B 00 14 1A'
+ '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
+ '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '06 14 36 2E 2E 2E 00 00 00 00 00 00 00 00 00 0A'
+ '29 10 35 1E 1E 1E 00 7F 7F 7F 7F 7F 7F 7F 7F 01'
+ '03 1F 63 62 62 62 7F 2C 3D 38 41 40 3E 3C 3F 0D'
+ '05 24 65 4E 4F 52 7F 7C 76 37 47 31 33 32 42 08'
+ '7F 23 6B 51 53 53 7F 7D 7D 12 15 19 19 18 19 13'
+ '7F 23 7D 66 68 69 7F 7E 72 7D 77 75 72 72 7E 28'
+ '7F 02 7F 0B 0C 04 7F 7B 3B 58 5B 5A 5C 5B 69 25'
+ '0F 16 1C 20 11 07 7F 5C 54 54 57 59 5A 5A 67 27'
+ '25 17 6C 44 46 45 7F 3A 57 58 55 55 56 57 66 26'
+ '2F 22 4B 2D 48 43 00 2A 61 55 55 55 56 57 67 1D'
+ '0E 21 7A 5D 64 49 00 1B 71 60 5E 5F 5F 5E 5E 6A'
+ '71 30 7F 00 00 00 00 04 72 6F 6D 6B 6A 6A 69 70'
+ '75 1A 00 00 00 00 00 7F 6E 50 77 75 73 74 78 54'
+ '79 09 00 00 00 00 00 7F 2B 4A 4D 4C 4C 4C 4C 4A'
+ '39 7F 00 00 00 00 00 00 7F 7F 7F 7F 7F 7F 7F 7F'
+ '7F 00 00 00 00 00 FF C0 00 00 FF 80 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 80 0F'
+ '00 00 C0 1F 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00'
+ '00 00 00 09 99 99 00 00 00 00 00 0F FF FF 0F FA'
+ '77 77 00 0F 88 88 0F F0 00 00 00 0F FF FF 0F F7'
+ '77 77 70 00 00 00 07 77 77 77 70 00 00 00 07 77'
+ '77 77 70 08 88 88 07 77 77 77 70 08 87 77 07 77'
+ '77 77 70 07 8F 77 07 77 77 77 77 70 00 00 08 77'
+ '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 77'
+ '77 77 77 70 00 00 00 00 00 00 00 00 00 00 FF 80'
+ '00 00 FF 80 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 07 00 00 80 07'
+ '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 08 88 88 88 88 00 00 00 00 00 00 00 00 00 08'
+ '88 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '08 09 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
+ '00 07 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
+ '00 0F FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
+ '00 0F F8 88 88 88 00 8F FF 7A FF F7 77 77 77 00'
+ '00 0F FF FF FF FF 00 7F FF AA A7 77 77 77 70 00'
+ '00 0F F8 88 88 88 00 7F FF FA 77 00 00 00 07 70'
+ '00 0F FF FF FF FF 00 7F FF 00 00 00 00 00 00 00'
+ '00 0F F8 88 88 88 00 7F FF 77 77 77 77 77 77 70'
+ '00 0F FF FF FF FF 00 7F FF 77 77 77 77 77 77 70'
+ '00 00 00 00 00 00 00 7F FF FF FF FF FF FF FF F0'
+ '00 00 00 88 80 00 00 77 77 77 77 77 77 77 77 78'
+ '00 00 08 88 80 00 00 77 77 77 77 77 77 77 77 78'
+ '80 08 88 80 00 00 00 77 77 77 77 77 77 77 77 78'
+ '80 08 88 88 88 88 00 87 77 77 77 77 77 77 77 78'
+ '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 78'
+ '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 78'
+ '88 88 F8 87 77 77 00 07 77 77 77 77 77 77 77 70'
+ '88 87 F8 8F 77 77 00 07 77 77 77 77 77 77 77 70'
+ '00 07 77 77 77 77 00 07 77 77 77 77 77 77 77 77'
+ '77 70 00 00 00 00 00 08 77 77 77 77 77 77 77 77'
+ '77 70 00 00 00 00 00 08 77 77 77 77 77 77 77 77'
+ '77 70 00 00 00 00 00 00 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
+ '77 00 00 00 00 00 00 00 00 88 88 88 88 88 88 88'
+ '80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF E0 00 FF FF E0 00 FF FF'
+ 'E0 00 FF FF E8 00 E0 00 00 00 80 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 3F 80 00 00 7F C0 00 00 7F C0 00 00 7F C0 00'
+ '00 7F E0 00 00 7F E0 00 00 FF E0 00 00 FF E0 00'
+ '01 FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 01 01 01 00 02 02 02 00 03 03 03 00 04 04'
+ '04 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
+ '08 00 09 09 09 00 0A 0A 0A 00 0B 0B 0B 00 0C 0C'
+ '0C 00 0D 0D 0D 00 0E 0E 0E 00 10 10 10 00 11 11'
+ '11 00 12 12 10 00 12 12 12 00 13 13 13 00 14 14'
+ '14 00 15 15 15 00 16 16 14 00 16 16 16 00 17 17'
+ '17 00 18 18 18 00 19 19 19 00 1B 1B 1B 00 1C 1C'
+ '1C 00 1E 1E 1E 00 1F 1F 1F 00 22 22 1F 00 20 20'
+ '20 00 21 21 21 00 22 22 22 00 23 23 23 00 24 24'
+ '24 00 25 25 25 00 26 26 26 00 27 27 27 00 28 28'
+ '24 00 2A 2A 25 00 2B 2B 26 00 28 28 28 00 29 29'
+ '29 00 2A 2A 2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E'
+ '2E 00 2F 2F 2F 00 30 30 2C 00 30 30 30 00 32 32'
+ '32 00 33 33 33 00 36 36 30 00 34 34 34 00 35 35'
+ '35 00 36 36 36 00 37 37 37 00 39 39 39 00 3B 3B'
+ '3B 00 3C 3C 3C 00 3D 3D 3D 00 3F 3F 3F 00 40 40'
+ '40 00 41 41 41 00 42 42 42 00 43 43 43 00 44 44'
+ '44 00 45 45 45 00 46 46 46 00 47 47 47 00 48 48'
+ '48 00 49 49 49 00 4A 4A 4A 00 4B 4B 4B 00 4C 4C'
+ '4C 00 4E 4E 4E 00 4F 4F 4F 00 50 50 50 00 52 52'
+ '52 00 53 53 53 00 54 54 54 00 57 57 57 00 5B 58'
+ '57 00 59 59 59 00 5D 5D 5D 00 5E 5E 5E 00 5F 5F'
+ '5F 00 61 61 61 00 64 64 64 00 65 65 65 00 66 66'
+ '66 00 6D 6A 67 00 6A 6A 6A 00 7F 60 60 00 71 71'
+ '71 00 75 75 75 00 77 77 77 00 7B 77 75 00 79 79'
+ '79 00 7A 7A 7A 00 7E 7E 7E 00 7F 7F 7F 00 C0 00'
+ '00 00 83 7A 75 00 D5 40 40 00 00 C0 00 00 00 FF'
+ '00 00 87 80 7D 00 80 80 80 00 83 83 83 00 84 84'
+ '84 00 8B 86 84 00 8A 8A 8A 00 8C 8C 8C 00 8D 8D'
+ '8D 00 8E 8E 8E 00 90 90 90 00 93 93 93 00 97 97'
+ '97 00 99 99 99 00 9A 9A 9A 00 9E 9E 9E 00 9F 9F'
+ '9F 00 A3 A3 9E 00 A4 A4 A4 00 A6 A6 A6 00 A7 A7'
+ 'A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA AA 00 AB AB'
+ 'AB 00 AD A8 AB 00 AB AC AC 00 AD AD AD 00 AE AE'
+ 'AE 00 AF AF AF 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
+ 'B2 00 B3 B3 B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7'
+ 'B7 00 B8 B4 B6 00 B8 B6 B6 00 B8 B8 B8 00 BA BA'
+ 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 EA 80 80 00 CA A8 94 00 CC AF'
+ '9D 00 E9 B6 99 00 E9 B8 9C 00 CE B6 A6 00 D0 B3'
+ 'A3 00 D0 BC B0 00 EA BB A0 00 EA BC A1 00 EB BE'
+ 'A5 00 D2 C3 B9 00 EC C0 A7 00 EC C2 AA 00 ED C5'
+ 'AE 00 ED C6 AF 00 EE C8 B3 00 EF CC B8 00 F0 CF'
+ 'BC 00 F0 D0 BE 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2'
+ 'C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6'
+ 'C6 00 C8 C8 C8 00 C8 C9 C9 00 C9 C9 C9 00 CA CA'
+ 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
+ 'CE 00 CF CF CF 00 D5 CB C4 00 D0 CB C8 00 D7 D2'
+ 'CE 00 D9 D1 CC 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
+ 'D6 00 D7 D7 D7 00 DC D9 D7 00 D8 D8 D8 00 D9 D9'
+ 'D9 00 DA DA D8 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 FF C0'
+ 'C0 00 F1 D2 C2 00 F2 D6 C7 00 F3 D9 CB 00 F4 DD'
+ 'D0 00 F6 E4 D9 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
+ 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
+ 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
+ 'EE 00 EF EF EF 00 F9 EE E8 00 F0 F0 F0 00 F1 F1'
+ 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
+ 'F5 00 F6 F6 F6 00 F7 F7 F7 00 FD F9 F7 00 F8 F8'
+ 'F8 00 F9 F9 F9 00 FA FA FA 00 FF FF FF 00 00 00'
+ '00 00 C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 F8 F8 F8 F8 F8'
+ 'F8 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 3D 3D 3D 3D 3D'
+ 'F8 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 73 73 73 73 73'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 16 36 36 1F 04'
+ 'F8 68 68 68 68 68 68 68 68 68 68 68 68 68 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 28 00 00 73 0C'
+ 'F8 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 6A 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 F8 29 F8 F8 F8 0C'
+ 'F8 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 00 00'
+ '00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 11 2A 32 1F 0F'
+ 'F8 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 00 00'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 04 0C 0C 0F 19'
+ 'F8 E7 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 00 F8'
+ 'F8 F8 F8 21 2F 2E 2F 2E 2E 2E 2E 2E 2E 2E 2E 2E'
+ '2E 2E 2D 2D 2D 2D 2D 2D 2D 2D F8 0C 0C 0F 19 18'
+ 'F8 E6 E1 79 79 79 79 79 79 79 79 79 79 79 00 F8'
+ 'F8 26 76 91 87 86 85 BB BA B9 B7 B2 B1 B0 B0 B1'
+ 'AE AF 99 99 96 97 94 97 97 97 F8 0C 0F 19 19 1D'
+ 'F8 E5 CF DA DA DA DB DB DB DC DD DD DD DE F8 F8'
+ '01 72 85 E5 E2 E2 E2 C6 6B 6B E1 E2 E2 DD D1 CB'
+ 'C4 BB BB BB BB BB B6 BB 83 30 F8 F8 F8 19 1E 19'
+ 'F8 E4 E0 E1 E2 E2 E3 E4 E4 E4 E5 E5 E5 E6 F8 F8'
+ '1A 85 E5 E5 E2 E2 E2 6C 6C 6C 6B DB D3 C7 BA C4'
+ 'B9 BB BB BB BB BB BB BB 40 30 F8 F8 F8 1E 15 13'
+ 'F8 E3 E1 79 79 79 79 79 79 79 79 79 79 79 F8 F8'
+ '2C 85 E4 E5 E5 E2 E2 6C 6C 6C 6C B9 B5 5C 5C 5C'
+ '5C 5C 5C 5C 5C 5C 5C BB 77 40 F8 F8 F8 F8 0E 0F'
+ 'F8 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 F8 F8'
+ '2B C3 E6 E5 E5 E2 E2 E2 6C 6C 8E 8E 8F 3C 3C 3C'
+ '3C 3C 3C 3C 3C 3C 3C 8F 8F 8F F8 F8 F8 F8 0A 0D'
+ 'F8 E2 E1 DD DD DD DD DE DE DF E0 E0 E0 E1 F8 F8'
+ '2B C3 E8 E2 E5 E2 E2 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 24 1E 05 07 0A'
+ 'F8 DF E1 79 79 79 79 79 79 79 79 79 79 79 F8 F8'
+ '27 C3 E9 E5 E5 E5 E5 6E 3C 3C 3C 3C 3C 3C 3C 3C'
+ '3C 3C 3C 3C 3C 3C 3C 3C 3C 3C F8 2E 10 02 03 03'
+ 'F8 D0 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 F8 F8'
+ '27 C4 ED E4 E5 E5 E5 80 80 84 88 8A 89 89 89 89'
+ '89 89 84 84 84 84 84 84 84 84 F8 34 0C F8 F8 F8'
+ 'F8 DF DF E0 E1 E1 E2 E3 E3 E3 E4 E4 E4 E5 F8 F8'
+ '26 C5 EE E5 E7 E5 E3 E2 E0 DE DC CF D0 CB CC C4'
+ 'C4 BD C2 C2 C2 C2 C2 C2 C2 C2 F8 3A 02 03 04 04'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ '26 C5 F2 F4 F1 F1 F1 F0 F0 EF EF EE EE EE ED ED'
+ 'EC EC EC EB EB EB E9 E9 E8 E8 F8 3A 07 09 0B 0D'
+ '0F 13 1A 1D 27 37 42 46 46 46 46 2F 2F 2F F8 F8'
+ '24 C8 F7 E3 DB DC DC DA D3 D3 D3 D3 D3 DA DA DA'
+ 'DA DA DA DA DA DA DA DA DA DA F8 3F 0D 10 12 17'
+ '1B 21 26 33 3D 44 47 46 46 46 2F 2F 2F 2F F8 F8'
+ '24 D2 F4 CC B2 95 99 CB CE CC CC CC CC CC CC CC'
+ 'CC CC CC CC CC CC CC CC CC CC F8 44 23 18 1B 20'
+ '27 2E 38 40 44 47 4A 46 46 2F 2F 2F 2F 2F F8 F8'
+ '1E CE EE B4 82 90 8A B1 CE CB CB CB CB CB C9 C9'
+ 'C9 C9 C9 C9 C9 C9 CB CB CB CB F8 4B 30 1E 25 2E'
+ '31 3B 43 44 47 4B 49 42 39 2F 23 1C 1C 14 F8 F8'
+ '05 B0 F1 96 8C B1 84 95 CB C7 C7 C7 C6 C5 C5 C7'
+ 'C9 CB CB C9 C7 C5 C5 C5 C6 C7 F8 4B 4C 27 30 35'
+ '3D 45 44 47 4B 4B 45 3D 34 2D 25 1C 1C 17 00 F8'
+ 'F8 7E EF BD B3 C4 99 B7 C5 C4 C2 C5 C2 C2 C7 C7'
+ 'C7 C7 C7 C7 C7 C7 C2 C2 C6 C2 F8 50 53 3D 38 3F'
+ 'F8 73 73 73 73 73 73 73 73 73 73 73 73 73 00 F8'
+ 'F8 66 E9 C3 BD B9 BD C3 BC BD C7 C7 C7 C7 C7 C7'
+ 'C7 C7 C7 C7 C7 C7 C7 C7 C7 DB F8 53 57 56 49 45'
+ 'F8 70 F3 EA D9 D7 AC A8 A2 9D 9D 9D 9D 9D 00 F8'
+ 'F8 55 E3 C2 BB BB BB B8 C5 C5 C5 C5 C6 C7 C8 C8'
+ 'C8 C8 C8 C8 C8 C8 C7 C7 CF DE F8 57 57 5B 5E 44'
+ 'F8 75 F7 BF 71 6D 69 A0 A6 9D 9D 9D 9D 9D 00 F8'
+ 'F8 40 C9 C4 B8 B9 B8 C6 C5 C5 C5 C3 C4 C4 C4 C4'
+ 'C4 C4 C5 C4 C5 C5 C4 C4 C3 C2 F8 57 57 5B 5E 44'
+ 'F8 75 F7 BF 71 6D 69 A0 A6 9D 9D 9D 9D 9D 00 F8'
+ 'F8 22 90 CF B8 B9 BC C5 C5 BD C3 C2 C2 C2 C2 BD'
+ 'C5 C5 BC C5 C5 C5 C5 C5 C5 BC F8 57 5B 5E 5E 60'
+ 'F8 78 F7 92 52 4E 54 AD A9 A3 9D 9D 9D 9D 00 F8'
+ 'F8 07 7C D1 BA BB C5 C5 C5 C2 C2 C2 C2 C2 C2 C5'
+ 'C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5B 5B 5E 60 64'
+ 'F8 7B F7 89 50 4D 5D D6 AB A7 9E 9D 9D 9D 00 00'
+ 'F8 F8 6F D1 BD C3 C5 C5 C2 C2 C2 C2 C2 C2 C2 C2'
+ 'BD C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5B 5B 5E 64 64'
+ '3D 83 F7 7F 4F 4C 63 D8 D5 AA A4 9D 9D 9D 00 00'
+ 'F8 F8 58 D0 C3 C4 C5 C5 C3 C3 C3 C3 C3 C3 C3 C3'
+ 'C3 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 5E 60 64 66 66'
+ 'F8 8B F7 DA D3 CA C1 D9 D7 AC A8 A2 A2 9D 00 00'
+ 'F8 F8 41 CB C6 C4 C5 C5 C5 C5 C5 C5 C5 C5 C5 C5'
+ 'C5 C5 C5 C5 C5 C5 C5 C5 C5 C5 F8 F8 F8 F8 F8 F8'
+ 'F8 7D CD CD CD CD C0 BE A5 A1 9F 9C 9C 9B 00 00'
+ 'F8 F8 2F BA C8 C7 C5 C5 C8 C8 C8 C8 C8 C8 C8 C8'
+ 'C8 C8 C8 C5 C5 C5 C5 C5 BA B7 B4 B2 B0 8D 97 C2'
+ '79 09 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00'
+ 'F8 F8 19 8A CF CF D2 D2 D2 CC CE CE CE CE CE CE'
+ 'CE CE CE CE D1 D1 D1 D1 D1 CE D1 D1 E1 CC BA B8'
+ '65 02 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00'
+ 'F8 F8 08 78 D0 D3 D0 D2 D2 D2 D1 D1 D1 D1 D1 D1'
+ 'D1 D1 D1 D1 D1 D1 D1 D1 D1 D1 E1 E1 E1 D1 D0 B4'
+ '51 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F8 F8 62 C5 DC DB D2 D2 D2 D2 D2 DA DA DA DA'
+ 'DA DA DA DA DA DA DA DA DB DB E1 E1 E1 DD CC 95'
+ '3B F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F8 F8 4B B7 DF DD DE E5 E5 E5 E5 E5 E5 DE DE'
+ 'DE DE DE DE DE DE DF DF E1 E1 E1 E1 DE E0 C8 81'
+ '20 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F8 F8 38 97 E0 E0 E0 E1 E1 E5 E5 E5 E5 E5 E5'
+ 'E5 E5 E5 E5 E5 E5 E5 E1 E1 E1 E1 E1 E0 E2 C6 7A'
+ '0B F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F8 F8 1D 84 DE E7 E1 E0 E6 E5 E4 E7 E5 E5 E5'
+ 'E5 E5 E5 E5 E5 E5 E5 E5 E5 E6 E4 DF E5 E5 C8 72'
+ 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 F8 F8 08 79 DE D3 97 AF C8 E6 E7 E7 E8 E8 E7'
+ 'E6 E5 E5 E6 E7 E8 E8 E7 E8 DE B0 98 C3 E6 C6 61'
+ 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 74 DA B2 8C 93 8C E5 EC EB EB EB EB'
+ 'EB EB EB EB EB EB EB EB EE C7 8A 8F 90 E5 BB 59'
+ 'F8 F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 5A BC D1 D0 C7 DE F5 F5 F5 F5 F5 F5'
+ 'F5 F5 F5 F5 F5 F5 F5 F5 F6 ED D3 CB D0 C9 8A 37'
+ 'F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 1A 6E 98 C5 C9 CF CB CB CB CB CB CB'
+ 'CB CB CB CB CB CB CB CB CB CC CC C9 BB 8A 56 06'
+ 'F8 F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 F8 F8 F8 0C 3E 49 48 48 48 48 48 48 48 48'
+ '48 48 48 48 48 48 48 48 48 48 48 49 49 31 02 F8'
+ 'F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8'
+ 'F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F3 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 C0 00 00 00 03 FF 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
+ '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
+ '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
+ '77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 08 88 88 88 88 88 88 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 08 88 88 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 09 99 99 99 99 99 99 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 09'
+ '99 99 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 07 77 77 77 77 77 77 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07'
+ '77 77 77 77 77 77 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 0F FF FF FF FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F'
+ 'F8 88 88 88 88 88 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 00 00 00 0F 7F FF FF FF FF FF 00 08'
+ '7F FF F7 AA FF FF 77 77 77 77 77 70 00 00 00 0F'
+ 'FF FF FF FF FF FF 00 07 FF FF FA AA AF 77 77 77'
+ '77 77 77 00 00 00 00 0F F8 88 88 88 88 88 00 07'
+ 'FF FF FA AA A7 78 88 88 88 88 87 80 00 00 00 0F'
+ 'FF FF FF FF FF FF 00 07 FF FF FF AA 77 70 00 00'
+ '00 00 07 77 00 00 00 0F FF FF FF FF FF FF 00 07'
+ 'FF FF F0 00 00 00 00 00 00 00 00 00 00 00 00 0F'
+ 'F8 88 88 88 88 88 00 07 FF FF F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 07 FF FF FF FF FF FF 00 07'
+ 'FF FF F7 77 77 77 77 77 77 77 77 77 00 00 00 0F'
+ 'FF FF FF FF FF FF 00 07 FF FF FF FF F7 77 77 77'
+ '77 77 77 77 00 00 00 00 00 00 00 00 00 00 00 07'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00'
+ '00 00 88 88 80 00 00 07 F7 7F FF 77 77 7F FF FF'
+ 'FF FF FF FF 00 00 00 00 00 08 88 88 00 00 00 07'
+ '77 77 77 77 77 77 77 77 77 7F 77 F7 08 00 00 00'
+ '00 88 88 80 00 00 00 07 F7 77 77 77 77 77 77 77'
+ '77 77 77 77 08 00 00 00 88 88 88 00 00 00 00 07'
+ '77 77 77 77 77 77 77 77 77 77 77 77 08 80 00 08'
+ '88 88 80 00 00 00 00 07 77 77 77 77 77 77 77 77'
+ '77 77 77 77 08 80 00 08 88 88 88 88 88 88 00 08'
+ '77 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
+ 'FF F7 77 77 77 77 00 08 77 77 77 77 77 77 77 77'
+ '77 77 77 77 08 88 88 08 F7 88 87 77 77 77 00 00'
+ '77 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
+ 'F7 88 87 77 77 77 00 00 77 77 77 77 77 77 77 77'
+ '77 77 77 77 08 88 88 08 F7 88 87 77 77 77 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 08 88 88 08'
+ 'F7 88 87 77 77 77 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 08 88 88 07 F7 88 8F 77 77 77 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 08 88 88 07'
+ 'FF 77 7F 77 77 77 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 00 00 00 07 77 77 77 77 77 77 00 00'
+ '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '00 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
+ '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
+ '00 00 00 00 00 00 00 00 00 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
+ '00 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
+ '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
+ '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
+ '00 87 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
+ '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
+ '77 77 77 77 77 77 70 00 00 00 00 00 00 00 00 00'
+ '00 08 77 77 77 77 77 77 77 77 77 77 77 77 80 00'
+ '00 00 00 00 00 00 00 00 00 00 08 88 88 88 88 88'
+ '88 88 88 88 88 80 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F3 00 00 00 00 FF FF FF F0 00 00 00 00 F0 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 03 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
+ '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 24 00 00 00 6C 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C'
+ '3C FF 3C 3C 3C FF 00 00 00 FF 7F 60 60 FF 7F 60'
+ '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
+ '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
+ '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 16 16 14 FF 36 36 30 FF 36 36 30 FF 22 22'
+ '1F FF 04 04 04 FF 00 00 00 FF C0 00 00 FF C0 00'
+ '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF C0 00'
+ '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF C0 00'
+ '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 28 28 24 FF 00 00 00 B4 00 00 00 9C 8C 8C'
+ '8C FF 0C 0C 0C FF 00 00 00 FF D5 40 40 FF D5 40'
+ '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
+ '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
+ '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 2A 2A 25 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 0C 0C 0C FF 00 00 00 FF EA 80 80 FF EA 80'
+ '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
+ '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
+ '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 FF 12 12 10 FF 2B 2B 26 FF 30 30 2C FF 22 22'
+ '1F FF 10 10 10 FF 00 00 00 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
+ '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 FF 04 04 04 FF 0C 0C 0C FF 0C 0C 0C FF 10 10'
+ '10 FF 18 18 18 FF 00 00 00 FF ED ED ED FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
+ '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
+ '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 00 00'
+ '00 FF 0C 0C 0C FF 0C 0C 0C FF 10 10 10 FF 18 18'
+ '18 FF 17 17 17 FF 00 00 00 FF EC EC EC FF E7 E7'
+ 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
+ '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
+ '90 FF B8 B4 B6 FF AD AD AD FF AB AC AC FF AD A8'
+ 'AB FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
+ 'C9 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF'
+ 'BF FF BF BF BF FF BC BC BC FF BD BD BD FF BA BA'
+ 'BA FF BD BD BD FF BD BD BD FF BD BD BD FF 00 00'
+ '00 FF 0C 0C 0C FF 10 10 10 FF 18 18 18 FF 18 18'
+ '18 FF 1E 1E 1E FF 00 00 00 FF EB EB EB FF DB DB'
+ 'DB FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
+ 'E1 FF E1 E1 E1 FF E1 E1 E1 FF E2 E2 E2 FF E3 E3'
+ 'E3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF 00 00'
+ '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF AD A8'
+ 'AB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF D4 D4 D4 FF 00 C0 00 FF 00 C0 00 FF E7 E7'
+ 'E7 FF E8 E8 E8 FF E8 E8 E8 FF E3 E3 E3 FF DD DD'
+ 'DD FF D8 D8 D8 FF D2 D2 D2 FF CD CD CD FF CD CD'
+ 'CD FF CD CD CD FF CD CD CD FF CD CD CD FF C8 C9'
+ 'C9 FF CD CD CD FF AA AA AA FF 2E 2E 2E FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 18 18 18 FF 1F 1F'
+ '1F FF 18 18 18 FF 00 00 00 FF EA EA EA FF E6 E6'
+ 'E6 FF E7 E7 E7 FF E8 E8 E8 FF E8 E8 E8 FF E9 E9'
+ 'E9 FF EA EA EA FF EA EA EA FF EA EA EA FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF 00 00'
+ '00 15 00 00 00 F0 19 19 19 FF AD A8 AB FF EB EB'
+ 'EB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 C0'
+ '00 FF E1 E1 E1 FF DF DF DF FF D5 D5 D5 FF CC CC'
+ 'CC FF D2 D2 D2 FF CB CB CB FF CD CD CD FF CD CD'
+ 'CD FF CD CD CD FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF CD CD CD FF 40 40 40 FF 2E 2E 2E FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 1F 1F 1F FF 15 15'
+ '15 FF 13 13 13 FF 00 00 00 FF E9 E9 E9 FF E7 E7'
+ 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
+ '00 30 00 00 00 FA 29 29 29 FF AD A8 AB FF EA EA'
+ 'EA FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
+ 'E8 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF 00 FF'
+ '00 FF CB CB CB FF C8 C8 C8 FF 66 66 66 FF 66 66'
+ '66 FF 66 66 66 FF 66 66 66 FF 66 66 66 FF 66 66'
+ '66 FF 66 66 66 FF 66 66 66 FF 66 66 66 FF 66 66'
+ '66 FF CD CD CD FF 93 93 93 FF 40 40 40 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 0E 0E'
+ '0E FF 10 10 10 FF 00 00 00 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
+ '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
+ 'E8 FF E8 E8 E8 FF 00 FF 00 FF 00 FF 00 FF B5 B5'
+ 'B5 FF B5 B5 B5 FF B6 B6 B6 FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 0A 0A'
+ '0A FF 0D 0D 0D FF 00 00 00 FF E8 E8 E8 FF E7 E7'
+ 'E7 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5 E5 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF 00 00'
+ '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
+ 'EE FF E8 E8 E8 FF EB EB EB FF E8 E8 E8 FF E8 E8'
+ 'E8 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 24 24 24 FF 1F 1F 1F FF 05 05 05 FF 07 07'
+ '07 FF 0A 0A 0A FF 00 00 00 FF E5 E5 E5 FF E7 E7'
+ 'E7 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
+ 'EF FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF 80 80 80 FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 00 00'
+ '00 FF 2B 2B 2B FF 11 11 11 FF 02 02 02 FF 03 03'
+ '03 FF 03 03 03 FF 00 00 00 FF DC DC DC FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
+ 'F2 FF EA EA EA FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF A7 A7 A7 FF A7 A7 A7 FF AB AB AB FF AE AE'
+ 'AE FF B0 B0 B0 FF AF AF AF FF AF AF AF FF AF AF'
+ 'AF FF AF AF AF FF AF AF AF FF AF AF AF FF AB AB'
+ 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
+ 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF 00 00'
+ '00 FF 32 32 32 FF 0C 0C 0C FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF E5 E5 E5 FF E5 E5'
+ 'E5 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8'
+ 'E8 FF E9 E9 E9 FF E9 E9 E9 FF E9 E9 E9 FF EA EA'
+ 'EA FF EA EA EA FF EA EA EA FF EB EB EB FF 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
+ 'F3 FF EB EB EB FF ED ED ED FF EB EB EB FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF DB DB DB FF DC DC DC FF D8 D8 D8 FF D9 D9'
+ 'D9 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF 00 00'
+ '00 FF 37 37 37 FF 02 02 02 FF 03 03 03 FF 04 04'
+ '04 FF 04 04 04 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
+ 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF 00 00'
+ '00 FF 37 37 37 FF 07 07 07 FF 09 09 09 FF 0B 0B'
+ '0B FF 0D 0D 0D FF 10 10 10 FF 13 13 13 FF 19 19'
+ '19 FF 1E 1E 1E FF 27 27 27 FF 34 34 34 FF 42 42'
+ '42 FF 46 46 46 FF 46 46 46 FF 46 46 46 FF 46 46'
+ '46 FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
+ '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
+ 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
+ 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF 00 00'
+ '00 FF 3F 3F 3F FF 0D 0D 0D FF 11 11 11 FF 12 12'
+ '12 FF 16 16 16 FF 1B 1B 1B FF 21 21 21 FF 26 26'
+ '26 FF 30 30 30 FF 3C 3C 3C FF 44 44 44 FF 47 47'
+ '47 FF 46 46 46 FF 46 46 46 FF 46 46 46 FF 2C 2C'
+ '2C FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
+ '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
+ 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
+ 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF 00 00'
+ '00 FF 44 44 44 FF 23 23 23 FF 17 17 17 FF 1B 1B'
+ '1B FF 20 20 20 FF 27 27 27 FF 2B 2B 2B FF 35 35'
+ '35 FF 40 40 40 FF 44 44 44 FF 47 47 47 FF 4A 4A'
+ '4A FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
+ '2C FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 00 00'
+ '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
+ 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
+ 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF 00 00'
+ '00 FF 4B 4B 4B FF 2E 2E 2E FF 1F 1F 1F FF 25 25'
+ '25 FF 2B 2B 2B FF 2F 2F 2F FF 39 39 39 FF 43 43'
+ '43 FF 44 44 44 FF 47 47 47 FF 4B 4B 4B FF 49 49'
+ '49 FF 42 42 42 FF 36 36 36 FF 2C 2C 2C FF 23 23'
+ '23 FF 1C 1C 1C FF 1C 1C 1C FF 14 14 14 FF 00 00'
+ '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
+ 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
+ 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF 00 00'
+ '00 FF 4B 4B 4B FF 4C 4C 4C FF 27 27 27 FF 2E 2E'
+ '2E FF 33 33 33 FF 3C 3C 3C FF 45 45 45 FF 44 44'
+ '44 FF 47 47 47 FF 4B 4B 4B FF 4B 4B 4B FF 45 45'
+ '45 FF 3C 3C 3C FF 32 32 32 FF 2A 2A 2A FF 25 25'
+ '25 FF 1C 1C 1C FF 1C 1C 1C FF 16 16 16 FF 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
+ 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
+ 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0 D0 FF 00 00'
+ '00 FF 52 52 52 FF 57 57 57 FF 3C 3C 3C FF 35 35'
+ '35 FF 3F 3F 3F FF 00 00 00 FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 00 00'
+ '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
+ 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
+ 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF E1 E1 E1 FF 00 00'
+ '00 FF 57 57 57 FF 5E 5E 5E FF 5D 5D 5D FF 49 49'
+ '49 FF 45 45 45 FF 00 00 00 FF 84 84 84 FF FD F9'
+ 'F7 FF F9 EE E8 FF F6 E4 D9 FF F3 D9 CB FF F0 CF'
+ 'BC FF ED C5 AE FF EA BB A0 FF E9 B6 99 FF E9 B6'
+ '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
+ 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF CA CA CA FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF 00 00'
+ '00 FF 5E 5E 5E FF 5E 5E 5E FF 65 65 65 FF 6A 6A'
+ '6A FF 44 44 44 FF 00 00 00 FF 8E 8E 8E FF FF FF'
+ 'FF FF D0 CB C8 FF 8B 86 84 FF 87 80 7D FF 83 7A'
+ '75 FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
+ '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
+ 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
+ 'CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D2 D2 D2 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF 00 00'
+ '00 FF 5E 5E 5E FF 5E 5E 5E FF 65 65 65 FF 6A 6A'
+ '6A FF 44 44 44 FF 00 00 00 FF 8E 8E 8E FF FF FF'
+ 'FF FF D0 CB C8 FF 8B 86 84 FF 87 80 7D FF 83 7A'
+ '75 FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
+ '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
+ 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
+ 'CE FF D3 D3 D3 FF D3 D3 D3 FF CF CF CF FF D1 D1'
+ 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF D3 D3 D3 FF D3 D3 D3 FF CE CE'
+ 'CE FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CE CE CE FF 00 00'
+ '00 FF 5E 5E 5E FF 65 65 65 FF 6A 6A 6A FF 6A 6A'
+ '6A FF 71 71 71 FF 00 00 00 FF 97 97 97 FF FF FF'
+ 'FF FF B8 B6 B6 FF 54 54 54 FF 4F 4F 4F FF 5B 58'
+ '57 FF F0 D0 BE FF ED C6 AF FF EA BC A1 FF E9 B6'
+ '99 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
+ '9F FF DD DD DD FF CC CC CC FF CD CD CD FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
+ '00 FF 65 65 65 FF 6A 6A 6A FF 6A 6A 6A FF 71 71'
+ '71 FF 79 79 79 FF 00 00 00 FF 9E 9E 9E FF FF FF'
+ 'FF FF AF AF AF FF 52 52 52 FF 4E 4E 4E FF 6D 6A'
+ '67 FF F2 D6 C7 FF EF CC B8 FF EC C2 AA FF E9 B8'
+ '9C FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
+ '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
+ '00 FF 65 65 65 FF 6A 6A 6A FF 71 71 71 FF 7E 7E'
+ '7E FF 79 79 79 FF 00 00 00 FF AA AA AA FF FF FF'
+ 'FF FF A6 A6 A6 FF 50 50 50 FF 4C 4C 4C FF 7B 77'
+ '75 FF F4 DD D0 FF F1 D2 C2 FF EE C8 B3 FF EB BE'
+ 'A5 FF E9 B6 99 FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
+ '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
+ '00 FF 65 65 65 FF 71 71 71 FF 79 79 79 FF 7E 7E'
+ '7E FF 7E 7E 7E FF 00 00 00 FF B1 B1 B1 FF FF FF'
+ 'FF FF E0 E0 E0 FF DF DF DF FF DC D9 D7 FF D9 D1'
+ 'CC FF F6 E4 D9 FF F3 D9 CB FF F0 CF BC FF ED C5'
+ 'AE FF EA BB A0 FF EA BB A0 FF E9 B6 99 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
+ '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF A3 A3 9E FF DA DA'
+ 'D8 FF DA DA D8 FF DA DA D8 FF DA DA D8 FF D7 D2'
+ 'CE FF D5 CB C4 FF D2 C3 B9 FF D0 BC B0 FF CE B6'
+ 'A6 FF CC AF 9D FF CC AF 9D FF CA A8 94 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
+ '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF CC CC CC FF C9 C9 C9 FF C6 C6'
+ 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
+ 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
+ '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
+ '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF DE DE'
+ 'DE FF DE DE DE FF DE DE DE FF D9 D9 D9 FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DA DA DA FF DD DD'
+ 'DD FF DD DD DD FF E7 E7 E7 FF D9 D9 D9 FF CC CC'
+ 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
+ '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
+ '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
+ 'DC FF DE DE DE FF DE DE DE FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF DD DD DD FF DC DC'
+ 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
+ '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
+ '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
+ 'DE FF DE DE DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E3 E3 E3 FF D9 D9'
+ 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
+ '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
+ '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
+ 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
+ '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
+ '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
+ '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
+ '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
+ 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
+ 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EA EA'
+ 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
+ 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
+ '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
+ 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
+ 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
+ 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
+ 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
+ '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
+ 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
+ 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
+ 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
+ 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
+ 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
+ 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
+ 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
+ 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
+ '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
+ '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
+ '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
+ '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
+ '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 FF FF FF F0 00 00 00 00 FF FF'
+ 'FF F0 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 C0 00 00 00 03 FF 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
+ '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 24 00 00 00 6C 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 3C 3C 3C FF 3C 3C 3C FF 3C 3C 3C FF 3C 3C'
+ '3C FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
+ '60 FF 7F 60 60 FF 7F 60 60 FF 7F 60 60 FF 7F 60'
+ '60 FF 7F 60 60 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 04 00 00 00 14 00 00 00 26 00 00 00 2D 00 00'
+ '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
+ '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
+ '00 2D 00 00 00 2D 00 00 00 2D 00 00 00 2D 00 00'
+ '00 2D 28 28 24 FF 00 00 00 8F 8C 8C 8C FF 0C 0C'
+ '0C FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
+ '40 FF D5 40 40 FF D5 40 40 FF D5 40 40 FF D5 40'
+ '40 FF D5 40 40 FF 00 00 00 00 00 00 00 07 00 00'
+ '00 23 00 00 00 55 00 00 00 7E 00 00 00 8C 00 00'
+ '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
+ '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
+ '00 8C 00 00 00 8C 00 00 00 8C 00 00 00 8C 00 00'
+ '00 8C 2A 2A 25 FF 00 00 00 FF 00 00 00 FF 0C 0C'
+ '0C FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
+ '80 FF EA 80 80 FF EA 80 80 FF EA 80 80 FF EA 80'
+ '80 FF EA 80 80 FF 00 00 00 00 00 00 00 1F 00 00'
+ '00 C2 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 04 04 04 FF 0C 0C 0C FF 10 10 10 FF 18 18'
+ '18 FF ED ED ED FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF 00 00 00 00 00 00 00 C0 00 00'
+ '00 FF 21 21 21 FF 2C 2C 2C FF 2C 2C 2C FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 0C 0C 0C FF 0C 0C 0C FF 18 18 18 FF 17 17'
+ '17 FF EC EC EC FF E7 E7 E7 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 00 00 00 06 01 01 01 FF 8A 8A'
+ '8A FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 00 C0 00 FF E7 E7 E7 FF E8 E8 E8 FF E3 E3'
+ 'E3 FF D8 D8 D8 FF D2 D2 D2 FF CD CD CD FF CD CD'
+ 'CD FF CD CD CD FF C8 C9 C9 FF AA AA AA FF 2E 2E'
+ '2E FF 00 00 00 FF 00 00 00 FF 1F 1F 1F FF 18 18'
+ '18 FF EA EA EA FF E6 E6 E6 FF E8 E8 E8 FF E8 E8'
+ 'E8 FF EA EA EA FF EA EA EA FF EB EB EB FF EB EB'
+ 'EB FF EC EC EC FF 00 00 00 1B 19 19 19 FF AD A8'
+ 'AB FF EB EB EB FF E8 E8 E8 FF E8 E8 E8 FF 00 FF'
+ '00 FF 00 FF 00 FF 00 C0 00 FF DF DF DF FF D5 D5'
+ 'D5 FF D2 D2 D2 FF CB CB CB FF CD CD CD FF CD CD'
+ 'CD FF CD CD CD FF CD CD CD FF 40 40 40 FF 2E 2E'
+ '2E FF 00 00 00 FF 00 00 00 FF 15 15 15 FF 13 13'
+ '13 FF E9 E9 E9 FF E7 E7 E7 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 00 00 00 3A 28 28 28 FF D1 D1'
+ 'D1 FF EB EB EB FF EB EB EB FF E8 E8 E8 FF E8 E8'
+ 'E8 FF 00 FF 00 FF B5 B5 B5 FF B6 B6 B6 FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF B6 B6 B6 FF B6 B6'
+ 'B6 FF 00 00 00 FF 00 00 00 FF 0A 0A 0A FF 0D 0D'
+ '0D FF E8 E8 E8 FF E7 E7 E7 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E7 E7 E7 FF 00 00 00 39 28 28 28 FF D1 D1'
+ 'D1 FF E8 E8 E8 FF EB EB EB FF E8 E8 E8 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 24 24 24 FF 1F 1F 1F FF 07 07 07 FF 0A 0A'
+ '0A FF E5 E5 E5 FF E7 E7 E7 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 99 99 99 FF 99 99 99 FF 99 99'
+ '99 FF 99 99 99 FF 00 00 00 39 27 27 27 FF D2 D2'
+ 'D2 FF EA EA EA FF EB EB EB FF EB EB EB FF A7 A7'
+ 'A7 FF AB AB AB FF AE AE AE FF AF AF AF FF AF AF'
+ 'AF FF AF AF AF FF AF AF AF FF AB AB AB FF AB AB'
+ 'AB FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
+ 'AB FF 32 32 32 FF 0C 0C 0C FF 00 00 00 FF 00 00'
+ '00 FF E5 E5 E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E9 E9 E9 FF E9 E9 E9 FF EA EA EA FF EA EA'
+ 'EA FF EB EB EB FF 00 00 00 39 26 26 26 FF D3 D3'
+ 'D3 FF EB EB EB FF ED ED ED FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E4 E4 E4 FF E2 E2 E2 FF DC DC DC FF D8 D8'
+ 'D8 FF D2 D2 D2 FF D2 D2 D2 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF 37 37 37 FF 02 02 02 FF 04 04 04 FF 04 04'
+ '04 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 37 24 24 24 FF D6 D6'
+ 'D6 FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E0 E0'
+ 'E0 FF DF DF DF FF DF DF DF FF DF DF DF FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF 3F 3F 3F FF 0D 0D 0D FF 12 12 12 FF 16 16'
+ '16 FF 21 21 21 FF 26 26 26 FF 3C 3C 3C FF 44 44'
+ '44 FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
+ '2C FF 2C 2C 2C FF 00 00 00 34 24 24 24 FF DE DE'
+ 'DE FF D9 D9 D9 FF C4 C4 C4 FF BF BF BF FF D8 D8'
+ 'D8 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF 44 44 44 FF 23 23 23 FF 1B 1B 1B FF 20 20'
+ '20 FF 2B 2B 2B FF 35 35 35 FF 44 44 44 FF 47 47'
+ '47 FF 46 46 46 FF 46 46 46 FF 2C 2C 2C FF 2C 2C'
+ '2C FF 2C 2C 2C FF 00 00 00 07 05 05 05 FF C2 C2'
+ 'C2 FF BC BC BC FF B2 B2 B2 FF AB AB AB FF BB BB'
+ 'BB FF D5 D5 D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3'
+ 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D3 D3 D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5'
+ 'D5 FF 4B 4B 4B FF 4C 4C 4C FF 2E 2E 2E FF 33 33'
+ '33 FF 45 45 45 FF 44 44 44 FF 4B 4B 4B FF 4B 4B'
+ '4B FF 3C 3C 3C FF 32 32 32 FF 25 25 25 FF 1C 1C'
+ '1C FF 16 16 16 FF 00 00 00 00 00 00 00 FF A4 A4'
+ 'A4 FF CF CF CF FF C5 C5 C5 FF BF BF BF FF C9 C9'
+ 'C9 FF D2 D2 D2 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0'
+ 'D0 FF 52 52 52 FF 57 57 57 FF 35 35 35 FF 3F 3F'
+ '3F FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 00 00 00 00 00 00 00 FF 59 59'
+ '59 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CA CA'
+ 'CA FF D3 D3 D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5'
+ 'D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D5 D5 D5 FF DB DB DB FF E4 E4'
+ 'E4 FF 5E 5E 5E FF 5E 5E 5E FF 6A 6A 6A FF 44 44'
+ '44 FF 8E 8E 8E FF FF FF FF FF 8B 86 84 FF 87 80'
+ '7D FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
+ '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 FF 40 40'
+ '40 FF D2 D2 D2 FF CA CA CA FF CA CA CA FF D4 D4'
+ 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3 D3 FF D2 D2'
+ 'D2 FF D3 D3 D3 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0'
+ 'D0 FF 5E 5E 5E FF 5E 5E 5E FF 6A 6A 6A FF 44 44'
+ '44 FF 8E 8E 8E FF FF FF FF FF 8B 86 84 FF 87 80'
+ '7D FF D0 B3 A3 FF EC C0 A7 FF E9 B6 99 FF E9 B6'
+ '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 F4 07 07'
+ '07 FF DD DD DD FF CC CC CC FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 65 65 65 FF 6A 6A 6A FF 71 71 71 FF 79 79'
+ '79 FF 9E 9E 9E FF FF FF FF FF 52 52 52 FF 4E 4E'
+ '4E FF F2 D6 C7 FF EF CC B8 FF E9 B8 9C FF E9 B6'
+ '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 BA 00 00'
+ '00 FF DD DD DD FF CF CF CF FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 3C 3C 3C FF 6A 6A 6A FF 71 71 71 FF 79 79'
+ '79 FF AA AA AA FF FF FF FF FF 50 50 50 FF 4C 4C'
+ '4C FF F4 DD D0 FF F1 D2 C2 FF EB BE A5 FF E9 B6'
+ '99 FF E9 B6 99 FF 00 00 00 00 00 00 00 4D 00 00'
+ '00 FF D8 D8 D8 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF A3 A3 9E FF DA DA D8 FF DA DA D8 FF DA DA'
+ 'D8 FF D5 CB C4 FF D2 C3 B9 FF CE B6 A6 FF CC AF'
+ '9D FF CA A8 94 FF 00 00 00 00 00 00 00 1A 00 00'
+ '00 FF CC CC CC FF D6 D6 D6 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CC CC CC FF C9 C9'
+ 'C9 FF C4 C4 C4 FF C2 C2 C2 FF BD BD BD FF D0 D0'
+ 'D0 FF 09 09 09 FF 00 00 00 FF 00 00 00 6C 00 00'
+ '00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00'
+ '00 D2 97 97 97 FF DC DC DC FF DC DC DC FF DE DE'
+ 'DE FF DE DE DE FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF E7 E7 E7 FF E7 E7 E7 FF DC DC DC FF C6 C6'
+ 'C6 FF 00 00 00 FF 00 00 00 FF 00 00 00 59 00 00'
+ '00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 AF 77 77 77 FF D3 D3 D3 FF E1 E1 E1 FF DE DE'
+ 'DE FF DE DE DE FF DE DE DE FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1'
+ 'E1 FF E7 E7 E7 FF E7 E7 E7 FF D9 D9 D9 FF BB BB'
+ 'BB FF 00 00 00 FF 00 00 00 FF 00 00 00 40 00 00'
+ '00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 66 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E7 E7 E7 FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF D4 D4 D4 FF 9A 9A'
+ '9A FF 00 00 00 FF 00 00 00 A4 00 00 00 2B 00 00'
+ '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 2D 1E 1E 1E FF AB AB AB FF ED ED ED FF E7 E7'
+ 'E7 FF EC EC EC FF EB EB EB FF ED ED ED FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EC EC'
+ 'EC FF E5 E5 E5 FF EB EB EB FF D6 D6 D6 FF 8A 8A'
+ '8A FF 00 00 00 FF 00 00 00 7B 00 00 00 1B 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 8D 8D 8D FF C4 C4 C4 FF B2 B2'
+ 'B2 FF B2 B2 B2 FF EB EB EB FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5'
+ 'D5 FF B6 B6 B6 FF B7 B7 B7 FF CD CD CD FF 61 61'
+ '61 FF 00 00 00 FF 00 00 00 50 00 00 00 0F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 64 64 64 FF DD DD DD FF DC DC'
+ 'DC FF E4 E4 E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA FA FF F2 F2'
+ 'F2 FF D8 D8 D8 FF DC DC DC FF B0 B0 B0 FF 34 34'
+ '34 FF 00 00 00 E5 00 00 00 31 00 00 00 04 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF 3D 3D 3D FF 49 49'
+ '49 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 49 49 49 FF 49 49 49 FF 02 02 02 FF 00 00'
+ '00 FF 00 00 00 49 00 00 00 14 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 00 00 00 7F 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FA 00 00'
+ '00 7C 00 00 00 12 00 00 00 04 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF E0 00 FF FF E0 00 FF FF'
+ 'E0 00 C0 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 1F 80 00 00 1F C0 00 00 1F C0 00 00 1F C0 00'
+ '00 1F E0 00 00 3F E0 00 00 3F E0 00 00 7F E0 00'
+ '00 7F FF FF FF FF 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 00 00 00 FF 00 00 00 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 36 36 30 FF 00 00 00 FF C0 00'
+ '00 FF C0 00 00 FF C0 00 00 FF C0 00 00 FF 00 00'
+ '00 00 00 00 00 16 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 FF 30 30 2C FF 00 00 00 FF FF C0'
+ 'C0 FF FF C0 C0 FF FF C0 C0 FF FF C0 C0 FF 00 00'
+ '00 54 90 90 90 FF AB AC AC FF CC CC CC FF C4 C4'
+ 'C4 FF C2 C2 C2 FF C1 C1 C1 FF BC BC BC FF BD BD'
+ 'BD FF 00 00 00 FF 18 18 18 FF 00 00 00 FF E0 E0'
+ 'E0 FF E1 E1 E1 FF E2 E2 E2 FF E3 E3 E3 FF 00 00'
+ '00 FA EA EA EA FF E8 E8 E8 FF 00 FF 00 FF CB CB'
+ 'CB FF 66 66 66 FF 66 66 66 FF 66 66 66 FF CD CD'
+ 'CD FF 00 00 00 FF 00 00 00 FF 00 00 00 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
+ '00 F9 EF EF EF FF EB EB EB FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B 3B FF 3B 3B'
+ '3B FF 00 00 00 FF 02 02 02 FF 00 00 00 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF 00 00'
+ '00 F9 F7 F7 F7 FF F6 F6 F6 FF F5 F5 F5 FF F3 F3'
+ 'F3 FF F2 F2 F2 FF F1 F1 F1 FF F0 F0 F0 FF EF EF'
+ 'EF FF 00 00 00 FF 09 09 09 FF 10 10 10 FF 1E 1E'
+ '1E FF 42 42 42 FF 46 46 46 FF 2C 2C 2C FF 00 00'
+ '00 F7 F3 F3 F3 FF B7 B7 B7 FF DA DA DA FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF 00 00 00 FF 1F 1F 1F FF 2F 2F 2F FF 44 44'
+ '44 FF 49 49 49 FF 2C 2C 2C FF 1C 1C 1C FF 00 00'
+ '00 73 EF EF EF FF CB CB CB FF CE CE CE FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF 00 00 00 FF 5D 5D 5D FF 00 00 00 FF F9 EE'
+ 'E8 FF F0 CF BC FF E9 B6 99 FF E9 B6 99 FF 00 00'
+ '00 25 B7 B7 B7 FF CB CB CB FF D3 D3 D3 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 00 00 00 FF 6A 6A 6A FF 00 00 00 FF B8 B6'
+ 'B6 FF 5B 58 57 FF EA BC A1 FF E9 B6 99 FF 00 00'
+ '00 00 5F 5F 5F FF D2 D2 D2 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 00 00 00 FF 79 79 79 FF 00 00 00 FF E0 E0'
+ 'E0 FF D9 D1 CC FF F0 CF BC FF EA BB A0 FF 00 00'
+ '00 00 18 18 18 FF DB DB DB FF DE DE DE FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF D9 D9 D9 FF 7A 7A 7A FF 00 00'
+ '00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF E5 E5 E5 FF EB EB EB FF EB EB'
+ 'EB FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
+ 'E5 FF E7 E7 E7 FF E6 E6 E6 FF 20 20 20 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 DD E4 E4 E4 FF C1 C1 C1 FF ED ED'
+ 'ED FF EE EE EE FF EB EB EB FF ED ED ED FF ED ED'
+ 'ED FF C2 C2 C2 FF EC EC EC FF 00 00 00 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 44 80 80 80 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D9 D9 D9 FF B0 B0 B0 FF 00 00 00 ED 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 2C 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 70 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 80'
+ '00 00 FF 80 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 80 07 00 00 80 0F'
+ '00 00 80 0F 00 00 80 0F 00 00 C0 1F 00 00'
+} */
+
+
+/* BINRES drive.ico */
+8 ICON drive.ico
+/* {
+ '00 00 01 00 0C 00 10 10 10 00 01 00 04 00 28 01'
+ '00 00 C6 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 EE 01 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 56 07 00 00 20 20 10 00 01 00 04 00 E8 02'
+ '00 00 BE 0B 00 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 A6 0E 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 4E 17 00 00 30 30 10 00 01 00 04 00 68 06'
+ '00 00 F6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 5E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 06 3D 00 00 40 40 10 00 01 00 04 00 68 0A'
+ '00 00 AE 62 00 00 40 40 00 00 01 00 08 00 28 16'
+ '00 00 16 6D 00 00 40 40 00 00 01 00 20 00 28 42'
+ '00 00 3E 83 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 88'
+ '88 88 88 88 88 77 88 77 77 77 77 77 77 88 77 88'
+ '88 88 88 88 AA 77 88 FF FF FF FF FF FF 88 8F 77'
+ '77 77 77 77 77 F8 87 88 88 88 88 88 88 78 08 78'
+ '88 FF FF 88 87 80 00 87 88 77 77 88 87 80 00 87'
+ '88 88 88 88 78 00 00 08 77 77 77 77 78 00 00 00'
+ '88 88 88 88 80 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01'
+ '00 00 C0 01 00 00 C0 03 00 00 E0 03 00 00 F0 07'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 65 65'
+ '65 00 6E 6E 6E 00 71 71 71 00 78 78 78 00 7A 7A'
+ '7A 00 7B 7B 7B 00 7E 7E 7E 00 3F BE 3F 00 1E DD'
+ '1E 00 FF 00 FF 00 81 81 81 00 84 84 84 00 87 87'
+ '87 00 8A 8A 8A 00 8F 8F 8F 00 92 92 92 00 93 93'
+ '93 00 94 94 94 00 95 95 95 00 96 96 96 00 97 97'
+ '97 00 9B 9B 9B 00 9C 9C 9C 00 9E 9E 9E 00 A0 A0'
+ 'A0 00 A1 A1 A1 00 A2 A2 A2 00 A3 A3 A3 00 A4 A4'
+ 'A4 00 A5 A5 A5 00 A6 A6 A6 00 A7 A7 A7 00 A8 A8'
+ 'A8 00 A9 A9 A9 00 AA AA AA 00 AB AB AB 00 AC AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
+ 'B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B8'
+ 'B8 00 B9 B9 B9 00 BA BA BA 00 BB BB BB 00 BC BC'
+ 'BC 00 BD BD BD 00 BE BE BE 00 BF BF BF 00 C0 C0'
+ 'C0 00 C1 C1 C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C4'
+ 'C4 00 C5 C5 C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8'
+ 'C8 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CF CF'
+ 'CF 00 D0 D0 D0 00 D6 D6 D6 00 D7 D7 D7 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 2F 22 39 35 3A 3C 3B 3A 34 31'
+ '2E 29 25 23 17 2F 48 20 17 1B 1A 1D 1B 18 17 15'
+ '10 0D 0C 0B 0D 25 2F 19 2A 2F 34 2F 2D 25 20 1D'
+ '18 16 11 12 0A 0F 48 0E 07 43 45 45 47 49 48 48'
+ '49 48 4C 4F 3F 33 3E 14 1F 24 28 2C 30 35 38 3A'
+ '3D 40 43 1C 21 4D 3E 21 22 25 28 2E 30 35 3A 3A'
+ '3E 41 41 4B 27 40 00 38 1E 26 2A 2A 07 50 50 4E'
+ '3A 46 41 24 07 00 00 00 37 1F 2B 1E 32 3F 44 21'
+ '27 48 4D 23 41 00 00 00 41 23 2E 32 2D 20 22 2C'
+ '44 4E 29 4A 00 00 00 00 00 45 21 35 39 3E 3F 44'
+ '4B 51 30 41 00 00 00 00 00 00 36 23 35 37 43 43'
+ '46 32 40 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF 00 00 FF FF 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 01 00 00 C0 01 00 00 C0 03'
+ '00 00 E0 03 00 00 F0 07 00 00 FF FF 00 00 FF FF'
+ '00 00 FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 CE CE'
+ 'CE 73 96 96 96 F9 BE BE BE F9 B8 B8 B8 F8 BF BF'
+ 'BF F9 C3 C3 C3 F9 C2 C2 C2 F9 BF BF BF F9 B7 B7'
+ 'B7 F8 B0 B0 B0 F8 AB AB AB F8 A1 A1 A1 F8 9A 9A'
+ '9A F8 97 97 97 FA 6C 6C 6C F9 AC AC AC 54 E9 E9'
+ 'E9 A8 9C 9C 9C FF 8A 8A 8A FF 94 94 94 FF 93 93'
+ '93 FF 96 96 96 FF 94 94 94 FF 8F 8F 8F FF 8A 8A'
+ '8A FF 84 84 84 FF 7E 7E 7E FF 78 78 78 FF 71 71'
+ '71 FF 6E 6E 6E FF 81 81 81 FF AA AA AA 7F 9B 9B'
+ '9B A3 92 92 92 FF A8 A8 A8 FF AD AD AD FF B2 B2'
+ 'B2 FF AD AD AD FF AB AB AB FF A3 A3 A3 FF 9C 9C'
+ '9C FF 96 96 96 FF 8F 8F 8F FF 87 87 87 FF 40 BF'
+ '40 FF 1E DD 1E FF 65 65 65 FF 58 58 58 A8 CF CF'
+ 'CF 92 7A 7A 7A FF C0 C0 C0 FF C1 C1 C1 FF C3 C3'
+ 'C3 FF C3 C3 C3 FF C5 C5 C5 FF C7 C7 C7 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C7 C7 C7 FF C6 C6 C6 FF CA CA'
+ 'CA FF D0 D0 D0 FF BD BD BD FF A5 A5 A5 91 B2 B2'
+ 'B2 4B 81 81 81 FF 9B 9B 9B FF A2 A2 A2 FF A6 A6'
+ 'A6 FF AA AA AA FF AE AE AE FF B3 B3 B3 FF B6 B6'
+ 'B6 FF B8 B8 B8 FF BB BB BB FF BE BE BE FF C1 C1'
+ 'C1 FF 95 95 95 FF 9E 9E 9E FF E7 E7 E7 48 00 00'
+ '00 00 92 92 92 BA A0 A0 A0 FF A3 A3 A3 FF A6 A6'
+ 'A6 FF AC AC AC FF AE AE AE FF B3 B3 B3 FF B8 B8'
+ 'B8 FF B8 B8 B8 FF BC BC BC FF BF BF BF FF BF BF'
+ 'BF FF C9 C9 C9 FF A1 A1 A1 DD 00 00 00 00 00 00'
+ '00 00 99 99 99 4E 97 97 97 FF A4 A4 A4 FF A8 A8'
+ 'A8 FF A8 A8 A8 FF C0 C0 C0 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF CF CF CF FF B8 B8 B8 FF C4 C4 C4 FF BF BF'
+ 'BF FF A2 A2 A2 FF BF BF BF 59 00 00 00 00 00 00'
+ '00 00 00 00 00 00 B2 B2 B2 F8 9B 9B 9B FF A9 A9'
+ 'A9 FF 97 97 97 FF B0 B0 B0 FF BD BD BD FF C2 C2'
+ 'C2 FF 9E 9E 9E FF A5 A5 A5 FF C6 C6 C6 FF CB CB'
+ 'CB FF 9B 9B 9B D7 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 C1 C1 C1 37 A1 A1 A1 FF AC AC'
+ 'AC FF B0 B0 B0 FF AB AB AB FF 9C 9C 9C FF A0 A0'
+ 'A0 FF AA AA AA FF C2 C2 C2 FF CF CF CF FF A7 A7'
+ 'A7 FF D4 D4 D4 61 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 9C 9C 9C 18 C8 C8 C8 90 9E 9E'
+ '9E FF B3 B3 B3 FF B7 B7 B7 FF BC BC BC FF BD BD'
+ 'BD FF C2 C2 C2 FF C9 C9 C9 FF D7 D7 D7 FF AD AD'
+ 'AD F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 CB CB CB 3B B0 B0'
+ 'B0 EC A0 A0 A0 FB B3 B3 B3 FB B5 B5 B5 FC C1 C1'
+ 'C1 F8 C1 C1 C1 F9 C4 C4 C4 F9 AF AF AF F4 BC BC'
+ 'BC 84 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 01 00 00 80 01'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 07 00 00 E0 07'
+ '00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 77 78 88 88 88 88 88 88 88'
+ '88 88 88 87 77 00 08 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 80 08 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 88 80 88 87 88 88 88 88 88 88 88 88'
+ '88 88 88 AA 78 88 77 78 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 77 88 87 77 77 77 77 77 77 77 77'
+ '77 77 77 77 78 88 87 78 8F FF FF FF FF FF FF FF'
+ 'FF FF FF F8 87 78 88 88 F7 77 77 77 77 77 77 77'
+ '77 77 77 7F 88 88 08 8F 78 88 88 88 88 88 88 88'
+ '88 88 88 87 F8 80 08 87 88 88 88 88 88 88 88 88'
+ '88 88 88 88 78 80 00 87 88 88 88 88 88 88 88 88'
+ '88 88 88 88 78 00 00 87 88 88 88 88 8F FF FF F8'
+ '88 88 88 88 78 00 00 08 78 88 88 88 F8 88 88 8F'
+ '88 88 88 87 80 00 00 08 78 88 88 88 88 88 88 88'
+ '88 88 88 87 80 00 00 00 87 88 88 88 78 88 88 87'
+ '88 88 88 78 00 00 00 00 87 88 88 88 87 77 77 78'
+ '88 88 88 78 00 00 00 00 08 78 88 88 88 88 88 88'
+ '88 88 87 80 00 00 00 00 08 78 88 88 88 88 88 88'
+ '88 88 87 80 00 00 00 00 00 87 88 88 88 88 88 88'
+ '88 88 78 00 00 00 00 00 00 87 77 77 77 77 77 77'
+ '77 77 78 00 00 00 00 00 00 08 88 88 88 88 88 88'
+ '88 88 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF C0 00 00 03 80 00'
+ '00 01 80 00 00 01 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 01 80 00'
+ '00 01 C0 00 00 03 C0 00 00 03 E0 00 00 07 E0 00'
+ '00 07 F0 00 00 0F F0 00 00 0F F8 00 00 1F F8 00'
+ '00 1F FC 00 00 3F FC 00 00 3F FE 00 00 7F FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 4D 4D 4D 00 4E 4E 4E 00 56 56'
+ '56 00 5C 5C 5C 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
+ '61 00 63 63 63 00 64 64 64 00 65 65 65 00 66 66'
+ '66 00 68 68 68 00 6A 6A 6A 00 6C 6C 6C 00 6E 6E'
+ '6E 00 6F 6F 6F 00 70 70 70 00 72 72 72 00 73 73'
+ '73 00 74 74 74 00 75 75 75 00 77 77 77 00 79 79'
+ '79 00 7A 7A 7A 00 7B 7B 7B 00 7D 7D 7D 00 7E 7E'
+ '7E 00 1A D9 1A 00 1B DA 1B 00 FF 00 FF 00 80 80'
+ '80 00 81 81 81 00 83 83 83 00 84 84 84 00 85 85'
+ '85 00 86 86 86 00 87 87 87 00 88 88 88 00 89 89'
+ '89 00 8A 8A 8A 00 8B 8B 8B 00 8C 8C 8C 00 8D 8D'
+ '8D 00 8E 8E 8E 00 8F 8F 8F 00 90 90 90 00 91 91'
+ '91 00 92 92 92 00 93 93 93 00 94 94 94 00 95 95'
+ '95 00 96 96 96 00 97 97 97 00 98 98 98 00 99 99'
+ '99 00 9A 9A 9A 00 9B 9B 9B 00 9C 9C 9C 00 9D 9D'
+ '9D 00 9E 9E 9E 00 9F 9F 9F 00 A0 A0 A0 00 A1 A1'
+ 'A1 00 A2 A2 A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5'
+ 'A5 00 A6 A6 A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
+ 'A9 00 AA AA AA 00 AB AB AB 00 AC AC AC 00 AD AD'
+ 'AD 00 AE AE AE 00 AF AF AF 00 B0 B0 B0 00 B1 B1'
+ 'B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5'
+ 'B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B8 B8 00 B9 B9'
+ 'B9 00 BA BA BA 00 BB BB BB 00 BC BC BC 00 BD BD'
+ 'BD 00 BE BE BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9'
+ 'C9 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
+ 'CD 00 CE CE CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D3 D3 D3 00 D4 D4 D4 00 D8 D8 D8 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 49'
+ '3B 40 43 4E 55 54 56 58 59 59 56 55 52 4F 4D 49'
+ '45 42 3E 38 35 32 30 2C 24 1C 18 17 2E 00 00 4E'
+ '4D 52 58 58 58 5B 5E 60 62 62 60 5E 5B 59 54 51'
+ '4E 4A 47 44 3F 3B 37 34 2F 2C 22 20 21 00 00 4F'
+ '4C 57 24 3B 3C 3D 3C 3D 3F 3C 37 32 2F 2C 29 24'
+ '22 1F 1C 19 17 15 12 10 0E 0A 22 1D 1D 00 5E 55'
+ '55 37 5B 53 55 54 57 5A 5B 53 51 4E 49 45 41 3B'
+ '38 34 31 2A 28 22 1F 19 26 25 14 1F 1D 46 4F 38'
+ '38 3E 53 50 53 54 58 59 58 51 4F 4A 46 42 3C 38'
+ '35 32 2E 28 23 20 1E 1A 17 14 0D 0C 0B 29 44 3A'
+ '2E 3C 44 4E 52 55 58 56 57 56 57 55 52 51 4D 4B'
+ '48 45 42 40 3C 36 32 31 2D 23 1C 21 1B 47 4C 4C'
+ '2D 33 42 48 4A 4C 4E 4F 50 51 54 55 57 55 55 56'
+ '57 57 57 55 55 56 58 57 56 65 60 51 37 64 5A 4E'
+ '16 11 30 2D 34 36 37 39 3B 3B 3D 3C 3E 3E 3D 3E'
+ '3E 3E 40 3E 3E 3F 40 42 36 4B 5E 58 52 63 00 4A'
+ '0F 2B 35 4B 4C 4D 4F 51 53 55 57 59 5B 5C 5E 60'
+ '62 63 65 66 07 68 69 6B 62 37 3A 48 5C 00 00 59'
+ '2F 3B 4D 48 4A 4C 4D 50 52 54 56 58 5A 5C 5D 5F'
+ '60 62 63 65 66 07 07 68 6B 76 35 41 5E 00 00 00'
+ '32 40 48 49 4C 4D 50 51 54 56 57 59 58 5A 5C 5F'
+ '62 64 65 66 68 69 6A 6A 6B 6D 31 4C 00 00 00 00'
+ '51 36 3C 4A 4C 4E 50 52 54 57 59 5B 6E 6C 6C 70'
+ '65 63 68 69 69 6A 6C 6C 72 46 42 5E 00 00 00 00'
+ '00 36 46 4D 4D 4F 51 53 56 53 4F 5D 5C 5A 5B 5F'
+ '69 62 62 6B 6B 6D 6E 6E 79 31 4F 00 00 00 00 00'
+ '00 51 41 4A 4E 50 52 54 5A 3E 61 5D 5F 61 63 65'
+ '69 64 46 70 6D 6F 70 74 5C 44 60 00 00 00 00 00'
+ '00 00 48 49 4F 50 53 55 59 4B 50 5D 62 64 07 68'
+ '64 37 59 6F 6F 70 74 78 40 56 00 00 00 00 00 00'
+ '00 00 50 46 52 53 53 56 58 5C 5E 4E 48 44 46 48'
+ '4A 6B 71 6E 70 75 6E 40 55 62 00 00 00 00 00 00'
+ '00 00 00 41 13 4F 56 56 58 5B 5C 60 66 6A 6C 6D'
+ '6C 6B 6D 70 72 66 3E 6F 5F 00 00 00 00 00 00 00'
+ '00 00 00 49 49 4F 55 57 59 5B 5D 5F 61 64 66 69'
+ '6B 6D 6F 72 73 79 61 5E 64 00 00 00 00 00 00 00'
+ '00 00 00 00 51 52 55 57 59 5D 58 69 6C 61 68 69'
+ '6B 6E 70 72 74 7A 59 5C 00 00 00 00 00 00 00 00'
+ '00 00 00 00 65 54 54 57 59 5D 56 59 5A 58 68 6A'
+ '6C 6E 70 73 75 7B 53 65 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 65 69 61 61 63 66 6A 6A 6A 6A 6D'
+ '6F 71 73 77 71 69 62 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 80 00 00 01 80 00 00 01 80 00 00 01 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 01 80 00 00 01 C0 00 00 03 C0 00'
+ '00 03 E0 00 00 07 E0 00 00 07 F0 00 00 0F F0 00'
+ '00 0F F8 00 00 1F F8 00 00 1F FC 00 00 3F FC 00'
+ '00 3F FE 00 00 7F FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 99 99 99 C7 92 92'
+ '92 F4 97 97 97 F4 9A 9A 9A F4 A6 A6 A6 F4 AD AD'
+ 'AD F4 AC AC AC F3 AE AE AE F4 B0 B0 B0 F4 B1 B1'
+ 'B1 F4 B1 B1 B1 F4 AE AE AE F4 AD AD AD F4 AA AA'
+ 'AA F5 A7 A7 A7 F5 A5 A5 A5 F4 A0 A0 A0 F3 9C 9C'
+ '9C F3 99 99 99 F3 95 95 95 F3 8F 8F 8F F3 8C 8C'
+ '8C F3 88 88 88 F3 86 86 86 F4 82 82 82 F3 7B 7B'
+ '7B F4 70 70 70 F7 6A 6A 6A F4 68 68 68 F4 71 71'
+ '71 B8 00 00 00 00 00 00 00 00 A7 A7 A7 FA A6 A6'
+ 'A6 FF AB AB AB FF B1 B1 B1 FF B1 B1 B1 FF B1 B1'
+ 'B1 FF B4 B4 B4 FF B7 B7 B7 FF B9 B9 B9 FF BB BB'
+ 'BB FF BB BB BB FF B9 B9 B9 FF B7 B7 B7 FF B4 B4'
+ 'B4 FF B2 B2 B2 FF AD AD AD FF AA AA AA FF A7 A7'
+ 'A7 FF A3 A3 A3 FF A0 A0 A0 FF 9D 9D 9D FF 98 98'
+ '98 FF 94 94 94 FF 90 90 90 FF 8D 8D 8D FF 88 88'
+ '88 FF 85 85 85 FF 7B 7B 7B FF 79 79 79 FF 78 78'
+ '78 F8 00 00 00 00 AC AC AC 3E A8 A8 A8 FE A5 A5'
+ 'A5 FF B0 B0 B0 FF 7E 7E 7E FF 94 94 94 FF 95 95'
+ '95 FF 96 96 96 FF 95 95 95 FF 96 96 96 FF 98 98'
+ '98 FF 95 95 95 FF 90 90 90 FF 8B 8B 8B FF 88 88'
+ '88 FF 85 85 85 FF 81 81 81 FF 7E 7E 7E FF 7B 7B'
+ '7B FF 77 77 77 FF 73 73 73 FF 6F 6F 6F FF 6C 6C'
+ '6C FF 68 68 68 FF 64 64 64 FF 61 61 61 FF 5D 5D'
+ '5D FF 4D 4D 4D FF 7B 7B 7B FF 74 74 74 FF 74 74'
+ '74 FE 87 87 87 3E AB AB AB 71 AE AE AE FF AE AE'
+ 'AE FF 90 90 90 FF B4 B4 B4 FF AC AC AC FF AE AE'
+ 'AE FF AD AD AD FF B0 B0 B0 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF AC AC AC FF AA AA AA FF A7 A7 A7 FF A2 A2'
+ 'A2 FF 9E 9E 9E FF 9A 9A 9A FF 94 94 94 FF 91 91'
+ '91 FF 8D 8D 8D FF 8A 8A 8A FF 83 83 83 FF 80 80'
+ '80 FF 7B 7B 7B FF 77 77 77 FF 6F 6F 6F FF 1B DA'
+ '1B FF 1B DA 1B FF 66 66 66 FF 77 77 77 FF 74 74'
+ '74 FF 7A 7A 7A 79 9C 9C 9C A8 91 91 91 FF 91 91'
+ '91 FF 97 97 97 FF AC AC AC FF A9 A9 A9 FF AC AC'
+ 'AC FF AD AD AD FF B1 B1 B1 FF B2 B2 B2 FF B1 B1'
+ 'B1 FF AA AA AA FF A8 A8 A8 FF A3 A3 A3 FF 9F 9F'
+ '9F FF 9B 9B 9B FF 95 95 95 FF 91 91 91 FF 8E 8E'
+ '8E FF 8B 8B 8B FF 87 87 87 FF 80 80 80 FF 7D 7D'
+ '7D FF 79 79 79 FF 75 75 75 FF 70 70 70 FF 6C 6C'
+ '6C FF 66 66 66 FF 5C 5C 5C FF 56 56 56 FF 4E 4E'
+ '4E FF 67 67 67 B4 96 96 96 D4 93 93 93 FF 87 87'
+ '87 FF 95 95 95 FF 9D 9D 9D FF A7 A7 A7 FF AB AB'
+ 'AB FF AE AE AE FF B1 B1 B1 FF AF AF AF FF B0 B0'
+ 'B0 FF AF AF AF FF B0 B0 B0 FF AE AE AE FF AB AB'
+ 'AB FF AA AA AA FF A6 A6 A6 FF A4 A4 A4 FF A1 A1'
+ 'A1 FF 9E 9E 9E FF 9B 9B 9B FF 99 99 99 FF 95 95'
+ '95 FF 8F 8F 8F FF 8B 8B 8B FF 8A 8A 8A FF 86 86'
+ '86 FF 7D 7D 7D FF 73 73 73 FF 7A 7A 7A FF 72 72'
+ '72 FF 9C 9C 9C E4 93 93 93 9A A5 A5 A5 FF 86 86'
+ '86 FF 8C 8C 8C FF 9B 9B 9B FF A1 A1 A1 FF A3 A3'
+ 'A3 FF A5 A5 A5 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AA AA AA FF AD AD AD FF AE AE AE FF B0 B0'
+ 'B0 FF AE AE AE FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B0 B0 B0 FF B0 B0 B0 FF AE AE AE FF AE AE'
+ 'AE FF AF AF AF FF B1 B1 B1 FF B0 B0 B0 FF AF AF'
+ 'AF FF BE BE BE FF B9 B9 B9 FF AA AA AA FF 90 90'
+ '90 FF BB BB BB 9F 90 90 90 45 A7 A7 A7 FE 6A 6A'
+ '6A FF 63 63 63 FF 89 89 89 FF 86 86 86 FF 8D 8D'
+ '8D FF 8F 8F 8F FF 90 90 90 FF 92 92 92 FF 94 94'
+ '94 FF 94 94 94 FF 96 96 96 FF 95 95 95 FF 97 97'
+ '97 FF 97 97 97 FF 96 96 96 FF 97 97 97 FF 97 97'
+ '97 FF 97 97 97 FF 99 99 99 FF 97 97 97 FF 97 97'
+ '97 FF 98 98 98 FF 99 99 99 FF 9B 9B 9B FF 8F 8F'
+ '8F FF A4 A4 A4 FF B7 B7 B7 FF B1 B1 B1 FF AB AB'
+ 'AB F9 A8 A8 A8 2F 00 00 00 00 9C 9C 9C CF 5F 5F'
+ '5F FF 84 84 84 FF 8E 8E 8E FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A8 A8 A8 FF AA AA AA FF AC AC'
+ 'AC FF AE AE AE FF B0 B0 B0 FF B2 B2 B2 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B7 B7 B7 FF B9 B9 B9 FF BB BB'
+ 'BB FF BC BC BC FF BE BE BE FF BF BF BF FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C2 C2 C2 FF C4 C4 C4 FF BB BB'
+ 'BB FF 90 90 90 FF 93 93 93 FF A1 A1 A1 FF B0 B0'
+ 'B0 B0 00 00 00 00 00 00 00 00 9D 9D 9D 63 88 88'
+ '88 FF 94 94 94 FF A6 A6 A6 FF A1 A1 A1 FF A3 A3'
+ 'A3 FF A5 A5 A5 FF A6 A6 A6 FF A9 A9 A9 FF AB AB'
+ 'AB FF AD AD AD FF AF AF AF FF B1 B1 B1 FF B3 B3'
+ 'B3 FF B5 B5 B5 FF B6 B6 B6 FF B8 B8 B8 FF B9 B9'
+ 'B9 FF BB BB BB FF BC BC BC FF BE BE BE FF BF BF'
+ 'BF FF C0 C0 C0 FF C0 C0 C0 FF C1 C1 C1 FF C4 C4'
+ 'C4 FF CF CF CF FF 8E 8E 8E FF 99 99 99 F7 91 91'
+ '91 33 00 00 00 00 00 00 00 00 00 00 00 00 85 85'
+ '85 E3 99 99 99 FF A1 A1 A1 FF A2 A2 A2 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A9 A9 A9 FF AA AA AA FF AD AD'
+ 'AD FF AF AF AF FF B0 B0 B0 FF B2 B2 B2 FF B1 B1'
+ 'B1 FF B3 B3 B3 FF B5 B5 B5 FF B8 B8 B8 FF BB BB'
+ 'BB FF BD BD BD FF BE BE BE FF BF BF BF FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C6 C6 C6 FF 8A 8A 8A FF 97 97 97 A5 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 7D 8F 8F 8F FF 95 95 95 FF A3 A3 A3 FF A5 A5'
+ 'A5 FF A7 A7 A7 FF A9 A9 A9 FF AB AB AB FF AD AD'
+ 'AD FF B0 B0 B0 FF B2 B2 B2 FF B4 B4 B4 FF C7 C7'
+ 'C7 FF C5 C5 C5 FF C5 C5 C5 FF C9 C9 C9 FF BE BE'
+ 'BE FF BC BC BC FF C1 C1 C1 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C5 C5 C5 FF C5 C5 C5 FF CB CB'
+ 'CB FF 9F 9F 9F FF 9A 9A 9A F7 8D 8D 8D 2D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 8A 8A'
+ '8A 18 8D 8D 8D F3 9F 9F 9F FF A6 A6 A6 FF A6 A6'
+ 'A6 FF A8 A8 A8 FF AA AA AA FF AC AC AC FF AF AF'
+ 'AF FF AC AC AC FF A8 A8 A8 FF B6 B6 B6 FF B5 B5'
+ 'B5 FF B3 B3 B3 FF B4 B4 B4 FF B8 B8 B8 FF C2 C2'
+ 'C2 FF BB BB BB FF BB BB BB FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C6 C6 C6 FF C7 C7 C7 FF C7 C7 C7 FF D3 D3'
+ 'D3 FF 8A 8A 8A FF 9A 9A 9A A3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 9C 9C 9C 9B 9A 9A 9A FF A3 A3 A3 FF A7 A7'
+ 'A7 FF A9 A9 A9 FF AB AB AB FF AD AD AD FF B3 B3'
+ 'B3 FF 97 97 97 FF BA BA BA FF B6 B6 B6 FF B8 B8'
+ 'B8 FF BA BA BA FF BC BC BC FF BE BE BE FF C2 C2'
+ 'C2 FF BD BD BD FF 9F 9F 9F FF C9 C9 C9 FF C6 C6'
+ 'C6 FF C8 C8 C8 FF C9 C9 C9 FF CD CD CD FF B5 B5'
+ 'B5 FF 9C 9C 9C F7 96 96 96 2C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 9C 9C 9C 27 A0 A0 A0 F8 A2 A2 A2 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF AC AC AC FF AE AE AE FF B2 B2'
+ 'B2 FF A4 A4 A4 FF A9 A9 A9 FF B6 B6 B6 FF BB BB'
+ 'BB FF BD BD BD FF C0 C0 C0 FF C1 C1 C1 FF BD BD'
+ 'BD FF 90 90 90 FF B2 B2 B2 FF C8 C8 C8 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CD CD CD FF D1 D1 D1 FF 99 99'
+ '99 FF A6 A6 A6 A2 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 9D 9D 9D AA 9F 9F 9F FF AB AB'
+ 'AB FF AC AC AC FF AC AC AC FF AF AF AF FF B1 B1'
+ 'B1 FF B5 B5 B5 FF B7 B7 B7 FF A7 A7 A7 FF A1 A1'
+ 'A1 FF 9D 9D 9D FF 9F 9F 9F FF A1 A1 A1 FF A3 A3'
+ 'A3 FF C4 C4 C4 FF CA CA CA FF C7 C7 C7 FF C9 C9'
+ 'C9 FF CE CE CE FF C7 C7 C7 FF 99 99 99 FF AD AD'
+ 'AD F2 A1 A1 A1 26 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A6 A6 A6 37 9A 9A 9A FC 65 65'
+ '65 FF A8 A8 A8 FF AF AF AF FF AF AF AF FF B1 B1'
+ 'B1 FF B4 B4 B4 FF B5 B5 B5 FF B9 B9 B9 FF BF BF'
+ 'BF FF C3 C3 C3 FF C5 C5 C5 FF C6 C6 C6 FF C5 C5'
+ 'C5 FF C4 C4 C4 FF C6 C6 C6 FF C9 C9 C9 FF CB CB'
+ 'CB FF BF BF BF FF 97 97 97 FF C8 C8 C8 FF B2 B2'
+ 'B2 9A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 98 98 98 BF A2 A2'
+ 'A2 FF A8 A8 A8 FF AE AE AE FF B0 B0 B0 FF B2 B2'
+ 'B2 FF B4 B4 B4 FF B6 B6 B6 FF B8 B8 B8 FF BA BA'
+ 'BA FF BD BD BD FF BF BF BF FF C2 C2 C2 FF C4 C4'
+ 'C4 FF C6 C6 C6 FF C8 C8 C8 FF CB CB CB FF CC CC'
+ 'CC FF D3 D3 D3 FF BA BA BA FF B7 B7 B7 F4 AA AA'
+ 'AA 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A7 A7 A7 40 AA AA'
+ 'AA FD AB AB AB FF AE AE AE FF B0 B0 B0 FF B2 B2'
+ 'B2 FF B6 B6 B6 FF B1 B1 B1 FF C2 C2 C2 FF C5 C5'
+ 'C5 FF BA BA BA FF C1 C1 C1 FF C2 C2 C2 FF C4 C4'
+ 'C4 FF C7 C7 C7 FF C9 C9 C9 FF CB CB CB FF CD CD'
+ 'CD FF D4 D4 D4 FF B2 B2 B2 FE AC AC AC 8F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 BD BD'
+ 'BD C6 AD AD AD FE AD AD AD FF B0 B0 B0 FF B2 B2'
+ 'B2 FF B6 B6 B6 FF AF AF AF FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B1 B1 B1 FF C1 C1 C1 FF C3 C3 C3 FF C5 C5'
+ 'C5 FF C7 C7 C7 FF C9 C9 C9 FF CC CC CC FF CE CE'
+ 'CE FF D8 D8 D8 FF AB AB AB F0 AD AD AD 16 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 B6 B6'
+ 'B6 38 BD BD BD BE C3 C3 C3 CD BA BA BA EC BA BA'
+ 'BA F4 BC BC BC F4 BF BF BF F4 C3 C3 C3 F4 C3 C3'
+ 'C3 F2 C3 C3 C3 F2 C3 C3 C3 F2 C6 C6 C6 F4 C8 C8'
+ 'C8 F4 CA CA CA F4 CD CD CD F4 D1 D1 D1 F4 CC CC'
+ 'CC D3 C2 C2 C2 CD B3 B3 B3 65 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 01 80 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 01 80 00'
+ '00 01 C0 00 00 03 C0 00 00 03 C0 00 00 07 E0 00'
+ '00 07 E0 00 00 0F F0 00 00 0F F0 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 3F FC 00 00 7F FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 00 00 77 77 78 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 77 77 77 00 08 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 80 08 88 88 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 88 88 80 08 88'
+ '87 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 8A AA 78 88 80 08 88 87 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 78 88 80 87 77'
+ '78 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 87 77 78 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 87'
+ '77 7F FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 77 77 78 88 88 78 88 F7 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 F8 88 87 88 07 88'
+ '8F 78 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF F8 7F 88 88 70 08 88 F7 8F 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 7F 87 F8 88 80 08 8F'
+ '78 F7 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 87 F8 7F 88 00 00 87 8F 78 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 7F 87 80 00 00 87'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 87 80 00 00 08 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 78 00 00 00 08'
+ '78 88 88 88 88 88 88 88 88 FF FF 88 88 88 88 88'
+ '88 88 88 78 00 00 00 00 87 88 88 88 88 88 88 8F'
+ 'FF 88 88 FF F8 88 88 88 88 88 87 80 00 00 00 00'
+ '87 88 88 88 88 88 88 F8 88 88 88 88 8F 88 88 88'
+ '88 88 87 80 00 00 00 00 08 78 88 88 88 88 8F 88'
+ '88 88 88 88 88 F8 88 88 88 88 78 00 00 00 00 00'
+ '08 78 88 88 88 88 87 88 88 88 88 88 88 78 88 88'
+ '88 88 78 00 00 00 00 00 00 87 88 88 88 88 88 78'
+ '88 88 88 88 87 88 88 88 88 87 80 00 00 00 00 00'
+ '00 87 88 88 88 88 88 87 77 88 88 77 78 88 88 88'
+ '88 87 80 00 00 00 00 00 00 08 77 88 88 88 88 88'
+ '88 77 77 88 88 88 88 88 87 78 00 00 00 00 00 00'
+ '00 08 78 78 88 88 88 88 88 88 88 88 88 88 88 88'
+ '78 78 00 00 00 00 00 00 00 00 87 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 87 80 00 00 00 00 00 00'
+ '00 00 87 88 88 88 88 8F FF 88 88 88 88 88 88 88'
+ '87 80 00 00 00 00 00 00 00 00 08 78 88 88 88 77'
+ '77 78 88 88 88 88 88 88 78 00 00 00 00 00 00 00'
+ '00 00 08 78 88 88 88 88 88 88 88 88 88 88 88 88'
+ '78 00 00 00 00 00 00 00 00 00 00 87 77 77 77 77'
+ '77 77 77 77 77 77 77 77 80 00 00 00 00 00 00 00'
+ '00 00 00 08 88 88 88 88 88 88 88 88 88 88 88 88'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 C0 00'
+ '00 00 00 03 00 00 C0 00 00 00 00 03 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 03 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 00 07 00 00 E0 00 00 00 00 0F 00 00 E0 00'
+ '00 00 00 0F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 3F 00 00 F8 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FC 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 FF 00 00 FE 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF 80'
+ '00 00 03 FF 00 00 FF C0 00 00 07 FF 00 00 FF E0'
+ '00 00 0F FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 4F 4F'
+ '4F 00 52 52 52 00 56 56 56 00 57 57 57 00 58 58'
+ '58 00 59 59 59 00 5A 5A 5A 00 5B 5B 5B 00 5C 5C'
+ '5C 00 5F 5F 5F 00 60 60 60 00 61 61 61 00 62 62'
+ '62 00 64 64 64 00 66 66 66 00 67 67 67 00 68 68'
+ '68 00 6A 6A 6A 00 6B 6B 6B 00 6C 6C 6C 00 6D 6D'
+ '6D 00 6E 6E 6E 00 6F 6F 6F 00 70 70 70 00 71 71'
+ '71 00 72 72 72 00 73 73 73 00 74 74 74 00 75 75'
+ '75 00 76 76 76 00 77 77 77 00 78 78 78 00 79 79'
+ '79 00 7A 7A 7A 00 7B 7B 7B 00 7C 7C 7C 00 7D 7D'
+ '7D 00 7E 7E 7E 00 7F 7F 7F 00 33 B2 33 00 37 B6'
+ '37 00 1A D9 1A 00 FF 00 FF 00 80 80 80 00 81 81'
+ '81 00 82 82 82 00 83 83 83 00 84 84 84 00 85 85'
+ '85 00 86 86 86 00 87 87 87 00 88 88 88 00 89 89'
+ '89 00 8A 8A 8A 00 8B 8B 8B 00 8C 8C 8C 00 8D 8D'
+ '8D 00 8E 8E 8E 00 8F 8F 8F 00 90 90 90 00 91 91'
+ '91 00 92 92 92 00 93 93 93 00 94 94 94 00 95 95'
+ '95 00 96 96 96 00 97 97 97 00 98 98 98 00 99 99'
+ '99 00 9A 9A 9A 00 9B 9B 9B 00 9C 9C 9C 00 9D 9D'
+ '9D 00 9E 9E 9E 00 9F 9F 9F 00 A0 A0 A0 00 A1 A1'
+ 'A1 00 A2 A2 A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5'
+ 'A5 00 A6 A6 A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
+ 'A9 00 AA AA AA 00 AB AB AB 00 AC AC AC 00 AD AD'
+ 'AD 00 AE AE AE 00 AF AF AF 00 B0 B0 B0 00 B1 B1'
+ 'B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5'
+ 'B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B8 B8 00 B9 B9'
+ 'B9 00 BA BA BA 00 BB BB BB 00 BC BC BC 00 BD BD'
+ 'BD 00 BE BE BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9'
+ 'C9 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
+ 'CD 00 CE CE CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D5 D5 D5 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 FB'
+ 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 65 59 5A 5D 5D 59 64 67'
+ '68 69 6B 6C 6E 6E 70 6F 6C 6B 69 67 64 63 61 5F'
+ '5B 59 57 53 51 4E 4B 49 46 42 41 3C 3A 38 2F 2C'
+ '2B 2B 2B 30 00 00 00 00 4F 4E 4F 52 54 5B 5E 60'
+ '61 63 64 66 66 68 69 67 65 64 62 60 5E 5D 5A 58'
+ '56 54 52 4F 4D 4A 47 44 42 3F 3D 3B 37 30 26 23'
+ '21 1E 1D 1D 00 00 00 69 59 59 5A 5C 5F 60 61 62'
+ '64 65 66 68 6A 6A 6B 6A 69 68 65 63 62 60 5C 5A'
+ '58 57 53 51 50 4E 4B 48 46 43 40 3E 3B 39 36 2D'
+ '28 28 26 26 51 00 00 68 5A 5B 5C 61 35 47 49 49'
+ '4A 4A 4A 4B 4B 4B 4B 49 46 43 40 3F 3C 3A 38 35'
+ '2F 2D 2B 29 27 25 22 20 1E 1B 1A 18 17 15 13 0B'
+ '2C 27 25 25 3F 00 00 60 5B 5C 5D 4E 57 60 61 62'
+ '63 62 63 66 66 68 67 62 5F 5D 5B 57 54 53 50 4C'
+ '4A 47 44 41 3F 3C 39 37 2F 2C 2A 26 22 32 33 31'
+ '19 26 24 22 28 00 00 64 61 61 63 42 63 61 62 63'
+ '62 64 65 67 68 69 65 62 60 5E 5C 59 55 52 50 4C'
+ '4A 46 44 42 3F 3B 39 35 2F 2C 29 25 21 1E 1B 1B'
+ '14 28 25 22 1E 00 64 41 40 41 41 50 5E 5D 5F 61'
+ '61 62 65 66 67 66 62 5F 5E 5C 59 56 54 50 4E 49'
+ '48 45 43 42 3E 3B 37 35 2E 2B 28 25 22 1E 1C 19'
+ '14 0F 0E 0C 0D 49 69 57 59 57 56 57 59 59 5A 5B'
+ '5C 5E 5F 60 61 60 5D 5A 58 56 53 50 4E 4B 48 45'
+ '43 41 3D 3C 39 35 2F 2C 2A 27 25 24 22 1F 1B 19'
+ '18 16 13 10 11 37 4C 27 45 2C 48 48 4D 5A 5E 63'
+ '66 66 69 68 68 6A 6B 6A 6C 6E 6D 6C 6B 6A 68 68'
+ '67 66 65 64 62 60 61 5F 5B 58 57 54 54 53 4F 49'
+ '44 44 48 40 4E 5B 64 43 4B 29 50 50 50 44 40 40'
+ '42 43 44 44 46 48 49 49 4B 4C 4D 4F 4D 4D 4D 4D'
+ '4D 4D 4E 4E 4D 4C 4C 4D 4E 4D 4D 4E 4D 50 55 6E'
+ '7D 53 5D 39 41 69 00 6C 5B 53 2E 0A 43 5A 5E 62'
+ '66 68 6B 6B 6C 6E 6F 71 72 71 72 73 73 74 74 73'
+ '73 71 70 6E 6D 6C 69 67 67 6A 6D 6C 6A 69 6B 88'
+ '52 78 61 6D 6B 00 00 57 49 12 12 49 39 2D 4F 52'
+ '53 54 54 55 56 57 57 58 59 5A 5A 5C 5D 5D 5C 5C'
+ '5D 5D 5E 5E 5F 5F 5E 60 5F 5F 60 5F 62 46 5A 41'
+ '72 63 61 53 5E 00 00 65 42 0F 4F 25 3F 54 57 58'
+ '59 5B 5C 5D 5F 5F 61 62 64 64 66 67 68 69 6A 6B'
+ '6C 6D 6E 6F 71 71 72 73 74 74 07 07 76 79 52 49'
+ '50 55 4F 57 00 00 00 00 4F 21 54 48 54 56 57 59'
+ '5A 5B 5D 5E 5F 61 62 63 64 65 67 68 69 6A 6B 6C'
+ '6D 6E 6F 70 71 73 73 74 07 76 76 77 77 78 79 6D'
+ '43 4A 46 5F 00 00 00 00 60 2A 54 42 56 57 58 59'
+ '5B 5C 5D 5F 60 61 62 64 65 66 68 69 6A 6C 6C 6D'
+ '6E 70 71 72 73 74 74 76 76 77 78 78 79 79 79 7C'
+ '4F 46 51 00 00 00 00 00 00 4B 2F 48 56 57 59 5A'
+ '5B 5D 5E 60 61 62 64 65 66 68 68 6A 6B 6C 6D 6E'
+ '70 71 72 73 74 07 76 77 78 78 79 7A 7A 7B 7B 6F'
+ '44 4A 62 00 00 00 00 00 00 5D 2C 56 47 58 59 5B'
+ '5C 5D 5F 60 62 63 64 66 67 68 69 69 67 68 69 6A'
+ '6F 72 73 74 07 76 77 78 79 7A 7A 7B 7C 7C 7E 53'
+ '46 54 00 00 00 00 00 00 00 00 51 3E 49 59 5A 5B'
+ '5D 5E 60 61 62 64 65 66 67 68 74 83 88 86 86 84'
+ '86 89 72 73 77 77 79 79 7A 7B 7C 7C 7D 7E 7A 41'
+ '4D 62 00 00 00 00 00 00 00 00 62 35 53 57 5A 5C'
+ '5D 5F 60 62 63 64 66 61 5A 68 67 6B 6E 70 71 72'
+ '6E 68 7D 6F 6E 79 79 7A 7C 7C 7D 7E 7E 80 62 46'
+ '55 00 00 00 00 00 00 00 00 00 00 46 4D 51 5B 5C'
+ '5E 5F 61 62 64 65 64 50 68 6B 6C 6D 6F 70 71 73'
+ '73 07 77 67 59 79 7A 7B 7C 7D 7F 7F 80 81 4B 51'
+ '66 00 00 00 00 00 00 00 00 00 00 5F 47 54 5B 5D'
+ '5E 60 61 63 64 66 5F 56 6C 6B 6D 6E 6F 71 72 73'
+ '74 76 78 6A 49 7D 7B 7D 7E 7F 80 81 81 6B 4E 58'
+ '00 00 00 00 00 00 00 00 00 00 00 00 4E 54 56 5D'
+ '5F 60 62 63 65 66 69 5A 58 67 6E 6F 70 71 73 07'
+ '77 07 65 3A 65 7C 7D 7E 7F 80 81 82 7E 4F 56 67'
+ '00 00 00 00 00 00 00 00 00 00 00 00 5D 50 59 5C'
+ '5F 61 62 64 65 67 68 69 6C 61 54 51 5B 5F 5E 56'
+ '4A 49 53 7B 7C 7C 7E 7F 80 81 83 78 59 54 58 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 45 50 56'
+ '60 60 63 64 66 67 68 6A 6B 6D 70 73 68 65 67 73'
+ '7C 7C 7A 7B 7C 7E 7F 80 81 82 68 59 56 58 6D 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 5F 42 24'
+ '38 52 63 64 66 67 69 6A 6C 6D 6F 70 72 73 07 76'
+ '78 79 7A 7C 7D 7E 7F 81 83 65 56 82 68 5A 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 50'
+ '43 60 63 65 66 68 69 6B 6C 6E 6F 71 72 74 07 77'
+ '78 79 7B 7C 7E 7F 81 82 83 83 71 62 63 6D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 54'
+ '5F 62 63 65 66 68 69 6B 6D 6E 72 72 72 74 76 77'
+ '79 7A 7B 7D 7E 80 80 83 84 85 83 53 66 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 57'
+ '60 62 64 65 67 68 6A 6A 63 72 76 77 72 71 76 77'
+ '79 7A 7C 7D 7F 80 82 83 85 86 6D 60 70 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63'
+ '5F 62 64 65 67 68 6A 6B 63 67 69 69 60 6C 76 78'
+ '79 7B 7C 7E 7F 81 82 84 85 88 5D 6C 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '61 65 63 65 67 68 6A 6C 6D 70 71 73 74 07 76 78'
+ '79 7B 7C 7E 7F 81 82 84 87 77 65 73 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '67 6D 70 6C 6A 6C 6D 6E 6F 71 72 74 07 76 78 79'
+ '7C 7C 7D 7E 80 81 83 83 7A 6A 72 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 C0 00 00 00 00 03 00 00 C0 00'
+ '00 00 00 03 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 03 00 00 C0 00'
+ '00 00 00 03 00 00 C0 00 00 00 00 07 00 00 E0 00'
+ '00 00 00 07 00 00 E0 00 00 00 00 0F 00 00 F0 00'
+ '00 00 00 0F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 FF 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
+ '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF C0'
+ '00 00 03 FF 00 00 FF C0 00 00 07 FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 80 25 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 A0 A0 A0 3E B0 B0 B0 FC A4 A4 A4 FC A5 A5'
+ 'A5 FC A8 A8 A8 FC A8 A8 A8 FC A4 A4 A4 FC AF AF'
+ 'AF FC B2 B2 B2 FC B3 B3 B3 FC B4 B4 B4 FC B6 B6'
+ 'B6 FC B7 B7 B7 FC B9 B9 B9 FC B9 B9 B9 FC BB BB'
+ 'BB FC BA BA BA FC B7 B7 B7 FC B6 B6 B6 FC B4 B4'
+ 'B4 FC B2 B2 B2 FC AF AF AF FC AE AE AE FC AC AC'
+ 'AC FC AA AA AA FC A6 A6 A6 FC A4 A4 A4 FC A2 A2'
+ 'A2 FC 9E 9E 9E FC 9C 9C 9C FC 99 99 99 FC 95 95'
+ '95 FC 93 93 93 FC 90 90 90 FC 8C 8C 8C FC 8B 8B'
+ '8B FC 86 86 86 FC 84 84 84 FC 82 82 82 FC 7D 7D'
+ '7D FC 7A 7A 7A FC 79 79 79 FC 79 79 79 FC 79 79'
+ '79 FC 74 74 74 DB 8D 8D 8D 1B 00 00 00 00 00 00'
+ '00 00 A4 A4 A4 65 9A 9A 9A FF 99 99 99 FF 9A 9A'
+ '9A FF 9D 9D 9D FF 9F 9F 9F FF A6 A6 A6 FF A9 A9'
+ 'A9 FF AB AB AB FF AC AC AC FF AE AE AE FF AF AF'
+ 'AF FF B1 B1 B1 FF B1 B1 B1 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B2 B2 B2 FF B0 B0 B0 FF AF AF AF FF AD AD'
+ 'AD FF AB AB AB FF A9 A9 A9 FF A8 A8 A8 FF A5 A5'
+ 'A5 FF A3 A3 A3 FF A1 A1 A1 FF 9F 9F 9F FF 9D 9D'
+ '9D FF 9A 9A 9A FF 98 98 98 FF 95 95 95 FF 92 92'
+ '92 FF 8F 8F 8F FF 8D 8D 8D FF 8A 8A 8A FF 88 88'
+ '88 FF 86 86 86 FF 82 82 82 FF 7F 7F 7F FF 75 75'
+ '75 FF 72 72 72 FF 70 70 70 FF 6D 6D 6D FF 6C 6C'
+ '6C FF 6C 6C 6C FF 7F 7F 7F 5A 00 00 00 00 00 00'
+ '00 00 AC AC AC 98 A4 A4 A4 FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A7 A7 A7 FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B3 B3 B3 FF B5 B5 B5 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B5 B5 B5 FF B4 B4 B4 FF B3 B3 B3 FF B0 B0'
+ 'B0 FF AE AE AE FF AD AD AD FF AB AB AB FF A7 A7'
+ 'A7 FF A5 A5 A5 FF A3 A3 A3 FF A2 A2 A2 FF 9E 9E'
+ '9E FF 9C 9C 9C FF 9B 9B 9B FF 99 99 99 FF 96 96'
+ '96 FF 93 93 93 FF 91 91 91 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 89 89 89 FF 86 86 86 FF 84 84 84 FF 81 81'
+ '81 FF 7C 7C 7C FF 77 77 77 FF 77 77 77 FF 75 75'
+ '75 FF 75 75 75 FF 83 83 83 95 00 00 00 00 00 00'
+ '00 00 B0 B0 B0 CF A5 A5 A5 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF AC AC AC FF 80 80 80 FF 92 92 92 FF 94 94'
+ '94 FF 94 94 94 FF 95 95 95 FF 95 95 95 FF 95 95'
+ '95 FF 96 96 96 FF 96 96 96 FF 96 96 96 FF 96 96'
+ '96 FF 94 94 94 FF 91 91 91 FF 8E 8E 8E FF 8B 8B'
+ '8B FF 8A 8A 8A FF 87 87 87 FF 85 85 85 FF 83 83'
+ '83 FF 80 80 80 FF 7E 7E 7E FF 7C 7C 7C FF 7A 7A'
+ '7A FF 78 78 78 FF 76 76 76 FF 74 74 74 FF 71 71'
+ '71 FF 6F 6F 6F FF 6D 6D 6D FF 6A 6A 6A FF 68 68'
+ '68 FF 66 66 66 FF 64 64 64 FF 61 61 61 FF 5F 5F'
+ '5F FF 52 52 52 FF 7B 7B 7B FF 76 76 76 FF 74 74'
+ '74 FF 74 74 74 FF 7E 7E 7E D0 00 00 00 00 00 00'
+ '00 00 AB AB AB FA A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF 99 99 99 FF A2 A2 A2 FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AD AD AD FF AE AE'
+ 'AE FF B1 B1 B1 FF B1 B1 B1 FF B3 B3 B3 FF B2 B2'
+ 'B2 FF AD AD AD FF AA AA AA FF A8 A8 A8 FF A6 A6'
+ 'A6 FF A2 A2 A2 FF 9F 9F 9F FF 9E 9E 9E FF 9B 9B'
+ '9B FF 97 97 97 FF 95 95 95 FF 92 92 92 FF 8F 8F'
+ '8F FF 8C 8C 8C FF 8A 8A 8A FF 87 87 87 FF 84 84'
+ '84 FF 82 82 82 FF 7E 7E 7E FF 7B 7B 7B FF 79 79'
+ '79 FF 75 75 75 FF 71 71 71 FF 37 B6 37 FF 1B DA'
+ '1B FF 34 B3 34 FF 67 67 67 FF 75 75 75 FF 73 73'
+ '73 FF 71 71 71 FF 76 76 76 FC 00 00 00 00 B9 B9'
+ 'B9 3B AF AF AF FF AC AC AC FF AC AC AC FF AE AE'
+ 'AE FF 8D 8D 8D FF AE AE AE FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AD AD AD FF AF AF AF FF B0 B0'
+ 'B0 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B0 B0'
+ 'B0 FF AD AD AD FF AB AB AB FF A9 A9 A9 FF A7 A7'
+ 'A7 FF A4 A4 A4 FF A0 A0 A0 FF 9D 9D 9D FF 9B 9B'
+ '9B FF 97 97 97 FF 95 95 95 FF 91 91 91 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8A 8A 8A FF 86 86 86 FF 84 84'
+ '84 FF 80 80 80 FF 7E 7E 7E FF 7B 7B 7B FF 78 78'
+ '78 FF 74 74 74 FF 70 70 70 FF 6D 6D 6D FF 6A 6A'
+ '6A FF 6A 6A 6A FF 60 60 60 FF 77 77 77 FF 74 74'
+ '74 FF 71 71 71 FF 6D 6D 6D FF 8A 8A 8A 48 9A 9A'
+ '9A 72 8C 8C 8C FF 8B 8B 8B FF 8C 8C 8C FF 8C 8C'
+ '8C FF 9B 9B 9B FF A9 A9 A9 FF A8 A8 A8 FF AA AA'
+ 'AA FF AC AC AC FF AC AC AC FF AD AD AD FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B1 B1 B1 FF AD AD'
+ 'AD FF AA AA AA FF A9 A9 A9 FF A7 A7 A7 FF A4 A4'
+ 'A4 FF A1 A1 A1 FF 9F 9F 9F FF 9B 9B 9B FF 99 99'
+ '99 FF 94 94 94 FF 93 93 93 FF 90 90 90 FF 8E 8E'
+ '8E FF 8D 8D 8D FF 89 89 89 FF 86 86 86 FF 82 82'
+ '82 FF 80 80 80 FF 7D 7D 7D FF 7A 7A 7A FF 77 77'
+ '77 FF 74 74 74 FF 71 71 71 FF 6D 6D 6D FF 6B 6B'
+ '6B FF 67 67 67 FF 60 60 60 FF 59 59 59 FF 58 58'
+ '58 FF 56 56 56 FF 57 57 57 FF 6B 6B 6B 83 AE AE'
+ 'AE A7 A2 A2 A2 FF A4 A4 A4 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A2 A2 A2 FF A4 A4 A4 FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A7 A7 A7 FF A9 A9 A9 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AB AB AB FF A8 A8'
+ 'A8 FF A5 A5 A5 FF A3 A3 A3 FF A1 A1 A1 FF 9E 9E'
+ '9E FF 9B 9B 9B FF 99 99 99 FF 96 96 96 FF 93 93'
+ '93 FF 90 90 90 FF 8E 8E 8E FF 8C 8C 8C FF 88 88'
+ '88 FF 87 87 87 FF 84 84 84 FF 80 80 80 FF 7E 7E'
+ '7E FF 7B 7B 7B FF 79 79 79 FF 76 76 76 FF 74 74'
+ '74 FF 73 73 73 FF 71 71 71 FF 6E 6E 6E FF 6A 6A'
+ '6A FF 67 67 67 FF 66 66 66 FF 62 62 62 FF 5F 5F'
+ '5F FF 5A 5A 5A FF 5B 5B 5B FF 6D 6D 6D BF 8D 8D'
+ '8D CF 76 76 76 FF 90 90 90 FF 7B 7B 7B FF 93 93'
+ '93 FF 93 93 93 FF 98 98 98 FF A5 A5 A5 FF A9 A9'
+ 'A9 FF AE AE AE FF B1 B1 B1 FF B1 B1 B1 FF B4 B4'
+ 'B4 FF B3 B3 B3 FF B3 B3 B3 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B5 B5 B5 FF B7 B7 B7 FF B9 B9 B9 FF B8 B8'
+ 'B8 FF B7 B7 B7 FF B6 B6 B6 FF B5 B5 B5 FF B3 B3'
+ 'B3 FF B3 B3 B3 FF B2 B2 B2 FF B1 B1 B1 FF B0 B0'
+ 'B0 FF AF AF AF FF AD AD AD FF AB AB AB FF AC AC'
+ 'AC FF AA AA AA FF A6 A6 A6 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF 9F 9F 9F FF 9F 9F 9F FF 9E 9E 9E FF 9A 9A'
+ '9A FF 94 94 94 FF 8F 8F 8F FF 8F 8F 8F FF 93 93'
+ '93 FF 8B 8B 8B FF 99 99 99 FF A1 A1 A1 D2 98 98'
+ '98 6B 8E 8E 8E FF 96 96 96 FF 78 78 78 FF 9B 9B'
+ '9B FF 9B 9B 9B FF 9B 9B 9B FF 8F 8F 8F FF 8B 8B'
+ '8B FF 8B 8B 8B FF 8D 8D 8D FF 8E 8E 8E FF 8F 8F'
+ '8F FF 8F 8F 8F FF 91 91 91 FF 93 93 93 FF 94 94'
+ '94 FF 94 94 94 FF 96 96 96 FF 97 97 97 FF 98 98'
+ '98 FF 9A 9A 9A FF 98 98 98 FF 98 98 98 FF 98 98'
+ '98 FF 98 98 98 FF 98 98 98 FF 98 98 98 FF 99 99'
+ '99 FF 99 99 99 FF 98 98 98 FF 97 97 97 FF 97 97'
+ '97 FF 98 98 98 FF 99 99 99 FF 98 98 98 FF 98 98'
+ '98 FF 99 99 99 FF 98 98 98 FF 9B 9B 9B FF A0 A0'
+ 'A0 FF B9 B9 B9 FF C8 C8 C8 FF 9E 9E 9E FF A8 A8'
+ 'A8 FF 84 84 84 FF 8C 8C 8C FF A3 A3 A3 6D 7F 7F'
+ '7F 3A B7 B7 B7 FF A6 A6 A6 FF 9E 9E 9E FF 7D 7D'
+ '7D FF 4F 4F 4F FF 8E 8E 8E FF A5 A5 A5 FF A9 A9'
+ 'A9 FF AD AD AD FF B1 B1 B1 FF B3 B3 B3 FF B6 B6'
+ 'B6 FF B6 B6 B6 FF B7 B7 B7 FF B9 B9 B9 FF BA BA'
+ 'BA FF BC BC BC FF BD BD BD FF BC BC BC FF BD BD'
+ 'BD FF BE BE BE FF BE BE BE FF BF BF BF FF BF BF'
+ 'BF FF BE BE BE FF BE BE BE FF BC BC BC FF BB BB'
+ 'BB FF B9 B9 B9 FF B8 B8 B8 FF B7 B7 B7 FF B4 B4'
+ 'B4 FF B2 B2 B2 FF B2 B2 B2 FF B5 B5 B5 FF B8 B8'
+ 'B8 FF B7 B7 B7 FF B5 B5 B5 FF B4 B4 B4 FF B6 B6'
+ 'B6 FF D3 D3 D3 FF 9D 9D 9D FF C3 C3 C3 FF AC AC'
+ 'AC FF B8 B8 B8 FF B5 B5 B5 F3 CE CE CE 15 00 00'
+ '00 00 98 98 98 C2 94 94 94 FF 5C 5C 5C FF 5C 5C'
+ '5C FF 94 94 94 FF 84 84 84 FF 7C 7C 7C FF 9A 9A'
+ '9A FF 9D 9D 9D FF 9E 9E 9E FF 9F 9F 9F FF 9F 9F'
+ '9F FF A0 A0 A0 FF A1 A1 A1 FF A2 A2 A2 FF A2 A2'
+ 'A2 FF A3 A3 A3 FF A4 A4 A4 FF A5 A5 A5 FF A5 A5'
+ 'A5 FF A7 A7 A7 FF A8 A8 A8 FF A8 A8 A8 FF A7 A7'
+ 'A7 FF A7 A7 A7 FF A8 A8 A8 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF A9 A9 A9 FF AA AA AA FF AA AA AA FF A9 A9'
+ 'A9 FF AB AB AB FF AA AA AA FF AA AA AA FF AB AB'
+ 'AB FF AA AA AA FF AD AD AD FF 91 91 91 FF A5 A5'
+ 'A5 FF 8C 8C 8C FF BD BD BD FF AE AE AE FF AC AC'
+ 'AC FF 9E 9E 9E FF 95 95 95 87 00 00 00 00 00 00'
+ '00 00 86 86 86 48 8D 8D 8D FF 59 59 59 FF 9A 9A'
+ '9A FF 74 74 74 FF 8A 8A 8A FF 9F 9F 9F FF A2 A2'
+ 'A2 FF A3 A3 A3 FF A4 A4 A4 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF A8 A8 A8 FF AA AA AA FF AA AA AA FF AC AC'
+ 'AC FF AD AD AD FF AF AF AF FF AF AF AF FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9'
+ 'B9 FF BA BA BA FF BC BC BC FF BC BC BC FF BD BD'
+ 'BD FF BE BE BE FF BF BF BF FF BF BF BF FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C1 C1 C1 FF C4 C4 C4 FF 9D 9D'
+ '9D FF 94 94 94 FF 9B 9B 9B FF A0 A0 A0 FF 9A 9A'
+ '9A FF A0 A0 A0 F2 7F 7F 7F 12 00 00 00 00 00 00'
+ '00 00 00 00 00 00 92 92 92 D1 70 70 70 FF 9F 9F'
+ '9F FF 93 93 93 FF 9F 9F 9F FF A1 A1 A1 FF A2 A2'
+ 'A2 FF A4 A4 A4 FF A5 A5 A5 FF A6 A6 A6 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF AA AA AA FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B2 B2'
+ 'B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9 B9 FF BA BA'
+ 'BA FF BB BB BB FF BC BC BC FF BE BE BE FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF B8 B8 B8 FF 8E 8E 8E FF 95 95 95 FF 91 91'
+ '91 FF 95 95 95 82 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 83 83 83 59 79 79 79 FF 9F 9F'
+ '9F FF 8D 8D 8D FF A1 A1 A1 FF A2 A2 A2 FF A3 A3'
+ 'A3 FF A4 A4 A4 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF AA AA AA FF AB AB AB FF AC AC AC FF AD AD'
+ 'AD FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B5 B5 B5 FF B7 B7 B7 FF B7 B7'
+ 'B7 FF B8 B8 B8 FF B9 B9 B9 FF BB BB BB FF BC BC'
+ 'BC FF BD BD BD FF BE BE BE FF BF BF BF FF BF BF'
+ 'BF FF C1 C1 C1 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C7 C7 C7 FF 9A 9A 9A FF 91 91 91 FF 9A 9A'
+ '9A EF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 90 90 90 E0 7E 7E'
+ '7E FF 93 93 93 FF A1 A1 A1 FF A2 A2 A2 FF A4 A4'
+ 'A4 FF A5 A5 A5 FF A6 A6 A6 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AB AB AB FF AC AC AC FF AD AD AD FF AF AF'
+ 'AF FF B0 B0 B0 FF B1 B1 B1 FF B3 B3 B3 FF B3 B3'
+ 'B3 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8'
+ 'B8 FF B9 B9 B9 FF BB BB BB FF BC BC BC FF BD BD'
+ 'BD FF BE BE BE FF BF BF BF FF C0 C0 C0 FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF BA BA BA FF 8F 8F 8F FF 95 95 95 FF 99 99'
+ '99 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 8A 8A 8A 70 7B 7B'
+ '7B FF A1 A1 A1 FF 92 92 92 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8 A8 FF AA AA'
+ 'AA FF AB AB AB FF AD AD AD FF AE AE AE FF AF AF'
+ 'AF FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B4 B4 B4 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF BA BA BA FF BD BD BD FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C4 C4 C4 FF C5 C5 C5 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C7 C7 C7 FF C7 C7 C7 FF C9 C9'
+ 'C9 FF 9E 9E 9E FF 91 91 91 FF 9C 9C 9C EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B F7 89 89 89 FF 94 94 94 FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A8 A8 A8 FF A9 A9 A9 FF AB AB'
+ 'AB FF AC AC AC FF AD AD AD FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF BF BF'
+ 'BF FF CE CE CE FF D3 D3 D3 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF CF CF CF FF D1 D1 D1 FF D5 D5 D5 FF BD BD'
+ 'BD FF BE BE BE FF C2 C2 C2 FF C2 C2 C2 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9 C9 FF C5 C5'
+ 'C5 FF 8C 8C 8C FF 98 98 98 FF 97 97 97 74 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 9B'
+ '9B 85 80 80 80 FF 9E 9E 9E FF A2 A2 A2 FF A5 A5'
+ 'A5 FF A7 A7 A7 FF A8 A8 A8 FF AA AA AA FF AB AB'
+ 'AB FF AD AD AD FF AE AE AE FF AF AF AF FF B1 B1'
+ 'B1 FF AC AC AC FF A5 A5 A5 FF B3 B3 B3 FF B2 B2'
+ 'B2 FF B6 B6 B6 FF B9 B9 B9 FF BB BB BB FF BC BC'
+ 'BC FF BD BD BD FF B9 B9 B9 FF B3 B3 B3 FF C8 C8'
+ 'C8 FF BA BA BA FF B9 B9 B9 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C7 C7 C7 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF C9 C9 C9 FF CB CB CB FF AD AD'
+ 'AD FF 91 91 91 FF 9D 9D 9D E7 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 94'
+ '94 18 8F 8F 8F F7 98 98 98 FF 9C 9C 9C FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A9 A9 A9 FF AA AA AA FF AC AC'
+ 'AC FF AD AD AD FF AF AF AF FF B0 B0 B0 FF AF AF'
+ 'AF FF 9B 9B 9B FF B3 B3 B3 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF B8 B8 B8 FF BA BA BA FF BB BB BB FF BC BC'
+ 'BC FF BE BE BE FF BE BE BE FF C0 C0 C0 FF C2 C2'
+ 'C2 FF B2 B2 B2 FF A4 A4 A4 FF C4 C4 C4 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8 C8 FF CA CA'
+ 'CA FF CA CA CA FF CB CB CB FF CC CC CC FF 96 96'
+ '96 FF 9C 9C 9C FF 9E 9E 9E 6F 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 9B 9B 9B 9A 92 92 92 FF 9F 9F 9F FF A6 A6'
+ 'A6 FF A8 A8 A8 FF A9 A9 A9 FF AB AB AB FF AC AC'
+ 'AC FF AE AE AE FF AF AF AF FF B1 B1 B1 FF AA AA'
+ 'AA FF A1 A1 A1 FF B7 B7 B7 FF B6 B6 B6 FF B8 B8'
+ 'B8 FF B9 B9 B9 FF BA BA BA FF BC BC BC FF BD BD'
+ 'BD FF BE BE BE FF BF BF BF FF C1 C1 C1 FF C3 C3'
+ 'C3 FF B5 B5 B5 FF 94 94 94 FF C8 C8 C8 FF C6 C6'
+ 'C6 FF C8 C8 C8 FF C9 C9 C9 FF CA CA CA FF CB CB'
+ 'CB FF CC CC CC FF CC CC CC FF B6 B6 B6 FF 99 99'
+ '99 FF 9F 9F 9F E3 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 99 99 99 28 99 99 99 FD 9F 9F 9F FF A1 A1'
+ 'A1 FF A8 A8 A8 FF AA AA AA FF AB AB AB FF AD AD'
+ 'AD FF AE AE AE FF B0 B0 B0 FF B1 B1 B1 FF B4 B4'
+ 'B4 FF A5 A5 A5 FF A3 A3 A3 FF B2 B2 B2 FF B9 B9'
+ 'B9 FF BA BA BA FF BB BB BB FF BC BC BC FF BE BE'
+ 'BE FF C0 C0 C0 FF C2 C2 C2 FF C0 C0 C0 FF B0 B0'
+ 'B0 FF 85 85 85 FF B0 B0 B0 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CB CB CB FF CC CC'
+ 'CC FF CD CD CD FF C9 C9 C9 FF 9A 9A 9A FF A1 A1'
+ 'A1 FF 9D 9D 9D 69 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 9D 9D 9D B0 9B 9B 9B FF A4 A4'
+ 'A4 FF A7 A7 A7 FF AA AA AA FF AC AC AC FF AD AD'
+ 'AD FF AF AF AF FF B0 B0 B0 FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B7 B7 B7 FF AC AC AC FF 9F 9F'
+ '9F FF 9C 9C 9C FF A6 A6 A6 FF AA AA AA FF A9 A9'
+ 'A9 FF A1 A1 A1 FF 95 95 95 FF 94 94 94 FF 9E 9E'
+ '9E FF C6 C6 C6 FF C7 C7 C7 FF C7 C7 C7 FF C9 C9'
+ 'C9 FF CA CA CA FF CB CB CB FF CC CC CC FF CE CE'
+ 'CE FF C3 C3 C3 FF A4 A4 A4 FF 9F 9F 9F FF 9E 9E'
+ '9E DB 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A6 A6 A6 1A 90 90 90 FE 9B 9B'
+ '9B FF A1 A1 A1 FF AB AB AB FF AB AB AB FF AE AE'
+ 'AE FF AF AF AF FF B1 B1 B1 FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B5 B5 B5 FF B6 B6 B6 FF B8 B8 B8 FF BB BB'
+ 'BB FF BE BE BE FF B3 B3 B3 FF B0 B0 B0 FF B2 B2'
+ 'B2 FF BE BE BE FF C7 C7 C7 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C7 C7 C7 FF C9 C9 C9 FF CA CA'
+ 'CA FF CB CB CB FF CC CC CC FF CD CD CD FF B3 B3'
+ 'B3 FF A4 A4 A4 FF A1 A1 A1 FF A3 A3 A3 FF A4 A4'
+ 'A4 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A3 A3 A3 C3 8D 8D'
+ '8D FF 73 73 73 FF 83 83 83 FF 9D 9D 9D FF AE AE'
+ 'AE FF AF AF AF FF B1 B1 B1 FF B2 B2 B2 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B7 B7 B7 FF B8 B8 B8 FF BA BA'
+ 'BA FF BB BB BB FF BD BD BD FF BE BE BE FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C3 C3 C3 FF C4 C4 C4 FF C5 C5'
+ 'C5 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9 C9 FF CA CA'
+ 'CA FF CC CC CC FF CE CE CE FF B0 B0 B0 FF A1 A1'
+ 'A1 FF CD CD CD FF B3 B3 B3 FF A0 A0 A0 D6 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A5 A5 A5 44 8C 8C'
+ '8C FE 9B 9B 9B FF 8E 8E 8E FF AB AB AB FF AE AE'
+ 'AE FF B0 B0 B0 FF B1 B1 B1 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B6 B6 B6 FF B7 B7 B7 FF B9 B9 B9 FF BA BA'
+ 'BA FF BC BC BC FF BD BD BD FF BF BF BF FF C0 C0'
+ 'C0 FF C2 C2 C2 FF C3 C3 C3 FF C4 C4 C4 FF C6 C6'
+ 'C6 FF C7 C7 C7 FF C9 C9 C9 FF CA CA CA FF CC CC'
+ 'CC FF CD CD CD FF CE CE CE FF CE CE CE FF BC BC'
+ 'BC FF AD AD AD FF AE AE AE FE A5 A5 A5 50 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A6 A6'
+ 'A6 C3 9F 9F 9F FF AA AA AA FF AD AD AD FF AE AE'
+ 'AE FF B0 B0 B0 FF B1 B1 B1 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B6 B6 B6 FF B8 B8 B8 FF B9 B9 B9 FF BD BD'
+ 'BD FF BD BD BD FF BD BD BD FF BF BF BF FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6'
+ 'C6 FF C8 C8 C8 FF C9 C9 C9 FF CB CB CB FF CB CB'
+ 'CB FF CE CE CE FF CF CF CF FF D0 D0 D0 FF CE CE'
+ 'CE FF 9E 9E 9E FF AC AC AC C5 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A6 A6'
+ 'A6 45 A2 A2 A2 FE AB AB AB FF AD AD AD FF AF AF'
+ 'AF FF B0 B0 B0 FF B2 B2 B2 FF B3 B3 B3 FF B5 B5'
+ 'B5 FF B5 B5 B5 FF AE AE AE FF BD BD BD FF C1 C1'
+ 'C1 FF C2 C2 C2 FF BD BD BD FF BC BC BC FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C4 C4 C4 FF C5 C5 C5 FF C7 C7'
+ 'C7 FF C8 C8 C8 FF CA CA CA FF CB CB CB FF CD CD'
+ 'CD FF CE CE CE FF D0 D0 D0 FF D1 D1 D1 FF B8 B8'
+ 'B8 FF AB AB AB FE AB AB AB 3D 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 A9 A9 A9 C4 AA AA AA FF AD AD AD FF AF AF'
+ 'AF FF B0 B0 B0 FF B2 B2 B2 FF B3 B3 B3 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF AE AE AE FF B2 B2 B2 FF B4 B4'
+ 'B4 FF B4 B4 B4 FF AB AB AB FF B7 B7 B7 FF C1 C1'
+ 'C1 FF C3 C3 C3 FF C4 C4 C4 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C9 C9 C9 FF CA CA CA FF CC CC CC FF CD CD'
+ 'CD FF CF CF CF FF D0 D0 D0 FF D3 D3 D3 FF A8 A8'
+ 'A8 FF B3 B3 B3 B2 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 AE AE AE 46 AC AC AC FE B0 B0 B0 FF AE AE'
+ 'AE FF B0 B0 B0 FF B2 B2 B2 FF B3 B3 B3 FF B5 B5'
+ 'B5 FF B7 B7 B7 FF B8 B8 B8 FF BB BB BB FF BC BC'
+ 'BC FF BE BE BE FF BF BF BF FF C0 C0 C0 FF C1 C1'
+ 'C1 FF C3 C3 C3 FF C4 C4 C4 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C9 C9 C9 FF CA CA CA FF CC CC CC FF CD CD'
+ 'CD FF CF CF CF FF D2 D2 D2 FF C2 C2 C2 FF B0 B0'
+ 'B0 FC B3 B3 B3 2C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A4 A4 A4 7C B4 B4 B4 A0 B9 B9'
+ 'B9 B3 B4 B4 B4 C0 B4 B4 B4 EC B6 B6 B6 ED B7 B7'
+ 'B7 ED B9 B9 B9 ED BA BA BA ED BC BC BC ED BD BD'
+ 'BD ED BF BF BF ED C0 C0 C0 ED C1 C1 C1 ED C3 C3'
+ 'C3 ED C4 C4 C4 ED C7 C7 C7 ED C8 C8 C8 ED C9 C9'
+ 'C9 ED CA CA CA ED CC CC CC ED CD CD CD ED CF CF'
+ 'CF EE D2 D2 D2 C1 C7 C7 C7 B8 B0 B0 B0 A9 B8 B8'
+ 'B8 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 01 00 00 C0 00 00 00 00 03 00 00 C0 00'
+ '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
+ '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 3F 00 00 F8 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 7F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 FF 00 00 FE 00 00 00 00 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
+ '00 00 03 FF 00 00 FF 80 00 00 03 FF 00 00 FF C0'
+ '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 04 00 00 00'
+ '00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 80 00 00 87 77 77 77 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 77 77 77 78 00 00 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 00 00 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 00 08 88 88 88 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 78 88 88 88 80 08 88 88 88 78 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 8A'
+ 'AA A7 88 88 88 80 08 88 88 87 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 8A'
+ 'AA A8 78 88 88 80 88 88 88 87 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 78 88 88 88 87 77 77 78 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 77 77 78 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 88 88 88 87 88 88 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF 88 88 78 88 88 78 88 8F 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 F8 88 87 88 08 88 88 F7 88 FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'F8 88 7F 88 88 80 08 88 8F 78 8F 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '7F 88 87 F8 88 00 00 88 F7 88 F7 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '87 F8 88 7F 88 00 00 88 78 8F 78 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 7F 88 87 80 00 00 08 78 F7 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 87 F8 78 80 00 00 08 78 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 88 78 00 00 00 00 87 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 80 00 00 00 00 87 88 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 87 80 00 00 00 00 08 78 88 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 88 78 00 00 00 00 00 08 78 88 88 88 88 88 88'
+ '88 88 88 88 8F FF FF FF 88 88 88 88 88 88 88 88'
+ '88 88 78 00 00 00 00 00 00 87 88 88 88 88 88 88'
+ '88 88 88 FF F8 88 88 88 FF F8 88 88 88 88 88 88'
+ '88 87 80 00 00 00 00 00 00 87 88 88 88 88 88 88'
+ '88 88 FF 88 88 88 88 88 88 8F F8 88 88 88 88 88'
+ '88 87 80 00 00 00 00 00 00 08 78 88 88 88 88 88'
+ '88 8F 88 88 88 88 88 88 88 88 8F 88 88 88 88 88'
+ '88 78 00 00 00 00 00 00 00 08 78 88 88 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
+ '88 78 00 00 00 00 00 00 00 00 87 88 88 88 88 88'
+ '88 87 88 88 88 88 88 88 88 88 87 88 88 88 88 88'
+ '87 80 00 00 00 00 00 00 00 00 87 88 88 88 88 88'
+ '88 88 77 88 88 88 88 88 88 87 78 88 88 88 88 88'
+ '87 80 00 00 00 00 00 00 00 00 08 77 78 88 88 88'
+ '88 88 88 77 78 88 88 88 77 78 88 88 88 88 88 77'
+ '78 00 00 00 00 00 00 00 00 00 08 78 87 88 88 88'
+ '88 88 88 88 87 77 77 77 88 88 88 88 88 88 87 88'
+ '78 00 00 00 00 00 00 00 00 00 00 87 88 78 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 78 87'
+ '80 00 00 00 00 00 00 00 00 00 00 87 87 87 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 87 88 F7'
+ '80 00 00 00 00 00 00 00 00 00 00 08 78 78 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 8F 78'
+ '00 00 00 00 00 00 00 00 00 00 00 08 78 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 88 78'
+ '00 00 00 00 00 00 00 00 00 00 00 00 87 88 88 88'
+ '88 88 8F FF FF 88 88 88 88 88 88 88 88 88 87 80'
+ '00 00 00 00 00 00 00 00 00 00 00 00 87 88 88 88'
+ '88 88 78 88 88 78 88 88 88 88 88 88 88 88 87 80'
+ '00 00 00 00 00 00 00 00 00 00 00 00 08 78 88 88'
+ '88 88 87 77 77 88 88 88 88 88 88 88 88 88 78 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 08 78 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 78 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 87 77 77'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 88 88 88'
+ '88 88 88 88 88 88 88 88 88 88 88 88 88 88 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF F0 00 00 00 00 00 00 07 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 07 E0 00'
+ '00 00 00 00 00 07 E0 00 00 00 00 00 00 0F F0 00'
+ '00 00 00 00 00 1F F0 00 00 00 00 00 00 1F F8 00'
+ '00 00 00 00 00 3F F8 00 00 00 00 00 00 3F FC 00'
+ '00 00 00 00 00 7F FC 00 00 00 00 00 00 7F FE 00'
+ '00 00 00 00 00 FF FE 00 00 00 00 00 00 FF FF 00'
+ '00 00 00 00 01 FF FF 00 00 00 00 00 01 FF FF 80'
+ '00 00 00 00 03 FF FF 80 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 07 FF FF C0 00 00 00 00 07 FF FF E0'
+ '00 00 00 00 0F FF FF E0 00 00 00 00 0F FF FF F0'
+ '00 00 00 00 1F FF FF F0 00 00 00 00 1F FF FF F8'
+ '00 00 00 00 3F FF FF F8 00 00 00 00 3F FF FF FC'
+ '00 00 00 00 7F FF FF FC 00 00 00 00 FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 40 00 00 00 80 00'
+ '00 00 01 00 08 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 C0 DC'
+ 'C0 00 F0 CA A6 00 50 50 50 00 52 52 52 00 53 53'
+ '53 00 55 55 55 00 57 57 57 00 58 58 58 00 5A 5A'
+ '5A 00 5C 5C 5C 00 5D 5D 5D 00 5F 5F 5F 00 60 60'
+ '60 00 61 61 61 00 62 62 62 00 63 63 63 00 64 64'
+ '64 00 65 65 65 00 66 66 66 00 67 67 67 00 68 68'
+ '68 00 69 69 69 00 6A 6A 6A 00 6B 6B 6B 00 6C 6C'
+ '6C 00 6D 6D 6D 00 6E 6E 6E 00 6F 6F 6F 00 70 70'
+ '70 00 71 71 71 00 72 72 72 00 73 73 73 00 74 74'
+ '74 00 75 75 75 00 76 76 76 00 77 77 77 00 78 78'
+ '78 00 79 79 79 00 7A 7A 7A 00 7B 7B 7B 00 7C 7C'
+ '7C 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F 7F 00 35 B4'
+ '35 00 38 B7 38 00 39 B8 39 00 1B DA 1B 00 1C DB'
+ '1C 00 FF 00 FF 00 80 80 80 00 81 81 81 00 82 82'
+ '82 00 83 83 83 00 84 84 84 00 85 85 85 00 86 86'
+ '86 00 87 87 87 00 88 88 88 00 89 89 89 00 8A 8A'
+ '8A 00 8B 8B 8B 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E'
+ '8E 00 8F 8F 8F 00 90 90 90 00 91 91 91 00 92 92'
+ '92 00 93 93 93 00 94 94 94 00 95 95 95 00 96 96'
+ '96 00 97 97 97 00 98 98 98 00 99 99 99 00 9A 9A'
+ '9A 00 9B 9B 9B 00 9C 9C 9C 00 9D 9D 9D 00 9E 9E'
+ '9E 00 9F 9F 9F 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2'
+ 'A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6'
+ 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
+ 'AA 00 AB AB AB 00 AC AC AC 00 AD AD AD 00 AE AE'
+ 'AE 00 AF AF AF 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
+ 'B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6'
+ 'B6 00 B7 B7 B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA'
+ 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2'
+ 'C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6'
+ 'C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9 C9 00 CA CA'
+ 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
+ 'CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D4 D4 D4 00 D7 D7 D7 00 D9 D9 D9 00 DA DA'
+ 'DA 00 DB DB DB 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 F0 FB FF 00 A4 A0 A0 00 80 80'
+ '80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 59 59 5A 5C 5D 5E 60 61 61 63 64 65 66 67'
+ '68 69 69 6A 6A 69 68 67 65 64 63 61 60 5F 5D 5C'
+ '5A 59 57 56 54 52 50 4D 4C 4B 48 47 45 43 42 40'
+ '3E 3C 3B 32 30 2F 2D 2C 2C 2D 33 00 00 00 00 00'
+ '5B 4B 4D 4E 4F 50 52 53 56 63 64 65 66 67 68 69'
+ '6A 6B 6C 6D 6D 6B 6A 68 67 66 64 63 62 61 5F 5D'
+ '5C 5A 58 57 55 53 51 4F 4D 4B 49 47 45 43 41 3F'
+ '3D 3B 32 2A 23 21 20 1E 1D 1B 1B 45 00 00 00 00'
+ '63 5D 5E 5E 60 61 61 62 64 65 66 67 68 69 6A 6B'
+ '6C 6D 6D 6E 6E 6D 6C 6A 69 68 66 65 63 62 60 5F'
+ '5D 5C 5A 58 56 55 53 52 4F 4E 4B 4A 48 45 44 42'
+ '40 3D 3A 32 31 2F 2D 2C 2B 2A 2A 40 00 00 00 00'
+ '61 5F 5F 60 61 62 60 5B 5D 5E 60 61 62 63 64 66'
+ '67 68 68 69 69 69 68 67 65 63 62 61 60 5F 5C 5B'
+ '5A 59 58 55 53 53 51 50 4E 4D 4A 48 46 44 43 41'
+ '3F 3D 3B 33 30 2E 2C 2B 2B 2A 29 2E 00 00 00 00'
+ '60 60 60 61 62 63 3D 4E 4F 4F 50 50 51 50 50 51'
+ '51 51 51 51 50 4D 4B 49 47 45 43 41 40 3E 3C 3A'
+ '33 31 30 2D 2C 2A 29 27 25 23 22 21 1F 1D 1B 1A'
+ '18 16 14 13 12 0D 2C 2B 2B 29 28 28 00 00 00 70'
+ '60 60 61 62 63 5D 4B 65 66 67 68 69 69 68 68 6A'
+ '6C 6B 6D 6E 6C 68 65 64 62 60 5D 5C 5A 58 56 54'
+ '52 50 4E 4C 49 47 45 43 41 3F 3D 3A 32 30 2E 2C'
+ '2A 36 38 37 34 14 20 2A 2A 28 26 26 54 00 00 6C'
+ '61 62 62 63 63 45 64 65 66 67 68 69 68 68 6B 6C'
+ '6D 6E 6E 6D 6A 67 66 64 62 61 5E 5B 5A 58 56 53'
+ '51 4F 4D 4B 49 47 46 44 40 3E 3D 3A 32 30 2D 2B'
+ '28 35 37 37 34 1C 13 2A 29 26 24 23 40 00 00 68'
+ '63 63 63 64 66 43 64 66 67 68 68 68 69 6A 6C 6C'
+ '6D 6E 6E 6C 69 67 66 64 62 60 5E 5C 5A 57 55 52'
+ '50 4F 4C 4B 49 47 45 43 3F 3E 3C 3A 31 2F 2D 2A'
+ '27 25 22 21 1E 1C 10 29 28 25 22 20 27 00 00 43'
+ '42 42 43 43 44 5A 64 64 63 65 66 67 67 69 6B 6C'
+ '6B 6D 6D 69 67 66 64 63 60 5E 5D 5A 58 56 54 51'
+ '4F 4E 4B 49 48 47 44 42 3F 3D 3B 33 31 2E 2C 2A'
+ '28 25 23 21 1D 1C 18 0E 0F 0E 0D 0C 0C 00 00 60'
+ '5F 5F 60 60 60 61 61 62 63 64 64 65 66 66 68 69'
+ '69 6A 69 67 65 63 62 60 5E 5C 5B 58 56 54 52 4F'
+ '4E 4C 4B 49 47 45 43 41 3E 3C 3A 32 30 2E 2D 2B'
+ '29 27 24 22 1F 1D 1F 1C 1B 19 17 15 14 00 62 57'
+ '59 54 46 4A 4B 4B 4F 52 54 55 56 57 58 58 5A 5B'
+ '5A 5A 5A 59 59 56 56 57 55 54 52 50 4F 4D 4B 49'
+ '47 46 44 42 40 3E 3C 33 32 31 2E 2B 28 25 23 22'
+ '20 1F 1D 1A 17 15 14 13 13 16 2D 2E 2E 4E 53 33'
+ '1D 56 31 55 59 5A 5F 67 71 74 78 7B 7E 7E 80 81'
+ '7F 81 83 84 85 84 86 87 86 86 86 85 85 85 84 84'
+ '83 82 82 82 82 81 80 7F 80 7F 7E 7E 7C 7B 7B 79'
+ '79 78 78 76 75 6D 64 5F 5E 5E 3A 26 5D 63 6C 3E'
+ '52 4E 26 50 54 55 56 57 4E 4C 4C 4E 4F 51 51 52'
+ '53 54 56 56 57 58 59 5A 5A 5C 5C 5C 5B 5A 5A 5B'
+ '5B 5C 5C 5C 5C 5C 5C 5B 5B 5B 5B 5D 5D 5C 5D 5D'
+ '5E 5D 5F 61 6C 81 83 62 57 5B 3C 55 4A 70 00 70'
+ '6B 5C 55 52 3D 12 32 58 65 6D 70 73 76 76 78 77'
+ '76 77 79 07 7B 7D 7E 7D 7E 7E 7E 7F 7F 7F 7F 7E'
+ '7D 7C 7C 07 79 77 77 76 74 71 70 6F 70 73 75 75'
+ '74 73 71 71 77 75 54 81 6A 74 7B 63 7E 00 00 56'
+ '50 51 4D 1F 0C 2A 4F 47 2C 3B 3B 3D 3E 3F 3F 40'
+ '40 42 43 43 43 44 45 45 44 45 46 46 46 46 45 45'
+ '45 45 45 45 45 44 45 44 43 43 43 43 43 43 43 43'
+ '44 43 43 50 4E 6F 8E 51 73 6D 57 51 65 00 00 6D'
+ '4C 43 0A 11 41 4E 3A 2B 54 5B 5D 5F 60 61 61 63'
+ '63 64 65 66 67 68 69 6A 6A 6B 6C 6D 6D 6E 6E 6F'
+ '6F 70 70 71 72 72 73 73 74 74 75 75 75 75 76 76'
+ '77 77 60 4D 65 4E 57 8C 5F 5B 5D 4F 00 00 00 00'
+ '53 31 0B 4B 4C 28 40 56 5A 5C 5D 5E 5F 60 61 62'
+ '63 64 65 66 67 68 69 6A 6B 6C 6D 6D 6E 6F 70 71'
+ '72 72 73 74 75 75 76 77 77 78 78 79 79 07 07 7B'
+ '7B 7B 7B 6D 45 59 58 4D 70 4D 54 66 00 00 00 00'
+ '69 48 1C 59 3F 4D 56 5B 5C 5D 5E 5F 60 61 62 63'
+ '64 65 66 67 68 69 6A 6B 6C 6C 6D 6E 6F 70 71 72'
+ '72 73 74 75 75 76 77 78 78 79 79 07 07 7B 7B 7C'
+ '7C 7C 7D 7D 07 56 4A 53 4B 4C 50 00 00 00 00 00'
+ '00 4D 28 4D 53 50 5A 5B 5C 5D 5E 5F 60 61 62 63'
+ '64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 72'
+ '73 74 75 76 76 77 78 78 79 07 07 7B 7B 7C 7C 7D'
+ '7D 7D 7E 7E 7E 7E 5C 50 4A 4D 00 00 00 00 00 00'
+ '00 66 44 2C 5E 45 5B 5C 5D 5E 5F 60 61 62 63 64'
+ '65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 71 72 73'
+ '74 75 76 77 77 78 79 79 07 7B 7B 7C 7C 7D 7D 7E'
+ '7E 7F 7F 7F 7F 7F 50 50 4C 54 00 00 00 00 00 00'
+ '00 00 4C 29 56 4B 59 5C 5D 5E 5F 60 61 63 64 65'
+ '66 67 68 69 6A 6B 6C 6D 6E 6E 6F 70 71 72 73 74'
+ '75 76 77 77 78 79 07 07 7B 7C 7C 7D 7E 7E 7F 7F'
+ '7F 80 80 80 80 6D 4C 4A 4F 00 00 00 00 00 00 00'
+ '00 00 63 41 3C 55 4D 5D 5E 5F 60 61 62 63 64 65'
+ '66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75'
+ '76 76 77 78 79 07 7B 7B 7C 7D 7D 7E 7F 7F 80 80'
+ '80 81 81 81 82 55 4D 4E 55 00 00 00 00 00 00 00'
+ '00 00 00 4F 2D 58 4A 5D 5E 5F 60 61 62 64 65 66'
+ '67 68 69 6A 6B 6C 6D 6E 6F 70 7C 8B 8F 91 8F 8D'
+ '88 7D 74 78 07 7B 7B 7C 7D 7E 7E 7F 80 80 81 81'
+ '82 82 82 82 76 4A 4E 50 00 00 00 00 00 00 00 00'
+ '00 00 00 63 43 47 51 5B 5F 60 61 62 63 64 65 66'
+ '67 68 69 6A 6B 6D 6A 6B 73 7C 7F 79 73 70 70 73'
+ '79 85 91 8E 75 76 7C 7D 7E 7F 7F 80 81 81 82 82'
+ '83 83 83 84 60 4D 50 5C 00 00 00 00 00 00 00 00'
+ '00 00 00 00 4F 33 59 55 5F 60 61 62 63 64 65 67'
+ '68 69 6A 6B 6C 63 5F 6B 6E 70 72 73 74 75 76 77'
+ '78 78 72 72 88 6F 70 7E 7F 7F 80 81 81 82 83 83'
+ '84 84 84 80 4F 4F 55 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 63 43 52 55 5F 60 62 63 64 65 66 67'
+ '68 69 6A 6B 66 56 68 6F 70 71 73 74 74 76 77 77'
+ '78 79 07 7B 75 6E 62 76 7F 80 81 82 82 83 84 84'
+ '85 85 86 6C 50 52 60 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 52 48 5B 5A 61 62 63 64 65 66 67'
+ '68 6A 6B 6C 60 5B 6F 70 71 72 73 74 75 76 77 78'
+ '79 07 7B 7C 7D 6C 64 66 80 81 82 83 83 84 85 85'
+ '86 86 84 58 55 57 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 63 4F 5A 58 61 62 63 65 66 67 68'
+ '69 6A 6B 6C 5E 5D 6C 70 71 73 74 75 76 77 78 79'
+ '07 7B 7C 7D 07 65 4C 75 81 82 83 84 84 85 86 86'
+ '87 87 70 53 59 63 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 54 54 5E 5D 63 64 65 66 67 68'
+ '69 6A 6B 6D 6D 60 5D 67 70 73 74 75 76 77 78 79'
+ '07 7B 07 70 5A 41 67 81 82 83 84 84 85 86 87 87'
+ '88 7C 57 5A 5A 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 60 54 57 62 60 64 65 66 67 68'
+ '6A 6B 6C 6D 6E 6F 70 68 5A 60 67 6C 6E 6F 70 6E'
+ '6A 62 4F 47 56 7B 81 82 83 83 84 85 86 87 88 88'
+ '79 5F 5B 59 63 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 4D 4E 57 63 64 65 67 68 69'
+ '6A 6B 6C 6D 6E 6F 70 72 75 6A 61 5B 57 56 57 5B'
+ '5F 64 73 7F 7F 80 81 82 83 84 85 86 87 88 86 71'
+ '60 55 57 5D 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 56 55 52 4C 63 65 68 69'
+ '6A 6B 6C 6E 6F 70 71 72 73 74 75 76 77 79 07 7B'
+ '7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 7C 60 61'
+ '62 63 5A 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 57 41 2E 18 5A 59 68 69'
+ '6A 6C 6D 6E 6F 70 71 72 73 74 76 77 78 79 07 7B'
+ '7C 7D 7E 7F 80 81 82 84 85 86 86 87 88 63 5D 70'
+ '90 6A 5B 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 33 50 40 48 65 68 6A'
+ '6B 6C 6D 6E 6F 70 71 73 74 75 76 77 78 79 07 7B'
+ '7D 7E 7F 80 81 82 83 84 85 86 87 88 89 82 6E 6B'
+ '80 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 5A 5A 61 66 67 69 6A'
+ '6B 6C 6D 6E 6F 71 72 73 74 75 76 77 78 07 7B 7C'
+ '7D 7E 7F 80 81 82 83 85 86 87 88 89 8A 8B 8C 6D'
+ '5A 67 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 66 59 62 67 68 69 6A'
+ '6B 6C 6D 6E 70 71 72 73 77 7C 07 7B 79 07 7B 7C'
+ '7D 7E 7F 81 82 83 84 85 86 87 88 89 8A 8B 88 5F'
+ '66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 5E 62 66 68 69 6A'
+ '6B 6C 6D 6F 70 6F 66 74 07 07 7C 79 72 77 7B 7C'
+ '7D 7F 80 81 82 83 84 85 86 87 89 8A 8B 8C 78 63'
+ '6B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 69 61 67 68 69 6A'
+ '6B 6C 6E 6F 70 6F 65 6C 70 75 74 6A 5E 74 7B 7D'
+ '7E 7F 80 81 82 83 84 86 87 88 89 8A 8B 8B 68 6A'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 62 67 68 69 6A'
+ '6B 6D 6E 6F 70 71 72 74 71 6F 71 77 79 07 7B 7D'
+ '7E 7F 80 81 82 84 85 86 87 88 89 8A 8B 7F 67 70'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 6E 66 6D 6E 6B'
+ '6C 6D 6E 6F 70 71 72 74 75 76 77 78 79 07 7C 7D'
+ '7E 7F 80 81 82 84 85 86 87 88 89 8A 85 6A 6B 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 68 75 74 74'
+ '71 70 72 73 74 75 75 77 78 79 07 7B 7B 7C 7D 7E'
+ '7F 7F 81 82 83 84 85 86 86 84 7B 75 75 6B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 00'
+ '00 00 00 00 00 07 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 07 E0 00'
+ '00 00 00 00 00 0F E0 00 00 00 00 00 00 0F F0 00'
+ '00 00 00 00 00 1F F0 00 00 00 00 00 00 1F F8 00'
+ '00 00 00 00 00 3F F8 00 00 00 00 00 00 3F FC 00'
+ '00 00 00 00 00 7F FC 00 00 00 00 00 00 7F FE 00'
+ '00 00 00 00 00 FF FE 00 00 00 00 00 00 FF FF 00'
+ '00 00 00 00 01 FF FF 00 00 00 00 00 01 FF FF 80'
+ '00 00 00 00 03 FF FF C0 00 00 00 00 07 FF FF C0'
+ '00 00 00 00 07 FF FF E0 00 00 00 00 0F FF FF E0'
+ '00 00 00 00 0F FF FF E0 00 00 00 00 1F FF FF F0'
+ '00 00 00 00 1F FF FF F0 00 00 00 00 3F FF FF F8'
+ '00 00 00 00 3F FF FF F8 00 00 00 00 7F FF FF FC'
+ '00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 20 00 00 00'
+ '00 00 00 42 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 AA AA'
+ 'AA 78 9D 9D 9D E8 9C 9C 9C E8 9C 9C 9C E8 9D 9D'
+ '9D E8 9F 9F 9F E8 A0 A0 A0 E8 A1 A1 A1 E8 A3 A3'
+ 'A3 E8 A4 A4 A4 E8 A5 A5 A5 E8 A7 A7 A7 E8 A8 A8'
+ 'A8 E8 A9 A9 A9 E8 AA AA AA E8 AB AB AB E8 AC AC'
+ 'AC E8 AD AD AD E8 AD AD AD E8 AE AE AE E8 AE AE'
+ 'AE E8 AD AD AD E8 AC AC AC E8 AB AB AB E8 A9 A9'
+ 'A9 E8 A8 A8 A8 E8 A7 A7 A7 E8 A4 A4 A4 E8 A3 A3'
+ 'A3 E8 A2 A2 A2 E8 A0 A0 A0 E8 9F 9F 9F E8 9D 9D'
+ '9D E8 9C 9C 9C E8 99 99 99 E8 98 98 98 E8 96 96'
+ '96 E8 94 94 94 E8 92 92 92 E8 8F 8F 8F E8 8D 8D'
+ '8D E8 8C 8C 8C E8 89 89 89 E8 88 88 88 E8 86 86'
+ '86 E8 83 83 83 E8 82 82 82 E8 80 80 80 E8 7E 7E'
+ '7E E8 7C 7C 7C E8 7B 7B 7B E8 78 78 78 E8 75 75'
+ '75 E8 74 74 74 E8 72 72 72 E8 71 71 71 E8 71 71'
+ '71 E8 72 72 72 E8 75 75 75 DD 81 81 81 51 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 BE 91 91 91 FF 93 93 93 FF 94 94 94 FF 95 95'
+ '95 FF 96 96 96 FF 98 98 98 FF 99 99 99 FF 9C 9C'
+ '9C FF A9 A9 A9 FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B3 B3'
+ 'B3 FF B1 B1 B1 FF B0 B0 B0 FF AE AE AE FF AD AD'
+ 'AD FF AC AC AC FF AA AA AA FF A9 A9 A9 FF A8 A8'
+ 'A8 FF A7 A7 A7 FF A5 A5 A5 FF A3 A3 A3 FF A2 A2'
+ 'A2 FF A0 A0 A0 FF 9E 9E 9E FF 9D 9D 9D FF 9B 9B'
+ '9B FF 99 99 99 FF 97 97 97 FF 95 95 95 FF 93 93'
+ '93 FF 91 91 91 FF 8F 8F 8F FF 8D 8D 8D FF 8B 8B'
+ '8B FF 89 89 89 FF 87 87 87 FF 85 85 85 FF 83 83'
+ '83 FF 81 81 81 FF 7E 7E 7E FF 76 76 76 FF 6F 6F'
+ '6F FF 6D 6D 6D FF 6C 6C 6C FF 6A 6A 6A FF 69 69'
+ '69 FF 67 67 67 FF 67 67 67 FF 73 73 73 B0 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A8 A8'
+ 'A8 F1 A3 A3 A3 FF A4 A4 A4 FF A4 A4 A4 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A7 A7 A7 FF A8 A8 A8 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AD AD AD FF AE AE'
+ 'AE FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2'
+ 'B2 FF B3 B3 B3 FF B3 B3 B3 FF B4 B4 B4 FF B4 B4'
+ 'B4 FF B3 B3 B3 FF B2 B2 B2 FF B0 B0 B0 FF AF AF'
+ 'AF FF AE AE AE FF AC AC AC FF AB AB AB FF A9 A9'
+ 'A9 FF A8 A8 A8 FF A6 A6 A6 FF A5 A5 A5 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A0 A0 A0 FF 9E 9E 9E FF 9C 9C'
+ '9C FF 9B 9B 9B FF 99 99 99 FF 98 98 98 FF 95 95'
+ '95 FF 94 94 94 FF 91 91 91 FF 90 90 90 FF 8E 8E'
+ '8E FF 8B 8B 8B FF 8A 8A 8A FF 88 88 88 FF 86 86'
+ '86 FF 83 83 83 FF 80 80 80 FF 7E 7E 7E FF 7D 7D'
+ '7D FF 7B 7B 7B FF 79 79 79 FF 78 78 78 FF 77 77'
+ '77 FF 76 76 76 FF 76 76 76 FF 81 81 81 EA 00 00'
+ '00 00 00 00 00 00 00 00 00 00 B7 B7 B7 2B A7 A7'
+ 'A7 FE A5 A5 A5 FF A5 A5 A5 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF A8 A8 A8 FF A6 A6 A6 FF A1 A1 A1 FF A3 A3'
+ 'A3 FF A4 A4 A4 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF AA AA AA FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AE AE AE FF AF AF AF FF AF AF'
+ 'AF FF AF AF AF FF AE AE AE FF AD AD AD FF AB AB'
+ 'AB FF A9 A9 A9 FF A8 A8 A8 FF A7 A7 A7 FF A6 A6'
+ 'A6 FF A5 A5 A5 FF A2 A2 A2 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9F 9F 9F FF 9E 9E 9E FF 9B 9B 9B FF 99 99'
+ '99 FF 99 99 99 FF 97 97 97 FF 96 96 96 FF 94 94'
+ '94 FF 93 93 93 FF 90 90 90 FF 8E 8E 8E FF 8C 8C'
+ '8C FF 8A 8A 8A FF 89 89 89 FF 87 87 87 FF 85 85'
+ '85 FF 83 83 83 FF 81 81 81 FF 7F 7F 7F FF 7C 7C'
+ '7C FF 7A 7A 7A FF 78 78 78 FF 77 77 77 FF 77 77'
+ '77 FF 76 76 76 FF 75 75 75 FF 7A 7A 7A FE 9B 9B'
+ '9B 29 00 00 00 00 00 00 00 00 B0 B0 B0 62 A6 A6'
+ 'A6 FF A6 A6 A6 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF 83 83 83 FF 94 94 94 FF 95 95'
+ '95 FF 95 95 95 FF 96 96 96 FF 96 96 96 FF 97 97'
+ '97 FF 96 96 96 FF 96 96 96 FF 97 97 97 FF 97 97'
+ '97 FF 97 97 97 FF 97 97 97 FF 97 97 97 FF 96 96'
+ '96 FF 93 93 93 FF 91 91 91 FF 8F 8F 8F FF 8D 8D'
+ '8D FF 8B 8B 8B FF 89 89 89 FF 87 87 87 FF 86 86'
+ '86 FF 84 84 84 FF 82 82 82 FF 80 80 80 FF 7F 7F'
+ '7F FF 7D 7D 7D FF 7C 7C 7C FF 79 79 79 FF 78 78'
+ '78 FF 76 76 76 FF 75 75 75 FF 73 73 73 FF 71 71'
+ '71 FF 6F 6F 6F FF 6E 6E 6E FF 6D 6D 6D FF 6B 6B'
+ '6B FF 69 69 69 FF 67 67 67 FF 66 66 66 FF 64 64'
+ '64 FF 62 62 62 FF 60 60 60 FF 5F 5F 5F FF 5D 5D'
+ '5D FF 55 55 55 FF 78 78 78 FF 77 77 77 FF 77 77'
+ '77 FF 75 75 75 FF 74 74 74 FF 74 74 74 FF 8D 8D'
+ '8D 65 00 00 00 00 00 00 00 00 B0 B0 B0 98 A6 A6'
+ 'A6 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF A3 A3 A3 FF 91 91 91 FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AF AF AF FF AF AF'
+ 'AF FF AE AE AE FF AE AE AE FF B0 B0 B0 FF B2 B2'
+ 'B2 FF B1 B1 B1 FF B3 B3 B3 FF B4 B4 B4 FF B2 B2'
+ 'B2 FF AE AE AE FF AB AB AB FF AA AA AA FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A3 A3 A3 FF A2 A2 A2 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9C 9C 9C FF 9A 9A 9A FF 98 98'
+ '98 FF 96 96 96 FF 94 94 94 FF 92 92 92 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8B 8B 8B FF 89 89 89 FF 87 87'
+ '87 FF 85 85 85 FF 83 83 83 FF 80 80 80 FF 7E 7E'
+ '7E FF 7C 7C 7C FF 7A 7A 7A FF 78 78 78 FF 76 76'
+ '76 FF 73 73 73 FF 38 B7 38 FF 1C DB 1C FF 1B DA'
+ '1B FF 30 AF 30 FF 6C 6C 6C FF 76 76 76 FF 76 76'
+ '76 FF 74 74 74 FF 72 72 72 FF 72 72 72 FF 84 84'
+ '84 A0 00 00 00 00 00 00 00 00 AF AF AF CE A7 A7'
+ 'A7 FF A8 A8 A8 FF A8 A8 A8 FF A9 A9 A9 FF A9 A9'
+ 'A9 FF 8B 8B 8B FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AF AF AF FF AE AE'
+ 'AE FF AE AE AE FF B1 B1 B1 FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B4 B4 B4 FF B3 B3 B3 FF B0 B0'
+ 'B0 FF AD AD AD FF AC AC AC FF AA AA AA FF A8 A8'
+ 'A8 FF A7 A7 A7 FF A4 A4 A4 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF 9E 9E 9E FF 9C 9C 9C FF 99 99 99 FF 97 97'
+ '97 FF 95 95 95 FF 93 93 93 FF 91 91 91 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8C 8C 8C FF 8A 8A 8A FF 86 86'
+ '86 FF 84 84 84 FF 83 83 83 FF 80 80 80 FF 7E 7E'
+ '7E FF 7C 7C 7C FF 79 79 79 FF 77 77 77 FF 74 74'
+ '74 FF 71 71 71 FF 37 B6 37 FF 1B DA 1B FF 1B DA'
+ '1B FF 34 B3 34 FF 5F 5F 5F FF 76 76 76 FF 75 75'
+ '75 FF 72 72 72 FF 70 70 70 FF 6F 6F 6F FF 7D 7D'
+ '7D DC 00 00 00 00 00 00 00 00 AE AE AE FA A9 A9'
+ 'A9 FF A9 A9 A9 FF A9 A9 A9 FF AA AA AA FF AC AC'
+ 'AC FF 89 89 89 FF AA AA AA FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AE AE AE FF AE AE AE FF AF AF'
+ 'AF FF B0 B0 B0 FF B2 B2 B2 FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B4 B4 B4 FF B2 B2 B2 FF AF AF'
+ 'AF FF AD AD AD FF AC AC AC FF AA AA AA FF A8 A8'
+ 'A8 FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF A0 A0'
+ 'A0 FF 9D 9D 9D FF 9B 9B 9B FF 98 98 98 FF 96 96'
+ '96 FF 95 95 95 FF 92 92 92 FF 91 91 91 FF 8F 8F'
+ '8F FF 8D 8D 8D FF 8B 8B 8B FF 89 89 89 FF 85 85'
+ '85 FF 84 84 84 FF 82 82 82 FF 80 80 80 FF 7D 7D'
+ '7D FF 7B 7B 7B FF 79 79 79 FF 76 76 76 FF 73 73'
+ '73 FF 71 71 71 FF 6E 6E 6E FF 6D 6D 6D FF 6A 6A'
+ '6A FF 68 68 68 FF 5A 5A 5A FF 75 75 75 FF 74 74'
+ '74 FF 71 71 71 FF 6E 6E 6E FF 6C 6C 6C FF 73 73'
+ '73 FE A3 A3 A3 19 99 99 99 3C 89 89 89 FF 88 88'
+ '88 FF 88 88 88 FF 89 89 89 FF 89 89 89 FF 8A 8A'
+ '8A FF A0 A0 A0 FF AA AA AA FF AA AA AA FF A9 A9'
+ 'A9 FF AB AB AB FF AC AC AC FF AD AD AD FF AD AD'
+ 'AD FF AF AF AF FF B1 B1 B1 FF B2 B2 B2 FF B1 B1'
+ 'B1 FF B3 B3 B3 FF B3 B3 B3 FF AF AF AF FF AD AD'
+ 'AD FF AC AC AC FF AA AA AA FF A9 A9 A9 FF A6 A6'
+ 'A6 FF A4 A4 A4 FF A3 A3 A3 FF A0 A0 A0 FF 9E 9E'
+ '9E FF 9C 9C 9C FF 9A 9A 9A FF 97 97 97 FF 95 95'
+ '95 FF 94 94 94 FF 91 91 91 FF 8F 8F 8F FF 8E 8E'
+ '8E FF 8D 8D 8D FF 8A 8A 8A FF 88 88 88 FF 85 85'
+ '85 FF 83 83 83 FF 81 81 81 FF 7F 7F 7F FF 7D 7D'
+ '7D FF 7A 7A 7A FF 78 78 78 FF 76 76 76 FF 74 74'
+ '74 FF 71 71 71 FF 6F 6F 6F FF 6D 6D 6D FF 69 69'
+ '69 FF 68 68 68 FF 64 64 64 FF 57 57 57 FF 58 58'
+ '58 FF 57 57 57 FF 55 55 55 FF 53 53 53 FF 53 53'
+ '53 FF 76 76 76 54 B9 B9 B9 72 A6 A6 A6 FF A5 A5'
+ 'A5 FF A5 A5 A5 FF A6 A6 A6 FF A6 A6 A6 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AA AA AA FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AC AC AC FF AE AE AE FF AF AF AF FF AF AF'
+ 'AF FF B0 B0 B0 FF AF AF AF FF AD AD AD FF AB AB'
+ 'AB FF A9 A9 A9 FF A8 A8 A8 FF A6 A6 A6 FF A4 A4'
+ 'A4 FF A2 A2 A2 FF A1 A1 A1 FF 9E 9E 9E FF 9C 9C'
+ '9C FF 9A 9A 9A FF 98 98 98 FF 95 95 95 FF 94 94'
+ '94 FF 92 92 92 FF 91 91 91 FF 8F 8F 8F FF 8D 8D'
+ '8D FF 8B 8B 8B FF 89 89 89 FF 87 87 87 FF 84 84'
+ '84 FF 82 82 82 FF 80 80 80 FF 7E 7E 7E FF 7C 7C'
+ '7C FF 7A 7A 7A FF 79 79 79 FF 77 77 77 FF 75 75'
+ '75 FF 73 73 73 FF 70 70 70 FF 6E 6E 6E FF 6B 6B'
+ '6B FF 69 69 69 FF 6B 6B 6B FF 68 68 68 FF 67 67'
+ '67 FF 65 65 65 FF 63 63 63 FF 61 61 61 FF 60 60'
+ '60 FF 7F 7F 7F 90 9D 9D 9D B1 9D 9D 9D FF 9F 9F'
+ '9F FF 9A 9A 9A FF 8C 8C 8C FF 90 90 90 FF 91 91'
+ '91 FF 91 91 91 FF 95 95 95 FF 98 98 98 FF 9A 9A'
+ '9A FF 9B 9B 9B FF 9C 9C 9C FF 9D 9D 9D FF 9E 9E'
+ '9E FF 9E 9E 9E FF A0 A0 A0 FF A1 A1 A1 FF A0 A0'
+ 'A0 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9C 9C 9C FF 9C 9C 9C FF 9D 9D 9D FF 9B 9B'
+ '9B FF 9A 9A 9A FF 98 98 98 FF 96 96 96 FF 95 95'
+ '95 FF 93 93 93 FF 91 91 91 FF 8F 8F 8F FF 8D 8D'
+ '8D FF 8C 8C 8C FF 8A 8A 8A FF 88 88 88 FF 86 86'
+ '86 FF 84 84 84 FF 82 82 82 FF 7F 7F 7F FF 7E 7E'
+ '7E FF 7D 7D 7D FF 7A 7A 7A FF 77 77 77 FF 74 74'
+ '74 FF 71 71 71 FF 6F 6F 6F FF 6E 6E 6E FF 6C 6C'
+ '6C FF 6B 6B 6B FF 69 69 69 FF 66 66 66 FF 63 63'
+ '63 FF 61 61 61 FF 60 60 60 FF 5F 5F 5F FF 5F 5F'
+ '5F FF 62 62 62 FF 79 79 79 FF 7A 7A 7A FF 7A 7A'
+ '7A FF 89 89 89 CC 89 89 89 B4 7F 7F 7F FF 69 69'
+ '69 FF 9C 9C 9C FF 7D 7D 7D FF 9B 9B 9B FF 9F 9F'
+ '9F FF A0 A0 A0 FF A5 A5 A5 FF AD AD AD FF B7 B7'
+ 'B7 FF BA BA BA FF BE BE BE FF C1 C1 C1 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C6 C6 C6 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF C7 C7 C7 FF C9 C9 C9 FF CA CA CA FF CB CB'
+ 'CB FF CA CA CA FF CC CC CC FF CD CD CD FF CC CC'
+ 'CC FF CC CC CC FF CC CC CC FF CB CB CB FF CB CB'
+ 'CB FF CB CB CB FF CA CA CA FF CA CA CA FF C9 C9'
+ 'C9 FF C8 C8 C8 FF C8 C8 C8 FF C8 C8 C8 FF C8 C8'
+ 'C8 FF C7 C7 C7 FF C6 C6 C6 FF C5 C5 C5 FF C6 C6'
+ 'C6 FF C5 C5 C5 FF C4 C4 C4 FF C4 C4 C4 FF C2 C2'
+ 'C2 FF C1 C1 C1 FF C1 C1 C1 FF BF BF BF FF BF BF'
+ 'BF FF BE BE BE FF BE BE BE FF BC BC BC FF BB BB'
+ 'BB FF B3 B3 B3 FF AA AA AA FF A5 A5 A5 FF A4 A4'
+ 'A4 FF A4 A4 A4 FF 80 80 80 FF 72 72 72 FF A3 A3'
+ 'A3 FF 9F 9F 9F B1 83 83 83 3C 84 84 84 FE 98 98'
+ '98 FF 94 94 94 FF 72 72 72 FF 96 96 96 FF 9A 9A'
+ '9A FF 9B 9B 9B FF 9C 9C 9C FF 9D 9D 9D FF 94 94'
+ '94 FF 92 92 92 FF 92 92 92 FF 94 94 94 FF 95 95'
+ '95 FF 97 97 97 FF 97 97 97 FF 98 98 98 FF 99 99'
+ '99 FF 9A 9A 9A FF 9C 9C 9C FF 9C 9C 9C FF 9D 9D'
+ '9D FF 9E 9E 9E FF 9F 9F 9F FF A0 A0 A0 FF A0 A0'
+ 'A0 FF A2 A2 A2 FF A2 A2 A2 FF A2 A2 A2 FF A1 A1'
+ 'A1 FF A0 A0 A0 FF A0 A0 A0 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF A2 A2 A2 FF A2 A2 A2 FF A2 A2 A2 FF A2 A2'
+ 'A2 FF A2 A2 A2 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1'
+ 'A1 FF A1 A1 A1 FF A1 A1 A1 FF A3 A3 A3 FF A3 A3'
+ 'A3 FF A2 A2 A2 FF A3 A3 A3 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A5 A5 A5 FF A7 A7 A7 FF B2 B2'
+ 'B2 FF C7 C7 C7 FF C9 C9 C9 FF A8 A8 A8 FF 9D 9D'
+ '9D FF A1 A1 A1 FF 82 82 82 FF 9B 9B 9B FF 90 90'
+ '90 FE 97 97 97 40 00 00 00 00 B6 B6 B6 F7 B1 B1'
+ 'B1 FF A2 A2 A2 FF 9B 9B 9B FF 98 98 98 FF 83 83'
+ '83 FF 5D 5D 5D FF 7E 7E 7E FF 9E 9E 9E FF AB AB'
+ 'AB FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF BC BC'
+ 'BC FF BC BC BC FF BE BE BE FF BD BD BD FF BC BC'
+ 'BC FF BD BD BD FF BF BF BF FF C0 C0 C0 FF C1 C1'
+ 'C1 FF C3 C3 C3 FF C4 C4 C4 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C5 C5 C5 FF C5 C5'
+ 'C5 FF C5 C5 C5 FF C5 C5 C5 FF C4 C4 C4 FF C3 C3'
+ 'C3 FF C2 C2 C2 FF C2 C2 C2 FF C0 C0 C0 FF BF BF'
+ 'BF FF BD BD BD FF BD BD BD FF BC BC BC FF BA BA'
+ 'BA FF B7 B7 B7 FF B6 B6 B6 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B9 B9 B9 FF BB BB BB FF BB BB BB FF BA BA'
+ 'BA FF B9 B9 B9 FF B7 B7 B7 FF B7 B7 B7 FF BD BD'
+ 'BD FF BB BB BB FF 9A 9A 9A FF C7 C7 C7 FF B0 B0'
+ 'B0 FF BA BA BA FF C1 C1 C1 FF A9 A9 A9 FF C5 C5'
+ 'C5 E1 00 00 00 00 00 00 00 00 87 87 87 A0 96 96'
+ '96 FF 97 97 97 FF 93 93 93 FF 6B 6B 6B FF 53 53'
+ '53 FF 76 76 76 FF 95 95 95 FF 8D 8D 8D FF 78 78'
+ '78 FF 81 81 81 FF 81 81 81 FF 83 83 83 FF 84 84'
+ '84 FF 85 85 85 FF 85 85 85 FF 86 86 86 FF 86 86'
+ '86 FF 88 88 88 FF 89 89 89 FF 89 89 89 FF 89 89'
+ '89 FF 8A 8A 8A FF 8B 8B 8B FF 8B 8B 8B FF 8A 8A'
+ '8A FF 8B 8B 8B FF 8C 8C 8C FF 8C 8C 8C FF 8C 8C'
+ '8C FF 8C 8C 8C FF 8B 8B 8B FF 8B 8B 8B FF 8B 8B'
+ '8B FF 8B 8B 8B FF 8B 8B 8B FF 8B 8B 8B FF 8B 8B'
+ '8B FF 8A 8A 8A FF 8B 8B 8B FF 8A 8A 8A FF 89 89'
+ '89 FF 89 89 89 FF 89 89 89 FF 89 89 89 FF 89 89'
+ '89 FF 89 89 89 FF 89 89 89 FF 89 89 89 FF 8A 8A'
+ '8A FF 89 89 89 FF 89 89 89 FF 96 96 96 FF 94 94'
+ '94 FF B5 B5 B5 FF D7 D7 D7 FF 97 97 97 FF B9 B9'
+ 'B9 FF B3 B3 B3 FF 9D 9D 9D FF 97 97 97 FF 8C 8C'
+ '8C 66 00 00 00 00 00 00 00 00 73 73 73 2C 92 92'
+ '92 FD 89 89 89 FF 50 50 50 FF 5C 5C 5C FF 87 87'
+ '87 FF 94 94 94 FF 80 80 80 FF 77 77 77 FF 9A 9A'
+ '9A FF A1 A1 A1 FF A3 A3 A3 FF A5 A5 A5 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A7 A7 A7 FF A9 A9 A9 FF A9 A9'
+ 'A9 FF AA AA AA FF AB AB AB FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B4 B4 B4 FF B5 B5 B5 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8'
+ 'B8 FF B8 B8 B8 FF B9 B9 B9 FF B9 B9 B9 FF BA BA'
+ 'BA FF BA BA BA FF BB BB BB FF BB BB BB FF BB BB'
+ 'BB FF BB BB BB FF BC BC BC FF BC BC BC FF BD BD'
+ 'BD FF BD BD BD FF A6 A6 A6 FF 93 93 93 FF AB AB'
+ 'AB FF 94 94 94 FF 9D 9D 9D FF D2 D2 D2 FF A5 A5'
+ 'A5 FF A1 A1 A1 FF A3 A3 A3 FF 8E 8E 8E DC 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 89 89'
+ '89 B4 7D 7D 7D FF 52 52 52 FF 91 91 91 FF 92 92'
+ '92 FF 74 74 74 FF 86 86 86 FF 9C 9C 9C FF A0 A0'
+ 'A0 FF A2 A2 A2 FF A3 A3 A3 FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AA AA AA FF AB AB AB FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8'
+ 'B8 FF B8 B8 B8 FF B9 B9 B9 FF BA BA BA FF BB BB'
+ 'BB FF BB BB BB FF BC BC BC FF BD BD BD FF BD BD'
+ 'BD FF BE BE BE FF BE BE BE FF BF BF BF FF BF BF'
+ 'BF FF C0 C0 C0 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF C1 C1 C1 FF C1 C1 C1 FF B3 B3 B3 FF 8B 8B'
+ '8B FF 9F 9F 9F FF 9E 9E 9E FF 93 93 93 FF B6 B6'
+ 'B6 FF 93 93 93 FF 9A 9A 9A FE 8A 8A 8A 5E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 7B'
+ '7B 3E 8E 8E 8E FE 68 68 68 FF 9F 9F 9F FF 85 85'
+ '85 FF 93 93 93 FF 9C 9C 9C FF A1 A1 A1 FF A2 A2'
+ 'A2 FF A3 A3 A3 FF A4 A4 A4 FF A5 A5 A5 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9 A9 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AD AD AD FF AE AE'
+ 'AE FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2'
+ 'B2 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8 B8 FF B8 B8'
+ 'B8 FF B9 B9 B9 FF BA BA BA FF BB BB BB FF BB BB'
+ 'BB FF BC BC BC FF BD BD BD FF BE BE BE FF BE BE'
+ 'BE FF BF BF BF FF BF BF BF FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF C2 C2 C2 FF C3 C3 C3 FF C3 C3 C3 FF C0 C0'
+ 'C0 FF 9C 9C 9C FF 90 90 90 FF 99 99 99 FF 91 91'
+ '91 FF 92 92 92 FF 8E 8E 8E D6 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 86 86 86 C7 74 74 74 FF 93 93 93 FF 99 99'
+ '99 FF 96 96 96 FF A0 A0 A0 FF A1 A1 A1 FF A2 A2'
+ 'A2 FF A3 A3 A3 FF A4 A4 A4 FF A5 A5 A5 FF A6 A6'
+ 'A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9 A9 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AD AD AD FF AE AE'
+ 'AE FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2'
+ 'B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B8 B8 B8 FF B8 B8 B8 FF B9 B9'
+ 'B9 FF BA BA BA FF BB BB BB FF BC BC BC FF BC BC'
+ 'BC FF BD BD BD FF BE BE BE FF BE BE BE FF BF BF'
+ 'BF FF C0 C0 C0 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3 C3 FF C3 C3'
+ 'C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF A2 A2 A2 FF 96 96 96 FF 90 90'
+ '90 FF 93 93 93 FE 8B 8B 8B 56 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 82 82 82 52 8A 8A 8A FE 78 78 78 FF A4 A4'
+ 'A4 FF 8B 8B 8B FF A1 A1 A1 FF A2 A2 A2 FF A3 A3'
+ 'A3 FF A4 A4 A4 FF A5 A5 A5 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF A8 A8 A8 FF A9 A9 A9 FF AA AA AA FF AB AB'
+ 'AB FF AC AC AC FF AD AD AD FF AE AE AE FF AF AF'
+ 'AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3'
+ 'B3 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9 B9 FF BA BA'
+ 'BA FF BB BB BB FF BC BC BC FF BD BD BD FF BD BD'
+ 'BD FF BE BE BE FF BF BF BF FF BF BF BF FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C5 C5 C5 FF C5 C5 C5 FF C5 C5'
+ 'C5 FF C5 C5 C5 FF 96 96 96 FF 96 96 96 FF 92 92'
+ '92 FF 91 91 91 D0 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 8A 8A 8A D9 75 75 75 FF 9C 9C'
+ '9C FF 91 91 91 FF 9F 9F 9F FF A2 A2 A2 FF A3 A3'
+ 'A3 FF A4 A4 A4 FF A5 A5 A5 FF A6 A6 A6 FF A7 A7'
+ 'A7 FF A9 A9 A9 FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF B8 B8 B8 FF B9 B9 B9 FF BA BA BA FF BB BB'
+ 'BB FF BC BC BC FF BD BD BD FF BD BD BD FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C0 C0 C0 FF C1 C1'
+ 'C1 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C5 C5 C5 FF C5 C5 C5 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF B3 B3 B3 FF 92 92 92 FF 90 90 90 FF 95 95'
+ '95 FE 8F 8F 8F 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 87 87 87 66 87 87 87 FF 82 82'
+ '82 FF 9B 9B 9B FF 93 93 93 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A5 A5 A5 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF AA AA AA FF AB AB AB FF AC AC'
+ 'AC FF AD AD AD FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8'
+ 'B8 FF B9 B9 B9 FF BA BA BA FF BB BB BB FF BC BC'
+ 'BC FF BC BC BC FF BD BD BD FF BE BE BE FF BF BF'
+ 'BF FF C0 C0 C0 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4 C4 FF C5 C5'
+ 'C5 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C7 C7 C7 FF C7 C7 C7 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF 9B 9B 9B FF 93 93 93 FF 94 94 94 FF 91 91'
+ '91 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 91 91 91 E7 79 79'
+ '79 FF 9E 9E 9E FF 90 90 90 FF A3 A3 A3 FF A4 A4'
+ 'A4 FF A5 A5 A5 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF AA AA AA FF AB AB AB FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF C2 C2 C2 FF D1 D1 D1 FF D9 D9'
+ 'D9 FF DB DB DB FF D9 D9 D9 FF D4 D4 D4 FF CE CE'
+ 'CE FF C3 C3 C3 FF BA BA BA FF BE BE BE FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C7 C7 C7 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C8 C8 C8 FF C8 C8 C8 FF C8 C8 C8 FF BC BC'
+ 'BC FF 90 90 90 FF 94 94 94 FF 96 96 96 FE 8E 8E'
+ '8E 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 8F 8F 8F 79 89 89'
+ '89 FF 8D 8D 8D FF 97 97 97 FF A1 A1 A1 FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AA AA AA FF AB AB AB FF AC AC AC FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B3 B3 B3 FF B0 B0 B0 FF B1 B1 B1 FF B9 B9'
+ 'B9 FF C2 C2 C2 FF C5 C5 C5 FF BF BF BF FF B9 B9'
+ 'B9 FF B6 B6 B6 FF B6 B6 B6 FF B9 B9 B9 FF BF BF'
+ 'BF FF CB CB CB FF DB DB DB FF D7 D7 D7 FF BB BB'
+ 'BB FF BC BC BC FF C2 C2 C2 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C7 C7 C7 FF C8 C8 C8 FF C8 C8 C8 FF C9 C9'
+ 'C9 FF C9 C9 C9 FF C9 C9 C9 FF CA CA CA FF A6 A6'
+ 'A6 FF 93 93 93 FF 96 96 96 FF 99 99 99 C1 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 87 87 87 11 93 93'
+ '93 F2 7F 7F 7F FF 9F 9F 9F FF 9B 9B 9B FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9'
+ 'A9 FF AA AA AA FF AB AB AB FF AD AD AD FF AE AE'
+ 'AE FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2'
+ 'B2 FF A9 A9 A9 FF A5 A5 A5 FF B1 B1 B1 FF B4 B4'
+ 'B4 FF B6 B6 B6 FF B8 B8 B8 FF B9 B9 B9 FF BA BA'
+ 'BA FF BB BB BB FF BC BC BC FF BD BD BD FF BE BE'
+ 'BE FF BE BE BE FF B8 B8 B8 FF B8 B8 B8 FF CE CE'
+ 'CE FF B5 B5 B5 FF B6 B6 B6 FF C4 C4 C4 FF C5 C5'
+ 'C5 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7 C7 FF C7 C7'
+ 'C7 FF C8 C8 C8 FF C9 C9 C9 FF C9 C9 C9 FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF C6 C6 C6 FF 95 95'
+ '95 FF 95 95 95 FF 9B 9B 9B FE 99 99 99 3F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 96 96'
+ '96 8D 89 89 89 FF 98 98 98 FF 9B 9B 9B FF A5 A5'
+ 'A5 FF A6 A6 A6 FF A8 A8 A8 FF A9 A9 A9 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AD AD AD FF AE AE'
+ 'AE FF AF AF AF FF B0 B0 B0 FF B1 B1 B1 FF AC AC'
+ 'AC FF 9C 9C 9C FF AE AE AE FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B9 B9 B9 FF BA BA BA FF BA BA'
+ 'BA FF BC BC BC FF BD BD BD FF BD BD BD FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF BB BB'
+ 'BB FF B4 B4 B4 FF A8 A8 A8 FF BC BC BC FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8 C8 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CB CB'
+ 'CB FF CB CB CB FF CC CC CC FF B2 B2 B2 FF 96 96'
+ '96 FF 98 98 98 FF 9D 9D 9D BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 95'
+ '95 1D 97 97 97 F9 8E 8E 8E FF A1 A1 A1 FF A0 A0'
+ 'A0 FF A7 A7 A7 FF A8 A8 A8 FF A9 A9 A9 FF AA AA'
+ 'AA FF AB AB AB FF AC AC AC FF AD AD AD FF AE AE'
+ 'AE FF B0 B0 B0 FF B1 B1 B1 FF B2 B2 B2 FF A6 A6'
+ 'A6 FF A1 A1 A1 FF B5 B5 B5 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF B8 B8 B8 FF B9 B9 B9 FF BA BA BA FF BB BB'
+ 'BB FF BC BC BC FF BD BD BD FF BE BE BE FF BF BF'
+ 'BF FF C0 C0 C0 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF B2 B2 B2 FF AA AA AA FF AC AC AC FF C6 C6'
+ 'C6 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9 C9 FF C9 C9'
+ 'C9 FF CA CA CA FF CB CB CB FF CB CB CB FF CC CC'
+ 'CC FF CC CC CC FF CA CA CA FF 9E 9E 9E FF 9B 9B'
+ '9B FF 9D 9D 9D FE 9D 9D 9D 37 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 9B 9B 9B A1 95 95 95 FF A0 A0 A0 FF 9E 9E'
+ '9E FF A7 A7 A7 FF A8 A8 A8 FF A9 A9 A9 FF AB AB'
+ 'AB FF AC AC AC FF AD AD AD FF AE AE AE FF AF AF'
+ 'AF FF B0 B0 B0 FF B1 B1 B1 FF B2 B2 B2 FF A4 A4'
+ 'A4 FF A3 A3 A3 FF B2 B2 B2 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF B9 B9 B9 FF BA BA BA FF BB BB BB FF BC BC'
+ 'BC FF BD BD BD FF BE BE BE FF BF BF BF FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3 C3 FF C0 C0'
+ 'C0 FF AB AB AB FF 92 92 92 FF BB BB BB FF C7 C7'
+ 'C7 FF C8 C8 C8 FF C9 C9 C9 FF CA CA CA FF CA CA'
+ 'CA FF CB CB CB FF CC CC CC FF CC CC CC FF CD CD'
+ 'CD FF CD CD CD FF B6 B6 B6 FF 99 99 99 FF 9F 9F'
+ '9F FF 9F 9F 9F B2 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 9E 9E 9E 2D 9A 9A 9A FD 9A 9A 9A FF A4 A4'
+ 'A4 FF A3 A3 A3 FF A9 A9 A9 FF AA AA AA FF AB AB'
+ 'AB FF AC AC AC FF AD AD AD FF AE AE AE FF AF AF'
+ 'AF FF B0 B0 B0 FF B1 B1 B1 FF B3 B3 B3 FF B3 B3'
+ 'B3 FF A6 A6 A6 FF A3 A3 A3 FF AD AD AD FF B6 B6'
+ 'B6 FF B9 B9 B9 FF BA BA BA FF BB BB BB FF BC BC'
+ 'BC FF BD BD BD FF BE BE BE FF BF BF BF FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C0 C0 C0 FF B6 B6 B6 FF A0 A0'
+ 'A0 FF 87 87 87 FF AD AD AD FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CB CB'
+ 'CB FF CC CC CC FF CD CD CD FF CD CD CD FF CE CE'
+ 'CE FF C2 C2 C2 FF 9D 9D 9D FF A0 A0 A0 FF A0 A0'
+ 'A0 FD 9F 9F 9F 30 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 9C 9C 9C B5 9A 9A 9A FF 9D 9D'
+ '9D FF A8 A8 A8 FF A6 A6 A6 FF AA AA AA FF AB AB'
+ 'AB FF AC AC AC FF AD AD AD FF AE AE AE FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B6 B6 B6 FF AE AE AE FF A0 A0'
+ 'A0 FF A6 A6 A6 FF AD AD AD FF B2 B2 B2 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B6 B6 B6 FF B4 B4 B4 FF B0 B0'
+ 'B0 FF A8 A8 A8 FF 95 95 95 FF 8D 8D 8D FF 9C 9C'
+ '9C FF C1 C1 C1 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9'
+ 'C9 FF C9 C9 C9 FF CA CA CA FF CB CB CB FF CC CC'
+ 'CC FF CD CD CD FF CE CE CE FF CE CE CE FF BF BF'
+ 'BF FF A5 A5 A5 FF A1 A1 A1 FF 9F 9F 9F FF 9D 9D'
+ '9D AA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A4 A4 A4 2D 90 90 90 F1 94 94'
+ '94 FF 9D 9D 9D FF A9 A9 A9 FF AA AA AA FF AB AB'
+ 'AB FF AD AD AD FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4'
+ 'B4 FF B5 B5 B5 FF B6 B6 B6 FF B8 B8 B8 FF BB BB'
+ 'BB FF B0 B0 B0 FF A7 A7 A7 FF A1 A1 A1 FF 9D 9D'
+ '9D FF 9C 9C 9C FF 9D 9D 9D FF A1 A1 A1 FF A5 A5'
+ 'A5 FF AA AA AA FF B9 B9 B9 FF C5 C5 C5 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9'
+ 'C9 FF CA CA CA FF CB CB CB FF CC CC CC FF CD CD'
+ 'CD FF CE CE CE FF CC CC CC FF B7 B7 B7 FF A6 A6'
+ 'A6 FF 9B 9B 9B FF 9D 9D 9D FF A0 A0 A0 EB 97 97'
+ '97 1B 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A7 A7 A7 AC 9C 9C'
+ '9C FF 9B 9B 9B FF 98 98 98 FF 92 92 92 FF A9 A9'
+ 'A9 FF AB AB AB FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B1 B1 B1 FF B2 B2 B2 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9'
+ 'B9 FF BA BA BA FF BB BB BB FF BC BC BC FF BD BD'
+ 'BD FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6'
+ 'C6 FF C7 C7 C7 FF C8 C8 C8 FF C9 C9 C9 FF CA CA'
+ 'CA FF CB CB CB FF CC CC CC FF CD CD CD FF CE CE'
+ 'CE FF C2 C2 C2 FF A6 A6 A6 FF A7 A7 A7 FF A8 A8'
+ 'A8 FF A9 A9 A9 FF A0 A0 A0 FF AD AD AD 8D 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A7 A7 A7 4F 9D 9D'
+ '9D FE 87 87 87 FF 7A 7A 7A FF 64 64 64 FF A0 A0'
+ 'A0 FF 9F 9F 9F FF AE AE AE FF AF AF AF FF B0 B0'
+ 'B0 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9'
+ 'B9 FF BA BA BA FF BC BC BC FF BD BD BD FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6'
+ 'C6 FF C7 C7 C7 FF C8 C8 C8 FF CA CA CA FF CB CB'
+ 'CB FF CC CC CC FF CC CC CC FF CD CD CD FF CE CE'
+ 'CE FF A9 A9 A9 FF A3 A3 A3 FF B6 B6 B6 FF DA DA'
+ 'DA FF B0 B0 B0 FF A0 A0 A0 F6 A1 A1 A1 1E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A5 A5'
+ 'A5 CC 7F 7F 7F FF 96 96 96 FF 86 86 86 FF 8E 8E'
+ '8E FF AB AB AB FF AE AE AE FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B7 B7 B7 FF B9 B9 B9 FF BA BA'
+ 'BA FF BB BB BB FF BC BC BC FF BD BD BD FF BE BE'
+ 'BE FF BF BF BF FF C0 C0 C0 FF C1 C1 C1 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C8 C8 C8 FF C9 C9 C9 FF CA CA CA FF CB CB'
+ 'CB FF CC CC CC FF CD CD CD FF CE CE CE FF CF CF'
+ 'CF FF C8 C8 C8 FF B4 B4 B4 FF B1 B1 B1 FF C6 C6'
+ 'C6 FF A6 A6 A6 FF A6 A6 A6 8A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 AC AC'
+ 'AC 4D A0 A0 A0 FE A0 A0 A0 FF A7 A7 A7 FF AC AC'
+ 'AC FF AD AD AD FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5'
+ 'B5 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9 B9 FF BA BA'
+ 'BA FF BB BB BB FF BC BC BC FF BD BD BD FF BE BE'
+ 'BE FF C0 C0 C0 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF C8 C8 C8 FF C9 C9 C9 FF CB CB CB FF CC CC'
+ 'CC FF CD CD CD FF CE CE CE FF CF CF CF FF D0 D0'
+ 'D0 FF D1 D1 D1 FF D2 D2 D2 FF B3 B3 B3 FF A0 A0'
+ 'A0 FF AC AC AC ED B4 B4 B4 11 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 A7 A7 A7 CB 9F 9F 9F FF A8 A8 A8 FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B4 B4 B4 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B8 B8 B8 FF B9 B9 B9 FF BD BD'
+ 'BD FF C2 C2 C2 FF C0 C0 C0 FF C1 C1 C1 FF BF BF'
+ 'BF FF C0 C0 C0 FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C5 C5 C5 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CB CB CB FF CC CC'
+ 'CC FF CD CD CD FF CE CE CE FF CF CF CF FF D0 D0'
+ 'D0 FF D1 D1 D1 FF CE CE CE FF A5 A5 A5 FF AC AC'
+ 'AC FF AC AC AC 75 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 AB AB AB 4C A4 A4 A4 FE A8 A8 A8 FF AC AC'
+ 'AC FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B3 B3 B3 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B5 B5 B5 FF AC AC AC FF BA BA BA FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C2 C2 C2 FF BF BF BF FF B8 B8'
+ 'B8 FF BD BD BD FF C1 C1 C1 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CB CB CB FF CC CC'
+ 'CC FF CD CD CD FF CF CF CF FF D0 D0 D0 FF D1 D1'
+ 'D1 FF D2 D2 D2 FF BE BE BE FF A9 A9 A9 FF AF AF'
+ 'AF E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 AA AA AA CA A7 A7 A7 FF AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B2 B2 B2 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B5 B5 B5 FF AB AB AB FF B2 B2 B2 FF B6 B6'
+ 'B6 FF BB BB BB FF BA BA BA FF B0 B0 B0 FF A4 A4'
+ 'A4 FF BA BA BA FF C1 C1 C1 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF CA CA CA FF CC CC CC FF CD CD'
+ 'CD FF CE CE CE FF CF CF CF FF D0 D0 D0 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF AE AE AE FF B0 B0 B0 FE B1 B1'
+ 'B1 5F 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 AD AD AD 4B A8 A8 A8 FE AD AD'
+ 'AD FF AE AE AE FF AF AF AF FF B0 B0 B0 FF B1 B1'
+ 'B1 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B8 B8 B8 FF BA BA BA FF B7 B7'
+ 'B7 FF B5 B5 B5 FF B7 B7 B7 FF BD BD BD FF BF BF'
+ 'BF FF C0 C0 C0 FF C1 C1 C1 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF CA CA CA FF CB CB CB FF CC CC CC FF CD CD'
+ 'CD FF CE CE CE FF CF CF CF FF D0 D0 D0 FF D1 D1'
+ 'D1 FF C5 C5 C5 FF AD AD AD FF B4 B4 B4 D1 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 B1 B1 B1 C9 AC AC'
+ 'AC FF B3 B3 B3 FF B4 B4 B4 FF B1 B1 B1 FF B2 B2'
+ 'B2 FF B3 B3 B3 FF B4 B4 B4 FF B5 B5 B5 FF B6 B6'
+ 'B6 FF B7 B7 B7 FF B8 B8 B8 FF BA BA BA FF BB BB'
+ 'BB FF BC BC BC FF BD BD BD FF BE BE BE FF BF BF'
+ 'BF FF C0 C0 C0 FF C2 C2 C2 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C5 C5 C5 FF C6 C6 C6 FF C7 C7 C7 FF C8 C8'
+ 'C8 FF CA CA CA FF CB CB CB FF CC CC CC FF CD CD'
+ 'CD FF CE CE CE FF CF CF CF FF D0 D0 D0 FF CB CB'
+ 'CB FF B0 B0 B0 FF B1 B1 B1 FE B5 B5 B5 49 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 AD AD AD 1C A0 A0'
+ 'A0 91 B4 B4 B4 74 B6 B6 B6 9A B6 B6 B6 9E B4 B4'
+ 'B4 C7 B5 B5 B5 E8 B7 B7 B7 E8 B8 B8 B8 E8 B9 B9'
+ 'B9 E8 BA BA BA E8 BB BB BB E8 BD BD BD E8 BE BE'
+ 'BE E8 BF BF BF E8 C0 C0 C0 E8 C1 C1 C1 E8 C1 C1'
+ 'C1 E8 C2 C2 C2 E8 C3 C3 C3 E8 C4 C4 C4 E8 C5 C5'
+ 'C5 E8 C6 C6 C6 E8 C8 C8 C8 E8 C9 C9 C9 E8 CA CA'
+ 'CA E8 CB CB CB E8 CC CC CC E8 CD CD CD E8 CD CD'
+ 'CD E8 CB CB CB E7 C2 C2 C2 AD B8 B8 B8 9F B7 B7'
+ 'B7 8C A6 A6 A6 96 B9 B9 B9 54 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 01 80 00 00 00 00 00 00 01 80 00'
+ '00 00 00 00 00 03 C0 00 00 00 00 00 00 03 C0 00'
+ '00 00 00 00 00 07 E0 00 00 00 00 00 00 07 E0 00'
+ '00 00 00 00 00 0F F0 00 00 00 00 00 00 0F F0 00'
+ '00 00 00 00 00 1F F8 00 00 00 00 00 00 1F F8 00'
+ '00 00 00 00 00 3F F8 00 00 00 00 00 00 3F FC 00'
+ '00 00 00 00 00 7F FC 00 00 00 00 00 00 7F FE 00'
+ '00 00 00 00 00 FF FE 00 00 00 00 00 00 FF FF 00'
+ '00 00 00 00 01 FF FF 00 00 00 00 00 01 FF FF 80'
+ '00 00 00 00 03 FF FF 80 00 00 00 00 03 FF FF C0'
+ '00 00 00 00 07 FF FF C0 00 00 00 00 07 FF FF E0'
+ '00 00 00 00 0F FF FF E0 00 00 00 00 1F FF FF F0'
+ '00 00 00 00 1F FF FF F0 00 00 00 00 3F FF FF F8'
+ '00 00 00 00 3F FF FF F8 00 00 00 00 7F FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF'
+} */
+
+/* BINRES netdrive.ico */
+9 ICON netdrive.ico
+/* {
+ '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 3E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
+ '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
+ '00 00 8E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
+ '00 00 5E 21 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 C6 27 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 6E 4D 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 02 02 02 00 04 04 04 00 05 06 06 00 06 06'
+ '06 00 09 09 09 00 0A 0A 0A 00 0C 0C 0C 00 12 12'
+ '12 00 14 14 14 00 15 15 15 00 16 16 16 00 1D 1D'
+ '1D 00 1F 1F 1F 00 21 21 21 00 22 22 22 00 23 23'
+ '23 00 24 24 24 00 25 25 25 00 26 26 26 00 38 38'
+ '38 00 39 39 39 00 3B 3B 3B 00 00 67 67 00 43 43'
+ '43 00 46 46 46 00 4A 4A 4A 00 54 4C 50 00 53 53'
+ '53 00 55 55 55 00 56 56 56 00 58 58 58 00 59 59'
+ '59 00 5A 58 59 00 5A 5A 5A 00 5B 5B 5B 00 5C 5C'
+ '5C 00 5D 5D 5D 00 5E 5E 5E 00 65 58 5F 00 60 60'
+ '60 00 61 61 61 00 62 62 62 00 64 64 64 00 67 67'
+ '67 00 69 69 69 00 71 71 71 00 72 72 72 00 73 73'
+ '73 00 75 75 75 00 78 78 78 00 7A 7A 7A 00 7B 7B'
+ '7B 00 7C 7C 7C 00 7F 7F 7F 00 24 A7 64 00 3C AD'
+ '74 00 25 DC 7F 00 7D AA 94 00 18 FF FF 00 56 D8'
+ 'D8 00 81 81 81 00 83 83 83 00 89 89 89 00 8A 8A'
+ '8A 00 8B 8B 8B 00 8F 8F 8F 00 91 89 8C 00 90 90'
+ '90 00 91 91 91 00 94 94 94 00 95 95 95 00 97 97'
+ '97 00 99 99 99 00 9A 9A 9A 00 9C 9C 9C 00 9D 9D'
+ '9D 00 9E 9E 9E 00 9F 9F 9F 00 A0 91 91 00 94 B6'
+ 'A4 00 93 BD A9 00 A0 A0 A0 00 A1 A1 A1 00 A3 A3'
+ 'A3 00 A4 A4 A4 00 A5 A5 A5 00 A8 A8 A8 00 A9 A9'
+ 'A9 00 AA AA AA 00 AC AC AC 00 AD AD AD 00 AE AE'
+ 'AE 00 AF AF AF 00 B7 AF AF 00 AD B9 B3 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
+ 'B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B9 B9'
+ 'B9 00 BC BC BC 00 BD BD BD 00 BE BE BE 00 BF BF'
+ 'BF 00 89 CF CF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C0'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C2 00 C5 C2'
+ 'C4 00 C4 C4 C4 00 C5 C5 C5 00 C6 C5 C6 00 C6 C6'
+ 'C6 00 C8 C3 C5 00 CC C4 C8 00 C8 C8 C8 00 C9 C9'
+ 'C9 00 CB C9 CA 00 CA CA CA 00 CB CB CB 00 CC CC'
+ 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D2 C1'
+ 'CA 00 D3 C8 CD 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
+ 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
+ 'DA 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
+ 'DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
+ 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
+ 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
+ 'EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2'
+ 'F2 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7'
+ 'F7 00 F8 F8 F8 00 F9 F9 F9 00 FC FC FC 00 FD FD'
+ 'FD 00 FF FF FF 00 00 00 00 00 62 00 1A 02 40 9F'
+ '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
+ 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
+ '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
+ '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
+ '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
+ '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
+ 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
+ '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
+ '68 65 6C 6C 33 32 5C 6E 65 74 64 72 69 76 65 2E'
+ '69 63 6F 00 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
+ '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
+ 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
+ '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
+ '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
+ '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
+ 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
+ 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 B2 B2'
+ 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 17 17 B2'
+ 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 62 62'
+ '62 62 62 62 62 62 62 62 62 62 62 5E 6D 3B 3B 6D'
+ '5E 62 62 62 62 62 62 62 62 62 62 62 62 62 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 3C 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 4F 4F 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 0D 0D B2'
+ 'B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 00 00 00 00 00 00'
+ '00 B2 B2 09 26 26 2C 2B 2A 28 26 25 24 1E 1D 22'
+ '20 1F 1F 1F 1E 21 27 1B 05 B2 B2 00 00 00 00 00'
+ '00 B2 09 6E AA A0 58 64 68 6F 86 88 8C 8D 92 92'
+ '91 93 90 8E 82 79 38 51 43 03 B2 00 00 00 00 00'
+ '00 B2 1E AC 9C 9A 0C 1A 33 41 4C 54 5D 59 4E 4B'
+ '59 66 56 48 85 3A 39 37 84 13 B2 00 00 00 00 00'
+ '00 B2 25 A8 9D 99 1C 34 40 46 54 58 64 59 47 44'
+ '52 60 4A 3F 7D 70 50 5F 73 13 B2 00 00 00 00 00'
+ '00 B2 23 A9 9F 9E 24 2F 3E 42 4E 56 63 53 32 2E'
+ '41 52 3D 2C 7F 77 7A 74 6E 12 B2 00 00 00 00 00'
+ '00 B2 23 AB A2 9E 3D 44 4A 52 58 5B 64 5A 4B 49'
+ '54 5C 4C 45 7B 76 6F 6F 72 11 B2 00 00 00 00 00'
+ '00 B2 22 AD A6 A5 AF AE AA A8 A4 A2 9F 9D A0 9E'
+ '9A 96 96 96 8C 8A 88 7F 75 10 B2 00 00 00 00 00'
+ '00 B2 20 B1 A5 A3 A2 9D 9D 9C 9D 9D 9E 9D 9D 9D'
+ '9D 9D 9D 9C 9F A3 A2 AE 8B 0E B2 00 00 00 00 00'
+ '00 B2 25 B1 78 61 69 8E 8D 8D 8D 8D 8C 8C 8C 8C'
+ '8D 8D 8D 8E 87 65 65 8C AB 13 B2 00 00 00 00 00'
+ '00 B2 18 B1 5D 67 57 87 8D 8B 89 87 8A 8B 8B 8A'
+ '87 88 8A 90 68 62 58 7B 9E 0C B2 00 00 00 00 00'
+ '00 B2 10 9E 82 86 78 86 82 8F 9A 99 9C A0 A0 9D'
+ '9A 9B 91 83 83 83 75 8E 6B 06 B2 00 00 00 00 00'
+ '00 B2 08 87 87 80 81 81 9F 9C 90 8E 8D 8C 8C 8D'
+ '8E 91 9C 9F 86 7E 81 98 48 B2 B2 00 00 00 00 00'
+ '00 B2 01 55 8E 7C 81 9B 89 82 86 86 83 86 86 86'
+ '86 86 81 83 9C 83 78 9F 29 B2 B2 00 00 00 00 00'
+ '00 B2 B2 31 9A 7C 90 88 82 86 83 86 81 7E 7F 7F'
+ '7F 7F 7F 7E 80 90 72 A5 15 B2 B2 00 00 00 00 00'
+ '00 00 B2 19 A0 83 8E 82 86 86 86 86 86 80 71 72'
+ '75 76 76 76 72 81 76 A1 0A B2 00 00 00 00 00 00'
+ '00 00 B2 0F A4 87 87 88 87 87 87 87 87 88 81 75'
+ '6E 6C 6B 6E 6E 6E 78 8C 01 B2 00 00 00 00 00 00'
+ '00 00 B2 02 94 8F 80 8E 8C 8D 8D 8D 8D 8D 8D 8E'
+ '8D 8A 86 80 7C 67 7C 63 B2 B2 00 00 00 00 00 00'
+ '00 00 B2 B2 76 99 89 89 94 92 91 91 91 91 91 91'
+ '92 92 93 95 8C 89 93 3F B2 B2 00 00 00 00 00 00'
+ '00 00 00 B2 45 9C 99 8B 8C 96 99 97 97 97 97 97'
+ '97 99 95 8E 88 9D 8E 1F B2 00 00 00 00 00 00 00'
+ '00 00 00 B2 2C 9C 9D 9D 95 87 8F 98 99 9A 9A 99'
+ '98 8F 87 95 9E A1 82 14 B2 00 00 00 00 00 00 00'
+ '00 00 00 B2 16 93 A0 8F A2 A4 9C 98 97 94 94 97'
+ '98 9A A4 9A 91 A7 78 0C B2 00 00 00 00 00 00 00'
+ '00 00 00 B2 13 94 6F 5B 76 A8 A6 A6 A6 A5 A5 A6'
+ 'A6 A6 A3 65 5B 9D 6A 0B B2 00 00 00 00 00 00 00'
+ '00 00 00 B2 07 4D A2 9A AB B0 AF AF AF AF AF AF'
+ 'AF AF AF A7 9C 9B 30 B2 B2 00 00 00 00 00 00 00'
+ '00 00 00 B2 B2 0B 31 34 33 32 32 32 32 32 32 32'
+ '32 32 32 33 35 2D 04 B2 00 00 00 00 00 00 00 00'
+ '00 00 00 00 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2 B2'
+ 'B2 B2 B2 B2 B2 B2 B2 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF 00 00 00 00 00 00 00 00 FF FE 7F FF FF FE'
+ '7F FF F0 00 00 0F E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
+ '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 0C 0C 0C 00 15 15'
+ '15 00 1F 12 12 00 19 19 19 00 25 20 22 00 29 29'
+ '29 00 35 35 35 00 3E 3E 3E 00 40 40 40 00 57 57'
+ '57 00 6D 6D 6D 00 73 73 73 00 75 75 75 00 78 78'
+ '78 00 7B 7B 7B 00 7D 7D 7D 00 7F 7F 7F 00 89 7D'
+ '7D 00 66 8E 7A 00 86 7B 81 00 5E CA 93 00 4F D8'
+ 'D8 00 85 85 85 00 8C 8C 8C 00 8F 8F 8F 00 90 90'
+ '90 00 91 91 91 00 97 97 97 00 98 95 97 00 99 99'
+ '99 00 9B 9A 9B 00 9B 9B 9B 00 9F 9F 9F 00 A1 A1'
+ 'A1 00 A3 A3 A3 00 A5 A5 A5 00 A9 A9 A9 00 AC AC'
+ 'AC 00 AE AE AE 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
+ 'B4 00 B6 B6 B6 00 B8 B8 B8 00 BA BA BA 00 BF BF'
+ 'BF 00 C1 C1 C1 00 C2 C2 C2 00 C0 C7 C4 00 C4 C4'
+ 'C4 00 C7 C7 C7 00 CB C9 CA 00 CA CA CA 00 CC CC'
+ 'CC 00 CD CD CD 00 CF CF CF 00 D4 C9 CF 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DF DF'
+ 'DF 00 E0 E0 E0 00 E1 E1 E1 00 E3 E3 E3 00 E4 E4'
+ 'E4 00 E6 E6 E6 00 E7 E7 E7 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EC EC EC 00 ED ED ED 00 EF EF EF 00 F0 F0'
+ 'F0 00 F3 F3 F3 00 F4 F4 F4 00 F7 F7 F7 00 FC FC'
+ 'FC 00 00 00 00 00 A9 A9 A9 00 AA AA AA 00 AC AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B7 AF'
+ 'AF 00 AD B9 B3 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
+ 'B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6'
+ 'B6 00 B7 B7 B7 00 B9 B9 B9 00 BC BC BC 00 BD BD'
+ 'BD 00 BE BE BE 00 BF BF BF 00 89 CF CF 00 C0 C0'
+ 'C0 00 C1 C1 C1 00 C2 C0 C1 00 C2 C2 C2 00 C3 C3'
+ 'C3 00 C4 C1 C2 00 C5 C2 C4 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C6 C5 C6 00 C6 C6 C6 00 C8 C3 C5 00 CC C4'
+ 'C8 00 C8 C8 C8 00 C9 C9 C9 00 CB C9 CA 00 CA CA'
+ 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
+ 'CE 00 CF CF CF 00 D2 C1 CA 00 D3 C8 CD 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
+ 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
+ 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
+ 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
+ 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
+ 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F4 F4 F4 00 F5 F5'
+ 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
+ 'F9 00 FC FC FC 00 FD FD FD 00 FF FF FF 00 00 00'
+ '00 00 62 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
+ '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
+ 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 6E'
+ '65 74 64 72 69 76 65 2E 69 63 6F 00 4B 00 14 1A'
+ '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
+ '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 17 17 17 17 17 17 12 16 16 12'
+ '17 17 17 17 17 17 00 00 00 57 57 57 57 03 03 57'
+ '57 57 57 57 00 00 00 00 07 2B 1A 1C 21 20 21 23'
+ '22 1D 13 05 00 00 00 57 2B 56 08 18 25 2A 1E 29'
+ '1F 31 15 14 00 00 00 57 27 55 0B 19 24 26 10 20'
+ '0F 34 39 0D 00 00 00 57 28 56 56 54 52 4F 51 4E'
+ '4E 4A 51 0E 00 00 00 57 2A 2C 2E 40 3D 3F 3F 3E'
+ '42 2C 33 1B 00 00 00 00 11 43 35 47 47 48 48 47'
+ '48 37 46 0A 00 00 00 00 09 46 43 38 38 36 36 37'
+ '36 43 4B 04 00 00 00 00 01 50 3B 3A 3A 3A 32 2E'
+ '2E 30 48 57 00 00 00 00 57 4C 3C 45 43 43 44 44'
+ '41 36 30 57 00 00 00 00 57 2C 4F 42 46 49 49 47'
+ '43 52 1B 57 00 00 00 00 57 19 43 4F 53 51 51 53'
+ '49 4D 0C 57 00 00 00 00 00 06 2E 30 30 30 30 30'
+ '2F 2D 02 00 00 00 00 00 00 00 57 57 57 57 57 57'
+ '57 57 00 00 00 00 FF FF 00 00 00 00 00 00 E0 03'
+ '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
+ '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
+ '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 60 00 00 00 00 00 00 00 77 77'
+ '77 77 77 77 77 7E E7 77 77 77 77 77 77 77 00 00'
+ '00 00 00 00 00 0E E0 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 08 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 88 88 88 88 88 88 88 88 88 88 00 00 00 00 00'
+ '07 FF 77 77 77 77 77 77 77 77 67 80 00 00 00 00'
+ '8F FF 08 88 87 77 88 77 78 78 66 70 00 00 00 00'
+ '8F FF 88 88 77 77 88 77 88 77 77 70 00 00 00 00'
+ '8F FF 88 88 87 77 88 87 88 77 77 70 00 00 00 00'
+ '8F FF 88 87 77 77 88 77 88 77 77 70 00 00 00 00'
+ '8F FF FF FF FF FF FF FF FF 77 77 70 00 00 00 00'
+ '8F FF FF FF FF FF FF FF FF FF FF 70 00 00 00 00'
+ '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
+ '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
+ '0F 77 77 77 FF FF FF FF 77 77 77 70 00 00 00 00'
+ '07 77 77 FF 77 77 77 77 FF 77 7F 80 00 00 00 00'
+ '07 77 7F 77 77 77 77 77 77 F7 7F 80 00 00 00 00'
+ '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
+ '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
+ '00 F7 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
+ '00 77 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
+ '00 7F 77 77 77 77 77 77 77 77 78 00 00 00 00 00'
+ '00 8F F7 7F FF FF FF FF 77 7F 78 00 00 00 00 00'
+ '00 8F FF 77 7F FF FF F7 77 FF 70 00 00 00 00 00'
+ '00 07 F7 FF FF F7 7F FF FF 7F 70 00 00 00 00 00'
+ '00 07 77 7F FF FF FF FF F7 7F 70 00 00 00 00 00'
+ '00 08 FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 88 88 88 88 88 88 88 88 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF 00 00 00 00 00 00 00 00 FF FE 7F FF FF FE'
+ '7F FF F0 00 00 0F E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
+ '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
+ '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 88 88'
+ '88 8E E8 88 88 88 00 00 00 00 00 00 00 00 00 07'
+ '88 88 87 78 80 00 00 7F 08 77 87 87 88 00 00 7F'
+ '88 77 88 87 78 00 00 7F FF FF FF FF F8 00 00 77'
+ '77 77 77 77 78 00 00 87 7F FF FF F7 78 00 00 07'
+ '77 77 77 77 F0 00 00 0F 77 77 77 77 F0 00 00 0F'
+ '77 77 77 77 70 00 00 07 F7 7F FF 7F 80 00 00 08'
+ '7F FF FF FF 80 00 00 00 77 77 77 77 00 00 00 00'
+ '00 00 00 00 00 00 FF FF 00 00 00 00 00 00 E0 03'
+ '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
+ '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
+ '00 00 F0 0F 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 01 01 01 00 02 02 02 00 05 05 05 00 06 06'
+ '06 00 07 07 07 00 08 08 08 00 09 09 09 00 0B 0B'
+ '0B 00 0C 0C 0C 00 13 13 13 00 18 18 18 00 19 19'
+ '19 00 1A 1A 1A 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
+ '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
+ '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2A 2A'
+ '2A 00 2B 2B 2B 00 2C 2C 2C 00 2D 2D 2D 00 2E 2C'
+ '2D 00 2F 2F 2F 00 34 34 34 00 35 35 35 00 39 39'
+ '39 00 3B 3B 3B 00 3D 3D 3D 00 3F 3F 3F 00 40 40'
+ '40 00 41 41 41 00 42 42 42 00 47 47 47 00 48 48'
+ '48 00 49 49 49 00 4B 4B 4B 00 4F 4F 4F 00 53 53'
+ '53 00 56 56 56 00 58 58 58 00 59 59 59 00 5A 5A'
+ '5A 00 5B 5B 5B 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
+ '61 00 63 63 63 00 64 64 64 00 66 66 66 00 67 67'
+ '67 00 68 68 68 00 6A 6A 6A 00 6B 6B 6B 00 6C 6C'
+ '6C 00 70 70 70 00 71 71 71 00 72 72 72 00 73 73'
+ '73 00 74 74 74 00 75 75 75 00 76 76 76 00 77 77'
+ '77 00 78 78 78 00 79 79 79 00 7A 7A 7A 00 7C 7C'
+ '7C 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F 7F 00 2F 99'
+ '64 00 1C A8 60 00 0A BF 61 00 20 A8 63 00 51 A7'
+ '7C 00 17 CE 71 00 00 DC DC 00 00 FF FF 00 6B FF'
+ 'FF 00 80 80 80 00 81 81 81 00 83 83 83 00 84 83'
+ '84 00 85 85 85 00 87 87 87 00 88 88 88 00 8A 8A'
+ '8A 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
+ '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 94 94'
+ '94 00 97 97 97 00 98 98 98 00 99 99 99 00 9A 9A'
+ '9A 00 9C 9C 9C 00 9D 9D 9D 00 9F 9F 9F 00 83 AB'
+ '97 00 96 AB A0 00 90 AF A0 00 99 AC A2 00 95 B2'
+ 'A3 00 9D B3 A8 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2'
+ 'A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6'
+ 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
+ 'AA 00 AB AB AB 00 AD A8 AB 00 AB AC AC 00 AC AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B3 B4'
+ 'B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B4'
+ 'B6 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BB BB'
+ 'BB 00 BF BB BD 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 91 D6 B4 00 91 D8 B5 00 C3 BD'
+ 'C0 00 C2 BE C0 00 C7 BF C3 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C3 00 C4 C3'
+ 'C3 00 C4 C3 C4 00 C6 C2 C4 00 C6 C3 C4 00 C6 C3'
+ 'C5 00 C4 C4 C4 00 C5 C4 C4 00 C5 C5 C5 00 C7 C4'
+ 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C8 C9'
+ 'C9 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CC CC'
+ 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
+ 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
+ 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
+ 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
+ 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
+ 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4'
+ 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
+ 'F8 00 F9 F9 F9 00 FA FA FA 00 FC FC FC 00 FF FF'
+ 'FF 00 00 00 00 00 A9 F1 E7 77 F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
+ '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
+ '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
+ '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
+ 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
+ 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 52 52 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 55 55'
+ '55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55'
+ '55 55 55 55 52 53 53 52 55 55 55 55 55 55 55 55'
+ '55 55 55 55 55 55 55 55 55 55 55 55 55 55 9B 9B'
+ '9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B'
+ '9B 9B 9B 9B 54 54 54 54 9B 9B 9B 9B 9B 9B 9B 9B'
+ '9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 9B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 54 54 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9B 9B E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9B 9B E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 E1 E1 11 1A 19 1A 19 19 19 19 19'
+ '19 19 19 19 19 19 18 18 18 18 18 18 18 18 18 19'
+ '19 19 1C 1C 0A E1 E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 14 61 AE B1 AF B2 B1 B0 AF AD AA'
+ 'A9 A7 A5 9E 9D 9D 9E 9B 9C 95 95 92 93 8F 90 89'
+ '88 8C 81 7F 7E 35 07 E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 01 5C CF CC CB B9 59 5B 62 66 74 81'
+ '8F 9B 9E A9 AF AE AE BA AE B7 AF BB B0 B8 AA AC'
+ 'A2 71 4F 4D 6E 91 2B E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 0C AA D0 C6 CA AF 21 23 2D 3F 5A 62'
+ '6A 77 7A 80 8B 7B 69 93 67 8B 73 9E 75 93 66 A6'
+ '9A 50 51 4E 4C 98 58 01 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 17 B5 CE C8 CB B1 27 33 46 5A 60 65'
+ '72 79 7C 82 8E 76 61 8D 5C 83 64 95 65 8B 5B A0'
+ 'A4 70 96 97 6C 9F 5F 01 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 16 B5 D0 CA CB B5 39 41 4A 59 5F 65'
+ '72 79 7C 82 8F 6B 57 87 48 7A 5A 90 5C 86 46 9D'
+ 'A5 A3 6F 6D 99 A5 5E 01 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 16 B5 D2 CB CC BA 3D 3E 49 59 5F 65'
+ '72 79 7C 82 90 66 40 81 3A 72 45 8B 48 7D 38 9D'
+ 'A9 A1 A8 A2 95 A7 5E 01 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 15 B5 D3 CD CF BA 3A 3C 45 56 5C 63'
+ '69 75 78 7D 8E 61 37 77 31 66 3B 85 3D 76 2E 9C'
+ 'AB A7 9E 9D 9C A9 5F 01 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 15 B6 D6 CF CE C3 79 79 7D 82 84 87'
+ '8A 8E 8E 8F 93 8B 85 94 83 8F 85 94 84 8F 7D A7'
+ 'AB A9 A5 9E 9D AD 5F E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 14 B7 D7 CF CF CE D1 CF CD CC CA C8'
+ 'C6 C5 C3 C2 BF BF C0 BC BD BA BA B6 B6 B3 B4 AF'
+ 'AE AD AA A5 9B AE 5F E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 14 B7 DB DC DA DA DA D9 D9 D8 D8 D7'
+ 'D7 D7 D6 D6 D5 D5 D5 D4 D4 D4 D3 D3 D2 D2 D1 D1'
+ 'D1 D0 D0 CF C4 B4 5E E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 13 BA E0 CD C5 C6 C6 C4 C3 C3 C3 C3'
+ 'C3 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4'
+ 'C6 C7 C7 C7 DC D3 5D E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 13 C2 DC BD A5 90 95 BC BE BD BD BD'
+ 'BD BD BD BD BD BD BD BD BD BD BD BD BD BD BD BF'
+ 'B3 92 90 B5 C2 E0 68 E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 0F BE D7 A9 7B 8B 84 9E BE BC BC BC'
+ 'BC BC BB BB BB BB BB BB BB BB BC BC BC BC BD B6'
+ '7A 8A 85 89 BC DF 69 E1 E1 00 00 00 00 00 00 00'
+ '00 00 E1 E1 03 9D DA 92 86 9E 7D 90 BC B9 B9 B9'
+ 'B8 B7 B7 B9 BB BC BC BB B9 B7 B7 B7 B8 B9 BB AD'
+ '78 9E 87 81 BA D9 43 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 76 D8 B3 A7 B6 95 AD B7 B6 B4 B7'
+ 'C1 C5 C7 CA CE D1 D1 CF CB C8 C6 C2 B8 B4 B6 B7'
+ 'A7 B4 9D 95 BD CC 2D E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 4A D3 B5 B3 AF B3 B5 B2 B3 C3 D4'
+ 'D0 C5 C2 C1 C0 BF BF C0 C1 C2 C5 D0 D5 C5 B5 B2'
+ 'B4 AF B2 B5 BD B8 23 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 2F CD B4 B1 B1 B1 AE BA D1 CA C0'
+ 'B8 B9 BA BA BA BA BA BA BA BA B9 B9 BF C8 D1 BE'
+ 'AE B1 B1 AF C3 8D 12 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 24 BB B6 AE AF AE B8 CD C0 B4 B5'
+ 'B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B6 B5 B4 BC CE'
+ 'BC AD AE AD C4 72 06 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 12 8B BF AE AF B2 C8 B8 B3 B5 B4'
+ 'B4 B4 B4 B3 B1 B2 B2 B2 B2 B2 B2 B2 B2 B2 B0 B4'
+ 'C6 B3 AA AD C6 55 E1 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 E1 E1 05 6B C1 B0 B1 BF BA B2 B4 B4 B4'
+ 'B4 B4 B4 B3 B0 AD AE AE AE AE AE AE AE AE AE AB'
+ 'B3 BE AA AD C6 30 E1 E1 E1 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 57 C1 B3 B5 BF B5 B4 B4 B4 B4'
+ 'B4 B4 B4 B4 B3 AD A7 A9 A9 A9 A9 A9 A9 A9 A9 A9'
+ 'AA B7 AB AD C2 26 E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 33 C0 B5 B6 B8 B5 B5 B5 B5 B5'
+ 'B5 B5 B5 B5 B5 B4 AB 9E 9E 9E A5 A5 A5 A5 A5 A5'
+ 'A5 AA A7 AF B0 1B E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 25 BC B8 B6 B4 B7 B7 B7 B7 B7'
+ 'B7 B7 B7 B7 B7 B7 B7 B1 AA A5 9D 9C 9B 9C 9C 9C'
+ '9D 95 9B B2 86 0D E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 1A B0 BA B9 B0 B9 BA BA BA BA'
+ 'BA BA BA BA BA BA BA BB BA B9 B7 B3 B0 AD A9 A5'
+ '9D 87 93 B4 67 07 E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 0B 84 BF BF B4 B6 BF BD BE BE'
+ 'BE BE BE BE BE BE BE BE BE BE BE BF BF BE BD BD'
+ 'B3 A7 B0 AE 47 02 E1 E1 00 00 00 00 00 00 00 00'
+ '00 00 00 00 E1 E1 06 65 C0 C3 C0 B2 BA C2 C1 C1'
+ 'C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C1 C2 BC'
+ 'B2 C1 C0 A9 2C E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 E1 E1 44 B7 C6 C5 C2 B2 BB C5 C6'
+ 'C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C4 C5 C5 BD B1'
+ 'BE C7 BD 90 20 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 E1 E1 2A AD C9 C7 C8 C5 BB B6 BE'
+ 'C8 C9 C8 C8 C8 C8 C8 C8 C8 C8 C9 C9 C0 B6 BA C4'
+ 'C8 CA BA 7A 10 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 E1 E1 1F 93 CA CA CA CB CB C3 B6'
+ 'B7 C2 C7 C7 C8 C8 C8 C8 C7 C7 C2 B8 B5 C1 CB CB'
+ 'CA CC B8 68 08 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 E1 E1 0E 7D C8 D1 CB CA D0 CF CE'
+ 'C8 C4 C3 C3 C1 C0 C0 C1 C3 C3 C3 C6 CD D0 CE C9'
+ 'CF CF BA 5C E1 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 E1 E1 06 67 C8 C3 93 9C BA D0 D1'
+ 'D1 D2 D2 D1 D0 CF CF D0 D1 D2 D2 D1 D2 C8 9D 94'
+ 'B5 D0 B8 42 E1 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E1 E1 5E C4 A5 86 8D 86 CF D5'
+ 'D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D4 D7 B9 84 8A'
+ '8B CF B1 34 E1 E1 E1 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E1 E1 36 B2 C1 C0 B9 C8 DD DD'
+ 'DD DD DD DD DD DD DD DD DD DD DD DD DE D6 C3 BC'
+ 'C0 BB 84 1E E1 E1 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E1 E1 0C 55 94 B7 BB BF BC BC'
+ 'BC BC BC BC BC BC BC BC BC BC BC BC BC BD BD BB'
+ 'B1 84 32 04 E1 E1 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E1 E1 E1 09 22 29 28 28 28 28'
+ '28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 29'
+ '29 1D 02 E1 E1 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1'
+ 'E1 E1 E1 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FE 3F FF FF 00 00 FF FF'
+ 'FE 3F FF FF 00 00 FF FF FE 3F FF FF 00 00 FC 00'
+ '00 00 00 7F 00 00 F8 00 00 00 00 3F 00 00 F8 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
+ '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
+ '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0E E0 00 00 00 00 00 00 00 00 00 00 00 88 88'
+ '88 88 88 88 88 88 88 88 88 EE EE 88 88 88 88 88'
+ '88 88 88 88 88 88 77 77 77 77 77 77 77 77 77 77'
+ '77 EE EE 77 77 77 77 77 77 77 77 77 77 77 00 00'
+ '00 00 00 00 00 00 00 00 00 0E E0 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 07 70 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 07 70 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
+ '00 08 FF F7 88 88 77 77 77 77 77 77 77 77 77 77'
+ '66 87 80 00 00 00 00 00 00 07 FF F7 00 88 88 87'
+ '77 77 87 87 77 77 87 78 66 67 80 00 00 00 00 00'
+ '00 07 FF F7 88 88 88 77 77 77 87 87 87 87 87 77'
+ '77 87 80 00 00 00 00 00 00 07 FF F7 88 88 88 77'
+ '77 78 87 87 87 87 87 77 77 77 80 00 00 00 00 00'
+ '00 07 FF F7 88 88 88 77 77 78 87 87 87 87 87 77'
+ '77 77 80 00 00 00 00 00 00 07 FF F7 88 88 88 87'
+ '77 78 87 88 87 87 87 77 77 77 80 00 00 00 00 00'
+ '00 07 FF F7 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 80 00 00 00 00 00 00 07 FF FF FF FF FF FF'
+ '77 77 77 77 77 77 77 77 77 77 80 00 00 00 00 00'
+ '00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF F7 80 00 00 00 00 00 00 07 FF FF FF 77 77 7F'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 7F 80 00 00 00 00 00'
+ '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 7F'
+ 'FF FF FF FF F7 77 77 77 77 7F 80 00 00 00 00 00'
+ '00 08 F7 77 77 77 7F FF 77 77 77 77 FF FF 77 77'
+ '77 77 00 00 00 00 00 00 00 08 F7 77 77 7F F7 77'
+ '77 77 77 77 77 7F F7 77 77 77 00 00 00 00 00 00'
+ '00 00 77 77 77 F7 77 77 77 77 77 77 77 77 7F 77'
+ '77 F7 00 00 00 00 00 00 00 00 77 77 7F 77 77 77'
+ '77 77 77 77 77 77 77 F7 77 F8 00 00 00 00 00 00'
+ '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 F8 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
+ '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 70 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
+ '00 00 07 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 00 00 07 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
+ '00 00 08 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 00 00 08 7F F7 77 77 77'
+ '77 77 77 77 77 77 77 7F 77 00 00 00 00 00 00 00'
+ '00 00 08 7F FF F7 77 77 77 77 77 77 77 77 7F FF'
+ '77 00 00 00 00 00 00 00 00 00 00 7F FF FF 77 77'
+ '77 77 77 77 77 77 FF FF 78 00 00 00 00 00 00 00'
+ '00 00 00 7F FF FF FF FF 77 77 77 77 7F FF FF FF'
+ '78 00 00 00 00 00 00 00 00 00 00 8F 77 77 FF FF'
+ 'FF FF FF FF FF FF 77 7F 78 00 00 00 00 00 00 00'
+ '00 00 00 8F 77 77 FF FF FF FF FF FF FF F7 77 7F'
+ '78 00 00 00 00 00 00 00 00 00 00 87 77 7F FF FF'
+ 'FF FF FF FF FF FF 77 77 70 00 00 00 00 00 00 00'
+ '00 00 00 08 77 77 77 77 77 77 77 77 77 77 77 77'
+ '80 00 00 00 00 00 00 00 00 00 00 00 08 88 88 88'
+ '88 88 88 88 88 88 88 80 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FE 3F FF FF 00 00 FF FF FE 3F FF FF 00 00 FF FF'
+ 'FE 3F FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
+ '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
+ '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 48 00 00'
+ '00 78 00 00 00 78 00 00 00 48 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 DC DC FF 00 DC'
+ 'DC FF 00 00 00 B4 00 00 00 9C 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 00 DC DC FF 00 FF FF FF 00 FF'
+ 'FF FF 00 DC DC FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF 6B FF FF FF 6B FF FF FF 6B FF'
+ 'FF FF 6B FF FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 6B FF FF FF 6B FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 C0 C0 C0 FF C0 C0'
+ 'C0 FF 00 00 00 92 00 00 00 37 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 C0 C0 C0 FF C0 C0'
+ 'C0 FF 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 35 00 00 00 18 00 00'
+ '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
+ '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F1 00 00 00 B1 00 00'
+ '00 5C 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
+ '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
+ '2D FF 2E 2C 2D FF 13 13 13 FF 00 00 00 FF 00 00'
+ '00 F6 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
+ '90 FF CA CA CA FF CD CD CD FF CB CB CB FF CE CE'
+ 'CE FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
+ 'C9 FF C7 C7 C7 FF C6 C6 C6 FF C5 C5 C5 FF C4 C4'
+ 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF BF FF BF BF'
+ 'BF FF BC BC BC FF BD BD BD FF BA BA BA FF BB BB'
+ 'BB FF B5 B5 B5 FF B3 B4 B3 FF B8 B4 B6 FF AD AD'
+ 'AD FF AB AC AC FF AD A8 AB FF 63 63 63 FF 09 09'
+ '09 FF 00 00 00 EF 00 00 00 42 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF EB EB'
+ 'EB FF E8 E8 E8 FF E7 E7 E7 FF D5 D5 D5 FF 85 85'
+ '85 FF 88 88 88 FF 92 92 92 FF 98 98 98 FF A2 A2'
+ 'A2 FF AD AD AD FF BA BA BA FF C0 C0 C0 FF C3 C3'
+ 'C3 FF C6 C6 C6 FF CB CB CB FF CA CA CA FF CA CA'
+ 'CA FF D6 D6 D6 FF CA CA CA FF D3 D3 D3 FF CB CB'
+ 'CB FF D7 D7 D7 FF CC CC CC FF D4 D4 D4 FF C7 C7'
+ 'C7 FF C8 C9 C9 FF C6 C2 C4 FF 9D B3 A8 FF 20 A8'
+ '63 FF 1C A8 60 FF 90 AF A0 FF BF BB BD FF 4F 4F'
+ '4F FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 15 00 00 00 F0 19 19 19 FF C7 C7 C7 FF EC EC'
+ 'EC FF E2 E2 E2 FF E6 E6 E6 FF CB CB CB FF 3B 3B'
+ '3B FF 3F 3F 3F FF 56 56 56 FF 72 72 72 FF 87 87'
+ '87 FF 92 92 92 FF 9D 9D 9D FF A5 A5 A5 FF A8 A8'
+ 'A8 FF AC AC AC FF B7 B7 B7 FF A9 A9 A9 FF 9C 9C'
+ '9C FF BD BD BD FF 99 99 99 FF B7 B7 B7 FF A1 A1'
+ 'A1 FF C3 C3 C3 FF A3 A3 A3 FF BD BD BD FF 98 98'
+ '98 FF C5 C4 C4 FF C7 BF C3 FF 51 A7 7C FF 17 CE'
+ '71 FF 0A BF 61 FF 2F 99 64 FF C3 BD C0 FF 84 83'
+ '84 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 30 00 00 00 FA 29 29 29 FF D1 D1 D1 FF EA EA'
+ 'EA FF E4 E4 E4 FF E7 E7 E7 FF CD CD CD FF 47 47'
+ '47 FF 5F 5F 5F FF 79 79 79 FF 87 87 87 FF 8F 8F'
+ '8F FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF B9 B9 B9 FF A4 A4 A4 FF 90 90'
+ '90 FF B8 B8 B8 FF 8A 8A 8A FF AF AF AF FF 94 94'
+ '94 FF BF BF BF FF 97 97 97 FF B7 B7 B7 FF 88 88'
+ '88 FF C4 C3 C3 FF C6 C3 C5 FF 95 B2 A3 FF 91 D6'
+ 'B4 FF 91 D8 B5 FF 83 AB 97 FF C4 C1 C3 FF 8E 8E'
+ '8E FF 01 01 01 FF 00 00 00 B7 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
+ 'EC FF E6 E6 E6 FF E7 E7 E7 FF D1 D1 D1 FF 68 68'
+ '68 FF 74 74 74 FF 7E 7E 7E FF 85 85 85 FF 8E 8E'
+ '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF BA BA BA FF 9F 9F 9F FF 83 83'
+ '83 FF B3 B3 B3 FF 7C 7C 7C FF A8 A8 A8 FF 87 87'
+ '87 FF BB BB BB FF 8A 8A 8A FF B2 B2 B2 FF 79 79'
+ '79 FF C2 C2 C2 FF C4 C4 C4 FF C6 C3 C4 FF 99 AC'
+ 'A2 FF 96 AB A0 FF C2 BE C0 FF C4 C4 C4 FF 8D 8D'
+ '8D FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
+ 'EE FF E7 E7 E7 FF E8 E8 E8 FF D6 D6 D6 FF 70 70'
+ '70 FF 71 71 71 FF 7D 7D 7D FF 85 85 85 FF 8E 8E'
+ '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF BB BB BB FF 98 98 98 FF 73 73'
+ '73 FF AD AD AD FF 6A 6A 6A FF A0 A0 A0 FF 78 78'
+ '78 FF B7 B7 B7 FF 7C 7C 7C FF AB AB AB FF 67 67'
+ '67 FF C2 C2 C2 FF C6 C6 C6 FF C4 C3 C4 FF C7 C4'
+ 'C5 FF C6 C2 C4 FF BF BF BF FF C5 C5 C5 FF 8D 8D'
+ '8D FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
+ 'EF FF E9 E9 E9 FF EB EB EB FF D6 D6 D6 FF 6A 6A'
+ '6A FF 6C 6C 6C FF 78 78 78 FF 81 81 81 FF 8A 8A'
+ '8A FF 93 93 93 FF 9C 9C 9C FF A3 A3 A3 FF A6 A6'
+ 'A6 FF AB AB AB FF B9 B9 B9 FF 90 90 90 FF 66 66'
+ '66 FF A5 A5 A5 FF 5B 5B 5B FF 98 98 98 FF 6B 6B'
+ '6B FF B1 B1 B1 FF 70 70 70 FF A4 A4 A4 FF 58 58'
+ '58 FF C1 C1 C1 FF C8 C8 C8 FF C5 C5 C5 FF C3 C3'
+ 'C3 FF C2 C2 C2 FF C1 C1 C1 FF C6 C6 C6 FF 8E 8E'
+ '8E FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
+ 'F2 FF EB EB EB FF EA EA EA FF DF DF DF FF A7 A7'
+ 'A7 FF A7 A7 A7 FF AB AB AB FF AE AE AE FF B0 B0'
+ 'B0 FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF B9 B9'
+ 'B9 FF BA BA BA FF BD BD BD FF B7 B7 B7 FF B1 B1'
+ 'B1 FF BE BE BE FF AF AF AF FF BA BA BA FF B1 B1'
+ 'B1 FF BE BE BE FF B0 B0 B0 FF BA BA BA FF AB AB'
+ 'AB FF C5 C5 C5 FF C8 C8 C8 FF C6 C6 C6 FF C4 C4'
+ 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C9 C9 C9 FF 8E 8E'
+ '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
+ 'F3 FF EB EB EB FF EB EB EB FF EA EA EA FF ED ED'
+ 'ED FF EB EB EB FF E9 E9 E9 FF E8 E8 E8 FF E6 E6'
+ 'E6 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF'
+ 'DF FF DE DE DE FF DB DB DB FF DB DB DB FF DC DC'
+ 'DC FF D8 D8 D8 FF D9 D9 D9 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
+ 'D0 FF CB CB CB FF CA CA CA FF C9 C9 C9 FF C7 C7'
+ 'C7 FF C4 C4 C4 FF C0 C0 C0 FF CA CA CA FF 8E 8E'
+ '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
+ 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF E0 E0 E0 FF D0 D0 D0 FF 8D 8D'
+ '8D FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
+ 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
+ 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF EF FF 8C 8C'
+ '8C FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
+ 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
+ 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF DB DB DB FF CF CF CF FF BC BC BC FF BB BB'
+ 'BB FF D1 D1 D1 FF DE DE DE FF FF FF FF FF 9A 9A'
+ '9A FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
+ 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
+ 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9'
+ 'D9 FF D2 D2 D2 FF A8 A8 A8 FF B6 B6 B6 FF B1 B1'
+ 'B1 FF B5 B5 B5 FF D8 D8 D8 FF FC FC FC FF 9C 9C'
+ '9C FF 00 00 00 FF 00 00 00 AE 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
+ 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
+ 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D7 D7'
+ 'D7 FF C9 C9 C9 FF A6 A6 A6 FF C3 C3 C3 FF B3 B3'
+ 'B3 FF AD AD AD FF D6 D6 D6 FF F5 F5 F5 FF 76 76'
+ '76 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
+ 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
+ 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF DD DD DD FF E1 E1 E1 FF E3 E3'
+ 'E3 FF E6 E6 E6 FF EA EA EA FF ED ED ED FF ED ED'
+ 'ED FF EB EB EB FF E7 E7 E7 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF DE DE DE FF D4 D4 D4 FF D0 D0 D0 FF D2 D2'
+ 'D2 FF D3 D3 D3 FF C5 C5 C5 FF D0 D0 D0 FF C2 C2'
+ 'C2 FF BF BF BF FF D9 D9 D9 FF E8 E8 E8 FF 56 56'
+ '56 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
+ 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
+ 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF DF DF'
+ 'DF FF F0 F0 F0 FF EC EC EC FF E1 E1 E1 FF DE DE'
+ 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DB DB'
+ 'DB FF DC DC DC FF DD DD DD FF DE DE DE FF E1 E1'
+ 'E1 FF EC EC EC FF F1 F1 F1 FF E1 E1 E1 FF D1 D1'
+ 'D1 FF CE CE CE FF D0 D0 D0 FF CB CB CB FF CE CE'
+ 'CE FF D1 D1 D1 FF D9 D9 D9 FF D4 D4 D4 FF 3F 3F'
+ '3F FF 00 00 00 FF 00 00 00 55 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
+ 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF CA CA CA FF D6 D6 D6 FF ED ED ED FF E6 E6'
+ 'E6 FF DC DC DC FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF ED ED'
+ 'ED FF DA DA DA FF CA CA CA FF CD CD CD FF CD CD'
+ 'CD FF CB CB CB FF DF DF DF FF B8 B8 B8 FF 22 22'
+ '22 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
+ 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
+ 'CA FF D4 D4 D4 FF E9 E9 E9 FF DC DC DC FF D0 D0'
+ 'D0 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D8 D8'
+ 'D8 FF EA EA EA FF D8 D8 D8 FF C9 C9 C9 FF CA CA'
+ 'CA FF C9 C9 C9 FF E0 E0 E0 FF A0 A0 A0 FF 08 08'
+ '08 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
+ 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
+ 'CE FF E4 E4 E4 FF D4 D4 D4 FF CF CF CF FF D1 D1'
+ 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF CD CD CD FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CC CC'
+ 'CC FF D0 D0 D0 FF E2 E2 E2 FF CF CF CF FF C7 C7'
+ 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 C2 00 00 00 0E 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
+ '9F FF DD DD DD FF CC CC CC FF CD CD CD FF DB DB'
+ 'DB FF D6 D6 D6 FF CE CE CE FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF C8 C8 C8 FF CF CF CF FF DA DA DA FF C7 C7'
+ 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 5A 5A 5A FF 00 00'
+ '00 FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
+ '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF DB DB'
+ 'DB FF D1 D1 D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C7 C7 C7 FF D3 D3 D3 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF DE DE DE FF 42 42 42 FF 00 00'
+ '00 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
+ '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D4 D4'
+ 'D4 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D0 D0 D0 FF C8 C8'
+ 'C8 FF C3 C3 C3 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF CB CB CB FF CC CC CC FF 2D 2D 2D FF 00 00'
+ '00 F8 00 00 00 40 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
+ '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF CD CD CD FF C7 C7 C7 FF C4 C4 C4 FF C2 C2'
+ 'C2 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF C1 C1 C1 FF C2 C2 C2 FF BF BF BF FF C0 C0'
+ 'C0 FF CE CE CE FF B2 B2 B2 FF 1A 1A 1A FF 00 00'
+ '00 E5 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
+ '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF CC CC'
+ 'CC FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF C6 C6'
+ 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
+ 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
+ '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
+ '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF D0 D0'
+ 'D0 FF D2 D2 D2 FF DB DB DB FF D9 D9 D9 FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DB DB DB FF DB DB DB FF DA DA DA FF D9 D9'
+ 'D9 FF D9 D9 D9 FF CF CF CF FF C5 C5 C5 FF CC CC'
+ 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
+ '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
+ '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
+ 'DC FF CE CE CE FF D6 D6 D6 FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DE DE'
+ 'DE FF D8 D8 D8 FF CE CE CE FF DD DD DD FF DC DC'
+ 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
+ '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
+ '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DE DE DE FF CE CE CE FF D7 D7 D7 FF E1 E1'
+ 'E1 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF D9 D9'
+ 'D9 FF CD CD CD FF DA DA DA FF E3 E3 E3 FF D9 D9'
+ 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
+ '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
+ '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF E1 E1 E1 FF D7 D7 D7 FF D2 D2'
+ 'D2 FF DA DA DA FF E4 E4 E4 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF DC DC DC FF D2 D2 D2 FF D6 D6'
+ 'D6 FF E0 E0 E0 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
+ 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
+ '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
+ '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF DF DF'
+ 'DF FF D2 D2 D2 FF D3 D3 D3 FF DE DE DE FF E3 E3'
+ 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3 E3 FF DE DE'
+ 'DE FF D4 D4 D4 FF D1 D1 D1 FF DD DD DD FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
+ '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
+ '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
+ 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
+ 'EB FF EA EA EA FF E4 E4 E4 FF E0 E0 E0 FF DF DF'
+ 'DF FF DF DF DF FF DD DD DD FF DC DC DC FF DC DC'
+ 'DC FF DD DD DD FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF E2 E2 E2 FF E9 E9 E9 FF EC EC EC FF EA EA'
+ 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
+ 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
+ '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
+ 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
+ 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
+ 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
+ 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
+ '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
+ 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
+ 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
+ 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
+ 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
+ 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
+ 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
+ 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
+ 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
+ '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
+ '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
+ '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
+ '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
+ '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FE 1F FF FF 00 00 FF FF'
+ 'FE 1F FF FF 00 00 FF 00 00 00 00 7F 00 00 FC 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
+ '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 DC DC FF 00 DC DC FF 00 00 00 9C 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 00 FF FF FF 00 FF FF FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 6B FF FF FF 6B FF FF FF 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 C0 C0 C0 FF C0 C0 C0 FF 00 00 00 37 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 05 00 00 00 C5 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F1 00 00'
+ '00 B1 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 21 21'
+ '21 FF 2B 2B 2B FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2E 2C 2D FF 13 13 13 FF 00 00'
+ '00 FF 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 AD 01 01 01 FF EB EB EB FF E8 E8'
+ 'E8 FF D5 D5 D5 FF 85 85 85 FF 92 92 92 FF 98 98'
+ '98 FF AD AD AD FF BA BA BA FF C3 C3 C3 FF C6 C6'
+ 'C6 FF CA CA CA FF CA CA CA FF CA CA CA FF D3 D3'
+ 'D3 FF D7 D7 D7 FF CC CC CC FF C7 C7 C7 FF C8 C9'
+ 'C9 FF 9D B3 A8 FF 20 A8 63 FF 90 AF A0 FF BF BB'
+ 'BD FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F0 19 19 19 FF EC EC EC FF E2 E2'
+ 'E2 FF CB CB CB FF 3B 3B 3B FF 56 56 56 FF 72 72'
+ '72 FF 92 92 92 FF 9D 9D 9D FF A8 A8 A8 FF AC AC'
+ 'AC FF A9 A9 A9 FF 9C 9C 9C FF 99 99 99 FF B7 B7'
+ 'B7 FF C3 C3 C3 FF A3 A3 A3 FF 98 98 98 FF C5 C4'
+ 'C4 FF 51 A7 7C FF 17 CE 71 FF 2F 99 64 FF C3 BD'
+ 'C0 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 28 28 28 FF EC EC EC FF E6 E6'
+ 'E6 FF D1 D1 D1 FF 68 68 68 FF 7E 7E 7E FF 85 85'
+ '85 FF 97 97 97 FF A0 A0 A0 FF AA AA AA FF AE AE'
+ 'AE FF 9F 9F 9F FF 83 83 83 FF 7C 7C 7C FF A8 A8'
+ 'A8 FF BB BB BB FF 8A 8A 8A FF 79 79 79 FF C2 C2'
+ 'C2 FF C6 C3 C4 FF 99 AC A2 FF C2 BE C0 FF C4 C4'
+ 'C4 FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 28 28 28 FF EE EE EE FF E7 E7'
+ 'E7 FF D6 D6 D6 FF 70 70 70 FF 7D 7D 7D FF 85 85'
+ '85 FF 97 97 97 FF A0 A0 A0 FF AA AA AA FF AE AE'
+ 'AE FF 98 98 98 FF 73 73 73 FF 6A 6A 6A FF A0 A0'
+ 'A0 FF B7 B7 B7 FF 7C 7C 7C FF 67 67 67 FF C2 C2'
+ 'C2 FF C4 C3 C4 FF C7 C4 C5 FF BF BF BF FF C5 C5'
+ 'C5 FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 27 27 27 FF F2 F2 F2 FF EB EB'
+ 'EB FF DF DF DF FF A7 A7 A7 FF AB AB AB FF AE AE'
+ 'AE FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF BA BA'
+ 'BA FF B7 B7 B7 FF B1 B1 B1 FF AF AF AF FF BA BA'
+ 'BA FF BE BE BE FF B0 B0 B0 FF AB AB AB FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C4 C4 C4 FF C2 C2 C2 FF C9 C9'
+ 'C9 FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 26 26 26 FF F3 F3 F3 FF EB EB'
+ 'EB FF EA EA EA FF ED ED ED FF E9 E9 E9 FF E8 E8'
+ 'E8 FF E4 E4 E4 FF E2 E2 E2 FF DF DF DF FF DE DE'
+ 'DE FF DB DB DB FF DC DC DC FF D9 D9 D9 FF D6 D6'
+ 'D6 FF D2 D2 D2 FF D2 D2 D2 FF D0 D0 D0 FF CB CB'
+ 'CB FF C9 C9 C9 FF C7 C7 C7 FF C0 C0 C0 FF CA CA'
+ 'CA FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 24 24 24 FF FF FF FF FF E9 E9'
+ 'E9 FF E2 E2 E2 FF E2 E2 E2 FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E3 E3 E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF'
+ 'EF FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FA 24 24 24 FF F8 F8 F8 FF D9 D9'
+ 'D9 FF BB BB BB FF BF BF BF FF DA DA DA FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF DB DB'
+ 'DB FF BC BC BC FF BB BB BB FF DE DE DE FF FF FF'
+ 'FF FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 D0 05 05 05 FF F6 F6 F6 FF BC BC'
+ 'BC FF C3 C3 C3 FF AB AB AB FF D8 D8 D8 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D5 D5'
+ 'D5 FF D8 D8 D8 FF D8 D8 D8 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D7 D7 D7 FF C9 C9'
+ 'C9 FF C3 C3 C3 FF B3 B3 B3 FF D6 D6 D6 FF F5 F5'
+ 'F5 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF F4 F4 F4 FF CF CF'
+ 'CF FF D2 D2 D2 FF BF BF BF FF D3 D3 D3 FF D2 D2'
+ 'D2 FF D3 D3 D3 FF DD DD DD FF E3 E3 E3 FF E6 E6'
+ 'E6 FF ED ED ED FF ED ED ED FF E7 E7 E7 FF E4 E4'
+ 'E4 FF DE DE DE FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D0 D0 D0 FF C2 C2 C2 FF D9 D9 D9 FF E8 E8'
+ 'E8 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 59 00 00 00 FF E9 E9 E9 FF D0 D0'
+ 'D0 FF CD CD CD FF CD CD CD FF D6 D6 D6 FF ED ED'
+ 'ED FF DC DC DC FF D4 D4 D4 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D5 D5 D5 FF DB DB DB FF ED ED ED FF DA DA'
+ 'DA FF CD CD CD FF CD CD CD FF DF DF DF FF B8 B8'
+ 'B8 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 3E 00 00 00 FE D7 D7 D7 FF D2 D2'
+ 'D2 FF CB CB CB FF CA CA CA FF E9 E9 E9 FF DC DC'
+ 'DC FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D8 D8 D8 FF EA EA'
+ 'EA FF C9 C9 C9 FF CA CA CA FF E0 E0 E0 FF A0 A0'
+ 'A0 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 0C 00 00 00 E1 9F 9F 9F FF DD DD'
+ 'DD FF CD CD CD FF DB DB DB FF CE CE CE FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
+ 'CF FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF C8 C8'
+ 'C8 FF DA DA DA FF C7 C7 C7 FF E2 E2 E2 FF 5A 5A'
+ '5A FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 B2 83 83 83 FF DD DD'
+ 'DD FF D1 D1 D1 FF DB DB DB FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF C9 C9 C9 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF D3 D3 D3 FF C8 C8 C8 FF DE DE DE FF 42 42'
+ '42 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 4B 41 41 41 FF D8 D8'
+ 'D8 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C7 C7 C7 FF C4 C4'
+ 'C4 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF BF BF BF FF C0 C0 C0 FF B2 B2 B2 FF 1A 1A'
+ '1A FF 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 1A 2C 2C 2C FF CC CC'
+ 'CC FF D5 D5 D5 FF CC CC CC FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF CF CF CF FF CC CC CC FF C6 C6 C6 FF C4 C4'
+ 'C4 FF B3 B3 B3 FF BD BD BD FF 99 99 99 FF 09 09'
+ '09 FF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 08 08 08 FF 97 97'
+ '97 FF DF DF DF FF DC DC DC FF D6 D6 D6 FF DE DE'
+ 'DE FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DE DE DE FF D8 D8'
+ 'D8 FF DD DD DD FF DC DC DC FF 53 53 53 FF 00 00'
+ '00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 77 77'
+ '77 FF E2 E2 E2 FF E1 E1 E1 FF CE CE CE FF D7 D7'
+ 'D7 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E1 E1 E1 FF D9 D9 D9 FF CD CD'
+ 'CD FF E3 E3 E3 FF D9 D9 D9 FF 39 39 39 FF 00 00'
+ '00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 35 35'
+ '35 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF D2 D2 D2 FF D3 D3 D3 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF D4 D4 D4 FF D1 D1 D1 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E8 E8 E8 FF D4 D4 D4 FF 0B 0B 0B FF 00 00'
+ '00 ED 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 1E 1E'
+ '1E FF E4 E4 E4 FF ED ED ED FF E6 E6 E6 FF EC EC'
+ 'EC FF EA EA EA FF E4 E4 E4 FF DF DF DF FF DF DF'
+ 'DF FF DC DC DC FF DC DC DC FF DF DF DF FF DF DF'
+ 'DF FF E2 E2 E2 FF E9 E9 E9 FF EA EA EA FF E5 E5'
+ 'E5 FF EB EB EB FF D6 D6 D6 FF 00 00 00 FF 00 00'
+ '00 C3 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 AE 00 00'
+ '00 FF E0 E0 E0 FF C4 C4 C4 FF B8 B8 B8 FF B2 B2'
+ 'B2 FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F3 F3 F3 FF B0 B0 B0 FF B6 B6'
+ 'B6 FF EB EB EB FF CD CD CD FF 00 00 00 FF 00 00'
+ '00 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00'
+ '00 FF CE CE CE FF DD DD DD FF D5 D5 D5 FF E4 E4'
+ 'E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF FA FA FA FF DF DF DF FF D8 D8'
+ 'D8 FF D7 D7 D7 FF B0 B0 B0 FF 00 00 00 FF 00 00'
+ '00 67 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00'
+ '00 9C 0C 0C 0C FF 3D 3D 3D FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 49 49'
+ '49 FF 2F 2F 2F FF 02 02 02 FF 00 00 00 5C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 06 00 00 00 F1 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 D6 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00'
+ '00 00 FF FE 3F FF FF FE 3F FF F0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 F0 00 00 0F F0 00 00 0F F0 00'
+ '00 0F F0 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 3F FC 00'
+ '00 7F FF FF FF FF 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 78 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF 6B FF FF FF 6B FF'
+ 'FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 26 26 26 FF CD CD CD FF CD CD'
+ 'CD FF C9 C9 C9 FF C5 C5 C5 FF C2 C2 C2 FF C0 C0'
+ 'C0 FF BF BF BF FF BA BA BA FF B3 B4 B3 FF AB AC'
+ 'AC FF 09 09 09 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 30 D1 D1 D1 FF E7 E7 E7 FF 5F 5F'
+ '5F FF 8F 8F 8F FF A7 A7 A7 FF B9 B9 B9 FF B8 B8'
+ 'B8 FF 94 94 94 FF B7 B7 B7 FF C6 C3 C5 FF 91 D8'
+ 'B5 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 33 D1 D1 D1 FF EB EB EB FF 6C 6C'
+ '6C FF 8A 8A 8A FF A3 A3 A3 FF B9 B9 B9 FF A5 A5'
+ 'A5 FF 6B 6B 6B FF A4 A4 A4 FF C8 C8 C8 FF C2 C2'
+ 'C2 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 33 D3 D3 D3 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F3 F3 F3 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EE EE EE FF ED ED ED FF EB EB'
+ 'EB FF 8D 8D 8D FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 25 DA DA DA FF A9 A9 A9 FF C3 C3'
+ 'C3 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D8 D8 D8 FF D8 D8 D8 FF A8 A8 A8 FF B5 B5'
+ 'B5 FF 9C 9C 9C FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 7E 7E 7E FF CF CF CF FF D1 D1'
+ 'D1 FF DF DF DF FF E1 E1 E1 FF DC DC DC FF DC DC'
+ 'DC FF E1 E1 E1 FF E1 E1 E1 FF D0 D0 D0 FF D1 D1'
+ 'D1 FF 3F 3F 3F FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 22 22 22 FF CA CA CA FF E4 E4'
+ 'E4 FF D1 D1 D1 FF D0 D0 D0 FF CD CD CD FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF E2 E2 E2 FF C9 C9'
+ 'C9 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF CB CB'
+ 'CB FF 00 00 00 F8 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 D8 DB DB DB FF D2 D2'
+ 'D2 FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF CF CF CF FF CA CA'
+ 'CA FF 00 00 00 B8 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 89 C9 C9 C9 FF E4 E4'
+ 'E4 FF D2 D2 D2 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E5 E5 E5 FF D2 D2 D2 FF E4 E4 E4 FF A8 A8'
+ 'A8 FF 00 00 00 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 99 99 99 FF BD BD'
+ 'BD FF EC EC EC FF EE EE EE FF EC EC EC FF EC EC'
+ 'EC FF EE EE EE FF E4 E4 E4 FF D1 D1 D1 FF 75 75'
+ '75 FF 00 00 00 06 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 19 19 19 FF D3 D3'
+ 'D3 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D9 D9 D9 FF CD CD CD FF 06 06'
+ '06 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E0 03 00 00 C0 03 00 00 80 03'
+ '00 00 80 03 00 00 80 03 00 00 80 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 E0 07 00 00 F0 0F 00 00'
+} */
+
+/* BINRES netdrive2.ico */
+10 ICON netdrive2.ico
+/* {
+ '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 3E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
+ '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
+ '00 00 8E 11 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
+ '00 00 5E 23 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 C6 29 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 6E 4F 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 02 02 02 00 04 04 04 00 05 06 06 00 06 06'
+ '06 00 00 00 0D 00 09 09 09 00 0A 0A 0A 00 0C 0C'
+ '0C 00 12 12 12 00 14 14 14 00 15 15 15 00 16 16'
+ '16 00 1F 1F 10 00 1D 1D 1D 00 00 00 20 00 00 00'
+ '2C 00 00 00 2D 00 21 21 21 00 22 22 22 00 23 23'
+ '23 00 24 24 24 00 25 25 25 00 26 26 26 00 38 38'
+ '38 00 39 39 39 00 3B 3B 3B 00 43 43 43 00 46 46'
+ '46 00 4A 4A 4A 00 54 4C 50 00 53 53 53 00 55 55'
+ '55 00 56 56 56 00 59 59 52 00 5A 5A 53 00 5C 5C'
+ '55 00 5D 5D 56 00 58 58 58 00 59 59 59 00 5A 58'
+ '59 00 5A 5A 5A 00 5B 5B 5B 00 5C 5C 5C 00 5D 5D'
+ '5D 00 5E 5E 5E 00 65 58 5F 00 60 60 60 00 61 61'
+ '61 00 62 62 62 00 64 64 64 00 67 67 67 00 69 69'
+ '69 00 71 71 71 00 72 72 72 00 73 73 73 00 75 75'
+ '75 00 78 78 78 00 7A 7A 7A 00 7B 7B 7B 00 7C 7C'
+ '7C 00 7F 7F 7F 00 24 A7 64 00 3C AD 74 00 25 DC'
+ '7F 00 7C 7C A3 00 00 00 C9 00 00 00 CD 00 00 00'
+ 'D3 00 00 00 D8 00 00 00 FF 00 2B 2B FF 00 7D AA'
+ '94 00 81 81 81 00 83 83 83 00 89 89 89 00 8A 8A'
+ '8A 00 8B 8B 8B 00 8F 8F 8F 00 91 89 8C 00 90 90'
+ '90 00 91 91 91 00 94 94 94 00 95 95 95 00 97 97'
+ '97 00 99 99 99 00 9A 9A 9A 00 9C 9C 9C 00 9D 9D'
+ '9D 00 9E 9E 9E 00 9F 9F 9F 00 94 B6 A4 00 93 BD'
+ 'A9 00 A0 A0 A0 00 A1 A1 A1 00 A3 A3 A3 00 A4 A4'
+ 'A4 00 A5 A5 A5 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
+ 'AA 00 AC AC AC 00 AD AD AD 00 AE AE AE 00 AF AF'
+ 'AF 00 B8 B8 A7 00 AA AA BC 00 AD B9 B3 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B4 B4'
+ 'B4 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B9 B9'
+ 'B9 00 BC BC BC 00 BD BD BD 00 BE BE BE 00 BF BF'
+ 'BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C0 C1 00 C2 C2'
+ 'C2 00 C3 C3 C3 00 C4 C1 C2 00 C5 C2 C4 00 C4 C4'
+ 'C4 00 C5 C5 C5 00 C6 C5 C6 00 C6 C6 C6 00 C8 C3'
+ 'C5 00 CC C4 C8 00 C8 C8 C8 00 C9 C9 C9 00 CB C9'
+ 'CA 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
+ 'CD 00 CE CE CE 00 CF CF CF 00 D2 C1 CA 00 D3 C8'
+ 'CD 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3'
+ 'D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7'
+ 'D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA DA 00 DB DB'
+ 'DB 00 DC DC DC 00 DD DD DD 00 DE DE DE 00 DF DF'
+ 'DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3'
+ 'E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7'
+ 'E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
+ 'EB 00 EC EC EC 00 ED ED ED 00 EE EE EE 00 EF EF'
+ 'EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2 F2 00 F4 F4'
+ 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
+ 'F8 00 F9 F9 F9 00 FC FC FC 00 FD FD FD 00 FF FF'
+ 'FF 00 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
+ '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 08 6C'
+ '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
+ '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
+ 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
+ '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
+ '68 65 6C 6C 33 32 5C 6E 65 74 64 72 69 76 65 32'
+ '2E 69 63 6F 00 00 14 1A 95 00 1F 3B D4 77 15 00'
+ '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
+ 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
+ '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
+ '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
+ '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
+ 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
+ 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 42 45 BD 00 45'
+ '42 BD 00 00 00 00 00 00 00 00 00 00 00 00 BD BD'
+ 'BD BD BD BD BD BD BD BD BD BD BD 05 46 43 43 46'
+ '05 BD BD BD BD BD BD BD BD BD BD BD BD BD 6E 6E'
+ '6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 69 41 46 46 41'
+ '69 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 6E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 47 46 46 47'
+ 'BD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 44 46 6A 6A 46'
+ '44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 BD BD BD BD BD BD BD BD BD 10 0F 0D 0D 0F'
+ '11 BD BD BD BD BD BD BD BD 00 00 00 00 00 00 00'
+ '00 BD BD 0A 2D 2D 33 32 31 2F 2D 25 24 21 20 23'
+ '22 26 26 26 21 28 2E 1E 06 BD 00 00 00 00 00 00'
+ '00 BD 0A 79 B5 AB 63 70 74 7A 91 93 97 98 9D 9D'
+ '9C 9E 9B 99 8D 84 3F 5C 4F 03 BD 00 00 00 00 00'
+ '00 BD 21 B7 A7 A5 0E 1D 3A 4D 58 5F 68 64 5A 57'
+ '64 72 61 54 90 48 40 3E 8F 17 BD 00 00 00 00 00'
+ '00 BD 2C B3 A8 A4 1F 3B 4C 52 5F 63 70 64 53 50'
+ '5D 6C 56 4B 88 7B 5B 6B 7E 17 BD 00 00 00 00 00'
+ '00 BD 2A B4 AA A9 2B 36 4A 4E 5A 61 6F 5E 39 35'
+ '4D 5D 49 33 8A 82 85 7F 79 16 BD 00 00 00 00 00'
+ '00 BD 2A B6 AD A9 49 50 56 5D 63 66 70 65 57 55'
+ '5F 67 58 51 86 81 7A 7A 7D 15 BD 00 00 00 00 00'
+ '00 BD 29 B8 B1 B0 BA B9 B5 B3 AF AD AA A8 AB A9'
+ 'A5 A1 A1 A1 97 95 93 8A 80 14 BD 00 00 00 00 00'
+ '00 BD 27 BC B0 AE AD A8 A8 A7 A8 A8 A9 A8 A8 A8'
+ 'A8 A8 A8 A7 AA AE AD B9 96 12 BD 00 00 00 00 00'
+ '00 BD 2C BC 83 6D 75 99 98 98 98 98 97 97 97 97'
+ '98 98 98 99 92 71 71 97 B6 17 BD 00 00 00 00 00'
+ '00 BD 1B BC 68 73 62 92 98 96 94 92 95 96 96 95'
+ '92 93 95 9B 74 6E 63 86 A9 0E BD 00 00 00 00 00'
+ '00 BD 14 A9 8D 91 83 91 8D 9A A5 A4 A7 AB AB A8'
+ 'A5 A6 9C 8E 8E 8E 80 99 77 07 BD 00 00 00 00 00'
+ '00 BD 09 92 92 8B 8C 8C AA A7 9B 99 98 97 97 98'
+ '99 9C A7 AA 91 89 8C A3 54 BD BD 00 00 00 00 00'
+ '00 BD 01 60 99 87 8C A6 94 8D 91 91 8E 91 91 91'
+ '91 91 8C 8E A7 8E 83 AA 30 BD BD 00 00 00 00 00'
+ '00 BD BD 38 A5 87 9B 93 8D 91 8E 91 8C 89 8A 8A'
+ '8A 8A 8A 89 8B 9B 7D B0 19 BD BD 00 00 00 00 00'
+ '00 00 BD 1C AB 8E 99 8D 91 91 91 91 91 8B 7C 7D'
+ '80 81 81 81 7D 8C 81 AC 0B BD 00 00 00 00 00 00'
+ '00 00 BD 13 AF 92 92 93 92 92 92 92 92 93 8C 80'
+ '79 78 77 79 79 79 83 97 01 BD 00 00 00 00 00 00'
+ '00 00 BD 02 9F 9A 8B 99 97 98 98 98 98 98 98 99'
+ '98 95 91 8B 87 73 87 6F BD BD 00 00 00 00 00 00'
+ '00 00 BD BD 81 A4 94 94 9F 9D 9C 9C 9C 9C 9C 9C'
+ '9D 9D 9E A0 97 94 9E 4B BD BD 00 00 00 00 00 00'
+ '00 00 00 BD 51 A7 A4 96 97 A1 A4 A2 A2 A2 A2 A2'
+ 'A2 A4 A0 99 93 A8 99 26 BD 00 00 00 00 00 00 00'
+ '00 00 00 BD 33 A7 A8 A8 A0 92 9A A3 A4 A5 A5 A4'
+ 'A3 9A 92 A0 A9 AC 8D 18 BD 00 00 00 00 00 00 00'
+ '00 00 00 BD 1A 9E AB 9A AD AF A7 A3 A2 9F 9F A2'
+ 'A3 A5 AF A5 9C B2 83 0E BD 00 00 00 00 00 00 00'
+ '00 00 00 BD 17 9F 7A 66 81 B3 B1 B1 B1 B0 B0 B1'
+ 'B1 B1 AE 71 66 A8 76 0C BD 00 00 00 00 00 00 00'
+ '00 00 00 BD 08 59 AD A5 B6 BB BA BA BA BA BA BA'
+ 'BA BA BA B2 A7 A6 37 BD BD 00 00 00 00 00 00 00'
+ '00 00 00 BD BD 0C 38 3B 3A 39 39 39 39 39 39 39'
+ '39 39 39 3A 3C 34 04 BD 00 00 00 00 00 00 00 00'
+ '00 00 00 00 BD BD BD BD BD BD BD BD BD BD BD BD'
+ 'BD BD BD BD BD BD BD 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
+ '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF FF F8'
+ '1F FF F0 00 00 1F E0 00 00 0F E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
+ '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 06 06 06 00 09 09'
+ '09 00 19 19 19 00 22 22 22 00 26 26 26 00 3F 3F'
+ '3F 00 5F 5F 5F 00 6B 6B 6B 00 6C 6C 6C 00 75 75'
+ '75 00 7E 7E 7E 00 7F 7F 7F 00 00 00 FF 00 8A 8A'
+ '8A 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F 8F 00 94 94'
+ '94 00 99 99 99 00 9C 9C 9C 00 A3 A3 A3 00 A4 A4'
+ 'A4 00 A5 A5 A5 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
+ 'A9 00 AB AC AC 00 B3 B4 B3 00 B5 B5 B5 00 B7 B7'
+ 'B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BD BD'
+ 'BD 00 BF BF BF 00 91 D8 B5 00 C0 C0 C0 00 C2 C2'
+ 'C2 00 C3 C3 C3 00 C6 C3 C5 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C8 C8 C8 00 C9 C9 C9 00 CA CA CA 00 CB CB'
+ 'CB 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D7 D7'
+ 'D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA DA 00 DB DB'
+ 'DB 00 DC DC DC 00 DF DF DF 00 E1 E1 E1 00 E2 E2'
+ 'E2 00 E4 E4 E4 00 E5 E5 E5 00 E7 E7 E7 00 EB EB'
+ 'EB 00 EC EC EC 00 ED ED ED 00 EE EE EE 00 EF EF'
+ 'EF 00 F0 F0 F0 00 F1 F1 F1 00 F3 F3 F3 00 F4 F4'
+ 'F4 00 F5 F5 F5 00 F6 F6 F6 00 00 00 00 00 8F 8F'
+ '8F 00 91 89 8C 00 90 90 90 00 91 91 91 00 94 94'
+ '94 00 95 95 95 00 97 97 97 00 99 99 99 00 9A 9A'
+ '9A 00 9C 9C 9C 00 9D 9D 9D 00 9E 9E 9E 00 9F 9F'
+ '9F 00 94 B6 A4 00 93 BD A9 00 A0 A0 A0 00 A1 A1'
+ 'A1 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A8 A8'
+ 'A8 00 A9 A9 A9 00 AA AA AA 00 AC AC AC 00 AD AD'
+ 'AD 00 AE AE AE 00 AF AF AF 00 B8 B8 A7 00 AA AA'
+ 'BC 00 AD B9 B3 00 B0 B0 B0 00 B1 B1 B1 00 B2 B2'
+ 'B2 00 B3 B3 B3 00 B4 B4 B4 00 B5 B5 B5 00 B6 B6'
+ 'B6 00 B7 B7 B7 00 B9 B9 B9 00 BC BC BC 00 BD BD'
+ 'BD 00 BE BE BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C0 C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1'
+ 'C2 00 C5 C2 C4 00 C4 C4 C4 00 C5 C5 C5 00 C6 C5'
+ 'C6 00 C6 C6 C6 00 C8 C3 C5 00 CC C4 C8 00 C8 C8'
+ 'C8 00 C9 C9 C9 00 CB C9 CA 00 CA CA CA 00 CB CB'
+ 'CB 00 CC CC CC 00 CD CD CD 00 CE CE CE 00 CF CF'
+ 'CF 00 D2 C1 CA 00 D3 C8 CD 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
+ 'D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9'
+ 'D9 00 DA DA DA 00 DB DB DB 00 DC DC DC 00 DD DD'
+ 'DD 00 DE DE DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1'
+ 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
+ 'F1 00 F2 F2 F2 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
+ 'F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9 F9 00 FC FC'
+ 'FC 00 FD FD FD 00 FF FF FF 00 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 08 6C 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 6E'
+ '65 74 64 72 69 76 65 32 2E 69 63 6F 00 00 14 1A'
+ '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
+ '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
+ '95 00 00 00 00 00 4D 4D 4D 4D 4D 4D 4D 0D 0D 4D'
+ '4D 4D 4D 4D 4D 4D 25 25 25 25 25 25 25 0D 0D 25'
+ '25 25 25 25 25 25 00 00 00 4D 4D 4D 4D 4D 4D 4D'
+ '4D 4D 4D 4D 00 00 00 00 05 2F 2F 2C 2A 26 25 23'
+ '21 1C 1B 02 00 00 00 4D 33 41 07 11 18 20 1F 12'
+ '1E 28 24 10 00 00 00 4D 33 42 09 0E 15 20 17 08'
+ '16 2B 26 10 00 00 00 4D 35 4C 4B 4A 49 48 47 46'
+ '45 44 42 0F 00 00 00 4D 39 1A 27 37 37 36 36 37'
+ '37 19 1D 14 00 00 00 00 0B 31 33 3C 3D 3B 3B 3D'
+ '3D 32 33 06 00 00 00 00 04 2D 3F 33 32 2F 30 30'
+ '30 3E 2C 4D 00 00 00 00 4D 33 33 33 33 33 27 29'
+ '29 29 2E 4D 00 00 00 00 4D 3A 34 39 39 39 39 39'
+ '39 31 2D 4D 00 00 00 00 4D 2C 3F 34 40 3F 3F 40'
+ '34 3F 19 4D 00 00 00 00 4D 13 22 43 45 43 43 45'
+ '3F 33 0A 4D 00 00 00 00 00 03 35 37 37 37 37 37'
+ '38 2F 01 00 00 00 00 00 00 00 4D 4D 4D 4D 4D 4D'
+ '4D 4D 00 00 00 00 00 00 00 00 00 00 00 00 E0 03'
+ '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
+ '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
+ '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 0C C0 0C C0 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 CC CC 00 00 00 00 00 00 00 77 77'
+ '77 77 77 77 77 8C C8 77 77 77 77 77 77 77 00 00'
+ '00 00 00 00 00 CC CC 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 0C C7 7C C0 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 88 88 88 88 88 88 88 88 88 88 00 00 00 00 00'
+ '07 FF 77 77 77 77 77 77 77 77 67 80 00 00 00 00'
+ '8F FF 08 88 87 77 88 77 78 78 66 70 00 00 00 00'
+ '8F FF 88 88 77 77 88 77 88 77 77 70 00 00 00 00'
+ '8F FF 88 88 87 77 88 87 88 77 77 70 00 00 00 00'
+ '8F FF 88 87 77 77 88 77 88 77 77 70 00 00 00 00'
+ '8F FF FF FF FF FF FF FF FF 77 77 70 00 00 00 00'
+ '8F FF FF FF FF FF FF FF FF FF FF 70 00 00 00 00'
+ '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
+ '8F 77 77 77 77 77 77 77 77 77 77 F0 00 00 00 00'
+ '0F 77 77 77 FF FF FF FF 77 77 77 70 00 00 00 00'
+ '07 77 77 FF 77 77 77 77 FF 77 7F 80 00 00 00 00'
+ '07 77 7F 77 77 77 77 77 77 F7 7F 80 00 00 00 00'
+ '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
+ '08 F7 77 77 77 77 77 77 77 77 7F 00 00 00 00 00'
+ '00 F7 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
+ '00 77 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
+ '00 7F 77 77 77 77 77 77 77 77 78 00 00 00 00 00'
+ '00 8F F7 7F FF FF FF FF 77 7F 78 00 00 00 00 00'
+ '00 8F FF 77 7F FF FF F7 77 FF 70 00 00 00 00 00'
+ '00 07 F7 FF FF F7 7F FF FF 7F 70 00 00 00 00 00'
+ '00 07 77 7F FF FF FF FF F7 7F 70 00 00 00 00 00'
+ '00 08 FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 00 88 88 88 88 88 88 88 88 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
+ '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF FF F8'
+ '1F FF F0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
+ '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 0F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
+ '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 0C C0 00 00 00 77 77'
+ '77 7C C7 77 77 77 00 00 00 00 00 00 00 00 00 07'
+ '77 77 77 77 70 00 00 7F 88 77 78 77 78 00 00 7F'
+ '88 77 78 77 78 00 00 7F FF FF FF FF F8 00 00 77'
+ '77 77 77 77 78 00 00 87 77 F7 7F F7 70 00 00 07'
+ 'F7 77 77 7F 70 00 00 07 77 77 77 77 70 00 00 07'
+ '77 77 77 77 70 00 00 07 F7 FF FF 7F 70 00 00 08'
+ '7F FF FF F7 80 00 00 00 77 77 77 77 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 03'
+ '00 00 C0 03 00 00 80 03 00 00 80 03 00 00 80 03'
+ '00 00 80 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 E0 07'
+ '00 00 F0 0F 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
+ '00 00 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF 00 00 00 9C 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 00 00 FF FF 00 00'
+ 'FF FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF 00 00 00 3C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 01 00 00 00 04 00 00 00 09 00 00'
+ '00 09 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
+ '00 09 00 00 FF FF 00 00 FF FF C0 C0 C0 FF C0 C0'
+ 'C0 FF 00 00 FF FF 00 00 FF FF 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 05 00 00 00 C5 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F1 00 00 00 B1 00 00 00 0D 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00'
+ '00 9B 00 00 00 FF 21 21 21 FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
+ '2D FF 13 13 13 FF 00 00 00 FF 00 00 00 69 00 00'
+ '00 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 AD 01 01'
+ '01 FF EB EB EB FF E8 E8 E8 FF D5 D5 D5 FF 85 85'
+ '85 FF 92 92 92 FF 98 98 98 FF AD AD AD FF BA BA'
+ 'BA FF C3 C3 C3 FF C6 C6 C6 FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF D3 D3 D3 FF D7 D7 D7 FF CC CC'
+ 'CC FF C7 C7 C7 FF C8 C9 C9 FF 9D B3 A8 FF 20 A8'
+ '63 FF 90 AF A0 FF BF BB BD FF 00 00 00 FF 00 00'
+ '00 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F0 19 19'
+ '19 FF EC EC EC FF E2 E2 E2 FF CB CB CB FF 3B 3B'
+ '3B FF 56 56 56 FF 72 72 72 FF 92 92 92 FF 9D 9D'
+ '9D FF A8 A8 A8 FF AC AC AC FF A9 A9 A9 FF 9C 9C'
+ '9C FF 99 99 99 FF B7 B7 B7 FF C3 C3 C3 FF A3 A3'
+ 'A3 FF 98 98 98 FF C5 C4 C4 FF 51 A7 7C FF 17 CE'
+ '71 FF 2F 99 64 FF C3 BD C0 FF 01 01 01 FF 00 00'
+ '00 A3 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 28 28'
+ '28 FF EC EC EC FF E6 E6 E6 FF D1 D1 D1 FF 68 68'
+ '68 FF 7E 7E 7E FF 85 85 85 FF 97 97 97 FF A0 A0'
+ 'A0 FF AA AA AA FF AE AE AE FF 9F 9F 9F FF 83 83'
+ '83 FF 7C 7C 7C FF A8 A8 A8 FF BB BB BB FF 8A 8A'
+ '8A FF 79 79 79 FF C2 C2 C2 FF C6 C3 C4 FF 99 AC'
+ 'A2 FF C2 BE C0 FF C4 C4 C4 FF 01 01 01 FF 00 00'
+ '00 BA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 28 28'
+ '28 FF EE EE EE FF E7 E7 E7 FF D6 D6 D6 FF 70 70'
+ '70 FF 7D 7D 7D FF 85 85 85 FF 97 97 97 FF A0 A0'
+ 'A0 FF AA AA AA FF AE AE AE FF 98 98 98 FF 73 73'
+ '73 FF 6A 6A 6A FF A0 A0 A0 FF B7 B7 B7 FF 7C 7C'
+ '7C FF 67 67 67 FF C2 C2 C2 FF C4 C3 C4 FF C7 C4'
+ 'C5 FF BF BF BF FF C5 C5 C5 FF 01 01 01 FF 00 00'
+ '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 27 27'
+ '27 FF F2 F2 F2 FF EB EB EB FF DF DF DF FF A7 A7'
+ 'A7 FF AB AB AB FF AE AE AE FF B3 B3 B3 FF B6 B6'
+ 'B6 FF B9 B9 B9 FF BA BA BA FF B7 B7 B7 FF B1 B1'
+ 'B1 FF AF AF AF FF BA BA BA FF BE BE BE FF B0 B0'
+ 'B0 FF AB AB AB FF C5 C5 C5 FF C6 C6 C6 FF C4 C4'
+ 'C4 FF C2 C2 C2 FF C9 C9 C9 FF 00 00 00 FF 00 00'
+ '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 26 26'
+ '26 FF F3 F3 F3 FF EB EB EB FF EA EA EA FF ED ED'
+ 'ED FF E9 E9 E9 FF E8 E8 E8 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF DF DF DF FF DE DE DE FF DB DB DB FF DC DC'
+ 'DC FF D9 D9 D9 FF D6 D6 D6 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D0 D0 D0 FF CB CB CB FF C9 C9 C9 FF C7 C7'
+ 'C7 FF C0 C0 C0 FF CA CA CA FF 00 00 00 FF 00 00'
+ '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 F9 24 24'
+ '24 FF FF FF FF FF E9 E9 E9 FF E2 E2 E2 FF E2 E2'
+ 'E2 FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF F8 F8 F8 FF EF EF EF FF 00 00 00 FF 00 00'
+ '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FA 24 24'
+ '24 FF F8 F8 F8 FF D9 D9 D9 FF BB BB BB FF BF BF'
+ 'BF FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF DB DB DB FF BC BC BC FF BB BB'
+ 'BB FF DE DE DE FF FF FF FF FF 00 00 00 FF 00 00'
+ '00 BA 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 D0 05 05'
+ '05 FF F6 F6 F6 FF BC BC BC FF C3 C3 C3 FF AB AB'
+ 'AB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
+ 'D4 FF D3 D3 D3 FF D5 D5 D5 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3 D3 FF D4 D4'
+ 'D4 FF D7 D7 D7 FF C9 C9 C9 FF C3 C3 C3 FF B3 B3'
+ 'B3 FF D6 D6 D6 FF F5 F5 F5 FF 00 00 00 FF 00 00'
+ '00 8C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 00 00'
+ '00 FF F4 F4 F4 FF CF CF CF FF D2 D2 D2 FF BF BF'
+ 'BF FF D3 D3 D3 FF D2 D2 D2 FF D3 D3 D3 FF DD DD'
+ 'DD FF E3 E3 E3 FF E6 E6 E6 FF ED ED ED FF ED ED'
+ 'ED FF E7 E7 E7 FF E4 E4 E4 FF DE DE DE FF D4 D4'
+ 'D4 FF D2 D2 D2 FF D3 D3 D3 FF D0 D0 D0 FF C2 C2'
+ 'C2 FF D9 D9 D9 FF E8 E8 E8 FF 00 00 00 FF 00 00'
+ '00 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
+ '00 FF E9 E9 E9 FF D0 D0 D0 FF CD CD CD FF CD CD'
+ 'CD FF D6 D6 D6 FF ED ED ED FF DC DC DC FF D4 D4'
+ 'D4 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5 D5 FF DB DB'
+ 'DB FF ED ED ED FF DA DA DA FF CD CD CD FF CD CD'
+ 'CD FF DF DF DF FF B8 B8 B8 FF 00 00 00 FB 00 00'
+ '00 3A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
+ '00 FE D7 D7 D7 FF D2 D2 D2 FF CB CB CB FF CA CA'
+ 'CA FF E9 E9 E9 FF DC DC DC FF D1 D1 D1 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D1 D1'
+ 'D1 FF D8 D8 D8 FF EA EA EA FF C9 C9 C9 FF CA CA'
+ 'CA FF E0 E0 E0 FF A0 A0 A0 FF 00 00 00 EB 00 00'
+ '00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
+ '00 E1 9F 9F 9F FF DD DD DD FF CD CD CD FF DB DB'
+ 'DB FF CE CE CE FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF C8 C8 C8 FF DA DA DA FF C7 C7'
+ 'C7 FF E2 E2 E2 FF 5A 5A 5A FF 00 00 00 94 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 B2 83 83 83 FF DD DD DD FF D1 D1 D1 FF DB DB'
+ 'DB FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF C9 C9 C9 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF D3 D3 D3 FF C8 C8'
+ 'C8 FF DE DE DE FF 42 42 42 FF 00 00 00 6C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 4B 41 41 41 FF D8 D8 D8 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF C7 C7 C7 FF C4 C4 C4 FF C1 C1 C1 FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C1 C1 C1 FF BF BF BF FF C0 C0'
+ 'C0 FF B2 B2 B2 FF 1A 1A 1A FF 00 00 00 28 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 1A 2C 2C 2C FF CC CC CC FF D5 D5 D5 FF CC CC'
+ 'CC FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D5 D5 D5 FF CF CF CF FF CC CC'
+ 'CC FF C6 C6 C6 FF C4 C4 C4 FF B3 B3 B3 FF BD BD'
+ 'BD FF 99 99 99 FF 09 09 09 FF 00 00 00 19 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 08 08 08 FF 97 97 97 FF DF DF DF FF DC DC'
+ 'DC FF D6 D6 D6 FF DE DE DE FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DE DE DE FF D8 D8 D8 FF DD DD DD FF DC DC'
+ 'DC FF 53 53 53 FF 00 00 00 FF 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 77 77 77 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF CE CE CE FF D7 D7 D7 FF E2 E2 E2 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
+ 'E1 FF D9 D9 D9 FF CD CD CD FF E3 E3 E3 FF D9 D9'
+ 'D9 FF 39 39 39 FF 00 00 00 FF 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 FF 35 35 35 FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E7 E7 E7 FF E7 E7 E7 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF E3 E3 E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E3 E3 E3 FF E3 E3 E3 FF D4 D4 D4 FF D1 D1'
+ 'D1 FF E7 E7 E7 FF E7 E7 E7 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 0B 0B 0B FF 00 00 00 ED 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 F9 1E 1E 1E FF E4 E4 E4 FF ED ED'
+ 'ED FF E6 E6 E6 FF EC EC EC FF EA EA EA FF E4 E4'
+ 'E4 FF DF DF DF FF DF DF DF FF DC DC DC FF DC DC'
+ 'DC FF DF DF DF FF DF DF DF FF E2 E2 E2 FF E9 E9'
+ 'E9 FF EA EA EA FF E5 E5 E5 FF EB EB EB FF D6 D6'
+ 'D6 FF 00 00 00 FF 00 00 00 C3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 AE 00 00 00 FF E0 E0 E0 FF C4 C4'
+ 'C4 FF B8 B8 B8 FF B2 B2 B2 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3'
+ 'F3 FF B0 B0 B0 FF B6 B6 B6 FF EB EB EB FF CD CD'
+ 'CD FF 00 00 00 FF 00 00 00 85 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 80 00 00 00 FF CE CE CE FF DD DD'
+ 'DD FF D5 D5 D5 FF E4 E4 E4 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
+ 'FA FF DF DF DF FF D8 D8 D8 FF D7 D7 D7 FF B0 B0'
+ 'B0 FF 00 00 00 FF 00 00 00 67 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 02 00 00 00 9C 0C 0C 0C FF 3D 3D'
+ '3D FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 49 49 49 FF 2F 2F 2F FF 02 02'
+ '02 FF 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 06 00 00 00 F1 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
+ '8F FF 00 00 00 00 00 00 00 00 FF FC 1F FF F8 00'
+ '1F FF F0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 E0 00'
+ '00 07 E0 00 00 07 E0 00 00 07 E0 00 00 07 F0 00'
+ '00 0F F0 00 00 0F F0 00 00 0F F0 00 00 1F F8 00'
+ '00 1F F8 00 00 1F F8 00 00 1F F8 00 00 1F F8 00'
+ '00 1F F8 00 00 3F FC 00 00 7F FF FF FF FF 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
+ '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ 'CC 00 00 CC 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 CC C0 0C CC 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '0C CC CC C0 00 00 00 00 00 00 00 00 00 00 88 88'
+ '88 88 88 88 88 88 88 88 88 CC CC 88 88 88 88 88'
+ '88 88 88 88 88 88 77 77 77 77 77 77 77 77 77 77'
+ '77 CC CC 77 77 77 77 77 77 77 77 77 77 77 00 00'
+ '00 00 00 00 00 00 00 00 0C CC CC C0 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ 'CC C7 7C CC 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 CC 07 70 CC 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
+ '00 08 FF F7 88 88 77 77 77 77 77 77 77 77 77 77'
+ '66 87 80 00 00 00 00 00 00 07 FF F7 00 88 88 87'
+ '77 77 87 87 77 77 87 78 66 67 80 00 00 00 00 00'
+ '00 07 FF F7 88 88 88 77 77 77 87 87 87 87 87 77'
+ '77 87 80 00 00 00 00 00 00 07 FF F7 88 88 88 77'
+ '77 78 87 87 87 87 87 77 77 77 80 00 00 00 00 00'
+ '00 07 FF F7 88 88 88 77 77 78 87 87 87 87 87 77'
+ '77 77 80 00 00 00 00 00 00 07 FF F7 88 88 88 87'
+ '77 78 87 88 87 87 87 77 77 77 80 00 00 00 00 00'
+ '00 07 FF F7 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 77 80 00 00 00 00 00 00 07 FF FF FF FF FF FF'
+ '77 77 77 77 77 77 77 77 77 77 80 00 00 00 00 00'
+ '00 07 FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF F7 80 00 00 00 00 00 00 07 FF FF FF 77 77 7F'
+ 'FF FF FF FF FF FF FF FF FF FF 80 00 00 00 00 00'
+ '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 7F 80 00 00 00 00 00'
+ '00 07 F7 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 7F 80 00 00 00 00 00 00 07 F7 77 77 77 77 7F'
+ 'FF FF FF FF F7 77 77 77 77 7F 80 00 00 00 00 00'
+ '00 08 F7 77 77 77 7F FF 77 77 77 77 FF FF 77 77'
+ '77 77 00 00 00 00 00 00 00 08 F7 77 77 7F F7 77'
+ '77 77 77 77 77 7F F7 77 77 77 00 00 00 00 00 00'
+ '00 00 77 77 77 F7 77 77 77 77 77 77 77 77 7F 77'
+ '77 F7 00 00 00 00 00 00 00 00 77 77 7F 77 77 77'
+ '77 77 77 77 77 77 77 F7 77 F8 00 00 00 00 00 00'
+ '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 F8 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 78 00 00 00 00 00 00'
+ '00 00 87 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 70 00 00 00 00 00 00 00 00 87 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
+ '00 00 07 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 00 00 07 77 77 77 77 77'
+ '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
+ '00 00 08 77 77 77 77 77 77 77 77 77 77 77 77 77'
+ '77 80 00 00 00 00 00 00 00 00 08 7F F7 77 FF FF'
+ 'FF FF FF FF FF FF 77 7F 77 00 00 00 00 00 00 00'
+ '00 00 08 7F FF F7 77 FF FF FF FF FF FF 77 7F FF'
+ '77 00 00 00 00 00 00 00 00 00 00 7F FF FF 77 77'
+ 'FF FF FF FF 77 77 FF FF 78 00 00 00 00 00 00 00'
+ '00 00 00 7F FF FF FF FF 77 77 77 77 7F FF FF FF'
+ '78 00 00 00 00 00 00 00 00 00 00 8F 77 77 FF FF'
+ 'FF FF FF FF FF FF 77 7F 78 00 00 00 00 00 00 00'
+ '00 00 00 8F 77 77 FF FF FF FF FF FF FF F7 77 7F'
+ '78 00 00 00 00 00 00 00 00 00 00 87 77 7F FF FF'
+ 'FF FF FF FF FF FF 77 77 70 00 00 00 00 00 00 00'
+ '00 00 00 08 77 77 77 77 77 77 77 77 77 77 77 77'
+ '80 00 00 00 00 00 00 00 00 00 00 00 08 88 88 88'
+ '88 88 88 88 88 88 88 80 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF F1 C7 FF FF 00 00 FF FF'
+ 'F0 07 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'F8 0F FF FF 00 00 FF FF F0 07 FF FF 00 00 FF FF'
+ 'F2 07 FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
+ '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
+ '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ 'FF FF 00 00 FF FF 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 FF FF 00 00 FF FF 00 00'
+ '00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 30 00 00 00 24 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 30 00 00'
+ '00 30 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
+ '00 3C 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 9C 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 90 00 00 00 90 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
+ 'FF FF 00 00 FF FF 00 00 FF FF 00 00 00 3C 00 00'
+ '00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ 'FF FF 00 00 FF FF 00 00 FF FF C0 C0 C0 FF C0 C0'
+ 'C0 FF 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00'
+ '00 15 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
+ '00 09 00 00 00 09 00 00 00 09 00 00 00 09 00 00'
+ '00 09 00 00 00 09 00 00 00 09 00 00 00 07 00 00'
+ '00 04 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ 'FF FF 00 00 FF FF 00 00 00 37 C0 C0 C0 FF C0 C0'
+ 'C0 FF 00 00 00 37 00 00 FF FF 00 00 FF FF 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 35 00 00 00 18 00 00'
+ '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
+ '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F1 00 00 00 B1 00 00'
+ '00 5C 00 00 00 0D 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
+ '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2E 2C'
+ '2D FF 2E 2C 2D FF 13 13 13 FF 00 00 00 FF 00 00'
+ '00 F6 00 00 00 69 00 00 00 09 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
+ '90 FF CA CA CA FF CD CD CD FF CB CB CB FF CE CE'
+ 'CE FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
+ 'C9 FF C7 C7 C7 FF C6 C6 C6 FF C5 C5 C5 FF C4 C4'
+ 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2 C2 FF C3 C3'
+ 'C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF BF FF BF BF'
+ 'BF FF BC BC BC FF BD BD BD FF BA BA BA FF BB BB'
+ 'BB FF B5 B5 B5 FF B3 B4 B3 FF B8 B4 B6 FF AD AD'
+ 'AD FF AB AC AC FF AD A8 AB FF 63 63 63 FF 09 09'
+ '09 FF 00 00 00 EF 00 00 00 42 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 03 00 00 00 AD 01 01 01 FF 8A 8A 8A FF EB EB'
+ 'EB FF E8 E8 E8 FF E7 E7 E7 FF D5 D5 D5 FF 85 85'
+ '85 FF 88 88 88 FF 92 92 92 FF 98 98 98 FF A2 A2'
+ 'A2 FF AD AD AD FF BA BA BA FF C0 C0 C0 FF C3 C3'
+ 'C3 FF C6 C6 C6 FF CB CB CB FF CA CA CA FF CA CA'
+ 'CA FF D6 D6 D6 FF CA CA CA FF D3 D3 D3 FF CB CB'
+ 'CB FF D7 D7 D7 FF CC CC CC FF D4 D4 D4 FF C7 C7'
+ 'C7 FF C8 C9 C9 FF C6 C2 C4 FF 9D B3 A8 FF 20 A8'
+ '63 FF 1C A8 60 FF 90 AF A0 FF BF BB BD FF 4F 4F'
+ '4F FF 00 00 00 FF 00 00 00 81 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 15 00 00 00 F0 19 19 19 FF C7 C7 C7 FF EC EC'
+ 'EC FF E2 E2 E2 FF E6 E6 E6 FF CB CB CB FF 3B 3B'
+ '3B FF 3F 3F 3F FF 56 56 56 FF 72 72 72 FF 87 87'
+ '87 FF 92 92 92 FF 9D 9D 9D FF A5 A5 A5 FF A8 A8'
+ 'A8 FF AC AC AC FF B7 B7 B7 FF A9 A9 A9 FF 9C 9C'
+ '9C FF BD BD BD FF 99 99 99 FF B7 B7 B7 FF A1 A1'
+ 'A1 FF C3 C3 C3 FF A3 A3 A3 FF BD BD BD FF 98 98'
+ '98 FF C5 C4 C4 FF C7 BF C3 FF 51 A7 7C FF 17 CE'
+ '71 FF 0A BF 61 FF 2F 99 64 FF C3 BD C0 FF 84 83'
+ '84 FF 01 01 01 FF 00 00 00 A3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 30 00 00 00 FA 29 29 29 FF D1 D1 D1 FF EA EA'
+ 'EA FF E4 E4 E4 FF E7 E7 E7 FF CD CD CD FF 47 47'
+ '47 FF 5F 5F 5F FF 79 79 79 FF 87 87 87 FF 8F 8F'
+ '8F FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF B9 B9 B9 FF A4 A4 A4 FF 90 90'
+ '90 FF B8 B8 B8 FF 8A 8A 8A FF AF AF AF FF 94 94'
+ '94 FF BF BF BF FF 97 97 97 FF B7 B7 B7 FF 88 88'
+ '88 FF C4 C3 C3 FF C6 C3 C5 FF 95 B2 A3 FF 91 D6'
+ 'B4 FF 91 D8 B5 FF 83 AB 97 FF C4 C1 C3 FF 8E 8E'
+ '8E FF 01 01 01 FF 00 00 00 B7 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 34 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EC EC'
+ 'EC FF E6 E6 E6 FF E7 E7 E7 FF D1 D1 D1 FF 68 68'
+ '68 FF 74 74 74 FF 7E 7E 7E FF 85 85 85 FF 8E 8E'
+ '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF BA BA BA FF 9F 9F 9F FF 83 83'
+ '83 FF B3 B3 B3 FF 7C 7C 7C FF A8 A8 A8 FF 87 87'
+ '87 FF BB BB BB FF 8A 8A 8A FF B2 B2 B2 FF 79 79'
+ '79 FF C2 C2 C2 FF C4 C4 C4 FF C6 C3 C4 FF 99 AC'
+ 'A2 FF 96 AB A0 FF C2 BE C0 FF C4 C4 C4 FF 8D 8D'
+ '8D FF 01 01 01 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 28 28 28 FF D1 D1 D1 FF EE EE'
+ 'EE FF E7 E7 E7 FF E8 E8 E8 FF D6 D6 D6 FF 70 70'
+ '70 FF 71 71 71 FF 7D 7D 7D FF 85 85 85 FF 8E 8E'
+ '8E FF 97 97 97 FF A0 A0 A0 FF A7 A7 A7 FF AA AA'
+ 'AA FF AE AE AE FF BB BB BB FF 98 98 98 FF 73 73'
+ '73 FF AD AD AD FF 6A 6A 6A FF A0 A0 A0 FF 78 78'
+ '78 FF B7 B7 B7 FF 7C 7C 7C FF AB AB AB FF 67 67'
+ '67 FF C2 C2 C2 FF C6 C6 C6 FF C4 C3 C4 FF C7 C4'
+ 'C5 FF C6 C2 C4 FF BF BF BF FF C5 C5 C5 FF 8D 8D'
+ '8D FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D1 D1 D1 FF EF EF'
+ 'EF FF E9 E9 E9 FF EB EB EB FF D6 D6 D6 FF 6A 6A'
+ '6A FF 6C 6C 6C FF 78 78 78 FF 81 81 81 FF 8A 8A'
+ '8A FF 93 93 93 FF 9C 9C 9C FF A3 A3 A3 FF A6 A6'
+ 'A6 FF AB AB AB FF B9 B9 B9 FF 90 90 90 FF 66 66'
+ '66 FF A5 A5 A5 FF 5B 5B 5B FF 98 98 98 FF 6B 6B'
+ '6B FF B1 B1 B1 FF 70 70 70 FF A4 A4 A4 FF 58 58'
+ '58 FF C1 C1 C1 FF C8 C8 C8 FF C5 C5 C5 FF C3 C3'
+ 'C3 FF C2 C2 C2 FF C1 C1 C1 FF C6 C6 C6 FF 8E 8E'
+ '8E FF 01 01 01 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 27 27 27 FF D2 D2 D2 FF F2 F2'
+ 'F2 FF EB EB EB FF EA EA EA FF DF DF DF FF A7 A7'
+ 'A7 FF A7 A7 A7 FF AB AB AB FF AE AE AE FF B0 B0'
+ 'B0 FF B3 B3 B3 FF B6 B6 B6 FF B9 B9 B9 FF B9 B9'
+ 'B9 FF BA BA BA FF BD BD BD FF B7 B7 B7 FF B1 B1'
+ 'B1 FF BE BE BE FF AF AF AF FF BA BA BA FF B1 B1'
+ 'B1 FF BE BE BE FF B0 B0 B0 FF BA BA BA FF AB AB'
+ 'AB FF C5 C5 C5 FF C8 C8 C8 FF C6 C6 C6 FF C4 C4'
+ 'C4 FF C3 C3 C3 FF C2 C2 C2 FF C9 C9 C9 FF 8E 8E'
+ '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F3 F3'
+ 'F3 FF EB EB EB FF EB EB EB FF EA EA EA FF ED ED'
+ 'ED FF EB EB EB FF E9 E9 E9 FF E8 E8 E8 FF E6 E6'
+ 'E6 FF E4 E4 E4 FF E2 E2 E2 FF E1 E1 E1 FF DF DF'
+ 'DF FF DE DE DE FF DB DB DB FF DB DB DB FF DC DC'
+ 'DC FF D8 D8 D8 FF D9 D9 D9 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
+ 'D0 FF CB CB CB FF CA CA CA FF C9 C9 C9 FF C7 C7'
+ 'C7 FF C4 C4 C4 FF C0 C0 C0 FF CA CA CA FF 8E 8E'
+ '8E FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
+ 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF ED ED'
+ 'ED FF ED ED ED FF ED ED ED FF EC EC EC FF EC EC'
+ 'EC FF EB EB EB FF E0 E0 E0 FF D0 D0 D0 FF 8D 8D'
+ '8D FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
+ 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
+ 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E2 E2 E2 FF E3 E3 E3 FF E3 E3'
+ 'E3 FF E3 E3 E3 FF F8 F8 F8 FF EF EF EF FF 8C 8C'
+ '8C FF 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
+ 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
+ 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF DB DB DB FF CF CF CF FF BC BC BC FF BB BB'
+ 'BB FF D1 D1 D1 FF DE DE DE FF FF FF FF FF 9A 9A'
+ '9A FF 00 00 00 FF 00 00 00 BA 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
+ 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
+ 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9'
+ 'D9 FF D2 D2 D2 FF A8 A8 A8 FF B6 B6 B6 FF B1 B1'
+ 'B1 FF B5 B5 B5 FF D8 D8 D8 FF FC FC FC FF 9C 9C'
+ '9C FF 00 00 00 FF 00 00 00 AE 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
+ 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
+ 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D7 D7'
+ 'D7 FF C9 C9 C9 FF A6 A6 A6 FF C3 C3 C3 FF B3 B3'
+ 'B3 FF AD AD AD FF D6 D6 D6 FF F5 F5 F5 FF 76 76'
+ '76 FF 00 00 00 FF 00 00 00 8C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
+ 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
+ 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF DD DD DD FF E1 E1 E1 FF E3 E3'
+ 'E3 FF E6 E6 E6 FF EA EA EA FF ED ED ED FF ED ED'
+ 'ED FF EB EB EB FF E7 E7 E7 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF DE DE DE FF D4 D4 D4 FF D0 D0 D0 FF D2 D2'
+ 'D2 FF D3 D3 D3 FF C5 C5 C5 FF D0 D0 D0 FF C2 C2'
+ 'C2 FF BF BF BF FF D9 D9 D9 FF E8 E8 E8 FF 56 56'
+ '56 FF 00 00 00 FF 00 00 00 72 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
+ 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
+ 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF DF DF'
+ 'DF FF F0 F0 F0 FF EC EC EC FF E1 E1 E1 FF DE DE'
+ 'DE FF DD DD DD FF DC DC DC FF DB DB DB FF DB DB'
+ 'DB FF DC DC DC FF DD DD DD FF DE DE DE FF E1 E1'
+ 'E1 FF EC EC EC FF F1 F1 F1 FF E1 E1 E1 FF D1 D1'
+ 'D1 FF CE CE CE FF D0 D0 D0 FF CB CB CB FF CE CE'
+ 'CE FF D1 D1 D1 FF D9 D9 D9 FF D4 D4 D4 FF 3F 3F'
+ '3F FF 00 00 00 FF 00 00 00 55 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
+ 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF CA CA CA FF D6 D6 D6 FF ED ED ED FF E6 E6'
+ 'E6 FF DC DC DC FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF ED ED'
+ 'ED FF DA DA DA FF CA CA CA FF CD CD CD FF CD CD'
+ 'CD FF CB CB CB FF DF DF DF FF B8 B8 B8 FF 22 22'
+ '22 FF 00 00 00 FB 00 00 00 3A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
+ 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
+ 'CA FF D4 D4 D4 FF E9 E9 E9 FF DC DC DC FF D0 D0'
+ 'D0 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D8 D8'
+ 'D8 FF EA EA EA FF D8 D8 D8 FF C9 C9 C9 FF CA CA'
+ 'CA FF C9 C9 C9 FF E0 E0 E0 FF A0 A0 A0 FF 08 08'
+ '08 FF 00 00 00 EB 00 00 00 22 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
+ 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
+ 'CE FF E4 E4 E4 FF D4 D4 D4 FF CF CF CF FF D1 D1'
+ 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF CD CD CD FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CC CC'
+ 'CC FF D0 D0 D0 FF E2 E2 E2 FF CF CF CF FF C7 C7'
+ 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 C2 00 00 00 0E 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
+ '9F FF DD DD DD FF CC CC CC FF CD CD CD FF DB DB'
+ 'DB FF D6 D6 D6 FF CE CE CE FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF C8 C8 C8 FF CF CF CF FF DA DA DA FF C7 C7'
+ 'C7 FF C9 C9 C9 FF E2 E2 E2 FF 5A 5A 5A FF 00 00'
+ '00 FF 00 00 00 94 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
+ '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF DB DB'
+ 'DB FF D1 D1 D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF C9 C9 C9 FF C5 C5'
+ 'C5 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C7 C7 C7 FF D3 D3 D3 FF C8 C8'
+ 'C8 FF C9 C9 C9 FF DE DE DE FF 42 42 42 FF 00 00'
+ '00 FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
+ '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D4 D4'
+ 'D4 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D0 D0 D0 FF C8 C8'
+ 'C8 FF C3 C3 C3 FF C3 C3 C3 FF C3 C3 C3 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C7 C7 C7 FF C5 C5'
+ 'C5 FF CB CB CB FF CC CC CC FF 2D 2D 2D FF 00 00'
+ '00 F8 00 00 00 40 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
+ '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF CD CD CD FF C7 C7 C7 FF C4 C4 C4 FF C2 C2'
+ 'C2 FF C1 C1 C1 FF C0 C0 C0 FF C1 C1 C1 FF C1 C1'
+ 'C1 FF C1 C1 C1 FF C2 C2 C2 FF BF BF BF FF C0 C0'
+ 'C0 FF CE CE CE FF B2 B2 B2 FF 1A 1A 1A FF 00 00'
+ '00 E5 00 00 00 28 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
+ '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF CC CC'
+ 'CC FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D7 D7 D7 FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF CF CF CF FF CC CC CC FF C9 C9 C9 FF C6 C6'
+ 'C6 FF C4 C4 C4 FF C2 C2 C2 FF B3 B3 B3 FF BD BD'
+ 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
+ '00 CF 00 00 00 19 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
+ '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF D0 D0'
+ 'D0 FF D2 D2 D2 FF DB DB DB FF D9 D9 D9 FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DB DB DB FF DB DB DB FF DA DA DA FF D9 D9'
+ 'D9 FF D9 D9 D9 FF CF CF CF FF C5 C5 C5 FF CC CC'
+ 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
+ '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
+ '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
+ 'DC FF CE CE CE FF D6 D6 D6 FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DE DE'
+ 'DE FF D8 D8 D8 FF CE CE CE FF DD DD DD FF DC DC'
+ 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
+ '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
+ '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DE DE DE FF CE CE CE FF D7 D7 D7 FF E1 E1'
+ 'E1 FF E2 E2 E2 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF D9 D9'
+ 'D9 FF CD CD CD FF DA DA DA FF E3 E3 E3 FF D9 D9'
+ 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
+ '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
+ '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF E1 E1 E1 FF D7 D7 D7 FF D2 D2'
+ 'D2 FF DA DA DA FF E4 E4 E4 FF E5 E5 E5 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF DC DC DC FF D2 D2 D2 FF D6 D6'
+ 'D6 FF E0 E0 E0 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
+ 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
+ '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
+ '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF DF DF'
+ 'DF FF D2 D2 D2 FF D3 D3 D3 FF DE DE DE FF E3 E3'
+ 'E3 FF E3 E3 E3 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E3 E3 E3 FF E3 E3 E3 FF DE DE'
+ 'DE FF D4 D4 D4 FF D1 D1 D1 FF DD DD DD FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
+ '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
+ '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
+ 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
+ 'EB FF EA EA EA FF E4 E4 E4 FF E0 E0 E0 FF DF DF'
+ 'DF FF DF DF DF FF DD DD DD FF DC DC DC FF DC DC'
+ 'DC FF DD DD DD FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF E2 E2 E2 FF E9 E9 E9 FF EC EC EC FF EA EA'
+ 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
+ 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
+ '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
+ 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
+ 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
+ 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
+ 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
+ '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
+ 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
+ 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
+ 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
+ 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
+ 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
+ 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
+ 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
+ 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
+ '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
+ '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
+ '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
+ '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
+ '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'F1 C7 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF F8 07 FF FF 00 00 FF FF'
+ 'E0 00 00 3F 00 00 FF 00 00 00 00 7F 00 00 FC 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 01 FF 00 00 FF 80 00 00 03 FF 00 00 FF E0'
+ '00 00 07 FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
+ '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
+ '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 13 13'
+ '13 00 18 18 18 00 19 19 19 00 1A 1A 1A 00 1E 1E'
+ '1E 00 1F 1F 1F 00 20 20 20 00 21 21 21 00 22 22'
+ '22 00 24 24 24 00 26 26 26 00 27 27 27 00 28 28'
+ '28 00 29 29 29 00 2A 2A 2A 00 2B 2B 2B 00 2C 2C'
+ '2C 00 2D 2D 2D 00 2E 2C 2D 00 2F 2F 2F 00 34 34'
+ '34 00 35 35 35 00 39 39 39 00 3B 3B 3B 00 3D 3D'
+ '3D 00 3F 3F 3F 00 40 40 40 00 41 41 41 00 42 42'
+ '42 00 47 47 47 00 48 48 48 00 49 49 49 00 4B 4B'
+ '4B 00 4F 4F 4F 00 53 53 53 00 56 56 56 00 58 58'
+ '58 00 59 59 59 00 5A 5A 5A 00 5B 5B 5B 00 5D 5D'
+ '5D 00 5F 5F 5F 00 61 61 61 00 63 63 63 00 64 64'
+ '64 00 66 66 66 00 67 67 67 00 68 68 68 00 6A 6A'
+ '6A 00 6B 6B 6B 00 6C 6C 6C 00 70 70 70 00 71 71'
+ '71 00 72 72 72 00 73 73 73 00 74 74 74 00 75 75'
+ '75 00 76 76 76 00 77 77 77 00 78 78 78 00 79 79'
+ '79 00 7A 7A 7A 00 7C 7C 7C 00 7D 7D 7D 00 7E 7E'
+ '7E 00 7F 7F 7F 00 2F 99 64 00 1C A8 60 00 0A BF'
+ '61 00 20 A8 63 00 51 A7 7C 00 17 CE 71 00 00 00'
+ 'FF 00 80 80 80 00 81 81 81 00 83 83 83 00 84 83'
+ '84 00 85 85 85 00 87 87 87 00 88 88 88 00 8A 8A'
+ '8A 00 8C 8C 8C 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
+ '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 94 94'
+ '94 00 97 97 97 00 98 98 98 00 99 99 99 00 9A 9A'
+ '9A 00 9C 9C 9C 00 9D 9D 9D 00 9F 9F 9F 00 83 AB'
+ '97 00 96 AB A0 00 90 AF A0 00 99 AC A2 00 95 B2'
+ 'A3 00 9D B3 A8 00 A0 A0 A0 00 A1 A1 A1 00 A2 A2'
+ 'A2 00 A3 A3 A3 00 A4 A4 A4 00 A5 A5 A5 00 A6 A6'
+ 'A6 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9 A9 00 AA AA'
+ 'AA 00 AB AB AB 00 AD A8 AB 00 AB AC AC 00 AC AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
+ 'B0 00 B1 B1 B1 00 B2 B2 B2 00 B3 B3 B3 00 B3 B4'
+ 'B3 00 B5 B5 B5 00 B6 B6 B6 00 B7 B7 B7 00 B8 B4'
+ 'B6 00 B8 B8 B8 00 B9 B9 B9 00 BA BA BA 00 BB BB'
+ 'BB 00 BF BB BD 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 91 D6 B4 00 91 D8 B5 00 C3 BD'
+ 'C0 00 C2 BE C0 00 C7 BF C3 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C1 C3 00 C4 C3'
+ 'C3 00 C4 C3 C4 00 C6 C2 C4 00 C6 C3 C4 00 C6 C3'
+ 'C5 00 C4 C4 C4 00 C5 C4 C4 00 C5 C5 C5 00 C7 C4'
+ 'C5 00 C6 C6 C6 00 C7 C7 C7 00 C8 C8 C8 00 C8 C9'
+ 'C9 00 C9 C9 C9 00 CA CA CA 00 CB CB CB 00 CC CC'
+ 'CC 00 CD CD CD 00 CE CE CE 00 CF CF CF 00 D0 D0'
+ 'D0 00 D1 D1 D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 DF DF DF 00 E0 E0'
+ 'E0 00 E1 E1 E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4'
+ 'E4 00 E5 E5 E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8'
+ 'E8 00 E9 E9 E9 00 EA EA EA 00 EB EB EB 00 EC EC'
+ 'EC 00 ED ED ED 00 EE EE EE 00 EF EF EF 00 F0 F0'
+ 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4'
+ 'F4 00 F5 F5 F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8'
+ 'F8 00 F9 F9 F9 00 FA FA FA 00 FC FC FC 00 FF FF'
+ 'FF 00 00 00 00 00 10 DA 4B 00 F8 0F 0D 01 71 CC'
+ '43 00 F8 0F 0D 01 40 E3 0C 01 A4 1A 95 00 2C A3'
+ 'AF 00 C4 F5 AF 00 03 00 00 00 40 E3 0C 01 2F 0C'
+ '00 00 B8 10 0D 01 30 00 00 00 00 00 00 00 40 00'
+ '00 00 F8 0F 0D 01 C0 00 00 00 30 00 00 00 00 09'
+ '00 00 00 24 00 00 00 00 00 00 00 00 00 00 30 00'
+ '00 00 30 00 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 52 52 DF 00 00 00'
+ '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 52 52 52 DF 00 52'
+ '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 DF DF DF DF DF DF DF DF DF DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF 52 52 52 52 52'
+ '52 DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
+ 'DF DF DF DF DF DF 53 53 53 53 53 53 53 53 53 53'
+ '53 53 53 53 53 53 53 53 53 53 53 53 52 52 52 52'
+ '53 53 53 53 53 53 53 53 53 53 53 53 53 53 53 53'
+ '53 53 53 53 53 53 99 99 99 99 99 99 99 99 99 99'
+ '99 99 99 99 99 99 99 99 99 99 99 99 52 52 52 52'
+ '99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
+ '99 99 99 99 99 99 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 52 52 52 52 52'
+ '52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 52 52 52 99 99 52'
+ '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 52 52 00 99 99 DF'
+ '52 52 DF 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF DF DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 DF DF DF DF 11'
+ '1A 19 1A 19 19 19 19 19 19 19 19 19 19 19 18 18'
+ '18 18 18 18 18 18 18 19 19 19 1C 1C 0A DF DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 DF DF 14 5F AC'
+ 'AF AD B0 AF AE AD AB A8 A7 A5 A3 9C 9B 9B 9C 99'
+ '9A 93 93 90 91 8D 8E 87 86 8A 7F 7D 7C 35 07 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 01 5A CD CA'
+ 'C9 B7 57 59 60 64 72 7F 8D 99 9C A7 AD AC AC B8'
+ 'AC B5 AD B9 AE B6 A8 AA A0 6F 4F 4D 6C 8F 2B DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 0C A8 CE C4'
+ 'C8 AD 21 23 2D 3F 58 60 68 75 78 7E 89 79 67 91'
+ '65 89 71 9C 73 91 64 A4 98 50 51 4E 4C 96 56 01'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 17 B3 CC C6'
+ 'C9 AF 27 33 46 58 5E 63 70 77 7A 80 8C 74 5F 8B'
+ '5A 81 62 93 63 89 59 9E A2 6E 94 95 6A 9D 5D 01'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 16 B3 CE C8'
+ 'C9 B3 39 41 4A 57 5D 63 70 77 7A 80 8D 69 55 85'
+ '48 78 58 8E 5A 84 46 9B A3 A1 6D 6B 97 A3 5C 01'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 16 B3 D0 C9'
+ 'CA B8 3D 3E 49 57 5D 63 70 77 7A 80 8E 64 40 7F'
+ '3A 70 45 89 48 7B 38 9B A7 9F A6 A0 93 A5 5C 01'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 15 B3 D1 CB'
+ 'CD B8 3A 3C 45 54 5A 61 67 73 76 7B 8C 5F 37 75'
+ '31 64 3B 83 3D 74 2E 9A A9 A5 9C 9B 9A A7 5D 01'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 15 B4 D4 CD'
+ 'CC C1 77 77 7B 80 82 85 88 8C 8C 8D 91 89 83 92'
+ '81 8D 83 92 82 8D 7B A5 A9 A7 A3 9C 9B AB 5D DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 14 B5 D5 CD'
+ 'CD CC CF CD CB CA C8 C6 C4 C3 C1 C0 BD BD BE BA'
+ 'BB B8 B8 B4 B4 B1 B2 AD AC AB A8 A3 99 AC 5D DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 14 B5 D9 DA'
+ 'D8 D8 D8 D7 D7 D6 D6 D5 D5 D5 D4 D4 D3 D3 D3 D2'
+ 'D2 D2 D1 D1 D0 D0 CF CF CF CE CE CD C2 B2 5C DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 13 B8 DE CB'
+ 'C3 C4 C4 C2 C1 C1 C1 C1 C1 C2 C2 C2 C2 C2 C2 C2'
+ 'C2 C2 C2 C2 C2 C2 C2 C2 C4 C5 C5 C5 DA D1 5B DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 13 C0 DA BB'
+ 'A3 8E 93 BA BC BB BB BB BB BB BB BB BB BB BB BB'
+ 'BB BB BB BB BB BB BB BD B1 90 8E B3 C0 DE 66 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 0F BC D5 A7'
+ '79 89 82 9C BC BA BA BA BA BA B9 B9 B9 B9 B9 B9'
+ 'B9 B9 BA BA BA BA BB B4 78 88 83 87 BA DD 67 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 DF DF 03 9B D8 90'
+ '84 9C 7B 8E BA B7 B7 B7 B6 B5 B5 B7 B9 BA BA B9'
+ 'B7 B5 B5 B5 B6 B7 B9 AB 76 9C 85 7F B8 D7 43 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 74 D6 B1'
+ 'A5 B4 93 AB B5 B4 B2 B5 BF C3 C5 C8 CC CF CF CD'
+ 'C9 C6 C4 C0 B6 B2 B4 B5 A5 B2 9B 93 BB CA 2D DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 4A D1 B3'
+ 'B1 AD B1 B3 B0 B1 C1 D2 CE C3 C0 BF BE BD BD BE'
+ 'BF C0 C3 CE D3 C3 B3 B0 B2 AD B0 B3 BB B6 23 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 2F CB B2'
+ 'AF AF AF AC B8 CF C8 BE B6 B7 B8 B8 B8 B8 B8 B8'
+ 'B8 B8 B7 B7 BD C6 CF BC AC AF AF AD C1 8B 12 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 24 B9 B4'
+ 'AC AD AC B6 CB BE B2 B3 B4 B4 B4 B4 B4 B4 B4 B4'
+ 'B4 B4 B4 B4 B3 B2 BA CC BA AB AC AB C2 70 06 DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 12 89 BD'
+ 'AC AD B0 C6 B6 B1 B3 B2 B2 B2 B2 B1 AF B0 B0 B0'
+ 'B0 B0 B0 B0 B0 B0 AE B2 C4 B1 A8 AB C4 53 DF DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 DF DF 05 69 BF'
+ 'AE AF BD B8 B0 B2 B2 B2 B2 B2 B2 B1 AE AB AC AC'
+ 'AC AC AC AC AC AC AC A9 B1 BC A8 AB C4 30 DF DF'
+ 'DF 00 00 00 00 00 00 00 00 00 00 00 DF DF 55 BF'
+ 'B1 B3 BD B3 B2 B2 B2 B2 B2 B2 B2 B2 B1 AB A5 A7'
+ 'A7 A7 A7 A7 A7 A7 A7 A7 A8 B5 A9 AB C0 26 DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 33 BE'
+ 'B3 B4 B6 B3 B3 B3 B3 B3 B3 B3 B3 B3 B3 B2 A9 9C'
+ '9C 9C A3 A3 A3 A3 A3 A3 A3 A8 A5 AD AE 1B DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 25 BA'
+ 'B6 B4 B2 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 B5 AF'
+ 'A8 A3 9B 9A 99 9A 9A 9A 9B 93 99 B0 84 0D DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 1A AE'
+ 'B8 B7 AE B7 B8 B8 B8 B8 B8 B8 B8 B8 B8 B8 B8 B9'
+ 'B8 B7 B5 B1 AE AB A7 A3 9B 85 91 B2 65 07 DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 0B 82'
+ 'BD BD B2 B4 BD BB BC BC BC BC BC BC BC BC BC BC'
+ 'BC BC BC BD BD BC BB BB B1 A5 AE AC 47 02 DF DF'
+ '00 00 00 00 00 00 00 00 00 00 00 00 DF DF 06 63'
+ 'BE C1 BE B0 B8 C0 BF BF BF BF BF BF BF BF BF BF'
+ 'BF BF BF BF BF BF C0 BA B0 BF BE A7 2C DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 44'
+ 'B5 C4 C3 C0 B0 B9 C3 C4 C2 C2 C2 C2 C2 C2 C2 C2'
+ 'C2 C2 C2 C2 C3 C3 BB AF BC C5 BB 8E 20 DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 2A'
+ 'AB C7 C5 C6 C3 B9 B4 BC C6 C7 C6 C6 C6 C6 C6 C6'
+ 'C6 C6 C7 C7 BE B4 B8 C2 C6 C8 B8 78 10 DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 1F'
+ '91 C8 C8 C8 C9 C9 C1 B4 B5 C0 C5 C5 C6 C6 C6 C6'
+ 'C5 C5 C0 B6 B3 BF C9 C9 C8 CA B6 66 08 DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 0E'
+ '7B C6 CF C9 C8 CE CD CC C6 C2 C1 C1 BF BE BE BF'
+ 'C1 C1 C1 C4 CB CE CC C7 CD CD B8 5A DF DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF 06'
+ '65 C6 C1 91 9A B8 CE CF CF D0 D0 CF CE CD CD CE'
+ 'CF D0 D0 CF D0 C6 9B 92 B3 CE B6 42 DF DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ '5C C2 A3 84 8B 84 CD D3 D2 D2 D2 D2 D2 D2 D2 D2'
+ 'D2 D2 D2 D2 D5 B7 82 88 89 CD AF 34 DF DF DF 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ '36 B0 BF BE B7 C6 DB DB DB DB DB DB DB DB DB DB'
+ 'DB DB DB DB DC D4 C1 BA BE B9 82 1E DF DF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ '0C 53 92 B5 B9 BD BA BA BA BA BA BA BA BA BA BA'
+ 'BA BA BA BA BA BB BB B9 AF 82 32 04 DF DF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF DF'
+ 'DF 09 22 29 28 28 28 28 28 28 28 28 28 28 28 28'
+ '28 28 28 28 28 28 28 29 29 1D 02 DF DF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF DF 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 DF DF DF DF DF DF DF DF DF DF DF DF DF DF DF'
+ 'DF DF DF DF DF DF DF DF DF DF DF 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF F1 C7 FF FF 00 00 FF FF'
+ 'F0 87 FF FF 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'F8 0F FF FF 00 00 FF FF F0 07 FF FF 00 00 FF FF'
+ 'F2 07 FF FF 00 00 FC 00 00 00 00 7F 00 00 F8 00'
+ '00 00 00 3F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 F8 00'
+ '00 00 00 1F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 3F 00 00 FC 00 00 00 00 3F 00 00 FC 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FE 00'
+ '00 00 00 7F 00 00 FE 00 00 00 00 7F 00 00 FF 00'
+ '00 00 00 7F 00 00 FF 00 00 00 00 FF 00 00 FF 00'
+ '00 00 00 FF 00 00 FF 00 00 00 01 FF 00 00 FF 80'
+ '00 00 03 FF 00 00 FF E0 00 00 07 FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 24 00 00 00 30 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 FF FF 00 00'
+ 'FF FF 00 00 00 3C 00 00 00 30 00 00 00 30 00 00'
+ '00 30 00 00 00 30 00 00 00 30 00 00 00 30 C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00 FF FF 00 00'
+ 'FF FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0'
+ 'C0 FF C0 C0 C0 FF C0 C0 C0 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 26 26 26 FF CD CD CD FF CD CD'
+ 'CD FF C9 C9 C9 FF C5 C5 C5 FF C2 C2 C2 FF C0 C0'
+ 'C0 FF BF BF BF FF BA BA BA FF B3 B4 B3 FF AB AC'
+ 'AC FF 09 09 09 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 30 D1 D1 D1 FF E7 E7 E7 FF 5F 5F'
+ '5F FF 8F 8F 8F FF A7 A7 A7 FF B9 B9 B9 FF B8 B8'
+ 'B8 FF 94 94 94 FF B7 B7 B7 FF C6 C3 C5 FF 91 D8'
+ 'B5 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 33 D1 D1 D1 FF EB EB EB FF 6C 6C'
+ '6C FF 8A 8A 8A FF A3 A3 A3 FF B9 B9 B9 FF A5 A5'
+ 'A5 FF 6B 6B 6B FF A4 A4 A4 FF C8 C8 C8 FF C2 C2'
+ 'C2 FF 8E 8E 8E FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 33 D3 D3 D3 FF F6 F6 F6 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F3 F3 F3 FF F1 F1 F1 FF F0 F0'
+ 'F0 FF EF EF EF FF EE EE EE FF ED ED ED FF EB EB'
+ 'EB FF 8D 8D 8D FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 25 DA DA DA FF A9 A9 A9 FF C3 C3'
+ 'C3 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D8 D8 D8 FF D8 D8 D8 FF A8 A8 A8 FF B5 B5'
+ 'B5 FF 9C 9C 9C FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 7E 7E 7E FF CF CF CF FF D1 D1'
+ 'D1 FF DF DF DF FF E1 E1 E1 FF DC DC DC FF DC DC'
+ 'DC FF E1 E1 E1 FF E1 E1 E1 FF D0 D0 D0 FF D1 D1'
+ 'D1 FF 3F 3F 3F FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 22 22 22 FF CA CA CA FF E4 E4'
+ 'E4 FF D1 D1 D1 FF D0 D0 D0 FF CD CD CD FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF E2 E2 E2 FF C9 C9'
+ 'C9 FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF C3 C3'
+ 'C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF CB CB'
+ 'CB FF 00 00 00 F8 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 D8 DB DB DB FF D2 D2'
+ 'D2 FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF CF CF CF FF CA CA'
+ 'CA FF 00 00 00 B8 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 89 C9 C9 C9 FF E4 E4'
+ 'E4 FF D2 D2 D2 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E5 E5 E5 FF D2 D2 D2 FF E4 E4 E4 FF A8 A8'
+ 'A8 FF 00 00 00 4E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 99 99 99 FF BD BD'
+ 'BD FF EC EC EC FF EE EE EE FF EC EC EC FF EC EC'
+ 'EC FF EE EE EE FF E4 E4 E4 FF D1 D1 D1 FF 75 75'
+ '75 FF 00 00 00 06 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 19 19 19 FF D3 D3'
+ 'D3 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D9 D9 D9 FF CD CD CD FF 06 06'
+ '06 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 E0 03 00 00 C0 03 00 00 80 03'
+ '00 00 80 03 00 00 80 03 00 00 80 03 00 00 C0 03'
+ '00 00 C0 03 00 00 C0 03 00 00 C0 03 00 00 C0 03'
+ '00 00 C0 03 00 00 E0 07 00 00 F0 0F 00 00'
+} */
+
+/* BINRES cdrom.ico */
+11 ICON cdrom.ico
+/* {
+ '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
+ '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 3E 09 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
+ '00 00 4E 1F 00 00 20 20 00 00 01 00 04 00 E8 02'
+ '00 00 76 20 00 00 10 10 00 00 01 00 20 00 68 04'
+ '00 00 5E 23 00 00 30 30 00 00 01 00 04 00 68 06'
+ '00 00 C6 27 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 2E 2E 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 D6 3C 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 01 01 01 00 01 02 02 00 02 03 03 00 05 05'
+ '05 00 06 06 06 00 07 07 07 00 09 09 09 00 0B 0B'
+ '0B 00 10 10 10 00 13 13 13 00 18 18 18 00 1B 1C'
+ '1B 00 1E 1E 1E 00 22 26 23 00 23 29 24 00 24 2E'
+ '25 00 3B 40 3C 00 3E 40 3F 00 40 41 40 00 41 43'
+ '42 00 42 44 43 00 46 48 47 00 4E 50 4F 00 50 52'
+ '51 00 54 55 55 00 56 56 56 00 57 57 57 00 57 58'
+ '58 00 59 59 59 00 5A 5A 5A 00 5A 5B 5B 00 5B 5C'
+ '5C 00 5D 5E 5E 00 5F 68 5F 00 71 71 72 00 72 72'
+ '73 00 74 74 74 00 77 76 77 00 78 76 77 00 72 78'
+ '72 00 79 76 78 00 7A 76 78 00 7B 77 79 00 7D 78'
+ '7A 00 7F 78 7B 00 7F 7F 7F 00 80 7A 7D 00 81 7C'
+ '7F 00 0E CE 0E 00 14 C2 15 00 10 CE 10 00 6D 90'
+ '6D 00 82 7D 80 00 84 80 83 00 86 83 85 00 8D 8B'
+ '8C 00 90 8F 90 00 95 96 95 00 97 97 97 00 98 98'
+ '98 00 98 99 99 00 99 9A 9A 00 9B 9C 9B 00 9F A0'
+ '9F 00 A7 A7 A7 00 A9 A8 A9 00 AB AA AA 00 AD AC'
+ 'AC 00 AE AE AE 00 B1 B0 B1 00 B3 B2 B3 00 B4 B3'
+ 'B4 00 B6 B6 B6 00 B8 B8 B8 00 B9 B9 B9 00 BB BB'
+ 'BB 00 BE BE BE 00 C0 C0 C0 00 C2 C3 C2 00 C3 C3'
+ 'C2 00 C5 C2 C3 00 C7 C1 C4 00 C9 C3 C5 00 CA C6'
+ 'C7 00 CA C8 C8 00 CA C9 C9 00 CB CA CA 00 CC CB'
+ 'CB 00 CD CB CB 00 CD CC CC 00 CD CD CD 00 CE CE'
+ 'CE 00 CE CF CF 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D4 D3 D3 00 D4 D4 D4 00 D5 D4'
+ 'D4 00 D7 D4 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DD DD DD 00 DE DE DE 00 FB D6 D7 00 FD D4'
+ 'D5 00 FE D4 D6 00 FE D4 DF 00 F7 D9 DA 00 F0 DE'
+ 'DF 00 EA DB E2 00 FE D3 E9 00 FE D3 ED 00 FE D4'
+ 'EF 00 F2 DA E8 00 F9 DA EF 00 FE D4 F1 00 FE D5'
+ 'F4 00 FE D6 F6 00 FC DB F4 00 FE D8 F9 00 FE DB'
+ 'F9 00 FE DC F8 00 E1 E0 E0 00 E7 E5 E6 00 E7 E6'
+ 'E6 00 E7 E7 E7 00 EA E3 E3 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 EF EE EE 00 F0 EE EF 00 F0 EF F0 00 F1 F0'
+ 'F0 00 F1 F1 F1 00 F2 F2 F2 00 F2 F3 F3 00 F3 F5'
+ 'F5 00 F7 F6 F8 00 FA F7 FA 00 FB FA FB 00 FC F8'
+ 'FC 00 00 00 00 00 FF FF FF FF 37 90 F5 77 00 00'
+ '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
+ '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
+ '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
+ '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 54 00'
+ '00 00 00 00 00 00 03 00 00 00 5C 00 1A 02 40 9F'
+ '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
+ 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
+ '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
+ '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 88 36'
+ '0C 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
+ '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
+ 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
+ '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
+ '68 65 6C 6C 33 32 5C 63 64 72 6F 6D 2E 69 63 6F'
+ '00 00 1A 93 4B 00 14 1A 95 00 1F 3B D4 77 15 00'
+ '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
+ 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
+ '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
+ '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
+ '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
+ 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
+ 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
+ '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 99 99 0D 09 08 0C 99 99 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 99 21 11 45 4C 5D 55 21 14 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 99 23 4D 97 7F 7F 76 71 72 74 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 99 23 75 80 7B 7B 72 71 71 71 94 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 10 28 98 7C 78 7B 72 71 71 6F 94 92 00 00'
+ '99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
+ '99 10 1F 59 7D 78 78 7B 71 71 6F 93 92 92 00 99'
+ '08 15 19 17 21 23 1F 1D 1D 1E 1E 1D 1D 1C 1C 1F'
+ '1F 12 40 81 78 78 78 7B 71 71 8E 91 92 92 99 99'
+ '37 6A 82 83 50 32 98 8B 84 82 67 64 64 64 61 63'
+ '1B 17 75 7C 78 7B 78 78 7B 7F 7F 7B 93 92 99 03'
+ '65 94 89 81 31 31 33 79 5C 5E 5A 5B 5B 5B 67 24'
+ '0E 23 97 7A 92 77 7B 78 7F 53 6F 7F 8E 8F 99 07'
+ '83 8D 89 98 34 31 41 52 4E 4E 4E 4E 4E 4E 50 4E'
+ '2F 27 97 93 93 8C 7A 7F 48 40 23 70 7E 90 99 05'
+ '92 8B 93 3A 2B 38 2A 25 25 25 25 25 25 25 25 26'
+ '23 3A 97 92 92 93 92 7E 10 00 00 3A 81 93 99 04'
+ '92 8F 91 44 39 3A 3F 3F 3F 3F 3F 3D 3C 3C 3C 3E'
+ '35 40 97 92 92 93 76 7E 11 99 00 52 7E 8D 99 03'
+ '90 8F 89 90 8A 89 87 86 82 82 82 82 82 82 82 83'
+ '47 3D 97 92 92 93 8E 7C 53 38 52 81 7E 76 99 02'
+ '96 96 8A 8D 88 87 87 87 88 88 87 87 87 87 85 8B'
+ '4B 23 97 92 92 92 8F 8D 7F 81 7F 7F 77 7B 99 01'
+ '97 82 46 46 66 68 67 67 67 67 66 66 66 67 67 6A'
+ '50 22 95 93 92 92 92 94 72 71 71 76 7B 78 99 99'
+ '94 5F 44 44 51 69 66 64 63 63 67 68 66 63 63 64'
+ '82 23 49 97 92 92 92 94 6F 71 71 76 7B 78 00 99'
+ '55 86 58 55 5C 5F 60 60 61 64 63 63 63 64 5F 62'
+ '62 84 20 65 94 92 92 71 71 71 71 76 78 78 00 99'
+ '3F 86 5A 5C 5B 60 63 63 64 66 66 66 66 66 64 68'
+ '82 68 3B 2D 97 95 6F 71 71 71 77 7B 7B 7C 00 99'
+ '22 82 55 56 64 61 60 60 60 5F 61 60 60 61 60 5F'
+ '5C 62 69 3A 38 73 6F 71 71 77 7B 7B 81 75 00 99'
+ '11 6C 57 5F 62 5F 5F 5E 5E 5F 62 60 62 62 62 62'
+ '60 62 5C 5B 39 36 57 72 81 81 98 98 48 3A 00 99'
+ '0B 57 62 61 60 5E 5F 5F 5F 5E 5E 62 62 62 62 62'
+ '62 62 66 4D 4A 0C 02 13 19 18 16 15 99 00 00 99'
+ '08 4A 66 61 61 60 60 60 60 60 61 61 61 61 61 61'
+ '61 61 64 4C 48 0F 99 00 00 00 00 00 00 00 00 99'
+ '99 3A 82 66 67 67 67 67 67 67 67 67 63 64 64 64'
+ '63 64 5E 54 5A 10 99 00 00 00 00 00 00 00 00 99'
+ '99 23 8A 6D 6E 6D 6B 6B 6B 6B 6B 6B 6C 6D 6D 6C'
+ '6E 83 84 6E 46 0A 99 00 00 00 00 00 00 00 00 00'
+ '99 11 84 86 82 82 82 82 86 82 82 82 82 82 82 82'
+ '83 85 84 83 38 02 99 00 00 00 00 00 00 00 00 00'
+ '99 0B 82 87 85 88 8B 8A 8A 87 88 88 88 88 87 84'
+ '85 87 85 84 23 99 99 00 00 00 00 00 00 00 00 00'
+ '99 99 56 90 69 83 8B 8B 8A 8A 8A 89 8A 8B 8B 8B'
+ '87 69 89 8B 17 99 99 00 00 00 00 00 00 00 00 00'
+ '99 99 4F 6B 43 45 92 8F 8F 8F 8F 8D 8F 8F 8F 94'
+ '54 42 5A 92 12 99 99 00 00 00 00 00 00 00 00 00'
+ '00 99 24 6E 88 8B 97 97 97 97 97 97 97 97 97 97'
+ '95 87 83 4C 06 99 00 00 00 00 00 00 00 00 00 00'
+ '00 99 07 1A 30 2C 29 29 29 29 29 29 29 29 29 29'
+ '2B 2F 23 10 99 99 00 00 00 00 00 00 00 00 00 00'
+ '00 00 99 99 99 99 99 99 99 99 99 99 99 99 99 99'
+ '99 99 99 99 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF 00 FF FF FE 00 FF FF FC 00 FF FF F8 00 FF FF'
+ 'F0 00 C0 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
+ '00 7F C0 00 00 7F C0 00 00 7F C0 00 00 7F E0 00'
+ '00 FF E0 00 00 FF F0 00 03 FF FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 05 05 05 00 0C 0F'
+ '0F 00 0D 11 0E 00 15 15 15 00 36 36 36 00 39 39'
+ '39 00 40 43 41 00 44 47 45 00 53 53 53 00 5B 60'
+ '5D 00 67 68 68 00 64 6A 69 00 69 69 69 00 6B 6C'
+ '6B 00 6E 6E 6E 00 6F 6E 6E 00 6F 70 70 00 72 72'
+ '72 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F 7F 00 00 FF'
+ '00 00 75 99 75 00 88 6C 88 00 84 7E 84 00 8B 7E'
+ '82 00 80 80 80 00 84 84 84 00 93 93 93 00 97 97'
+ '97 00 9A 98 98 00 9B 9B 9B 00 9D 9D 9D 00 9F 9F'
+ '9F 00 A0 A0 A0 00 A5 A5 A5 00 A6 A6 A6 00 A8 A2'
+ 'A8 00 B8 AC B8 00 BB BB BB 00 A6 D4 A6 00 D8 AE'
+ 'C6 00 CB BD C9 00 C0 C0 C0 00 C2 C2 C2 00 C2 C3'
+ 'C3 00 C3 C3 C3 00 C8 C8 C8 00 C9 C9 C9 00 CE CE'
+ 'CE 00 CF CF CF 00 D3 C2 CD 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D6 D0 D6 00 D4 D4'
+ 'D4 00 D5 D5 D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8'
+ 'D8 00 D9 D9 D9 00 DA DA DA 00 DB DB DB 00 DC DC'
+ 'DC 00 DE DE DE 00 FF D2 CD 00 FF D2 CE 00 E2 C2'
+ 'DA 00 FF D8 D7 00 FF D4 D8 00 FA DD DA 00 FD DC'
+ 'DC 00 FF DE DF 00 F4 D7 EA 00 FF D3 E8 00 FF D6'
+ 'E8 00 FF D7 EF 00 FF D3 F1 00 FF D3 F2 00 FF D3'
+ 'F3 00 FF D4 F5 00 FF D7 F7 00 FF D9 F7 00 FD D9'
+ 'FB 00 E1 E1 E1 00 E3 E4 E3 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EA EB EB 00 EB EB EB 00 ED ED ED 00 FF E3'
+ 'E1 00 F5 EA EF 00 FF EF EF 00 FD E7 F4 00 FB ED'
+ 'F4 00 FE E7 FA 00 FF E2 FF 00 FF E9 FF 00 FF ED'
+ 'FE 00 FF EE FF 00 EE F9 F7 00 F1 F1 F1 00 F1 F3'
+ 'F2 00 F2 F2 F2 00 F3 F3 F3 00 F0 F5 F2 00 F0 F6'
+ 'F3 00 F0 F7 F7 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
+ 'F6 00 FF F0 FF 00 FF F3 FF 00 FF F6 FF 00 F9 F9'
+ 'F9 00 FA FA FA 00 FB FB FB 00 FC FC FC 00 FD FD'
+ 'FD 00 FF FD FE 00 FE FE FE 00 FF FF FF 00 00 00'
+ '00 00 E7 E5 E6 00 E7 E6 E6 00 E7 E7 E7 00 EA E3'
+ 'E3 00 E8 E8 E8 00 E9 E9 E9 00 EA EA EA 00 EB EB'
+ 'EB 00 EC EC EC 00 ED ED ED 00 EF EE EE 00 F0 EE'
+ 'EF 00 F0 EF F0 00 F1 F0 F0 00 F1 F1 F1 00 F2 F2'
+ 'F2 00 F2 F3 F3 00 F3 F5 F5 00 F7 F6 F8 00 FA F7'
+ 'FA 00 FB FA FB 00 FC F8 FC 00 00 00 00 00 FF FF'
+ 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
+ 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
+ '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
+ '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
+ 'F5 77 00 EC FD 7F 54 00 00 00 00 00 00 00 03 00'
+ '00 00 5C 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
+ '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
+ 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 63'
+ '64 72 6F 6D 2E 69 63 6F 00 00 1A 93 4B 00 14 1A'
+ '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
+ '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 03 0A 0C 02 00 00 00 00 00 00 00 00 00 00'
+ '00 0E 6B 68 4B 64 00 82 82 82 82 82 82 82 82 82'
+ '11 77 53 45 49 73 82 10 26 17 27 25 22 21 23 08'
+ '4C 52 50 4E 67 71 82 7F 79 16 29 39 33 38 28 09'
+ '81 63 55 2B 2A 66 82 81 30 18 19 14 14 13 1B 1C'
+ '80 72 6A 82 07 79 82 81 74 6D 61 60 60 60 6F 1E'
+ '7E 6E 65 46 56 4F 82 7D 24 38 3D 3B 3D 3C 41 1D'
+ '5F 74 6C 47 48 51 82 3D 32 32 37 3A 3B 3B 38 58'
+ '1A 81 4A 44 4D 54 82 20 37 38 35 35 36 37 37 38'
+ '2E 1F 62 69 78 34 00 0D 43 35 35 35 36 37 37 38'
+ '36 0B 00 00 00 00 00 06 61 40 3E 3F 3F 3E 3E 42'
+ '57 12 00 00 00 00 00 01 70 5E 5C 5B 5A 5A 59 60'
+ '75 05 00 00 00 00 00 82 5D 31 7A 76 74 75 7B 32'
+ '7C 04 00 00 00 00 00 82 0F 2C 2F 2D 2D 2D 2D 2C'
+ '1E 82 00 00 00 00 00 00 82 82 82 82 82 82 82 82'
+ '82 00 00 00 00 00 FF F0 00 00 FF E0 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 0F'
+ '00 00 80 0F 00 00 80 0F 00 00 80 0F 00 00 80 0F'
+ '00 00 C0 1F 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0C 00 00 00 30 00 00 00 48 00 00 00 90 00 00'
+ '00 90 00 00 00 90 00 00 00 78 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 86 86'
+ '86 FF 7A 7A 7A FF AA AA AA FF DA DA DA FF F2 F2'
+ 'F2 FF CE CE CE FF AA AA AA FF 6E 6E 6E FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 0C 7A 7A 7A FF 80 80'
+ '80 FF FF FF FF FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 D4 FF FF D4 D4 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ '00 13 00 00 00 78 6E 6E 6E FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 56 62 62 62 FF E6 E6 E6 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 05 00 00 00 69 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 62 62 62 FF 56 56'
+ '56 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 9B 00 00 00 FF 21 21 21 FF 2C 2C'
+ '2C FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 4A 4A 4A FF 62 62'
+ '62 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 03 01 01 01 FF 8A 8A 8A FF EB EB EB FF E8 E8'
+ 'E8 FF E8 E8 E8 FF D4 D4 D4 FF 00 C0 00 FF E7 E7'
+ 'E7 FF E8 E8 E8 FF E3 E3 E3 FF D8 D8 D8 FF D2 D2'
+ 'D2 FF CD CD CD FF CD CD CD FF CD CD CD FF C8 C9'
+ 'C9 FF AA AA AA FF 2E 2E 2E FF 62 62 62 FF DA DA'
+ 'DA FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 FF FF FF D4 FF FF FF D4'
+ 'FF FF FF D4 F0 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 15 19 19 19 FF AD A8 AB FF EB EB EB FF E8 E8'
+ 'E8 FF E8 E8 E8 FF 00 FF 00 FF 00 FF 00 FF 00 C0'
+ '00 FF DF DF DF FF D5 D5 D5 FF D2 D2 D2 FF CB CB'
+ 'CB FF CD CD CD FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF 40 40 40 FF 2E 2E 2E FF 7A 7A 7A FF F2 F2'
+ 'F2 FF FF D4 E3 FF F2 F2 F2 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 FF FF FF D4 E3 FF FF D4'
+ 'E3 FF FF D4 FF FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 34 28 28 28 FF D1 D1 D1 FF EB EB EB FF EB EB'
+ 'EB FF E8 E8 E8 FF E8 E8 E8 FF 00 FF 00 FF B5 B5'
+ 'B5 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6'
+ 'B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6 B6 FF B6 B6'
+ 'B6 FF B6 B6 B6 FF B6 B6 B6 FF A4 A0 A0 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 F0 FF B6 B6 B6 FF AA AA AA FF 62 62'
+ '62 FF FF D4 E3 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
+ '00 33 28 28 28 FF D1 D1 D1 FF E8 E8 E8 FF EB EB'
+ 'EB FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF B6 B6 B6 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 E3 FF 6E 6E 6E FF 00 00 00 00 00 00'
+ '00 00 B6 B6 B6 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
+ '00 33 27 27 27 FF D2 D2 D2 FF EA EA EA FF EB EB'
+ 'EB FF A7 A7 A7 FF A7 A7 A7 FF AB AB AB FF AE AE'
+ 'AE FF AF AF AF FF AF AF AF FF AF AF AF FF AF AF'
+ 'AF FF AB AB AB FF AB AB AB FF AB AB AB FF AB AB'
+ 'AB FF AB AB AB FF AB AB AB FF CE CE CE FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
+ 'E3 FF FF D4 E3 FF 80 80 80 FF 00 00 00 78 00 00'
+ '00 00 FF D4 F0 FF FF D4 F0 FF F2 F2 F2 FF 00 00'
+ '00 33 26 26 26 FF D3 D3 D3 FF E8 E8 E8 FF E6 E6'
+ 'E6 FF E2 E2 E2 FF DB DB DB FF D8 D8 D8 FF D9 D9'
+ 'D9 FF D2 D2 D2 FF CF CF CF FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CE CE CE FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 F0 FF C0 C0 C0 FF 62 62 62 FF 80 80'
+ '80 FF FF D4 F0 FF FF D4 F0 FF FF D4 E3 FF 00 00'
+ '00 33 24 24 24 FF D6 D6 D6 FF E9 E9 E9 FF E1 E1'
+ 'E1 FF E2 E2 E2 FF E0 E0 E0 FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF 92 92 92 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 FF FF FF D4 FF FF FF D4'
+ 'FF FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 34 24 24 24 FF DE DE DE FF D9 D9 D9 FF C4 C4'
+ 'C4 FF BF BF BF FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF 7A 7A 7A FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 07 05 05 05 FF C2 C2 C2 FF BC BC BC FF B2 B2'
+ 'B2 FF AB AB AB FF BB BB BB FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D4 D4 D4 FF D3 D3 D3 FF D5 D5 D5 FF D7 D7'
+ 'D7 FF D8 D8 D8 FF D7 D7 D7 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D4 D4 D4 FF D5 D5 D5 FF 62 62 62 FF 86 86'
+ '86 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 FF A4 A4 A4 FF CF CF CF FF C5 C5'
+ 'C5 FF BF BF BF FF C9 C9 C9 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
+ 'D0 FF D4 D4 D4 FF D0 D0 D0 FF D3 D3 D3 FF 62 62'
+ '62 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 FF 59 59 59 FF D0 D0 D0 FF CD CD'
+ 'CD FF CD CD CD FF CA CA CA FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF DB DB DB FF E4 E4 E4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 92 92 92 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 FE 40 40 40 FF D2 D2 D2 FF CA CA'
+ 'CA FF CA CA CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D3 D3 D3 FF D2 D2 D2 FF D3 D3 D3 FF D2 D2'
+ 'D2 FF D1 D1 D1 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 6E 6E 6E FF 92 92 92 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 E1 07 07 07 FF DD DD DD FF CC CC'
+ 'CC FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF C4 C4 C4 FF B3 B3 B3 FF 62 62 62 FF 9E 9E'
+ '9E FF FF D4 D4 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF CE CE CE FF 9E 9E 9E FF 92 92 92 FF 00 00'
+ '00 00 00 00 00 B2 00 00 00 FF DD DD DD FF CF CF'
+ 'CF FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
+ 'CF FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF B3 B3 B3 FF B3 B3 B3 FF 00 00 00 FF 00 00'
+ '00 FF 62 62 62 FF 86 86 86 FF 86 86 86 FF 86 86'
+ '86 FF 6E 6E 6E FF 00 00 00 24 00 00 00 00 00 00'
+ '00 00 00 00 00 4B 00 00 00 FE D8 D8 D8 FF D4 D4'
+ 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF B3 B3 B3 FF B3 B3 B3 FF 00 00 00 CF 00 00'
+ '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 1A 00 00 00 F2 CC CC CC FF D6 D6'
+ 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4'
+ 'C4 FF BD BD BD FF D0 D0 D0 FF 09 09 09 FF 00 00'
+ '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 02 00 00 00 BF 97 97 97 FF DC DC'
+ 'DC FF DC DC DC FF DE DE DE FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF E7 E7 E7 FF E7 E7'
+ 'E7 FF DC DC DC FF C6 C6 C6 FF 00 00 00 FF 00 00'
+ '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 77 77 77 FF D3 D3'
+ 'D3 FF E1 E1 E1 FF DE DE DE FF DE DE DE FF DE DE'
+ 'DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF D9 D9 D9 FF BB BB BB FF 00 00 00 FF 00 00'
+ '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 62 35 35 35 FF BD BD'
+ 'BD FF E6 E6 E6 FF E6 E6 E6 FF E7 E7 E7 FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF D4 D4 D4 FF 9A 9A 9A FF 00 00 00 ED 00 00'
+ '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 2D 1E 1E 1E FF AB AB'
+ 'AB FF ED ED ED FF E7 E7 E7 FF EC EC EC FF EB EB'
+ 'EB FF ED ED ED FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EC EC EC FF E5 E5 E5 FF EB EB'
+ 'EB FF D6 D6 D6 FF 8A 8A 8A FF 00 00 00 C3 00 00'
+ '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 8D 8D'
+ '8D FF C4 C4 C4 FF B2 B2 B2 FF B2 B2 B2 FF EB EB'
+ 'EB FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F3 F3 F3 FF D5 D5 D5 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF CD CD CD FF 61 61 61 FF 00 00 00 85 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FF 64 64'
+ '64 FF DD DD DD FF DC DC DC FF E4 E4 E4 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF FA FA FA FF F2 F2 F2 FF D8 D8 D8 FF DC DC'
+ 'DC FF B0 B0 B0 FF 34 34 34 FF 00 00 00 67 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 9C 00 00'
+ '00 FF 3D 3D 3D FF 49 49 49 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 49 49 49 FF 49 49'
+ '49 FF 02 02 02 FF 00 00 00 FF 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00'
+ '00 7F 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 D6 00 00 00 5C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF 00 FF FF FE 00 FF FF FC 00 FF FF E0 00 FF FF'
+ 'F0 00 80 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
+ '00 7F C0 00 00 7F C0 00 00 7F E0 00 00 7F E0 00'
+ '00 FF E0 00 01 FF E0 00 01 FF FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
+ '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
+ '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
+ '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
+ '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
+ 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 08 FF FF 00 00 00 00 00 8F FF FF 08 88'
+ '88 88 80 FF FF FF 0F FA F7 77 88 FF F7 FF 0F 88'
+ '88 88 88 FF F0 8F 0F FF FF FF F8 FF F8 FF 0F 77'
+ '77 77 78 FF FF FF 07 77 77 77 77 7F FF FF 07 77'
+ '77 77 77 8F FF FF 07 77 77 77 77 70 28 80 08 77'
+ '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 77'
+ '77 77 77 70 00 00 00 77 77 77 77 70 00 00 00 00'
+ '00 00 00 00 00 00 FF E0 00 00 FF C0 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 07 00 00 80 07 00 00 80 07 00 00 80 0F'
+ '00 00 C0 1F 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 77 77 88 00 00'
+ '00 00 00 00 00 00 00 00 00 08 7F FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 00 8F FF FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 08 FF FF FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 87 FF FF FF FF FF 00 08'
+ '88 88 88 88 88 88 88 80 8F FF FF FF FF FF 00 87'
+ 'FF 7A FF FF 77 77 77 88 FF FF FF FF FF FF 00 7F'
+ 'FF AA AF 77 77 77 78 08 FF FF FF F7 FF FF 00 FF'
+ 'FF 8A 77 77 77 77 77 88 FF FF FF 78 8F FF 00 FF'
+ 'F8 88 88 88 88 88 88 88 FF FF FF 00 08 FF 00 FF'
+ 'F7 88 88 88 88 88 88 88 FF FF FF 00 07 FF 00 FF'
+ 'FF FF FF FF FF FF FF 78 FF FF FF 78 7F FF 00 FF'
+ 'FF FF FF FF FF FF FF 78 FF FF FF FF FF FF 00 FF'
+ '77 77 77 77 77 77 77 78 FF FF FF FF FF FF 00 F7'
+ '77 77 77 77 77 77 77 78 7F FF FF FF FF FF 00 77'
+ '77 77 77 77 77 77 77 77 87 FF FF FF FF FF 00 87'
+ '77 77 77 77 77 77 77 77 88 FF FF FF FF FF 00 87'
+ '77 77 77 77 77 77 77 77 78 8F FF FF FF FF 00 07'
+ '77 77 77 77 77 77 77 77 77 88 7F FF FF 78 00 07'
+ '77 77 77 77 77 77 77 77 77 70 02 88 88 70 00 07'
+ '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 08'
+ '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 08'
+ '77 77 77 77 77 77 77 77 77 70 00 00 00 00 00 00'
+ '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
+ '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
+ '77 77 77 77 77 77 77 77 77 80 00 00 00 00 00 00'
+ '77 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00'
+ '87 77 77 77 77 77 77 77 77 00 00 00 00 00 00 00'
+ '08 88 88 88 88 88 88 88 80 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF 00 FF FF FE 00 FF FF FC 00 FF FF F8 00 FF FF'
+ 'F0 00 C0 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 18 00 00 00 08 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 80 00 00 00 80 00 00 00 80 00 00 00 80 00'
+ '00 01 80 00 00 7F 80 00 00 7F 80 00 00 7F C0 00'
+ '00 7F C0 00 00 7F C0 00 00 7F C0 00 00 7F E0 00'
+ '00 FF E0 00 00 FF F0 00 03 FF FF FF FF FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 20 00 00 00'
+ '00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 78 6E 6E 6E FF 62 62'
+ '62 FF 00 00 00 9C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 62 62 62 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'D4 FF FF D4 D4 FF 00 00 00 00 00 00 00 16 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 42 62 62'
+ '62 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF F2 F2 F2 FF 00 00 00 54 90 90 90 FF AB AC'
+ 'AC FF CC CC CC FF C4 C4 C4 FF C2 C2 C2 FF C1 C1'
+ 'C1 FF BC BC BC FF BD BD BD FF 6E 6E 6E FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'E3 FF F2 F2 F2 FF 00 00 00 FA EA EA EA FF E8 E8'
+ 'E8 FF 00 FF 00 FF CB CB CB FF C8 C8 C8 FF C8 C8'
+ 'C8 FF C8 C8 C8 FF C8 C8 C8 FF 56 56 56 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 F0 FF B6 B6 B6 FF FF B1'
+ 'C7 FF FF D4 E3 FF 00 00 00 F9 EF EF EF FF EB EB'
+ 'EB FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 80 80 80 FF 80 80 80 FF 62 62 62 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 F0 FF 00 00 00 78 62 62'
+ '62 FF F2 F2 F2 FF 00 00 00 F9 F7 F7 F7 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F3 F3 F3 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF EF EF EF FF 62 62 62 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4 E3 FF FF D4'
+ 'FF FF FF D4 F0 FF 00 00 00 F7 F3 F3 F3 FF B7 B7'
+ 'B7 FF DA DA DA FF D8 D8 D8 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D8 D8 D8 FF D3 D3 D3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 F0 FF 00 00 00 73 EF EF EF FF CB CB'
+ 'CB FF CE CE CE FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D3 D3 D3 FF 7A 7A'
+ '7A FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF 00 00 00 25 B7 B7 B7 FF CB CB'
+ 'CB FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4'
+ 'C4 FF 80 80 80 FF FF D4 D4 FF FF D4 F0 FF FF D4'
+ 'F0 FF E6 E6 E6 FF 00 00 00 00 5F 5F 5F FF D2 D2'
+ 'D2 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF 99 99 99 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 18 18 18 FF DB DB'
+ 'DB FF DE DE DE FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DD DD DD FF DD DD DD FF DD DD DD FF D9 D9'
+ 'D9 FF 7A 7A 7A FF 00 00 00 0A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 FF E5 E5'
+ 'E5 FF EB EB EB FF EB EB EB FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF 20 20 20 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 DD E4 E4'
+ 'E4 FF C1 C1 C1 FF ED ED ED FF EE EE EE FF EB EB'
+ 'EB FF ED ED ED FF ED ED ED FF C2 C2 C2 FF EC EC'
+ 'EC FF 00 00 00 FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 44 80 80'
+ '80 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF B0 B0'
+ 'B0 FF 00 00 00 ED 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 2C 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF F0 00 00 FF E0 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 0F'
+ '00 00 80 07 00 00 80 0F 00 00 80 0F 00 00 80 0F'
+ '00 00 C0 1F 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 08 88 88 80 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '88 87 77 F7 77 88 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 08 87 FF FF FF FF F7 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87'
+ 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 08 FF FF FF FF FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 08 8F FF'
+ 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 88 7F FF FF FF FF FF FF FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 08 88 FF FF'
+ 'FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 08 8F FF FF FF FF FF FF FF FF 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 88 8F FF FF'
+ 'FF FF FF FF FF FF 00 08 7F FF F7 AA FF FF 77 77'
+ '77 77 77 70 88 7F FF FF FF FF FF FF FF FF 00 07'
+ 'FF FF FA AA AF 77 77 77 77 77 77 00 88 FF FF FF'
+ 'FF FF FF FF FF FF 00 07 FF FF FA AA A7 77 77 77'
+ '77 77 77 80 88 FF FF FF FF FF 78 87 FF FF 00 07'
+ 'FF FF FF AA 77 77 77 77 77 77 77 77 87 FF FF FF'
+ 'FF F7 87 88 FF FF 00 07 FF FF 88 88 88 88 88 88'
+ '88 88 88 88 87 FF FF FF FF F8 00 08 7F FF 00 07'
+ 'FF FF 88 88 88 88 88 88 88 88 88 88 87 FF FF FF'
+ 'FF F8 00 08 7F FF 00 07 FF FF 77 77 77 77 77 77'
+ '77 77 77 77 87 FF FF FF FF F8 00 08 FF FF 00 07'
+ 'FF FF F7 77 77 77 77 77 77 77 77 77 87 FF FF FF'
+ 'FF F7 88 8F FF FF 00 07 FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF 87 FF FF FF FF FF FF FF FF FF 00 07'
+ 'FF FF FF 77 77 7F FF FF FF FF FF FF 88 FF FF FF'
+ 'FF FF FF FF FF FF 00 07 77 77 77 77 77 77 77 77'
+ '77 77 77 77 88 FF FF FF FF FF FF FF FF FF 00 07'
+ '77 77 77 77 77 77 77 77 77 77 77 77 78 7F FF FF'
+ 'FF FF FF FF FF FF 00 07 77 77 77 77 77 77 77 77'
+ '77 77 77 77 78 8F FF FF FF FF FF FF FF FF 00 07'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 87 FF FF'
+ 'FF FF FF FF FF FF 00 08 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 88 7F FF FF FF FF FF FF FF 00 08'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 78 8F FF'
+ 'FF FF FF FF FF FF 00 00 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 88 FF FF FF FF FF FF FF 00 00'
+ '77 77 77 77 77 77 77 77 77 77 77 77 77 77 78 87'
+ 'FF FF FF FF FF F8 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 88 87 FF FF FF 78 88 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '08 88 88 88 80 00 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '00 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
+ '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
+ '00 77 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
+ '00 00 00 00 00 00 00 00 00 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
+ '00 87 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
+ '00 00 00 00 00 00 00 00 00 87 77 77 77 77 77 77'
+ '77 77 77 77 77 77 78 00 00 00 00 00 00 00 00 00'
+ '00 87 77 77 77 77 77 77 77 77 77 77 77 77 70 00'
+ '00 00 00 00 00 00 00 00 00 08 77 77 77 77 77 77'
+ '77 77 77 77 77 77 80 00 00 00 00 00 00 00 00 00'
+ '00 00 08 88 88 88 88 88 88 88 88 88 88 80 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF F0 00 00 00 FF FF FF FF E0 00 00 00 FF FF'
+ 'FF FF C0 00 00 00 FF FF FF FF 80 00 00 00 FF FF'
+ 'FF FE 00 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
+ 'FF FC 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 00'
+ '00 00 00 60 00 00 00 00 00 00 00 20 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 07 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
+ '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
+ '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
+ '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 18 18'
+ '18 00 19 19 19 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
+ '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
+ '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2A 2A'
+ '2A 00 2B 2B 2B 00 2C 2C 2C 00 2E 2E 2E 00 2F 2F'
+ '2F 00 34 34 34 00 35 35 35 00 39 39 39 00 3D 3D'
+ '3D 00 40 40 40 00 41 41 41 00 48 48 48 00 49 49'
+ '49 00 4A 4A 4A 00 4B 4B 4B 00 53 53 53 00 56 56'
+ '56 00 59 59 59 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
+ '61 00 62 62 62 00 64 64 64 00 6E 6E 6E 00 75 75'
+ '75 00 77 77 77 00 7A 7A 7A 00 7E 7E 7E 00 7F 7F'
+ '7F 00 00 C0 00 00 00 FF 00 00 80 80 80 00 83 83'
+ '83 00 86 86 86 00 8A 8A 8A 00 8D 8D 8D 00 90 90'
+ '90 00 92 92 92 00 93 93 93 00 97 97 97 00 99 99'
+ '99 00 9A 9A 9A 00 9E 9E 9E 00 9F 9F 9F 00 A4 A0'
+ 'A0 00 A4 A4 A4 00 A7 A7 A7 00 A8 A8 A8 00 A9 A9'
+ 'A9 00 AA AA AA 00 AB AB AB 00 AD A8 AB 00 AB AC'
+ 'AC 00 AD AD AD 00 AE AE AE 00 AF AF AF 00 B0 B0'
+ 'B0 00 B2 B2 B2 00 B3 B3 B3 00 B5 B5 B5 00 B6 B6'
+ 'B6 00 B7 B7 B7 00 B8 B4 B6 00 B8 B8 B8 00 BA BA'
+ 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 FF B1 C7 00 C0 C0 C0 00 C1 C1'
+ 'C1 00 C2 C2 C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5'
+ 'C5 00 C6 C6 C6 00 C8 C8 C8 00 C8 C9 C9 00 C9 C9'
+ 'C9 00 CA CA CA 00 CB CB CB 00 CC CC CC 00 CD CD'
+ 'CD 00 CE CE CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1'
+ 'D1 00 D2 D2 D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5'
+ 'D5 00 D6 D6 D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9'
+ 'D9 00 DA DA DA 00 DB DB DB 00 DC DC DC 00 DD DD'
+ 'DD 00 DE DE DE 00 DF DF DF 00 FF D4 D4 00 FF D4'
+ 'E3 00 FF D4 F0 00 FF D4 FF 00 E0 E0 E0 00 E1 E1'
+ 'E1 00 E2 E2 E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5'
+ 'E5 00 E6 E6 E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9'
+ 'E9 00 EA EA EA 00 EB EB EB 00 EC EC EC 00 ED ED'
+ 'ED 00 EE EE EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1'
+ 'F1 00 F2 F2 F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5'
+ 'F5 00 F6 F6 F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9'
+ 'F9 00 FA FA FA 00 FF FF FF 00 00 00 00 00 78 EE'
+ '0C 01 78 EE 0C 01 40 00 00 00 40 00 00 00 01 00'
+ '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
+ '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 70 EE 0C 01 00 24 0D 01 01 01'
+ 'F5 77 78 01 38 00 78 EE 0C 01 E0 19 0D 01 E8 19'
+ '0D 01 78 01 38 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 BE B3 E7 77 70 EE 0C 01 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 08 04 00 00 E4 00 00 00 08 04 00 00 08 01'
+ '00 00 00 00 00 00 00 00 00 00 00 00 01 01 00 00'
+ '38 00 BC 18 95 00 C0 18 95 00 B0 19 95 00 F0 88'
+ 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 81 E9'
+ '49 00 00 00 38 00 00 00 00 00 78 EE 0C 01 78 EE'
+ '0C 01 A4 1A 95 00 40 00 00 00 40 00 00 00 B8 10'
+ 'E9 77 FF FF FF FF C9 F1 E7 77 16 EA 4B 00 F8 00'
+ '00 00 B4 1A 95 00 DC E3 49 00 E0 A3 4E 00 FF FF'
+ 'FF FF 10 00 00 00 10 DA 4B 00 78 EE 0C 01 71 CC'
+ '43 00 78 EE 0C 01 50 7E 0D 01 A4 1A 95 00 F8 A2'
+ 'AF 00 C4 F5 AF 00 04 00 00 00 50 7E 0D 01 0F 02'
+ '00 00 B8 EE 0C 01 10 00 00 00 00 00 00 00 20 00'
+ '00 00 78 EE 0C 01 40 00 00 00 10 00 00 00 00 01'
+ '00 00 00 04 00 00 00 00 00 00 00 00 00 00 10 00'
+ '00 00 10 00 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 35 2D 2B'
+ '2B 2B 35 9D 9D 9D 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 9D 9D 37 2D 30 47 6B 77'
+ '93 77 6B 47 35 2D 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 9D 9D 30 35 6B 9C 7F 7F 7F'
+ '7F 7D 7D 7D 7D 5D 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 9D 9D 9D 2B 5D 7F 7F 7F 7F 7F 7F'
+ '7D 7D 7D 7D 7D 93 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 9D 9D 9D 2D 87 7F 7F 7F 7F 7F 7F 7D'
+ '7D 7D 7D 7D 93 93 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 9D 26 2B 87 7F 7F 7F 7F 7F 7F 7D 7D'
+ '7D 7D 7D 93 93 93 00 00 00 00 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 23 2B 5F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
+ '7D 7D 93 93 93 93 00 00 9D 9D 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 2B 26 3B 7F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
+ '7D 93 93 93 93 93 00 9D 9D 9D 9D 0F 18 17 18 17'
+ '17 17 17 17 17 17 17 17 17 17 16 16 16 16 16 16'
+ '16 16 16 23 2B 93 7F 7F 7F 7F 7F 7F 7F 7D 7D 7D'
+ '93 93 93 93 93 93 00 9D 9D 12 3A 54 4B 4A 49 6A'
+ '69 68 66 61 60 5F 5F 60 5D 5E 5B 5B 58 59 56 59'
+ '59 59 2D 26 40 7F 7F 7F 7F 7F 7F 7F 7F 7D 7D 7F'
+ '7E 7E 93 93 93 93 9D 9D 01 38 49 8C 89 89 89 71'
+ '33 33 88 89 89 84 7A 75 6F 6A 6A 6A 6A 6A 65 6A'
+ '47 19 26 2B 77 7F 7F 7F 7F 7F 7F 7F 7F 80 80 80'
+ '80 80 7F 93 93 93 9D 9D 0B 49 8C 8C 89 89 89 34'
+ '34 34 33 82 7C 72 69 6F 68 6A 6A 6A 6A 6A 6A 6A'
+ '1F 19 26 30 93 93 7E 93 7F 7F 7F 7F 7F 80 7F 7E'
+ '7E 80 80 93 93 93 9D 9D 15 49 8B 8C 8C 89 89 34'
+ '34 34 34 68 64 64 64 64 64 64 64 64 64 64 64 64'
+ '3C 1F 26 3B 93 93 93 93 93 7E 7F 7F 7F 7F 52 35'
+ '3B 5C 7F 7F 7E 93 9D 9D 14 6E 8D 8C 8C 89 89 89'
+ '34 34 51 51 52 52 52 52 52 52 52 52 52 52 52 52'
+ '52 52 26 42 93 93 93 93 93 93 93 7F 7F 52 2D 47'
+ '2B 30 7E 7F 93 93 9D 9D 14 6E 8F 89 8C 89 35 35'
+ '35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35'
+ '35 35 2B 52 93 93 93 93 93 93 93 7F 7E 2D 00 00'
+ '00 2B 52 7F 93 93 9D 9D 13 6E 90 8C 8C 8C 35 35'
+ '35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35'
+ '35 35 2B 52 93 93 93 93 93 93 93 7F 7D 2B 9D 00'
+ '00 2B 52 7F 93 93 9D 9D 13 6F 93 8B 8C 8C 44 44'
+ '44 48 4C 4E 4D 4D 4D 4D 4D 4D 48 48 48 48 48 48'
+ '48 48 2B 6B 93 93 93 93 93 93 7E 7F 7E 35 9D 9D'
+ '00 30 7F 7F 7E 93 9D 9D 12 70 8A 89 87 85 83 78'
+ '79 75 76 6F 6F 6C 6D 6D 6D 6D 6D 6D 6D 6D 6D 6D'
+ '6D 6D 2B 6B 93 93 93 93 93 93 93 7F 7F 5D 30 2B'
+ '35 87 7F 7F 93 7E 9D 9D 12 70 98 99 97 97 97 96'
+ '96 95 95 94 94 94 93 93 92 92 92 91 91 91 90 90'
+ '8F 8F 2B 47 93 93 93 93 93 93 93 7E 7F 7F 7E 7D'
+ '7E 80 80 7F 7F 7F 9D 9D 11 73 9C 8A 82 83 83 81'
+ '7C 7C 7C 7C 7C 81 81 81 81 81 81 81 81 81 81 81'
+ '81 81 2B 3B 93 93 93 93 93 93 93 93 93 80 80 80'
+ '80 80 7F 7F 7F 7F 9D 9D 11 7B 99 76 61 57 5B 75'
+ '77 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76'
+ '76 76 2D 30 93 93 93 93 93 93 93 93 93 7E 7D 7D'
+ '7D 7D 7F 7F 7F 7F 9D 9D 0D 77 94 63 46 53 4E 60'
+ '77 75 75 75 75 75 74 74 74 74 74 74 74 74 75 75'
+ '75 75 70 2B 5D 93 93 93 93 93 93 93 93 93 7D 7D'
+ '7D 7D 7F 7F 7F 7F 9D 9D 03 5F 97 58 4F 60 48 57'
+ '75 72 72 72 71 70 70 72 74 75 75 74 72 70 70 70'
+ '71 72 70 2B 37 93 93 93 93 93 93 93 93 7D 7D 7D'
+ '7D 7D 7F 7F 7F 7F 00 9D 9D 43 95 6C 62 6F 5B 66'
+ '70 6F 6D 70 6D 6D 72 72 72 72 72 72 72 72 6D 6D'
+ '71 6D 70 70 2B 52 93 93 93 93 93 93 7D 7D 7D 7D'
+ '7D 7D 7F 7F 7F 7F 00 9D 9D 31 90 6E 6C 68 6C 6E'
+ '6B 6C 72 72 72 72 72 72 72 72 72 72 72 72 72 72'
+ '72 82 70 70 30 30 5C 93 93 93 93 7D 7D 7D 7D 7D'
+ '7D 7F 7F 7F 7F 7F 00 9D 9D 27 8A 6D 6A 6A 6A 67'
+ '70 70 70 70 71 72 73 73 73 73 73 73 73 73 72 72'
+ '78 85 70 70 70 2D 3B 93 93 93 7D 7D 7D 7D 7D 7D'
+ '7F 7F 7F 7F 7F 7F 00 9D 9D 1F 74 6F 67 68 67 71'
+ '70 70 70 6E 6F 6F 6F 6F 6F 6F 70 6F 70 70 6F 6F'
+ '6E 6D 70 70 70 61 2D 3B 93 7D 7D 7D 7D 7D 7D 7F'
+ '7F 7F 7F 7F 7F 7F 00 9D 9D 10 53 78 67 68 6B 70'
+ '70 6C 6E 6D 6D 6D 6D 6C 70 70 6B 70 70 70 70 70'
+ '70 6B 70 70 70 61 61 2D 35 6B 7D 7D 7D 7D 7F 7F'
+ '7F 7F 7F 7F 87 3B 00 9D 9D 05 41 7A 69 6A 70 70'
+ '70 6D 6D 6D 6D 6D 6D 70 70 70 70 70 70 70 70 70'
+ '70 70 70 70 70 61 61 50 3E 2B 40 5D 7D 7F 7F 7F'
+ '7F 9C 6B 40 2B 3B 00 00 9D 9D 36 7A 6C 6E 70 70'
+ '6D 6D 6D 6D 6D 6D 6D 6D 6C 70 70 70 70 70 70 70'
+ '70 70 70 70 70 70 50 50 3E 9D 9D 30 2B 37 37 37'
+ '37 2B 2D 00 00 00 00 00 9D 9D 29 79 6E 6F 70 70'
+ '6E 6E 6E 6E 6E 6E 6E 6E 6E 70 70 70 70 70 70 70'
+ '70 70 70 70 70 70 50 50 3E 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 9D 9D 20 75 71 6F 70 70'
+ '70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70'
+ '70 70 70 70 70 70 50 50 3E 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 9D 9D 18 69 73 72 70 70'
+ '73 73 73 73 73 73 73 73 73 73 73 70 70 70 70 70'
+ '70 70 70 70 61 70 59 6D 3E 07 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 9D 9D 0A 4E 78 78 7B 7B'
+ '7B 76 77 77 77 77 77 77 77 77 77 77 7A 7A 7A 7A'
+ '7A 77 7A 7A 88 76 69 67 30 02 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 9D 9D 06 3D 79 7C 79 7B'
+ '7B 7B 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A'
+ '7A 7A 88 88 88 7A 79 63 25 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 2F 70 83 82 7B'
+ '7B 7B 7B 7B 81 81 81 81 81 81 81 81 81 81 81 81'
+ '82 82 88 88 88 84 76 57 1D 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 24 66 86 84 85'
+ '8C 8C 8C 8C 8C 8C 85 85 85 85 85 85 85 85 86 86'
+ '88 88 88 88 85 87 73 45 0E 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 1C 59 87 87 87'
+ '88 88 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 88'
+ '88 88 88 88 87 89 71 3F 08 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 0C 48 85 8E 88'
+ '87 8D 8C 8B 8E 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C 8C'
+ '8C 8D 8B 86 8C 8C 73 38 9D 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 9D 9D 06 3E 85 7C 59'
+ '5E 73 8D 8E 8E 8F 8F 8E 8D 8C 8C 8D 8E 8F 8F 8E'
+ '8F 85 5F 5A 6E 8D 71 2E 9D 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 9D 9D 39 81 61 4F'
+ '55 4F 8C 92 91 91 91 91 91 91 91 91 91 91 91 91'
+ '94 72 4E 52 53 8C 6A 2A 9D 9D 9D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 9D 9D 2C 6B 7A 79'
+ '72 85 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A 9A'
+ '9B 93 7C 75 79 74 4E 1B 9D 9D 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 9D 9D 0B 35 5A 70'
+ '74 78 75 75 75 75 75 75 75 75 75 75 75 75 75 75'
+ '75 76 76 74 6A 4E 28 04 9D 9D 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 9D 9D 9D 09 1E 22'
+ '21 21 21 21 21 21 21 21 21 21 21 21 21 21 21 21'
+ '21 21 21 22 22 1A 02 9D 9D 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D 9D'
+ '9D 9D 9D 9D 9D 9D 9D 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF F0 00 00 00 FF FF'
+ 'FF FF E0 00 00 00 FF FF FF FF C0 00 00 00 FF FF'
+ 'FF FF 80 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
+ 'FF FC 00 00 00 00 FF FF FF FC 00 00 00 00 F0 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 E0 00 00 00 00 00 00 00 60 00 00 00 00'
+ '00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 C0 00 00 00 00 07 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
+ '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0C 00 00 00 24 00 00 00 30 00 00 00 48 00 00'
+ '00 78 00 00 00 90 00 00 00 90 00 00 00 90 00 00'
+ '00 90 00 00 00 78 00 00 00 48 00 00 00 30 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
+ '00 3C 00 00 00 78 00 00 00 90 80 80 80 FF 6E 6E'
+ '6E FF 62 62 62 FF 62 62 62 FF 62 62 62 FF 80 80'
+ '80 FF 00 00 00 B4 00 00 00 9C 00 00 00 90 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 86 86'
+ '86 FF 6E 6E 6E FF 7A 7A 7A FF AA AA AA FF CE CE'
+ 'CE FF DA DA DA FF F2 F2 F2 FF DA DA DA FF CE CE'
+ 'CE FF AA AA AA FF 80 80 80 FF 6E 6E 6E FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 0C 00 00 00 3C 7A 7A 7A FF 80 80'
+ '80 FF CE CE CE FF FF FF FF FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 24 00 00 00 48 62 62 62 FF C0 C0 C0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
+ '00 78 6E 6E 6E FF E6 E6 E6 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 56 56 56 56 FF 62 62'
+ '62 FF E6 E6 E6 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 16 00 00 00 34 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 42 00 00 00 42 4A 4A 4A FF 62 62 62 FF C2 C2'
+ 'C2 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 05 00 00 00 69 00 00'
+ '00 C5 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 FF 62 62 62 FF 56 56 56 FF 92 92 92 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 05 00 00 00 9B 00 00 00 FF 00 00'
+ '00 FF 21 21 21 FF 2C 2C 2C FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 4A 4A 4A FF 62 62 62 FF F2 F2 F2 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF 00 00'
+ '00 00 00 00 00 54 00 00 00 FF 26 26 26 FF 90 90'
+ '90 FF B8 B4 B6 FF AD AD AD FF AB AC AC FF AD A8'
+ 'AB FF CD CD CD FF CC CC CC FF CB CB CB FF C9 C9'
+ 'C9 FF C4 C4 C4 FF C3 C3 C3 FF C2 C2 C2 FF C2 C2'
+ 'C2 FF C3 C3 C3 FF C0 C0 C0 FF C1 C1 C1 FF BF BF'
+ 'BF FF BF BF BF FF BC BC BC FF BD BD BD FF BA BA'
+ 'BA FF BD BD BD FF BD BD BD FF BD BD BD FF 6E 6E'
  '6E FF 56 56 56 FF 9E 9E 9E FF FF D4 F0 FF FF D4'
  'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
  'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 D4 FF FF D4'
  'F0 FF FF D4 F0 FF FF D4 E3 FF F2 F2 F2 FF 00 00'
  '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF E9 E9'
  'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
- 'E2 FF DB DB DB FF DC DC DC FF D8 D8 D8 FF D9 D9'
- 'D9 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF 62 62'
- '62 FF CE CE CE FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 F0 FF FF D4 F0 FF C0 C0 C0 FF 7A 7A'
- '7A FF 62 62 62 FF 80 80 80 FF E6 E6 E6 FF FF D4'
- 'F0 FF FF D4 F0 FF F2 F2 F2 FF FF D4 E3 FF 00 00'
- '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
- 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
- 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
- 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
- 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF 62 62'
- '62 FF AA AA AA FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 E3 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'E3 FF FF D4 D4 FF FF D4 E3 FF FF D4 FF FF FF D4'
- 'FF FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
- 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF 62 62'
- '62 FF 92 92 92 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 FF FF FF D4'
- 'FF FF FF D4 FF FF FF D4 FF FF FF D4 FF FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
- 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
- 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'E2 FF DB DB DB FF DC DC DC FF D8 D8 D8 FF D9 D9'
+ 'D9 FF D2 D2 D2 FF D2 D2 D2 FF CF CF CF FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF 62 62'
+ '62 FF CE CE CE FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 F0 FF FF D4 F0 FF C0 C0 C0 FF 7A 7A'
+ '7A FF 62 62 62 FF 80 80 80 FF E6 E6 E6 FF FF D4'
+ 'F0 FF FF D4 F0 FF F2 F2 F2 FF FF D4 E3 FF 00 00'
+ '00 33 00 00 00 F9 26 26 26 FF D3 D3 D3 FF F7 F7'
+ 'F7 FF F8 F8 F8 FF F6 F6 F6 FF F6 F6 F6 FF F6 F6'
+ 'F6 FF F5 F5 F5 FF F5 F5 F5 FF F4 F4 F4 FF F4 F4'
+ 'F4 FF F3 F3 F3 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F1 F1 F1 FF F1 F1 F1 FF F1 F1'
+ 'F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF EF EF'
+ 'EF FF EF EF EF FF EE EE EE FF EE EE EE FF 62 62'
+ '62 FF AA AA AA FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 E3 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'E3 FF FF D4 D4 FF FF D4 E3 FF FF D4 FF FF FF D4'
+ 'FF FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 33 00 00 00 F9 24 24 24 FF D6 D6 D6 FF FF FF'
+ 'FF FF E9 E9 E9 FF E1 E1 E1 FF E2 E2 E2 FF E2 E2'
+ 'E2 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF 62 62'
+ '62 FF 92 92 92 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 FF FF FF D4'
+ 'FF FF FF D4 FF FF FF D4 FF FF FF D4 FF FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 34 00 00 00 FA 24 24 24 FF DE DE DE FF F8 F8'
+ 'F8 FF D9 D9 D9 FF C4 C4 C4 FF BB BB BB FF BF BF'
+ 'BF FF D8 D8 D8 FF DA DA DA FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF 6E 6E'
+ '6E FF 7A 7A 7A FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
+ 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
+ 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
+ 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D3 D3'
+ 'D3 FF 62 62 62 FF C0 C0 C0 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
+ 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
+ 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF 62 62 62 FF 86 86 86 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
+ 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
+ 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0 D0 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF 62 62 62 FF B6 B6 B6 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
+ 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
+ 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF D5 D5 D5 FF E1 E1 E1 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF 7A 7A 7A FF 7A 7A 7A FF FF B1'
+ 'C7 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
+ 'F2 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
+ 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
+ 'CD FF CA CA CA FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
+ 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF 6E 6E 6E FF 92 92'
+ '92 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
+ 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
+ 'CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D2 D2 D2 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF 6E 6E'
+ '6E FF 92 92 92 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
+ '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
+ 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
+ 'CE FF D3 D3 D3 FF D3 D3 D3 FF CF CF CF FF D1 D1'
+ 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF CF CF CF FF D3 D3 D3 FF D3 D3 D3 FF CE CE'
+ 'CE FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CE CE CE FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF 6E 6E 6E FF 80 80 80 FF CE CE CE FF FF D4'
+ 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF E6 E6 E6 FF 92 92 92 FF 00 00'
+ '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
+ '9F FF DD DD DD FF CC CC CC FF CD CD CD FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF B3 B3 B3 FF 99 99 99 FF 62 62 62 FF 9E 9E'
+ '9E FF C0 C0 C0 FF FF D4 D4 FF FF D4 F0 FF FF D4'
+ 'F0 FF FF D4 F0 FF FF D4 F0 FF FF FF FF FF CE CE'
+ 'CE FF 9E 9E 9E FF 62 62 62 FF 92 92 92 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
+ '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
+ 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 FF 00 00'
+ '00 FF 7A 7A 7A FF 62 62 62 FF 86 86 86 FF 86 86'
+ '86 FF 86 86 86 FF 86 86 86 FF 62 62 62 FF 6E 6E'
+ '6E FF 00 00 00 24 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
+ '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
+ 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 CF 00 00'
+ '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
+ '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
+ 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 CF 00 00'
+ '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
+ '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
+ 'D3 FF D3 D3 D3 FF C4 C4 C4 FF D3 D3 D3 FF BD BD'
+ 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
+ '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
+ '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF DE DE'
+ 'DE FF DE DE DE FF DE DE DE FF D9 D9 D9 FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DA DA DA FF DD DD'
+ 'DD FF DD DD DD FF E7 E7 E7 FF D9 D9 D9 FF CC CC'
+ 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
+ '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
+ '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
+ 'DC FF DE DE DE FF DE DE DE FF DE DE DE FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF DD DD DD FF DC DC'
+ 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
+ '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
+ '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
+ 'E1 FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
+ 'DE FF DE DE DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E3 E3 E3 FF D9 D9'
+ 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
+ '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
+ '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
+ 'E3 FF E4 E4 E4 FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
+ 'E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
+ 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
+ '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
+ '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
+ 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
+ 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
+ '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
+ '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
+ 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
+ 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
+ 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EA EA'
+ 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
+ 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
+ '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
+ '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
+ 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
+ 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
+ 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
+ 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
+ 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
+ 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
+ '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
+ 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
+ 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
+ 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
+ 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
+ '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
+ 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
+ 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
+ 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
+ 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
+ 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
+ '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
+ '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
+ '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
+ '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
+ '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF F0 00 00 00 FF FF FF FF E0 00 00 00 FF FF'
+ 'FF FF C0 00 00 00 FF FF FF FF 80 00 00 00 FF FF'
+ 'FF FF 00 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
+ 'FF FC 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 00'
+ '00 00 00 60 00 00 00 00 00 00 00 20 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
+ '00 00 00 01 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
+ '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00'
+} */
+
+/* BINRES ramdisk.ico */
+12 ICON ramdisk.ico
+/* {
+ '00 00 01 00 07 00 20 20 00 00 01 00 04 00 E8 02'
+ '00 00 76 00 00 00 10 10 00 00 01 00 08 00 68 05'
+ '00 00 5E 03 00 00 10 10 00 00 01 00 04 00 28 01'
+ '00 00 C6 08 00 00 30 30 00 00 01 00 08 00 A8 0E'
+ '00 00 EE 09 00 00 30 30 00 00 01 00 04 00 68 06'
+ '00 00 96 18 00 00 30 30 00 00 01 00 20 00 A8 25'
+ '00 00 FE 1E 00 00 20 20 00 00 01 00 20 00 A8 10'
+ '00 00 A6 44 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 88 00 66 00 00 00 00 00 00 00 00 00 00'
+ '00 00 08 08 80 E6 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 08 07 EE 00 00 00 00 00 00 00 00 00 00'
+ '00 08 00 08 00 0E 00 60 00 00 00 00 00 00 00 00'
+ '00 80 00 80 80 08 00 66 00 00 00 00 00 00 00 00'
+ '08 00 08 00 08 00 80 E6 00 00 00 00 00 00 00 00'
+ '80 00 80 00 00 80 07 EE 00 00 00 00 00 00 00 08'
+ '00 08 00 00 00 08 00 0E 00 60 00 00 00 00 00 80'
+ '00 80 00 08 00 00 80 08 00 66 00 00 00 00 00 80'
+ '08 00 00 80 80 00 08 00 80 E6 00 00 00 00 00 80'
+ '80 00 08 08 08 00 00 80 07 EE 00 00 00 00 00 88'
+ '00 00 80 80 80 00 00 08 00 0E 00 60 00 00 66 07'
+ '00 00 08 08 00 00 00 00 80 08 00 66 00 00 66 00'
+ '70 00 00 80 00 08 00 00 08 00 80 E6 00 00 EE EE'
+ '07 00 00 00 00 00 80 00 00 80 07 EE 00 00 0E E0'
+ '00 70 00 00 08 00 08 00 00 08 00 0E 00 60 00 00'
+ '66 07 00 00 00 80 00 80 00 00 80 08 00 66 00 00'
+ '66 00 70 00 00 08 00 08 00 00 08 00 80 E6 00 00'
+ 'EE EE 07 00 00 00 80 00 80 00 00 80 07 EE 00 00'
+ '0E E0 00 70 00 00 08 00 00 00 00 08 00 0E 00 00'
+ '00 00 66 07 00 00 00 80 00 00 00 00 80 08 00 00'
+ '00 00 66 00 70 00 00 00 08 88 00 00 08 08 00 00'
+ '00 00 EE EE 07 00 00 00 80 80 80 00 00 87 00 00'
+ '00 00 0E E0 00 70 00 00 88 08 80 00 00 70 00 00'
+ '00 00 00 00 66 07 00 00 80 80 80 00 07 00 00 00'
+ '00 00 00 00 66 00 70 00 08 88 00 00 70 00 00 00'
+ '00 00 00 00 EE EE 07 00 00 00 00 07 00 00 00 00'
+ '00 00 00 00 0E E0 00 70 00 00 00 70 00 00 00 00'
+ '00 00 00 00 00 00 66 07 00 00 07 00 00 00 00 00'
+ '00 00 00 00 00 00 66 00 70 00 70 00 00 00 00 00'
+ '00 00 00 00 00 00 EE EE 07 07 00 00 00 00 00 00'
+ '00 00 00 00 00 00 0E E0 00 70 00 00 00 00 FF CC'
+ 'FF FF FF 84 FF FF FF 00 FF FF FE 00 DF FF FC 00'
+ 'CF FF F8 00 4F FF F0 00 0F FF E0 00 0D FF C0 00'
+ '0C FF C0 00 04 FF C0 00 00 FF C0 00 00 DF 00 00'
+ '00 CF 00 00 00 4F 08 00 00 0F 9C 00 00 0D F0 00'
+ '00 0C F0 00 00 04 F0 80 00 00 F9 C0 00 00 FF 00'
+ '00 00 FF 00 00 00 FF 08 00 00 FF 9C 00 01 FF F0'
+ '00 03 FF F0 00 07 FF F0 80 0F FF F9 C0 1F FF FF'
+ '00 3F FF FF 00 7F FF FF 08 FF FF FF 9D FF 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 1C 04 04 00 18 18'
+ '18 00 1A 1A 1A 00 1C 1C 1C 00 36 0E 0E 00 3C 14'
+ '14 00 34 1C 1C 00 20 20 20 00 24 24 24 00 28 28'
+ '28 00 30 30 30 00 38 38 38 00 3C 3C 3C 00 40 28'
+ '28 00 46 46 46 00 48 48 48 00 4C 4C 4C 00 50 50'
+ '50 00 52 52 52 00 54 54 54 00 56 56 56 00 58 58'
+ '58 00 68 68 68 00 74 74 74 00 78 78 78 00 7E 7E'
+ '7E 00 7F 7F 7F 00 00 92 92 00 00 9C 9C 00 00 BC'
+ 'BC 00 00 C0 C0 00 00 D0 D0 00 00 DF DF 00 00 E3'
+ 'E3 00 00 E5 E5 00 00 F7 F7 00 00 FB FB 00 00 FF'
+ 'FF 00 90 90 90 00 A8 A8 A8 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
+ '95 00 00 00 38 00 A8 44 F9 77 11 00 00 00 B8 09'
+ '38 00 00 00 38 00 70 63 0C 01 98 17 95 00 00 00'
+ '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
+ 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 76 00'
+ '00 00 76 00 00 00 07 00 00 00 B0 18 95 00 00 00'
+ '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
+ '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 10 00 00 00 00 00 00 00 58 00'
+ '5A 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
+ '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
+ '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
+ 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
+ '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
+ 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
+ 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
+ '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
+ '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
+ 'F5 77 00 EC FD 7F 58 00 00 00 00 00 00 00 03 00'
+ '00 00 60 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
+ '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
+ 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 72'
+ '61 6D 64 69 73 6B 2E 69 63 6F 00 93 4B 00 14 1A'
+ '95 00 1F 3B D4 77 11 00 00 00 88 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 70 63 0C 01 76 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 76 00 00 00 A4 1A 95 00 07 00'
+ '00 00 00 00 00 00 76 00 00 00 76 00 00 00 07 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 70 63 0C 01 76 00 00 00 58 1A'
+ '95 00 00 00 00 00 00 00 00 00 00 18 00 1F 00 00'
+ '00 00 00 00 00 00 00 00 00 00 04 0F 07 26 00 00'
+ '00 00 00 00 00 00 00 00 00 08 08 04 13 01 00 20'
+ '00 00 00 00 00 00 00 00 08 08 0A 29 29 15 07 26'
+ '00 00 00 00 00 00 00 11 04 0A 29 29 29 29 15 01'
+ '00 20 00 00 00 00 00 1A 03 29 0B 29 29 29 29 15'
+ '07 26 00 00 00 00 1C 05 0C 29 29 0B 29 29 29 29'
+ '15 01 00 20 00 00 21 25 00 0D 29 29 0B 29 29 29'
+ '29 15 07 26 00 00 00 00 1D 06 0D 29 29 16 12 29'
+ '29 29 15 01 00 1E 00 00 24 25 00 0D 29 29 14 09'
+ '29 29 29 15 07 23 00 00 00 00 1D 06 0D 29 29 0A'
+ '02 12 29 29 13 0E 00 00 00 00 24 25 00 0D 29 29'
+ '19 17 12 29 29 28 00 00 00 00 00 00 1D 06 0D 29'
+ '10 19 04 29 27 00 00 00 00 00 00 00 24 25 00 0D'
+ '29 29 29 27 00 00 00 00 00 00 00 00 00 00 1D 06'
+ '0D 29 27 00 00 00 00 00 00 00 00 00 00 00 21 22'
+ '00 1A 00 00 00 00 FA FF 00 00 F0 FF 00 00 E0 BF'
+ '00 00 C0 3F 00 00 80 2F 00 00 80 0F 00 00 00 0B'
+ '00 00 20 03 00 00 C0 02 00 00 C8 00 00 00 F0 00'
+ '00 00 F2 00 00 00 FC 01 00 00 FC 83 00 00 FF 07'
+ '00 00 FF 2F 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '08 0E 00 00 00 00 00 00 08 0E 00 00 00 00 00 00'
+ '00 80 0E 00 00 00 00 00 00 08 0E 00 00 00 08 00'
+ '00 00 80 0E 00 00 08 00 00 00 08 0E 00 00 60 00'
+ '00 00 00 80 0E 00 EE 00 00 00 00 08 0E 00 00 60'
+ '00 08 80 00 80 06 00 EE 00 00 80 00 08 0E 00 00'
+ '60 00 00 08 00 80 00 00 EE 00 00 88 80 07 00 00'
+ '00 60 00 88 00 80 00 00 00 EE 00 00 08 00 00 00'
+ '00 00 60 00 80 00 00 00 00 00 EE 08 00 00 FA FF'
+ '00 00 F0 FF 00 00 E0 BF 00 00 C0 3F 00 00 80 2F'
+ '00 00 80 0F 00 00 00 0B 00 00 20 03 00 00 C0 02'
+ '00 00 C8 00 00 00 F0 00 00 00 F2 00 00 00 FC 01'
+ '00 00 FC 83 00 00 FF 07 00 00 FF 2F 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
+ '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
+ '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 18 18'
+ '18 00 19 19 19 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
+ '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
+ '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2B 2B'
+ '2B 00 2C 2C 2C 00 2F 2F 2F 00 34 34 34 00 35 35'
+ '35 00 39 39 39 00 3B 3B 3B 00 3D 3D 3D 00 3F 3F'
+ '3F 00 40 40 40 00 41 41 41 00 47 47 47 00 48 48'
+ '48 00 49 49 49 00 4B 4B 4B 00 53 53 53 00 56 56'
+ '56 00 59 59 59 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
+ '61 00 64 64 64 00 68 68 68 00 6A 6A 6A 00 6C 6C'
+ '6C 00 70 70 70 00 71 71 71 00 72 72 72 00 74 74'
+ '74 00 75 75 75 00 77 77 77 00 78 78 78 00 79 79'
+ '79 00 7A 7A 7A 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F'
+ '7F 00 00 80 80 00 00 FF FF 00 80 80 80 00 81 81'
+ '81 00 83 83 83 00 85 85 85 00 87 87 87 00 88 88'
+ '88 00 8A 8A 8A 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
+ '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 97 97'
+ '97 00 98 98 98 00 99 99 99 00 9A 9A 9A 00 9C 9C'
+ '9C 00 9D 9D 9D 00 9F 9F 9F 00 A0 A0 A0 00 A2 A2'
+ 'A2 00 A4 A4 A4 00 A5 A5 A5 00 A7 A7 A7 00 A8 A8'
+ 'A8 00 A9 A9 A9 00 AB AB AB 00 AD AD AD 00 AE AE'
+ 'AE 00 B0 B0 B0 00 B2 B2 B2 00 B3 B3 B3 00 B6 B6'
+ 'B6 00 B7 B7 B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA'
+ 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
+ 'BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2'
+ 'C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6'
+ 'C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9 C9 00 CA CA'
+ 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
+ 'CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
+ 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
+ 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
+ 'DA 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
+ 'DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
+ 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
+ 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
+ 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
+ 'EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2'
+ 'F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
+ 'F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9 F9 00 FA FA'
+ 'FA 00 FF FF FF 00 00 00 00 00 10 19 95 00 42 00'
+ '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
+ 'F5 77 00 EC FD 7F 58 00 00 00 00 00 00 00 03 00'
+ '00 00 60 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
+ '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
+ 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
+ '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
+ '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
+ '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
+ '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
+ '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
+ '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 72'
+ '61 6D 64 69 73 6B 2E 69 63 6F 00 93 4B 00 14 1A'
+ '95 00 1F 3B D4 77 11 00 00 00 88 00 00 00 4F 3B'
+ 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
+ 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 1A 95 00 70 63 0C 01 76 00 00 00 00 00'
+ '00 00 C9 F1 E7 77 76 00 00 00 A4 1A 95 00 07 00'
+ '00 00 00 00 00 00 76 00 00 00 76 00 00 00 07 00'
+ '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
+ 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
+ '4B 00 F8 00 00 00 70 63 0C 01 76 00 00 00 58 1A'
+ '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4'
+ 'A4 A4 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D'
+ '3D A4 A4 3B 3B A4 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4'
+ '3D 3D A4 3C 3B A4 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4'
+ '3D A4 68 3C 3C A4 00 A4 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4 A4'
+ '3D A4 A4 A4 3C A4 00 3B A4 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4 A4 3D'
+ 'A4 3D A4 A4 3D A4 00 3B 3B 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 3D A4 A4 A4 3D A4'
+ 'A4 A4 3D A4 A4 3D 00 3C 3B A4 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4'
+ 'A4 A4 A4 3D A4 A4 68 3C 3C A4 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4'
+ 'A4 A4 A4 A4 3D A4 A4 A4 3C A4 00 3B A4 00 00 00'
+ '00 00 00 00 00 00 00 A4 A4 A4 A4 0F 17 16 17 16'
+ '16 16 16 16 16 16 16 3D A4 A4 A4 3D A4 A4 A4 A4'
+ '3D A4 A4 A4 A4 3D A4 A4 3D A4 00 3B 3B A4 00 00'
+ '00 00 00 00 00 00 00 A4 A4 12 47 72 75 73 76 75'
+ '74 73 71 6F 6E 6D 6C 3D A4 A4 3D A4 A4 A4 A4 3D'
+ 'A4 3D A4 A4 A4 A4 3D A4 A4 3D A4 3C 3B A4 00 00'
+ '00 00 00 00 00 00 A4 A4 01 43 93 90 8F 7D 40 42'
+ '48 4B 52 59 62 68 6B 3D A4 3D A4 A4 A4 A4 3D A4'
+ '3D A4 3D A4 A4 A4 A4 3D A4 A4 68 3C 3C A4 00 A4'
+ '00 00 00 00 00 00 A4 A4 0B 6F 94 8A 8E 73 1C 1E'
+ '26 31 41 48 4F 54 56 3D 3D A4 A4 A4 A4 3D A4 3D'
+ 'A4 3D A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3C A4 00 3B'
+ 'A4 00 00 00 00 00 A4 A4 15 79 92 8C 8F 75 21 29'
+ '36 41 46 4A 51 3B 3B A4 68 A4 A4 A4 A4 A4 3D A4'
+ '3D A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 3D A4 00 3B'
+ '3B A4 00 00 00 00 A4 A4 14 79 94 8E 8F 79 2C 32'
+ '39 40 45 4A 51 3B 3B A4 A4 68 A4 A4 A4 A4 A4 3D'
+ 'A4 A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 3D A4 3C'
+ '3B A4 00 00 00 00 A4 A4 14 79 96 8F 90 7E 2F 30'
+ '38 40 45 4A 51 3C 3C 3C 3C 4E 68 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 68 3C'
+ '3C A4 00 A4 00 00 A4 A4 13 79 97 91 93 7E 2D 2E'
+ '35 3E 43 49 4E 4E 3C 3C 4E 4E 4E 68 A4 A4 A4 A4'
+ 'A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 A4'
+ '3C A4 00 3B A4 00 A4 A4 13 7A 9A 93 92 87 55 55'
+ '58 5A 5B 5D 5E 61 61 62 65 3B 3B A4 68 A4 A4 A4'
+ 'A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4'
+ '3D A4 A4 3B 3B A4 A4 A4 12 7B 9B 93 93 92 95 93'
+ '91 90 8E 8C 8A 89 87 86 83 3B 3B A4 A4 68 A4 A4'
+ 'A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4'
+ 'A4 3D A4 3C 3B A4 A4 A4 12 7B 9F A0 9E 9E 9E 9D'
+ '9D 9C 9C 9B 9B 9B 9A 9A 99 3C 3C 3C 3C 99 68 A4'
+ 'A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D'
+ 'A4 A4 68 3C 3C A4 A4 A4 11 7E A3 91 89 8A 8A 88'
+ '87 87 87 87 87 88 88 88 88 88 3C 3C 81 81 81 68'
+ 'A4 A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 A4 A4 A4 A4'
+ '3D A4 A4 A4 3C A4 A4 A4 11 86 A0 81 6C 63 67 80'
+ '82 81 81 81 81 81 81 81 81 81 81 81 81 3B 3B A4'
+ '68 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 A4 A4 A4'
+ 'A4 3D A4 A4 3D A4 A4 A4 0D 82 9B 6E 57 5F 5B 6B'
+ '82 80 80 80 80 80 7F 7F 7F 7F 7F 7F 7F 3B 3B A4'
+ 'A4 68 A4 A4 A4 A4 A4 A4 A4 A4 3D 3D 3D A4 A4 A4'
+ 'A4 A4 3D A4 3D A4 A4 A4 03 6A 9E 64 5C 6B 58 63'
+ '80 7D 7D 7D 7C 7B 7B 7D 7F 80 80 7F 7D 3C 3C 3C'
+ '3C 7F 68 A4 A4 A4 A4 A4 A4 3D A4 3D A4 3D A4 A4'
+ 'A4 A4 A4 3D 68 A4 00 A4 A4 53 9C 77 6D 7A 67 71'
+ '7B 7A 78 7B 85 89 8B 8E 92 95 95 93 8F 8F 3C 3C'
+ '8F 8F 7F 68 A4 A4 A4 A4 A4 3D 3D A4 3D 3D A4 A4'
+ 'A4 A4 A4 68 A4 A4 00 A4 A4 39 97 79 77 73 77 79'
+ '76 77 87 98 94 89 86 85 84 83 83 84 85 86 89 94'
+ '99 3B 3B A4 68 A4 A4 A4 A4 3D A4 3D A4 3D A4 A4'
+ 'A4 A4 68 A4 A4 00 00 A4 A4 27 91 78 75 75 75 72'
+ '7E 95 8E 84 7C 7D 7E 7E 7E 7E 7E 7E 7E 7E 7D 7D'
+ '83 3B 3B A4 A4 68 A4 A4 A4 A4 3D 3D 3D A4 A4 A4'
+ 'A4 68 A4 A4 00 00 00 A4 A4 1F 7F 7A 72 73 72 7C'
+ '91 84 78 79 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A'
+ '79 3C 3C 3C 3C 4C 68 A4 A4 A4 A4 A4 A4 A4 A4 A4'
+ '68 A4 A4 00 00 00 00 A4 A4 10 5F 83 72 73 76 8C'
+ '7C 77 79 78 78 78 78 77 75 76 76 76 76 76 76 76'
+ '76 76 3C 3C 77 77 4C 68 A4 A4 A4 A4 A4 A4 A4 68'
+ 'A4 A4 00 00 00 00 00 A4 A4 05 50 85 74 75 83 7E'
+ '76 78 78 78 78 78 78 77 74 71 72 72 72 72 72 72'
+ '72 72 72 70 77 3B 3B A4 68 A4 A4 A4 A4 A4 68 A4'
+ 'A4 00 00 00 00 00 00 00 A4 A4 3F 85 77 79 83 79'
+ '78 78 78 78 78 78 78 78 77 71 6D 6E 6E 6E 6E 6E'
+ '6E 6E 6E 6E 6F 3B 3B A4 A4 68 A4 A4 A4 68 A4 A4'
+ '00 00 00 00 00 00 00 00 A4 A4 29 84 79 7A 7C 79'
+ '79 79 79 79 79 79 79 79 79 78 70 6B 6B 6B 6C 6C'
+ '6C 6C 6C 6C 6C 3C 3C 3C 3C 07 68 A4 68 A4 A4 00'
+ '00 00 00 00 00 00 00 00 A4 A4 20 80 7C 7A 78 7B'
+ '7B 7B 7B 7B 7B 7B 7B 7B 7B 7B 7B 75 6F 6C 6A 69'
+ '68 69 69 69 6A 6A 3C 3C 4C 07 A4 68 A4 A4 00 00'
+ '00 00 00 00 00 00 00 00 A4 A4 17 74 7E 7D 74 7D'
+ '7E 7E 7E 7E 7E 7E 7E 7E 7E 7E 7E 7F 7E 7D 7B 77'
+ '74 71 6E 6C 6A 5D 65 78 4C 07 A4 A4 00 00 00 00'
+ '00 00 00 00 00 00 00 00 A4 A4 0A 5B 83 83 78 7A'
+ '83 81 82 82 82 82 82 82 82 82 82 82 82 82 82 83'
+ '83 82 81 81 77 6D 74 72 37 02 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 A4 A4 06 4A 84 87 84 76'
+ '7E 86 85 85 85 85 85 85 85 85 85 85 85 85 85 85'
+ '85 85 86 80 76 85 84 6E 25 A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 34 7B 8A 89 86'
+ '76 7F 89 8A 88 88 88 88 88 88 88 88 88 88 88 88'
+ '89 89 81 75 82 8B 81 63 1B A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 24 71 8D 8B 8C'
+ '89 7F 7A 82 8C 8D 8C 8C 8C 8C 8C 8C 8C 8C 8D 8D'
+ '84 7A 7E 88 8C 8E 7E 56 0E A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 1A 65 8E 8E 8E'
+ '8F 8F 87 7A 7B 86 8B 8B 8C 8C 8C 8C 8B 8B 86 7C'
+ '79 85 8F 8F 8E 90 7C 4D 08 A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 0C 58 8C 95 8F'
+ '8E 94 93 92 8C 88 87 87 85 84 84 85 87 87 87 8A'
+ '91 94 92 8D 93 93 7E 43 A4 A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 A4 A4 06 4C 8C 87 65'
+ '69 7E 94 95 95 96 96 95 94 93 93 94 95 96 96 95'
+ '96 8C 6A 66 79 94 7C 33 A4 A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 44 88 6C 5C'
+ '60 5C 93 99 98 98 98 98 98 98 98 98 98 98 98 98'
+ '9B 7D 5B 5E 5F 93 75 2A A4 A4 A4 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 2B 76 85 84'
+ '7D 8C A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
+ 'A2 9A 87 80 84 7F 5B 19 A4 A4 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 0B 3D 66 7B'
+ '7F 83 80 80 80 80 80 80 80 80 80 80 80 80 80 80'
+ '80 81 81 7F 75 5B 28 04 A4 A4 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 A4 A4 A4 09 1D 23'
+ '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22'
+ '22 22 22 23 23 18 02 A4 A4 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 A4 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4'
+ 'A4 A4 A4 A4 A4 A4 A4 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF 0F FF FF 00 00 FF FF'
+ 'FE 00 FF FF 00 00 FF FF FC 00 FF FF 00 00 FF FF'
+ 'F8 00 BF FF 00 00 FF FF F0 00 9F FF 00 00 FF FF'
+ 'E0 00 9F FF 00 00 FF FF E0 00 8F FF 00 00 F0 00'
+ '00 00 0F FF 00 00 C0 00 00 00 09 FF 00 00 80 00'
+ '00 00 08 FF 00 00 80 00 00 00 00 FF 00 00 00 00'
+ '00 00 00 BF 00 00 00 00 00 00 00 9F 00 00 00 00'
+ '00 00 00 8F 00 00 00 00 00 00 00 0F 00 00 00 00'
+ '00 00 00 0B 00 00 00 00 00 00 00 09 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 0F 00 00 80 00'
+ '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 C0 00'
+ '00 00 00 7F 00 00 C0 00 00 00 00 FF 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
+ '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
+ '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
+ '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
+ 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 08 80 06 60 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 88 0E 60 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 08 00 80 7E E0 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 80 00 E0 06 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '08 00 08 08 00 80 06 60 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 80 00 80 00 80 08 0E 60'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08'
+ '00 08 00 00 08 00 7E E0 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 80 00 80 00 00 00 80 00 E0'
+ '06 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00'
+ '08 00 00 80 00 08 00 80 06 60 00 00 00 00 00 00'
+ '87 77 77 77 77 77 78 00 80 00 08 08 00 00 80 08'
+ '0E 60 00 00 00 00 00 08 FF F7 88 88 77 77 78 08'
+ '00 00 80 80 80 00 08 00 7E E0 00 00 00 00 00 07'
+ 'FF F7 00 88 88 87 78 80 00 08 08 08 00 00 00 80'
+ '00 E0 06 00 00 00 00 07 FF F7 88 88 88 76 60 70'
+ '00 00 80 80 00 00 00 08 00 80 06 60 00 00 00 07'
+ 'FF F7 88 88 88 76 60 07 00 00 08 00 00 80 00 00'
+ '80 08 0E 60 00 00 00 07 FF F7 88 88 88 7E EE E8'
+ '70 00 00 00 00 08 00 00 08 00 7E E0 00 00 00 07'
+ 'FF F7 88 88 88 88 EE 88 87 00 00 00 80 00 80 00'
+ '00 80 00 E0 06 00 00 07 FF F7 77 77 77 77 77 76'
+ '60 70 00 00 08 00 08 00 00 08 00 80 06 60 00 07'
+ 'FF FF FF FF FF FF 77 76 60 07 00 00 00 80 00 80'
+ '00 00 80 08 0E 60 00 07 FF FF FF FF FF FF FF FE'
+ 'EE EF 70 00 00 08 00 08 00 00 08 00 7E E0 00 07'
+ 'FF FF FF 77 77 7F FF FF EE 77 77 00 00 00 80 00'
+ '00 00 00 80 00 E0 00 07 77 77 F7 77 77 77 77 77'
+ '77 76 60 70 00 00 08 00 00 00 00 08 00 80 00 07'
+ '77 77 F7 77 77 77 77 77 77 76 60 07 00 00 00 00'
+ '88 80 00 00 80 80 00 07 77 7F F7 77 77 77 77 77'
+ '77 7E EE E7 70 00 00 08 08 08 00 00 08 70 00 07'
+ 'FF FF 77 77 77 7F FF FF FF FF EE FF 77 00 00 08'
+ '80 88 00 00 07 00 00 08 77 77 77 77 7F FF 77 77'
+ '77 77 FF F6 60 70 00 08 08 08 00 00 70 00 00 08'
+ '77 77 77 7F F7 77 77 77 77 77 77 76 60 07 00 00'
+ '88 80 00 07 00 00 00 00 77 77 77 F7 77 77 77 77'
+ '77 77 77 7E EE E8 70 00 00 00 00 70 00 00 00 00'
+ '77 77 7F 77 77 77 77 77 77 77 77 77 EE 77 87 00'
+ '00 00 07 00 00 00 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 77 76 60 70 00 00 70 00 00 00 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 77 76 60 07'
+ '00 07 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
+ '77 77 77 77 77 7E EE E0 70 70 00 00 00 00 00 00'
+ '87 77 77 77 77 77 77 77 77 77 77 77 77 77 EE 80'
+ '07 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
+ '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
+ '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
+ '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
+ '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
+ '00 77 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
+ '00 00 00 00 00 00 00 00 00 7F FF FF F7 77 77 77'
+ '77 77 77 7F FF FF 78 00 00 00 00 00 00 00 00 00'
+ '00 8F 77 77 F7 77 77 77 77 77 77 FF 77 7F 78 00'
+ '00 00 00 00 00 00 00 00 00 8F 77 77 F7 77 77 77'
+ '77 77 77 F7 77 7F 78 00 00 00 00 00 00 00 00 00'
+ '00 87 77 7F F7 77 77 77 77 77 77 FF 77 77 70 00'
+ '00 00 00 00 00 00 00 00 00 08 77 77 77 77 77 77'
+ '77 77 77 77 77 77 80 00 00 00 00 00 00 00 00 00'
+ '00 00 08 88 88 88 88 88 88 88 88 88 88 80 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF 01 FF FF 00 00 FF FF FE 00 FF FF 00 00 FF FF'
+ 'FC 00 FF FF 00 00 FF FF F8 00 BF FF 00 00 FF FF'
+ 'F0 00 9F FF 00 00 FF FF F0 00 8F FF 00 00 FF FF'
+ 'E0 00 8F FF 00 00 F0 00 00 00 0F FF 00 00 C0 00'
+ '00 00 09 FF 00 00 80 00 00 00 08 FF 00 00 80 00'
+ '00 00 00 FF 00 00 00 00 00 00 00 BF 00 00 00 00'
+ '00 00 00 9F 00 00 00 00 00 00 00 8F 00 00 00 00'
+ '00 00 00 0F 00 00 00 00 00 00 00 0B 00 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 08 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
+ '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
+ '00 00 00 03 00 00 80 00 00 00 00 07 00 00 80 00'
+ '00 00 00 0F 00 00 80 00 00 00 00 1F 00 00 C0 00'
+ '00 00 00 3F 00 00 C0 00 00 00 00 7F 00 00 C0 00'
+ '00 00 00 FF 00 00 C0 00 00 00 03 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
+ '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 20 00 00 00'
+ '00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 00'
+ '00 78 00 00 00 78 00 00 00 3C 00 00 00 30 00 00'
+ '00 6C 00 00 00 6C 00 00 00 24 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 3C 80 80 80 FF 80 80'
+ '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 3C 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
+ '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 3C 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
+ '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
+ 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
+ '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 3E 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 3E 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 00 00 FF FF FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 16 00 00 00 34 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
+ '00 3E 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 05 00 00 00 69 00 00 00 C5 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
+ '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 80 80 FF 00 00'
+ '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00'
+ '00 9B 00 00 00 FF 00 00 00 FF 21 21 21 FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 80 80 FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 54 00 00'
+ '00 FF 26 26 26 FF 90 90 90 FF CA CA CA FF CD CD'
+ 'CD FF CB CB CB FF CE CE CE FF CD CD CD FF CC CC'
+ 'CC FF CB CB CB FF C9 C9 C9 FF C7 C7 C7 FF C6 C6'
+ 'C6 FF C5 C5 C5 FF C4 C4 C4 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 84 00 FF FF FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
+ '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 03 00 00 00 AD 01 01'
+ '01 FF 8A 8A 8A FF EB EB EB FF E8 E8 E8 FF E7 E7'
+ 'E7 FF D5 D5 D5 FF 85 85 85 FF 88 88 88 FF 92 92'
+ '92 FF 98 98 98 FF A2 A2 A2 FF AD AD AD FF BA BA'
+ 'BA FF C0 C0 C0 FF C3 C3 C3 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
+ '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 15 00 00 00 F0 19 19'
+ '19 FF C7 C7 C7 FF EC EC EC FF E2 E2 E2 FF E6 E6'
+ 'E6 FF CB CB CB FF 3B 3B 3B FF 3F 3F 3F FF 56 56'
+ '56 FF 72 72 72 FF 87 87 87 FF 92 92 92 FF 9D 9D'
+ '9D FF A5 A5 A5 FF A8 A8 A8 FF 80 80 80 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
+ 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
+ '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 30 00 00 00 FA 29 29'
+ '29 FF D1 D1 D1 FF EA EA EA FF E4 E4 E4 FF E7 E7'
+ 'E7 FF CD CD CD FF 47 47 47 FF 5F 5F 5F FF 79 79'
+ '79 FF 87 87 87 FF 8F 8F 8F FF 97 97 97 FF A0 A0'
+ 'A0 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 34 00 00 00 F9 28 28'
+ '28 FF D1 D1 D1 FF EC EC EC FF E6 E6 E6 FF E7 E7'
+ 'E7 FF D1 D1 D1 FF 68 68 68 FF 74 74 74 FF 7E 7E'
+ '7E FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
+ 'A0 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
+ '00 18 00 00 00 0C 00 00 00 33 00 00 00 F9 28 28'
+ '28 FF D1 D1 D1 FF EE EE EE FF E7 E7 E7 FF E8 E8'
+ 'E8 FF D6 D6 D6 FF 70 70 70 FF 71 71 71 FF 7D 7D'
+ '7D FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
+ 'A0 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
+ 'FF FF 9C 9C 9C FF C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
+ '00 54 00 00 00 3C 00 00 00 33 00 00 00 F9 27 27'
+ '27 FF D1 D1 D1 FF EF EF EF FF E9 E9 E9 FF EB EB'
+ 'EB FF D6 D6 D6 FF 6A 6A 6A FF 6C 6C 6C FF 78 78'
+ '78 FF 81 81 81 FF 8A 8A 8A FF 93 93 93 FF 9C 9C'
+ '9C FF 9C 9C 9C FF 00 FF FF FF 00 FF FF FF 9C 9C'
+ '9C FF 9C 9C 9C FF 9C 9C 9C FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
+ 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
+ '00 84 00 00 00 78 00 00 00 33 00 00 00 F9 27 27'
+ '27 FF D2 D2 D2 FF F2 F2 F2 FF EB EB EB FF EA EA'
+ 'EA FF DF DF DF FF A7 A7 A7 FF A7 A7 A7 FF AB AB'
+ 'AB FF AE AE AE FF B0 B0 B0 FF B3 B3 B3 FF B6 B6'
+ 'B6 FF B9 B9 B9 FF B9 B9 B9 FF BA BA BA FF BD BD'
+ 'BD FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 33 00 00 00 F9 26 26'
+ '26 FF D3 D3 D3 FF F3 F3 F3 FF EB EB EB FF EB EB'
+ 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF E9 E9'
+ 'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
+ 'E2 FF E1 E1 E1 FF DF DF DF FF DE DE DE FF DB DB'
+ 'DB FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
+ '80 FF 00 00 00 90 00 00 00 33 00 00 00 F9 26 26'
+ '26 FF D3 D3 D3 FF F7 F7 F7 FF F8 F8 F8 FF F6 F6'
+ 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
+ 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
+ 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
+ 'F1 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
+ 'FF FF F1 F1 F1 FF C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 33 00 00 00 F9 24 24'
+ '24 FF D6 D6 D6 FF FF FF FF FF E9 E9 E9 FF E1 E1'
+ 'E1 FF E2 E2 E2 FF E2 E2 E2 FF E0 E0 E0 FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
+ 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF 00 FF FF FF 00 FF FF FF D9 D9'
+ 'D9 FF D9 D9 D9 FF D9 D9 D9 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
+ 'FF FF 00 00 00 90 00 00 00 34 00 00 00 FA 24 24'
+ '24 FF DE DE DE FF F8 F8 F8 FF D9 D9 D9 FF C4 C4'
+ 'C4 FF BB BB BB FF BF BF BF FF D8 D8 D8 FF DA DA'
+ 'DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
  'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
  'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF 6E 6E'
- '6E FF 7A 7A 7A FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 E3 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 25 00 00 00 F7 1F 1F 1F FF DA DA DA FF F3 F3'
- 'F3 FF C6 C6 C6 FF A9 A9 A9 FF B7 B7 B7 FF B0 B0'
- 'B0 FF C3 C3 C3 FF DA DA DA FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7'
+ 'D9 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 90 00 00 00 25 00 00 00 F7 1F 1F'
+ '1F FF DA DA DA FF F3 F3 F3 FF C6 C6 C6 FF A9 A9'
+ 'A9 FF B7 B7 B7 FF B0 B0 B0 FF C3 C3 C3 FF DA DA'
+ 'DA FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
  'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D3 D3'
- 'D3 FF 62 62 62 FF C0 C0 C0 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 07 00 00 00 D0 05 05 05 FF C2 C2 C2 FF F6 F6'
- 'F6 FF BC BC BC FF B2 B2 B2 FF C3 C3 C3 FF AB AB'
- 'AB FF BB BB BB FF D8 D8 D8 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D4 D4 D4 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D5 D5 D5 FF D7 D7 D7 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D7 D7 D7 FF D5 D5 D5 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D3 D3'
- 'D3 FF 62 62 62 FF 86 86 86 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 9C 00 00 00 FF A4 A4 A4 FF F4 F4'
- 'F4 FF CF CF CF FF C5 C5 C5 FF D2 D2 D2 FF BF BF'
- 'BF FF C9 C9 C9 FF D3 D3 D3 FF D2 D2 D2 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D4 D4 D4 FF D0 D0 D0 FF D3 D3'
- 'D3 FF D3 D3 D3 FF 62 62 62 FF B6 B6 B6 FF F2 F2'
- 'F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF F2 F2 F2 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 73 00 00 00 FF 7E 7E 7E FF EF EF'
- 'EF FF D1 D1 D1 FF CF CF CF FF CB CB CB FF CF CF'
- 'CF FF D1 D1 D1 FF CE CE CE FF CF CF CF FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5'
- 'D5 FF D5 D5 D5 FF D5 D5 D5 FF E1 E1 E1 FF D3 D3'
- 'D3 FF D3 D3 D3 FF 7A 7A 7A FF 7A 7A 7A FF FF B1'
- 'C7 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2'
- 'F2 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 59 00 00 00 FF 59 59 59 FF E9 E9'
- 'E9 FF D0 D0 D0 FF CD CD CD FF CD CD CD FF CD CD'
- 'CD FF CA CA CA FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D4 D4 D4 FF D5 D5 D5 FF D6 D6'
+ 'D7 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 78 00 00 00 07 00 00 00 D0 05 05'
+ '05 FF C2 C2 C2 FF F6 F6 F6 FF BC BC BC FF B2 B2'
+ 'B2 FF C3 C3 C3 FF AB AB AB FF BB BB BB FF D8 D8'
+ 'D8 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
+ 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D5 D5 D5 FF D7 D7'
+ 'D7 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D5 D5'
+ 'D5 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
+ 'FF FF D7 D7 D7 FF C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF C0 C0'
+ 'C0 FF 00 00 00 3C 00 00 00 00 00 00 00 9C 00 00'
+ '00 FF A4 A4 A4 FF F4 F4 F4 FF CF CF CF FF C5 C5'
+ 'C5 FF D2 D2 D2 FF BF BF BF FF C9 C9 C9 FF D3 D3'
+ 'D3 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF DD DD'
+ 'DD FF E1 E1 E1 FF E3 E3 E3 FF E6 E6 E6 FF EA EA'
+ 'EA FF ED ED ED FF ED ED ED FF EB EB EB FF E7 E7'
+ 'E7 FF E7 E7 E7 FF 00 FF FF FF 00 FF FF FF E7 E7'
+ 'E7 FF E7 E7 E7 FF D7 D7 D7 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 73 00 00'
+ '00 FF 7E 7E 7E FF EF EF EF FF D1 D1 D1 FF CF CF'
+ 'CF FF CB CB CB FF CF CF CF FF D1 D1 D1 FF CE CE'
+ 'CE FF CF CF CF FF DF DF DF FF F0 F0 F0 FF EC EC'
+ 'EC FF E1 E1 E1 FF DE DE DE FF DD DD DD FF DC DC'
+ 'DC FF DB DB DB FF DB DB DB FF DC DC DC FF DD DD'
+ 'DD FF DE DE DE FF E1 E1 E1 FF EC EC EC FF F1 F1'
+ 'F1 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
+ '00 FF 59 59 59 FF E9 E9 E9 FF D0 D0 D0 FF CD CD'
+ 'CD FF CD CD CD FF CD CD CD FF CA CA CA FF D6 D6'
+ 'D6 FF ED ED ED FF E6 E6 E6 FF DC DC DC FF D4 D4'
+ 'D4 FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
  'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D5 D5'
- 'D5 FF D5 D5 D5 FF DB DB DB FF E4 E4 E4 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF 6E 6E 6E FF 92 92'
- '92 FF F2 F2 F2 FF F2 F2 F2 FF F2 F2 F2 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 3E 00 00 00 FE 40 40 40 FF D7 D7'
- 'D7 FF D2 D2 D2 FF CA CA CA FF CB CB CB FF CA CA'
- 'CA FF D4 D4 D4 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D1 D1 D1 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D2 D2 D2 FF D3 D3 D3 FF D3 D3 D3 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D1 D1 D1 FF D0 D0 D0 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF 6E 6E'
- '6E FF 92 92 92 FF F2 F2 F2 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'D4 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF 00 00'
- '00 00 00 00 00 25 00 00 00 F8 22 22 22 FF B7 B7'
- 'B7 FF DB DB DB FF CA CA CA FF CB CB CB FF CE CE'
- 'CE FF D3 D3 D3 FF D3 D3 D3 FF CF CF CF FF D1 D1'
- 'D1 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF CF CF CF FF D3 D3 D3 FF D3 D3 D3 FF CE CE'
- 'CE FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CE CE CE FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF C4 C4'
- 'C4 FF 6E 6E 6E FF 80 80 80 FF CE CE CE FF FF D4'
- 'D4 FF FF D4 D4 FF FF D4 D4 FF FF D4 D4 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF E6 E6 E6 FF 92 92 92 FF 00 00'
- '00 00 00 00 00 0C 00 00 00 E1 07 07 07 FF 9F 9F'
- '9F FF DD DD DD FF CC CC CC FF CD CD CD FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF C4 C4 C4 FF C4 C4'
- 'C4 FF B3 B3 B3 FF 99 99 99 FF 62 62 62 FF 9E 9E'
- '9E FF C0 C0 C0 FF FF D4 D4 FF FF D4 F0 FF FF D4'
- 'F0 FF FF D4 F0 FF FF D4 F0 FF FF FF FF FF CE CE'
- 'CE FF 9E 9E 9E FF 62 62 62 FF 92 92 92 FF 00 00'
- '00 00 00 00 00 00 00 00 00 B2 00 00 00 FF 83 83'
- '83 FF DD DD DD FF CF CF CF FF D1 D1 D1 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D6 FF D6 D6 D6 FF D5 D5 D5 FF D5 D5 D5 FF DB DB'
+ 'DB FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 80 80 80 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
+ '00 FE 40 40 40 FF D7 D7 D7 FF D2 D2 D2 FF CA CA'
+ 'CA FF CB CB CB FF CA CA CA FF D4 D4 D4 FF E9 E9'
+ 'E9 FF DC DC DC FF D0 D0 D0 FF D1 D1 D1 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
+ 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D1 D1'
+ 'D1 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
+ 'FF FF 99 99 99 FF C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 25 00 00'
+ '00 F8 22 22 22 FF B7 B7 B7 FF DB DB DB FF CA CA'
+ 'CA FF CB CB CB FF CE CE CE FF E4 E4 E4 FF D4 D4'
+ 'D4 FF CF CF CF FF D1 D1 D1 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CD CD'
+ 'CD FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
+ 'CE FF CE CE CE FF 00 FF FF FF 00 FF FF FF CF CF'
+ 'CF FF CF CF CF FF 99 99 99 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
+ '00 E1 07 07 07 FF 9F 9F 9F FF DD DD DD FF CC CC'
+ 'CC FF CD CD CD FF DB DB DB FF D6 D6 D6 FF CE CE'
+ 'CE FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CC CC'
+ 'CC FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
+ 'CA FF CA CA CA FF CA CA CA FF C8 C8 C8 FF CF CF'
+ 'CF FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 B2 00 00 00 FF 83 83 83 FF DD DD DD FF CF CF'
+ 'CF FF D1 D1 D1 FF DB DB DB FF D1 D1 D1 FF D0 D0'
  'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF CF CF CF FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
- 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 FF 00 00'
- '00 FF 7A 7A 7A FF 62 62 62 FF 86 86 86 FF 86 86'
- '86 FF 86 86 86 FF 86 86 86 FF 62 62 62 FF 6E 6E'
- '6E FF 00 00 00 24 00 00 00 0C 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 5F 5F'
- '5F FF DC DC DC FF D1 D1 D1 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
+ 'CF FF C9 C9 C9 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
+ 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C7 C7'
+ 'C7 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 80 00 00 00 FF 5F 5F 5F FF DC DC DC FF D1 D1'
+ 'D1 FF D2 D2 D2 FF D4 D4 D4 FF D1 D1 D1 FF D1 D1'
  'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D3 D3 D3 FF D3 D3'
+ 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
+ 'D1 FF D0 D0 D0 FF C8 C8 C8 FF C3 C3 C3 FF C3 C3'
+ 'C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
+ 'C4 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
+ 'FF FF 09 09 09 FF C0 C0 C0 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 3D 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 4B 00 00 00 FE 41 41 41 FF D8 D8 D8 FF D4 D4'
+ 'D4 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
  'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
  'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
- 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 CF 00 00'
- '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CD CD CD FF C7 C7'
+ 'C7 FF C4 C4 C4 FF C2 C2 C2 FF C1 C1 C1 FF C0 C0'
+ 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2'
+ 'C2 FF C2 C2 C2 FF 00 FF FF FF 00 FF FF FF 99 99'
+ '99 FF 09 09 09 FF 00 00 00 CF C0 C0 C0 FF 00 00'
+ '00 40 00 00 00 0E 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 1A 00 00 00 F2 2C 2C 2C FF CC CC CC FF D6 D6'
+ 'D6 FF D5 D5 D5 FF CC CC CC FF D5 D5 D5 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
+ 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D7 D7 D7 FF D6 D6'
+ 'D6 FF D5 D5 D5 FF D3 D3 D3 FF CF CF CF FF CC CC'
+ 'CC FF C9 C9 C9 FF C6 C6 C6 FF C4 C4 C4 FF C2 C2'
+ 'C2 FF B3 B3 B3 FF BD BD BD FF D0 D0 D0 FF 99 99'
+ '99 FF 09 09 09 FF 00 00 00 CF 00 00 00 3E 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 09 00 00 00 D8 18 18 18 FF B0 B0 B0 FF DB DB'
+ 'DB FF DB DB DB FF D0 D0 D0 FF D2 D2 D2 FF DB DB'
+ 'DB FF D9 D9 D9 FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
+ 'DA FF DA DA DA FF DA DA DA FF DB DB DB FF DB DB'
+ 'DB FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF CF CF'
+ 'CF FF C5 C5 C5 FF CC CC CC FF CA CA CA FF 7A 7A'
+ '7A FF 02 02 02 FF 00 00 00 B8 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 02 00 00 00 BF 08 08 08 FF 97 97 97 FF DC DC'
+ 'DC FF DF DF DF FF DC DC DC FF CE CE CE FF D6 D6'
+ 'D6 FF DE DE DE FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
+ 'DD FF DD DD DD FF DE DE DE FF D8 D8 D8 FF CE CE'
+ 'CE FF DD DD DD FF DC DC DC FF C6 C6 C6 FF 53 53'
+ '53 FF 00 00 00 FF 00 00 00 A0 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 A4 00 00 00 FF 77 77 77 FF D3 D3'
+ 'D3 FF E2 E2 E2 FF E1 E1 E1 FF DE DE DE FF CE CE'
+ 'CE FF D7 D7 D7 FF E1 E1 E1 FF E2 E2 E2 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
+ 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
+ 'E1 FF E1 E1 E1 FF D9 D9 D9 FF CD CD CD FF DA DA'
+ 'DA FF E3 E3 E3 FF D9 D9 D9 FF BB BB BB FF 39 39'
+ '39 FF 00 00 00 FF 00 00 00 7E 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 89 00 00 00 FF 4B 4B 4B FF C9 C9'
+ 'C9 FF E5 E5 E5 FF E3 E3 E3 FF E4 E4 E4 FF E1 E1'
+ 'E1 FF D7 D7 D7 FF D2 D2 D2 FF DA DA DA FF E4 E4'
+ 'E4 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF DC DC'
+ 'DC FF D2 D2 D2 FF D6 D6 D6 FF E0 E0 E0 FF E4 E4'
+ 'E4 FF E6 E6 E6 FF D6 D6 D6 FF A8 A8 A8 FF 20 20'
+ '20 FF 00 00 00 FD 00 00 00 4E 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 62 00 00 00 FF 35 35 35 FF BD BD'
+ 'BD FF E6 E6 E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7'
+ 'E7 FF E7 E7 E7 FF DF DF DF FF D2 D2 D2 FF D3 D3'
+ 'D3 FF DE DE DE FF E3 E3 E3 FF E3 E3 E3 FF E4 E4'
+ 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3'
+ 'E3 FF E3 E3 E3 FF DE DE DE FF D4 D4 D4 FF D1 D1'
+ 'D1 FF DD DD DD FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
+ 'E6 FF E8 E8 E8 FF D4 D4 D4 FF 9A 9A 9A FF 0B 0B'
+ '0B FF 00 00 00 ED 00 00 00 2C 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 2D 00 00 00 F9 1E 1E 1E FF AB AB'
+ 'AB FF E4 E4 E4 FF ED ED ED FF E7 E7 E7 FF E6 E6'
+ 'E6 FF EC EC EC FF EB EB EB FF EA EA EA FF E4 E4'
+ 'E4 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DD DD'
+ 'DD FF DC DC DC FF DC DC DC FF DD DD DD FF DF DF'
+ 'DF FF DF DF DF FF DF DF DF FF E2 E2 E2 FF E9 E9'
+ 'E9 FF EC EC EC FF EA EA EA FF E5 E5 E5 FF EB EB'
+ 'EB FF EB EB EB FF D6 D6 D6 FF 8A 8A 8A FF 00 00'
+ '00 FF 00 00 00 C3 00 00 00 17 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 09 00 00 00 DD 08 08 08 FF 99 99'
+ '99 FF E4 E4 E4 FF DF DF DF FF BD BD BD FF C1 C1'
+ 'C1 FF D6 D6 D6 FF EC EC EC FF ED ED ED FF ED ED'
+ 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EC EC'
+ 'EC FF EB EB EB FF EB EB EB FF EC EC EC FF ED ED'
+ 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EE EE'
+ 'EE FF E4 E4 E4 FF C2 C2 C2 FF BE BE BE FF D1 D1'
+ 'D1 FF EC EC EC FF D4 D4 D4 FF 75 75 75 FF 00 00'
+ '00 FF 00 00 00 9C 00 00 00 06 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 AE 00 00 00 FF 8D 8D'
+ '8D FF E0 E0 E0 FF C4 C4 C4 FF B2 B2 B2 FF B8 B8'
+ 'B8 FF B2 B2 B2 FF EB EB EB FF F1 F1 F1 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
+ 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3'
+ 'F3 FF D5 D5 D5 FF B0 B0 B0 FF B6 B6 B6 FF B7 B7'
+ 'B7 FF EB EB EB FF CD CD CD FF 61 61 61 FF 00 00'
+ '00 FF 00 00 00 85 00 00 00 01 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 64 64'
+ '64 FF CE CE CE FF DD DD DD FF DC DC DC FF D5 D5'
+ 'D5 FF E4 E4 E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
+ 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
+ 'FA FF F2 F2 F2 FF DF DF DF FF D8 D8 D8 FF DC DC'
+ 'DC FF D7 D7 D7 FF B0 B0 B0 FF 34 34 34 FF 00 00'
+ '00 FF 00 00 00 67 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 44 00 00 00 FF 19 19'
+ '19 FF 80 80 80 FF BE BE BE FF D3 D3 D3 FF D7 D7'
+ 'D7 FF DB DB DB FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
+ 'D8 FF D9 D9 D9 FF D9 D9 D9 FF D7 D7 D7 FF CD CD'
+ 'CD FF B0 B0 B0 FF 5D 5D 5D FF 06 06 06 FF 00 00'
+ '00 ED 00 00 00 2B 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 02 00 00 00 9C 00 00'
+ '00 FF 0C 0C 0C FF 3D 3D 3D FF 49 49 49 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
+ '48 FF 48 48 48 FF 48 48 48 FF 49 49 49 FF 49 49'
+ '49 FF 2F 2F 2F FF 02 02 02 FF 00 00 00 FF 00 00'
+ '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00'
+ '00 7F 00 00 00 F1 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 D6 00 00 00 5C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 2C 00 00 00 7E 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
+ '00 84 00 00 00 70 00 00 00 1A 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF 80 7F FF 00 00 FF FF'
+ 'FF 00 7F FF 00 00 FF FF FE 00 0F FF 00 00 FF FF'
+ 'FC 00 07 FF 00 00 FF FF F8 00 07 FF 00 00 FF FF'
+ 'F0 00 07 FF 00 00 FF FF E0 00 84 FF 00 00 F0 00'
+ '00 00 04 7F 00 00 C0 00 00 00 00 7F 00 00 80 00'
+ '00 00 00 7F 00 00 80 00 00 00 00 0F 00 00 00 00'
+ '00 00 00 07 00 00 00 00 00 00 00 07 00 00 00 00'
+ '00 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
+ '00 00 00 01 00 00 80 00 00 00 00 03 00 00 80 00'
+ '00 00 00 07 00 00 80 00 00 00 00 0F 00 00 80 00'
+ '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 C0 00'
+ '00 00 00 7F 00 00 C0 00 00 00 00 FF 00 00 C0 00'
+ '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
+ '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
+ '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
+ '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
+ '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0C 00 00 00 3C 80 80 80 FF 80 80 80 FF 00 00'
+ '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
+ '00 3C 80 80 80 FF 00 00 00 FF 80 80 80 FF 80 80'
+ '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 0C 00 00 00 3C 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
+ '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
+ '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0C 00 00 00 3C 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
+ '00 3C 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 24 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
+ '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
+ '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 0C 00 00 00 24 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 24 00 00 00 6C 80 80 80 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
+ '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
+ '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
+ '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 FF'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
+ '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
+ '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
+ '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
+ '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 4B 00 00 00 FE 41 41'
- '41 FF D8 D8 D8 FF D4 D4 D4 FF D2 D2 D2 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF B3 B3'
- 'B3 FF B3 B3 B3 FF 99 99 99 FF 00 00 00 CF 00 00'
- '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1A 00 00 00 F2 2C 2C'
- '2C FF CC CC CC FF D6 D6 D6 FF D5 D5 D5 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF C4 C4 C4 FF D3 D3 D3 FF BD BD'
- 'BD FF D0 D0 D0 FF 99 99 99 FF 09 09 09 FF 00 00'
- '00 CF 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 80 80 80 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 D8 18 18'
- '18 FF B0 B0 B0 FF DB DB DB FF DB DB DB FF DE DE'
- 'DE FF DE DE DE FF DE DE DE FF D9 D9 D9 FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DA DA DA FF DD DD'
- 'DD FF DD DD DD FF E7 E7 E7 FF D9 D9 D9 FF CC CC'
- 'CC FF CA CA CA FF 7A 7A 7A FF 02 02 02 FF 00 00'
- '00 B8 00 00 00 0A 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
+ '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 BF 08 08'
- '08 FF 97 97 97 FF DC DC DC FF DF DF DF FF DC DC'
- 'DC FF DE DE DE FF DE DE DE FF DE DE DE FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF DD DD DD FF DC DC'
- 'DC FF C6 C6 C6 FF 53 53 53 FF 00 00 00 FF 00 00'
- '00 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
+ '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 00 00'
- '00 FF 77 77 77 FF D3 D3 D3 FF E2 E2 E2 FF E1 E1'
- 'E1 FF DE DE DE FF DE DE DE FF DE DE DE FF DE DE'
- 'DE FF DE DE DE FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E1 E1 E1 FF E1 E1 E1 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E7 E7 E7 FF E3 E3 E3 FF D9 D9'
- 'D9 FF BB BB BB FF 39 39 39 FF 00 00 00 FF 00 00'
- '00 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 89 00 00'
- '00 FF 4B 4B 4B FF C9 C9 C9 FF E5 E5 E5 FF E3 E3'
- 'E3 FF E4 E4 E4 FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E5 E5'
- 'E5 FF E5 E5 E5 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E4 E4 E4 FF E6 E6 E6 FF D6 D6'
- 'D6 FF A8 A8 A8 FF 20 20 20 FF 00 00 00 FD 00 00'
- '00 4E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 62 00 00'
- '00 FF 35 35 35 FF BD BD BD FF E6 E6 E6 FF E6 E6'
- 'E6 FF E6 E6 E6 FF E7 E7 E7 FF E7 E7 E7 FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF E7 E7 E7 FF E7 E7 E7 FF E7 E7 E7 FF E7 E7'
- 'E7 FF E7 E7 E7 FF E6 E6 E6 FF E8 E8 E8 FF D4 D4'
- 'D4 FF 9A 9A 9A FF 0B 0B 0B FF 00 00 00 ED 00 00'
- '00 2C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
+ '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2D 00 00'
- '00 F9 1E 1E 1E FF AB AB AB FF E4 E4 E4 FF ED ED'
- 'ED FF E7 E7 E7 FF E6 E6 E6 FF EC EC EC FF EB EB'
- 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EB EB EB FF EB EB'
- 'EB FF EB EB EB FF EB EB EB FF EC EC EC FF EA EA'
- 'EA FF E5 E5 E5 FF EB EB EB FF EB EB EB FF D6 D6'
- 'D6 FF 8A 8A 8A FF 00 00 00 FF 00 00 00 C3 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 09 00 00'
- '00 DD 08 08 08 FF 99 99 99 FF E4 E4 E4 FF DF DF'
- 'DF FF BD BD BD FF C1 C1 C1 FF D6 D6 D6 FF EC EC'
- 'EC FF ED ED ED FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EC EC EC FF EB EB EB FF EB EB'
- 'EB FF EC EC EC FF ED ED ED FF EE EE EE FF EE EE'
- 'EE FF ED ED ED FF EE EE EE FF E4 E4 E4 FF C2 C2'
- 'C2 FF BE BE BE FF D1 D1 D1 FF EC EC EC FF D4 D4'
- 'D4 FF 75 75 75 FF 00 00 00 FF 00 00 00 9C 00 00'
- '00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 AE 00 00 00 FF 8D 8D 8D FF E0 E0 E0 FF C4 C4'
- 'C4 FF B2 B2 B2 FF B8 B8 B8 FF B2 B2 B2 FF EB EB'
- 'EB FF F1 F1 F1 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F3 F3 F3 FF D5 D5 D5 FF B0 B0'
- 'B0 FF B6 B6 B6 FF B7 B7 B7 FF EB EB EB FF CD CD'
- 'CD FF 61 61 61 FF 00 00 00 FF 00 00 00 85 00 00'
- '00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
+ '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
+ 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 64 64 64 FF CE CE CE FF DD DD'
- 'DD FF DC DC DC FF D5 D5 D5 FF E4 E4 E4 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF FA FA FA FF F2 F2 F2 FF DF DF'
- 'DF FF D8 D8 D8 FF DC DC DC FF D7 D7 D7 FF B0 B0'
- 'B0 FF 34 34 34 FF 00 00 00 FF 00 00 00 67 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
+ '00 3C C0 C0 C0 FF 00 00 00 FF C0 C0 C0 FF 00 00'
+ '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 44 00 00 00 FF 19 19 19 FF 80 80 80 FF BE BE'
- 'BE FF D3 D3 D3 FF D7 D7 D7 FF DB DB DB FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D7 D7 D7 FF CD CD CD FF B0 B0 B0 FF 5D 5D'
- '5D FF 06 06 06 FF 00 00 00 ED 00 00 00 2B 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
+ '00 0C 00 00 00 00 C0 C0 C0 FF 00 00 00 18 00 00'
+ '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00'
+ '3F FF FE 00 07 FF FC 00 03 FF F8 00 03 FF F0 00'
+ '03 FF E0 00 00 7F C0 00 00 3F C0 00 00 3F C0 00'
+ '00 3F C0 00 00 07 00 00 00 03 00 00 00 03 00 00'
+ '00 03 00 00 00 00 00 00 00 00 80 00 00 00 F0 00'
+ '00 00 F0 00 00 00 F0 00 00 00 F8 00 00 00 FF 00'
+ '00 00 FF 00 00 00 FF 00 00 00 FF 80 00 00 FF F0'
+ '00 00 FF F0 00 01 FF F0 00 03 FF F8 00 07 FF FF'
+ '00 0F FF FF 00 1F FF FF 00 3F FF FF 84 7F'
+} */
+
+
+
+/* BINRES mycomputer.ico */
+15 ICON mycomputer.ico
+/*{
+ '00 00 01 00 0C 00 10 10 10 00 00 00 00 00 28 01'
+ '00 00 C6 00 00 00 10 10 00 00 00 00 00 00 68 05'
+ '00 00 EE 01 00 00 10 10 00 00 00 00 00 00 68 04'
+ '00 00 56 07 00 00 20 20 10 00 00 00 00 00 E8 02'
+ '00 00 BE 0B 00 00 20 20 00 00 00 00 00 00 A8 08'
+ '00 00 A6 0E 00 00 20 20 00 00 00 00 00 00 A8 10'
+ '00 00 4E 17 00 00 30 30 10 00 00 00 00 00 68 06'
+ '00 00 F6 27 00 00 30 30 00 00 00 00 00 00 A8 0E'
+ '00 00 5E 2E 00 00 30 30 00 00 00 00 00 00 A8 25'
+ '00 00 06 3D 00 00 40 40 10 00 00 00 00 00 68 0A'
+ '00 00 AE 62 00 00 40 40 00 00 00 00 00 00 28 16'
+ '00 00 16 6D 00 00 40 40 00 00 00 00 00 00 28 42'
+ '00 00 3E 83 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 70 70 70 70 00 00 00 07 07'
+ '07 07 07 77 77 77 00 70 00 77 70 07 07 77 00 70'
+ '00 00 00 07 77 77 87 A7 87 77 77 07 A7 77 76 66'
+ '66 66 67 07 00 07 76 66 66 66 67 07 00 07 76 66'
+ '66 66 67 07 00 07 76 66 66 66 67 07 00 07 76 66'
+ '66 66 67 08 00 07 76 66 66 66 67 08 00 07 76 66'
+ '66 66 67 08 00 07 76 66 66 77 77 08 77 77 77 78'
+ '88 88 87 78 88 88 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 C0 7F 00 00 80 00 00 00 C0 00 00 00 C0 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 FF FF 00 00 28 00'
+ '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
+ '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 0C 0C 0C 00 14 14 14 00 16 16'
+ '16 00 1D 1D 1D 00 28 28 28 00 29 29 29 00 2A 2A'
+ '2A 00 2B 2B 2B 00 2D 2D 2D 00 39 39 39 00 3A 3A'
+ '3A 00 3B 3B 3B 00 3C 3C 3C 00 3E 3E 3E 00 3F 3F'
+ '3F 00 74 46 00 00 75 46 00 00 75 47 00 00 76 47'
+ '00 00 7B 4E 03 00 79 4D 04 00 7F 50 03 00 7F 51'
+ '04 00 40 40 40 00 41 41 41 00 42 42 42 00 44 44'
+ '44 00 45 45 45 00 46 46 46 00 48 48 48 00 49 49'
+ '49 00 4A 4A 4A 00 4B 4B 4B 00 4D 4D 4D 00 4F 4F'
+ '4F 00 50 50 50 00 51 51 51 00 53 53 53 00 55 55'
+ '55 00 56 56 56 00 57 57 57 00 58 58 58 00 59 59'
+ '59 00 5A 5A 5A 00 5C 5C 5C 00 5D 5D 5D 00 5E 5E'
+ '5E 00 6A 64 5A 00 6D 68 5F 00 7E 73 5E 00 61 61'
+ '61 00 62 62 62 00 61 65 61 00 64 64 64 00 65 65'
+ '65 00 66 66 66 00 67 67 67 00 6A 6A 6A 00 71 6C'
+ '65 00 75 71 69 00 71 71 71 00 72 72 72 00 74 74'
+ '74 00 75 75 75 00 76 76 76 00 77 77 77 00 7D 79'
+ '73 00 7C 7B 73 00 7B 79 75 00 79 79 79 00 7B 7B'
+ '7B 00 7F 7F 7F 00 80 52 04 00 80 52 05 00 81 54'
+ '06 00 81 55 07 00 83 57 07 00 82 57 08 00 82 59'
+ '0B 00 84 58 08 00 84 59 09 00 85 59 09 00 86 5A'
+ '09 00 86 5B 0A 00 87 5B 0A 00 84 5B 0C 00 88 5D'
+ '0B 00 89 5F 0C 00 8A 60 0D 00 8B 62 0E 00 8C 63'
+ '0F 00 8E 65 10 00 8F 66 11 00 8F 67 11 00 89 68'
+ '1B 00 90 69 12 00 91 6A 13 00 90 6B 16 00 95 6F'
+ '16 00 99 74 1A 00 9A 76 1A 00 9B 76 1B 00 9E 7B'
+ '1E 00 8A 70 3F 00 82 77 62 00 80 79 6C 00 8B 7F'
+ '6A 00 7B BA 71 00 9A 82 3B 00 A2 80 21 00 A7 87'
+ '26 00 A8 89 27 00 A9 8A 27 00 AD 8F 2B 00 AD 90'
+ '2C 00 B6 9B 34 00 B7 9D 35 00 B8 9E 36 00 BD A6'
+ '3C 00 9B 85 55 00 9C 96 6F 00 91 86 74 00 97 92'
+ '72 00 9E 91 7C 00 A2 90 60 00 A1 92 64 00 A1 96'
+ '6B 00 B2 A1 62 00 C4 AF 41 00 C7 B4 45 00 CB B9'
+ '4A 00 D0 C0 4F 00 FF 00 FF 00 81 81 81 00 86 86'
+ '86 00 8A 8A 8A 00 8B 8B 8B 00 8C 8C 8C 00 8D 8D'
+ '8D 00 92 8E 89 00 91 91 91 00 92 92 92 00 99 97'
+ '91 00 99 97 92 00 99 99 99 00 9A 9A 9A 00 9F 9F'
+ '9F 00 A7 9B 80 00 A5 9F 96 00 B2 A6 88 00 B0 A4'
+ '8C 00 B5 B0 87 00 A4 A4 A4 00 A8 A8 A8 00 AD AE'
+ 'AA 00 AD AD AD 00 AE AE AE 00 B8 B6 B4 00 BA BA'
+ 'BA 00 C3 B9 83 00 C1 C1 C1 00 C6 C6 C6 00 C9 C9'
+ 'C9 00 CF CF CF 00 D0 D0 D0 00 D2 D2 D2 00 D9 D9'
+ 'D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 9C 00 00 00 FF 0C 0C 0C FF 3D 3D'
- '3D FF 49 49 49 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 49 49 49 FF 49 49 49 FF 2F 2F 2F FF 02 02'
- '02 FF 00 00 00 FF 00 00 00 5C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 06 00 00 00 7F 00 00 00 F1 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 D6 00 00 00 5C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2C 00 00'
- '00 7E 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 70 00 00'
- '00 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 A7 A7 A7 A7 A7 A7 A7 A7 A7 A7'
+ 'A7 A7 A7 A7 A7 A7 A7 A7 29 29 29 29 40 8A 8A A7'
+ 'A7 A7 A7 A7 A7 A7 A7 40 1C 1F 27 29 33 33 39 39'
+ '27 40 29 40 46 91 A7 A7 46 02 03 07 27 1C 1F 07'
+ '09 40 09 1C 1C 33 A7 A7 91 02 07 A6 07 07 07 07'
+ '1C 85 33 28 29 46 9A 6B 95 93 96 7B 6A 31 31 69'
+ '1F 8A 6B 40 46 91 8F 61 61 59 50 4B 4B 50 50 67'
+ '1F 8A 09 09 09 46 8F 50 50 50 50 50 59 5B 61 77'
+ '1C 8C 09 1C 1C 46 8B 14 4B 4B 56 61 61 65 66 7C'
+ '09 91 1C 1C 1C 85 42 11 15 50 5C 65 6D 70 71 7D'
+ '1C 91 17 1F 1F 8A 3B 11 4B 56 61 6D 71 74 76 7E'
+ '1C 98 1C 27 27 85 3A 11 4B 59 65 6E 74 80 82 78'
+ '1D 99 1F 27 29 8C 30 11 15 59 65 70 74 81 83 7A'
+ '1D 9A 27 29 33 8C 2F 11 14 50 5E 6C 7F 9F 97 42'
+ '1F 9A 27 29 33 8A 42 79 94 9D A3 A5 A3 A0 A0 8A'
+ '40 A1 9A A1 A5 A6 A7 A7 A7 A7 A7 A7 A7 A7 A7 A7'
+ 'A7 A7 A7 A7 A7 A7 FF FF 00 00 C0 7F 00 00 80 00'
+ '00 00 C0 00 00 00 C4 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 FF FF 00 00 28 00 00 00 10 00 00 00 20 00'
+ '00 00 01 00 20 00 00 00 00 00 40 04 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 59 59 59 25 4F 4F 4F EB 45 45 45 CE 50 50'
+ '50 AC 61 61 61 8A 62 62 62 68 60 60 60 45 6D 6D'
+ '6D 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 57 57 57 B1 46 46 46 FE 4A 4A 4A FF 55 55'
+ '55 FF 57 57 57 FF 62 62 62 FF 66 66 66 FF 6A 6A'
+ '6A FF 63 63 63 F5 3A 3A 3A CC 75 75 75 FC 52 52'
+ '52 EC 5E 5E 5E CA 58 58 58 A8 71 71 71 7C 00 00'
+ '00 00 00 00 00 00 5F 5F 5F AB 14 14 14 FF 1D 1D'
+ '1D FF 28 28 28 FA 44 44 44 DC 46 46 46 FF 48 48'
+ '48 FF 29 29 29 FF 3B 3B 3B FF 74 74 74 FF 39 39'
+ '39 FF 45 45 45 FF 44 44 44 FF 62 62 62 F8 00 00'
+ '00 00 00 00 00 00 76 76 76 88 08 08 08 EC 15 15'
+ '15 E2 0B 0B 0B FD 29 29 29 FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2D 2D 2D FF 40 40 40 FF 86 86 86 FF 61 65'
+ '61 FF 59 59 59 FF 5C 5C 5C FF 79 79 79 F8 A8 AA'
+ 'A4 CB 7B BA 71 FF B1 A4 84 ED A5 98 7B ED AE A0'
+ '84 DD 9D 90 7A F8 8B 7F 6A FF 82 77 62 FF 7E 73'
+ '5E FF 80 79 6C FF 4D 4D 4D FF 8C 8C 8C FF 7B BA'
+ '71 FF 71 71 71 FF 79 79 79 FF 98 98 98 F8 95 93'
+ '8D E8 90 6B 16 FF 91 6A 13 FF 8B 62 0E FF 84 59'
+ '09 FF 81 55 07 FF 81 54 06 FF 82 57 08 FF 84 59'
+ '09 FF 8A 70 3F FF 4B 4B 4B FF 8C 8C 8C FF 3A 3A'
+ '3A FF 3E 3E 3E FF 3F 3F 3F FF 73 73 73 F8 95 93'
+ '8D EA 82 59 0B FF 87 5B 0A FF 85 59 09 FF 84 58'
+ '08 FF 86 5B 0A FF 8A 60 0D FF 8E 65 10 FF 90 69'
+ '12 FF 9B 85 55 FF 42 42 42 FF 92 92 92 FF 3C 3C'
+ '3C FF 42 42 42 FF 42 42 42 FF 79 79 79 F8 8E 8A'
+ '85 ED 79 4D 04 FF 80 52 05 FF 83 57 07 FF 88 5D'
+ '0B FF 8F 67 11 FF 95 6F 16 FF 9B 76 1B FF 9E 7B'
+ '1E FF A2 90 60 FF 3E 3E 3E FF 99 99 99 FF 40 40'
+ '40 FF 45 45 45 FF 48 48 48 FF 7F 7F 7F F8 78 74'
+ '6E EF 75 47 00 FF 7F 50 03 FF 86 5A 09 FF 8F 66'
+ '11 FF 99 74 1A FF A2 80 21 FF A9 8A 27 FF AD 8F'
+ '2B FF A1 92 64 FF 42 42 42 FF 9F 9F 9F FF 41 41'
+ '41 FF 49 49 49 FF 4F 4F 4F FF 84 84 84 F8 70 6C'
+ '64 F0 74 46 00 FF 7F 51 04 FF 89 5F 0C FF 95 6F'
+ '16 FF A2 80 21 FF AD 90 2C FF B7 9D 35 FF BD A6'
+ '3C FF A1 96 6B FF 45 45 45 FF A4 A4 A4 FF 45 45'
+ '45 FF 50 50 50 FF 57 57 57 FF 88 88 88 F8 6D 68'
+ '60 F3 75 46 00 FF 80 52 04 FF 8B 62 0E FF 99 74'
+ '1A FF A7 87 26 FF B6 9B 34 FF C4 AF 41 FF CB B9'
+ '4A FF 9C 96 6F FF 48 48 48 FF A8 A8 A8 FF 4B 4B'
+ '4B FF 56 56 56 FF 5E 5E 5E FF 8C 8C 8C F8 69 64'
+ '5B F4 76 47 00 FF 80 52 05 FF 8C 63 0F FF 9A 76'
+ '1A FF A8 89 27 FF B8 9E 36 FF C7 B4 45 FF D0 C0'
+ '4F FF 97 92 72 FF 49 49 49 FF AD AD AD FF 51 51'
+ '51 FF 5C 5C 5C FF 64 64 64 FF 90 90 90 F8 66 60'
+ '55 F4 75 47 00 FF 7B 4E 03 FF 84 5B 0C FF 89 68'
+ '1B FF 9A 82 3B FF B2 A1 62 FF C3 B9 82 FA B5 AF'
+ '85 F6 7C 7B 73 FF 4B 4B 4B FF AE AE AE FF 53 53'
+ '53 FF 5E 5E 5E FF 61 61 61 FF 8A 8A 8A F8 72 70'
+ '6B E1 88 7B 66 D8 99 91 84 B3 B2 AF AB 90 E2 E2'
+ 'E2 6D FF FF FF 4A FF FF FF 23 00 00 00 00 00 00'
+ '00 00 0D 0D 0D 49 47 47 47 9C C7 C7 C7 E0 AA AA'
+ 'AA D0 C1 C1 C1 BE D8 D8 D8 AB EB EB EB 93 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ '00 00 80 7F 00 00 80 00 00 00 C0 00 00 00 C0 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 01 80 00 00 FF FF 00 00 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 04 00 00 00'
+ '00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 70 70 80 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 07 07 07 77 77 77 00 00'
+ '00 00 00 00 00 00 00 00 70 70 70 70 70 70 70 77'
+ '77 77 77 77 78 88 00 07 77 07 77 07 07 07 07 70'
+ '07 77 00 00 00 07 00 00 00 00 00 07 07 77 77 00'
+ '07 77 07 77 70 07 00 00 00 00 00 00 00 00 00 00'
+ '07 77 07 77 70 07 00 00 07 00 00 00 00 00 00 00'
+ '07 77 00 00 00 07 00 00 07 07 77 70 00 00 00 00'
+ '07 77 77 77 77 78 78 A8 88 88 88 88 88 77 77 77'
+ '07 77 7A 77 77 78 78 66 66 66 66 66 66 66 66 67'
+ '07 77 00 00 00 08 78 66 66 66 66 66 66 66 66 67'
+ '07 77 00 00 00 08 78 66 66 66 66 66 66 66 66 67'
+ '07 77 07 77 70 08 78 66 66 66 66 66 66 66 66 67'
+ '07 77 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 67'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 77'
+ '07 87 00 00 00 78 78 66 66 66 66 66 66 66 66 77'
+ '07 87 77 77 77 78 78 66 66 66 66 66 66 66 66 78'
+ '07 87 70 00 07 78 78 66 66 66 66 66 66 66 66 77'
+ '07 87 77 77 77 78 78 66 66 66 66 66 66 67 77 77'
+ '07 87 00 00 00 78 78 66 66 66 66 66 77 78 88 87'
+ '07 87 77 77 77 78 78 66 77 77 88 88 88 80 08 77'
+ '07 88 77 78 88 88 77 78 88 80 00 00 00 00 00 00'
+ '08 88 88 88 88 88 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF F0 7F FF FF F0 00 FF FF E0 00 00 00 E0 00'
+ '00 00 F8 08 00 00 F8 00 00 00 F8 00 00 00 F8 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 01 80 00 01 FF F8 00 FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 0A 0A 0A 00 14 14 14 00 1C 1C 1C 00 23 23'
+ '23 00 25 25 25 00 29 29 29 00 2D 2D 2D 00 30 30'
+ '30 00 32 32 32 00 34 34 34 00 36 36 36 00 38 38'
+ '38 00 3A 3A 3A 00 3C 3C 3C 00 3E 3E 3E 00 78 48'
+ '00 00 7A 4A 00 00 7B 4C 01 00 7B 4D 02 00 7C 4D'
+ '02 00 7C 4E 02 00 7E 4E 02 00 7F 50 03 00 7E 50'
+ '04 00 7F 52 04 00 73 4F 1E 00 77 59 32 00 40 40'
+ '40 00 42 42 42 00 44 44 44 00 46 46 46 00 48 48'
+ '48 00 4A 4A 4A 00 4C 4C 4C 00 4E 4E 4E 00 50 50'
+ '50 00 52 52 52 00 54 54 54 00 56 56 56 00 58 58'
+ '58 00 5A 5A 5A 00 5C 5C 5C 00 5E 5E 5E 00 7C 65'
+ '47 00 7B 6B 54 00 7B 6B 59 00 60 60 60 00 62 62'
+ '62 00 64 64 64 00 66 66 66 00 68 68 68 00 6A 6A'
+ '6A 00 6C 6C 6C 00 6E 6E 6E 00 70 70 70 00 72 72'
+ '72 00 74 74 74 00 76 76 76 00 79 79 79 00 7C 7C'
+ '7C 00 7E 7E 7E 00 80 51 04 00 80 53 05 00 80 53'
+ '06 00 81 54 05 00 80 54 06 00 82 55 07 00 82 56'
+ '07 00 84 58 07 00 83 57 08 00 83 58 08 00 84 58'
+ '08 00 85 59 0A 00 85 5A 0A 00 86 5A 0A 00 87 5C'
+ '0B 00 87 5D 0C 00 89 5E 0B 00 88 5D 0C 00 88 5E'
+ '0C 00 8A 60 0C 00 8A 60 0E 00 8B 62 0E 00 8C 63'
+ '0F 00 8D 64 0E 00 8C 64 10 00 8E 66 11 00 8C 65'
+ '12 00 8F 67 12 00 8F 68 12 00 90 69 13 00 91 6A'
+ '12 00 91 6A 14 00 93 6C 15 00 93 6D 16 00 94 6E'
+ '16 00 95 70 17 00 96 70 16 00 96 70 18 00 97 72'
+ '19 00 99 74 19 00 98 74 1A 00 99 76 1B 00 9A 76'
+ '1B 00 9A 77 1C 00 9C 78 1B 00 9B 78 1C 00 9C 78'
+ '1D 00 9E 7A 1C 00 9D 7A 1E 00 9E 7B 1E 00 9F 7C'
+ '1E 00 8A 6B 22 00 9F 7D 20 00 8E 75 35 00 A0 7F'
+ '21 00 80 6E 56 00 81 71 5B 00 83 73 5C 00 82 74'
+ '5F 00 83 73 61 00 86 76 65 00 89 79 6A 00 8B 7C'
+ '6D 00 8D 7F 6F 00 7B BA 71 00 7C BA 72 00 A1 80'
+ '22 00 A2 81 22 00 A3 82 23 00 A6 84 22 00 A4 84'
+ '24 00 A7 87 26 00 A7 88 27 00 AB 8A 27 00 AA 8B'
+ '29 00 AA 8C 29 00 AB 8E 2B 00 AC 8E 2A 00 AE 91'
+ '2C 00 AF 93 2D 00 AF 93 2E 00 B1 95 2F 00 B1 96'
+ '2F 00 AC 93 35 00 A3 92 3E 00 A7 95 3D 00 AD 98'
+ '3B 00 B2 97 30 00 B3 98 30 00 B4 9A 31 00 B5 9B'
+ '32 00 B6 9D 33 00 B9 A0 35 00 B9 A1 36 00 BA A2'
+ '37 00 BD A5 39 00 BD A6 39 00 BF A8 3A 00 C0 AA'
+ '3C 00 C1 AC 3D 00 C2 AD 3E 00 C3 AE 3E 00 C9 B4'
+ '3F 00 9B 88 52 00 A4 95 47 00 B2 A4 4A 00 8B 80'
+ '6F 00 9B 91 60 00 8F 82 72 00 8B 81 74 00 93 87'
+ '79 00 95 8C 7F 00 A8 9B 70 00 C1 AF 44 00 C5 B1'
+ '40 00 C6 B2 41 00 C9 B5 43 00 C9 B6 43 00 CB B8'
+ '44 00 CD BC 47 00 CF BE 48 00 FF 00 FF 00 81 81'
+ '81 00 82 82 82 00 85 85 85 00 86 86 86 00 88 88'
+ '88 00 8A 8A 8A 00 8C 8C 8C 00 8C 8D 8E 00 8E 8E'
+ '8E 00 98 8E 81 00 91 8E 91 00 8D 90 93 00 8E 90'
+ '94 00 90 90 90 00 93 93 93 00 96 93 90 00 91 93'
+ '97 00 94 94 94 00 96 96 96 00 95 97 9B 00 98 98'
+ '98 00 99 99 9A 00 9D 9A 99 00 98 9A 9E 00 9C 9C'
+ '9C 00 A0 95 89 00 A0 99 90 00 A8 9E 92 00 B4 AB'
+ '8C 00 B0 A7 9A 00 9E 9F A0 00 9D 9E A2 00 A0 A0'
+ 'A0 00 A0 A1 A2 00 A2 A2 A2 00 A4 A4 A4 00 A6 A6'
+ 'A6 00 A8 A9 A8 00 A8 A9 AB 00 AA AA AA 00 AC AC'
+ 'AC 00 AE AE AE 00 B7 AF A1 00 B0 B0 AE 00 BD B6'
+ 'A8 00 BF BB AA 00 B0 B0 B0 00 B2 B2 B2 00 B7 B6'
+ 'B3 00 B4 B4 B4 00 B6 B6 B6 00 BD BB B5 00 BF BC'
+ 'B4 00 B8 B8 B8 00 BA BA BA 00 BC BC BC 00 BE BE'
+ 'BE 00 C1 BB AF 00 C1 BE B6 00 C5 C1 BA 00 C2 C0'
+ 'BC 00 C1 C1 C1 00 C6 C5 C5 00 C6 C6 C6 00 C7 C8'
+ 'CA 00 C8 C8 C8 00 CC CC CC 00 D0 D0 D0 00 D2 D2'
+ 'D2 00 D6 D6 D6 00 D8 DF D7 00 DC DC DC 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 29 29 30 37 BB 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 0C 1F 1F 1F 24 1F 25 29 29 36 3B BB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 1F 1F 0C 1F 1F 24 29 25 25 29 29 30 30 30 29'
+ '36 36 37 29 36 29 24 29 37 BB C6 DC EE F5 00 00'
+ '00 25 24 24 24 24 1F 24 25 25 29 30 30 30 30 36'
+ '25 07 05 1F 37 29 07 36 25 25 25 0C 07 C6 00 00'
+ '00 00 00 05 01 02 03 05 07 1F 00 29 25 25 29 25'
+ '07 07 05 24 3B 29 09 1F 24 24 24 1F 09 C6 00 00'
+ '00 00 00 09 01 01 01 01 01 01 07 05 07 05 07 05'
+ '05 07 07 24 3B 30 09 09 09 07 09 09 09 C6 00 00'
+ '00 00 00 24 01 01 01 01 01 01 07 05 05 07 07 07'
+ '07 07 07 25 BB 37 25 24 1F 0C 0C 09 09 D0 00 00'
+ '00 00 00 36 02 BB 3B 3B 25 01 05 05 07 05 05 07'
+ '07 07 09 25 BB C2 7E BC BB C6 C6 D0 C6 E1 3B FE'
+ '7E F3 EC EB EB EB EB F3 E9 E1 DD D6 CF CB C6 C4'
+ 'C4 BC 24 25 BC BB 37 3B 3B BB BC C5 C6 E9 37 EC'
+ '6D 6D 64 62 5C 55 4E 47 41 17 16 16 16 17 17 17'
+ '41 2D 20 25 C6 36 0C 0C 0C 0C 1F 0C 0C E1 37 E4'
+ '62 5C 5C 59 55 4E 47 47 41 41 41 41 41 41 47 47'
+ '47 79 1F 29 C6 37 0C 0C 0C 0C 0C 1F 0C E1 37 E2'
+ '59 59 55 4E 47 47 47 46 41 46 46 47 47 4E 4E 4E'
+ '59 A8 0C 29 D0 37 0C 1F 0C 1F 09 0C 1F DD 37 D5'
+ '4E 47 47 47 4E 46 47 46 47 47 4E 4E 59 59 59 59'
+ '59 AD 0C 29 D0 3B 0C 0C 1F 1F 1F 1F 1F E1 37 D3'
+ '41 46 41 46 46 46 46 47 4E 59 59 59 59 5C 5F 5F'
+ '66 D2 07 29 DC 3B 1F 0C 1F 0C 1F 1F 1F E9 37 D1'
+ '16 16 17 17 46 41 47 4E 59 59 59 5C 66 66 6E 6E'
+ '6D D0 07 29 DC 3B 0C 1F 1F 1F 1F 1F 1F E9 37 C1'
+ '16 16 16 16 17 47 4E 59 59 5F 66 6E 6E 84 84 84'
+ '84 D0 08 30 DC 3B 1F 1F 0C 1F 1F 24 24 E9 37 AC'
+ '10 10 10 17 47 47 59 59 5F 6D 6E 84 86 86 86 8C'
+ '87 D0 09 30 E1 BB 0C 1F 24 1F 24 24 24 E9 36 AA'
+ '10 10 16 17 47 47 59 5C 6D 6E 86 86 8E 8E 99 99'
+ '86 D6 09 30 E1 BB 1F 1F 1F 24 24 24 25 EE 36 A8'
+ '10 10 16 17 47 59 5D 66 6E 84 86 8E 99 9C 9C 9C'
+ '94 D6 09 30 E1 BB 1F 1F 24 24 24 25 29 EE 36 A8'
+ '10 10 10 44 47 59 5C 66 84 86 8E 99 9C A1 B1 B1'
+ '94 D0 09 30 E9 BB 1F 24 24 25 29 29 30 EE 30 7B'
+ '10 10 16 17 47 5D 5C 6D 74 86 99 99 A1 B1 B4 B4'
+ '93 D8 0C 30 E9 BC 24 24 24 25 29 29 30 F5 30 79'
+ '10 10 16 46 47 5D 5F 6D 84 86 8E 9C A1 B4 B4 B6'
+ '93 DC 09 30 E9 C6 24 24 25 29 30 30 36 EE 30 79'
+ '16 10 16 41 4E 59 5F 66 84 86 99 9B A1 B4 B6 B6'
+ 'A6 CB 0C 30 E9 C6 24 25 29 29 30 30 30 EE 29 77'
+ '10 10 10 41 47 59 5C 6E 80 86 8C 99 A1 A4 AF A7'
+ 'A9 C5 0C 30 E9 C6 24 25 29 30 30 30 36 EE 29 75'
+ '10 10 10 17 47 4E 59 71 73 A5 AE D4 E5 F5 F8 EE'
+ 'DC 29 0C 30 E9 C6 25 29 29 30 36 30 36 EE 29 2E'
+ '1A 1B 2C 77 AA C6 DE EE F8 FC FC F8 F8 00 00 DC'
+ 'BB 29 1F 30 E9 DC 37 3B D0 DC EE F8 FC FF 3B BC'
+ 'D0 DC E3 ED EE 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 DC EE F8 FF FC FF FC FC FC F8 F8 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF F0 7F FF FF F0 00'
+ 'FF FF E0 00 00 00 E0 00 00 00 F8 08 00 00 F8 00'
+ '00 00 F8 00 00 00 F8 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01'
+ '80 00 01 FF F8 00 FF FF FF FF FF FF FF FF 28 00'
+ '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
+ '00 00 80 10 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF FF F0 00 00 00 FF FF FF FF E0 00 00 00 FF FF'
- 'FF FF C0 00 00 00 FF FF FF FF 80 00 00 00 FF FF'
- 'FF FF 00 00 00 00 FF FF FF FE 00 00 00 00 FF FF'
- 'FF FC 00 00 00 00 F0 00 00 00 00 00 00 00 C0 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 00'
- '00 00 00 60 00 00 00 00 00 00 00 20 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 C0 00'
- '00 00 00 01 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
- '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00'
-} */
-
-/* BINRES ramdisk.ico */
-12 ICON ramdisk.ico
-/* {
- '00 00 01 00 07 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 76 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 5E 03 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 C6 08 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 EE 09 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 96 18 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 FE 1E 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 A6 44 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
- '00 00 00 88 00 66 00 00 00 00 00 00 00 00 00 00'
- '00 00 08 08 80 E6 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 08 07 EE 00 00 00 00 00 00 00 00 00 00'
- '00 08 00 08 00 0E 00 60 00 00 00 00 00 00 00 00'
- '00 80 00 80 80 08 00 66 00 00 00 00 00 00 00 00'
- '08 00 08 00 08 00 80 E6 00 00 00 00 00 00 00 00'
- '80 00 80 00 00 80 07 EE 00 00 00 00 00 00 00 08'
- '00 08 00 00 00 08 00 0E 00 60 00 00 00 00 00 80'
- '00 80 00 08 00 00 80 08 00 66 00 00 00 00 00 80'
- '08 00 00 80 80 00 08 00 80 E6 00 00 00 00 00 80'
- '80 00 08 08 08 00 00 80 07 EE 00 00 00 00 00 88'
- '00 00 80 80 80 00 00 08 00 0E 00 60 00 00 66 07'
- '00 00 08 08 00 00 00 00 80 08 00 66 00 00 66 00'
- '70 00 00 80 00 08 00 00 08 00 80 E6 00 00 EE EE'
- '07 00 00 00 00 00 80 00 00 80 07 EE 00 00 0E E0'
- '00 70 00 00 08 00 08 00 00 08 00 0E 00 60 00 00'
- '66 07 00 00 00 80 00 80 00 00 80 08 00 66 00 00'
- '66 00 70 00 00 08 00 08 00 00 08 00 80 E6 00 00'
- 'EE EE 07 00 00 00 80 00 80 00 00 80 07 EE 00 00'
- '0E E0 00 70 00 00 08 00 00 00 00 08 00 0E 00 00'
- '00 00 66 07 00 00 00 80 00 00 00 00 80 08 00 00'
- '00 00 66 00 70 00 00 00 08 88 00 00 08 08 00 00'
- '00 00 EE EE 07 00 00 00 80 80 80 00 00 87 00 00'
- '00 00 0E E0 00 70 00 00 88 08 80 00 00 70 00 00'
- '00 00 00 00 66 07 00 00 80 80 80 00 07 00 00 00'
- '00 00 00 00 66 00 70 00 08 88 00 00 70 00 00 00'
- '00 00 00 00 EE EE 07 00 00 00 00 07 00 00 00 00'
- '00 00 00 00 0E E0 00 70 00 00 00 70 00 00 00 00'
- '00 00 00 00 00 00 66 07 00 00 07 00 00 00 00 00'
- '00 00 00 00 00 00 66 00 70 00 70 00 00 00 00 00'
- '00 00 00 00 00 00 EE EE 07 07 00 00 00 00 00 00'
- '00 00 00 00 00 00 0E E0 00 70 00 00 00 00 FF CC'
- 'FF FF FF 84 FF FF FF 00 FF FF FE 00 DF FF FC 00'
- 'CF FF F8 00 4F FF F0 00 0F FF E0 00 0D FF C0 00'
- '0C FF C0 00 04 FF C0 00 00 FF C0 00 00 DF 00 00'
- '00 CF 00 00 00 4F 08 00 00 0F 9C 00 00 0D F0 00'
- '00 0C F0 00 00 04 F0 80 00 00 F9 C0 00 00 FF 00'
- '00 00 FF 00 00 00 FF 08 00 00 FF 9C 00 01 FF F0'
- '00 03 FF F0 00 07 FF F0 80 0F FF F9 C0 1F FF FF'
- '00 3F FF FF 00 7F FF FF 08 FF FF FF 9D FF 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 1C 04 04 00 18 18'
- '18 00 1A 1A 1A 00 1C 1C 1C 00 36 0E 0E 00 3C 14'
- '14 00 34 1C 1C 00 20 20 20 00 24 24 24 00 28 28'
- '28 00 30 30 30 00 38 38 38 00 3C 3C 3C 00 40 28'
- '28 00 46 46 46 00 48 48 48 00 4C 4C 4C 00 50 50'
- '50 00 52 52 52 00 54 54 54 00 56 56 56 00 58 58'
- '58 00 68 68 68 00 74 74 74 00 78 78 78 00 7E 7E'
- '7E 00 7F 7F 7F 00 00 92 92 00 00 9C 9C 00 00 BC'
- 'BC 00 00 C0 C0 00 00 D0 D0 00 00 DF DF 00 00 E3'
- 'E3 00 00 E5 E5 00 00 F7 F7 00 00 FB FB 00 00 FF'
- 'FF 00 90 90 90 00 A8 A8 A8 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
- '95 00 00 00 38 00 A8 44 F9 77 11 00 00 00 B8 09'
- '38 00 00 00 38 00 70 63 0C 01 98 17 95 00 00 00'
- '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
- 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 76 00'
- '00 00 76 00 00 00 07 00 00 00 B0 18 95 00 00 00'
- '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
- '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 5A 5A 5A 11 4B 4B 4B DD 48 48 48 D4 38 38'
+ '38 B3 34 34 34 92 3D 3D 3D 70 47 47 47 4F 48 48'
+ '48 2E 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 58 00'
- '5A 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
- '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
- '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
- 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
- '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 58 00 00 00 00 00 00 00 03 00'
- '00 00 60 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 72'
- '61 6D 64 69 73 6B 2E 69 63 6F 00 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 11 00 00 00 88 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 70 63 0C 01 76 00 00 00 00 00'
- '00 00 C9 F1 E7 77 76 00 00 00 A4 1A 95 00 07 00'
- '00 00 00 00 00 00 76 00 00 00 76 00 00 00 07 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 70 63 0C 01 76 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 18 00 1F 00 00'
- '00 00 00 00 00 00 00 00 00 00 04 0F 07 26 00 00'
- '00 00 00 00 00 00 00 00 00 08 08 04 13 01 00 20'
- '00 00 00 00 00 00 00 00 08 08 0A 29 29 15 07 26'
- '00 00 00 00 00 00 00 11 04 0A 29 29 29 29 15 01'
- '00 20 00 00 00 00 00 1A 03 29 0B 29 29 29 29 15'
- '07 26 00 00 00 00 1C 05 0C 29 29 0B 29 29 29 29'
- '15 01 00 20 00 00 21 25 00 0D 29 29 0B 29 29 29'
- '29 15 07 26 00 00 00 00 1D 06 0D 29 29 16 12 29'
- '29 29 15 01 00 1E 00 00 24 25 00 0D 29 29 14 09'
- '29 29 29 15 07 23 00 00 00 00 1D 06 0D 29 29 0A'
- '02 12 29 29 13 0E 00 00 00 00 24 25 00 0D 29 29'
- '19 17 12 29 29 28 00 00 00 00 00 00 1D 06 0D 29'
- '10 19 04 29 27 00 00 00 00 00 00 00 24 25 00 0D'
- '29 29 29 27 00 00 00 00 00 00 00 00 00 00 1D 06'
- '0D 29 27 00 00 00 00 00 00 00 00 00 00 00 21 22'
- '00 1A 00 00 00 00 FA FF 00 00 F0 FF 00 00 E0 BF'
- '00 00 C0 3F 00 00 80 2F 00 00 80 0F 00 00 00 0B'
- '00 00 20 03 00 00 C0 02 00 00 C8 00 00 00 F0 00'
- '00 00 F2 00 00 00 FC 01 00 00 FC 83 00 00 FF 07'
- '00 00 FF 2F 00 00 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 04 00 00 00 00 00 80 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
- '08 0E 00 00 00 00 00 00 08 0E 00 00 00 00 00 00'
- '00 80 0E 00 00 00 00 00 00 08 0E 00 00 00 08 00'
- '00 00 80 0E 00 00 08 00 00 00 08 0E 00 00 60 00'
- '00 00 00 80 0E 00 EE 00 00 00 00 08 0E 00 00 60'
- '00 08 80 00 80 06 00 EE 00 00 80 00 08 0E 00 00'
- '60 00 00 08 00 80 00 00 EE 00 00 88 80 07 00 00'
- '00 60 00 88 00 80 00 00 00 EE 00 00 08 00 00 00'
- '00 00 60 00 80 00 00 00 00 00 EE 08 00 00 FA FF'
- '00 00 F0 FF 00 00 E0 BF 00 00 C0 3F 00 00 80 2F'
- '00 00 80 0F 00 00 00 0B 00 00 20 03 00 00 C0 02'
- '00 00 C8 00 00 00 F0 00 00 00 F2 00 00 00 FC 01'
- '00 00 FC 83 00 00 FF 07 00 00 FF 2F 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
- '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 01 01 00 02 02'
- '02 00 05 05 05 00 06 06 06 00 07 07 07 00 08 08'
- '08 00 09 09 09 00 0B 0B 0B 00 0C 0C 0C 00 18 18'
- '18 00 19 19 19 00 1E 1E 1E 00 1F 1F 1F 00 20 20'
- '20 00 21 21 21 00 22 22 22 00 24 24 24 00 26 26'
- '26 00 27 27 27 00 28 28 28 00 29 29 29 00 2B 2B'
- '2B 00 2C 2C 2C 00 2F 2F 2F 00 34 34 34 00 35 35'
- '35 00 39 39 39 00 3B 3B 3B 00 3D 3D 3D 00 3F 3F'
- '3F 00 40 40 40 00 41 41 41 00 47 47 47 00 48 48'
- '48 00 49 49 49 00 4B 4B 4B 00 53 53 53 00 56 56'
- '56 00 59 59 59 00 5D 5D 5D 00 5F 5F 5F 00 61 61'
- '61 00 64 64 64 00 68 68 68 00 6A 6A 6A 00 6C 6C'
- '6C 00 70 70 70 00 71 71 71 00 72 72 72 00 74 74'
- '74 00 75 75 75 00 77 77 77 00 78 78 78 00 79 79'
- '79 00 7A 7A 7A 00 7D 7D 7D 00 7E 7E 7E 00 7F 7F'
- '7F 00 00 80 80 00 00 FF FF 00 80 80 80 00 81 81'
- '81 00 83 83 83 00 85 85 85 00 87 87 87 00 88 88'
- '88 00 8A 8A 8A 00 8D 8D 8D 00 8E 8E 8E 00 8F 8F'
- '8F 00 90 90 90 00 92 92 92 00 93 93 93 00 97 97'
- '97 00 98 98 98 00 99 99 99 00 9A 9A 9A 00 9C 9C'
- '9C 00 9D 9D 9D 00 9F 9F 9F 00 A0 A0 A0 00 A2 A2'
- 'A2 00 A4 A4 A4 00 A5 A5 A5 00 A7 A7 A7 00 A8 A8'
- 'A8 00 A9 A9 A9 00 AB AB AB 00 AD AD AD 00 AE AE'
- 'AE 00 B0 B0 B0 00 B2 B2 B2 00 B3 B3 B3 00 B6 B6'
- 'B6 00 B7 B7 B7 00 B8 B8 B8 00 B9 B9 B9 00 BA BA'
- 'BA 00 BB BB BB 00 BC BC BC 00 BD BD BD 00 BE BE'
- 'BE 00 BF BF BF 00 C0 C0 C0 00 C1 C1 C1 00 C2 C2'
- 'C2 00 C3 C3 C3 00 C4 C4 C4 00 C5 C5 C5 00 C6 C6'
- 'C6 00 C7 C7 C7 00 C8 C8 C8 00 C9 C9 C9 00 CA CA'
- 'CA 00 CB CB CB 00 CC CC CC 00 CD CD CD 00 CE CE'
- 'CE 00 CF CF CF 00 D0 D0 D0 00 D1 D1 D1 00 D2 D2'
- 'D2 00 D3 D3 D3 00 D4 D4 D4 00 D5 D5 D5 00 D6 D6'
- 'D6 00 D7 D7 D7 00 D8 D8 D8 00 D9 D9 D9 00 DA DA'
- 'DA 00 DB DB DB 00 DC DC DC 00 DD DD DD 00 DE DE'
- 'DE 00 DF DF DF 00 E0 E0 E0 00 E1 E1 E1 00 E2 E2'
- 'E2 00 E3 E3 E3 00 E4 E4 E4 00 E5 E5 E5 00 E6 E6'
- 'E6 00 E7 E7 E7 00 E8 E8 E8 00 E9 E9 E9 00 EA EA'
- 'EA 00 EB EB EB 00 EC EC EC 00 ED ED ED 00 EE EE'
- 'EE 00 EF EF EF 00 F0 F0 F0 00 F1 F1 F1 00 F2 F2'
- 'F2 00 F3 F3 F3 00 F4 F4 F4 00 F5 F5 F5 00 F6 F6'
- 'F6 00 F7 F7 F7 00 F8 F8 F8 00 F9 F9 F9 00 FA FA'
- 'FA 00 FF FF FF 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 58 00 00 00 00 00 00 00 03 00'
- '00 00 60 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 88 36 0C 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 72'
- '61 6D 64 69 73 6B 2E 69 63 6F 00 93 4B 00 14 1A'
- '95 00 1F 3B D4 77 11 00 00 00 88 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 70 63 0C 01 76 00 00 00 00 00'
- '00 00 C9 F1 E7 77 76 00 00 00 A4 1A 95 00 07 00'
- '00 00 00 00 00 00 76 00 00 00 76 00 00 00 07 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 70 63 0C 01 76 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4'
- 'A4 A4 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 47 47 47 8F 39 39 39 FF 45 45 45 FF 46 46'
+ '46 FF 45 45 45 FF 50 50 50 FF 44 44 44 FF 52 52'
+ '52 FF 58 58 58 FD 59 59 59 EA 57 57 57 CA 54 54'
+ '54 A9 54 54 54 88 59 59 59 67 62 62 62 46 60 60'
+ '60 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 70'
+ '70 46 43 43 43 F9 44 44 44 FF 3E 3E 3E FF 3E 3E'
+ '3E FF 46 46 46 FF 51 51 51 FF 5A 5A 5A FF 56 56'
+ '56 FF 55 55 55 FF 58 58 58 FF 5C 5C 5C FF 63 63'
+ '63 FF 64 64 64 FF 64 64 64 FF 5F 5F 5F FF 66 66'
+ '66 FE 65 65 65 E8 2E 2E 2E 89 46 46 46 D5 6E 6E'
+ '6E FE 5D 5D 5D FD 46 46 46 F7 4E 4E 4E DC 54 54'
+ '54 BB 5A 5A 5A 9B 66 66 66 7A 75 75 75 59 A3 A3'
+ 'A3 38 D4 D4 D4 12 00 00 00 00 00 00 00 00 54 54'
+ '54 85 45 45 45 DD 4A 4A 4A F4 4A 4A 4A FF 4E 4E'
+ '4E FF 4D 4D 4D FF 4D 4D 4D FF 4E 4E 4E FF 53 53'
+ '53 FF 56 56 56 FF 5B 5B 5B FF 60 60 60 FF 63 63'
+ '63 FF 61 61 61 FF 63 63 63 FF 69 69 69 FF 5C 5C'
+ '5C FF 2C 2C 2C FF 26 26 26 FF 46 46 46 FF 74 74'
+ '74 FF 5A 5A 5A FF 2E 2E 2E FF 6B 6B 6B FF 53 53'
+ '53 FF 58 58 58 FF 4F 4F 4F FF 3F 3F 3F FF 2E 2E'
+ '2E FF 8C 8C 8C DC 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 87 87 87 5C 2B 2B 2B FF 0B 0B'
+ '0B FF 14 14 14 FF 1C 1C 1C FF 23 23 23 FF 2A 2A'
+ '2A FF 3B 3B 3B EF 6B 6B 6B 95 52 52 52 E9 50 50'
+ '50 FF 55 55 55 FF 5A 5A 5A FF 50 50 50 FF 29 29'
+ '29 FF 29 29 29 FF 29 29 29 FF 4A 4A 4A FF 79 79'
+ '79 FF 5E 5E 5E FF 30 30 30 FF 48 48 48 FF 4F 4F'
+ '4F FF 4D 4D 4D FF 4C 4C 4C FF 43 43 43 FF 34 34'
+ '34 FF 91 91 91 F2 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 97 97 97 3B 38 38 38 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 09 09 09 FC 2B 2B 2B F9 28 28 28 FF 29 29'
+ '29 FF 2B 2B 2B FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B'
+ '2B FF 2C 2C 2C FF 2D 2D 2D FF 4E 4E 4E FF 7E 7E'
+ '7E FF 62 62 62 FF 31 31 31 FF 32 32 32 FF 33 33'
+ '33 FF 33 33 33 FF 34 34 34 FF 35 35 35 FF 35 35'
+ '35 FF 94 94 94 F2 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 B3 B3 B3 1B 4F 4F 4F FE 01 01'
+ '01 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 02 02 02 FF 2E 2E 2E FF 28 28 28 FF 2B 2B'
+ '2B FF 2D 2D 2D FF 2B 2B 2B FF 2C 2C 2C FF 2E 2E'
+ '2E FF 2E 2E 2E FF 2F 2F 2F FF 51 51 51 FF 82 82'
+ '82 FF 75 75 75 FF 52 52 52 FF 4D 4D 4D FF 46 46'
+ '46 FF 3A 3A 3A FF 38 38 38 FF 35 35 35 FF 35 35'
+ '35 FF 96 96 96 F2 AA AA AA 12 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 6A 6A 6A F7 16 16'
+ '16 F4 52 52 52 7F 4C 4C 4C 85 53 53 53 8F 46 46'
+ '46 DE 0A 0A 0A FF 28 28 28 FF 25 25 25 FF 28 28'
+ '28 FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2D 2D 2D FF 31 31 31 FF 53 53 53 FF 87 87'
+ '87 FF 91 8E 91 FF 7B BA 71 FF 8A 8A 8A FF 87 87'
+ '87 FF 90 90 90 FF 98 98 98 FF 98 98 98 FF 8F 8F'
+ '8F FF AE AE AE F2 68 68 68 CA D8 DF D7 FD 7B BA'
+ '71 FC C5 C1 BA FC C1 BE B6 FC BF BC B4 FE BF BC'
+ 'B5 FE BE BB B5 FD BD BB B5 FC C2 C0 BC FC B7 B6'
+ 'B3 FD B0 B0 AE FF A8 A9 A8 FF A0 A1 A2 FF 98 9B'
+ '9E FF 95 97 9B FF 91 93 97 FF 8E 90 94 FF 8D 90'
+ '93 FF 8C 8D 8E FF 4A 4A 4A FF 55 55 55 FF 8B 8B'
+ '8B FF 85 85 85 FF 74 74 74 FF 76 76 76 FF 7A 7A'
+ '7A FF 86 86 86 FF 8D 8D 8D FF 8E 8E 8E FF 99 99'
+ '99 FF B4 B4 B4 F2 5F 5F 5F CC C1 BB AF FF 9E 7A'
+ '1C FF 9C 78 1B FF 99 74 19 FF 96 70 16 FF 91 6A'
+ '12 FF 8D 64 0E FF 89 5E 0B FF 84 58 07 FF 81 54'
+ '05 FF 7F 50 03 FF 7E 4F 03 FF 7E 4E 02 FF 7E 4E'
+ '02 FF 7F 50 03 FF 80 51 04 FF 80 51 05 FF 81 53'
+ '06 FF 7B 6B 54 FF 49 49 49 FF 57 57 57 FF 90 90'
+ '90 FF 6F 6F 6F FF 38 38 38 FF 39 39 39 FF 3A 3A'
+ '3A FF 3B 3B 3B FF 3C 3C 3C FF 3D 3D 3D FF 3C 3C'
+ '3C FF A4 A4 A4 F2 61 61 61 D1 BD B6 A8 FF 95 70'
+ '17 FF 94 6E 16 FF 92 6B 14 FF 8F 67 12 FF 8C 64'
+ '10 FF 89 5F 0D FF 85 5A 0A FF 83 57 08 FF 81 54'
+ '07 FF 80 53 05 FF 80 53 05 FF 80 53 05 FF 81 55'
+ '06 FF 82 56 07 FF 83 57 08 FF 84 58 09 FF 85 5A'
+ '0A FF 82 74 5F FF 44 44 44 FF 58 58 58 FF 94 94'
+ '94 FF 71 71 71 FF 3A 3A 3A FF 3B 3B 3B FF 3C 3C'
+ '3C FF 3D 3D 3D FF 3E 3E 3E FF 3E 3E 3E FF 3F 3F'
+ '3F FF A8 A8 A8 F2 64 64 64 D6 B7 AF A1 FF 8E 66'
+ '11 FF 8D 64 10 FF 8B 63 0F FF 8A 60 0E FF 88 5D'
+ '0C FF 85 5A 0A FF 83 57 08 FF 82 56 07 FF 82 56'
+ '07 FF 82 56 07 FF 83 57 08 FF 84 59 09 FF 86 5A'
+ '0A FF 87 5C 0B FF 88 5E 0C FF 89 5F 0D FF 8A 61'
+ '0E FF 8B 80 6F FF 3E 3E 3E FF 59 59 59 FF 98 98'
+ '98 FF 74 74 74 FF 3B 3B 3B FF 3D 3D 3D FF 3D 3D'
+ '3D FF 3C 3C 3C FF 39 39 39 FF 3D 3D 3D FF 41 41'
+ '41 FF AA AA AA F2 62 62 62 D6 B0 A7 9A FF 87 5C'
+ '0B FF 86 5B 0B FF 85 5A 0A FF 85 59 0A FF 84 59'
+ '09 FF 83 57 08 FF 83 57 08 FF 83 57 08 FF 84 59'
+ '09 FF 85 5A 0A FF 87 5D 0C FF 89 5F 0D FF 8B 62'
+ '0F FF 8D 64 10 FF 8E 66 11 FF 8F 67 12 FF 90 69'
+ '13 FF 95 8C 7F FF 36 36 36 FF 5B 5B 5B FF 9C 9C'
+ '9C FF 77 77 77 FF 3D 3D 3D FF 3D 3D 3D FF 41 41'
+ '41 FF 45 45 45 FF 46 46 46 FF 44 44 44 FF 43 43'
+ '43 FF AD AD AD F2 63 63 63 D7 A8 9E 92 FF 82 55'
+ '07 FF 81 55 06 FF 81 55 06 FF 81 55 07 FF 82 56'
+ '07 FF 82 56 07 FF 83 57 08 FF 85 5A 0A FF 87 5D'
+ '0C FF 8A 60 0E FF 8C 64 10 FF 8F 67 12 FF 91 6A'
+ '14 FF 93 6D 16 FF 95 6F 17 FF 96 70 18 FF 97 73'
+ '19 FF A0 99 90 FF 2D 2D 2D FF 5D 5D 5D FF A0 A0'
+ 'A0 FF 7A 7A 7A FF 3E 3E 3E FF 3F 3F 3F FF 41 41'
+ '41 FF 42 42 42 FF 43 43 43 FF 44 44 44 FF 45 45'
+ '45 FF B3 B3 B3 F2 65 65 65 DB A0 95 89 FF 7D 4F'
+ '03 FF 7D 4F 03 FF 7E 50 04 FF 7E 51 04 FF 80 54'
+ '06 FF 82 56 07 FF 85 59 0A FF 88 5E 0C FF 8C 63'
+ '0F FF 8F 68 12 FF 92 6B 15 FF 95 70 17 FF 98 74'
+ '1A FF 9A 77 1C FF 9C 78 1D FF 9D 7A 1E FF 9F 7C'
+ '1E FF 9F 9B 98 FF 2D 2D 2D FF 5F 5F 5F FF A4 A4'
+ 'A4 FF 7C 7C 7C FF 40 40 40 FF 41 41 41 FF 43 43'
+ '43 FF 44 44 44 FF 45 45 45 FF 48 48 48 FF 4A 4A'
+ '4A FF B5 B5 B5 F2 66 66 66 DE 98 8E 81 FF 7A 4A'
+ '00 FF 7A 4B 01 FF 7C 4E 02 FF 7E 51 04 FF 81 55'
+ '06 FF 84 58 09 FF 88 5E 0C FF 8C 64 10 FF 91 6A'
+ '14 FF 95 6F 17 FF 99 74 1A FF 9C 79 1D FF 9F 7D'
+ '20 FF A1 80 22 FF A3 83 23 FF A4 84 24 FF A6 84'
+ '22 FF 9C 9A 9B FF 30 30 30 FF 60 60 60 FF A7 A7'
+ 'A7 FF 7F 7F 7F FF 41 41 41 FF 43 43 43 FF 44 44'
+ '44 FF 45 45 45 FF 48 48 48 FF 4B 4B 4B FF 4E 4E'
+ '4E FF B7 B7 B7 F2 64 64 64 DF 93 87 79 FF 78 48'
+ '00 FF 79 49 00 FF 7C 4D 02 FF 7E 51 04 FF 82 56'
+ '07 FF 86 5B 0B FF 8B 62 0F FF 90 69 13 FF 95 70'
+ '17 FF 9A 77 1C FF 9F 7D 20 FF A3 82 23 FF A7 87'
+ '26 FF AA 8B 29 FF AC 8E 2A FF AC 8F 2B FF AB 8A'
+ '27 FF 99 9A 9E FF 32 32 32 FF 61 61 61 FF AA AA'
+ 'AA FF 83 83 83 FF 42 42 42 FF 44 44 44 FF 46 46'
+ '46 FF 4A 4A 4A FF 4D 4D 4D FF 4F 4F 4F FF 52 52'
+ '52 FF B9 B9 B9 F2 62 62 62 DF 8F 82 72 FF 78 48'
+ '00 FF 78 48 00 FF 7B 4C 01 FF 7F 52 04 FF 83 58'
+ '08 FF 89 5F 0D FF 8E 66 11 FF 94 6E 16 FF 9A 76'
+ '1B FF 9F 7D 20 FF A4 84 24 FF AA 8C 29 FF AE 91'
+ '2C FF B1 95 2F FF B3 99 31 FF B4 9A 31 FF AB 8E'
+ '2B FF 9D 9E A2 FF 34 34 34 FF 63 63 63 FF AC AC'
+ 'AC FF 85 85 85 FF 44 44 44 FF 46 46 46 FF 49 49'
+ '49 FF 4D 4D 4D FF 50 50 50 FF 54 54 54 FF 57 57'
+ '57 FF BA BA BA F2 61 61 61 E2 8D 7F 6F FF 79 49'
+ '00 FF 78 48 00 FF 7B 4C 01 FF 80 53 05 FF 85 5A'
+ '0A FF 8B 62 0E FF 90 69 13 FF 97 72 19 FF 9E 7B'
+ '1E FF A3 83 23 FF AA 8C 29 FF AF 93 2E FF B5 9B'
+ '32 FF B9 A1 36 FF BD A5 39 FF BD A6 39 FF AC 93'
+ '35 FF 9E 9F A1 FF 35 35 35 FF 63 63 63 FF AE AE'
+ 'AE FF 86 86 86 FF 45 45 45 FF 49 49 49 FF 4D 4D'
+ '4D FF 50 50 50 FF 54 54 54 FF 57 57 57 FF 5A 5A'
+ '5A FF BC BC BC F2 60 60 60 E4 8B 7C 6D FF 79 49'
+ '00 FF 78 48 00 FF 7B 4C 01 FF 80 54 06 FF 86 5B'
+ '0A FF 8C 64 10 FF 93 6D 15 FF 99 76 1B FF A0 7F'
+ '21 FF A7 88 27 FF AE 91 2C FF B5 9B 32 FF BB A3'
+ '37 FF C1 AC 3D FF C5 B1 40 FF C6 B2 41 FF AD 98'
+ '3B FF 9C 9C 9D FF 36 36 36 FF 64 64 64 FF B0 B0'
+ 'B0 FF 88 88 88 FF 48 48 48 FF 4C 4C 4C FF 50 50'
+ '50 FF 55 55 55 FF 58 58 58 FF 5C 5C 5C FF 5F 5F'
+ '5F FF BC BC BC F2 5E 5E 5E E9 89 79 6A FF 79 49'
+ '00 FF 78 48 00 FF 7C 4D 02 FF 81 55 06 FF 87 5C'
+ '0B FF 8D 65 11 FF 94 6E 16 FF 9B 78 1C FF A2 81'
+ '22 FF AA 8C 29 FF B1 96 2F FF B9 A0 35 FF C0 AA'
+ '3C FF C6 B3 41 FF CB B8 44 FF CB B9 45 FF A7 95'
+ '3D FF 9F 9F A0 FF 36 36 36 FF 64 64 64 FF B2 B2'
+ 'B2 FF 8C 8C 8C FF 4B 4B 4B FF 4F 4F 4F FF 53 53'
+ '53 FF 57 57 57 FF 5B 5B 5B FF 5F 5F 5F FF 62 62'
+ '62 FF BE BE BE F2 5B 5B 5B E9 86 76 65 FF 79 49'
+ '00 FF 78 48 00 FF 7C 4D 02 FF 81 55 07 FF 87 5D'
+ '0C FF 8E 66 11 FF 95 6F 17 FF 9C 79 1D FF A3 82'
+ '23 FF AA 8C 29 FF B3 98 30 FF BA A2 37 FF C3 AE'
+ '3E FF C9 B6 43 FF CD BC 47 FF CF BE 48 FF A3 92'
+ '3E FF A2 A2 A2 FF 37 37 37 FF 64 64 64 FF B3 B3'
+ 'B3 FF 90 90 90 FF 4E 4E 4E FF 53 53 53 FF 57 57'
+ '57 FF 5C 5C 5C FF 60 60 60 FF 63 63 63 FF 67 67'
+ '67 FF BE BE BE F2 58 58 58 E9 83 73 61 FF 79 49'
+ '00 FF 78 48 00 FF 7B 4D 02 FF 81 55 06 FF 87 5D'
+ '0B FF 8E 66 11 FF 94 6F 17 FF 9C 79 1D FF A3 82'
+ '23 FF AA 8C 29 FF B2 97 30 FF B9 A1 36 FF C2 AD'
+ '3E FF C9 B5 43 FF CD BC 47 FF CF BE 48 FF A4 95'
+ '47 FF 99 99 9A FF 37 37 37 FF 63 63 63 FF B4 B4'
+ 'B4 FF 93 93 93 FF 51 51 51 FF 55 55 55 FF 5A 5A'
+ '5A FF 5E 5E 5E FF 61 61 61 FF 65 65 65 FF 67 67'
+ '67 FF BF BF BF F2 56 56 56 E9 81 71 5B FF 79 49'
+ '00 FF 78 48 00 FF 7A 4B 01 FF 80 53 06 FF 86 5B'
+ '0A FF 8C 64 10 FF 93 6C 15 FF 9A 76 1B FF A0 7F'
+ '21 FF A7 88 27 FF AF 93 2D FF B6 9D 33 FF BF A8'
+ '3A FF C9 B4 3F FF C1 AF 44 FF B2 A4 4A FF 9B 91'
+ '60 FF 91 91 91 FF 38 38 38 FF 64 64 64 FF B5 B5'
+ 'B5 FF 93 93 93 FF 51 51 51 FF 54 54 54 FF 58 58'
+ '58 FF 5E 5E 5E FF 62 62 62 FF 65 65 65 FF 68 68'
+ '68 FF BE BE BE F2 53 53 53 E9 80 6E 56 FF 79 49'
+ '00 FF 78 48 00 FF 79 49 00 FF 7E 51 04 FF 84 58'
+ '08 FF 8A 60 0C FF 8C 65 12 FF 8A 6B 22 FF 8E 75'
+ '35 FF 9B 88 52 FF A8 9B 70 FF B4 AB 8C FF BF BB'
+ 'AA FE C6 C5 C5 F8 C8 C9 CB EF BA BA BA FE A6 A6'
+ 'A6 FF 5E 5E 5E FF 38 38 38 FF 64 64 64 FF B5 B5'
+ 'B5 FF 91 91 91 FF 59 59 59 FF 59 59 59 FF 5F 5F'
+ '5F FF 64 64 64 FF 68 68 68 FF 68 68 68 FF 6B 6B'
+ '6B FF BD BD BD F2 50 50 50 E9 7B 6B 59 FF 73 4F'
+ '1E FF 77 59 32 FF 7C 65 47 FF 83 73 5C FF 8B 81'
+ '74 FF 96 93 90 FE A7 A8 AA F2 BC BC BC D4 D1 D1'
+ 'D1 B3 DD DD DD 90 E6 E6 E6 69 EF EF EF 43 EF EF'
+ 'EF 21 00 00 00 00 00 00 00 00 42 42 42 32 3E 3E'
+ '3E 7B 3C 3C 3C C3 3B 3B 3B FA 64 64 64 FF B4 B4'
+ 'B4 FF A2 A2 A2 FF 76 76 76 FF 7C 7C 7C FF 96 96'
+ '96 FF A7 A7 A7 FF B8 B8 B8 FF C8 C8 C8 FF D6 D6'
+ 'D6 FF DE DE DE EE 60 60 60 B4 87 87 87 EA 8E 8E'
+ '8E C6 97 97 97 A2 9F 9F 9F 7E AA AA AA 5B BB BB'
+ 'BB 39 BF BF BF 18 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 46 46 46 12 7F 7F 7F 72 BC BC'
+ 'BC C6 CA CA CA C1 E0 E0 E0 AE E4 E4 E4 9C EA EA'
+ 'EA 8B EE EE EE 79 ED ED ED 67 F0 F0 F0 55 F3 F3'
+ 'F3 43 F8 F8 F8 29 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D'
- '3D A4 A4 3B 3B A4 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4'
- '3D 3D A4 3C 3B A4 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4'
- '3D A4 68 3C 3C A4 00 A4 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4 A4'
- '3D A4 A4 A4 3C A4 00 3B A4 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 3D A4 A4 A4 3D'
- 'A4 3D A4 A4 3D A4 00 3B 3B 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 3D A4 A4 A4 3D A4'
- 'A4 A4 3D A4 A4 3D 00 3C 3B A4 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4'
- 'A4 A4 A4 3D A4 A4 68 3C 3C A4 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4'
- 'A4 A4 A4 A4 3D A4 A4 A4 3C A4 00 3B A4 00 00 00'
- '00 00 00 00 00 00 00 A4 A4 A4 A4 0F 17 16 17 16'
- '16 16 16 16 16 16 16 3D A4 A4 A4 3D A4 A4 A4 A4'
- '3D A4 A4 A4 A4 3D A4 A4 3D A4 00 3B 3B A4 00 00'
- '00 00 00 00 00 00 00 A4 A4 12 47 72 75 73 76 75'
- '74 73 71 6F 6E 6D 6C 3D A4 A4 3D A4 A4 A4 A4 3D'
- 'A4 3D A4 A4 A4 A4 3D A4 A4 3D A4 3C 3B A4 00 00'
- '00 00 00 00 00 00 A4 A4 01 43 93 90 8F 7D 40 42'
- '48 4B 52 59 62 68 6B 3D A4 3D A4 A4 A4 A4 3D A4'
- '3D A4 3D A4 A4 A4 A4 3D A4 A4 68 3C 3C A4 00 A4'
- '00 00 00 00 00 00 A4 A4 0B 6F 94 8A 8E 73 1C 1E'
- '26 31 41 48 4F 54 56 3D 3D A4 A4 A4 A4 3D A4 3D'
- 'A4 3D A4 A4 A4 A4 A4 A4 3D A4 A4 A4 3C A4 00 3B'
- 'A4 00 00 00 00 00 A4 A4 15 79 92 8C 8F 75 21 29'
- '36 41 46 4A 51 3B 3B A4 68 A4 A4 A4 A4 A4 3D A4'
- '3D A4 A4 A4 A4 A4 A4 A4 A4 3D A4 A4 3D A4 00 3B'
- '3B A4 00 00 00 00 A4 A4 14 79 94 8E 8F 79 2C 32'
- '39 40 45 4A 51 3B 3B A4 A4 68 A4 A4 A4 A4 A4 3D'
- 'A4 A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 3D A4 3C'
- '3B A4 00 00 00 00 A4 A4 14 79 96 8F 90 7E 2F 30'
- '38 40 45 4A 51 3C 3C 3C 3C 4E 68 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 68 3C'
- '3C A4 00 A4 00 00 A4 A4 13 79 97 91 93 7E 2D 2E'
- '35 3E 43 49 4E 4E 3C 3C 4E 4E 4E 68 A4 A4 A4 A4'
- 'A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4 A4'
- '3C A4 00 3B A4 00 A4 A4 13 7A 9A 93 92 87 55 55'
- '58 5A 5B 5D 5E 61 61 62 65 3B 3B A4 68 A4 A4 A4'
- 'A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4 A4'
- '3D A4 A4 3B 3B A4 A4 A4 12 7B 9B 93 93 92 95 93'
- '91 90 8E 8C 8A 89 87 86 83 3B 3B A4 A4 68 A4 A4'
- 'A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D A4'
- 'A4 3D A4 3C 3B A4 A4 A4 12 7B 9F A0 9E 9E 9E 9D'
- '9D 9C 9C 9B 9B 9B 9A 9A 99 3C 3C 3C 3C 99 68 A4'
- 'A4 A4 A4 A4 A4 3D A4 A4 A4 3D A4 A4 A4 A4 A4 3D'
- 'A4 A4 68 3C 3C A4 A4 A4 11 7E A3 91 89 8A 8A 88'
- '87 87 87 87 87 88 88 88 88 88 3C 3C 81 81 81 68'
- 'A4 A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 A4 A4 A4 A4'
- '3D A4 A4 A4 3C A4 A4 A4 11 86 A0 81 6C 63 67 80'
- '82 81 81 81 81 81 81 81 81 81 81 81 81 3B 3B A4'
- '68 A4 A4 A4 A4 A4 A4 3D A4 A4 A4 A4 A4 A4 A4 A4'
- 'A4 3D A4 A4 3D A4 A4 A4 0D 82 9B 6E 57 5F 5B 6B'
- '82 80 80 80 80 80 7F 7F 7F 7F 7F 7F 7F 3B 3B A4'
- 'A4 68 A4 A4 A4 A4 A4 A4 A4 A4 3D 3D 3D A4 A4 A4'
- 'A4 A4 3D A4 3D A4 A4 A4 03 6A 9E 64 5C 6B 58 63'
- '80 7D 7D 7D 7C 7B 7B 7D 7F 80 80 7F 7D 3C 3C 3C'
- '3C 7F 68 A4 A4 A4 A4 A4 A4 3D A4 3D A4 3D A4 A4'
- 'A4 A4 A4 3D 68 A4 00 A4 A4 53 9C 77 6D 7A 67 71'
- '7B 7A 78 7B 85 89 8B 8E 92 95 95 93 8F 8F 3C 3C'
- '8F 8F 7F 68 A4 A4 A4 A4 A4 3D 3D A4 3D 3D A4 A4'
- 'A4 A4 A4 68 A4 A4 00 A4 A4 39 97 79 77 73 77 79'
- '76 77 87 98 94 89 86 85 84 83 83 84 85 86 89 94'
- '99 3B 3B A4 68 A4 A4 A4 A4 3D A4 3D A4 3D A4 A4'
- 'A4 A4 68 A4 A4 00 00 A4 A4 27 91 78 75 75 75 72'
- '7E 95 8E 84 7C 7D 7E 7E 7E 7E 7E 7E 7E 7E 7D 7D'
- '83 3B 3B A4 A4 68 A4 A4 A4 A4 3D 3D 3D A4 A4 A4'
- 'A4 68 A4 A4 00 00 00 A4 A4 1F 7F 7A 72 73 72 7C'
- '91 84 78 79 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A'
- '79 3C 3C 3C 3C 4C 68 A4 A4 A4 A4 A4 A4 A4 A4 A4'
- '68 A4 A4 00 00 00 00 A4 A4 10 5F 83 72 73 76 8C'
- '7C 77 79 78 78 78 78 77 75 76 76 76 76 76 76 76'
- '76 76 3C 3C 77 77 4C 68 A4 A4 A4 A4 A4 A4 A4 68'
- 'A4 A4 00 00 00 00 00 A4 A4 05 50 85 74 75 83 7E'
- '76 78 78 78 78 78 78 77 74 71 72 72 72 72 72 72'
- '72 72 72 70 77 3B 3B A4 68 A4 A4 A4 A4 A4 68 A4'
- 'A4 00 00 00 00 00 00 00 A4 A4 3F 85 77 79 83 79'
- '78 78 78 78 78 78 78 78 77 71 6D 6E 6E 6E 6E 6E'
- '6E 6E 6E 6E 6F 3B 3B A4 A4 68 A4 A4 A4 68 A4 A4'
- '00 00 00 00 00 00 00 00 A4 A4 29 84 79 7A 7C 79'
- '79 79 79 79 79 79 79 79 79 78 70 6B 6B 6B 6C 6C'
- '6C 6C 6C 6C 6C 3C 3C 3C 3C 07 68 A4 68 A4 A4 00'
- '00 00 00 00 00 00 00 00 A4 A4 20 80 7C 7A 78 7B'
- '7B 7B 7B 7B 7B 7B 7B 7B 7B 7B 7B 75 6F 6C 6A 69'
- '68 69 69 69 6A 6A 3C 3C 4C 07 A4 68 A4 A4 00 00'
- '00 00 00 00 00 00 00 00 A4 A4 17 74 7E 7D 74 7D'
- '7E 7E 7E 7E 7E 7E 7E 7E 7E 7E 7E 7F 7E 7D 7B 77'
- '74 71 6E 6C 6A 5D 65 78 4C 07 A4 A4 00 00 00 00'
- '00 00 00 00 00 00 00 00 A4 A4 0A 5B 83 83 78 7A'
- '83 81 82 82 82 82 82 82 82 82 82 82 82 82 82 83'
- '83 82 81 81 77 6D 74 72 37 02 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 A4 A4 06 4A 84 87 84 76'
- '7E 86 85 85 85 85 85 85 85 85 85 85 85 85 85 85'
- '85 85 86 80 76 85 84 6E 25 A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 34 7B 8A 89 86'
- '76 7F 89 8A 88 88 88 88 88 88 88 88 88 88 88 88'
- '89 89 81 75 82 8B 81 63 1B A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 24 71 8D 8B 8C'
- '89 7F 7A 82 8C 8D 8C 8C 8C 8C 8C 8C 8C 8C 8D 8D'
- '84 7A 7E 88 8C 8E 7E 56 0E A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 1A 65 8E 8E 8E'
- '8F 8F 87 7A 7B 86 8B 8B 8C 8C 8C 8C 8B 8B 86 7C'
- '79 85 8F 8F 8E 90 7C 4D 08 A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 0C 58 8C 95 8F'
- '8E 94 93 92 8C 88 87 87 85 84 84 85 87 87 87 8A'
- '91 94 92 8D 93 93 7E 43 A4 A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 A4 A4 06 4C 8C 87 65'
- '69 7E 94 95 95 96 96 95 94 93 93 94 95 96 96 95'
- '96 8C 6A 66 79 94 7C 33 A4 A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 44 88 6C 5C'
- '60 5C 93 99 98 98 98 98 98 98 98 98 98 98 98 98'
- '9B 7D 5B 5E 5F 93 75 2A A4 A4 A4 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 2B 76 85 84'
- '7D 8C A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1 A1'
- 'A2 9A 87 80 84 7F 5B 19 A4 A4 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 0B 3D 66 7B'
- '7F 83 80 80 80 80 80 80 80 80 80 80 80 80 80 80'
- '80 81 81 7F 75 5B 28 04 A4 A4 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 A4 A4 A4 09 1D 23'
- '22 22 22 22 22 22 22 22 22 22 22 22 22 22 22 22'
- '22 22 22 23 23 18 02 A4 A4 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 A4 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4 A4'
- 'A4 A4 A4 A4 A4 A4 A4 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF 0F FF FF 00 00 FF FF'
- 'FE 00 FF FF 00 00 FF FF FC 00 FF FF 00 00 FF FF'
- 'F8 00 BF FF 00 00 FF FF F0 00 9F FF 00 00 FF FF'
- 'E0 00 9F FF 00 00 FF FF E0 00 8F FF 00 00 F0 00'
- '00 00 0F FF 00 00 C0 00 00 00 09 FF 00 00 80 00'
- '00 00 08 FF 00 00 80 00 00 00 00 FF 00 00 00 00'
- '00 00 00 BF 00 00 00 00 00 00 00 9F 00 00 00 00'
- '00 00 00 8F 00 00 00 00 00 00 00 0F 00 00 00 00'
- '00 00 00 0B 00 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 01 00 00 80 00 00 00 00 03 00 00 80 00'
- '00 00 00 07 00 00 80 00 00 00 00 0F 00 00 80 00'
- '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 C0 00'
- '00 00 00 7F 00 00 C0 00 00 00 00 FF 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
- '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
- '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF E0 1F FF FF E0 00 1F FF C0 00 00 00 C0 00'
+ '00 00 F0 00 00 00 F0 00 00 00 F0 00 00 00 78 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 08 80 06 60 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 88 0E 60 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 08 00 80 7E E0 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 80 00 E0 06 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '08 00 08 08 00 80 06 60 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 80 00 80 00 80 08 0E 60'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08'
- '00 08 00 00 08 00 7E E0 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 80 00 80 00 00 00 80 00 E0'
- '06 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00'
- '08 00 00 80 00 08 00 80 06 60 00 00 00 00 00 00'
- '87 77 77 77 77 77 78 00 80 00 08 08 00 00 80 08'
- '0E 60 00 00 00 00 00 08 FF F7 88 88 77 77 78 08'
- '00 00 80 80 80 00 08 00 7E E0 00 00 00 00 00 07'
- 'FF F7 00 88 88 87 78 80 00 08 08 08 00 00 00 80'
- '00 E0 06 00 00 00 00 07 FF F7 88 88 88 76 60 70'
- '00 00 80 80 00 00 00 08 00 80 06 60 00 00 00 07'
- 'FF F7 88 88 88 76 60 07 00 00 08 00 00 80 00 00'
- '80 08 0E 60 00 00 00 07 FF F7 88 88 88 7E EE E8'
- '70 00 00 00 00 08 00 00 08 00 7E E0 00 00 00 07'
- 'FF F7 88 88 88 88 EE 88 87 00 00 00 80 00 80 00'
- '00 80 00 E0 06 00 00 07 FF F7 77 77 77 77 77 76'
- '60 70 00 00 08 00 08 00 00 08 00 80 06 60 00 07'
- 'FF FF FF FF FF FF 77 76 60 07 00 00 00 80 00 80'
- '00 00 80 08 0E 60 00 07 FF FF FF FF FF FF FF FE'
- 'EE EF 70 00 00 08 00 08 00 00 08 00 7E E0 00 07'
- 'FF FF FF 77 77 7F FF FF EE 77 77 00 00 00 80 00'
- '00 00 00 80 00 E0 00 07 77 77 F7 77 77 77 77 77'
- '77 76 60 70 00 00 08 00 00 00 00 08 00 80 00 07'
- '77 77 F7 77 77 77 77 77 77 76 60 07 00 00 00 00'
- '88 80 00 00 80 80 00 07 77 7F F7 77 77 77 77 77'
- '77 7E EE E7 70 00 00 08 08 08 00 00 08 70 00 07'
- 'FF FF 77 77 77 7F FF FF FF FF EE FF 77 00 00 08'
- '80 88 00 00 07 00 00 08 77 77 77 77 7F FF 77 77'
- '77 77 FF F6 60 70 00 08 08 08 00 00 70 00 00 08'
- '77 77 77 7F F7 77 77 77 77 77 77 76 60 07 00 00'
- '88 80 00 07 00 00 00 00 77 77 77 F7 77 77 77 77'
- '77 77 77 7E EE E8 70 00 00 00 00 70 00 00 00 00'
- '77 77 7F 77 77 77 77 77 77 77 77 77 EE 77 87 00'
- '00 00 07 00 00 00 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 77 76 60 70 00 00 70 00 00 00 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 77 76 60 07'
- '00 07 00 00 00 00 00 00 87 77 77 77 77 77 77 77'
- '77 77 77 77 77 7E EE E0 70 70 00 00 00 00 00 00'
- '87 77 77 77 77 77 77 77 77 77 77 77 77 77 EE 80'
- '07 00 00 00 00 00 00 00 07 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '07 77 77 77 77 77 77 77 77 77 77 77 77 77 77 80'
- '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '08 77 77 77 77 77 77 77 77 77 77 77 77 77 77 00'
- '00 00 00 00 00 00 00 00 08 77 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
- '00 77 77 77 77 77 77 77 77 77 77 77 77 77 78 00'
- '00 00 00 00 00 00 00 00 00 7F FF FF F7 77 77 77'
- '77 77 77 7F FF FF 78 00 00 00 00 00 00 00 00 00'
- '00 8F 77 77 F7 77 77 77 77 77 77 FF 77 7F 78 00'
- '00 00 00 00 00 00 00 00 00 8F 77 77 F7 77 77 77'
- '77 77 77 F7 77 7F 78 00 00 00 00 00 00 00 00 00'
- '00 87 77 7F F7 77 77 77 77 77 77 FF 77 77 70 00'
- '00 00 00 00 00 00 00 00 00 08 77 77 77 77 77 77'
- '77 77 77 77 77 77 80 00 00 00 00 00 00 00 00 00'
- '00 00 08 88 88 88 88 88 88 88 88 88 88 80 00 00'
+ '00 00 00 00 00 00 00 01 80 00 00 FF F0 00 FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 04 00 00 00 00 00 80 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
+ '00 00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
+ 'C0 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
+ '00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 77 77 70 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 70 70 70 70 70 77 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '07 07 77 07 77 07 77 07 77 07 77 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 70 70 70 70 70 70 70'
+ '70 70 70 70 77 07 77 77 77 77 77 70 00 00 00 00'
+ '07 07 07 07 07 77 77 77 77 77 77 77 77 00 77 77'
+ '00 70 00 07 77 78 00 00 70 70 70 70 70 70 70 70'
+ '70 70 70 77 00 00 77 77 07 77 77 77 70 78 00 00'
+ '00 00 00 00 07 07 77 77 77 77 77 70 00 00 77 77'
+ '07 77 77 77 70 78 00 00 00 00 00 00 00 00 00 07'
+ '00 00 07 00 00 00 77 77 00 00 00 00 00 78 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 77'
+ '00 00 00 00 00 78 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 77 77 00 00 00 00 00 78 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 77'
+ '77 77 77 77 77 78 00 00 00 00 70 78 88 77 00 00'
+ '00 00 00 00 00 00 77 77 77 77 77 77 77 88 78 8A'
+ 'A8 88 88 88 88 88 87 77 77 77 77 77 77 70 77 77'
+ '7A 77 78 77 78 88 78 77 77 77 77 77 77 77 77 77'
+ '77 77 77 77 77 70 77 77 77 77 77 77 77 78 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 67 70 77 77'
+ '00 00 00 00 00 78 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 67 70 77 77 00 00 00 00 00 78 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 67 70 77 87'
+ '00 00 00 00 00 78 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 67 70 77 87 00 00 00 00 00 78 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 68 70 77 87'
+ '00 77 77 77 00 78 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 68 00 77 87 00 00 00 00 00 78 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 68 00 77 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 68 00 77 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 68 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 68 00 78 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 68 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 78 00 78 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 78 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 78 00 78 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 66 78 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 66 78 00 78 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 67 78 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 67 78 00 78 87 00 00 00 00 00 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 67 87 00 78 87'
+ '00 00 00 00 00 7F 78 76 66 66 66 66 66 66 66 66'
+ '66 66 66 67 87 00 78 87 07 77 77 77 70 7F 78 76'
+ '66 66 66 66 66 66 66 66 66 66 66 67 87 00 78 87'
+ '07 00 00 00 70 7F 78 66 66 66 66 66 66 66 66 66'
+ '66 66 67 77 87 00 78 87 07 77 77 77 70 7F 78 66'
+ '66 66 66 66 66 66 66 67 77 77 78 88 F7 00 78 87'
+ '00 00 00 00 00 7F 78 66 66 66 66 66 66 67 77 78'
+ '88 FF 88 77 70 00 78 87 00 00 07 77 77 7F 78 66'
+ '66 67 77 77 78 88 88 88 80 00 08 77 70 00 78 87'
+ '77 77 77 88 88 8F 78 77 77 78 88 88 88 00 00 00'
+ '00 00 00 00 00 07 78 88 88 8F FF FF FF F8 78 88'
+ '88 80 00 00 00 00 00 00 00 00 00 00 00 00 88 88'
+ '88 88 88 80 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
- 'FF 01 FF FF 00 00 FF FF FE 00 FF FF 00 00 FF FF'
- 'FC 00 FF FF 00 00 FF FF F8 00 BF FF 00 00 FF FF'
- 'F0 00 9F FF 00 00 FF FF F0 00 8F FF 00 00 FF FF'
- 'E0 00 8F FF 00 00 F0 00 00 00 0F FF 00 00 C0 00'
- '00 00 09 FF 00 00 80 00 00 00 08 FF 00 00 80 00'
- '00 00 00 FF 00 00 00 00 00 00 00 BF 00 00 00 00'
- '00 00 00 9F 00 00 00 00 00 00 00 8F 00 00 00 00'
- '00 00 00 0F 00 00 00 00 00 00 00 0B 00 00 00 00'
- '00 00 00 09 00 00 00 00 00 00 00 08 00 00 00 00'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FC 1F'
+ 'FF FF FF FF 00 00 FC 00 3F FF FF FF 00 00 F8 00'
+ '00 3F FF FF 00 00 F8 00 00 02 00 1F 00 00 F0 00'
+ '00 00 00 00 00 00 F0 00 00 00 00 00 00 00 FF 00'
+ '00 00 00 00 00 00 FF 00 20 00 00 00 00 00 FF 00'
+ '00 00 00 00 00 00 FF 00 00 00 00 00 00 00 FF 00'
+ '00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '07 80 00 00 00 00 00 03 FF FE 00 00 00 00 01 FF'
+ 'FF FF 00 1F 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 30 00 00 00 60 00 00 00 01 00 08 00 00 00'
+ '00 00 00 09 00 00 00 00 00 00 00 00 00 00 00 01'
+ '00 00 00 01 00 00 00 00 00 00 05 05 05 00 0A 0A'
+ '0A 00 0D 0D 0D 00 13 13 13 00 1B 1B 1B 00 21 21'
+ '21 00 26 26 26 00 29 29 29 00 2D 2D 2D 00 31 31'
+ '31 00 35 35 35 00 38 38 38 00 3A 3A 3A 00 3D 3D'
+ '3D 00 76 48 02 00 78 48 00 00 79 4A 00 00 7A 4A'
+ '00 00 7B 4C 01 00 7B 4C 02 00 7C 4E 02 00 73 4A'
+ '0C 00 7E 50 04 00 7F 52 05 00 7F 54 07 00 7E 55'
+ '0A 00 7F 57 0D 00 7D 58 11 00 7C 5B 17 00 73 50'
+ '1C 00 7F 60 1E 00 76 5A 2E 00 7B 5F 34 00 7F 66'
+ '2B 00 7D 61 37 00 7D 63 3A 00 7D 64 3E 00 41 41'
+ '41 00 44 44 44 00 46 46 46 00 49 49 49 00 4C 4C'
+ '4C 00 4E 4E 4E 00 51 51 51 00 54 54 54 00 56 56'
+ '56 00 58 58 58 00 5A 5A 5A 00 5D 5D 5D 00 7B 66'
+ '43 00 7D 65 41 00 7F 67 44 00 61 61 61 00 65 65'
+ '65 00 69 69 69 00 6C 6C 6C 00 6E 6E 6E 00 78 72'
+ '6A 00 7A 73 6A 00 71 71 71 00 75 75 75 00 78 78'
+ '78 00 7A 7A 7A 00 7D 7A 78 00 7C 7C 7C 00 7E 7E'
+ '7E 00 80 53 05 00 81 55 06 00 82 56 08 00 83 58'
+ '08 00 84 58 08 00 85 59 0A 00 85 5A 0A 00 86 5A'
+ '0A 00 86 5C 0B 00 87 5C 0C 00 88 5E 0C 00 8A 60'
+ '0E 00 8C 63 0F 00 8C 63 10 00 8D 65 11 00 88 63'
+ '15 00 8F 68 13 00 90 68 13 00 91 6A 14 00 92 6C'
+ '15 00 94 6E 16 00 95 70 17 00 96 71 18 00 98 73'
+ '19 00 99 74 1A 00 9A 77 1C 00 9B 78 1D 00 9C 79'
+ '1D 00 9E 7C 1F 00 86 67 23 00 81 64 24 00 9F 7D'
+ '20 00 85 6C 32 00 85 70 3A 00 A0 7E 20 00 81 69'
+ '46 00 82 6B 49 00 84 6D 4B 00 85 6F 4E 00 87 75'
+ '44 00 89 75 46 00 86 71 51 00 87 73 55 00 8F 7E'
+ '50 00 81 72 59 00 88 76 59 00 8A 78 5E 00 86 78'
+ '61 00 8A 7B 63 00 8B 7C 63 00 8C 7D 62 00 87 7E'
+ '6F 00 80 7E 7C 00 51 CB 51 00 5A CA 5A 00 A2 81'
+ '22 00 A4 83 24 00 A5 85 24 00 A7 88 26 00 A9 8A'
+ '28 00 AA 8D 29 00 AC 8E 2A 00 AD 90 2B 00 AE 92'
+ '2C 00 B1 95 2F 00 AE 93 30 00 A9 92 38 00 B2 96'
+ '30 00 B3 98 31 00 B4 99 31 00 B6 9C 33 00 B7 9D'
+ '34 00 B8 9F 35 00 B9 A1 36 00 BB A3 38 00 BD A5'
+ '39 00 BF A8 3B 00 C0 AA 3C 00 C2 AD 3D 00 C4 AF'
+ '3F 00 95 86 5B 00 91 83 5E 00 A4 92 44 00 A3 95'
+ '53 00 BC A8 40 00 91 81 63 00 94 83 63 00 95 84'
+ '64 00 98 86 64 00 9A 88 66 00 9D 8B 67 00 98 8C'
+ '66 00 91 81 68 00 95 86 6D 00 9A 8B 72 00 9D 92'
+ '71 00 9B 92 79 00 9E 90 78 00 A1 8F 6A 00 A3 91'
+ '6A 00 A5 93 6B 00 A6 94 6C 00 A8 97 6E 00 A8 9E'
+ '6A 00 AA 9A 6F 00 AE 9E 71 00 A3 96 7E 00 A2 98'
+ '79 00 C5 B1 40 00 C8 B4 42 00 CA B7 44 00 CB B8'
+ '45 00 CC BA 45 00 CD BC 47 00 CF BD 48 00 D0 BF'
+ '49 00 FF 00 FF 00 81 81 81 00 85 85 85 00 88 87'
+ '86 00 8F 8C 86 00 88 88 88 00 8A 8A 8A 00 8D 8D'
+ '8D 00 90 90 90 00 92 92 92 00 94 94 94 00 96 96'
+ '96 00 98 98 98 00 9A 9A 9A 00 9E 9E 9E 00 A4 9B'
+ '83 00 A8 9C 85 00 A6 9F 8C 00 8D BE 8D 00 AF A8'
+ '82 00 AC A2 8B 00 A6 A2 95 00 AA A3 94 00 AC A7'
+ '9D 00 B0 A6 91 00 B2 AA 96 00 B4 B0 98 00 A0 A0'
+ 'A0 00 A2 A2 A2 00 A4 A4 A4 00 A6 A6 A6 00 AF AC'
+ 'A7 00 A8 A8 A8 00 AA AA AA 00 AC AC AC 00 AE AE'
+ 'AE 00 B3 B2 AF 00 B9 B7 AF 00 B0 B0 B0 00 B2 B2'
+ 'B2 00 B6 B3 B0 00 B4 B4 B4 00 B6 B6 B6 00 B9 B9'
+ 'B9 00 BC BC BC 00 BE BE BE 00 C4 C1 B8 00 C0 C0'
+ 'C0 00 C2 C2 C2 00 C4 C4 C3 00 C4 C4 C4 00 C6 C6'
+ 'C6 00 C8 C8 C8 00 CB CB CB 00 CC CC CC 00 CE CE'
+ 'CE 00 C5 DB C5 00 D0 D0 D0 00 D2 D2 D2 00 D5 D5'
+ 'D5 00 D7 D7 D7 00 D9 D9 D9 00 DA DA DA 00 DC DC'
+ 'DC 00 E1 E1 E1 00 E3 E3 E3 00 E4 E4 E4 00 E6 E6'
+ 'E6 00 EB EB EB 00 ED ED ED 00 EE EE EE 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 35 2C 35 39'
+ 'B8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 26 26 2B 26'
+ '26 0D 26 26 26 31 39 B8 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 2B 26 26 2B 26'
+ '26 26 2C 26 31 31 31 31 2C 31 2C 2C 31 39 42 BE'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 0D 26 2B 0C 2B'
+ '26 2B 2C 2B 2C 2B 2C 31 31 31 35 35 35 31 35 31'
+ '35 39 39 42 00 42 35 35 3C 2C 2C 35 35 42 00 00'
+ '00 00 00 00 00 00 00 00 00 00 0D 0D 26 0C 26 0D'
+ '2B 2B 2B 2B 2C 2C 2C 31 2C 31 35 35 35 35 35 35'
+ '35 35 31 0D 07 07 2C 3C 42 2B 09 26 26 0D 0C 09'
+ '0D 26 31 35 B8 DA 00 00 00 00 31 31 2C 26 2B 26'
+ '2B 26 2B 2C 2C 2C 31 2C 31 31 31 35 35 39 35 39'
+ '39 31 0C 07 07 07 2C 3C 42 26 0C 2C 35 31 31 39'
+ '39 26 26 0C 2B D3 00 00 00 00 00 00 00 00 03 04'
+ '05 07 07 0C 0C 26 26 2C 3C 3C 35 35 35 39 35 35'
+ '31 09 07 09 07 09 31 3C B8 2B 09 26 31 35 31 31'
+ '31 2C 2B 0C 2B D3 00 00 00 00 00 00 00 00 01 01'
+ '01 01 01 01 01 01 01 07 00 2C 0C 09 0C 0C 0D 26'
+ '09 09 07 09 07 09 31 3C BE 2B 0C 0C 09 0C 09 0C'
+ '09 0C 0C 0C 26 DE 00 00 00 00 00 00 00 00 04 01'
+ '01 01 01 01 01 01 01 03 09 09 07 07 09 09 09 07'
+ '09 07 09 09 09 09 31 42 B8 2C 09 09 09 0C 09 0C'
+ '0C 09 0C 0C 2B DA 00 00 00 00 00 00 00 00 07 01'
+ '01 01 01 01 01 01 01 01 09 07 07 09 09 09 09 07'
+ '09 09 09 09 09 0C 2C B8 BE 2C 0C 09 0C 0C 0C 09'
+ '0C 0C 0C 0C 2B DE 00 00 00 00 00 00 00 00 0D 01'
+ '01 01 01 01 01 01 01 01 09 07 09 07 09 09 09 09'
+ '09 09 09 0C 09 09 35 B8 BE BE B8 B8 3C 39 35 31'
+ '31 2C 2C 2B 31 DE 00 00 00 00 00 00 00 00 2C 03'
+ '39 DA D3 C5 C1 39 07 01 09 07 07 09 09 09 09 09'
+ '09 0C 09 09 0C 09 35 B8 C1 BE 78 BE C1 BE B8 BE'
+ 'C1 C5 C5 C1 D3 E2 42 DE EF 79 C9 EE EE EB E2 E2'
+ 'E2 EB E2 EE EB E2 DA C5 C1 C1 BE B8 B8 B8 B8 42'
+ '3C 42 42 3C 2B 0C 35 BE C1 C1 C5 C1 C1 C1 BE D3'
+ 'C5 C5 C5 C5 D3 E2 39 DE E5 AC AC AC AB AC AC A9'
+ 'A9 A9 A9 9C 9C 9C 9B 9B 9B 98 9B 74 74 74 74 74'
+ '74 74 72 BC 2C 0C 35 BE C1 31 0D 26 2B 2C 2C 35'
+ '39 35 39 3C B8 EB 39 DA D0 5E 5E 5C 5C 58 57 57'
+ '50 4E 4B 4B 4B 43 18 18 15 15 15 18 18 43 43 18'
+ '18 43 18 42 2C 0C 35 BE C5 31 0D 0D 0D 0D 0D 0D'
+ '0D 0D 26 26 2C EE 35 DE CF 5C 59 57 57 57 53 50'
+ '50 4E 4B 47 43 43 43 18 18 19 18 43 18 43 47 47'
+ '4B 47 19 B8 2C 0C 35 C1 C5 31 0D 0D 0D 0D 0D 26'
+ '0D 26 0D 0D 31 EE 35 DE CB 57 57 57 50 53 50 50'
+ '4E 4D 4B 47 4B 43 43 43 43 43 47 4B 47 4B 47 4B'
+ '4B 4B 1B BE 2B 09 39 BE D3 35 0D 0D 0D 26 0D 26'
+ '0D 26 26 26 2C F0 35 DE C7 50 4E 50 50 4E 4E 4B'
+ '4B 4B 47 47 43 4B 46 4B 4B 4B 47 4B 4B 4B 4B 4B'
+ '4D 4E 1C C1 26 0C 39 C1 D3 35 0D 0D 0D 0D 0D 0D'
+ '0D 0D 26 26 31 F0 35 DA AD 4D 4D 4D 4E 4B 4B 4B'
+ '4B 47 47 47 4B 43 46 47 4B 4B 4B 4B 4D 50 50 50'
+ '50 50 1D D3 26 09 39 C1 D3 39 0D 0D 26 26 2B 26'
+ '26 26 26 26 31 F5 35 DA A4 4B 4B 47 43 4B 43 4B'
+ '43 47 47 47 43 4B 4B 4B 4B 4D 50 50 53 57 50 57'
+ '57 57 1F DA 0D 0C 39 C5 D3 35 26 26 0D 0D 26 26'
+ '26 26 26 26 31 F5 35 D3 A4 43 43 43 43 43 4B 43'
+ '47 47 47 47 4B 4B 4D 4E 50 50 57 53 57 57 57 59'
+ '58 58 61 DE 0C 09 39 C5 DA 39 0D 26 26 26 26 26'
+ '26 26 2B 26 31 F7 35 D3 A0 18 18 43 43 43 18 43'
+ '43 47 47 4B 4B 4E 50 50 57 53 57 59 5C 5C 5C 5C'
+ '5C 5C 22 E2 09 0C 3C C5 DA 39 0D 26 26 26 26 2B'
+ '26 26 26 2B 35 F7 35 C5 9B 15 15 15 15 18 18 43'
+ '43 4B 47 4B 4E 50 57 53 57 59 5C 5C 5C 5C 5E 5F'
+ '5F 5F 63 E2 0C 0C 3C C5 DA 39 26 26 26 26 26 26'
+ '2B 2B 2B 2B 31 F7 35 C5 74 15 10 15 15 15 18 43'
+ '46 4B 4B 4E 50 53 57 58 5C 5C 5C 5E 65 7A 7A 7A'
+ '7A 7A 64 E2 0C 09 3C D3 DE 39 26 26 26 2B 26 2B'
+ '26 2B 2B 2B 35 F7 35 C3 71 10 10 15 15 15 18 43'
+ '4B 4B 4D 4E 57 57 58 5C 5C 5E 65 7A 7A 7E 7F 7F'
+ '7F 7F 6A DE 0C 0C 3C D3 DE 3C 26 26 26 26 2B 26'
+ '2B 2B 2B 2B 35 F7 31 C1 71 15 10 10 15 15 43 43'
+ '4B 4B 4E 57 50 59 5C 5E 65 7A 7D 7F 7F 81 81 81'
+ '81 81 6E DE 0C 09 42 D3 E2 3C 26 2B 26 26 2B 2B'
+ '2B 2B 2B 2C 39 F7 31 C1 6C 10 10 15 15 15 43 4B'
+ '47 4E 50 57 58 5C 5C 65 7A 7F 7F 81 81 86 88 88'
+ '88 88 93 D3 0C 0C 3C DA E2 42 26 26 2B 2B 2B 2B'
+ '2B 2C 2C 31 39 F7 31 BF 6C 15 10 10 15 15 43 43'
+ '4D 4E 50 57 59 5C 65 7A 7F 7F 81 86 88 88 8D 8D'
+ '8D 8D 9C D3 0C 0C 42 D3 E2 3C 26 26 2B 26 2B 2B'
+ '2B 2C 31 2C 39 F7 31 BE 6C 10 10 10 15 15 43 4B'
+ '4D 50 57 57 5C 5E 7A 7E 7F 81 86 88 8D 8D 90 8F'
+ '8F 8F A2 C5 0C 0A 3E DA E2 42 26 2B 2B 2B 2B 2C'
+ '2C 31 31 31 39 F7 31 BE 69 10 15 10 15 15 43 4B'
+ '4D 50 57 57 5C 65 7A 7F 7F 86 88 8D 90 90 AF AF'
+ 'AF AF AE BF 0C 0C 3C DA E2 42 2B 26 2B 2C 2C 2C'
+ '31 2C 31 31 3C F7 31 BE 69 10 10 10 15 15 47 4B'
+ '4E 53 57 59 5E 65 7A 7F 86 88 8D 8D 90 B0 B0 B1'
+ 'B1 B1 C7 B8 0C 0C 42 DA E2 42 26 2C 2B 2C 2C 31'
+ '31 31 31 35 3C F7 31 B8 69 15 10 10 15 15 47 4B'
+ '4E 50 57 5C 5E 7A 7E 7F 86 88 8D 90 AF B0 B1 B1'
+ 'B1 B1 C8 B8 0C 0C 3C DA E2 B8 2B 2B 2C 2C 31 2C'
+ '31 31 35 35 3C F7 31 B8 66 10 15 10 15 15 4B 4B'
+ '4E 57 57 59 5E 7A 7D 7F 86 88 8D 92 92 B1 B5 B6'
+ 'B6 B5 CD 42 0C 0C 42 DA EB 42 2B 2C 2C 31 2C 35'
+ '31 35 35 39 3C FA 2C BA 34 15 10 10 15 15 47 4B'
+ '4D 50 57 5C 5E 7A 7D 7F 86 8B 8D 90 B0 B1 B1 B6'
+ 'B6 B1 CE 3E 0C 0C 3C DA E2 B8 2C 2C 2C 31 31 31'
+ '35 35 35 39 42 F7 2C B8 34 10 10 10 15 15 4B 4B'
+ '4D 53 57 5C 5E 7A 7E 7F 86 88 8D 90 AF B1 B1 B6'
+ 'B5 B0 D6 39 0C 0C 42 DA EB BE 2C 2C 31 2C 31 31'
+ '35 39 35 35 3C F7 2C B8 25 15 10 10 10 15 47 47'
+ '50 50 57 57 5E 65 7A 7F 81 88 8D 8F 90 B1 B1 B1'
+ 'B1 97 DE 35 0D 0C 3E DA EB B8 2C 2C 2C 31 31 31'
+ '31 35 35 35 42 F7 2C B8 25 10 10 15 10 15 18 47'
+ '4B 50 50 59 5C 5E 7A 7E 7F 81 85 95 96 AB CA D1'
+ 'DC EA FA 35 0C 0C 3E DA E2 BC 2C 2C 31 31 31 31'
+ '39 39 39 39 3C FA 2B 42 23 15 10 10 10 15 18 4B'
+ '4B 4D 50 60 63 6B 94 A3 CC DE EB F0 F7 FA F6 E1'
+ 'C5 B8 37 0D 0C 0D 3E DA EB B8 31 2C 31 31 35 35'
+ '35 35 39 39 3C FA 2B 42 21 10 10 16 1E 20 34 6F'
+ '76 BB C5 D7 DE EB EB EE EE EE EE 00 00 00 00 E1'
+ 'C1 39 26 0D 0C 0D 42 DA E2 BE 2C 31 39 42 BE C1'
+ 'DA DE EB F0 F5 F7 2B 3C 3B 3A 42 BC BF C1 C3 D3'
+ 'DA DD DE E2 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 31 3C DA EB EE F0 F5 F5 F7 FA FD'
+ 'FA FD FA FA FA F5 C1 42 BE C1 D3 DA DE 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 DE DE E2 EE F0 F0 EE EE EE EB'
+ 'EE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00'
- '00 00 00 00 00 00 80 00 00 00 00 01 00 00 80 00'
- '00 00 00 03 00 00 80 00 00 00 00 07 00 00 80 00'
- '00 00 00 0F 00 00 80 00 00 00 00 1F 00 00 C0 00'
- '00 00 00 3F 00 00 C0 00 00 00 00 7F 00 00 C0 00'
- '00 00 00 FF 00 00 C0 00 00 00 03 FF 00 00 C0 00'
- '00 00 07 FF 00 00 C0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 F0 00 00 00 07 FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 1F FF 00 00 F8 00 00 00 3F FF 00 00 FE 00'
- '00 00 7F FF 00 00 FF FF FF FF FF FF 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 20 00 00 00'
- '00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FC 1F FF FF FF FF 00 00 FC 00'
+ '3F FF FF FF 00 00 F8 00 00 3F FF FF 00 00 F8 00'
+ '00 02 00 FF 00 00 F0 00 00 00 00 00 00 00 F0 00'
+ '00 00 00 00 00 00 FF 00 00 00 00 00 00 00 FF 00'
+ '20 00 00 00 00 00 FF 00 00 00 00 00 00 00 FF 00'
+ '00 00 00 00 00 00 FF 00 00 00 00 00 00 00 FF 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 00'
- '00 78 00 00 00 78 00 00 00 3C 00 00 00 30 00 00'
- '00 6C 00 00 00 6C 00 00 00 24 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -12575,11 +20309,13 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 07 80 00 00 00 00 00 03'
+ 'FF FE 00 00 00 00 01 FF FF FF 00 1F 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 28 00 00 00 30 00 00 00 60 00'
+ '00 00 01 00 20 00 00 00 00 00 80 25 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 3C 80 80 80 FF 80 80'
- '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -12589,10 +20325,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3C 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
- '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -12601,10 +20333,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 3C 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
- '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -12612,11 +20340,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3C 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
- 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
- '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
@@ -12624,11 +20347,6 @@ END
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 3E 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3E 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 00 00 FF FF FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
- '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 16 00 00 00 34 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 3E 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
- '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 05 00 00 00 69 00 00 00 C5 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 80 80 FF 00 00'
- '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00'
- '00 9B 00 00 00 FF 00 00 00 FF 21 21 21 FF 2C 2C'
- '2C FF 2B 2B 2B FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
- '2B FF 2B 2B 2B FF 2B 2B 2B FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 90 00 00 00 30 00 80 80 FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 54 00 00'
- '00 FF 26 26 26 FF 90 90 90 FF CA CA CA FF CD CD'
- 'CD FF CB CB CB FF CE CE CE FF CD CD CD FF CC CC'
- 'CC FF CB CB CB FF C9 C9 C9 FF C7 C7 C7 FF C6 C6'
- 'C6 FF C5 C5 C5 FF C4 C4 C4 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 84 00 FF FF FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
- '00 18 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 03 00 00 00 AD 01 01'
- '01 FF 8A 8A 8A FF EB EB EB FF E8 E8 E8 FF E7 E7'
- 'E7 FF D5 D5 D5 FF 85 85 85 FF 88 88 88 FF 92 92'
- '92 FF 98 98 98 FF A2 A2 A2 FF AD AD AD FF BA BA'
- 'BA FF C0 C0 C0 FF C3 C3 C3 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
- '00 54 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 15 00 00 00 F0 19 19'
- '19 FF C7 C7 C7 FF EC EC EC FF E2 E2 E2 FF E6 E6'
- 'E6 FF CB CB CB FF 3B 3B 3B FF 3F 3F 3F FF 56 56'
- '56 FF 72 72 72 FF 87 87 87 FF 92 92 92 FF 9D 9D'
- '9D FF A5 A5 A5 FF A8 A8 A8 FF 80 80 80 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
- 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
- '00 84 00 00 00 78 00 00 00 24 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 30 00 00 00 FA 29 29'
- '29 FF D1 D1 D1 FF EA EA EA FF E4 E4 E4 FF E7 E7'
- 'E7 FF CD CD CD FF 47 47 47 FF 5F 5F 5F FF 79 79'
- '79 FF 87 87 87 FF 8F 8F 8F FF 97 97 97 FF A0 A0'
- 'A0 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 34 00 00 00 F9 28 28'
- '28 FF D1 D1 D1 FF EC EC EC FF E6 E6 E6 FF E7 E7'
- 'E7 FF D1 D1 D1 FF 68 68 68 FF 74 74 74 FF 7E 7E'
- '7E FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
- 'A0 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
- '80 FF 00 00 00 90 00 00 00 30 00 00 00 0C 00 00'
- '00 18 00 00 00 0C 00 00 00 33 00 00 00 F9 28 28'
- '28 FF D1 D1 D1 FF EE EE EE FF E7 E7 E7 FF E8 E8'
- 'E8 FF D6 D6 D6 FF 70 70 70 FF 71 71 71 FF 7D 7D'
- '7D FF 85 85 85 FF 8E 8E 8E FF 97 97 97 FF A0 A0'
- 'A0 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
- 'FF FF 9C 9C 9C FF C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 30 00 00 00 24 00 00'
- '00 54 00 00 00 3C 00 00 00 33 00 00 00 F9 27 27'
- '27 FF D1 D1 D1 FF EF EF EF FF E9 E9 E9 FF EB EB'
- 'EB FF D6 D6 D6 FF 6A 6A 6A FF 6C 6C 6C FF 78 78'
- '78 FF 81 81 81 FF 8A 8A 8A FF 93 93 93 FF 9C 9C'
- '9C FF 9C 9C 9C FF 00 FF FF FF 00 FF FF FF 9C 9C'
- '9C FF 9C 9C 9C FF 9C 9C 9C FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
- 'FF FF 00 00 00 9C 00 00 00 48 00 80 80 FF 00 00'
- '00 84 00 00 00 78 00 00 00 33 00 00 00 F9 27 27'
- '27 FF D2 D2 D2 FF F2 F2 F2 FF EB EB EB FF EA EA'
- 'EA FF DF DF DF FF A7 A7 A7 FF A7 A7 A7 FF AB AB'
- 'AB FF AE AE AE FF B0 B0 B0 FF B3 B3 B3 FF B6 B6'
- 'B6 FF B9 B9 B9 FF B9 B9 B9 FF BA BA BA FF BD BD'
- 'BD FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 00 00 84 00 80 80 FF 00 80'
- '80 FF 00 00 00 90 00 00 00 33 00 00 00 F9 26 26'
- '26 FF D3 D3 D3 FF F3 F3 F3 FF EB EB EB FF EB EB'
- 'EB FF EA EA EA FF ED ED ED FF EB EB EB FF E9 E9'
- 'E9 FF E8 E8 E8 FF E6 E6 E6 FF E4 E4 E4 FF E2 E2'
- 'E2 FF E1 E1 E1 FF DF DF DF FF DE DE DE FF DB DB'
- 'DB FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 B4 00 FF FF FF 00 80'
- '80 FF 00 00 00 90 00 00 00 33 00 00 00 F9 26 26'
- '26 FF D3 D3 D3 FF F7 F7 F7 FF F8 F8 F8 FF F6 F6'
- 'F6 FF F6 F6 F6 FF F6 F6 F6 FF F5 F5 F5 FF F5 F5'
- 'F5 FF F4 F4 F4 FF F4 F4 F4 FF F3 F3 F3 FF F3 F3'
- 'F3 FF F3 F3 F3 FF F2 F2 F2 FF F2 F2 F2 FF F1 F1'
- 'F1 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
- 'FF FF F1 F1 F1 FF C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 FF FF FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 33 00 00 00 F9 24 24'
- '24 FF D6 D6 D6 FF FF FF FF FF E9 E9 E9 FF E1 E1'
- 'E1 FF E2 E2 E2 FF E2 E2 E2 FF E0 E0 E0 FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF DF DF DF FF DF DF'
- 'DF FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF 00 FF FF FF 00 FF FF FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 FF'
- 'FF FF 00 00 00 90 00 00 00 34 00 00 00 FA 24 24'
- '24 FF DE DE DE FF F8 F8 F8 FF D9 D9 D9 FF C4 C4'
- 'C4 FF BB BB BB FF BF BF BF FF D8 D8 D8 FF DA DA'
- 'DA FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9 D9 FF D9 D9'
- 'D9 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 90 00 00 00 25 00 00 00 F7 1F 1F'
- '1F FF DA DA DA FF F3 F3 F3 FF C6 C6 C6 FF A9 A9'
- 'A9 FF B7 B7 B7 FF B0 B0 B0 FF C3 C3 C3 FF DA DA'
- 'DA FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7 D7 FF D7 D7'
- 'D7 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 78 00 00 00 07 00 00 00 D0 05 05'
- '05 FF C2 C2 C2 FF F6 F6 F6 FF BC BC BC FF B2 B2'
- 'B2 FF C3 C3 C3 FF AB AB AB FF BB BB BB FF D8 D8'
- 'D8 FF D5 D5 D5 FF D5 D5 D5 FF D5 D5 D5 FF D4 D4'
- 'D4 FF D3 D3 D3 FF D3 D3 D3 FF D5 D5 D5 FF D7 D7'
- 'D7 FF D8 D8 D8 FF D8 D8 D8 FF D7 D7 D7 FF D5 D5'
- 'D5 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
- 'FF FF D7 D7 D7 FF C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF C0 C0'
- 'C0 FF 00 00 00 3C 00 00 00 00 00 00 00 9C 00 00'
- '00 FF A4 A4 A4 FF F4 F4 F4 FF CF CF CF FF C5 C5'
- 'C5 FF D2 D2 D2 FF BF BF BF FF C9 C9 C9 FF D3 D3'
- 'D3 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF DD DD'
- 'DD FF E1 E1 E1 FF E3 E3 E3 FF E6 E6 E6 FF EA EA'
- 'EA FF ED ED ED FF ED ED ED FF EB EB EB FF E7 E7'
- 'E7 FF E7 E7 E7 FF 00 FF FF FF 00 FF FF FF E7 E7'
- 'E7 FF E7 E7 E7 FF D7 D7 D7 FF C0 C0 C0 FF 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 43 43 43 C2 3C 3C 3C D7 3A 3A'
+ '3A B6 35 35 35 94 35 35 35 73 32 32 32 51 2F 2F'
+ '2F 30 2D 2D 2D 11 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 48 48 48 66 3F 3F 3F FE 45 45 45 FF 4C 4C'
+ '4C FF 45 45 45 FF 43 43 43 FF 3A 3A 3A FF 42 42'
+ '42 FE 3E 3E 3E FB 3D 3D 3D EB 40 40 40 CA 43 43'
+ '43 A9 47 47 47 87 49 49 49 65 47 47 47 44 48 48'
+ '48 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 3E 3E 3E E7 41 41 41 FF 46 46 46 FF 47 47'
+ '47 FF 40 40 40 FF 41 41 41 FF 46 46 46 FF 52 52'
+ '52 FF 45 45 45 FF 56 56 56 FF 5B 5B 5B FF 5C 5C'
+ '5C FF 5B 5B 5B FF 59 59 59 FF 57 57 57 FF 55 55'
+ '55 FE 52 52 52 F6 50 50 50 DE 50 50 50 BD 53 53'
+ '53 9B 55 55 55 7A 56 56 56 58 53 53 53 37 4D 4D'
+ '4D 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 78 78 78 13 4B 4B'
+ '4B 99 3D 3D 3D FF 42 42 42 FF 49 49 49 FF 3A 3A'
+ '3A FF 4A 4A 4A FF 42 42 42 FF 4A 4A 4A FF 51 51'
+ '51 FF 4A 4A 4A FF 58 58 58 FF 4F 4F 4F FF 55 55'
+ '55 FF 5B 5B 5B FF 58 58 58 FF 61 61 61 FF 61 61'
+ '61 FF 63 63 63 FF 63 63 63 FF 5C 5C 5C FF 67 67'
+ '67 FF 5F 5F 5F FF 63 63 63 FF 6B 6B 6B FF 6B 6B'
+ '6B FD 6B 6B 6B CF 42 42 42 36 2A 2A 2A 73 4E 4E'
+ '4E D0 66 66 66 FC 6E 6E 6E FD 54 54 54 F8 4D 4D'
+ '4D F4 58 58 58 DA 61 61 61 B9 6D 6D 6D 98 7B 7B'
+ '7B 76 90 90 90 55 9C 9C 9C 34 A5 A5 A5 14 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 67 67 67 3B 3D 3D'
+ '3D FF 3E 3E 3E FF 45 45 45 FF 34 34 34 FF 48 48'
+ '48 FF 3E 3E 3E FF 48 48 48 FF 4C 4C 4C FF 4E 4E'
+ '4E FF 51 51 51 FF 57 57 57 FF 51 51 51 FF 57 57'
+ '57 FF 5C 5C 5C FF 57 57 57 FF 5F 5F 5F FF 63 63'
+ '63 FF 5F 5F 5F FF 62 62 62 FF 66 66 66 FF 60 60'
+ '60 FF 60 60 60 FF 66 66 66 FF 62 62 62 FF 63 63'
+ '63 FF 36 36 36 F4 25 25 25 FD 25 25 25 FF 54 54'
+ '54 FF 6E 6E 6E FF 7C 7C 7C FF 47 47 47 FF 2D 2D'
+ '2D FF 3C 3C 3C FF 44 44 44 FF 3B 3B 3B FF 33 33'
+ '33 FF 30 30 30 FF 3B 3B 3B FF 45 45 45 FD 4E 4E'
+ '4E ED 52 52 52 CF 65 65 65 AD 8C 8C 8C 57 00 00'
+ '00 00 00 00 00 00 00 00 00 00 51 51 51 71 4A 4A'
+ '4A D3 48 48 48 E2 4C 4C 4C F4 45 45 45 FF 4D 4D'
+ '4D FF 43 43 43 FF 4E 4E 4E FF 49 49 49 FF 4A 4A'
+ '4A FF 56 56 56 FF 4F 4F 4F FF 55 55 55 FF 5B 5B'
+ '5B FF 53 53 53 FF 57 57 57 FF 5D 5D 5D FF 5D 5D'
+ '5D FF 60 60 60 FF 64 64 64 FF 68 68 68 FF 67 67'
+ '67 FF 65 65 65 FF 69 69 69 FF 60 60 60 FF 32 32'
+ '32 FF 26 26 26 FF 26 26 26 FF 27 27 27 FF 56 56'
+ '56 FF 72 72 72 FF 7F 7F 7F FF 49 49 49 FF 2F 2F'
+ '2F FF 5A 5A 5A FF 60 60 60 FF 5B 5B 5B FF 5D 5D'
+ '5D FF 6D 6D 6D FF 68 68 68 FF 47 47 47 FF 45 45'
+ '45 FF 32 32 32 FF 4B 4B 4B FF A2 A2 A2 DD 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 89 89 89 1A 6C 6C 6C FD 0D 0D'
+ '0D FF 13 13 13 FF 1B 1B 1B FF 22 22 22 FF 29 29'
+ '29 FF 32 32 32 FF 35 35 35 FF 40 40 40 FF 48 48'
+ '48 FF 50 50 50 F3 67 67 67 D3 68 68 68 E4 61 61'
+ '61 F7 62 62 62 FF 65 65 65 FF 68 68 68 FF 66 66'
+ '66 FF 66 66 66 FF 5C 5C 5C FF 2D 2D 2D FF 29 29'
+ '29 FF 29 29 29 FF 29 29 29 FF 29 29 29 FF 58 58'
+ '58 FF 75 75 75 FF 82 82 82 FF 4C 4C 4C FF 30 30'
+ '30 FF 45 45 45 FF 5A 5A 5A FF 61 61 61 FF 5E 5E'
+ '5E FF 5D 5D 5D FF 62 62 62 FF 4F 4F 4F FF 4E 4E'
+ '4E FF 34 34 34 FF 4D 4D 4D FF A8 A8 A8 EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 78 78 78 EF 04 04'
+ '04 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
  '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 73 00 00'
- '00 FF 7E 7E 7E FF EF EF EF FF D1 D1 D1 FF CF CF'
- 'CF FF CB CB CB FF CF CF CF FF D1 D1 D1 FF CE CE'
- 'CE FF CF CF CF FF DF DF DF FF F0 F0 F0 FF EC EC'
- 'EC FF E1 E1 E1 FF DE DE DE FF DD DD DD FF DC DC'
- 'DC FF DB DB DB FF DB DB DB FF DC DC DC FF DD DD'
- 'DD FF DE DE DE FF E1 E1 E1 FF EC EC EC FF F1 F1'
- 'F1 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 59 00 00'
- '00 FF 59 59 59 FF E9 E9 E9 FF D0 D0 D0 FF CD CD'
- 'CD FF CD CD CD FF CD CD CD FF CA CA CA FF D6 D6'
- 'D6 FF ED ED ED FF E6 E6 E6 FF DC DC DC FF D4 D4'
- 'D4 FF D5 D5 D5 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D5 D5 D5 FF D5 D5 D5 FF DB DB'
- 'DB FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 80 80 80 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3E 00 00'
- '00 FE 40 40 40 FF D7 D7 D7 FF D2 D2 D2 FF CA CA'
- 'CA FF CB CB CB FF CA CA CA FF D4 D4 D4 FF E9 E9'
- 'E9 FF DC DC DC FF D0 D0 D0 FF D1 D1 D1 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2'
- 'D2 FF D2 D2 D2 FF D2 D2 D2 FF D2 D2 D2 FF D1 D1'
- 'D1 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
- 'FF FF 99 99 99 FF C0 C0 C0 FF 00 00 00 FF 00 00'
+ '00 FF 0D 0D 0D E2 2D 2D 2D 6A 2A 2A 2A B9 2A 2A'
+ '2A F8 2D 2D 2D FF 33 33 33 FF 39 39 39 FF 3E 3E'
+ '3E FF 40 40 40 FF 2C 2C 2C FF 2A 2A 2A FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2C 2C 2C FF 5B 5B'
+ '5B FF 78 78 78 FF 85 85 85 FF 4E 4E 4E FF 30 30'
+ '30 FF 31 31 31 FF 32 32 32 FF 32 32 32 FF 33 33'
+ '33 FF 33 33 33 FF 33 33 33 FF 33 33 33 FF 37 37'
+ '37 FF 35 35 35 FF 4E 4E 4E FF AA AA AA EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 7E 7E 7E D3 13 13'
+ '13 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
  '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 25 00 00'
- '00 F8 22 22 22 FF B7 B7 B7 FF DB DB DB FF CA CA'
- 'CA FF CB CB CB FF CE CE CE FF E4 E4 E4 FF D4 D4'
- 'D4 FF CF CF CF FF D1 D1 D1 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CD CD'
- 'CD FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF CE CE CE FF CE CE CE FF CE CE'
- 'CE FF CE CE CE FF 00 FF FF FF 00 FF FF FF CF CF'
- 'CF FF CF CF CF FF 99 99 99 FF C0 C0 C0 FF 00 00'
+ '00 FF 0C 0C 0C FF 2B 2B 2B FF 28 28 28 FF 28 28'
+ '28 FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2B 2B 2B FF 2C 2C 2C FF 2D 2D'
+ '2D FF 2D 2D 2D FF 2D 2D 2D FF 2E 2E 2E FF 5E 5E'
+ '5E FF 7B 7B 7B FF 89 89 89 FF 50 50 50 FF 31 31'
+ '31 FF 32 32 32 FF 33 33 33 FF 33 33 33 FF 34 34'
+ '34 FF 34 34 34 FF 35 35 35 FF 36 36 36 FF 36 36'
+ '36 FF 36 36 36 FF 50 50 50 FF AE AE AE EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 84 84 84 B3 26 26'
+ '26 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
  '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 E1 07 07 07 FF 9F 9F 9F FF DD DD DD FF CC CC'
- 'CC FF CD CD CD FF DB DB DB FF D6 D6 D6 FF CE CE'
- 'CE FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF CF FF CC CC'
- 'CC FF C9 C9 C9 FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF CA CA CA FF CA CA'
- 'CA FF CA CA CA FF CA CA CA FF C8 C8 C8 FF CF CF'
- 'CF FF 00 80 80 FF 00 80 80 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 FF 06 06 06 FF 2E 2E 2E FF 29 29 29 FF 29 29'
+ '29 FF 2A 2A 2A FF 2D 2D 2D FF 2D 2D 2D FF 2C 2C'
+ '2C FF 2B 2B 2B FF 2C 2C 2C FF 2D 2D 2D FF 2E 2E'
+ '2E FF 2E 2E 2E FF 2F 2F 2F FF 30 30 30 FF 60 60'
+ '60 FF 7E 7E 7E FF 8C 8C 8C FF 53 53 53 FF 31 31'
+ '31 FF 32 32 32 FF 34 34 34 FF 34 34 34 FF 35 35'
+ '35 FF 35 35 35 FF 36 36 36 FF 36 36 36 FF 37 37'
+ '37 FF 37 37 37 FF 51 51 51 FF B4 B4 B4 EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 8C 8C 8C 93 3B 3B'
+ '3B FF 06 06 06 FF 03 03 03 FF 01 01 01 FF 01 01'
+ '01 FF 00 00 00 FF 01 01 01 FF 00 00 00 FF 00 00'
+ '00 FF 06 06 06 FF 2D 2D 2D FF 29 29 29 FF 29 29'
+ '29 FF 2B 2B 2B FF 2D 2D 2D FF 2D 2D 2D FF 2D 2D'
+ '2D FF 2C 2C 2C FF 2D 2D 2D FF 2F 2F 2F FF 2F 2F'
+ '2F FF 30 30 30 FF 30 30 30 FF 31 31 31 FF 62 62'
+ '62 FF 80 80 80 FF 8F 8F 8F FF 8A 8A 8A FF 88 88'
+ '88 FF 82 82 82 FF 78 78 78 FF 71 71 71 FF 65 65'
+ '65 FF 5A 5A 5A FF 5F 5F 5F FF 5A 5A 5A FF 54 54'
+ '54 FF 4B 4B 4B FF 5D 5D 5D FF B5 B5 B5 EB 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 94 94 94 75 51 51'
+ '51 FF 0E 0E 0E FF 2E 2E 2E 90 8B 8B 8B 4D 7E 7E'
+ '7E 57 71 71 71 63 5F 5F 5F 6D 58 58 58 C3 28 28'
+ '28 FF 0A 0A 0A FF 2A 2A 2A FF 29 29 29 FF 29 29'
+ '29 FF 2C 2C 2C FF 2E 2E 2E FF 2E 2E 2E FF 2E 2E'
+ '2E FF 2D 2D 2D FF 2E 2E 2E FF 30 30 30 FF 30 30'
+ '30 FF 31 31 31 FF 31 31 31 FF 32 32 32 FF 64 64'
+ '64 FF 84 84 84 FF 92 92 92 FF 8F 8F 8F FF 51 CB'
+ '51 FF 8A 8A 8A FF 8F 8F 8F FF 8D 8D 8D FF 88 88'
+ '88 FF 8F 8F 8F FF 97 97 97 FF 9B 9B 9B FF 9B 9B'
+ '9B FF 99 99 99 FF A2 A2 A2 FF B8 B8 B8 EB 5C 5C'
+ '5C A5 B4 B4 B4 F2 C5 DD C5 EC 51 CB 51 EA 87 BE'
+ '87 E5 D1 D1 D1 E5 CC CC CC E5 C8 C8 C8 F3 BC BC'
+ 'BC FF B8 B8 B8 FF C0 C0 C0 F3 C5 C5 C5 EC BE BE'
+ 'BE E9 C7 C7 C7 E5 C6 C6 C6 E5 BC BC BC ED AF AF'
+ 'AF FF 9A 9A 9A FF 9C 9C 9C FF 95 95 95 FF 8D 8D'
+ '8D FF 88 88 88 FF 86 86 86 FF 82 82 82 FF 80 80'
+ '80 FF 7B 7B 7B FF 7B 7B 7B FF 7B 7B 7B FF 7A 7A'
+ '7A FF 78 78 78 FF 4E 4E 4E FF 32 32 32 FF 66 66'
+ '66 FF 87 87 87 FF 95 95 95 FF 96 96 96 FF 99 99'
+ '99 FF 98 98 98 FF 96 96 96 FF 93 93 93 FF 8E 8E'
+ '8E FF A0 A0 A0 FF 9B 9B 9B FF 9F 9F 9F FF 9F 9F'
+ '9F FF A0 A0 A0 FF A7 A7 A7 FF BC BC BC EB 46 46'
+ '46 B2 B4 B4 B4 FF C4 C1 B8 FF AE 9E 71 FF AF 9F'
+ '72 FF AE 9E 71 FF AB 9B 6F FF AB 9A 6F FF AA 99'
+ '6F FF A8 97 6E FF A5 93 6B FF A6 94 6C FF A3 91'
+ '6A FF A1 8F 6A FF 9D 8B 67 FF 9A 88 66 FF 98 86'
+ '64 FF 95 84 64 FF 94 83 63 FF 91 81 63 FF 8F 7F'
+ '62 FF 8D 7E 63 FF 8C 7D 63 FF 8C 7D 63 FF 8C 7D'
+ '63 FF 8B 7C 63 FF 8A 7B 63 FF 8A 7B 63 FF 86 78'
+ '61 FF 88 87 86 FF 59 59 59 FF 32 32 32 FF 67 67'
+ '67 FF 89 89 89 FF 98 98 98 FF 5F 5F 5F FF 40 40'
+ '40 FF 43 43 43 FF 4C 4C 4C FF 53 53 53 FF 56 56'
+ '56 FF 65 65 65 FF 68 68 68 FF 69 69 69 FF 6F 6F'
+ '6F FF 74 74 74 FF 83 83 83 FF C2 C2 C2 EB 43 43'
+ '43 B2 B3 B3 B3 FF B2 AA 96 FF 9C 79 1D FF 9C 78'
+ '1D FF 9B 77 1C FF 99 75 1B FF 97 72 19 FF 94 6F'
+ '17 FF 92 6B 15 FF 8F 67 12 FF 8C 63 10 FF 89 60'
+ '0D FF 86 5B 0B FF 84 58 09 FF 82 56 07 FF 80 53'
+ '06 FF 7F 52 05 FF 7E 51 04 FF 7E 50 04 FF 7E 50'
+ '04 FF 7E 50 04 FF 7E 51 04 FF 7F 52 05 FF 80 53'
+ '05 FF 80 54 06 FF 81 54 06 FF 82 56 07 FF 7F 54'
+ '07 FF 7D 7A 78 FF 54 54 54 FF 33 33 33 FF 69 69'
+ '69 FF 8C 8C 8C FF 9B 9B 9B FF 5E 5E 5E FF 38 38'
+ '38 FF 39 39 39 FF 3A 3A 3A FF 3A 3A 3A FF 3B 3B'
+ '3B FF 3C 3C 3C FF 3C 3C 3C FF 3D 3D 3D FF 3D 3D'
+ '3D FF 3D 3D 3D FF 56 56 56 FF C9 C9 C9 EB 47 47'
+ '47 B9 B2 B2 B2 FF B0 A6 91 FF 98 73 19 FF 97 72'
+ '19 FF 96 71 18 FF 94 6F 17 FF 93 6C 15 FF 91 69'
+ '14 FF 8F 67 12 FF 8C 63 10 FF 8A 60 0E FF 87 5C'
+ '0B FF 85 59 09 FF 83 57 08 FF 82 55 07 FF 81 54'
+ '06 FF 80 53 05 FF 7F 52 05 FF 7F 52 05 FF 7F 52'
+ '05 FF 80 53 06 FF 80 54 06 FF 81 55 07 FF 82 56'
+ '07 FF 82 56 08 FF 83 57 08 FF 84 58 09 FF 7E 55'
+ '0A FF 81 81 81 FF 50 50 50 FF 33 33 33 FF 6A 6A'
+ '6A FF 8F 8F 8F FF 9E 9E 9E FF 5F 5F 5F FF 39 39'
+ '39 FF 3A 3A 3A FF 3B 3B 3B FF 3C 3C 3C FF 3C 3C'
+ '3C FF 3D 3D 3D FF 3D 3D 3D FF 3E 3E 3E FF 3E 3E'
+ '3E FF 3F 3F 3F FF 57 57 57 FF CE CE CE EB 48 48'
+ '48 BD B1 B1 B1 FF AC A2 8B FF 92 6C 15 FF 92 6B'
+ '15 FF 91 6A 14 FF 90 69 13 FF 8F 67 12 FF 8D 65'
+ '11 FF 8C 63 0F FF 8A 60 0E FF 88 5D 0C FF 85 5A'
+ '0A FF 84 58 09 FF 83 57 08 FF 82 56 07 FF 81 55'
+ '07 FF 81 55 07 FF 81 55 07 FF 81 55 07 FF 82 56'
+ '07 FF 83 57 08 FF 84 58 09 FF 84 58 09 FF 85 59'
+ '0A FF 85 5A 0A FF 86 5B 0B FF 87 5C 0C FF 7F 57'
+ '0D FF 8A 8A 8A FF 4D 4D 4D FF 32 32 32 FF 6B 6B'
+ '6B FF 91 91 91 FF A0 A0 A0 FF 61 61 61 FF 3B 3B'
+ '3B FF 3C 3C 3C FF 3D 3D 3D FF 3E 3E 3E FF 3E 3E'
+ '3E FF 3F 3F 3F FF 3F 3F 3F FF 40 40 40 FF 40 40'
+ '40 FF 40 40 40 FF 58 58 58 FF D2 D2 D2 EB 49 49'
+ '49 C1 AE AE AE FF A8 9C 85 FF 8E 66 11 FF 8E 65'
+ '11 FF 8D 65 10 FF 8C 63 10 FF 8B 62 0F FF 8A 60'
+ '0E FF 88 5E 0D FF 87 5C 0B FF 85 5A 0A FF 84 58'
+ '09 FF 83 57 08 FF 82 57 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 57 08 FF 84 58 08 FF 84 58 09 FF 85 59'
+ '0A FF 86 5B 0B FF 87 5C 0B FF 88 5D 0C FF 88 5E'
+ '0D FF 89 5F 0D FF 8A 60 0E FF 8B 61 0F FF 7D 58'
+ '11 FF 96 96 96 FF 47 47 47 FF 31 31 31 FF 6D 6D'
+ '6D FF 94 94 94 FF A3 A3 A3 FF 63 63 63 FF 3C 3C'
+ '3C FF 3B 3B 3B FF 37 37 37 FF 38 38 38 FF 39 39'
+ '39 FF 3A 3A 3A FF 3B 3B 3B FF 3E 3E 3E FF 40 40'
+ '40 FF 41 41 41 FF 59 59 59 FF D7 D7 D7 EB 48 48'
+ '48 C1 AC AC AC FF A3 96 7E FF 89 5F 0D FF 89 5F'
+ '0D FF 88 5E 0D FF 88 5E 0C FF 87 5D 0C FF 87 5C'
+ '0B FF 86 5B 0B FF 85 59 0A FF 84 58 09 FF 83 58'
+ '08 FF 83 57 08 FF 83 57 08 FF 84 58 09 FF 84 59'
+ '09 FF 85 59 0A FF 86 5B 0B FF 87 5C 0B FF 88 5E'
+ '0C FF 89 5F 0D FF 8A 61 0E FF 8C 63 0F FF 8C 64'
+ '10 FF 8D 65 10 FF 8E 66 11 FF 8E 66 12 FF 7C 5B'
+ '17 FF A1 A1 A1 FF 41 41 41 FF 31 31 31 FF 6F 6F'
+ '6F FF 97 97 97 FF A6 A6 A6 FF 65 65 65 FF 3D 3D'
+ '3D FF 3C 3C 3C FF 42 42 42 FF 44 44 44 FF 46 46'
+ '46 FF 47 47 47 FF 45 45 45 FF 40 40 40 FF 40 40'
+ '40 FF 42 42 42 FF 5A 5A 5A FF DC DC DC EB 47 47'
+ '47 C1 A9 A9 A9 FF 9E 90 78 FF 85 5A 0A FF 85 59'
+ '0A FF 84 59 09 FF 84 58 09 FF 84 58 09 FF 84 58'
+ '09 FF 84 58 09 FF 83 57 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 58 08 FF 84 58 09 FF 85 5A 0A FF 86 5C'
+ '0B FF 87 5D 0C FF 89 5F 0D FF 8A 61 0E FF 8C 63'
+ '10 FF 8D 64 10 FF 8F 67 12 FF 90 68 13 FF 90 69'
+ '13 FF 91 6A 14 FF 92 6B 15 FF 92 6C 15 FF 7F 60'
+ '1E FF AB AB AB FF 3B 3B 3B FF 32 32 32 FF 71 71'
+ '71 FF 9A 9A 9A FF A8 A8 A8 FF 67 67 67 FF 3D 3D'
+ '3D FF 3E 3E 3E FF 3E 3E 3E FF 3F 3F 3F FF 40 40'
+ '40 FF 41 41 41 FF 41 41 41 FF 42 42 42 FF 42 42'
+ '42 FF 43 43 43 FF 5B 5B 5B FF E0 E0 E0 EB 47 47'
+ '47 C3 A6 A6 A6 FF 9A 8B 72 FF 82 56 07 FF 82 56'
+ '07 FF 81 55 07 FF 81 55 07 FF 81 55 07 FF 82 56'
+ '07 FF 82 56 07 FF 82 56 07 FF 82 57 08 FF 83 57'
+ '08 FF 84 58 09 FF 86 5B 0B FF 87 5D 0C FF 89 5F'
+ '0D FF 8B 61 0F FF 8C 64 10 FF 8E 66 11 FF 90 68'
+ '13 FF 91 6A 14 FF 93 6D 16 FF 94 6E 16 FF 95 6F'
+ '17 FF 96 70 18 FF 96 71 18 FF 97 72 19 FF 81 64'
+ '24 FF B5 B5 B5 FF 35 35 35 FF 32 32 32 FF 72 72'
+ '72 FF 9C 9C 9C FF AB AB AB FF 69 69 69 FF 3F 3F'
+ '3F FF 40 40 40 FF 40 40 40 FF 41 41 41 FF 42 42'
+ '42 FF 43 43 43 FF 43 43 43 FF 45 45 45 FF 45 45'
+ '45 FF 46 46 46 FF 5F 5F 5F FF E4 E4 E4 EB 49 49'
+ '49 C8 A2 A2 A2 FF 95 86 6D FF 7F 52 05 FF 7E 51'
+ '04 FF 7E 51 04 FF 7F 52 05 FF 7F 52 05 FF 80 53'
+ '06 FF 81 54 06 FF 81 55 07 FF 83 57 08 FF 84 58'
+ '09 FF 86 5B 0B FF 88 5E 0C FF 8A 61 0E FF 8C 64'
+ '10 FF 8E 66 12 FF 90 68 13 FF 92 6B 14 FF 94 6E'
+ '16 FF 96 70 18 FF 98 73 19 FF 99 75 1A FF 9A 75'
+ '1B FF 9A 77 1C FF 9B 77 1C FF 9B 77 1C FF 7F 66'
+ '2B FF B9 B9 B9 FF 32 32 32 FF 33 33 33 FF 74 74'
+ '74 FF 9F 9F 9F FF AE AE AE FF 6B 6B 6B FF 40 40'
+ '40 FF 41 41 41 FF 41 41 41 FF 42 42 42 FF 44 44'
+ '44 FF 44 44 44 FF 45 45 45 FF 45 45 45 FF 47 47'
+ '47 FF 49 49 49 FF 62 62 62 FF E4 E4 E4 EB 48 48'
+ '48 C8 9F 9F 9F FF 91 81 68 FF 7D 4E 03 FF 7C 4D'
+ '02 FF 7C 4E 03 FF 7D 4F 03 FF 7E 50 04 FF 7F 52'
+ '05 FF 81 54 06 FF 82 56 07 FF 84 58 08 FF 86 5A'
+ '0A FF 88 5E 0C FF 8B 61 0F FF 8D 65 11 FF 90 68'
+ '13 FF 92 6B 15 FF 94 6E 17 FF 96 71 18 FF 98 74'
+ '1A FF 9A 77 1C FF 9C 78 1D FF 9D 7A 1E FF 9E 7C'
+ '1F FF 9F 7D 20 FF A0 7E 20 FF 9F 7E 20 FF 84 6C'
+ '33 FF B9 B9 B9 FF 33 33 33 FF 33 33 33 FF 75 75'
+ '75 FF A1 A1 A1 FF B0 B0 B0 FF 6D 6D 6D FF 41 41'
+ '41 FF 42 42 42 FF 43 43 43 FF 43 43 43 FF 44 44'
+ '44 FF 45 45 45 FF 46 46 46 FF 48 48 48 FF 4A 4A'
+ '4A FF 4B 4B 4B FF 63 63 63 FF E6 E6 E6 EB 4B 4B'
+ '4B CE 9D 9D 9D FF 8D 7C 63 FF 7A 4B 01 FF 7A 4B'
+ '00 FF 7B 4C 01 FF 7C 4E 03 FF 7E 4F 03 FF 7F 52'
+ '05 FF 81 55 07 FF 83 57 08 FF 85 5A 0A FF 88 5D'
+ '0C FF 8B 61 0E FF 8D 65 11 FF 90 69 13 FF 93 6D'
+ '16 FF 96 71 18 FF 98 74 1A FF 9A 77 1C FF 9D 7A'
+ '1E FF 9F 7D 1F FF A0 7F 21 FF A2 81 22 FF A3 83'
+ '23 FF A4 84 24 FF A4 84 24 FF A4 84 24 FF 85 70'
+ '3A FF BA BA BA FF 33 33 33 FF 33 33 33 FF 77 77'
+ '77 FF A3 A3 A3 FF B3 B3 B3 FF 6E 6E 6E FF 41 41'
+ '41 FF 43 43 43 FF 44 44 44 FF 45 45 45 FF 46 46'
+ '46 FF 47 47 47 FF 49 49 49 FF 4B 4B 4B FF 4D 4D'
+ '4D FF 4E 4E 4E FF 66 66 66 FF E4 E4 E4 EB 4A 4A'
+ '4A D0 99 99 99 FF 8A 78 5E FF 79 49 00 FF 79 49'
+ '00 FF 7A 4A 00 FF 7C 4D 02 FF 7E 4F 03 FF 7F 52'
+ '05 FF 82 55 07 FF 84 58 09 FF 86 5C 0B FF 89 60'
+ '0D FF 8D 65 10 FF 90 68 13 FF 93 6D 16 FF 96 72'
+ '18 FF 9A 76 1B FF 9C 79 1E FF 9F 7D 1F FF A1 80'
+ '21 FF A3 83 23 FF A6 86 25 FF A7 88 27 FF A9 8A'
+ '28 FF AA 8B 29 FF AA 8C 29 FF AA 8B 29 FF 87 75'
+ '44 FF B6 B6 B6 FF 33 33 33 FF 34 34 34 FF 78 78'
+ '78 FF A4 A4 A4 FF B5 B5 B5 FF 71 71 71 FF 41 41'
+ '41 FF 42 42 42 FF 44 44 44 FF 45 45 45 FF 46 46'
+ '46 FF 48 48 48 FF 4A 4A 4A FF 4C 4C 4C FF 4E 4E'
+ '4E FF 50 50 50 FF 67 67 67 FF E4 E4 E4 EB 49 49'
+ '49 D0 96 96 96 FF 88 76 59 FF 79 49 00 FF 79 49'
+ '00 FF 79 4A 00 FF 7C 4D 02 FF 7D 4F 03 FF 80 53'
+ '05 FF 82 56 07 FF 85 59 0A FF 88 5E 0C FF 8C 63'
+ '0F FF 8F 67 12 FF 93 6C 15 FF 96 71 18 FF 9A 76'
+ '1B FF 9D 7A 1E FF A0 7F 21 FF A3 83 23 FF A6 86'
+ '26 FF A9 8A 28 FF AB 8D 2A FF AD 90 2B FF AE 92'
+ '2C FF AF 93 2D FF AF 93 2D FF AF 92 2D FF 8F 7E'
+ '50 FF B0 B0 B0 FF 34 34 34 FF 35 35 35 FF 79 79'
+ '79 FF A6 A6 A6 FF B6 B6 B6 FF 74 74 74 FF 43 43'
+ '43 FF 44 44 44 FF 45 45 45 FF 47 47 47 FF 49 49'
+ '49 FF 4C 4C 4C FF 4E 4E 4E FF 50 50 50 FF 52 52'
+ '52 FF 53 53 53 FF 6A 6A 6A FF E4 E4 E4 EB 48 48'
+ '48 D0 93 93 93 FF 87 73 55 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7D 4F 03 FF 80 53'
+ '06 FF 83 57 08 FF 86 5B 0B FF 8A 60 0E FF 8D 65'
+ '11 FF 92 6A 14 FF 95 70 18 FF 99 75 1B FF 9D 7A'
+ '1E FF A0 7F 21 FF A4 83 24 FF A7 88 27 FF AB 8D'
+ '29 FF AD 90 2C FF AF 93 2D FF B1 96 2F FF B3 98'
+ '31 FF B4 9A 32 FF B4 9A 32 FF B4 99 31 FF 95 86'
+ '5B FF A9 A9 A9 FF 34 34 34 FF 35 35 35 FF 7A 7A'
+ '7A FF A7 A7 A7 FF B8 B8 B8 FF 75 75 75 FF 44 44'
+ '44 FF 45 45 45 FF 47 47 47 FF 49 49 49 FF 4C 4C'
+ '4C FF 4E 4E 4E FF 50 50 50 FF 52 52 52 FF 54 54'
+ '54 FF 57 57 57 FF 6C 6C 6C FF E6 E6 E6 EB 47 47'
+ '47 D0 90 90 90 FF 86 72 52 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7E 4F 03 FF 81 54'
+ '06 FF 84 58 09 FF 87 5D 0C FF 8B 62 0F FF 8F 67'
+ '12 FF 93 6D 16 FF 97 73 19 FF 9C 78 1D FF A0 7E'
+ '20 FF A3 83 23 FF A7 88 27 FF AB 8E 2A FF AF 92'
+ '2D FF B2 96 30 FF B4 9A 32 FF B7 9E 34 FF B9 A0'
+ '36 FF BA A2 37 FF BA A2 37 FF B9 A1 36 FF 98 8C'
+ '66 FF A4 A4 A4 FF 35 35 35 FF 36 36 36 FF 7A 7A'
+ '7A FF A9 A9 A9 FF BA BA BA FF 75 75 75 FF 44 44'
+ '44 FF 45 45 45 FF 48 48 48 FF 4B 4B 4B FF 4D 4D'
+ '4D FF 4F 4F 4F FF 52 52 52 FF 55 55 55 FF 56 56'
+ '56 FF 58 58 58 FF 6D 6D 6D FF E6 E6 E6 EB 4A 4A'
+ '4A D7 8E 8E 8E FF 86 70 50 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7E 50 04 FF 81 55'
+ '07 FF 85 59 0A FF 89 5E 0D FF 8D 64 10 FF 91 69'
+ '14 FF 95 70 17 FF 99 75 1B FF 9E 7C 1F FF A2 81'
+ '22 FF A6 87 26 FF AB 8D 2A FF AE 92 2D FF B3 97'
+ '30 FF B6 9D 33 FF BA A1 36 FF BD A5 39 FF BF A9'
+ '3B FF C1 AB 3C FF C0 AA 3C FF BF A8 3B FF 9D 92'
+ '71 FF 9F 9F 9F FF 35 35 35 FF 36 36 36 FF 7A 7A'
+ '7A FF AA AA AA FF BC BC BC FF 78 78 78 FF 47 47'
+ '47 FF 49 49 49 FF 4C 4C 4C FF 4E 4E 4E FF 51 51'
+ '51 FF 53 53 53 FF 56 56 56 FF 58 58 58 FF 5A 5A'
+ '5A FF 5C 5C 5C FF 6F 6F 6F FF E6 E6 E6 EB 4A 4A'
+ '4A D7 8C 8C 8C FF 85 6F 4E FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7E 50 04 FF 82 55'
+ '07 FF 85 5A 0A FF 89 60 0D FF 8E 66 11 FF 92 6B'
+ '15 FF 96 72 18 FF 9B 77 1C FF 9F 7D 20 FF A4 84'
+ '24 FF A9 8A 28 FF AD 90 2C FF B1 96 2F FF B6 9C'
+ '33 FF BA A2 37 FF BE A7 3A FF C2 AD 3E FF C5 B0'
+ '40 FF C6 B2 41 FF C6 B2 41 FF C5 B1 40 FF A2 98'
+ '79 FF 91 91 91 FF 36 36 36 FF 37 37 37 FF 7A 7A'
+ '7A FF AB AB AB FF BD BD BD FF 79 79 79 FF 48 48'
+ '48 FF 4B 4B 4B FF 4D 4D 4D FF 50 50 50 FF 53 53'
+ '53 FF 55 55 55 FF 58 58 58 FF 5A 5A 5A FF 5D 5D'
+ '5D FF 5F 5F 5F FF 71 71 71 FF E6 E6 E6 EB 4C 4C'
+ '4C DA 8A 8A 8A FF 84 6D 4B FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7E 51 04 FF 82 56'
+ '07 FF 86 5B 0B FF 8A 61 0E FF 8F 67 12 FF 93 6C'
+ '15 FF 98 73 19 FF 9C 79 1D FF A1 7F 21 FF A6 86'
+ '25 FF AB 8D 2A FF AF 93 2D FF B4 9A 32 FF B9 A0'
+ '36 FF BD A6 3A FF C3 AE 3E FF C6 B2 41 FF C9 B5'
+ '43 FF CA B7 44 FF CA B7 44 FF C9 B6 43 FF A4 9B'
+ '83 FF 89 89 89 FF 36 36 36 FF 37 37 37 FF 7B 7B'
+ '7B FF AD AD AD FF BE BE BE FF 7C 7C 7C FF 4A 4A'
+ '4A FF 4D 4D 4D FF 4F 4F 4F FF 52 52 52 FF 55 55'
+ '55 FF 57 57 57 FF 5A 5A 5A FF 5D 5D 5D FF 5F 5F'
+ '5F FF 62 62 62 FF 73 73 73 FF E7 E7 E7 EB 4B 4B'
+ '4B DF 88 88 88 FF 82 6B 49 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 02 FF 7F 51 04 FF 83 57'
+ '08 FF 86 5C 0B FF 8A 61 0E FF 8F 67 12 FF 94 6D'
+ '16 FF 98 74 1A FF 9D 7A 1E FF A1 80 22 FF A7 88'
+ '26 FF AC 8E 2A FF B1 95 2F FF B6 9D 33 FF BB A3'
+ '38 FF C0 AA 3C FF C5 B1 40 FF C8 B5 43 FF CB B9'
+ '45 FF CD BB 46 FF CC BB 46 FF CC BA 46 FF A6 9F'
+ '8C FF 83 83 83 FF 37 37 37 FF 37 37 37 FF 7A 7A'
+ '7A FF AD AD AD FF BF BF BF FF 80 80 80 FF 4C 4C'
+ '4C FF 4E 4E 4E FF 51 51 51 FF 54 54 54 FF 57 57'
+ '57 FF 59 59 59 FF 5C 5C 5C FF 5E 5E 5E FF 61 61'
+ '61 FF 62 62 62 FF 73 73 73 FF E7 E7 E7 EB 49 49'
+ '49 DF 87 87 87 FF 81 69 46 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7F 51 04 FF 83 57'
+ '08 FF 87 5C 0B FF 8B 62 0F FF 8F 68 13 FF 94 6E'
+ '16 FF 99 75 1B FF 9E 7B 1F FF A2 81 22 FF A7 88'
+ '27 FF AC 8F 2B FF B1 96 2F FF B7 9E 34 FF BC A4'
+ '38 FF C2 AC 3D FF C6 B2 41 FF CA B7 44 FF CD BC'
+ '47 FF CF BD 48 FF CF BE 48 FF CD BB 46 FF AA A3'
+ '94 FF 7C 7C 7C FF 37 37 37 FF 38 38 38 FF 7A 7A'
+ '7A FF AE AE AE FF C0 C0 C0 FF 83 83 83 FF 4E 4E'
+ '4E FF 51 51 51 FF 54 54 54 FF 57 57 57 FF 5A 5A'
+ '5A FF 5C 5C 5C FF 5F 5F 5F FF 62 62 62 FF 64 64'
+ '64 FF 67 67 67 FF 76 76 76 FF E7 E7 E7 EB 46 46'
+ '46 DF 85 85 85 FF 7F 67 44 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7F 51 04 FF 83 57'
+ '08 FF 87 5C 0B FF 8B 62 0F FF 8F 68 13 FF 94 6E'
+ '16 FF 99 75 1B FF 9E 7B 1F FF A2 81 22 FF A7 88'
+ '26 FF AC 8F 2B FF B2 96 2F FF B7 9D 34 FF BC A4'
+ '38 FF C2 AD 3E FF C7 B3 42 FF CB B8 45 FF CE BD'
+ '47 FF CF BE 48 FF D0 BF 49 FF CC BA 45 FF AC A7'
+ '9D FF 77 77 77 FF 37 37 37 FF 38 38 38 FF 79 79'
+ '79 FF AF AF AF FF C1 C1 C1 FF 85 85 85 FF 50 50'
+ '50 FF 52 52 52 FF 55 55 55 FF 58 58 58 FF 5B 5B'
+ '5B FF 5E 5E 5E FF 61 61 61 FF 64 64 64 FF 66 66'
+ '66 FF 69 69 69 FF 77 77 77 FF E7 E7 E7 EB 44 44'
+ '44 DF 83 83 83 FF 7D 65 41 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7E 51 04 FF 83 57'
+ '08 FF 86 5B 0B FF 8B 61 0E FF 8F 67 12 FF 93 6D'
+ '16 FF 98 74 1A FF 9D 7A 1E FF A2 81 22 FF A6 86'
+ '26 FF AB 8E 2A FF B1 95 2F FF B6 9C 33 FF BB A2'
+ '37 FF C1 AB 3C FF C6 B2 41 FF CA B7 44 FF CC BB'
+ '46 FF CF BD 48 FF CF BE 48 FF C8 B4 42 FF AF AC'
+ 'A7 FF 6E 6E 6E FF 37 37 37 FF 39 39 39 FF 79 79'
+ '79 FF AF AF AF FF C2 C2 C2 FF 87 87 87 FF 51 51'
+ '51 FF 54 54 54 FF 57 57 57 FF 5A 5A 5A FF 5D 5D'
+ '5D FF 5F 5F 5F FF 61 61 61 FF 64 64 64 FF 65 65'
+ '65 FF 67 67 67 FF 77 77 77 FF E7 E7 E7 EB 43 43'
+ '43 DF 81 81 81 FF 7D 64 3E FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4B 01 FF 7E 50 04 FF 82 56'
+ '07 FF 86 5A 0A FF 89 60 0E FF 8E 66 11 FF 92 6C'
+ '15 FF 97 72 19 FF 9B 78 1D FF A0 7E 20 FF A5 85'
+ '24 FF A9 8B 28 FF AF 92 2D FF B4 99 31 FF B8 9F'
+ '35 FF BE A7 3A FF C4 AF 3F FF C8 B4 42 FF CA B7'
+ '44 FF CC BA 46 FF CD BC 47 FF BC A8 40 FF B6 B3'
+ 'B0 FF 67 67 67 FF 38 38 38 FF 39 39 39 FF 7A 7A'
+ '7A FF AF AF AF FF C2 C2 C2 FF 88 88 88 FF 54 54'
+ '54 FF 54 54 54 FF 54 54 54 FF 56 56 56 FF 5A 5A'
+ '5A FF 5E 5E 5E FF 61 61 61 FF 64 64 64 FF 64 64'
+ '64 FF 63 63 63 FF 75 75 75 FF E7 E7 E7 EB 42 42'
+ '42 DF 7F 7F 7F FF 7D 63 3A FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 79 4A 00 FF 7D 4E 03 FF 81 54'
+ '06 FF 84 59 09 FF 88 5E 0C FF 8D 64 10 FF 90 69'
+ '14 FF 95 70 17 FF 9A 76 1B FF 9E 7B 1F FF A3 82'
+ '23 FF A7 88 26 FF AC 8F 2B FF AE 93 30 FF A9 92'
+ '38 FF A4 92 44 FF A3 95 53 FF A8 9E 6A FF AF A8'
+ '82 FF B4 B0 98 FF B9 B7 AF FF C4 C4 C3 FF E6 E6'
+ 'E6 FF 5F 5F 5F FF 38 38 38 FF 39 39 39 FF 79 79'
+ '79 FF AF AF AF FF C2 C2 C2 FF 84 84 84 FF 50 50'
+ '50 FF 53 53 53 FF 59 59 59 FF 5C 5C 5C FF 5F 5F'
+ '5F FF 62 62 62 FF 66 66 66 FF 68 68 68 FF 6B 6B'
+ '6B FF 6E 6E 6E FF 77 77 77 FF E9 E9 E9 EB 3E 3E'
+ '3E DF 7E 7E 7E FF 7D 61 37 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 79 49 00 FF 7B 4D 02 FF 7F 52'
+ '05 FF 83 57 08 FF 86 5B 0B FF 89 60 0E FF 88 63'
+ '15 FF 86 67 23 FF 86 6D 32 FF 89 75 46 FF 91 83'
+ '5E FF 9B 92 79 FF A6 A2 95 FF B3 B2 AF FF C5 C5'
+ 'C5 FF D7 D7 D7 FF E4 E4 E4 FC EA EA EA EA E3 E3'
+ 'E3 D5 B5 B5 B5 F7 9A 9A 9A FF 81 81 81 FF 68 68'
+ '68 FF 3B 3B 3B FF 38 38 38 FF 3A 3A 3A FF 79 79'
+ '79 FF AF AF AF FF C2 C2 C2 FF 86 86 86 FF 57 57'
+ '57 FF 57 57 57 FF 5B 5B 5B FF 5F 5F 5F FF 63 63'
+ '63 FF 64 64 64 FF 66 66 66 FF 67 67 67 FF 6A 6A'
+ '6A FF 6C 6C 6C FF 76 76 76 FF E9 E9 E9 EB 3D 3D'
+ '3D DF 7C 7C 7C FF 7B 5F 34 FF 78 48 00 FF 76 48'
+ '02 FF 73 4A 0C FF 73 50 1C FF 76 5A 2E FF 7B 66'
+ '43 FF 81 72 59 FF 87 7E 6F FF 8F 8C 86 FF 9B 9A'
+ '9A FF A9 A9 A9 FF B6 B6 B6 FF C2 C2 C2 FB CA CA'
+ 'CA EA D2 D2 D2 C8 D7 D7 D7 A2 DC DC DC 76 E0 E0'
+ 'E0 54 E0 E0 E0 32 E2 E2 E2 12 00 00 00 00 00 00'
+ '00 00 43 43 43 13 3C 3C 3C 55 39 39 39 9F 39 39'
+ '39 E4 39 39 39 FE 39 39 39 FF 3B 3B 3B FF 79 79'
+ '79 FF AE AE AE FF C1 C1 C1 FF 88 88 88 FF 54 54'
+ '54 FF 5B 5B 5B FF 6D 6D 6D FF 79 79 79 FF 8B 8B'
+ '8B FF 96 96 96 FF A9 A9 A9 FF B7 B7 B7 FF C4 C4'
+ 'C4 FF D2 D2 D2 FF DA DA DA FF E6 E6 E6 EB 3E 3E'
+ '3E DE 79 79 79 FF 7A 73 6A FF 78 72 6A FF 80 7E'
+ '7C FF 89 89 89 FF 90 90 90 FF 95 95 95 FE 99 99'
+ '99 F6 9F 9F 9F DA A3 A3 A3 B8 A8 A8 A8 96 AD AD'
+ 'AD 74 B4 B4 B4 52 BB BB BB 31 BB BB BB 13 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 B2 00 00 00 FF 83 83 83 FF DD DD DD FF CF CF'
- 'CF FF D1 D1 D1 FF DB DB DB FF D1 D1 D1 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0'
- 'D0 FF D0 D0 D0 FF D0 D0 D0 FF D0 D0 D0 FF CF CF'
- 'CF FF C9 C9 C9 FF C5 C5 C5 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6'
- 'C6 FF C6 C6 C6 FF C6 C6 C6 FF C6 C6 C6 FF C7 C7'
- 'C7 FF 00 80 80 FF 00 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 80 00 00 00 FF 5F 5F 5F FF DC DC DC FF D1 D1'
- 'D1 FF D2 D2 D2 FF D4 D4 D4 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1 D1 FF D1 D1'
- 'D1 FF D0 D0 D0 FF C8 C8 C8 FF C3 C3 C3 FF C3 C3'
- 'C3 FF C3 C3 C3 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4 C4 FF C4 C4'
- 'C4 FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF'
- 'FF FF 09 09 09 FF C0 C0 C0 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 3D 00 00 00 0C 00 00 00 00 00 00'
+ '00 00 3C 3C 3C 33 3B 3B 3B 7C 3C 3C 3C C6 7A 7A'
+ '7A FA AD AD AD FF C1 C1 C1 FF CE CE CE FF D7 D7'
+ 'D7 FF DC DC DC FF D9 D9 D9 FF E4 E4 E4 FF EB EB'
+ 'EB FF EE EE EE FE EE EE EE FE EE EE EE FB F0 F0'
+ 'F0 F4 F0 F0 F0 E5 EF EF EF D3 E5 E5 E5 9E 4F 4F'
+ '4F 6D 78 78 78 F1 81 81 81 D6 88 88 88 B2 8C 8C'
+ '8C 8E 91 91 91 69 97 97 97 45 A2 A2 A2 21 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 4B 00 00 00 FE 41 41 41 FF D8 D8 D8 FF D4 D4'
- 'D4 FF D2 D2 D2 FF D0 D0 D0 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3 D3 FF D3 D3'
- 'D3 FF D3 D3 D3 FF D3 D3 D3 FF CD CD CD FF C7 C7'
- 'C7 FF C4 C4 C4 FF C2 C2 C2 FF C1 C1 C1 FF C0 C0'
- 'C0 FF C1 C1 C1 FF C1 C1 C1 FF C1 C1 C1 FF C2 C2'
- 'C2 FF C2 C2 C2 FF 00 FF FF FF 00 FF FF FF 99 99'
- '99 FF 09 09 09 FF 00 00 00 CF C0 C0 C0 FF 00 00'
- '00 40 00 00 00 0E 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1A 00 00 00 F2 2C 2C 2C FF CC CC CC FF D6 D6'
- 'D6 FF D5 D5 D5 FF CC CC CC FF D5 D5 D5 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6 D6 FF D6 D6'
- 'D6 FF D6 D6 D6 FF D6 D6 D6 FF D7 D7 D7 FF D6 D6'
- 'D6 FF D5 D5 D5 FF D3 D3 D3 FF CF CF CF FF CC CC'
- 'CC FF C9 C9 C9 FF C6 C6 C6 FF C4 C4 C4 FF C2 C2'
- 'C2 FF B3 B3 B3 FF BD BD BD FF D0 D0 D0 FF 99 99'
- '99 FF 09 09 09 FF 00 00 00 CF 00 00 00 3E 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 93 93'
+ '93 55 B2 B2 B2 A9 BF BF BF A9 D4 D4 D4 9D DF DF'
+ 'DF 89 E3 E3 E3 77 E0 E0 E0 65 E6 E6 E6 53 E3 E3'
+ 'E3 40 E3 E3 E3 2F ED ED ED 1D 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 09 00 00 00 D8 18 18 18 FF B0 B0 B0 FF DB DB'
- 'DB FF DB DB DB FF D0 D0 D0 FF D2 D2 D2 FF DB DB'
- 'DB FF D9 D9 D9 FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DA DA DA FF DA DA'
- 'DA FF DA DA DA FF DA DA DA FF DB DB DB FF DB DB'
- 'DB FF DA DA DA FF D9 D9 D9 FF D9 D9 D9 FF CF CF'
- 'CF FF C5 C5 C5 FF CC CC CC FF CA CA CA FF 7A 7A'
- '7A FF 02 02 02 FF 00 00 00 B8 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 02 00 00 00 BF 08 08 08 FF 97 97 97 FF DC DC'
- 'DC FF DF DF DF FF DC DC DC FF CE CE CE FF D6 D6'
- 'D6 FF DE DE DE FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DD DD DD FF DD DD DD FF DD DD'
- 'DD FF DD DD DD FF DE DE DE FF D8 D8 D8 FF CE CE'
- 'CE FF DD DD DD FF DC DC DC FF C6 C6 C6 FF 53 53'
- '53 FF 00 00 00 FF 00 00 00 A0 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 A4 00 00 00 FF 77 77 77 FF D3 D3'
- 'D3 FF E2 E2 E2 FF E1 E1 E1 FF DE DE DE FF CE CE'
- 'CE FF D7 D7 D7 FF E1 E1 E1 FF E2 E2 E2 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0'
- 'E0 FF E0 E0 E0 FF E0 E0 E0 FF E0 E0 E0 FF E1 E1'
- 'E1 FF E1 E1 E1 FF D9 D9 D9 FF CD CD CD FF DA DA'
- 'DA FF E3 E3 E3 FF D9 D9 D9 FF BB BB BB FF 39 39'
- '39 FF 00 00 00 FF 00 00 00 7E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 89 00 00 00 FF 4B 4B 4B FF C9 C9'
- 'C9 FF E5 E5 E5 FF E3 E3 E3 FF E4 E4 E4 FF E1 E1'
- 'E1 FF D7 D7 D7 FF D2 D2 D2 FF DA DA DA FF E4 E4'
- 'E4 FF E5 E5 E5 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E5 E5 E5 FF E5 E5 E5 FF DC DC'
- 'DC FF D2 D2 D2 FF D6 D6 D6 FF E0 E0 E0 FF E4 E4'
- 'E4 FF E6 E6 E6 FF D6 D6 D6 FF A8 A8 A8 FF 20 20'
- '20 FF 00 00 00 FD 00 00 00 4E 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 62 00 00 00 FF 35 35 35 FF BD BD'
- 'BD FF E6 E6 E6 FF E6 E6 E6 FF E6 E6 E6 FF E7 E7'
- 'E7 FF E7 E7 E7 FF DF DF DF FF D2 D2 D2 FF D3 D3'
- 'D3 FF DE DE DE FF E3 E3 E3 FF E3 E3 E3 FF E4 E4'
- 'E4 FF E4 E4 E4 FF E4 E4 E4 FF E4 E4 E4 FF E3 E3'
- 'E3 FF E3 E3 E3 FF DE DE DE FF D4 D4 D4 FF D1 D1'
- 'D1 FF DD DD DD FF E7 E7 E7 FF E7 E7 E7 FF E6 E6'
- 'E6 FF E8 E8 E8 FF D4 D4 D4 FF 9A 9A 9A FF 0B 0B'
- '0B FF 00 00 00 ED 00 00 00 2C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2D 00 00 00 F9 1E 1E 1E FF AB AB'
- 'AB FF E4 E4 E4 FF ED ED ED FF E7 E7 E7 FF E6 E6'
- 'E6 FF EC EC EC FF EB EB EB FF EA EA EA FF E4 E4'
- 'E4 FF E0 E0 E0 FF DF DF DF FF DF DF DF FF DD DD'
- 'DD FF DC DC DC FF DC DC DC FF DD DD DD FF DF DF'
- 'DF FF DF DF DF FF DF DF DF FF E2 E2 E2 FF E9 E9'
- 'E9 FF EC EC EC FF EA EA EA FF E5 E5 E5 FF EB EB'
- 'EB FF EB EB EB FF D6 D6 D6 FF 8A 8A 8A FF 00 00'
- '00 FF 00 00 00 C3 00 00 00 17 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 09 00 00 00 DD 08 08 08 FF 99 99'
- '99 FF E4 E4 E4 FF DF DF DF FF BD BD BD FF C1 C1'
- 'C1 FF D6 D6 D6 FF EC EC EC FF ED ED ED FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EC EC'
- 'EC FF EB EB EB FF EB EB EB FF EC EC EC FF ED ED'
- 'ED FF EE EE EE FF EE EE EE FF ED ED ED FF EE EE'
- 'EE FF E4 E4 E4 FF C2 C2 C2 FF BE BE BE FF D1 D1'
- 'D1 FF EC EC EC FF D4 D4 D4 FF 75 75 75 FF 00 00'
- '00 FF 00 00 00 9C 00 00 00 06 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 AE 00 00 00 FF 8D 8D'
- '8D FF E0 E0 E0 FF C4 C4 C4 FF B2 B2 B2 FF B8 B8'
- 'B8 FF B2 B2 B2 FF EB EB EB FF F1 F1 F1 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0'
- 'F0 FF F0 F0 F0 FF F0 F0 F0 FF F0 F0 F0 FF F3 F3'
- 'F3 FF D5 D5 D5 FF B0 B0 B0 FF B6 B6 B6 FF B7 B7'
- 'B7 FF EB EB EB FF CD CD CD FF 61 61 61 FF 00 00'
- '00 FF 00 00 00 85 00 00 00 01 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 80 00 00 00 FF 64 64'
- '64 FF CE CE CE FF DD DD DD FF DC DC DC FF D5 D5'
- 'D5 FF E4 E4 E4 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9'
- 'F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF FA FA'
- 'FA FF F2 F2 F2 FF DF DF DF FF D8 D8 D8 FF DC DC'
- 'DC FF D7 D7 D7 FF B0 B0 B0 FF 34 34 34 FF 00 00'
- '00 FF 00 00 00 67 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 44 00 00 00 FF 19 19'
- '19 FF 80 80 80 FF BE BE BE FF D3 D3 D3 FF D7 D7'
- 'D7 FF DB DB DB FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8 D8 FF D8 D8'
- 'D8 FF D9 D9 D9 FF D9 D9 D9 FF D7 D7 D7 FF CD CD'
- 'CD FF B0 B0 B0 FF 5D 5D 5D FF 06 06 06 FF 00 00'
- '00 ED 00 00 00 2B 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 02 00 00 00 9C 00 00'
- '00 FF 0C 0C 0C FF 3D 3D 3D FF 49 49 49 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 48 48 48 FF 48 48'
- '48 FF 48 48 48 FF 48 48 48 FF 49 49 49 FF 49 49'
- '49 FF 2F 2F 2F FF 02 02 02 FF 00 00 00 FF 00 00'
- '00 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00'
- '00 7F 00 00 00 F1 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 D6 00 00 00 5C 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 FC 03'
+ 'FF FF FF FF 00 00 F8 00 07 FF FF FF 00 00 F8 00'
+ '00 07 FF FF 00 00 E0 00 00 00 00 0F 00 00 E0 00'
+ '00 00 00 00 00 00 E0 00 00 00 00 00 00 00 FC 00'
+ '00 00 00 00 00 00 FE 00 00 00 00 00 00 00 FE 00'
+ '00 00 00 00 00 00 FE 00 00 00 00 00 00 00 FE 00'
+ '00 00 00 00 00 00 FE 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '01 80 00 00 00 00 00 00 FF F8 00 00 00 00 00 FF'
+ 'FF FF 00 1F 00 00 FF FF FF FF FF FF 00 00 FF FF'
+ 'FF FF FF FF 00 00 FF FF FF FF FF FF 00 00 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 04 00 00 00'
+ '00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80'
+ '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
+ '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
+ '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 07 77 70 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 70 70 70 70 70 77'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 07 07 07 07 07 77 07'
+ '07 07 77 77 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 70 70 70 70 70 70'
+ '70 70 70 70 70 70 77 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 77 07 07 07 77 07 77'
+ '07 77 07 77 77 77 77 77 77 70 00 07 77 77 77 77'
+ '77 00 00 00 00 00 00 00 00 70 70 70 70 70 70 70'
+ '70 70 70 70 70 70 70 70 70 77 70 07 77 70 00 00'
+ '00 77 77 77 88 88 00 00 07 00 07 07 07 07 77 07'
+ '77 07 77 07 77 77 77 77 77 70 00 07 77 70 00 77'
+ '77 70 00 00 00 78 00 00 00 70 70 70 70 70 70 70'
+ '70 70 70 70 70 70 77 70 70 00 00 07 77 70 00 77'
+ '77 77 77 77 00 78 00 00 00 00 00 70 00 07 07 77'
+ '77 77 77 77 77 77 77 77 00 00 00 07 77 70 00 77'
+ '77 77 77 77 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 07 00 07 77 77 77 70 00 00 00 07 77 70 00 00'
+ '00 00 77 77 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 00 70 00 00 00 00 00 00 00 00 07 77 70 00 00'
+ '00 00 00 00 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 07 77 70 00 00'
+ '00 00 00 00 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 07 77 70 00 00'
+ '00 00 00 00 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 07 77 77 77 77'
+ '77 00 00 00 00 78 00 00 00 00 00 70 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 07 77 77 77 77'
+ '77 77 77 77 77 78 00 00 00 00 00 70 00 88 88 88'
+ '77 00 00 00 00 00 00 00 00 00 00 07 77 77 A7 77'
+ '77 77 77 77 77 88 77 88 AA 88 88 88 88 88 88 88'
+ '88 77 77 77 77 77 77 77 77 77 70 07 77 77 77 77'
+ '77 78 77 77 87 88 77 F8 88 88 88 88 88 88 88 88'
+ '88 88 88 88 87 77 77 77 77 77 70 07 77 77 77 77'
+ '77 77 88 88 88 88 77 F7 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 67 70 07 77 77 00 00'
+ '00 00 00 07 77 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 67 70 07 77 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 67 70 07 77 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 67 70 07 77 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 67 70 07 78 87 00 07'
+ '77 77 77 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 68 70 07 78 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 68 70 07 78 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 68 70 07 78 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 00 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 07 78 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 07 88 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 07 88 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 07 88 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 78 87 00 00'
+ '00 00 00 00 07 88 77 87 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 78 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 66 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 87 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F7 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F7 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F7 00 07 88 87 00 00'
+ '00 00 00 00 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F7 00 07 88 87 00 00'
+ '00 77 77 77 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F7 00 07 88 87 07 77'
+ '77 00 00 07 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 66 66 66 67 F0 00 07 88 87 07 00'
+ '00 00 00 07 07 88 77 86 66 66 66 66 66 66 66 66'
+ '66 66 66 66 66 77 77 77 78 F0 00 07 88 87 07 00'
+ '00 07 77 77 07 8F 77 86 66 66 66 66 66 66 66 66'
+ '66 67 77 77 77 88 88 FF FF 80 00 07 88 87 07 77'
+ '77 70 00 00 07 8F 77 86 66 66 66 66 66 66 66 67'
+ '77 77 88 88 FF FF 88 77 77 00 00 07 88 87 00 00'
+ '00 00 07 77 77 8F 77 86 66 66 66 66 77 77 78 88'
+ '88 88 88 00 00 00 00 87 70 00 00 07 88 87 77 77'
+ '77 77 77 88 88 8F 77 86 67 77 77 77 78 88 88 80'
+ '00 00 00 00 00 00 00 00 00 77 70 07 88 88 88 88'
+ 'FF FF FF FF FF F8 77 88 88 88 88 88 88 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 08 77 78 FF FF FF'
+ 'FF FF FF F8 88 88 87 77 78 80 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 08 88 88 88'
+ '80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF 87 FF FF FF FF FF FF FF 00'
+ '0F FF FF FF FF FF FE 00 00 0F FF FF FF FF FE 00'
+ '00 00 3F FF FF FF FC 00 00 00 01 E0 03 FF F8 00'
+ '00 00 00 00 00 00 F8 00 00 00 00 00 00 00 F8 00'
+ '00 00 00 00 00 00 FF C0 00 00 00 00 00 00 FF C0'
+ '00 E0 00 00 00 00 FF C0 00 00 00 00 00 00 FF C0'
+ '00 00 00 00 00 00 FF C0 00 00 00 00 00 00 FF C0'
+ '00 00 00 00 00 00 FF C0 00 00 00 00 00 00 FF C0'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 3F C0 00 00 00 00 00 1F FF FC 00 00 00 00 03'
+ 'FF FF FF 80 00 00 01 FF FF FF FF F8 07 FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 28 00 00 00 40 00 00 00 80 00'
+ '00 00 01 00 08 00 00 00 00 00 00 10 00 00 00 00'
+ '00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00'
+ '00 00 05 05 05 00 09 09 09 00 0E 0E 0E 00 11 11'
+ '11 00 16 16 16 00 19 19 19 00 1E 1E 1E 00 25 25'
+ '25 00 29 29 29 00 2D 2D 2D 00 31 31 31 00 35 35'
+ '35 00 39 39 39 00 3D 3D 3D 00 75 47 02 00 79 49'
+ '00 00 7B 4C 01 00 7C 4E 02 00 73 4C 0F 00 7E 50'
+ '03 00 7E 51 04 00 6D 4E 1A 00 6A 4F 1F 00 77 51'
+ '18 00 74 53 1F 00 77 54 1E 00 78 53 1B 00 6B 51'
+ '24 00 6C 53 29 00 6B 54 2D 00 77 57 26 00 78 56'
+ '21 00 7F 5E 22 00 7E 5E 26 00 75 5A 2F 00 78 58'
+ '29 00 7E 5F 29 00 7A 5B 2C 00 7B 5D 2F 00 67 54'
+ '32 00 6E 56 33 00 6B 5A 3B 00 70 58 35 00 7D 5E'
+ '32 00 70 5A 38 00 7E 60 2C 00 7E 61 30 00 7E 61'
+ '35 00 7E 62 39 00 7E 64 3D 00 41 41 41 00 45 45'
+ '45 00 49 49 49 00 4D 4D 4D 00 51 51 51 00 55 55'
+ '55 00 59 59 59 00 5D 5D 5D 00 77 64 43 00 72 61'
+ '45 00 7E 66 41 00 7E 6C 40 00 7E 68 45 00 77 69'
+ '50 00 7B 6D 56 00 75 6A 5A 00 7A 70 5C 00 61 61'
+ '61 00 65 65 65 00 69 69 69 00 6D 6D 6D 00 79 74'
+ '6D 00 71 71 71 00 75 75 75 00 78 78 78 00 7A 7A'
+ '7A 00 7D 7D 7D 00 80 53 05 00 81 55 06 00 82 56'
+ '08 00 84 57 08 00 83 58 08 00 84 59 09 00 86 5C'
+ '0B 00 87 5C 0C 00 88 5E 0C 00 83 5F 15 00 8A 61'
+ '0E 00 8C 63 0F 00 8C 63 10 00 8D 65 10 00 8F 68'
+ '13 00 90 68 13 00 91 6A 14 00 92 6C 15 00 94 6E'
+ '16 00 95 70 17 00 96 71 18 00 98 73 19 00 99 75'
+ '1A 00 9A 77 1C 00 9B 78 1C 00 9C 79 1D 00 9E 7C'
+ '1F 00 80 5F 21 00 82 61 21 00 84 62 20 00 86 65'
+ '21 00 88 67 20 00 89 69 21 00 8D 6C 22 00 8F 6F'
+ '24 00 80 62 2E 00 90 71 25 00 93 74 26 00 94 76'
+ '27 00 9F 7D 20 00 95 77 28 00 97 79 29 00 98 7A'
+ '2A 00 80 62 30 00 80 67 31 00 88 78 3D 00 8C 7B'
+ '3D 00 8F 7F 3C 00 A0 7E 20 00 81 6B 49 00 83 6E'
+ '4C 00 86 76 41 00 84 77 49 00 86 71 4F 00 82 74'
+ '53 00 89 75 54 00 85 78 51 00 86 79 56 00 8C 79'
+ '58 00 8F 7C 5B 00 91 7F 5F 00 80 77 68 00 81 79'
+ '6C 00 78 B0 78 00 78 B6 78 00 9C 82 2F 00 9F 85'
+ '2D 00 9C 85 32 00 9C 86 35 00 96 83 39 00 96 82'
+ '3C 00 9B 86 38 00 A2 81 22 00 A0 82 27 00 A4 83'
+ '24 00 A3 84 26 00 A5 85 24 00 A7 88 26 00 A8 88'
+ '27 00 A1 84 28 00 A8 89 28 00 AA 8C 29 00 AC 8E'
+ '2A 00 AD 90 2B 00 AE 91 2C 00 B0 93 2E 00 B0 94'
+ '2E 00 B2 96 30 00 B3 98 30 00 B4 99 31 00 B6 9C'
+ '33 00 B7 9D 34 00 B8 9F 35 00 B9 A1 35 00 BC A5'
+ '38 00 BF A9 3B 00 C0 A9 3B 00 C0 AA 3C 00 C2 AC'
+ '3D 00 C4 AF 3F 00 C4 B0 3F 00 92 82 48 00 93 87'
+ '59 00 9F 95 5C 00 A7 9A 50 00 BB A9 44 00 B2 A2'
+ '4B 00 89 80 6A 00 96 85 64 00 99 89 6A 00 9C 8D'
+ '6F 00 9E 97 6D 00 88 80 73 00 8E 87 7E 00 97 8F'
+ '70 00 9F 91 74 00 A0 94 79 00 A3 98 7D 00 C1 AC'
+ '40 00 C5 B1 40 00 C8 B5 42 00 CA B7 44 00 CB B8'
+ '45 00 CC BA 45 00 CD BC 47 00 CE BD 48 00 D0 BF'
+ '49 00 D0 C0 49 00 FF 00 FF 00 81 81 81 00 84 84'
+ '84 00 86 86 86 00 89 86 82 00 89 89 89 00 8D 8D'
+ '8D 00 91 8D 84 00 93 90 8A 00 90 90 90 00 92 92'
+ '92 00 95 95 95 00 99 99 99 00 9C 9C 9C 00 9E 9E'
+ '9E 00 A1 9C 80 00 A3 9C 87 00 A0 9B 8A 00 A2 A0'
+ '9D 00 A1 A1 A1 00 A4 A4 A3 00 A5 A5 A5 00 A8 A6'
+ 'A2 00 A9 A8 A0 00 A8 A8 A8 00 AA AA AA 00 AC AC'
+ 'AC 00 AE AE AE 00 B1 B1 B1 00 B5 B5 B5 00 B8 B8'
+ 'B7 00 B9 B9 B9 00 BD BD BD 00 8B DC 8B 00 88 E0'
+ '88 00 C1 C1 C1 00 C5 C5 C5 00 C9 C9 C9 00 CD CD'
+ 'CD 00 C2 D2 C2 00 D2 D2 D2 00 D5 D5 D5 00 D9 D9'
+ 'D9 00 DE DE DE 00 C9 E0 C9 00 E1 E1 E1 00 E5 E5'
+ 'E5 00 E9 E9 E9 00 EE EE EE 00 F1 F1 F1 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 35 38 46 4D 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 38 35 39 38 33 0C 0C 0C 33 38'
+ '46 4D 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 39 0C 0C 0C 0C 33 38 33 35 38 38'
+ '0C 33 33 33 35 35 38 46 4D D3 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 33 33 33 38 38 33 0C 33 33 35 35'
+ '33 39 44 44 46 44 44 39 39 38 38 35 38 39 44 4D'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 35 33 33 35 33 33 33 33 35 33 38 35'
+ '38 39 38 39 35 44 38 39 39 44 44 46 44 44 46 44'
+ '39 39 46 46 46 00 00 00 00 44 44 46 46 38 39 39'
+ '44 44 4B D3 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 46 33 33 33 33 0C 33 33 33 35 35 35 39'
+ '35 39 35 44 38 39 38 44 39 46 39 46 44 44 39 44'
+ '44 44 44 44 46 39 35 09 08 44 46 4D 4D 0C 0C 09'
+ '0C 09 0C 33 33 38 44 4B D3 DA E7 EC ED ED 00 00'
+ '00 00 00 33 33 0C 33 09 33 33 33 38 33 39 35 38'
+ '38 38 38 38 38 39 38 44 39 44 44 44 39 46 46 44'
+ '44 4B 44 46 33 09 08 08 08 44 46 4D 4D 0C 09 0C'
+ '44 39 38 35 33 33 33 09 0C 0C 09 33 4B E6 00 00'
+ '00 00 00 44 39 38 38 39 33 39 33 35 35 35 35 35'
+ '38 35 38 38 39 38 39 39 44 44 39 44 44 44 46 44'
+ '46 46 46 33 09 08 08 08 08 46 46 CF CF 0C 09 0C'
+ '4D 35 39 38 44 4B 4B 38 35 33 0C 09 4B E7 00 00'
+ '00 00 00 00 00 00 00 00 33 05 07 08 09 0C 33 33'
+ '33 35 39 39 44 44 46 39 44 39 44 44 44 44 44 44'
+ '46 44 0C 08 09 09 09 09 09 46 46 CF D3 0C 0C 0C'
+ '44 4B 46 4B 44 44 38 38 33 33 0C 0C 4B E7 00 00'
+ '00 00 00 00 00 00 00 00 35 FF FF FF FF FF FF FF'
+ 'FF FF FF FF 02 33 00 00 00 35 35 38 38 39 39 44'
+ '39 09 09 09 09 09 09 09 09 46 4D CF D3 0C 0C 09'
+ '0C 09 0C 09 33 0C 33 35 35 33 0C 0C 4D E7 00 00'
+ '00 00 00 00 00 00 00 00 39 FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF 07 35 0B 09 09 09 08 09 09 09 09'
+ '09 09 09 09 09 09 09 09 0C 46 4B CF D3 0C 0C 09'
+ '0C 0C 0C 09 0C 09 33 0C 0C 0C 0C 0C 4D E7 00 00'
+ '00 00 00 00 00 00 00 00 46 FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF 05 09 09 09 09 09 09 09 09 09 0C'
+ '09 09 09 0C 09 0C 09 0C 09 46 4B CF D8 33 09 0C'
+ '0C 09 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 4D EA 00 00'
+ '00 00 00 00 00 00 00 00 4D FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF 02 0C 08 09 09 09 09 0C 09 09 09'
+ '09 09 0C 09 09 09 0C 09 0C 46 4D D3 D3 33 09 0C'
+ '09 33 0C 09 33 0C 0C 0C 0C 0C 0C 0C CF EA 00 00'
+ '00 00 00 00 00 00 00 00 CF 07 FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF 09 09 09 09 09 09 09 0C 09 09'
+ '0C 09 09 0C 09 0C 09 0C 0C 4B 4B D3 D8 44 44 39'
+ '38 35 33 33 0C 09 0C 0C 0C 33 0C 33 4D EA 00 00'
+ '00 00 00 00 00 00 00 00 D3 09 02 02 05 05 05 FF'
+ '02 FF FF FF FF 02 0C 09 09 09 09 0C 09 09 0C 09'
+ '09 0C 09 0C 09 0C 09 0C 09 46 4D D8 D8 D3 D3 D8'
+ 'D3 D3 D3 CF 4D 4D CF 4D 4D 46 44 44 D8 ED 00 00'
+ '00 00 00 00 00 00 00 00 D8 33 02 0C EA F1 F1 F1'
+ 'ED ED D3 38 02 02 09 09 09 09 09 09 0C 09 09 0C'
+ '09 09 0C 0C 09 0C 0C 0C 0C 4B CF D8 D8 D3 EF D8'
+ 'D3 D3 D8 CF DA D3 DA DA DA E6 DA DA E7 ED D8 D3'
+ 'F7 F5 8E 8E F3 F4 F4 F4 ED E7 E6 E7 F1 F4 F1 ED'
+ 'F4 F1 ED EA D3 4D D3 CF 4D 4B 4B 46 4B 46 4B 44'
+ '46 44 46 44 46 44 33 0C 09 4B CF D8 DA D3 D8 D8'
+ 'D8 D8 D8 D3 E6 DA DA E6 DA DA E6 DA EA ED 4B 4B'
+ 'F9 FA EF EF F4 F4 F1 F4 F4 F4 F1 F4 F1 F4 F1 F1'
+ 'F4 F1 ED F1 ED EA EA EA E7 E6 E6 DA DA DA DA DA'
+ 'DA DA D8 DA D8 DA 46 0C 0C 4B CF D8 DA 4B 4B 4B'
+ '4B CF CF CF D3 E6 E1 E6 E6 E6 E6 DA EA F1 46 4B'
+ 'FB DE 77 77 76 77 77 73 73 73 73 6F 6F 6D 6F 6D'
+ '6D 6D 6D 21 69 6D 21 21 21 21 25 71 71 79 71 71'
+ '79 79 79 79 2D D3 44 0C 09 4D CF DA E6 33 0C 0C'
+ '0C 33 0C 33 0C 0C 0C 0C 33 33 33 38 D8 F1 4B 4B'
+ 'F9 C3 67 67 67 65 65 65 60 60 60 5C 5C 58 56 54'
+ '50 50 50 15 15 15 15 15 15 15 15 15 15 4E 4E 4E'
+ '4E 50 50 50 16 D3 39 0C 0C 4B D3 DA DA 33 33 0C'
+ '0C 0C 33 0C 33 0C 33 33 0D 33 33 33 D3 F4 46 4B'
+ 'F9 C2 65 62 65 62 60 60 60 5C 5C 58 58 58 54 54'
+ '50 50 50 50 15 15 50 15 15 15 15 4E 4E 4E 4E 4E'
+ '50 50 54 4E 17 D8 39 0C 0C 4D D3 DA E7 33 0C 33'
+ '0C 33 0C 33 0C 33 33 0D 33 0D 33 0D D3 F4 46 4B'
+ 'F7 C1 60 60 60 60 60 5D 5C 5C 5C 58 58 56 54 54'
+ '50 50 50 4E 50 4E 15 4E 15 4E 4E 4E 50 50 54 4E'
+ '54 54 4E 56 17 DA 38 0C 09 4D D3 DA E7 33 33 0C'
+ '0C 33 0C 33 33 0D 33 33 0C 33 33 0E D8 F4 46 4D'
+ 'F9 BB 60 5C 60 5C 5C 5C 58 58 58 58 54 54 54 50'
+ '50 50 4E 4E 4E 4E 50 4E 50 50 54 54 54 4E 56 54'
+ '54 56 56 56 1E DA 38 0C 0C 4D D8 E6 E6 33 0C 33'
+ '33 0C 33 0C 33 0D 33 33 33 33 33 33 D7 F4 46 4D'
+ 'F4 BB 58 5C 58 5C 56 56 58 58 56 54 54 54 4E 50'
+ '50 50 50 54 50 50 50 54 54 4E 54 54 54 56 56 56'
+ '56 56 58 58 1E E7 35 0C 09 CF D3 E6 E6 33 33 0C'
+ '33 0C 0C 0C 0C 0C 0C 0C 33 0D 33 33 D8 F7 46 4B'
+ 'F4 BA 58 58 58 56 56 56 56 56 54 54 50 54 50 50'
+ '50 50 50 54 4E 54 50 54 54 54 56 54 58 58 58 58'
+ '5C 5C 58 5C 28 EA 35 0C 0C CF D8 E6 E7 33 33 33'
+ '0C 33 33 35 35 35 35 33 33 33 33 33 D8 F7 46 4B'
+ 'F4 8A 54 54 54 54 54 54 54 50 54 50 4E 50 54 4E'
+ '50 54 4E 54 54 54 56 56 56 58 58 5C 58 5C 58 60'
+ '58 5D 60 5C 2A ED 33 09 0C CF D8 E6 E7 35 33 33'
+ '33 33 33 33 33 0E 33 33 33 33 33 0E DA F9 46 4D'
+ 'F1 8A 54 50 50 50 4E 54 4E 50 4E 54 50 4E 50 54'
+ '4E 54 56 54 54 56 56 58 5C 58 58 5C 60 60 60 60'
+ '60 60 60 60 3C ED 33 0C 0C CF DA E7 EA 35 33 0C'
+ '33 33 33 33 33 0E 0E 0E 33 0E 33 35 DA F8 44 4B'
+ 'F1 88 4E 4E 4E 4E 4E 4E 4E 54 4E 4E 4E 56 4E 54'
+ '54 54 54 56 56 58 5C 58 5C 60 5D 60 60 60 60 60'
+ '60 60 62 60 40 F1 0C 09 0C CF DA E7 EA 35 33 33'
+ '0C 33 33 33 33 0E 35 33 35 33 35 33 E1 F9 44 4D'
+ 'ED 88 15 4E 4E 4E 4E 4E 4E 4E 4E 51 4E 50 50 50'
+ '56 54 56 56 5C 5C 5C 5C 5D 60 60 60 62 62 62 65'
+ '65 65 65 65 43 ED 0C 0C 09 D3 DA E7 ED 35 33 33'
+ '33 33 33 33 33 33 35 33 35 33 35 35 DA FB 44 4D'
+ 'EC 83 15 15 15 15 15 15 15 4E 4E 4E 54 4E 56 54'
+ '54 56 58 5C 5C 5C 5D 60 60 60 62 65 65 65 67 65'
+ '67 67 67 67 8B ED 09 0C 0D D3 DA EA ED 35 33 33'
+ '33 33 33 33 33 35 33 35 33 35 35 35 E6 F9 44 4D'
+ 'EA 80 15 15 15 15 15 15 15 15 4E 4E 4E 54 54 54'
+ '56 5C 58 5D 5D 60 60 61 65 65 65 65 67 67 67 7E'
+ '7E 96 7E 7E BE EA 0C 0C 0C D3 DA EA ED 35 33 33'
+ '33 33 33 33 33 35 33 35 35 35 37 35 E1 F9 44 4D'
+ 'EA 80 10 0F 10 10 15 15 15 15 4E 54 50 50 56 56'
+ '5C 56 60 60 60 61 65 65 65 65 67 7E 96 96 96 96'
+ '96 96 96 96 BF EA 0C 09 0C D3 E6 E7 ED 38 33 33'
+ '33 33 33 35 33 35 35 35 37 35 37 37 E1 F9 44 4D'
+ 'E7 3F 10 10 10 15 0F 15 15 15 4E 4E 56 54 56 56'
+ '5C 5D 5D 60 62 65 65 65 67 7E 96 96 9B 96 9B 9F'
+ '9F 9F 9F 96 D7 E7 0C 0C 0C D3 E1 EA ED 38 33 33'
+ '33 33 33 33 35 33 35 35 35 37 35 38 E1 F9 44 4B'
+ 'E7 3F 10 10 10 10 10 15 15 14 4E 56 4E 56 56 5C'
+ '5C 5D 60 65 65 65 65 7E 96 96 9B 9B 9F 9F A1 9F'
+ '9F 9F 9F 96 DA E1 0C 0C 0C D8 E6 E9 F1 38 33 33'
+ '33 35 33 35 35 35 35 37 37 37 37 37 E6 F9 39 4D'
+ 'E6 31 10 10 10 10 15 10 15 4E 4E 50 56 56 5C 56'
+ '5D 60 62 65 65 7E 7E 96 9B 9B 9F 9F 9F A3 A1 A3'
+ 'A3 A3 A3 96 E6 DA 0C 0C 0C D3 E1 EA ED 39 33 33'
+ '33 35 33 35 35 35 38 37 37 37 38 38 E1 F9 39 4D'
+ 'DA 31 15 0F 10 10 10 15 15 4E 54 50 56 56 58 60'
+ '60 60 65 65 67 7E 96 96 9F 9F 9F A3 A3 A6 A7 A7'
+ 'A7 A7 A7 9D E7 DA 0B 0C 0C D8 E6 EA F1 38 33 35'
+ '35 33 35 35 35 38 35 38 37 38 38 39 E6 F9 39 4D'
+ 'DA 31 0F 10 10 10 15 10 15 4E 4E 56 56 58 5D 5D'
+ '60 65 65 65 7E 96 9F 9C 9F A3 A3 A3 A7 A7 AA AA'
+ 'AB AB AB 9D EA D8 0C 0C 0C D3 E6 ED F1 39 35 33'
+ '35 35 38 35 38 35 38 38 38 38 39 39 E1 F9 39 4D'
+ 'DA 31 10 10 10 10 10 15 15 4E 54 56 56 5B 5D 60'
+ '60 65 65 7E 96 96 9F 9F A3 A3 A7 AA AB AB AC AC'
+ 'AC AC AC 92 ED D3 0C 0C 0C D8 E6 EC F1 38 33 35'
+ '33 35 35 35 35 38 38 38 38 38 39 39 E6 F9 39 4B'
+ 'DA 30 10 10 10 10 15 10 14 50 50 54 58 5C 5C 60'
+ '65 65 67 7E 96 9F 9F A1 A3 A7 AA AA AC AC AF AF'
+ 'AF AF AF 92 F3 CF 0C 0C 0C D3 E6 ED F1 39 35 35'
+ '35 35 38 38 38 38 38 38 39 39 39 39 E6 F9 39 4B'
+ 'DA 2C 10 10 10 10 10 15 15 50 54 56 56 58 60 60'
+ '60 65 7E 96 96 9F 9F A3 A7 A7 AB AC AF AF C5 C5'
+ 'C6 C5 C5 95 F4 4B 0C 0C 33 D3 E7 ED F3 39 35 35'
+ '35 37 35 38 38 38 38 39 39 39 44 44 E6 F9 39 4B'
+ 'D8 2C 10 10 10 10 15 10 4E 50 50 56 58 60 5D 61'
+ '65 67 7E 96 9F 9F A3 A3 AA AB AC AD AF C5 C6 C6'
+ 'C6 C6 C6 93 F7 44 0C 0C 0C D8 E7 ED F1 44 35 35'
+ '35 38 37 35 38 38 39 39 39 44 44 44 E6 F9 39 4B'
+ 'D8 2C 15 0F 10 10 10 15 14 50 54 56 58 5D 60 62'
+ '65 67 7E 96 9F 9F A3 A7 A7 AB AD AF C5 C6 C8 C8'
+ 'C8 C8 C8 7D F9 44 33 0C 33 D3 E7 ED F4 44 35 35'
+ '38 35 39 38 38 39 39 39 44 39 44 44 E7 F9 38 4B'
+ 'D3 2C 0F 10 10 10 15 15 4E 50 54 56 5C 5D 60 62'
+ '65 67 96 96 9F 9F A3 A7 AB AC AF C5 C5 C6 C8 C8'
+ 'CB C8 C8 7D FB 39 0C 0C 0C D8 E7 ED F4 44 35 38'
+ '35 38 38 38 38 39 39 44 44 44 44 44 E7 F9 38 46'
+ 'D8 25 10 10 10 10 10 15 15 50 54 56 58 5D 60 62'
+ '67 75 96 96 9F A1 A3 AA AA AC AF C5 C6 C8 C8 CD'
+ 'CB CD CB 7B FF 38 0C 33 0C D3 E7 ED F4 44 36 38'
+ '38 38 38 39 39 39 44 44 44 44 46 46 E7 F9 38 4B'
+ 'D7 24 10 10 10 10 15 10 4E 50 54 56 5C 5D 60 62'
+ '65 67 96 9B 9F 9F A3 A7 AB AC AF C5 C6 C8 C8 CB'
+ 'CB CD CB 81 FE 38 0C 0C 0C D8 E7 ED F4 46 35 36'
+ '38 38 38 39 39 44 44 44 44 46 46 46 E7 F9 38 46'
+ 'D8 24 10 10 10 10 10 15 15 54 54 56 58 60 60 62'
+ '67 75 96 96 9F A1 A3 A7 AA AC AF C5 C6 C8 CB CB'
+ 'CD CC CD 83 FE 35 0C 0D 33 D3 E7 F1 F4 46 38 38'
+ '38 38 39 39 39 44 44 44 44 46 46 46 E6 F9 38 4B'
+ 'D3 1F 10 10 10 10 10 15 14 4E 54 56 58 5C 60 61'
+ '65 67 7E 96 9C 9F A3 A7 AA AC AF AF C5 C8 C8 C8'
+ 'CB CB C8 86 FE 0E 33 0B 0C D3 E7 F1 F1 49 35 38'
+ '38 38 39 39 39 44 39 46 44 44 44 46 E7 F9 35 46'
+ 'D3 20 10 10 10 10 10 15 4E 50 54 54 58 5C 60 60'
+ '65 67 7E 96 96 9F A3 A3 A7 AB AC AF C5 C6 C8 C8'
+ 'C8 CD CD 87 FE 33 0C 0D 33 D3 E7 F1 F4 46 38 38'
+ '38 39 39 39 44 44 44 44 46 44 44 44 E7 F9 38 46'
+ 'D3 21 0F 10 10 10 10 15 15 4E 54 54 56 58 60 60'
+ '65 65 67 96 9B 9F 9F A3 A7 AA AC AF C4 B7 B8 B6'
+ 'B5 BD DE E5 FD 0D 0D 0D 0D D7 E6 F1 F4 46 38 35'
+ '38 35 39 39 39 44 44 44 46 46 46 4B E6 FB 35 4B'
+ 'CF 20 10 10 10 10 10 10 15 4E 4E 54 56 58 5C 5D'
+ '60 65 67 7E 96 9D 8F 95 B3 B4 C0 DF E7 EC F3 F9'
+ 'FB FF FF FE F3 0D 0C 0D 0D D3 E7 F1 F4 44 38 38'
+ '39 39 39 44 44 44 44 46 46 4B 46 46 E6 FB 35 46'
+ 'D3 1B 10 10 10 10 10 10 15 4E 4E 54 56 56 57 6D'
+ '30 3E 84 B9 D5 E0 EA F1 F7 F9 FB FB FC FB F9 EA'
+ 'D3 4B 39 33 33 0C 0D 0D 0D D7 E7 F1 F4 46 39 38'
+ '39 39 44 44 44 44 46 46 44 44 46 46 E6 FB 35 46'
+ 'CF 1B 10 10 10 10 0F 13 19 23 3B 40 8B D2 D8 E1'
+ 'E7 ED F1 F4 F4 F7 F7 F7 00 00 00 00 00 00 00 00'
+ 'E7 CF 39 0E 0C 0D 0D 0D 0D D3 E7 F1 F1 46 38 38'
+ '35 39 38 44 4B 4D D8 DA EA ED F4 F7 F9 FB 35 46'
+ 'CF 2B 28 3C 42 48 CF D3 D7 D8 DA E6 E6 E6 E7 EA'
+ 'ED 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 D8 46 33 0E 33 D3 E7 F1 F1 EA E7 EA'
+ 'ED F4 FB FE FF FF FF FF FF FF FF FF FE F7 38 44'
+ 'CF CF CF D3 D3 D4 D8 DA E6 E6 EA EA 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 E6 4D D3 DA F1 F1 F7 F9 F9'
+ 'FB FE FB FB FB FB FB FB FB F9 F9 F7 F7 F1 E7 4D'
+ 'CF D8 E0 E6 EA 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 F1 F1 F4 F4 F4'
+ 'F1 F1 F4 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 2C 00 00 00 7E 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 84 00 00 00 84 00 00 00 84 00 00'
- '00 84 00 00 00 70 00 00 00 1A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 87'
+ 'FF FF FF FF FF FF FF 00 0F FF FF FF FF FF FE 00'
+ '00 0F FF FF FF FF FE 00 00 00 3F FF FF FF FC 00'
+ '00 00 01 E0 03 FF F8 00 00 00 00 00 00 00 F8 00'
+ '00 00 00 00 00 00 F8 00 00 00 00 00 00 00 FF C0'
+ '00 00 00 00 00 00 FF DF FC E0 00 00 00 00 FF DF'
+ 'FE 00 00 00 00 00 FF DF FE 00 00 00 00 00 FF DF'
+ 'FE 00 00 00 00 00 FF CF FF 00 00 00 00 00 FF C0'
+ '5E 00 00 00 00 00 FF C0 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF 80 7F FF 00 00 FF FF'
- 'FF 00 7F FF 00 00 FF FF FE 00 0F FF 00 00 FF FF'
- 'FC 00 07 FF 00 00 FF FF F8 00 07 FF 00 00 FF FF'
- 'F0 00 07 FF 00 00 FF FF E0 00 84 FF 00 00 F0 00'
- '00 00 04 7F 00 00 C0 00 00 00 00 7F 00 00 80 00'
- '00 00 00 7F 00 00 80 00 00 00 00 0F 00 00 00 00'
- '00 00 00 07 00 00 00 00 00 00 00 07 00 00 00 00'
- '00 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00'
- '00 00 00 01 00 00 80 00 00 00 00 03 00 00 80 00'
- '00 00 00 07 00 00 80 00 00 00 00 0F 00 00 80 00'
- '00 00 00 1F 00 00 C0 00 00 00 00 3F 00 00 C0 00'
- '00 00 00 7F 00 00 C0 00 00 00 00 FF 00 00 C0 00'
- '00 00 03 FF 00 00 C0 00 00 00 07 FF 00 00 C0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 E0 00'
- '00 00 07 FF 00 00 E0 00 00 00 07 FF 00 00 F0 00'
- '00 00 07 FF 00 00 F0 00 00 00 0F FF 00 00 F0 00'
- '00 00 0F FF 00 00 F0 00 00 00 1F FF 00 00 F8 00'
- '00 00 3F FF 00 00 FE 00 00 00 7F FF 00 00 FF FF'
- 'FF FF FF FF 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 20 00 00 00 00 00 00 10 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0C 00 00 00 3C 80 80 80 FF 80 80 80 FF 00 00'
- '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 3C 80 80 80 FF 00 00 00 FF 80 80 80 FF 80 80'
- '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 3F C0 00 00 00 00 00'
+ '1F FF FC 00 00 00 00 03 FF FF FF 80 00 00 01 FF'
+ 'FF FF FF F8 07 FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 28 00'
+ '00 00 40 00 00 00 80 00 00 00 01 00 20 00 00 00'
+ '00 00 00 42 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 3C 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
- '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
- '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0C 00 00 00 3C 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00'
- '00 3C 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0C 00 00 00 3C 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 24 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
- '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
- '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 0C 00 00 00 24 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
- '00 24 00 00 00 6C 80 80 80 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
- '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
- '00 78 00 00 00 24 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
- '00 90 00 00 00 30 00 00 00 0C 00 00 00 18 00 FF'
- 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 90 00 00 00 30 00 00 00 24 00 00 00 54 00 00'
- '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
- '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
- '00 9C 00 00 00 48 00 80 80 FF 00 00 00 84 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 B4 00 00 00 84 00 80 80 FF 00 80 80 FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 B4 00 FF FF FF 00 80 80 FF 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
- 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 FF FF FF 00 FF FF FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
- '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 FF FF FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 80 80 80 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
- 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 80 80 80 FF C0 C0 C0 FF 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
- '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 80 80 80 FF 00 00 00 FF 80 80 80 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 80 80 80 FF 00 00 00 FF 80 80'
- '80 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 80 80 80 FF 80 80 80 FF 80 80 80 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
- 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 48 C0 C0 C0 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
- '00 30 00 00 00 6C C0 C0 C0 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF C0 C0 C0 FF 00 00 00 3C 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF C0 C0 C0 FF 00 00 00 3C 00 00 00 0C 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80'
- '80 FF 00 80 80 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF C0 C0'
- 'C0 FF 00 00 00 3C 00 00 00 0C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF'
- 'FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 00'
- '00 3C C0 C0 C0 FF 00 00 00 FF C0 C0 C0 FF 00 00'
- '00 3C 00 00 00 0C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 FF FF FF 00 FF FF FF 00 00 00 24 00 00'
- '00 0C 00 00 00 00 C0 C0 C0 FF 00 00 00 18 00 00'
- '00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00'
- '3F FF FE 00 07 FF FC 00 03 FF F8 00 03 FF F0 00'
- '03 FF E0 00 00 7F C0 00 00 3F C0 00 00 3F C0 00'
- '00 3F C0 00 00 07 00 00 00 03 00 00 00 03 00 00'
- '00 03 00 00 00 00 00 00 00 00 80 00 00 00 F0 00'
- '00 00 F0 00 00 00 F0 00 00 00 F8 00 00 00 FF 00'
- '00 00 FF 00 00 00 FF 00 00 00 FF 80 00 00 FF F0'
- '00 00 FF F0 00 01 FF F0 00 03 FF F8 00 07 FF FF'
- '00 0F FF FF 00 1F FF FF 00 3F FF FF 84 7F'
-} */
-
-
-
-/* BINRES mycomputer.ico */
-15 ICON mycomputer.ico
-/* {
- '00 00 01 00 09 00 20 20 00 00 01 00 08 00 A8 08'
- '00 00 96 00 00 00 10 10 00 00 01 00 08 00 68 05'
- '00 00 3E 09 00 00 20 20 00 00 01 00 04 00 E8 02'
- '00 00 A6 0E 00 00 10 10 00 00 01 00 04 00 28 01'
- '00 00 8E 11 00 00 30 30 00 00 01 00 08 00 A8 0E'
- '00 00 B6 12 00 00 30 30 00 00 01 00 04 00 68 06'
- '00 00 5E 21 00 00 30 30 00 00 01 00 20 00 A8 25'
- '00 00 C6 27 00 00 20 20 00 00 01 00 20 00 A8 10'
- '00 00 6E 4D 00 00 10 10 00 00 01 00 20 00 68 04'
- '00 00 16 5E 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 08 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 00 00 00 02 00 00 00 03 00 00 00 00 00'
- '05 00 11 11 11 00 22 22 22 00 33 33 33 00 44 44'
- '44 00 55 55 55 00 66 66 66 00 6F 6D 70 00 77 77'
- '77 00 7F 7F 7F 00 99 33 00 00 CC 33 00 00 99 66'
- '33 00 CC 66 00 00 CC 66 33 00 D0 60 38 00 CC 99'
- '33 00 CC 99 66 00 FF 99 66 00 FF CC 66 00 88 88'
- '88 00 99 99 99 00 AA AA AA 00 BB BB BB 00 CC 99'
- '99 00 CC CC CC 00 DD DD DD 00 FF CC CC 00 EE EE'
- 'EE 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 15 00 00 00 78 0A 38 00 00 00 38 00 B0 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 96 00 00 00 96 00 00 00 09 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 5E 00 60 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 5E 00'
- '00 00 00 00 00 00 03 00 00 00 66 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 C0 CE'
- '0B 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 6D 79 63 6F 6D 70 75 74 65'
- '72 2E 69 63 6F 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 22 22 22 22 01 01 01 02 02'
- '02 03 04 03 22 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 0B 1B 1A 1A 1A 1A 19 19 19'
- '19 18 0D 18 07 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 22 05 1E 21 20 1E 1E 1D 1D 1D 1B'
- '1B 1B 19 1A 0D 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 22 06 20 21 20 20 20 20 1E 1E 1D'
- '1D 1D 1A 1A 18 04 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 05 1D 21 21 21 20 20 20 1E 1E'
- '1D 1D 1A 1B 0D 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 19 21 21 21 21 20 1E 1E 1E'
- '1E 1D 1B 1D 09 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 22 06 1E 21 21 21 20 1A 1B 20'
- '1E 1E 1D 19 05 22 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 22 08 20 21 21 21 1E 1E 20'
- '20 20 1A 06 22 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 22 07 1B 21 21 21 21 21'
- '1E 18 06 22 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 22 03 07 0A 1A 18 09'
- '06 22 22 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 22 22 22 22 22 22 22 22 22 22 04 0C 08 22'
- '22 22 22 22 22 22 22 22 22 22 00 00 00 00 00 00'
- '00 22 06 19 1A 1A 1A 1A 1A 1A 1A 1A 1A 1D 1B 1A'
- '19 19 19 19 19 19 19 19 0C 05 22 00 00 00 00 00'
- '22 04 1B 21 21 21 21 21 21 21 20 20 20 1E 1E 1E'
- '1E 1E 1E 1E 1E 1E 1D 1D 1E 0D 22 00 00 00 00 00'
- '22 06 20 21 20 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E'
- '1E 1E 1D 1D 1D 1D 1D 1D 1D 1A 04 00 00 00 00 00'
- '22 06 20 21 1C 12 12 14 14 15 15 15 15 15 15 15'
- '15 15 14 13 12 12 12 1B 1D 1A 04 00 00 00 00 00'
- '22 06 20 21 1C 11 12 12 13 14 14 14 14 14 14 14'
- '14 13 12 12 12 12 12 1B 1E 1A 04 00 00 00 00 00'
- '22 06 20 21 1C 11 12 12 12 13 13 14 14 14 14 13'
- '13 12 12 12 12 11 11 1B 1E 1A 04 00 00 00 00 00'
- '22 06 20 21 1C 0F 12 12 12 12 12 12 12 12 12 12'
- '12 12 12 12 12 11 11 1B 1E 1A 04 00 00 00 00 00'
- '22 06 20 21 1C 0E 11 12 12 12 12 12 12 12 12 12'
- '12 12 12 11 11 0E 0E 1B 1E 1A 04 00 00 00 00 00'
- '22 06 20 21 15 0E 0E 11 11 12 12 12 12 12 12 12'
- '12 12 11 0F 0E 0E 0E 1B 1E 1A 03 00 00 00 00 00'
- '22 06 20 21 15 0E 0E 11 12 12 12 12 12 12 12 12'
- '12 12 12 12 0E 0E 0E 1B 1E 1A 03 00 00 00 00 00'
- '22 06 1E 21 15 0E 12 12 12 13 13 14 14 14 14 14'
- '13 13 12 12 12 11 0E 1D 20 1A 02 00 00 00 00 00'
- '22 06 1E 21 15 11 12 12 13 14 14 14 15 15 15 14'
- '14 14 13 12 12 12 11 1B 20 1A 01 00 00 00 00 00'
- '22 06 1E 21 15 12 12 13 14 14 15 15 15 15 15 15'
- '15 14 14 13 12 12 12 1D 20 1A 01 00 00 00 00 00'
- '22 06 1E 21 15 12 13 14 14 15 15 16 16 16 16 16'
- '15 15 14 14 13 12 12 1D 21 1A 22 00 00 00 00 00'
- '22 06 1E 21 15 12 14 14 15 15 16 16 16 16 16 16'
- '16 15 15 14 13 12 12 1F 21 1A 22 00 00 00 00 00'
- '22 06 1E 21 15 12 15 15 15 15 15 16 17 17 17 16'
- '15 15 15 15 15 12 10 1F 21 1A 22 00 00 00 00 00'
- '22 05 1E 21 20 1E 20 20 20 20 20 20 20 20 20 20'
- '20 20 20 20 20 1E 1E 21 21 1A 22 00 00 00 00 00'
- '22 22 18 21 21 21 21 21 21 21 21 21 21 21 21 21'
- '21 21 21 21 21 21 21 21 20 09 22 00 00 00 00 00'
- '00 22 05 09 0C 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B'
- '0B 0B 0B 0B 0B 0B 0B 0B 08 02 22 00 00 00 00 00'
- '00 00 22 22 22 22 22 22 22 22 22 22 22 22 22 22'
- '22 22 22 22 22 22 22 22 22 22 00 00 00 00 FF FF'
- 'FF FF FF 00 00 FF FF 00 00 FF FE 00 00 FF FE 00'
- '00 FF FF 00 00 FF FF 00 00 FF FF 00 00 FF FF 80'
- '01 FF FF C0 03 FF FF E0 07 FF F0 00 00 0F E0 00'
- '00 07 C0 00 00 07 C0 00 00 07 C0 00 00 07 C0 00'
- '00 07 C0 00 00 07 C0 00 00 07 C0 00 00 07 C0 00'
- '00 07 C0 00 00 07 C0 00 00 07 C0 00 00 07 C0 00'
- '00 07 C0 00 00 07 C0 00 00 07 C0 00 00 07 C0 00'
- '00 07 C0 00 00 07 E0 00 00 07 F0 00 00 0F 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00'
- '00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 01 00 00 00 02 00'
- '00 00 03 00 00 00 00 00 05 00 08 00 00 00 11 11'
- '11 00 22 22 22 00 33 33 33 00 44 44 44 00 55 55'
- '55 00 66 66 66 00 6F 6D 70 00 77 77 77 00 7F 7F'
- '7F 00 99 33 00 00 CC 66 00 00 CC 66 33 00 D0 60'
- '38 00 CC 66 66 00 CC 99 33 00 CC 99 66 00 FF 99'
- '66 00 FF CC 66 00 88 88 88 00 99 99 99 00 AA AA'
- 'AA 00 BB BB BB 00 CC 99 99 00 CC CC 99 00 FF CC'
- '99 00 CC CC CC 00 DD DD DD 00 EE EE EE 00 FF FF'
- 'FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 40 40 40 9E 34 34 34 DA 31 31'
+ '31 B9 2D 2D 2D 97 2D 2D 2D 76 2D 2D 2D 54 2D 2D'
+ '2D 32 1E 1E 1E 11 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17'
- '95 00 00 00 38 00 A8 44 F9 77 15 00 00 00 78 0A'
- '38 00 00 00 38 00 B0 6C 38 00 98 17 95 00 00 00'
- '00 00 E0 19 95 00 F0 88 FA 77 70 38 F5 77 FF FF'
- 'FF FF A8 44 F9 77 70 7D F5 77 3A 8A F5 77 96 00'
- '00 00 96 00 00 00 09 00 00 00 B0 18 95 00 00 00'
- '00 00 CB 44 F9 77 38 9F 07 00 CD 8B F5 77 78 13'
- '05 00 37 90 F5 77 00 00 00 00 3E 8A F5 77 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 5E 00'
- '60 00 00 EC FD 7F 1A 02 00 00 4C 16 95 00 40 9F'
- '07 00 FC 15 95 00 FF FF FF FF B4 1A 95 00 45 00'
- '00 00 28 02 00 00 FF FF FF FF E2 D8 F5 77 7D 9B'
- 'F5 77 94 B6 01 00 00 00 05 00 F4 17 95 00 80 00'
- '10 C0 B4 1A 95 00 F0 88 FA 77 88 1C F5 77 FF FF'
- 'FF FF 37 90 F5 77 00 00 00 00 3E 8A F5 77 9B B2'
- 'E7 77 B7 00 00 00 02 00 00 00 A4 1A 95 00 01 00'
- '00 00 18 00 00 00 00 00 00 00 10 19 95 00 42 00'
- '00 00 00 00 00 00 F4 18 95 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 0C 00 00 00 02 00 00 00 01 01'
- 'F5 77 00 EC FD 7F 5E 00 00 00 00 00 00 00 03 00'
- '00 00 66 00 1A 02 40 9F 07 00 00 00 00 00 40 9F'
- '07 00 05 00 00 00 BE B3 E7 77 4C 19 95 00 A3 B4'
- 'E7 77 F8 00 00 00 00 00 00 C0 00 00 00 00 00 00'
- '00 00 02 00 00 00 80 00 00 00 00 00 00 00 8C 1A'
- '95 00 7F E9 4B 00 C0 CE 0B 01 00 00 00 C0 00 00'
- '00 00 80 1A 95 00 02 00 00 00 80 00 00 00 00 00'
- '00 00 C0 27 95 00 C4 F5 AF 00 02 00 00 00 44 3A'
- '5C 6F 73 65 78 70 65 72 74 73 5C 72 65 61 63 74'
- '6F 73 5C 6C 69 62 5C 73 68 65 6C 6C 33 32 5C 6D'
- '79 63 6F 6D 70 75 74 65 72 2E 69 63 6F 00 14 1A'
- '95 00 1F 3B D4 77 15 00 00 00 A8 00 00 00 4F 3B'
- 'D4 77 E0 19 95 00 33 3B D4 77 64 C5 F5 77 A9 F1'
- 'E7 77 F8 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 1A 95 00 B0 6C 38 00 96 00 00 00 00 00'
- '00 00 C9 F1 E7 77 96 00 00 00 A4 1A 95 00 09 00'
- '00 00 00 00 00 00 96 00 00 00 96 00 00 00 09 00'
- '00 00 F4 19 95 00 33 3B D4 77 B4 1A 95 00 09 48'
- 'E9 77 B8 10 E9 77 FF FF FF FF C9 F1 E7 77 16 EA'
- '4B 00 F8 00 00 00 B0 6C 38 00 96 00 00 00 58 1A'
- '95 00 00 00 00 00 00 00 00 00 01 05 05 05 05 05'
- '05 01 00 00 00 00 00 00 00 00 0A 1F 1B 1A 1A 19'
- '18 08 00 00 00 00 00 00 00 00 0D 22 21 21 20 1F'
- '1B 09 00 00 00 00 00 00 00 00 08 21 22 20 20 21'
- '1B 07 00 00 00 00 00 00 00 00 00 0A 20 21 21 1B'
- '08 00 00 00 00 00 00 00 02 04 04 23 06 0D 0B 06'
- '23 05 05 02 00 00 00 03 19 1F 1F 1F 1B 1F 1B 1B'
- '1B 1B 1B 0C 23 00 00 06 21 1E 1E 1E 1E 1E 1E 1D'
- '1C 15 1D 1B 05 00 00 07 21 15 10 11 12 14 14 11'
- '11 10 15 1B 05 00 00 07 21 15 10 11 11 11 11 11'
- '11 0F 15 1B 05 00 00 06 21 11 0F 11 11 11 11 11'
- '11 0F 15 1B 05 00 00 06 21 13 11 12 14 14 14 14'
- '11 10 15 1B 05 00 00 06 20 15 11 14 15 16 15 15'
- '14 11 15 1F 05 00 00 06 20 15 14 15 16 17 17 16'
- '15 11 1C 1F 04 00 00 05 1F 22 21 21 21 21 21 21'
- '21 21 22 1A 23 00 00 00 07 09 09 09 09 09 09 09'
- '09 09 09 06 00 00 F0 0F 00 00 F0 0F 00 00 F0 0F'
- '00 00 F0 0F 00 00 F8 1F 00 00 C0 03 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 C0 03 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 80 00 00 00 00 80 00 00 80 80 00 00 00 00'
- '80 00 80 00 80 00 00 80 80 00 C0 C0 C0 00 80 80'
- '80 00 FF 00 00 00 00 FF 00 00 FF FF 00 00 00 00'
- 'FF 00 FF 00 FF 00 00 FF FF 00 FF FF FF 00 00 00'
+ '00 00 53 53 53 40 4F 4F 4F FC 51 51 51 FF 54 54'
+ '54 FF 54 54 54 FF 42 42 42 FF 35 35 35 FF 35 35'
+ '35 FF 34 34 34 FE 37 37 37 EB 3A 3A 3A CC 3F 3F'
+ '3F AA 3F 3F 3F 88 40 40 40 67 3E 3E 3E 45 41 41'
+ '41 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 08 77 77 78 88 88 88 80 00 00 00 00 00 00'
- '00 00 07 FF 77 77 77 77 87 80 00 00 00 00 00 00'
- '00 00 0F FF FF FF 77 77 77 80 00 00 00 00 00 00'
- '00 00 07 FF FF FF 77 77 77 80 00 00 00 00 00 00'
- '00 00 08 FF FF FF 77 77 77 80 00 00 00 00 00 00'
- '00 00 00 FF FF F7 7F F7 78 00 00 00 00 00 00 00'
- '00 00 00 8F FF F7 7F FF 70 00 00 00 00 00 00 00'
- '00 00 00 00 7F FF FF 78 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 87 88 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 08 80 00 00 00 00 00 00 00 00 00'
- '08 77 77 77 77 77 77 88 88 88 88 80 00 00 00 00'
- '7F FF FF FF FF FF 7F 77 77 77 77 78 00 00 00 00'
- 'FF FF 77 77 77 77 77 77 77 77 77 77 00 00 00 00'
- 'FF 73 33 88 87 77 77 88 83 33 37 77 00 00 00 00'
- 'FF 73 33 33 88 88 88 83 33 33 37 77 00 00 00 00'
- 'FF 73 33 33 33 88 33 33 33 33 37 77 00 00 00 00'
- 'FF 73 33 33 33 33 33 33 33 33 37 77 00 00 00 00'
- 'FF 83 33 33 33 33 33 33 33 33 37 77 00 00 00 00'
- 'FF 83 33 33 33 33 33 33 33 33 37 77 00 00 00 00'
- 'FF 83 33 33 33 33 33 33 33 33 37 F7 00 00 00 00'
- 'FF 83 33 33 33 38 33 33 33 33 37 F7 00 00 00 00'
- 'FF 83 33 33 88 88 88 83 33 33 37 F7 00 00 00 00'
- '7F 83 33 88 88 87 88 88 83 33 37 F7 00 00 00 00'
- '7F 83 38 88 77 77 77 78 88 33 37 F7 00 00 00 00'
- '7F 83 38 88 77 77 77 78 88 33 37 F7 00 00 00 00'
- '7F 83 88 87 77 77 77 77 88 83 37 F7 00 00 00 00'
- '7F FF FF FF FF FF FF FF FF FF 7F F7 00 00 00 00'
- '8F FF FF FF FF FF FF FF FF FF FF F8 00 00 00 00'
- '08 88 88 88 88 88 88 88 88 88 88 80 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00'
- '00 FF FE 00 00 7F FE 00 00 7F FE 00 00 7F FE 00'
- '00 7F FE 00 00 7F FE 00 00 7F FF 00 00 FF FF 00'
- '00 FF FF 80 01 FF F0 00 00 0F E0 00 00 07 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 E0 00 00 07 28 00'
- '00 00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
- '00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
- '87 77 78 80 00 00 00 00 8F FF 77 78 00 00 00 00'
- '0F FF 7F 70 00 00 00 00 08 FF F7 80 00 00 00 00'
- '00 08 80 00 00 00 00 87 77 77 77 77 78 00 00 F7'
- '77 77 77 78 77 00 00 F8 33 88 83 33 87 00 00 F8'
- '33 33 33 33 87 00 00 F3 33 33 33 33 87 00 00 F3'
- '38 88 88 33 87 00 00 F8 38 88 88 83 87 00 00 F8'
- '88 77 78 83 77 00 00 7F FF FF FF FF F7 00 00 08'
- '88 88 88 88 80 00 E0 0F 00 00 E0 07 00 00 E0 07'
- '00 00 E0 07 00 00 F0 0F 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 08 00 00 00 00 00 00 09 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 01 00 00 00 02 00 00 00 03 00 00 00 00 00'
- '05 00 08 00 00 00 11 11 11 00 22 22 22 00 33 33'
- '33 00 44 44 44 00 55 55 55 00 6D 65 5C 00 69 6E'
- '65 00 6F 6D 70 00 77 77 77 00 7F 7F 7F 00 99 33'
- '00 00 CC 33 00 00 99 66 33 00 98 69 38 00 CC 66'
- '00 00 CC 66 33 00 D0 60 38 00 CC 99 33 00 CC 99'
- '66 00 FF 99 66 00 FF CC 66 00 88 88 88 00 99 99'
- '99 00 AA AA AA 00 BB BB BB 00 CC 99 99 00 FF CC'
- '99 00 CC CC CC 00 DD DD DD 00 EE EE EE 00 FF FF'
- 'FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 43 43 43 C9 31 31 31 FF 31 31 31 FF 37 37'
+ '37 FF 3A 3A 3A FF 43 43 43 FF 56 56 56 FF 3E 3E'
+ '3E FF 4D 4D 4D FF 53 53 53 FF 50 50 50 FF 39 39'
+ '39 FF 47 47 47 FF 45 45 45 FF 45 45 45 FF 45 45'
+ '45 FE 45 45 45 F8 48 48 48 DD 4B 4B 4B BD 4D 4D'
+ '4D 9B 4D 4D 4D 7A 4B 4B 4B 58 4B 4B 4B 36 45 45'
+ '45 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 C0 17 95 00 00 00 38 00 A8 44'
- 'F9 77 15 00 00 00 78 0A 38 00 00 00 38 00 B0 6C'
- '38 00 98 17 95 00 00 00 00 00 E0 19 95 00 F0 88'
- 'FA 77 70 38 F5 77 FF FF FF FF A8 44 F9 77 70 7D'
- 'F5 77 3A 8A F5 77 96 00 00 00 96 00 00 00 09 00'
- '00 00 B0 18 95 00 00 00 00 00 CB 44 F9 77 38 9F'
- '07 00 CD 8B F5 77 78 13 05 00 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00'
- '00 00 00 00 00 00 5E 00 60 00 00 EC FD 7F 1A 02'
- '00 00 4C 16 95 00 40 9F 07 00 FC 15 95 00 FF FF'
- 'FF FF B4 1A 95 00 45 00 00 00 28 02 00 00 FF FF'
- 'FF FF E2 D8 F5 77 7D 9B F5 77 94 B6 01 00 00 00'
- '05 00 F4 17 95 00 80 00 10 C0 B4 1A 95 00 F0 88'
- 'FA 77 88 1C F5 77 FF FF FF FF 37 90 F5 77 00 00'
- '00 00 3E 8A F5 77 9B B2 E7 77 B7 00 00 00 02 00'
- '00 00 A4 1A 95 00 01 00 00 00 18 00 00 00 00 00'
- '00 00 10 19 95 00 42 00 00 00 00 00 00 00 F4 18'
- '95 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00'
- '00 00 02 00 00 00 01 01 F5 77 00 EC FD 7F 5E 00'
- '00 00 00 00 00 00 03 00 00 00 66 00 1A 02 40 9F'
- '07 00 00 00 00 00 40 9F 07 00 05 00 00 00 BE B3'
- 'E7 77 4C 19 95 00 A3 B4 E7 77 F8 00 00 00 00 00'
- '00 C0 00 00 00 00 00 00 00 00 02 00 00 00 80 00'
- '00 00 00 00 00 00 8C 1A 95 00 7F E9 4B 00 C0 CE'
- '0B 01 00 00 00 C0 00 00 00 00 80 1A 95 00 02 00'
- '00 00 80 00 00 00 00 00 00 00 C0 27 95 00 C4 F5'
- 'AF 00 02 00 00 00 44 3A 5C 6F 73 65 78 70 65 72'
- '74 73 5C 72 65 61 63 74 6F 73 5C 6C 69 62 5C 73'
- '68 65 6C 6C 33 32 5C 6D 79 63 6F 6D 70 75 74 65'
- '72 2E 69 63 6F 00 14 1A 95 00 1F 3B D4 77 15 00'
- '00 00 A8 00 00 00 4F 3B D4 77 E0 19 95 00 33 3B'
- 'D4 77 64 C5 F5 77 A9 F1 E7 77 F8 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 1A 95 00 B0 6C'
- '38 00 96 00 00 00 00 00 00 00 C9 F1 E7 77 96 00'
- '00 00 A4 1A 95 00 09 00 00 00 00 00 00 00 96 00'
- '00 00 96 00 00 00 09 00 00 00 F4 19 95 00 33 3B'
- 'D4 77 B4 1A 95 00 09 48 E9 77 B8 10 E9 77 FF FF'
- 'FF FF C9 F1 E7 77 16 EA 4B 00 F8 00 00 00 B0 6C'
- '38 00 96 00 00 00 58 1A 95 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 50'
+ '50 5F 3A 3A 3A FE 44 44 44 FF 4C 4C 4C FF 51 51'
+ '51 FF 51 51 51 FF 49 49 49 FF 34 34 34 FF 46 46'
+ '46 FF 40 40 40 FF 4B 4B 4B FF 4C 4C 4C FF 42 42'
+ '42 FF 59 59 59 FF 5F 5F 5F FF 64 64 64 FF 65 65'
+ '65 FF 63 63 63 FF 60 60 60 FF 5B 5B 5B FF 58 58'
+ '58 FF 55 55 55 FF 53 53 53 FF 52 52 52 FF 51 51'
+ '51 FD 51 51 51 EC 53 53 53 D0 56 56 56 AE 56 56'
+ '56 8D 55 55 55 6B 53 53 53 49 52 52 52 28 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 25 25 25 25 25'
- '25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25'
- '25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 25 25 25 25 25 25'
- '25 25 25 25 01 01 01 01 01 02 02 03 04 04 03 25'
- '25 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 07 1C 1E 1E 1D'
- '1D 1D 1D 1D 1D 1D 1D 1C 1C 1C 1C 1B 1B 1B 1B 0A'
- '03 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 0A 24 24 23 23'
- '22 22 22 22 21 21 21 21 1E 1E 1E 1D 1C 1C 1C 1D'
- '07 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 0F 24 24 23 23'
- '22 22 22 22 21 21 21 21 1E 1E 1E 1E 1D 1C 1C 1D'
- '09 25 25 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 1C 24 24 24 23'
- '23 23 23 23 23 22 22 22 21 21 21 1E 1D 1D 1D 1E'
- '09 25 25 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 1B 24 24 24 24'
- '24 24 24 24 24 23 23 22 22 22 21 21 1E 1D 1D 1E'
- '09 25 25 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 25 25 0B 24 24 24 23'
- '23 23 22 22 22 22 22 21 21 21 1E 1E 1D 1D 1E 1E'
- '07 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 25 08 23 24 24 24'
- '24 24 24 23 23 23 23 22 22 22 22 21 1E 1E 1E 1C'
- '06 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 25 04 1C 24 24 24'
- '24 24 24 24 22 1E 21 22 23 22 22 21 21 1E 1E 09'
- '25 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 25 25 06 21 24 24'
- '24 24 24 24 1D 1C 1C 21 23 22 22 21 21 22 1B 25'
- '25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 25 25 09 21 24'
- '24 24 24 24 23 22 22 23 23 23 22 22 22 0E 06 25'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 25 25 08 1E'
- '24 24 24 24 24 24 24 24 23 23 23 21 0E 05 25 25'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 25 25 05'
- '0A 21 24 24 24 24 24 24 24 22 1C 08 25 25 25 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 25 25'
- '25 06 09 0C 1B 1D 1D 0F 0A 08 04 25 25 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 04 0F 09 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 00 00 00 00 00 00 00 00 00'
- '00 00 00 25 25 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 0A 1E 1B 07 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 25 25 00 00 00 00 00 00 00'
- '00 00 25 25 04 0A 1D 1D 1D 1D 1D 1D 1D 1D 1D 1D'
- '1D 1D 1D 1D 21 21 21 1E 1D 1D 1D 1D 1C 1C 1C 1C'
- '1C 1C 1C 1C 1C 1C 08 25 25 00 00 00 00 00 00 00'
- '00 00 25 25 0E 24 24 24 24 24 24 24 24 24 23 23'
- '23 23 23 23 23 22 22 22 22 22 22 22 22 22 22 22'
- '22 21 21 21 21 22 21 08 25 25 00 00 00 00 00 00'
- '00 25 25 06 22 24 24 24 23 23 23 23 23 23 23 23'
- '23 23 22 22 22 22 22 22 22 22 22 21 21 21 21 21'
- '21 21 21 21 1E 1E 22 1D 25 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 23 23 23 23 23 23 23 23 23'
- '23 23 23 23 23 23 22 22 22 22 22 22 22 22 22 22'
- '22 22 21 22 21 1E 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 09 23 24 24 21 18 18 18 1F 1F 1F 20 20'
- '20 20 20 20 20 20 20 20 20 20 20 20 1F 1F 1F 18'
- '18 18 18 1F 22 21 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 14 15 15 15 15 16 17 17'
- '17 17 17 18 18 18 17 17 17 17 17 16 15 15 15 15'
- '15 14 14 15 22 21 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 14 15 15 15 15 16 17 17'
- '17 17 17 18 18 18 18 17 17 17 17 16 15 15 15 15'
- '15 15 14 15 22 21 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 14 15 15 15 15 15 16 16'
- '17 17 17 17 17 17 17 17 17 16 16 15 15 15 15 15'
- '15 15 14 15 22 21 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 14 15 15 15 15 15 15 15'
- '16 16 16 17 17 17 16 16 16 15 15 15 15 15 15 15'
- '15 14 10 15 22 21 21 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 11 14 15 15 15 15 15 15'
- '15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15'
- '14 14 10 15 22 21 22 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 14 14 15 15 15 15 15'
- '15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 14'
- '14 10 10 15 23 21 22 1D 04 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 11 14 14 15 15 15 15'
- '15 15 15 15 15 15 15 15 15 15 15 15 15 14 14 14'
- '10 10 10 15 23 21 22 1D 03 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 10 10 14 14 14 14 15'
- '15 15 15 15 15 15 15 15 15 15 15 15 14 14 14 10'
- '10 10 10 15 23 21 22 1D 03 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 10 10 10 14 14 15 15'
- '15 15 15 15 15 15 15 15 15 15 15 15 15 14 14 10'
- '10 10 10 15 23 22 22 1D 03 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 10 10 10 15 15 15 15'
- '15 15 15 16 16 16 16 15 15 15 15 15 15 15 15 14'
- '10 10 10 15 23 22 22 1D 02 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 1F 10 10 14 15 15 15 15 15'
- '16 16 16 17 17 17 17 17 16 16 16 15 15 15 15 15'
- '15 10 10 15 23 22 22 1D 02 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 18 10 14 15 15 15 15 16 16'
- '17 17 17 17 17 17 17 17 17 17 17 16 15 15 15 15'
- '15 15 10 15 23 22 22 1D 02 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 18 10 15 15 15 16 16 17 17'
- '17 17 18 18 18 18 18 18 17 17 17 17 16 16 15 15'
- '15 15 15 15 23 22 22 1D 01 25 00 00 00 00 00 00'
- '00 25 25 08 23 24 24 18 14 15 15 15 16 17 17 17'
- '18 18 18 18 18 18 18 18 18 18 17 17 17 17 16 15'
- '15 15 15 15 23 22 22 1D 01 25 00 00 00 00 00 00'
- '00 25 25 08 22 24 24 18 15 15 15 16 17 17 17 18'
- '18 18 18 18 19 19 18 18 18 18 18 18 17 17 17 16'
- '15 15 15 15 23 22 23 1D 25 25 00 00 00 00 00 00'
- '00 25 25 08 22 24 24 18 15 15 16 17 17 17 18 18'
- '18 19 19 19 19 19 19 19 19 18 18 18 18 17 17 16'
- '16 15 15 15 23 23 23 1D 25 25 00 00 00 00 00 00'
- '00 25 25 08 22 24 24 18 14 16 16 17 17 18 18 18'
- '19 19 19 19 19 19 19 19 19 19 18 18 18 17 17 17'
- '16 15 15 15 23 24 24 1D 25 25 00 00 00 00 00 00'
- '00 25 25 07 22 24 24 18 10 15 17 17 17 18 18 19'
- '19 19 19 1A 1A 1A 1A 19 19 19 19 18 18 17 17 17'
- '16 15 15 15 23 24 24 1D 25 25 00 00 00 00 00 00'
- '00 25 25 07 22 24 24 1F 12 15 18 18 18 18 18 18'
- '18 18 18 1A 1A 1A 1A 18 18 18 18 18 18 18 18 18'
- '18 15 12 13 24 24 24 1D 25 25 00 00 00 00 00 00'
- '00 25 25 07 22 24 24 23 23 23 23 23 23 23 23 23'
- '23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 22'
- '22 22 22 23 24 24 24 1D 25 25 00 00 00 00 00 00'
- '00 25 25 06 21 24 24 24 24 24 24 24 24 24 24 24'
- '24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24'
- '24 24 24 24 24 24 24 0F 25 25 00 00 00 00 00 00'
- '00 00 25 25 0A 22 24 24 24 24 24 24 24 24 24 24'
- '24 24 24 24 24 24 24 24 24 24 24 24 24 24 24 24'
- '24 24 24 24 24 24 1D 07 25 25 00 00 00 00 00 00'
- '00 00 25 25 01 08 0D 0F 0F 0F 0F 0F 0F 0F 0F 0F'
- '0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0E 0E 0E'
- '0E 0E 0E 0E 0E 0A 06 25 25 00 00 00 00 00 00 00'
- '00 00 00 25 25 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 25 25 00 00 00 00 00 00 00'
- '00 00 00 00 00 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25'
- '25 25 25 25 25 25 25 00 00 00 00 00 00 00 FF FF'
- 'FF FF FF FF 00 00 FF F8 00 00 1F FF 00 00 FF F0'
- '00 00 0F FF 00 00 FF E0 00 00 0F FF 00 00 FF E0'
- '00 00 0F FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 0F FF 00 00 FF F0 00 00 0F FF 00 00 FF F0'
- '00 00 0F FF 00 00 FF F0 00 00 1F FF 00 00 FF F8'
- '00 00 3F FF 00 00 FF FC 00 00 3F FF 00 00 FF FE'
- '00 00 7F FF 00 00 FF FF 00 01 FF FF 00 00 FE 00'
- '00 00 00 7F 00 00 F8 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 1F 00 00 F8 00'
- '00 00 00 1F 00 00 FE 00 00 00 00 7F 00 00 28 00'
- '00 00 30 00 00 00 60 00 00 00 01 00 04 00 00 00'
- '00 00 80 04 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 80'
- '00 00 80 80 00 00 00 00 80 00 80 00 80 00 00 80'
- '80 00 C0 C0 C0 00 80 80 80 00 FF 00 00 00 00 FF'
- '00 00 FF FF 00 00 00 00 FF 00 FF 00 FF 00 00 FF'
- 'FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 87 77 77 77 77 78 88 88 88 88 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 08 FF FF FF'
- '77 77 77 77 77 88 87 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 08 FF FF F7 77 77 77 77 77 78 87 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 08 FF FF FF'
- 'FF FF 77 77 77 77 77 80 00 00 00 00 00 00 00 00'
- '00 00 00 00 08 FF FF FF FF FF FF 77 77 77 77 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 08 FF FF FF'
- 'F7 77 77 77 77 77 77 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 FF FF FF FF FF FF F7 77 77 78 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 8F FF FF'
- 'FF 77 7F FF 77 77 78 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 07 FF FF FF 78 87 FF 77 77 80 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F FF'
- 'FF F7 FF FF 77 78 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 07 FF FF FF FF FF F7 80 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87'
- 'FF FF FF FF 80 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 08 87 78 80 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 08 80 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 87 80 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 08 77 77 77 77 77 77'
- '77 77 77 77 77 77 77 78 88 78 00 00 00 00 00 00'
- '00 8F FF FF FF FF FF FF FF FF FF FF F7 77 77 77'
- '77 77 70 00 00 00 00 00 00 7F FF FF FF FF FF FF'
- 'FF F7 77 77 77 77 77 77 77 77 77 00 00 00 00 00'
- '00 FF FF FF FF FF FF FF FF FF FF FF F7 77 77 77'
- '77 77 77 00 00 00 00 00 00 FF F7 87 77 77 77 77'
- '77 77 77 77 77 77 77 78 87 F7 77 00 00 00 00 00'
- '00 FF F7 33 33 33 38 88 88 88 88 88 33 33 33 33'
- '33 F7 77 00 00 00 00 00 00 FF F7 33 33 33 38 88'
- '88 88 88 88 83 33 33 33 33 F7 77 00 00 00 00 00'
- '00 FF F7 33 33 33 33 38 88 88 88 83 33 33 33 33'
- '33 F7 77 00 00 00 00 00 00 FF F7 33 33 33 33 33'
- '33 33 33 33 33 33 33 33 33 F7 77 00 00 00 00 00'
- '00 FF F7 33 33 33 33 33 33 33 33 33 33 33 33 33'
- '33 F7 77 00 00 00 00 00 00 FF F7 33 33 33 33 33'
- '33 33 33 33 33 33 33 33 13 F7 77 00 00 00 00 00'
- '00 FF F7 13 33 33 33 33 33 33 33 33 33 33 33 33'
- '13 F7 77 00 00 00 00 00 00 FF F7 13 33 33 33 33'
- '33 33 33 33 33 33 33 31 13 F7 77 00 00 00 00 00'
- '00 FF F8 11 33 33 33 33 33 33 33 33 33 33 33 11'
- '13 F7 77 00 00 00 00 00 00 FF F8 11 13 33 33 33'
- '33 33 33 33 33 33 33 11 13 F7 77 00 00 00 00 00'
- '00 FF F8 11 33 33 33 33 38 88 83 33 33 33 33 33'
- '13 F7 F7 00 00 00 00 00 00 FF F8 13 33 33 33 88'
- '88 88 88 88 83 33 33 33 33 F7 F7 00 00 00 00 00'
- '00 FF F8 33 33 33 88 88 88 88 88 88 88 33 33 33'
- '33 F7 F7 00 00 00 00 00 00 FF F8 33 33 38 88 88'
- '88 88 88 88 88 83 33 33 33 F7 F7 00 00 00 00 00'
- '00 FF F8 33 33 88 88 88 88 77 78 88 88 88 33 33'
- '38 FF F7 00 00 00 00 00 00 FF F8 33 38 88 88 87'
- '77 77 77 78 88 88 83 33 38 FF F7 00 00 00 00 00'
- '00 FF F8 33 38 88 88 77 77 77 77 77 88 88 88 33'
- '33 FF F7 00 00 00 00 00 00 FF F8 33 38 88 87 77'
- '77 77 77 77 78 88 83 33 33 FF F7 00 00 00 00 00'
- '00 FF F8 38 88 88 87 77 77 77 77 77 78 88 88 88'
- '38 FF F7 00 00 00 00 00 00 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF F7 00 00 00 00 00'
- '00 7F FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF F8 00 00 00 00 00 00 8F FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF 70 00 00 00 00 00'
- '00 00 88 88 88 88 88 88 88 88 88 88 88 88 88 88'
- '88 88 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF FF FF FF FF FF 00 00 FF F8'
- '00 00 1F FF 00 00 FF F0 00 00 0F FF 00 00 FF E0'
- '00 00 0F FF 00 00 FF E0 00 00 0F FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF E0 00 00 0F FF 00 00 FF F0'
- '00 00 0F FF 00 00 FF F0 00 00 0F FF 00 00 FF F0'
- '00 00 1F FF 00 00 FF F8 00 00 3F FF 00 00 FF FC'
- '00 00 3F FF 00 00 FF FE 00 00 7F FF 00 00 FF FF'
- '00 01 FF FF 00 00 FE 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 1F 00 00 F0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 E0 00 00 00 00 0F 00 00 E0 00'
- '00 00 00 0F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 1F 00 00 F8 00 00 00 00 1F 00 00 FE 00'
- '00 00 00 7F 00 00 28 00 00 00 30 00 00 00 60 00'
- '00 00 01 00 20 00 00 00 00 00 00 24 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 5D 5D 5D 13 3F 3F'
+ '3F E1 47 47 47 FF 44 44 44 FF 49 49 49 FF 44 44'
+ '44 FF 39 39 39 FF 46 46 46 FF 3B 3B 3B FF 4C 4C'
+ '4C FF 40 40 40 FF 4F 4F 4F FF 4E 4E 4E FF 51 51'
+ '51 FF 5F 5F 5F FF 4C 4C 4C FF 5F 5F 5F FF 4E 4E'
+ '4E FF 5C 5C 5C FF 56 56 56 FF 5E 5E 5E FF 5D 5D'
+ '5D FF 63 63 63 FF 65 65 65 FF 69 69 69 FF 64 64'
+ '64 FF 61 61 61 FF 6A 6A 6A FF 60 60 60 FF 5D 5D'
+ '5D FF 5F 5F 5F FF 69 69 69 FF 6A 6A 6A FE 67 67'
+ '67 F7 68 68 68 BA 66 66 66 1E 38 38 38 1B 2B 2B'
+ '2B 63 52 52 52 D1 62 62 62 FA 6B 6B 6B FE 6C 6C'
+ '6C FA 50 50 50 F5 58 58 58 F1 66 66 66 D8 73 73'
+ '73 B7 85 85 85 97 8E 8E 8E 74 96 96 96 53 9E 9E'
+ '9E 32 99 99 99 14 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 85 85 85 17 5E 5E 5E DE 3F 3F'
+ '3F FF 3D 3D 3D FF 41 41 41 FF 3A 3A 3A FF 3B 3B'
+ '3B FF 40 40 40 FF 46 46 46 FF 3A 3A 3A FF 4C 4C'
+ '4C FF 4B 4B 4B FF 4F 4F 4F FF 5B 5B 5B FF 4B 4B'
+ '4B FF 5D 5D 5D FF 4C 4C 4C FF 5D 5D 5D FF 51 51'
+ '51 FF 5F 5F 5F FF 53 53 53 FF 61 61 61 FF 58 58'
+ '58 FF 65 65 65 FF 5B 5B 5B FF 67 67 67 FF 5C 5C'
+ '5C FF 64 64 64 FF 5E 5E 5E FF 60 60 60 FF 63 63'
+ '63 FF 5E 5E 5E FF 60 60 60 FF 62 62 62 FF 68 68'
+ '68 FE 4E 4E 4E D9 28 28 28 C4 25 25 25 F8 25 25'
+ '25 FF 62 62 62 FF 69 69 69 FF 7A 7A 7A FF 7E 7E'
+ '7E FF 31 31 31 FF 2D 2D 2D FF 2D 2D 2D FF 2D 2D'
+ '2D FF 2D 2D 2D FF 33 33 33 FF 3B 3B 3B FF 49 49'
+ '49 FE 51 51 51 FA 5D 5D 5D E7 62 62 62 CC 6C 6C'
+ '6C AA 7C 7C 7C 89 8A 8A 8A 67 9E 9E 9E 45 9E 9E'
+ '9E 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 5A 5A 5A 1F 3E 3E 3E F2 3B 3B'
+ '3B FF 38 38 38 FF 3E 3E 3E FF 33 33 33 FF 3E 3E'
+ '3E FF 47 47 47 FF 3B 3B 3B FF 56 56 56 FF 3F 3F'
+ '3F FF 57 57 57 FF 49 49 49 FF 50 50 50 FF 52 52'
+ '52 FF 50 50 50 FF 56 56 56 FF 55 55 55 FF 56 56'
+ '56 FF 5C 5C 5C FF 56 56 56 FF 63 63 63 FF 58 58'
+ '58 FF 68 68 68 FF 5D 5D 5D FF 66 66 66 FF 5F 5F'
+ '5F FF 66 66 66 FF 64 64 64 FF 64 64 64 FF 67 67'
+ '67 FF 6C 6C 6C FF 67 67 67 FF 69 69 69 FF 47 47'
+ '47 FF 25 25 25 FF 25 25 25 FF 25 25 25 FF 26 26'
+ '26 FF 64 64 64 FF 6B 6B 6B FF 7C 7C 7C FF 80 80'
+ '80 FF 33 33 33 FF 2E 2E 2E FF 33 33 33 FF 66 66'
+ '66 FF 5F 5F 5F FF 52 52 52 FF 4C 4C 4C FF 45 45'
+ '45 FF 3E 3E 3E FF 38 38 38 FF 34 34 34 FF 33 33'
+ '33 FF 32 32 32 FF 31 31 31 FF 39 39 39 FF 75 75'
+ '75 FE 90 90 90 86 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 5C 5C 5C 5B 4A 4A 4A C9 4F 4F'
+ '4F D7 48 48 48 E5 4F 4F 4F F2 59 59 59 FE 43 43'
+ '43 FF 57 57 57 FF 42 42 42 FF 51 51 51 FF 48 48'
+ '48 FF 4A 4A 4A FF 4D 4D 4D FF 49 49 49 FF 51 51'
+ '51 FF 4D 4D 4D FF 54 54 54 FF 51 51 51 FF 59 59'
+ '59 FF 56 56 56 FF 5E 5E 5E FF 5D 5D 5D FF 5F 5F'
+ '5F FF 5F 5F 5F FF 60 60 60 FF 62 62 62 FF 60 60'
+ '60 FF 65 65 65 FF 65 65 65 FF 64 64 64 FF 67 67'
+ '67 FF 6C 6C 6C FF 6B 6B 6B FF 3B 3B 3B FF 27 27'
+ '27 FF 26 26 26 FF 27 27 27 FF 27 27 27 FF 27 27'
+ '27 FF 65 65 65 FF 6E 6E 6E FF 7E 7E 7E FF 83 83'
+ '83 FF 34 34 34 FF 2F 2F 2F FF 36 36 36 FF 7C 7C'
+ '7C FF 4D 4D 4D FF 5A 5A 5A FF 50 50 50 FF 63 63'
+ '63 FF 75 75 75 FF 74 74 74 FF 57 57 57 FF 50 50'
+ '50 FF 43 43 43 FF 32 32 32 FF 33 33 33 FF 76 76'
+ '76 FF A8 A8 A8 DB 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 78 78 78 D0 47 47'
+ '47 FF 16 16 16 FF 1D 1D 1D FF 25 25 25 FF 2B 2B'
+ '2B FF 33 33 33 FF 3B 3B 3B FF 40 40 40 FF 4C 4C'
+ '4C FF 4D 4D 4D FF 5D 5D 5D FF 58 58 58 FF 67 67'
+ '67 FF 5D 5D 5D FE 69 69 69 FE 5B 5B 5B FF 61 61'
+ '61 FF 5C 5C 5C FF 5D 5D 5D FF 63 63 63 FF 5D 5D'
+ '5D FF 66 66 66 FF 60 60 60 FF 64 64 64 FF 67 67'
+ '67 FF 62 62 62 FF 32 32 32 FF 28 28 28 FF 28 28'
+ '28 FF 29 29 29 FF 28 28 28 FF 28 28 28 FF 29 29'
+ '29 FF 68 68 68 FF 70 70 70 FF 81 81 81 FF 86 86'
+ '86 FF 35 35 35 FF 30 30 30 FF 34 34 34 FF 66 66'
+ '66 FF 6C 6C 6C FF 73 73 73 FF 70 70 70 FF 6B 6B'
+ '6B FF 64 64 64 FF 5A 5A 5A FF 5A 5A 5A FF 43 43'
+ '43 FF 43 43 43 FF 33 33 33 FF 33 33 33 FF 77 77'
+ '77 FF AC AC AC E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 7C 7C 7C AE 4B 4B'
+ '4B FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 02 02 02 FF 05 05'
+ '05 FF 1C 1C 1C C6 72 72 72 26 65 65 65 53 4D 4D'
+ '4D AF 45 45 45 F6 49 49 49 FF 50 50 50 FF 53 53'
+ '53 FF 5A 5A 5A FF 5D 5D 5D FF 63 63 63 FF 5B 5B'
+ '5B FF 2F 2F 2F FF 29 29 29 FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B'
+ '2B FF 6A 6A 6A FF 73 73 73 FF 83 83 83 FF 89 89'
+ '89 FF 36 36 36 FF 30 30 30 FF 30 30 30 FF 31 31'
+ '31 FF 31 31 31 FF 32 32 32 FF 31 31 31 FF 36 36'
+ '36 FF 39 39 39 FF 44 44 44 FF 49 49 49 FF 4B 4B'
+ '4B FF 47 47 47 FF 35 35 35 FF 35 35 35 FF 7A 7A'
+ '7A FF AB AB AB E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 80 80 80 8D 5B 5B'
+ '5B FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 14 14 14 EE 2D 2D 2D C5 29 29 29 F8 28 28'
+ '28 FF 28 28 28 FF 28 28 28 FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A 2A FF 2A 2A'
+ '2A FF 2A 2A 2A FF 2B 2B 2B FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C 2C FF 2D 2D'
+ '2D FF 6C 6C 6C FF 75 75 75 FF 86 86 86 FF 8C 8C'
+ '8C FF 37 37 37 FF 31 31 31 FF 31 31 31 FF 32 32'
+ '32 FF 32 32 32 FF 32 32 32 FF 33 33 33 FF 33 33'
+ '33 FF 33 33 33 FF 34 34 34 FF 34 34 34 FF 35 35'
+ '35 FF 36 36 36 FF 35 35 35 FF 35 35 35 FF 7C 7C'
+ '7C FF AE AE AE E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 86 86 86 6C 6B 6B'
+ '6B FF 01 01 01 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 10 10 10 FF 2C 2C 2C FF 29 29 29 FF 28 28'
+ '28 FF 29 29 29 FF 2A 2A 2A FF 2B 2B 2B FF 2C 2C'
+ '2C FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2B 2B 2B FF 2C 2C 2C FF 2D 2D 2D FF 2D 2D'
+ '2D FF 2D 2D 2D FF 2D 2D 2D FF 2E 2E 2E FF 2E 2E'
+ '2E FF 6E 6E 6E FF 77 77 77 FF 88 88 88 FF 8E 8E'
+ '8E FF 38 38 38 FF 31 31 31 FF 32 32 32 FF 32 32'
+ '32 FF 33 33 33 FF 33 33 33 FF 34 34 34 FF 34 34'
+ '34 FF 34 34 34 FF 35 35 35 FF 35 35 35 FF 36 36'
+ '36 FF 36 36 36 FF 36 36 36 FF 36 36 36 FF 7E 7E'
+ '7E FF B1 B1 B1 E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 8E 8E 8E 4D 7B 7B'
+ '7B FF 06 06 06 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 08 08 08 FF 30 30 30 FF 29 29 29 FF 29 29'
+ '29 FF 29 29 29 FF 2A 2A 2A FF 2C 2C 2C FF 2D 2D'
+ '2D FF 2C 2C 2C FF 2C 2C 2C FF 2B 2B 2B FF 2B 2B'
+ '2B FF 2C 2C 2C FF 2D 2D 2D FF 2E 2E 2E FF 2E 2E'
+ '2E FF 2E 2E 2E FF 2F 2F 2F FF 2F 2F 2F FF 30 30'
+ '30 FF 70 70 70 FF 79 79 79 FF 8A 8A 8A FF 91 91'
+ '91 FF 3A 3A 3A FF 32 32 32 FF 32 32 32 FF 33 33'
+ '33 FF 34 34 34 FF 34 34 34 FF 34 34 34 FF 35 35'
+ '35 FF 35 35 35 FF 36 36 36 FF 36 36 36 FF 36 36'
+ '36 FF 36 36 36 FF 37 37 37 FF 37 37 37 FF 81 81'
+ '81 FF B5 B5 B5 E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 93 93 93 2D 83 83'
+ '83 FE 17 17 17 FF 03 03 03 FF 01 01 01 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
+ '00 FF 07 07 07 FF 2F 2F 2F FF 29 29 29 FF 29 29'
+ '29 FF 29 29 29 FF 2A 2A 2A FF 2C 2C 2C FF 2E 2E'
+ '2E FF 2D 2D 2D FF 2C 2C 2C FF 2C 2C 2C FF 2C 2C'
+ '2C FF 2D 2D 2D FF 2E 2E 2E FF 2F 2F 2F FF 2F 2F'
+ '2F FF 2F 2F 2F FF 30 30 30 FF 30 30 30 FF 31 31'
+ '31 FF 71 71 71 FF 7B 7B 7B FF 8D 8D 8D FF 93 93'
+ '93 FF 64 64 64 FF 61 61 61 FF 59 59 59 FF 54 54'
+ '54 FF 4E 4E 4E FF 46 46 46 FF 40 40 40 FF 36 36'
+ '36 FF 34 34 34 FF 35 35 35 FF 36 36 36 FF 37 37'
+ '37 FF 37 37 37 FF 38 38 38 FF 38 38 38 FF 82 82'
+ '82 FF B5 B5 B5 E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 BB BB BB 13 89 89'
+ '89 F9 2B 2B 2B FF 09 09 09 FF 07 07 07 FE 12 12'
+ '12 FE 18 18 18 FE 0F 0F 0F FE 08 08 08 FE 05 05'
+ '05 FF 04 04 04 FF 02 02 02 FF 01 01 01 FF 01 01'
+ '01 FF 08 08 08 FF 2D 2D 2D FF 29 29 29 FF 29 29'
+ '29 FF 29 29 29 FF 2B 2B 2B FF 2D 2D 2D FF 2E 2E'
+ '2E FF 2E 2E 2E FF 2D 2D 2D FF 2D 2D 2D FF 2D 2D'
+ '2D FF 2E 2E 2E FF 2F 2F 2F FF 2F 2F 2F FF 2F 2F'
+ '2F FF 30 30 30 FF 31 31 31 FF 31 31 31 FF 31 31'
+ '31 FF 73 73 73 FF 7D 7D 7D FF 8F 8F 8F FF 94 94'
+ '94 FF 87 87 87 FF 8D 8D 8D FF 8F 8F 8F FF 8A 8A'
+ '8A FF 89 89 89 FF 8C 8C 8C FF 85 85 85 FF 7A 7A'
+ '7A FF 79 79 79 FF 87 87 87 FF 7F 7F 7F FF 7A 7A'
+ '7A FF 73 73 73 FF 6A 6A 6A FF 62 62 62 FF 92 92'
+ '92 FF B8 B8 B8 E5 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 91 91'
+ '91 EB 3F 3F 3F FF 0E 0E 0E FF 1C 1C 1C E0 9C 9C'
+ '9C 27 CA CA CA 2C D4 D4 D4 36 C9 C9 C9 3E B7 B7'
+ 'B7 4B 9D 9D 9D 56 75 75 75 AB 53 53 53 FE 0B 0B'
+ '0B FF 0B 0B 0B FF 2B 2B 2B FF 29 29 29 FF 29 29'
+ '29 FF 29 29 29 FF 2B 2B 2B FF 2E 2E 2E FF 2E 2E'
+ '2E FF 2E 2E 2E FF 2E 2E 2E FF 2D 2D 2D FF 2E 2E'
+ '2E FF 2F 2F 2F FF 30 30 30 FF 30 30 30 FF 30 30'
+ '30 FF 31 31 31 FF 31 31 31 FF 32 32 32 FF 32 32'
+ '32 FF 75 75 75 FF 80 80 80 FF 91 91 91 FF 97 97'
+ '97 FF 8A 8A 8A FF 8B DC 8B FF 8F 8F 8F FF 8A 8A'
+ '8A FF 8E 8E 8E FF 8C 8C 8C FF 82 82 82 FF 98 98'
+ '98 FF 8F 8F 8F FF 96 96 96 FF 9C 9C 9C FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9A 9A 9A FF 9B 9B 9B FF AC AC'
+ 'AC FF BC BC BC E5 63 63 63 79 83 83 83 E8 DE DE'
+ 'DE CF C2 D6 C2 CE 66 B4 66 CD 62 AB 62 C4 CE CE'
+ 'CE C4 D1 D1 D1 C4 D2 D2 D2 C4 CC CC CC C9 BD BD'
+ 'BD F9 AC AC AC FF A4 A4 A4 FF AA AA AA F3 C6 C6'
+ 'C6 CF C6 C6 C6 CE C0 C0 C0 CB C0 C0 C0 C4 C7 C7'
+ 'C7 C4 C3 C3 C3 C4 B9 B9 B9 CA B0 B0 B0 FD 8D 8D'
+ '8D FF 7F 7F 7F FF 88 88 88 FF 83 83 83 FF 7C 7C'
+ '7C FF 76 76 76 FF 73 73 73 FF 73 73 73 FF 73 73'
+ '73 FF 6D 6D 6D FF 6D 6D 6D FF 68 68 68 FF 66 66'
+ '66 FF 67 67 67 FF 68 68 68 FF 67 67 67 FF 68 68'
+ '68 FF 63 63 63 FF 4B 4B 4B FF 32 32 32 FF 32 32'
+ '32 FF 76 76 76 FF 82 82 82 FF 93 93 93 FF 99 99'
+ '99 FF 8C 8C 8C FF 93 93 93 FF 94 94 94 FF 94 94'
+ '94 FF 93 93 93 FF 94 94 94 FF 8B 8B 8B FF 9F 9F'
+ '9F FF A1 A1 A1 FF 99 99 99 FF 9F 9F 9F FF 9F 9F'
+ '9F FF 9F 9F 9F FF A0 A0 A0 FF A0 A0 A0 FF AE AE'
+ 'AE FF BE BE BE E5 42 42 42 99 76 76 76 FF E0 E0'
+ 'E0 FF C9 E0 C9 FF 88 E0 88 FF 8B DC 8B FF CD CD'
+ 'CD FF CB CB CB FF CA CA CA FF CB CB CB FF CE CE'
+ 'CE FF CA CA CA FF CB CB CB FF CA CA CA FF C4 C4'
+ 'C4 FF C9 C9 C9 FF C3 C3 C3 FF C6 C6 C6 FF C9 C9'
+ 'C9 FF C4 C4 C4 FF C0 C0 C0 FF BC BC BC FF B9 B9'
+ 'B9 FF B5 B5 B5 FF B2 B2 B2 FF AE AE AE FF AB AB'
+ 'AB FF A6 A6 A6 FF A3 A3 A3 FF 9F 9F 9F FF 9D 9D'
+ '9D FF 9D 9D 9D FF 9B 9B 9B FF 9A 9A 9A FF 98 98'
+ '98 FF 98 98 98 FF 98 98 98 FF 96 96 96 FF 95 95'
+ '95 FF 94 94 94 FF 69 69 69 FF 33 33 33 FF 32 32'
+ '32 FF 78 78 78 FF 84 84 84 FF 95 95 95 FF 9D 9D'
+ '9D FF 6D 6D 6D FF 73 73 73 FF 73 73 73 FF 76 76'
+ '76 FF 80 80 80 FF 83 83 83 FF 85 85 85 FF 89 89'
+ '89 FF 9E 9E 9E FF A3 A3 A3 FF A4 A4 A4 FF A5 A5'
+ 'A5 FF A7 A7 A7 FF A4 A4 A4 FF A2 A2 A2 FF AE AE'
+ 'AE FF C1 C1 C1 E5 3D 3D 3D 99 76 76 76 FF E0 E0'
+ 'E0 FF A3 9C 87 FF 98 7A 2A FF 97 7A 29 FF 97 79'
+ '29 FF 97 79 29 FF 95 77 28 FF 94 76 27 FF 93 74'
+ '26 FF 90 71 25 FF 8F 6F 24 FF 8D 6C 22 FF 8A 6A'
+ '22 FF 89 68 21 FF 88 67 20 FF 86 65 21 FF 85 63'
+ '20 FF 84 62 20 FF 82 60 20 FF 81 5F 20 FF 80 5F'
+ '21 FF 7F 5E 22 FF 80 5F 23 FF 7F 5F 25 FF 7E 5E'
+ '27 FF 7F 5F 28 FF 7E 5F 2A FF 7E 60 2C FF 7F 61'
+ '2D FF 80 62 2E FF 80 62 2F FF 80 63 2F FF 80 62'
+ '30 FF 80 62 30 FF 80 63 30 FF 7E 61 30 FF 70 5A'
+ '38 FF 89 89 89 FF 64 64 64 FF 32 32 32 FF 32 32'
+ '32 FF 79 79 79 FF 86 86 86 FF 98 98 98 FF A0 A0'
+ 'A0 FF 41 41 41 FF 38 38 38 FF 39 39 39 FF 39 39'
+ '39 FF 3A 3A 3A FF 3A 3A 3A FF 3A 3A 3A FF 3A 3A'
+ '3A FF 3A 3A 3A FF 3B 3B 3B FF 3B 3B 3B FF 3C 3C'
+ '3C FF 43 43 43 FF 4B 4B 4B FF 4F 4F 4F FF 93 93'
+ '93 FF C3 C3 C3 E5 3C 3C 3C 99 75 75 75 FF DE DE'
+ 'DE FF A3 98 7D FF 9C 79 1D FF 9C 79 1D FF 9B 78'
+ '1C FF 9A 77 1C FF 99 75 1B FF 98 73 1A FF 96 71'
+ '18 FF 94 6E 16 FF 92 6B 15 FF 90 68 13 FF 8E 66'
+ '11 FF 8C 63 0F FF 89 60 0E FF 87 5D 0C FF 85 59'
+ '0A FF 84 58 08 FF 82 56 07 FF 81 54 06 FF 7F 52'
+ '05 FF 7F 52 05 FF 7E 51 04 FF 7E 50 04 FF 7E 50'
+ '03 FF 7E 50 04 FF 7E 50 04 FF 7E 50 04 FF 7E 51'
+ '04 FF 7F 52 05 FF 80 53 05 FF 80 53 06 FF 81 54'
+ '06 FF 81 55 07 FF 82 56 07 FF 83 57 08 FF 6D 4E'
+ '1A FF 8B 8B 8B FF 5F 5F 5F FF 33 33 33 FF 33 33'
+ '33 FF 7B 7B 7B FF 88 88 88 FF 9A 9A 9A FF A2 A2'
+ 'A2 FF 42 42 42 FF 38 38 38 FF 39 39 39 FF 3A 3A'
+ '3A FF 3A 3A 3A FF 3A 3A 3A FF 3B 3B 3B FF 3C 3C'
+ '3C FF 3C 3C 3C FF 3D 3D 3D FF 3C 3C 3C FF 3D 3D'
+ '3D FF 3D 3D 3D FF 3D 3D 3D FF 3E 3E 3E FF 8E 8E'
+ '8E FF C8 C8 C8 E5 40 40 40 A1 76 76 76 FF DD DD'
+ 'DD FF A0 94 79 FF 99 74 1A FF 98 74 1A FF 98 73'
+ '19 FF 97 72 19 FF 96 70 18 FF 94 6F 17 FF 93 6C'
+ '15 FF 91 6A 14 FF 8F 68 13 FF 8D 65 11 FF 8B 63'
+ '0F FF 8A 60 0E FF 87 5D 0C FF 85 5A 0A FF 84 58'
+ '09 FF 83 57 08 FF 82 55 07 FF 81 54 06 FF 80 53'
+ '05 FF 7F 52 05 FF 7F 52 05 FF 7F 51 04 FF 7F 51'
+ '04 FF 7F 51 04 FF 7F 52 05 FF 80 53 05 FF 80 53'
+ '06 FF 81 54 06 FF 81 55 07 FF 82 55 07 FF 82 56'
+ '08 FF 83 57 08 FF 83 58 08 FF 84 58 09 FF 6A 4F'
+ '1F FF 90 90 90 FF 5C 5C 5C FF 33 33 33 FF 33 33'
+ '33 FF 7C 7C 7C FF 8A 8A 8A FF 9C 9C 9C FF A5 A5'
+ 'A5 FF 43 43 43 FF 39 39 39 FF 39 39 39 FF 3A 3A'
+ '3A FF 3B 3B 3B FF 3B 3B 3B FF 3C 3C 3C FF 3C 3C'
+ '3C FF 3D 3D 3D FF 3D 3D 3D FF 3D 3D 3D FF 3E 3E'
+ '3E FF 3E 3E 3E FF 3F 3F 3F FF 3F 3F 3F FF 90 90'
+ '90 FF CB CB CB E5 40 40 40 A2 77 77 77 FF DB DB'
+ 'DB FF 9F 91 74 FF 95 6F 17 FF 95 6F 17 FF 94 6E'
+ '17 FF 93 6D 16 FF 92 6B 15 FF 91 6A 14 FF 90 68'
+ '13 FF 8F 67 12 FF 8D 65 11 FF 8C 63 0F FF 8A 61'
+ '0E FF 88 5E 0D FF 87 5C 0B FF 85 5A 0A FF 84 58'
+ '09 FF 83 57 08 FF 82 56 07 FF 81 55 07 FF 81 54'
+ '06 FF 81 54 06 FF 80 54 06 FF 80 53 06 FF 80 54'
+ '06 FF 81 54 06 FF 82 55 07 FF 82 56 07 FF 82 56'
+ '08 FF 83 57 08 FF 84 58 08 FF 84 58 08 FF 84 58'
+ '09 FF 85 59 0A FF 85 5A 0A FF 86 5B 0B FF 6B 51'
+ '24 FF 97 97 97 FF 57 57 57 FF 33 33 33 FF 32 32'
+ '32 FF 7E 7E 7E FF 8C 8C 8C FF 9E 9E 9E FF A7 A7'
+ 'A7 FF 44 44 44 FF 3A 3A 3A FF 3B 3B 3B FF 3B 3B'
+ '3B FF 3C 3C 3C FF 3C 3C 3C FF 3D 3D 3D FF 3D 3D'
+ '3D FF 3E 3E 3E FF 3F 3F 3F FF 3E 3E 3E FF 3F 3F'
+ '3F FF 3F 3F 3F FF 3F 3F 3F FF 40 40 40 FF 91 91'
+ '91 FF CF CF CF E5 46 46 46 AB 78 78 78 FF D8 D8'
+ 'D8 FF 9C 8D 6F FF 91 6A 14 FF 91 6A 14 FF 91 69'
+ '14 FF 90 68 13 FF 8F 67 12 FF 8E 66 12 FF 8D 65'
+ '11 FF 8C 64 10 FF 8B 62 0F FF 8A 60 0E FF 88 5E'
+ '0C FF 87 5C 0B FF 85 5A 0A FF 84 58 09 FF 83 58'
+ '08 FF 82 57 08 FF 82 56 07 FF 82 55 07 FF 82 55'
+ '07 FF 82 55 07 FF 82 56 07 FF 82 56 07 FF 82 56'
+ '07 FF 83 57 08 FF 84 58 09 FF 84 59 09 FF 85 59'
+ '09 FF 85 5A 0A FF 86 5A 0A FF 86 5B 0A FF 86 5B'
+ '0B FF 87 5D 0C FF 88 5E 0C FF 88 5E 0D FF 6C 53'
+ '29 FF 9E 9E 9E FF 54 54 54 FF 32 32 32 FF 31 31'
+ '31 FF 7F 7F 7F FF 8E 8E 8E FF A0 A0 A0 FF AA AA'
+ 'AA FF 45 45 45 FF 3B 3B 3B FF 3B 3B 3B FF 3C 3C'
+ '3C FF 3D 3D 3D FF 3D 3D 3D FF 3E 3E 3E FF 3E 3E'
+ '3E FF 3E 3E 3E FF 3F 3F 3F FF 40 40 40 FF 40 40'
+ '40 FF 41 41 41 FF 40 40 40 FF 40 40 40 FF 93 93'
+ '93 FF D1 D1 D1 E5 44 44 44 AC 78 78 78 FF D4 D4'
+ 'D4 FF 99 89 6A FF 8E 66 11 FF 8E 65 11 FF 8D 65'
+ '11 FF 8D 64 10 FF 8C 63 10 FF 8B 62 0F FF 8A 61'
+ '0E FF 89 60 0D FF 88 5E 0D FF 87 5D 0C FF 86 5B'
+ '0B FF 85 5A 0A FF 84 58 09 FF 83 57 08 FF 82 57'
+ '08 FF 82 57 08 FF 83 57 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 57 08 FF 84 58 08 FF 84 58 09 FF 84 59'
+ '09 FF 85 5A 0A FF 86 5B 0B FF 87 5C 0B FF 87 5C'
+ '0C FF 88 5D 0C FF 88 5F 0D FF 89 5F 0D FF 89 5F'
+ '0D FF 8A 61 0E FF 8B 61 0F FF 8B 62 0F FF 6B 54'
+ '2D FF A8 A8 A8 FF 4F 4F 4F FF 31 31 31 FF 31 31'
+ '31 FF 81 81 81 FF 90 90 90 FF A2 A2 A2 FF AB AB'
+ 'AB FF 46 46 46 FF 3C 3C 3C FF 3B 3B 3B FF 3C 3C'
+ '3C FF 37 37 37 FF 39 39 39 FF 37 37 37 FF 37 37'
+ '37 FF 37 37 37 FF 37 37 37 FF 3E 3E 3E FF 3F 3F'
+ '3F FF 3F 3F 3F FF 40 40 40 FF 41 41 41 FF 95 95'
+ '95 FF D4 D4 D4 E5 42 42 42 AC 79 79 79 FF CF CF'
+ 'CF FF 96 85 64 FF 8A 61 0E FF 8A 61 0E FF 8A 60'
+ '0E FF 89 60 0D FF 89 5F 0D FF 88 5E 0D FF 88 5E'
+ '0C FF 87 5D 0C FF 87 5C 0B FF 86 5A 0B FF 85 59'
+ '0A FF 84 58 09 FF 84 58 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 57 08 FF 84 58 08 FF 84 58 09 FF 84 58'
+ '09 FF 85 59 09 FF 85 5A 0A FF 86 5B 0A FF 86 5C'
+ '0B FF 87 5D 0C FF 88 5E 0C FF 89 5F 0D FF 8A 60'
+ '0E FF 8B 62 0F FF 8B 62 0F FF 8C 63 0F FF 8C 64'
+ '10 FF 8D 65 10 FF 8D 65 11 FF 8E 66 11 FF 67 54'
+ '32 FF B2 B2 B2 FF 48 48 48 FF 31 31 31 FF 32 32'
+ '32 FF 83 83 83 FF 93 93 93 FF A4 A4 A4 FF AE AE'
+ 'AE FF 47 47 47 FF 3D 3D 3D FF 3C 3C 3C FF 3E 3E'
+ '3E FF 42 42 42 FF 41 41 41 FF 48 48 48 FF 4A 4A'
+ '4A FF 4B 4B 4B FF 4A 4A 4A FF 40 40 40 FF 3F 3F'
+ '3F FF 40 40 40 FF 42 42 42 FF 42 42 42 FF 97 97'
+ '97 FF D8 D8 D8 E5 41 41 41 AC 79 79 79 FF CB CB'
+ 'CB FF 91 7F 5F FF 87 5C 0B FF 87 5C 0B FF 86 5C'
+ '0B FF 86 5B 0B FF 86 5B 0B FF 86 5B 0B FF 85 5A'
+ '0A FF 85 5A 0A FF 85 59 0A FF 84 58 09 FF 84 58'
+ '09 FF 84 58 08 FF 83 58 08 FF 83 57 08 FF 83 57'
+ '08 FF 84 58 09 FF 85 58 09 FF 85 59 0A FF 85 5A'
+ '0A FF 86 5B 0B FF 87 5D 0C FF 88 5E 0C FF 89 5F'
+ '0D FF 8A 61 0E FF 8B 61 0F FF 8C 63 10 FF 8D 64'
+ '10 FF 8E 66 11 FF 8E 66 11 FF 8F 67 12 FF 8F 68'
+ '13 FF 90 68 13 FF 90 69 13 FF 91 69 14 FF 6B 5A'
+ '3B FF BA BA BA FF 42 42 42 FF 32 32 32 FF 32 32'
+ '32 FF 84 84 84 FF 95 95 95 FF A6 A6 A6 FF AF AF'
+ 'AF FF 48 48 48 FF 3D 3D 3D FF 3D 3D 3D FF 3D 3D'
+ '3D FF 3D 3D 3D FF 3F 3F 3F FF 40 40 40 FF 40 40'
+ '40 FF 40 40 40 FF 40 40 40 FF 40 40 40 FF 41 41'
+ '41 FF 40 40 40 FF 42 42 42 FF 43 43 43 FF 99 99'
+ '99 FF DB DB DB E5 3F 3F 3F AC 79 79 79 FF C7 C7'
+ 'C7 FF 8F 7C 5B FF 84 59 09 FF 84 58 09 FF 84 58'
+ '09 FF 84 58 08 FF 83 58 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 57 08 FF 84 57 08 FF 83 57 08 FF 83 57'
+ '08 FF 83 57 08 FF 83 57 08 FF 83 58 08 FF 84 58'
+ '09 FF 85 59 0A FF 86 5B 0B FF 87 5C 0B FF 87 5D'
+ '0C FF 88 5E 0D FF 8A 60 0E FF 8B 61 0F FF 8C 63'
+ '10 FF 8D 65 10 FF 8E 66 11 FF 8F 68 13 FF 90 68'
+ '13 FF 91 6A 14 FF 91 6A 14 FF 92 6B 15 FF 92 6C'
+ '15 FF 93 6D 16 FF 93 6D 16 FF 93 6D 16 FF 72 62'
+ '45 FF BE BE BE FF 3B 3B 3B FF 31 31 31 FF 32 32'
+ '32 FF 86 86 86 FF 97 97 97 FF A8 A8 A8 FF B2 B2'
+ 'B2 FF 49 49 49 FF 3E 3E 3E FF 3F 3F 3F FF 40 40'
+ '40 FF 40 40 40 FF 40 40 40 FF 41 41 41 FF 41 41'
+ '41 FF 42 42 42 FF 41 41 41 FF 41 41 41 FF 42 42'
+ '42 FF 43 43 43 FF 44 44 44 FF 44 44 44 FF 9B 9B'
+ '9B FF DD DD DD E5 3E 3E 3E AF 79 79 79 FF C2 C2'
+ 'C2 FF 8C 79 58 FF 82 56 07 FF 82 56 07 FF 82 55'
+ '07 FF 81 55 07 FF 81 55 07 FF 82 55 07 FF 81 55'
+ '07 FF 82 56 07 FF 82 56 07 FF 82 56 07 FF 82 56'
+ '07 FF 83 57 08 FF 83 57 08 FF 84 58 09 FF 85 59'
+ '0A FF 86 5B 0B FF 87 5D 0C FF 88 5F 0D FF 89 60'
+ '0E FF 8B 62 0F FF 8C 64 10 FF 8D 65 11 FF 8F 67'
+ '12 FF 90 68 13 FF 91 6A 14 FF 92 6C 15 FF 93 6D'
+ '16 FF 94 6E 17 FF 95 6F 17 FF 95 70 18 FF 96 71'
+ '18 FF 96 71 18 FF 97 72 19 FF 97 72 19 FF 77 69'
+ '50 FF C1 C1 C1 FF 36 36 36 FF 32 32 32 FF 32 32'
+ '32 FF 87 87 87 FF 98 98 98 FF AA AA AA FF B4 B4'
+ 'B4 FF 4A 4A 4A FF 3D 3D 3D FF 3F 3F 3F FF 3F 3F'
+ '3F FF 40 40 40 FF 40 40 40 FF 41 41 41 FF 42 42'
+ '42 FF 43 43 43 FF 44 44 44 FF 45 45 45 FF 45 45'
+ '45 FF 46 46 46 FF 45 45 45 FF 47 47 47 FF 9E 9E'
+ '9E FF E3 E3 E3 E5 43 43 43 B6 79 79 79 FF BD BD'
+ 'BD FF 89 75 54 FF 80 53 05 FF 7F 52 05 FF 7F 52'
+ '05 FF 7F 52 05 FF 80 53 05 FF 7F 53 05 FF 80 53'
+ '06 FF 81 54 06 FF 81 55 07 FF 81 55 07 FF 82 56'
+ '07 FF 83 57 08 FF 84 57 08 FF 85 59 0A FF 86 5B'
+ '0B FF 87 5D 0C FF 89 5F 0D FF 8B 61 0E FF 8C 64'
+ '10 FF 8E 66 11 FF 8F 67 12 FF 90 68 13 FF 91 6A'
+ '14 FF 93 6C 15 FF 94 6E 17 FF 96 71 18 FF 97 72'
+ '19 FF 98 73 19 FF 98 74 1A FF 99 75 1B FF 9A 76'
+ '1B FF 9A 76 1B FF 9A 76 1B FF 9A 76 1B FF 7A 70'
+ '5C FF BF BF BF FF 32 32 32 FF 32 32 32 FF 33 33'
+ '33 FF 89 89 89 FF 9A 9A 9A FF AC AC AC FF B6 B6'
+ 'B6 FF 4C 4C 4C FF 40 40 40 FF 41 41 41 FF 41 41'
+ '41 FF 41 41 41 FF 42 42 42 FF 42 42 42 FF 43 43'
+ '43 FF 44 44 44 FF 45 45 45 FF 45 45 45 FF 45 45'
+ '45 FF 46 46 46 FF 48 48 48 FF 49 49 49 FF 9F 9F'
+ '9F FF E2 E2 E2 E5 41 41 41 B6 7A 7A 7A FF B8 B8'
+ 'B8 FF 86 71 4F FF 7E 50 04 FF 7D 4F 03 FF 7D 4F'
+ '03 FF 7E 4F 03 FF 7E 50 04 FF 7E 51 04 FF 7F 51'
+ '04 FF 7F 52 05 FF 80 54 06 FF 81 55 07 FF 82 56'
+ '08 FF 83 57 08 FF 85 59 09 FF 86 5B 0B FF 88 5D'
+ '0C FF 8A 60 0E FF 8B 62 0F FF 8D 65 10 FF 8F 67'
+ '12 FF 90 69 13 FF 92 6B 15 FF 93 6C 15 FF 95 6F'
+ '17 FF 96 71 18 FF 98 73 1A FF 99 75 1B FF 9A 76'
+ '1B FF 9B 78 1C FF 9C 78 1D FF 9C 79 1D FF 9D 7A'
+ '1E FF 9D 7A 1E FF 9D 7A 1E FF 9D 7A 1E FF 80 77'
+ '68 FF BA BA BA FF 33 33 33 FF 33 33 33 FF 33 33'
+ '33 FF 8A 8A 8A FF 9B 9B 9B FF AD AD AD FF B8 B8'
+ 'B8 FF 4D 4D 4D FF 40 40 40 FF 41 41 41 FF 41 41'
+ '41 FF 42 42 42 FF 43 43 43 FF 44 44 44 FF 44 44'
+ '44 FF 45 45 45 FF 46 46 46 FF 46 46 46 FF 47 47'
+ '47 FF 49 49 49 FF 4A 4A 4A FF 4A 4A 4A FF A0 A0'
+ 'A0 FF E3 E3 E3 E5 3F 3F 3F B6 7A 7A 7A FF B4 B4'
+ 'B4 FF 83 6E 4C FF 7C 4D 02 FF 7C 4D 02 FF 7C 4D'
+ '02 FF 7C 4D 02 FF 7D 4E 03 FF 7E 4F 03 FF 7E 50'
+ '04 FF 7F 52 05 FF 80 54 06 FF 81 55 07 FF 83 57'
+ '08 FF 84 58 09 FF 86 5B 0B FF 88 5D 0C FF 8A 60'
+ '0E FF 8C 63 0F FF 8E 66 11 FF 90 68 13 FF 91 6A'
+ '14 FF 93 6D 16 FF 95 6F 17 FF 96 71 18 FF 98 74'
+ '1A FF 9A 76 1B FF 9B 77 1C FF 9C 79 1E FF 9E 7B'
+ '1F FF 9E 7C 1F FF 9F 7D 20 FF A0 7E 20 FF A0 7F'
+ '21 FF A1 80 21 FF A1 7F 21 FF A0 7E 20 FF 88 80'
+ '73 FF B5 B5 B5 FF 33 33 33 FF 33 33 33 FF 33 33'
+ '33 FF 8B 8B 8B FF 9D 9D 9D FF AF AF AF FF B9 B9'
+ 'B9 FF 4F 4F 4F FF 41 41 41 FF 42 42 42 FF 42 42'
+ '42 FF 43 43 43 FF 43 43 43 FF 44 44 44 FF 45 45'
+ '45 FF 45 45 45 FF 46 46 46 FF 47 47 47 FF 49 49'
+ '49 FF 4A 4A 4A FF 4C 4C 4C FF 4D 4D 4D FF A1 A1'
+ 'A1 FF E2 E2 E2 E5 44 44 44 BF 7A 7A 7A FF B1 B1'
+ 'B1 FF 81 6B 49 FF 7A 4B 01 FF 7A 4B 00 FF 7B 4B'
+ '01 FF 7B 4C 02 FF 7C 4E 02 FF 7D 4F 03 FF 7E 50'
+ '04 FF 7F 52 05 FF 81 54 06 FF 82 56 07 FF 84 58'
+ '09 FF 85 5A 0A FF 87 5D 0C FF 89 60 0D FF 8C 63'
+ '0F FF 8E 66 11 FF 90 68 13 FF 92 6B 15 FF 94 6E'
+ '17 FF 96 71 18 FF 98 73 1A FF 9A 76 1B FF 9B 78'
+ '1C FF 9D 7A 1E FF 9E 7C 1F FF A0 7E 20 FF A1 80'
+ '21 FF A2 81 22 FF A3 82 23 FF A4 83 24 FF A4 84'
+ '24 FF A4 84 24 FF A4 84 24 FF A2 81 22 FF 8E 87'
+ '7E FF B1 B1 B1 FF 33 33 33 FF 33 33 33 FF 34 34'
+ '34 FF 8D 8D 8D FF 9F 9F 9F FF B1 B1 B1 FF BB BB'
+ 'BB FF 50 50 50 FF 42 42 42 FF 43 43 43 FF 44 44'
+ '44 FF 44 44 44 FF 45 45 45 FF 46 46 46 FF 46 46'
+ '46 FF 47 47 47 FF 49 49 49 FF 4B 4B 4B FF 4C 4C'
+ '4C FF 4D 4D 4D FF 4E 4E 4E FF 50 50 50 FF A2 A2'
+ 'A2 FF E2 E2 E2 E5 42 42 42 C0 7A 7A 7A FF AD AD'
+ 'AD FF 7E 68 45 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 7A 4B 01 FF 7C 4D 02 FF 7D 4F 03 FF 7E 50'
+ '04 FF 7F 52 05 FF 81 55 07 FF 83 57 08 FF 85 59'
+ '09 FF 86 5B 0B FF 88 5E 0D FF 8B 62 0F FF 8D 65'
+ '11 FF 90 68 13 FF 92 6B 15 FF 94 6F 17 FF 97 72'
+ '19 FF 99 75 1B FF 9B 77 1C FF 9D 7A 1E FF 9E 7C'
+ '1F FF A0 7E 21 FF A2 81 22 FF A3 83 23 FF A5 85'
+ '25 FF A6 86 26 FF A7 88 26 FF A8 89 27 FF A8 89'
+ '28 FF A8 8A 28 FF A8 89 27 FF A3 82 23 FF 93 90'
+ '8A FF AA AA AA FF 33 33 33 FF 34 34 34 FF 34 34'
+ '34 FF 8D 8D 8D FF A0 A0 A0 FF B2 B2 B2 FF BD BD'
+ 'BD FF 51 51 51 FF 40 40 40 FF 41 41 41 FF 42 42'
+ '42 FF 43 43 43 FF 43 43 43 FF 44 44 44 FF 46 46'
+ '46 FF 47 47 47 FF 49 49 49 FF 4A 4A 4A FF 4B 4B'
+ '4B FF 4D 4D 4D FF 4E 4E 4E FF 50 50 50 FF A2 A2'
+ 'A2 FF E0 E0 E0 E5 41 41 41 C0 7A 7A 7A FF A8 A8'
+ 'A8 FF 7E 66 41 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 7A 4A 00 FF 7B 4C 02 FF 7D 4F 03 FF 7E 50'
+ '04 FF 80 53 05 FF 82 55 07 FF 84 58 08 FF 85 5A'
+ '0A FF 87 5D 0C FF 8A 60 0E FF 8D 64 10 FF 8F 67'
+ '12 FF 92 6B 15 FF 94 6E 17 FF 97 72 19 FF 99 75'
+ '1B FF 9C 79 1D FF 9E 7C 1F FF A0 7E 20 FF A2 81'
+ '22 FF A4 83 24 FF A6 86 25 FF A7 88 27 FF A9 8A'
+ '28 FF AA 8C 29 FF AB 8E 2A FF AC 8F 2B FF AD 8F'
+ '2B FF AC 8F 2B FF AC 8F 2B FF A4 84 24 FF 99 99'
+ '98 FF A2 A2 A2 FF 33 33 33 FF 34 34 34 FF 35 35'
+ '35 FF 8F 8F 8F FF A1 A1 A1 FF B4 B4 B4 FF BE BE'
+ 'BE FF 55 55 55 FF 42 42 42 FF 44 44 44 FF 45 45'
+ '45 FF 45 45 45 FF 46 46 46 FF 47 47 47 FF 48 48'
+ '48 FF 4A 4A 4A FF 4C 4C 4C FF 4E 4E 4E FF 50 50'
+ '50 FF 51 51 51 FF 52 52 52 FF 53 53 53 FF A3 A3'
+ 'A3 FF E2 E2 E2 E5 3F 3F 3F C0 79 79 79 FF A5 A5'
+ 'A5 FF 7E 65 3F FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 4A 00 FF 7B 4C 02 FF 7D 4E 03 FF 7E 51'
+ '04 FF 80 53 06 FF 82 56 07 FF 84 58 09 FF 86 5B'
+ '0B FF 89 5F 0D FF 8B 63 0F FF 8E 66 12 FF 91 6A'
+ '14 FF 94 6E 16 FF 97 72 18 FF 99 75 1B FF 9C 79'
+ '1D FF 9E 7C 1F FF A1 7F 21 FF A3 82 23 FF A5 85'
+ '25 FF A7 88 27 FF AA 8B 29 FF AB 8D 2A FF AD 8F'
+ '2B FF AE 91 2C FF AF 93 2D FF B0 94 2E FF B0 94'
+ '2E FF B0 94 2E FF B0 94 2E FF A3 84 26 FF A4 A4'
+ 'A3 FF 9E 9E 9E FF 34 34 34 FF 34 34 34 FF 35 35'
+ '35 FF 8F 8F 8F FF A2 A2 A2 FF B5 B5 B5 FF BF BF'
+ 'BF FF 56 56 56 FF 43 43 43 FF 44 44 44 FF 44 44'
+ '44 FF 46 46 46 FF 47 47 47 FF 49 49 49 FF 4B 4B'
+ '4B FF 4C 4C 4C FF 4E 4E 4E FF 50 50 50 FF 51 51'
+ '51 FF 53 53 53 FF 54 54 54 FF 55 55 55 FF A4 A4'
+ 'A4 FF E0 E0 E0 E5 3D 3D 3D C0 79 79 79 FF A1 A1'
+ 'A1 FF 7E 64 3C FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7C 4E 03 FF 7E 51'
+ '04 FF 80 53 06 FF 83 57 08 FF 85 59 0A FF 88 5D'
+ '0C FF 8A 61 0E FF 8D 65 10 FF 90 68 13 FF 93 6C'
+ '15 FF 96 71 18 FF 99 75 1B FF 9C 78 1D FF 9E 7C'
+ '1F FF A0 7F 21 FF A3 83 23 FF A6 86 25 FF A9 8A'
+ '28 FF AB 8D 2A FF AD 90 2B FF AE 92 2D FF B0 94'
+ '2E FF B1 96 2F FF B3 98 30 FF B4 99 31 FF B4 9A'
+ '31 FF B4 99 31 FF B3 98 31 FF A1 84 28 FF AD AD'
+ 'AD FF 94 94 94 FF 34 34 34 FF 35 35 35 FF 35 35'
+ '35 FF 90 90 90 FF A3 A3 A3 FF B6 B6 B6 FF C1 C1'
+ 'C1 FF 57 57 57 FF 44 44 44 FF 45 45 45 FF 46 46'
+ '46 FF 47 47 47 FF 48 48 48 FF 4B 4B 4B FF 4D 4D'
+ '4D FF 4F 4F 4F FF 50 50 50 FF 52 52 52 FF 53 53'
+ '53 FF 54 54 54 FF 56 56 56 FF 58 58 58 FF A5 A5'
+ 'A5 FF E2 E2 E2 E5 3D 3D 3D C0 78 78 78 FF 9E 9E'
+ '9E FF 7F 63 3A FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7D 4E 03 FF 7E 51'
+ '04 FF 81 54 06 FF 83 58 08 FF 86 5B 0B FF 89 5F'
+ '0D FF 8B 63 0F FF 8E 66 11 FF 91 6A 14 FF 94 6E'
+ '17 FF 97 73 19 FF 9A 77 1C FF 9D 7B 1E FF A0 7E'
+ '21 FF A3 82 23 FF A6 86 26 FF A9 8A 28 FF AC 8E'
+ '2A FF AE 91 2C FF B0 94 2E FF B2 96 30 FF B4 99'
+ '31 FF B6 9C 33 FF B7 9E 34 FF B8 9F 35 FF B8 A0'
+ '35 FF B8 9F 35 FF B8 9F 35 FF 9F 85 2D FF B6 B6'
+ 'B5 FF 90 90 90 FF 35 35 35 FF 35 35 35 FF 36 36'
+ '36 FF 91 91 91 FF A4 A4 A4 FF B8 B8 B8 FF C2 C2'
+ 'C2 FF 57 57 57 FF 45 45 45 FF 46 46 46 FF 47 47'
+ '47 FF 49 49 49 FF 4C 4C 4C FF 4D 4D 4D FF 4F 4F'
+ '4F FF 50 50 50 FF 52 52 52 FF 54 54 54 FF 55 55'
+ '55 FF 56 56 56 FF 58 58 58 FF 59 59 59 FF A6 A6'
+ 'A6 FF E0 E0 E0 E5 3D 3D 3D C4 77 77 77 FF 9C 9C'
+ '9C FF 7E 62 38 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7C 4E 03 FF 7F 51'
+ '04 FF 81 55 07 FF 84 58 09 FF 86 5C 0B FF 89 60'
+ '0D FF 8D 64 10 FF 8F 67 12 FF 92 6C 15 FF 96 70'
+ '18 FF 99 75 1A FF 9C 79 1D FF 9F 7D 20 FF A2 81'
+ '22 FF A5 85 25 FF A9 8A 28 FF AC 8E 2A FF AE 91'
+ '2C FF B1 95 2F FF B4 99 31 FF B6 9C 33 FF B8 9F'
+ '35 FF BA A2 36 FF BC A4 38 FF BD A5 39 FF BD A5'
+ '39 FF BD A5 39 FF BC A4 38 FF 9C 85 32 FF BE BE'
+ 'BE FF 89 89 89 FF 35 35 35 FF 36 36 36 FF 36 36'
+ '36 FF 91 91 91 FF A5 A5 A5 FF B9 B9 B9 FF C3 C3'
+ 'C3 FF 57 57 57 FF 44 44 44 FF 45 45 45 FF 47 47'
+ '47 FF 48 48 48 FF 4B 4B 4B FF 4D 4D 4D FF 4F 4F'
+ '4F FF 50 50 50 FF 53 53 53 FF 55 55 55 FF 56 56'
+ '56 FF 57 57 57 FF 59 59 59 FF 5B 5B 5B FF A6 A6'
+ 'A6 FF E0 E0 E0 E5 40 40 40 CA 77 77 77 FF 9A 9A'
+ '9A FF 7F 62 36 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4B 01 FF 7D 4E 03 FF 7F 52'
+ '05 FF 82 56 07 FF 85 59 09 FF 87 5D 0C FF 8A 61'
+ '0E FF 8E 65 11 FF 90 69 13 FF 94 6E 16 FF 97 72'
+ '19 FF 9A 77 1C FF 9E 7B 1F FF A1 80 21 FF A4 84'
+ '24 FF A8 88 27 FF AB 8D 2A FF AE 91 2C FF B1 95'
+ '2F FF B4 99 31 FF B7 9D 34 FF B9 A1 36 FF BC A4'
+ '38 FF BE A7 3A FF C0 AA 3C FF C2 AC 3D FF C2 AD'
+ '3D FF C2 AC 3D FF C1 AB 3C FF 9C 86 35 FF C5 C5'
+ 'C5 FF 84 84 84 FF 35 35 35 FF 36 36 36 FF 37 37'
+ '37 FF 91 91 91 FF A6 A6 A6 FF BA BA BA FF C5 C5'
+ 'C5 FF 5A 5A 5A FF 47 47 47 FF 48 48 48 FF 4A 4A'
+ '4A FF 4D 4D 4D FF 4F 4F 4F FF 50 50 50 FF 52 52'
+ '52 FF 54 54 54 FF 56 56 56 FF 58 58 58 FF 59 59'
+ '59 FF 5B 5B 5B FF 5C 5C 5C FF 5E 5E 5E FF A6 A6'
+ 'A6 FF E3 E3 E3 E5 40 40 40 CA 76 76 76 FF 98 98'
+ '98 FF 7E 60 34 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4B 01 FF 7D 4E 03 FF 7F 52'
+ '05 FF 82 56 07 FF 85 59 0A FF 88 5D 0C FF 8B 62'
+ '0F FF 8E 66 12 FF 91 6A 14 FF 95 6F 17 FF 98 74'
+ '1A FF 9B 78 1D FF 9F 7C 1F FF A2 81 22 FF A6 86'
+ '25 FF A9 8B 28 FF AD 8F 2B FF B0 93 2E FF B3 98'
+ '30 FF B6 9D 33 FF B9 A1 36 FF BC A5 39 FF C0 A9'
+ '3B FF C3 AD 3E FF C4 B0 40 FF C6 B2 40 FF C6 B2'
+ '41 FF C6 B2 41 FF C5 B1 40 FF 9B 86 38 FF CE CE'
+ 'CE FF 72 72 72 FF 36 36 36 FF 36 36 36 FF 37 37'
+ '37 FF 91 91 91 FF A7 A7 A7 FF BB BB BB FF C5 C5'
+ 'C5 FF 5B 5B 5B FF 47 47 47 FF 4A 4A 4A FF 4C 4C'
+ '4C FF 4D 4D 4D FF 50 50 50 FF 52 52 52 FF 54 54'
+ '54 FF 56 56 56 FF 58 58 58 FF 59 59 59 FF 5B 5B'
+ '5B FF 5D 5D 5D FF 5E 5E 5E FF 60 60 60 FF A7 A7'
+ 'A7 FF E2 E2 E2 E5 40 40 40 CA 75 75 75 FF 97 97'
+ '97 FF 7E 5F 33 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4B 01 FF 7D 4F 03 FF 7F 52'
+ '05 FF 83 56 08 FF 85 5A 0A FF 88 5E 0C FF 8C 63'
+ '0F FF 8F 67 12 FF 92 6B 15 FF 96 70 18 FF 99 75'
+ '1B FF 9D 79 1E FF A0 7E 20 FF A3 83 23 FF A7 88'
+ '27 FF AB 8D 2A FF AE 91 2C FF B2 96 2F FF B6 9B'
+ '33 FF B8 A0 35 FF BC A4 38 FF BF A9 3B FF C3 AE'
+ '3E FF C6 B1 40 FF C7 B3 42 FF C8 B5 43 FF C9 B6'
+ '43 FF C9 B6 43 FF C8 B5 43 FF 96 83 39 FF D6 D6'
+ 'D6 FF 6A 6A 6A FF 36 36 36 FF 37 37 37 FF 37 37'
+ '37 FF 91 91 91 FF A8 A8 A8 FF BC BC BC FF C6 C6'
+ 'C6 FF 5D 5D 5D FF 49 49 49 FF 4B 4B 4B FF 4D 4D'
+ '4D FF 4F 4F 4F FF 51 51 51 FF 53 53 53 FF 55 55'
+ '55 FF 56 56 56 FF 59 59 59 FF 5B 5B 5B FF 5D 5D'
+ '5D FF 5F 5F 5F FF 60 60 60 FF 62 62 62 FF A7 A7'
+ 'A7 FF E3 E3 E3 E5 44 44 44 D4 74 74 74 FF 96 96'
+ '96 FF 7D 5E 31 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7D 4F 03 FF 80 53'
+ '06 FF 83 57 08 FF 86 5B 0B FF 89 5F 0D FF 8C 64'
+ '10 FF 8F 68 13 FF 93 6C 15 FF 96 71 18 FF 9A 76'
+ '1B FF 9D 7A 1E FF A0 7F 21 FF A4 84 24 FF A8 89'
+ '28 FF AC 8E 2A FF AF 93 2D FF B3 98 31 FF B7 9E'
+ '34 FF BB A2 37 FF BE A7 3A FF C3 AD 3E FF C6 B1'
+ '40 FF C8 B4 42 FF CA B7 44 FF CB B9 45 FF CC BA'
+ '45 FF CB B9 45 FF CB B8 45 FF 8F 7F 3C FF DE DE'
+ 'DE FF 65 65 65 FF 36 36 36 FF 37 37 37 FF 38 38'
+ '38 FF 90 90 90 FF A9 A9 A9 FF BD BD BD FF C7 C7'
+ 'C7 FF 61 61 61 FF 4A 4A 4A FF 4D 4D 4D FF 4F 4F'
+ '4F FF 51 51 51 FF 54 54 54 FF 56 56 56 FF 57 57'
+ '57 FF 59 59 59 FF 5A 5A 5A FF 5C 5C 5C FF 5D 5D'
+ '5D FF 5F 5F 5F FF 61 61 61 FF 62 62 62 FF A8 A8'
+ 'A8 FF E2 E2 E2 E5 42 42 42 D4 73 73 73 FF 93 93'
+ '93 FF 7B 5D 2F FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7E 50 03 FF 80 53'
+ '06 FF 83 57 08 FF 86 5B 0B FF 89 5F 0D FF 8C 64'
+ '10 FF 90 68 13 FF 93 6D 16 FF 97 72 19 FF 9A 77'
+ '1C FF 9E 7B 1F FF A1 80 21 FF A5 85 25 FF A9 8A'
+ '28 FF AD 8F 2B FF B0 94 2E FF B4 9A 32 FF B9 A0'
+ '35 FF BC A4 38 FF C0 AA 3C FF C4 AF 3F FF C7 B3'
+ '41 FF C9 B6 43 FF CC B9 45 FF CD BC 47 FF CD BB'
+ '47 FF CD BB 46 FF CC BB 46 FF 8C 7B 3D FF E6 E6'
+ 'E6 FF 5C 5C 5C FF 37 37 37 FF 37 37 37 FF 38 38'
+ '38 FF 90 90 90 FF A9 A9 A9 FF BD BD BD FF C8 C8'
+ 'C8 FF 63 63 63 FF 4C 4C 4C FF 4D 4D 4D FF 50 50'
+ '50 FF 51 51 51 FF 53 53 53 FF 55 55 55 FF 57 57'
+ '57 FF 5A 5A 5A FF 5C 5C 5C FF 5F 5F 5F FF 61 61'
+ '61 FF 63 63 63 FF 64 64 64 FF 66 66 66 FF A8 A8'
+ 'A8 FF E3 E3 E3 E5 3F 3F 3F D4 73 73 73 FF 92 92'
+ '92 FF 7A 5B 2C FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7D 4F 03 FF 80 53'
+ '06 FF 83 57 08 FF 86 5B 0B FF 89 5F 0D FF 8C 64'
+ '10 FF 90 68 13 FF 93 6D 16 FF 97 72 19 FF 9B 77'
+ '1C FF 9E 7C 1F FF A1 80 22 FF A5 86 25 FF A9 8A'
+ '28 FF AD 90 2B FF B1 95 2F FF B5 9B 32 FF B9 A0'
+ '36 FF BD A5 39 FF C1 AB 3D FF C5 B1 40 FF C8 B4'
+ '42 FF CB B8 45 FF CD BB 46 FF CE BD 48 FF CF BE'
+ '48 FF CF BE 48 FF CF BD 48 FF 88 78 3D FF ED ED'
+ 'ED FF 57 57 57 FF 37 37 37 FF 37 37 37 FF 38 38'
+ '38 FF 8F 8F 8F FF A9 A9 A9 FF BE BE BE FF C9 C9'
+ 'C9 FF 66 66 66 FF 4D 4D 4D FF 50 50 50 FF 52 52'
+ '52 FF 54 54 54 FF 57 57 57 FF 58 58 58 FF 5B 5B'
+ '5B FF 5C 5C 5C FF 5F 5F 5F FF 60 60 60 FF 63 63'
+ '63 FF 64 64 64 FF 66 66 66 FF 68 68 68 FF A8 A8'
+ 'A8 FF E2 E2 E2 E5 3E 3E 3E D4 72 72 72 FF 91 91'
+ '91 FF 79 59 2A FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4B 01 FF 7D 4F 03 FF 80 53'
+ '06 FF 83 58 08 FF 86 5C 0B FF 89 5F 0D FF 8D 65'
+ '10 FF 90 68 13 FF 93 6D 16 FF 97 72 19 FF 9B 77'
+ '1C FF 9E 7C 1F FF A1 80 22 FF A6 86 25 FF A9 8A'
+ '28 FF AD 90 2B FF B1 95 2F FF B5 9B 33 FF B9 A0'
+ '36 FF BD A6 39 FF C2 AC 3D FF C6 B2 40 FF C9 B5'
+ '43 FF CB B9 45 FF CE BC 47 FF CF BE 48 FF CF BE'
+ '48 FF D0 BF 49 FF D0 BF 49 FF 86 76 41 FF EF EF'
+ 'EF FF 52 52 52 FF 37 37 37 FF 38 38 38 FF 39 39'
+ '39 FF 8F 8F 8F FF A9 A9 A9 FF BF BF BF FF C9 C9'
+ 'C9 FF 69 69 69 FF 4F 4F 4F FF 51 51 51 FF 53 53'
+ '53 FF 55 55 55 FF 58 58 58 FF 5A 5A 5A FF 5C 5C'
+ '5C FF 5E 5E 5E FF 60 60 60 FF 62 62 62 FF 64 64'
+ '64 FF 66 66 66 FF 68 68 68 FF 6A 6A 6A FF A8 A8'
+ 'A8 FF E3 E3 E3 E5 3C 3C 3C D4 71 71 71 FF 8F 8F'
+ '8F FF 78 58 29 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7B 4C 01 FF 7D 4F 03 FF 80 53'
+ '06 FF 84 58 09 FF 86 5B 0B FF 89 5F 0D FF 8D 64'
+ '10 FF 90 68 13 FF 93 6D 16 FF 97 72 19 FF 9B 77'
+ '1C FF 9E 7C 1F FF A1 80 22 FF A5 85 25 FF A8 8A'
+ '28 FF AD 90 2B FF B1 95 2F FF B5 9A 32 FF B8 A0'
+ '35 FF BC A5 39 FF C1 AB 3D FF C5 B1 40 FF C8 B5'
+ '43 FF CB B8 45 FF CD BC 47 FF CF BE 48 FF D0 BF'
+ '49 FF D0 BF 49 FF D0 C0 49 FF 84 77 49 FF EF EF'
+ 'EF FF 4A 4A 4A FF 37 37 37 FF 38 38 38 FF 39 39'
+ '39 FF 8F 8F 8F FF AA AA AA FF C0 C0 C0 FF C9 C9'
+ 'C9 FF 6B 6B 6B FF 50 50 50 FF 52 52 52 FF 54 54'
+ '54 FF 56 56 56 FF 59 59 59 FF 5B 5B 5B FF 5D 5D'
+ '5D FF 5F 5F 5F FF 61 61 61 FF 63 63 63 FF 65 65'
+ '65 FF 67 67 67 FF 69 69 69 FF 6B 6B 6B FF A9 A9'
+ 'A9 FF E2 E2 E2 E5 3A 3A 3A D4 70 70 70 FF 8D 8D'
+ '8D FF 77 57 26 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4B 01 FF 7D 4F 03 FF 80 53'
+ '05 FF 83 57 08 FF 86 5A 0A FF 89 5F 0D FF 8C 64'
+ '10 FF 8F 68 13 FF 93 6C 15 FF 96 71 18 FF 9A 76'
+ '1B FF 9D 7B 1E FF A1 7F 21 FF A4 84 24 FF A8 88'
+ '27 FF AC 8E 2A FF B0 94 2E FF B4 99 31 FF B7 9E'
+ '34 FF BB A3 37 FF C0 A9 3B FF C4 B0 3F FF C7 B3'
+ '42 FF CA B7 44 FF CC BA 45 FF CE BC 47 FF CF BE'
+ '48 FF CF BE 48 FF CF BE 48 FF 85 78 51 FF EE EE'
+ 'EE FF 43 43 43 FF 37 37 37 FF 38 38 38 FF 39 39'
+ '39 FF 8E 8E 8E FF AA AA AA FF C0 C0 C0 FF C9 C9'
+ 'C9 FF 6D 6D 6D FF 51 51 51 FF 54 54 54 FF 56 56'
+ '56 FF 58 58 58 FF 59 59 59 FF 5B 5B 5B FF 5E 5E'
+ '5E FF 5F 5F 5F FF 60 60 60 FF 63 63 63 FF 64 64'
+ '64 FF 65 65 65 FF 67 67 67 FF 69 69 69 FF AB AB'
+ 'AB FF E3 E3 E3 E5 39 39 39 D4 6F 6F 6F FF 8C 8C'
+ '8C FF 78 56 23 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 7A 4A 00 FF 7D 4E 03 FF 7F 52'
+ '05 FF 83 56 08 FF 85 5A 0A FF 88 5E 0C FF 8B 62'
+ '0F FF 8F 67 12 FF 92 6B 15 FF 95 70 17 FF 99 75'
+ '1B FF 9C 79 1D FF A0 7E 20 FF A3 83 23 FF A6 87'
+ '26 FF AA 8C 29 FF AE 92 2C FF B2 97 30 FF B5 9B'
+ '33 FF B9 A1 36 FF BD A6 39 FF C2 AD 3E FF C6 B1'
+ '40 FF C8 B5 43 FF CA B7 44 FF CC BA 45 FF CD BC'
+ '47 FF CD BC 47 FF CE BD 47 FF 86 79 56 FF ED ED'
+ 'ED FF 3D 3D 3D FF 38 38 38 FF 38 38 38 FF 3A 3A'
+ '3A FF 8F 8F 8F FF AA AA AA FF C1 C1 C1 FF C9 C9'
+ 'C9 FF 6D 6D 6D FF 50 50 50 FF 54 54 54 FF 57 57'
+ '57 FF 5A 5A 5A FF 5B 5B 5B FF 5E 5E 5E FF 60 60'
+ '60 FF 61 61 61 FF 61 61 61 FF 62 62 62 FF 64 64'
+ '64 FF 61 61 61 FF 5E 5E 5E FF 64 64 64 FF A8 A8'
+ 'A8 FF E2 E2 E2 E5 38 38 38 D4 6E 6E 6E FF 8A 8A'
+ '8A FF 78 56 20 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 79 49 00 FF 7C 4D 02 FF 7E 51'
+ '04 FF 82 55 07 FF 84 58 09 FF 87 5C 0C FF 8A 61'
+ '0E FF 8E 66 11 FF 91 6A 14 FF 94 6E 17 FF 97 73'
+ '19 FF 9B 77 1C FF 9E 7C 1F FF A1 80 22 FF A5 85'
+ '25 FF A8 89 28 FF AD 8F 2B FF B0 94 2E FF B4 99'
+ '31 FF B7 9E 34 FF BB A3 37 FF BF A9 3B FF C1 AC'
+ '40 FF BB A9 44 FF B2 A2 4B FF A7 9A 50 FF 9F 95'
+ '5C FF 9E 97 6D FF A1 9C 80 FF A8 A6 A2 FF EB EB'
+ 'EB FF 39 39 39 FF 38 38 38 FF 39 39 39 FF 3A 3A'
+ '3A FF 8F 8F 8F FF AA AA AA FF C1 C1 C1 FF C9 C9'
+ 'C9 FF 6A 6A 6A FF 50 50 50 FF 4E 4E 4E FF 50 50'
+ '50 FF 53 53 53 FF 55 55 55 FF 57 57 57 FF 5B 5B'
+ '5B FF 5F 5F 5F FF 62 62 62 FF 66 66 66 FF 69 69'
+ '69 FF 6B 6B 6B FF 6D 6D 6D FF 6C 6C 6C FF A8 A8'
+ 'A8 FF E5 E5 E5 E5 37 37 37 D4 6C 6C 6C FF 89 89'
+ '89 FF 77 54 1E FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 79 49 00 FF 7A 4B 01 FF 7E 50'
+ '04 FF 81 54 06 FF 83 57 08 FF 86 5B 0B FF 89 5F'
+ '0D FF 8C 64 10 FF 8F 67 12 FF 92 6C 15 FF 96 71'
+ '18 FF 99 75 1B FF 9C 79 1D FF A0 7E 20 FF A3 83'
+ '23 FF A0 82 27 FF 9C 82 2F FF 96 82 3C FF 92 82'
+ '48 FF 93 87 59 FF 97 8F 70 FF A0 9B 8A FF A9 A8'
+ 'A0 FF B8 B8 B7 FF CA CA CA FF DC DC DC FF E8 E8'
+ 'E8 FF EF EF EF FF F1 F1 F1 FF ED ED ED FF CC CC'
+ 'CC FF 38 38 38 FF 38 38 38 FF 39 39 39 FF 3A 3A'
+ '3A FF 8E 8E 8E FF AA AA AA FF C1 C1 C1 FF C9 C9'
+ 'C9 FF 6A 6A 6A FF 57 57 57 FF 56 56 56 FF 58 58'
+ '58 FF 5A 5A 5A FF 5D 5D 5D FF 5F 5F 5F FF 61 61'
+ '61 FF 63 63 63 FF 66 66 66 FF 68 68 68 FF 6A 6A'
+ '6A FF 6C 6C 6C FF 6F 6F 6F FF 6D 6D 6D FF A8 A8'
+ 'A8 FF E4 E4 E4 E5 34 34 34 D4 6C 6C 6C FF 88 88'
+ '88 FF 78 53 1B FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 79 49 00 FF 79 49 00 FF 7A 4A 00 FF 7D 4F'
+ '03 FF 80 53 05 FF 82 56 07 FF 85 59 09 FF 87 5D'
+ '0C FF 88 5F 0E FF 83 5F 15 FF 82 63 22 FF 80 67'
+ '31 FF 7E 6C 40 FF 82 74 53 FF 89 80 6A FF 91 8D'
+ '84 FF A2 A0 9D FF B3 B3 B3 FF C5 C5 C5 FF D5 D5'
+ 'D5 FF DF DF DF FF E5 E5 E5 FF E6 E6 E6 FE E8 E8'
+ 'E8 F3 E9 E9 E9 D9 E6 E6 E6 BE B1 B1 B1 DF 8B 8B'
+ '8B FE 75 75 75 FF 5C 5C 5C FF 46 46 46 FF 3C 3C'
+ '3C FF 38 38 38 FF 38 38 38 FF 39 39 39 FF 3A 3A'
+ '3A FF 8E 8E 8E FF AA AA AA FF C1 C1 C1 FF C9 C9'
+ 'C9 FF 6B 6B 6B FF 58 58 58 FF 56 56 56 FF 58 58'
+ '58 FF 5C 5C 5C FF 60 60 60 FF 64 64 64 FF 63 63'
+ '63 FF 64 64 64 FF 65 65 65 FF 65 65 65 FF 67 67'
+ '67 FF 69 69 69 FF 6B 6B 6B FF 6C 6C 6C FF A6 A6'
+ 'A6 FF E4 E4 E4 E5 33 33 33 D4 6A 6A 6A FF 86 86'
+ '86 FF 77 51 18 FF 79 49 00 FF 79 49 00 FF 79 49'
+ '00 FF 78 48 00 FF 75 47 02 FF 73 4C 0F FF 74 53'
+ '1F FF 75 5A 2F FF 77 64 43 FF 7B 6D 56 FF 81 79'
+ '6C FF 89 86 82 FF 95 95 94 FF A1 A1 A1 FF AD AD'
+ 'AD FF B9 B9 B9 FF C1 C1 C1 FF C9 C9 C9 FF CE CE'
+ 'CE FE D2 D2 D2 F6 D5 D5 D5 DB DB DB DB AC DE DE'
+ 'DE 87 DE DE DE 65 E3 E3 E3 42 E7 E7 E7 20 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 41'
+ '41 2F 3B 3B 3B 79 3A 3A 3A C1 38 38 38 F8 38 38'
+ '38 FF 39 39 39 FF 39 39 39 FF 3A 3A 3A FF 3B 3B'
+ '3B FF 8E 8E 8E FF A9 A9 A9 FF C0 C0 C0 FF C8 C8'
+ 'C8 FF 6E 6E 6E FF 50 50 50 FF 51 51 51 FF 53 53'
+ '53 FF 54 54 54 FF 54 54 54 FF 63 63 63 FF 70 70'
+ '70 FF 7D 7D 7D FF 92 92 92 FF 9D 9D 9D FF AE AE'
+ 'AE FF B9 B9 B9 FF C8 C8 C8 FF D3 D3 D3 FF DE DE'
+ 'DE FF E4 E4 E4 E5 33 33 33 D4 68 68 68 FF 83 83'
+ '83 FF 70 58 35 FF 6E 56 33 FF 72 60 45 FF 75 6A'
+ '5A FF 79 74 6D FF 83 82 80 FF 8A 8A 8A FF 91 91'
+ '91 FF 97 97 97 FF 9D 9D 9D FF A1 A1 A1 FF A5 A5'
+ 'A5 FF A7 A7 A7 FE AC AC AC ED B0 B0 B0 D0 B5 B5'
+ 'B5 AE BA BA BA 8D BF BF BF 6C C3 C3 C3 49 C7 C7'
+ 'C7 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 0C 00 00 00 2F 00 00 00 38 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 37 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 38 00 00 00 2A 00 00 00 0B 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 3F 3F 3F 14 3D 3D'
+ '3D 57 3B 3B 3B A2 3A 3A 3A E6 3B 3B 3B FE 3C 3C'
+ '3C FF 8E 8E 8E FF A8 A8 A8 FF C0 C0 C0 FF C7 C7'
+ 'C7 FF AE AE AE FF AC AC AC FF B6 B6 B6 FF B8 B8'
+ 'B8 FF CB CB CB FF E1 E1 E1 FF EE EE EE FF F2 F2'
+ 'F2 FF F2 F2 F2 FF F3 F3 F3 FF F3 F3 F3 FF F2 F2'
+ 'F2 FF F1 F1 F1 FF F1 F1 F1 FF F2 F2 F2 FF EB EB'
+ 'EB FF DB DB DB D5 39 39 39 CD 66 66 66 FF 7F 7F'
+ '7F FF 81 81 81 FF 85 85 85 FF 89 89 89 FF 8C 8C'
+ '8C FF 8E 8E 8E FF 91 91 91 FC 96 96 96 E4 98 98'
+ '98 C2 9B 9B 9B 9F A0 A0 A0 7C A4 A4 A4 5A AB AB'
+ 'AB 37 B9 B9 B9 16 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 43 00 00 00 B0 00 00 00 F4 00 00 00 F8 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F7 00 00 00 F7 00 00 00 F7 00 00 00 F7 00 00'
- '00 F8 00 00 00 DA 00 00 00 85 00 00 00 28 00 00'
+ '00 00 00 00 00 00 00 00 00 00 42 42 42 36 3D 3D'
+ '3D 80 88 88 88 E8 9C 9C 9C FF BC BC BC FF C5 C5'
+ 'C5 FF D2 D2 D2 FF DD DD DD FF E0 E0 E0 FF E2 E2'
+ 'E2 FF E8 E8 E8 FF E7 E7 E7 FE E6 E6 E6 FB E8 E8'
+ 'E8 F3 E7 E7 E7 E2 EA EA EA D1 EA EA EA BF F1 F1'
+ 'F1 AD F0 F0 F0 9A F0 F0 F0 89 EF EF EF 76 F2 F2'
+ 'F2 64 F5 F5 F5 35 58 58 58 2B 6C 6C 6C D4 80 80'
+ '80 E8 83 83 83 C2 87 87 87 9E 8D 8D 8D 79 91 91'
+ '91 54 9A 9A 9A 30 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 11 00 00'
- '00 E2 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 01 01 01 FF 01 01 01 FF 01 01'
- '01 FF 01 01 01 FF 01 01 01 FF 02 02 02 FF 02 02'
- '02 FF 03 03 03 FF 04 04 04 FF 04 04 04 FF 03 03'
- '03 FF 00 00 00 FF 00 00 00 FF 00 00 00 AF 00 00'
- '00 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 A3 A3 A3 54 C4 C4 C4 8C C8 C8 C8 8C BB BB'
+ 'BB 8B E1 E1 E1 77 E5 E5 E5 63 E3 E3 E3 53 E6 E6'
+ 'E6 3F D7 D7 D7 2D E3 E3 E3 1C 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 65 00 00'
- '00 FF 20 20 20 FF 9B 9B 9B FF B9 B9 B9 FF B5 B5'
- 'B5 FF B2 B2 B2 FF B0 B0 B0 FF AE AE AE FF AB AB'
- 'AB FF A9 A9 A9 FF A7 A7 A7 FF A4 A4 A4 FF A2 A2'
- 'A2 FF 9F 9F 9F FF 9C 9C 9C FF 9B 9B 9B FF 96 96'
- '96 FF 8C 8C 8C FF 86 86 86 FF 88 88 88 FF 8E 8E'
- '8E FF 5A 5A 5A FF 03 03 03 FF 00 00 00 E9 00 00'
- '00 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 A6 00 00'
- '00 FF 59 59 59 FF FF FF FF FF FA FA FA FF F1 F1'
- 'F1 FF EB EB EB FF E4 E4 E4 FF E0 E0 E0 FF DC DC'
- 'DC FF D8 D8 D8 FF D4 D4 D4 FF D0 D0 D0 FF CB CB'
- 'CB FF C7 C7 C7 FF C3 C3 C3 FF BF BF BF FF BB BB'
- 'BB FF B0 B0 B0 FF 9E 9E 9E FF 97 97 97 FF 9E 9E'
- '9E FF B0 B0 B0 FF 25 25 25 FF 00 00 00 FD 00 00'
- '00 5A 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 C6 00 00'
- '00 FF 82 82 82 FF FF FF FF FF F7 F7 F7 FF F1 F1'
- 'F1 FF E9 E9 E9 FF E4 E4 E4 FF DF DF DF FF DA DA'
- 'DA FF D6 D6 D6 FF D2 D2 D2 FF CE CE CE FF CA CA'
- 'CA FF C7 C7 C7 FF C3 C3 C3 FF BF BF BF FF BB BB'
- 'BB FF B8 B8 B8 FF A9 A9 A9 FF 9C 9C 9C FF 98 98'
- '98 FF AF AF AF FF 3D 3D 3D FF 00 00 00 FF 00 00'
- '00 7C 00 00 00 01 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 D4 00 00'
- '00 FF 92 92 92 FF FF FF FF FF FF FF FF FF F9 F9'
- 'F9 FF F6 F6 F6 FF F6 F6 F6 FF F3 F3 F3 FF EF EF'
- 'EF FF EC EC EC FF E6 E6 E6 FF E1 E1 E1 FF DC DC'
- 'DC FF D6 D6 D6 FF D1 D1 D1 FF CC CC CC FF C6 C6'
- 'C6 FF C3 C3 C3 FF AF AF AF FF A5 A5 A5 FF A8 A8'
- 'A8 FF B6 B6 B6 FF 44 44 44 FF 00 00 00 FF 00 00'
- '00 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 B5 00 00'
- '00 FF 84 84 84 FF FF FF FF FF FF FF FF FF F7 F7'
- 'F7 FF FB FB FB FF FD FD FD FF FC FC FC FF FC FC'
- 'FC FF FA FA FA FF F8 F8 F8 FF F1 F1 F1 FF EB EB'
- 'EB FF E5 E5 E5 FF DF DF DF FF D9 D9 D9 FF D3 D3'
- 'D3 FF CF CF CF FF B5 B5 B5 FF A3 A3 A3 FF AD AD'
- 'AD FF BB BB BB FF 3D 3D 3D FF 00 00 00 FF 00 00'
- '00 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 88 00 00'
- '00 FF 5F 5F 5F FF FF FF FF FF FF FF FF FF FB FB'
- 'FB FF EF EF EF FF EE EE EE FF E9 E9 E9 FF E3 E3'
- 'E3 FF DF DF DF FF DD DD DD FF DA DA DA FF D5 D5'
- 'D5 FF D0 D0 D0 FF CC CC CC FF C7 C7 C7 FF C3 C3'
- 'C3 FF BE BE BE FF B0 B0 B0 FF B2 B2 B2 FF B4 B4'
- 'B4 FF BA BA BA FF 28 28 28 FF 00 00 00 F7 00 00'
- '00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 34 00 00'
- '00 FA 2E 2E 2E FF ED ED ED FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FA FA'
- 'FA FF F5 F5 F5 FF F4 F4 F4 FF EF EF EF FF EB EB'
- 'EB FF E5 E5 E5 FF E0 E0 E0 FF DC DC DC FF D8 D8'
- 'D8 FF D2 D2 D2 FF C2 C2 C2 FF BA BA BA FF C1 C1'
- 'C1 FF 97 97 97 FF 0A 0A 0A FF 00 00 00 D5 00 00'
- '00 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00'
- '00 C8 04 04 04 FF 97 97 97 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FD FD FD FF DF DF DF FF BE BE BE FF C4 C4'
- 'C4 FF E4 E4 E4 FF E6 E6 E6 FF E1 E1 E1 FF DD DD'
- 'DD FF D1 D1 D1 FF C5 C5 C5 FF C2 C2 C2 FF BF BF'
- 'BF FF 43 43 43 FF 00 00 00 FF 00 00 00 9A 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 6C 00 00 00 FF 18 18 18 FF D1 D1 D1 FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FE FE FE FF B2 B2 B2 FF 9D 9D 9D FF 98 98'
- '98 FF D1 D1 D1 FF ED ED ED FF E5 E5 E5 FF DF DF'
- 'DF FF D1 D1 D1 FF CC CC CC FF D5 D5 D5 FF 84 84'
- '84 FF 00 00 00 FF 00 00 00 E2 00 00 00 29 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 96 00 00 00 FF 3E 3E 3E FF D1 D1'
- 'D1 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF ED ED ED FF DE DE DE FF E1 E1'
- 'E1 FF EC EC EC FF EE EE EE FF E7 E7 E7 FF DC DC'
- 'DC FF DC DC DC FF D7 D7 D7 FF 7B 7B 7B FF 14 14'
- '14 FF 00 00 00 FF 00 00 00 5F 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1A 00 00 00 C6 00 00 00 FF 35 35'
- '35 FF C3 C3 C3 FF F9 F9 F9 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FC FC FC FF FC FC'
- 'FC FF F7 F7 F7 FF F0 F0 F0 FF EC EC EC FF EB EB'
- 'EB FF CF CF CF FF 77 77 77 FF 07 07 07 FF 00 00'
- '00 FD 00 00 00 8F 00 00 00 05 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 05 00 00 00 B6 00 00'
- '00 FF 08 08 08 FF 58 58 58 FF CB CB CB FF FD FD'
- 'FD FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF F9 F9 F9 FF E3 E3 E3 FF 9E 9E'
- '9E FF 31 31 31 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00'
- '00 0C 00 00 00 14 00 00 00 14 00 00 00 14 00 00'
- '00 14 00 00 00 14 00 00 00 0E 00 00 00 1F 00 00'
- '00 7B 00 00 00 E9 00 00 00 FF 10 10 10 FF 3E 3E'
- '3E FF 69 69 69 FF 89 89 89 FF B1 B1 B1 FF A2 A2'
- 'A2 FF 7E 7E 7E FF 57 57 57 FF 2C 2C 2C FF 04 04'
- '04 FF 00 00 00 FF 00 00 00 BF 00 00 00 4F 00 00'
- '00 14 00 00 00 11 00 00 00 14 00 00 00 14 00 00'
- '00 14 00 00 00 14 00 00 00 14 00 00 00 0C 00 00'
- '00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 04 00 00 00 4C 00 00 00 8A 00 00'
- '00 AD 00 00 00 BB 00 00 00 B9 00 00 00 B9 00 00'
- '00 B9 00 00 00 B9 00 00 00 B9 00 00 00 B5 00 00'
- '00 AB 00 00 00 D1 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 04 04 04 FF 7E 7E 7E FF 4B 4B'
- '4B FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 F1 00 00 00 BA 00 00 00 AF 00 00'
- '00 B7 00 00 00 B9 00 00 00 B9 00 00 00 B9 00 00'
- '00 B9 00 00 00 B9 00 00 00 B8 00 00 00 A5 00 00'
- '00 85 00 00 00 43 00 00 00 0A 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 06 00 00 00 95 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 54 54 54 FF BD BD BD FF 8A 8A'
- '8A FF 1B 1B 1B FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 F0 00 00 00 69 00 00 00 0D 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 7A 00 00 00 FF 04 04 04 FF 5A 5A 5A FF A7 A7'
- 'A7 FF AD AD AD FF AB AB AB FF AA AA AA FF AA AA'
- 'AA FF AA AA AA FF A9 A9 A9 FF A9 A9 A9 FF A8 A8'
- 'A8 FF A8 A8 A8 FF A8 A8 A8 FF A7 A7 A7 FF A6 A6'
- 'A6 FF A9 A9 A9 FF C5 C5 C5 FF D3 D3 D3 FF C6 C6'
- 'C6 FF B4 B4 B4 FF A3 A3 A3 FF A3 A3 A3 FF A3 A3'
- 'A3 FF A2 A2 A2 FF A1 A1 A1 FF A1 A1 A1 FF A1 A1'
- 'A1 FF A0 A0 A0 FF A0 A0 A0 FF 9F 9F 9F FF 9F 9F'
- '9F FF 9E 9E 9E FF A1 A1 A1 FF 94 94 94 FF 31 31'
- '31 FF 00 00 00 FF 00 00 00 F6 00 00 00 5C 00 00'
- '00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00'
- '00 EA 00 00 00 FF 78 78 78 FF FA FA FA FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FE FE FE FF FB FB'
- 'FB FF FA FA FA FF F8 F8 F8 FF F7 F7 F7 FF F4 F4'
- 'F4 FF F3 F3 F3 FF F2 F2 F2 FF F0 F0 F0 FF EF EF'
- 'EF FF EC EC EC FF E6 E6 E6 FF E2 E2 E2 FF E2 E2'
- 'E2 FF E3 E3 E3 FF E4 E4 E4 FF E2 E2 E2 FF E0 E0'
- 'E0 FF DE DE DE FF DC DC DC FF DB DB DB FF D9 D9'
- 'D9 FF D8 D8 D8 FF D6 D6 D6 FF D4 D4 D4 FF D3 D3'
- 'D3 FF D0 D0 D0 FF CF CF CF FF DD DD DD FF CB CB'
- 'CB FF 39 39 39 FF 00 00 00 FF 00 00 00 AF 00 00'
- '00 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 78 00 00'
- '00 FF 17 17 17 FF DF DF DF FF FF FF FF FF F7 F7'
- 'F7 FF F6 F8 F8 FF F5 F6 F8 FF F3 F4 F5 FF F1 F3'
- 'F4 FF EF F0 F2 FF ED EF F0 FF EC ED EE FF E9 EA'
- 'EB FF E8 E9 EA FF E6 E7 E9 FF E4 E6 E7 FF E2 E3'
- 'E4 FF E0 E1 E3 FF DF E0 E1 FF DD DE DF FF DB DC'
- 'DD FF D9 DB DC FF D8 D8 D9 FF D6 D7 D8 FF D4 D5'
- 'D7 FF D2 D4 D4 FF D0 D1 D3 FF CE D0 D1 FF CD CE'
- 'CF FF CB CD CE FF CA CB CD FF C7 C9 CA FF C6 C8'
- 'C9 FF C4 C6 C7 FF C2 C3 C3 FF C0 C0 C0 FF D9 D9'
- 'D9 FF A4 A4 A4 FF 00 00 00 FF 00 00 00 EE 00 00'
- '00 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 39 39 39 FF F0 F0 F0 FF FF FF FF FF F9 F9'
- 'F9 FF F6 F0 EB FF F5 EF EA FF F5 EE EA FF F3 EE'
- 'E9 FF F3 ED E9 FF F2 EC E8 FF F2 EC E8 FF F0 EC'
- 'E6 FF F0 EB E6 FF F0 EA E6 FF EF EA E4 FF ED E8'
- 'E4 FF ED E8 E3 FF EC E7 E2 FF EB E6 E1 FF E9 E5'
- 'E0 FF E8 E4 DF FF E7 E2 DD FF E6 E1 DC FF E5 DF'
- 'DB FF E3 DE D9 FF E2 DD D8 FF E1 DB D6 FF DF DA'
- 'D4 FF DE D8 D3 FF DD D7 D2 FF DB D5 D0 FF D9 D3'
- 'CE FF DB D5 D2 FF D3 D2 D2 FF C3 C3 C3 FF CB CB'
- 'CB FF AE AE AE FF 05 05 05 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 3C 3C 3C FF F1 F1 F1 FF FF FF FF FF FB FF'
- 'FF FF E2 CA B9 FF D8 9B 70 FF DC A2 79 FF DE A7'
- '7D FF E1 AA 81 FF E3 AF 85 FF E5 B2 88 FF E8 B6'
- '8C FF E9 B9 8E FF EB BB 91 FF ED BE 94 FF EE C0'
- '95 FF EF C1 96 FF EF C2 97 FF EF C2 97 FF EE C1'
- '97 FF EE C0 95 FF EC BE 93 FF EB BB 90 FF E9 B8'
- '8E FF E7 B5 8B FF E5 B1 87 FF E3 AE 84 FF E1 AA'
- '81 FF DF A6 7D FF DC A2 79 FF D9 9E 75 FF D6 97'
- '6E FF E0 AB 8B FF E5 E3 E2 FF C4 C5 C6 FF CC CC'
- 'CC FF AB AB AB FF 06 06 06 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 3A 3A 3A FF F1 F1 F1 FF FF FF FF FF FD FF'
- 'FF FF D0 A9 90 FF BC 56 11 FF C3 63 1F FF C6 69'
- '26 FF CA 70 2C FF CD 76 32 FF D1 7B 37 FF D4 81'
- '3D FF D7 86 41 FF D9 89 44 FF DC 8D 48 FF DD 90'
- '4A FF DF 92 4D FF DF 93 4D FF DF 93 4D FF DE 91'
- '4C FF DD 90 4A FF DB 8C 46 FF D8 88 43 FF D6 83'
- '3F FF D3 7E 3A FF D0 78 34 FF CC 73 2F FF C8 6D'
- '2A FF C5 67 24 FF C1 61 1E FF BD 5A 17 FF B6 4E'
- '0A FF C4 6F 38 FF E5 E2 E0 FF C7 C8 C9 FF CF CF'
- 'CF FF AC AC AC FF 05 05 05 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 39 39 39 FF F0 F0 F0 FF FF FF FF FF FF FF'
- 'FF FF D1 AC 94 FF BC 5A 19 FF C2 66 26 FF C6 6C'
- '2C FF CA 72 32 FF CD 77 37 FF D0 7C 3C FF D3 81'
- '40 FF D5 85 44 FF D7 88 47 FF D9 8C 4A FF DA 8E'
- '4C FF DC 8F 4D FF DC 90 4E FF DC 90 4E FF DB 8F'
- '4D FF DA 8D 4B FF D9 8A 49 FF D6 87 46 FF D4 83'
- '42 FF D1 7F 3E FF CE 7A 39 FF CB 75 34 FF C8 70'
- '30 FF C5 6A 2B FF C1 64 25 FF BD 5E 1F FF B7 53'
- '12 FF C6 73 3F FF E6 E3 E1 FF C8 C9 CA FF D0 D0'
- 'D0 FF AC AC AC FF 05 05 05 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 38 38 38 FF F0 F0 F0 FF FF FF FF FF FF FF'
- 'FF FF D1 AB 92 FF B9 55 14 FF BF 61 22 FF C3 67'
- '28 FF C6 6D 2D FF CA 71 31 FF CC 76 36 FF CF 7B'
- '3A FF D1 7E 3D FF D3 81 40 FF D5 85 44 FF D6 87'
- '45 FF D7 88 47 FF D7 89 47 FF D7 89 47 FF D7 87'
- '47 FF D6 86 45 FF D4 83 42 FF D2 80 3F FF D0 7D'
- '3C FF CE 79 38 FF CB 74 34 FF C8 6F 2F FF C5 6A'
- '2B FF C2 65 26 FF BE 60 21 FF BA 5A 1B FF B4 4E'
- '0F FF C4 70 3C FF E6 E3 E2 FF CA CB CC FF D2 D2'
- 'D2 FF AC AC AC FF 05 05 05 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 38 38 38 FF F0 F0 F0 FF FF FF FF FF FF FF'
- 'FF FF D0 A9 91 FF B7 51 10 FF BD 5C 1D FF C0 62'
- '23 FF C3 67 28 FF C6 6C 2C FF C9 71 30 FF CB 75'
- '34 FF CE 78 37 FF CF 7B 3A FF D0 7E 3D FF D1 7F'
- '3E FF D2 81 40 FF D3 81 40 FF D2 81 40 FF D2 80'
- '3F FF D1 7F 3E FF D0 7C 3C FF CE 79 39 FF CD 76'
- '36 FF CA 73 32 FF C7 6E 2E FF C5 6A 2A FF C2 66'
- '26 FF BF 60 21 FF BC 5B 1C FF B8 55 17 FF B2 4A'
- '0A FF C2 6C 39 FF E7 E4 E3 FF CC CD CE FF D4 D4'
- 'D4 FF AB AB AB FF 04 04 04 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 36 36 36 FF EF EF EF FF FF FF FF FF FF FF'
- 'FF FF CE A7 8F FF B3 4C 0B FF B9 58 18 FF BC 5D'
- '1E FF C0 62 23 FF C3 66 27 FF C5 6A 2B FF C7 6E'
- '2E FF C9 71 31 FF CB 74 33 FF CC 76 36 FF CD 78'
- '37 FF CE 79 39 FF CE 79 39 FF CE 79 39 FF CE 79'
- '38 FF CD 77 37 FF CC 75 35 FF CA 72 32 FF C8 70'
- '30 FF C6 6C 2D FF C3 68 29 FF C1 64 25 FF BE 60'
- '21 FF BC 5B 1C FF B8 56 18 FF B5 50 12 FF AF 45'
- '05 FF BF 68 35 FF E8 E5 E3 FF CD CF D0 FF D6 D6'
- 'D6 FF AB AB AB FF 04 04 04 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 36 36 36 FF EE EE EE FF FF FF FF FF FF FF'
- 'FF FF CC A4 8C FF B0 46 06 FF B6 51 13 FF B9 57'
- '18 FF BC 5B 1D FF BF 60 21 FF C1 64 24 FF C3 67'
- '28 FF C5 6A 2B FF C6 6D 2D FF C8 6F 2F FF C9 70'
- '30 FF C9 72 32 FF C9 72 32 FF C9 72 32 FF C9 72'
- '31 FF C8 70 30 FF C7 6E 2E FF C6 6B 2C FF C4 69'
- '2A FF C2 66 26 FF BF 62 22 FF BD 5E 1F FF BA 5A'
- '1B FF B8 55 17 FF B5 50 12 FF B2 4B 0D FF AC 40'
- '00 FF BC 64 31 FF E9 E5 E4 FF D0 D1 D2 FF D8 D8'
- 'D8 FF AA AA AA FF 04 04 04 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 35 35 35 FF ED ED ED FF FF FF FF FF FF FF'
- 'FF FF CA A0 88 FF AD 40 00 FF B3 4C 0E FF B5 51'
- '13 FF B8 56 17 FF BB 5A 1B FF BD 5D 1E FF BF 61'
- '21 FF C0 63 24 FF C1 65 25 FF C2 67 28 FF C3 69'
- '29 FF C5 69 2A FF C5 6A 2A FF C5 6A 2A FF C4 69'
- '29 FF C4 68 28 FF C2 66 27 FF C0 64 24 FF BF 61'
- '22 FF BE 5E 20 FF BC 5B 1D FF BA 58 19 FF B7 54'
- '16 FF B5 50 12 FF B2 4B 0D FF AF 46 08 FF A8 3B'
- '00 FF BB 62 30 FF EA E7 E5 FF D1 D3 D4 FF D9 D9'
- 'D9 FF AA AA AA FF 03 03 03 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 34 34 34 FF EC EC EC FF FF FF FF FF FF FF'
- 'FF FF C6 9D 85 FF A9 3A 00 FF AF 46 09 FF B2 4B'
- '0E FF B4 4F 12 FF B6 53 15 FF B8 55 17 FF B9 58'
- '19 FF BB 5C 1D FF BF 60 22 FF C2 66 27 FF C4 68'
- '29 FF C5 6A 2A FF C5 6B 2B FF C5 6B 2B FF C5 6B'
- '2B FF C5 69 2A FF C3 68 29 FF C1 65 26 FF BF 60'
- '22 FF BB 59 1B FF B7 54 15 FF B4 4F 11 FF B3 4D'
- '0F FF B1 4A 0C FF AE 45 08 FF AB 40 03 FF A6 38'
- '00 FF BA 61 2F FF EA E7 E6 FF D3 D4 D5 FF DB DB'
- 'DB FF A9 A9 A9 FF 03 03 03 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 33 33 33 FF EC EC EC FF FF FF FF FF FF FF'
- 'FF FF C4 9A 83 FF A6 37 00 FF AC 40 03 FF AE 45'
- '07 FF AF 47 0A FF B3 4D 0F FF B9 57 18 FF BE 5F'
- '20 FF C4 68 29 FF C6 6D 2D FF C8 70 30 FF CA 72'
- '31 FF CA 73 33 FF CB 74 33 FF CB 74 33 FF CB 73'
- '33 FF CA 73 32 FF C9 71 31 FF C8 70 30 FF C7 6D'
- '2D FF C4 69 2A FF BF 60 22 FF B8 56 18 FF B3 4D'
- '0F FF AC 42 04 FF AA 3F 02 FF A9 3E 01 FF A6 38'
- '00 FF BA 61 2F FF EB E8 E6 FF D5 D6 D7 FF DC DC'
- 'DC FF A9 A9 A9 FF 03 03 03 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 32 32 32 FF EB EB EB FF FF FF FF FF FF FF'
- 'FF FF C3 99 81 FF A6 37 00 FF A9 3D 00 FF A9 3D'
- '00 FF B1 49 0C FF C0 63 24 FF C6 6D 2D FF C9 71'
- '31 FF CA 74 33 FF CB 75 35 FF CD 78 37 FF CE 79'
- '39 FF CF 7B 3A FF CF 7B 3B FF CF 7B 3B FF CF 7B'
- '3A FF CE 7A 3A FF CD 79 38 FF CC 76 36 FF CB 74'
- '34 FF C9 71 32 FF C7 6E 2F FF C6 6B 2B FF C2 66'
- '27 FF B7 54 16 FF AA 40 03 FF A8 3C 00 FF A6 38'
- '00 FF BA 61 2F FF EC E9 E7 FF D7 D9 D9 FF DF DF'
- 'DF FF A8 A8 A8 FF 02 02 02 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 31 31 31 FF EA EA EA FF FF FF FF FF FF FF'
- 'FF FF C2 98 80 FF A5 36 00 FF A8 3C 00 FF B7 55'
- '17 FF C4 6A 2A FF C8 70 31 FF CA 73 33 FF CD 76'
- '36 FF CE 79 39 FF D0 7C 3B FF D1 7F 3E FF D2 80'
- '3F FF D3 82 41 FF D3 83 42 FF D3 83 42 FF D3 82'
- '41 FF D3 81 40 FF D2 80 3F FF D0 7D 3C FF CF 7B'
- '3A FF CD 78 37 FF CB 74 34 FF C9 71 30 FF C7 6E'
- '2E FF C5 6A 2B FF BE 5F 20 FF B0 4A 0C FF A5 36'
- '00 FF BA 61 2F FF EC E9 E8 FF D8 DA DA FF E0 E0'
- 'E0 FF A7 A7 A7 FF 02 02 02 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 30 30 30 FF E9 E9 E9 FF FF FF FF FF FF FF'
- 'FF FF C0 96 7E FF A6 37 00 FF B8 55 17 FF C7 6D'
- '2E FF C9 71 31 FF CC 75 35 FF CD 79 39 FF D0 7D'
- '3C FF D2 80 3F FF D3 83 42 FF D5 86 44 FF D7 87'
- '46 FF D8 89 48 FF D8 8A 48 FF D8 8A 48 FF D8 89'
- '48 FF D7 88 47 FF D6 87 45 FF D5 84 43 FF D3 82'
- '41 FF D1 7E 3D FF CE 7A 3A FF CD 77 36 FF CA 73'
- '33 FF C7 6E 2E FF C5 6B 2B FF C0 63 23 FF AD 41'
- '02 FF BA 60 2E FF ED EA E9 FF DA DC DD FF E2 E2'
- 'E2 FF A7 A7 A7 FF 02 02 02 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2F 2F 2F FF E8 E8 E8 FF FF FF FF FF FE FF'
- 'FF FF BD 92 7B FF AF 45 05 FF C7 6D 2D FF C9 71'
- '31 FF CC 76 35 FF CF 7A 3A FF D1 7E 3E FF D4 83'
- '42 FF D6 86 46 FF D8 8A 48 FF DA 8D 4B FF DB 8F'
- '4D FF DC 90 4E FF DC 91 50 FF DC 91 50 FF DC 91'
- '4F FF DC 90 4E FF DA 8E 4C FF D9 8B 49 FF D7 88'
- '47 FF D5 84 43 FF D2 80 3F FF D0 7C 3B FF CD 78'
- '37 FF CB 73 32 FF C7 6E 2E FF C5 6A 2B FF BC 5B'
- '1A FF BD 65 33 FF EE EA E9 FF DC DE DF FF E4 E4'
- 'E4 FF A7 A7 A7 FF 01 01 01 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2E 2E 2E FF E7 E7 E7 FF FF FF FF FF FE FF'
- 'FF FF BD 93 7B FF BA 57 17 FF C9 71 31 FF CB 74'
- '34 FF CE 7A 3A FF D2 7F 3E FF D4 84 43 FF D7 88'
- '47 FF DA 8C 4A FF DC 8F 4D FF DE 93 51 FF DF 96'
- '54 FF E0 98 56 FF E1 99 56 FF E1 99 56 FF E1 99'
- '56 FF E0 97 55 FF DE 94 53 FF DD 91 50 FF DB 8E'
- '4C FF D8 8A 48 FF D5 85 44 FF D3 81 40 FF D0 7C'
- '3C FF CD 77 37 FF C9 72 32 FF C6 6D 2D FF C2 62'
- '21 FF C4 70 3D FF ED EA E8 FF DE DF E0 FF E5 E5'
- 'E5 FF A6 A6 A6 FF 01 01 01 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2C 2C 2C FF E5 E5 E5 FF FF FF FF FF FD FF'
- 'FF FF BE 96 7E FF C2 64 22 FF CB 74 33 FF CE 79'
- '38 FF D1 7F 3E FF D5 84 43 FF D7 89 48 FF DA 8E'
- '4C FF DE 92 50 FF E0 96 54 FF E2 9A 58 FF E3 9C'
- '5A FF E5 9F 5C FF E6 A0 5D FF E6 A0 5D FF E5 A0'
- '5D FF E4 9E 5B FF E3 9B 59 FF E1 98 56 FF DF 94'
- '52 FF DC 90 4E FF D8 8B 49 FF D6 86 45 FF D3 81'
- '40 FF D0 7C 3B FF CC 77 36 FF C9 70 30 FF C4 68'
- '26 FF C8 76 43 FF EE EA E9 FF E1 E2 E3 FF E8 E8'
- 'E8 FF A5 A5 A5 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2C 2C 2C FF E5 E5 E5 FF FF FF FF FF FD FF'
- 'FF FF BC 94 7B FF C4 67 24 FF CD 77 37 FF D0 7C'
- '3C FF D4 83 42 FF D7 88 47 FF DB 8D 4C FF DE 93'
- '51 FF E1 97 56 FF E3 9C 59 FF E6 A0 5D FF E7 A3'
- '60 FF E9 A6 63 FF EA A8 64 FF EA A8 64 FF E9 A7'
- '64 FF E8 A5 62 FF E7 A2 5F FF E4 9E 5B FF E2 99'
- '57 FF DF 95 53 FF DC 8F 4D FF D8 8A 49 FF D6 86'
- '44 FF D2 80 3F FF CF 7A 3A FF CB 74 33 FF C6 6B'
- '29 FF C7 76 43 FF F6 F2 F0 FF F4 F5 F6 FF F6 F6'
- 'F6 FF A5 A5 A5 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2B 2B 2B FF E4 E4 E4 FF FF FF FF FF FD FF'
- 'FF FF B7 8D 75 FF BC 5A 19 FF CF 7C 3B FF D2 80'
- '3E FF D5 85 44 FF D9 8C 4A FF DD 91 4F FF E0 97'
- '55 FF E3 9C 5A FF E6 A1 5E FF E9 A5 63 FF EB A9'
- '66 FF ED AD 69 FF EF AF 6B FF EF AF 6C FF EE AF'
- '6A FF ED AB 68 FF EA A7 65 FF E7 A3 61 FF E4 9E'
- '5C FF E1 99 57 FF DE 93 52 FF DA 8E 4C FF D7 88'
- '47 FF D4 82 41 FF D0 7C 3C FF CC 77 36 FF C7 6C'
- '2A FF C3 6F 3D FF F7 F3 F2 FF F7 F9 FA FF FC FC'
- 'FC FF A5 A5 A5 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2A 2A 2A FF E3 E3 E3 FF FF FF FF FF FD FF'
- 'FF FF B4 88 70 FF AF 41 01 FF D0 78 34 FF D4 81'
- '3E FF D8 87 43 FF DC 8D 49 FF E0 93 4F FF E3 9A'
- '55 FF E7 A0 5B FF EB A5 60 FF EE AA 65 FF F1 AF'
- '6A FF F3 B3 6E FF F5 B6 70 FF F5 B6 70 FF F4 B5'
- '6F FF F2 B2 6C FF F0 AD 67 FF EC A7 62 FF E9 A2'
- '5D FF E5 9C 58 FF E1 96 52 FF DE 90 4C FF DA 8A'
- '46 FF D6 83 40 FF D2 7D 3A FF CF 78 35 FF C1 5F'
- '1B FF BB 5F 2C FF F9 F5 F3 FF F9 FB FB FF FE FE'
- 'FE FF A5 A5 A5 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 2A 2A 2A FF E3 E3 E3 FF FF FF FF FF FD FF'
- 'FF FF B4 95 84 FF A0 4F 23 FF B6 71 43 FF CB 89'
- '53 FF CE 8D 57 FF D1 92 5B FF D4 97 61 FF D7 9D'
- '66 FF DA A2 6A FF DD A7 6E FF E0 AB 73 FF E4 B0'
- '78 FF E6 B4 7B FF E7 B7 7F FF E8 B7 7F FF E6 B6'
- '7D FF E5 B2 7A FF E2 AE 76 FF DE A9 71 FF DC A4'
- '6C FF D9 9F 68 FF D5 99 63 FF D2 94 5D FF CF 8F'
- '59 FF CC 8A 54 FF CA 85 4F FF C3 7E 4A FF A7 5A'
- '2C FF B3 73 4F FF FA F8 F7 FF FC FD FD FF FF FF'
- 'FF FF A5 A5 A5 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 84 00 00'
- '00 FF 26 26 26 FF E1 E1 E1 FF FF FF FF FF FF FF'
- 'FF FF EC EC ED FF E6 E6 E7 FF E6 E5 E6 FF E9 E7'
- 'E5 FF E9 E7 E5 FF E9 E7 E5 FF E9 E7 E5 FF E9 E7'
- 'E5 FF E9 E8 E6 FF E9 E8 E6 FF EA E8 E6 FF EA E8'
- 'E6 FF EA E8 E6 FF EA E8 E6 FF EA E8 E6 FF EA E8'
- 'E6 FF EA E8 E6 FF EA E8 E6 FF E9 E8 E6 FF E8 E7'
- 'E5 FF E8 E6 E4 FF E8 E6 E4 FF E8 E6 E4 FF E8 E6'
- 'E4 FF E7 E5 E3 FF E7 E5 E3 FF E6 E4 E3 FF E3 E3'
- 'E3 FF E9 E9 E9 FF FC FC FC FF FD FD FD FF FF FF'
- 'FF FF A4 A4 A4 FF 00 00 00 FF 00 00 00 F7 00 00'
- '00 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 7D 00 00'
- '00 FF 0D 0D 0D FF C4 C4 C4 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FE FE FE FF FF FF FF FF FB FB'
- 'FB FF 7F 7F 7F FF 00 00 00 FF 00 00 00 F2 00 00'
- '00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00'
- '00 FB 00 00 00 FF 56 56 56 FF E3 E3 E3 FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FD FD FD FF AF AF'
- 'AF FF 21 21 21 FF 00 00 00 FF 00 00 00 B9 00 00'
- '00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 8D 00 00 00 FF 01 01 01 FF 2F 2F 2F FF 6D 6D'
- '6D FF 7D 7D 7D FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C'
- '7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C'
- '7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C'
- '7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C'
- '7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C 7C FF 7C 7C'
- '7C FF 7C 7C 7C FF 7C 7C 7C FF 7B 7B 7B FF 7B 7B'
- '7B FF 7B 7B 7B FF 7A 7A 7A FF 7A 7A 7A FF 7A 7A'
- '7A FF 7A 7A 7A FF 77 77 77 FF 57 57 57 FF 18 18'
- '18 FF 00 00 00 FF 00 00 00 FF 00 00 00 57 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 19 00 00 00 B9 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 F5 00 00 00 86 00 00 00 04 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 63 00 00 00 D0 00 00'
- '00 F3 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F1 00 00 00 EF 00 00'
- '00 B2 00 00 00 3D 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF F8'
- '00 00 1F FF 00 00 FF F0 00 00 0F FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 03 FF 00 00 FF C0 00 00 03 FF 00 00 FF C0'
- '00 00 07 FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 07 FF 00 00 FF E0 00 00 07 FF 00 00 FF E0'
- '00 00 0F FF 00 00 FF F0 00 00 0F FF 00 00 FF F8'
- '00 00 1F FF 00 00 FF F8 00 00 1F FF 00 00 FF FC'
- '00 00 7F FF 00 00 FE 00 00 00 00 7F 00 00 F8 00'
- '00 00 00 1F 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 E0 00 00 00 00 07 00 00 E0 00'
- '00 00 00 07 00 00 F0 00 00 00 00 0F 00 00 F0 00'
- '00 00 00 0F 00 00 FC 00 00 00 00 3F 00 00 28 00'
- '00 00 20 00 00 00 40 00 00 00 01 00 20 00 00 00'
- '00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 0B 00 00 00 4B 00 00'
- '00 63 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 61 00 00'
- '00 61 00 00 00 61 00 00 00 61 00 00 00 63 00 00'
- '00 3D 00 00 00 05 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 04 00 00 00 AF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FF 00 00 00 FF 01 01 01 FF 01 01'
- '01 FF 01 01 01 FF 02 02 02 FF 02 02 02 FF 02 02'
- '02 FF 03 03 03 FF 05 05 05 FF 03 03 03 FF 00 00'
- '00 FA 00 00 00 80 00 00 00 03 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 3E 00 00 00 FD 6E 6E 6E FF B7 B7'
- 'B7 FF AD AD AD FF A9 A9 A9 FF A5 A5 A5 FF A2 A2'
- 'A2 FF 9F 9F 9F FF 9B 9B 9B FF 97 97 97 FF 94 94'
- '94 FF 8C 8C 8C FF 83 83 83 FF 85 85 85 FF 38 38'
- '38 FF 00 00 00 EA 00 00 00 27 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 67 0F 0F 0F FF D8 D8 D8 FF FF FF'
- 'FF FF ED ED ED FF E2 E2 E2 FF DB DB DB FF D3 D3'
- 'D3 FF CD CD CD FF C8 C8 C8 FF C2 C2 C2 FF BC BC'
- 'BC FF B4 B4 B4 FF 9F 9F 9F FF A2 A2 A2 FF 7F 7F'
- '7F FF 00 00 00 FD 00 00 00 47 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 72 1B 1B 1B FF E6 E6 E6 FF FF FF'
- 'FF FF F6 F6 F6 FF F5 F5 F5 FF F1 F1 F1 FF EC EC'
- 'EC FF E4 E4 E4 FF DC DC DC FF D4 D4 D4 FF CC CC'
- 'CC FF C5 C5 C5 FF AB AB AB FF AD AD AD FF 90 90'
- '90 FF 04 04 04 FF 00 00 00 50 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FE 00'
+ '01 FF FF FF FF FF FE 00 00 01 FF FF FF FF FC 00'
+ '00 00 03 FF FF FF F8 00 00 00 00 00 00 FF F0 00'
+ '00 00 00 00 00 01 F0 00 00 00 00 00 00 00 F0 00'
+ '00 00 00 00 00 00 FF 80 00 00 00 00 00 00 FF 80'
+ '00 00 00 00 00 00 FF 80 00 00 00 00 00 00 FF 80'
+ '00 00 00 00 00 00 FF 80 00 00 00 00 00 00 FF 80'
+ '00 00 00 00 00 00 FF 80 00 00 00 00 00 00 FF C0'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 56 0D 0D 0D FF D4 D4 D4 FF FF FF'
- 'FF FF F7 F7 F7 FF F8 F8 F8 FF F3 F3 F3 FF F0 F0'
- 'F0 FF EC EC EC FF E3 E3 E3 FF DA DA DA FF D2 D2'
- 'D2 FF CA CA CA FF B0 B0 B0 FF B8 B8 B8 FF 82 82'
- '82 FF 00 00 00 F8 00 00 00 32 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 1F 00 00 00 ED 94 94 94 FF FF FF'
- 'FF FF FE FE FE FF FD FD FD FF FA FA FA FF F3 F3'
- 'F3 FF E5 E5 E5 FF E1 E1 E1 FF E0 E0 E0 FF DA DA'
- 'DA FF D1 D1 D1 FF BF BF BF FF C5 C5 C5 FF 52 52'
- '52 FF 00 00 00 CD 00 00 00 0D 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 97 29 29 29 FF E4 E4'
- 'E4 FF FF FF FF FF FF FF FF FF FF FF FF FF F0 F0'
- 'F0 FF AB AB AB FF B4 B4 B4 FF E8 E8 E8 FF E4 E4'
- 'E4 FF D5 D5 D5 FF D3 D3 D3 FF 9D 9D 9D FF 0C 0C'
- '0C FF 00 00 00 6C 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 1C 00 00 00 D8 4C 4C'
- '4C FF EC EC EC FF FF FF FF FF FF FF FF FF FA FA'
- 'FA FF E2 E2 E2 FF E3 E3 E3 FF F0 F0 F0 FF EA EA'
- 'EA FF E6 E6 E6 FF B1 B1 B1 FF 23 23 23 FF 00 00'
- '00 B7 00 00 00 08 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 2B 00 00'
- '00 D5 33 33 33 FF B4 B4 B4 FF F9 F9 F9 FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FB FB FB FF DC DC'
- 'DC FF 89 89 89 FF 1A 1A 1A FF 00 00 00 B6 00 00'
- '00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 09 00 00 00 28 00 00'
- '00 38 00 00 00 37 00 00 00 37 00 00 00 2C 00 00'
- '00 50 00 00 00 CC 03 03 03 FF 31 31 31 FF 67 67'
- '67 FF A2 A2 A2 FF 90 90 90 FF 59 59 59 FF 22 22'
- '22 FF 00 00 00 FF 00 00 00 B4 00 00 00 41 00 00'
- '00 2F 00 00 00 37 00 00 00 37 00 00 00 37 00 00'
- '00 27 00 00 00 09 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 32 00 00 00 BE 00 00 00 F7 00 00'
- '00 FB 00 00 00 FA 00 00 00 FA 00 00 00 FA 00 00'
- '00 F3 00 00 00 F2 00 00 00 FF 00 00 00 FF 05 05'
- '05 FF 79 79 79 FF 4C 4C 4C FF 00 00 00 FF 00 00'
- '00 FF 00 00 00 FD 00 00 00 F0 00 00 00 F6 00 00'
- '00 FA 00 00 00 FA 00 00 00 FA 00 00 00 FB 00 00'
- '00 F1 00 00 00 AE 00 00 00 29 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 1B 00 00 00 DB 26 26 26 FF 94 94 94 FF AD AD'
- 'AD FF AA AA AA FF A9 A9 A9 FF A7 A7 A7 FF A7 A7'
- 'A7 FF A6 A6 A6 FF A4 A4 A4 FF A2 A2 A2 FF AB AB'
- 'AB FF CD CD CD FF BF BF BF FF A2 A2 A2 FF 9E 9E'
- '9E FF 9E 9E 9E FF 9C 9C 9C FF 9C 9C 9C FF 9B 9B'
- '9B FF 9A 9A 9A FF 99 99 99 FF 9B 9B 9B FF 77 77'
- '77 FF 11 11 11 FF 00 00 00 C1 00 00 00 14 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 6F 06 06 06 FF C0 C0 C0 FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FD FF FF FF FA FD FE FF F7 FA'
- 'FC FF F4 F7 F9 FF F1 F4 F6 FF EE F1 F3 FF EA EC'
- 'EE FF E2 E4 E6 FF E1 E3 E5 FF E2 E5 E7 FF E1 E2'
- 'E5 FF DE E0 E2 FF DA DD DF FF D8 DA DD FF D5 D8'
- 'DA FF D3 D6 D8 FF D0 D3 D5 FF CE CF CF FF DD DD'
- 'DD FF 81 81 81 FF 00 00 00 FF 00 00 00 4E 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 22 22 22 FF EB EB EB FF FF FF FF FF F3 EA'
- 'E4 FF F0 E0 D4 FF EF E1 D6 FF EF E1 D6 FF EF E1'
- 'D6 FF EE E1 D6 FF ED E1 D6 FF EC E1 D5 FF EC E0'
- 'D5 FF EA DE D3 FF E9 DD D2 FF E7 DA CF FF E5 D8'
- 'CD FF E2 D5 CA FF DF D2 C7 FF DD CF C4 FF DB CC'
- 'C1 FF D8 C9 BE FF D8 C8 BD FF D2 CE CC FF CB CC'
- 'CC FF AB AB AB FF 06 06 06 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 24 24 24 FF EB EB EB FF FF FF FF FF D4 AB'
- '8F FF C5 67 26 FF CD 77 39 FF D2 81 42 FF D7 89'
- '4A FF DC 91 50 FF E0 97 57 FF E3 9C 5C FF E5 9F'
- '5E FF E5 9F 5F FF E4 9E 5D FF E2 9A 5A FF DF 94'
- '55 FF DA 8D 4E FF D6 85 47 FF D1 7D 3F FF CC 75'
- '37 FF C6 6A 2C FF C5 68 2B FF D8 C3 B5 FF CE D1'
- 'D3 FF A9 A9 A9 FF 06 06 06 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 22 22 22 FF EA EA EA FF FF FF FF FF D0 A5'
- '89 FF BD 5A 16 FF C6 6A 2A FF CB 73 32 FF D0 7A'
- '3A FF D4 82 40 FF D7 87 45 FF DA 8C 49 FF DB 8E'
- '4B FF DB 8E 4C FF DA 8D 4A FF D8 89 47 FF D5 84'
- '42 FF D2 7E 3C FF CD 76 35 FF C8 6E 2E FF C3 66'
- '26 FF BD 5B 1A FF BB 59 1A FF D7 C0 B2 FF D1 D5'
- 'D8 FF A9 A9 A9 FF 05 05 05 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 22 22 22 FF EA EA EA FF FF FF FF FF D0 A4'
- '88 FF BA 54 12 FF C2 65 25 FF C7 6D 2D FF CB 73'
- '34 FF CF 7A 39 FF D2 7F 3E FF D3 82 42 FF D4 84'
- '43 FF D5 84 43 FF D4 83 42 FF D2 80 3F FF D0 7C'
- '3B FF CD 76 36 FF C8 6F 30 FF C4 68 29 FF BF 60'
- '21 FF B9 56 17 FF B8 54 17 FF D8 C1 B3 FF D4 D8'
- 'DA FF A9 A9 A9 FF 05 05 05 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 21 21 21 FF E9 E9 E9 FF FF FF FF FF CD A0'
- '84 FF B5 4C 0B FF BD 5D 1E FF C1 64 25 FF C5 6B'
- '2A FF C9 70 30 FF CB 74 34 FF CD 77 37 FF CD 78'
- '38 FF CD 78 38 FF CD 78 37 FF CC 75 35 FF CA 72'
- '32 FF C7 6D 2D FF C3 67 27 FF BF 60 21 FF BB 58'
- '1A FF B5 4F 10 FF B4 4D 11 FF D8 C0 B2 FF D8 DB'
- 'DE FF A9 A9 A9 FF 04 04 04 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 20 20 20 FF E8 E8 E8 FF FF FF FF FF CA 9B'
- '80 FF B0 44 02 FF B8 54 15 FF BC 5A 1C FF BF 60'
- '21 FF C1 65 25 FF C4 68 28 FF C5 6B 2B FF C6 6C'
- '2D FF C6 6D 2D FF C6 6C 2D FF C4 69 2A FF C2 66'
- '26 FF C0 61 22 FF BD 5D 1E FF B9 57 19 FF B5 50'
- '12 FF B0 47 08 FF B0 46 0A FF D8 C0 B2 FF DA DE'
- 'E0 FF A8 A8 A8 FF 04 04 04 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 20 20 20 FF E7 E7 E7 FF FF FF FF FF C6 96'
- '7B FF AA 3B 00 FF B2 4A 0D FF B4 4F 11 FF B8 55'
- '17 FF BD 5E 1F FF C2 65 25 FF C4 69 2A FF C5 6B'
- '2C FF C6 6C 2C FF C6 6C 2C FF C4 69 2A FF C2 65'
- '26 FF BE 5E 20 FF B8 55 17 FF B3 4C 0E FF AF 46'
- '08 FF AB 3F 01 FF AD 43 06 FF DA C2 B4 FF DE E2'
- 'E4 FF A7 A7 A7 FF 03 03 03 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1F 1F 1F FF E6 E6 E6 FF FF FF FF FF C2 93'
- '78 FF A5 34 00 FF AB 40 03 FF B6 52 14 FF C1 64'
- '26 FF C7 6E 2F FF CA 73 33 FF CC 77 36 FF CD 78'
- '38 FF CD 79 38 FF CD 78 38 FF CC 77 37 FF CB 74'
- '34 FF C8 6F 30 FF C4 69 2A FF BC 5C 1D FF AF 47'
- '0A FF A7 3A 00 FF AC 43 06 FF DB C3 B5 FF E0 E4'
- 'E7 FF A7 A7 A7 FF 03 03 03 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1E 1E 1E FF E5 E5 E5 FF FF FF FF FF C1 90'
- '76 FF A6 36 00 FF BA 59 1A FF C8 6F 2F FF CC 75'
- '35 FF CF 7A 3A FF D1 7F 3E FF D3 82 41 FF D4 83'
- '42 FF D4 84 43 FF D4 83 42 FF D3 82 41 FF D1 7E'
- '3E FF CF 7A 39 FF CC 75 35 FF C9 70 30 FF C3 67'
- '27 FF B3 4D 0E FF AC 42 06 FF DC C4 B6 FF E3 E7'
- 'EA FF A7 A7 A7 FF 02 02 02 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1D 1D 1D FF E4 E4 E4 FF FF FF FF FF BE 8E'
- '73 FF B7 50 0E FF CA 72 32 FF CD 77 37 FF D1 7D'
- '3D FF D4 83 43 FF D8 88 47 FF D9 8C 4B FF DB 8F'
- '4D FF DB 8F 4D FF DB 8F 4D FF D9 8C 4B FF D8 88'
- '47 FF D4 83 43 FF D1 7D 3D FF CD 76 36 FF C9 70'
- '30 FF C4 67 27 FF B5 51 14 FF DC C3 B6 FF E6 EA'
- 'EC FF A6 A6 A6 FF 01 01 01 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1C 1C 1C FF E2 E2 E2 FF FF FF FF FF C3 96'
- '7A FF C4 65 22 FF CD 76 36 FF D2 7E 3E FF D6 85'
- '44 FF DA 8C 4B FF DD 92 50 FF E0 97 54 FF E1 99'
- '57 FF E2 99 58 FF E1 99 57 FF E0 97 54 FF DD 92'
- '50 FF DA 8C 4B FF D6 85 44 FF D2 7E 3E FF CC 76'
- '36 FF C7 6D 2D FF C2 65 27 FF DE C6 B9 FF E8 EB'
- 'EE FF A6 A6 A6 FF 01 01 01 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1B 1B 1B FF E1 E1 E1 FF FF FF FF FF C5 9A'
- '7E FF C8 6C 28 FF D1 7D 3C FF D6 85 44 FF DA 8D'
- '4B FF DF 94 52 FF E3 9B 59 FF E6 A1 5E FF E8 A4'
- '62 FF E9 A5 62 FF E8 A4 62 FF E6 A1 5E FF E3 9B'
- '59 FF DF 94 52 FF DA 8D 4B FF D6 85 44 FF D0 7D'
- '3C FF CA 72 31 FF C7 6D 2E FF E5 CE C1 FF F4 F8'
- 'FA FF A7 A7 A7 FF 00 00 00 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1A 1A 1A FF E0 E0 E0 FF FF FF FF FF BC 8D'
- '70 FF C7 68 23 FF D4 81 3E FF D9 89 46 FF DE 92'
- '4E FF E4 9A 56 FF E9 A2 5E FF ED AA 65 FF F0 AE'
- '6A FF F1 B0 6B FF F0 AE 6A FF ED AA 65 FF E9 A2'
- '5E FF E4 9A 56 FF DE 92 4E FF D9 89 46 FF D4 80'
- '3D FF CE 76 33 FF C2 63 23 FF E9 D0 C2 FF FF FF'
- 'FF FF AA AA AA FF 00 00 00 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 1A 1A 1A FF E0 E0 E0 FF FF FF FF FF B5 8D'
- '76 FF B4 60 29 FF CF 88 4F FF D4 90 56 FF D9 98'
- '5D FF DE A0 65 FF E3 A8 6D FF E7 AF 74 FF EB B5'
- '79 FF EC B7 7B FF EB B5 79 FF E7 AF 74 FF E3 A8'
- '6D FF DE A0 65 FF D8 98 5D FF D3 90 56 FF CF 87'
- '4E FF C7 7C 44 FF B0 5D 2B FF E8 D3 C8 FF FF FF'
- 'FF FF AB AB AB FF 00 00 00 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 84 15 15 15 FF DB DB DB FF FF FF FF FF EE EC'
- 'EC FF E7 E4 E2 FF EB E7 E4 FF EB E8 E5 FF EC E8'
- 'E5 FF EC E9 E6 FF EC E9 E6 FF EC EA E7 FF ED EA'
- 'E7 FF ED EA E7 FF ED EA E7 FF EC EA E7 FF EC E9'
- 'E6 FF EB E8 E5 FF EA E8 E5 FF EA E7 E4 FF EA E6'
- 'E3 FF E8 E4 E2 FF E6 E3 E2 FF F8 F8 F7 FF FF FF'
- 'FF FF A7 A7 A7 FF 00 00 00 FF 00 00 00 61 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 6C 00 00 00 FF 8E 8E 8E FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
- 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF F4 F4'
- 'F4 FF 58 58 58 FF 00 00 00 FD 00 00 00 45 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 16 00 00 00 D5 0A 0A 0A FF 53 53 53 FF 74 74'
- '74 FF 72 72 72 FF 72 72 72 FF 72 72 72 FF 72 72'
- '72 FF 72 72 72 FF 72 72 72 FF 71 71 71 FF 71 71'
- '71 FF 71 71 71 FF 71 71 71 FF 71 71 71 FF 71 71'
- '71 FF 71 71 71 FF 71 71 71 FF 71 71 71 FF 70 70'
- '70 FF 70 70 70 FF 70 70 70 FF 6F 6F 6F FF 3F 3F'
- '3F FF 02 02 02 FF 00 00 00 B2 00 00 00 05 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 28 00 00 00 B1 00 00 00 EF 00 00'
- '00 F1 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F0 00 00'
- '00 F0 00 00 00 F0 00 00 00 F0 00 00 00 F2 00 00'
- '00 E8 00 00 00 97 00 00 00 15 00 00 00 00 00 00'
- '00 00 00 00 00 00 FF 00 00 FF FE 00 00 7F FE 00'
- '00 7F FE 00 00 7F FE 00 00 7F FE 00 00 7F FE 00'
- '00 7F FF 00 00 FF FF 00 00 FF FF 80 01 FF F0 00'
- '00 0F E0 00 00 07 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 E0 00 00 07 28 00 00 00 10 00 00 00 20 00'
- '00 00 01 00 20 00 00 00 00 00 00 04 00 00 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 03 01 01'
- '01 7C 08 08 08 AD 08 08 08 A8 08 08 08 A8 08 08'
- '08 A8 08 08 08 A8 08 08 08 AD 01 01 01 6D 00 00'
  '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 31 57 57'
- '57 FA CE CE CE FF BB BB BB FF B1 B1 B1 FF A8 A8'
- 'A8 FF 9D 9D 9D FF 8D 8D 8D FF 30 30 30 F2 00 00'
- '00 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 3A 7B 7B'
- '7B FC FF FF FF FF F5 F5 F5 FF EC EC EC FF DD DD'
- 'DD FF CA CA CA FF BA BA BA FF 4C 4C 4C F7 00 00'
- '00 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 0D 37 37'
- '37 D7 F5 F5 F5 FF FF FF FF FF E2 E2 E2 FF D9 D9'
- 'D9 FF E6 E6 E6 FF B7 B7 B7 FF 1C 1C 1C C5 00 00'
- '00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 45 59 59 59 EB E5 E5 E5 FF F1 F1 F1 FF EA EA'
- 'EA FF C2 C2 C2 FF 3B 3B 3B E1 00 00 00 35 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 12 02 02 02 78 06 06 06 96 05 06'
- '06 8A 00 00 00 C6 16 16 16 FF 77 77 77 FF 66 66'
- '66 FF 11 11 11 FF 00 00 00 BC 07 07 07 89 07 07'
- '07 96 02 02 02 73 00 00 00 0E 00 00 00 00 00 00'
- '00 00 03 03 03 9C 94 94 93 FF D1 D4 D7 FF C7 CD'
- 'D0 FF C3 C7 CA FF B9 BD C0 FF C2 C6 C9 FF BB BF'
- 'C2 FF B0 B4 B8 FF B2 B7 BA FF B0 B5 B9 FF B1 B4'
- 'B6 FF 6E 6D 6D FF 00 00 00 84 00 00 00 00 00 00'
- '00 00 19 19 1A CC EC ED ED FF ED C9 B1 FF E6 B4'
- '8F FF EB BF 9B FF ED C4 A0 FF EB C3 9E FF E8 C0'
- '9B FF E5 BA 95 FF DD AF 8B FF D4 9E 79 FF D9 B9'
- 'A5 FF B9 BB BD FF 09 0A 0A A8 00 00 00 00 00 00'
- '00 00 1A 1B 1B CC EB EC ED FF CC 86 58 FF C2 5E'
- '17 FF CE 75 30 FF D5 80 3B FF D8 85 40 FF D6 82'
- '3D FF D1 78 34 FF C8 6A 26 FF BA 4F 08 FF CC 8E'
- '68 FF B8 BC C0 FF 09 09 09 A8 00 00 00 00 00 00'
- '00 00 19 1A 1A CC EA EB EC FF C7 81 57 FF B9 53'
- '12 FF C2 66 26 FF C7 6E 2E FF CA 71 32 FF C8 6F'
- '30 FF C4 68 29 FF BD 5C 1E FF B1 45 04 FF C9 8C'
- '68 FF BA BE C1 FF 08 09 09 A8 00 00 00 00 00 00'
- '00 00 18 19 1A CC E9 EA EB FF BE 73 4A FF AF 44'
- '03 FF C0 62 23 FF C6 6D 2D FF C9 71 31 FF C8 70'
- '30 FF C4 69 2A FF BB 5A 1B FF A9 39 00 FF C7 88'
- '65 FF BC C1 C4 FF 08 08 08 A8 00 00 00 00 00 00'
- '00 00 18 18 19 CC E6 E7 E8 FF C1 7A 4F FF C2 62'
- '1F FF D0 7C 3C FF D5 85 44 FF D7 88 47 FF D7 87'
- '46 FF D3 81 40 FF CC 76 36 FF BB 57 13 FF CC 8F'
- '6C FF BD C1 C4 FF 07 08 08 A8 00 00 00 00 00 00'
- '00 00 16 17 18 CC E3 E4 E4 FF CD 8D 60 FF D0 78'
- '33 FF DA 8C 49 FF E2 98 54 FF E6 9F 5B FF E4 9C'
- '59 FF DE 92 4F FF D6 84 42 FF C9 6B 26 FF DA A2'
- '7C FF C1 C5 C8 FF 07 07 07 A8 00 00 00 00 00 00'
- '00 00 17 17 18 CC E4 E4 E5 FF CA 90 6A FF D5 89'
- '4B FF E1 9F 63 FF EB AE 71 FF F0 B9 7A FF EE B5'
- '77 FF E6 A7 6A FF DC 97 5B FF CC 7B 3D FF DF AD'
- '8D FF D0 D4 D7 FF 06 07 07 A8 00 00 00 00 00 00'
- '00 00 09 09 09 C1 CB CC CC FF FA F6 F4 FF F2 EE'
- 'EA FF F4 F0 EC FF F4 F1 EE FF F4 F2 EE FF F4 F2'
- 'EE FF F4 F0 ED FF F2 EF EA FF F0 EB E8 FF FD FA'
- 'F8 FF AF AF AF FF 00 00 00 9F 00 00 00 00 00 00'
- '00 00 00 00 00 4A 1E 1E 1D E2 45 46 47 F3 43 45'
- '46 F0 42 43 45 F0 42 43 44 F0 42 43 44 F0 42 43'
- '44 F0 42 43 44 F0 42 43 44 F0 42 44 45 F0 41 42'
- '43 F4 16 16 16 D9 00 00 00 39 00 00 00 00 E0 0F'
- '00 00 E0 07 00 00 E0 07 00 00 E0 07 00 00 F0 0F'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00 80 01'
- '00 00 80 01 00 00 80 01 00 00 80 01 00 00'
-} */
-
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 03 C0 00 00 00 00 00 01 FF F8 00 00 00 00 00'
+ 'FF FF FF 80 00 00 00 FF FF FF FF E0 07 FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF'
+}*/ 
 
 
 
index b879d18..a22384d 100644 (file)
@@ -46,6 +46,7 @@ typedef struct
        IContextMenu2Vtbl *lpVtbl;
        IShellFolder*   pSFParent;
        DWORD           ref;
+       BOOL            bDesktop;
 } BgCmImpl;
 
 
@@ -54,7 +55,7 @@ static struct IContextMenu2Vtbl cmvt;
 /**************************************************************************
 *   ISVBgCm_Constructor()
 */
-IContextMenu2 *ISvBgCm_Constructor(IShellFolder*       pSFParent)
+IContextMenu2 *ISvBgCm_Constructor(IShellFolder* pSFParent, BOOL bDesktop)
 {
        BgCmImpl* cm;
 
@@ -62,6 +63,7 @@ IContextMenu2 *ISvBgCm_Constructor(IShellFolder*      pSFParent)
        cm->lpVtbl = &cmvt;
        cm->ref = 1;
        cm->pSFParent = pSFParent;
+       cm->bDesktop = bDesktop;
        if(pSFParent) IShellFolder_AddRef(pSFParent);
 
        TRACE("(%p)->()\n",cm);
@@ -362,12 +364,22 @@ static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
              case FCIDM_SHVIEW_NEWFOLDER:
                DoNewFolder(iface, lpSV);
                break;
+
              case FCIDM_SHVIEW_INSERT:
                DoPaste(iface);
                break;
+
+             case FCIDM_SHVIEW_PROPERTIES:
+               if (This->bDesktop) {
+                   ShellExecuteA(lpcmi->hwnd, "open", "rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL);
+               } else {
+                   FIXME("launch item properties dialog\n");
+               }
+               break;
+
              default:
                /* if it's a id just pass it to the parent shv */
-               SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
+               if (hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
                break;
            }
          }
diff --git a/reactos/lib/shellext/slayer/De.rc b/reactos/lib/shellext/slayer/De.rc
new file mode 100644 (file)
index 0000000..245907e
--- /dev/null
@@ -0,0 +1,38 @@
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
+\r
+IDD_SLAYERSHEET DIALOGEX 0, 0, 224, 226\r
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION\r
+CAPTION "Kompatibilität"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "Falls dieses Programm Probleme verursacht, wählen Sie den zutreffenden Kompatibilitätsmodus, der mit der Betriebssystem-Version übereinstimmt, unter der das Programm korrekt funktionierte.", -1, 7,7,210,31\r
+  GROUPBOX "Kompatibilitätsmodus", IDC_COMPATGROUP, 7,41,210,49\r
+  CHECKBOX "Programm im Kompatibilitätsmodus ausführen für:", IDC_CHKRUNCOMPATIBILITY, 18,57,188,10, BS_AUTOCHECKBOX | WS_TABSTOP\r
+  COMBOBOX IDC_COMPATIBILITYMODE, 18,70,188,85, CBS_HASSTRINGS | CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED\r
+  GROUPBOX "Anzeigeeinstellungen", -1, 7,99,210,61, BS_GROUPBOX | WS_DISABLED\r
+  CHECKBOX "Mit 256 Farben ausführen", IDC_CHKRUNIN256COLORS, 18,114,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED\r
+  CHECKBOX "In Bildschirmauflösung 640 x 480 ausführen", IDC_CHKRUNIN640480RES, 18,129,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED\r
+  CHECKBOX "Visuelle Designs deaktivieren", IDC_CHKDISABLEVISUALTHEMES, 18,144,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED\r
+  PUSHBUTTON "Kompatibilitätsmodus ändern", IDC_EDITCOMPATIBILITYMODES, 117,167,100,15\r
+  /* CONTROL "Weitere Informationen über <A>Programmkompatibilität</A>.", IDC_INFOLINK, "SysLink", WS_CHILD | WS_TABSTOP | WS_VISIBLE, 7,207,210,10, WS_EX_NOPARENTNOTIFY */\r
+END\r
+\r
+IDD_EDITCOMPATIBILITYMODES DIALOGEX 0, 0, 230, 139\r
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Kompatibilitätsmodus ändern"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LISTBOX IDC_COMPATIBILITYMODE, 9,6,148,108, LBS_NOTIFY | LBS_WANTKEYBOARDINPUT | WS_BORDER\r
+  PUSHBUTTON "&Hinzufügen...", IDC_ADD, 162,6,60,14, WS_DISABLED\r
+  PUSHBUTTON "&Ändern...", IDC_EDIT, 162,24,60,14, WS_DISABLED\r
+  PUSHBUTTON "&Löschen", IDC_DELETE, 162,42,60,14, WS_DISABLED\r
+  PUSHBUTTON "&OK", IDOK, 95,116,60,14\r
+  PUSHBUTTON "&Abbrechen", IDCANCEL, 162,116,60,14\r
+END\r
+\r
+STRINGTABLE \r
+BEGIN\r
+  IDS_SLAYER "Slayer"\r
+  IDS_DESCRIPTION "Application Compatibility Layer Shell Extension"\r
+END\r
+\r
diff --git a/reactos/lib/shellext/slayer/en.rc b/reactos/lib/shellext/slayer/en.rc
deleted file mode 100644 (file)
index b78d892..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
-
-IDD_SLAYERSHEET DIALOGEX 0, 0, 224, 226
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
-CAPTION "Compatibility"
-FONT 8, "MS Shell Dlg", 0, 0, 0x0
-BEGIN
-  LTEXT "If you have problems running this program in ReactOS, select an operating system ReactOS should report to the application.", -1, 7,7,210,31
-  GROUPBOX "Compatibility mode", IDC_COMPATGROUP, 7,41,210,49
-  CHECKBOX "Run this program in compatibility mode for:", IDC_CHKRUNCOMPATIBILITY, 18,57,188,10, BS_AUTOCHECKBOX | WS_TABSTOP
-  COMBOBOX IDC_COMPATIBILITYMODE, 18,70,188,85, CBS_HASSTRINGS | CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED
-  GROUPBOX "Display settings", -1, 7,99,210,61, BS_GROUPBOX | WS_DISABLED
-  CHECKBOX "Run in 256 colors", IDC_CHKRUNIN256COLORS, 18,114,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED
-  CHECKBOX "Run in 640x480 screenresolution", IDC_CHKRUNIN640480RES, 18,129,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED
-  CHECKBOX "Disable visual themes", IDC_CHKDISABLEVISUALTHEMES, 18,144,188,10, BS_AUTOCHECKBOX | WS_TABSTOP | WS_DISABLED
-  PUSHBUTTON "E&dit compatibility modes...", IDC_EDITCOMPATIBILITYMODES, 117,167,100,15
-  /* CONTROL "Learn more about <A>program compatibility</A>.", IDC_INFOLINK, "SysLink", WS_CHILD | WS_TABSTOP | WS_VISIBLE, 7,207,210,10, WS_EX_NOPARENTNOTIFY */
-END
-
-IDD_EDITCOMPATIBILITYMODES DIALOGEX 0, 0, 230, 139
-STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
-CAPTION "Edit Compatibility Modes"
-FONT 8, "MS Shell Dlg", 0, 0, 0x0
-BEGIN
-  LISTBOX IDC_COMPATIBILITYMODE, 9,6,148,108, LBS_NOTIFY | LBS_WANTKEYBOARDINPUT | WS_BORDER
-  PUSHBUTTON "&Add...", IDC_ADD, 162,6,60,14, WS_DISABLED
-  PUSHBUTTON "&Edit...", IDC_EDIT, 162,24,60,14, WS_DISABLED
-  PUSHBUTTON "&Delete", IDC_DELETE, 162,42,60,14, WS_DISABLED
-  PUSHBUTTON "&OK", IDOK, 95,116,60,14
-  PUSHBUTTON "&Cancel", IDCANCEL, 162,116,60,14
-END
-
-STRINGTABLE 
-BEGIN
-  IDS_SLAYER "Slayer"
-  IDS_DESCRIPTION "Application Compatibility Layer Shell Extension"
-END
-
index 9789762..0e69992 100644 (file)
@@ -9,5 +9,12 @@
 #define REACTOS_STR_ORIGINAL_FILENAME  "slayer.dll\0"
 #include <reactos/version.rc>
 
-#include "en.rc"
+/*
+ * Everything specific to any language goes in one of the specific
+ * files. Note that you can and may override resources which also have
+ * a neutral version. This is to get localized bitmaps for example.
+ */
+
+#include "En.rc"
+#include "De.rc"
 
index 340ac20..81109b9 100644 (file)
@@ -43,7 +43,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
  *  when you right-click on a file).\r
  *\r
  * HELPERS\r
- * You can use this object tranparently by calling the helper functions\r
+ * You can use this object transparently by calling the helper functions\r
  * AssocQueryKeyA(), AssocQueryStringA() and AssocQueryStringByKeyA(). These\r
  * create an IQueryAssociations object, perform the requested actions\r
  * and then dispose of the object. Alternatively, you can create an instance\r
index 7b2785d..ec9a4a3 100644 (file)
@@ -62,7 +62,7 @@ typedef struct tagDLGDATAEX
 /* Dialogue procedure for general message boxes */\r
 static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
 {\r
-  DLGDATAEX *d = (DLGDATAEX *)GetWindowLongW(hDlg, DWL_USER);\r
+  DLGDATAEX *d = (DLGDATAEX *)GetWindowLongPtrW(hDlg, DWLP_USER);\r
 \r
   TRACE("(%p,%u,%d,%ld) data %p\n", hDlg, uMsg, wParam, lParam, d);\r
 \r
@@ -71,7 +71,7 @@ static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
   case WM_INITDIALOG:\r
   {\r
     /* FIXME: Not sure where native stores its lParam */\r
-    SetWindowLongW(hDlg, DWL_USER, lParam);\r
+    SetWindowLongPtrW(hDlg, DWLP_USER, lParam);\r
     d = (DLGDATAEX *)lParam;\r
     TRACE("WM_INITDIALOG: %p, %s,%p,%p\n", hDlg, debugstr_w(d->lpszId),\r
           d->dlgProc, (void*)d->lParam);\r
index 616d1ba..112c124 100644 (file)
@@ -2397,7 +2397,7 @@ HWND WINAPI SHCreateWorkerWindowA(LONG wndProc, HWND hWndParent, DWORD dwExStyle
                          hWndParent, hMenu, shlwapi_hInstance, 0);\r
   if (hWnd)\r
   {\r
-    SetWindowLongA(hWnd, DWL_MSGRESULT, z);\r
+    SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);\r
 \r
     if (wndProc)\r
       SetWindowLongPtrA(hWnd, GWLP_WNDPROC, wndProc);\r
@@ -2684,7 +2684,7 @@ HWND WINAPI SHCreateWorkerWindowW(LONG wndProc, HWND hWndParent, DWORD dwExStyle
                          hWndParent, hMenu, shlwapi_hInstance, 0);\r
   if (hWnd)\r
   {\r
-    SetWindowLongW(hWnd, DWL_MSGRESULT, z);\r
+    SetWindowLongPtrW(hWnd, DWLP_MSGRESULT, z);\r
 \r
     if (wndProc)\r
       SetWindowLongPtrW(hWnd, GWLP_WNDPROC, wndProc);\r
index 63e501b..f234b7e 100644 (file)
 368 stdcall @(wstr wstr ptr long wstr) kernel32.GetPrivateProfileStructW
 369 stdcall @(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW
 370 stdcall -noname ExtractIconWrapW(long wstr long)
-371 stdcall DdeInitializeWrapW(ptr ptr long long) user32.DdeInitializeW
-372 stdcall DdeCreateStringHandleWrapW(long ptr long) user32.DdeCreateStringHandleW
-373 stdcall DdeQueryStringWrapW(long ptr wstr long long) user32.DdeQueryStringW
+371 stdcall -noname DdeInitializeWrapW(ptr ptr long long) user32.DdeInitializeW
+372 stdcall -noname DdeCreateStringHandleWrapW(long ptr long) user32.DdeCreateStringHandleW
+373 stdcall -noname DdeQueryStringWrapW(long ptr wstr long long) user32.DdeQueryStringW
 374 stub -noname SHCheckDiskForMediaA
 375 stub -noname SHCheckDiskForMediaW
 376 stdcall -noname MLGetUILanguage()  # kernel32.GetUserDefaultUILanguage
 389 stdcall -noname GetSaveFileNameWrapW(ptr)
 390 stdcall -noname WNetRestoreConnectionWrapW(long wstr)
 391 stdcall -noname WNetGetLastErrorWrapW(ptr ptr long ptr long)
-392 stdcall EndDialogWrap(ptr ptr) user32.EndDialog
+392 stdcall -noname EndDialogWrap(ptr ptr) user32.EndDialog
 393 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamW
 394 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamA
 395 stub -noname MLWinHelpA
 456 stdcall -noname PathIsValidCharW(long long)
 457 stub -noname GetLongPathNameWrapW
 458 stub -noname GetLongPathNameWrapA
-459 stdcall SHExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA
-460 stdcall SHExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW
+459 stdcall -noname SHExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA
+460 stdcall -noname SHExpandEnvironmentStringsW(wstr ptr long) kernel32.ExpandEnvironmentStringsW
 461 stdcall -noname SHGetAppCompatFlags(long)
 462 stub -noname UrlFixupW
 463 stub -noname SHExpandEnvironmentStringsForUserA
index 8d3fced..e9706e2 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
 \r
 IDD_ERR_DIALOG DIALOG MOVEABLE DISCARDABLE 0, 0, 220, 60\r
 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
index fc6b6f7..78f5c1d 100644 (file)
@@ -534,7 +534,7 @@ LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
 /*************************************************************************\r
  * StrRStrIA   [SHLWAPI.@]\r
  *\r
- * Find the last occurence of a substring within a string.\r
+ * Find the last occurrence of a substring within a string.\r
  *\r
  * PARAMS\r
  *  lpszStr    [I] String to search in\r
@@ -542,7 +542,7 @@ LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
  *  lpszSearch [I] String to look for\r
  *\r
  * RETURNS\r
- *  The last occurence lpszSearch within lpszStr, or NULL if not found.\r
+ *  The last occurrence lpszSearch within lpszStr, or NULL if not found.\r
  */\r
 LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)\r
 {\r
@@ -711,7 +711,7 @@ int WINAPI StrToIntW(LPCWSTR lpszStr)
  * NOTES\r
  *  Leading whitespace, '-' and '+' are allowed before the number. If\r
  *  dwFlags includes STIF_SUPPORT_HEX, hexadecimal numbers are allowed, if\r
- *  preceeded by '0x'. If this flag is not set, or there is no '0x' prefix,\r
+ *  preceded by '0x'. If this flag is not set, or there is no '0x' prefix,\r
  *  the string is treated as a decimal string. A leading '-' is ignored for\r
  *  hexadecimal numbers.\r
  */\r
@@ -1171,7 +1171,7 @@ static LPWSTR WINAPI SHLWAPI_StrRChrHelperW(LPCWSTR lpszStr,
 /**************************************************************************\r
  * StrRChrA    [SHLWAPI.@]\r
  *\r
- * Find the last occurence of a character in string.\r
+ * Find the last occurrence of a character in string.\r
  *\r
  * PARAMS\r
  *  lpszStr [I] String to search in\r
@@ -1205,7 +1205,7 @@ LPWSTR WINAPI StrRChrW(LPCWSTR lpszStr, LPCWSTR lpszEnd, WORD ch)
 /**************************************************************************\r
  * StrRChrIA   [SHLWAPI.@]\r
  *\r
- * Find the last occurence of a character in string, ignoring case.\r
+ * Find the last occurrence of a character in string, ignoring case.\r
  *\r
  * PARAMS\r
  *  lpszStr [I] String to search in\r
index 3275d1b..44c3b18 100644 (file)
@@ -6,7 +6,7 @@ TARGET_TYPE = dynlink
 
 TARGET_NAME = smdll
 
-TARGET_SDKLIBS = ntdll.a
+TARGET_SDKLIBS = smlib.a ntdll.a
 
 TARGET_CFLAGS = -I./include -Wall -Werror
 
@@ -19,9 +19,7 @@ TARGET_LFLAGS = -nostartfiles -nostdlib
 
 TARGET_OBJECTS = \
        dllmain.o \
-       connect.o \
-       execpgm.o \
-       compses.o
+       query.o
        
 DEP_OBJECTS = $(TARGET_OBJECTS)
 
diff --git a/reactos/lib/smdll/query.c b/reactos/lib/smdll/query.c
new file mode 100644 (file)
index 0000000..0e8fe38
--- /dev/null
@@ -0,0 +1,39 @@
+/* $Id: compses.c 13731 2005-02-23 23:37:06Z ea $\r
+ *\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS system libraries\r
+ * FILE:            lib/smdll/query.c\r
+ * PURPOSE:         Call SM API SM_API_QUERY (not in NT)\r
+ */\r
+#define NTOS_MODE_USER\r
+#include <ntos.h>\r
+#include <sm/api.h>\r
+#include <sm/helper.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/**********************************************************************\r
+ * NAME                                                        EXPORTED\r
+ *     SmQuery/4\r
+ *\r
+ * DESCRIPTION\r
+ *\r
+ * ARGUMENTS\r
+ *\r
+ * RETURN VALUE\r
+ */\r
+NTSTATUS STDCALL\r
+SmQuery (IN      HANDLE                SmApiPort,\r
+        IN      SM_INFORMATION_CLASS  SmInformationClass,\r
+        IN OUT  PVOID                 Data,\r
+        IN OUT  PULONG                DataLength)\r
+{\r
+       /* TODO */\r
+       if(NULL != DataLength)\r
+       {\r
+               *DataLength = 0;\r
+       }\r
+       return STATUS_SUCCESS;  \r
+}\r
+/* EOF */\r
index 0c2e91e..8be3c1f 100644 (file)
@@ -3,3 +3,4 @@ EXPORTS
 SmCompleteSession@12
 SmConnectApiPort@16
 SmExecuteProgram@8
+SmQuery@16
index 4441cec..4344f47 100644 (file)
@@ -2,10 +2,9 @@
        <importlibrary definition="smdll.def" />\r
        <include base="smdll">.</include>\r
        <define name="_DISABLE_TIDENTS" />\r
+       <library>smlib</library>\r
        <library>ntdll</library>\r
        <file>dllmain.c</file>\r
-       <file>connect.c</file>\r
-       <file>execpgm.c</file>\r
-       <file>compses.c</file>\r
+       <file>query.c</file>\r
        <file>smdll.rc</file>\r
 </module>\r
similarity index 88%
rename from reactos/lib/smdll/compses.c
rename to reactos/lib/smlib/compses.c
index eaaccbc..f4b4316 100644 (file)
@@ -1,64 +1,64 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/smlib/compses.c
- * PURPOSE:         Call SM API SM_API_COMPLETE_SESSION
- */
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <sm/api.h>
-#include <sm/helper.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/**********************************************************************
- * NAME                                                        EXPORTED
- *     SmCompleteSession/3
- *
- * DESCRIPTION
- *     This function is called by an environment subsystem server to
- *     tell the SM it finished initialization phase and is ready to
- *     manage processes it registered for (SmConnectApiPort).
- *
- * ARGUMENTS
- *     hSmApiPort: port handle returned by SmConnectApiPort;
- *     hSbApiPort: call back API port of the subsystem (handle);
- *     hApiPort  : API port of the subsystem (handle).
- *
- * RETURN VALUE
- *     Success status as handed by the SM reply; otherwise a failure
- *     status code.
- */
-NTSTATUS STDCALL
-SmCompleteSession (IN HANDLE hSmApiPort,
-                  IN HANDLE hSbApiPort,
-                  IN HANDLE hApiPort)
-{
-  NTSTATUS         Status;
-  SM_PORT_MESSAGE  SmReqMsg;
-    
-  DPRINT("SMDLL: %s called\n", __FUNCTION__);
-
-  /* Marshal Ses in the LPC message */
-  SmReqMsg.CompSes.hApiPort   = hApiPort;
-  SmReqMsg.CompSes.hSbApiPort = hSbApiPort;
-
-  /* SM API to invoke */
-  SmReqMsg.ApiIndex = SM_API_COMPLETE_SESSION;
-
-  /* Port message */
-  SmReqMsg.Header.MessageType = LPC_NEW_MESSAGE;
-  SmReqMsg.Header.DataSize    = SM_PORT_DATA_SIZE(SmReqMsg.CompSes);
-  SmReqMsg.Header.MessageSize = SM_PORT_MESSAGE_SIZE;
-  Status = NtRequestWaitReplyPort (hSmApiPort, (PLPC_MESSAGE) & SmReqMsg, (PLPC_MESSAGE) & SmReqMsg);
-  if (NT_SUCCESS(Status))
-  {
-    return SmReqMsg.Status;
-  }
-  DPRINT("SMDLL: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);
-  return Status;
-}
-
-/* EOF */
+/* $Id: compses.c 13731 2005-02-23 23:37:06Z ea $\r
+ *\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS system libraries\r
+ * FILE:            lib/smlib/compses.c\r
+ * PURPOSE:         Call SM API SM_API_COMPLETE_SESSION\r
+ */\r
+#define NTOS_MODE_USER\r
+#include <ntos.h>\r
+#include <sm/api.h>\r
+#include <sm/helper.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/**********************************************************************\r
+ * NAME                                                        EXPORTED\r
+ *     SmCompleteSession/3\r
+ *\r
+ * DESCRIPTION\r
+ *     This function is called by an environment subsystem server to\r
+ *     tell the SM it finished initialization phase and is ready to\r
+ *     manage processes it registered for (SmConnectApiPort).\r
+ *\r
+ * ARGUMENTS\r
+ *     hSmApiPort: port handle returned by SmConnectApiPort;\r
+ *     hSbApiPort: call back API port of the subsystem (handle);\r
+ *     hApiPort  : API port of the subsystem (handle).\r
+ *\r
+ * RETURN VALUE\r
+ *     Success status as handed by the SM reply; otherwise a failure\r
+ *     status code.\r
+ */\r
+NTSTATUS STDCALL\r
+SmCompleteSession (IN HANDLE hSmApiPort,\r
+                  IN HANDLE hSbApiPort,\r
+                  IN HANDLE hApiPort)\r
+{\r
+  NTSTATUS         Status;\r
+  SM_PORT_MESSAGE  SmReqMsg;\r
+    \r
+  DPRINT("SMLIB: %s called\n", __FUNCTION__);\r
+\r
+  /* Marshal Ses in the LPC message */\r
+  SmReqMsg.CompSes.hApiPort   = hApiPort;\r
+  SmReqMsg.CompSes.hSbApiPort = hSbApiPort;\r
+\r
+  /* SM API to invoke */\r
+  SmReqMsg.ApiIndex = SM_API_COMPLETE_SESSION;\r
+\r
+  /* Port message */\r
+  SmReqMsg.Header.MessageType = LPC_NEW_MESSAGE;\r
+  SmReqMsg.Header.DataSize    = SM_PORT_DATA_SIZE(SmReqMsg.CompSes);\r
+  SmReqMsg.Header.MessageSize = SM_PORT_MESSAGE_SIZE;\r
+  Status = NtRequestWaitReplyPort (hSmApiPort, (PLPC_MESSAGE) & SmReqMsg, (PLPC_MESSAGE) & SmReqMsg);\r
+  if (NT_SUCCESS(Status))\r
+  {\r
+    return SmReqMsg.Status;\r
+  }\r
+  DPRINT("SMLIB: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+  return Status;\r
+}\r
+\r
+/* EOF */\r
similarity index 81%
rename from reactos/lib/smdll/connect.c
rename to reactos/lib/smlib/connect.c
index 17ba96c..ce6f135 100644 (file)
@@ -1,95 +1,98 @@
-/* $Id$
- *
- * COPYRIGHT:  See COPYING in the top level directory
- * PROJECT:    ReactOS system libraries
- * FILE:       reactos/lib/smdll/connect.c
- * PURPOSE:    Connect to the API LPC port exposed by the SM
- */
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <sm/api.h>
-#include <sm/helper.h>
-#include <pe.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/**********************************************************************
- * NAME                                                        EXPORTED
- *     SmConnectApiPort/4
- *
- * DESCRIPTION
- *     Connect to SM API port and register a session "begin" port (Sb)
- *     or to issue API requests to SmApiPort.
- *
- * ARGUMENTS
- *     pSbApiPortName: name of the Sb port the calling subsystem
- *             server already created in the system name space;
- *     hSbApiPort: LPC port handle (checked, but not used);
- *     dwSubsystem: a valid IMAGE_SUBSYSTEM_xxx value;
- *     phSmApiPort: a pointer to a HANDLE, which will be
- *             filled with a valid client-side LPC comm port.
- *     
- * RETURN VALUE
- *     If all three optional values are omitted, an LPC status.
- *     STATUS_INVALID_PARAMETER_MIX if PortName is defined and
- *     both hSbApiPort and dwSubsystem are 0.
- */
-NTSTATUS STDCALL
-SmConnectApiPort (IN      PUNICODE_STRING  pSbApiPortName  OPTIONAL,
-                 IN      HANDLE           hSbApiPort      OPTIONAL,
-                 IN      DWORD            dwSubsystem     OPTIONAL,
-                 IN OUT  PHANDLE          phSmApiPort)
-{
-  UNICODE_STRING              SmApiPortName;
-  SECURITY_QUALITY_OF_SERVICE SecurityQos;
-  NTSTATUS                    Status = STATUS_SUCCESS;
-  SM_CONNECT_DATA             ConnectData = {0,{0}};
-  ULONG                       ConnectDataLength = 0;
-
-  DPRINT("SMDLL: %s called\n", __FUNCTION__);
-
-  if (pSbApiPortName->Length > (sizeof pSbApiPortName->Buffer[0] * SM_SB_NAME_MAX_LENGTH))
-  {
-         return STATUS_INVALID_PARAMETER_1;
-  }
-  if (pSbApiPortName)
-  {
-    if (NULL == hSbApiPort || IMAGE_SUBSYSTEM_UNKNOWN == dwSubsystem)
-    {
-      return STATUS_INVALID_PARAMETER_MIX;
-    }
-    RtlZeroMemory (& ConnectData, sizeof ConnectData);
-    ConnectData.Subsystem = dwSubsystem;
-    RtlCopyMemory (& ConnectData.SbName,
-                  pSbApiPortName->Buffer,
-                  pSbApiPortName->Length);
-  }
-  ConnectDataLength = sizeof ConnectData;
-
-  SecurityQos.Length              = sizeof (SecurityQos);
-  SecurityQos.ImpersonationLevel  = SecurityIdentification;
-  SecurityQos.ContextTrackingMode = TRUE;
-  SecurityQos.EffectiveOnly       = TRUE;
-
-  RtlInitUnicodeString (& SmApiPortName, SM_API_PORT_NAME);
-
-  Status = NtConnectPort (
-             phSmApiPort,
-             & SmApiPortName,
-             & SecurityQos,
-             NULL,
-             NULL,
-             NULL,
-             & ConnectData,
-             & ConnectDataLength
-             );
-  if (NT_SUCCESS(Status))
-  {
-    return STATUS_SUCCESS;
-  }
-  DPRINT("SMDLL: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);
-  return Status;
-}
-
-/* EOF */
+/* $Id: connect.c 14015 2005-03-13 17:00:19Z ea $\r
+ *\r
+ * COPYRIGHT:  See COPYING in the top level directory\r
+ * PROJECT:    ReactOS system libraries\r
+ * FILE:       reactos/lib/smlib/connect.c\r
+ * PURPOSE:    Connect to the API LPC port exposed by the SM\r
+ */\r
+#define NTOS_MODE_USER\r
+#include <ntos.h>\r
+#include <sm/api.h>\r
+#include <sm/helper.h>\r
+#include <pe.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/**********************************************************************\r
+ * NAME                                                        EXPORTED\r
+ *     SmConnectApiPort/4\r
+ *\r
+ * DESCRIPTION\r
+ *     Connect to SM API port and register a session "begin" port (Sb)\r
+ *     or to issue API requests to SmApiPort.\r
+ *\r
+ * ARGUMENTS\r
+ *     pSbApiPortName: name of the Sb port the calling subsystem\r
+ *             server already created in the system name space;\r
+ *     hSbApiPort: LPC port handle (checked, but not used);\r
+ *     dwSubsystem: a valid IMAGE_SUBSYSTEM_xxx value;\r
+ *     phSmApiPort: a pointer to a HANDLE, which will be\r
+ *             filled with a valid client-side LPC comm port.\r
+ *     \r
+ * RETURN VALUE\r
+ *     If all three optional values are omitted, an LPC status.\r
+ *     STATUS_INVALID_PARAMETER_MIX if PortName is defined and\r
+ *     both hSbApiPort and dwSubsystem are 0.\r
+ */\r
+NTSTATUS STDCALL\r
+SmConnectApiPort (IN      PUNICODE_STRING  pSbApiPortName  OPTIONAL,\r
+                 IN      HANDLE           hSbApiPort      OPTIONAL,\r
+                 IN      DWORD            dwSubsystem     OPTIONAL,\r
+                 IN OUT  PHANDLE          phSmApiPort)\r
+{\r
+  UNICODE_STRING              SmApiPortName;\r
+  SECURITY_QUALITY_OF_SERVICE SecurityQos;\r
+  NTSTATUS                    Status = STATUS_SUCCESS;\r
+  SM_CONNECT_DATA             ConnectData = {0,{0}};\r
+  ULONG                       ConnectDataLength = 0;\r
+\r
+  DPRINT("SMLIB: %s called\n", __FUNCTION__);\r
+\r
+  if (pSbApiPortName)\r
+  {\r
+    if (pSbApiPortName->Length > (sizeof pSbApiPortName->Buffer[0] * SM_SB_NAME_MAX_LENGTH))\r
+    {\r
+         return STATUS_INVALID_PARAMETER_1;\r
+    }\r
+    if (NULL == hSbApiPort || IMAGE_SUBSYSTEM_UNKNOWN == dwSubsystem)\r
+    {\r
+      return STATUS_INVALID_PARAMETER_MIX;\r
+    }\r
+    RtlZeroMemory (& ConnectData, sizeof ConnectData);\r
+    ConnectData.Subsystem = dwSubsystem;\r
+    if (pSbApiPortName->Length > 0)\r
+    {\r
+      RtlCopyMemory (& ConnectData.SbName,\r
+                    pSbApiPortName->Buffer,\r
+                    pSbApiPortName->Length);\r
+    }\r
+  }\r
+  ConnectDataLength = sizeof ConnectData;\r
+\r
+  SecurityQos.Length              = sizeof (SecurityQos);\r
+  SecurityQos.ImpersonationLevel  = SecurityIdentification;\r
+  SecurityQos.ContextTrackingMode = TRUE;\r
+  SecurityQos.EffectiveOnly       = TRUE;\r
+\r
+  RtlInitUnicodeString (& SmApiPortName, SM_API_PORT_NAME);\r
+\r
+  Status = NtConnectPort (\r
+             phSmApiPort,\r
+             & SmApiPortName,\r
+             & SecurityQos,\r
+             NULL,\r
+             NULL,\r
+             NULL,\r
+             & ConnectData,\r
+             & ConnectDataLength\r
+             );\r
+  if (NT_SUCCESS(Status))\r
+  {\r
+    return STATUS_SUCCESS;\r
+  }\r
+  DPRINT("SMLIB: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+  return Status;\r
+}\r
+\r
+/* EOF */\r
similarity index 87%
rename from reactos/lib/smdll/execpgm.c
rename to reactos/lib/smlib/execpgm.c
index 4770968..75b7aaf 100644 (file)
@@ -1,76 +1,76 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/smdll/execpgm.c
- * PURPOSE:         Call SM API SM_API_EXECPGM
- */
-#define NTOS_MODE_USER
-#include <ntos.h>
-#include <sm/api.h>
-#include <sm/helper.h>
-#include <string.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/**********************************************************************
- * NAME                                                        EXPORTED
- *     SmExecuteProgram/2
- *
- * DESCRIPTION
- *     This function is used to make the SM start an environment
- *     subsystem server process.
- *
- * ARGUMENTS
- *     hSmApiPort: port handle returned by SmConnectApiPort;
- *     Pgm       : name of the subsystem (to be used by the SM to
- *                 lookup the image name from the registry).
- *                 Valid names are: DEBUG, WINDOWS, POSIX, OS2,
- *                 and VMS.
- *     
- * RETURN VALUE
- *     Success status as handed by the SM reply; otherwise a failure
- *     status code.
- */
-NTSTATUS STDCALL
-SmExecuteProgram (IN HANDLE          hSmApiPort,
-                 IN PUNICODE_STRING Pgm)
-{
-  NTSTATUS         Status;
-  SM_PORT_MESSAGE  SmReqMsg;
-
-
-  DPRINT("SMDLL: %s called\n", __FUNCTION__);
-
-  /* Check Pgm's length */
-  if (Pgm->Length > (sizeof (Pgm->Buffer[0]) * SM_EXEXPGM_MAX_LENGTH))
-  {
-    return STATUS_INVALID_PARAMETER;
-  }
-  /* Marshal Pgm in the LPC message */
-  RtlZeroMemory (& SmReqMsg, sizeof SmReqMsg);
-  SmReqMsg.ExecPgm.NameLength = Pgm->Length;
-  RtlCopyMemory (SmReqMsg.ExecPgm.Name,
-                Pgm->Buffer,
-                Pgm->Length);
-               
-  /* SM API to invoke */
-  SmReqMsg.ApiIndex = SM_API_EXECUTE_PROGRAMME;
-
-  /* LPC message */
-  SmReqMsg.Header.MessageType = LPC_NEW_MESSAGE;
-  SmReqMsg.Header.DataSize    = SM_PORT_DATA_SIZE(SmReqMsg.ExecPgm);
-  SmReqMsg.Header.MessageSize = SM_PORT_MESSAGE_SIZE;
-
-  /* Call SM and wait for a reply */
-  Status = NtRequestWaitReplyPort (hSmApiPort, (PLPC_MESSAGE) & SmReqMsg, (PLPC_MESSAGE) & SmReqMsg);
-  if (NT_SUCCESS(Status))
-  {
-    return SmReqMsg.Status;
-  }
-  DPRINT("SMDLL: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);
-  return Status;
-}
-
-/* EOF */
+/* $Id: execpgm.c 13731 2005-02-23 23:37:06Z ea $\r
+ *\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS system libraries\r
+ * FILE:            lib/smlib/execpgm.c\r
+ * PURPOSE:         Call SM API SM_API_EXECPGM\r
+ */\r
+#define NTOS_MODE_USER\r
+#include <ntos.h>\r
+#include <sm/api.h>\r
+#include <sm/helper.h>\r
+#include <string.h>\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+/**********************************************************************\r
+ * NAME                                                        EXPORTED\r
+ *     SmExecuteProgram/2\r
+ *\r
+ * DESCRIPTION\r
+ *     This function is used to make the SM start an environment\r
+ *     subsystem server process.\r
+ *\r
+ * ARGUMENTS\r
+ *     hSmApiPort: port handle returned by SmConnectApiPort;\r
+ *     Pgm       : name of the subsystem (to be used by the SM to\r
+ *                 lookup the image name from the registry).\r
+ *                 Valid names are: DEBUG, WINDOWS, POSIX, OS2,\r
+ *                 and VMS.\r
+ *     \r
+ * RETURN VALUE\r
+ *     Success status as handed by the SM reply; otherwise a failure\r
+ *     status code.\r
+ */\r
+NTSTATUS STDCALL\r
+SmExecuteProgram (IN HANDLE          hSmApiPort,\r
+                 IN PUNICODE_STRING Pgm)\r
+{\r
+  NTSTATUS         Status;\r
+  SM_PORT_MESSAGE  SmReqMsg;\r
+\r
+\r
+  DPRINT("SMLIB: %s called\n", __FUNCTION__);\r
+\r
+  /* Check Pgm's length */\r
+  if (Pgm->Length > (sizeof (Pgm->Buffer[0]) * SM_EXEXPGM_MAX_LENGTH))\r
+  {\r
+    return STATUS_INVALID_PARAMETER;\r
+  }\r
+  /* Marshal Pgm in the LPC message */\r
+  RtlZeroMemory (& SmReqMsg, sizeof SmReqMsg);\r
+  SmReqMsg.ExecPgm.NameLength = Pgm->Length;\r
+  RtlCopyMemory (SmReqMsg.ExecPgm.Name,\r
+                Pgm->Buffer,\r
+                Pgm->Length);\r
+               \r
+  /* SM API to invoke */\r
+  SmReqMsg.ApiIndex = SM_API_EXECUTE_PROGRAMME;\r
+\r
+  /* LPC message */\r
+  SmReqMsg.Header.MessageType = LPC_NEW_MESSAGE;\r
+  SmReqMsg.Header.DataSize    = SM_PORT_DATA_SIZE(SmReqMsg.ExecPgm);\r
+  SmReqMsg.Header.MessageSize = SM_PORT_MESSAGE_SIZE;\r
+\r
+  /* Call SM and wait for a reply */\r
+  Status = NtRequestWaitReplyPort (hSmApiPort, (PLPC_MESSAGE) & SmReqMsg, (PLPC_MESSAGE) & SmReqMsg);\r
+  if (NT_SUCCESS(Status))\r
+  {\r
+    return SmReqMsg.Status;\r
+  }\r
+  DPRINT("SMLIB: %s failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+  return Status;\r
+}\r
+\r
+/* EOF */\r
diff --git a/reactos/lib/smlib/makefile b/reactos/lib/smlib/makefile
new file mode 100644 (file)
index 0000000..9ec7cc1
--- /dev/null
@@ -0,0 +1,35 @@
+\r
+PATH_TO_TOP = ../..\r
+\r
+TARGET_TYPE = library\r
+\r
+TARGET_NAME = smlib\r
+\r
+include $(PATH_TO_TOP)/config\r
+\r
+TARGET_CFLAGS = -Wall -Werror -ffreestanding\r
+\r
+# require os code to explicitly request A/W version of structs/functions\r
+TARGET_CFLAGS += -D_DISABLE_TIDENTS\r
+\r
+ifneq ($(DBG), 0)\r
+TARGET_CFLAGS += -DDBG\r
+endif\r
+\r
+TARGET_OBJECTS = \\r
+       connect.o \\r
+       execpgm.o \\r
+       compses.o\r
+\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+DEP_OBJECTS := $(TARGET_OBJECTS)\r
+\r
+TARGET_CLEAN = $(DEP_FILES)\r
+\r
+include $(PATH_TO_TOP)/tools/depend.mk\r
+\r
+# EOF\r
diff --git a/reactos/lib/smlib/smlib.xml b/reactos/lib/smlib/smlib.xml
new file mode 100644 (file)
index 0000000..6b06eb1
--- /dev/null
@@ -0,0 +1,7 @@
+<module name="smlib" type="staticlibrary">
+       <include base="smlib">.</include>
+       <define name="_DISABLE_TIDENTS" />
+       <file>connect.c</file>
+       <file>execpgm.c</file>
+       <file>compses.c</file>
+</module>
index 8694d1c..d3a2904 100644 (file)
@@ -13,7 +13,7 @@ include Makefile.$(ARCH)
 TARGET_CFLAGS = -Wall -Werror
 
 # require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API
 
 ifeq ($(DBG), 1)
   TARGET_CFLAGS += -g
index 4ddca56..db615e3 100644 (file)
@@ -1125,6 +1125,7 @@ static BOOL
 SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
 {
   HANDLE hToken;
+  DWORD PrevSize;
   TOKEN_PRIVILEGES priv, previouspriv;
   BOOL Ret = FALSE;
   
@@ -1133,7 +1134,7 @@ SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
    */
   
   if(OpenProcessToken(GetCurrentProcess(),
-                      TOKEN_ADJUST_PRIVILEGES,
+                      TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                       &hToken))
   {
     priv.PrivilegeCount = 1;
@@ -1148,7 +1149,7 @@ SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
                                &priv,
                                sizeof(previouspriv),
                                &previouspriv,
-                               0) &&
+                               &PrevSize) &&
          GetLastError() == ERROR_SUCCESS)
       {
         /*
index e9b37fb..2b54813 100644 (file)
@@ -7,7 +7,7 @@ TARGET_TYPE = library
 TARGET_NAME = tgetopt
 
 # require os code to explicitly request A/W version of structs/functions
-TARGET_CFLAGS += -D_DISABLE_TIDENTS
+TARGET_CFLAGS += -D__USE_W32API -D_DISABLE_TIDENTS
 
 TARGET_OBJECTS = getopt.o _wgetopt.o
  
index 056a2e4..f6ca435 100644 (file)
@@ -1,5 +1,10 @@
+# Up until Windows 2000 these APIs have hardcoded ordinals.\r
+# Keep it that way for compatibility.\r
 1 stub CDLGetLongPathNameA\r
 2 stub CDLGetLongPathNameW\r
+# IsJITInProgress has a hardcoded ordinal on WinME and Windows 2000\r
+#3 stub IsJITInProgress\r
+\r
 @ stub AsyncGetClassBits\r
 @ stub AsyncInstallDistributionUnit\r
 @ stub BindAsyncMoniker\r
diff --git a/reactos/lib/user32/Da.rc b/reactos/lib/user32/Da.rc
new file mode 100644 (file)
index 0000000..e31b210
--- /dev/null
@@ -0,0 +1,74 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialogs
+//
+
+SELWINDOW DIALOG DISCARDABLE 20, 20, 220, 140
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+    WS_SYSMENU
+FONT 8, "Bitstream Vera Sans"
+CAPTION "Vælg Vindue"
+BEGIN
+  LISTBOX 100, 5, 5, 210, 110, LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL
+  PUSHBUTTON "&OK", 1, 60, 120, 40, 15, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP
+  PUSHBUTTON "&Fortryd", 2, 120, 120, 40, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menus
+//
+
+EDITMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+  POPUP "DUMMY"
+  BEGIN
+    MENUITEM "&Fortryd", EM_UNDO
+    MENUITEM SEPARATOR
+    MENUITEM "Kl&ip", WM_CUT
+    MENUITEM "&Kopier", WM_COPY
+    MENUITEM "&Indsæt", WM_PASTE
+    MENUITEM "&Slet", WM_CLEAR
+    MENUITEM SEPARATOR
+    MENUITEM "Vælg &Alle", EM_SETSEL
+  END
+}
+
+SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+  MENUITEM "&Gendan", 61728
+  MENUITEM "&Flyt", 61456
+  MENUITEM "&Størrelse", 61440
+  MENUITEM "M&inimere", 61472
+  MENUITEM "Ma&ksimere", 61488
+  MENUITEM SEPARATOR
+  MENUITEM "&Luk\tAlt-F4", 61536
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Strings
+//
+
+STRINGTABLE
+{
+  IDS_ERROR,    "Fejl"
+  IDS_OK,       "OK"
+  IDS_CANCEL,   "Fortryd"
+  IDS_ABORT,    "&Afbryd"
+  IDS_RETRY,    "&Forsøg Igen"
+  IDS_IGNORE,   "&Ignorer"
+  IDS_YES,      "&Ja"
+  IDS_NO,       "&Nej"
+  IDS_HELP,     "Hjælp"
+  IDS_TRYAGAIN, "&Forsøg Igen"
+  IDS_CONTINUE, "&Forsæt"
+}
+
+STRINGTABLE
+{
+  IDS_MDI_MOREWINDOWS, "&More Windows..."
+}
+
diff --git a/reactos/lib/user32/Sv.rc b/reactos/lib/user32/Sv.rc
new file mode 100644 (file)
index 0000000..4ac5fc8
--- /dev/null
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Swedish (SE) resources\r
+/*\r
+ * Copyright 2005 David Nordenberg\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialogs\r
+//\r
+\r
+SELWINDOW DIALOG DISCARDABLE 20, 20, 220, 140\r
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION |\r
+    WS_SYSMENU\r
+FONT 8, "Bitstream Vera Sans"\r
+CAPTION "Välj fönster"\r
+BEGIN\r
+  LISTBOX 100, 5, 5, 210, 110, LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL\r
+  PUSHBUTTON "&OK", 1, 60, 120, 40, 15, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+  PUSHBUTTON "&Avbryt", 2, 120, 120, 40, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menus\r
+//\r
+\r
+EDITMENU MENU LOADONCALL MOVEABLE DISCARDABLE\r
+{\r
+  POPUP "DUMMY"\r
+  BEGIN\r
+    MENUITEM "&Ångra", EM_UNDO\r
+    MENUITEM SEPARATOR\r
+    MENUITEM "&Klipp ut", WM_CUT\r
+    MENUITEM "K&opiera", WM_COPY\r
+    MENUITEM "K&listra in", WM_PASTE\r
+    MENUITEM "&Ta bort", WM_CLEAR\r
+    MENUITEM SEPARATOR\r
+    MENUITEM "&Markera allt", EM_SETSEL\r
+  END\r
+}\r
+\r
+\r
+SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE\r
+{\r
+  MENUITEM "&Återställ", 61728\r
+  MENUITEM "&Flytta", 61456\r
+  MENUITEM "S&torlek", 61440\r
+  MENUITEM "&Minimera", 61472\r
+  MENUITEM "Ma&ximera", 61488\r
+  MENUITEM SEPARATOR\r
+  MENUITEM "&Stäng\tAlt-F4", 61536\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Strings\r
+//\r
+\r
+STRINGTABLE\r
+{\r
+  IDS_ERROR,    "Fel"\r
+  IDS_OK,       "OK"\r
+  IDS_CANCEL,   "Avbryt"\r
+  IDS_ABORT,    "&Avbryt"\r
+  IDS_RETRY,    "&Försök igen"\r
+  IDS_IGNORE,   "&Ignorera"\r
+  IDS_YES,      "&Ja"\r
+  IDS_NO,       "&Nej"\r
+  IDS_HELP,     "Hjälp"\r
+  IDS_TRYAGAIN, "&Försök igen"\r
+  IDS_CONTINUE, "F&ortsätt"\r
+}\r
+\r
+STRINGTABLE\r
+{\r
+  IDS_MDI_MOREWINDOWS, "&Fler fönster..."\r
+}\r
+\r
index 3505f6e..699765a 100644 (file)
@@ -1,7 +1,8 @@
 /* $Id$ */
 
 #include <defines.h>
-#include <messages.h>
+#include <winuser.h>
+
 #include <resource.h>
 
 #define REACTOS_VERSION_DLL
@@ -59,4 +60,6 @@ OBM_COMBO BITMAP "resources/obm_combo.bmp"
 OBM_MNARROW BITMAP "resources/obm_mnarrow.bmp"
 
 #include "En.rc"
+#include "Da.rc"
 #include "De.rc"
+#include "Sv.rc"
index 5840e2a..f560695 100644 (file)
@@ -291,32 +291,31 @@ HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccl, int cEntries)
 int WINAPI CopyAcceleratorTableA
 (
  HACCEL hAccelSrc,
- LPACCEL lpAccelDst,
+ LPACCEL lpAccelDst, /* can be NULL */
  int cAccelEntries
 )
 {
- int i;
-
- cAccelEntries = CopyAcceleratorTableW(hAccelSrc, lpAccelDst, cAccelEntries);
+   int i;
  
- if(cAccelEntries == 0) return 0;
-
- for(i = 0; i < cAccelEntries; ++ i)
-  if(!(lpAccelDst[i].fVirt & FVIRTKEY))
-  {
-   NTSTATUS nErrCode = RtlUnicodeToMultiByteN
-   (
-    (PCHAR)&lpAccelDst[i].key,
-    sizeof(lpAccelDst[i].key),
-    NULL,
-    (PWCHAR)&lpAccelDst[i].key,
-    sizeof(lpAccelDst[i].key)
-   );
-
-   if(!NT_SUCCESS(nErrCode)) lpAccelDst[i].key = 0;
-  }
-
- return cAccelEntries;
+   cAccelEntries = CopyAcceleratorTableW(hAccelSrc, lpAccelDst, cAccelEntries);
+   if (lpAccelDst == NULL) return cAccelEntries;
+
+   for(i = 0; i < cAccelEntries; ++ i)
+   if(!(lpAccelDst[i].fVirt & FVIRTKEY))
+   {
+      NTSTATUS nErrCode = RtlUnicodeToMultiByteN(
+         (PCHAR)&lpAccelDst[i].key,
+         sizeof(lpAccelDst[i].key),
+         NULL,
+         (PWCHAR)&lpAccelDst[i].key,
+         sizeof(lpAccelDst[i].key)
+         ); 
+      if(!NT_SUCCESS(nErrCode)) lpAccelDst[i].key = 0;
+   }
+   return cAccelEntries;
 }
 
 
index 26fae34..b7cff98 100644 (file)
@@ -552,7 +552,7 @@ LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
 
   /* FIXME: Handle color conversion and transparency. */
 
-  hScreenDc = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+  hScreenDc = CreateCompatibleDC(NULL);
   if (hScreenDc == NULL)
     {
       RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
index 6d7ed4b..e0f9d0d 100644 (file)
@@ -31,7 +31,7 @@
 #define WM_QUERYDROPOBJECT  0x022B
 #endif
 
-LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn);
+LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
 LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
 LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
 LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
@@ -317,7 +317,8 @@ DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
     {
       while(!hittest)
        {
-         GetMessageW(&msg, NULL, 0, 0);
+         if (GetMessageW(&msg, NULL, 0, 0) <= 0)
+           break;
          switch(msg.message)
            {
            case WM_MOUSEMOVE:
@@ -572,7 +573,8 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
     {
       int dx = 0, dy = 0;
 
-      GetMessageW(&msg, 0, 0, 0);
+      if (GetMessageW(&msg, 0, 0, 0) <= 0)
+        break;
       
       /* Exit on button-up, Return, or Esc */
       if ((msg.message == WM_LBUTTONUP) ||
@@ -947,7 +949,7 @@ User32DefWindowProc(HWND hWnd,
     {
        case WM_NCPAINT:
        {
-            return DefWndNCPaint(hWnd, (HRGN)wParam);
+            return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
         }
 
         case WM_NCCALCSIZE:
@@ -1470,7 +1472,7 @@ DefWindowProcA(HWND hWnd,
             
             if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
             {
-                DefWndNCPaint(hWnd, (HRGN)1);
+                DefWndNCPaint(hWnd, (HRGN)1, -1);
             }
             return TRUE;
         }
@@ -1530,7 +1532,7 @@ DefWindowProcW(HWND hWnd,
             
             if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
             {
-                DefWndNCPaint(hWnd, (HRGN)1);
+                DefWndNCPaint(hWnd, (HRGN)1, -1);
             }
             return (1);
         }
index 7417386..53775c1 100644 (file)
@@ -708,8 +708,12 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
     rect.left = rect.top = 0;
     rect.right = MulDiv(template.cx, dlgInfo->xBaseUnit, 4);
     rect.bottom =  MulDiv(template.cy, dlgInfo->yBaseUnit, 8);
+    if (template.style & WS_CHILD)
+        template.style &= ~(WS_CAPTION|WS_SYSMENU);
     if (template.style & DS_MODALFRAME)
         template.exStyle |= WS_EX_DLGMODALFRAME;
+    if (template.style & DS_CONTROL)
+        template.exStyle |= WS_EX_CONTROLPARENT;
     AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), template.exStyle );
     rect.right -= rect.left;
     rect.bottom -= rect.top;
index b49ef2b..7e26167 100644 (file)
@@ -156,8 +156,7 @@ BOOL
 STDCALL
 DeregisterShellHookWindow(HWND hWnd)
 {
-  UNIMPLEMENTED;
-  return FALSE;
+  return NtUserCallHwnd(HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW, (DWORD)hWnd);
 }
 
 /*
@@ -167,8 +166,7 @@ BOOL
 STDCALL
 RegisterShellHookWindow(HWND hWnd)
 {
-  UNIMPLEMENTED;
-  return FALSE;
+  return NtUserCallHwnd(HWND_ROUTINE_REGISTERSHELLHOOKWINDOW, (DWORD)hWnd);
 }
 
 /*
index e9c2811..a6019e9 100644 (file)
@@ -566,7 +566,7 @@ LookupIconIdFromDirectoryEx(
       HDC hdc;
       int ColorBits;
 
-      hdc = GetDC(0);
+      hdc = CreateICW(NULL, NULL, NULL, NULL);
       if (Flags & LR_MONOCHROME)
       {
          ColorBits = 1;
@@ -577,7 +577,7 @@ LookupIconIdFromDirectoryEx(
          if (ColorBits > 8)
             ColorBits = 8;
       }
-      ReleaseDC(0, hdc);
+      DeleteDC(hdc);
 
       entry = CURSORICON_FindBestIcon( dir, cxDesired, cyDesired, ColorBits );
 
index b0c4673..c7ce634 100644 (file)
@@ -32,7 +32,6 @@
 /* INCLUDES ******************************************************************/
 
 #include "user32.h"
-#include <messages.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
index 50e50f5..444d84b 100644 (file)
@@ -288,10 +288,9 @@ UserDrawCaptionButtonWnd(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type)
  * - Correct drawing of size-box
  */
 LRESULT
-DefWndNCPaint(HWND hWnd, HRGN hRgn)
+DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active)
 {
    HDC hDC;
-   BOOL Active;
    DWORD Style, ExStyle;
    HWND Parent;
    RECT ClientRect, WindowRect, CurrentRect, TempRect;
@@ -309,15 +308,18 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn)
    
    Parent = GetParent(hWnd);
    ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
-   if (ExStyle & WS_EX_MDICHILD)
+   if (Active == -1)
    {
-      Active = IsChild(GetForegroundWindow(), hWnd);
-      if (Active)
-         Active = (hWnd == (HWND)SendMessageW(Parent, WM_MDIGETACTIVE, 0, 0));
-   }
-   else
-   {
-      Active = (GetForegroundWindow() == hWnd);
+      if (ExStyle & WS_EX_MDICHILD)
+      {
+         Active = IsChild(GetForegroundWindow(), hWnd);
+         if (Active)
+            Active = (hWnd == (HWND)SendMessageW(Parent, WM_MDIGETACTIVE, 0, 0));
+      }
+      else
+      {
+         Active = (GetForegroundWindow() == hWnd);
+      }
    }
    GetWindowRect(hWnd, &WindowRect);
    GetClientRect(hWnd, &ClientRect);
@@ -376,7 +378,7 @@ DefWndNCPaint(HWND hWnd, HRGN hRgn)
    }
 
    /* Now the other bit of the frame */
-   if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME)
+   if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME)
    {
       DWORD Width = GetSystemMetrics(SM_CXBORDER);
       DWORD Height = GetSystemMetrics(SM_CYBORDER);
@@ -660,7 +662,7 @@ DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
 LRESULT
 DefWndNCActivate(HWND hWnd, WPARAM wParam)
 {
-   DefWndNCPaint(hWnd, (HRGN)1);
+   DefWndNCPaint(hWnd, (HRGN)1, wParam);
    return TRUE;
 }
 
@@ -882,79 +884,75 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
 VOID
 DefWndDoButton(HWND hWnd, WPARAM wParam)
 {
-  MSG Msg;
-  BOOL InBtn, HasBtn = FALSE;
-  ULONG Btn, Style;
-  WPARAM SCMsg, CurBtn = wParam, OrigBtn = wParam;
-  HDC WindowDC = NULL;
+   MSG Msg;
+   HDC WindowDC;
+   BOOL Pressed = TRUE, OldState;
+   WPARAM SCMsg;
+   ULONG ButtonType, Style;
   
-  Style = GetWindowLongW(hWnd, GWL_STYLE);
-  switch(wParam)
-  {
-    case HTCLOSE:
-      Btn = DFCS_CAPTIONCLOSE;
-      SCMsg = SC_CLOSE;
-      HasBtn = (Style & WS_SYSMENU);
-      break;
-    case HTMINBUTTON:
-      Btn = DFCS_CAPTIONMIN;
-      SCMsg = ((Style & WS_MINIMIZE) ? SC_RESTORE : SC_MINIMIZE);
-      HasBtn = (Style & WS_MINIMIZEBOX);
-      break;
-    case HTMAXBUTTON:
-      Btn = DFCS_CAPTIONMAX;
-      SCMsg = ((Style & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE);
-      HasBtn = (Style & WS_MAXIMIZEBOX);
-      break;
-    default:
-      return;
-  }
-  
-  InBtn = HasBtn;
-  
-  SetCapture(hWnd);
+   Style = GetWindowLongW(hWnd, GWL_STYLE);
+   switch (wParam)
+   {
+      case HTCLOSE:
+         if (!(Style & WS_SYSMENU))
+            return;
+         ButtonType = DFCS_CAPTIONCLOSE;
+         SCMsg = SC_CLOSE;
+         break;
+      case HTMINBUTTON:
+         if (!(Style & WS_MINIMIZEBOX))
+            return;
+         ButtonType = DFCS_CAPTIONMIN;
+         SCMsg = ((Style & WS_MINIMIZE) ? SC_RESTORE : SC_MINIMIZE);
+         break;
+      case HTMAXBUTTON:
+         if (!(Style & WS_MAXIMIZEBOX))
+            return;
+         ButtonType = DFCS_CAPTIONMAX;
+         SCMsg = ((Style & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE);
+         break;
+
+      default:
+         ASSERT(FALSE);
+         return;
+   }
   
-  if(HasBtn)
-  {
-    WindowDC = GetWindowDC(hWnd);
-    UserDrawCaptionButtonWnd(hWnd, WindowDC, HasBtn , Btn);
-  }
+   /*
+    * FIXME: Not sure where to do this, but we must flush the pending
+    * window updates when someone clicks on the close button and at
+    * the same time the window is overlapped with another one. This
+    * looks like a good place for now...
+    */
+   UpdateWindow(hWnd);
+
+   WindowDC = GetWindowDC(hWnd);
+   UserDrawCaptionButtonWnd(hWnd, WindowDC, TRUE, ButtonType);
+
+   SetCapture(hWnd);
   
- for(;;)
-  {
-    GetMessageW(&Msg, 0, 0, 0);
-    switch(Msg.message)
-    {
-      case WM_LBUTTONUP:
-        if(InBtn)
-          goto done;
-        else
-        {
-          ReleaseCapture();
-          if (HasBtn)
-            ReleaseDC(hWnd, WindowDC);
-          return;
-        }
-      case WM_MOUSEMOVE:
-        if(HasBtn)
-        {
-          CurBtn = DefWndNCHitTest(hWnd, Msg.pt);
-          if(InBtn != (CurBtn == OrigBtn))
-          {
-            UserDrawCaptionButtonWnd( hWnd, WindowDC, (CurBtn == OrigBtn) , Btn);
-          }
-          InBtn = CurBtn == OrigBtn;
-        }
-        break;
-    }
-  }
+   for (;;)
+   {
+      if (GetMessageW(&Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST) <= 0)
+         break;
+    
+      if (Msg.message == WM_LBUTTONUP)
+         break;
+
+      if (Msg.message != WM_MOUSEMOVE)
+         continue;
+
+      OldState = Pressed;
+      Pressed = (DefWndNCHitTest(hWnd, Msg.pt) == wParam);
+      if (Pressed != OldState)
+         UserDrawCaptionButtonWnd(hWnd, WindowDC, Pressed, ButtonType);
+   }
   
-done:
-  UserDrawCaptionButtonWnd( hWnd, WindowDC, FALSE , Btn);
-  ReleaseDC(hWnd, WindowDC);
-  ReleaseCapture();
-  SendMessageW(hWnd, WM_SYSCOMMAND, SCMsg, 0);
-  return;
+   if (Pressed)
+      UserDrawCaptionButtonWnd(hWnd, WindowDC, FALSE, ButtonType);
+   ReleaseCapture();
+   ReleaseDC(hWnd, WindowDC);
+   if (Pressed)
+      SendMessageW(hWnd, WM_SYSCOMMAND, SCMsg, 0);
 }
 
 
index 20efad6..bab497b 100644 (file)
@@ -22,7 +22,7 @@
 
 BOOL ControlsInitialized = FALSE;
 
-LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn);
+LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
 
 /* FUNCTIONS *****************************************************************/
 
@@ -1236,7 +1236,7 @@ SetWindowTextA(HWND hWnd,
     
     if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
     {
-      DefWndNCPaint(hWnd, (HRGN)1);
+      DefWndNCPaint(hWnd, (HRGN)1, -1);
     }
     return TRUE;
   }
@@ -1270,7 +1270,7 @@ SetWindowTextW(HWND hWnd,
     
     if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
     {
-      DefWndNCPaint(hWnd, (HRGN)1);
+      DefWndNCPaint(hWnd, (HRGN)1, -1);
     }
     return TRUE;
   }
index c6d12ff..218b055 100644 (file)
@@ -43,4 +43,5 @@ BEGIN
     IDS_CACHE          "Lokale Einstellungen\\Temporary Internet Files"
     IDS_HISTORY        "Lokale Einstellungen\\Verlauf"
     IDS_COOKIES        "Cookies"
+    IDS_PROGRAMFILES   "%SystemDrive%\\Programme"
 END
index 854e3ae..264094a 100644 (file)
@@ -81,6 +81,9 @@ DEFINE_GUID(FMTID_SummaryInformation,0xF29F85E0,0x4FF9,0x1068,0xAB,0x91,0x08,0x0
 DEFINE_GUID(FMTID_DocSummaryInformation,0xD5CDD502,0x2E9C,0x101B,0x93,0x97,0x08,0x00,0x2B,0x2C,0xF9,0xAE);
 DEFINE_GUID(FMTID_UserDefinedProperties,0xD5CDD505,0x2E9C,0x101B,0x93,0x97,0x08,0x00,0x2B,0x2C,0xF9,0xAE);
 
+DEFINE_GUID(IID_IRichEditOle,0x00020D00,0,0,0xC0,0,0,0,0,0,0,0x46);
+DEFINE_GUID(IID_IRichEditOleCallback,0x00020D03,0,0,0xC0,0,0,0,0,0,0,0x46);
+
 DEFINE_OLEGUID(IID_StdOle,0x00020430,0,0);
 
 DEFINE_GUID(CLSID_StdFont,0x0be35203,0x8f91,0x11ce,0x9d,0xe3,0x00,0xaa,0x00,0x4b,0xb8,0x51);
index 0348c5e..44516e8 100644 (file)
@@ -1,4 +1,5 @@
 #include <windows.h>
+#include <winerror.h>
 #include <wininet.h>
 
 #define NDEBUG
index f039027..9bda8da 100644 (file)
@@ -226,7 +226,7 @@ BOOL        DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz)
     if (lRet == ERROR_SUCCESS) return TRUE;\r
     /* default to system.ini if we can't find it in the registry,\r
      * to support native installations where system.ini is still used */\r
-    return GetPrivateProfileStringW(sectName, keyName, &wsznull, buf, sz, wszSystemIni);\r
+    return GetPrivateProfileStringW(sectName, keyName, &wsznull, buf, sz / sizeof(WCHAR), wszSystemIni);\r
 }\r
 \r
 /**************************************************************************\r
index 0ebeaa6..6cf7a63 100644 (file)
@@ -278,6 +278,11 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2)
     case MCI_UPDATE:\r
     case MCI_RESUME:\r
     case MCI_DELETE:\r
+    case MCI_MONITOR:\r
+    case MCI_SETAUDIO:\r
+    case MCI_SIGNAL:\r
+    case MCI_SETVIDEO:\r
+    case MCI_LIST:\r
         return 0;\r
 \r
     case MCI_OPEN:\r
@@ -975,8 +980,8 @@ static      LPCWSTR         MCI_FindCommand(UINT uTbl, LPCWSTR verb)
  */\r
 static DWORD           MCI_GetReturnType(LPCWSTR lpCmd)\r
 {\r
-    lpCmd += strlenW(lpCmd) + 1 + sizeof(DWORD) + sizeof(WORD);\r
-    if (*lpCmd == '\0' && *(const WORD*)(lpCmd + 1 + sizeof(DWORD)) == MCI_RETURN) {\r
+    lpCmd = (LPCWSTR)((BYTE*)(lpCmd + strlenW(lpCmd) + 1) + sizeof(DWORD) + sizeof(WORD));\r
+    if (*lpCmd == '\0' && *(const WORD*)((BYTE*)(lpCmd + 1) + sizeof(DWORD)) == MCI_RETURN) {\r
        return *(const DWORD*)(lpCmd + 1);\r
     }\r
     return 0L;\r
@@ -1743,7 +1748,7 @@ errCleanUp:
 /**************************************************************************\r
  *                     MCI_Close                               [internal]\r
  */\r
-static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)\r
+static DWORD MCI_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)\r
 {\r
     DWORD              dwRet;\r
     LPWINE_MCIDRIVER   wmd;\r
@@ -1835,7 +1840,7 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm
                    RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);\r
                    RegCloseKey( hKey );\r
                }\r
-               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf), wszSystemIni))\r
+               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf) / sizeof(buf[0]), wszSystemIni))\r
                    for (s = buf; *s; s += strlenW(s) + 1) cnt++;\r
            }\r
        } else {\r
@@ -1887,7 +1892,7 @@ static    DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParm
                RegCloseKey( hKey );\r
            }\r
            if (!s) {\r
-               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf), wszSystemIni)) {\r
+               if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf) / sizeof(buf[0]), wszSystemIni)) {\r
                    for (p = buf; *p; p += strlenW(p) + 1, cnt++) {\r
                         TRACE("%ld: %s\n", cnt, debugstr_w(p));\r
                        if (cnt == lpParms->dwNumber - 1) {\r
index ea8daef..dbd912e 100644 (file)
@@ -408,9 +408,19 @@ MMRESULT WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
 {\r
     TRACE("(%p, %u)\n", lpCaps, wSize);\r
 \r
+    if (lpCaps == 0) {\r
+        WARN("invalid lpCaps\n");\r
+        return TIMERR_NOCANDO;\r
+    }\r
+\r
+    if (wSize < sizeof(TIMECAPS)) {\r
+        WARN("invalid wSize\n");\r
+        return TIMERR_NOCANDO;\r
+    }\r
+\r
     lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;\r
     lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;\r
-    return 0;\r
+    return TIMERR_NOERROR;\r
 }\r
 \r
 /**************************************************************************\r
index 9fb05d2..2ff43cd 100644 (file)
@@ -62,6 +62,9 @@ typedef       struct tagWAVEMAPDATA {
     /* ratio to compute position from a PCM playback to any format */\r
     DWORD       avgSpeedOuter;\r
     DWORD       avgSpeedInner;\r
+    /* channel size of inner and outer */\r
+    DWORD       nSamplesPerSecOuter;\r
+    DWORD       nSamplesPerSecInner;\r
 } WAVEMAPDATA;\r
 \r
 static BOOL    WAVEMAP_IsData(WAVEMAPDATA* wm)\r
@@ -177,6 +180,7 @@ static      DWORD   wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
     wom->dwClientInstance = lpDesc->dwInstance;\r
     wom->u.out.hOuterWave = (HWAVEOUT)lpDesc->hWave;\r
     wom->avgSpeedOuter = wom->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;\r
+    wom->nSamplesPerSecOuter = wom->nSamplesPerSecInner = lpDesc->lpFormat->nSamplesPerSec;\r
 \r
     for (i = ndlo; i < ndhi; i++) {\r
        /* if no ACM stuff is involved, no need to handle callbacks at this\r
@@ -198,7 +202,7 @@ static      DWORD   wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 \r
 #define        TRY(sps,bps)    wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \\r
                         switch (res=wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \\r
-                            case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \\r
+                            case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; wom->nSamplesPerSecInner = wfx.nSamplesPerSec; goto found; \\r
                             case WAVERR_BADFORMAT: break; \\r
                             default: goto error; \\r
                         }\r
@@ -414,12 +418,59 @@ static    DWORD   wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwPara
 static DWORD   wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)\r
 {\r
     DWORD       val;\r
+    MMTIME      timepos;\r
     TRACE("(%p %p %08lx)\n", wom, lpTime, dwParam2);\r
 \r
-    val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);\r
-    if (lpTime->wType == TIME_BYTES)\r
-        lpTime->u.cb = MulDiv(lpTime->u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);\r
-    /* other time types don't require conversion */\r
+    memcpy(&timepos, lpTime, sizeof(timepos));\r
+\r
+    /* For TIME_MS, we're going to recalculate using TIME_BYTES */\r
+    if (lpTime->wType == TIME_MS)\r
+        timepos.wType = TIME_BYTES;\r
+\r
+    val = waveOutGetPosition(wom->u.out.hInnerWave, &timepos, dwParam2);\r
+\r
+    if (lpTime->wType == TIME_BYTES || lpTime->wType == TIME_MS)\r
+    {\r
+        DWORD dwInnerSamplesPerOuter = wom->nSamplesPerSecInner / wom->nSamplesPerSecOuter;\r
+        if (dwInnerSamplesPerOuter > 0)\r
+        {\r
+            DWORD dwInnerBytesPerSample = wom->avgSpeedInner / wom->nSamplesPerSecInner;\r
+            DWORD dwInnerBytesPerOuterSample = dwInnerBytesPerSample * dwInnerSamplesPerOuter;\r
+            DWORD remainder = 0;\r
+\r
+            /* If we are up sampling (going from lower sample rate to higher),\r
+            **   we need to make a special accomodation for times when we've\r
+            **   written a partial output sample.  This happens frequently\r
+            **   to us because we use msacm to do our up sampling, and it\r
+            **   will up sample on an unaligned basis.\r
+            ** For example, if you convert a 2 byte wide 8,000 'outer'\r
+            **   buffer to a 2 byte wide 48,000 inner device, you would\r
+            **   expect 2 bytes of input to produce 12 bytes of output.\r
+            **   Instead, msacm will produce 8 bytes of output.\r
+            **   But reporting our position as 1 byte of output is\r
+            **   nonsensical; the output buffer position needs to be\r
+            **   aligned on outer sample size, and aggressively rounded up.\r
+            */\r
+            remainder = timepos.u.cb % dwInnerBytesPerOuterSample;\r
+            if (remainder > 0)\r
+            {\r
+                timepos.u.cb -= remainder;\r
+                timepos.u.cb += dwInnerBytesPerOuterSample;\r
+            }\r
+        }\r
+\r
+        lpTime->u.cb = MulDiv(timepos.u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);\r
+\r
+        /* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */\r
+        if (lpTime->wType == TIME_MS)\r
+            lpTime->u.cb = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter);\r
+    }\r
+    else if (lpTime->wType == TIME_SAMPLES)\r
+        lpTime->u.cb = MulDiv(timepos.u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner);\r
+    else\r
+        /* other time types don't require conversion */\r
+        lpTime->u = timepos.u;\r
+\r
     return val;\r
 }\r
 \r
@@ -691,6 +742,7 @@ static      DWORD   widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
     }\r
 \r
     wim->avgSpeedOuter = wim->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;\r
+    wim->nSamplesPerSecOuter = wim->nSamplesPerSecInner = lpDesc->lpFormat->nSamplesPerSec;\r
 \r
     for (i = ndlo; i < ndhi; i++) {\r
        if (waveInOpen(&wim->u.in.hInnerWave, i, lpDesc->lpFormat, (DWORD)widCallback,\r
@@ -710,7 +762,7 @@ static      DWORD   widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 \r
 #define        TRY(sps,bps)    wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \\r
                         switch (res=widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \\r
-                        case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \\r
+                        case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; wim->nSamplesPerSecInner = wfx.nSamplesPerSec; goto found; \\r
                         case WAVERR_BADFORMAT: break; \\r
                         default: goto error; \\r
                         }\r
@@ -915,6 +967,8 @@ static      DWORD   widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2)
     val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2);\r
     if (lpTime->wType == TIME_BYTES)\r
         lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->avgSpeedInner);\r
+    if (lpTime->wType == TIME_SAMPLES)\r
+        lpTime->u.cb = MulDiv(lpTime->u.cb, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner);\r
     /* other time types don't require conversion */\r
     return val;\r
 }\r
index 29be5a6..7c4712c 100644 (file)
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  */\r
 \r
-STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT\r
+STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL\r
    BEGIN\r
 \r
    /* MMSYS errors */\r
index a257b93..4caaa10 100644 (file)
@@ -10,6 +10,7 @@
 
 #undef __USE_W32API
 #include <windows.h>
+#include <winerror.h>
 
 /*
  * @unimplemented
similarity index 53%
rename from reactos/lib/coredll/coredll_main.c
rename to reactos/lib/winsta/main.c
index 3617049..b9d235d 100644 (file)
@@ -1,39 +1,50 @@
-/*
- * ReactOS-CE Core OS Dll
- *
- * Copyright 2004 Steven Edwards
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * TODO:
- * ATM this is just a dummy forwarding dll for the WinCE API to Win32 API
- * When you exit a simple WinCE app on Windows or on ReactOS it causes
- * a program error or unhandled exception probl'y because we dont handle
- * threading and process attaching/detaching like we should here.
- *
- * There will be some parts of the WinCE API that cant just be forwarded to
- * the Win32 API as paramater names or types may differ. In that case you will
- * need to copy the Win32 implementation and make the needed changes.
- */
-
-#include "windows.h"
-
-BOOL STDCALL
-DllMain(HANDLE hDll,
-       DWORD dwReason,
-       LPVOID lpReserved)
-{
-   return TRUE;
-}
+/*\r
+ * ReactOS WinStation\r
+ * Copyright (C) 2005 ReactOS Team\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+/* $Id$\r
+ *\r
+ * PROJECT:         ReactOS winsta.dll\r
+ * FILE:            lib/winsta/main.c\r
+ * PURPOSE:         WinStation\r
+ * PROGRAMMER:      Emanuele Aliberti <ea@reactos.com>\r
+ */\r
+#include <windows.h>\r
+\r
+HINSTANCE hDllInstance;\r
+\r
+\r
+BOOL STDCALL\r
+DllMain(HINSTANCE hinstDLL,\r
+       DWORD     dwReason,\r
+       LPVOID    lpvReserved)\r
+{\r
+  switch (dwReason)\r
+  {\r
+    case DLL_PROCESS_ATTACH:\r
+      hDllInstance = hinstDLL;\r
+      break;\r
+    case DLL_THREAD_ATTACH:\r
+      break;\r
+    case DLL_THREAD_DETACH:\r
+      break;\r
+    case DLL_PROCESS_DETACH:\r
+      break;\r
+  }\r
+  return TRUE;\r
+}\r
+/* EOF */\r
diff --git a/reactos/lib/winsta/makefile b/reactos/lib/winsta/makefile
new file mode 100644 (file)
index 0000000..e4dad8b
--- /dev/null
@@ -0,0 +1,23 @@
+# $Id$\r
+\r
+PATH_TO_TOP = ../..\r
+\r
+TARGET_TYPE = dynlink\r
+\r
+TARGET_NAME = winsta\r
+\r
+TARGET_CFLAGS = -g -Werror -Wall\r
+\r
+TARGET_OBJECTS = \\r
+       main.o \\r
+       misc.o \\r
+       server.o \\r
+       ws.o\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+include $(TOOLS_PATH)/helper.mk\r
+\r
+include $(TOOLS_PATH)/depend.mk\r
+\r
+# EOF\r
diff --git a/reactos/lib/winsta/misc.c b/reactos/lib/winsta/misc.c
new file mode 100644 (file)
index 0000000..9c030ab
--- /dev/null
@@ -0,0 +1,12 @@
+/* $Id$ */\r
+#include <windows.h>\r
+#include "winsta.h"\r
+\r
+WINSTASTUB(LogonIdFromWinStationNameA)\r
+WINSTASTUB(LogonIdFromWinStationNameW)\r
+WINSTASTUB(RemoteAssistancePrepareSystemRestore)\r
+WINSTASTUB(_NWLogonQueryAdmin)\r
+WINSTASTUB(_NWLogonSetAdmin)\r
+/* EOF */\r
+\r
+\r
diff --git a/reactos/lib/winsta/server.c b/reactos/lib/winsta/server.c
new file mode 100644 (file)
index 0000000..d541075
--- /dev/null
@@ -0,0 +1,21 @@
+/* $Id$ */\r
+#include <windows.h>\r
+#include "winsta.h"\r
+\r
+WINSTASTUB(ServerGetInternetConnectorStatus)\r
+WINSTASTUB(ServerLicensingClose)\r
+WINSTASTUB(ServerLicensingDeactivateCurrentPolicy)\r
+WINSTASTUB(ServerLicensingFreePolicyInformation)\r
+WINSTASTUB(ServerLicensingGetAvailablePolicyIds)\r
+WINSTASTUB(ServerLicensingGetPolicy)\r
+WINSTASTUB(ServerLicensingGetPolicyInformationA)\r
+WINSTASTUB(ServerLicensingGetPolicyInformationW)\r
+WINSTASTUB(ServerLicensingLoadPolicy)\r
+WINSTASTUB(ServerLicensingOpenA)\r
+WINSTASTUB(ServerLicensingOpenW)\r
+WINSTASTUB(ServerLicensingSetPolicy)\r
+WINSTASTUB(ServerLicensingUnloadPolicy)\r
+WINSTASTUB(ServerQueryInetConnectorInformationA)\r
+WINSTASTUB(ServerQueryInetConnectorInformationW)\r
+WINSTASTUB(ServerSetInternetConnectorStatus)\r
+/* EOF */\r
diff --git a/reactos/lib/winsta/winsta.def b/reactos/lib/winsta/winsta.def
new file mode 100644 (file)
index 0000000..34dd802
--- /dev/null
@@ -0,0 +1,100 @@
+; $Id$\r
+LIBRARY winsta.dll\r
+EXPORTS\r
+LogonIdFromWinStationNameA@0\r
+LogonIdFromWinStationNameW@0\r
+RemoteAssistancePrepareSystemRestore@0\r
+ServerGetInternetConnectorStatus@0\r
+ServerLicensingClose@0\r
+ServerLicensingDeactivateCurrentPolicy@0\r
+ServerLicensingFreePolicyInformation@0\r
+ServerLicensingGetAvailablePolicyIds@0\r
+ServerLicensingGetPolicy@0\r
+ServerLicensingGetPolicyInformationA@0\r
+ServerLicensingGetPolicyInformationW@0\r
+ServerLicensingLoadPolicy@0\r
+ServerLicensingOpenA@0\r
+ServerLicensingOpenW@0\r
+ServerLicensingSetPolicy@0\r
+ServerLicensingUnloadPolicy@0\r
+ServerQueryInetConnectorInformationA@0\r
+ServerQueryInetConnectorInformationW@0\r
+ServerSetInternetConnectorStatus@0\r
+WinStationActivateLicense@0\r
+WinStationAutoReconnect@0\r
+WinStationBroadcastSystemMessage@0\r
+WinStationCheckLoopBack@0\r
+WinStationCloseServer@0\r
+WinStationConnectA@0\r
+WinStationConnectCallback@0\r
+WinStationConnectW@0\r
+WinStationDisconnect@0\r
+WinStationEnumerateA@0\r
+WinStationEnumerateLicenses@0\r
+WinStationEnumerateProcesses@0\r
+WinStationEnumerateW@0\r
+WinStationEnumerate_IndexedA@0\r
+WinStationEnumerate_IndexedW@0\r
+WinStationFreeGAPMemory@0\r
+WinStationFreeMemory@0\r
+WinStationGenerateLicense@0\r
+WinStationGetAllProcesses@0\r
+WinStationGetLanAdapterNameA@0\r
+WinStationGetLanAdapterNameW@0\r
+WinStationGetMachinePolicy@0\r
+WinStationGetProcessSid@0\r
+WinStationGetTermSrvCountersValue@0\r
+WinStationInstallLicense@0\r
+WinStationIsHelpAssistantSession@0\r
+WinStationNameFromLogonIdA@0\r
+WinStationNameFromLogonIdW@0\r
+WinStationNtsdDebug@0\r
+WinStationOpenServerA@0\r
+WinStationOpenServerW@0\r
+WinStationQueryInformationA@0\r
+WinStationQueryInformationW@0\r
+WinStationQueryLicense@0\r
+WinStationQueryLogonCredentialsW@0\r
+WinStationQueryUpdateRequired@0\r
+WinStationRegisterConsoleNotification@0\r
+WinStationRemoveLicense@0\r
+WinStationRenameA@0\r
+WinStationRenameW@0\r
+WinStationRequestSessionsList@0\r
+WinStationReset@0\r
+WinStationSendMessageA@0\r
+WinStationSendMessageW@0\r
+WinStationSendWindowMessage@0\r
+WinStationServerPing@0\r
+WinStationSetInformationA@0\r
+WinStationSetInformationW@0\r
+WinStationSetPoolCount@0\r
+WinStationShadow@0\r
+WinStationShadowStop@0\r
+WinStationShutdownSystem@0\r
+WinStationTerminateProcess@0\r
+WinStationUnRegisterConsoleNotification@0\r
+WinStationVirtualOpen@0\r
+WinStationWaitSystemEvent@0\r
+_NWLogonQueryAdmin@0\r
+_NWLogonSetAdmin@0\r
+_WinStationAnnoyancePopup@0\r
+_WinStationBeepOpen@0\r
+_WinStationBreakPoint@0\r
+_WinStationCallback@0\r
+_WinStationCheckForApplicationName@0\r
+_WinStationFUSCanRemoteUserDisconnect@0\r
+_WinStationGetApplicationInfo@0\r
+_WinStationNotifyDisconnectPipe@0\r
+_WinStationNotifyLogoff@0\r
+_WinStationNotifyLogon@0\r
+_WinStationNotifyNewSession@0\r
+_WinStationReInitializeSecurity@0\r
+_WinStationReadRegistry@0\r
+_WinStationShadowTarget@0\r
+_WinStationShadowTargetSetup@0\r
+_WinStationUpdateClientCachedCredentials@0\r
+_WinStationUpdateSettings@0\r
+_WinStationUpdateUserConfig@0\r
+_WinStationWaitForConnect@0\r
+; EOF\r
diff --git a/reactos/lib/winsta/winsta.h b/reactos/lib/winsta/winsta.h
new file mode 100644 (file)
index 0000000..86e74ea
--- /dev/null
@@ -0,0 +1,7 @@
+#if !defined(_WINSTA_H)\r
+#define _WINSTA_H\r
+\r
+#define WINSTASTUB(n) VOID STDCALL n (VOID) { }\r
+\r
+#endif /* !def _WINSTA_H */\r
+\r
diff --git a/reactos/lib/winsta/winsta.rc b/reactos/lib/winsta/winsta.rc
new file mode 100644 (file)
index 0000000..d9c3a50
--- /dev/null
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS WinStation\0"\r
+#define REACTOS_STR_INTERNAL_NAME      "winsta\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME  "winsta.dll\0"\r
+#include <reactos/version.rc>\r
diff --git a/reactos/lib/winsta/ws.c b/reactos/lib/winsta/ws.c
new file mode 100644 (file)
index 0000000..fd57495
--- /dev/null
@@ -0,0 +1,80 @@
+/* $Id$ */\r
+#include <windows.h>\r
+#include "winsta.h"\r
+\r
+WINSTASTUB(WinStationActivateLicense)\r
+WINSTASTUB(WinStationAutoReconnect)\r
+WINSTASTUB(WinStationBroadcastSystemMessage)\r
+WINSTASTUB(WinStationCheckLoopBack)\r
+WINSTASTUB(WinStationCloseServer)\r
+WINSTASTUB(WinStationConnectA)\r
+WINSTASTUB(WinStationConnectCallback)\r
+WINSTASTUB(WinStationConnectW)\r
+WINSTASTUB(WinStationDisconnect)\r
+WINSTASTUB(WinStationEnumerateA)\r
+WINSTASTUB(WinStationEnumerateLicenses)\r
+WINSTASTUB(WinStationEnumerateProcesses)\r
+WINSTASTUB(WinStationEnumerateW)\r
+WINSTASTUB(WinStationEnumerate_IndexedA)\r
+WINSTASTUB(WinStationEnumerate_IndexedW)\r
+WINSTASTUB(WinStationFreeGAPMemory)\r
+WINSTASTUB(WinStationFreeMemory)\r
+WINSTASTUB(WinStationGenerateLicense)\r
+WINSTASTUB(WinStationGetAllProcesses)\r
+WINSTASTUB(WinStationGetLanAdapterNameA)\r
+WINSTASTUB(WinStationGetLanAdapterNameW)\r
+WINSTASTUB(WinStationGetMachinePolicy)\r
+WINSTASTUB(WinStationGetProcessSid)\r
+WINSTASTUB(WinStationGetTermSrvCountersValue)\r
+WINSTASTUB(WinStationInstallLicense)\r
+WINSTASTUB(WinStationIsHelpAssistantSession)\r
+WINSTASTUB(WinStationNameFromLogonIdA)\r
+WINSTASTUB(WinStationNameFromLogonIdW)\r
+WINSTASTUB(WinStationNtsdDebug)\r
+WINSTASTUB(WinStationOpenServerA)\r
+WINSTASTUB(WinStationOpenServerW)\r
+WINSTASTUB(WinStationQueryInformationA)\r
+WINSTASTUB(WinStationQueryInformationW)\r
+WINSTASTUB(WinStationQueryLicense)\r
+WINSTASTUB(WinStationQueryLogonCredentialsW)\r
+WINSTASTUB(WinStationQueryUpdateRequired)\r
+WINSTASTUB(WinStationRegisterConsoleNotification)\r
+WINSTASTUB(WinStationRemoveLicense)\r
+WINSTASTUB(WinStationRenameA)\r
+WINSTASTUB(WinStationRenameW)\r
+WINSTASTUB(WinStationRequestSessionsList)\r
+WINSTASTUB(WinStationReset)\r
+WINSTASTUB(WinStationSendMessageA)\r
+WINSTASTUB(WinStationSendMessageW)\r
+WINSTASTUB(WinStationSendWindowMessage)\r
+WINSTASTUB(WinStationServerPing)\r
+WINSTASTUB(WinStationSetInformationA)\r
+WINSTASTUB(WinStationSetInformationW)\r
+WINSTASTUB(WinStationSetPoolCount)\r
+WINSTASTUB(WinStationShadow)\r
+WINSTASTUB(WinStationShadowStop)\r
+WINSTASTUB(WinStationShutdownSystem)\r
+WINSTASTUB(WinStationTerminateProcess)\r
+WINSTASTUB(WinStationUnRegisterConsoleNotification)\r
+WINSTASTUB(WinStationVirtualOpen)\r
+WINSTASTUB(WinStationWaitSystemEvent)\r
+WINSTASTUB(_WinStationAnnoyancePopup)\r
+WINSTASTUB(_WinStationBeepOpen)\r
+WINSTASTUB(_WinStationBreakPoint)\r
+WINSTASTUB(_WinStationCallback)\r
+WINSTASTUB(_WinStationCheckForApplicationName)\r
+WINSTASTUB(_WinStationFUSCanRemoteUserDisconnect)\r
+WINSTASTUB(_WinStationGetApplicationInfo)\r
+WINSTASTUB(_WinStationNotifyDisconnectPipe)\r
+WINSTASTUB(_WinStationNotifyLogoff)\r
+WINSTASTUB(_WinStationNotifyLogon)\r
+WINSTASTUB(_WinStationNotifyNewSession)\r
+WINSTASTUB(_WinStationReInitializeSecurity)\r
+WINSTASTUB(_WinStationReadRegistry)\r
+WINSTASTUB(_WinStationShadowTarget)\r
+WINSTASTUB(_WinStationShadowTargetSetup)\r
+WINSTASTUB(_WinStationUpdateClientCachedCredentials)\r
+WINSTASTUB(_WinStationUpdateSettings)\r
+WINSTASTUB(_WinStationUpdateUserConfig)\r
+WINSTASTUB(_WinStationWaitForConnect)\r
+/* EOF */\r
index e1c6977..0ffac31 100644 (file)
@@ -1,3 +1,131 @@
-
 LIBRARY wintrust.dll
+EXPORTS
+;CryptCATVerifyMember
+;CryptSIPGetInfo
+;CryptSIPGetRegWorkingFlags
+;GenericChainCertificateTrust
+;GenericChainFinalProv
+;HTTPSCertificateTrust
+;SoftpubDefCertInit
+;SoftpubFreeDefUsageCallData
+;SoftpubLoadDefUsageCallData
+;WTHelperCertFindIssuerCertificate
+;AddPersonalTrustDBPages
+;CatalogCompactHashDatabase
+;CryptCATAdminAcquireContext
+;CryptCATAdminAddCatalog
+;CryptCATAdminCalcHashFromFileHandle
+;CryptCATAdminEnumCatalogFromHash
+;CryptCATAdminPauseServiceForBackup
+;CryptCATAdminReleaseCatalogContext
+;CryptCATAdminReleaseContext
+;CryptCATAdminRemoveCatalog
+;CryptCATAdminResolveCatalogPath
+;CryptCATCDFClose
+;CryptCATCDFEnumAttributes
+;CryptCATCDFEnumAttributesWithCDFTag
+;CryptCATCDFEnumCatAttributes
+;CryptCATCDFEnumMembers
+;CryptCATCDFEnumMembersByCDFTag
+;CryptCATCDFEnumMembersByCDFTagEx
+;CryptCATCDFOpen
+;CryptCATCatalogInfoFromContext
+;CryptCATClose
+;CryptCATEnumerateAttr
+;CryptCATEnumerateCatAttr
+;CryptCATEnumerateMember
+;CryptCATGetAttrInfo
+;CryptCATGetCatAttrInfo
+;CryptCATGetMemberInfo
+;CryptCATHandleFromStore
+;CryptCATOpen
+;CryptCATPersistStore
+;CryptCATPutAttrInfo
+;CryptCATPutCatAttrInfo
+;CryptCATPutMemberInfo
+;CryptCATStoreFromHandle
+;CryptSIPCreateIndirectData
+;CryptSIPGetSignedDataMsg
+;CryptSIPPutSignedDataMsg
+;CryptSIPRemoveSignedDataMsg
+;CryptSIPVerifyIndirectData
+;DllRegisterServer
+;DllUnregisterServer
+;DriverCleanupPolicy
+;DriverFinalPolicy
+;DriverInitializePolicy
+;FindCertsByIssuer
+;HTTPSFinalProv
+;I_CryptCatAdminMigrateToNewCatDB
+;IsCatalogFile
+;MsCatConstructHashTag
+;MsCatFreeHashTag
+;OfficeCleanupPolicy
+;OfficeInitializePolicy
+;OpenPersonalTrustDBDialog
+;OpenPersonalTrustDBDialogEx
+;SoftpubAuthenticode
+;SoftpubCheckCert
+;SoftpubCleanup
+;SoftpubDllRegisterServer
+;SoftpubDllUnregisterServer
+;SoftpubDumpStructure
+;SoftpubInitialize
+;SoftpubLoadMessage
+;SoftpubLoadSignature
+;TrustDecode
+;TrustFindIssuerCertificate
+;TrustFreeDecode
+;TrustIsCertificateSelfSigned
+;TrustOpenStores
+;WTHelperCertCheckValidSignature
+;WTHelperCertIsSelfSigned
+;WTHelperCheckCertUsage
+;WTHelperGetAgencyInfo
+;WTHelperGetFileHandle
+;WTHelperGetFileHash
+;WTHelperGetFileName
+;WTHelperGetKnownUsages
+;WTHelperGetProvCertFromChain
+;WTHelperGetProvPrivateDataFromChain
+;WTHelperGetProvSignerFromChain
+;WTHelperIsInRootStore
+;WTHelperOpenKnownStores
+;WTHelperProvDataFromStateData
+;WVTAsn1CatMemberInfoDecode
+;WVTAsn1CatMemberInfoEncode
+;WVTAsn1CatNameValueDecode
+;WVTAsn1CatNameValueEncode
+;WVTAsn1SpcFinancialCriteriaInfoDecode
+;WVTAsn1SpcFinancialCriteriaInfoEncode
+;WVTAsn1SpcIndirectDataContentDecode
+;WVTAsn1SpcIndirectDataContentEncode
+;WVTAsn1SpcLinkDecode
+;WVTAsn1SpcLinkEncode
+;WVTAsn1SpcMinimalCriteriaInfoDecode
+;WVTAsn1SpcMinimalCriteriaInfoEncode
+;WVTAsn1SpcPeImageDataDecode
+;WVTAsn1SpcPeImageDataEncode
+;WVTAsn1SpcSigInfoDecode
+;WVTAsn1SpcSigInfoEncode
+;WVTAsn1SpcSpAgencyInfoDecode
+;WVTAsn1SpcSpAgencyInfoEncode
+;WVTAsn1SpcSpOpusInfoDecode
+;WVTAsn1SpcSpOpusInfoEncode
+;WVTAsn1SpcStatementTypeDecode
+;WVTAsn1SpcStatementTypeEncode
+WinVerifyTrust@12
+;WinVerifyTrustEx
+WintrustAddActionID
+;WintrustAddDefaultForUsage
+;WintrustCertificateTrust
+;WintrustGetDefaultForUsage
+;WintrustGetRegPolicyFlags
+;WintrustLoadFunctionPointers
+;WintrustRemoveActionID
+;WintrustSetRegPolicyFlags
+;mscat32DllRegisterServer
+;mscat32DllUnregisterServer
+;mssip32DllRegisterServer
+;mssip32DllUnregisterServer
 ; EOF
index 7cb725b..001970b 100644 (file)
@@ -18,7 +18,7 @@
 #include <windows.h>
 #undef assert
 #include <debug.h>
-#include <WinDNS.h> // DNS_A_DATA
+#include <windns.h> // DNS_A_DATA
 
 /* Exported by ntdll.dll, but where is the prototype? */
 unsigned long strtoul(const char *nptr, char **endptr, int base);
diff --git a/reactos/media/drivers/etc/KDBinit b/reactos/media/drivers/etc/KDBinit
new file mode 100644 (file)
index 0000000..53a68e1
--- /dev/null
@@ -0,0 +1,15 @@
+# Example KDB.init file\r
+#\r
+# The disassembly flavor is set to "intel" (default is "at&t") and the\r
+#\r
+\r
+# Set the disassembly flavor to "intel" (default is "at&t")\r
+set syntax intel\r
+\r
+# Change the condition to enter KDB on INT3 to "always" (default is "kmode")\r
+set condition INT3 first always\r
+\r
+# This is a special command available only in the KDB.init file - it breaks into\r
+# KDB when it is interpreting the init file at startup.\r
+#break\r
+\r
diff --git a/reactos/media/themes/.gitignore b/reactos/media/themes/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index f3579cd..952b6c8 100644 (file)
@@ -353,6 +353,12 @@ typedef struct _KEY_OBJECT
 
   /* List of subkeys loaded */
   struct _KEY_OBJECT **SubKeys;
+
+  /* List entry into the global key object list */
+  LIST_ENTRY ListEntry;
+  
+  /* Time stamp for the last access by the parse routine */
+  ULONG TimeStamp;
 } KEY_OBJECT, *PKEY_OBJECT;
 
 /* Bits 31-22 (top 10 bits) of the cell index is the directory index */
@@ -529,10 +535,11 @@ CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
 NTSTATUS
 CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
 
-PKEY_OBJECT
+NTSTATUS
 CmiScanKeyList(IN PKEY_OBJECT Parent,
               IN PUNICODE_STRING KeyName,
-              IN ULONG Attributes);
+              IN ULONG Attributes,
+              PKEY_OBJECT* ReturnedObject);
 
 NTSTATUS
 CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive);
index b44a7f0..9b1f635 100644 (file)
@@ -21,6 +21,7 @@
 
 extern POBJECT_TYPE  CmiKeyType;
 extern PREGISTRY_HIVE  CmiVolatileHive;
+extern LIST_ENTRY CmiKeyObjectListHead;
 
 static BOOLEAN CmiRegistryInitialized = FALSE;
 
@@ -300,6 +301,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
   KeEnterCriticalRegion();
   ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
+  InsertTailList(&CmiKeyObjectListHead, &KeyObject->ListEntry);
+
   /* add key to subkeys of parent if needed */
   Status = CmiAddSubKey(KeyObject->RegistryHive,
                        KeyObject->ParentKey,
@@ -355,7 +358,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
   ExReleaseResourceLite(&CmiRegistryLock);
   KeLeaveCriticalRegion();
 
-  ObDereferenceObject(KeyObject);
+  
   ObDereferenceObject(Object);
 
   if (Disposition)
@@ -419,6 +422,9 @@ NtDeleteKey(IN HANDLE KeyHandle)
 
   /* Dereference the object */
   ObDereferenceObject(KeyObject);
+  /* Remove the keep-alive reference */
+  ObDereferenceObject(KeyObject);
+
   if (KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
     ObDereferenceObject(KeyObject);
 
@@ -454,9 +460,12 @@ NtEnumerateKey(IN HANDLE KeyHandle,
   PKEY_FULL_INFORMATION  FullInformation;
   PDATA_CELL ClassCell;
   ULONG NameSize, ClassSize;
+  KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status;
   
   PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
 
   DPRINT("KH %x  I %d  KIC %x KI %x  L %d  RL %x\n",
         KeyHandle,
@@ -470,7 +479,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
   Status = ObReferenceObjectByHandle(KeyHandle,
                KEY_ENUMERATE_SUB_KEYS,
                CmiKeyType,
-               UserMode,
+               PreviousMode,
                (PVOID *) &KeyObject,
                NULL);
   if (!NT_SUCCESS(Status))
@@ -513,8 +522,7 @@ NtEnumerateKey(IN HANDLE KeyHandle,
       for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
        {
          CurKey = KeyObject->SubKeys[i];
-         if (CurKey->RegistryHive == CmiVolatileHive ||
-             CurKey->RegistryHive != RegistryHive)
+         if (CurKey->RegistryHive != RegistryHive)
            {
              if (j == Index)
                break;
@@ -1051,7 +1059,7 @@ NtFlushKey(IN HANDLE KeyHandle)
 
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
-                                    KEY_QUERY_VALUE,
+                                    0,
                                     CmiKeyType,
                                     PreviousMode,
                                     (PVOID *)&KeyObject,
@@ -1213,7 +1221,7 @@ NtQueryKey(IN HANDLE KeyHandle,
 
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
-               KEY_READ,
+               (KeyInformationClass != KeyNameInformation ? KEY_QUERY_VALUE : 0),
                CmiKeyType,
                UserMode,
                (PVOID *) &KeyObject,
@@ -1372,6 +1380,13 @@ NtQueryKey(IN HANDLE KeyHandle,
          }
        break;
 
+      case KeyNameInformation:
+      case KeyCachedInformation:
+      case KeyFlagsInformation:
+        DPRINT1("Key information class 0x%x not yet implemented!\n", KeyInformationClass);
+        Status = STATUS_NOT_IMPLEMENTED;
+        break;
+
       default:
        DPRINT1("Not handling 0x%x\n", KeyInformationClass);
        Status = STATUS_INVALID_INFO_CLASS;
@@ -1653,14 +1668,12 @@ NtSetValueKey(IN HANDLE KeyHandle,
         KeyHandle, ValueName, Type);
 
   DesiredAccess = KEY_SET_VALUE;
-  if (Type == REG_LINK)
-    DesiredAccess |= KEY_CREATE_LINK;
 
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
                                     DesiredAccess,
                                     CmiKeyType,
-                                    UserMode,
+                                    ExGetPreviousMode(),
                                     (PVOID *)&KeyObject,
                                     NULL);
   if (!NT_SUCCESS(Status))
@@ -1998,6 +2011,34 @@ NtNotifyChangeKey (IN HANDLE KeyHandle,
        return(STATUS_NOT_IMPLEMENTED);
 }
 
+#if 0
+NTSTATUS STDCALL
+NtNotifyChangeKey (IN HANDLE KeyHandle,
+                  IN HANDLE Event,
+                  IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+                  IN PVOID ApcContext OPTIONAL,
+                  OUT PIO_STATUS_BLOCK IoStatusBlock,
+                  IN ULONG CompletionFilter,
+                  IN BOOLEAN WatchSubtree,
+                  OUT PVOID Buffer,
+                  IN ULONG Length,
+                  IN BOOLEAN Asynchronous)
+{
+     return NtNotifyChangeMultipleKeys(KeyHandle,          
+                                       0,
+                                       NULL,
+                                       Event,
+                                       ApcRoutine,
+                                       ApcContext,
+                                       IoStatusBlock,
+                                       CompletionFilter,
+                                       WatchTree,
+                                       Buffer,
+                                       Length,
+                                       Asynchronous);
+}
+
+#endif
 
 NTSTATUS STDCALL
 NtQueryMultipleValueKey (IN HANDLE KeyHandle,
index 304192c..671afd0 100644 (file)
 
 POBJECT_TYPE  CmiKeyType = NULL;
 PREGISTRY_HIVE  CmiVolatileHive = NULL;
-KSPIN_LOCK  CmiKeyListLock;
 
 LIST_ENTRY CmiHiveListHead;
 
 ERESOURCE CmiRegistryLock;
 
+KTIMER CmiWorkerTimer;
+LIST_ENTRY CmiKeyObjectListHead;
+ULONG CmiTimer = 0;
+
 volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
 volatile BOOLEAN CmiHiveSyncPending = FALSE;
 KDPC CmiHiveSyncDpc;
@@ -241,6 +244,92 @@ CmiCheckRegistry(BOOLEAN Verbose)
   CmiCheckByName(Verbose, L"User");
 }
 
+VOID STDCALL
+CmiWorkerThread(PVOID Param)
+{
+  NTSTATUS Status;
+  PLIST_ENTRY CurrentEntry;
+  PKEY_OBJECT CurrentKey;
+  ULONG Count;
+
+
+  while (1)
+  {
+    Status = KeWaitForSingleObject(&CmiWorkerTimer, 
+                                  Executive, 
+                                  KernelMode, 
+                                  FALSE, 
+                                  NULL);
+    if (Status == STATUS_SUCCESS)
+    {
+      DPRINT("CmiWorkerThread\n");
+
+      /* Acquire hive lock */
+      KeEnterCriticalRegion();
+      ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
+      CmiTimer++;
+
+      Count = 0;
+      CurrentEntry = CmiKeyObjectListHead.Blink;
+      while (CurrentEntry != &CmiKeyObjectListHead)
+      {
+         CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
+        if (CurrentKey->TimeStamp + 120 > CmiTimer)
+        {
+           /* The object was accessed in the last 10min */
+           break;
+        }
+        if (1 == ObGetObjectPointerCount(CurrentKey) &&
+            !(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
+        {
+           ObDereferenceObject(CurrentKey);
+            CurrentEntry = CmiKeyObjectListHead.Blink;
+           Count++;
+        }
+        else
+        {
+           CurrentEntry = CurrentEntry->Blink;
+        }
+      }
+      ExReleaseResourceLite(&CmiRegistryLock);
+      KeLeaveCriticalRegion();
+
+      DPRINT("Removed %d key objects\n", Count);
+
+    }
+    else
+    {
+      KEBUGCHECK(0);
+    }
+  }
+}
+
+VOID
+INIT_FUNCTION
+STDCALL
+CmInitHives(BOOLEAN SetupBoot)
+{
+    PCHAR BaseAddress;
+    
+    /* Load Registry Hives. This one can be missing. */
+    if (CachedModules[SystemRegistry]) {
+        BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
+        CmImportSystemHive(BaseAddress,
+                           CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    }
+    
+    BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
+    CmImportHardwareHive(BaseAddress,
+                         CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    
+
+    /* Create dummy keys if no hardware hive was found */
+    CmImportHardwareHive (NULL, 0);
+
+    /* Initialize volatile registry settings */
+    if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+}   
 
 VOID INIT_FUNCTION
 CmInitializeRegistry(VOID)
@@ -254,6 +343,9 @@ CmInitializeRegistry(VOID)
   HANDLE RootKeyHandle;
   HANDLE KeyHandle;
   NTSTATUS Status;
+  LARGE_INTEGER DueTime;
+  HANDLE ThreadHandle;
+  CLIENT_ID ThreadId;
 
   /*  Initialize the Key object type  */
   CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
@@ -286,6 +378,29 @@ CmInitializeRegistry(VOID)
   /* Initialize registry lock */
   ExInitializeResourceLite(&CmiRegistryLock);
 
+  /* Initialize the key object list */
+  InitializeListHead(&CmiKeyObjectListHead);
+
+  /* Initialize the worker timer */
+  KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer);
+
+  /* Initialize the worker thread */
+  Status = PsCreateSystemThread(&ThreadHandle,
+                               THREAD_ALL_ACCESS,
+                               NULL,
+                               NULL,
+                               &ThreadId,
+                               CmiWorkerThread,
+                               NULL);
+  if (!NT_SUCCESS(Status))
+  {
+    KEBUGCHECK(0);
+  }
+
+  /* Start the timer */  
+  DueTime.QuadPart = -1;
+  KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
+
   /*  Build volatile registry store  */
   Status = CmiCreateVolatileHive (&CmiVolatileHive);
   ASSERT(NT_SUCCESS(Status));
@@ -308,7 +423,7 @@ CmInitializeRegistry(VOID)
   ASSERT(NT_SUCCESS(Status));
   Status = ObInsertObject(RootKey,
                          NULL,
-                         STANDARD_RIGHTS_REQUIRED,
+                         KEY_ALL_ACCESS,
                          0,
                          NULL,
                          &RootKeyHandle);
@@ -321,6 +436,7 @@ CmInitializeRegistry(VOID)
   RootKey->NumberOfSubKeys = 0;
   RootKey->SubKeys = NULL;
   RootKey->SizeOfSubKeys = 0;
+  InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry);
   Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
   ASSERT(NT_SUCCESS(Status));
 
@@ -336,7 +452,6 @@ CmInitializeRegistry(VOID)
   CmiVolatileHive->RootSecurityCell = RootSecurityCell;
 #endif
 
-  KeInitializeSpinLock(&CmiKeyListLock);
 
   /* Create '\Registry\Machine' key. */
   RtlInitUnicodeString(&KeyName,
@@ -347,7 +462,7 @@ CmInitializeRegistry(VOID)
                             RootKeyHandle,
                             NULL);
   Status = ZwCreateKey(&KeyHandle,
-                      STANDARD_RIGHTS_REQUIRED,
+                      KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
@@ -364,7 +479,7 @@ CmInitializeRegistry(VOID)
                             RootKeyHandle,
                             NULL);
   Status = ZwCreateKey(&KeyHandle,
-                      STANDARD_RIGHTS_REQUIRED,
+                      KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
@@ -648,6 +763,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
   NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset, NULL);
   NewKey->Flags = 0;
   NewKey->NumberOfSubKeys = 0;
+  InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
   if (NewKey->KeyCell->NumberOfSubKeys != 0)
     {
       NewKey->SubKeys = ExAllocatePool(NonPagedPool,
@@ -702,6 +818,8 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
   PREGISTRY_HIVE Hive;
   HANDLE KeyHandle;
   NTSTATUS Status;
+  PLIST_ENTRY CurrentEntry;
+  PKEY_OBJECT CurrentKey;
 
   DPRINT("CmiDisconnectHive() called\n");
 
@@ -741,11 +859,36 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
       return STATUS_INVALID_PARAMETER;
     }
 
+  /* Acquire registry lock exclusively */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
+  CurrentEntry = CmiKeyObjectListHead.Flink;
+  while (CurrentEntry != &CmiKeyObjectListHead)
+  {
+     CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
+     if (1 == ObGetObjectPointerCount(CurrentKey) &&
+        !(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
+     {
+        ObDereferenceObject(CurrentKey);
+        CurrentEntry = CmiKeyObjectListHead.Flink;
+     }
+     else
+     {
+        CurrentEntry = CurrentEntry->Flink;
+     }
+  }
+
   if (ObGetObjectHandleCount (KeyObject) != 0 ||
       ObGetObjectPointerCount (KeyObject) != 2)
     {
-      DPRINT1 ("Hive is still in use\n");
+      DPRINT1 ("Hive is still in use (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject));
       ObDereferenceObject (KeyObject);
+      
+      /* Release registry lock */
+      ExReleaseResourceLite (&CmiRegistryLock);
+      KeLeaveCriticalRegion();
+
       return STATUS_UNSUCCESSFUL;
     }
 
@@ -757,6 +900,10 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
 
   *RegistryHive = Hive;
 
+  /* Release registry lock */
+  ExReleaseResourceLite (&CmiRegistryLock);
+  KeLeaveCriticalRegion();
+
   DPRINT ("CmiDisconnectHive() done\n");
 
   return STATUS_SUCCESS;
index 0bb1984..4a5ffa8 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "cm.h"
 
+extern LIST_ENTRY CmiKeyObjectListHead;
+extern ULONG CmiTimer;
 
 static NTSTATUS
 CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
@@ -76,10 +78,22 @@ CmiObjectParse(PVOID ParsedObject,
                KeyName.Length);
   KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] = 0;
 
+  /* Acquire hive lock */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
-  FoundObject = CmiScanKeyList(ParsedKey,
-                              &KeyName,
-                              Attributes);
+
+  Status = CmiScanKeyList(ParsedKey,
+                         &KeyName,
+                         Attributes,
+                         &FoundObject);
+  if (!NT_SUCCESS(Status))
+  {
+     ExReleaseResourceLite(&CmiRegistryLock);
+     KeLeaveCriticalRegion();
+     RtlFreeUnicodeString(&KeyName);
+     return Status;
+  }
   if (FoundObject == NULL)
     {
       Status = CmiScanForSubKey(ParsedKey->RegistryHive,
@@ -91,6 +105,8 @@ CmiObjectParse(PVOID ParsedObject,
                                Attributes);
       if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
        {
+          ExReleaseResourceLite(&CmiRegistryLock);
+          KeLeaveCriticalRegion();
          RtlFreeUnicodeString(&KeyName);
          return(STATUS_UNSUCCESSFUL);
        }
@@ -104,6 +120,9 @@ CmiObjectParse(PVOID ParsedObject,
                                    &LinkPath);
          if (NT_SUCCESS(Status))
            {
+              ExReleaseResourceLite(&CmiRegistryLock);
+              KeLeaveCriticalRegion();
+
              DPRINT("LinkPath '%wZ'\n", &LinkPath);
 
              /* build new FullPath for reparsing */
@@ -140,7 +159,7 @@ CmiObjectParse(PVOID ParsedObject,
        }
 
       /* Create new key object and put into linked list */
-      DPRINT("CmiObjectParse: %s\n", Path);
+      DPRINT("CmiObjectParse: %S\n", *Path);
       Status = ObCreateObject(KernelMode,
                              CmiKeyType,
                              NULL,
@@ -152,14 +171,19 @@ CmiObjectParse(PVOID ParsedObject,
                              (PVOID*)&FoundObject);
       if (!NT_SUCCESS(Status))
        {
+          ExReleaseResourceLite(&CmiRegistryLock);
+          KeLeaveCriticalRegion();
          RtlFreeUnicodeString(&KeyName);
          return(Status);
        }
+      /* Add the keep-alive reference */
+      ObReferenceObject(FoundObject);
 
       FoundObject->Flags = 0;
       FoundObject->KeyCell = SubKeyCell;
       FoundObject->KeyCellOffset = BlockOffset;
       FoundObject->RegistryHive = ParsedKey->RegistryHive;
+      InsertTailList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
       RtlpCreateUnicodeString(&FoundObject->Name,
               KeyName.Buffer, NonPagedPool);
       CmiAddKeyToList(ParsedKey, FoundObject);
@@ -179,6 +203,11 @@ CmiObjectParse(PVOID ParsedObject,
          if (NT_SUCCESS(Status))
            {
              DPRINT("LinkPath '%wZ'\n", &LinkPath);
+       
+              ExReleaseResourceLite(&CmiRegistryLock);
+              KeLeaveCriticalRegion();
+
+             ObDereferenceObject(FoundObject);
 
              /* build new FullPath for reparsing */
              TargetPath.MaximumLength = LinkPath.MaximumLength;
@@ -212,13 +241,15 @@ CmiObjectParse(PVOID ParsedObject,
              return(STATUS_REPARSE);
            }
        }
-
-      ObReferenceObjectByPointer(FoundObject,
-                                STANDARD_RIGHTS_REQUIRED,
-                                NULL,
-                                UserMode);
     }
 
+  RemoveEntryList(&FoundObject->ListEntry);
+  InsertHeadList(&CmiKeyObjectListHead, &FoundObject->ListEntry);
+  FoundObject->TimeStamp = CmiTimer;
+
+  ExReleaseResourceLite(&CmiRegistryLock);
+  KeLeaveCriticalRegion();
+
   DPRINT("CmiObjectParse: %s\n", FoundObject->Name);
 
   *Path = EndPtr;
@@ -274,11 +305,16 @@ CmiObjectDelete(PVOID DeletedObject)
 
   ObReferenceObject (ParentKeyObject);
 
+  /* Acquire hive lock */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
   if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
     {
       DPRINT1("Key not found in parent list ???\n");
     }
 
+  RemoveEntryList(&KeyObject->ListEntry);
   RtlFreeUnicodeString(&KeyObject->Name);
 
   if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
@@ -302,6 +338,9 @@ CmiObjectDelete(PVOID DeletedObject)
 
   ObDereferenceObject (ParentKeyObject);
 
+  ExReleaseResourceLite(&CmiRegistryLock);
+  KeLeaveCriticalRegion();
+
   if (KeyObject->NumberOfSubKeys)
     {
       KEBUGCHECK(REGISTRY_ERROR);
@@ -532,11 +571,9 @@ VOID
 CmiAddKeyToList(PKEY_OBJECT ParentKey,
                PKEY_OBJECT NewKey)
 {
-  KIRQL OldIrql;
 
   DPRINT("ParentKey %.08x\n", ParentKey);
 
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
 
   if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
     {
@@ -568,7 +605,6 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
                NULL,
                UserMode);
   NewKey->ParentKey = ParentKey;
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 }
 
 
@@ -576,11 +612,9 @@ NTSTATUS
 CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
 {
   PKEY_OBJECT ParentKey;
-  KIRQL OldIrql;
   DWORD Index;
 
   ParentKey = KeyToRemove->ParentKey;
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
   /* FIXME: If list maintained in alphabetic order, use dichotomic search */
   for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++)
     {
@@ -591,7 +625,6 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
                          &ParentKey->SubKeys[Index + 1],
                          (ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
          ParentKey->NumberOfSubKeys--;
-         KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 
          DPRINT("Dereference parent key: 0x%x\n", ParentKey);
        
@@ -599,25 +632,23 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
          return STATUS_SUCCESS;
        }
     }
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
 
   return STATUS_UNSUCCESSFUL;
 }
 
 
-PKEY_OBJECT
+NTSTATUS
 CmiScanKeyList(PKEY_OBJECT Parent,
               PUNICODE_STRING KeyName,
-              ULONG Attributes)
+              ULONG Attributes,
+              PKEY_OBJECT* ReturnedObject)
 {
   PKEY_OBJECT CurKey;
-  KIRQL OldIrql;
   ULONG Index;
-
+  
   DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
         KeyName, &Parent->Name);
 
-  KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
   /* FIXME: if list maintained in alphabetic order, use dichotomic search */
   for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
     {
@@ -627,8 +658,7 @@ CmiScanKeyList(PKEY_OBJECT Parent,
          if ((KeyName->Length == CurKey->Name.Length)
              && (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
            {
-             KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-             return CurKey;
+             break;
            }
        }
       else
@@ -636,14 +666,26 @@ CmiScanKeyList(PKEY_OBJECT Parent,
          if ((KeyName->Length == CurKey->Name.Length)
              && (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
            {
-             KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-             return CurKey;
+             break;
            }
        }
     }
-  KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-
-  return NULL;
+  
+  if (Index < Parent->NumberOfSubKeys)
+  {
+     if (CurKey->Flags & KO_MARKED_FOR_DELETE)
+     {
+        *ReturnedObject = NULL;
+       return STATUS_UNSUCCESSFUL;
+     }
+     ObReferenceObject(CurKey);
+     *ReturnedObject = CurKey;
+  }
+  else
+  {
+     *ReturnedObject = NULL;
+  }
+  return STATUS_SUCCESS;
 }
 
 
index 4864066..95c5f4c 100644 (file)
@@ -52,10 +52,10 @@ extern long MmSafeCopyFromUser(void *Dest, void *Src, unsigned long NumberOfByte
 
 
 int
-print_insn_i386_att (bfd_vma pc, struct disassemble_info *info);
+print_insn_i386 (bfd_vma pc, struct disassemble_info *info);
 
 int
-KdbPrintDisasm(void* Ignored, const char* fmt, ...)
+KdbpPrintDisasm(void* Ignored, const char* fmt, ...)
 {
   va_list ap;
   static char buffer[256];
@@ -69,46 +69,46 @@ KdbPrintDisasm(void* Ignored, const char* fmt, ...)
 }
 
 int
-KdbNopPrintDisasm(void* Ignored, const char* fmt, ...)
+KdbpNopPrintDisasm(void* Ignored, const char* fmt, ...)
 {
   return(0);
 }
 
 int static
-KdbReadMemory(unsigned int Addr, unsigned char* Data, unsigned int Length, 
-             struct disassemble_info * Ignored)
+KdbpReadMemory(unsigned int Addr, unsigned char* Data, unsigned int Length,
+              struct disassemble_info * Ignored)
 {
   return KdbpSafeReadMemory(Data, (void *)Addr, Length); /* 0 means no error */
 }
 
 void static
-KdbMemoryError(int Status, unsigned int Addr, 
-              struct disassemble_info * Ignored)
+KdbpMemoryError(int Status, unsigned int Addr,
+               struct disassemble_info * Ignored)
 {
 }
 
 void static
-KdbPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored)
+KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored)
 {
   if (!KdbSymPrintAddress((void*)Addr))
     {
-      DbgPrint("<0x%X>", Addr);
+      DbgPrint("<%08x>", Addr);
     }
 }
 
 void static
-KdbNopPrintAddress(unsigned int Addr, struct disassemble_info * Ignored)
+KdbpNopPrintAddress(unsigned int Addr, struct disassemble_info * Ignored)
 {
 }
 
 #include "dis-asm.h"
 
 long
-KdbGetInstLength(unsigned int Address)
+KdbpGetInstLength(unsigned int Address)
 {
   disassemble_info info;
 
-  info.fprintf_func = KdbNopPrintDisasm;
+  info.fprintf_func = KdbpNopPrintDisasm;
   info.stream = NULL;
   info.application_data = NULL;
   info.flavour = bfd_target_unknown_flavour;
@@ -116,9 +116,9 @@ KdbGetInstLength(unsigned int Address)
   info.mach = bfd_mach_i386_i386;
   info.insn_sets = 0;
   info.flags = 0;
-  info.read_memory_func = KdbReadMemory;
-  info.memory_error_func = KdbMemoryError;
-  info.print_address_func = KdbNopPrintAddress;
+  info.read_memory_func = KdbpReadMemory;
+  info.memory_error_func = KdbpMemoryError;
+  info.print_address_func = KdbpNopPrintAddress;
   info.symbol_at_address_func = NULL;
   info.buffer = NULL;
   info.buffer_vma = info.buffer_length = 0;
@@ -126,25 +126,25 @@ KdbGetInstLength(unsigned int Address)
   info.display_endian = BIG_ENDIAN_LITTLE;
   info.disassembler_options = NULL;
 
-  return(print_insn_i386_att(Address, &info));
+  return(print_insn_i386(Address, &info));
 }
 
 long
-KdbDisassemble(unsigned int Address)
+KdbpDisassemble(unsigned int Address, unsigned long IntelSyntax)
 {
   disassemble_info info;
 
-  info.fprintf_func = KdbPrintDisasm;
+  info.fprintf_func = KdbpPrintDisasm;
   info.stream = NULL;
   info.application_data = NULL;
   info.flavour = bfd_target_unknown_flavour;
   info.arch = bfd_arch_i386;
-  info.mach = bfd_mach_i386_i386;
+  info.mach = IntelSyntax ? bfd_mach_i386_i386_intel_syntax : bfd_mach_i386_i386;
   info.insn_sets = 0;
   info.flags = 0;
-  info.read_memory_func = KdbReadMemory;
-  info.memory_error_func = KdbMemoryError;
-  info.print_address_func = KdbPrintAddressInCode;
+  info.read_memory_func = KdbpReadMemory;
+  info.memory_error_func = KdbpMemoryError;
+  info.print_address_func = KdbpPrintAddressInCode;
   info.symbol_at_address_func = NULL;
   info.buffer = NULL;
   info.buffer_vma = info.buffer_length = 0;
@@ -152,7 +152,7 @@ KdbDisassemble(unsigned int Address)
   info.display_endian = BIG_ENDIAN_LITTLE;
   info.disassembler_options = NULL;
 
-  return(print_insn_i386_att(Address, &info));
+  return(print_insn_i386(Address, &info));
 }
 
 /* Print i386 instructions for GDB, the GNU debugger.
@@ -2113,7 +2113,7 @@ print_insn (pc, info)
 #else
   mode_64bit = 0;
   priv.orig_sizeflag = AFLAG | DFLAG;
-  intel_syntax = 0;
+  /*intel_syntax = 0;*/
 #endif
 
   if (intel_syntax)
index 2da6570..cda895a 100644 (file)
@@ -1,29 +1,19 @@
 #include <internal/ke.h>
 #include <internal/i386/segment.h>
 
-       .data
-_KdbEipTemp:
-       .int    0
+.text
 
-       .text
-.globl _KdbEnter       
+.globl _KdbEnter
 _KdbEnter:
-       /*
-        * Record when we are inside the debugger.
-        */
-       incl    _KdbEntryCount
-
-       /*
-        * Save the callers eip.
-        */
-       popl    _KdbEipTemp
-               
        /*
         * Set up a trap frame
         */
+                                /* Ss - space already reserved by return EIP */
+        pushl   %esp            /* Esp */
        pushfl                  /* Eflags */
        pushl   %cs             /* Cs */
-       pushl   _KdbEipTemp     /* Eip */
+       pushl   12(%esp)        /* Eip */
+       movl    %ss, 16(%esp)   /* Save Ss */
        pushl   $0              /* ErrorCode */
        pushl   %ebp            /* Ebp */
        pushl   %ebx            /* Ebx */
@@ -56,34 +46,35 @@ _KdbEnter:
        pushl   $0              /* TempEip */
        pushl   $0              /* TempCs */
        pushl   $0              /* DebugPointer */
-       pushl   $0              /* DebugArgMark */
-       pushl   _KdbEipTemp     /* DebugEip */
+       pushl   $3              /* DebugArgMark (Exception number) */
+       pushl   0x60(%esp)      /* DebugEip */
        pushl   %ebp            /* DebugEbp */
 
-       /*
-        * Push a pointer to the trap frame
-        */
-       pushl   %esp
-
        /*
         * Call KDB
         */
-       call    _KdbInternalEnter
+       movl    %esp, %eax
+       pushl   $1              /* FirstChance */
+       pushl   %eax            /* Push a pointer to the trap frame */
+       pushl   $0              /* Context */
+       pushl   $0              /* PreviousMode (KernelMode) */
+       pushl   $0              /* ExceptionRecord */
+       call    _KdbEnterDebuggerException
 
        /*
-        * Pop the argument
+        * Pop the arguments and unused portions of the trap frame:
+        *   DebugEbp
+        *   DebugEip
+        *   DebugArgMark
+        *   DebugPointer
+        *   TempCs
+        *   TempEip
         */
-       popl    %eax    
+       addl    $(11*4), %esp
 
        /*
-        * Ignore unused portions of the trap frame.
+        * Restore/update debugging registers.
         */
-       popl    %eax            /* DebugEbp */
-       popl    %eax            /* DebugEip */
-       popl    %eax            /* DebugArgMark */
-       popl    %eax            /* DebugPointer */
-       popl    %eax            /* TempCs */
-       popl    %eax            /* TempEip */
        popl    %eax            /* Dr0 */
        movl    %eax, %dr0
        popl    %eax            /* Dr1 */
@@ -113,13 +104,17 @@ _KdbEnter:
        popl    %edi            /* Edi */
        popl    %esi            /* Esi */
        popl    %ebx            /* Ebx */
-       popl    %ebp            /* Ebp */
-       addl    $4, %esp        /* ErrorCode */
 
-       /*
-        * Record when we are in the debugger.
-        */
-       decl    _KdbEntryCount
+        /* Remove SS:ESP from the stack */
+        movl    16(%esp), %ebp
+        movl    %ebp, 24(%esp)
+        movl    12(%esp), %ebp
+        movl    %ebp, 20(%esp)
+        movl    8(%esp), %ebp
+        movl    %ebp, 16(%esp)
+        
+       popl    %ebp            /* Ebp */
+       addl    $12, %esp       /* ErrorCode and SS:ESP */
 
        /*
         * Return to the caller.
@@ -127,5 +122,26 @@ _KdbEnter:
        iret
 
 
+.globl _KdbpStackSwitchAndCall@8
+_KdbpStackSwitchAndCall@8:
+        pushl   %ebp
+        movl    %esp, %ebp
+        
+        movl    0x8(%esp), %eax         /* New stack */
+        movl    0xC(%esp), %ecx         /* Function to call */
+        movl    %esp, %edx              /* Old stack */
+
+        /* Switch stack */
+        movl    %eax, %esp
+        pushl   %edx
+
+        /* Call function */
+        call    *%ecx
+
+        /* Switch back to old stack */
+        popl    %esp
+
+        /* Return */
+        popl    %ebp
+        ret     $8
 
-       
diff --git a/reactos/ntoskrnl/dbg/i386/longjmp.S b/reactos/ntoskrnl/dbg/i386/longjmp.S
new file mode 100644 (file)
index 0000000..1edbaaf
--- /dev/null
@@ -0,0 +1,70 @@
+        .file   "longjmp.S"\r
+/*\r
+ * Copyright (C) 1998, 1999, Jonathan S. Shapiro.\r
+ *\r
+ * This file is part of the EROS Operating System.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2,\r
+ * or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ */\r
+\r
+        /*\r
+         * typedef struct {\r
+         *  unsigned long ebx, esi, edi;\r
+         *  unsigned long ebp;\r
+         *  unsigned long sp;\r
+         *  unsigned long pc;\r
+         * } jmp_buf[1];\r
+         */\r
+        \r
+        /*\r
+         * On entry, the stack to longjmp looks like:\r
+         *\r
+         *     value\r
+         *     ptr to jmp_buf\r
+         *     return PC\r
+         */\r
+\r
+.globl _longjmp\r
+_longjmp:\r
+        pushl   %ebp\r
+        movl    %esp,%ebp\r
+\r
+        movl    8(%ebp),%ecx            /* address of jmp_buf to ecx */\r
+        movl    12(%ebp),%eax           /* return value to %eax */\r
+        testl   %eax,%eax\r
+        jne     1f\r
+        incl    %eax                    /* return 1 if handed 0 */\r
+\r
+1:      \r
+        movl    (%ecx),%ebx             /* restore %ebx */\r
+        movl    4(%ecx),%esi            /* restore %esi */\r
+        movl    8(%ecx),%edi            /* restore %edi */\r
+        \r
+        /*\r
+         * From this instant on we are not running in a valid frame\r
+         */\r
+        \r
+        movl    12(%ecx),%ebp           /* restore %ebp */\r
+        movl    16(%ecx),%esp           /* restore %esp */\r
+        /* movl 20(%ecx),%eax           return PC */\r
+\r
+        /*\r
+         * Since we are abandoning the stack in any case, \r
+         * there isn't much point in doing the usual return \r
+         * discipline.\r
+         */\r
+        \r
+        jmpl    *20(%ecx)\r
+       \r
diff --git a/reactos/ntoskrnl/dbg/i386/setjmp.S b/reactos/ntoskrnl/dbg/i386/setjmp.S
new file mode 100644 (file)
index 0000000..d53e059
--- /dev/null
@@ -0,0 +1,59 @@
+        .file   "setjmp.S"\r
+/*\r
+ * Copyright (C) 1998, 1999, Jonathan S. Shapiro.\r
+ *\r
+ * This file is part of the EROS Operating System.\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2,\r
+ * or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+ */\r
+\r
+/* #include <eros/i486/asm.h> */\r
+        \r
+        \r
+        /*\r
+         * typedef struct {\r
+         *  unsigned long ebx, esi, edi;\r
+         *  unsigned long ebp;\r
+         *  unsigned long sp;\r
+         *  unsigned long pc;\r
+         * } jmp_buf[1];\r
+         */\r
+        \r
+        /*\r
+         * On entry, the stack to setjmp looks like:\r
+         *\r
+         *     ptr to jmp_buf\r
+         *     return PC\r
+         */\r
+.globl _setjmp\r
+_setjmp:       \r
+        pushl   %ebp\r
+        movl    %esp,%ebp\r
+        \r
+        movl    0x8(%ebp),%eax          /* address of jmp_buf to eax */\r
+        movl    %ebx,(%eax)             /* save %ebx */\r
+        movl    %esi,4(%eax)            /* save %esi */\r
+        movl    %edi,8(%eax)            /* save %edi */\r
+        leal    8(%ebp),%edx            /* calling proc's esp, not ours! */\r
+        movl    %edx,16(%eax)\r
+        movl    4(%ebp), %edx           /* save return PC */\r
+        movl    %edx,20(%eax)\r
+        movl    0(%ebp),%edx            /* calling proc's ebp, not ours! */\r
+        movl    %edx,12(%eax)\r
+\r
+        xorl    %eax,%eax               /* return 0 the first time */\r
+        leave\r
+        ret    $4\r
+\r
index fa97e88..f6a0863 100644 (file)
 
 #include <ntoskrnl.h>
 #include "kdb.h"
-#include "kjs.h"
 #define NDEBUG
 #include <internal/debug.h>
 
 /* TYPES *********************************************************************/
 
-/* GLOBALS *******************************************************************/
-
-#define BS 8
-#define DEL 127
-
-BOOL KbdEchoOn = TRUE;
-
-typedef struct
-{
-  BOOLEAN Enabled;
-  BOOLEAN Temporary;
-  BOOLEAN Assigned;
-  ULONG Address;
-  UCHAR SavedInst;
-} KDB_ACTIVE_BREAKPOINT;
+/* DEFINES *******************************************************************/
 
-#define KDB_MAXIMUM_BREAKPOINT_COUNT (255)
+#define KDB_STACK_SIZE                   (4096*3)
+#define KDB_MAXIMUM_BREAKPOINT_COUNT     256
+#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT  4
+#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT  256
 
-static ULONG KdbBreakPointCount = 0;
-static KDB_ACTIVE_BREAKPOINT 
- KdbActiveBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT];
+#define __STRING(x) #x
+#define _STRING(x) __STRING(x)
 
-static BOOLEAN KdbHandleUmode = FALSE;
-static BOOLEAN KdbHandleHandled = FALSE;
-static BOOLEAN KdbBreakOnModuleLoad = FALSE;
-
-static BOOLEAN KdbIgnoreNextSingleStep = FALSE;
-static ULONG KdbLastSingleStepFrom = 0xFFFFFFFF;
-static BOOLEAN KdbEnteredOnSingleStep = FALSE;
-
-ULONG KdbEntryCount = 0;
+/* GLOBALS *******************************************************************/
 
-int isalpha( int );
-VOID
-PsDumpThreads(BOOLEAN System);
-ULONG 
-DbgContCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG 
-DbgStopCondition(ULONG Aargc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgModuleLoadedAction(ULONG Aargc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgEchoToggle(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG 
-DbgRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG 
-DbgDRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG 
-DbgCRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG 
-DbgBugCheckCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgBackTraceCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgAddrCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgXCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgScriptCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgThreadListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgProcessListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgProcessHelpCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgShowFilesCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgEnableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDisableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDisassemble(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgSetBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgDeleteBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgSetMemoryBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgStep(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgStepOver(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-ULONG
-DbgFinish(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-
-struct
+STATIC LONG KdbEntryCount = 0;
+STATIC CHAR KdbStack[KDB_STACK_SIZE];
+
+STATIC ULONG KdbBreakPointCount = 0;  /* Number of used breakpoints in the array */
+STATIC KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT] = {{0}};  /* Breakpoint array */
+STATIC ULONG KdbSwBreakPointCount = 0;  /* Number of enabled software breakpoints */
+STATIC ULONG KdbHwBreakPointCount = 0;  /* Number of enabled hardware breakpoints */
+STATIC PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]; /* Enabled software breakpoints, orderless */
+STATIC PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]; /* Enabled hardware breakpoints, orderless */
+STATIC PKDB_BREAKPOINT KdbBreakPointToReenable = NULL; /* Set to a breakpoint struct when single stepping after
+                                                          a software breakpoint was hit, to reenable it */
+LONG KdbLastBreakPointNr = -1;  /* Index of the breakpoint which cause KDB to be entered */
+ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
+BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
+
+STATIC BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB was entered because of single step */
+PEPROCESS KdbCurrentProcess = NULL;  /* The current process context in which KDB runs */
+PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was intered */
+PETHREAD KdbCurrentThread = NULL;  /* The current thread context in which KDB runs */
+PETHREAD KdbOriginalThread = NULL; /* The thread in whichs context KDB was entered */
+PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL; /* Pointer to the current trapframe */
+STATIC KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } };  /* The trapframe which was passed to KdbEnterDebuggerException */
+STATIC KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }; /* The trapframe of the current thread (KdbCurrentThread) */
+STATIC KAPC_STATE KdbApcState;
+
+/* Array of conditions when to enter KDB */
+STATIC KDB_ENTER_CONDITION KdbEnterConditions[][2] =
 {
-  PCH Name;
-  PCH Syntax;
-  PCH Help;
-  ULONG (*Fn)(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf);
-} DebuggerCommands[] = {
-  {"cont", "cont", "Exit the debugger", DbgContCommand},
-  {"echo", "echo", "Toggle serial echo", DbgEchoToggle},
-  {"condition", "condition [all|umode|kmode]", "Kdbg enter condition", DbgStopCondition},
-  {"module-loaded", "module-loaded [break|continue]", "Module-loaded action", DbgModuleLoadedAction},
-
-  {"regs", "regs", "Display general purpose registers", DbgRegsCommand},
-  {"dregs", "dregs", "Display debug registers", DbgDRegsCommand},
-  {"cregs", "cregs", "Display control registers", DbgCRegsCommand},
-  {"bugcheck", "bugcheck", "Bugcheck the system", DbgBugCheckCommand},
-  {"bt", "bt [*frame-address]|[thread-id]","Do a backtrace", DbgBackTraceCommand},
-  {"addr", "addr <address>", "Displays symbol info", DbgAddrCommand},
-  {"x", "x <addr> <words>", "Displays <addr> for <words>", DbgXCommand},
-  {"plist", "plist", "Display processes in the system", DbgProcessListCommand},
-  {"tlist", "tlist [sys]", "Display threads in the system", DbgThreadListCommand},
-  {"sfiles", "sfiles", "Show files that print debug prints", DbgShowFilesCommand},
-  {"efile", "efile <filename>", "Enable debug prints from file", DbgEnableFileCommand},
-  {"dfile", "dfile <filename>", "Disable debug prints from file", DbgDisableFileCommand},
-  {"js", "js", "Script mode", DbgScriptCommand},
-  {"disasm", "disasm <address>", "Disables 10 instructions at <address> or "
-   "eip", DbgDisassemble},
-  {"bp", "bp <address>", "Sets an int3 breakpoint at a given address",
-   DbgSetBreakPoint},
-  {"bc", "bc <breakpoint number>", "Deletes a breakpoint",
-   DbgDeleteBreakPoint},
-  {"ba", "ba <debug register> <access type> <length> <address>", 
-   "Sets a breakpoint using a debug register", DbgSetMemoryBreakPoint},
-  {"t", "t", "Steps forward a single instructions", DbgStep},
-  {"p", "p", "Steps forward a single instructions skipping calls", 
-   DbgStepOver},
-  {"finish", "finish", "Runs until the current function exits", DbgFinish},
-  {"help", "help", "Display help screen", DbgProcessHelpCommand},
-  {NULL, NULL, NULL}
+   /* First chance       Last chance */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* Zero devide */
+   { KdbEnterAlways,     KdbDoNotEnter },       /* Debug trap */
+   { KdbDoNotEnter,      KdbEnterAlways },      /* NMI */
+   { KdbEnterFromKmode,  KdbDoNotEnter },       /* INT3 */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* Overflow */
+   { KdbDoNotEnter,      KdbEnterFromKmode },
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* Invalid opcode */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* No math coprocessor fault */
+   { KdbEnterAlways,     KdbEnterAlways },
+   { KdbEnterAlways,     KdbEnterAlways },
+   { KdbDoNotEnter,      KdbEnterFromKmode },
+   { KdbDoNotEnter,      KdbEnterFromKmode },
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* Stack fault */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* General protection fault */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* Page fault */
+   { KdbEnterAlways,     KdbEnterAlways },      /* Reserved (15) */
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* FPU fault */
+   { KdbDoNotEnter,      KdbEnterFromKmode },
+   { KdbDoNotEnter,      KdbEnterFromKmode },
+   { KdbDoNotEnter,      KdbEnterFromKmode },   /* SIMD fault */
+   { KdbDoNotEnter,      KdbEnterFromKmode }    /* Last entry: used for unknown exceptions */
 };
 
-static const char *ExceptionTypeStrings[] =
-  {
-    "Divide Error",
-    "Debug Trap",
-    "NMI",
-    "Breakpoint",
-    "Overflow",
-    "BOUND range exceeded",
-    "Invalid Opcode",
-    "No Math Coprocessor",
-    "Double Fault",
-    "Unknown(9)",
-    "Invalid TSS",
-    "Segment Not Present",
-    "Stack Segment Fault",
-    "General Protection",
-    "Page Fault",
-    "Reserved(15)",
-    "Math Fault",
-    "Alignment Check",
-    "Machine Check",
-    "SIMD Fault"
-  };
-
-volatile DWORD x_dr0 = 0, x_dr1 = 0, x_dr2 = 0, x_dr3 = 0, x_dr7 = 0;
-
-extern LONG KdbDisassemble(ULONG Address);
-extern LONG KdbGetInstLength(ULONG Address);
+/* Exception descriptions */
+STATIC CONST PCHAR ExceptionNrToString[] =
+{
+   "Divide Error",
+   "Debug Trap",
+   "NMI",
+   "Breakpoint",
+   "Overflow",
+   "BOUND range exceeded",
+   "Invalid Opcode",
+   "No Math Coprocessor",
+   "Double Fault",
+   "Unknown(9)",
+   "Invalid TSS",
+   "Segment Not Present",
+   "Stack Segment Fault",
+   "General Protection",
+   "Page Fault",
+   "Reserved(15)",
+   "Math Fault",
+   "Alignment Check",
+   "Machine Check",
+   "SIMD Fault"
+};
 
 /* FUNCTIONS *****************************************************************/
 
-/*
- * Convert a string to an unsigned long integer.
+/*!\brief Overwrites the instruction at \a Address with \a NewInst and stores
+ *        the old instruction in *OldInst.
+ *
+ * \param Process  Process in which's context to overwrite the instruction.
+ * \param Address  Address at which to overwrite the instruction.
+ * \param NewInst  New instruction (written to \a Address)
+ * \param OldInst  Old instruction (read from \a Address)
  *
- * Ignores `locale' stuff.  Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
+ * \returns NTSTATUS
  */
-unsigned long
-strtoul(const char *nptr, char **endptr, int base)
+STATIC NTSTATUS
+KdbpOverwriteInstruction(
+   IN  PEPROCESS Process,
+   IN  ULONG_PTR Address,
+   IN  UCHAR NewInst,
+   OUT PUCHAR OldInst  OPTIONAL)
 {
-  const char *s = nptr;
-  unsigned long acc;
-  int c;
-  unsigned long cutoff;
-  int neg = 0, any, cutlim;
-
-  /*
-   * See strtol for comments as to the logic used.
-   */
-  do {
-    c = *s++;
-  } while (isspace(c));
-  if (c == '-')
-  {
-    neg = 1;
-    c = *s++;
-  }
-  else if (c == '+')
-    c = *s++;
-  if ((base == 0 || base == 16) &&
-      c == '0' && (*s == 'x' || *s == 'X'))
-  {
-    c = s[1];
-    s += 2;
-    base = 16;
-  }
-  if (base == 0)
-    base = c == '0' ? 8 : 10;
-  cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
-  cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
-  for (acc = 0, any = 0;; c = *s++)
-  {
-    if (isdigit(c))
-      c -= '0';
-    else if (isalpha(c))
-      c -= isupper(c) ? 'A' - 10 : 'a' - 10;
-    else
-      break;
-    if (c >= base)
-      break;
-    if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
-      any = -1;
-    else {
-      any = 1;
-      acc *= base;
-      acc += c;
-    }
-  }
-  if (any < 0)
-  {
-    acc = ULONG_MAX;
-  }
-  else if (neg)
-    acc = -acc;
-  if (endptr != 0)
-    *endptr = any ? (char *)s - 1 : (char *)nptr;
-  return acc;
-}
+   NTSTATUS Status;
+   ULONG Protect;
+   PEPROCESS CurrentProcess = PsGetCurrentProcess();
+   KAPC_STATE ApcState;
 
+   /* Get the protection for the address. */
+   Protect = MmGetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address));
+   
+   /* Return if that page isn't present. */
+   if (Protect & PAGE_NOACCESS)
+   {
+      return STATUS_MEMORY_NOT_ALLOCATED;
+   }
+   
+   /* Attach to the process */
+   if (CurrentProcess != Process)
+   {
+      KeStackAttachProcess(EPROCESS_TO_KPROCESS(Process), &ApcState);
+   }
+
+   /* Make the page writeable if it is read only. */
+   if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+   {
+      MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address),
+                      (Protect & ~(PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ)) | PAGE_READWRITE);
+   }
+   
+   /* Copy the old instruction back to the caller. */
+   if (OldInst != NULL)
+   {
+      Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
+      if (!NT_SUCCESS(Status))
+      {
+         if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+         {
+            MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
+         }
+         /* Detach from process */
+         if (CurrentProcess != Process)
+         {
+            KeDetachProcess();
+         }
+        return Status;
+      }
+   }
+   
+   /* Copy the new instruction in its place. */
+   Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
+   
+   /* Restore the page protection. */
+   if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
+   {
+      MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
+   }
+   
+   /* Detach from process */
+   if (CurrentProcess != Process)
+   {
+      KeUnstackDetachProcess(&ApcState);
+   }
 
-char*
-strpbrk(const char* s, const char* accept)
-{
-  int i;
-  for (; (*s) != 0; s++)
-    {
-      for (i = 0; accept[i] != 0; i++)
-       {
-         if (accept[i] == (*s))
-           {
-             return((char *)s);
-           }
-       }
-    }
-  return(NULL);
+   return Status;
 }
 
-
-#if 0
-NTSTATUS
-KdbpSafeReadMemory(PVOID dst, PVOID src, INT size)
+/*!\brief Checks whether the given instruction can be single stepped or has to be
+ *        stepped over using a temporary breakpoint.
+ *
+ * \retval TRUE   Instruction is a call.
+ * \retval FALSE  Instruction is not a call.
+ */
+BOOLEAN
+KdbpShouldStepOverInstruction(ULONG_PTR Eip)
 {
-  INT page, page_end;
-  
-  /* check source */
-  page_end = (((ULONG_PTR)src + size) / PAGE_SIZE);
-  for (page = ((ULONG_PTR)src / PAGE_SIZE); page <= page_end; page++)
-  {
-    if (!MmIsPagePresent(NULL, (PVOID)(page * PAGE_SIZE)))
-      return STATUS_UNSUCCESSFUL;
-  }
+   UCHAR Mem[3];
+   INT i = 0;
 
-  /* copy memory */
-  RtlCopyMemory(dst, src, size);
-  return STATUS_SUCCESS;
-}
+   if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+   {
+      KdbpPrint("Couldn't access memory at 0x%x\n", (UINT)Eip);
+      return FALSE;
+   }
 
+   /* Check if the current instruction is a call. */
+   while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
+      i++;
+   if (i == sizeof (Mem))
+      return FALSE;
+   if (Mem[i] == 0xE8 || Mem[i] == 0x9A || Mem[i] == 0xF2 || Mem[i] == 0xF3 ||
+       (((i + 1) < sizeof (Mem)) && Mem[i] == 0xFF && (Mem[i+1] & 0x38) == 0x10))
+   {
+      return TRUE;
+   }
+   return FALSE;
+}
 
-NTSTATUS
-KdbpSafeWriteMemory(PVOID dst, PVOID src, INT size)
+/*!\brief Steps over an instruction
+ *
+ * If the given instruction should be stepped over, this function inserts a
+ * temporary breakpoint after the instruction and returns TRUE, otherwise it
+ * returns FALSE.
+ *
+ * \retval TRUE   Temporary breakpoint set after instruction.
+ * \retval FALSE  No breakpoint was set.
+ */
+BOOLEAN
+KdbpStepOverInstruction(ULONG_PTR Eip)
 {
-  return KdbpSafeWriteMemory(dst, src, size);
-  INT page, page_end;
-
-  /* check destination */
-  page_end = (((ULONG_PTR)dst + size) / PAGE_SIZE);
-  for (page = ((ULONG_PTR)dst / PAGE_SIZE); page <= page_end; page++)
-  {
-    if (!MmIsPagePresent(NULL, (PVOID)(page * PAGE_SIZE)))
-      return STATUS_UNSUCCESSFUL;
-  }
+   LONG InstLen;
 
-  /* copy memory */
-  RtlCopyMemory(dst, src, size);
-  return STATUS_SUCCESS;
-}
-#endif /* unused */
+   if (!KdbpShouldStepOverInstruction(Eip))
+      return FALSE;
 
+   InstLen = KdbpGetInstLength(Eip);
+   if (InstLen < 1)
+      return FALSE;
 
-VOID
-KdbGetCommand(PCH Buffer)
-{
-  CHAR Key;
-  PCH Orig = Buffer;
-  static CHAR LastCommand[256] = "";
-  ULONG ScanCode = 0;
-  static CHAR LastKey = '\0';
-  
-  KbdEchoOn = !((KdDebugState & KD_DEBUG_KDNOECHO) != 0);
-  
-  for (;;)
-    {
-      if (KdDebugState & KD_DEBUG_KDSERIAL)
-       while ((Key = KdbTryGetCharSerial()) == -1);
-      else
-       while ((Key = KdbTryGetCharKeyboard(&ScanCode)) == -1);
-
-      if (Key == '\n' && LastKey == '\r')
-        {
-          /* Ignore this key... */
-        }
-      else if (Key == '\r' || Key == '\n')
-       {
-         DbgPrint("\n");
-         /*
-           Repeat the last command if the user presses enter. Reduces the
-           risk of RSI when single-stepping.
-         */
-         if (Buffer == Orig)
-           {
-             strcpy(Buffer, LastCommand);
-           }
-         else
-           {
-             *Buffer = 0;
-             strcpy(LastCommand, Orig);
-           }
-         LastKey = Key;
-         return;
-       }
-      else if (Key == BS || Key == DEL)
-        {
-          if (Buffer > Orig)
-            {
-              Buffer--;
-              *Buffer = 0;
-             if (KbdEchoOn)
-               DbgPrint("%c %c", BS, BS);
-             else
-               DbgPrint(" %c", BS);
-           }
-        }
-      else if (ScanCode == 72)
-       {
-         ULONG i;
-         while (Buffer > Orig)
-           {
-             Buffer--;
-             *Buffer = 0;
-             if (KbdEchoOn)
-               DbgPrint("%c %c", BS, BS);
-             else
-               DbgPrint(" %c", BS);
-           }
-         for (i = 0; LastCommand[i] != 0; i++)
-           {
-             if (KbdEchoOn)
-               DbgPrint("%c", LastCommand[i]);
-             *Buffer = LastCommand[i];
-             Buffer++;
-           }
-       }
-      else
-        {
-         if (KbdEchoOn)
-           DbgPrint("%c", Key);
-
-          *Buffer = Key;
-          Buffer++;
-        }
-      LastKey = Key;
-    }
+   if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+      return FALSE;
+
+   return TRUE;
 }
 
-BOOLEAN STATIC
-KdbDecodeAddress(PCHAR Buffer, PULONG Address)
+/*!\brief Steps into an instruction (interrupts)
+ *
+ * If the given instruction should be stepped into, this function inserts a
+ * temporary breakpoint at the target instruction and returns TRUE, otherwise it
+ * returns FALSE.
+ *
+ * \retval TRUE   Temporary breakpoint set at target instruction.
+ * \retval FALSE  No breakpoint was set.
+ */
+BOOLEAN
+KdbpStepIntoInstruction(ULONG_PTR Eip)
 {
-  while (isspace(*Buffer))
-    {
-      Buffer++;
-    }
-  if (Buffer[0] == '<')
-    {
-      PCHAR ModuleName = Buffer + 1;
-      PCHAR AddressString = strpbrk(Buffer, ":");
-      extern LIST_ENTRY ModuleTextListHead;
-      PLIST_ENTRY current_entry;
-      MODULE_TEXT_SECTION* current = NULL;
-      static WCHAR ModuleNameW[256];
-      ULONG i;
-
-      if (AddressString == NULL)
-       {
-         DbgPrint("Address %x is malformed.\n", Buffer);
-         return(FALSE);
-       }
-      *AddressString = 0;
-      AddressString++;
-      while (isspace(*AddressString))
-       {
-         AddressString++;
-       }
-
-      for (i = 0; ModuleName[i] != 0 && !isspace(ModuleName[i]); i++)
-       {
-         ModuleNameW[i] = (WCHAR)ModuleName[i];
-       }
-      ModuleNameW[i] = 0;
-
-      /* Find the module. */
-      current_entry = ModuleTextListHead.Flink;
+   struct __attribute__((packed)) {
+      USHORT Limit;
+      ULONG Base;
+   } Idtr;
+   UCHAR Mem[2];
+   INT IntVect;
+   ULONG IntDesc[2];
+   ULONG_PTR TargetEip;
+
+   /* Read memory */
+   if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
+   {
+      /*KdbpPrint("Couldn't access memory at 0x%x\n", (UINT)Eip);*/
+      return FALSE;
+   }
+
+   /* Check for INT instruction */
+   /* FIXME: Check for iret */
+   if (Mem[0] == 0xcc)
+      IntVect = 3;
+   else if (Mem[0] == 0xcd)
+      IntVect = Mem[1];
+   else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.Eflags & (1<<11)) /* 1 << 11 is the overflow flag */
+      IntVect = 4;
+   else
+      return FALSE;
+
+   if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
+   {
+      return FALSE;
+   }
+
+   /* Read the interrupt descriptor table register  */
+   asm volatile("sidt %0" : : "m"(Idtr));
+   if (IntVect >= (Idtr.Limit + 1) / 8)
+   {
+      /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
+      return TRUE;
+   }
+
+   /* Get the interrupt descriptor */
+   if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
+   {
+      /*KdbpPrint("Couldn't access memory at 0x%x\n", (UINT)Idtr.Base + (IntVect * 8));*/
+      return FALSE;
+   }
    
-      while (current_entry != &ModuleTextListHead &&
-            current_entry != NULL)
-       {
-         current = 
-           CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
-         if (wcscmp(ModuleNameW, current->Name) == 0)
-           {
-             break;
-           }
-         current_entry = current_entry->Flink;
-       }
-      if (current_entry == NULL || current_entry == &ModuleTextListHead)
-       {
-         DbgPrint("Couldn't find module %s.\n", ModuleName);
-         return(FALSE);
-       }
-      *Address = current->Base;
-      *Address += strtoul(AddressString, NULL, 16);
-      return(TRUE);
-    }
-  else
-    {
-      *Address = strtoul(Buffer, NULL, 0);
-      return(TRUE);
-    }
+   /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
+   if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
+   {
+      return FALSE;
+   }
+   if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
+   {
+      /* FIXME: Task gates not supported */
+      return FALSE;
+   }
+   else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
+            ((IntDesc[1] & 0x1fe0) == 0x0f00))   /* 32 bit Trap gate */
+   {
+      /* FIXME: Should the segment selector of the interrupt gate be checked? */
+      TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
+   }
+   else
+   {
+      return FALSE;
+   }
+
+   /* Insert breakpoint */
+   if (!NT_SUCCESS(KdbpInsertBreakPoint(TargetEip, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
+      return FALSE;
+
+   return TRUE;
 }
 
-NTSTATUS STATIC
-KdbOverwriteInst(ULONG Address, PUCHAR PreviousInst, UCHAR NewInst)
+/*!\brief Gets the number of the next breakpoint >= Start.
+ *
+ * \param Start   Breakpoint number to start searching at. -1 if no more breakpoints are found.
+ *
+ * \returns Breakpoint number (-1 if no more breakpoints are found)
+ */
+LONG
+KdbpGetNextBreakPointNr(
+   IN ULONG Start  OPTIONAL)
 {
-  NTSTATUS Status;
-  ULONG Protect;
-  /* Get the protection for the address. */
-  Protect = MmGetPageProtect(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
-  /* Return if that page isn't present. */
-  if (Protect & PAGE_NOACCESS)
-    {
-      return(STATUS_MEMORY_NOT_ALLOCATED);
-    }
-  if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
-    {
-      MmSetPageProtect(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address), 
-                      (Protect & ~(PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ)) | PAGE_READWRITE);
-    }
-  /* Copy the old instruction back to the caller. */
-  if (PreviousInst != NULL)
-    {
-      Status = KdbpSafeReadMemory(PreviousInst, (PUCHAR)Address, 1);
-      if (!NT_SUCCESS(Status))
-           {
-          if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
-            {
-              MmSetPageProtect(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address), Protect);
-            }
-             return(Status);
-           }
-    }
-  /* Copy the new instruction in its place. */
-  Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
-  if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
-    {
-      MmSetPageProtect(PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address), Protect);
-    }
-  return Status;
+   for (; Start < RTL_NUMBER_OF(KdbBreakPoints); Start++)
+   {
+      if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
+         return Start;
+   }
+   return -1;
 }
 
-
-VOID STATIC
-KdbRenableBreakPoints(VOID)
+/*!\brief Returns information of the specified breakpoint.
+ *
+ * \param BreakPointNr         Number of the breakpoint to return information of.
+ * \param Address              Receives the address of the breakpoint.
+ * \param Type                 Receives the type of the breakpoint (hardware or software)
+ * \param Size                 Size - for memory breakpoints.
+ * \param AccessType           Access type - for hardware breakpoints.
+ * \param DebugReg             Debug register - for enabled hardware breakpoints.
+ * \param Enabled              Whether the breakpoint is enabled or not.
+ * \param Process              The owning process of the breakpoint.
+ * \param ConditionExpression  The expression which was given as condition for the bp.
+ *
+ * \returns NULL on failure, pointer to a KDB_BREAKPOINT struct on success.
+ */
+BOOLEAN
+KdbpGetBreakPointInfo(
+   IN  ULONG BreakPointNr,
+   OUT ULONG_PTR *Address  OPTIONAL,
+   OUT KDB_BREAKPOINT_TYPE *Type  OPTIONAL,
+   OUT UCHAR *Size  OPTIONAL,
+   OUT KDB_ACCESS_TYPE *AccessType  OPTIONAL,
+   OUT UCHAR *DebugReg  OPTIONAL,
+   OUT BOOLEAN *Enabled  OPTIONAL,
+   OUT BOOLEAN *Global  OPTIONAL,
+   OUT PEPROCESS *Process  OPTIONAL,
+   OUT PCHAR *ConditionExpression  OPTIONAL)
 {
-  ULONG i;
-  for (i = 0; i < KDB_MAXIMUM_BREAKPOINT_COUNT; i++)
-    {
-      if (KdbActiveBreakPoints[i].Assigned &&
-         !KdbActiveBreakPoints[i].Enabled)
-       {
-         KdbActiveBreakPoints[i].Enabled = TRUE;
-         (VOID)KdbOverwriteInst(KdbActiveBreakPoints[i].Address,
-                                &KdbActiveBreakPoints[i].SavedInst, 
-                                0xCC);
-       }
-    }
-}
+   PKDB_BREAKPOINT bp;
 
-LONG STATIC
-KdbIsBreakPointOurs(PKTRAP_FRAME Tf)
-{
-  ULONG i;
-  for (i = 0; i < KDB_MAXIMUM_BREAKPOINT_COUNT; i++)
-    {
-      if (KdbActiveBreakPoints[i].Assigned &&
-         KdbActiveBreakPoints[i].Address == (Tf->Eip - 1))
-       {
-         return(i);
-       }
-    }
-  return(-1);
+   if (BreakPointNr >= RTL_NUMBER_OF(KdbBreakPoints) ||
+       KdbBreakPoints[BreakPointNr].Type == KdbBreakPointNone)
+   {
+      return FALSE;
+   }
+   
+   bp = KdbBreakPoints + BreakPointNr;
+   if (Address != NULL)
+      *Address = bp->Address;
+   if (Type != NULL)
+      *Type = bp->Type;
+   if (bp->Type == KdbBreakPointHardware)
+   {
+      if (Size != NULL)
+         *Size = bp->Data.Hw.Size;
+      if (AccessType != NULL)
+         *AccessType = bp->Data.Hw.AccessType;
+      if (DebugReg != NULL && bp->Enabled)
+         *DebugReg = bp->Data.Hw.DebugReg;
+   }
+   if (Enabled != NULL)
+      *Enabled = bp->Enabled;
+   if (Global != NULL)
+      *Global = bp->Global;
+   if (Process != NULL)
+      *Process = bp->Process;
+   if (ConditionExpression != NULL)
+      *ConditionExpression = bp->ConditionExpression;
+
+   return TRUE;
 }
 
-VOID STATIC
-KdbDeleteBreakPoint(ULONG BreakPointNr)
+/*!\brief Inserts a breakpoint into the breakpoint array.
+ *
+ * The \a Process of the breakpoint is set to \a KdbCurrentProcess
+ *
+ * \param Address              Address at which to set the breakpoint.
+ * \param Type                 Type of breakpoint (hardware or software)
+ * \param Size                 Size of breakpoint (for hardware/memory breakpoints)
+ * \param AccessType           Access type (for hardware breakpoins)
+ * \param ConditionExpression  Expression which must evaluate to true for conditional breakpoints.
+ * \param Global               Wether the breakpoint is global or local to a process.
+ * \param BreakPointNumber     Receives the breakpoint number on success
+ *
+ * \returns NTSTATUS
+ */
+NTSTATUS
+KdbpInsertBreakPoint(
+   IN  ULONG_PTR Address,
+   IN  KDB_BREAKPOINT_TYPE Type,
+   IN  UCHAR Size  OPTIONAL,
+   IN  KDB_ACCESS_TYPE AccessType  OPTIONAL,
+   IN  PCHAR ConditionExpression  OPTIONAL,
+   IN  BOOLEAN Global,
+   OUT PULONG BreakPointNumber  OPTIONAL)
 {
-  KdbBreakPointCount--;
-  KdbActiveBreakPoints[BreakPointNr].Assigned = FALSE;
-}
+   LONG i;
+   PVOID Condition;
+   PCHAR ConditionExpressionDup;
+   LONG ErrOffset;
+   CHAR ErrMsg[128];
 
-NTSTATUS STATIC
-KdbInsertBreakPoint(ULONG Address, BOOLEAN Temporary)
-{
-  NTSTATUS Status;
-  UCHAR SavedInst;
-  ULONG i;  
-  if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-  for (i = 0; i < KDB_MAXIMUM_BREAKPOINT_COUNT; i++)
-    {
-      if (!KdbActiveBreakPoints[i].Assigned)
-       {
-         break;
-       }
-    }
-  Status = KdbOverwriteInst(Address, &SavedInst, 0xCC);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-  KdbActiveBreakPoints[i].Assigned = TRUE;
-  KdbActiveBreakPoints[i].Enabled = TRUE;
-  KdbActiveBreakPoints[i].Address = Address;
-  KdbActiveBreakPoints[i].Temporary = Temporary;
-  KdbActiveBreakPoints[i].SavedInst = SavedInst;
-  return(STATUS_SUCCESS);
-}
+   ASSERT(Type != KdbBreakPointNone);
 
-ULONG
-DbgSetBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  ULONG Addr;
-  NTSTATUS Status;
-  ULONG i;
-  if (Argc < 2)
-    {
-      DbgPrint("Need an address to set the breakpoint at.\n");
-      return(1);
-    }
-  /* Stitch the remaining arguments back into a single string. */
-  for (i = 2; i < Argc; i++)
-    {
-      Argv[i][-1] = ' ';
-    }
-  if (!KdbDecodeAddress(Argv[1], &Addr))
-    {
-      return(1);
-    }
-  DbgPrint("Setting breakpoint at 0x%X\n", Addr);
-  if (!NT_SUCCESS(Status = KdbInsertBreakPoint(Addr, FALSE)))
-    {
-      DbgPrint("Failed to set breakpoint (Status %X)\n", Status);
-    }
-  return(1);
-}
+   if (Type == KdbBreakPointHardware)
+   {
+      if ((Address % Size) != 0)
+      {
+         KdbpPrint("Address (0x%x) must be aligned to a multiple of the size (%d)\n", Address, Size);
+         return STATUS_UNSUCCESSFUL;
+      }
+      if (AccessType == KdbAccessExec && Size != 1)
+      {
+         KdbpPrint("Size must be 1 for execution breakpoints.\n");
+         return STATUS_UNSUCCESSFUL;
+      }
+   }
 
-ULONG
-DbgDeleteBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  ULONG BreakPointNr;
-  if (Argc != 2)
-    {
-      DbgPrint("Need a breakpoint number to delete.\n");
-      return(1);
-    }  
-  BreakPointNr = strtoul(Argv[1], NULL, 10);
-  DbgPrint("Deleting breakpoint %d.\n", BreakPointNr);
-  KdbDeleteBreakPoint(BreakPointNr);
-  return(1);
-}
+   if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT)
+   {
+      return STATUS_UNSUCCESSFUL;
+   }
+   
+   /* Parse conditon expression string and duplicate it */
+   if (ConditionExpression != NULL)
+   {
+      Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
+      if (Condition == NULL)
+      {
+         if (ErrOffset >= 0)
+            KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
+         else
+            KdbpPrint("Couldn't parse expression: %s", ErrMsg);
+         return STATUS_UNSUCCESSFUL;
+      }
 
-ULONG
-DbgSetMemoryBreakPoint(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  ULONG DebugRegNr;
-  UCHAR BreakType;
-  ULONG Length, Address;
-  ULONG Rw = 0;
-  ULONG i;
-  if (Argc != 2 && Argc < 5)
-    {
-      DbgPrint("ba <0-3> <r|w|e> <1|2|4> <address>\n");
-      return(1);
-    }
-  DebugRegNr = strtoul(Argv[1], NULL, 10);
-  if (DebugRegNr >= 4)
-    {
-      DbgPrint("Debug register number should be between 0 and 3.\n");
-      return(1);
-    }
-  if (Argc == 2)
-    {
-      /* Clear the breakpoint. */
-      Tf->Dr7 &= ~(0x3 << (DebugRegNr * 2));
-      if ((Tf->Dr7 & 0xFF) == 0)
-       {
-         /* 
-            If no breakpoints are enabled then 
-            clear the exact match flags. 
-         */
-         Tf->Dr7 &= 0xFFFFFCFF;
-       }
-      return(1);
-    }
-  BreakType = Argv[2][0];
-  if (BreakType != 'r' && BreakType != 'w' && BreakType != 'e')
-    {
-      DbgPrint("Access type to break on should be either 'r', 'w' or 'e'.\n");
-      return(1);
-    }
-  Length = strtoul(Argv[3], NULL, 10);
-  if (Length != 1 && Length != 2 && Length != 4)
-    {
-      DbgPrint("Length of the breakpoint should be one, two or four.\n");
-      return(1);
-    }
-  if (Length != 1 && BreakType == 'e')
-    {
-      DbgPrint("The length of an execution breakpoint should be one.\n");
-      return(1);
-    }
-  /* Stitch the remaining arguments back into a single string. */
-  for (i = 4; i < Argc; i++)
-    {
-      Argv[i][-1] = ' ';
-    }
-  if (!KdbDecodeAddress(Argv[4], &Address))
-    {
-      return(1);
-    }
-  if ((Address & (Length - 1)) != 0)
-    {
-      DbgPrint("The breakpoint address should be aligned to a multiple of "
-              "the breakpoint length.\n");
-      return(1);
-    }
-
-  /* Set the breakpoint address. */
-  switch (DebugRegNr)
-    {
-    case 0: Tf->Dr0 = Address; break;
-    case 1: Tf->Dr1 = Address; break;
-    case 2: Tf->Dr2 = Address; break;
-    case 3: Tf->Dr3 = Address; break;
-    }
-  /* Enable the breakpoint. */
-  Tf->Dr7 |= (0x3 << (DebugRegNr * 2));
-  /* Enable the exact match bits. */
-  Tf->Dr7 |= 0x00000300;
-  /* Clear existing state. */
-  Tf->Dr7 &= ~(0xF << (16 + (DebugRegNr * 4)));
-  /* Set the breakpoint type. */
-  switch (BreakType)
-    {
-    case 'r': Rw = 3; break;
-    case 'w': Rw = 1; break;
-    case 'e': Rw = 0; break;
-    }  
-  Tf->Dr7 |= (Rw << (16 + (DebugRegNr * 4)));
-  /* Set the breakpoint length. */
-  Tf->Dr7 |= ((Length - 1) << (18 + (DebugRegNr * 4)));
-
-  return(1);
-}
+      i = strlen(ConditionExpression) + 1;
+      ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
+      RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
+
+   }
+   else
+   {
+      Condition = NULL;
+      ConditionExpressionDup = NULL;
+   }
+
+   /* Find unused breakpoint */
+   if (Type == KdbBreakPointTemporary)
+   {
+      for (i = RTL_NUMBER_OF(KdbBreakPoints) - 1; i >= 0; i--)
+      {
+         if (KdbBreakPoints[i].Type == KdbBreakPointNone)
+            break;
+      }
+   }
+   else
+   {
+      for (i = 0; i < RTL_NUMBER_OF(KdbBreakPoints); i++)
+      {
+         if (KdbBreakPoints[i].Type == KdbBreakPointNone)
+            break;
+      }
+   }
+   ASSERT(i < RTL_NUMBER_OF(KdbBreakPoints));
+   
+   /* Set the breakpoint */
+   ASSERT(KdbCurrentProcess != NULL);
+   KdbBreakPoints[i].Type = Type;
+   KdbBreakPoints[i].Address = Address;
+   KdbBreakPoints[i].Enabled = FALSE;
+   KdbBreakPoints[i].Global = Global;
+   KdbBreakPoints[i].Process = KdbCurrentProcess;
+   KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
+   KdbBreakPoints[i].Condition = Condition;
+   if (Type == KdbBreakPointHardware)
+   {
+
+      KdbBreakPoints[i].Data.Hw.Size = Size;
+      KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
+   }
+   KdbBreakPointCount++;
+   
+   if (Type != KdbBreakPointTemporary)
+      KdbpPrint("Breakpoint %d inserted.\n", i);
 
-ULONG
-DbgStep(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  /* Set the single step flag and return to the interrupted code. */
-  Tf->Eflags |= (1 << 8);
-  KdbIgnoreNextSingleStep = FALSE;
-  KdbLastSingleStepFrom = Tf->Eip;
-  return(0);
-}
+   /* Try to enable the breakpoint */
+   KdbpEnableBreakPoint(i, NULL);
 
-ULONG
-DbgStepOver(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  PUCHAR Eip;
-  UCHAR Mem[3];
-
-  if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Tf->Eip, sizeof (Mem))))
-    {
-      DbgPrint("Couldn't access memory at 0x%x\n", (UINT)Tf->Eip);
-      return(1);
-    }
-  Eip = Mem;
-
-  /* Check if the current instruction is a call. */
-  while (Eip[0] == 0x66 || Eip[0] == 0x67)
-    {
-      Eip++;
-    }
-  if (Eip[0] == 0xE8 || Eip[0] == 0x9A || Eip[0] == 0xF2 || Eip[0] == 0xF3 ||
-      (Eip[0] == 0xFF && (Eip[1] & 0x38) == 0x10))
-    {
-      ULONG NextInst = Tf->Eip + KdbGetInstLength(Tf->Eip);
-      KdbLastSingleStepFrom = Tf->Eip;
-      KdbInsertBreakPoint(NextInst, TRUE);
-      return(0);
-    }
-  else
-    {
-      return(DbgStep(Argc, Argv, Tf));
-    }
-}
+   /* Return the breakpoint number */
+   if (BreakPointNumber != NULL)
+      *BreakPointNumber = i;
 
-ULONG
-DbgFinish(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  PULONG Ebp = (PULONG)Tf->Ebp;
-  ULONG ReturnAddress;
-  NTSTATUS Status;
-  PKTHREAD CurrentThread;
-
-  /* Check that ebp points onto the stack. */
-  CurrentThread = KeGetCurrentThread();
-  if (CurrentThread == NULL ||
-      !(Ebp >= (PULONG)CurrentThread->StackLimit && 
-       Ebp <= (PULONG)CurrentThread->StackBase))
-    {
-      DbgPrint("This function doesn't appear to have a valid stack frame.\n");
-      return(1);
-    }
-
-  /* Get the address of the caller. */
-  Status = KdbpSafeReadMemory(&ReturnAddress, Ebp + 1, sizeof(ULONG));
-  if (!NT_SUCCESS(Status))
-    {
-      DbgPrint("Memory access error (%X) while getting return address.\n",
-              Status);
-      return(1);
-    }
-
-  /* Set a temporary breakpoint at that location. */
-  Status = KdbInsertBreakPoint(ReturnAddress, TRUE);
-  if (!NT_SUCCESS(Status))
-    {
-      DbgPrint("Couldn't set a temporary breakpoint at %X (Status %X)\n",
-              ReturnAddress, Status);
-      return(1);
-    }
-
-  /*
-    Otherwise start running again and with any luck we will break back into
-    the debugger when the current function returns.
-  */
-  return(0);
+   return STATUS_SUCCESS;
 }
 
-ULONG
-DbgDisassemble(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Deletes a breakpoint
+ *
+ * \param BreakPointNr  Number of the breakpoint to delete. Can be -1
+ * \param BreakPoint    Breakpoint to delete. Can be NULL.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure (invalid breakpoint number)
+ */
+BOOLEAN
+KdbpDeleteBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL)
 {
-  ULONG Address, i;
-  LONG InstLen;
-  if (Argc >= 2)
-    {
-      /* Stitch the remaining arguments back into a single string. */
-      for (i = 2; i < Argc; i++)
-       {
-         Argv[i][-1] = ' ';
-       }
-      if (!KdbDecodeAddress(Argv[1], &Address))
-       {
-         return(1);
-       }
-    }
-  else
-    {
-      Address = Tf->Eip;
-    }
-  for (i = 0; i < 10; i++)
-    {
-      if (!KdbSymPrintAddress((PVOID)Address))
-       {
-         DbgPrint("<%x>", Address);
-       }
-      DbgPrint(": ");
-      InstLen = KdbDisassemble(Address);      
-      if (InstLen < 0)
-       {
-         DbgPrint("<INVALID>\n");
-         return(1);
-       }
-      DbgPrint("\n");
-      Address += InstLen;
-    }
-  
-  return(1);
+   if (BreakPointNr < 0)
+   {
+      ASSERT(BreakPoint != NULL);
+      BreakPointNr = BreakPoint - KdbBreakPoints;
+   }
+   if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+   if (BreakPoint == NULL)
+   {
+      BreakPoint = KdbBreakPoints + BreakPointNr;
+   }
+   if (BreakPoint->Type == KdbBreakPointNone)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+
+   if (BreakPoint->Enabled &&
+       !KdbpDisableBreakPoint(-1, BreakPoint))
+      return FALSE;
+
+   if (BreakPoint->Type != KdbBreakPointTemporary)
+      KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
+   BreakPoint->Type = KdbBreakPointNone;
+   KdbBreakPointCount--;
+   
+   return TRUE;
 }
 
-ULONG
-DbgProcessHelpCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Checks if the breakpoint was set by the debugger
+ *
+ * Tries to find a breakpoint in the breakpoint array which caused
+ * the debug exception to happen.
+ *
+ * \param ExpNr      Exception Number (1 or 3)
+ * \param TrapFrame  Exception trapframe
+ *
+ * \returns Breakpoint number, -1 on error.
+ */
+STATIC LONG
+KdbpIsBreakPointOurs(
+   IN ULONG ExpNr,
+   IN PKTRAP_FRAME TrapFrame)
 {
-  ULONG i, j, len;
-
-  DbgPrint("Kernel debugger commands:\n");
-  for (i = 0; DebuggerCommands[i].Name != NULL; i++)
-    {
-      DbgPrint("  %s", DebuggerCommands[i].Syntax);
-      len = strlen(DebuggerCommands[i].Syntax);
-      if (len < 35)
-        {
-          for (j = 0; j < 35 - len; j++)
-          {
-            DbgPrint(" ");
-          }
-        }
-      DbgPrint(" - %s\n", DebuggerCommands[i].Help);
-    }
-  return(1);
-}
+   INT i;
+   ASSERT(ExpNr == 1 || ExpNr == 3);
 
-ULONG
-DbgThreadListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  BOOL System = FALSE;
-  if (Argc == 2 && (!strcmp(Argv[1], "sys") || !strcmp(Argv[1], "SYS")))
-    System = TRUE;
-    
-  PsDumpThreads(System);
-  return(1);
+   if (ExpNr == 3) /* Software interrupt */
+   {
+      ULONG_PTR BpEip = (ULONG_PTR)TrapFrame->Eip - 1; /* Get EIP of INT3 instruction */
+      for (i = 0; i < KdbSwBreakPointCount; i++)
+      {
+         ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
+                 KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
+         ASSERT(KdbSwBreakPoints[i]->Enabled);
+         if (KdbSwBreakPoints[i]->Address == BpEip)
+         {
+            return KdbSwBreakPoints[i] - KdbBreakPoints;
+         }
+      }
+   }
+   else if (ExpNr == 1) /* Hardware interrupt */
+   {
+      UCHAR DebugReg;
+      for (i = 0; i < KdbHwBreakPointCount; i++)
+      {
+         ASSERT(KdbHwBreakPoints[i]->Type == KdbBreakPointHardware &&
+                KdbHwBreakPoints[i]->Enabled);
+         DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
+         if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
+         {
+            return KdbHwBreakPoints[i] - KdbBreakPoints;
+         }
+      }
+   }
+   
+   return -1;
 }
 
-ULONG
-DbgProcessListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Enables a breakpoint.
+ *
+ * \param BreakPointNr  Number of the breakpoint to enable Can be -1.
+ * \param BreakPoint    Breakpoint to enable. Can be NULL.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure.
+ *
+ * \sa KdbpDisableBreakPoint
+ */
+BOOLEAN
+KdbpEnableBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL)
 {
-  extern LIST_ENTRY PsActiveProcessHead;
-  PLIST_ENTRY current_entry;
-  PEPROCESS current;
-  ULONG i = 1;
-
-  if (PsActiveProcessHead.Flink == NULL)
-    {
-      DbgPrint("No processes.\n");
-      return(1);
-    }
-
-  DbgPrint("Process list: ");
-  current_entry = PsActiveProcessHead.Flink;
-  while (current_entry != &PsActiveProcessHead)
-    {
-      current = CONTAINING_RECORD(current_entry, EPROCESS, ProcessListEntry);
-      DbgPrint("%d %.8s", current->UniqueProcessId, 
-              current->ImageFileName);
-      i++;
-      if ((i % 4) == 0)
-       {
-         DbgPrint("\n");
-       }
-      current_entry = current_entry->Flink;
-    }
-  return(1);
-}
+   NTSTATUS Status;
+   INT i;
+   ULONG ul;
+
+   if (BreakPointNr < 0)
+   {
+      ASSERT(BreakPoint != NULL);
+      BreakPointNr = BreakPoint - KdbBreakPoints;
+   }
+   if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+   if (BreakPoint == NULL)
+   {
+      BreakPoint = KdbBreakPoints + BreakPointNr;
+   }
+   if (BreakPoint->Type == KdbBreakPointNone)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+   
+   if (BreakPoint->Enabled == TRUE)
+   {
+      KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
+      return TRUE;
+   }
+
+   if (BreakPoint->Type == KdbBreakPointSoftware ||
+       BreakPoint->Type == KdbBreakPointTemporary)
+   {
+      if (KdbSwBreakPointCount >= KDB_MAXIMUM_SW_BREAKPOINT_COUNT)
+      {
+         KdbpPrint("Maximum number of SW breakpoints (%d) used. "
+                   "Disable another breakpoint in order to enable this one.\n",
+                   KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
+         return FALSE;
+      }
+      Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
+                                        0xCC, &BreakPoint->Data.SavedInstruction);
+      if (!NT_SUCCESS(Status))
+      {
+         KdbpPrint("Couldn't access memory at 0x%x\n", BreakPoint->Address);
+         return FALSE;
+      }
+      KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
+   }
+   else
+   {
+      if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
+         ASSERT(BreakPoint->Data.Hw.Size == 1);
+      ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
+      if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
+      {
+         KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
+                   "Disable another breakpoint in order to enable this one.\n",
+                   KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
+         return FALSE;
+      }
 
-VOID
-DbgPrintBackTrace(PULONG Frame, ULONG_PTR StackBase, ULONG_PTR StackLimit)
-{
-  PVOID Address;
-
-  DbgPrint("Frames:\n");
-  while (Frame != NULL)
-    {
-      if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, Frame + 1, sizeof (Address))))
-        {
-          DbgPrint("\nCouldn't access memory at 0x%x!\n", (UINT)(Frame + 1));
-          break;
-        }
-      KdbSymPrintAddress(Address);
-      DbgPrint("\n");
-      if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, Frame, sizeof (Frame))))
-        {
-          DbgPrint("\nCouldn't access memory at 0x%x!\n", (UINT)Frame);
-          break;
-        }
-    }
-}
+      /* Find unused hw breakpoint */
+      ASSERT(KDB_MAXIMUM_HW_BREAKPOINT_COUNT == 4);
+      for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
+      {
+         if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
+            break;
+      }
+      ASSERT(i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
 
-ULONG
-DbgAddrCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME tf)
-{
-  PVOID Addr;
+      /* Set the breakpoint address. */
+      switch (i)
+      {
+      case 0:
+         KdbTrapFrame.Tf.Dr0 = BreakPoint->Address;
+         break;
+      case 1:
+         KdbTrapFrame.Tf.Dr1 = BreakPoint->Address;
+         break;
+      case 2:
+         KdbTrapFrame.Tf.Dr2 = BreakPoint->Address;
+         break;
+      case 3:
+         KdbTrapFrame.Tf.Dr3 = BreakPoint->Address;
+         break;
+      }
 
-  if (Argc == 2)
-    {
-      Addr = (PVOID)strtoul(Argv[1], NULL, 0);
-      KdbSymPrintAddress(Addr);
-    }
+      /* Enable the global breakpoint */
+      KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2));
 
-  return(1);
-}
+      /* Enable the exact match bits. */
+      KdbTrapFrame.Tf.Dr7 |= 0x00000300;
 
-ULONG
-DbgXCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME tf)
-{
-  PDWORD Addr = NULL;
-  DWORD Items = 1;
-  DWORD i = 0;
-  DWORD Item;
-
-  if (Argc >= 2)
-    Addr = (PDWORD)strtoul(Argv[1], NULL, 0);
-  if (Argc >= 3)
-    Items = (DWORD)strtoul(Argv[2], NULL, 0);
-
-  if (Addr == NULL)
-    return(1);
-
-  for (i = 0; i < Items; i++)
-    {
-      if( (i % 4) == 0 )
-        {
-         if (i != 0)
-            DbgPrint("\n");
-         DbgPrint("%08x:", (int)(&Addr[i]));
-        }
-      if (!NT_SUCCESS(KdbpSafeReadMemory(&Item, Addr + i, sizeof (Item))))
-        {
-          DbgPrint("\nCouldn't access memory at 0x%x!\n", (UINT)(Addr + i));
-          break;
-        }
-      DbgPrint("%08x ", Item);
-    }
-
-  return(1);
-}
+      /* Clear existing state. */
+      KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4)));
 
-static int KjsReadRegValue( void *context,
-                           JSNode *result,
-                           JSNode *args ) {
-  PCHAR cp;
-  PVOID *context_list = context;
-  PKJS kjs = (PKJS)context_list[0];
-  JSVirtualMachine *vm = kjs->vm;
-  NTSTATUS Status;
-  RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { 0 } };
-  UNICODE_STRING NameString;
-  UNICODE_STRING PathString;
-  UNICODE_STRING DefaultString;
-  UNICODE_STRING ValueResult;
-  ANSI_STRING AnsiResult;
-  
-  if (args->u.vinteger != 2 ||
-      args[1].type != JS_STRING || args[2].type != JS_STRING) {
-    return JS_PROPERTY_FOUND;
-  }
-
-  RtlInitUnicodeString(&PathString,NULL);
-  RtlInitUnicodeString(&NameString,NULL);
-  
-  cp = js_string_to_c_string (vm, &args[1]);
-  RtlCreateUnicodeStringFromAsciiz(&PathString,cp);
-  js_free(cp);
-  cp = js_string_to_c_string (vm, &args[2]);
-  RtlCreateUnicodeStringFromAsciiz(&NameString,cp);
-  js_free(cp);
-  
-  RtlInitUnicodeString(&ValueResult,NULL);
-  RtlInitUnicodeString(&DefaultString,L"");
-  RtlInitAnsiString(&AnsiResult,NULL);
-
-  QueryTable->EntryContext = 0;
-  QueryTable->Flags =
-    RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
-  QueryTable->Name = NameString.Buffer;
-  QueryTable->DefaultType = REG_SZ;
-  QueryTable->DefaultData = &DefaultString;
-  QueryTable->EntryContext = &ValueResult;
-  Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, 
-                                  PathString.Buffer, 
-                                  QueryTable, 
-                                  NULL, 
-                                  NULL );
-  
-  RtlFreeUnicodeString(&NameString);
-  RtlFreeUnicodeString(&PathString);
-  
-  if (NT_SUCCESS(Status)) {
-    RtlInitAnsiString(&AnsiResult,NULL);
-    RtlUnicodeStringToAnsiString(&AnsiResult,
-                                &ValueResult,
-                                TRUE);
-    js_vm_make_string (vm, result, AnsiResult.Buffer, 
-                      strlen(AnsiResult.Buffer));
-    RtlFreeAnsiString(&AnsiResult);
-  } else {
-    result->type = JS_INTEGER;
-    result->u.vinteger = Status;
-  }
-
-  return JS_PROPERTY_FOUND;
-}
+      /* Set the breakpoint type. */
+      switch (BreakPoint->Data.Hw.AccessType)
+      {
+      case KdbAccessExec:
+         ul = 0;
+         break;
+      case KdbAccessWrite:
+         ul = 1;
+         break;
+      case KdbAccessRead:
+      case KdbAccessReadWrite:
+         ul = 3;
+         break;
+      default:
+         ASSERT(0);
+         return TRUE;
+         break;
+      }
+      KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
 
-static int KjsGetRegister( void *context, 
-                          JSNode *result, 
-                          JSNode *args ) {
-  PVOID *context_list = context;
-  if( args->u.vinteger == 1 && args->type == JS_INTEGER ) {
-    DWORD Result = ((DWORD *)context_list[1])[args[1].u.vinteger];
-    result->type = JS_INTEGER;
-    result->u.vinteger = Result;
-  }
-
-  return JS_PROPERTY_FOUND;
-}
+      /* Set the breakpoint length. */
+      KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
 
-static int KjsGetNthModule( void *context,
-                           JSNode *result,
-                           JSNode *args ) {
-  PVOID *context_list = context;
-  PKJS kjs = (PKJS)context_list[0];
-  JSVirtualMachine *vm = kjs->vm;
-  PLIST_ENTRY current_entry;
-  MODULE_TEXT_SECTION *current = NULL;
-  extern LIST_ENTRY ModuleTextListHead;
-  int n = 0;
-  
-  if (args->u.vinteger != 1 || args[1].type != JS_INTEGER) {
-    return JS_PROPERTY_FOUND;
-  }
-
-  current_entry = ModuleTextListHead.Flink;
-
-  while (current_entry != &ModuleTextListHead &&
-        current_entry != NULL &&
-        n <= args[1].u.vinteger) {
-    current = CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION,
-                               ListEntry);    
-    current_entry = current_entry->Flink;
-    n++;
-  }
-
-  if (current_entry && current) {
-    ANSI_STRING NameStringNarrow;
-    UNICODE_STRING NameUnicodeString;
-
-    RtlInitUnicodeString( &NameUnicodeString, current->Name );
-    RtlUnicodeStringToAnsiString( &NameStringNarrow,
-                                 &NameUnicodeString,
-                                 TRUE );
-
-    js_vm_make_array (vm, result, 2);
-  
-    js_vm_make_string (vm, 
-                      &result->u.varray->data[0], 
-                      NameStringNarrow.Buffer,
-                      NameStringNarrow.Length);
-
-    RtlFreeAnsiString(&NameStringNarrow);
-
-    result->u.varray->data[1].type = JS_INTEGER;
-    result->u.varray->data[1].u.vinteger = (DWORD)current->Base;
-    result->type = JS_ARRAY;
-    return JS_PROPERTY_FOUND;
-  }
-  result->type = JS_UNDEFINED;
-  return JS_PROPERTY_FOUND;
-}
+      /* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
+      if (&KdbTrapFrame != KdbCurrentTrapFrame)
+      {
+         KdbCurrentTrapFrame->Tf.Dr0 = KdbTrapFrame.Tf.Dr0;
+         KdbCurrentTrapFrame->Tf.Dr1 = KdbTrapFrame.Tf.Dr1;
+         KdbCurrentTrapFrame->Tf.Dr2 = KdbTrapFrame.Tf.Dr2;
+         KdbCurrentTrapFrame->Tf.Dr3 = KdbTrapFrame.Tf.Dr3;
+         KdbCurrentTrapFrame->Tf.Dr6 = KdbTrapFrame.Tf.Dr6;
+         KdbCurrentTrapFrame->Tf.Dr7 = KdbTrapFrame.Tf.Dr7;
+      }
 
-static BOOL FindJSEndMark( PCHAR Buffer ) {
-  int i;
+      BreakPoint->Data.Hw.DebugReg = i;
+      KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint;
+   }
 
-  for( i = 0; Buffer[i] && Buffer[i+1]; i++ ) {
-    if( Buffer[i] == ';' && Buffer[i+1] == ';' ) return TRUE;
-  }
-  return FALSE;
+   BreakPoint->Enabled = TRUE;
+   if (BreakPoint->Type != KdbBreakPointTemporary)
+      KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
+   return TRUE;
 }
 
-ULONG
-DbgScriptCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME tf)
+/*!\brief Disables a breakpoint.
+ *
+ * \param BreakPointNr  Number of the breakpoint to disable. Can be -1
+ * \param BreakPoint    Breakpoint to disable. Can be NULL.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure.
+ *
+ * \sa KdbpEnableBreakPoint
+ */
+BOOLEAN
+KdbpDisableBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL)
 {
-  PCHAR Buffer;
-  PCHAR BufferStart;
-  static void *interp = 0;
-  void *script_cmd_context[2];
-
-  if( !interp ) interp = kjs_create_interp(NULL);
-  if( !interp ) return 1;
-
-  BufferStart = Buffer = ExAllocatePool( NonPagedPool, 4096 );
-  if( !Buffer ) return 1;
-
-  script_cmd_context[0] = interp;
-  script_cmd_context[1] = &tf;
-  
-  kjs_system_register( interp, "regs", script_cmd_context,
-                      KjsGetRegister );
-  kjs_system_register( interp, "regread", script_cmd_context,
-                      KjsReadRegValue );
-  kjs_system_register( interp, "getmodule", script_cmd_context,
-                      KjsGetNthModule );
-
-  kjs_eval( interp,
-           "eval("
-           "System.regread("
-           "'\\\\Registry\\\\Machine\\\\System\\\\"
-           "CurrentControlSet\\\\Control\\\\Kdb',"
-           "'kjsinit'));" );
-
-  DbgPrint("\nKernel Debugger Script Interface (JavaScript :-)\n");
-  DbgPrint("Terminate input with ;; and end scripting with .\n");
-  do
-    {
-      if( Buffer != BufferStart )
-       DbgPrint("..... ");
-      else
-       DbgPrint("kjs:> ");
-      KdbGetCommand( BufferStart );
-      if( BufferStart[0] == '.' ) {
-       if( BufferStart != Buffer ) {
-         DbgPrint("Input Aborted.\n");
-         BufferStart = Buffer;
-       } else {
-         /* Single dot input -> exit */
-         break;
-       }
-      } else {
-       if( FindJSEndMark( Buffer ) ) {
-         kjs_eval( interp, Buffer );
-         BufferStart = Buffer;
-         DbgPrint("\n");
-       } else {
-         BufferStart = BufferStart + strlen(BufferStart);
-       }
+   INT i;
+   NTSTATUS Status;
+   
+   if (BreakPointNr < 0)
+   {
+      ASSERT(BreakPoint != NULL);
+      BreakPointNr = BreakPoint - KdbBreakPoints;
+   }
+   if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+   if (BreakPoint == NULL)
+   {
+      BreakPoint = KdbBreakPoints + BreakPointNr;
+   }
+   if (BreakPoint->Type == KdbBreakPointNone)
+   {
+      KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+      return FALSE;
+   }
+
+   if (BreakPoint->Enabled == FALSE)
+   {
+      KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
+      return TRUE;
+   }
+
+   if (BreakPoint->Type == KdbBreakPointSoftware ||
+       BreakPoint->Type == KdbBreakPointTemporary)
+   {
+      ASSERT(KdbSwBreakPointCount > 0);
+      Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
+                                        BreakPoint->Data.SavedInstruction, NULL);
+      if (!NT_SUCCESS(Status))
+      {
+         KdbpPrint("Couldn't restore original instruction.\n");
+         return FALSE;
+      }
+         
+      for (i = 0; i < KdbSwBreakPointCount; i++)
+      {
+         if (KdbSwBreakPoints[i] == BreakPoint)
+         {
+            KdbSwBreakPoints[i] = KdbSwBreakPoints[--KdbSwBreakPointCount];
+            i = -1; /* if the last breakpoint is disabled dont break with i >= KdbSwBreakPointCount */
+            break;
+         }
+      }
+      if (i != -1) /* not found */
+         ASSERT(0);
+   }
+   else
+   {
+      ASSERT(BreakPoint->Type == KdbBreakPointHardware);
+      
+      /* Clear the breakpoint. */
+      KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
+      if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
+      {
+         /*
+          * If no breakpoints are enabled then clear the exact match flags.
+          */
+         KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
       }
-    } while (TRUE);
-
-  ExFreePool( Buffer );
-
-  kjs_system_unregister( interp, script_cmd_context, KjsGetRegister );
-  kjs_system_unregister( interp, script_cmd_context, KjsReadRegValue );
-  kjs_system_unregister( interp, script_cmd_context, KjsGetNthModule );
 
-  return(1);
+      for (i = 0; i < KdbHwBreakPointCount; i++)
+      {
+         if (KdbHwBreakPoints[i] == BreakPoint)
+         {
+            KdbHwBreakPoints[i] = KdbHwBreakPoints[--KdbHwBreakPointCount];
+            i = -1; /* if the last breakpoint is disabled dont break with i >= KdbHwBreakPointCount */
+            break;
+         }
+      }
+      if (i != -1) /* not found */
+         ASSERT(0);
+   }
+
+   BreakPoint->Enabled = FALSE;
+   if (BreakPoint->Type != KdbBreakPointTemporary)
+      KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
+   return TRUE;
 }
 
-ULONG
-DbgBackTraceCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Gets the first or last chance enter-condition for exception nr. \a ExceptionNr
+ *
+ * \param ExceptionNr  Number of the exception to get condition of.
+ * \param FirstChance  Whether to get first or last chance condition.
+ * \param Condition    Receives the condition setting.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure (invalid exception nr)
+ */
+BOOLEAN
+KdbpGetEnterCondition(
+   IN LONG ExceptionNr,
+   IN BOOLEAN FirstChance,
+   OUT KDB_ENTER_CONDITION *Condition)
 {
-  ULONG_PTR StackBase, StackLimit;
-  extern unsigned int init_stack, init_stack_top;
-
-  /* Without an argument we print the current stack. */
-  if (Argc == 1)
-    {
-      if (PsGetCurrentThread() != NULL)
-       {
-         StackBase = (ULONG_PTR)PsGetCurrentThread()->Tcb.StackBase;
-         StackLimit = PsGetCurrentThread()->Tcb.StackLimit;
-       }
-      else
-       {
-         StackBase = (ULONG_PTR)init_stack_top;
-         StackLimit = (ULONG_PTR)init_stack;
-       }
-      DbgPrintBackTrace((PULONG)&Tf->DebugEbp, StackBase, StackLimit);
-    }
-  /* 
-   * If there are two arguments and the second begins with a asterik treat it
-   * as the address of a frame to start printing the back trace from.
-   */
-  else if (Argc == 2 && Argv[1][0] == '*')
-    {
-      PULONG Frame;
-      Frame = (PULONG)strtoul(&Argv[1][1], NULL, 0);
-      DbgPrintBackTrace(Frame, ULONG_MAX, 0);
-    }
-  /*
-   * Otherwise treat the argument as the id of a thread whose back trace is to
-   * be printed.
-   */
-  else
-    {
-    }
-  return(1);
+   if (ExceptionNr >= RTL_NUMBER_OF(KdbEnterConditions))
+      return FALSE;
+
+   *Condition = KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1];
+   return TRUE;
 }
 
-VOID
-DbgPrintCr0(ULONG Cr0)
+/*!\brief Sets the first or last chance enter-condition for exception nr. \a ExceptionNr
+ *
+ * \param ExceptionNr  Number of the exception to set condition of (-1 for all)
+ * \param FirstChance  Whether to set first or last chance condition.
+ * \param Condition    The new condition setting.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure (invalid exception nr)
+ */
+BOOLEAN
+KdbpSetEnterCondition(
+   IN LONG ExceptionNr,
+   IN BOOLEAN FirstChance,
+   IN KDB_ENTER_CONDITION Condition)
 {
-  ULONG i;
-
-  DbgPrint("CR0:");
-  if (Cr0 & (1 << 0))
-    {
-      DbgPrint(" PE");
-    }
-  if (Cr0 & (1 << 1))
-    {
-      DbgPrint(" MP");
-    }
-  if (Cr0 & (1 << 2))
-    {
-      DbgPrint(" EM");
-    }
-  if (Cr0 & (1 << 3))
-    {
-      DbgPrint(" TS");
-    }
-  if (!(Cr0 & (1 << 4)))
-    {
-      DbgPrint(" !BIT5");
-    }
-  if (Cr0 & (1 << 5))
-    {
-      DbgPrint(" NE");
-    }
-  for (i = 6; i < 16; i++)
-    {
-      if (Cr0 & (1 << i))
-       {
-         DbgPrint(" BIT%d", i);
-       }
-    }
-  if (Cr0 & (1 << 16))
-    {
-      DbgPrint(" WP");
-    }
-  if (Cr0 & (1 << 17))
-    {
-      DbgPrint(" BIT17");
-    }
-  if (Cr0 & (1 << 18))
-    {
-      DbgPrint(" AM");
-    }
-  for (i = 19; i < 29; i++)
-    {
-      if (Cr0 & (1 << i))
-       {
-         DbgPrint(" BIT%d", i);
-       }
-    }
-  if (Cr0 & (1 << 29))
-    {
-      DbgPrint(" NW");
-    }
-  if (Cr0 & (1 << 30))
-    {
-      DbgPrint(" CD");
-    }
-  if (Cr0 & (1 << 31))
-    {
-      DbgPrint(" PG");
-    }
-  DbgPrint("\n");
+   if (ExceptionNr < 0)
+   {
+      for (ExceptionNr = 0; ExceptionNr < RTL_NUMBER_OF(KdbEnterConditions); ExceptionNr++)
+      {
+         if (ExceptionNr == 1 || ExceptionNr == 8 ||
+             ExceptionNr == 9 || ExceptionNr == 15) /* Reserved exceptions */
+         {
+            continue;
+         }
+         KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
+      }
+   }
+   else
+   {
+      if (ExceptionNr >= RTL_NUMBER_OF(KdbEnterConditions) ||
+          ExceptionNr == 1 || ExceptionNr == 8 || /* Do not allow changing of the debug */
+          ExceptionNr == 9 || ExceptionNr == 15)  /* trap or reserved exceptions */
+      {
+         return FALSE;
+      }
+      KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
+   }
+   return TRUE;
 }
 
-ULONG 
-DbgCRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Switches to another thread context
+ *
+ * \param ThreadId  Id of the thread to switch to.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure (i.e. invalid thread id)
+ */
+BOOLEAN
+KdbpAttachToThread(
+   PVOID ThreadId)
 {
-  ULONG Cr0, Cr1, Cr2, Cr3, Cr4;
-  ULONG Ldtr;
-  USHORT Tr;
-  
-  __asm__ __volatile__ ("movl %%cr0, %0\n\t" : "=d" (Cr0));
-  /*  __asm__ __volatile__ ("movl %%cr1, %0\n\t" : "=d" (Cr1)); */
-  Cr1 = 0;
-  __asm__ __volatile__ ("movl %%cr2, %0\n\t" : "=d" (Cr2));
-  __asm__ __volatile__ ("movl %%cr3, %0\n\t" : "=d" (Cr3));
-  __asm__ __volatile__ ("movl %%cr4, %0\n\t" : "=d" (Cr4));
-  __asm__ __volatile__ ("str %0\n\t" : "=d" (Tr));
-  __asm__ __volatile__ ("sldt %0\n\t" : "=d" (Ldtr));
-  DbgPrintCr0(Cr0);
-  DbgPrint("CR1 %.8x CR2 %.8x CR3 %.8x CR4 %.8x TR %.8x LDTR %.8x\n",
-          Cr1, Cr2, Cr3, Cr4, (ULONG)Tf, Ldtr);
-  return(1);
+   PETHREAD Thread = NULL;
+   PEPROCESS Process;
+
+   /* Get a pointer to the thread */
+   if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
+   {
+      KdbpPrint("Invalid thread id: 0x%08x\n", (UINT)ThreadId);
+      return FALSE;
+   }
+   Process = Thread->ThreadsProcess;
+
+   if (KeIsExecutingDpc() && Process != KdbCurrentProcess)
+   {
+      KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
+      return FALSE;
+   }
+   
+   /* Save the current thread's context (if we previously attached to a thread) */
+   if (KdbCurrentThread != KdbOriginalThread)
+   {
+      ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame);
+      RtlCopyMemory(KdbCurrentThread->Tcb.TrapFrame, &KdbCurrentTrapFrame->Tf, sizeof (KTRAP_FRAME));
+   }
+   else
+   {
+      ASSERT(KdbCurrentTrapFrame == &KdbTrapFrame);
+   }
+
+   /* Switch to the thread's context */
+   if (Thread != KdbOriginalThread)
+   {
+      ASSERT(Thread->Tcb.TrapFrame != NULL);
+      RtlCopyMemory(&KdbThreadTrapFrame.Tf, Thread->Tcb.TrapFrame, sizeof (KTRAP_FRAME));
+      asm volatile(
+         "movl %%cr0, %0"    "\n\t"
+         "movl %%cr2, %1"    "\n\t"
+         "movl %%cr3, %2"    "\n\t"
+         "movl %%cr4, %3"    "\n\t"
+         : "=r"(KdbTrapFrame.Cr0), "=r"(KdbTrapFrame.Cr2),
+           "=r"(KdbTrapFrame.Cr3), "=r"(KdbTrapFrame.Cr4));
+      KdbCurrentTrapFrame = &KdbThreadTrapFrame;
+   }
+   else /* Switching back to original thread */
+   {
+      KdbCurrentTrapFrame = &KdbTrapFrame;
+   }
+   KdbCurrentThread = Thread;
+
+   /* Attach to the thread's process */
+   ASSERT(KdbCurrentProcess == PsGetCurrentProcess());
+   if (KdbCurrentProcess != Process)
+   {
+      if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
+      {
+         KeUnstackDetachProcess(&KdbApcState);
+      }
+      if (KdbOriginalProcess != Process)
+      {
+         KeStackAttachProcess(EPROCESS_TO_KPROCESS(Process), &KdbApcState);
+      }
+      KdbCurrentProcess = Process;
+   }
+
+   return TRUE;
 }
 
-ULONG 
-DbgDRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Switches to another process/thread context
+ *
+ * This function switches to the first thread in the specified process.
+ *
+ * \param ProcessId  Id of the process to switch to.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure (i.e. invalid process id)
+ */
+BOOLEAN
+KdbpAttachToProcess(
+   PVOID ProcessId)
 {
-  DbgPrint("Trap   : DR0 %.8x DR1 %.8x DR2 %.8x DR3 %.8x DR6 %.8x DR7 %.8x\n",
-          Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3, Tf->Dr6, Tf->Dr7);
-  return(1);
+   PEPROCESS Process = NULL;
+   PETHREAD Thread;
+   PLIST_ENTRY Entry;
+
+   /* Get a pointer to the process */
+   if (!NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)))
+   {
+      KdbpPrint("Invalid process id: 0x%08x\n", (UINT)ProcessId);
+      return FALSE;
+   }
+
+   Entry = Process->ThreadListHead.Flink;
+   if (Entry == &KdbCurrentProcess->ThreadListHead)
+   {
+      KdbpPrint("No threads in process 0x%08x, cannot attach to process!\n", (UINT)ProcessId);
+      return FALSE;
+   }
+
+   Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+
+   return KdbpAttachToThread(Thread->Cid.UniqueThread);
 }
 
-ULONG
-DbgContCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief Calls the main loop ...
+ */
+STATIC VOID
+KdbpCallMainLoop()
 {
-  /* Not too difficult. */
-  return(0);
+   KdbpCliMainLoop(KdbEnteredOnSingleStep);
 }
 
-ULONG
-DbgStopCondition(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-    if( Argc == 1 ) {
-       if( KdbHandleHandled ) DbgPrint("all\n");
-       else if( KdbHandleUmode ) DbgPrint("umode\n");
-       else DbgPrint("kmode\n");
-    } 
-    else if( !strcmp(Argv[1],"all") ) 
-    { KdbHandleHandled = TRUE; KdbHandleUmode = TRUE; }
-    else if( !strcmp(Argv[1],"umode") )
-    { KdbHandleHandled = FALSE; KdbHandleUmode = TRUE; }
-    else if( !strcmp(Argv[1],"kmode") )
-    { KdbHandleHandled = FALSE; KdbHandleUmode = FALSE; }
-
-    return(TRUE);
+/*!\brief Internal function to enter KDB.
+ *
+ * Disables interrupts, releases display ownership, ...
+ */
+STATIC VOID
+KdbpInternalEnter()
+{  
+   PETHREAD Thread;
+   PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
+   ULONG SavedStackLimit;
+   
+   KbdDisableMouse();
+   if (KdDebugState & KD_DEBUG_SCREEN)
+   {
+      HalReleaseDisplayOwnership();
+   }
+
+   /* Call the interface's main loop on a different stack */
+   Thread = PsGetCurrentThread();
+   SavedInitialStack = Thread->Tcb.InitialStack;
+   SavedStackBase = Thread->Tcb.StackBase;
+   SavedStackLimit = Thread->Tcb.StackLimit;
+   SavedKernelStack = Thread->Tcb.KernelStack;
+   Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
+   Thread->Tcb.StackLimit = (ULONG)KdbStack;
+   Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
+
+   /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase);*/
+
+   KdbpStackSwitchAndCall(Thread->Tcb.KernelStack, KdbpCallMainLoop);
+
+   Thread->Tcb.InitialStack = SavedInitialStack;
+   Thread->Tcb.StackBase = SavedStackBase;
+   Thread->Tcb.StackLimit = SavedStackLimit;
+   Thread->Tcb.KernelStack = SavedKernelStack;
+   KbdEnableMouse();
 }
 
-ULONG
-DbgModuleLoadedAction(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
+/*!\brief KDB Exception filter
+ *
+ * Called by the exception dispatcher.
+ *
+ * \param ExceptionRecord  Unused.
+ * \param PreviousMode     UserMode if the exception was raised from umode, otherwise KernelMode.
+ * \param Context          Unused.
+ * \param TrapFrame        Exception TrapFrame.
+ * \param FirstChance      TRUE when called before exception frames were serached,
+ *                         FALSE for the second call.
+ *
+ * \returns KD_CONTINUE_TYPE
+ */
+KD_CONTINUE_TYPE
+KdbEnterDebuggerException(
+   IN PEXCEPTION_RECORD ExceptionRecord  OPTIONAL,
+   IN KPROCESSOR_MODE PreviousMode,
+   IN PCONTEXT Context  OPTIONAL,
+   IN OUT PKTRAP_FRAME TrapFrame,
+   IN BOOLEAN FirstChance)
 {
-    if (Argc == 1)
+   ULONG ExpNr = (ULONG)TrapFrame->DebugArgMark;
+   KDB_ENTER_CONDITION EnterCondition;
+   KD_CONTINUE_TYPE ContinueType = kdHandleException;
+   PKDB_BREAKPOINT BreakPoint;
+   ULONG ul;
+   ULONGLONG ull;
+   BOOLEAN Resume = FALSE;
+   BOOLEAN EnterConditionMet = TRUE;
+   ULONG OldEflags;
+
+   KdbCurrentProcess = PsGetCurrentProcess();
+
+   /* Set continue type to kdContinue for single steps and breakpoints */
+   if (ExpNr == 1 || ExpNr == 3)
+      ContinueType = kdContinue;
+
+   /* Check if we should handle the exception. */
+   ul = min(ExpNr, RTL_NUMBER_OF(KdbEnterConditions) - 1);
+   EnterCondition = KdbEnterConditions[ul][FirstChance ? 0 : 1];
+   if (EnterCondition == KdbDoNotEnter ||
+       (EnterCondition == KdbEnterFromUmode && PreviousMode != UserMode) ||
+       (EnterCondition == KdbEnterFromKmode && PreviousMode != KernelMode))
+   {
+      EnterConditionMet = FALSE;
+   }
+
+   /* If we stopped on one of our breakpoints then let the user know. */
+   KdbLastBreakPointNr = -1;
+   KdbEnteredOnSingleStep = FALSE;
+
+   if (FirstChance && (ExpNr == 1 || ExpNr == 3) &&
+       (KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExpNr, TrapFrame)) >= 0)
+   {
+      BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
+
+      if (ExpNr == 3)
       {
-       if (KdbBreakOnModuleLoad)
-          DbgPrint("Current setting: break\n");
-       else
-          DbgPrint("Current setting: continue\n");
+         /*
+          * The breakpoint will point to the next instruction by default so
+          * point it back to the start of original instruction.
+          */
+         TrapFrame->Eip--;
+
+         /*
+          * ... and restore the original instruction.
+          */
+         if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
+                                                  BreakPoint->Data.SavedInstruction, NULL)))
+         {
+            DbgPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
+            KEBUGCHECK(0);
+         }
       }
-    else if (!strcmp(Argv[1], "break"))
+
+      if ((BreakPoint->Type == KdbBreakPointHardware) &&
+          (BreakPoint->Data.Hw.AccessType == KdbAccessExec))
       {
-        KdbBreakOnModuleLoad = TRUE;
+         Resume = TRUE; /* Set the resume flag when continuing execution */
       }
-    else if (!strcmp(Argv[1], "continue"))
+      
+      /*
+       * When a temporary breakpoint is hit we have to make sure that we are
+       * in the same context in which it was set, otherwise it could happen
+       * that another process/thread hits it before and it gets deleted.
+       */
+      else if (BreakPoint->Type == KdbBreakPointTemporary &&
+               BreakPoint->Process == KdbCurrentProcess)
       {
-        KdbBreakOnModuleLoad = FALSE;
+         ASSERT((TrapFrame->Eflags & X86_EFLAGS_TF) == 0);
+         
+         /*
+          * Delete the temporary breakpoint which was used to step over or into the instruction.
+          */
+         KdbpDeleteBreakPoint(-1, BreakPoint);
+
+         if (--KdbNumSingleSteps > 0)
+         {
+            if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
+                (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
+            {
+               TrapFrame->Eflags |= X86_EFLAGS_TF;
+            }
+            goto continue_execution; /* return */
+         }
+
+         KdbEnteredOnSingleStep = TRUE;
       }
-    else
+
+      /*
+       * If we hit a breakpoint set by the debugger we set the single step flag,
+       * ignore the next single step and reenable the breakpoint.
+       */
+      else if (BreakPoint->Type == KdbBreakPointSoftware ||
+               BreakPoint->Type == KdbBreakPointTemporary)
       {
-        DbgPrint("Unknown setting: %s\n", Argv[1]);
+         ASSERT(ExpNr == 3);
+         TrapFrame->Eflags |= X86_EFLAGS_TF;
+         KdbBreakPointToReenable = BreakPoint;
+      }
+      
+      /*
+       * Make sure that the breakpoint should be triggered in this context
+       */
+      if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
+      {
+            goto continue_execution; /* return */
+      }
+      
+      /*
+       * Check if the condition for the breakpoint is met.
+       */
+      if (BreakPoint->Condition != NULL)
+      {
+         /* Setup the KDB trap frame */
+         RtlCopyMemory(&KdbTrapFrame.Tf, TrapFrame, sizeof (KTRAP_FRAME));
+         asm volatile(
+            "movl %%cr0, %0"    "\n\t"
+            "movl %%cr2, %1"    "\n\t"
+            "movl %%cr3, %2"    "\n\t"
+            "movl %%cr4, %3"    "\n\t"
+            : "=r"(KdbTrapFrame.Cr0), "=r"(KdbTrapFrame.Cr2),
+              "=r"(KdbTrapFrame.Cr3), "=r"(KdbTrapFrame.Cr4));
+
+         ull = 0;
+         if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
+         {
+            /* FIXME: Print warning? */
+         }
+         else if (ull == 0) /* condition is not met */
+         {
+            goto continue_execution; /* return */
+         }
       }
 
-    return(TRUE);
-}
-
-ULONG
-DbgEchoToggle(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  KbdEchoOn = !KbdEchoOn;
-  return(TRUE);
-}
+      if (BreakPoint->Type == KdbBreakPointSoftware)
+      {
+         DbgPrint("Entered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
+                  KdbLastBreakPointNr, TrapFrame->Cs & 0xffff, TrapFrame->Eip);
+      }
+      else if (BreakPoint->Type == KdbBreakPointHardware)
+      {
+         DbgPrint("Entered debugger on breakpoint #%d: %s 0x%08x\n",
+                  KdbLastBreakPointNr,
+                  (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
+                  ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
+                   ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")
+                  ),
+                  BreakPoint->Address
+                 );
 
-VOID
-DbgPrintEflags(ULONG Eflags)
-{
-  DbgPrint("EFLAGS:");
-  if (Eflags & (1 << 0))
-    {
-      DbgPrint(" CF");
-    }
-  if (!(Eflags & (1 << 1)))
-    {
-      DbgPrint(" !BIT1");
-    }
-  if (Eflags & (1 << 2))
-    {
-      DbgPrint(" PF");
-    }
-  if (Eflags & (1 << 3))
-    {
-      DbgPrint(" BIT3");
-    }
-  if (Eflags & (1 << 4))
-    {
-      DbgPrint(" AF");
-    }
-  if (Eflags & (1 << 5))
-    {
-      DbgPrint(" BIT5");
-    }
-  if (Eflags & (1 << 6))
-    {
-      DbgPrint(" ZF");
-    }
-  if (Eflags & (1 << 7))
-    {
-      DbgPrint(" SF");
-    }
-  if (Eflags & (1 << 8))
-    {
-      DbgPrint(" TF");
-    }
-  if (Eflags & (1 << 9))
-    {
-      DbgPrint(" IF");
-    }
-  if (Eflags & (1 << 10))
-    {
-      DbgPrint(" DF");
-    }
-  if (Eflags & (1 << 11))
-    {
-      DbgPrint(" OF");
-    }
-  if ((Eflags & ((1 << 12) | (1 << 13))) == 0)
-    {
-      DbgPrint(" IOPL0");
-    }
-  else if ((Eflags & ((1 << 12) | (1 << 13))) == 1)
-    {
-      DbgPrint(" IOPL1");
-    }
-  else if ((Eflags & ((1 << 12) | (1 << 13))) == 2)
-    {
-      DbgPrint(" IOPL2");
-    }
-  else if ((Eflags & ((1 << 12) | (1 << 13))) == 3)
-    {
-      DbgPrint(" IOPL3");
-    }
-  if (Eflags & (1 << 14))
-    {
-      DbgPrint(" NT");
-    }
-  if (Eflags & (1 << 15))
-    {
-      DbgPrint(" BIT15");
-    }
-  if (Eflags & (1 << 16))
-    {
-      DbgPrint(" RF");
-    }
-  if (Eflags & (1 << 17))
-    {
-      DbgPrint(" VF");
-    }
-  if (Eflags & (1 << 18))
-    {
-      DbgPrint(" AC");
-    }
-  if (Eflags & (1 << 19))
-    {
-      DbgPrint(" VIF");
-    }
-  if (Eflags & (1 << 20))
-    {
-      DbgPrint(" VIP");
-    }
-  if (Eflags & (1 << 21))
-    {
-      DbgPrint(" ID");
-    }
-  if (Eflags & (1 << 22))
-    {
-      DbgPrint(" BIT22");
-    }
-  if (Eflags & (1 << 23))
-    {
-      DbgPrint(" BIT23");
-    }
-  if (Eflags & (1 << 24))
-    {
-      DbgPrint(" BIT24");
-    }
-  if (Eflags & (1 << 25))
-    {
-      DbgPrint(" BIT25");
-    }
-  if (Eflags & (1 << 26))
-    {
-      DbgPrint(" BIT26");
-    }
-  if (Eflags & (1 << 27))
-    {
-      DbgPrint(" BIT27");
-    }
-  if (Eflags & (1 << 28))
-    {
-      DbgPrint(" BIT28");
-    }
-  if (Eflags & (1 << 29))
-    {
-      DbgPrint(" BIT29");
-    }
-  if (Eflags & (1 << 30))
-    {
-      DbgPrint(" BIT30");
-    }
-  if (Eflags & (1 << 31))
-    {
-      DbgPrint(" BIT31");
-    }
-  DbgPrint("\n");
-}
+      }
+   }
+   else if (ExpNr == 1)
+   {
+      /* Silently ignore a debugger initiated single step. */
+      if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable != NULL)
+      {
+         /* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
+         BreakPoint = KdbBreakPointToReenable;
+         KdbBreakPointToReenable = NULL;
+         ASSERT(BreakPoint->Type == KdbBreakPointSoftware ||
+                BreakPoint->Type == KdbBreakPointTemporary);
+
+         /*
+          * Reenable the breakpoint we disabled to execute the breakpointed
+          * instruction.
+          */
+         if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
+                                                  &BreakPoint->Data.SavedInstruction)))
+         {
+            DbgPrint("Warning: Couldn't reenable breakpoint %d\n",
+                     BreakPoint - KdbBreakPoints);
+         }
+
+         /* Unset TF if we are no longer single stepping. */
+         if (KdbNumSingleSteps == 0)
+            TrapFrame->Eflags &= ~X86_EFLAGS_TF;
+         goto continue_execution; /* return */
+      }
 
-ULONG
-DbgRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  DbgPrint("CS:EIP %.4x:%.8x, EAX %.8x EBX %.8x ECX %.8x EDX %.8x\n",
-          Tf->Cs & 0xFFFF, Tf->Eip, Tf->Eax, Tf->Ebx, Tf->Ecx, Tf->Edx);
-  DbgPrint("ESI %.8x EDI %.8x EBP %.8x SS:ESP %.4x:%.8x\n",
-          Tf->Esi, Tf->Edi, Tf->Ebp, Tf->Ss & 0xFFFF, Tf->Esp);
-  DbgPrintEflags(Tf->Eflags);
-  return(1);
-}
+      /* Check if we expect a single step */
+      if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
+      {
+         /*ASSERT((TrapFrame->Eflags & X86_EFLAGS_TF) != 0);*/
+         if (--KdbNumSingleSteps > 0)
+         {
+            if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
+                (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
+            {
+               TrapFrame->Eflags &= ~X86_EFLAGS_TF;
+            }
+            else
+            {
+               TrapFrame->Eflags |= X86_EFLAGS_TF;
+            }
+            goto continue_execution; /* return */
+         }
 
-ULONG
-DbgBugCheckCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  KEBUGCHECK(0xDEADDEAD);
-  return(1);
-}
+         TrapFrame->Eflags &= ~X86_EFLAGS_TF;
+         KdbEnteredOnSingleStep = TRUE;
+      }
+      else
+      {
+         if (!EnterConditionMet)
+         {
+            return ContinueType;
+         }
+         DbgPrint("Entered debugger on unexpected debug trap!\n");
+      }
+   }
+   else if (ExpNr == 3)
+   {
+      if (KdbInitFileBuffer != NULL)
+      {
+         KdbpCliInterpretInitFile();
+         EnterConditionMet = FALSE;
+      }
+      if (!EnterConditionMet)
+      {
+         return ContinueType;
+      }
 
-ULONG
-DbgShowFilesCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  DbgShowFiles();
-  return(1);
-}
+      DbgPrint("Entered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
+               TrapFrame->Cs & 0xffff, TrapFrame->Eip - 1);
+   }
+   else
+   {
+      CONST PCHAR ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
+                                    (ExceptionNrToString[ExpNr]) :
+                                    ("Unknown/User defined exception");
 
-ULONG
-DbgEnableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  if (Argc == 2)
-    {
-      if (strlen(Argv[1]) > 0)
-        {
-          DbgEnableFile(Argv[1]);
-        }
-    }
-  return(1);
-}
+      if (!EnterConditionMet)
+      {
+         return ContinueType;
+      }
 
-ULONG
-DbgDisableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf)
-{
-  if (Argc == 2)
-    {
-      if (strlen(Argv[1]) > 0)
-        {
-          DbgDisableFile(Argv[1]);
-        }
-    }
-  return(1);
-}
+      DbgPrint("Entered debugger on %s-chance exception number %d (%s)\n",
+               FirstChance ? "first" : "last", ExpNr, ExceptionString);
+      if (ExpNr == 14)
+      {
+         /* FIXME: Add noexec memory stuff */
+         ULONG Cr2, Err;
+         asm volatile("movl %%cr2, %0" : "=r"(Cr2));
+         Err = TrapFrame->ErrorCode;
+         DbgPrint("Memory at 0x%x could not be %s: ", Cr2, (Err & (1 << 1)) ? "written" : "read");
+         if ((Err & (1 << 0)) == 0)
+            DbgPrint("Page not present.\n");
+         else
+         {
+            if ((Err & (1 << 3)) != 0)
+               DbgPrint("Reserved bits in page directory set.\n");
+            else
+               DbgPrint("Page protection violation.\n");
+         }
+      }
+   }
+   
+   /* Once we enter the debugger we do not expect any more single steps to happen */
+   KdbNumSingleSteps = 0;
+   
+   /* Update the current process pointer */
+   KdbCurrentProcess = KdbOriginalProcess = PsGetCurrentProcess();
+   KdbCurrentThread = KdbOriginalThread = PsGetCurrentThread();
+   KdbCurrentTrapFrame = &KdbTrapFrame;
+
+   /* Setup the KDB trap frame */
+   RtlCopyMemory(&KdbTrapFrame.Tf, TrapFrame, sizeof(KTRAP_FRAME));
+   asm volatile(
+      "movl %%cr0, %0"    "\n\t"
+      "movl %%cr2, %1"    "\n\t"
+      "movl %%cr3, %2"    "\n\t"
+      "movl %%cr4, %3"    "\n\t"
+      : "=r"(KdbTrapFrame.Cr0), "=r"(KdbTrapFrame.Cr2),
+        "=r"(KdbTrapFrame.Cr3), "=r"(KdbTrapFrame.Cr4));
+
+   /* Enter critical section */
+   Ke386SaveFlags(OldEflags);
+   Ke386DisableInterrupts();
+
+   /* Exception inside the debugger? Game over. */
+   if (InterlockedIncrement(&KdbEntryCount) > 1)
+   {
+      Ke386RestoreFlags(OldEflags);
+      return kdHandleException;
+   }
+
+   /* Call the main loop. */
+   KdbpInternalEnter();
+
+   /* Check if we should single step */
+   if (KdbNumSingleSteps > 0)
+   {
+      if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
+          (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
+      {
+         ASSERT((KdbCurrentTrapFrame->Tf.Eflags & X86_EFLAGS_TF) == 0);
+         /*KdbCurrentTrapFrame->Tf.Eflags &= ~X86_EFLAGS_TF;*/
+      }
+      else
+      {
+         KdbCurrentTrapFrame->Tf.Eflags |= X86_EFLAGS_TF;
+      }
+   }
+
+   /* Save the current thread's trapframe */
+   if (KdbCurrentTrapFrame == &KdbThreadTrapFrame)
+   {
+      RtlCopyMemory(KdbCurrentThread->Tcb.TrapFrame, KdbCurrentTrapFrame, sizeof (KTRAP_FRAME));
+   }
+
+   /* Detach from attached process */
+   if (KdbCurrentProcess != KdbOriginalProcess)
+   {
+      KeUnstackDetachProcess(&KdbApcState);
+   }
+
+   /* Update the exception TrapFrame */
+   RtlCopyMemory(TrapFrame, &KdbTrapFrame.Tf, sizeof(KTRAP_FRAME));
+#if 0
+   asm volatile(
+      "movl %0, %%cr0"    "\n\t"
+      "movl %1, %%cr2"    "\n\t"
+      "movl %2, %%cr3"    "\n\t"
+      "movl %3, %%cr4"    "\n\t"
+      : : "r"(KdbTrapFrame.Cr0), "r"(KdbTrapFrame.Cr2),
+          "r"(KdbTrapFrame.Cr3), "r"(KdbTrapFrame.Cr4));
+#endif
+
+   /* Decrement the entry count */
+   InterlockedDecrement(&KdbEntryCount);
+
+   /* Leave critical section */
+   Ke386RestoreFlags(OldEflags);
+
+continue_execution:
+   /* Clear debug status */
+   if (ExpNr == 1 || ExpNr == 3) /* FIXME: Why clear DR6 on INT3? */
+   {
+      /* Set the RF flag so we don't trigger the same breakpoint again. */
+      if (Resume)
+      {
+         TrapFrame->Eflags |= X86_EFLAGS_RF;
+      }
+         
+      /* Clear dr6 status flags. */
+      TrapFrame->Dr6 &= ~0x0000e00f;
 
-VOID
-KdbCreateThreadHook(PCONTEXT Context)
-{
-  Context->Dr0 = x_dr0;
-  Context->Dr1 = x_dr1;
-  Context->Dr2 = x_dr2;
-  Context->Dr3 = x_dr3;
-  Context->Dr7 = x_dr7;
-}
+   }
 
-ULONG
-KdbDoCommand(PCH CommandLine, PKTRAP_FRAME Tf)
-{
-  ULONG i;
-  PCH s1;
-  PCH s;
-  static PCH Argv[256];
-  ULONG Argc;
-  static CHAR OrigCommand[256];
-
-  strcpy(OrigCommand, CommandLine);
-
-  Argc = 0;
-  s = CommandLine;
-  while ((s1 = strpbrk(s, "\t ")) != NULL)
-    {
-      Argv[Argc] = s;
-      *s1 = 0;
-      s = s1 + 1;
-      Argc++;
-    }
-  Argv[Argc] = s;
-  Argc++;
-
-  for (i = 0; DebuggerCommands[i].Name != NULL; i++)
-    {
-      if (strcmp(DebuggerCommands[i].Name, Argv[0]) == 0)
-       {
-         return(DebuggerCommands[i].Fn(Argc, Argv, Tf));
-       }
-    }
-  DbgPrint("Command '%s' is unknown.", OrigCommand);
-  return(1);
+   return ContinueType;
 }
 
 VOID
-KdbMainLoop(PKTRAP_FRAME Tf)
+KdbInit()
 {
-  CHAR Command[256];
-  ULONG s;
-
-  if (!KdbEnteredOnSingleStep)
-    {
-      DbgPrint("\nEntered kernel debugger (type \"help\" for a list of commands)\n");
-    }
-  else
-    {
-      if (!KdbSymPrintAddress((PVOID)Tf->Eip))
-       {
-         DbgPrint("<%x>", Tf->Eip);
-       }
-      DbgPrint(": ");
-      if (KdbDisassemble(Tf->Eip) < 0)
-       {
-         DbgPrint("<INVALID>");
-       }
-      KdbEnteredOnSingleStep = FALSE;
-      KdbLastSingleStepFrom = 0xFFFFFFFF;
-    }
-
-  do
-    {
-      DbgPrint("\nkdb:> ");
-
-      KdbGetCommand(Command);
-      s = KdbDoCommand(Command, Tf);    
-    } while (s != 0);
+   KdbpCliInit();
 }
 
 VOID
-KdbInternalEnter(PKTRAP_FRAME Tf)
-{  
-  __asm__ __volatile__ ("cli\n\t");
-  KbdDisableMouse();
-  if (KdDebugState & KD_DEBUG_SCREEN)
-    {
-      HalReleaseDisplayOwnership();
-    }
-  (VOID)KdbMainLoop(Tf);
-  KbdEnableMouse();
-  __asm__ __volatile__("sti\n\t");
-}
-
-KD_CONTINUE_TYPE
-KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
-                         KPROCESSOR_MODE PreviousMode,
-                         PCONTEXT Context,
-                         PKTRAP_FRAME TrapFrame,
-                         BOOLEAN AlwaysHandle)
+KdbDeleteProcessHook(IN PEPROCESS Process)
 {
-  LONG BreakPointNr;
-  ULONG ExpNr = (ULONG)TrapFrame->DebugArgMark;
-
-  /* Always handle beakpoints */
-  if (ExpNr != 1 && ExpNr != 3)
-    {
-      DbgPrint(":KDBG:Entered:%s:%s\n",
-               PreviousMode==KernelMode ? "kmode" : "umode",
-               AlwaysHandle ? "always" : "if-unhandled");
-
-      /* If we aren't handling umode exceptions then return */
-      if (PreviousMode == UserMode && !KdbHandleUmode && !AlwaysHandle)
-        {
-          return kdHandleException;
-        }
-
-      /* If the exception would be unhandled (and we care) then handle it */
-      if (PreviousMode == KernelMode && !KdbHandleHandled && !AlwaysHandle)
-        {
-          return kdHandleException;
-        }
-    }
-
-  /* Exception inside the debugger? Game over. */
-  if (KdbEntryCount > 0)
-    {
-      return(kdHandleException);
-    }
-  KdbEntryCount++;
-
-  /* Clear the single step flag. */
-  TrapFrame->Eflags &= ~(1 << 8);
-  /* 
-     Reenable any breakpoints we disabled so we could execute the breakpointed
-     instructions.
-  */
-  KdbRenableBreakPoints();
-  /* Silently ignore a debugger initiated single step. */
-  if (ExpNr == 1 && KdbIgnoreNextSingleStep)
-    {      
-      KdbIgnoreNextSingleStep = FALSE;
-      KdbEntryCount--;
-      return(kdContinue);
-    }
-  /* If we stopped on one of our breakpoints then let the user know. */
-  if (ExpNr == 3 && (BreakPointNr = KdbIsBreakPointOurs(TrapFrame)) >= 0)
-    {
-      DbgPrint("Entered debugger on breakpoint %d.\n", BreakPointNr);
-      /*
-       The breakpoint will point to the next instruction by default so
-       point it back to the start of original instruction.
-      */
-      TrapFrame->Eip--;
-      /*
-       ..and restore the original instruction.
-      */
-      (VOID)KdbOverwriteInst(TrapFrame->Eip, NULL,
-                            KdbActiveBreakPoints[BreakPointNr].SavedInst);
-      /*
-       If this was a breakpoint set by the debugger then delete it otherwise
-       flag to enable it again after we step over this instruction.
-      */
-      if (KdbActiveBreakPoints[BreakPointNr].Temporary)
-       {
-         KdbActiveBreakPoints[BreakPointNr].Assigned = FALSE;
-         KdbBreakPointCount--;
-         KdbEnteredOnSingleStep = TRUE;
-       }
-      else
-       {
-         KdbActiveBreakPoints[BreakPointNr].Enabled = FALSE;
-         TrapFrame->Eflags |= (1 << 8);
-         KdbIgnoreNextSingleStep = TRUE;
-       }
-    }
-  else if (ExpNr == 1)
-    {
-      if ((TrapFrame->Dr6 & 0xF) != 0)
-       {
-         DbgPrint("Entered debugger on memory breakpoint(s) %s%s%s%s.\n",
-                  (TrapFrame->Dr6 & 0x1) ? "1" : "",
-                  (TrapFrame->Dr6 & 0x2) ? "2" : "",
-                  (TrapFrame->Dr6 & 0x4) ? "3" : "",
-                  (TrapFrame->Dr6 & 0x8) ? "4" : "");
-       }
-      else if (KdbLastSingleStepFrom != 0xFFFFFFFF)
-       {
-         KdbEnteredOnSingleStep = TRUE;
-       }
-      else
-       {
-         DbgPrint("Entered debugger on unexpected debug trap.\n");
-       }
-    }
-  else
-    {
-      const char *ExceptionString =
-         (ExpNr < (sizeof (ExceptionTypeStrings) / sizeof (ExceptionTypeStrings[0]))) ?
-         (ExceptionTypeStrings[ExpNr]) :
-         ("Unknown/User defined exception");
-      DbgPrint("Entered debugger on exception number %d (%s)\n", ExpNr, ExceptionString);
-    }
-  KdbInternalEnter(TrapFrame);
-  KdbEntryCount--;
-  if (ExpNr != 1 && ExpNr != 3)
-    {
-      return(kdHandleException);
-    }
-  else
-    {
-      /* Clear dr6 status flags. */
-      TrapFrame->Dr6 &= 0xFFFF1F00;
-      /* Set the RF flag to we don't trigger the same breakpoint again. */
-      if (ExpNr == 1)
-       {
-         TrapFrame->Eflags |= (1 << 16);
-       }
-      return(kdContinue);
-    }
+   KdbSymFreeProcessSymbols(Process);
+   
+   /* FIXME: Delete breakpoints for process */
 }
 
 VOID
 KdbModuleLoaded(IN PUNICODE_STRING Name)
 {
-  if (!KdbBreakOnModuleLoad)
-    return;
-    
-  DbgPrint("Module %wZ loaded.\n", Name);
-  DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
+   KdbpCliModuleLoaded(Name);
 }
 
+
index 46c0876..c9b631d 100644 (file)
@@ -1,6 +1,82 @@
+#ifndef NTOSKRNL_KDB_H
+#define NTOSKRNL_KDB_H
+
+/* INCLUDES ******************************************************************/
+
 #define NTOS_MODE_KERNEL
 #include <ntos.h>
 
+#include <internal/ke.h>
+
+/* DEFINES *******************************************************************/
+
+#define TAG_KDBG        (('K' << 24) | ('D' << 16) | ('B' << 8) | 'G')
+
+#ifndef RTL_NUMBER_OF
+# define RTL_NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+
+/* TYPES *********************************************************************/
+
+/* from kdb.c */
+typedef struct _KDB_KTRAP_FRAME
+{
+   KTRAP_FRAME  Tf;
+   ULONG        Cr0;
+   ULONG        Cr1; /* reserved/unused */
+   ULONG        Cr2;
+   ULONG        Cr3;
+   ULONG        Cr4;
+} KDB_KTRAP_FRAME, *PKDB_KTRAP_FRAME;
+
+typedef enum _KDB_BREAKPOINT_TYPE
+{
+   KdbBreakPointNone = 0,
+   KdbBreakPointSoftware,
+   KdbBreakPointHardware,
+   KdbBreakPointTemporary
+} KDB_BREAKPOINT_TYPE;
+
+typedef enum _KDB_ACCESS_TYPE
+{
+   KdbAccessRead,
+   KdbAccessWrite,
+   KdbAccessReadWrite,
+   KdbAccessExec
+} KDB_ACCESS_TYPE;
+
+typedef struct _KDB_BREAKPOINT
+{
+   KDB_BREAKPOINT_TYPE    Type;         /* Type of breakpoint */
+   BOOLEAN                Enabled;      /* Whether the bp is enabled */
+   ULONG_PTR              Address;      /* Address of the breakpoint */
+   BOOLEAN                Global;       /* Whether the breakpoint is global or local to a process */
+   PEPROCESS              Process;      /* Owning process */
+   PCHAR                  ConditionExpression;
+   PVOID                  Condition;
+   union {
+      /* KdbBreakPointSoftware */
+      UCHAR               SavedInstruction;
+      /* KdbBreakPointHardware */
+      struct {
+         UCHAR            DebugReg : 2;
+         UCHAR            Size : 3;
+         KDB_ACCESS_TYPE  AccessType;
+      } Hw;
+   } Data;
+} KDB_BREAKPOINT, *PKDB_BREAKPOINT;
+
+typedef enum _KDB_ENTER_CONDITION
+{
+   KdbDoNotEnter,
+   KdbEnterAlways,
+   KdbEnterFromKmode,
+   KdbEnterFromUmode
+} KDB_ENTER_CONDITION;
+
+
+/* from kdb_symbols.c */
 typedef struct _KDB_MODULE_INFO
 {
     WCHAR        Name[256];
@@ -9,6 +85,74 @@ typedef struct _KDB_MODULE_INFO
     PROSSYM_INFO RosSymInfo;
 } KDB_MODULE_INFO, *PKDB_MODULE_INFO;
 
+
+/* FUNCTIONS *****************************************************************/
+
+/* from i386/i386-dis.c */
+
+LONG
+KdbpDisassemble(
+   IN ULONG Address,
+   IN ULONG IntelSyntax);
+   
+LONG
+KdbpGetInstLength(
+   IN ULONG Address);
+
+/* from i386/kdb_help.S */
+
+STDCALL VOID
+KdbpStackSwitchAndCall(
+   IN PVOID NewStack,
+   IN VOID (*Function)(VOID));
+
+/* from kdb_cli.c */
+
+extern PCHAR KdbInitFileBuffer;
+
+VOID
+KdbpCliInit();
+
+VOID
+KdbpCliMainLoop(
+   IN BOOLEAN EnteredOnSingleStep);
+
+VOID
+KdbpCliModuleLoaded(
+   IN PUNICODE_STRING Name);
+
+VOID
+KdbpCliInterpretInitFile();
+
+VOID
+KdbpPrint(
+   IN PCHAR Format,
+   IN ...  OPTIONAL);
+
+/* from kdb_expr.c */
+
+BOOLEAN
+KdbpRpnEvaluateExpression(
+   IN  PCHAR Expression,
+   IN  PKDB_KTRAP_FRAME TrapFrame,
+   OUT PULONGLONG Result,
+   OUT PLONG ErrOffset  OPTIONAL,
+   OUT PCHAR ErrMsg  OPTIONAL);
+
+PVOID
+KdbpRpnParseExpression(
+   IN  PCHAR Expression,
+   OUT PLONG ErrOffset  OPTIONAL,
+   OUT PCHAR ErrMsg  OPTIONAL);
+
+BOOLEAN
+KdbpRpnEvaluateParsedExpression(
+   IN  PVOID Expression,
+   IN  PKDB_KTRAP_FRAME TrapFrame,
+   OUT PULONGLONG Result,
+   OUT PLONG ErrOffset  OPTIONAL,
+   OUT PCHAR ErrMsg  OPTIONAL);
+
 /* from kdb_symbols.c */
 
 BOOLEAN
@@ -33,13 +177,97 @@ KdbSymGetAddressInformation(IN PROSSYM_INFO  RosSymInfo,
                             OUT PCH FileName  OPTIONAL,
                             OUT PCH FunctionName  OPTIONAL);
 
+/* from kdb.c */
+
+extern PEPROCESS KdbCurrentProcess;
+extern PETHREAD KdbCurrentThread;
+extern LONG KdbLastBreakPointNr;
+extern ULONG KdbNumSingleSteps;
+extern BOOLEAN KdbSingleStepOver;
+extern PKDB_KTRAP_FRAME KdbCurrentTrapFrame;
+
+VOID
+KdbInit();
+
+VOID
+KdbModuleLoaded(
+   IN PUNICODE_STRING Name);
+
+LONG
+KdbpGetNextBreakPointNr(
+   IN ULONG Start  OPTIONAL);
+
+BOOLEAN
+KdbpGetBreakPointInfo(
+   IN  ULONG BreakPointNr,
+   OUT ULONG_PTR *Address  OPTIONAL,
+   OUT KDB_BREAKPOINT_TYPE *Type  OPTIONAL,
+   OUT UCHAR *Size  OPTIONAL,
+   OUT KDB_ACCESS_TYPE *AccessType  OPTIONAL,
+   OUT UCHAR *DebugReg  OPTIONAL,
+   OUT BOOLEAN *Enabled  OPTIONAL,
+   OUT BOOLEAN *Global  OPTIONAL,
+   OUT PEPROCESS *Process  OPTIONAL,
+   OUT PCHAR *ConditionExpression  OPTIONAL);
+
+NTSTATUS
+KdbpInsertBreakPoint(
+   IN  ULONG_PTR Address,
+   IN  KDB_BREAKPOINT_TYPE Type,
+   IN  UCHAR Size  OPTIONAL,
+   IN  KDB_ACCESS_TYPE AccessType  OPTIONAL,
+   IN  PCHAR ConditionExpression  OPTIONAL,
+   IN  BOOLEAN Global,
+   OUT PULONG BreakPointNumber  OPTIONAL);
+   
+BOOLEAN
+KdbpDeleteBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL);
+
+BOOLEAN
+KdbpEnableBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL);
+
+BOOLEAN
+KdbpDisableBreakPoint(
+   IN LONG BreakPointNr  OPTIONAL,
+   IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL);
+
+BOOLEAN
+KdbpGetEnterCondition(
+   IN LONG ExceptionNr,
+   IN BOOLEAN FirstChance,
+   OUT KDB_ENTER_CONDITION *Condition);
+
+BOOLEAN
+KdbpSetEnterCondition(
+   IN LONG ExceptionNr,
+   IN BOOLEAN FirstChance,
+   IN KDB_ENTER_CONDITION Condition);
+
+BOOLEAN
+KdbpAttachToThread(
+   PVOID ThreadId);
+
+BOOLEAN
+KdbpAttachToProcess(
+   PVOID ProcessId);
+
 /* other functions */
-#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
-#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
+
+#define KdbpSafeReadMemory(dst, src, size)   MmSafeCopyFromUser(dst, src, size)
+#define KdbpSafeWriteMemory(dst, src, size)  MmSafeCopyToUser(dst, src, size)
+
+#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard(ScanCode, 0)
 CHAR
-KdbTryGetCharKeyboard(PULONG ScanCode);
-ULONG
-KdbTryGetCharSerial(VOID);
+KdbpTryGetCharKeyboard(PULONG ScanCode, UINT Retry);
+
+#define KdbpGetCharSerial()  KdbpTryGetCharSerial(0)
+CHAR
+KdbpTryGetCharSerial(UINT Retry);
+
 VOID
 KdbEnter(VOID);
 VOID
@@ -50,24 +278,7 @@ VOID
 DbgEnableFile(PCH Filename);
 VOID
 DbgDisableFile(PCH Filename);
-VOID
-KdbInitProfiling();
-VOID
-KdbInitProfiling2();
-VOID
-KdbDisableProfiling();
-VOID
-KdbEnableProfiling();
-VOID
-KdbProfileInterrupt(ULONG_PTR Eip);
 
-VOID
-KdbModuleLoaded(IN PUNICODE_STRING Name);
 
+#endif /* NTOSKRNL_KDB_H */
 
-struct KDB_BPINFO {
-    DWORD Addr;
-    DWORD Type;
-    DWORD Size;
-    DWORD Enabled;
-};
diff --git a/reactos/ntoskrnl/dbg/kdb_cli.c b/reactos/ntoskrnl/dbg/kdb_cli.c
new file mode 100644 (file)
index 0000000..75f2c78
--- /dev/null
@@ -0,0 +1,2368 @@
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2005 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$
+ *
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/dbg/kdb_cli.c
+ * PURPOSE:         Kernel debugger command line interface
+ * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)
+ * UPDATE HISTORY:
+ *                  Created 16/01/2005
+ */
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#include <ctype.h>
+#include "kdb.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* DEFINES *******************************************************************/
+
+#define KEY_BS          8
+#define KEY_ESC         27
+#define KEY_DEL         127
+
+#define KEY_SCAN_UP     72
+#define KEY_SCAN_DOWN   80
+
+#define KDB_ENTER_CONDITION_TO_STRING(cond)                               \
+                   ((cond) == KdbDoNotEnter ? "never" :                   \
+                   ((cond) == KdbEnterAlways ? "always" :                 \
+                   ((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
+
+#define KDB_ACCESS_TYPE_TO_STRING(type)                                   \
+                   ((type) == KdbAccessRead ? "read" :                    \
+                   ((type) == KdbAccessWrite ? "write" :                  \
+                   ((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
+
+#define NPX_STATE_TO_STRING(state)                                        \
+                   ((state) == NPX_STATE_INVALID ? "Invalid" :            \
+                   ((state) == NPX_STATE_VALID ? "Valid" :                \
+                   ((state) == NPX_STATE_DIRTY ? "Dirty" : "Unknown")))
+
+/* PROTOTYPES ****************************************************************/
+
+STATIC BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]);
+
+STATIC BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]);
+
+STATIC BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
+
+STATIC BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
+
+STATIC BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
+STATIC BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
+
+/* GLOBALS *******************************************************************/
+
+STATIC BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
+
+STATIC CHAR KdbCommandHistoryBuffer[2048]; /* Command history string ringbuffer */
+STATIC PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL }; /* Command history ringbuffer */
+STATIC LONG KdbCommandHistoryBufferIndex = 0;
+STATIC LONG KdbCommandHistoryIndex = 0;
+
+STATIC ULONG KdbNumberOfRowsPrinted = 0;
+STATIC ULONG KdbNumberOfColsPrinted = 0;
+STATIC BOOLEAN KdbOutputAborted = FALSE;
+STATIC LONG KdbNumberOfRowsTerminal = -1;
+STATIC LONG KdbNumberOfColsTerminal = -1;
+
+PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
+
+STATIC CONST struct
+{
+   PCHAR Name;
+   PCHAR Syntax;
+   PCHAR Help;
+   BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
+} KdbDebuggerCommands[] = {
+   /* Data */
+   { NULL, NULL, "Data", NULL },
+   { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
+   { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
+   { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX },
+   { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
+   { "cregs", "cregs", "Display control registers.", KdbpCmdRegs },
+   { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
+   { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
+   { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
+
+   /* Flow control */
+   { NULL, NULL, "Flow control", NULL },
+   { "cont", "cont", "Continue execution (leave debugger)", KdbpCmdContinue },
+   { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
+   { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
+   { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
+   { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+   { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+   { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
+   { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
+   { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
+
+   /* Process/Thread */
+   { NULL, NULL, "Process/Thread", NULL },
+   { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
+   { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
+
+   /* System information */
+   { NULL, NULL, "System info", NULL },
+   { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
+   { "gdt", "gdt", "Display global descriptor table.", KdbpCmdGdtLdtIdt },
+   { "ldt", "ldt", "Display local descriptor table.", KdbpCmdGdtLdtIdt },
+   { "idt", "idt", "Display interrupt descriptor table.", KdbpCmdGdtLdtIdt },
+   { "pcr", "pcr", "Display processor control region.", KdbpCmdPcr },
+   { "tss", "tss", "Display task state segment.", KdbpCmdTss },
+
+   /* Others */
+   { NULL, NULL, "Others", NULL },
+   { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
+   { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
+   { "help", "help", "Display help screen.", KdbpCmdHelp }
+};
+
+/* FUNCTIONS *****************************************************************/
+
+/*!\brief Evaluates an expression...
+ *
+ * Much like KdbpRpnEvaluateExpression, but prints the error message (if any)
+ * at the given offset.
+ *
+ * \param Expression  Expression to evaluate.
+ * \param ErrOffset   Offset (in characters) to print the error message at.
+ * \param Result      Receives the result on success.
+ *
+ * \retval TRUE   Success.
+ * \retval FALSE  Failure.
+ */
+STATIC BOOLEAN
+KdbpEvaluateExpression(
+   IN  PCHAR Expression,
+   IN  LONG ErrOffset,
+   OUT PULONGLONG Result)
+{
+   STATIC CHAR ErrMsgBuffer[130] = "^ ";
+   LONG ExpressionErrOffset = -1;
+   PCHAR ErrMsg = ErrMsgBuffer;
+   BOOLEAN Ok;
+
+   Ok = KdbpRpnEvaluateExpression(Expression, KdbCurrentTrapFrame, Result,
+                                  &ExpressionErrOffset, ErrMsgBuffer + 2);
+   if (!Ok)
+   {
+      if (ExpressionErrOffset >= 0)
+         ExpressionErrOffset += ErrOffset;
+      else
+         ErrMsg += 2;
+      KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
+   }
+   
+   return Ok;
+}
+
+/*!\brief Evaluates an expression and displays the result.
+ */
+STATIC BOOLEAN
+KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
+{
+   INT i, len;
+   ULONGLONG Result = 0;
+   ULONG ul;
+   LONG l = 0;
+   BOOLEAN Ok;
+
+   if (Argc < 2)
+   {
+      KdbpPrint("?: Argument required\n");
+      return TRUE;
+   }
+   
+   /* Put the arguments back together */
+   Argc--;
+   for (i = 1; i < Argc; i++)
+   {
+      len = strlen(Argv[i]);
+      Argv[i][len] = ' ';
+   }
+   
+   /* Evaluate the expression */
+   Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
+   if (Ok)
+   {
+      if (Result > 0x00000000ffffffffLL)
+      {
+         if (Result & 0x8000000000000000LL)
+            KdbpPrint("0x%016I64x  %20I64u  %20I64d\n", Result, Result, Result);
+         else
+            KdbpPrint("0x%016I64x  %20I64u\n", Result, Result);
+      }
+      else
+      {
+         ul = (ULONG)Result;
+         if (ul <= 0xff && ul >= 0x80)
+            l = (LONG)((CHAR)ul);
+         else if (ul <= 0xffff && ul >= 0x8000)
+            l = (LONG)((SHORT)ul);
+         else
+            l = (LONG)ul;
+         if (l < 0)
+            KdbpPrint("0x%08lx  %10lu  %10ld\n", ul, ul, l);
+         else
+            KdbpPrint("0x%08lx  %10lu\n", ul, ul);
+      }
+   }
+   
+   return TRUE;
+}
+
+/*!\brief Disassembles 10 instructions at eip or given address or
+ *        displays 16 dwords from memory at given address.
+ */
+STATIC BOOLEAN
+KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[])
+{
+   ULONG Count;
+   ULONG ul;
+   INT i;
+   ULONGLONG Result = 0;
+   ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip;
+   LONG InstLen;
+
+   if (Argv[0][0] == 'x') /* display memory */
+      Count = 16;
+   else /* disassemble */
+      Count = 10;
+
+   if (Argc >= 2)
+   {
+      /* Check for [L count] part */
+      ul = 0;
+      if (strcmp(Argv[Argc-2], "L") == 0)
+      {
+         ul = strtoul(Argv[Argc-1], NULL, 0);
+         if (ul > 0)
+         {
+            Count = ul;
+            Argc -= 2;
+         }
+      }
+      else if (Argv[Argc-1][0] == 'L')
+      {
+         ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
+         if (ul > 0)
+         {
+            Count = ul;
+            Argc--;
+         }
+      }
+
+      /* Put the remaining arguments back together */
+      Argc--;
+      for (ul = 1; ul < Argc; ul++)
+      {
+         Argv[ul][strlen(Argv[ul])] = ' ';
+      }
+      Argc++;
+   }
+
+   /* Evaluate the expression */
+   if (Argc > 1)
+   {
+      if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+         return TRUE;
+      if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+         KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+      Address = (ULONG_PTR)Result;
+   }
+   else if (Argv[0][0] == 'x')
+   {
+      KdbpPrint("x: Address argument required.\n");
+      return TRUE;
+   }
+
+   if (Argv[0][0] == 'x')
+   {
+      /* Display dwords */
+      ul = 0;
+      while (Count > 0)
+      {
+         if (!KdbSymPrintAddress((PVOID)Address))
+            KdbpPrint("<%x>:", Address);
+         else
+            KdbpPrint(":");
+         i = min(4, Count);
+         Count -= i;
+         while (--i >= 0)
+         {
+            if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
+               KdbpPrint(" ????????");
+            else
+               KdbpPrint(" %08x", ul);
+            Address += sizeof(ul);
+         }
+         KdbpPrint("\n");
+      }
+   }
+   else
+   {
+      /* Disassemble */
+      while (Count-- > 0)
+      {
+         if (!KdbSymPrintAddress((PVOID)Address))
+            KdbpPrint("<%08x>: ", Address);
+         else
+            KdbpPrint(": ");
+         InstLen = KdbpDisassemble(Address, KdbUseIntelSyntax);
+         if (InstLen < 0)
+         {
+            KdbpPrint("<INVALID>\n");
+            return TRUE;
+         }
+         KdbpPrint("\n");
+         Address += InstLen;
+      }
+   }
+
+   return TRUE;
+}
+
+/*!\brief Displays CPU registers.
+ */
+STATIC BOOLEAN
+KdbpCmdRegs(ULONG Argc, PCHAR Argv[])
+{
+   PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf;
+   INT i;
+   STATIC CONST PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
+                                         " ZF", " SF", " TF", " IF", " DF", " OF",
+                                         NULL, NULL, " NT", " BIT15", " RF", " VF",
+                                         " AC", " VIF", " VIP", " ID", " BIT22",
+                                         " BIT23", " BIT24", " BIT25", " BIT26",
+                                         " BIT27", " BIT28", " BIT29", " BIT30",
+                                         " BIT31" };
+
+   if (Argv[0][0] == 'r') /* regs */
+   {
+      KdbpPrint("CS:EIP  0x%04x:0x%08x\n"
+                "SS:ESP  0x%04x:0x%08x\n"
+                "   EAX  0x%08x   EBX  0x%08x\n"
+                "   ECX  0x%08x   EDX  0x%08x\n"
+                "   ESI  0x%08x   EDI  0x%08x\n"
+                "   EBP  0x%08x\n",
+                Tf->Cs & 0xFFFF, Tf->Eip,
+                Tf->Ss, Tf->Esp,
+                Tf->Eax, Tf->Ebx,
+                Tf->Ecx, Tf->Edx,
+                Tf->Esi, Tf->Edi,
+                Tf->Ebp);
+      KdbpPrint("EFLAGS  0x%08x ", Tf->Eflags);
+      for (i = 0; i < 32; i++)
+      {
+         if (i == 1)
+         {
+            if ((Tf->Eflags & (1 << 1)) == 0)
+               KdbpPrint(" !BIT1");
+         }
+         else if (i == 12)
+         {
+            KdbpPrint(" IOPL%d", (Tf->Eflags >> 12) & 3);
+         }
+         else if (i == 13)
+         {
+         }
+         else if ((Tf->Eflags & (1 << i)) != 0)
+            KdbpPrint(EflagsBits[i]);
+      }
+      KdbpPrint("\n");
+   }
+   else if (Argv[0][0] == 'c') /* cregs */
+   {
+      ULONG Cr0, Cr2, Cr3, Cr4;
+      struct __attribute__((packed)) {
+         USHORT Limit;
+         ULONG Base;
+      } Gdtr, Ldtr, Idtr;
+      ULONG Tr;
+      STATIC CONST PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                         " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
+      STATIC CONST PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
+                                         " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+                                         
+      Cr0 = KdbCurrentTrapFrame->Cr0;
+      Cr2 = KdbCurrentTrapFrame->Cr2;
+      Cr3 = KdbCurrentTrapFrame->Cr3;
+      Cr4 = KdbCurrentTrapFrame->Cr4;
+
+      /* Get descriptor table regs */
+      asm volatile("sgdt %0" : : "m"(Gdtr));
+      asm volatile("sldt %0" : : "m"(Ldtr));
+      asm volatile("sidt %0" : : "m"(Idtr));
+
+      /* Get the task register */
+      asm volatile("str %0" : "=g"(Tr));
+      
+      /* Display the control registers */
+      KdbpPrint("CR0  0x%08x ", Cr0);
+      for (i = 0; i < 32; i++)
+      {
+         if (Cr0Bits[i] == NULL)
+            continue;
+         if ((Cr0 & (1 << i)) != 0)
+            KdbpPrint(Cr0Bits[i]);
+      }
+      KdbpPrint("\nCR2  0x%08x\n", Cr2);
+      KdbpPrint("CR3  0x%08x  Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
+                (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
+      KdbpPrint("CR4  0x%08x ", Cr4);
+      for (i = 0; i < 32; i++)
+      {
+         if (Cr4Bits[i] == NULL)
+            continue;
+         if ((Cr4 & (1 << i)) != 0)
+            KdbpPrint(Cr4Bits[i]);
+      }
+      
+      /* Display the descriptor table regs */
+      KdbpPrint("\nGDTR  Base 0x%08x  Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
+      KdbpPrint("LDTR  Base 0x%08x  Size 0x%04x\n", Ldtr.Base, Ldtr.Limit);
+      KdbpPrint("IDTR  Base 0x%08x  Size 0x%04x\n", Idtr.Base, Idtr.Limit);
+   }
+   else if (Argv[0][0] == 's') /* sregs */
+   {
+      KdbpPrint("CS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Cs & 0xffff, (Tf->Cs & 0xffff) >> 3,
+                (Tf->Cs & (1 << 2)) ? 'L' : 'G', Tf->Cs & 3);
+      KdbpPrint("DS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Ds, Tf->Ds >> 3, (Tf->Ds & (1 << 2)) ? 'L' : 'G', Tf->Ds & 3);
+      KdbpPrint("ES  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Es, Tf->Es >> 3, (Tf->Es & (1 << 2)) ? 'L' : 'G', Tf->Es & 3);
+      KdbpPrint("FS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Fs, Tf->Fs >> 3, (Tf->Fs & (1 << 2)) ? 'L' : 'G', Tf->Fs & 3);
+      KdbpPrint("GS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Gs, Tf->Gs >> 3, (Tf->Gs & (1 << 2)) ? 'L' : 'G', Tf->Gs & 3);
+      KdbpPrint("SS  0x%04x  Index 0x%04x  %cDT RPL%d\n",
+                Tf->Ss, Tf->Ss >> 3, (Tf->Ss & (1 << 2)) ? 'L' : 'G', Tf->Ss & 3);
+   }
+   else /* dregs */
+   {
+      ASSERT(Argv[0][0] == 'd');
+      KdbpPrint("DR0  0x%08x\n"
+                "DR1  0x%08x\n"
+                "DR2  0x%08x\n"
+                "DR3  0x%08x\n"
+                "DR6  0x%08x\n"
+                "DR7  0x%08x\n",
+                Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3,
+                Tf->Dr6, Tf->Dr7);
+   }
+   return TRUE;
+}
+
+/*!\brief Displays a backtrace.
+ */
+STATIC BOOLEAN
+KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
+{
+   ULONG Count;
+   ULONG ul;
+   ULONGLONG Result = 0;
+   ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
+   ULONG_PTR Address;
+
+   if (Argc >= 2)
+   {
+      /* Check for [L count] part */
+      ul = 0;
+      if (strcmp(Argv[Argc-2], "L") == 0)
+      {
+         ul = strtoul(Argv[Argc-1], NULL, 0);
+         if (ul > 0)
+         {
+            Count = ul;
+            Argc -= 2;
+         }
+      }
+      else if (Argv[Argc-1][0] == 'L')
+      {
+         ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
+         if (ul > 0)
+         {
+            Count = ul;
+            Argc--;
+         }
+      }
+
+      /* Put the remaining arguments back together */
+      Argc--;
+      for (ul = 1; ul < Argc; ul++)
+      {
+         Argv[ul][strlen(Argv[ul])] = ' ';
+      }
+      Argc++;
+   }
+
+   /* Check if frame addr or thread id is given. */
+   if (Argc > 1)
+   {
+      if (Argv[1][0] == '*')
+      {
+         Argv[1]++;
+         /* Evaluate the expression */
+         if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+            return TRUE;
+         if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+            KdbpPrint("Warning: Address %I64x is beeing truncated\n");
+         Frame = (ULONG_PTR)Result;
+      }
+      else
+      {
+
+         KdbpPrint("Thread backtrace not supported yet!\n");
+         return TRUE;
+      }
+   }
+
+   KdbpPrint("Frames:\n");
+   while (Frame != 0)
+   {
+      if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof (ULONG_PTR))))
+      {
+         KdbpPrint("Couldn't access memory at 0x%x!\n", Frame + sizeof(ULONG_PTR));
+         break;
+      }
+      if (!KdbSymPrintAddress((PVOID)Address))
+         KdbpPrint("<%08x>\n", Address);
+      else
+         KdbpPrint("\n");
+      if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR))))
+      {
+         KdbpPrint("Couldn't access memory at 0x%x!\n", Frame);
+         break;
+      }
+   }
+   
+   return TRUE;
+}
+
+/*!\brief Continues execution of the system/leaves KDB.
+ */
+STATIC BOOLEAN
+KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
+{
+   /* Exit the main loop */
+   return FALSE;
+}
+
+/*!\brief Continues execution of the system/leaves KDB.
+ */
+STATIC BOOLEAN
+KdbpCmdStep(ULONG Argc, PCHAR Argv[])
+{
+   ULONG Count = 1;
+   
+   if (Argc > 1)
+   {
+      Count = strtoul(Argv[1], NULL, 0);
+      if (Count == 0)
+      {
+         KdbpPrint("%s: Integer argument required\n", Argv[0]);
+         return TRUE;
+      }
+   }
+   
+   if (Argv[0][0] == 'n')
+      KdbSingleStepOver = TRUE;
+   else
+      KdbSingleStepOver = FALSE;
+
+   /* Set the number of single steps and return to the interrupted code. */
+   KdbNumSingleSteps = Count;
+
+   return FALSE;
+}
+
+/*!\brief Lists breakpoints.
+ */
+STATIC BOOLEAN
+KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
+{
+   LONG l;
+   ULONG_PTR Address = 0;
+   KDB_BREAKPOINT_TYPE Type = 0;
+   KDB_ACCESS_TYPE AccessType = 0;
+   UCHAR Size = 0;
+   UCHAR DebugReg = 0;
+   BOOLEAN Enabled = FALSE;
+   BOOLEAN Global = FALSE;
+   PEPROCESS Process = NULL;
+   PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
+   CHAR Buffer[20];
+
+   l = KdbpGetNextBreakPointNr(0);
+   if (l < 0)
+   {
+      KdbpPrint("No breakpoints.\n");
+      return TRUE;
+   }
+   
+   KdbpPrint("Breakpoints:\n");
+   do
+   {
+      if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
+                                 &Enabled, &Global, &Process, &ConditionExpr))
+      {
+         continue;
+      }
+
+      if (l == KdbLastBreakPointNr)
+      {
+         str1 = "\x1b[1m*";
+         str2 = "\x1b[0m";
+      }
+      else
+      {
+         str1 = " ";
+         str2 = "";
+      }
+
+      if (Global)
+         GlobalOrLocal = "  global";
+      else
+      {
+         GlobalOrLocal = Buffer;
+         sprintf(Buffer, "  PID 0x%08lx",
+                 (ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
+      }
+
+      if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
+      {
+         KdbpPrint(" %s%03d  BPX  0x%08x%s%s%s%s%s\n",
+                   str1, l, Address,
+                   Enabled ? "" : "  disabled",
+                   GlobalOrLocal,
+                   ConditionExpr ? "  IF " : "",
+                   ConditionExpr ? ConditionExpr : "",
+                   str2);
+      }
+      else if (Type == KdbBreakPointHardware)
+      {
+         if (!Enabled)
+         {
+            KdbpPrint(" %s%03d  BPM  0x%08x  %-5s %-5s  disabled%s%s%s%s\n", str1, l, Address,
+                      KDB_ACCESS_TYPE_TO_STRING(AccessType),
+                      Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
+                      GlobalOrLocal,
+                      ConditionExpr ? "  IF " : "",
+                      ConditionExpr ? ConditionExpr : "",
+                      str2);
+         }
+         else
+         {
+            KdbpPrint(" %s%03d  BPM  0x%08x  %-5s %-5s  DR%d%s%s%s%s\n", str1, l, Address,
+                      KDB_ACCESS_TYPE_TO_STRING(AccessType),
+                      Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
+                      DebugReg,
+                      GlobalOrLocal,
+                      ConditionExpr ? "  IF " : "",
+                      ConditionExpr ? ConditionExpr : "",
+                      str2);
+         }
+      }
+   }
+   while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
+
+   return TRUE;
+}
+
+/*!\brief Enables, disables or clears a breakpoint.
+ */
+STATIC BOOLEAN
+KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
+{
+   PCHAR pend;
+   ULONG BreakPointNr;
+
+   if (Argc < 2)
+   {
+      KdbpPrint("%s: argument required\n", Argv[0]);
+      return TRUE;
+   }
+
+   pend = Argv[1];
+   BreakPointNr = strtoul(Argv[1], &pend, 0);
+   if (pend == Argv[1] || *pend != '\0')
+   {
+      KdbpPrint("%s: integer argument required\n", Argv[0]);
+      return TRUE;
+   }
+
+   if (Argv[0][1] == 'e') /* enable */
+   {
+      KdbpEnableBreakPoint(BreakPointNr, NULL);
+   }
+   else if (Argv [0][1] == 'd') /* disable */
+   {
+      KdbpDisableBreakPoint(BreakPointNr, NULL);
+   }
+   else /* clear */
+   {
+      ASSERT(Argv[0][1] == 'c');
+      KdbpDeleteBreakPoint(BreakPointNr, NULL);
+   }
+
+   return TRUE;
+}
+
+/*!\brief Sets a software or hardware (memory) breakpoint at the given address.
+ */
+STATIC BOOLEAN
+KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
+{
+   ULONGLONG Result = 0;
+   ULONG_PTR Address;
+   KDB_BREAKPOINT_TYPE Type;
+   UCHAR Size = 0;
+   KDB_ACCESS_TYPE AccessType = 0;
+   INT AddressArgIndex, ConditionArgIndex, i;
+   BOOLEAN Global = TRUE;
+   
+   if (Argv[0][2] == 'x') /* software breakpoint */
+   {
+      if (Argc < 2)
+      {
+         KdbpPrint("bpx: Address argument required.\n");
+         return TRUE;
+      }
+
+      AddressArgIndex = 1;
+      Type = KdbBreakPointSoftware;
+   }
+   else /* memory breakpoint */
+   {
+      ASSERT(Argv[0][2] == 'm');
+      
+      if (Argc < 2)
+      {
+         KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
+         return TRUE;
+      }
+
+      if (_stricmp(Argv[1], "x") == 0)
+         AccessType = KdbAccessExec;
+      else if (_stricmp(Argv[1], "r") == 0)
+         AccessType = KdbAccessRead;
+      else if (_stricmp(Argv[1], "w") == 0)
+         AccessType = KdbAccessWrite;
+      else if (_stricmp(Argv[1], "rw") == 0)
+         AccessType = KdbAccessReadWrite;
+      else
+      {
+         KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
+         return TRUE;
+      }
+      
+      if (Argc < 3)
+      {
+         KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
+         return TRUE;
+      }
+      AddressArgIndex = 3;
+      if (_stricmp(Argv[2], "byte") == 0)
+         Size = 1;
+      else if (_stricmp(Argv[2], "word") == 0)
+         Size = 2;
+      else if (_stricmp(Argv[2], "dword") == 0)
+         Size = 4;
+      else if (AccessType == KdbAccessExec)
+      {
+         Size = 1;
+         AddressArgIndex--;
+      }
+      else
+      {
+         KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
+         return TRUE;
+      }
+      
+      if (Argc <= AddressArgIndex)
+      {
+         KdbpPrint("bpm: Address argument required.\n");
+         return TRUE;
+      }
+
+      Type = KdbBreakPointHardware;
+   }
+   
+   /* Put the arguments back together */
+   ConditionArgIndex = -1;
+   for (i = AddressArgIndex; i < (Argc-1); i++)
+   {
+      if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
+      {
+         ConditionArgIndex = i + 2;
+         if (ConditionArgIndex >= Argc)
+         {
+            KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
+            return TRUE;
+         }
+         for (i = ConditionArgIndex; i < (Argc-1); i++)
+            Argv[i][strlen(Argv[i])] = ' ';
+         break;
+      }
+      Argv[i][strlen(Argv[i])] = ' ';
+   }
+
+   /* Evaluate the address expression */
+   if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
+                               sizeof("kdb:> ")-1 + (Argv[AddressArgIndex]-Argv[0]),
+                               &Result))
+   {
+      return TRUE;
+   }
+   if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+      KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+   Address = (ULONG_PTR)Result;
+
+   KdbpInsertBreakPoint(Address, Type, Size, AccessType,
+                        (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
+                        Global, NULL);
+   
+   return TRUE;
+}
+
+/*!\brief Lists threads or switches to another thread context.
+ */
+STATIC BOOLEAN
+KdbpCmdThread(ULONG Argc, PCHAR Argv[])
+{
+   PLIST_ENTRY Entry;
+   PETHREAD Thread = NULL;
+   PEPROCESS Process = NULL;
+   PULONG Esp;
+   PULONG Ebp;
+   ULONG Eip;
+   ULONG ul = 0;
+   PCHAR State, pend, str1, str2;
+   STATIC CONST PCHAR ThreadStateToString[THREAD_STATE_MAX] =
+                                          { "Initialized", "Ready", "Running",
+                                            "Suspended", "Frozen", "Terminated1",
+                                            "Terminated2", "Blocked" };
+   ASSERT(KdbCurrentProcess != NULL);
+
+   if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
+   {
+      Process = KdbCurrentProcess;
+      
+      if (Argc >= 3)
+      {
+         ul = strtoul(Argv[2], &pend, 0);
+         if (Argv[2] == pend)
+         {
+            KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
+            return TRUE;
+         }
+         if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
+         {
+            KdbpPrint("thread: Invalid process id!\n");
+            return TRUE;
+         }
+      }
+      
+      Entry = Process->ThreadListHead.Flink;
+      if (Entry == &Process->ThreadListHead)
+      {
+         if (Argc >= 3)
+            KdbpPrint("No threads in process 0x%08x!\n", ul);
+         else
+            KdbpPrint("No threads in current process!\n");
+         return TRUE;
+      }
+
+      KdbpPrint("  TID         State        Prior.  Affinity    EBP         EIP\n");
+      do
+      {
+         Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+
+         if (Thread == KdbCurrentThread)
+         {
+            str1 = "\x1b[1m*";
+            str2 = "\x1b[0m";
+         }
+         else
+         {
+            str1 = " ";
+            str2 = "";
+         }
+
+         if (Thread->Tcb.TrapFrame != NULL)
+         {
+            Esp = (PULONG)Thread->Tcb.TrapFrame->Esp;
+            Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
+            Eip = Thread->Tcb.TrapFrame->Eip;
+         }
+         else
+         {
+            Esp = (PULONG)Thread->Tcb.KernelStack;
+            Ebp = (PULONG)Esp[4];
+            Eip = 0;
+            if (Ebp != NULL) /* FIXME: Should we attach to the process to read Ebp[1]? */
+               KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));;
+         }
+         if (Thread->Tcb.State < THREAD_STATE_MAX)
+            State = ThreadStateToString[Thread->Tcb.State];
+         else
+            State = "Unknown";
+      
+         KdbpPrint(" %s0x%08x  %-11s  %3d     0x%08x  0x%08x  0x%08x%s\n",
+                   str1,
+                   Thread->Cid.UniqueThread,
+                   State,
+                   Thread->Tcb.Priority,
+                   Thread->Tcb.Affinity,
+                   Ebp,
+                   Eip,
+                   str2);
+      
+         Entry = Entry->Flink;
+      }
+      while (Entry != &Process->ThreadListHead);
+   }
+   else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
+   {
+      if (Argc < 3)
+      {
+         KdbpPrint("thread attach: thread id argument required!\n");
+         return TRUE;
+      }
+
+      ul = strtoul(Argv[2], &pend, 0);
+      if (Argv[2] == pend)
+      {
+         KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
+         return TRUE;
+      }
+      if (!KdbpAttachToThread((PVOID)ul))
+      {
+         return TRUE;
+      }
+      KdbpPrint("Attached to thread 0x%08x.\n", ul);
+   }
+   else
+   {
+      Thread = KdbCurrentThread;
+
+      if (Argc >= 2)
+      {
+         ul = strtoul(Argv[1], &pend, 0);
+         if (Argv[1] == pend)
+         {
+            KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
+            return TRUE;
+         }
+         if (!NT_SUCCESS(PsLookupThreadByThreadId((PVOID)ul, &Thread)))
+         {
+            KdbpPrint("thread: Invalid thread id!\n");
+            return TRUE;
+         }
+      }
+      
+      if (Thread->Tcb.State < THREAD_STATE_MAX)
+         State = ThreadStateToString[Thread->Tcb.State];
+      else
+         State = "Unknown";
+      KdbpPrint("%s"
+                "  TID:            0x%08x\n"
+                "  State:          %s (0x%x)\n"
+                "  Priority:       %d\n"
+                "  Affinity:       0x%08x\n"
+                "  Initial Stack:  0x%08x\n"
+                "  Stack Limit:    0x%08x\n"
+                "  Stack Base:     0x%08x\n"
+                "  Kernel Stack:   0x%08x\n"
+                "  Trap Frame:     0x%08x\n"
+                "  NPX State:      %s (0x%x)\n",
+                (Argc < 2) ? "Current Thread:\n" : "",
+                Thread->Cid.UniqueThread,
+                State, Thread->Tcb.State,
+                Thread->Tcb.Priority,
+                Thread->Tcb.Affinity,
+                Thread->Tcb.InitialStack,
+                Thread->Tcb.StackLimit,
+                Thread->Tcb.StackBase,
+                Thread->Tcb.KernelStack,
+                Thread->Tcb.TrapFrame,
+                NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState);
+
+   }
+
+   return TRUE;
+}
+
+/*!\brief Lists processes or switches to another process context.
+ */
+STATIC BOOLEAN
+KdbpCmdProc(ULONG Argc, PCHAR Argv[])
+{
+   PLIST_ENTRY Entry;
+   PEPROCESS Process;
+   PCHAR State, pend, str1, str2;
+   ULONG ul;
+   extern LIST_ENTRY PsActiveProcessHead;
+
+   if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
+   {
+      Entry = PsActiveProcessHead.Flink;
+      if (Entry == &PsActiveProcessHead)
+      {
+         KdbpPrint("No processes in the system!\n");
+         return TRUE;
+      }
+   
+      KdbpPrint("  PID         State       Filename\n");
+      do
+      {
+         Process = CONTAINING_RECORD(Entry, EPROCESS, ProcessListEntry);
+
+         if (Process == KdbCurrentProcess)
+         {
+            str1 = "\x1b[1m*";
+            str2 = "\x1b[0m";
+         }
+         else
+         {
+            str1 = " ";
+            str2 = "";
+         }
+
+         State = ((Process->Pcb.State == PROCESS_STATE_TERMINATED) ? "Terminated" :
+                 ((Process->Pcb.State == PROCESS_STATE_ACTIVE) ? "Active" : "Unknown"));
+      
+         KdbpPrint(" %s0x%08x  %-10s  %s%s\n",
+                   str1,
+                   Process->UniqueProcessId,
+                   State,
+                   Process->ImageFileName,
+                   str2);
+      
+         Entry = Entry->Flink;
+      }
+      while(Entry != &PsActiveProcessHead);
+   }
+   else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
+   {
+      if (Argc < 3)
+      {
+         KdbpPrint("process attach: process id argument required!\n");
+         return TRUE;
+      }
+
+      ul = strtoul(Argv[2], &pend, 0);
+      if (Argv[2] == pend)
+      {
+         KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
+         return TRUE;
+      }
+      if (!KdbpAttachToProcess((PVOID)ul))
+      {
+         return TRUE;
+      }
+      KdbpPrint("Attached to process 0x%08x, thread 0x%08x.\n", (UINT)ul,
+                (UINT)KdbCurrentThread->Cid.UniqueThread);
+   }
+   else
+   {
+      Process = KdbCurrentProcess;
+
+      if (Argc >= 2)
+      {
+         ul = strtoul(Argv[1], &pend, 0);
+         if (Argv[1] == pend)
+         {
+            KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
+            return TRUE;
+         }
+         if (!NT_SUCCESS(PsLookupProcessByProcessId((PVOID)ul, &Process)))
+         {
+            KdbpPrint("proc: Invalid process id!\n");
+            return TRUE;
+         }
+      }
+
+      State = ((Process->Pcb.State == PROCESS_STATE_TERMINATED) ? "Terminated" :
+              ((Process->Pcb.State == PROCESS_STATE_ACTIVE) ? "Active" : "Unknown"));
+      KdbpPrint("%s"
+                "  PID:             0x%08x\n"
+                "  State:           %s (0x%x)\n"
+                "  Image Filename:  %s\n",
+                (Argc < 2) ? "Current process:\n" : "",
+                Process->UniqueProcessId,
+                State, Process->Pcb.State,
+                Process->ImageFileName);
+   }
+
+   return TRUE;
+}
+
+/*!\brief Lists loaded modules or the one containing the specified address.
+ */
+STATIC BOOLEAN
+KdbpCmdMod(ULONG Argc, PCHAR Argv[])
+{
+   ULONGLONG Result = 0;
+   ULONG_PTR Address;
+   KDB_MODULE_INFO Info;
+   BOOLEAN DisplayOnlyOneModule = FALSE;
+   INT i = 0;
+
+   if (Argc >= 2)
+   {
+      /* Put the arguments back together */
+      Argc--;
+      while (--Argc >= 1)
+         Argv[Argc][strlen(Argv[Argc])] = ' ';
+
+      /* Evaluate the expression */
+      if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result))
+      {
+         return TRUE;
+      }
+      if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
+         KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
+      Address = (ULONG_PTR)Result;
+      
+      if (!KdbpSymFindModuleByAddress((PVOID)Address, &Info))
+      {
+         KdbpPrint("No module containing address 0x%x found!\n", Address);
+         return TRUE;
+      }
+      DisplayOnlyOneModule = TRUE;
+   }
+   else
+   {
+      if (!KdbpSymFindModuleByIndex(0, &Info))
+      {
+         KdbpPrint("No modules.\n");
+         return TRUE;
+      }
+      i = 1;
+   }
+
+   KdbpPrint("  Base      Size      Name\n");
+   for (;;)
+   {
+      KdbpPrint("  %08x  %08x  %ws\n", Info.Base, Info.Size, Info.Name);
+
+      if ((!DisplayOnlyOneModule && !KdbpSymFindModuleByIndex(i++, &Info)) ||
+          DisplayOnlyOneModule)
+      {
+         break;
+      }
+   }
+
+   return TRUE;
+}
+
+/*!\brief Displays GDT, LDT or IDTd.
+ */
+STATIC BOOLEAN
+KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[])
+{
+   struct __attribute__((packed)) {
+      USHORT Limit;
+      ULONG Base;
+   } Reg;
+   ULONG SegDesc[2];
+   ULONG SegBase;
+   ULONG SegLimit;
+   PCHAR SegType;
+   USHORT SegSel;
+   UCHAR Type, Dpl;
+   INT i;
+   ULONG ul;
+
+   if (Argv[0][0] == 'i')
+   {
+      /* Read IDTR */
+      asm volatile("sidt %0" : : "m"(Reg));
+
+      if (Reg.Limit < 7)
+      {
+         KdbpPrint("Interrupt descriptor table is empty.\n");
+         return TRUE;
+      }
+      KdbpPrint("IDT Base: 0x%08x  Limit: 0x%04x\n", Reg.Base, Reg.Limit);
+      KdbpPrint("  Idx  Type        Seg. Sel.  Offset      DPL\n");
+      for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
+      {
+         if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
+         {
+            KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
+            return TRUE;
+         }
+
+         Dpl = ((SegDesc[1] >> 13) & 3);
+         if ((SegDesc[1] & 0x1f00) == 0x0500)        /* Task gate */
+            SegType = "TASKGATE";
+         else if ((SegDesc[1] & 0x1fe0) == 0x0e00)   /* 32 bit Interrupt gate */
+            SegType = "INTGATE32";
+         else if ((SegDesc[1] & 0x1fe0) == 0x0600)   /* 16 bit Interrupt gate */
+            SegType = "INTGATE16";
+         else if ((SegDesc[1] & 0x1fe0) == 0x0f00)   /* 32 bit Trap gate */
+            SegType = "TRAPGATE32";
+         else if ((SegDesc[1] & 0x1fe0) == 0x0700)   /* 16 bit Trap gate */
+            SegType = "TRAPGATE16";
+         else
+            SegType = "UNKNOWN";
+
+         if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
+         {
+            KdbpPrint("  %03d  %-10s  [NP]       [NP]        %02d\n",
+                      i / 8, SegType, Dpl);
+         }
+         else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
+         {
+            SegSel = SegDesc[0] >> 16;
+            KdbpPrint("  %03d  %-10s  0x%04x                 %02d\n",
+                      i / 8, SegType, SegSel, Dpl);
+         }
+         else
+         {
+            SegSel = SegDesc[0] >> 16;
+            SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
+            KdbpPrint("  %03d  %-10s  0x%04x     0x%08x  %02d\n",
+                      i / 8, SegType, SegSel, SegBase, Dpl);
+         }
+      }
+   }
+   else
+   {
+      ul = 0;
+      if (Argv[0][0] == 'g')
+      {
+         /* Read GDTR */
+         asm volatile("sgdt %0" : : "m"(Reg));
+         i = 8;
+      }
+      else
+      {
+         ASSERT(Argv[0][0] == 'l');
+         /* Read LDTR */
+         asm volatile("sldt %0" : : "m"(Reg));
+         i = 0;
+         ul = 1 << 2;
+      }
+      
+      if (Reg.Limit < 7)
+      {
+         KdbpPrint("%s descriptor table is empty.\n",
+                   Argv[0][0] == 'g' ? "Global" : "Local");
+         return TRUE;
+      }
+      KdbpPrint("%cDT Base: 0x%08x  Limit: 0x%04x\n",
+                Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
+      KdbpPrint("  Idx  Sel.    Type         Base        Limit       DPL  Attribs\n");
+      for ( ; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
+      {
+         if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
+         {
+            KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
+            return TRUE;
+         }
+         Dpl = ((SegDesc[1] >> 13) & 3);
+         Type = ((SegDesc[1] >> 8) & 0xf);
+
+         SegBase = SegDesc[0] >> 16;
+         SegBase |= (SegDesc[1] & 0xff) << 16;
+         SegBase |= SegDesc[1] & 0xff000000;
+         SegLimit = SegDesc[0] & 0x0000ffff;
+         SegLimit |= (SegDesc[1] >> 16) & 0xf;
+         if ((SegDesc[1] & (1 << 23)) != 0)
+         {
+            SegLimit *= 4096;
+            SegLimit += 4095;
+         }
+         else
+         {
+            SegLimit++;
+         }
+
+         if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
+         {
+            switch (Type)
+            {
+            case 1: SegType = "TSS16(Avl)"; break;
+            case 2: SegType = "LDT"; break;
+            case 3: SegType = "TSS16(Busy)"; break;
+            case 4: SegType = "CALLGATE16"; break;
+            case 5: SegType = "TASKGATE"; break;
+            case 6: SegType = "INTGATE16"; break;
+            case 7: SegType = "TRAPGATE16"; break;
+            case 9: SegType = "TSS32(Avl)"; break;
+            case 11: SegType = "TSS32(Busy)"; break;
+            case 12: SegType = "CALLGATE32"; break;
+            case 14: SegType = "INTGATE32"; break;
+            case 15: SegType = "INTGATE32"; break;
+            default: SegType = "UNKNOWN"; break;
+            }
+            if (!(Type >= 1 && Type <= 3) &&
+                Type != 9 && Type != 11)
+            {
+               SegBase = 0;
+               SegLimit = 0;
+            }
+         }
+         else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
+         {
+            if ((SegDesc[1] & (1 << 22)) != 0)
+               SegType = "DATA32";
+            else
+               SegType = "DATA16";
+
+         }
+         else /* Code segment */
+         {
+            if ((SegDesc[1] & (1 << 22)) != 0)
+               SegType = "CODE32";
+            else
+               SegType = "CODE16";
+         }
+
+         if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
+         {
+            KdbpPrint("  %03d  0x%04x  %-11s  [NP]        [NP]        %02d   NP\n",
+                      i / 8, i | Dpl | ul, SegType, Dpl);
+         }
+         else
+         {
+            KdbpPrint("  %03d  0x%04x  %-11s  0x%08x  0x%08x  %02d  ",
+                      i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
+            if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
+            {
+               /* FIXME: Display system segment */
+            }
+            else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
+            {
+               if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
+                  KdbpPrint(" E");
+               KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
+               if ((SegDesc[1] & (1 << 8)) != 0)
+                  KdbpPrint(" A");
+            }
+            else /* Code segment */
+            {
+               if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
+                  KdbpPrint(" C");
+               KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
+               if ((SegDesc[1] & (1 << 8)) != 0)
+                  KdbpPrint(" A");
+            }
+            if ((SegDesc[1] & (1 << 20)) != 0)
+               KdbpPrint(" AVL");
+            KdbpPrint("\n");
+         }
+      }
+   }
+   
+   return TRUE;
+}
+
+/*!\brief Displays the KPCR
+ */
+STATIC BOOLEAN
+KdbpCmdPcr(ULONG Argc, PCHAR Argv[])
+{
+   PKPCR Pcr = KeGetCurrentKPCR();
+
+   KdbpPrint("Current PCR is at 0x%08x.\n", (INT)Pcr);
+   KdbpPrint("  Tib.ExceptionList:         0x%08x\n"
+             "  Tib.StackBase:             0x%08x\n"
+             "  Tib.StackLimit:            0x%08x\n"
+             "  Tib.SubSystemTib:          0x%08x\n"
+             "  Tib.FiberData/Version:     0x%08x\n"
+             "  Tib.ArbitraryUserPointer:  0x%08x\n"
+             "  Tib.Self:                  0x%08x\n"
+             "  Self:                      0x%08x\n"
+             "  PCRCB:                     0x%08x\n"
+             "  Irql:                      0x%02x\n"
+             "  IRR:                       0x%08x\n"
+             "  IrrActive:                 0x%08x\n"
+             "  IDR:                       0x%08x\n"
+             "  KdVersionBlock:            0x%08x\n"
+             "  IDT:                       0x%08x\n"
+             "  GDT:                       0x%08x\n"
+             "  TSS:                       0x%08x\n"
+             "  MajorVersion:              0x%04x\n"
+             "  MinorVersion:              0x%04x\n"
+             "  SetMember:                 0x%08x\n"
+             "  StallScaleFactor:          0x%08x\n"
+             "  DebugActive:               0x%02x\n"
+             "  ProcessorNumber:           0x%02x\n"
+             "  L2CacheAssociativity:      0x%02x\n"
+             "  VdmAlert:                  0x%08x\n"
+             "  L2CacheSize:               0x%08x\n"
+             "  InterruptMode:             0x%08x\n",
+             Pcr->Tib.ExceptionList, Pcr->Tib.StackBase, Pcr->Tib.StackLimit,
+             Pcr->Tib.SubSystemTib, Pcr->Tib.FiberData, Pcr->Tib.ArbitraryUserPointer,
+             Pcr->Tib.Self, Pcr->Self, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
+             Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
+             Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
+             Pcr->DebugActive, Pcr->ProcessorNumber, Pcr->L2CacheAssociativity,
+             Pcr->VdmAlert, Pcr->L2CacheSize, Pcr->InterruptMode);
+   
+   return TRUE;
+}
+
+/*!\brief Displays the TSS
+ */
+STATIC BOOLEAN
+KdbpCmdTss(ULONG Argc, PCHAR Argv[])
+{
+   KTSS *Tss = KeGetCurrentKPCR()->TSS;
+
+   KdbpPrint("Current TSS is at 0x%08x.\n", (INT)Tss);
+   KdbpPrint("  PreviousTask:  0x%08x\n"
+             "  Ss0:Esp0:      0x%04x:0x%08x\n"
+             "  Ss1:Esp1:      0x%04x:0x%08x\n"
+             "  Ss2:Esp2:      0x%04x:0x%08x\n"
+             "  Cr3:           0x%08x\n"
+             "  Eip:           0x%08x\n"
+             "  Eflags:        0x%08x\n"
+             "  Eax:           0x%08x\n"
+             "  Ecx:           0x%08x\n"
+             "  Edx:           0x%08x\n"
+             "  Ebx:           0x%08x\n"
+             "  Esp:           0x%08x\n"
+             "  Ebp:           0x%08x\n"
+             "  Esi:           0x%08x\n"
+             "  Edi:           0x%08x\n"
+             "  Es:            0x%04x\n"
+             "  Cs:            0x%04x\n"
+             "  Ss:            0x%04x\n"
+             "  Ds:            0x%04x\n"
+             "  Fs:            0x%04x\n"
+             "  Gs:            0x%04x\n"
+             "  Ldt:           0x%04x\n"
+             "  Trap:          0x%04x\n"
+             "  IoMapBase:     0x%04x\n",
+             Tss->PreviousTask, Tss->Ss0, Tss->Esp0, Tss->Ss1, Tss->Esp1,
+             Tss->Ss2, Tss->Esp2, Tss->Cr3, Tss->Eip, Tss->Eflags, Tss->Eax,
+             Tss->Ecx, Tss->Edx, Tss->Ebx, Tss->Esp, Tss->Ebp, Tss->Esi,
+             Tss->Edi, Tss->Es, Tss->Cs, Tss->Ss, Tss->Ds, Tss->Fs, Tss->Gs,
+             Tss->Ldt, Tss->Trap, Tss->IoMapBase);
+   return TRUE;
+}
+
+/*!\brief Bugchecks the system.
+ */
+STATIC BOOLEAN
+KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[])
+{
+   KEBUGCHECK(0xDEADDEAD);
+   return TRUE;
+}
+
+/*!\brief Sets or displays a config variables value.
+ */
+STATIC BOOLEAN
+KdbpCmdSet(ULONG Argc, PCHAR Argv[])
+{
+   LONG l;
+   BOOLEAN First;
+   PCHAR pend = 0;
+   KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
+   KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
+   STATIC CONST PCHAR ExceptionNames[21] =
+      { "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
+        "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
+        "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
+        "MACHINECHECK", "SIMDFAULT", "OTHERS" };
+
+   if (Argc == 1)
+   {
+      KdbpPrint("Available settings:\n");
+      KdbpPrint("  syntax [intel|at&t]\n");
+      KdbpPrint("  condition [exception|*] [first|last] [never|always|kmode|umode]\n");
+   }
+   else if (strcmp(Argv[1], "syntax") == 0)
+   {
+      if (Argc == 2)
+         KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
+      else if (Argc >= 3)
+      {
+         if (_stricmp(Argv[2], "intel") == 0)
+            KdbUseIntelSyntax = TRUE;
+         else if (_stricmp(Argv[2], "at&t") == 0)
+            KdbUseIntelSyntax = FALSE;
+         else
+            KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
+      }
+   }
+   else if (strcmp(Argv[1], "condition") == 0)
+   {
+      if (Argc == 2)
+      {
+         KdbpPrint("Conditions:                 (First)  (Last)\n");
+         for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
+         {
+            if (ExceptionNames[l] == NULL)
+               continue;
+            if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
+               ASSERT(0);
+            if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
+               ASSERT(0);
+            KdbpPrint("  #%02d  %-20s %-8s %-8s\n", l, ExceptionNames[l],
+                      KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+                      KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+         }
+         ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
+         KdbpPrint("       %-20s %-8s %-8s\n", ExceptionNames[l],
+                   KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+                   KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+      }
+      else
+      {
+         if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
+            l = -1;
+         else
+         {
+            l = (LONG)strtoul(Argv[2], &pend, 0);
+            if (Argv[2] == pend)
+            {
+               for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
+               {
+                  if (ExceptionNames[l] == NULL)
+                     continue;
+                  if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
+                     break;
+               }
+            }
+            if (l >= RTL_NUMBER_OF(ExceptionNames))
+            {
+               KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
+               return TRUE;
+            }
+         }
+         if (Argc > 4)
+         {
+            if (_stricmp(Argv[3], "first") == 0)
+               First = TRUE;
+            else if (_stricmp(Argv[3], "last") == 0)
+               First = FALSE;
+            else
+            {
+               KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
+               return TRUE;
+            }
+            if (_stricmp(Argv[4], "never") == 0)
+               ConditionFirst = KdbDoNotEnter;
+            else if (_stricmp(Argv[4], "always") == 0)
+               ConditionFirst = KdbEnterAlways;
+            else if (_stricmp(Argv[4], "umode") == 0)
+               ConditionFirst = KdbEnterFromUmode;
+            else if (_stricmp(Argv[4], "kmode") == 0)
+               ConditionFirst = KdbEnterFromKmode;
+            else
+            {
+               KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
+               return TRUE;
+            }
+            if (!KdbpSetEnterCondition(l, First, ConditionFirst))
+            {
+               if (l >= 0)
+                  KdbpPrint("Couldn't change condition for exception #%02d\n", l);
+               else
+                  KdbpPrint("Couldn't change condition for all exceptions\n", l);
+            }
+         }
+         else /* Argc >= 3 */
+         {
+            if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
+               ASSERT(0);
+            if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
+               ASSERT(0);
+            if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
+            {
+               KdbpPrint("Condition for exception #%02d (%s): FirstChance %s  LastChance %s\n",
+                         l, ExceptionNames[l],
+                         KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+                         KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+            }
+            else
+            {
+               KdbpPrint("Condition for all other exceptions: FirstChance %s  LastChance %s\n",
+                         KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
+                         KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
+            }
+         }
+      }
+   }
+   else
+      KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
+
+   return TRUE;
+}
+
+/*!\brief Displays help screen.
+ */
+STATIC BOOLEAN
+KdbpCmdHelp(ULONG Argc, PCHAR Argv[])
+{
+   ULONG i;
+
+   KdbpPrint("Kernel debugger commands:\n");
+   for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
+   {
+      if (KdbDebuggerCommands[i].Syntax == NULL) /* Command group */
+      {
+         if (i > 0)
+            KdbpPrint("\n");
+         KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
+         continue;
+      }
+
+      KdbpPrint("  %-20s - %s\n",
+                KdbDebuggerCommands[i].Syntax,
+                KdbDebuggerCommands[i].Help);
+   }
+
+   return TRUE;
+}
+
+/*!\brief Prints the given string with printf-like formatting.
+ *
+ * \param Format  Format of the string/arguments.
+ * \param ...     Variable number of arguments matching the format specified in \a Format.
+ *
+ * \note Doesn't correctly handle \\t and terminal escape sequences when calculating the
+ *       number of lines required to print a single line from the Buffer in the terminal.
+ */
+VOID
+KdbpPrint(
+   IN PCHAR Format,
+   IN ...  OPTIONAL)
+{
+   STATIC CHAR Buffer[4096];
+   STATIC BOOLEAN TerminalInitialized = FALSE;
+   STATIC BOOLEAN TerminalConnected = FALSE;
+   STATIC BOOLEAN TerminalReportsSize = TRUE;
+   CHAR c = '\0';
+   PCHAR p, p2;
+   INT Length;
+   INT i, j;
+   INT RowsPrintedByTerminal;
+   ULONG ScanCode;
+   va_list ap;
+
+   /* Check if the user has aborted output of the current command */
+   if (KdbOutputAborted)
+      return;
+
+   /* Initialize the terminal */
+   if (!TerminalInitialized)
+   {
+      DbgPrint("\x1b[7h");      /* Enable linewrap */
+      
+      /* Query terminal type */
+      /*DbgPrint("\x1b[Z");*/
+      DbgPrint("\x05");
+      
+      TerminalInitialized = TRUE;
+      Length = 0;
+      for (;;)
+      {
+         c = KdbpTryGetCharSerial(5000);
+         if (c == -1)
+            break;
+         Buffer[Length++] = c;
+         if (Length >= (sizeof (Buffer) - 1))
+            break;
+      }
+      Buffer[Length] = '\0';
+      if (Length > 0)
+         TerminalConnected = TRUE;
+   }
+
+   /* Get number of rows and columns in terminal */
+   if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
+       (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
+   {
+      if ((KdDebugState & KD_DEBUG_KDSERIAL) && TerminalReportsSize)
+      {
+         /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
+         TerminalReportsSize = FALSE;
+         DbgPrint("\x1b[18t");
+         c = KdbpTryGetCharSerial(5000);
+         if (c == KEY_ESC)
+         {
+            c = KdbpTryGetCharSerial(5000);
+            if (c == '[')
+            {
+               Length = 0;
+               for (;;)
+               {
+                  c = KdbpTryGetCharSerial(5000);
+                  if (c == -1)
+                     break;
+                  Buffer[Length++] = c;
+                  if (isalpha(c) || Length >= (sizeof (Buffer) - 1))
+                     break;
+               }
+               Buffer[Length] = '\0';
+               if (Buffer[0] == '8' && Buffer[1] == ';')
+               {
+                  for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
+                  if (Buffer[i] == ';')
+                  {
+                     Buffer[i++] = '\0';
+                     /* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
+                     KdbNumberOfRowsTerminal = strtoul(Buffer + 2, NULL, 0);
+                     KdbNumberOfColsTerminal = strtoul(Buffer + i, NULL, 0);
+                     TerminalReportsSize = TRUE;
+                  }
+               }
+            }
+         }
+      }
+
+      if (KdbNumberOfRowsTerminal <= 0)
+      {
+         /* Set number of rows to the default. */
+         KdbNumberOfRowsTerminal = 24;
+      }
+      else if (KdbNumberOfColsTerminal <= 0)
+      {
+         /* Set number of cols to the default. */
+         KdbNumberOfColsTerminal = 80;
+      }
+   }
+
+   /* Get the string */
+   va_start(ap, Format);
+   Length = _vsnprintf(Buffer, sizeof (Buffer) - 1, Format, ap);
+   Buffer[Length] = '\0';
+   va_end(ap);
+
+   p = Buffer;
+   while (p[0] != '\0')
+   {
+      i = strcspn(p, "\n");
+      
+      /* Calculate the number of lines which will be printed in the terminal
+       * when outputting the current line
+       */
+      if (i > 0)
+         RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
+      else
+         RowsPrintedByTerminal = 0;
+      if (p[i] == '\n')
+         RowsPrintedByTerminal++;
+         
+      /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
+
+      /* Display a prompt if we printed one screen full of text */
+      if ((KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
+      {
+         if (KdbNumberOfColsPrinted > 0)
+            DbgPrint("\n");
+         DbgPrint("--- Press q to abort, any other key to continue ---");
+         if (KdDebugState & KD_DEBUG_KDSERIAL)
+            c = KdbpGetCharSerial();
+         else
+            c = KdbpGetCharKeyboard(&ScanCode);
+         if (c == '\r')
+         {
+            /* Try to read '\n' which might follow '\r' - if \n is not received here
+             * it will be interpreted as "return" when the next command should be read.
+             */
+            if (KdDebugState & KD_DEBUG_KDSERIAL)
+               c = KdbpTryGetCharSerial(5);
+            else
+               c = KdbpTryGetCharKeyboard(&ScanCode, 5);
+         }
+         DbgPrint("\n");
+         if (c == 'q')
+         {
+            KdbOutputAborted = TRUE;
+            return;
+         }
+         KdbNumberOfRowsPrinted = 0;
+         KdbNumberOfColsPrinted = 0;
+      }
+
+      /* Insert a NUL after the line and print only the current line. */
+      if (p[i] == '\n' && p[i + 1] != '\0')
+      {
+         c = p[i + 1];
+         p[i + 1] = '\0';
+      }
+      else
+      {
+         c = '\0';
+      }
+      
+      /* Remove escape sequences from the line if there's no terminal connected */
+      if (!TerminalConnected)
+      {
+         while ((p2 = strrchr(p, '\x1b')) != NULL) /* Look for escape character */
+         {
+            if (p2[1] == '[')
+            {
+               j = 2;
+               while (!isalpha(p2[j++]));
+               strcpy(p2, p2 + j);
+            }
+         }
+      }
+
+      DbgPrint("%s", p);
+
+      if (c != '\0')
+         p[i + 1] = c;
+
+      /* Set p to the start of the next line and
+       * remember the number of rows/cols printed
+       */
+      p += i;
+      if (p[0] == '\n')
+      {
+         p++;
+         KdbNumberOfColsPrinted = 0;
+      }
+      else
+      {
+         ASSERT(p[0] == '\0');
+         KdbNumberOfColsPrinted += i;
+      }
+      KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
+   }
+}
+
+/*!\brief Appends a command to the command history
+ *
+ * \param Command  Pointer to the command to append to the history.
+ */
+STATIC VOID
+KdbpCommandHistoryAppend(
+   IN PCHAR Command)
+{
+   LONG Length1 = strlen(Command) + 1;
+   LONG Length2 = 0;
+   INT i;
+   PCHAR Buffer;
+   
+   ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+
+   if (Length1 <= 1 ||
+       (KdbCommandHistory[KdbCommandHistoryIndex] != NULL &&
+        strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0))
+   {
+      return;
+   }
+
+   /* Calculate Length1 and Length2 */
+   Buffer = KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex;
+   KdbCommandHistoryBufferIndex += Length1;
+   if (KdbCommandHistoryBufferIndex >= RTL_NUMBER_OF(KdbCommandHistoryBuffer))
+   {
+      KdbCommandHistoryBufferIndex -= RTL_NUMBER_OF(KdbCommandHistoryBuffer);
+      Length2 = KdbCommandHistoryBufferIndex;
+      Length1 -= Length2;
+   }
+
+   /* Remove previous commands until there is enough space to append the new command */
+   for (i = KdbCommandHistoryIndex; KdbCommandHistory[i] != NULL;)
+   {
+      if ((Length2 > 0 &&
+           (KdbCommandHistory[i] >= Buffer ||
+            KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))) ||
+          (Length2 <= 0 &&
+           (KdbCommandHistory[i] >= Buffer &&
+            KdbCommandHistory[i] < (KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex))))
+      {
+         KdbCommandHistory[i] = NULL;
+      }
+      i--;
+      if (i < 0)
+         i = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+      if (i == KdbCommandHistoryIndex)
+         break;
+   }
+
+   /* Make sure the new command history entry is free */
+   KdbCommandHistoryIndex++;
+   KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory);
+   if (KdbCommandHistory[KdbCommandHistoryIndex] != NULL)
+   {
+      KdbCommandHistory[KdbCommandHistoryIndex] = NULL;
+   }
+
+   /* Append command */
+   KdbCommandHistory[KdbCommandHistoryIndex] = Buffer;
+   ASSERT((KdbCommandHistory[KdbCommandHistoryIndex] + Length1) <= KdbCommandHistoryBuffer + RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+   memcpy(KdbCommandHistory[KdbCommandHistoryIndex], Command, Length1);
+   if (Length2 > 0)
+   {
+      memcpy(KdbCommandHistoryBuffer, Command + Length1, Length2);
+   }
+}
+
+/*!\brief Reads a line of user-input.
+ *
+ * \param Buffer  Buffer to store the input into. Trailing newlines are removed.
+ * \param Size    Size of \a Buffer.
+ *
+ * \note Accepts only \n newlines, \r is ignored.
+ */
+STATIC VOID
+KdbpReadCommand(
+   OUT PCHAR Buffer,
+   IN  ULONG Size)
+{
+   CHAR Key;
+   PCHAR Orig = Buffer;
+   ULONG ScanCode = 0;
+   BOOLEAN EchoOn;
+   STATIC CHAR LastCommand[1024] = "";
+   STATIC CHAR NextKey = '\0';
+   INT CmdHistIndex = -1;
+   INT i;
+
+   EchoOn = !((KdDebugState & KD_DEBUG_KDNOECHO) != 0);
+
+   for (;;)
+   {
+      if (KdDebugState & KD_DEBUG_KDSERIAL)
+      {
+         Key = (NextKey == '\0') ? KdbpGetCharSerial() : NextKey;
+         ScanCode = 0;
+         if (Key == KEY_ESC) /* ESC */
+         {
+            Key = KdbpGetCharSerial();
+            if (Key == '[')
+            {
+               Key = KdbpGetCharSerial();
+               switch (Key)
+               {
+               case 'A':
+                  ScanCode = KEY_SCAN_UP;
+                  break;
+               case 'B':
+                  ScanCode = KEY_SCAN_DOWN;
+                  break;
+               case 'C':
+                  break;
+               case 'D':
+                  break;
+               }
+            }
+         }
+      }
+      else
+      {
+         ScanCode = 0;
+         Key = (NextKey == '\0') ? KdbpGetCharKeyboard(&ScanCode) : NextKey;
+      }
+
+      if ((Buffer - Orig) >= (Size - 1))
+      {
+         /* Buffer is full, accept only newlines */
+         if (Key != '\n')
+            continue;
+      }
+
+      if (Key == '\r')
+      {
+         /* Read the next char - this is to throw away a \n which most clients should
+          * send after \r.
+          */
+         if (KdDebugState & KD_DEBUG_KDSERIAL)
+            NextKey = KdbpTryGetCharSerial(5);
+         else
+            NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
+         if (NextKey == '\n')
+            NextKey = '\0';
+         DbgPrint("\n");
+        /*
+         * Repeat the last command if the user presses enter. Reduces the
+         * risk of RSI when single-stepping.
+         */
+        if (Buffer == Orig)
+        {
+            strncpy(Buffer, LastCommand, Size);
+            Buffer[Size - 1] = '\0';
+        }
+        else
+        {
+            *Buffer = '\0';
+            strncpy(LastCommand, Orig, sizeof (LastCommand));
+            LastCommand[sizeof (LastCommand) - 1] = '\0';
+         }
+         return;
+      }
+      else if (Key == KEY_BS || Key == KEY_DEL)
+      {
+         if (Buffer > Orig)
+         {
+            Buffer--;
+            *Buffer = 0;
+            if (EchoOn)
+               DbgPrint("%c %c", KEY_BS, KEY_BS);
+           else
+               DbgPrint(" %c", KEY_BS);
+         }
+      }
+      else if (ScanCode == KEY_SCAN_UP)
+      {
+         BOOLEAN Print = TRUE;
+         if (CmdHistIndex < 0)
+            CmdHistIndex = KdbCommandHistoryIndex;
+         else
+         {
+            i = CmdHistIndex - 1;
+            if (i < 0)
+               CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+            if (KdbCommandHistory[i] != NULL && i != KdbCommandHistoryIndex)
+               CmdHistIndex = i;
+            else
+               Print = FALSE;
+         }
+         if (Print && KdbCommandHistory[CmdHistIndex] != NULL)
+         {
+            while (Buffer > Orig)
+            {
+               Buffer--;
+               *Buffer = 0;
+               if (EchoOn)
+                  DbgPrint("%c %c", KEY_BS, KEY_BS);
+               else
+                  DbgPrint(" %c", KEY_BS);
+            }
+            i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
+            memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
+            Orig[i] = '\0';
+            Buffer = Orig + i;
+            DbgPrint("%s", Orig);
+         }
+      }
+      else if (ScanCode == KEY_SCAN_DOWN)
+      {
+         if (CmdHistIndex > 0 && CmdHistIndex != KdbCommandHistoryIndex)
+         {
+            i = CmdHistIndex + 1;
+            if (i >= RTL_NUMBER_OF(KdbCommandHistory))
+               i = 0;
+            if (KdbCommandHistory[i] != NULL)
+            {
+               CmdHistIndex = i;
+               while (Buffer > Orig)
+               {
+                  Buffer--;
+                  *Buffer = 0;
+                  if (EchoOn)
+                     DbgPrint("%c %c", KEY_BS, KEY_BS);
+                  else
+                     DbgPrint(" %c", KEY_BS);
+               }
+               i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
+               memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
+               Orig[i] = '\0';
+               Buffer = Orig + i;
+               DbgPrint("%s", Orig);
+            }
+         }
+      }
+      else
+      {
+         if (EchoOn)
+            DbgPrint("%c", Key);
+
+         *Buffer = Key;
+         Buffer++;
+      }
+   }
+}
+
+/*!\brief Parses command line and executes command if found
+ *
+ * \param Command    Command line to parse and execute if possible.
+ *
+ * \retval TRUE   Don't continue execution.
+ * \retval FALSE  Continue execution (leave KDB)
+ */
+STATIC BOOL
+KdbpDoCommand(
+   IN PCHAR Command)
+{
+   ULONG i;
+   PCHAR p;
+   ULONG Argc;
+   STATIC PCH Argv[256];
+   STATIC CHAR OrigCommand[1024];
+
+   strncpy(OrigCommand, Command, sizeof(OrigCommand) - 1);
+   OrigCommand[sizeof(OrigCommand) - 1] = '\0';
+
+   Argc = 0;
+   p = Command;
+   for (;;)
+   {
+      while (*p == '\t' || *p == ' ')
+         p++;
+      if (*p == '\0')
+         break;
+         
+      i = strcspn(p, "\t ");
+      Argv[Argc++] = p;
+      p += i;
+      if (*p == '\0')
+         break;
+      *p = '\0';
+      p++;
+   }
+   if (Argc < 1)
+      return TRUE;
+
+   for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
+   {
+      if (KdbDebuggerCommands[i].Name == NULL)
+         continue;
+
+      if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
+      {
+         return KdbDebuggerCommands[i].Fn(Argc, Argv);
+      }
+   }
+
+   KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
+   return TRUE;
+}
+
+/*!\brief KDB Main Loop.
+ *
+ * \param EnteredOnSingleStep  TRUE if KDB was entered on single step.
+ */
+VOID
+KdbpCliMainLoop(
+   IN BOOLEAN EnteredOnSingleStep)
+{
+   STATIC CHAR Command[1024];
+   BOOLEAN Continue;
+
+   if (EnteredOnSingleStep)
+   {
+      if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
+      {
+         DbgPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip);
+      }
+      DbgPrint(": ");
+      if (KdbpDisassemble(KdbCurrentTrapFrame->Tf.Eip, KdbUseIntelSyntax) < 0)
+      {
+         DbgPrint("<INVALID>");
+      }
+      DbgPrint("\n");
+   }
+
+   /* Flush the input buffer */
+   if (KdDebugState & KD_DEBUG_KDSERIAL)
+   {
+      while (KdbpTryGetCharSerial(1) != -1);
+   }
+   else
+   {
+      ULONG ScanCode;
+      while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
+   }
+
+   /* Main loop */
+   do
+   {
+      /* Print the prompt */
+      DbgPrint("kdb:> ");
+
+      /* Read a command and remember it */
+      KdbpReadCommand(Command, sizeof (Command));
+      KdbpCommandHistoryAppend(Command);
+      
+      /* Reset the number of rows/cols printed and output aborted state */
+      KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0;
+      KdbOutputAborted = FALSE;
+      
+      /* Call the command */
+      Continue = KdbpDoCommand(Command);
+   } while (Continue);
+}
+
+/*!\brief Called when a module is loaded.
+ *
+ * \param Name  Filename of the module which was loaded.
+ */
+VOID
+KdbpCliModuleLoaded(IN PUNICODE_STRING Name)
+{
+   return;
+
+   DbgPrint("Module %wZ loaded.\n", Name);
+   DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
+}
+
+/*!\brief This function is called by KdbEnterDebuggerException...
+ *
+ * Used to interpret the init file in a context with a trapframe setup
+ * (KdbpCliInit call KdbEnter which will call KdbEnterDebuggerException which will
+ * call this function if KdbInitFileBuffer is not NULL.
+ */
+VOID
+KdbpCliInterpretInitFile()
+{
+   PCHAR p1, p2;
+   INT i;
+   CHAR c;
+
+   /* Execute the commands in the init file */
+   DbgPrint("KDB: Executing KDBinit file...\n");
+   p1 = KdbInitFileBuffer;
+   while (p1[0] != '\0')
+   {
+      i = strcspn(p1, "\r\n");
+      if (i > 0)
+      {
+         c = p1[i];
+         p1[i] = '\0';
+
+         /* Look for "break" command and comments */
+         p2 = p1;
+         while (isspace(p2[0]))
+            p2++;
+         if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
+             (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
+         {
+            /* break into the debugger */
+            KdbpCliMainLoop(FALSE);
+         }
+         else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
+         {
+            KdbpDoCommand(p1);
+         }
+         
+         p1[i] = c;
+      }
+      p1 += i;
+      while (p1[0] == '\r' || p1[0] == '\n')
+         p1++;
+   }
+   DbgPrint("KDB: KDBinit executed\n");
+}
+
+/*!\brief Called when KDB is initialized
+ *
+ * Reads the KDBinit file from the SystemRoot\system32\drivers\etc directory and executes it.
+ */
+VOID
+KdbpCliInit()
+{
+   NTSTATUS Status;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING FileName;
+   IO_STATUS_BLOCK Iosb;
+   FILE_STANDARD_INFORMATION FileStdInfo;
+   HANDLE hFile = NULL;
+   INT FileSize;
+   PCHAR FileBuffer;
+   ULONG OldEflags;
+
+   /* Initialize the object attributes */
+   RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
+   InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
+   
+   /* Open the file */
+   Status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &Iosb, 0,
+                       FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
+                       FILE_NO_INTERMEDIATE_BUFFERING);
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT("Could not open \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+      return;
+   }
+
+   /* Get the size of the file */
+   Status = ZwQueryInformationFile(hFile, &Iosb, &FileStdInfo, sizeof (FileStdInfo),
+                                   FileStandardInformation);
+   if (!NT_SUCCESS(Status))
+   {
+      ZwClose(hFile);
+      DPRINT("Could not query size of \\SystemRoot\\system32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
+      return;
+   }
+   FileSize = FileStdInfo.EndOfFile.u.LowPart;
+
+   /* Allocate memory for the file */
+   FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
+   if (FileBuffer == NULL)
+   {
+      ZwClose(hFile);
+      DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
+      return;
+   }
+
+   /* Load file into memory */
+   Status = ZwReadFile(hFile, 0, 0, 0, &Iosb, FileBuffer, FileSize, 0, 0);
+   ZwClose(hFile);
+   if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
+   {
+      ExFreePool(FileBuffer);
+      DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
+      return;
+   }
+   FileSize = min(FileSize, Iosb.Information);
+   FileBuffer[FileSize] = '\0';
+
+   /* Enter critical section */
+   Ke386SaveFlags(OldEflags);
+   Ke386DisableInterrupts();
+
+   /* Interpret the init file... */
+   KdbInitFileBuffer = FileBuffer;
+   KdbEnter();
+   KdbInitFileBuffer = NULL;
+
+   /* Leave critical section */
+   Ke386RestoreFlags(OldEflags);
+
+   ExFreePool(FileBuffer);
+}
+
diff --git a/reactos/ntoskrnl/dbg/kdb_expr.c b/reactos/ntoskrnl/dbg/kdb_expr.c
new file mode 100644 (file)
index 0000000..fb36fed
--- /dev/null
@@ -0,0 +1,1081 @@
+/*\r
+ *  ReactOS kernel\r
+ *  Copyright (C) 2005 ReactOS Team\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+/* $Id$\r
+ *\r
+ * PROJECT:         ReactOS kernel\r
+ * FILE:            ntoskrnl/dbg/kdb_expr.c\r
+ * PURPOSE:         Kernel debugger expression evaluation\r
+ * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)\r
+ * UPDATE HISTORY:\r
+ *                  Created 15/01/2005\r
+ */\r
+\r
+/* Note:\r
+ *\r
+ * The given expression is parsed and stored in reverse polish notation,\r
+ * then it is evaluated and the result is returned.\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#include "kdb.h"\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* TYPES *********************************************************************/\r
+typedef enum _RPN_OP_TYPE\r
+{\r
+   RpnOpNop,\r
+   RpnOpBinaryOperator,\r
+   RpnOpUnaryOperator,\r
+   RpnOpImmediate,\r
+   RpnOpRegister,\r
+   RpnOpDereference\r
+} RPN_OP_TYPE;\r
+\r
+typedef ULONGLONG (*RPN_BINARY_OPERATOR)(ULONGLONG a, ULONGLONG b);\r
+\r
+typedef struct _RPN_OP\r
+{\r
+   RPN_OP_TYPE  Type;\r
+   ULONG        CharacterOffset;\r
+   union {\r
+      /* RpnOpBinaryOperator */\r
+      RPN_BINARY_OPERATOR  BinaryOperator;\r
+      /* RpnOpImmediate */\r
+      ULONGLONG            Immediate;\r
+      /* RpnOpRegister */\r
+      UCHAR                Register;\r
+      /* RpnOpDereference */\r
+      UCHAR                DerefMemorySize;\r
+   } Data;\r
+} RPN_OP, *PRPN_OP;\r
+\r
+typedef struct _RPN_STACK\r
+{\r
+   ULONG   Size;     /* Number of RPN_OPs on Ops */\r
+   ULONG   Sp;       /* Stack pointer */\r
+   RPN_OP  Ops[1];   /* Array of RPN_OPs */\r
+} RPN_STACK, *PRPN_STACK;\r
+\r
+/* DEFINES *******************************************************************/\r
+#define stricmp _stricmp\r
+\r
+#ifndef RTL_FIELD_SIZE\r
+# define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))\r
+#endif\r
+\r
+#define CONST_STRCPY(dst, src) \\r
+        do { if ((dst) != NULL) { memcpy(dst, src, sizeof(src)); } } while (0);\r
+\r
+#define RPN_OP_STACK_SIZE     256\r
+#define RPN_VALUE_STACK_SIZE  256\r
+\r
+/* GLOBALS *******************************************************************/\r
+STATIC struct { ULONG Size; ULONG Sp; RPN_OP Ops[RPN_OP_STACK_SIZE]; } RpnStack = { RPN_OP_STACK_SIZE, 0 };\r
+\r
+STATIC CONST struct { PCHAR Name; UCHAR Offset; UCHAR Size; } RegisterToTrapFrame[] =\r
+{\r
+   {"eip",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)},\r
+   {"eflags",  FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eflags),  RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eflags)},\r
+   {"eax",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eax),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eax)},\r
+   {"ebx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebx)},\r
+   {"ecx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ecx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ecx)},\r
+   {"edx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edx)},\r
+   {"esi",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esi),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esi)},\r
+   {"edi",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edi),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edi)},\r
+   {"esp",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esp),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esp)},\r
+   {"ebp",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebp),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebp)},\r
+   {"cs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Cs),      2 }, /* Use only the lower 2 bytes */\r
+   {"ds",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ds),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ds)},\r
+   {"es",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Es),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Es)},\r
+   {"fs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Fs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Fs)},\r
+   {"gs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Gs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Gs)},\r
+   {"ss",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ss),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ss)},\r
+   {"dr0",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr0),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr0)},\r
+   {"dr1",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr1),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr1)},\r
+   {"dr2",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr2),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr2)},\r
+   {"dr3",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr3),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr3)},\r
+   {"dr6",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr6),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr6)},\r
+   {"dr7",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr7),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr7)},\r
+   {"cr0",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr0),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr0)},\r
+   {"cr2",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr2),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr2)},\r
+   {"cr3",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)},\r
+   {"cr4",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)}\r
+};\r
+STATIC CONST INT RegisterToTrapFrameCount =\r
+                     sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]);\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorAdd(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return a + b;\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorSub(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return a - b;\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorMul(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return a * b;\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorDiv(ULONGLONG a, ULONGLONG b)\r
+{\r
+\r
+   return a / b;\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorMod(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return a % b;\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorEquals(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a == b);\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorNotEquals(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a != b);\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorLessThan(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a < b);\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorLessThanOrEquals(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a <= b);\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorGreaterThan(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a > b);\r
+}\r
+\r
+ULONGLONG\r
+RpnBinaryOperatorGreaterThanOrEquals(ULONGLONG a, ULONGLONG b)\r
+{\r
+   return (a >= b);\r
+}\r
+\r
+/*!\brief Dumps the given RPN stack content\r
+ *\r
+ * \param Stack  Pointer to a RPN_STACK structure.\r
+ */\r
+VOID\r
+RpnpDumpStack(\r
+   IN PRPN_STACK Stack)\r
+{\r
+   ULONG ul;\r
+\r
+   ASSERT(Stack != NULL);\r
+   DbgPrint("\nStack size: %ld\n", Stack->Sp);\r
+   for (ul = 0; ul < Stack->Sp; ul++)\r
+   {\r
+      PRPN_OP Op = Stack->Ops + ul;\r
+      switch (Op->Type)\r
+      {\r
+      case RpnOpNop:\r
+         DbgPrint("NOP,");\r
+         break;\r
+         \r
+      case RpnOpImmediate:\r
+         DbgPrint("0x%I64x,", Op->Data.Immediate);\r
+         break;\r
+         \r
+      case RpnOpBinaryOperator:\r
+         if (Op->Data.BinaryOperator == RpnBinaryOperatorAdd)\r
+            DbgPrint("+,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorSub)\r
+            DbgPrint("-,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorMul)\r
+            DbgPrint("*,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorDiv)\r
+            DbgPrint("/,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorMod)\r
+            DbgPrint("%%,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorEquals)\r
+            DbgPrint("==,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorNotEquals)\r
+            DbgPrint("!=,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThan)\r
+            DbgPrint("<,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThanOrEquals)\r
+            DbgPrint("<=,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThan)\r
+            DbgPrint(">,");\r
+         else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThanOrEquals)\r
+            DbgPrint(">=,");\r
+         else\r
+            DbgPrint("UNKNOWN OP,");\r
+         break;\r
+         \r
+      case RpnOpRegister:\r
+         DbgPrint("%s,", RegisterToTrapFrame[Op->Data.Register].Name);\r
+         break;\r
+         \r
+      case RpnOpDereference:\r
+         DbgPrint("[%s],",\r
+                (Op->Data.DerefMemorySize == 1) ? ("byte") :\r
+                ((Op->Data.DerefMemorySize == 2) ? ("word") :\r
+                 ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))\r
+                )\r
+               );\r
+         break;\r
+         \r
+      default:\r
+         DbgPrint("\nUnsupported Type: %d\n", Op->Type);\r
+         ul = Stack->Sp;\r
+         break;\r
+      }\r
+   }\r
+   DbgPrint("\n");\r
+}\r
+\r
+/*!\brief Clears the given RPN stack.\r
+ *\r
+ * \param Stack  Pointer to a RPN_STACK structure.\r
+ */\r
+STATIC VOID\r
+RpnpClearStack(\r
+   OUT PRPN_STACK Stack)\r
+{\r
+   ASSERT(Stack != NULL);\r
+   Stack->Sp = 0;\r
+}\r
+\r
+/*!\brief Pushes an RPN_OP onto the stack.\r
+ *\r
+ * \param Stack  Pointer to a RPN_STACK structure.\r
+ * \param Op     RPN_OP to be copied onto the stack.\r
+ */\r
+STATIC BOOLEAN\r
+RpnpPushStack(\r
+   IN OUT PRPN_STACK Stack,\r
+   IN     PRPN_OP Op)\r
+{\r
+   ASSERT(Stack != NULL);\r
+   ASSERT(Op != NULL);\r
+\r
+   if (Stack->Sp >= Stack->Size)\r
+      return FALSE;\r
+\r
+   memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));\r
+   Stack->Sp++;\r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Pops the top op from the stack.\r
+ *\r
+ * \param Stack  Pointer to a RPN_STACK structure.\r
+ * \param Op     Pointer to an RPN_OP to store the popped op into (can be NULL).\r
+ *\r
+ * \retval TRUE   Success.\r
+ * \retval FALSE  Failure (stack empty)\r
+ */\r
+STATIC BOOLEAN\r
+RpnpPopStack(\r
+   IN OUT PRPN_STACK Stack,\r
+   OUT    PRPN_OP Op  OPTIONAL)\r
+{\r
+   ASSERT(Stack != NULL);\r
+\r
+   if (Stack->Sp == 0)\r
+      return FALSE;\r
+\r
+   Stack->Sp--;\r
+   if (Op != NULL)\r
+      memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));\r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Gets the top op from the stack (not popping it)\r
+ *\r
+ * \param Stack  Pointer to a RPN_STACK structure.\r
+ * \param Op     Pointer to an RPN_OP to copy the top op into.\r
+ *\r
+ * \retval TRUE   Success.\r
+ * \retval FALSE  Failure (stack empty)\r
+ */\r
+STATIC BOOLEAN\r
+RpnpTopStack(\r
+   IN  PRPN_STACK Stack,\r
+   OUT PRPN_OP Op)\r
+{\r
+   ASSERT(Stack != NULL);\r
+   ASSERT(Op != NULL);\r
+\r
+   if (Stack->Sp == 0)\r
+      return FALSE;\r
+\r
+   memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));\r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Parses an expression.\r
+ *\r
+ * This functions parses the given expression until the end of string or a closing\r
+ * brace is found. As the function parses the string it pushes RPN_OPs onto the\r
+ * stack.\r
+ *\r
+ * Examples: 1+2*3 ; eax+10 ; (eax+16) * (ebx+4) ; dword[eax]\r
+ *\r
+ * \param Stack            Pointer to a RPN_STACK structure.\r
+ * \param Expression       String to parse.\r
+ * \param CharacterOffset  Character offset of the subexpression from the beginning of the expression.\r
+ * \param End              On success End is set to the character at which parsing stopped.\r
+ * \param ErrOffset        On failure this is set to the character offset at which the error occoured.\r
+ * \param ErrMsg           On failure a message describing the problem is copied into this buffer (128 bytes)\r
+ *\r
+ * \retval TRUE   Success.\r
+ * \retval FALSE  Failure.\r
+ */\r
+STATIC BOOLEAN\r
+RpnpParseExpression(\r
+   IN  PRPN_STACK Stack,\r
+   IN  PCHAR Expression,\r
+   OUT PCHAR *End  OPTIONAL,\r
+   IN  ULONG CharacterOffset,\r
+   OUT PLONG ErrOffset  OPTIONAL,\r
+   OUT PCHAR ErrMsg  OPTIONAL)\r
+{\r
+   PCHAR p = Expression;\r
+   PCHAR pend;\r
+   PCHAR Operator = NULL;\r
+   LONG OperatorOffset = -1;\r
+   RPN_OP RpnOp;\r
+   RPN_OP PoppedOperator;\r
+   BOOLEAN HavePoppedOperator = FALSE;\r
+   RPN_OP ComparativeOp;\r
+   BOOLEAN ComparativeOpFilled = FALSE;\r
+   BOOLEAN IsComparativeOp;\r
+   INT i, i2;\r
+   ULONG ul;\r
+   UCHAR MemorySize;\r
+   CHAR Buffer[16];\r
+   BOOLEAN First;\r
+\r
+   ASSERT(Stack != NULL);\r
+   ASSERT(Expression != NULL);\r
+\r
+   First = TRUE;\r
+   for (;;)\r
+   {\r
+      /* Skip whitespace */\r
+      while (isspace(*p))\r
+      {\r
+         p++;\r
+         CharacterOffset++;\r
+      }\r
+      \r
+      /* Check for end of expression */\r
+      if (p[0] == '\0' || p[0] == ')' || p[0] == ']')\r
+         break;\r
+\r
+      if (!First)\r
+      {\r
+         /* Remember operator */\r
+         Operator = p++;\r
+         OperatorOffset = CharacterOffset++;;\r
+      \r
+         /* Pop operator (to get the right operator precedence) */\r
+         HavePoppedOperator = FALSE;\r
+         if (*Operator == '*' || *Operator == '/' || *Operator == '%')\r
+         {\r
+            if (RpnpTopStack(Stack, &PoppedOperator) &&\r
+                PoppedOperator.Type == RpnOpBinaryOperator &&\r
+                (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd ||\r
+                PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub))\r
+            {\r
+               RpnpPopStack(Stack, NULL);\r
+               HavePoppedOperator = TRUE;\r
+            }\r
+            else if (PoppedOperator.Type == RpnOpNop)\r
+            {\r
+               RpnpPopStack(Stack, NULL);\r
+               /* Discard the NOP - it was only pushed to indicate there was a\r
+                * closing brace, so the previous operator shouldn't be popped.\r
+                */\r
+            }\r
+         }\r
+         else if ((Operator[0] == '=' && Operator[1] == '=') ||\r
+                  (Operator[0] == '!' && Operator[1] == '=') ||\r
+                  Operator[0] == '<' || Operator[0] == '>')\r
+         {\r
+            if (Operator[0] == '=' || Operator[0] == '!' ||\r
+                (Operator[0] == '<' && Operator[1] == '=') ||\r
+                (Operator[0] == '>' && Operator[1] == '='))\r
+            {\r
+               p++;\r
+               CharacterOffset++;\r
+            }\r
+#if 0\r
+            /* Parse rest of expression */\r
+            if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,\r
+                                     ErrOffset, ErrMsg))\r
+            {\r
+               return FALSE;\r
+            }\r
+            else if (pend == p + 1)\r
+            {\r
+               CONST_STRCPY(ErrMsg, "Expression expected");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = CharacterOffset + 1;\r
+               return FALSE;\r
+            }\r
+            goto end_of_expression; /* return */\r
+#endif\r
+         }\r
+         else if (Operator[0] != '+' && Operator[0] != '-')\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Operator expected");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = OperatorOffset;\r
+            return FALSE;\r
+         }\r
+\r
+         /* Skip whitespace */\r
+         while (isspace(*p))\r
+         {\r
+            p++;\r
+            CharacterOffset++;\r
+         }\r
+      }\r
+\r
+      /* Get operand */\r
+      MemorySize = sizeof(ULONG_PTR); /* default to pointer size */\r
+get_operand:\r
+      i = strcspn(p, "+-*/%()[]<>!=");\r
+      if (i > 0)\r
+      {\r
+         i2 = i;\r
+\r
+         /* Copy register name/memory size */\r
+         while (isspace(p[--i2]));\r
+         i2 = min(i2 + 1, sizeof (Buffer) - 1);\r
+         strncpy(Buffer, p, i2);\r
+         Buffer[i2] = '\0';\r
+\r
+         /* Memory size prefix */\r
+         if (p[i] == '[')\r
+         {\r
+            if (stricmp(Buffer, "byte") == 0)\r
+               MemorySize = 1;\r
+            else if (stricmp(Buffer, "word") == 0)\r
+               MemorySize = 2;\r
+            else if (stricmp(Buffer, "dword") == 0)\r
+               MemorySize = 4;\r
+            else if (stricmp(Buffer, "qword") == 0)\r
+               MemorySize = 8;\r
+            else\r
+            {\r
+               CONST_STRCPY(ErrMsg, "Invalid memory size prefix");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = CharacterOffset;\r
+               return FALSE;\r
+            }\r
+            \r
+            p += i;\r
+            CharacterOffset += i;\r
+            goto get_operand;\r
+         }\r
+\r
+         /* Try to find register */\r
+         for (i = 0; i < RegisterToTrapFrameCount; i++)\r
+         {\r
+            if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0)\r
+               break;\r
+         }\r
+         if (i < RegisterToTrapFrameCount)\r
+         {\r
+            RpnOp.Type = RpnOpRegister;\r
+            RpnOp.CharacterOffset = CharacterOffset;\r
+            RpnOp.Data.Register = i;\r
+            i = strlen(RegisterToTrapFrame[i].Name);\r
+            CharacterOffset += i;\r
+            p += i;\r
+         }\r
+         else\r
+         {\r
+            /* Immediate value */\r
+            /* FIXME: Need string to ULONGLONG function */\r
+            ul = strtoul(p, &pend, 0);\r
+            if (p != pend)\r
+            {\r
+               RpnOp.Type = RpnOpImmediate;\r
+               RpnOp.CharacterOffset = CharacterOffset;\r
+               RpnOp.Data.Immediate = (ULONGLONG)ul;\r
+               CharacterOffset += pend - p;\r
+               p = pend;\r
+            }\r
+            else\r
+            {\r
+               CONST_STRCPY(ErrMsg, "Operand expected");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = CharacterOffset;\r
+               return FALSE;\r
+            }\r
+         }\r
+\r
+         /* Push operand */\r
+         if (!RpnpPushStack(Stack, &RpnOp))\r
+         {\r
+            CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+      }\r
+      else if (i == 0)\r
+      {\r
+         if (p[0] == '(' || p[0] == '[') /* subexpression */\r
+         {\r
+            if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,\r
+                                     ErrOffset, ErrMsg))\r
+            {\r
+               return FALSE;\r
+            }\r
+            else if (pend == p + 1)\r
+            {\r
+               CONST_STRCPY(ErrMsg, "Expression expected");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = CharacterOffset + 1;\r
+               return FALSE;\r
+            }\r
+\r
+            if (p[0] == '[') /* dereference */\r
+            {\r
+               ASSERT(MemorySize == 1 || MemorySize == 2 ||\r
+                      MemorySize == 4 || MemorySize == 8);\r
+               if (pend[0] != ']')\r
+               {\r
+                  CONST_STRCPY(ErrMsg, "']' expected");\r
+                  if (ErrOffset != NULL)\r
+                     *ErrOffset = CharacterOffset + (pend - p);\r
+                  return FALSE;\r
+               }\r
+               RpnOp.Type = RpnOpDereference;\r
+               RpnOp.CharacterOffset = CharacterOffset;\r
+               RpnOp.Data.DerefMemorySize = MemorySize;\r
+               if (!RpnpPushStack(Stack, &RpnOp))\r
+               {\r
+                  CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+                  if (ErrOffset != NULL)\r
+                     *ErrOffset = -1;\r
+                  return FALSE;\r
+               }\r
+            }\r
+            else /* p[0] == '(' */\r
+            {\r
+               if (pend[0] != ')')\r
+               {\r
+                  CONST_STRCPY(ErrMsg, "')' expected");\r
+                  if (ErrOffset != NULL)\r
+                     *ErrOffset = CharacterOffset + (pend - p);\r
+                  return FALSE;\r
+               }\r
+            }\r
+\r
+            /* Push a "nop" to prevent popping of the + operator (which would\r
+             * result in (10+10)/2 beeing evaluated as 15)\r
+             */\r
+            RpnOp.Type = RpnOpNop;\r
+            if (!RpnpPushStack(Stack, &RpnOp))\r
+            {\r
+               CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = -1;\r
+               return FALSE;\r
+            }\r
+\r
+            /* Skip closing brace/bracket */\r
+            pend++;\r
+            \r
+            CharacterOffset += pend - p;\r
+            p = pend;\r
+         }\r
+         else if (First && p[0] == '-') /* Allow expressions like "- eax" */\r
+         {\r
+            RpnOp.Type = RpnOpImmediate;\r
+            RpnOp.CharacterOffset = CharacterOffset;\r
+            RpnOp.Data.Immediate = 0;\r
+            if (!RpnpPushStack(Stack, &RpnOp))\r
+            {\r
+               CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = -1;\r
+               return FALSE;\r
+            }\r
+         }\r
+         else\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Operand expected");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = CharacterOffset;\r
+            return FALSE;\r
+         }\r
+      }\r
+      else\r
+      {\r
+         CONST_STRCPY(ErrMsg, "strcspn() failed");\r
+         if (ErrOffset != NULL)\r
+            *ErrOffset = -1;\r
+         return FALSE;\r
+      }\r
+\r
+      if (!First)\r
+      {\r
+         /* Push operator */\r
+         RpnOp.CharacterOffset = OperatorOffset;\r
+         RpnOp.Type = RpnOpBinaryOperator;\r
+         IsComparativeOp = FALSE;\r
+         switch (*Operator)\r
+         {\r
+         case '+':\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorAdd;\r
+            break;\r
+\r
+         case '-':\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorSub;\r
+            break;\r
+\r
+         case '*':\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorMul;\r
+            break;\r
+\r
+         case '/':\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorDiv;\r
+            break;\r
+\r
+         case '%':\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorMod;\r
+            break;\r
+\r
+         case '=':\r
+            ASSERT(Operator[1] == '=');\r
+            IsComparativeOp = TRUE;\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorEquals;\r
+            break;\r
+            \r
+         case '!':\r
+            ASSERT(Operator[1] == '=');\r
+            IsComparativeOp = TRUE;\r
+            RpnOp.Data.BinaryOperator = RpnBinaryOperatorNotEquals;\r
+            break;\r
+\r
+         case '<':\r
+            IsComparativeOp = TRUE;\r
+            if (Operator[1] == '=')\r
+               RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals;\r
+            else\r
+               RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan;\r
+            break;\r
+\r
+         case '>':\r
+            IsComparativeOp = TRUE;\r
+            if (Operator[1] == '=')\r
+               RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals;\r
+            else\r
+               RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan;\r
+            break;\r
+\r
+         default:\r
+            ASSERT(0);\r
+            break;\r
+         }\r
+         if (IsComparativeOp)\r
+         {\r
+            if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))\r
+            {\r
+               CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = -1;\r
+               return FALSE;\r
+            }\r
+            memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));\r
+            ComparativeOpFilled = TRUE;\r
+         }\r
+         else if (!RpnpPushStack(Stack, &RpnOp))\r
+         {\r
+            CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+\r
+         /* Push popped operator */\r
+         if (HavePoppedOperator)\r
+         {\r
+            if (!RpnpPushStack(Stack, &PoppedOperator))\r
+            {\r
+               CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+               if (ErrOffset != NULL)\r
+                  *ErrOffset = -1;\r
+               return FALSE;\r
+            }\r
+         }\r
+      }\r
+      \r
+      First = FALSE;\r
+   }\r
+   \r
+//end_of_expression:\r
+\r
+   if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))\r
+   {\r
+      CONST_STRCPY(ErrMsg, "RPN op stack overflow");\r
+      if (ErrOffset != NULL)\r
+         *ErrOffset = -1;\r
+      return FALSE;\r
+   }\r
+\r
+   /* Skip whitespace */\r
+   while (isspace(*p))\r
+   {\r
+      p++;\r
+      CharacterOffset++;\r
+   }\r
+\r
+   if (End != NULL)\r
+      *End = p;\r
+   \r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Evaluates the RPN op stack and returns the result.\r
+ *\r
+ * \param Stack      Pointer to a RPN_STACK structure.\r
+ * \param TrapFrame  Register values.\r
+ * \param Result     Pointer to an ULONG to store the result into.\r
+ * \param ErrOffset  On failure this is set to the character offset at which the error occoured.\r
+ * \param ErrMsg     Buffer which receives an error message on failure (128 bytes)\r
+ *\r
+ * \retval TRUE   Success.\r
+ * \retval FALSE  Failure.\r
+ */\r
+STATIC BOOLEAN\r
+RpnpEvaluateStack(\r
+   IN  PRPN_STACK Stack,\r
+   IN  PKDB_KTRAP_FRAME TrapFrame,\r
+   OUT PULONGLONG Result,\r
+   OUT PLONG ErrOffset  OPTIONAL,\r
+   OUT PCHAR ErrMsg  OPTIONAL)\r
+{\r
+   ULONGLONG ValueStack[RPN_VALUE_STACK_SIZE];\r
+   ULONG ValueStackPointer = 0;\r
+   ULONG index;\r
+   ULONGLONG ull;\r
+   ULONG ul;\r
+   USHORT us;\r
+   UCHAR uc;\r
+   PVOID p;\r
+   BOOLEAN Ok;\r
+#ifdef DEBUG_RPN\r
+   ULONG ValueStackPointerMax = 0;\r
+#endif\r
+\r
+   ASSERT(Stack != NULL);\r
+   ASSERT(TrapFrame != NULL);\r
+   ASSERT(Result != NULL);\r
+\r
+   for (index = 0; index < Stack->Sp; index++)\r
+   {\r
+      PRPN_OP Op = Stack->Ops + index;\r
+\r
+#ifdef DEBUG_RPN\r
+      ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer);\r
+#endif\r
+\r
+      switch (Op->Type)\r
+      {\r
+      case RpnOpNop:\r
+         /* No operation */\r
+         break;\r
+         \r
+      case RpnOpImmediate:\r
+         if (ValueStackPointer == RPN_VALUE_STACK_SIZE)\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Value stack overflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+         ValueStack[ValueStackPointer++] = Op->Data.Immediate;\r
+         break;\r
+\r
+      case RpnOpRegister:\r
+         if (ValueStackPointer == RPN_VALUE_STACK_SIZE)\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Value stack overflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+         ul = Op->Data.Register;\r
+         p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);\r
+         switch (RegisterToTrapFrame[ul].Size)\r
+         {\r
+         case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;\r
+         case 2: ull = (ULONGLONG)(*(PUSHORT)p); break;\r
+         case 4: ull = (ULONGLONG)(*(PULONG)p); break;\r
+         case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;\r
+         default: ASSERT(0); return FALSE; break;\r
+         }\r
+         ValueStack[ValueStackPointer++] = ull;\r
+         break;\r
+\r
+      case RpnOpDereference:\r
+         if (ValueStackPointer < 1)\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Value stack underflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+\r
+         /* FIXME: Print a warning when address is out of range */\r
+         p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];\r
+         Ok = FALSE;\r
+         switch (Op->Data.DerefMemorySize)\r
+         {\r
+         case 1:\r
+            if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc))))\r
+            {\r
+               Ok = TRUE;\r
+               ull = (ULONGLONG)uc;\r
+            }\r
+            break;\r
+         case 2:\r
+            if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))\r
+            {\r
+               Ok = TRUE;\r
+               ull = (ULONGLONG)us;\r
+            }\r
+            break;\r
+         case 4:\r
+            if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))\r
+            {\r
+               Ok = TRUE;\r
+               ull = (ULONGLONG)ul;\r
+            }\r
+            break;\r
+         case 8:\r
+            if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))\r
+            {\r
+               Ok = TRUE;\r
+            }\r
+            break;\r
+         default:\r
+            ASSERT(0);\r
+            return FALSE;\r
+            break;\r
+         }\r
+         if (!Ok)\r
+         {\r
+            _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p);\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = Op->CharacterOffset;\r
+            return FALSE;\r
+         }\r
+         ValueStack[ValueStackPointer - 1] = ull;\r
+         break;\r
+\r
+      case RpnOpBinaryOperator:\r
+         if (ValueStackPointer < 2)\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Value stack underflow");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = -1;\r
+            return FALSE;\r
+         }\r
+         ValueStackPointer--;\r
+         ull = ValueStack[ValueStackPointer];\r
+         if (ull == 0 && (Op->Data.BinaryOperator == RpnBinaryOperatorDiv ||\r
+                          Op->Data.BinaryOperator == RpnBinaryOperatorDiv))\r
+         {\r
+            CONST_STRCPY(ErrMsg, "Devision by zero");\r
+            if (ErrOffset != NULL)\r
+               *ErrOffset = Op->CharacterOffset;\r
+            return FALSE;\r
+         }\r
+         ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);\r
+         ValueStack[ValueStackPointer - 1] = ull;\r
+         break;\r
+\r
+      default:\r
+         ASSERT(0);\r
+         return FALSE;\r
+      }\r
+   }\r
+#ifdef DEBUG_RPN\r
+   DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);\r
+#endif\r
+   if (ValueStackPointer != 1)\r
+   {\r
+      CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");\r
+      if (ErrOffset != NULL)\r
+         *ErrOffset = -1;\r
+      return FALSE;\r
+   }\r
+   \r
+   *Result = ValueStack[0];\r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Evaluates the given expression\r
+ *\r
+ * \param Expression  Expression to evaluate.\r
+ * \param TrapFrame   Register values.\r
+ * \param Result      Variable which receives the result on success.\r
+ * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)\r
+ * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)\r
+ *\r
+ * \retval TRUE   Success.\r
+ * \retval FALSE  Failure.\r
+ */\r
+BOOLEAN\r
+KdbpRpnEvaluateExpression(\r
+   IN  PCHAR Expression,\r
+   IN  PKDB_KTRAP_FRAME TrapFrame,\r
+   OUT PULONGLONG Result,\r
+   OUT PLONG ErrOffset  OPTIONAL,\r
+   OUT PCHAR ErrMsg  OPTIONAL)\r
+{\r
+   PRPN_STACK Stack = (PRPN_STACK)&RpnStack;\r
+   \r
+   ASSERT(Expression != NULL);\r
+   ASSERT(TrapFrame != NULL);\r
+   ASSERT(Result != NULL);\r
+\r
+   /* Clear the stack and parse the expression */\r
+   RpnpClearStack(Stack);\r
+   if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))\r
+   {\r
+      return FALSE;\r
+   }\r
+#ifdef DEBUG_RPN\r
+   RpnpDumpStack(Stack);\r
+#endif\r
+\r
+   /* Evaluate the stack */\r
+   if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))\r
+   {\r
+      return FALSE;\r
+   }\r
+\r
+   return TRUE;\r
+}\r
+\r
+/*!\brief Parses the given expression and returns a "handle" to it.\r
+ *\r
+ * \param Expression  Expression to evaluate.\r
+ * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)\r
+ * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)\r
+ *\r
+ * \returns "Handle" for the expression, NULL on failure.\r
+ *\r
+ * \sa KdbpRpnEvaluateExpression\r
+ */\r
+PVOID\r
+KdbpRpnParseExpression(\r
+   IN  PCHAR Expression,\r
+   OUT PLONG ErrOffset  OPTIONAL,\r
+   OUT PCHAR ErrMsg  OPTIONAL)\r
+{\r
+   LONG Size;\r
+   PRPN_STACK Stack = (PRPN_STACK)&RpnStack;\r
+   PRPN_STACK NewStack;\r
+\r
+   ASSERT(Expression != NULL);\r
+\r
+   /* Clear the stack and parse the expression */\r
+   RpnpClearStack(Stack);\r
+   if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))\r
+   {\r
+      return FALSE;\r
+   }\r
+#ifdef DEBUG_RPN\r
+   RpnpDumpStack(Stack);\r
+#endif\r
+\r
+   /* Duplicate the stack and return a pointer/handle to it */\r
+   ASSERT(Stack->Sp >= 1);\r
+   Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));\r
+   NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG);\r
+   if (NewStack == NULL)\r
+   {\r
+      CONST_STRCPY(ErrMsg, "Out of memory");\r
+      if (ErrOffset != NULL)\r
+         *ErrOffset = -1;\r
+      return NULL;\r
+   }\r
+   memcpy(NewStack, Stack, Size);\r
+   NewStack->Size = NewStack->Sp;\r
+   \r
+   return NewStack;\r
+}\r
+\r
+/*!\brief Evaluates the given expression and returns the result.\r
+ *\r
+ * \param Expression  Expression "handle" returned by KdbpRpnParseExpression.\r
+ * \param TrapFrame   Register values.\r
+ * \param Result      Variable which receives the result on success.\r
+ * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)\r
+ * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)\r
+ *\r
+ * \returns "Handle" for the expression, NULL on failure.\r
+ *\r
+ * \sa KdbpRpnParseExpression\r
+ */\r
+BOOLEAN\r
+KdbpRpnEvaluateParsedExpression(\r
+   IN  PVOID Expression,\r
+   IN  PKDB_KTRAP_FRAME TrapFrame,\r
+   OUT PULONGLONG Result,\r
+   OUT PLONG ErrOffset  OPTIONAL,\r
+   OUT PCHAR ErrMsg  OPTIONAL)\r
+{\r
+   PRPN_STACK Stack = (PRPN_STACK)Expression;\r
+\r
+   ASSERT(Expression != NULL);\r
+   ASSERT(TrapFrame != NULL);\r
+   ASSERT(Result != NULL);\r
+\r
+   /* Evaluate the stack */\r
+   return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);\r
+}\r
+\r
index bc0c6b3..bf3bfdc 100644 (file)
@@ -62,12 +62,13 @@ VOID KbdDisableMouse()
 }
 
 CHAR
-KdbTryGetCharKeyboard(PULONG ScanCode)
+KdbpTryGetCharKeyboard(PULONG ScanCode, UINT Retry)
 {
     static byte_t last_key = 0;
     static byte_t shift = 0;
     char c;
-    while(1) {
+    BOOLEAN KeepRetrying = (Retry == 0);
+    while (KeepRetrying || Retry-- > 0) {
        unsigned char status = kbd_read_status();
        while (status & KBD_STAT_OBF) {
            byte_t scancode;
@@ -91,6 +92,8 @@ KdbTryGetCharKeyboard(PULONG ScanCode)
            }
        }
     }
+    
+    return -1;
 }
 
 #endif
@@ -305,7 +308,7 @@ static char keymap[128][2] = {
  * Yes, this is horrible.
  */
 ULONG
-KdbTryGetCharKeyboard(VOID)
+KdbpTryGetCharKeyboard(VOID)
 {
        static unsigned shift_state, ctrl_state, meta_state;
        unsigned scan_code, ch;
index bd2d8f2..519e3ec 100644 (file)
@@ -20,11 +20,14 @@ extern KD_PORT_INFORMATION LogPortInfo;
 
 
 CHAR
-KdbTryGetCharSerial()
+KdbpTryGetCharSerial(UINT Retry)
 {
-  UCHAR Result;
+  CHAR Result = -1;
 
-  while( !KdPortGetByteEx (&LogPortInfo, &Result) );
+  if (Retry == 0)
+     while (!KdPortGetByteEx(&LogPortInfo, (PUCHAR)&Result));
+  else
+     while (!KdPortGetByteEx(&LogPortInfo, (PUCHAR)&Result) && Retry-- > 0);
 
   return Result;
 }
diff --git a/reactos/ntoskrnl/dbg/kdb_string.c b/reactos/ntoskrnl/dbg/kdb_string.c
new file mode 100644 (file)
index 0000000..52f3ed4
--- /dev/null
@@ -0,0 +1,124 @@
+/*\r
+ *  ReactOS kernel\r
+ *  Copyright (C) 2005 ReactOS Team\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+/* $Id$\r
+ *\r
+ * PROJECT:         ReactOS kernel\r
+ * FILE:            ntoskrnl/dbg/kdb_string.c\r
+ * PURPOSE:         Kernel debugger string functions\r
+ * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)\r
+ * UPDATE HISTORY:\r
+ *                  Created 17/01/2005\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+#include <ntoskrnl.h>\r
+#include <ctype.h>\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+#if 0\r
+int\r
+_stricmp(\r
+   const char *s1,\r
+   const char *s2)\r
+{\r
+   char c1, c2;\r
+   for (;;)\r
+   {\r
+      c1 = tolower(*s1++);\r
+      c2 = tolower(*s2++);\r
+      if (c1 < c2)\r
+         return -1;\r
+      else if (c1 > c2)\r
+         return 1;\r
+      if (c1 == '\0')\r
+         break;\r
+   }\r
+   return 0;\r
+}\r
+#endif /* unused */\r
+\r
+/*\r
+ * Convert a string to an unsigned long integer.\r
+ *\r
+ * Ignores `locale' stuff.  Assumes that the upper and lower case\r
+ * alphabets and digits are each contiguous.\r
+ */\r
+unsigned long\r
+strtoul(const char *nptr, char **endptr, int base)\r
+{\r
+  const char *s = nptr;\r
+  unsigned long acc;\r
+  int c;\r
+  unsigned long cutoff;\r
+  int neg = 0, any, cutlim;\r
+\r
+  /*\r
+   * See strtol for comments as to the logic used.\r
+   */\r
+  do {\r
+    c = *s++;\r
+  } while (isspace(c));\r
+  if (c == '-')\r
+  {\r
+    neg = 1;\r
+    c = *s++;\r
+  }\r
+  else if (c == '+')\r
+    c = *s++;\r
+  if ((base == 0 || base == 16) &&\r
+      c == '0' && (*s == 'x' || *s == 'X'))\r
+  {\r
+    c = s[1];\r
+    s += 2;\r
+    base = 16;\r
+  }\r
+  if (base == 0)\r
+    base = c == '0' ? 8 : 10;\r
+  cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;\r
+  cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;\r
+  for (acc = 0, any = 0;; c = *s++)\r
+  {\r
+    if (isdigit(c))\r
+      c -= '0';\r
+    else if (isalpha(c))\r
+      c -= isupper(c) ? 'A' - 10 : 'a' - 10;\r
+    else\r
+      break;\r
+    if (c >= base)\r
+      break;\r
+    if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))\r
+      any = -1;\r
+    else {\r
+      any = 1;\r
+      acc *= base;\r
+      acc += c;\r
+    }\r
+  }\r
+  if (any < 0)\r
+  {\r
+    acc = ULONG_MAX;\r
+  }\r
+  else if (neg)\r
+    acc = -acc;\r
+  if (endptr != 0)\r
+    *endptr = any ? (char *)s - 1 : (char *)nptr;\r
+  return acc;\r
+}\r
+\r
index 618711e..c95259e 100644 (file)
@@ -243,12 +243,12 @@ KdbSymPrintAddress(IN PVOID Address)
                                        FunctionName);
   if (NT_SUCCESS(Status))
     {
-      DbgPrint("<%ws: %x (%s:%d (%s))>",
+      DbgPrint("<%ws:%x (%s:%d (%s))>",
                Info.Name, RelativeAddress, FileName, LineNumber, FunctionName);
     }
   else
     {
-      DbgPrint("<%ws: %x>", Info.Name, RelativeAddress);
+      DbgPrint("<%ws:%x>", Info.Name, RelativeAddress);
     }
 
   return TRUE;
@@ -541,7 +541,7 @@ KdbSymFreeProcessSymbols(IN PEPROCESS Process)
   CurrentProcess = PsGetCurrentProcess();
   if (CurrentProcess != Process)
   {
-    KeAttachProcess(&Process->Pcb);
+    KeAttachProcess(EPROCESS_TO_KPROCESS(Process));
   }
   Peb = Process->Peb;
   ASSERT(Peb);
diff --git a/reactos/ntoskrnl/dbg/profile.c b/reactos/ntoskrnl/dbg/profile.c
deleted file mode 100755 (executable)
index 3b23505..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/* $Id$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/dbg/profile.c
- * PURPOSE:         Kernel profiling
- * 
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include "kdb.h"
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-#define PROFILE_SESSION_LENGTH 30 /* Session length in seconds */
-
-typedef struct _PROFILE_DATABASE_ENTRY
-{
-  ULONG_PTR Address;
-} PROFILE_DATABASE_ENTRY, *PPROFILE_DATABASE_ENTRY;
-
-#define PDE_BLOCK_ENTRIES ((PAGE_SIZE - (sizeof(LIST_ENTRY) + sizeof(ULONG))) / sizeof(PROFILE_DATABASE_ENTRY))
-
-typedef struct _PROFILE_DATABASE_BLOCK
-{
-   LIST_ENTRY ListEntry;
-   ULONG UsedEntries;
-   PROFILE_DATABASE_ENTRY Entries[PDE_BLOCK_ENTRIES];
-} PROFILE_DATABASE_BLOCK, *PPROFILE_DATABASE_BLOCK;
-
-typedef struct _PROFILE_DATABASE
-{
-  LIST_ENTRY ListHead;
-} PROFILE_DATABASE, *PPROFILE_DATABASE;
-
-typedef struct _SAMPLE_GROUP_INFO
-{
-  ULONG_PTR Address;
-  ULONG Count;
-  CHAR Description[128];
-  LIST_ENTRY ListEntry;
-} SAMPLE_GROUP_INFO, *PSAMPLE_GROUP_INFO;
-
-static volatile BOOLEAN KdbProfilingInitialized = FALSE;
-static volatile BOOLEAN KdbProfilingEnabled = FALSE;
-static volatile BOOLEAN KdbProfilingSuspended = FALSE;
-static PPROFILE_DATABASE KdbProfileDatabase = NULL;
-static KDPC KdbProfilerCollectorDpc;
-static HANDLE KdbProfilerThreadHandle;
-static CLIENT_ID KdbProfilerThreadCid;
-static HANDLE KdbProfilerLogFile;
-static KTIMER KdbProfilerTimer;
-static KMUTEX KdbProfilerLock;
-static BOOLEAN KdbEnableProfiler = FALSE;
-
-VOID
-KdbDeleteProfileDatabase(PPROFILE_DATABASE ProfileDatabase)
-{
-  PLIST_ENTRY current = NULL;
-
-  current = RemoveHeadList(&ProfileDatabase->ListHead);
-  while (current != &ProfileDatabase->ListHead)
-    {
-      PPROFILE_DATABASE_BLOCK block = CONTAINING_RECORD(
-               current, PROFILE_DATABASE_BLOCK, ListEntry);
-         ExFreePool(block);
-         current = RemoveHeadList(&ProfileDatabase->ListHead);
-    }
-}
-
-VOID
-KdbAddEntryToProfileDatabase(PPROFILE_DATABASE ProfileDatabase, ULONG_PTR Address)
-{
-  PPROFILE_DATABASE_BLOCK block;
-
-  if (IsListEmpty(&ProfileDatabase->ListHead))
-    {
-      block = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE_BLOCK));
-      ASSERT(block);
-      block->UsedEntries = 0;
-      InsertTailList(&ProfileDatabase->ListHead, &block->ListEntry);
-      block->Entries[block->UsedEntries++].Address = Address;
-      return;
-    }
-
-  block = CONTAINING_RECORD(ProfileDatabase->ListHead.Blink, PROFILE_DATABASE_BLOCK, ListEntry);
-  if (block->UsedEntries >= PDE_BLOCK_ENTRIES)
-    {
-      block = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE_BLOCK));
-      ASSERT(block);
-      block->UsedEntries = 0;
-      InsertTailList(&ProfileDatabase->ListHead, &block->ListEntry);
-    }
-  block->Entries[block->UsedEntries++].Address = Address;
-}
-
-VOID INIT_FUNCTION
-KdbInitProfiling()
-{
-  KdbEnableProfiler = TRUE;
-}
-
-VOID INIT_FUNCTION
-KdbInitProfiling2()
-{
-  if (KdbEnableProfiler)
-    {
-      KdbEnableProfiling();
-      KdbProfilingInitialized = TRUE;
-    }
-}
-
-VOID
-KdbSuspendProfiling()
-{
-  KdbProfilingSuspended = TRUE;
-}
-
-VOID
-KdbResumeProfiling()
-{
-  KdbProfilingSuspended = FALSE;
-}
-
-BOOLEAN
-KdbProfilerGetSymbolInfo(PVOID address, OUT PCH NameBuffer)
-{
-   PLIST_ENTRY current_entry;
-   MODULE_TEXT_SECTION* current;
-   extern LIST_ENTRY ModuleTextListHead;
-   ULONG_PTR RelativeAddress;
-   NTSTATUS Status;
-   CHAR FileName[256];
-   CHAR FunctionName[256];
-
-   current_entry = ModuleTextListHead.Flink;
-   
-   while (current_entry != &ModuleTextListHead &&
-         current_entry != NULL)
-     {
-       current = 
-         CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
-
-       if (address >= (PVOID)current->Base &&
-           address < (PVOID)(current->Base + current->Length))
-         {
-            RelativeAddress = (ULONG_PTR) address - current->Base;
-            Status = KdbSymGetAddressInformation(current->RosSymInfo,
-              RelativeAddress,
-              NULL,
-              FileName,
-              FunctionName);
-            if (NT_SUCCESS(Status))
-              {
-                sprintf(NameBuffer, "%s (%s)", FunctionName, FileName);
-                return(TRUE);
-              }
-            return(TRUE);
-         }
-       current_entry = current_entry->Flink;
-     }
-   return(FALSE);
-}
-
-PLIST_ENTRY
-KdbProfilerLargestSampleGroup(PLIST_ENTRY SamplesListHead)
-{
-  PLIST_ENTRY current;
-  PLIST_ENTRY largest;
-  ULONG count;
-
-  count = 0;
-  largest = SamplesListHead->Flink;
-  current = SamplesListHead->Flink;
-  while (current != SamplesListHead)
-    {
-      PSAMPLE_GROUP_INFO sgi = CONTAINING_RECORD(
-               current, SAMPLE_GROUP_INFO, ListEntry);
-
-      if (sgi->Count > count)
-        {
-          largest = current;
-          count = sgi->Count;
-        }
-
-         current = current->Flink;
-    }
-  if (count == 0)
-    {
-      return NULL;
-    }
-  return largest;
-}
-
-VOID
-KdbProfilerWriteString(PCH String)
-{
-  IO_STATUS_BLOCK Iosb;
-  NTSTATUS Status;
-  ULONG Length;
-
-  Length = strlen(String);
-  Status = NtWriteFile(KdbProfilerLogFile,
-    NULL,
-    NULL,
-    NULL,
-    &Iosb,
-    String,
-    Length,
-    NULL,
-    NULL);
-
- if (!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtWriteFile() failed with status 0x%.08x\n", Status);
-   }
-}
-
-NTSTATUS
-KdbProfilerWriteSampleGroups(PLIST_ENTRY SamplesListHead)
-{
-  CHAR Buffer[256];
-  PLIST_ENTRY current = NULL;
-  PLIST_ENTRY Largest;
-
-  KdbProfilerWriteString("\r\n\r\n");
-  KdbProfilerWriteString("Count     Symbol\r\n");
-  KdbProfilerWriteString("--------------------------------------------------\r\n");
-
-  current = SamplesListHead->Flink;
-  while (current != SamplesListHead)
-    {
-      Largest = KdbProfilerLargestSampleGroup(SamplesListHead);
-      if (Largest != NULL)
-        {
-          PSAMPLE_GROUP_INFO sgi = CONTAINING_RECORD(
-                   Largest, SAMPLE_GROUP_INFO, ListEntry);
-
-                 //DbgPrint("%.08lu  %s\n", sgi->Count, sgi->Description);
-
-                 sprintf(Buffer, "%.08lu  %s\r\n", sgi->Count, sgi->Description);
-          KdbProfilerWriteString(Buffer);
-
-          RemoveEntryList(Largest);
-          ExFreePool(sgi);
-        }
-      else
-        {
-          break;
-        }
-
-         current = SamplesListHead->Flink;
-    }
-
-  return STATUS_SUCCESS;
-}
-
-LONG STDCALL
-KdbProfilerKeyCompare(IN PVOID  Key1,
-  IN PVOID  Key2)
-{
-  int value = strcmp(Key1, Key2);
-
-  if (value == 0)
-    return 0;
-
-  return (value < 0) ? -1 : 1;
-}
-
-
-NTSTATUS
-KdbProfilerAnalyzeSamples()
-{
-  CHAR NameBuffer[512];
-  ULONG KeyLength;
-  PLIST_ENTRY current = NULL;
-  HASH_TABLE Hashtable;
-  LIST_ENTRY SamplesListHead;
-  ULONG Index;
-  ULONG_PTR Address;
-
-  if (!ExInitializeHashTable(&Hashtable, 12, KdbProfilerKeyCompare, TRUE))
-    {
-      DPRINT1("ExInitializeHashTable() failed.");
-      KEBUGCHECK(0);
-    }
-
-  InitializeListHead(&SamplesListHead);
-
-  current = RemoveHeadList(&KdbProfileDatabase->ListHead);
-  while (current != &KdbProfileDatabase->ListHead)
-    {
-      PPROFILE_DATABASE_BLOCK block;
-
-      block = CONTAINING_RECORD(current, PROFILE_DATABASE_BLOCK, ListEntry);
-
-      for (Index = 0; Index < block->UsedEntries; Index++)
-        {
-          PSAMPLE_GROUP_INFO sgi;
-          Address = block->Entries[Index].Address;
-             if (KdbProfilerGetSymbolInfo((PVOID) Address, (PCH) &NameBuffer))
-               {
-               }
-             else
-                   {
-                 sprintf(NameBuffer, "(0x%.08lx)", (ULONG) Address);
-                   }
-
-             KeyLength = strlen(NameBuffer);
-             if (!ExSearchHashTable(&Hashtable, (PVOID) NameBuffer, KeyLength, (PVOID *) &sgi))
-               {
-                 sgi = ExAllocatePool(NonPagedPool, sizeof(SAMPLE_GROUP_INFO));
-                 ASSERT(sgi);
-              sgi->Address = Address;
-                 sgi->Count = 1;
-                 strcpy(sgi->Description, NameBuffer);
-                 InsertTailList(&SamplesListHead, &sgi->ListEntry);
-                 ExInsertHashTable(&Hashtable, sgi->Description, KeyLength, (PVOID) sgi);
-               }
-             else
-               {
-                 sgi->Count++;
-               }
-        }
-
-      ExFreePool(block);
-
-      current = RemoveHeadList(&KdbProfileDatabase->ListHead);
-    }
-
-  KdbProfilerWriteSampleGroups(&SamplesListHead);
-
-  ExDeleteHashTable(&Hashtable);
-
-  KdbDeleteProfileDatabase(KdbProfileDatabase);
-
-  return STATUS_SUCCESS;
-}
-
-VOID STDCALL
-KdbProfilerThreadMain(PVOID Context)
-{
-  for (;;)
-    {
-      KeWaitForSingleObject(&KdbProfilerTimer, Executive, KernelMode, TRUE, NULL);
-
-      KeWaitForSingleObject(&KdbProfilerLock, Executive, KernelMode, FALSE, NULL);
-
-      KdbSuspendProfiling();
-
-      KdbProfilerAnalyzeSamples();
-
-      KdbResumeProfiling();
-
-      KeReleaseMutex(&KdbProfilerLock, FALSE);
-    }
-}
-
-VOID
-KdbDisableProfiling()
-{
-  if (KdbProfilingEnabled == TRUE)
-    {
-      /* FIXME: Implement */
-#if 0
-      KdbProfilingEnabled = FALSE;
-      /* Stop timer */
-      /* Close file */
-      if (KdbProfileDatabase != NULL)
-        {
-          KdbDeleteProfileDatabase(KdbProfileDatabase);
-          ExFreePool(KdbProfileDatabase);
-          KdbProfileDatabase = NULL;
-        }
-#endif
-    }
-}
-
-/*
- * SystemArgument1 = EIP
- */
-static VOID STDCALL
-KdbProfilerCollectorDpcRoutine(PKDPC Dpc, PVOID DeferredContext,
-  PVOID SystemArgument1, PVOID SystemArgument2)
-{
-  ULONG_PTR address = (ULONG_PTR) SystemArgument1;
-
-  KdbAddEntryToProfileDatabase(KdbProfileDatabase, address);
-}
-
-VOID INIT_FUNCTION
-KdbEnableProfiling()
-{
-  if (KdbProfilingEnabled == FALSE)
-    {
-         NTSTATUS Status;
-         OBJECT_ATTRIBUTES ObjectAttributes;
-         UNICODE_STRING FileName;
-         IO_STATUS_BLOCK Iosb;
-      LARGE_INTEGER DueTime;
-
-         RtlInitUnicodeString(&FileName, L"\\SystemRoot\\profiler.log");
-         InitializeObjectAttributes(&ObjectAttributes,
-               &FileName,
-               0,
-               NULL,
-               NULL);
-       
-         Status = NtCreateFile(&KdbProfilerLogFile,
-               FILE_ALL_ACCESS,
-               &ObjectAttributes,
-               &Iosb,
-               NULL,
-               FILE_ATTRIBUTE_NORMAL,
-               0,
-               FILE_SUPERSEDE,
-               FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
-               NULL,
-               0);
-         if (!NT_SUCCESS(Status))
-           {
-             DPRINT1("Failed to create profiler log file\n");
-             return;
-           }
-      KeInitializeMutex(&KdbProfilerLock, 0);
-
-      KdbProfileDatabase = ExAllocatePool(NonPagedPool, sizeof(PROFILE_DATABASE));
-      ASSERT(KdbProfileDatabase);
-      InitializeListHead(&KdbProfileDatabase->ListHead);
-      KeInitializeDpc(&KdbProfilerCollectorDpc, KdbProfilerCollectorDpcRoutine, NULL);
-
-         /* Initialize our periodic timer and its associated DPC object. When the timer
-            expires, the KdbProfilerSessionEndDpc deferred procedure call (DPC) is queued */
-         KeInitializeTimerEx(&KdbProfilerTimer, SynchronizationTimer);
-
-         Status = PsCreateSystemThread(&KdbProfilerThreadHandle,
-               THREAD_ALL_ACCESS,
-               NULL,
-               NULL,
-               &KdbProfilerThreadCid,
-               KdbProfilerThreadMain,
-               NULL);
-         if (!NT_SUCCESS(Status))
-           {
-             DPRINT1("Failed to create profiler thread\n");
-             return;
-           }
-
-         /* Start the periodic timer with an initial and periodic
-            relative expiration time of PROFILE_SESSION_LENGTH seconds */
-         DueTime.QuadPart = -(LONGLONG) PROFILE_SESSION_LENGTH * 1000 * 10000;
-         KeSetTimerEx(&KdbProfilerTimer, DueTime, PROFILE_SESSION_LENGTH * 1000, NULL);
-
-      KdbProfilingEnabled = TRUE;
-    }
-}
-
-VOID
-KdbProfileInterrupt(ULONG_PTR Address)
-{
-  ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
-
-  if (KdbProfilingInitialized != TRUE)
-    {
-      return;
-    }
-
-  if ((KdbProfilingEnabled) && (!KdbProfilingSuspended))
-    {
-      (BOOLEAN) KeInsertQueueDpc(&KdbProfilerCollectorDpc, (PVOID) Address, NULL);
-    }
-}
diff --git a/reactos/ntoskrnl/ex/btree.c b/reactos/ntoskrnl/ex/btree.c
deleted file mode 100644 (file)
index abefbee..0000000
+++ /dev/null
@@ -1,644 +0,0 @@
-/* $Id$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ex/btree.c
- * PURPOSE:         Binary tree support
- * 
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- */
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* DATA **********************************************************************/
-
-typedef struct _BINARY_TREE_NODE
-{
-  struct _BINARY_TREE_NODE  * Parent;
-  struct _BINARY_TREE_NODE  * LeftChild;
-  struct _BINARY_TREE_NODE  * RightChild;
-  PVOID  Key;
-  PVOID  Value;
-} BINARY_TREE_NODE, *PBINARY_TREE_NODE;
-
-typedef struct _TRAVERSE_CONTEXT {
-  PTRAVERSE_ROUTINE Routine;
-  PVOID Context;
-} TRAVERSE_CONTEXT, *PTRAVERSE_CONTEXT;
-
-/* FUNCTIONS ****************************************************************/
-
-#define ExpBinaryTreeRootNode(Tree)(((PBINARY_TREE) (Tree))->RootNode)
-#define ExpBinaryTreeIsExternalNode(Node)(((Node)->LeftChild == NULL) && ((Node)->RightChild == NULL))
-#define ExpBinaryTreeIsInternalNode(Node)(!ExpBinaryTreeIsExternalNode(Node))
-#define ExpBinaryTreeNodeKey(Node)((Node)->Key)
-#define ExpBinaryTreeNodeValue(Node)((Node)->Value)
-#define ExpBinaryTreeParentNode(Node)((Node)->Parent)
-#define ExpBinaryTreeLeftChildNode(Node)((Node)->LeftChild)
-#define ExpBinaryTreeRightChildNode(Node)((Node)->RightChild)
-#define ExpBinaryTreeNodeEqual(Equality)((Equality) == 0)
-#define ExpBinaryTreeNodeLess(Equality)((Equality) < 0)
-#define ExpBinaryTreeNodeMore(Equality)((Equality) > 0)
-
-
-/*
- * Lock the binary tree 
- */
-inline VOID
-ExpLockBinaryTree(PBINARY_TREE Tree,
- PKIRQL OldIrql)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      KeAcquireSpinLock(&Tree->Lock.NonPaged, OldIrql);
-         }
-       else
-               {
-      ExAcquireFastMutex(&Tree->Lock.Paged);
-               }
-}
-
-
-/*
- * Unlock the binary tree 
- */
-inline VOID
-ExpUnlockBinaryTree(PBINARY_TREE Tree,
-  PKIRQL OldIrql)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      KeReleaseSpinLock(&Tree->Lock.NonPaged, *OldIrql);
-         }
-       else
-               {
-      ExReleaseFastMutex(&Tree->Lock.Paged);
-               }
-}
-
-
-/*
- * Allocate resources for a new node and initialize it.
- */
-inline PBINARY_TREE_NODE
-ExpCreateBinaryTreeNode(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE Parent,
-  PVOID Value)
-{
-  PBINARY_TREE_NODE Node;
-
-       if (Tree->UseNonPagedPool)
-         {
-      Node = (PBINARY_TREE_NODE) ExAllocateFromNPagedLookasideList(&Tree->List.NonPaged);          
-         }
-       else
-               {
-      Node = (PBINARY_TREE_NODE) ExAllocateFromPagedLookasideList(&Tree->List.Paged);
-               }
-
-  if (Node)
-               {
-           ExpBinaryTreeParentNode(Node)     = Parent;
-      ExpBinaryTreeLeftChildNode(Node)  = NULL;
-      ExpBinaryTreeRightChildNode(Node) = NULL;
-      ExpBinaryTreeNodeValue(Node)      = Value;
-               }
-
-  return Node;
-}
-
-
-/*
- * Release resources for the node.
- */
-inline VOID
-ExpDestroyBinaryTreeNode(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE  Node)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      ExFreeToNPagedLookasideList(&Tree->List.NonPaged, Node);
-         }
-       else
-               {
-      ExFreeToPagedLookasideList(&Tree->List.Paged, Node);
-               }
-}
-
-
-/*
- * Replaces a child node of a node with a new node.
- * The lock for the tree must be acquired when this routine is called.
- */
-inline VOID
-ExpBinaryTreeReplaceChildNode(PBINARY_TREE_NODE Child,
-  PBINARY_TREE_NODE NewChild)
-{
-  if (ExpBinaryTreeLeftChildNode(ExpBinaryTreeParentNode(Child)) == Child)
-    {
-      ExpBinaryTreeLeftChildNode(ExpBinaryTreeParentNode(Child)) = NewChild;
-    }
-       else
-               {
-      ExpBinaryTreeRightChildNode(ExpBinaryTreeParentNode(Child)) = NewChild;
-               }
-}
-
-
-/*
- * Returns the sibling node of a node.
- * The lock for the tree must be acquired when this routine is called.
- */
-inline PBINARY_TREE_NODE
-ExpSiblingBinaryTreeNode(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE Node)
-{
-  if (Node == ExpBinaryTreeRootNode(Tree))
-               {
-      return NULL;
-               }
-  else
-    {
-      if (ExpBinaryTreeLeftChildNode(ExpBinaryTreeParentNode(Node)) == Node)
-                   {          
-          return ExpBinaryTreeRightChildNode(ExpBinaryTreeParentNode(Node));
-        }
-                       else
-                         {
-               return ExpBinaryTreeLeftChildNode(ExpBinaryTreeParentNode(Node));
-        }
-               }
-}
-
-
-/*
- * Expands an external node to an internal node.
- * The lock for the tree must be acquired when this routine is called.
- */
-VOID
-ExpExpandExternalBinaryTreeNode(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE Node)
-{
-  ExpBinaryTreeLeftChildNode(Node) = ExpCreateBinaryTreeNode(Tree, Node, NULL);
-
-  if (!ExpBinaryTreeLeftChildNode(Node))
-               {
-      /* FIXME: Throw exception */
-      DbgPrint("ExpCreateBinaryTreeNode() failed\n");
-               }
-
-  ExpBinaryTreeRightChildNode(Node) = ExpCreateBinaryTreeNode(Tree, Node, NULL);
-
-  if (!ExpBinaryTreeRightChildNode(Node))
-               {
-      ExpDestroyBinaryTreeNode(Tree, ExpBinaryTreeLeftChildNode(Node));
-      /* FIXME: Throw exception */
-      DbgPrint("ExpCreateBinaryTreeNode() failed\n");
-               }
-}
-
-
-/*
- * Searches a tree for a node with the specified key. If a node with the
- * specified key is not found, the external node where it should be is
- * returned.
- * The lock for the tree must be acquired when this routine is called.
- */
-inline PBINARY_TREE_NODE
-ExpSearchBinaryTree(PBINARY_TREE  Tree,
-  PVOID  Key,
-  PBINARY_TREE_NODE  Node)
-{
-  LONG Equality;
-
-  /* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
-
-  if (ExpBinaryTreeIsExternalNode(Node))
-    {
-      return Node;
-    }
-
-  Equality = (*Tree->Compare)(Key, ExpBinaryTreeNodeKey(Node));
-
-  if (ExpBinaryTreeNodeEqual(Equality))
-    {
-      return Node;
-    }
-
-  if (ExpBinaryTreeNodeLess(Equality))
-    {
-      return ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeLeftChildNode(Node));
-    }
-
-/*  if (ExpBinaryTreeNodeMore(Equality)) */
-    {
-      return ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRightChildNode(Node));
-    }
-}
-
-
-/*
- * Removes an external node and it's parent node from the tree.
- * The lock for the tree must be acquired when this routine is called.
- */
-VOID
-ExpRemoveAboveExternalBinaryTreeNode(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE Node)
-{
-  ASSERTMSG(ExpBinaryTreeIsExternalNode(Node), ("Node is not external"));
-
-  if (Node == ExpBinaryTreeRootNode(Tree))
-               {
-      return;
-               }
-  else
-               {
-      PBINARY_TREE_NODE GrandParent;
-           PBINARY_TREE_NODE NewChild;
-
-      GrandParent = ExpBinaryTreeParentNode(ExpBinaryTreeParentNode(Node));
-           NewChild = ExpSiblingBinaryTreeNode(Tree, Node);
-
-      if (GrandParent != NULL)
-        {
-          ExpBinaryTreeReplaceChildNode(ExpBinaryTreeParentNode(Node), NewChild);
-        }
-
-           ExpDestroyBinaryTreeNode(Tree, ExpBinaryTreeParentNode(Node));
-           ExpDestroyBinaryTreeNode(Tree, Node);
-               }
-}
-
-
-/*
- * Release resources used by nodes of a binary (sub)tree.
- */
-VOID
-ExpDeleteBinaryTree(PBINARY_TREE Tree,
-  PBINARY_TREE_NODE Node)
-{
-  /* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
-
-  if (ExpBinaryTreeIsInternalNode(Node))
-    {
-      ExpDeleteBinaryTree(Tree, ExpBinaryTreeLeftChildNode(Node));
-      ExpDeleteBinaryTree(Tree, ExpBinaryTreeRightChildNode(Node));
-    }
-
-  ExpDestroyBinaryTreeNode(Tree, Node);
-}
-
-
-/*
- * Traverse a binary tree using preorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseBinaryTreePreorder(PTRAVERSE_CONTEXT Context,
-  PBINARY_TREE_NODE Node)
-{
-  if (ExpBinaryTreeIsInternalNode(Node))
-               {
-                 /* Call the traversal routine */
-                 if (!(*Context->Routine)(Context->Context,
-                   ExpBinaryTreeNodeKey(Node),
-                   ExpBinaryTreeNodeValue(Node)))
-                   {
-                     return FALSE;
-                   }
-
-      /* Traverse left subtree */
-      ExpTraverseBinaryTreePreorder(Context, ExpBinaryTreeLeftChildNode(Node));
-
-      /* Traverse right subtree */
-      ExpTraverseBinaryTreePreorder(Context, ExpBinaryTreeRightChildNode(Node));
-               }
-
-  return TRUE;
-}
-
-
-/*
- * Traverse a binary tree using inorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseBinaryTreeInorder(PTRAVERSE_CONTEXT Context,
-  PBINARY_TREE_NODE Node)
-{
-  if (ExpBinaryTreeIsInternalNode(Node))
-               {
-      /* Traverse left subtree */
-      ExpTraverseBinaryTreeInorder(Context, ExpBinaryTreeLeftChildNode(Node));
-
-                 /* Call the traversal routine */
-                 if (!(*Context->Routine)(Context->Context,
-                   ExpBinaryTreeNodeKey(Node),
-                   ExpBinaryTreeNodeValue(Node)))
-                   {
-                     return FALSE;
-                   }
-
-      /* Traverse right subtree */
-      ExpTraverseBinaryTreeInorder(Context, ExpBinaryTreeRightChildNode(Node));
-               }
-
-  return TRUE;
-}
-
-
-/*
- * Traverse a binary tree using postorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseBinaryTreePostorder(PTRAVERSE_CONTEXT Context,
-  PBINARY_TREE_NODE Node)
-{
-  if (ExpBinaryTreeIsInternalNode(Node))
-               {
-      /* Traverse left subtree */
-      ExpTraverseBinaryTreePostorder(Context, ExpBinaryTreeLeftChildNode(Node));
-
-      /* Traverse right subtree */
-      ExpTraverseBinaryTreePostorder(Context, ExpBinaryTreeRightChildNode(Node));
-
-                 /* Call the traversal routine */
-                 return (*Context->Routine)(Context->Context,
-                   ExpBinaryTreeNodeKey(Node),
-                   ExpBinaryTreeNodeValue(Node));
-               }
-
-  return TRUE;
-}
-
-
-/*
- * Default key compare function. Compares the integer values of the two keys.
- */
-LONG STDCALL
-ExpBinaryTreeDefaultCompare(PVOID  Key1,
-  PVOID  Key2)
-{
-  if (Key1 == Key2)
-    return 0;
-
-  return (((LONG_PTR) Key1 < (LONG_PTR) Key2) ? -1 : 1);
-}
-
-
-/*
- * Initializes a binary tree.
- */
-BOOLEAN STDCALL
-ExInitializeBinaryTree(IN PBINARY_TREE  Tree,
-  IN PKEY_COMPARATOR  Compare,
-  IN BOOLEAN  UseNonPagedPool)
-{
-  RtlZeroMemory(Tree, sizeof(BINARY_TREE));
-
-  Tree->Compare = (Compare == NULL)
-    ? ExpBinaryTreeDefaultCompare : Compare;
-
-  Tree->UseNonPagedPool = UseNonPagedPool;
-
-  if (UseNonPagedPool)
-    {
-                 ExInitializeNPagedLookasideList(
-                   &Tree->List.NonPaged,           /* Lookaside list */
-                   NULL,                           /* Allocate routine */
-                   NULL,                           /* Free routine */
-                   0,                              /* Flags */
-                   sizeof(BINARY_TREE_NODE),       /* Size of each entry */
-                   TAG('E','X','B','T'),           /* Tag */
-                   0);                             /* Depth */
-
-      KeInitializeSpinLock(&Tree->Lock.NonPaged);
-               }
-               else
-               {
-                 ExInitializePagedLookasideList(
-                   &Tree->List.Paged,              /* Lookaside list */
-                   NULL,                           /* Allocate routine */
-                   NULL,                           /* Free routine */
-                   0,                              /* Flags */
-                   sizeof(BINARY_TREE_NODE),       /* Size of each entry */
-                   TAG('E','X','B','T'),           /* Tag */
-                   0);                             /* Depth */
-
-      ExInitializeFastMutex(&Tree->Lock.Paged);
-               }
-
-  ExpBinaryTreeRootNode(Tree) = ExpCreateBinaryTreeNode(Tree, NULL, NULL);
-
-  if (ExpBinaryTreeRootNode(Tree) == NULL)
-               {
-                 if (UseNonPagedPool)
-                   {
-          ExDeleteNPagedLookasideList(&Tree->List.NonPaged);
-                         }
-                       else
-                               {
-          ExDeletePagedLookasideList(&Tree->List.Paged);
-                               }
-      return FALSE;
-               }
-  else
-               {
-      return TRUE;
-               }
-}
-
-
-/*
- * Release resources used by a binary tree.
- */
-VOID STDCALL
-ExDeleteBinaryTree(IN PBINARY_TREE  Tree)
-{
-  /* Remove all nodes */
-  ExpDeleteBinaryTree(Tree, ExpBinaryTreeRootNode(Tree));
-
-  if (Tree->UseNonPagedPool)
-    {
-      ExDeleteNPagedLookasideList(&Tree->List.NonPaged);
-         }
-       else
-               {
-      ExDeletePagedLookasideList(&Tree->List.Paged);
-               }
-}
-
-
-/*
- * Insert a value in a binary tree.
- */
-VOID STDCALL
-ExInsertBinaryTree(IN PBINARY_TREE  Tree,
-  IN PVOID  Key,
-  IN PVOID  Value)
-{
-  PBINARY_TREE_NODE Node;
-  KIRQL OldIrql;
-
-  /* FIXME: Use SEH for error reporting */
-
-  ExpLockBinaryTree(Tree, &OldIrql);
-  Node = ExpBinaryTreeRootNode(Tree);
-  do
-    {
-      Node = ExpSearchBinaryTree(Tree, Key, Node);
-
-                 if (ExpBinaryTreeIsExternalNode(Node))
-                   {
-          break;
-                   }
-                       else
-                               {
-          Node = ExpBinaryTreeRightChildNode(Node);
-                               }
-    } while (TRUE);
-  ExpExpandExternalBinaryTreeNode(Tree, Node);
-  ExpBinaryTreeNodeKey(Node)   = Key;
-  ExpBinaryTreeNodeValue(Node) = Value;
-  ExpUnlockBinaryTree(Tree, &OldIrql);
-}
-
-
-/*
- * Search for a value associated with a given key in a binary tree.
- */
-BOOLEAN STDCALL
-ExSearchBinaryTree(IN PBINARY_TREE  Tree,
-  IN PVOID  Key,
-  OUT PVOID  * Value)
-{
-  PBINARY_TREE_NODE Node;
-  KIRQL OldIrql;
-
-  ExpLockBinaryTree(Tree, &OldIrql);
-  Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
-
-  if (ExpBinaryTreeIsInternalNode(Node))
-    {
-           *Value = ExpBinaryTreeNodeValue(Node);
-      ExpUnlockBinaryTree(Tree, &OldIrql);
-           return TRUE;
-         }
-       else
-               {
-      ExpUnlockBinaryTree(Tree, &OldIrql);
-      return FALSE;
-               }
-}
-
-
-/*
- * Remove a value associated with a given key from a binary tree.
- */
-BOOLEAN STDCALL
-ExRemoveBinaryTree(IN PBINARY_TREE  Tree,
-  IN PVOID  Key,
-  IN PVOID  * Value)
-{
-  PBINARY_TREE_NODE Node;
-  KIRQL OldIrql;
-
-  ExpLockBinaryTree(Tree, &OldIrql);
-
-  Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
-
-  if (ExpBinaryTreeIsExternalNode(Node))
-               {
-      ExpUnlockBinaryTree(Tree, &OldIrql);
-      return FALSE;
-               }
-       else
-               {
-      *Value = ExpBinaryTreeNodeValue(Node);
-                 if (ExpBinaryTreeIsExternalNode(ExpBinaryTreeLeftChildNode(Node)))
-                               {
-          Node = ExpBinaryTreeLeftChildNode(Node);
-                               }
-      else if (ExpBinaryTreeIsExternalNode(ExpBinaryTreeRightChildNode(Node)))
-                               {
-          Node = ExpBinaryTreeRightChildNode(Node);
-                               }
-      else
-        {
-          // Node has internal children
-          PBINARY_TREE_NODE SwapNode;
-
-          SwapNode = Node;
-          Node = ExpBinaryTreeRightChildNode(SwapNode);
-          do
-            {
-              Node = ExpBinaryTreeLeftChildNode(Node);
-            } while (ExpBinaryTreeIsInternalNode(Node));
-        }
-
-      ExpRemoveAboveExternalBinaryTreeNode(Tree, Node);
-      ExpUnlockBinaryTree(Tree, &OldIrql);
-      return TRUE;
-               }
-}
-
-
-/*
- * Traverse a binary tree using either preorder, inorder or postorder
- * traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- */
-BOOLEAN STDCALL
-ExTraverseBinaryTree(IN PBINARY_TREE  Tree,
-  IN TRAVERSE_METHOD  Method,
-  IN PTRAVERSE_ROUTINE  Routine,
-  IN PVOID  Context)
-{
-  TRAVERSE_CONTEXT tc;
-  BOOLEAN Status;
-  KIRQL OldIrql;
-
-  tc.Routine = Routine;
-  tc.Context = Context;
-
-  ExpLockBinaryTree(Tree, &OldIrql);
-
-  switch (Method)
-    {
-      case TraverseMethodPreorder:
-        Status = ExpTraverseBinaryTreePreorder(&tc, ExpBinaryTreeRootNode(Tree));
-        break;
-
-      case TraverseMethodInorder:
-        Status = ExpTraverseBinaryTreeInorder(&tc, ExpBinaryTreeRootNode(Tree));
-        break;
-
-      case TraverseMethodPostorder:
-        Status = ExpTraverseBinaryTreePostorder(&tc, ExpBinaryTreeRootNode(Tree));
-        break;
-
-      default:
-        Status = FALSE;
-        break;
-    }
-
-  ExpUnlockBinaryTree(Tree, &OldIrql);
-
-  return Status;
-}
-
-/* EOF */
diff --git a/reactos/ntoskrnl/ex/error.c b/reactos/ntoskrnl/ex/error.c
new file mode 100644 (file)
index 0000000..d1d99a5
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ex/error.c
+ * PURPOSE:         Error Functions and Status/Exception Dispatching/Raising
+ *
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Created File
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ****************************************************************/
+
+BOOLEAN ExReadyForErrors = FALSE;
+PEPORT ExpDefaultErrorPort = NULL;
+PEPROCESS ExpDefaultErrorPortProcess = NULL;
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * @implemented
+ */
+VOID 
+STDCALL
+ExRaiseAccessViolation(VOID)
+{
+    /* Raise the Right Status */
+    ExRaiseStatus (STATUS_ACCESS_VIOLATION);
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+ExRaiseDatatypeMisalignment (VOID)
+{
+    /* Raise the Right Status */
+    ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
+}
+
+/*
+ * @implemented
+ */
+VOID 
+STDCALL
+ExRaiseStatus(IN NTSTATUS Status)
+{
+    EXCEPTION_RECORD ExceptionRecord;
+
+    DPRINT("ExRaiseStatus(%x)\n", Status);
+
+    /* Set up an Exception Record */
+    ExceptionRecord.ExceptionRecord = NULL;
+    ExceptionRecord.NumberParameters = 0;
+    ExceptionRecord.ExceptionCode = Status;
+    ExceptionRecord.ExceptionFlags = 0;
+    
+    /* Call the Rtl Function */
+    RtlRaiseException(&ExceptionRecord);
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+ExRaiseException (PEXCEPTION_RECORD ExceptionRecord)
+{
+    /* Call the Rtl function */
+    RtlRaiseException(ExceptionRecord);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+ExSystemExceptionFilter(VOID)
+{
+    return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+ExRaiseHardError(IN NTSTATUS ErrorStatus,
+                 IN ULONG NumberOfParameters, 
+                 IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
+                 IN PVOID *Parameters, 
+                 IN HARDERROR_RESPONSE_OPTION ResponseOption, 
+                 OUT PHARDERROR_RESPONSE Response)
+{
+    UNIMPLEMENTED;
+}
+
+NTSTATUS 
+STDCALL 
+NtRaiseHardError(IN NTSTATUS ErrorStatus,
+                 IN ULONG NumberOfParameters,
+                 IN PUNICODE_STRING UnicodeStringParameterMask  OPTIONAL,
+                 IN PVOID *Parameters,
+                 IN HARDERROR_RESPONSE_OPTION ResponseOption,
+                 OUT PHARDERROR_RESPONSE Response)
+{
+    DPRINT1("Hard error %x\n", ErrorStatus);
+  
+    /* Call the Executive Function (WE SHOULD PUT SEH HERE/CAPTURE!) */
+    ExRaiseHardError(ErrorStatus,
+                     NumberOfParameters,
+                     UnicodeStringParameterMask,
+                     Parameters,
+                     ResponseOption,
+                     Response);
+  
+    /* Return Success */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS 
+STDCALL 
+NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
+{
+    
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+  
+    /* Check if we have the Privilege */
+    if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) {
+        
+        DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n");
+        return STATUS_PRIVILEGE_NOT_HELD;
+    }
+  
+    /* Only called once during bootup, make sure we weren't called yet */
+    if(!ExReadyForErrors) {
+        
+        Status = ObReferenceObjectByHandle(PortHandle,
+                                           0,
+                                           LpcPortObjectType,
+                                           PreviousMode,
+                                           (PVOID*)&ExpDefaultErrorPort,
+                                           NULL);
+        
+        /* Check for Success */
+        if(NT_SUCCESS(Status)) {
+            
+            /* Save the data */
+            ExpDefaultErrorPortProcess = PsGetCurrentProcess();
+            ExReadyForErrors = TRUE;
+        }
+    }
+  
+    return Status;
+}
+
+/* EOF */
index 4db20f5..0e52ef7 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id:$
- * 
+/* 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/nt/event.c
  * PURPOSE:         Named event support
  * 
- * PROGRAMMERS:     Philip Susi and David Welch
+ * PROGRAMMERS:     Alex Ionescu(alex@relsoft.net) - Fixed bugs/commented
+ *                  Philip Susi and David Welch
  */
 
 /* INCLUDES *****************************************************************/
 POBJECT_TYPE EXPORTED ExEventObjectType = NULL;
 
 static GENERIC_MAPPING ExpEventMapping = {
-       STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
-       EVENT_ALL_ACCESS};
-
-static const INFORMATION_CLASS_INFO ExEventInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* EventBasicInformation */
+    STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
+    EVENT_ALL_ACCESS};
+
+static const INFORMATION_CLASS_INFO ExEventInfoClass[] = {
+    
+    /* EventBasicInformation */
+    ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
 };
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STDCALL
-NtpCreateEvent(PVOID ObjectBody,
-              PVOID Parent,
-              PWSTR RemainingPath,
-              POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeEventImplementation(VOID)
 {
-   ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExEventObjectType->TypeName, L"Event", NonPagedPool);
-   
-   ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
-   ExEventObjectType->PeakObjects = 0;
-   ExEventObjectType->PeakHandles = 0;
-   ExEventObjectType->TotalObjects = 0;
-   ExEventObjectType->TotalHandles = 0;
-   ExEventObjectType->PagedPoolCharge = 0;
-   ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
-   ExEventObjectType->Mapping = &ExpEventMapping;
-   ExEventObjectType->Dump = NULL;
-   ExEventObjectType->Open = NULL;
-   ExEventObjectType->Close = NULL;
-   ExEventObjectType->Delete = NULL;
-   ExEventObjectType->Parse = NULL;
-   ExEventObjectType->Security = NULL;
-   ExEventObjectType->QueryName = NULL;
-   ExEventObjectType->OkayToClose = NULL;
-   ExEventObjectType->Create = NtpCreateEvent;
-   ExEventObjectType->DuplicationNotify = NULL;
-
-   ObpCreateTypeObject(ExEventObjectType);
+    /* Create the Event Object Type */
+    ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlInitUnicodeString(&ExEventObjectType->TypeName, L"Event");
+    ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
+    ExEventObjectType->PeakObjects = 0;
+    ExEventObjectType->PeakHandles = 0;
+    ExEventObjectType->TotalObjects = 0;
+    ExEventObjectType->TotalHandles = 0;
+    ExEventObjectType->PagedPoolCharge = 0;
+    ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
+    ExEventObjectType->Mapping = &ExpEventMapping;
+    ExEventObjectType->Dump = NULL;
+    ExEventObjectType->Open = NULL;
+    ExEventObjectType->Close = NULL;
+    ExEventObjectType->Delete = NULL;
+    ExEventObjectType->Parse = NULL;
+    ExEventObjectType->Security = NULL;
+    ExEventObjectType->QueryName = NULL;
+    ExEventObjectType->OkayToClose = NULL;
+    ExEventObjectType->Create = NULL;
+    ExEventObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExEventObjectType);
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtClearEvent(IN HANDLE EventHandle)
 {
-   PKEVENT Event;
-   NTSTATUS Status;
+    PKEVENT Event;
+    NTSTATUS Status;
+    
+    PAGED_CODE();
    
-   PAGED_CODE();
+    /* Reference the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       ExGetPreviousMode(),
+                                       (PVOID*)&Event,
+                                       NULL);
    
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     ExGetPreviousMode(),
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeClearEvent(Event);
-     ObDereferenceObject(Event);
-   }
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Clear the Event and Dereference */
+        KeClearEvent(Event);
+        ObDereferenceObject(Event);
+    }
    
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateEvent(OUT PHANDLE EventHandle,
-             IN ACCESS_MASK DesiredAccess,
-             IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-             IN EVENT_TYPE EventType,
-             IN BOOLEAN InitialState)
+              IN ACCESS_MASK DesiredAccess,
+              IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+              IN EVENT_TYPE EventType,
+              IN BOOLEAN InitialState)
 {
-   KPROCESSOR_MODE PreviousMode;
-   PKEVENT Event;
-   HANDLE hEvent;
-   NTSTATUS Status = STATUS_SUCCESS;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    HANDLE hEvent;
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
+    PAGED_CODE();
+    DPRINT("NtCreateEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
  
-   PreviousMode = ExGetPreviousMode();
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-   Status = ObCreateObject(PreviousMode,
-                           ExEventObjectType,
-                           ObjectAttributes,
-                           PreviousMode,
-                           NULL,
-                           sizeof(KEVENT),
-                           0,
-                           0,
-                           (PVOID*)&Event);
-   if(NT_SUCCESS(Status))
-   {
-     KeInitializeEvent(Event,
-                       EventType,
-                       InitialState);
-     Status = ObInsertObject((PVOID)Event,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hEvent);
-     ObDereferenceObject(Event);
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *EventHandle = hEvent;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Create the Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExEventObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KEVENT),
+                            0,
+                            0,
+                            (PVOID*)&Event);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Event */
+        KeInitializeEvent(Event,
+                          EventType,
+                          InitialState);
+        
+        /* Insert it */
+        Status = ObInsertObject((PVOID)Event,
+                                 NULL,
+                                 DesiredAccess,
+                                 0,
+                                 NULL,
+                                 &hEvent);
+        ObDereferenceObject(Event);
  
-   return Status;
-}
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *EventHandle = hEvent;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
 
+    /* Return Status */
+    return Status;
+}
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenEvent(OUT PHANDLE EventHandle,
-           IN ACCESS_MASK DesiredAccess,
-           IN POBJECT_ATTRIBUTES ObjectAttributes)
+            IN ACCESS_MASK DesiredAccess,
+            IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hEvent;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
+    HANDLE hEvent;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();    
+    DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check Output Safety */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExEventObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hEvent);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExEventObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hEvent);
              
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *EventHandle = hEvent;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *EventHandle = hEvent;
+                
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtPulseEvent(IN HANDLE EventHandle,
-            OUT PLONG PreviousState  OPTIONAL)
+             OUT PLONG PreviousState OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+    DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
+            EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
-     ObDereferenceObject(Event);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Pulse the Event */
+        LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
+        ObDereferenceObject(Event);
      
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
@@ -320,230 +307,203 @@ NtPulseEvent(IN HANDLE EventHandle,
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtQueryEvent(IN HANDLE EventHandle,
-            IN EVENT_INFORMATION_CLASS EventInformationClass,
-            OUT PVOID EventInformation,
-            IN ULONG EventInformationLength,
-            OUT PULONG ReturnLength  OPTIONAL)
+             IN EVENT_INFORMATION_CLASS EventInformationClass,
+             OUT PVOID EventInformation,
+             IN ULONG EventInformationLength,
+             OUT PULONG ReturnLength  OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode  = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
+    
+    PAGED_CODE();
+    DPRINT("NtQueryEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, EventInformationClass);
+    
+    /* Check buffers and class validity */
+    DefaultQueryInfoBufferCheck(EventInformationClass,
+                                ExEventInfoClass,
+                                EventInformation,
+                                EventInformationLength,
+                                ReturnLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        /* Invalid buffers */
+        DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
    
-   DefaultQueryInfoBufferCheck(EventInformationClass,
-                               ExEventInfoClass,
-                               EventInformation,
-                               EventInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_QUERY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(EventInformationClass)
-     {
-       case EventBasicInformation:
-       {
-         PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
-         
-         _SEH_TRY
-         {
-           if (Event->Header.Type == InternalNotificationEvent)
-             BasicInfo->EventType = NotificationEvent;
-           else
-             BasicInfo->EventType = SynchronizationEvent;
-           BasicInfo->EventState = KeReadStateEvent(Event);
-
-           if(ReturnLength != NULL)
-           {
-             *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Event);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_QUERY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+
+        _SEH_TRY {
+            
+            /* Return Event Type and State */
+            BasicInfo->EventType = Event->Header.Type;
+            BasicInfo->EventState = KeReadStateEvent(Event);
+
+            /* Return length */
+            if(ReturnLength) *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+     
+        /* Dereference the Object */
+        ObDereferenceObject(Event);
    }
 
+   /* Return status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtResetEvent(IN HANDLE EventHandle,
-            OUT PLONG PreviousState  OPTIONAL)
+             OUT PLONG PreviousState OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+    DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
+            EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeResetEvent(Event);
-     ObDereferenceObject(Event);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Reset the Event */
+        LONG Prev = KeResetEvent(Event);
+        ObDereferenceObject(Event);
      
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtSetEvent(IN HANDLE EventHandle,
-          OUT PLONG PreviousState  OPTIONAL)
+           OUT PLONG PreviousState  OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+    DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
+           EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState != NULL && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
-     ObDereferenceObject(Event);
-
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+
+        /* Set the Event */
+        LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
+        ObDereferenceObject(Event);
+
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtTraceEvent(
-       IN ULONG TraceHandle,
-       IN ULONG Flags,
-       IN ULONG TraceHeaderLength,
-       IN struct _EVENT_TRACE_HEADER* TraceHeader
-       )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
-}
-
-
 /* EOF */
index 15b05e6..5bcfb76 100644 (file)
@@ -1,11 +1,12 @@
-/* $Id: evtpair.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/evtpair.c
  * PURPOSE:         Support for event pairs
  *
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (Commented, reorganized, removed Thread Pair, used
+ *                                KeInitializeEventPair, added SEH)
+ *                  David Welch (welch@mcmail.com)
  *                  Skywing (skywing@valhallalegends.com)
  */
 
 #define NDEBUG
 #include <internal/debug.h>
 
-#ifndef NTSYSAPI
-#define NTSYSAPI
-#endif
-
-#ifndef NTAPI
-#define NTAPI STDCALL
-#endif
-
-
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL;
 
 static GENERIC_MAPPING ExEventPairMapping = {
-       STANDARD_RIGHTS_READ,
-       STANDARD_RIGHTS_WRITE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
-       EVENT_PAIR_ALL_ACCESS};
+    STANDARD_RIGHTS_READ,
+    STANDARD_RIGHTS_WRITE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
+    EVENT_PAIR_ALL_ACCESS};
 
-static KSPIN_LOCK ExThreadEventPairSpinLock;
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STDCALL
-ExpCreateEventPair(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("ExpCreateEventPair(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-  
-  return(STATUS_SUCCESS);
-}
-
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
 ExpInitializeEventPairImplementation(VOID)
 {
-   ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair", NonPagedPool);
-   ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
-   ExEventPairObjectType->PeakObjects = 0;
-   ExEventPairObjectType->PeakHandles = 0;
-   ExEventPairObjectType->TotalObjects = 0;
-   ExEventPairObjectType->TotalHandles = 0;
-   ExEventPairObjectType->PagedPoolCharge = 0;
-   ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
-   ExEventPairObjectType->Mapping = &ExEventPairMapping;
-   ExEventPairObjectType->Dump = NULL;
-   ExEventPairObjectType->Open = NULL;
-   ExEventPairObjectType->Close = NULL;
-   ExEventPairObjectType->Delete = NULL;
-   ExEventPairObjectType->Parse = NULL;
-   ExEventPairObjectType->Security = NULL;
-   ExEventPairObjectType->QueryName = NULL;
-   ExEventPairObjectType->OkayToClose = NULL;
-   ExEventPairObjectType->Create = ExpCreateEventPair;
-   ExEventPairObjectType->DuplicationNotify = NULL;
-
-   KeInitializeSpinLock(&ExThreadEventPairSpinLock);
-   ObpCreateTypeObject(ExEventPairObjectType);
+    /* Create the Event Pair Object Type */
+    ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlInitUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair");
+    ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
+    ExEventPairObjectType->PeakObjects = 0;
+    ExEventPairObjectType->PeakHandles = 0;
+    ExEventPairObjectType->TotalObjects = 0;
+    ExEventPairObjectType->TotalHandles = 0;
+    ExEventPairObjectType->PagedPoolCharge = 0;
+    ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
+    ExEventPairObjectType->Mapping = &ExEventPairMapping;
+    ExEventPairObjectType->Dump = NULL;
+    ExEventPairObjectType->Open = NULL;
+    ExEventPairObjectType->Close = NULL;
+    ExEventPairObjectType->Delete = NULL;
+    ExEventPairObjectType->Parse = NULL;
+    ExEventPairObjectType->Security = NULL;
+    ExEventPairObjectType->QueryName = NULL;
+    ExEventPairObjectType->OkayToClose = NULL;
+    ExEventPairObjectType->Create = NULL;
+    ExEventPairObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExEventPairObjectType);
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtCreateEventPair(OUT PHANDLE EventPairHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes)
+                  IN ACCESS_MASK DesiredAccess,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   PKEVENT_PAIR EventPair;
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKEVENT_PAIR EventPair;
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
+    DPRINT("NtCreateEventPair: %x\n", EventPairHandle);
    
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventPairHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObCreateObject(PreviousMode,
-                          ExEventPairObjectType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(KEVENT_PAIR),
-                          0,
-                          0,
-                          (PVOID*)&EventPair);
-   if(NT_SUCCESS(Status))
-   {
-     KeInitializeEvent(&EventPair->LowEvent,
-                      SynchronizationEvent,
-                      FALSE);
-     KeInitializeEvent(&EventPair->HighEvent,
-                      SynchronizationEvent,
-                      FALSE);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Create the Object */
+    DPRINT("Creating EventPair\n");
+    Status = ObCreateObject(PreviousMode,
+                            ExEventPairObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KEVENT_PAIR),
+                            0,
+                            0,
+                            (PVOID*)&EventPair);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Event */
+        DPRINT("Initializing EventPair\n");
+        KeInitializeEventPair(EventPair);
+        
+        /* Insert it */
+        Status = ObInsertObject((PVOID)EventPair,
+                                 NULL,
+                                 DesiredAccess,
+                                 0,
+                                 NULL,
+                                 &hEventPair);
+        ObDereferenceObject(EventPair);
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *EventPairHandle = hEventPair;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
 
-     Status = ObInsertObject ((PVOID)EventPair,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hEventPair);
-     ObDereferenceObject(EventPair);
-     
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *EventPairHandle = hEventPair;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenEventPair(OUT PHANDLE EventPairHandle,
-               IN ACCESS_MASK DesiredAccess,
-               IN POBJECT_ATTRIBUTES ObjectAttributes)
+                IN ACCESS_MASK DesiredAccess,
+                IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventPairHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExEventPairObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hEventPair);
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *EventPairHandle = hEventPair;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExEventPairObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hEventPair);
+             
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *EventPairHandle = hEventPair;
+                
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtSetHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    DPRINT("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
    
-   PAGED_CODE();
-
-   DPRINT("NtSetHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
+        
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtSetLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    
+    PreviousMode = ExGetPreviousMode();
+
+    DPRINT1("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
    
-   PAGED_CODE();
-
-   DPRINT("NtSetLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
-   
-   return Status;
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
+    
+    /* Return status */
+    return Status;
 }
 
 
 NTSTATUS STDCALL
 NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
+        
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+               
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+    
+    PAGED_CODE();
+    DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+               
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-#ifdef _ENABLE_THRDEVTPAIR
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
-{
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-       
-       PreviousMode = ExGetPreviousMode();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = Thread->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->HighEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
-
-       ObDereferenceObject(EventPair);
-
-       return Status;
-}
-
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
-{
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-
-       Thread = PsGetCurrentThread();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = PsGetCurrentThread()->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->LowEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
-
-       ObDereferenceObject(EventPair);
-
-       return Status;
-}
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when waiting on the
- * eventpair via NtSetLow/HighWaitHigh/LowThread.  Additionally, when
- * deleting a thread object, NtpSwapThreadEventPair(Thread, NULL) should
- * be called to release any preexisting eventpair object associated with
- * the thread.  The Microsoft name for this function is not known.
- */
-VOID
-ExpSwapThreadEventPair(
-       IN PETHREAD Thread,
-       IN PKEVENT_PAIR EventPair
-       )
-{
-       PKEVENT_PAIR OriginalEventPair;
-       KIRQL Irql;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       OriginalEventPair = Thread->EventPair;
-       Thread->EventPair = EventPair;
-
-       if(OriginalEventPair)
-               ObDereferenceObject(OriginalEventPair);
-
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-}
-
-#else /* !_ENABLE_THRDEVTPAIR */
-
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
-{
-        DPRINT1("NtSetLowWaitHighThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
-{
-        DPRINT1("NtSetHighWaitLowThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
-}
-
-#endif /* _ENABLE_THRDEVTPAIR */
-
 /* EOF */
diff --git a/reactos/ntoskrnl/ex/handle.c b/reactos/ntoskrnl/ex/handle.c
new file mode 100644 (file)
index 0000000..1c0d9d3
--- /dev/null
@@ -0,0 +1,958 @@
+/* $Id$
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ex/handle.c
+ * PURPOSE:         Generic Executive Handle Tables
+ * 
+ * PROGRAMMERS:     Thomas Weidenmueller <w3seek@reactos.com>
+ *
+ *  TODO:
+ *
+ *  - the last entry of a subhandle list should be reserved for auditing
+ *
+ *  ExSweepHandleTable (???)
+ *  ExReferenceHandleDebugInfo
+ *  ExSnapShotHandleTables
+ *  ExpMoveFreeHandles (???)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+static LIST_ENTRY ExpHandleTableHead;
+static FAST_MUTEX ExpHandleTableListLock;
+static LARGE_INTEGER ExpHandleShortWait;
+
+#define ExAcquireHandleTableListLock()                                         \
+  ExAcquireFastMutexUnsafe(&ExpHandleTableListLock)
+
+#define ExReleaseHandleTableListLock()                                         \
+  ExReleaseFastMutexUnsafe(&ExpHandleTableListLock)
+
+#define ExAcquireHandleTableLockExclusive(HandleTable)                         \
+  ExAcquireResourceExclusiveLite(&(HandleTable)->HandleTableLock, TRUE)
+
+#define ExAcquireHandleTableLockShared(HandleTable)                            \
+  ExAcquireResourceSharedLite(&(HandleTable)->HandleTableLock, TRUE)
+
+#define ExReleaseHandleTableLock(HandleTable)                                  \
+  ExReleaseResourceLite(&(HandleTable)->HandleTableLock)
+
+/*
+   5 bits: reserved
+   8 bits: top level index
+   10 bits: middle level index
+   9 bits: sub handle index
+*/
+#define N_TLI_BITS 8 /* top level index */
+#define N_MLI_BITS 10 /* middle level index */
+#define N_EI_BITS 9 /* sub handle index */
+#define TLI_OFFSET (N_MLI_BITS + N_EI_BITS)
+#define MLI_OFFSET N_EI_BITS
+#define EI_OFFSET 0
+
+#define N_TOPLEVEL_POINTERS (1 << N_TLI_BITS)
+#define N_MIDDLELEVEL_POINTERS (1 << N_MLI_BITS)
+#define N_SUBHANDLE_ENTRIES (1 << N_EI_BITS)
+#define EX_MAX_HANDLES (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES)
+
+#define VALID_HANDLE_MASK (((N_TOPLEVEL_POINTERS - 1) << TLI_OFFSET) |         \
+  ((N_MIDDLELEVEL_POINTERS - 1) << MLI_OFFSET) | ((N_SUBHANDLE_ENTRIES - 1) << EI_OFFSET))
+#define TLI_FROM_HANDLE(index) (ULONG)(((index) >> TLI_OFFSET) & (N_TOPLEVEL_POINTERS - 1))
+#define MLI_FROM_HANDLE(index) (ULONG)(((index) >> MLI_OFFSET) & (N_MIDDLELEVEL_POINTERS - 1))
+#define ELI_FROM_HANDLE(index) (ULONG)(((index) >> EI_OFFSET) & (N_SUBHANDLE_ENTRIES - 1))
+
+#define N_MAX_HANDLE (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES)
+
+#define BUILD_HANDLE(tli, mli, eli) ((((tli) & (N_TOPLEVEL_POINTERS - 1)) << TLI_OFFSET) | \
+  (((mli) & (N_MIDDLELEVEL_POINTERS - 1)) << MLI_OFFSET) | (((eli) & (N_SUBHANDLE_ENTRIES - 1)) << EI_OFFSET))
+
+#define IS_INVALID_EX_HANDLE(index)                                            \
+  (((index) & ~VALID_HANDLE_MASK) != 0)
+#define IS_VALID_EX_HANDLE(index)                                              \
+  (((index) & ~VALID_HANDLE_MASK) == 0)
+
+static BOOLEAN ExpInitialized = FALSE;
+
+/******************************************************************************/
+
+VOID
+ExpInitializeHandleTables(VOID)
+{
+  ExpHandleShortWait.QuadPart = -50000;
+  InitializeListHead(&ExpHandleTableHead);
+  ExInitializeFastMutex(&ExpHandleTableListLock);
+
+  ExpInitialized = TRUE;
+}
+
+PHANDLE_TABLE
+ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL)
+{
+  PHANDLE_TABLE HandleTable;
+  
+  PAGED_CODE();
+  
+  if(!ExpInitialized)
+  {
+    KEBUGCHECK(0);
+  }
+  
+  if(QuotaProcess != NULL)
+  {
+    /* FIXME - Charge process quota before allocating the handle table! */
+  }
+
+  /* allocate enough memory for the handle table and the lowest level */
+  HandleTable = ExAllocatePoolWithTag(NonPagedPool,
+                                      sizeof(HANDLE_TABLE) + (N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*)),
+                                      TAG('E', 'x', 'H', 't'));
+  if(HandleTable != NULL)
+  {
+    /* initialize the handle table */
+    HandleTable->Flags = 0;
+    HandleTable->HandleCount = 0;
+    HandleTable->Table = (PHANDLE_TABLE_ENTRY**)(HandleTable + 1);
+    HandleTable->QuotaProcess = QuotaProcess;
+    HandleTable->FirstFreeTableEntry = -1; /* no entries freed so far */
+    HandleTable->NextIndexNeedingPool = 0; /* no entries freed so far, so we have to allocate already for the first handle */
+    HandleTable->UniqueProcessId = (QuotaProcess ? QuotaProcess->UniqueProcessId : NULL);
+
+    ExInitializeResource(&HandleTable->HandleTableLock);
+
+    KeInitializeEvent(&HandleTable->HandleContentionEvent,
+                      NotificationEvent,
+                      FALSE);
+
+    RtlZeroMemory(HandleTable->Table, N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*));
+
+    /* during bootup KeGetCurrentThread() might be NULL, needs to be fixed... */
+    if(KeGetCurrentThread() != NULL)
+    {
+      /* insert it into the global handle table list */
+      KeEnterCriticalRegion();
+
+      ExAcquireHandleTableListLock();
+      InsertTailList(&ExpHandleTableHead,
+                     &HandleTable->HandleTableList);
+      ExReleaseHandleTableListLock();
+
+      KeLeaveCriticalRegion();
+    }
+    else
+    {
+      InsertTailList(&ExpHandleTableHead,
+                     &HandleTable->HandleTableList);
+    }
+  }
+  else
+  {
+    /* FIXME - return the quota to the process */
+  }
+  
+  return HandleTable;
+}
+
+static BOOLEAN
+ExLockHandleTableEntryNoDestructionCheck(IN PHANDLE_TABLE HandleTable,
+                                         IN PHANDLE_TABLE_ENTRY Entry)
+{
+  ULONG_PTR Current, New;
+
+  PAGED_CODE();
+
+  DPRINT("Entering handle table entry 0x%x lock...\n", Entry);
+
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+
+  for(;;)
+  {
+    Current = (volatile ULONG_PTR)Entry->u1.Object;
+
+    if(!Current)
+    {
+      DPRINT("Attempted to lock empty handle table entry 0x%x or handle table shut down\n", Entry);
+      break;
+    }
+
+    if(!(Current & EX_HANDLE_ENTRY_LOCKED))
+    {
+      New = Current | EX_HANDLE_ENTRY_LOCKED;
+      if(InterlockedCompareExchangePointer(&Entry->u1.Object,
+                                           (PVOID)New,
+                                           (PVOID)Current) == (PVOID)Current)
+      {
+        DPRINT("SUCCESS handle table 0x%x entry 0x%x lock\n", HandleTable, Entry);
+        /* we acquired the lock */
+        return TRUE;
+      }
+    }
+
+    /* wait about 5ms at maximum so we don't wait forever in unfortunate
+       co-incidences where releasing the lock in another thread happens right
+       before we're waiting on the contention event to get pulsed, which might
+       never happen again... */
+    KeWaitForSingleObject(&HandleTable->HandleContentionEvent,
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          &ExpHandleShortWait);
+  }
+
+  return FALSE;
+}
+
+VOID
+ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
+                     IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback  OPTIONAL,
+                     IN PVOID Context  OPTIONAL)
+{
+  PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
+  PEPROCESS QuotaProcess;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  
+  KeEnterCriticalRegion();
+  
+  /* ensure there's no other operations going by acquiring an exclusive lock */
+  ExAcquireHandleTableLockExclusive(HandleTable);
+  
+  ASSERT(!(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING));
+  
+  HandleTable->Flags |= EX_HANDLE_TABLE_CLOSING;
+  
+  KePulseEvent(&HandleTable->HandleContentionEvent,
+               EVENT_INCREMENT,
+               FALSE);
+  
+  /* remove the handle table from the global handle table list */
+  ExAcquireHandleTableListLock();
+  RemoveEntryList(&HandleTable->HandleTableList);
+  ExReleaseHandleTableListLock();
+  
+  /* call the callback function to cleanup the objects associated with the
+     handle table */
+  if(DestroyHandleCallback != NULL)
+  {
+    for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
+        tlp != lasttlp;
+        tlp++)
+    {
+      if((*tlp) != NULL)
+      {
+        for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
+            mlp != lastmlp;
+            mlp++)
+        {
+          if((*mlp) != NULL)
+          {
+            PHANDLE_TABLE_ENTRY curee, laste;
+            
+            for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
+                curee != laste;
+                curee++)
+            {
+              if(curee->u1.Object != NULL && ExLockHandleTableEntryNoDestructionCheck(HandleTable, curee))
+              {
+                DestroyHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
+                ExUnlockHandleTableEntry(HandleTable, curee);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  
+  QuotaProcess = HandleTable->QuotaProcess;
+  
+  /* free the tables */
+  for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
+      tlp != lasttlp;
+      tlp++)
+  {
+    if((*tlp) != NULL)
+    {
+      for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
+          mlp != lastmlp;
+          mlp++)
+      {
+        if((*mlp) != NULL)
+        {
+          ExFreePool(*mlp);
+          
+          if(QuotaProcess != NULL)
+          {
+            /* FIXME - return the quota to the process */
+          }
+        }
+      }
+
+      ExFreePool(*tlp);
+      
+      if(QuotaProcess != NULL)
+      {
+        /* FIXME - return the quota to the process */
+      }
+    }
+  }
+  
+  ExReleaseHandleTableLock(HandleTable);
+  
+  KeLeaveCriticalRegion();
+  
+  /* free the handle table */
+  ExDeleteResource(&HandleTable->HandleTableLock);
+  ExFreePool(HandleTable);
+  
+  if(QuotaProcess != NULL)
+  {
+    /* FIXME - return the quota to the process */
+  }
+}
+
+PHANDLE_TABLE
+ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
+                 IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback  OPTIONAL,
+                 IN PVOID Context  OPTIONAL,
+                 IN PHANDLE_TABLE SourceHandleTable)
+{
+  PHANDLE_TABLE HandleTable;
+  
+  PAGED_CODE();
+  
+  ASSERT(SourceHandleTable);
+
+  HandleTable = ExCreateHandleTable(QuotaProcess);
+  if(HandleTable != NULL)
+  {
+    PHANDLE_TABLE_ENTRY **tlp, **srctlp, **etlp, *mlp, *srcmlp, *emlp, stbl, srcstbl, estbl;
+    LONG tli, mli, eli;
+    
+    tli = mli = eli = 0;
+  
+    /* make sure the other handle table isn't being changed during the duplication */
+    ExAcquireHandleTableLockShared(SourceHandleTable);
+    
+    /* allocate enough tables */
+    etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS;
+    for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table;
+        srctlp != etlp;
+        srctlp++, tlp++)
+    {
+      if(*srctlp != NULL)
+      {
+        /* allocate middle level entry tables */
+        if(QuotaProcess != NULL)
+        {
+          /* FIXME - Charge process quota before allocating the handle table! */
+        }
+        
+        *tlp = ExAllocatePoolWithTag(PagedPool,
+                                     N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
+                                     TAG('E', 'x', 'H', 't'));
+        if(*tlp != NULL)
+        {
+          RtlZeroMemory(*tlp, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
+          
+          KeMemoryBarrier();
+          
+          emlp = *srctlp + N_MIDDLELEVEL_POINTERS;
+          for(srcmlp = *srctlp, mlp = *tlp;
+              srcmlp != emlp;
+              srcmlp++, mlp++)
+          {
+            if(*srcmlp != NULL)
+            {
+              /* allocate subhandle tables */
+              if(QuotaProcess != NULL)
+              {
+                /* FIXME - Charge process quota before allocating the handle table! */
+              }
+
+              *mlp = ExAllocatePoolWithTag(PagedPool,
+                                           N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY),
+                                           TAG('E', 'x', 'H', 't'));
+              if(*mlp != NULL)
+              {
+                RtlZeroMemory(*mlp, N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY));
+              }
+              else
+              {
+                goto freehandletable;
+              }
+            }
+            else
+            {
+              *mlp = NULL;
+            }
+          }
+        }
+        else
+        {
+freehandletable:
+          DPRINT1("Failed to duplicate handle table 0x%x\n", SourceHandleTable);
+
+          ExReleaseHandleTableLock(SourceHandleTable);
+          
+          ExDestroyHandleTable(HandleTable,
+                               NULL,
+                               NULL);
+          /* allocate an empty handle table */
+          return ExCreateHandleTable(QuotaProcess);
+        }
+      }
+    }
+
+    /* duplicate the handles */
+    HandleTable->HandleCount = SourceHandleTable->HandleCount;
+    HandleTable->FirstFreeTableEntry = SourceHandleTable->FirstFreeTableEntry;
+    HandleTable->NextIndexNeedingPool = SourceHandleTable->NextIndexNeedingPool;
+
+    /* make sure all tables are zeroed */
+    KeMemoryBarrier();
+
+    etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS;
+    for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table;
+        srctlp != etlp;
+        srctlp++, tlp++, tli++)
+    {
+      if(*srctlp != NULL)
+      {
+        ASSERT(*tlp != NULL);
+
+        emlp = *srctlp + N_MIDDLELEVEL_POINTERS;
+        for(srcmlp = *srctlp, mlp = *tlp;
+            srcmlp != emlp;
+            srcmlp++, mlp++, mli++)
+        {
+          if(*srcmlp != NULL)
+          {
+            ASSERT(*mlp != NULL);
+
+            /* walk all handle entries and duplicate them if wanted */
+            estbl = *srcmlp + N_SUBHANDLE_ENTRIES;
+            for(srcstbl = *srcmlp, stbl = *mlp;
+                srcstbl != estbl;
+                srcstbl++, stbl++, eli++)
+            {
+              /* try to duplicate the source handle */
+              if(srcstbl->u1.Object != NULL &&
+                 ExLockHandleTableEntry(SourceHandleTable,
+                                        srcstbl))
+              {
+                /* ask the caller if this handle should be duplicated */
+                if(DuplicateHandleCallback != NULL &&
+                   !DuplicateHandleCallback(HandleTable,
+                                            srcstbl,
+                                            Context))
+                {
+                  /* free the entry and chain it into the free list */
+                  HandleTable->HandleCount--;
+                  stbl->u1.Object = NULL;
+                  stbl->u2.NextFreeTableEntry = HandleTable->FirstFreeTableEntry;
+                  HandleTable->FirstFreeTableEntry = BUILD_HANDLE(tli, mli, eli);
+                }
+                else
+                {
+                  /* duplicate the handle and unlock it */
+                  stbl->u2.GrantedAccess = srcstbl->u2.GrantedAccess;
+                  stbl->u1.ObAttributes = srcstbl->u1.ObAttributes & ~EX_HANDLE_ENTRY_LOCKED;
+                }
+                ExUnlockHandleTableEntry(SourceHandleTable,
+                                         srcstbl);
+              }
+              else
+              {
+                /* this is a free handle table entry, copy over the entire
+                   structure as-is */
+                *stbl = *srcstbl;
+              }
+            }
+          }
+        }
+      }
+    }
+    
+    /* release the source handle table */
+    ExReleaseHandleTableLock(SourceHandleTable);
+  }
+  
+  return HandleTable;
+}
+
+static PHANDLE_TABLE_ENTRY
+ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                            OUT PLONG Handle)
+{
+  PHANDLE_TABLE_ENTRY Entry = NULL;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  ASSERT(Handle);
+  ASSERT(KeGetCurrentThread() != NULL);
+  
+  DPRINT("HT[0x%x]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount);
+  
+  if(HandleTable->HandleCount < EX_MAX_HANDLES)
+  {
+    ULONG tli, mli, eli;
+    
+    if(HandleTable->FirstFreeTableEntry != -1)
+    {
+      /* there's a free handle entry we can just grab and use */
+      tli = TLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
+      mli = MLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
+      eli = ELI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
+      
+      /* the pointer should be valid in any way!!! */
+      ASSERT(HandleTable->Table[tli]);
+      ASSERT(HandleTable->Table[tli][mli]);
+      
+      Entry = &HandleTable->Table[tli][mli][eli];
+      
+      *Handle = HandleTable->FirstFreeTableEntry;
+      
+      /* save the index to the next free handle (if available) */
+      HandleTable->FirstFreeTableEntry = Entry->u2.NextFreeTableEntry;
+      Entry->u2.NextFreeTableEntry = 0;
+      Entry->u1.Object = NULL;
+      
+      HandleTable->HandleCount++;
+    }
+    else
+    {
+      /* we need to allocate a new subhandle table first */
+      PHANDLE_TABLE_ENTRY cure, laste, ntbl, *nmtbl;
+      ULONG i;
+      BOOLEAN AllocatedMtbl;
+
+      ASSERT(HandleTable->NextIndexNeedingPool <= N_MAX_HANDLE);
+      
+      /* the index of the next table to be allocated was saved in
+         NextIndexNeedingPool the last time a handle entry was allocated and
+         the subhandle entry list was full. the subhandle entry index of
+         NextIndexNeedingPool should be 0 here! */
+      tli = TLI_FROM_HANDLE(HandleTable->NextIndexNeedingPool);
+      mli = MLI_FROM_HANDLE(HandleTable->NextIndexNeedingPool);
+      DPRINT("HandleTable->NextIndexNeedingPool: 0x%x\n", HandleTable->NextIndexNeedingPool);
+      DPRINT("tli: 0x%x mli: 0x%x eli: 0x%x\n", tli, mli, ELI_FROM_HANDLE(HandleTable->NextIndexNeedingPool));
+
+      ASSERT(ELI_FROM_HANDLE(HandleTable->NextIndexNeedingPool) == 0);
+
+      DPRINT("HandleTable->Table[%d] == 0x%x\n", tli, HandleTable->Table[tli]);
+      
+      /* allocate a middle level entry list if required */
+      nmtbl = HandleTable->Table[tli];
+      if(nmtbl == NULL)
+      {
+        if(HandleTable->QuotaProcess != NULL)
+        {
+          /* FIXME - Charge process quota before allocating the handle table! */
+        }
+        
+        nmtbl = ExAllocatePoolWithTag(PagedPool,
+                                      N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
+                                      TAG('E', 'x', 'H', 't'));
+        if(nmtbl == NULL)
+        {
+          if(HandleTable->QuotaProcess != NULL)
+          {
+            /* FIXME - return the quota to the process */
+          }
+          
+          return NULL;
+        }
+        
+        /* clear the middle level entry list */
+        RtlZeroMemory(nmtbl, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
+        
+        /* make sure the table was zeroed before we set one item */
+        KeMemoryBarrier();
+        
+        /* note, don't set the the pointer in the top level list yet because we
+           might screw up lookups if allocating a subhandle entry table failed
+           and this newly allocated table might get freed again */
+        AllocatedMtbl = TRUE;
+      }
+      else
+      {
+        AllocatedMtbl = FALSE;
+        
+        /* allocate a subhandle entry table in any case! */
+        ASSERT(nmtbl[mli] == NULL);
+      }
+
+      DPRINT("HandleTable->Table[%d][%d] == 0x%x\n", tli, mli, nmtbl[mli]);
+
+      if(HandleTable->QuotaProcess != NULL)
+      {
+        /* FIXME - Charge process quota before allocating the handle table! */
+      }
+
+      ntbl = ExAllocatePoolWithTag(PagedPool,
+                                   N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY),
+                                   TAG('E', 'x', 'H', 't'));
+      if(ntbl == NULL)
+      {
+        if(HandleTable->QuotaProcess != NULL)
+        {
+          /* FIXME - Return process quota charged  */
+        }
+        
+        /* free the middle level entry list, if allocated, because it's empty and
+           unused */
+        if(AllocatedMtbl)
+        {
+          ExFreePool(nmtbl);
+          
+          if(HandleTable->QuotaProcess != NULL)
+          {
+            /* FIXME - Return process quota charged  */
+          }
+        }
+        
+        return NULL;
+      }
+      
+      /* let's just use the very first entry */
+      Entry = ntbl;
+      Entry->u1.ObAttributes = EX_HANDLE_ENTRY_LOCKED;
+      Entry->u2.NextFreeTableEntry = 0;
+      
+      *Handle = HandleTable->NextIndexNeedingPool;
+      
+      HandleTable->HandleCount++;
+      
+      /* set the FirstFreeTableEntry member to the second entry and chain the
+         free entries */
+      HandleTable->FirstFreeTableEntry = HandleTable->NextIndexNeedingPool + 1;
+      for(cure = Entry + 1, laste = Entry + N_SUBHANDLE_ENTRIES, i = HandleTable->FirstFreeTableEntry + 1;
+          cure != laste;
+          cure++, i++)
+      {
+        cure->u1.Object = NULL;
+        cure->u2.NextFreeTableEntry = i;
+      }
+      /* truncate the free entry list */
+      (cure - 1)->u2.NextFreeTableEntry = -1;
+
+      /* save the pointers to the allocated list(s) */
+      InterlockedExchangePointer(&nmtbl[mli], ntbl);
+      if(AllocatedMtbl)
+      {
+        InterlockedExchangePointer(&HandleTable->Table[tli], nmtbl);
+      }
+      
+      /* increment the NextIndexNeedingPool to the next index where we need to
+         allocate new memory */
+      HandleTable->NextIndexNeedingPool += N_SUBHANDLE_ENTRIES;
+    }
+  }
+  else
+  {
+    DPRINT1("Can't allocate any more handles in handle table 0x%x!\n", HandleTable);
+  }
+  
+  return Entry;
+}
+
+static VOID
+ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                        IN PHANDLE_TABLE_ENTRY Entry,
+                        IN LONG Handle)
+{
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+  ASSERT(IS_VALID_EX_HANDLE(Handle));
+  
+  DPRINT("ExpFreeHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
+  
+  /* automatically unlock the entry if currently locked. We however don't notify
+     anyone who waited on the handle because we're holding an exclusive lock after
+     all and these locks will fail then */
+  InterlockedExchangePointer(&Entry->u1.Object, NULL);
+  Entry->u2.NextFreeTableEntry = HandleTable->FirstFreeTableEntry;
+  HandleTable->FirstFreeTableEntry = Handle;
+  
+  HandleTable->HandleCount--;
+}
+
+static PHANDLE_TABLE_ENTRY
+ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                          IN LONG Handle)
+{
+  PHANDLE_TABLE_ENTRY Entry = NULL;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  
+  if(IS_VALID_EX_HANDLE(Handle))
+  {
+    ULONG tli, mli, eli;
+    PHANDLE_TABLE_ENTRY *mlp;
+    
+    tli = TLI_FROM_HANDLE(Handle);
+    mli = MLI_FROM_HANDLE(Handle);
+    eli = ELI_FROM_HANDLE(Handle);
+    
+    mlp = HandleTable->Table[tli];
+    if(Handle < HandleTable->NextIndexNeedingPool &&
+       mlp != NULL && mlp[mli] != NULL && mlp[mli][eli].u1.Object != NULL)
+    {
+      Entry = &mlp[mli][eli];
+      DPRINT("handle lookup 0x%x -> entry 0x%x [HT:0x%x] ptr: 0x%x\n", Handle, Entry, HandleTable, mlp[mli][eli].u1.Object);
+    }
+  }
+  else
+  {
+    DPRINT("Looking up invalid handle 0x%x\n", Handle);
+  }
+  
+  return Entry;
+}
+
+BOOLEAN
+ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                       IN PHANDLE_TABLE_ENTRY Entry)
+{
+  ULONG_PTR Current, New;
+
+  PAGED_CODE();
+  
+  DPRINT("Entering handle table entry 0x%x lock...\n", Entry);
+  
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+  
+  for(;;)
+  {
+    Current = (volatile ULONG_PTR)Entry->u1.Object;
+    
+    if(!Current || (HandleTable->Flags & EX_HANDLE_TABLE_CLOSING))
+    {
+      DPRINT("Attempted to lock empty handle table entry 0x%x or handle table shut down\n", Entry);
+      break;
+    }
+    
+    if(!(Current & EX_HANDLE_ENTRY_LOCKED))
+    {
+      New = Current | EX_HANDLE_ENTRY_LOCKED;
+      if(InterlockedCompareExchangePointer(&Entry->u1.Object,
+                                           (PVOID)New,
+                                           (PVOID)Current) == (PVOID)Current)
+      {
+        DPRINT("SUCCESS handle table 0x%x entry 0x%x lock\n", HandleTable, Entry);
+        /* we acquired the lock */
+        return TRUE;
+      }
+    }
+
+    /* wait about 5ms at maximum so we don't wait forever in unfortunate
+       co-incidences where releasing the lock in another thread happens right
+       before we're waiting on the contention event to get pulsed, which might
+       never happen again... */
+    KeWaitForSingleObject(&HandleTable->HandleContentionEvent,
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          &ExpHandleShortWait);
+  }
+
+  return FALSE;
+}
+
+VOID
+ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                         IN PHANDLE_TABLE_ENTRY Entry)
+{
+  ULONG_PTR Current, New;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+  
+  DPRINT("ExUnlockHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
+  
+  Current = (volatile ULONG_PTR)Entry->u1.Object;
+
+  ASSERT(Current & EX_HANDLE_ENTRY_LOCKED);
+  
+  New = Current & ~EX_HANDLE_ENTRY_LOCKED;
+  
+  InterlockedExchangePointer(&Entry->u1.Object,
+                             (PVOID)New);
+
+  /* we unlocked the entry, pulse the contention event so threads who're waiting
+     on the release can continue */
+  KePulseEvent(&HandleTable->HandleContentionEvent,
+               EVENT_INCREMENT,
+               FALSE);
+}
+
+LONG
+ExCreateHandle(IN PHANDLE_TABLE HandleTable,
+               IN PHANDLE_TABLE_ENTRY Entry)
+{
+  PHANDLE_TABLE_ENTRY NewHandleTableEntry;
+  LONG Handle = EX_INVALID_HANDLE;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+  
+  /* The highest bit in Entry->u1.Object has to be 1 so we make sure it's a
+     pointer to kmode memory. It will cleared though because it also indicates
+     the lock */
+  ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
+  
+  KeEnterCriticalRegion();
+  ExAcquireHandleTableLockExclusive(HandleTable);
+  
+  NewHandleTableEntry = ExpAllocateHandleTableEntry(HandleTable,
+                                                    &Handle);
+  if(NewHandleTableEntry != NULL)
+  {
+    *NewHandleTableEntry = *Entry;
+    
+    ExUnlockHandleTableEntry(HandleTable,
+                             NewHandleTableEntry);
+  }
+
+  ExReleaseHandleTableLock(HandleTable);
+  KeLeaveCriticalRegion();
+
+  return Handle;
+}
+
+BOOLEAN
+ExDestroyHandle(IN PHANDLE_TABLE HandleTable,
+                IN LONG Handle)
+{
+  PHANDLE_TABLE_ENTRY HandleTableEntry;
+  BOOLEAN Ret = FALSE;
+  
+  PAGED_CODE();
+  
+  ASSERT(HandleTable);
+  
+  KeEnterCriticalRegion();
+  ExAcquireHandleTableLockExclusive(HandleTable);
+  
+  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
+                                               Handle);
+  
+  if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
+  {
+    /* free and automatically unlock the handle. However we don't need to pulse
+       the contention event since other locks on this entry will fail */
+    ExpFreeHandleTableEntry(HandleTable,
+                            HandleTableEntry,
+                            Handle);
+    Ret = TRUE;
+  }
+  
+  ExReleaseHandleTableLock(HandleTable);
+  KeLeaveCriticalRegion();
+  
+  return Ret;
+}
+
+VOID
+ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable,
+                       IN PHANDLE_TABLE_ENTRY Entry,
+                       IN LONG Handle)
+{
+  PAGED_CODE();
+
+  ASSERT(HandleTable);
+  ASSERT(Entry);
+  
+  /* This routine requires the entry to be locked */
+  ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
+  
+  DPRINT("DestroyHandleByEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
+
+  KeEnterCriticalRegion();
+  ExAcquireHandleTableLockExclusive(HandleTable);
+
+  /* free and automatically unlock the handle. However we don't need to pulse
+     the contention event since other locks on this entry will fail */
+  ExpFreeHandleTableEntry(HandleTable,
+                          Entry,
+                          Handle);
+
+  ExReleaseHandleTableLock(HandleTable);
+  KeLeaveCriticalRegion();
+}
+
+PHANDLE_TABLE_ENTRY
+ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable,
+                     IN LONG Handle)
+{
+  PHANDLE_TABLE_ENTRY HandleTableEntry;
+
+  PAGED_CODE();
+
+  ASSERT(HandleTable);
+  
+  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
+                                               Handle);
+  if (HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
+  {
+    DPRINT("ExMapHandleToPointer HT:0x%x Entry:0x%x locked\n", HandleTable, HandleTableEntry);
+    return HandleTableEntry;
+  }
+  
+  return NULL;
+}
+
+BOOLEAN
+ExChangeHandle(IN PHANDLE_TABLE HandleTable,
+               IN LONG Handle,
+               IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback,
+               IN PVOID Context)
+{
+  PHANDLE_TABLE_ENTRY HandleTableEntry;
+  BOOLEAN Ret = FALSE;
+
+  PAGED_CODE();
+
+  ASSERT(HandleTable);
+  ASSERT(ChangeHandleCallback);
+
+  KeEnterCriticalRegion();
+  
+  HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
+                                               Handle);
+
+  if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
+  {
+    Ret = ChangeHandleCallback(HandleTable,
+                               HandleTableEntry,
+                               NULL);
+
+    ExUnlockHandleTableEntry(HandleTable,
+                             HandleTableEntry);
+  }
+  
+  KeLeaveCriticalRegion();
+
+  return Ret;
+}
+
+/* EOF */
diff --git a/reactos/ntoskrnl/ex/hashtab.c b/reactos/ntoskrnl/ex/hashtab.c
deleted file mode 100644 (file)
index 82954c1..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/* $Id$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ex/hashtab.c
- * PURPOSE:         Hash table support
- * 
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- */
-
-/*
- * NOTES:           The hash function is from:
- *                  Bob Jenkins <bob_jenkins@burtleburtle.net>
- *                  http://burtleburtle.net/bob/hash/doobs.html
- */
-
-#include <ntoskrnl.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS ****************************************************************/
-
-#define ExpHashTableSize(n) ((ULONG)1 << (n))
-#define ExpHashTableMask(n) (ExpHashTableSize(n) - 1)
-
-#define ExpHashMix(a, b, c) \
-{ \
-  a -= b; a -= c; a ^= (c >> 13); \
-  b -= c; b -= a; b ^= (a << 8);  \
-  c -= a; c -= b; c ^= (b >> 13); \
-  a -= b; a -= c; a ^= (c >> 12); \
-  b -= c; b -= a; b ^= (a << 16); \
-  c -= a; c -= b; c ^= (b >> 5);  \
-  a -= b; a -= c; a ^= (c >> 3);  \
-  b -= c; b -= a; b ^= (a << 10); \
-  c -= a; c -= b; c ^= (b >> 15); \
-}
-
-
-ULONG
-ExpHash(PUCHAR Key,
-  ULONG KeyLength)
-{
-  register ULONG a, b, c, len;
-
-       /* Set up the internal state */
-       len = KeyLength;
-       a = b = 0x9e3779b9;    /* The golden ratio; an arbitrary value */
-       c = 0;
-
-       /* Handle most of the key */
-       while (len >= 12)
-               {
-                 a += (Key[0] + ((ULONG)Key[1]<<8) + ((ULONG)Key[2]<<16) + ((ULONG)Key[3]<<24));
-                 b += (Key[4] + ((ULONG)Key[5]<<8) + ((ULONG)Key[6]<<16) + ((ULONG)Key[7]<<24));
-                 c += (Key[8] + ((ULONG)Key[9]<<8) + ((ULONG)Key[10]<<16)+ ((ULONG)Key[11]<<24));
-                 ExpHashMix(a, b, c);
-                 Key += 12; len -= 12;
-               }
-
-       /* Handle the last 11 bytes */
-       c += KeyLength;
-       switch(len)       /* All the case statements fall through */
-               {
-                       case 11: c += ((ULONG)Key[10] << 24);
-                       case 10: c += ((ULONG)Key[9] << 16);
-                       case 9 : c += ((ULONG)Key[8] << 8);
-                         /* The first byte of c is reserved for the length */
-                       case 8 : b += ((ULONG)Key[7] << 24);
-                       case 7 : b += ((ULONG)Key[6] << 16);
-                       case 6 : b += ((ULONG)Key[5] << 8);
-                       case 5 : b += Key[4];
-                       case 4 : a += ((ULONG)Key[3] << 24);
-                       case 3 : a += ((ULONG)Key[2] << 16);
-                       case 2 : a += ((ULONG)Key[1] << 8);
-                       case 1 : a += Key[0];
-                       /* case 0: nothing left to add */
-               }
-
-       ExpHashMix(a, b, c);
-
-       return c;
-}
-
-
-/*
- * Lock the hash table 
- */
-inline VOID
-ExpLockHashTable(PHASH_TABLE HashTable,
-  PKIRQL OldIrql)
-{
-       if (HashTable->UseNonPagedPool)
-         {
-      KeAcquireSpinLock(&HashTable->Lock.NonPaged, OldIrql);
-         }
-       else
-               {
-      ExAcquireFastMutex(&HashTable->Lock.Paged);
-               }
-}
-
-
-/*
- * Unlock the hash table
- */
-inline VOID
-ExpUnlockHashTable(PHASH_TABLE HashTable,
-  PKIRQL OldIrql)
-{
-       if (HashTable->UseNonPagedPool)
-         {
-      KeReleaseSpinLock(&HashTable->Lock.NonPaged, *OldIrql);
-         }
-       else
-               {
-      ExReleaseFastMutex(&HashTable->Lock.Paged);
-               }
-}
-
-
-/*
- * Insert a value in a hash table.
- */
-inline VOID STDCALL
-ExpInsertHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  IN PVOID  Value)
-{
-  ULONG Index;
-
-  Index = (ExpHash(Key, KeyLength) & ExpHashTableMask(HashTable->HashTableSize));
-
-  ExInsertSplayTree(&HashTable->HashTrees[Index], Key, Value);
-}
-
-
-/*
- * Search for a value associated with a given key in a hash table.
- */
-inline BOOLEAN STDCALL
-ExpSearchHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  OUT PVOID  * Value)
-{
-  ULONG Index;
-
-  Index = (ExpHash(Key, KeyLength) & ExpHashTableMask(HashTable->HashTableSize));
-
-  return ExSearchSplayTree(&HashTable->HashTrees[Index], Key, Value);
-}
-
-
-/*
- * Remove a value associated with a given key from a hash table.
- */
-BOOLEAN STDCALL
-ExpRemoveHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  IN PVOID  * Value)
-{
-  ULONG Index;
-
-  Index = (ExpHash(Key, KeyLength) & ExpHashTableMask(HashTable->HashTableSize));
-
-  return ExRemoveSplayTree(&HashTable->HashTrees[Index], Key, Value);
-}
-
-
-/*
- * Initializes a hash table.
- */
-BOOLEAN STDCALL
-ExInitializeHashTable(IN PHASH_TABLE  HashTable,
-  IN ULONG  HashTableSize,
-  IN PKEY_COMPARATOR  Compare  OPTIONAL,
-  IN BOOLEAN  UseNonPagedPool)
-{
-  BOOLEAN Status;
-  ULONG Index;
-
-  RtlZeroMemory(HashTable, sizeof(HASH_TABLE));
-
-  HashTable->HashTableSize = HashTableSize;
-
-  HashTable->UseNonPagedPool = UseNonPagedPool;
-
-  if (UseNonPagedPool)
-    {
-      KeInitializeSpinLock(&HashTable->Lock.NonPaged);
-      HashTable->HashTrees = ExAllocatePool(NonPagedPool, ExpHashTableSize(HashTableSize) * sizeof(SPLAY_TREE));
-               }
-               else
-               {
-      ExInitializeFastMutex(&HashTable->Lock.Paged);
-      HashTable->HashTrees = ExAllocatePool(PagedPool, ExpHashTableSize(HashTableSize) * sizeof(SPLAY_TREE));
-               }
-
-  if (HashTable->HashTrees == NULL)
-               {
-      return FALSE;
-               }
-
-  for (Index = 0; Index < ExpHashTableSize(HashTableSize); Index++)
-    {
-      Status = ExInitializeSplayTree(&HashTable->HashTrees[Index], Compare, FALSE, UseNonPagedPool);
-
-      if (!Status)
-                               {
-          LONG i;
-
-          for (i = Index - 1; i >= 0; i--)
-                                               {
-              ExDeleteSplayTree(&HashTable->HashTrees[i]);
-                                               }
-
-          ExFreePool(HashTable->HashTrees);
-
-          return FALSE;
-                               }
-    }
-
-  return TRUE;
-}
-
-
-/*
- * Release resources used by a hash table.
- */
-VOID STDCALL
-ExDeleteHashTable(IN PHASH_TABLE  HashTable)
-{
-  ULONG Index;
-
-  for (Index = 0; Index < ExpHashTableSize(HashTable->HashTableSize); Index++)
-               {
-      ExDeleteSplayTree(&HashTable->HashTrees[Index]);
-               }
-
-  ExFreePool(HashTable->HashTrees);
-}
-
-
-/*
- * Insert a value in a hash table.
- */
-VOID STDCALL
-ExInsertHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  IN PVOID  Value)
-{
-  KIRQL OldIrql;
-
-  /* FIXME: Use SEH for error reporting */
-
-  ExpLockHashTable(HashTable, &OldIrql);
-  ExpInsertHashTable(HashTable, Key, KeyLength, Value);
-  ExpUnlockHashTable(HashTable, &OldIrql);
-}
-
-
-/*
- * Search for a value associated with a given key in a hash table.
- */
-BOOLEAN STDCALL
-ExSearchHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  OUT PVOID  * Value)
-{
-  BOOLEAN Status;
-  KIRQL OldIrql;
-
-  ExpLockHashTable(HashTable, &OldIrql);
-  Status = ExpSearchHashTable(HashTable, Key, KeyLength, Value);
-  ExpUnlockHashTable(HashTable, &OldIrql);
-
-  return Status;
-}
-
-
-/*
- * Remove a value associated with a given key from a hash table.
- */
-BOOLEAN STDCALL
-ExRemoveHashTable(IN PHASH_TABLE  HashTable,
-  IN PVOID  Key,
-  IN ULONG  KeyLength,
-  IN PVOID  * Value)
-{
-  BOOLEAN Status;
-  KIRQL OldIrql;
-
-  ExpLockHashTable(HashTable, &OldIrql);
-  Status = ExpRemoveHashTable(HashTable, Key, KeyLength, Value);
-  ExpUnlockHashTable(HashTable, &OldIrql);
-
-  return Status;
-}
-
-/* EOF */
index 03951a8..a5982fe 100644 (file)
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/init.c
  * PURPOSE:         Executive initalization
  * 
- * PROGRAMMERS:     Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
+ *                                                    and optimized/cleaned it.
+ *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)
  */
 
 #include <ntoskrnl.h>
+#include <ntos/bootvid.h>
+#include "../dbg/kdb.h"
 #define NDEBUG
 #include <internal/debug.h>
 
 /* DATA **********************************************************************/
 
+extern ULONG MmCoreDumpType;
+extern CHAR KiTimerSystemAuditing;
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+extern ADDRESS_RANGE KeMemoryMap[64];
+extern ULONG KeMemoryMapRangeCount;
+extern ULONG_PTR FirstKrnlPhysAddr;
+extern ULONG_PTR LastKrnlPhysAddr;
+extern ULONG_PTR LastKernelAddress;
+extern LOADER_MODULE KeLoaderModules[64];
+extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
+extern LIST_ENTRY KiProfileListHead;
+extern LIST_ENTRY KiProfileSourceListHead;
+extern KSPIN_LOCK KiProfileLock;
+
+VOID PspPostInitSystemProcess(VOID);
+
 /* FUNCTIONS ****************************************************************/
 
+static 
+VOID 
+INIT_FUNCTION
+InitSystemSharedUserPage (PCSZ ParameterLine)
+{
+    UNICODE_STRING ArcDeviceName;
+    UNICODE_STRING ArcName;
+    UNICODE_STRING BootPath;
+    UNICODE_STRING DriveDeviceName;
+    UNICODE_STRING DriveName;
+    WCHAR DriveNameBuffer[20];
+    PCHAR ParamBuffer;
+    PWCHAR ArcNameBuffer;
+    PCHAR p;
+    NTSTATUS Status;
+    ULONG Length;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE Handle;
+    ULONG i;
+    BOOLEAN BootDriveFound = FALSE;
+
+   /*
+    * NOTE:
+    *   The shared user page has been zeroed-out right after creation.
+    *   There is NO need to do this again.
+    */
+    Ki386SetProcessorFeatures();
+    
+    /* Set the Version Data */
+    SharedUserData->NtProductType = NtProductWinNt;
+    SharedUserData->ProductTypeIsValid = TRUE;
+    SharedUserData->NtMajorVersion = 5;
+    SharedUserData->NtMinorVersion = 0;
+   
+    /*
+     * Retrieve the current dos system path
+     * (e.g.: C:\reactos) from the given arc path
+     * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
+     * Format: "<arc_name>\<path> [options...]"
+     */
+
+    /* Create local parameter line copy */
+    ParamBuffer = ExAllocatePool(PagedPool, 256);
+    strcpy (ParamBuffer, (char *)ParameterLine);
+    DPRINT("%s\n", ParamBuffer);
+
+    /* Cut options off */
+    p = strchr (ParamBuffer, ' ');
+    if (p) *p = 0;
+    DPRINT("%s\n", ParamBuffer);
+
+    /* Extract path */
+    p = strchr (ParamBuffer, '\\');
+    if (p) {
+        
+        DPRINT("Boot path: %s\n", p);
+        RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
+        *p = 0;
+    
+    } else {
+        
+        DPRINT("Boot path: %s\n", "\\");
+        RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
+    }
+    DPRINT("Arc name: %s\n", ParamBuffer);
+   
+    /* Only ARC Name left - Build full ARC Name */
+    ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+    swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
+    RtlInitUnicodeString (&ArcName, ArcNameBuffer);
+    DPRINT("Arc name: %wZ\n", &ArcName);
+
+    /* Free ParamBuffer */
+    ExFreePool (ParamBuffer);
+
+    /* Allocate ARC Device Name string */
+    ArcDeviceName.Length = 0;
+    ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
+    ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+
+    /* Open the Symbolic Link */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ArcName,
+                               OBJ_OPENLINK,
+                               NULL,
+                               NULL);
+    Status = NtOpenSymbolicLinkObject(&Handle,
+                                      SYMBOLIC_LINK_ALL_ACCESS,
+                                      &ObjectAttributes);
+    
+    /* Free the String */
+    RtlFreeUnicodeString(&ArcName);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    
+    /* Query the Link */
+    Status = NtQuerySymbolicLinkObject(Handle,
+                                       &ArcDeviceName,
+                                       &Length);
+    NtClose (Handle);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
+
+    /* Allocate Device Name string */
+    DriveDeviceName.Length = 0;
+    DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
+    DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+
+    /* Loop Drives */
+    for (i = 0; i < 26; i++)  {
+        
+        /* Setup the String */
+        swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
+        RtlInitUnicodeString(&DriveName,
+                             DriveNameBuffer);
+        
+        /* Open the Symbolic Link */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &DriveName,
+                                   OBJ_OPENLINK,
+                                   NULL,
+                                   NULL);
+        Status = NtOpenSymbolicLinkObject(&Handle,
+                                          SYMBOLIC_LINK_ALL_ACCESS,
+                                          &ObjectAttributes);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to open link %wZ\n", &DriveName);
+            continue;
+        }
+        
+        /* Query it */
+        Status = NtQuerySymbolicLinkObject(Handle,
+                                           &DriveDeviceName,
+                                           &Length);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to query link %wZ\n", &DriveName);
+            continue;
+        }
+        DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName, &DriveDeviceName);
+
+        /* See if we've found the boot drive */
+        if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) {
+            
+            DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
+            swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath);
+            BootDriveFound = TRUE;
+        }
+
+        /* Close this Link */
+        NtClose (Handle);
+    }
+    
+    /* Free all the Strings we have in memory */
+    RtlFreeUnicodeString (&BootPath);
+    RtlFreeUnicodeString (&DriveDeviceName);
+    RtlFreeUnicodeString (&ArcDeviceName);
+
+    /* Make sure we found the Boot Drive */
+    if (BootDriveFound == FALSE) {
+        
+        DbgPrint("No system drive found!\n");
+        KEBUGCHECK (NO_BOOT_DEVICE);
+    }
+}
+
+inline
+VOID
+STDCALL
+ExecuteRuntimeAsserts(VOID)
+{
+    /*
+     * Fail at runtime if someone has changed various structures without
+     * updating the offsets used for the assembler code.
+     */
+    ASSERT(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
+    ASSERT(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, NpxState) == KTHREAD_NPX_STATE);
+    ASSERT(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
+    ASSERT(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
+    ASSERT(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
+    ASSERT(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
+    ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
+    ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
+    ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
+    ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
+    ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
+    ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
+    ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);  
+    ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
+    ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
+    ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
+    ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
+    ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
+}
+
+inline
+VOID
+STDCALL
+ParseAndCacheLoadedModules(PBOOLEAN SetupBoot)
+{
+    ULONG i;
+    PCHAR Name;
+    
+    /* Loop the Module List and get the modules we want */
+    for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
+       
+        /* Get the Name of this Module */
+        if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'))) {
+      
+            /* Save the name */
+            Name = (PCHAR)KeLoaderModules[i].String;
+          
+        } else {
+      
+            /* No name, skip */
+            Name++;
+        }
+      
+        /* Now check for any of the modules we will need later */
+        if (!_stricmp(Name, "ansi.nls")) {
+          
+            CachedModules[AnsiCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "oem.nls")) {
+          
+            CachedModules[OemCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "casemap.nls")) {
+      
+            CachedModules[UnicodeCasemap] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv")) {
+      
+            CachedModules[SystemRegistry] = &KeLoaderModules[i];
+            *SetupBoot = FALSE;
+      
+        } else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv")) {
+      
+            CachedModules[HardwareRegistry] = &KeLoaderModules[i];
+        }
+    }    
+}
+
+inline
+VOID
+STDCALL
+ParseCommandLine(PULONG MaxMem, 
+                 PBOOLEAN NoGuiBoot, 
+                 PBOOLEAN BootLog, 
+                 PBOOLEAN ForceAcpiDisable)
+{
+    PCHAR p1, p2; 
+    
+    p1 = (PCHAR)KeLoaderBlock.CommandLine;
+    while(*p1 && (p2 = strchr(p1, '/'))) {
+        
+        p2++;
+        if (!_strnicmp(p2, "MAXMEM", 6)) {
+            
+            p2 += 6;
+            while (isspace(*p2)) p2++;
+            
+            if (*p2 == '=') {
+                
+                p2++;
+                
+                while(isspace(*p2)) p2++;
+                
+                if (isdigit(*p2)) {
+                    while (isdigit(*p2)) {
+                        *MaxMem = *MaxMem * 10 + *p2 - '0';
+                        p2++;
+                    }                
+                    break;
+                }
+            }
+        } else if (!_strnicmp(p2, "NOGUIBOOT", 9)) {
+            
+            p2 += 9;
+            *NoGuiBoot = TRUE;
+            
+        } else if (!_strnicmp(p2, "CRASHDUMP", 9)) {
+            
+            p2 += 9;
+            if (*p2 == ':') {
+                
+                p2++;
+                if (!_strnicmp(p2, "FULL", 4)) {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
+                    
+                } else {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
+                }
+            }
+        } else if (!_strnicmp(p2, "BOOTLOG", 7)) {
+            
+            p2 += 7;
+            *BootLog = TRUE;
+        } else if (!_strnicmp(p2, "NOACPI", 6)) {
+            
+            p2 += 6;
+            *ForceAcpiDisable = TRUE;
+        }
+        
+        p1 = p2;
+    }
+}
+
+VOID 
+INIT_FUNCTION
+STDCALL
+ExpInitializeExecutive(VOID)
+{
+    CHAR str[50];
+    UNICODE_STRING EventName;
+    HANDLE InitDoneEventHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    BOOLEAN NoGuiBoot = FALSE;
+    BOOLEAN BootLog = FALSE;
+    ULONG MaxMem = 0;
+    BOOLEAN SetupBoot = TRUE;
+    BOOLEAN ForceAcpiDisable = FALSE;
+    LARGE_INTEGER Timeout;
+    HANDLE ProcessHandle;
+    HANDLE ThreadHandle;
+    NTSTATUS Status;
+
+    /* Check if the structures match the ASM offset constants */
+    ExecuteRuntimeAsserts();
+    
+    /* Sets up the Text Sections of the Kernel and HAL for debugging */
+    LdrInit1();
+    
+    /* Lower the IRQL to Dispatch Level */
+    KeLowerIrql(DISPATCH_LEVEL);
+    
+    /* Sets up the VDM Data */
+    NtEarlyInitVdm();
+
+    /* Parse Command Line Settings */
+    ParseCommandLine(&MaxMem, &NoGuiBoot, &BootLog, &ForceAcpiDisable);
+    
+    /* Initialize Kernel Memory Address Space */
+    MmInit1(FirstKrnlPhysAddr,
+            LastKrnlPhysAddr,
+            LastKernelAddress,
+            (PADDRESS_RANGE)&KeMemoryMap,
+            KeMemoryMapRangeCount,
+            MaxMem > 8 ? MaxMem : 4096);
+
+    /* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
+    ParseAndCacheLoadedModules(&SetupBoot);
+    
+    /* Initialize the kernel debugger */
+    KdInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
+    KeInit2();
+
+    /* Bring back the IRQL to Passive */
+    KeLowerIrql(PASSIVE_LEVEL);
+    
+    /* Initialize Profiling */
+    InitializeListHead(&KiProfileListHead);
+    InitializeListHead(&KiProfileSourceListHead);
+    KeInitializeSpinLock(&KiProfileLock);
+    
+    /* Load basic Security for other Managers */
+    if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+
+    /* Create the Basic Object Manager Types to allow new Object Types */
+    ObInit();
+    
+    /* Initialize Lookaside Lists */
+    ExInit2();
+    
+    /* Set up Region Maps, Sections and the Paging File */
+    MmInit2();
+
+    /* Initialize Tokens now that the Object Manager is ready */
+    if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
+    /* Set 1 CPU for now, we'll increment this later */
+    KeNumberProcessors = 1;
+    
+    /* Initalize the Process Manager */
+    PiInitProcessManager();
+
+    /* Break into the Debugger if requested */
+    if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+
+    /* Initialize all processors */
+    while (!HalAllProcessorsStarted()) {
+        
+        PVOID ProcessorStack;
+
+        /* Set up the Kernel and Process Manager for this CPU */
+        KePrepareForApplicationProcessorInit(KeNumberProcessors);
+        PsPrepareForApplicationProcessorInit(KeNumberProcessors);
+
+        /* Allocate a stack for use when booting the processor */
+        ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
+
+        /* Tell HAL a new CPU is being started */
+        HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
+        KeNumberProcessors++;
+    }
+
+    /* Do Phase 1 HAL Initalization */
+    HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize Basic System Objects and Worker Threads */
+    ExInit3();
+    
+    /* Create the system handle table, assign it to the system process, create
+       the client id table and assign a PID for the system process. This needs
+       to be done before the worker threads are initialized so the system
+       process gets the first PID (4) */
+    PspPostInitSystemProcess();
+
+    /* initialize the worker threads */
+    ExpInitializeWorkerThreads();
+    
+    /* initialize callbacks */
+    ExpInitializeCallbacks();
+    
+    /* Initialize the GDB Stub and break */
+    KdInit1();
+  
+    /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
+    IoInit();
+    
+    /* TBD */
+    PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
+  
+    /* Initialize the Registry (Hives are NOT yet loaded!) */
+    CmInitializeRegistry();
+  
+    /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
+    MmInit3();
+  
+    /* Initialize Cache Views */
+    CcInit();
+  
+    /* Hook System Interrupt for the Debugger */
+    KdInit2();
+    
+    /* Initialize File Locking */
+    FsRtlpInitFileLockingImplementation();
+
+    /* Report all resources used by hal */
+    HalReportResourceUsage();  
+
+    /* Clear the screen to blue */
+    HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+    /* Display version number and copyright/warranty message */
+    HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
+                     KERNEL_VERSION_BUILD_STR")\n");
+    HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
+    HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
+                     "Public License, and you\n");
+    HalDisplayString("are welcome to change it and/or distribute copies of it "
+                     "under certain\n"); 
+    HalDisplayString("conditions. There is absolutely no warranty for "
+                      "ReactOS.\n\n");
+
+    /* Display number of Processors */
+    sprintf(str,
+            "Found %d system processor(s). [%lu MB Memory]\n",
+            KeNumberProcessors,
+            (KeLoaderBlock.MemHigher + 1088)/ 1024);
+    HalDisplayString(str);
+
+    /* Print which Debugger is being used */
+    KdInit3();
+
+    /* Import and create NLS Data and Sections */
+    RtlpInitNls();
+
+    /* Import and Load Registry Hives */
+    CmInitHives(SetupBoot);
+    
+    /* Initialize the time zone information from the registry */
+    ExpInitTimeZoneInfo();
+   
+  /* Enter the kernel debugger before starting up the boot drivers */
+#ifdef KDBG
+    KdbEnter();
+#endif /* KDBG */
+
+    /* Setup Drivers and Root Device Node */
+    IoInit2(BootLog);
+
+    /* Display the boot screen image if not disabled */
+    if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
+    
+    /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
+    IoInit3();
+       
+    /* Initialize the Default Locale */
+    PiInitDefaultLocale();
+    
+    /* Initialize shared user page. Set dos system path, dos device map, etc. */
+    InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
+
+    /* Create 'ReactOSInitDone' event */
+    RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &EventName,
+                               0,
+                               NULL,
+                               NULL);
+    Status = ZwCreateEvent(&InitDoneEventHandle,
+                           EVENT_ALL_ACCESS,
+                           &ObjectAttributes,
+                           SynchronizationEvent,
+                           FALSE);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
+        InitDoneEventHandle = INVALID_HANDLE_VALUE;
+    }
+
+    /* Launch initial process */
+    Status = LdrLoadInitialProcess(&ProcessHandle,
+                                   &ThreadHandle);
+    
+    /* Check for success, Bugcheck if we failed */
+    if (!NT_SUCCESS(Status)) {
+        
+        KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /* Wait on the Completion Event */
+    if (InitDoneEventHandle != INVALID_HANDLE_VALUE) {
+
+        HANDLE Handles[2]; /* Init event, Initial process */
+
+        /* Setup the Handles to wait on */
+        Handles[0] = InitDoneEventHandle;
+        Handles[1] = ProcessHandle;
+
+        /* Wait for the system to be initialized */
+        Timeout.QuadPart = (LONGLONG)-1200000000;  /* 120 second timeout */
+        Status = ZwWaitForMultipleObjects(2,
+                                          Handles,
+                                          WaitAny,
+                                          FALSE,
+                                          &Timeout);
+        if (!NT_SUCCESS(Status)) {
+            
+            DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
+        
+        } else if (Status == STATUS_TIMEOUT) {
+            
+            DPRINT1("WARNING: System not initialized after 120 seconds.\n");
+        
+        } else if (Status == STATUS_WAIT_0 + 1) {
+            
+            /* Crash the system if the initial process was terminated. */
+            KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+
+        /* Disable the Boot Logo */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Signal the Event and close the handle */
+        ZwSetEvent(InitDoneEventHandle, NULL);
+        ZwClose(InitDoneEventHandle);
+    
+    } else {
+        
+        /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Crash the system if the initial process terminates within 5 seconds. */
+        Timeout.QuadPart = (LONGLONG)-50000000;  /* 5 second timeout */
+        Status = ZwWaitForSingleObject(ProcessHandle,
+                                       FALSE,
+                                       &Timeout);
+        
+        /* Check for timeout, crash if the initial process didn't initalize */
+        if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
+    }
+    
+    /* Enable the Clock, close remaining handles */
+    KiTimerSystemAuditing = 1;
+    ZwClose(ThreadHandle);
+    ZwClose(ProcessHandle);
+}
+
 VOID INIT_FUNCTION
 ExInit2(VOID)
 {
@@ -25,7 +666,6 @@ ExInit2(VOID)
 VOID INIT_FUNCTION
 ExInit3 (VOID)
 {
-  ExInitializeWorkerThreads();
   ExpInitializeEventImplementation();
   ExpInitializeEventPairImplementation();
   ExpInitializeMutantImplementation();
@@ -35,28 +675,7 @@ ExInit3 (VOID)
   ExpInitializeProfileImplementation();
   ExpWin32kInit();
   ExpInitUuids();
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
-{
-  if (ProcessorFeature >= PROCESSOR_FEATURE_MAX)
-    return(FALSE);
-
-  return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
-}
-
-
-VOID STDCALL
-ExPostSystemEvent (ULONG       Unknown1,
-                  ULONG        Unknown2,
-                  ULONG        Unknown3)
-{
-  /* doesn't do anything */
+  ExpInitializeHandleTables();
 }
 
 /* EOF */
index ddb57fc..5909597 100644 (file)
@@ -449,7 +449,7 @@ InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
   
   do
   {
-    oldslh = *ListHead;
+    oldslh = *(volatile SLIST_HEADER *)ListHead;
     le = oldslh.Next.Next;
     if(le == NULL)
     {
@@ -481,7 +481,7 @@ InterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
   
   do
   {
-    oldslh = *ListHead;
+    oldslh = *(volatile SLIST_HEADER *)ListHead;
     newslh.Depth = oldslh.Depth + 1;
     newslh.Sequence = oldslh.Sequence + 1;
     ListEntry->Next = oldslh.Next.Next;
index f6a2d4b..d0dc507 100644 (file)
@@ -1,11 +1,12 @@
-/* $Id:$
- * 
+/* 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/mutant.c
- * PURPOSE:         Synchronization primitives
+ * PURPOSE:         Executive Management of Mutants
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu - Fix tab/space mismatching, tiny fixes to query function and
+ *                                 add more debug output.
+ *                  David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 POBJECT_TYPE ExMutantObjectType = NULL;
 
 static GENERIC_MAPPING ExpMutantMapping = {
-       STANDARD_RIGHTS_READ | SYNCHRONIZE | MUTANT_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SYNCHRONIZE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
-       MUTANT_ALL_ACCESS};
+    STANDARD_RIGHTS_READ    | SYNCHRONIZE | MUTANT_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | SYNCHRONIZE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
+    MUTANT_ALL_ACCESS};
 
-static const INFORMATION_CLASS_INFO ExMutantInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* MutantBasicInformation */
+static const INFORMATION_CLASS_INFO ExMutantInfoClass[] = {
+    
+     /* MutantBasicInformation */
+    ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
 };
 
 /* FUNCTIONS *****************************************************************/
 
-
-NTSTATUS STDCALL
-ExpCreateMutant(PVOID ObjectBody,
-               PVOID Parent,
-               PWSTR RemainingPath,
-               POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID STDCALL
+VOID 
+STDCALL
 ExpDeleteMutant(PVOID ObjectBody)
 {
-  DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody);
 
-  KeReleaseMutant((PKMUTANT)ObjectBody,
-                 MUTANT_INCREMENT,
-                 TRUE,
-                 FALSE);
-}
+    DPRINT("ExpDeleteMutant(ObjectBody %x)\n", ObjectBody);
 
+    /* Make sure to release the Mutant */
+    KeReleaseMutant((PKMUTANT)ObjectBody,
+                    MUTANT_INCREMENT,
+                    TRUE,
+                    FALSE);
+}
 
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeMutantImplementation(VOID)
 {
-  ExMutantObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
-  RtlpCreateUnicodeString(&ExMutantObjectType->TypeName, L"Mutant", NonPagedPool);
-
-  ExMutantObjectType->Tag = TAG('M', 'T', 'N', 'T');
-  ExMutantObjectType->PeakObjects = 0;
-  ExMutantObjectType->PeakHandles = 0;
-  ExMutantObjectType->TotalObjects = 0;
-  ExMutantObjectType->TotalHandles = 0;
-  ExMutantObjectType->PagedPoolCharge = 0;
-  ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
-  ExMutantObjectType->Mapping = &ExpMutantMapping;
-  ExMutantObjectType->Dump = NULL;
-  ExMutantObjectType->Open = NULL;
-  ExMutantObjectType->Close = NULL;
-  ExMutantObjectType->Delete = ExpDeleteMutant;
-  ExMutantObjectType->Parse = NULL;
-  ExMutantObjectType->Security = NULL;
-  ExMutantObjectType->QueryName = NULL;
-  ExMutantObjectType->OkayToClose = NULL;
-  ExMutantObjectType->Create = ExpCreateMutant;
-  ExMutantObjectType->DuplicationNotify = NULL;
-
-  ObpCreateTypeObject(ExMutantObjectType);
-}
 
+    /* Allocate the Object Type */
+    ExMutantObjectType = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_TYPE), TAG('M', 't', 'n', 't'));
+
+    /* Create the Object Type */
+    RtlInitUnicodeString(&ExMutantObjectType->TypeName, L"Mutant");
+    ExMutantObjectType->Tag = TAG('M', 't', 'n', 't');
+    ExMutantObjectType->PeakObjects = 0;
+    ExMutantObjectType->PeakHandles = 0;
+    ExMutantObjectType->TotalObjects = 0;
+    ExMutantObjectType->TotalHandles = 0;
+    ExMutantObjectType->PagedPoolCharge = 0;
+    ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
+    ExMutantObjectType->Mapping = &ExpMutantMapping;
+    ExMutantObjectType->Dump = NULL;
+    ExMutantObjectType->Open = NULL;
+    ExMutantObjectType->Close = NULL;
+    ExMutantObjectType->Delete = ExpDeleteMutant;
+    ExMutantObjectType->Parse = NULL;
+    ExMutantObjectType->Security = NULL;
+    ExMutantObjectType->QueryName = NULL;
+    ExMutantObjectType->OkayToClose = NULL;
+    ExMutantObjectType->Create = NULL;
+    ExMutantObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExMutantObjectType);
+}
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateMutant(OUT PHANDLE MutantHandle,
-              IN ACCESS_MASK DesiredAccess,
-              IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-              IN BOOLEAN InitialOwner)
+               IN ACCESS_MASK DesiredAccess,
+               IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+               IN BOOLEAN InitialOwner)
 {
-  KPROCESSOR_MODE PreviousMode;
-  HANDLE hMutant;
-  PKMUTEX Mutant;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    HANDLE hMutant;
+    PKMUTANT Mutant;
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
+    DPRINT("NtCreateMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
   
-  PreviousMode = ExGetPreviousMode();
-
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(MutantHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(MutantHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
     }
-    _SEH_END;
-     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  Status = ObCreateObject(PreviousMode,
-                         ExMutantObjectType,
-                         ObjectAttributes,
-                         PreviousMode,
-                         NULL,
-                         sizeof(KMUTANT),
-                         0,
-                         0,
-                         (PVOID*)&Mutant);
-  if(NT_SUCCESS(Status))
-  {
-    KeInitializeMutant(Mutant,
-                      InitialOwner);
-
-    Status = ObInsertObject((PVOID)Mutant,
-                           NULL,
-                           DesiredAccess,
-                           0,
-                           NULL,
-                           &hMutant);
-    ObDereferenceObject(Mutant);
     
-    if(NT_SUCCESS(Status))
-    {
-      _SEH_TRY
-      {
-        *MutantHandle = hMutant;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
+    /* Create the Mutant Object*/
+    Status = ObCreateObject(PreviousMode,
+                            ExMutantObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KMUTANT),
+                            0,
+                            0,
+                            (PVOID*)&Mutant);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Kernel Mutant */
+        DPRINT("Initializing the Mutant\n");
+        KeInitializeMutant(Mutant, InitialOwner);
+
+        /* Insert the Object */
+        Status = ObInsertObject((PVOID)Mutant,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                &hMutant);
+        ObDereferenceObject(Mutant);
+    
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *MutantHandle = hMutant;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
     }
-  }
 
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenMutant(OUT PHANDLE MutantHandle,
-            IN ACCESS_MASK DesiredAccess,
-            IN POBJECT_ATTRIBUTES ObjectAttributes)
+             IN ACCESS_MASK DesiredAccess,
+             IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-  HANDLE hMutant;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hMutant;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
-
-  DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
-
-  PreviousMode = ExGetPreviousMode();
-
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(MutantHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  Status = ObOpenObjectByName(ObjectAttributes,
-                             ExMutantObjectType,
-                             NULL,
-                             PreviousMode,
-                             DesiredAccess,
-                             NULL,
-                             &hMutant);
-
-  if(NT_SUCCESS(Status))
-  {
-    _SEH_TRY
-    {
-      *MutantHandle = hMutant;
+    PAGED_CODE();
+    DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(MutantHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
     }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExMutantObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hMutant);
+
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *MutantHandle = hMutant;
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
     }
-    _SEH_END;
-  }
 
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtQueryMutant(IN HANDLE MutantHandle,
-             IN MUTANT_INFORMATION_CLASS MutantInformationClass,
-             OUT PVOID MutantInformation,
-             IN ULONG MutantInformationLength,
-             OUT PULONG ResultLength  OPTIONAL)
+              IN MUTANT_INFORMATION_CLASS MutantInformationClass,
+              OUT PVOID MutantInformation,
+              IN ULONG MutantInformationLength,
+              OUT PULONG ResultLength  OPTIONAL)
 {
-   PKMUTANT Mutant;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   DefaultQueryInfoBufferCheck(MutantInformationClass,
-                               ExMutantInfoClass,
-                               MutantInformation,
-                               MutantInformationLength,
-                               ResultLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(MutantHandle,
-                                     MUTANT_QUERY_STATE,
-                                     ExMutantObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Mutant,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(MutantInformationClass)
-     {
-       case MutantBasicInformation:
-       {
-         PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
-
-         _SEH_TRY
-         {
-           BasicInfo->Count = KeReadStateMutant(Mutant);
-           BasicInfo->Owned = (Mutant->OwnerThread != NULL);
-           BasicInfo->Abandoned = Mutant->Abandoned;
-
-           if(ResultLength != NULL)
-           {
-             *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Mutant);
-   }
-
-   return Status;
+    PKMUTANT Mutant;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
+    
+    PAGED_CODE();
+    
+    /* Check buffers and parameters */
+    DefaultQueryInfoBufferCheck(MutantInformationClass,
+                                ExMutantInfoClass,
+                                MutantInformation,
+                                MutantInformationLength,
+                                ResultLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        DPRINT("NtQueryMutant() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(MutantHandle,
+                                       MUTANT_QUERY_STATE,
+                                       ExMutantObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Mutant,
+                                       NULL);
+    /* Check for Status */
+    if(NT_SUCCESS(Status)) {
+
+         _SEH_TRY {
+             
+            /* Fill out the Basic Information Requested */
+            DPRINT("Returning Mutant Information\n");
+            BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
+            BasicInfo->OwnedByCaller = (Mutant->OwnerThread == KeGetCurrentThread());
+            BasicInfo->AbandonedState = Mutant->Abandoned;
+
+            /* Return the Result Length if requested */
+           if(ResultLength) *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        /* Release the Object */
+        ObDereferenceObject(Mutant);
+    }
+    
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtReleaseMutant(IN HANDLE MutantHandle,
-               IN PLONG PreviousCount  OPTIONAL)
+                IN PLONG PreviousCount  OPTIONAL)
 {
-   PKMUTANT Mutant;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKMUTANT Mutant;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
-         MutantHandle, PreviousCount);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousCount != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousCount,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();
+    
+    PreviousMode = ExGetPreviousMode();
+    
+    DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n", 
+            MutantHandle, 
+            PreviousCount);
+
+    /* Check Output Safety */
+    if(PreviousMode != KernelMode && PreviousCount) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousCount,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObReferenceObjectByHandle(MutantHandle,
-                                     MUTANT_QUERY_STATE,
-                                     ExMutantObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Mutant,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, 0, FALSE);
-     ObDereferenceObject(Mutant);
-
-     if(PreviousCount != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousCount = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
-
-   return Status;
+        if(!NT_SUCCESS(Status)) return Status;
+    } 
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(MutantHandle,
+                                       MUTANT_QUERY_STATE,
+                                       ExMutantObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Mutant,
+                                       NULL);
+    
+    /* Check for Success and release if such */
+    if(NT_SUCCESS(Status)) {
+        
+        LONG Prev = 0;
+        
+        /* release the mutant. doing so might raise an exception which we're
+           required to catch! */
+        _SEH_TRY {
+
+            Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, FALSE, FALSE);
+
+        } _SEH_HANDLE {
+
+            Status = _SEH_GetExceptionCode();
+
+        } _SEH_END;
+        
+        ObDereferenceObject(Mutant);
+
+        if(NT_SUCCESS(Status)) {
+
+            /* Return it */
+            if(PreviousCount) {
+
+                _SEH_TRY {
+
+                    *PreviousCount = Prev;
+
+                } _SEH_HANDLE {
+                
+                    Status = _SEH_GetExceptionCode();
+
+                } _SEH_END;
+            }
+        }
+    }
+
+    /* Return Status */
+    return Status;
 }
 
 /* EOF */
diff --git a/reactos/ntoskrnl/ex/napi.c b/reactos/ntoskrnl/ex/napi.c
deleted file mode 100644 (file)
index 76a82a4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $Id$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ex/napi.c
- * PURPOSE:         Native API support routines
- * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <ntdll/napi.h>
-#include <internal/debug.h>
-
-/* GLOBALS ******************************************************************/
-
-SSDT_ENTRY
-__declspec(dllexport)
-KeServiceDescriptorTable[SSDT_MAX_ENTRIES] =
-{
-       { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
-       { NULL,    NULL,   0,   NULL   },
-       { NULL,    NULL,   0,   NULL   },
-       { NULL,    NULL,   0,   NULL   }
-};
-
-SSDT_ENTRY 
-KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] =
-{
-       { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
-       { NULL,    NULL,   0,   NULL   },
-       { NULL,    NULL,   0,   NULL   },
-       { NULL,    NULL,   0,   NULL   }
-};
index 863add8..cb9c86b 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id:$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/nt/profile.c
- * PURPOSE:         Support for profiling
+ * FILE:            ntoskrnl/ex/profile.c
+ * PURPOSE:         Support for Executive Profile Objects
  * 
- * PROGRAMMERS:     No programmer listed.
+ * PROGRAMMERS:     Alex Ionescu
  */
 
 /* INCLUDES *****************************************************************/
 #include <ntoskrnl.h>
 #include <internal/debug.h>
 
-/* TYPES ********************************************************************/
+/* This structure is a *GUESS* -- Alex */
+typedef struct _EPROFILE {
+    PEPROCESS Process;
+    PVOID ImageBase;
+    ULONG ImageSize;
+    ULONG BucketSize;
+    PVOID Buffer;
+    ULONG BufferSize;
+    PKPROFILE KeProfile;
+    KPROFILE_SOURCE ProfileSource;
+    KAFFINITY Affinity;
+    PMDL Mdl;
+    PVOID LockedBuffer;
+} EPROFILE, *PEPROFILE;
 
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE EXPORTED ExProfileObjectType = NULL;
 
-static GENERIC_MAPPING ExpProfileMapping = {
-       STANDARD_RIGHTS_READ,
-       STANDARD_RIGHTS_WRITE,
-       STANDARD_RIGHTS_EXECUTE,
-       STANDARD_RIGHTS_ALL};
-
-/*
- * Size of the profile hash table.
- */
-#define PROFILE_HASH_TABLE_SIZE      (32)
-
-/*
- * Table of lists of per-process profiling data structures hashed by PID.
- */
-LIST_ENTRY ProcessProfileListHashTable[PROFILE_HASH_TABLE_SIZE];
-
-/*
- * Head of the list of profile data structures for the kernel.
- */
-LIST_ENTRY SystemProfileList;
-
-/*
- * Lock that protects the profiling data structures.
- */
-KSPIN_LOCK ProfileListLock;
+static KMUTEX ExpProfileMutex;
 
-/*
- * Timer interrupts happen before we have initialized the profiling
- * data structures so just ignore them before that.
- */
-BOOLEAN ProfileInitDone = FALSE;
+#define PROFILE_CONTROL 1
 
-VOID INIT_FUNCTION
-ExpInitializeProfileImplementation(VOID)
+static GENERIC_MAPPING ExpProfileMapping = {
+    STANDARD_RIGHTS_READ    | PROFILE_CONTROL,
+    STANDARD_RIGHTS_WRITE   | PROFILE_CONTROL,
+    STANDARD_RIGHTS_EXECUTE | PROFILE_CONTROL,
+    STANDARD_RIGHTS_ALL};
+
+VOID 
+STDCALL
+ExpDeleteProfile(PVOID ObjectBody)
 {
-  ULONG i;
+    PEPROFILE Profile;
 
-  InitializeListHead(&SystemProfileList);
-  
-  for (i = 0; i < PROFILE_HASH_TABLE_SIZE; i++)
-    {
-      InitializeListHead(&ProcessProfileListHashTable[i]);
+    /* Typecast the Object */
+    Profile = (PEPROFILE)ObjectBody;
+    
+    /* Check if there if the Profile was started */
+    if (Profile->LockedBuffer) {
+        
+        /* Stop the Profile */
+        KeStopProfile(Profile->KeProfile);
+    
+        /* Unmap the Locked Buffer */
+        MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
+        MmUnlockPages(Profile->Mdl);
+        ExFreePool(Profile->Mdl);
     }
-
-  KeInitializeSpinLock(&ProfileListLock);
-  ProfileInitDone = TRUE;
-
-  ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-  
-  RtlpCreateUnicodeString(&ExProfileObjectType->TypeName, L"Profile", NonPagedPool);
   
-  ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F');
-  ExProfileObjectType->PeakObjects = 0;
-  ExProfileObjectType->PeakHandles = 0;
-  ExProfileObjectType->TotalObjects = 0;
-  ExProfileObjectType->TotalHandles = 0;
-  ExProfileObjectType->PagedPoolCharge = 0;
-  ExProfileObjectType->NonpagedPoolCharge = sizeof(KPROFILE);
-  ExProfileObjectType->Mapping = &ExpProfileMapping;
-  ExProfileObjectType->Dump = NULL;
-  ExProfileObjectType->Open = NULL;
-  ExProfileObjectType->Close = NULL;
-  ExProfileObjectType->Delete = KiDeleteProfile;
-  ExProfileObjectType->Parse = NULL;
-  ExProfileObjectType->Security = NULL;
-  ExProfileObjectType->QueryName = NULL;
-  ExProfileObjectType->OkayToClose = NULL;
-  ExProfileObjectType->Create = NULL;
+    /* Check if a Process is associated */
+    if (Profile->Process != NULL) {
+        
+        /* Dereference it */
+        ObDereferenceObject(Profile->Process);
+        Profile->Process = NULL;
+    }
+}
 
-  ObpCreateTypeObject(ExProfileObjectType);
+VOID 
+INIT_FUNCTION
+ExpInitializeProfileImplementation(VOID)
+{
+    /* Initialize the Mutex to lock the States */
+    KeInitializeMutex(&ExpProfileMutex, 0x40);
+    
+    /* Create the Object Type */
+    ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlInitUnicodeString(&ExProfileObjectType->TypeName, L"Profile");
+    ExProfileObjectType->Tag = TAG('P', 'R', 'O', 'F');
+    ExProfileObjectType->PeakObjects = 0;
+    ExProfileObjectType->PeakHandles = 0;
+    ExProfileObjectType->TotalObjects = 0;
+    ExProfileObjectType->TotalHandles = 0;
+    ExProfileObjectType->PagedPoolCharge = 0;
+    ExProfileObjectType->NonpagedPoolCharge = sizeof(EPROFILE);
+    ExProfileObjectType->Mapping = &ExpProfileMapping;
+    ExProfileObjectType->Dump = NULL;
+    ExProfileObjectType->Open = NULL;
+    ExProfileObjectType->Close = NULL;
+    ExProfileObjectType->Delete = ExpDeleteProfile;
+    ExProfileObjectType->Parse = NULL;
+    ExProfileObjectType->Security = NULL;
+    ExProfileObjectType->QueryName = NULL;
+    ExProfileObjectType->OkayToClose = NULL;
+    ExProfileObjectType->Create = NULL;
+    ObpCreateTypeObject(ExProfileObjectType);
 }
 
-NTSTATUS STDCALL 
+NTSTATUS 
+STDCALL 
 NtCreateProfile(OUT PHANDLE ProfileHandle,
-               IN HANDLE Process  OPTIONAL,
-               IN PVOID ImageBase, 
-               IN ULONG ImageSize, 
-               IN ULONG BucketSize,
-               IN PVOID Buffer,
-               IN ULONG BufferSize,
-               IN KPROFILE_SOURCE ProfileSource,
-               IN KAFFINITY Affinity)
+                IN HANDLE Process OPTIONAL,
+                IN PVOID ImageBase, 
+                IN ULONG ImageSize, 
+                IN ULONG BucketSize,
+                IN PVOID Buffer,
+                IN ULONG BufferSize,
+                IN KPROFILE_SOURCE ProfileSource,
+                IN KAFFINITY Affinity)
 {
-  HANDLE hProfile;
-  PKPROFILE Profile;
-  PEPROCESS pProcess;
-  KPROCESSOR_MODE PreviousMode;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(BufferSize == 0)
-  {
-    return STATUS_INVALID_PARAMETER_7;
-  }
+    HANDLE hProfile;
+    PEPROFILE Profile;
+    PEPROCESS pProcess;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(ProfileHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-      ProbeForWrite(Buffer,
-                    BufferSize,
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    PAGED_CODE();
+
+    /* Easy way out */
+    if(BufferSize == 0) return STATUS_INVALID_PARAMETER_7;
+
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(ProfileHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+            
+            ProbeForWrite(Buffer,
+                          BufferSize,
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  /*
-   * Reference the associated process
-   */
-  if (Process != NULL)
-    {
-      Status = ObReferenceObjectByHandle(Process,
-                                        PROCESS_QUERY_INFORMATION,
-                                        PsProcessType,
-                                        PreviousMode,
-                                        (PVOID*)&pProcess,
-                                        NULL);
-      if (!NT_SUCCESS(Status))
-       {
-         return(Status);
-       }
-    }
-  else
-    {
-      pProcess = NULL;
-      if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege,
-                                 PreviousMode))
-      {
-        DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
-        return STATUS_PRIVILEGE_NOT_HELD;
-      }
+        if(!NT_SUCCESS(Status)) return Status;
     }
 
-  /*
-   * Check the parameters
-   */
-  if ((pProcess == NULL && ImageBase < (PVOID)KERNEL_BASE) ||
-      (pProcess != NULL && ImageBase >= (PVOID)KERNEL_BASE))
-    {
-      return(STATUS_INVALID_PARAMETER_3);
-    }
-  if (((ImageSize >> BucketSize) * 4) >= BufferSize)
-    {
-      return(STATUS_BUFFER_TOO_SMALL);
-    }
-  if (ProfileSource != ProfileTime)
-    {
-      return(STATUS_INVALID_PARAMETER_9);
-    }
-  if (Affinity != 0)
-    {
-      return(STATUS_INVALID_PARAMETER_10);
+    /* Check if a process was specified */
+    if (Process) {
+        
+        /* Reference it */
+        Status = ObReferenceObjectByHandle(Process,
+                                           PROCESS_QUERY_INFORMATION,
+                                           PsProcessType,
+                                           PreviousMode,
+                                           (PVOID*)&pProcess,
+                                           NULL);
+        if (!NT_SUCCESS(Status)) return(Status);
+        
+    } else {
+        
+        /* No process was specified, which means a System-Wide Profile */
+        pProcess = NULL;
+        
+        /* For this, we need to check the Privilege */
+        if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege, PreviousMode)) {
+            
+            DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
+            return STATUS_PRIVILEGE_NOT_HELD;
+        }
     }
 
-  /*
-   * Create the object
-   */
-  InitializeObjectAttributes(&ObjectAttributes,
+    /* Create the object */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               NULL,
+                               0,
+                               NULL,
+                               NULL);
+    Status = ObCreateObject(KernelMode,
+                            ExProfileObjectType,
+                            &ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(EPROFILE),
+                            0,
+                            0,
+                            (PVOID*)&Profile);
+    if (!NT_SUCCESS(Status)) return(Status);
+
+    /* Initialize it */
+    Profile->ImageBase = ImageBase;
+    Profile->ImageSize = ImageSize;
+    Profile->Buffer = Buffer;
+    Profile->BufferSize = BufferSize;
+    Profile->BucketSize = BucketSize;
+    Profile->LockedBuffer = NULL;
+    Profile->Affinity = Affinity;
+    Profile->Process = pProcess;
+    
+    /* Insert into the Object Tree */
+    Status = ObInsertObject ((PVOID)Profile,
                              NULL,
+                             PROFILE_CONTROL,
                              0,
                              NULL,
-                             NULL);
-
-  Status = ObCreateObject(KernelMode,
-                         ExProfileObjectType,
-                         &ObjectAttributes,
-                         PreviousMode,
-                         NULL,
-                         sizeof(KPROFILE),
-                         0,
-                         0,
-                         (PVOID*)&Profile);
-  if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-  /*
-   * Initialize it
-   */
-  Profile->Base = ImageBase;
-  Profile->Size = ImageSize;
-  Profile->BucketShift = BucketSize;
-  Profile->BufferMdl = MmCreateMdl(NULL, Buffer, BufferSize);
-  if(Profile->BufferMdl == NULL) {
-       DPRINT("MmCreateMdl: Out of memory!");
-       ObDereferenceObject (Profile);
-       return(STATUS_NO_MEMORY);
-  }  
-  MmProbeAndLockPages(Profile->BufferMdl, UserMode, IoWriteAccess);
-  Profile->Buffer = MmGetSystemAddressForMdl(Profile->BufferMdl);
-  Profile->BufferSize = BufferSize;
-  Profile->ProcessorMask = Affinity;
-  Profile->Started = FALSE;
-  Profile->Process = pProcess;
-
-  /*
-   * Insert the profile into the profile list data structures
-   */
-  KiInsertProfile(Profile);
-
-  Status = ObInsertObject ((PVOID)Profile,
-                          NULL,
-                          STANDARD_RIGHTS_ALL,
-                          0,
-                          NULL,
-                          &hProfile);
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject (Profile);
-      return Status;
+                             &hProfile);
+    ObDereferenceObject(Profile);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Dereference Process on failure */
+        if (pProcess) ObDereferenceObject(pProcess);
+        return Status;
     }
+    
+    /* Copy the created handle back to the caller*/
+    _SEH_TRY {
+        
+        *ProfileHandle = hProfile;
+        
+    } _SEH_HANDLE {
+        
+        Status = _SEH_GetExceptionCode();
+    } _SEH_END;
 
-  /*
-   * Copy the created handle back to the caller
-   */
-  _SEH_TRY
-  {
-    *ProfileHandle = hProfile;
-  }
-  _SEH_HANDLE
-  {
-    Status = _SEH_GetExceptionCode();
-  }
-  _SEH_END;
-
-  ObDereferenceObject(Profile);
-
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
-NTSTATUS STDCALL 
-NtQueryIntervalProfile(IN  KPROFILE_SOURCE ProfileSource,
-                      OUT PULONG Interval)
+NTSTATUS 
+STDCALL
+NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
+                          OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
 {
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(Interval,
-                    sizeof(ULONG),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    LARGE_INTEGER PerfFrequency;
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PerformanceCounter,
+                          sizeof(LARGE_INTEGER),
+                          sizeof(ULONG));
+            
+            ProbeForWrite(PerformanceFrequency,
+                          sizeof(LARGE_INTEGER),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
+        if(!NT_SUCCESS(Status)) return Status;
     }
-  }
-
-  if (ProfileSource == ProfileTime)
-    {
-      ULONG ReturnInterval;
 
-      /* FIXME: What units does this use, for now nanoseconds */
-      ReturnInterval = 100;
-
-      _SEH_TRY
-      {
-        *Interval = ReturnInterval;
-      }
-      _SEH_HANDLE
-      {
+    _SEH_TRY {
+        
+        /* Query the Kernel */
+        *PerformanceCounter = KeQueryPerformanceCounter(&PerfFrequency);
+        
+        /* Return Frequency if requested */
+        if(PerformanceFrequency) {
+            
+            *PerformanceFrequency = PerfFrequency;
+        }
+    } _SEH_HANDLE {
+        
         Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
-      
-      return Status;
-    }
-  return STATUS_INVALID_PARAMETER_2;
-}
+    
+    } _SEH_END;
 
-NTSTATUS STDCALL 
-NtSetIntervalProfile(IN ULONG Interval,
-                    IN KPROFILE_SOURCE Source)
-{
-  return(STATUS_NOT_IMPLEMENTED);
+    return Status;
 }
 
-NTSTATUS STDCALL 
+NTSTATUS 
+STDCALL 
 NtStartProfile(IN HANDLE ProfileHandle)
 {
-  PKPROFILE Profile;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
-  
-  PAGED_CODE();
+    PEPROFILE Profile;
+    PKPROFILE KeProfile;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PVOID TempLockedBuffer;
+    NTSTATUS Status;
   
-  PreviousMode = ExGetPreviousMode();
-
-  Status = ObReferenceObjectByHandle(ProfileHandle,
-                                    STANDARD_RIGHTS_ALL,
-                                    ExProfileObjectType,
-                                    PreviousMode,
-                                    (PVOID*)&Profile,
-                                    NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
+    PAGED_CODE();
+
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(ProfileHandle,
+                                       PROFILE_CONTROL,
+                                       ExProfileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Profile,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return(Status);
+    
+    /* To avoid a Race, wait on the Mutex */
+    KeWaitForSingleObject(&ExpProfileMutex, 
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          NULL);
+    
+    /* The Profile can still be enabled though, so handle that */
+    if (Profile->LockedBuffer) {
+    
+        /* Release our lock, dereference and return */
+        KeReleaseMutex(&ExpProfileMutex, FALSE);
+        ObDereferenceObject(Profile);
+        return STATUS_PROFILING_NOT_STOPPED;
     }
-  Profile->Started = TRUE;
-  ObDereferenceObject(Profile);
-  return(STATUS_SUCCESS);
+    
+    /* Allocate a Kernel Profile Object. */
+    KeProfile = ExAllocatePoolWithTag(NonPagedPool, 
+                                      sizeof(EPROFILE),
+                                      TAG('P', 'r', 'o', 'f'));
+   
+    /* Allocate the Mdl Structure */
+    Profile->Mdl = MmCreateMdl(NULL, Profile->Buffer, Profile->BufferSize);
+    
+    /* Probe and Lock for Write Access */
+    MmProbeAndLockPages(Profile->Mdl, PreviousMode, IoWriteAccess);
+    
+    /* Map the pages */
+    TempLockedBuffer = MmMapLockedPages(Profile->Mdl, KernelMode);
+    
+    /* Initialize the Kernel Profile Object */
+    Profile->KeProfile = KeProfile;
+    KeInitializeProfile(KeProfile,
+                        (PKPROCESS)Profile->Process,
+                        Profile->ImageBase,
+                        Profile->ImageSize,
+                        Profile->BucketSize,
+                        Profile->ProfileSource,
+                        Profile->Affinity);
+    
+    /* Start the Profiling */
+    KeStartProfile(KeProfile, TempLockedBuffer);
+    
+    /* Now it's safe to save this */
+    Profile->LockedBuffer = TempLockedBuffer;
+    
+    /* Release mutex, dereference and return */
+    KeReleaseMutex(&ExpProfileMutex, FALSE);
+    ObDereferenceObject(Profile);
+    return STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL 
+NTSTATUS
+STDCALL 
 NtStopProfile(IN HANDLE ProfileHandle)
 {
-  PKPROFILE Profile;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
+    PEPROFILE Profile;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
   
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-
-  Status = ObReferenceObjectByHandle(ProfileHandle,
-                                    STANDARD_RIGHTS_ALL,
-                                    ExProfileObjectType,
-                                    PreviousMode,
-                                    (PVOID*)&Profile,
-                                    NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
+    PAGED_CODE();
+
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(ProfileHandle,
+                                       PROFILE_CONTROL,
+                                       ExProfileObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Profile,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) return(Status);
+    
+    /* Get the Mutex */
+    KeWaitForSingleObject(&ExpProfileMutex, 
+                          Executive,
+                          KernelMode,
+                          FALSE,
+                          NULL);
+    
+    /* Make sure the Profile Object is really Started */
+    if (!Profile->LockedBuffer) {
+    
+        Status = STATUS_PROFILING_NOT_STARTED;
+        goto Exit;
     }
-  Profile->Started = FALSE;
-  ObDereferenceObject(Profile);
-  return(STATUS_SUCCESS);
+    
+    /* Stop the Profile */
+    KeStopProfile(Profile->KeProfile);
+    
+    /* Unlock the Buffer */
+    MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
+    MmUnlockPages(Profile->Mdl);
+    ExFreePool(Profile->KeProfile);
+    
+    /* Clear the Locked Buffer pointer, meaning the Object is Stopped */
+    Profile->LockedBuffer = NULL;
+    
+Exit:
+    /* Release Mutex, Dereference and Return */
+    KeReleaseMutex(&ExpProfileMutex, FALSE);
+    ObDereferenceObject(Profile);
+    return Status;
 }
 
+NTSTATUS 
+STDCALL 
+NtQueryIntervalProfile(IN  KPROFILE_SOURCE ProfileSource,
+                       OUT PULONG Interval)
+{
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    ULONG ReturnInterval;
+    NTSTATUS Status = STATUS_SUCCESS;
+  
+    PAGED_CODE();
+    
+    /* Check the Parameters for validity */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(Interval,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+    
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+  
+    /* Query the Interval */
+    ReturnInterval = KeQueryIntervalProfile(ProfileSource);
+
+    /* Return the data */
+    _SEH_TRY  {
+        
+        *Interval = ReturnInterval;
+        
+    } _SEH_HANDLE {
+        
+        Status = _SEH_GetExceptionCode();
+        
+    } _SEH_END;
+    
+    /* Return Success */  
+    return STATUS_SUCCESS;
+}
 
+NTSTATUS 
+STDCALL 
+NtSetIntervalProfile(IN ULONG Interval,
+                     IN KPROFILE_SOURCE Source)
+{
+    /* Let the Kernel do the job */
+    KeSetIntervalProfile(Interval, Source);
+    
+    /* Nothing can go wrong */
+    return STATUS_SUCCESS;
+}
index baf8a38..580d9bb 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/rundown.c
  * PURPOSE:         Rundown Protection Functions
  * 
- * PROGRAMMERS:     No programmer listed.
+ * PROGRAMMERS:     Alex Ionescu & Thomas Weidenmueller - Implementation
  */
 
 /* INCLUDES *****************************************************************/
index 274ce8a..2ec3d0e 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id: ntsem.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/sem.c
  * PURPOSE:         Synchronization primitives
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes.
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES *****************************************************************/
 POBJECT_TYPE ExSemaphoreObjectType;
 
 static GENERIC_MAPPING ExSemaphoreMapping = {
-       STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
-       SEMAPHORE_ALL_ACCESS};
-
-static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SemaphoreBasicInformation */
+    STANDARD_RIGHTS_READ    | SEMAPHORE_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | SEMAPHORE_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
+    SEMAPHORE_ALL_ACCESS};
+
+static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
+    
+     /* SemaphoreBasicInformation */
+    ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
 };
 
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-ExpCreateSemaphore(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateSemaphore(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeSemaphoreImplementation(VOID)
 {
-   ExSemaphoreObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExSemaphoreObjectType->TypeName, L"Semaphore", NonPagedPool);
-   
-   ExSemaphoreObjectType->Tag = TAG('S', 'E', 'M', 'T');
-   ExSemaphoreObjectType->PeakObjects = 0;
-   ExSemaphoreObjectType->PeakHandles = 0;
-   ExSemaphoreObjectType->TotalObjects = 0;
-   ExSemaphoreObjectType->TotalHandles = 0;
-   ExSemaphoreObjectType->PagedPoolCharge = 0;
-   ExSemaphoreObjectType->NonpagedPoolCharge = sizeof(KSEMAPHORE);
-   ExSemaphoreObjectType->Mapping = &ExSemaphoreMapping;
-   ExSemaphoreObjectType->Dump = NULL;
-   ExSemaphoreObjectType->Open = NULL;
-   ExSemaphoreObjectType->Close = NULL;
-   ExSemaphoreObjectType->Delete = NULL;
-   ExSemaphoreObjectType->Parse = NULL;
-   ExSemaphoreObjectType->Security = NULL;
-   ExSemaphoreObjectType->QueryName = NULL;
-   ExSemaphoreObjectType->OkayToClose = NULL;
-   ExSemaphoreObjectType->Create = ExpCreateSemaphore;
-   ExSemaphoreObjectType->DuplicationNotify = NULL;
-
-   ObpCreateTypeObject(ExSemaphoreObjectType);
+    
+    /* Create the Semaphore Object */
+    ExSemaphoreObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+    RtlInitUnicodeString(&ExSemaphoreObjectType->TypeName, L"Semaphore");
+    ExSemaphoreObjectType->Tag = TAG('S', 'E', 'M', 'T');
+    ExSemaphoreObjectType->PeakObjects = 0;
+    ExSemaphoreObjectType->PeakHandles = 0;
+    ExSemaphoreObjectType->TotalObjects = 0;
+    ExSemaphoreObjectType->TotalHandles = 0;
+    ExSemaphoreObjectType->PagedPoolCharge = 0;
+    ExSemaphoreObjectType->NonpagedPoolCharge = sizeof(KSEMAPHORE);
+    ExSemaphoreObjectType->Mapping = &ExSemaphoreMapping;
+    ExSemaphoreObjectType->Dump = NULL;
+    ExSemaphoreObjectType->Open = NULL;
+    ExSemaphoreObjectType->Close = NULL;
+    ExSemaphoreObjectType->Delete = NULL;
+    ExSemaphoreObjectType->Parse = NULL;
+    ExSemaphoreObjectType->Security = NULL;
+    ExSemaphoreObjectType->QueryName = NULL;
+    ExSemaphoreObjectType->OkayToClose = NULL;
+    ExSemaphoreObjectType->Create = NULL;
+    ExSemaphoreObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExSemaphoreObjectType);
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-                 IN LONG InitialCount,
-                 IN LONG MaximumCount)
+                  IN ACCESS_MASK DesiredAccess,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                  IN LONG InitialCount,
+                  IN LONG MaximumCount)
 {
-   PKSEMAPHORE Semaphore;
-   HANDLE hSemaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKSEMAPHORE Semaphore;
+    HANDLE hSemaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(SemaphoreHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObCreateObject(PreviousMode,
-                          ExSemaphoreObjectType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(KSEMAPHORE),
-                          0,
-                          0,
-                          (PVOID*)&Semaphore);
-   if (NT_SUCCESS(Status))
-   {
-     KeInitializeSemaphore(Semaphore,
-                          InitialCount,
-                          MaximumCount);
-
-     Status = ObInsertObject ((PVOID)Semaphore,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hSemaphore);
-
-     ObDereferenceObject(Semaphore);
+    PAGED_CODE();
+
+    /* Check Output Safety */
+    if(PreviousMode != KernelMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(SemaphoreHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Make sure the counts make sense */
+    if (!MaximumCount || InitialCount < 0 || InitialCount > MaximumCount) {
+    
+        DPRINT("Invalid Count Data!\n");
+        return STATUS_INVALID_PARAMETER;
+    }
 
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *SemaphoreHandle = hSemaphore;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+    /* Create the Semaphore Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExSemaphoreObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KSEMAPHORE),
+                            0,
+                            0,
+                            (PVOID*)&Semaphore);
+    
+    /* Check for Success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Initialize it */
+        KeInitializeSemaphore(Semaphore,
+                              InitialCount,
+                              MaximumCount);
+        
+        /* Insert it into the Object Tree */
+        Status = ObInsertObject((PVOID)Semaphore,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                &hSemaphore);
+        ObDereferenceObject(Semaphore);
+
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *SemaphoreHandle = hSemaphore;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
 
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
-               IN ACCESS_MASK  DesiredAccess,
-               IN POBJECT_ATTRIBUTES ObjectAttributes)
+                IN ACCESS_MASK DesiredAccess,
+                IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hSemaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hSemaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(SemaphoreHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(SemaphoreHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExSemaphoreObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hSemaphore);
+    
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *SemaphoreHandle = hSemaphore;
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
 
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-   
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExSemaphoreObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hSemaphore);
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *SemaphoreHandle = hSemaphore;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
-   
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
-                IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
-                OUT PVOID SemaphoreInformation,
-                IN ULONG SemaphoreInformationLength,
-                OUT PULONG ReturnLength  OPTIONAL)
+                 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
+                 OUT PVOID SemaphoreInformation,
+                 IN ULONG SemaphoreInformationLength,
+                 OUT PULONG ReturnLength  OPTIONAL)
 {
-   PKSEMAPHORE Semaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKSEMAPHORE Semaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    /* Check buffers and class validity */
+    DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
+                                ExSemaphoreInfoClass,
+                                SemaphoreInformation,
+                                SemaphoreInformationLength,
+                                ReturnLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        /* Invalid buffers */
+        DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
-                               ExSemaphoreInfoClass,
-                               SemaphoreInformation,
-                               SemaphoreInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(SemaphoreHandle,
-                                     SEMAPHORE_QUERY_STATE,
-                                     ExSemaphoreObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Semaphore,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(SemaphoreInformationClass)
-     {
-       case SemaphoreBasicInformation:
-       {
-         PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
-
-         _SEH_TRY
-         {
-           BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
-           BasicInfo->MaximumCount = Semaphore->Limit;
-
-           if(ReturnLength != NULL)
-           {
-             *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Semaphore);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(SemaphoreHandle,
+                                       SEMAPHORE_QUERY_STATE,
+                                       ExSemaphoreObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Semaphore,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+   
+        _SEH_TRY {
+            
+            PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
+            
+            /* Return the basic information */
+            BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
+            BasicInfo->MaximumCount = Semaphore->Limit;
+
+            /* Return length */
+            if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+     
+        /* Dereference the Object */
+        ObDereferenceObject(Semaphore);
    }
 
+   /* Return status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
-                  IN LONG ReleaseCount,
-                  OUT PLONG PreviousCount  OPTIONAL)
+                   IN LONG ReleaseCount,
+                   OUT PLONG PreviousCount  OPTIONAL)
 {
-   KPROCESSOR_MODE PreviousMode;
-   PKSEMAPHORE Semaphore;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PKSEMAPHORE Semaphore;
+    NTSTATUS Status = STATUS_SUCCESS; 
    
-   if(PreviousCount != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousCount,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+    
+    /* Check buffer validity */
+    if(PreviousCount != NULL && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousCount,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Make sure count makes sense */
+    if (!ReleaseCount) {
+    
+        DPRINT("Invalid Release Count\n");
+        return STATUS_INVALID_PARAMETER;
+    }
    
-   Status = ObReferenceObjectByHandle(SemaphoreHandle,
-                                     SEMAPHORE_MODIFY_STATE,
-                                     ExSemaphoreObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Semaphore,
-                                     NULL);
-   if (NT_SUCCESS(Status))
-   {
-     LONG PrevCount = KeReleaseSemaphore(Semaphore,
-                                         IO_NO_INCREMENT,
-                                         ReleaseCount,
-                                         FALSE);
-     ObDereferenceObject(Semaphore);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(SemaphoreHandle,
+                                       SEMAPHORE_MODIFY_STATE,
+                                       ExSemaphoreObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Semaphore,
+                                       NULL);
+    
+    /* Check for success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Release the semaphore */
+        LONG PrevCount = KeReleaseSemaphore(Semaphore,
+                                            IO_NO_INCREMENT,
+                                            ReleaseCount,
+                                            FALSE);
+        ObDereferenceObject(Semaphore);
      
-     if(PreviousCount != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousCount = PrevCount;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+        /* Return it */        
+        if(PreviousCount) {
+            
+            _SEH_TRY {
+                
+                *PreviousCount = PrevCount;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
+    }
 
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
 /* EOF */
diff --git a/reactos/ntoskrnl/ex/stree.c b/reactos/ntoskrnl/ex/stree.c
deleted file mode 100644 (file)
index f889d37..0000000
+++ /dev/null
@@ -1,1339 +0,0 @@
-/* $Id$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ex/stree.c
- * PURPOSE:         Splay tree support
- * 
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- * 
- * NOTES:           Based on a splay tree implementation by
- *                  Daniel Stenberg <Daniel.Stenberg@sth.frontec.se>
- *                  http://www.contactor.se/~dast/stuff/dsplay-1.2.tar.gz
- */
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* DATA **********************************************************************/
-
-#define WEIGHT 1
-#undef UNIQUE_KEYS
-
-typedef struct _SPLAY_TREE_NODE
-{
-  /* Children on this branch that has smaller keys than this node */
-  struct _SPLAY_TREE_NODE  * SmallerChild;
-
-  /* Children on this branch that has larger keys than this node */
-  struct _SPLAY_TREE_NODE  * LargerChild;
-
-  /* Points to a node with identical key */
-  struct _SPLAY_TREE_NODE  * Same;
-
-  /* Key of this node */
-  PVOID  Key;
-
-  /* Value of this node */
-  PVOID  Value;
-
-  /* The number of nodes rooted here */
-  LONG  Weight;
-} SPLAY_TREE_NODE, *PSPLAY_TREE_NODE;
-
-typedef struct _TRAVERSE_CONTEXT {
-  PTRAVERSE_ROUTINE Routine;
-  PVOID Context;
-} TRAVERSE_CONTEXT, *PTRAVERSE_CONTEXT;
-
-#define SPLAY_INDEX 0
-#define SEARCH_INDEX 1
-#define INSERT_INDEX 2
-#define REMOVE_INDEX 3
-
-typedef PSPLAY_TREE_NODE (*PSPLAY_TREE_SPLAY)(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node);
-
-typedef BOOLEAN (*PSPLAY_TREE_SEARCH)(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * ReturnNode);
-
-typedef PSPLAY_TREE_NODE (*PSPLAY_TREE_INSERT)(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE New);
-
-typedef PSPLAY_TREE_NODE (*PSPLAY_TREE_REMOVE)(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * RemovedNode);
-
-/* FUNCTIONS ****************************************************************/
-
-#define ExpSplayTreeRootNode(Tree)(((PSPLAY_TREE) (Tree))->RootNode)
-#define ExpSplayTreeNodeKey(Node)((Node)->Key)
-#define ExpSplayTreeNodeValue(Node)((Node)->Value)
-#define ExpSplayTreeSmallerChildNode(Node)((Node)->SmallerChild)
-#define ExpSplayTreeLargerChildNode(Node)((Node)->LargerChild)
-#define ExpSplayTreeNodeEqual(Equality)((Equality) == 0)
-#define ExpSplayTreeNodeLess(Equality)((Equality) < 0)
-#define ExpSplayTreeNodeMore(Equality)((Equality) > 0)
-#define ExpSplayTreeNodeSame(Node)((Node)->Same)
-#define ExpSplayTreeNodeWeight(Node)((Node)->Weight)
-#define ExpSplayTreeNodeGetWeight(Node)(((Node) == NULL) ? 0 : ((Node)->Weight))
-#define ExpSplayTreeNodeSetWeight(Node, _Weight)((Node)->Weight = (_Weight))
-
-#define KEY_NOTUSED (PVOID)-1
-
-
-/*
- * Lock the splay tree 
- */
-inline VOID
-ExpLockSplayTree(PSPLAY_TREE Tree,
-  PKIRQL OldIrql)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      KeAcquireSpinLock(&Tree->Lock.NonPaged, OldIrql);
-         }
-       else
-               {
-      ExAcquireFastMutex(&Tree->Lock.Paged);
-               }
-}
-
-
-/*
- * Unlock the splay tree 
- */
-inline VOID
-ExpUnlockSplayTree(PSPLAY_TREE Tree,
-  PKIRQL OldIrql)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      KeReleaseSpinLock(&Tree->Lock.NonPaged, *OldIrql);
-         }
-       else
-               {
-      ExReleaseFastMutex(&Tree->Lock.Paged);
-               }
-}
-
-
-/*
- * Allocate resources for a new node and initialize it.
- */
-inline PSPLAY_TREE_NODE
-ExpCreateSplayTreeNode(PSPLAY_TREE Tree,
-  PVOID Value)
-{
-  PSPLAY_TREE_NODE Node;
-
-       if (Tree->UseNonPagedPool)
-         {
-      Node = (PSPLAY_TREE_NODE) ExAllocateFromNPagedLookasideList(&Tree->List.NonPaged);
-         }
-       else
-               {
-      Node = (PSPLAY_TREE_NODE) ExAllocateFromPagedLookasideList(&Tree->List.Paged);
-               }
-
-  if (Node)
-               {
-      ExpSplayTreeSmallerChildNode(Node) = NULL;
-      ExpSplayTreeLargerChildNode(Node)  = NULL;
-      ExpSplayTreeNodeValue(Node)        = Value;
-               }
-
-  return Node;
-}
-
-/*
- * Release resources for the node.
- */
-inline VOID
-ExpDestroySplayTreeNode(PSPLAY_TREE Tree,
-  PSPLAY_TREE_NODE Node)
-{
-       if (Tree->UseNonPagedPool)
-         {
-      ExFreeToNPagedLookasideList(&Tree->List.NonPaged, Node);
-         }
-       else
-               {
-      ExFreeToPagedLookasideList(&Tree->List.Paged, Node);
-               }
-}
-
-
-/*
- * Splay using the key 'Key' (which may or may not be in the tree). The starting
- * root is Node.
- * The lock for the tree must be acquired when this routine is called.
- * This routine does not maintain weight information.
- */
-PSPLAY_TREE_NODE
-ExpSplayTreeNoWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE l;
-  PSPLAY_TREE_NODE r;
-  PSPLAY_TREE_NODE y;
-  LONG ChildEquality;
-  SPLAY_TREE_NODE N;
-  LONG Equality;
-
-  if (Node == NULL)
-    return Node;
-
-  ExpSplayTreeSmallerChildNode(&N) = NULL;
-  ExpSplayTreeLargerChildNode(&N)  = NULL;
-  l = &N;
-  r = &N;
-
-  for (;;)
-    {
-      Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-
-      if (ExpSplayTreeNodeLess(Equality))
-        {
-          if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                 break;
-
-          ChildEquality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(ExpSplayTreeSmallerChildNode(Node)));
-          if (ExpSplayTreeNodeLess(ChildEquality))
-            {
-              y = ExpSplayTreeSmallerChildNode(Node);     /* Rotate smaller */
-              ExpSplayTreeSmallerChildNode(Node) = ExpSplayTreeLargerChildNode(y);
-              ExpSplayTreeLargerChildNode(y) = Node;
-
-                               Node = y;
-                               if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                                 break;
-                       }
-
-                     ExpSplayTreeSmallerChildNode(r) = Node;           /* Link smaller */
-                     r = Node;
-                     Node = ExpSplayTreeSmallerChildNode(Node);
-                   }
-                 else if (ExpSplayTreeNodeMore(Equality))
-                   {
-                     if (ExpSplayTreeLargerChildNode(Node) == NULL)
-                             break;
-
-                     ChildEquality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(ExpSplayTreeLargerChildNode(Node)));
-                     if (ExpSplayTreeNodeMore(ChildEquality))
-                       {
-                               y = ExpSplayTreeLargerChildNode(Node);        /* Rotate larger */
-                               ExpSplayTreeLargerChildNode(Node) = ExpSplayTreeSmallerChildNode(y);
-                               ExpSplayTreeSmallerChildNode(y) = Node;
-               
-                               Node = y;
-                               if (ExpSplayTreeLargerChildNode(Node) == NULL)
-                                 break;
-                       }
-
-                     ExpSplayTreeLargerChildNode(l) = Node;            /* Link larger */
-                     l = Node;
-                     Node = ExpSplayTreeLargerChildNode(Node);         
-                   }
-                 else
-                   {
-                     break;
-                   }
-    }
-
-  ExpSplayTreeLargerChildNode(l)  = NULL;
-  ExpSplayTreeSmallerChildNode(r) = NULL;
-
-  ExpSplayTreeLargerChildNode(l)     = ExpSplayTreeSmallerChildNode(Node);  /* Assemble */
-  ExpSplayTreeSmallerChildNode(r)    = ExpSplayTreeLargerChildNode(Node);
-  ExpSplayTreeSmallerChildNode(Node) = ExpSplayTreeLargerChildNode(&N);
-  ExpSplayTreeLargerChildNode(Node)  = ExpSplayTreeSmallerChildNode(&N);
-
-  return Node;
-}
-
-
-/*
- * Splay using the key 'Key' (which may or may not be in the tree). The starting
- * root is Node.
- * The lock for the tree must be acquired when this routine is called.
- * This routine maintains weight information.
- */
-PSPLAY_TREE_NODE
-ExpSplayTreeWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE l;
-  PSPLAY_TREE_NODE r;
-  PSPLAY_TREE_NODE y;
-  LONG ChildEquality;
-  SPLAY_TREE_NODE N;
-  LONG Equality;
-#ifdef WEIGHT
-  LONG RootWeight;
-  LONG Weight1;
-  LONG Weight2;
-#endif
-
-  if (Node == NULL)
-    return Node;
-
-  ExpSplayTreeSmallerChildNode(&N) = NULL;
-  ExpSplayTreeLargerChildNode(&N)  = NULL;
-  l = &N;
-  r = &N;
-
-#ifdef WEIGHT
-  RootWeight = ExpSplayTreeNodeGetWeight(Node);
-  Weight1 = 0;
-  Weight2 = 0;
-#endif
-
-  for (;;)
-    {
-      Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-
-      if (ExpSplayTreeNodeLess(Equality))
-        {
-          if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                 break;
-
-          ChildEquality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(ExpSplayTreeSmallerChildNode(Node)));
-          if (ExpSplayTreeNodeLess(ChildEquality))
-            {
-              y = ExpSplayTreeSmallerChildNode(Node);     /* Rotate smaller */
-              ExpSplayTreeSmallerChildNode(Node) = ExpSplayTreeLargerChildNode(y);
-              ExpSplayTreeLargerChildNode(y) = Node;
-
-#ifdef WEIGHT
-              ExpSplayTreeNodeSetWeight(Node, ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(Node))
-                + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(Node)) + 1);
-#endif
-
-                               Node = y;
-                               if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                                 break;
-                       }
-               
-                     ExpSplayTreeSmallerChildNode(r) = Node;           /* Link smaller */
-                     r = Node;
-                     Node = ExpSplayTreeSmallerChildNode(Node);
-               
-#ifdef WEIGHT
-                     Weight2 += 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(r));
-#endif
-                   }
-                 else if (ExpSplayTreeNodeMore(Equality))
-                   {
-                     if (ExpSplayTreeLargerChildNode(Node) == NULL)
-                             break;
-               
-                     ChildEquality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(ExpSplayTreeLargerChildNode(Node)));
-                     if (ExpSplayTreeNodeMore(ChildEquality))
-                       {
-                               y = ExpSplayTreeLargerChildNode(Node);        /* Rotate larger */
-                               ExpSplayTreeLargerChildNode(Node) = ExpSplayTreeSmallerChildNode(y);
-                               ExpSplayTreeSmallerChildNode(y) = Node;
-               
-#ifdef WEIGHT
-                               ExpSplayTreeNodeSetWeight(Node, ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(Node))
-                           + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(Node)) + 1);
-#endif
-               
-                               Node = y;
-                               if (ExpSplayTreeLargerChildNode(Node) == NULL)
-                                 break;
-                       }
-               
-                     ExpSplayTreeLargerChildNode(l) = Node;            /* Link larger */
-                     l = Node;
-                     Node = ExpSplayTreeLargerChildNode(Node);
-               
-#ifdef WEIGHT
-                     Weight1 += 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(l));
-#endif
-               
-                   }
-                 else
-                   {
-                     break;
-                   }
-    }
-
-#ifdef WEIGHT
-  Weight1 += ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(Node)); /* Now Weight1 and Weight2 are the weights of */
-  Weight2 += ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(Node));  /* The 'smaller' and 'larger' trees we just built. */
-  ExpSplayTreeNodeSetWeight(Node, Weight1 + Weight2 + 1);
-#endif
-
-  ExpSplayTreeLargerChildNode(l)  = NULL;
-  ExpSplayTreeSmallerChildNode(r) = NULL;
-
-#ifdef WEIGHT
-  /* The following two loops correct the weight fields of the right path from
-   * the left child of the root and the right path from the left child of the
-   * root.
-   */
-  for (y = ExpSplayTreeLargerChildNode(&N); y != NULL; y = ExpSplayTreeLargerChildNode(y)) {
-    ExpSplayTreeNodeSetWeight(y, Weight1);
-    Weight1 -= 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(y));
-  }
-  for (y = ExpSplayTreeSmallerChildNode(&N); y != NULL; y = ExpSplayTreeSmallerChildNode(y)) {
-    ExpSplayTreeNodeSetWeight(y, Weight2);
-    Weight2 -= 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(y));
-  }
-#endif
-
-  ExpSplayTreeLargerChildNode(l)     = ExpSplayTreeSmallerChildNode(Node);  /* Assemble */
-  ExpSplayTreeSmallerChildNode(r)    = ExpSplayTreeLargerChildNode(Node);
-  ExpSplayTreeSmallerChildNode(Node) = ExpSplayTreeLargerChildNode(&N);
-  ExpSplayTreeLargerChildNode(Node)  = ExpSplayTreeSmallerChildNode(&N);
-
-  return Node;
-}
-
-
-inline PSPLAY_TREE_NODE
-ExpSplayTree(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node)
-{
-  return (*((PSPLAY_TREE_SPLAY)Tree->Reserved[SPLAY_INDEX]))(Tree, Key, Node);
-}
-
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- * This routine does not maintain weight information.
- */
-BOOLEAN
-ExpSearchSplayTreeNoWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * ReturnNode)
-{
-  LONG Equality;
-
-  if (Node == NULL)
-    return FALSE;
-
-  Node = ExpSplayTree(Tree, Key, Node);
-
-  Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-  if (ExpSplayTreeNodeEqual(Equality))
-    {
-      /* Found the key */
-
-      *ReturnNode = Node;
-                 return TRUE;
-         }
-       else
-         {
-           *ReturnNode = NULL;                 /* No match */
-           return FALSE;                       /* It wasn't there */
-         }
-}
-
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- * This routine maintains weight information.
- */
-BOOLEAN
-ExpSearchSplayTreeWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * ReturnNode)
-{
-  PSPLAY_TREE_NODE x = NULL;
-  LONG Equality;
-#ifdef WEIGHT
-  LONG tweight;
-#endif
-
-  if (Node == NULL)
-    return FALSE;
-
-#ifdef WEIGHT
-  tweight = ExpSplayTreeNodeGetWeight(Node);
-#endif
-
-  Node = ExpSplayTree(Tree, Key, Node);
-
-  Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-  if (ExpSplayTreeNodeEqual(Equality))
-    {
-      /* Found the key */
-
-#ifdef WEIGHT
-                 if (x != NULL)
-                   {
-                     ExpSplayTreeNodeSetWeight(x, tweight - 1);
-                   }
-#endif
-
-      *ReturnNode = Node;
-                 return TRUE;
-         }
-       else
-         {
-           *ReturnNode = NULL;                 /* No match */
-           return FALSE;                       /* It wasn't there */
-         }
-}
-
-
-inline BOOLEAN
-ExpSearchSplayTree(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * ReturnNode)
-{
-  return (*((PSPLAY_TREE_SEARCH)Tree->Reserved[SEARCH_INDEX]))(Tree, Key, Node, ReturnNode);
-}
-
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- * This routine does not maintain weight information.
- */
-PSPLAY_TREE_NODE
-ExpInsertSplayTreeNoWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE New)
-{
-  if (New == NULL)
-    return Node;
-
-  if (Node != NULL)
-    {
-      LONG Equality;
-
-      Node = ExpSplayTree(Tree, Key, Node);
-
-      Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-      if (ExpSplayTreeNodeEqual(Equality))
-        {
-
-#ifdef UNIQUE_KEYS
-
-      /* This is how to prevent the same node key getting added twice */
-      return NULL; 
-
-#else
-
-      /* It already exists one of this size */
-
-      ExpSplayTreeNodeSame(New) = Node;
-      ExpSplayTreeNodeKey(New) = Key;
-      ExpSplayTreeSmallerChildNode(New) = ExpSplayTreeSmallerChildNode(Node);
-      ExpSplayTreeLargerChildNode(New) = ExpSplayTreeLargerChildNode(Node);
-
-      ExpSplayTreeSmallerChildNode(Node) = New;
-      ExpSplayTreeNodeKey(Node) = KEY_NOTUSED;
-
-      /* New root node */
-      return New;
-
-#endif
-
-    }
-  }
-
-  if (Node == NULL)
-    {
-      ExpSplayTreeSmallerChildNode(New) = NULL;
-      ExpSplayTreeLargerChildNode(New)  = NULL;
-    }
-  else if (ExpSplayTreeNodeLess((*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node))))
-    {
-      ExpSplayTreeSmallerChildNode(New)  = ExpSplayTreeSmallerChildNode(Node);
-      ExpSplayTreeLargerChildNode(New)   = Node;
-      ExpSplayTreeSmallerChildNode(Node) = NULL;
-    }
-  else
-    {
-      ExpSplayTreeLargerChildNode(New)  = ExpSplayTreeLargerChildNode(Node);
-      ExpSplayTreeSmallerChildNode(New) = Node;
-      ExpSplayTreeLargerChildNode(Node) = NULL;
-    }
-
-  ExpSplayTreeNodeKey(New) = Key;
-
-#ifndef UNIQUE_KEYS
-  /* No identical nodes (yet) */
-  ExpSplayTreeNodeSame(New) = NULL;
-#endif
-
-  return New;
-}
-
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- * This routine maintains weight information.
- */
-PSPLAY_TREE_NODE
-ExpInsertSplayTreeWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE New)
-{
-  if (New == NULL)
-    return Node;
-
-  if (Node != NULL)
-    {
-      LONG Equality;
-
-      Node = ExpSplayTree(Tree, Key, Node);
-
-      Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-      if (ExpSplayTreeNodeEqual(Equality))
-        {
-
-#ifdef UNIQUE_KEYS
-
-      /* This is how to prevent the same node key getting added twice */
-      return NULL; 
-
-#else
-
-      /* It already exists one of this size */
-
-      ExpSplayTreeNodeSame(New) = Node;
-      ExpSplayTreeNodeKey(New) = Key;
-      ExpSplayTreeSmallerChildNode(New) = ExpSplayTreeSmallerChildNode(Node);
-      ExpSplayTreeLargerChildNode(New) = ExpSplayTreeLargerChildNode(Node);
-
-#ifdef WEIGHT
-      ExpSplayTreeNodeSetWeight(New, ExpSplayTreeNodeGetWeight(Node));
-#endif
-
-      ExpSplayTreeSmallerChildNode(Node) = New;
-      ExpSplayTreeNodeKey(Node) = KEY_NOTUSED;
-
-      /* New root node */
-      return New;
-
-#endif
-
-    }
-  }
-
-  if (Node == NULL)
-    {
-      ExpSplayTreeSmallerChildNode(New) = NULL;
-      ExpSplayTreeLargerChildNode(New)  = NULL;
-    }
-  else if (ExpSplayTreeNodeLess((*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node))))
-    {
-      ExpSplayTreeSmallerChildNode(New)  = ExpSplayTreeSmallerChildNode(Node);
-      ExpSplayTreeLargerChildNode(New)   = Node;
-      ExpSplayTreeSmallerChildNode(Node) = NULL;
-
-#ifdef WEIGHT
-      ExpSplayTreeNodeSetWeight(Node, 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(Node)));
-#endif
-
-    }
-  else
-    {
-      ExpSplayTreeLargerChildNode(New)  = ExpSplayTreeLargerChildNode(Node);
-      ExpSplayTreeSmallerChildNode(New) = Node;
-      ExpSplayTreeLargerChildNode(Node) = NULL;
-
-#ifdef WEIGHT
-      ExpSplayTreeNodeSetWeight(Node, 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(Node)));
-#endif
-
-    }
-
-  ExpSplayTreeNodeKey(New) = Key;
-
-#ifdef WEIGHT
-  ExpSplayTreeNodeSetWeight(New, 1 + ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(New))
-    + ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(New)));
-#endif
-
-#ifndef UNIQUE_KEYS
-  /* No identical nodes (yet) */
-  ExpSplayTreeNodeSame(New) = NULL;
-#endif
-
-  return New;
-}
-
-
-inline PSPLAY_TREE_NODE
-ExpInsertSplayTree(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE New)
-{
-  return (*((PSPLAY_TREE_INSERT)Tree->Reserved[INSERT_INDEX]))(Tree, Key, Node, New);
-}
-
-
-/*
- * Deletes the node with key 'Key' from the tree if it's there.
- * Return a pointer to the resulting tree.
- * The lock for the tree must be acquired when this routine is called.
- * This routine does not maintain weight information.
- */
-PSPLAY_TREE_NODE
-ExpRemoveSplayTreeNoWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * RemovedNode)
-{
-  PSPLAY_TREE_NODE x;
-  LONG Equality;
-
-  if (Node == NULL)
-    return NULL;
-
-  Node = ExpSplayTree(Tree, Key, Node);
-
-  Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-  if (ExpSplayTreeNodeEqual(Equality))
-    {
-      /* Found the key */
-
-#ifndef UNIQUE_KEYS
-           /* FIRST! Check if there is a list with identical sizes */
-      x = ExpSplayTreeNodeSame(Node);
-           if (x)
-             {
-               /* There is several, pick one from the list */
-
-               /* 'x' is the new root node */
-
-               ExpSplayTreeNodeKey(x)          = ExpSplayTreeNodeKey(Node);
-               ExpSplayTreeLargerChildNode(x)  = ExpSplayTreeLargerChildNode(Node);
-               ExpSplayTreeSmallerChildNode(x) = ExpSplayTreeSmallerChildNode(Node);
-
-          *RemovedNode = Node;
-          return x;
-        }
-#endif
-
-                 if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                   {
-                     x = ExpSplayTreeLargerChildNode(Node);
-                   }
-                 else
-                   {
-                     x = ExpSplayTree(Tree, Key, ExpSplayTreeSmallerChildNode(Node));
-                     ExpSplayTreeLargerChildNode(x) = ExpSplayTreeLargerChildNode(Node);
-                   }
-                 *RemovedNode = Node;
-               
-                 return x;
-         }
-       else
-         {
-           *RemovedNode = NULL;                /* No match */
-           return Node;                        /* It wasn't there */
-         }
-}
-
-
-/*
- * Deletes the node with key 'Key' from the tree if it's there.
- * Return a pointer to the resulting tree.
- * The lock for the tree must be acquired when this routine is called.
- * This routine maintains weight information.
- */
-PSPLAY_TREE_NODE
-ExpRemoveSplayTreeWeight(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * RemovedNode)
-{
-  PSPLAY_TREE_NODE x;
-  LONG Equality;
-
-#ifdef WEIGHT
-  LONG tweight;
-#endif
-
-  if (Node == NULL)
-    return NULL;
-
-#ifdef WEIGHT
-  tweight = ExpSplayTreeNodeGetWeight(Node);
-#endif
-
-  Node = ExpSplayTree(Tree, Key, Node);
-
-  Equality = (*Tree->Compare)(Key, ExpSplayTreeNodeKey(Node));
-  if (ExpSplayTreeNodeEqual(Equality))
-    {
-      /* Found the key */
-
-#ifndef UNIQUE_KEYS
-           /* FIRST! Check if there is a list with identical sizes */
-      x = ExpSplayTreeNodeSame(Node);
-           if (x)
-             {
-               /* There is several, pick one from the list */
-       
-               /* 'x' is the new root node */
-       
-               ExpSplayTreeNodeKey(x)          = ExpSplayTreeNodeKey(Node);
-               ExpSplayTreeLargerChildNode(x)  = ExpSplayTreeLargerChildNode(Node);
-               ExpSplayTreeSmallerChildNode(x) = ExpSplayTreeSmallerChildNode(Node);
-
-#ifdef WEIGHT
-          ExpSplayTreeNodeSetWeight(x, ExpSplayTreeNodeGetWeight(Node));
-#endif
-
-          *RemovedNode = Node;
-          return x;
-        }
-#endif
-
-                 if (ExpSplayTreeSmallerChildNode(Node) == NULL)
-                   {
-                     x = ExpSplayTreeLargerChildNode(Node);
-                   }
-                 else
-                   {
-                     x = ExpSplayTree(Tree, Key, ExpSplayTreeSmallerChildNode(Node));
-                     ExpSplayTreeLargerChildNode(x) = ExpSplayTreeLargerChildNode(Node);
-                   }
-                 *RemovedNode = Node;
-               
-#ifdef WEIGHT
-                 if (x != NULL)
-                   {
-                     ExpSplayTreeNodeSetWeight(x, tweight - 1);
-                   }
-#endif
-               
-                 return x;
-         }
-       else
-         {
-           *RemovedNode = NULL;                /* No match */
-           return Node;                        /* It wasn't there */
-         }
-}
-
-
-inline PSPLAY_TREE_NODE
-ExpRemoveSplayTree(PSPLAY_TREE Tree,
-  PVOID Key,
-  PSPLAY_TREE_NODE Node,
-  PSPLAY_TREE_NODE * RemovedNode)
-{
-  return (*((PSPLAY_TREE_REMOVE)Tree->Reserved[REMOVE_INDEX]))(Tree, Key, Node, RemovedNode);
-}
-
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- */
-ULONG
-ExpPrintSplayTree(PSPLAY_TREE Tree,
-  PSPLAY_TREE_NODE Node,
-  ULONG Distance)
-{
-  PSPLAY_TREE_NODE n;
-  ULONG d = 0;
-  ULONG i;
-
-  if (Node == NULL)
-    return 0;
-
-  Distance += ExpPrintSplayTree(Tree, ExpSplayTreeLargerChildNode(Node), Distance + 1);
-
-  for (i = 0; i < Distance; i++)
-    {
-      DbgPrint("  ");
-    }
-
-  if (Tree->Weighted)
-    {
-      DbgPrint("%d(%d)[%d]", ExpSplayTreeNodeKey(Node), ExpSplayTreeNodeGetWeight(Node), i);
-    }
-  else
-   {
-     DbgPrint("%d[%d]", ExpSplayTreeNodeKey(Node), i);
-   }
-
-  for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
-    {
-      d += i;
-
-      DbgPrint(" [+]");
-    }
-
-  d += i;
-
-  d += ExpPrintSplayTree(Tree, ExpSplayTreeSmallerChildNode(Node), Distance + 1);
-
-  return d;
-}
-
-
-#define MAX_DIFF 4
-
-#ifdef WEIGHT
-
-/*
- * The lock for the tree must be acquired when this routine is called.
- * Returns the new root of the tree.
- * Use of this routine could improve performance, or it might not.
- * FIXME: Do some performance tests
- */
-PSPLAY_TREE_NODE
-ExpSplayTreeMaxTreeWeight(PSPLAY_TREE Tree,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE First = Node;
-  LONG Diff;
-
-  do
-    {
-      Diff = ExpSplayTreeNodeGetWeight(ExpSplayTreeSmallerChildNode(Node))
-        - ExpSplayTreeNodeGetWeight(ExpSplayTreeLargerChildNode(Node));
-
-      if (Diff >= MAX_DIFF)
-        {
-          Node = ExpSplayTreeSmallerChildNode(Node);
-        }
-      else if (Diff <= -MAX_DIFF)
-        {
-          Node = ExpSplayTreeLargerChildNode(Node);
-        }
-      else
-        break;
-    } while (abs(Diff) >= MAX_DIFF);
-
-  if (Node != First)
-    return ExpSplayTree(Tree, ExpSplayTreeNodeKey(Node), First);
-  else
-    return First;
-}
-
-#endif
-
-
-/*
- * Traverse a splay tree using preorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseSplayTreePreorder(PTRAVERSE_CONTEXT Context,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE n; 
-
-  if (Node == NULL)
-    return TRUE;
-
-  /* Call the traversal routine */
-  if (!(*Context->Routine)(Context->Context,
-    ExpSplayTreeNodeKey(Node),
-    ExpSplayTreeNodeValue(Node)))
-    {
-      return FALSE;
-    }
-
-       for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
-               {
-                 /* Call the traversal routine */
-                 if (!(*Context->Routine)(Context->Context,
-                   ExpSplayTreeNodeKey(n),
-                   ExpSplayTreeNodeValue(n)))
-                   {
-                     return FALSE;
-                   }
-               }
-
-  /* Traverse 'smaller' subtree */
-  ExpTraverseSplayTreePreorder(Context, ExpSplayTreeSmallerChildNode(Node));
-
-  /* Traverse 'larger' subtree */
-  ExpTraverseSplayTreePreorder(Context, ExpSplayTreeLargerChildNode(Node));
-
-  return TRUE;
-}
-
-
-/*
- * Traverse a splay tree using inorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseSplayTreeInorder(PTRAVERSE_CONTEXT Context,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE n;
-
-  if (Node == NULL)
-    return TRUE;
-
-  /* Traverse 'smaller' subtree */
-  ExpTraverseSplayTreeInorder(Context, ExpSplayTreeSmallerChildNode(Node));
-
-  /* Call the traversal routine */
-  if (!(*Context->Routine)(Context->Context,
-    ExpSplayTreeNodeKey(Node),
-    ExpSplayTreeNodeValue(Node)))
-    {
-      return FALSE;
-    }
-
-       for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
-               {
-                 /* Call the traversal routine */
-                 if (!(*Context->Routine)(Context->Context,
-                   ExpSplayTreeNodeKey(n),
-                   ExpSplayTreeNodeValue(n)))
-                   {
-                     return FALSE;
-                   }
-               }
-
-  /* Traverse right subtree */
-  ExpTraverseSplayTreeInorder(Context, ExpSplayTreeLargerChildNode(Node));
-
-  return TRUE;
-}
-
-
-/*
- * Traverse a splay tree using postorder traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- * The lock for the tree must be acquired when this routine is called.
- */
-BOOLEAN
-ExpTraverseSplayTreePostorder(PTRAVERSE_CONTEXT Context,
-  PSPLAY_TREE_NODE Node)
-{
-  PSPLAY_TREE_NODE n;
-
-  if (Node == NULL)
-    return TRUE;
-
-  /* Traverse 'smaller' subtree */
-  ExpTraverseSplayTreePostorder(Context, ExpSplayTreeSmallerChildNode(Node));
-
-  /* Traverse 'larger' subtree */
-  ExpTraverseSplayTreePostorder(Context, ExpSplayTreeLargerChildNode(Node));
-
-  /* Call the traversal routine */
-  if (!(*Context->Routine)(Context->Context,
-    ExpSplayTreeNodeKey(Node),
-    ExpSplayTreeNodeValue(Node)))
-    {
-      return FALSE;
-    }
-
-       for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
-               {
-                 /* Call the traversal routine */
-                 if (!(*Context->Routine)(Context->Context,
-                   ExpSplayTreeNodeKey(n),
-                   ExpSplayTreeNodeValue(n)))
-                   {
-                     return FALSE;
-                   }
-               }
-
-  return TRUE;
-}
-
-
-/*
- * Default key compare function. Compares the integer values of the two keys.
- */
-LONG STDCALL
-ExpSplayTreeDefaultCompare(IN PVOID  Key1,
-  IN PVOID  Key2)
-{
-  if (Key1 == Key2)
-    return 0;
-
-  return (((LONG_PTR) Key1 < (LONG_PTR) Key2) ? -1 : 1);
-}
-
-
-/*
- * Initializes a splay tree.
- */
-BOOLEAN STDCALL
-ExInitializeSplayTree(IN PSPLAY_TREE  Tree,
-  IN PKEY_COMPARATOR  Compare,
-  IN BOOLEAN  Weighted,
-  IN BOOLEAN  UseNonPagedPool)
-{
-  RtlZeroMemory(Tree, sizeof(SPLAY_TREE));
-
-  Tree->Compare = (Compare == NULL)
-    ? ExpSplayTreeDefaultCompare : Compare;
-
-  Tree->Weighted = Weighted;
-
-  if (Weighted)
-    {
-      Tree->Reserved[SPLAY_INDEX]  = (PVOID) ExpSplayTreeWeight;
-      Tree->Reserved[SEARCH_INDEX] = (PVOID) ExpSearchSplayTreeWeight;
-      Tree->Reserved[INSERT_INDEX] = (PVOID) ExpInsertSplayTreeWeight;
-      Tree->Reserved[REMOVE_INDEX] = (PVOID) ExpRemoveSplayTreeWeight;
-    }
-       else
-               {
-      Tree->Reserved[SPLAY_INDEX]  = (PVOID) ExpSplayTreeNoWeight;
-      Tree->Reserved[SEARCH_INDEX] = (PVOID) ExpSearchSplayTreeNoWeight;
-      Tree->Reserved[INSERT_INDEX] = (PVOID) ExpInsertSplayTreeNoWeight;
-      Tree->Reserved[REMOVE_INDEX] = (PVOID) ExpRemoveSplayTreeNoWeight;
-               }
-
-  Tree->UseNonPagedPool = UseNonPagedPool;
-
-  if (UseNonPagedPool)
-    {
-                 ExInitializeNPagedLookasideList(
-                   &Tree->List.NonPaged,           /* Lookaside list */
-                   NULL,                           /* Allocate routine */
-                   NULL,                           /* Free routine */
-                   0,                              /* Flags */
-                   sizeof(SPLAY_TREE_NODE),        /* Size of each entry */
-                   TAG('E','X','S','T'),           /* Tag */
-                   0);                             /* Depth */
-
-      KeInitializeSpinLock(&Tree->Lock.NonPaged);
-               }
-               else
-               {
-                 ExInitializePagedLookasideList(
-                   &Tree->List.Paged,              /* Lookaside list */
-                   NULL,                           /* Allocate routine */
-                   NULL,                           /* Free routine */
-                   0,                              /* Flags */
-                   sizeof(SPLAY_TREE_NODE),       /* Size of each entry */
-                   TAG('E','X','S','T'),           /* Tag */
-                   0);                             /* Depth */
-
-      ExInitializeFastMutex(&Tree->Lock.Paged);
-               }
-
-  return TRUE;
-}
-
-
-/*
- * Release resources used by a splay tree.
- */
-VOID STDCALL
-ExDeleteSplayTree(IN PSPLAY_TREE  Tree)
-{
-  PSPLAY_TREE_NODE RemovedNode;
-  PSPLAY_TREE_NODE Node;
-
-  /* Remove all nodes */
-  Node = ExpSplayTreeRootNode(Tree);
-  while (Node != NULL)
-    {
-      Node = ExpRemoveSplayTree(Tree, Node->Key, Node, &RemovedNode);
-
-      if (RemovedNode != NULL)
-                 {
-          ExpDestroySplayTreeNode(Tree, RemovedNode);
-        }
-    }
-
-  if (Tree->UseNonPagedPool)
-    {
-      ExDeleteNPagedLookasideList(&Tree->List.NonPaged);
-         }
-       else
-               {
-      ExDeletePagedLookasideList(&Tree->List.Paged);
-               }
-}
-
-
-/*
- * Insert a value in a splay tree.
- */
-VOID STDCALL
-ExInsertSplayTree(IN PSPLAY_TREE  Tree,
-  IN PVOID  Key,
-  IN PVOID  Value)
-{
-  PSPLAY_TREE_NODE Node;
-  PSPLAY_TREE_NODE NewNode;
-  KIRQL OldIrql;
-
-  /* FIXME: Use SEH for error reporting */
-
-  NewNode = ExpCreateSplayTreeNode(Tree, Value);
-
-  ExpLockSplayTree(Tree, &OldIrql);
-  Node = ExpInsertSplayTree(Tree, Key, ExpSplayTreeRootNode(Tree), NewNode);
-  ExpSplayTreeRootNode(Tree) = Node;
-  ExpUnlockSplayTree(Tree, &OldIrql);
-}
-
-
-/*
- * Search for a value associated with a given key in a splay tree.
- */
-BOOLEAN STDCALL
-ExSearchSplayTree(IN PSPLAY_TREE  Tree,
-  IN PVOID  Key,
-  OUT PVOID  * Value)
-{
-  PSPLAY_TREE_NODE Node;
-  BOOLEAN Status;
-  KIRQL OldIrql;
-
-  ExpLockSplayTree(Tree, &OldIrql);
-  Status = ExpSearchSplayTree(Tree, Key, ExpSplayTreeRootNode(Tree), &Node);
-
-  if (Status)
-    {
-      ExpSplayTreeRootNode(Tree) = Node;
-      *Value = ExpSplayTreeNodeValue(Node);
-      ExpUnlockSplayTree(Tree, &OldIrql);
-                 return TRUE;
-         }
-       else
-         {
-      ExpUnlockSplayTree(Tree, &OldIrql);
-           return FALSE;
-         }
-}
-
-
-/*
- * Remove a value associated with a given key from a splay tree.
- */
-BOOLEAN STDCALL
-ExRemoveSplayTree(IN PSPLAY_TREE  Tree,
-  IN PVOID  Key,
-  IN PVOID  * Value)
-{
-  PSPLAY_TREE_NODE RemovedNode;
-  PSPLAY_TREE_NODE Node;
-  KIRQL OldIrql;
-
-  ExpLockSplayTree(Tree, &OldIrql);
-  Node = ExpRemoveSplayTree(Tree, Key, ExpSplayTreeRootNode(Tree), &RemovedNode);
-  ExpSplayTreeRootNode(Tree) = Node;
-  ExpUnlockSplayTree(Tree, &OldIrql);
-
-  if (RemovedNode != NULL)
-               {
-      *Value = ExpSplayTreeNodeValue(RemovedNode);
-      ExpDestroySplayTreeNode(Tree, RemovedNode);
-      return TRUE;
-               }
-       else
-               {
-      return FALSE;
-               }
-}
-
-
-/*
- * Return the weight of the root node in the splay tree.
- * The returned value is the number of nodes in the tree.
- */
-BOOLEAN STDCALL
-ExWeightOfSplayTree(IN PSPLAY_TREE  Tree,
-  OUT PULONG  Weight)
-{
-  KIRQL OldIrql;
-
-  ExpLockSplayTree(Tree, &OldIrql);
-
-       if (!Tree->Weighted)
-               {
-      ExpUnlockSplayTree(Tree, &OldIrql);
-      return FALSE;    
-               }
-
-  *Weight = ExpSplayTreeNodeWeight(ExpSplayTreeRootNode(Tree));
-  ExpUnlockSplayTree(Tree, &OldIrql);
-
-  return TRUE;
-}
-
-
-/*
- * Traverse a splay tree using either preorder, inorder or postorder
- * traversal method.
- * Returns FALSE, if the traversal was terminated prematurely or
- * TRUE if the callback routine did not request that the traversal
- * be terminated prematurely.
- */
-BOOLEAN STDCALL
-ExTraverseSplayTree(IN PSPLAY_TREE  Tree,
-  IN TRAVERSE_METHOD  Method,
-  IN PTRAVERSE_ROUTINE  Routine,
-  IN PVOID  Context)
-{
-  TRAVERSE_CONTEXT tc;
-  BOOLEAN Status;
-  KIRQL OldIrql;
-
-  tc.Routine = Routine;
-  tc.Context = Context;
-
-  ExpLockSplayTree(Tree, &OldIrql);
-
-  if (ExpSplayTreeRootNode(Tree) == NULL)
-               {
-      ExpUnlockSplayTree(Tree, &OldIrql);
-      return TRUE;
-               }
-
-  switch (Method)
-    {
-      case TraverseMethodPreorder:
-        Status = ExpTraverseSplayTreePreorder(&tc, ExpSplayTreeRootNode(Tree));
-        break;
-
-      case TraverseMethodInorder:
-        Status = ExpTraverseSplayTreeInorder(&tc, ExpSplayTreeRootNode(Tree));
-        break;
-
-      case TraverseMethodPostorder:
-        Status = ExpTraverseSplayTreePostorder(&tc, ExpSplayTreeRootNode(Tree));
-        break;
-
-      default:
-        Status = FALSE;
-        break;
-    }
-
-  ExpUnlockSplayTree(Tree, &OldIrql);
-
-  return Status;
-}
-
-/* EOF */
index bf4c528..3165f1e 100644 (file)
@@ -15,6 +15,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+extern PEPROCESS PsIdleProcess;
 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
 ULONGLONG STDCALL KeQueryInterruptTime(VOID);
 
@@ -46,17 +47,18 @@ ExGetCurrentProcessorCpuUsage (
        PULONG  CpuUsage
        )
 {
-       PKPCR Pcr;
+       PKPRCB Prcb;
        ULONG TotalTime;
-       ULONG PercentTime = 0;
        ULONGLONG ScaledIdle;
 
-       Pcr = KeGetCurrentKPCR();
+       Prcb = KeGetCurrentPrcb();
 
-       ScaledIdle = Pcr->PrcbData.IdleThread->KernelTime * 100;
-       TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-       if (TotalTime) PercentTime = 100 - (ScaledIdle / TotalTime);
-       CpuUsage = &PercentTime;
+       ScaledIdle = Prcb->IdleThread->KernelTime * 100;
+       TotalTime = Prcb->KernelTime + Prcb->UserTime;
+       if (TotalTime != 0)
+               *CpuUsage = 100 - (ScaledIdle / TotalTime);
+       else
+               *CpuUsage = 0;
 }
 
 /*
@@ -70,20 +72,27 @@ ExGetCurrentProcessorCounts (
        PULONG  ProcessorNumber
        )
 {
-       PKPCR Pcr;
-       ULONG TotalTime;
-       ULONG ThreadTime;
-       ULONG ProcNumber;
+       PKPRCB Prcb;
+
+       Prcb = KeGetCurrentPrcb();
 
-       Pcr = KeGetCurrentKPCR();
+       *ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime;
+       *TotalCpuTime = Prcb->CurrentThread->KernelTime;
+       *ProcessorNumber = KeGetCurrentKPCR()->ProcessorNumber;
+}
 
-       TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-       ThreadTime = Pcr->PrcbData.CurrentThread->KernelTime;
-       ProcNumber = Pcr->ProcessorNumber;
+/*
+ * @implemented
+ */
+BOOLEAN 
+STDCALL
+ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
+{
+    /* Quick check to see if it exists at all */
+    if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE);
 
-       ThreadKernelTime = &ThreadTime;
-       TotalCpuTime = &TotalTime;
-       ProcessorNumber = &ProcNumber;
+    /* Return our support for it */
+    return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
 }
 
 NTSTATUS STDCALL
@@ -363,7 +372,7 @@ QSI_DEF(SystemProcessorInformation)
 {
        PSYSTEM_PROCESSOR_INFORMATION Spi 
                = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
-       PKPCR Pcr;
+       PKPRCB Prcb;
        *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
        /*
         * Check user buffer's size 
@@ -372,12 +381,12 @@ QSI_DEF(SystemProcessorInformation)
        {
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
-       Pcr = KeGetCurrentKPCR();
+       Prcb = KeGetCurrentPrcb();
        Spi->ProcessorArchitecture = 0; /* Intel Processor */
-       Spi->ProcessorLevel        = Pcr->PrcbData.CpuType;
-       Spi->ProcessorRevision     = Pcr->PrcbData.CpuStep;
+       Spi->ProcessorLevel        = Prcb->CpuType;
+       Spi->ProcessorRevision     = Prcb->CpuStep;
        Spi->Unknown               = 0;
-       Spi->FeatureBits           = Pcr->PrcbData.FeatureBits;
+       Spi->FeatureBits           = Prcb->FeatureBits;
 
        DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
                Spi->ProcessorLevel, Spi->ProcessorRevision);
@@ -402,7 +411,7 @@ QSI_DEF(SystemPerformanceInformation)
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
        
-       TheIdleProcess = PsInitialSystemProcess; /* FIXME */
+       TheIdleProcess = PsIdleProcess;
        
        Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
 
@@ -603,13 +612,20 @@ QSI_DEF(SystemProcessInformation)
                SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
 
                // copy name to the end of the struct
-               RtlInitAnsiString(&imgName, pr->ImageFileName);
-               RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
+               if(pr != PsIdleProcess)
+               {
+                 RtlInitAnsiString(&imgName, pr->ImageFileName);
+                 RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
+               }
+               else
+               {
+                  RtlInitUnicodeString(&SpiCur->ProcessName, NULL);
+               }
 
                SpiCur->BasePriority = pr->Pcb.BasePriority;
                SpiCur->ProcessId = pr->UniqueProcessId;
                SpiCur->InheritedFromProcessId = pr->InheritedFromUniqueProcessId;
-               SpiCur->HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
+               SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
                SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
                SpiCur->VmCounters.VirtualSize = pr->VirtualSize.QuadPart;
                SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
@@ -660,12 +676,13 @@ QSI_DEF(SystemProcessInformation)
                else
                        pCur = pCur + curSize + inLen;
        }  while ((pr != syspr) && (pr != NULL));
+       
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
 
        *ReqSize = ovlSize;
-       if (pr != NULL)
-         {
-           ObDereferenceObject(pr);
-         }
        return (STATUS_SUCCESS);
 }
 
@@ -708,38 +725,36 @@ QSI_DEF(SystemDeviceInformation)
 /* Class 8 - Processor Performance Information */
 QSI_DEF(SystemProcessorPerformanceInformation)
 {
-       PSYSTEM_PROCESSORTIME_INFO Spi
-               = (PSYSTEM_PROCESSORTIME_INFO) Buffer;
+       PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+               = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
 
         ULONG i;
        LARGE_INTEGER CurrentTime;
-       PKPCR Pcr;
+       PKPRCB Prcb;
 
-       *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSORTIME_INFO);
+       *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
        /*
-        * Check user buffer's size 
+        * Check user buffer's size
         */
-       if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSORTIME_INFO))
+       if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
        {
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
 
        CurrentTime.QuadPart = KeQueryInterruptTime();
-       Pcr = (PKPCR)KPCR_BASE;   
+       Prcb = ((PKPCR)KPCR_BASE)->Prcb;
        for (i = 0; i < KeNumberProcessors; i++)
        {
-
-          Spi->TotalProcessorRunTime.QuadPart = (Pcr->PrcbData.IdleThread->KernelTime + Pcr->PrcbData.IdleThread->UserTime) * 100000LL; // IdleTime
-           Spi->TotalProcessorTime.QuadPart =  Pcr->PrcbData.KernelTime * 100000LL; // KernelTime
-           Spi->TotalProcessorUserTime.QuadPart = Pcr->PrcbData.UserTime * 100000LL;
-           Spi->TotalDPCTime.QuadPart = Pcr->PrcbData.DpcTime * 100000LL;
-           Spi->TotalInterruptTime.QuadPart = Pcr->PrcbData.InterruptTime * 100000LL;
-           Spi->TotalInterrupts = Pcr->PrcbData.InterruptCount; // Interrupt Count
+          Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL; // IdleTime
+           Spi->KernelTime.QuadPart =  Prcb->KernelTime * 100000LL; // KernelTime
+           Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
+           Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
+           Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
+           Spi->InterruptCount = Prcb->InterruptCount; // Interrupt Count
           Spi++;
-//        Pcr++;
-          Pcr = (PKPCR)((ULONG_PTR)Pcr + PAGE_SIZE);
+          Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
        }
-     
+
        return (STATUS_SUCCESS);
 }
 
@@ -843,20 +858,20 @@ QSI_DEF(SystemHandleInformation)
 
         do
          {
-            hCount = hCount + ObpGetHandleCountByHandleTable(&pr->HandleTable);
+            hCount = hCount + (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
             pr = PsGetNextProcess(pr);
 
            if ((pr == syspr) || (pr == NULL))
                break;
         } while ((pr != syspr) && (pr != NULL));
+        
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
 
        DPRINT("SystemHandleInformation 2\n");
 
-       if (pr != NULL)
-         {
-           ObDereferenceObject(pr);
-         }
-
         curSize = sizeof(SYSTEM_HANDLE_INFORMATION)+
                   (  (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) - 
                      (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) ));
@@ -877,9 +892,9 @@ QSI_DEF(SystemHandleInformation)
 
         do
          {
-            int Count = 0, HandleCount = 0;
+            int Count = 0, HandleCount;
 
-            HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
+            HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
 
             for (Count = 0; HandleCount > 0 ; HandleCount--)
                {
@@ -894,11 +909,10 @@ QSI_DEF(SystemHandleInformation)
                break;
           } while ((pr != syspr) && (pr != NULL));
 
-
-       if (pr != NULL)
-         {
-           ObDereferenceObject(pr);
-         }
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
 
        DPRINT("SystemHandleInformation 4\n");
        return (STATUS_SUCCESS);
@@ -1003,12 +1017,35 @@ QSI_DEF(SystemPoolTagInformation)
        return (STATUS_NOT_IMPLEMENTED);
 }
 
-/* Class 23 - Interrupt Information */
+/* Class 23 - Interrupt Information for all processors */
 QSI_DEF(SystemInterruptInformation)
 {
-       /* FIXME */
-       DPRINT1("NtQuerySystemInformation - SystemInterruptInformation not implemented\n");
-       return (STATUS_NOT_IMPLEMENTED);
+  PKPRCB Prcb;
+  UINT i;
+  ULONG ti;
+  PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
+  
+  if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION))
+  {
+    return (STATUS_INFO_LENGTH_MISMATCH);
+  }
+  
+  ti = KeQueryTimeIncrement();
+  
+  Prcb = ((PKPCR)KPCR_BASE)->Prcb;
+  for (i = 0; i < KeNumberProcessors; i++)
+  {
+    sii->ContextSwitches = Prcb->KeContextSwitches;
+    sii->DpcCount = 0; /* FIXME */
+    sii->DpcRate = 0; /* FIXME */
+    sii->TimeIncrement = ti;
+    sii->DpcBypassCount = 0; /* FIXME */
+    sii->ApcBypassCount = 0; /* FIXME */
+    sii++;
+    Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+  }
+  
+  return STATUS_SUCCESS;
 }
 
 /* Class 24 - DPC Behaviour Information */
@@ -1041,7 +1078,7 @@ QSI_DEF(SystemFullMemoryInformation)
        }
        DPRINT("SystemFullMemoryInformation\n");
 
-       TheIdleProcess = PsInitialSystemProcess; /* FIXME */
+       TheIdleProcess = PsIdleProcess;
 
         DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
                TheIdleProcess->UniqueProcessId,
index fa0a254..b54e6c3 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: nttimer.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/timer.c
@@ -12,6 +11,8 @@
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+
+#define NDEBUG
 #include <internal/debug.h>
 
 /* TYPES ********************************************************************/
@@ -23,7 +24,6 @@ typedef struct _ETIMER {
     KDPC TimerDpc;
     LIST_ENTRY ActiveTimerListEntry;
     KSPIN_LOCK Lock;
-    LONG Period;
     BOOLEAN ApcAssociated;
     BOOLEAN WakeTimer;
     LIST_ENTRY WakeTimerListEntry;
@@ -54,6 +54,58 @@ static const INFORMATION_CLASS_INFO ExTimerInfoClass[] = {
 
 /* FUNCTIONS *****************************************************************/
 
+VOID
+STDCALL
+ExTimerRundown(VOID)
+{
+    PETHREAD Thread = PsGetCurrentThread();
+    KIRQL OldIrql;
+    PLIST_ENTRY CurrentEntry;
+    PETIMER Timer;
+    
+    /* Lock the Thread's Active Timer List*/
+    KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
+    
+    while (!IsListEmpty(&Thread->ActiveTimerListHead)) \r
+    {\r
+        
+        /* Remove a Timer */
+       CurrentEntry = RemoveTailList(&Thread->ActiveTimerListHead);
+\r
+        /* Get the Timer */
+        Timer = CONTAINING_RECORD(CurrentEntry, ETIMER, ActiveTimerListEntry);\r
+        \r
+        ASSERT (Timer->ApcAssociated);
+       Timer->ApcAssociated = FALSE;      \r
+       
+        DPRINT("Timer, ThreadList: %x, %x\n", Timer, Thread);
+        
+        /* Unlock the list */
+        KeReleaseSpinLockFromDpcLevel(&Thread->ActiveTimerListLock);
+            
+        /* Lock the Timer */
+        KeAcquireSpinLockAtDpcLevel(&Timer->Lock);
+        
+        ASSERT (&Thread->Tcb == Timer->TimerApc.Thread);\r
+        
+        KeCancelTimer(&Timer->KeTimer);
+        KeRemoveQueueDpc(&Timer->TimerDpc);
+        KeRemoveQueueApc(&Timer->TimerApc);   
+                       
+        
+        /* Unlock the Timer */
+        KeReleaseSpinLock(&Timer->Lock, OldIrql);
+        
+        /* Dereference it, if needed */
+        ObDereferenceObject(Timer);
+        
+        /* Loop again */
+        KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
+    }       
+    
+    KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
+}
+
 VOID
 STDCALL
 ExpDeleteTimer(PVOID ObjectBody)
@@ -67,11 +119,12 @@ ExpDeleteTimer(PVOID ObjectBody)
     KeAcquireSpinLock(&ExpWakeListLock, &OldIrql);
     
     /* Check if it has a Wait List */
-    if (!IsListEmpty(&Timer->WakeTimerListEntry)) {
+    if (Timer->WakeTimer) {
     
         /* Remove it from the Wait List */
         DPRINT("Removing wake list\n");
         RemoveEntryList(&Timer->WakeTimerListEntry);
+       Timer->WakeTimer = FALSE;
     }
     
     /* Release the Wake List */
@@ -124,9 +177,9 @@ ExpTimerApcKernelRoutine(PKAPC Apc,
                          PVOID* SystemArguemnt2)
 {
     PETIMER Timer;
-    PETHREAD CurrentThread = PsGetCurrentThread();
     KIRQL OldIrql;
-    
+    PETHREAD CurrentThread = PsGetCurrentThread();
+
     /* We need to find out which Timer we are */
     Timer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);
     DPRINT("ExpTimerApcKernelRoutine(Apc: %x. Timer: %x)\n", Apc, Timer);
@@ -143,8 +196,8 @@ ExpTimerApcKernelRoutine(PKAPC Apc,
      */
     if ((Timer->ApcAssociated) && 
         (&CurrentThread->Tcb == Timer->TimerApc.Thread) && 
-        (!Timer->Period)) {
-    
+        (!Timer->KeTimer.Period)) {
+
         /* Remove it from the Active Timers List */
         DPRINT("Removing Timer\n");
         RemoveEntryList(&Timer->ActiveTimerListEntry);
@@ -176,7 +229,7 @@ ExpInitializeTimerImplementation(VOID)
     ExTimerType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
 
     /* Create the Executive Timer Object */
-    RtlpCreateUnicodeString(&ExTimerType->TypeName, L"Timer", NonPagedPool);
+    RtlInitUnicodeString(&ExTimerType->TypeName, L"Timer");
     ExTimerType->Tag = TAG('T', 'I', 'M', 'T');
     ExTimerType->PeakObjects = 0;
     ExTimerType->PeakHandles = 0;
@@ -209,7 +262,7 @@ NtCancelTimer(IN HANDLE TimerHandle,
               OUT PBOOLEAN CurrentState OPTIONAL)
 {
     PETIMER Timer;
-    KPROCESSOR_MODE PreviousMode;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     BOOLEAN State;
     KIRQL OldIrql;
     PETHREAD TimerThread;
@@ -217,9 +270,6 @@ NtCancelTimer(IN HANDLE TimerHandle,
     NTSTATUS Status = STATUS_SUCCESS;
     
     PAGED_CODE();
-    
-    PreviousMode = ExGetPreviousMode();
-   
     DPRINT("NtCancelTimer(0x%x, 0x%x)\n", TimerHandle, CurrentState);
    
     /* Check Parameter Validity */
@@ -301,10 +351,15 @@ NtCancelTimer(IN HANDLE TimerHandle,
 
         /* Make sure it's safe to write to the handle */
         if(CurrentState != NULL) {
+            
             _SEH_TRY {
+                
                 *CurrentState = State;
+                
             } _SEH_HANDLE {
+                
                 Status = _SEH_GetExceptionCode();
+                
             } _SEH_END;
         }
     }
@@ -323,28 +378,27 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
 {
     PETIMER Timer;
     HANDLE hTimer;
-    KPROCESSOR_MODE PreviousMode;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     
     PAGED_CODE();
-    
-    PreviousMode = ExGetPreviousMode();
-   
     DPRINT("NtCreateTimer(Handle: %x, Type: %d)\n", TimerHandle, TimerType);
 
     /* Check Parameter Validity */
     if (PreviousMode != KernelMode) {
+        
         _SEH_TRY {
+            
             ProbeForWrite(TimerHandle,
                           sizeof(HANDLE),
                           sizeof(ULONG));
         } _SEH_HANDLE {
+            
             Status = _SEH_GetExceptionCode();
+            
         } _SEH_END;
      
-        if(!NT_SUCCESS(Status)) {
-            return Status;
-        }
+        if(!NT_SUCCESS(Status)) return Status;
     }
     
     /* Create the Object */   
@@ -373,7 +427,6 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
 
         /* Set Initial State */
         Timer->ApcAssociated = FALSE;
-        InitializeListHead(&Timer->WakeTimerListEntry);
         Timer->WakeTimer = FALSE;
         
         /* Insert the Timer */
@@ -388,9 +441,13 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
   
         /* Make sure it's safe to write to the handle */
         _SEH_TRY {
+            
             *TimerHandle = hTimer;
+            
         } _SEH_HANDLE {
+            
             Status = _SEH_GetExceptionCode();
+            
         } _SEH_END;
     }
 
@@ -406,28 +463,28 @@ NtOpenTimer(OUT PHANDLE TimerHandle,
             IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
     HANDLE hTimer;
-    KPROCESSOR_MODE PreviousMode;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     
     PAGED_CODE();
-    
-    PreviousMode = ExGetPreviousMode();
-
     DPRINT("NtOpenTimer(TimerHandle: %x)\n", TimerHandle);
 
     /* Check Parameter Validity */
     if (PreviousMode != KernelMode) {
+        
         _SEH_TRY {
+            
             ProbeForWrite(TimerHandle,
                           sizeof(HANDLE),
                           sizeof(ULONG));
+            
         } _SEH_HANDLE {
+            
             Status = _SEH_GetExceptionCode();
+            
         } _SEH_END;
      
-        if(!NT_SUCCESS(Status)) {
-            return Status;
-        }
+        if(!NT_SUCCESS(Status)) return Status;
     }
 
     /* Open the Timer */
@@ -444,9 +501,13 @@ NtOpenTimer(OUT PHANDLE TimerHandle,
         
         /* Make sure it's safe to write to the handle */
         _SEH_TRY {
+            
             *TimerHandle = hTimer;
+            
         } _SEH_HANDLE {
+            
             Status = _SEH_GetExceptionCode();
+            
         } _SEH_END;
     }
 
@@ -464,16 +525,13 @@ NtQueryTimer(IN HANDLE TimerHandle,
              OUT PULONG ReturnLength  OPTIONAL)
 {
     PETIMER Timer;
-    KPROCESSOR_MODE PreviousMode;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     NTSTATUS Status = STATUS_SUCCESS;
     PTIMER_BASIC_INFORMATION BasicInfo = (PTIMER_BASIC_INFORMATION)TimerInformation;
     
     PAGED_CODE();
-    
-    PreviousMode = ExGetPreviousMode();
-
     DPRINT("NtQueryTimer(TimerHandle: %x, Class: %d)\n", TimerHandle, TimerInformationClass);
-    
+
     /* Check Validity */
     DefaultQueryInfoBufferCheck(TimerInformationClass,
                                 ExTimerInfoClass,
@@ -498,27 +556,24 @@ NtQueryTimer(IN HANDLE TimerHandle,
     
     /* Check for Success */
     if(NT_SUCCESS(Status)) {
+
+        /* Return the Basic Information */
+        _SEH_TRY {
+           
+            /* FIXME: Interrupt correction based on Interrupt Time */
+            DPRINT("Returning Information for Timer: %x. Time Remaining: %d\n", Timer, Timer->KeTimer.DueTime.QuadPart);
+            BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart;
+            BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
+
+            if(ReturnLength != NULL) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
+
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+                  
+        } _SEH_END;
         
-        switch(TimerInformationClass) {
-           case TimerBasicInformation: {
-              /* Return the Basic Information */
-               _SEH_TRY {
-
-                  /* FIXME: Interrupt correction based on Interrupt Time */
-                  DPRINT("Returning Information for Timer: %x. Time Remaining: %d\n", Timer, Timer->KeTimer.DueTime.QuadPart);
-                  BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart;
-                  BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
-
-                  if(ReturnLength != NULL) {
-                      *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
-                  }
-
-              } _SEH_HANDLE {
-                  Status = _SEH_GetExceptionCode();
-              } _SEH_END;
-           }
-        }
-        
+        /* Dereference Object */
         ObDereferenceObject(Timer);
     }
    
@@ -539,41 +594,40 @@ NtSetTimer(IN HANDLE TimerHandle,
     PETIMER Timer;
     KIRQL OldIrql;
     BOOLEAN State;
-    KPROCESSOR_MODE PreviousMode;
-    PETHREAD CurrentThread;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PETHREAD CurrentThread = PsGetCurrentThread();
     LARGE_INTEGER TimerDueTime;
     PETHREAD TimerThread;
     BOOLEAN KillTimer = FALSE;
     NTSTATUS Status = STATUS_SUCCESS;
     
     PAGED_CODE();
-    
-    PreviousMode = ExGetPreviousMode();
-    CurrentThread = PsGetCurrentThread();
-
     DPRINT("NtSetTimer(TimerHandle: %x, DueTime: %d, Apc: %x, Period: %d)\n", TimerHandle, DueTime->QuadPart, TimerApcRoutine, Period);
 
     /* Check Parameter Validity */
     if (PreviousMode != KernelMode) {
+        
         _SEH_TRY {
+            
             ProbeForRead(DueTime,
                          sizeof(LARGE_INTEGER),
                          sizeof(ULONG));
             TimerDueTime = *DueTime;
             
             if(PreviousState != NULL) {
+                
                 ProbeForWrite(PreviousState,
                               sizeof(BOOLEAN),
                               sizeof(BOOLEAN));
             }
             
         } _SEH_HANDLE {
+            
             Status = _SEH_GetExceptionCode();
+            
         } _SEH_END;
      
-        if(!NT_SUCCESS(Status)) {
-            return Status;
-        }
+        if(!NT_SUCCESS(Status)) return Status;        
     }
     
     /* Get the Timer Object */   
@@ -630,16 +684,16 @@ NtSetTimer(IN HANDLE TimerHandle,
         /* Handle Wake Timers */
         DPRINT("Doing Wake Semantics\n");
         KeAcquireSpinLockAtDpcLevel(&ExpWakeListLock);
-        if (WakeTimer) {
+        if (WakeTimer && !Timer->WakeTimer) {
         
             /* Insert it into the list */
+            Timer->WakeTimer = TRUE;
             InsertTailList(&ExpWakeList, &Timer->WakeTimerListEntry);
-        
-        } else {
+        } else if (!WakeTimer && Timer->WakeTimer) {
             
             /* Remove it from the list */
             RemoveEntryList(&Timer->WakeTimerListEntry);
-            Timer->WakeTimerListEntry.Flink = NULL;
+            Timer->WakeTimer = FALSE;
         }
         KeReleaseSpinLockFromDpcLevel(&ExpWakeListLock);
         
@@ -679,9 +733,6 @@ NtSetTimer(IN HANDLE TimerHandle,
         /* Dereference the Object */
         ObDereferenceObject(Timer);
         
-        /* Unlock the Timer */
-        KeReleaseSpinLock(&Timer->Lock, OldIrql);
-                
         /* Dereference if it was previously enabled */
         if (!TimerApcRoutine) ObDereferenceObject(Timer);
         if (KillTimer) ObDereferenceObject(Timer);
@@ -689,10 +740,15 @@ NtSetTimer(IN HANDLE TimerHandle,
 
         /* Make sure it's safe to write to the handle */
         if(PreviousState != NULL) {
+            
             _SEH_TRY {
+                
                 *PreviousState = State;
+                
             } _SEH_HANDLE {
+                
                 Status = _SEH_GetExceptionCode();
+                
             } _SEH_END;
         }
     }
index 7fc3ed9..6a93e85 100644 (file)
@@ -5,7 +5,8 @@
  * FILE:            ntoskrnl/ex/win32k.c
  * PURPOSE:         Executive Win32 subsystem support
  * 
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Moved callbacks to win32k and cleanup.
+ *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
 #include <ntoskrnl.h>
 
 /* DATA **********************************************************************/
 
-#define WINSTA_ACCESSCLIPBOARD (0x4L)
-#define WINSTA_ACCESSGLOBALATOMS       (0x20L)
-#define WINSTA_CREATEDESKTOP   (0x8L)
-#define WINSTA_ENUMDESKTOPS    (0x1L)
-#define WINSTA_ENUMERATE       (0x100L)
-#define WINSTA_EXITWINDOWS     (0x40L)
-#define WINSTA_READATTRIBUTES  (0x2L)
-#define WINSTA_READSCREEN      (0x200L)
-#define WINSTA_WRITEATTRIBUTES (0x10L)
-
-#define DF_ALLOWOTHERACCOUNTHOOK       (0x1L)
-#define DESKTOP_CREATEMENU     (0x4L)
-#define DESKTOP_CREATEWINDOW   (0x2L)
-#define DESKTOP_ENUMERATE      (0x40L)
-#define DESKTOP_HOOKCONTROL    (0x8L)
-#define DESKTOP_JOURNALPLAYBACK        (0x20L)
-#define DESKTOP_JOURNALRECORD  (0x10L)
-#define DESKTOP_READOBJECTS    (0x1L)
-#define DESKTOP_SWITCHDESKTOP  (0x100L)
-#define DESKTOP_WRITEOBJECTS   (0x80L)
-
 POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL;
 POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
 
 static GENERIC_MAPPING ExpWindowStationMapping = {
-  STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE |  WINSTA_READATTRIBUTES | WINSTA_READSCREEN,
-  STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES,
-  STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS,
-  STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP |
-                             WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |
-                             WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES
+    
+    STANDARD_RIGHTS_READ     | WINSTA_ENUMDESKTOPS      | WINSTA_ENUMERATE         | WINSTA_READATTRIBUTES | WINSTA_READSCREEN,
+    STANDARD_RIGHTS_WRITE    | WINSTA_ACCESSCLIPBOARD   | WINSTA_CREATEDESKTOP     | WINSTA_WRITEATTRIBUTES,
+    STANDARD_RIGHTS_EXECUTE  | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS,
+    STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD   | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP  |
+                               WINSTA_ENUMDESKTOPS      | WINSTA_ENUMERATE         | WINSTA_EXITWINDOWS    |
+                               WINSTA_READATTRIBUTES    | WINSTA_READSCREEN        | WINSTA_WRITEATTRIBUTES
 };
 
 static GENERIC_MAPPING ExpDesktopMapping = {
-  STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS,
-  STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL |
-                          DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS,
-  STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP,
-  STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE |
-                             DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
-                             DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS
+    
+    STANDARD_RIGHTS_READ     | DESKTOP_ENUMERATE       | DESKTOP_READOBJECTS,
+    STANDARD_RIGHTS_WRITE    | DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW    | DESKTOP_HOOKCONTROL   |
+                               DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD   | DESKTOP_WRITEOBJECTS,
+    STANDARD_RIGHTS_EXECUTE  | DESKTOP_SWITCHDESKTOP,
+    STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW    | DESKTOP_ENUMERATE     |
+                               DESKTOP_HOOKCONTROL     | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
+                               DESKTOP_READOBJECTS     | DESKTOP_SWITCHDESKTOP   | DESKTOP_WRITEOBJECTS
 };
 
-/* FUNCTIONS ****************************************************************/
+OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate = NULL;
+OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse = NULL;
+OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete = NULL;
+OBJECT_FIND_ROUTINE ExpWindowStationObjectFind = NULL;
+OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate = NULL;
+OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete = NULL;
 
+/* FUNCTIONS ****************************************************************/
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 ExpWinStaObjectCreate(PVOID ObjectBody,
-                     PVOID Parent,
-                     PWSTR RemainingPath,
-                     struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+                      PVOID Parent,
+                      PWSTR RemainingPath,
+                      struct _OBJECT_ATTRIBUTES* ObjectAttributes)
 {
-  PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
-  UNICODE_STRING UnicodeString;
-  NTSTATUS Status;
-
-  if (RemainingPath == NULL)
-       {
-               return STATUS_SUCCESS;
-       }
-
-  if (wcschr((RemainingPath + 1), '\\') != NULL)
-       {
-               return STATUS_UNSUCCESSFUL;
-       }
-
-  RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
-
-  DPRINT("Creating window station (0x%X)  Name (%wZ)\n", WinSta, &UnicodeString);
-
-  Status = RtlpCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer, NonPagedPool);
-  if (!NT_SUCCESS(Status))
-  {
-    return Status;
-  }
-
-  KeInitializeSpinLock(&WinSta->Lock);
-
-  InitializeListHead(&WinSta->DesktopListHead);
-
-#if 1
-  WinSta->AtomTable = NULL;
-#endif
-
-  Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
-  if (!NT_SUCCESS(Status))
-  {
-    RtlFreeUnicodeString(&WinSta->Name);
-    return Status;
-  }
-
-  WinSta->SystemMenuTemplate = (HANDLE)0;
-
-  DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
-
-  return STATUS_SUCCESS;
+    /* Call the Registered Callback */
+    return ExpWindowStationObjectCreate(ObjectBody, 
+                                        Parent, 
+                                        RemainingPath, 
+                                        ObjectAttributes);
 }
 
-VOID STDCALL
+VOID 
+STDCALL
 ExpWinStaObjectDelete(PVOID DeletedObject)
 {
-  PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject;
-
-  DPRINT("Deleting window station (0x%X)\n", WinSta);
-
-  RtlDestroyAtomTable(WinSta->AtomTable);
-
-  RtlFreeUnicodeString(&WinSta->Name);
+    /* Call the Registered Callback */
+    ExpWindowStationObjectDelete(DeletedObject);
 }
 
 PVOID
+STDCALL
 ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject,
-                   PWSTR Name,
-                   ULONG Attributes)
+                    PWSTR Name,
+                    ULONG Attributes)
 {
-  PLIST_ENTRY Current;
-  PDESKTOP_OBJECT CurrentObject;
-
-  DPRINT("WinStaObject (0x%X)  Name (%wS)\n", WinStaObject, Name);
-
-  if (Name[0] == 0)
-  {
-    return NULL;
-  }
-
-  Current = WinStaObject->DesktopListHead.Flink;
-  while (Current != &WinStaObject->DesktopListHead)
-  {
-    CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
-    DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
-    if (Attributes & OBJ_CASE_INSENSITIVE)
-    {
-      if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
-      {
-        DPRINT("Found desktop at (0x%X)\n", CurrentObject);
-        return CurrentObject;
-      }
-    }
-    else
-    {
-      if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
-      {
-        DPRINT("Found desktop at (0x%X)\n", CurrentObject);
-        return CurrentObject;
-      }
-    }
-    Current = Current->Flink;
-  }
-
-  DPRINT("Returning NULL\n");
-
-  return NULL;
+    /* Call the Registered Callback */
+    return ExpWindowStationObjectFind(WinStaObject, 
+                                      Name, 
+                                      Attributes);
 }
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 ExpWinStaObjectParse(PVOID Object,
-                    PVOID *NextObject,
-                    PUNICODE_STRING FullPath,
-                    PWSTR *Path,
-                    ULONG Attributes)
+                     PVOID *NextObject,
+                     PUNICODE_STRING FullPath,
+                     PWSTR *Path,
+                     ULONG Attributes)
 {
-  PVOID FoundObject;
-  NTSTATUS Status;
-  PWSTR End;
-
-  DPRINT("Object (0x%X)  Path (0x%X)  *Path (%wS)\n", Object, Path, *Path);
-
-  *NextObject = NULL;
-
-  if ((Path == NULL) || ((*Path) == NULL))
-  {
-    return STATUS_SUCCESS;
-  }
-
-  End = wcschr((*Path) + 1, '\\');
-  if (End != NULL)
-  {
-    DPRINT("Name contains illegal characters\n");
-    return STATUS_UNSUCCESSFUL;
-  }
-
-  FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes);
-  if (FoundObject == NULL)
-  {
-    DPRINT("Name was not found\n");
-    return STATUS_UNSUCCESSFUL;
-  }
-
-  Status = ObReferenceObjectByPointer(
-    FoundObject,
-    STANDARD_RIGHTS_REQUIRED,
-    NULL,
-    UserMode);
-
-  *NextObject = FoundObject;
-  *Path = NULL;
-
-  return Status;
+    /* Call the Registered Callback */
+    return ExpWindowStationObjectParse(Object, 
+                                       NextObject, 
+                                       FullPath, 
+                                       Path,
+                                       Attributes);
 }
 
-NTSTATUS STDCALL
-ExpDesktopObjectCreate(PVOID ObjectBody,
-                      PVOID Parent,
-                      PWSTR RemainingPath,
-                      struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+NTSTATUS 
+STDCALL
+ExpDesktopCreate(PVOID ObjectBody,
+                       PVOID Parent,
+                       PWSTR RemainingPath,
+                       struct _OBJECT_ATTRIBUTES* ObjectAttributes)
 {
-  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
-  UNICODE_STRING UnicodeString;
-
-  if (RemainingPath == NULL)
-       {
-               return STATUS_SUCCESS;
-       }
-
-  if (wcschr((RemainingPath + 1), '\\') != NULL)
-       {
-               return STATUS_UNSUCCESSFUL;
-       }
-
-  RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
-
-  DPRINT("Creating desktop (0x%X)  Name (%wZ)\n", Desktop, &UnicodeString);
-
-  KeInitializeSpinLock(&Desktop->Lock);
-
-  Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
-
-  /* Put the desktop on the window station's list of associcated desktops */
-  ExInterlockedInsertTailList(
-    &Desktop->WindowStation->DesktopListHead,
-    &Desktop->ListEntry,
-    &Desktop->WindowStation->Lock);
-
-  return RtlpCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer, NonPagedPool);
+    /* Call the Registered Callback */
+    return ExpDesktopObjectCreate(ObjectBody, 
+                                  Parent, 
+                                  RemainingPath, 
+                                  ObjectAttributes);
 }
 
-VOID STDCALL
-ExpDesktopObjectDelete(PVOID DeletedObject)
+VOID 
+STDCALL
+ExpDesktopDelete(PVOID DeletedObject)
 {
-  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
-  KIRQL OldIrql;
-
-  DPRINT("Deleting desktop (0x%X)\n", Desktop);
-
-  /* Remove the desktop from the window station's list of associcated desktops */
-  KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
-  RemoveEntryList(&Desktop->ListEntry);
-  KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
-
-  RtlFreeUnicodeString(&Desktop->Name);
+    /* Call the Registered Callback */
+    ExpDesktopObjectDelete(DeletedObject);
 }
 
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpWin32kInit(VOID)
 {
-  /* Create window station object type */
-  ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-  if (ExWindowStationObjectType == NULL)
-  {
-    CPRINT("Could not create window station object type\n");
-    KEBUGCHECK(0);
-  }
-
-  ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
-  ExWindowStationObjectType->TotalObjects = 0;
-  ExWindowStationObjectType->TotalHandles = 0;
-  ExWindowStationObjectType->PeakObjects = 0;
-  ExWindowStationObjectType->PeakHandles = 0;
-  ExWindowStationObjectType->PagedPoolCharge = 0;
-  ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT);
-  ExWindowStationObjectType->Mapping = &ExpWindowStationMapping;
-  ExWindowStationObjectType->Dump = NULL;
-  ExWindowStationObjectType->Open = NULL;
-  ExWindowStationObjectType->Close = NULL;
-  ExWindowStationObjectType->Delete = ExpWinStaObjectDelete;
-  ExWindowStationObjectType->Parse = ExpWinStaObjectParse;
-  ExWindowStationObjectType->Security = NULL;
-  ExWindowStationObjectType->QueryName = NULL;
-  ExWindowStationObjectType->OkayToClose = NULL;
-  ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
-  ExWindowStationObjectType->DuplicationNotify = NULL;
-  RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation");
-
-  ObpCreateTypeObject(ExWindowStationObjectType);
-
-  /* Create desktop object type */
-  ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-  if (ExDesktopObjectType == NULL)
-  {
-    CPRINT("Could not create desktop object type\n");
-    KEBUGCHECK(0);
-  }
-
-  ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K');
-  ExDesktopObjectType->TotalObjects = 0;
-  ExDesktopObjectType->TotalHandles = 0;
-  ExDesktopObjectType->PeakObjects = 0;
-  ExDesktopObjectType->PeakHandles = 0;
-  ExDesktopObjectType->PagedPoolCharge = 0;
-  ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT);
-  ExDesktopObjectType->Mapping = &ExpDesktopMapping;
-  ExDesktopObjectType->Dump = NULL;
-  ExDesktopObjectType->Open = NULL;
-  ExDesktopObjectType->Close = NULL;
-  ExDesktopObjectType->Delete = ExpDesktopObjectDelete;
-  ExDesktopObjectType->Parse = NULL;
-  ExDesktopObjectType->Security = NULL;
-  ExDesktopObjectType->QueryName = NULL;
-  ExDesktopObjectType->OkayToClose = NULL;
-  ExDesktopObjectType->Create = ExpDesktopObjectCreate;
-  ExDesktopObjectType->DuplicationNotify = NULL;
-  RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop");
-
-  ObpCreateTypeObject(ExDesktopObjectType);
+    /* Create window station object type */
+    ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+    ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S');
+    ExWindowStationObjectType->TotalObjects = 0;
+    ExWindowStationObjectType->TotalHandles = 0;
+    ExWindowStationObjectType->PeakObjects = 0;
+    ExWindowStationObjectType->PeakHandles = 0;
+    ExWindowStationObjectType->PagedPoolCharge = 0;
+    ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT);
+    ExWindowStationObjectType->Mapping = &ExpWindowStationMapping;
+    ExWindowStationObjectType->Dump = NULL;
+    ExWindowStationObjectType->Open = NULL;
+    ExWindowStationObjectType->Close = NULL;
+    ExWindowStationObjectType->Delete = ExpWinStaObjectDelete;
+    ExWindowStationObjectType->Parse = ExpWinStaObjectParse;
+    ExWindowStationObjectType->Security = NULL;
+    ExWindowStationObjectType->QueryName = NULL;
+    ExWindowStationObjectType->OkayToClose = NULL;
+    ExWindowStationObjectType->Create = ExpWinStaObjectCreate;
+    ExWindowStationObjectType->DuplicationNotify = NULL;
+    RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation");
+    ObpCreateTypeObject(ExWindowStationObjectType);
+
+    /* Create desktop object type */
+    ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+    ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K');
+    ExDesktopObjectType->TotalObjects = 0;
+    ExDesktopObjectType->TotalHandles = 0;
+    ExDesktopObjectType->PeakObjects = 0;
+    ExDesktopObjectType->PeakHandles = 0;
+    ExDesktopObjectType->PagedPoolCharge = 0;
+    ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT);
+    ExDesktopObjectType->Mapping = &ExpDesktopMapping;
+    ExDesktopObjectType->Dump = NULL;
+    ExDesktopObjectType->Open = NULL;
+    ExDesktopObjectType->Close = NULL;
+    ExDesktopObjectType->Delete = ExpDesktopDelete;
+    ExDesktopObjectType->Parse = NULL;
+    ExDesktopObjectType->Security = NULL;
+    ExDesktopObjectType->QueryName = NULL;
+    ExDesktopObjectType->OkayToClose = NULL;
+    ExDesktopObjectType->Create = ExpDesktopCreate;
+    ExDesktopObjectType->DuplicationNotify = NULL;
+    RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop");
+    ObpCreateTypeObject(ExDesktopObjectType);
 }
 
 /* EOF */
index 8d7bac1..0a5f82f 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:          See COPYING in the top level directory
  * PROJECT:            ReactOS kernel
  * FILE:               ntoskrnl/ex/work.c
  * PURPOSE:            Manage system work queues
  * 
- * PROGRAMMERS:        David Welch (welch@mcmail.com)
+ * PROGRAMMERS:        Alex Ionescu - Used correct work queue array and added some fixes and checks.
+ *                     Gunnar Dalsnes - Implemented
  */
 
 /* INCLUDES ******************************************************************/
 /*
  * PURPOSE: Queue of items waiting to be processed at normal priority
  */
-KQUEUE EiNormalWorkQueue;
-
-KQUEUE EiCriticalWorkQueue;
-
-KQUEUE EiHyperCriticalWorkQueue;
+EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
 
 /* FUNCTIONS ****************************************************************/
 
-//static NTSTATUS STDCALL
-static VOID STDCALL
-ExWorkerThreadEntryPoint(IN PVOID context)
 /*
  * FUNCTION: Entry point for a worker thread
  * ARGUMENTS:
@@ -44,138 +37,138 @@ ExWorkerThreadEntryPoint(IN PVOID context)
  * NOTE: To kill a worker thread you must queue an item whose callback
  * calls PsTerminateSystemThread
  */
+static
+VOID 
+STDCALL
+ExpWorkerThreadEntryPoint(IN PVOID Context)
 {
-
-   PWORK_QUEUE_ITEM item;
-   PLIST_ENTRY current;
+    PWORK_QUEUE_ITEM WorkItem;
+    PLIST_ENTRY QueueEntry;
+    WORK_QUEUE_TYPE WorkQueueType;
+    PEX_WORK_QUEUE WorkQueue;
    
-   while (TRUE) 
-   {
-      current = KeRemoveQueue( (PKQUEUE)context, KernelMode, NULL );
-      
-      /* can't happend since we do a KernelMode wait (and we're a system thread) */
-      ASSERT((NTSTATUS)current != STATUS_USER_APC);
-      
-      /* this should never happend either, since we wait with NULL timeout,
-       * but there's a slight possibility that STATUS_TIMEOUT is returned
-       * at queue rundown in NT (unlikely) -Gunnar
-       */
-      ASSERT((NTSTATUS)current != STATUS_TIMEOUT);
-      
-      /* based on INVALID_WORK_QUEUE_ITEM bugcheck desc. */
-      if (current->Flink == NULL || current->Blink == NULL)
-      {
-         KeBugCheck(INVALID_WORK_QUEUE_ITEM);
-      }
-      
-      /* "reinitialize" item (same as done in ExInitializeWorkItem) */
-      current->Flink = NULL;
+    /* Get Queue Type and Worker Queue */
+    WorkQueueType = (WORK_QUEUE_TYPE)Context;
+    WorkQueue = &ExWorkerQueue[WorkQueueType];
+    
+    /* Loop forever */
+    while (TRUE) {
+        
+        /* Wait for Something to Happen on the Queue */
+        QueueEntry = KeRemoveQueue(&WorkQueue->WorkerQueue, KernelMode, NULL);
       
-      item = CONTAINING_RECORD( current, WORK_QUEUE_ITEM, List);
-      item->WorkerRoutine(item->Parameter);
+        /* Can't happen since we do a KernelMode wait (and we're a system thread) */
+        ASSERT((NTSTATUS)QueueEntry != STATUS_USER_APC);
       
-      if (KeGetCurrentIrql() != PASSIVE_LEVEL)
-      {
-         KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
-      }
-   }
-   
+        /* this should never happen either, since we wait with NULL timeout,
+         * but there's a slight possibility that STATUS_TIMEOUT is returned
+         * at queue rundown in NT (unlikely) -Gunnar
+         */
+        ASSERT((NTSTATUS)QueueEntry != STATUS_TIMEOUT);
+    
+        /* Increment Processed Work Items */
+        InterlockedIncrement(&WorkQueue->WorkItemsProcessed);
+
+        /* Get the Work Item */
+        WorkItem = CONTAINING_RECORD(QueueEntry, WORK_QUEUE_ITEM, List);
+        
+        /* Call the Worker Routine */
+        WorkItem->WorkerRoutine(WorkItem->Parameter);
+    
+        /* Make sure it returned at right IRQL */
+        if (KeGetCurrentIrql() != PASSIVE_LEVEL) {
+        
+            /* FIXME: Make this an Ex */
+            KEBUGCHECK(WORKER_THREAD_RETURNED_AT_BAD_IRQL);
+        }
+    
+        /* Make sure it returned with Impersionation Disabled */
+        if (PsGetCurrentThread()->ActiveImpersonationInfo) {
+            
+            /* FIXME: Make this an Ex */
+            KEBUGCHECK(IMPERSONATING_WORKER_THREAD);
+        }
+    }
 }
 
-static VOID ExInitializeWorkQueue(PKQUEUE WorkQueue,
-                                 KPRIORITY Priority)
+static 
+VOID 
+STDCALL
+ExpInitializeWorkQueue(WORK_QUEUE_TYPE WorkQueueType,
+                       KPRIORITY Priority)
 {
-   ULONG i;
-   PETHREAD Thread;
-   HANDLE   hThread;
+    ULONG i;
+    PETHREAD Thread;
+    HANDLE hThread;
    
-   
-   for (i=0; i<NUMBER_OF_WORKER_THREADS; i++)
-     {
+    /* Loop through how many threads we need to create */
+    for (i = 0; i < NUMBER_OF_WORKER_THREADS; i++) {
+        
+        /* Create the System Thread */
+        PsCreateSystemThread(&hThread,
+                             THREAD_ALL_ACCESS,
+                             NULL,
+                             NULL,
+                             NULL,
+                             ExpWorkerThreadEntryPoint,
+                             (PVOID)WorkQueueType);
+        
+        /* Get the Thread */
+        ObReferenceObjectByHandle(hThread,
+                                  THREAD_SET_INFORMATION,
+                                  PsThreadType,
+                                  KernelMode,
+                                  (PVOID*)&Thread,
+                                  NULL);
+        
+        /* Set the Priority */
+        KeSetPriorityThread(&Thread->Tcb, Priority);
         
-   PsCreateSystemThread(&hThread,
-                            THREAD_ALL_ACCESS,
-                            NULL,
-                            NULL,
-                            NULL,
-                            ExWorkerThreadEntryPoint,
-              WorkQueue);
-   ObReferenceObjectByHandle(hThread,
-                                 THREAD_ALL_ACCESS,
-                                 PsThreadType,
-                                 KernelMode,
-                                 (PVOID*)&Thread,
-                                 NULL);
-       KeSetPriorityThread(&Thread->Tcb,
-                           Priority);
-       ObDereferenceObject(Thread);
-   ZwClose(hThread);
-     }
+        /* Dereference and close handle */
+        ObDereferenceObject(Thread);
+        ZwClose(hThread);
+    }
 }
 
-VOID INIT_FUNCTION
-ExInitializeWorkerThreads(VOID)
+VOID 
+INIT_FUNCTION
+ExpInitializeWorkerThreads(VOID)
 {
-   KeInitializeQueue( &EiNormalWorkQueue, NUMBER_OF_WORKER_THREADS );
-   KeInitializeQueue( &EiCriticalWorkQueue , NUMBER_OF_WORKER_THREADS );
-   KeInitializeQueue( &EiHyperCriticalWorkQueue , NUMBER_OF_WORKER_THREADS );
-
-   ExInitializeWorkQueue(&EiNormalWorkQueue,
-                        LOW_PRIORITY);
-   ExInitializeWorkQueue(&EiCriticalWorkQueue,
-                        LOW_REALTIME_PRIORITY);
-   ExInitializeWorkQueue(&EiHyperCriticalWorkQueue,
-                        HIGH_PRIORITY);
+    ULONG WorkQueueType;
+    
+    /* Initialize the Array */
+    for (WorkQueueType = 0; WorkQueueType < MaximumWorkQueue; WorkQueueType++) {
+    
+        RtlZeroMemory(&ExWorkerQueue[WorkQueueType], sizeof(EX_WORK_QUEUE));
+        KeInitializeQueue(&ExWorkerQueue[WorkQueueType].WorkerQueue, 0);
+    }
+    
+    /* Create the built-in worker threads for each work queue */
+    ExpInitializeWorkQueue(CriticalWorkQueue, LOW_REALTIME_PRIORITY);
+    ExpInitializeWorkQueue(DelayedWorkQueue, LOW_PRIORITY);
+    ExpInitializeWorkQueue(HyperCriticalWorkQueue, HIGH_PRIORITY);
 }
 
 /*
  * @implemented
- */
-VOID STDCALL
-ExQueueWorkItem (PWORK_QUEUE_ITEM      WorkItem,
-                WORK_QUEUE_TYPE                QueueType)
-/*
+ *
  * FUNCTION: Inserts a work item in a queue for one of the system worker
  * threads to process
  * ARGUMENTS:
  *        WorkItem = Item to insert
  *        QueueType = Queue to insert it in
  */
+VOID 
+STDCALL
+ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem,
+                WORK_QUEUE_TYPE QueueType)
 {
     ASSERT(WorkItem!=NULL);
     ASSERT_IRQL(DISPATCH_LEVEL);
     ASSERT(WorkItem->List.Flink == NULL);
-   /*
-    * Insert the item in the appropiate queue and wake up any thread
-    * waiting for something to do
-    */
-    switch(QueueType)
-    {
-    case DelayedWorkQueue:
-      KeInsertQueue (
-          &EiNormalWorkQueue,
-          &WorkItem->List
-            );
-       break;
-       
-    case CriticalWorkQueue:
-            KeInsertQueue (
-              &EiCriticalWorkQueue,
-              &WorkItem->List
-              );
-           break;
-
-    case HyperCriticalWorkQueue:
-            KeInsertQueue (
-             &EiHyperCriticalWorkQueue,
-             &WorkItem->List
-             );
-               break;
-     
-    default:
-        break;
-
-    }
+    
+    /* Insert the Queue */
+    KeInsertQueue(&ExWorkerQueue[QueueType].WorkerQueue, &WorkItem->List);
 }
 
 /* EOF */
index 837ed5a..8a84e77 100644 (file)
@@ -23,7 +23,6 @@ typedef struct _NOTIFY_ENTRY
    LIST_ENTRY ListEntry;
    PSTRING FullDirectoryName;
    BOOLEAN WatchTree;
-   BOOLEAN IgnoreBuffer;
    BOOLEAN PendingChanges;
    ULONG CompletionFilter;
    LIST_ENTRY IrpQueue;
@@ -395,7 +394,7 @@ FsRtlNotifyFullChangeDirectory (
    IN BOOLEAN           WatchTree,
    IN BOOLEAN           IgnoreBuffer,
    IN ULONG          CompletionFilter,
-   IN PIRP           NotifyIrp,
+   IN PIRP           Irp,
    IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback  OPTIONAL,
        IN      PSECURITY_SUBJECT_CONTEXT       SubjectContext          OPTIONAL
        )
@@ -404,7 +403,7 @@ FsRtlNotifyFullChangeDirectory (
    PNOTIFY_ENTRY NotifyEntry;
    ULONG IrpBuffLen;
    
-   if (!NotifyIrp)
+   if (!Irp)
    {
       /* all other params are ignored if NotifyIrp == NULL */
       FsRtlpWatchedDirectoryWasDeleted(NotifySync, NotifyList, FsContext);
@@ -415,14 +414,14 @@ FsRtlNotifyFullChangeDirectory (
    
    ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
    
-   IrpStack = IoGetCurrentIrpStackLocation(NotifyIrp);
+   IrpStack = IoGetCurrentIrpStackLocation(Irp);
    if (IrpStack->FileObject->Flags & FO_CLEANUP_COMPLETE)
    {
       ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
       
-      NotifyIrp->IoStatus.Information = 0;
-      NotifyIrp->IoStatus.Status = STATUS_NOTIFY_CLEANUP;
-      IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
+      Irp->IoStatus.Information = 0;
+      Irp->IoStatus.Status = STATUS_NOTIFY_CLEANUP;
+      IoCompleteRequest(Irp, IO_NO_INCREMENT);
       return;       
    }
    
@@ -463,12 +462,13 @@ FsRtlNotifyFullChangeDirectory (
                FSRTL_NOTIFY_TAG
                );
                
-            NotifyEntry->PrevEntry = NotifyEntry->Buffer;   
             NotifyEntry->BufferSize = IrpBuffLen;
          }
          _SEH_HANDLE
          {
-            /* ExAllocatePoolWithQuotaTag raised exception */
+            /* ExAllocatePoolWithQuotaTag raised exception but we dont care.
+               The impl. doesnt require a buffer, so well continue as usual.
+            */
          }
          _SEH_END;
       }
@@ -485,26 +485,29 @@ FsRtlNotifyFullChangeDirectory (
       /* No changes are pending. Queue the irp */
 
       /* Irp cancelation boilerplate */
-      IoSetCancelRoutine(NotifyIrp, FsRtlpNotifyCancelRoutine);
-      if (NotifyIrp->Cancel && IoSetCancelRoutine(NotifyIrp, NULL))
+      
+      /* save NotifySych for use in the cancel routine */
+      Irp->Tail.Overlay.DriverContext[3] = NotifySync;
+
+      IoSetCancelRoutine(Irp, FsRtlpNotifyCancelRoutine);
+      if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
       {              
          //irp was canceled
          ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
 
-         NotifyIrp->IoStatus.Status = STATUS_CANCELLED;
-         NotifyIrp->IoStatus.Information = 0;
+         Irp->IoStatus.Status = STATUS_CANCELLED;
+         Irp->IoStatus.Information = 0;
 
-         IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
          return;
       }
 
-      IoMarkIrpPending(NotifyIrp);
+      IoMarkIrpPending(Irp);
 
       //FIXME: any point in setting irp status/information before queueing?
+      Irp->IoStatus.Status = STATUS_PENDING;
       
-      /* save NotifySych for use in the cancel routine */
-      NotifyIrp->Tail.Overlay.DriverContext[3] = NotifySync;
-      InsertTailList(&NotifyEntry->IrpQueue, &NotifyIrp->Tail.Overlay.ListEntry);
+      InsertTailList(&NotifyEntry->IrpQueue, &Irp->Tail.Overlay.ListEntry);
 
       ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
       return;
@@ -524,24 +527,29 @@ FsRtlNotifyFullChangeDirectory (
       -Current irp buff was not large enough
       */
      
-      NotifyIrp->IoStatus.Information = 0;
-      NotifyIrp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR;
+      Irp->IoStatus.Information = 0;
+      Irp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR;
 
    }
    else
    {
-      /* terminate last entry */
-      NotifyEntry->PrevEntry->NextEntryOffset = 0;
-      
-      //FIXME: copy data correctly to user
-      memcpy(NotifyIrp->UserBuffer, NotifyEntry->Buffer, NotifyEntry->NextEntryOffset);
+      PVOID Adr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
+
+      if (Adr)
+      {
+         memcpy(Adr, NotifyEntry->Buffer, NotifyEntry->NextEntryOffset);
+         Irp->IoStatus.Information = NotifyEntry->NextEntryOffset;
+      }
+      else
+      {
+         Irp->IoStatus.Information = 0;
+      }
 
-      NotifyIrp->IoStatus.Information = NotifyEntry->NextEntryOffset;
-      NotifyIrp->IoStatus.Status = STATUS_SUCCESS;
+      Irp->IoStatus.Status = STATUS_SUCCESS;
    }
    
    /* reset buffer */
-   NotifyEntry->PrevEntry = NotifyEntry->Buffer; 
+   NotifyEntry->PrevEntry = NULL;
    NotifyEntry->NextEntryOffset = 0;
    NotifyEntry->BufferExhausted = FALSE;
    
@@ -549,7 +557,9 @@ FsRtlNotifyFullChangeDirectory (
 
    ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
    
-   IoCompleteRequest(NotifyIrp, IO_NO_INCREMENT);
+   IoCompleteRequest(Irp, IO_NO_INCREMENT);
+   
+   /* caller must return STATUS_PENDING */
 }
 
 
@@ -671,13 +681,17 @@ FsRtlNotifyFullReportChange (
    LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
    {
       ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName));
-         
+      
       /* rule out some easy cases */
-      /* FIXME: short vs. long names??? */
+      /* FIXME: short vs. long names??? lower case/upper case/mixed case? */
       if (!(FilterMatch & NotifyEntry->CompletionFilter)) continue;
       
-      FullDirLen = TargetNameOffset - (NotifyEntry->Unicode?sizeof(WCHAR):sizeof(char));
-      
+      FullDirLen = TargetNameOffset - (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
+      if (FullDirLen == 0)
+      {
+         /* special case for root dir */
+         FullDirLen = (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
+      }
       
       if (FullDirLen < NotifyEntry->FullDirectoryName->Length) continue;
       
@@ -685,6 +699,7 @@ FsRtlNotifyFullReportChange (
 
       DPRINT("NotifyEntry->FullDirectoryName: %wZ\n", NotifyEntry->FullDirectoryName);
       
+      /* FIXME: short vs. long names??? lower case/upper case/mixed case? */
       if (memcmp(NotifyEntry->FullDirectoryName->Buffer, 
             FullTargetName->Buffer, 
             NotifyEntry->FullDirectoryName->Length) != 0) continue;
@@ -751,22 +766,31 @@ FsRtlNotifyFullReportChange (
          }
          else
          {
-            //FIXME: copy data to user correctly
-            CurrentEntry = (PFILE_NOTIFY_INFORMATION)Irp->UserBuffer;
+            CurrentEntry = (PFILE_NOTIFY_INFORMATION)            
+               MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
+               
+            if (CurrentEntry)
+            {
+               CurrentEntry->Action = Action; 
+               CurrentEntry->NameLength = NameLenU;
+               CurrentEntry->NextEntryOffset = 0;
+
+               FsRtlpCopyName(
+                     CurrentEntry,
+                     NotifyEntry->Unicode,
+                     &RelativeName,
+                     StreamName
+                     );
+               
+               Irp->IoStatus.Information = RecordLen;
+            }
+            else
+            {
+               Irp->IoStatus.Information = 0;
+            }
             
-            CurrentEntry->Action = Action; 
-            CurrentEntry->NameLength = NameLenU;
-            CurrentEntry->NextEntryOffset = 0;
-
-            FsRtlpCopyName(
-                  CurrentEntry,
-                  NotifyEntry->Unicode,
-                  &RelativeName,
-                  StreamName
-                  );
 
             Irp->IoStatus.Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = RecordLen;
          }
          
          /* avoid holding lock while completing irp */
@@ -803,8 +827,10 @@ FsRtlNotifyFullReportChange (
                       StreamName
                       );
          
-         /* adjust buffer */
-         NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry;
+         if (NotifyEntry->PrevEntry)
+         {
+            NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry;
+         }
          NotifyEntry->PrevEntry = CurrentEntry;
          NotifyEntry->NextEntryOffset += RecordLen;
  
index ce8c2f5..3132413 100644 (file)
 /* Assert only on "checked" version */
 #ifndef NASSERT
 #ifdef CONFIG_SMP
-#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); }
-#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); }
+#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); }
+#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); }
 #else
-#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
-#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
+#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); }
+#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); }
 #endif
 
 #define assertmsg(_c_, _m_) \
index 3596bfe..4fe107e 100644 (file)
@@ -68,6 +68,8 @@ typedef struct _DESKTOP_OBJECT
   HANDLE PrevActiveWindow;
   /* Thread blocking input */
   PVOID BlockInputThread;
+
+  LIST_ENTRY ShellHookWindows;
 } DESKTOP_OBJECT, *PDESKTOP_OBJECT;
 
 
@@ -84,7 +86,9 @@ extern LARGE_INTEGER ExpTimeZoneBias;
 extern ULONG ExpTimeZoneId;
 
 extern POBJECT_TYPE ExEventPairObjectType;
-
+extern POBJECT_TYPE EXPORTED ExMutantObjectType;
+extern POBJECT_TYPE EXPORTED ExSemaphoreObjectType;
+extern POBJECT_TYPE EXPORTED ExTimerType;
 
 /* INITIALIZATION FUNCTIONS *************************************************/
 
@@ -98,23 +102,77 @@ ExInit3(VOID);
 VOID
 ExpInitTimeZoneInfo(VOID);
 VOID
-ExInitializeWorkerThreads(VOID);
+ExpInitializeWorkerThreads(VOID);
 VOID
 ExpInitLookasideLists(VOID);
 VOID
 ExpInitializeCallbacks(VOID);
 VOID
 ExpInitUuids(VOID);
+VOID
+STDCALL
+ExpInitializeExecutive(VOID);
 
-/* OTHER FUNCTIONS **********************************************************/
+/* HANDLE TABLE FUNCTIONS ***************************************************/
+
+#define EX_HANDLE_ENTRY_LOCKED (1 << ((sizeof(PVOID) * 8) - 1))
+#define EX_HANDLE_ENTRY_PROTECTFROMCLOSE (1 << 0)
+#define EX_HANDLE_ENTRY_INHERITABLE (1 << 1)
+#define EX_HANDLE_ENTRY_AUDITONCLOSE (1 << 2)
+
+#define EX_HANDLE_TABLE_CLOSING 0x1
+
+#define EX_INVALID_HANDLE (~0)
+
+#define EX_HANDLE_ENTRY_FLAGSMASK (EX_HANDLE_ENTRY_LOCKED |                    \
+                                   EX_HANDLE_ENTRY_PROTECTFROMCLOSE |          \
+                                   EX_HANDLE_ENTRY_INHERITABLE |               \
+                                   EX_HANDLE_ENTRY_AUDITONCLOSE)
 
-#ifdef _ENABLE_THRDEVTPAIR
+typedef VOID (STDCALL PEX_DESTROY_HANDLE_CALLBACK)(PHANDLE_TABLE HandleTable, PVOID Object, ULONG GrantedAccess, PVOID Context);
+typedef BOOLEAN (STDCALL PEX_DUPLICATE_HANDLE_CALLBACK)(PHANDLE_TABLE HandleTable, PHANDLE_TABLE_ENTRY HandleTableEntry, PVOID Context);
+typedef BOOLEAN (STDCALL PEX_CHANGE_HANDLE_CALLBACK)(PHANDLE_TABLE HandleTable, PHANDLE_TABLE_ENTRY HandleTableEntry, PVOID Context);
+
+VOID
+ExpInitializeHandleTables(VOID);
+PHANDLE_TABLE
+ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL);
+VOID
+ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
+                     IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback  OPTIONAL,
+                     IN PVOID Context  OPTIONAL);
+PHANDLE_TABLE
+ExDupHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL,
+                 IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback  OPTIONAL,
+                 IN PVOID Context  OPTIONAL,
+                 IN PHANDLE_TABLE SourceHandleTable);
+BOOLEAN
+ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                       IN PHANDLE_TABLE_ENTRY Entry);
+VOID
+ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable,
+                         IN PHANDLE_TABLE_ENTRY Entry);
+LONG
+ExCreateHandle(IN PHANDLE_TABLE HandleTable,
+               IN PHANDLE_TABLE_ENTRY Entry);
+BOOLEAN
+ExDestroyHandle(IN PHANDLE_TABLE HandleTable,
+                IN LONG Handle);
 VOID
-ExpSwapThreadEventPair(
-       IN struct _ETHREAD* Thread,
-       IN struct _KEVENT_PAIR* EventPair
-       );
-#endif /* _ENABLE_THRDEVTPAIR */
+ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable,
+                       IN PHANDLE_TABLE_ENTRY Entry,
+                       IN LONG Handle);
+PHANDLE_TABLE_ENTRY
+ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable,
+                     IN LONG Handle);
+
+BOOLEAN
+ExChangeHandle(IN PHANDLE_TABLE HandleTable,
+               IN LONG Handle,
+               IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback,
+               IN PVOID Context);
+
+/* OTHER FUNCTIONS **********************************************************/
 
 LONGLONG 
 FASTCALL
@@ -127,6 +185,10 @@ ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation);
 NTSTATUS
 ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);
 
+VOID
+STDCALL
+ExTimerRundown(VOID);
+
 #define InterlockedDecrementUL(Addend) \
    (ULONG)InterlockedDecrement((PLONG)(Addend))
 
index 14475e2..30267a8 100644 (file)
 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_FPU_H
 #define __NTOSKRNL_INCLUDE_INTERNAL_I386_FPU_H
 
+#define FN_CONTROL_WORD        0x0
+#define FN_STATUS_WORD         0x4
+#define FN_TAG_WORD            0x8
+#define FN_DATA_SELECTOR       0x18
+#define FN_CR0_NPX_STATE       0x20C
 #define SIZEOF_FX_SAVE_AREA    528
 
 #ifndef __ASM__
index 06612b5..5efe824 100644 (file)
 #define KTRAP_FRAME_RESERVED9      (0x8A)
 #define KTRAP_FRAME_SIZE           (0x8C)
 
+#define X86_EFLAGS_TF           0x00000100 /* Trap flag */
 #define X86_EFLAGS_IF           0x00000200 /* Interrupt Enable flag */
 #define X86_EFLAGS_IOPL         0x00003000 /* I/O Privilege Level bits */
 #define X86_EFLAGS_NT           0x00004000 /* Nested Task flag */
+#define X86_EFLAGS_RF           0x00010000 /* Resume flag */
 #define X86_EFLAGS_VM           0x00020000 /* Virtual Mode */
 #define X86_EFLAGS_ID           0x00200000 /* CPUID detection flag */
 
@@ -97,6 +99,7 @@
 #define X86_FEATURE_FXSR        0x01000000 /* FXSAVE/FXRSTOR instructions present */
 #define X86_FEATURE_SSE         0x02000000 /* SSE extension present */
 #define X86_FEATURE_SSE2        0x04000000 /* SSE2 extension present */
+#define X86_FEATURE_HT          0x10000000 /* Hyper-Threading present */
 
 #define X86_EXT_FEATURE_SSE3    0x00000001 /* SSE3 extension present */
 #define X86_EXT_FEATURE_3DNOW   0x40000000 /* 3DNOW! extension present */
index f6cf2dc..6eb1c41 100644 (file)
@@ -43,6 +43,7 @@
 #define KPCR_BASE                 0xFF000000
 
 #define KPCR_EXCEPTION_LIST       0x0
+#define KPCR_INITIAL_STACK        0x4
 #define KPCR_SELF                 0x1C
 #define KPCR_TSS                  0x40
 #define KPCR_CURRENT_THREAD       0x124        
@@ -102,7 +103,7 @@ typedef struct _KPRCB {
        ULONG CcCopyReadWait;
        ULONG CcCopyReadNoWaitMiss;
        ULONG KeAlignmentFixupCount;
-       ULONG SpareCounter0;
+       ULONG KeContextSwitches;
        ULONG KeDcacheFlushCount;
        ULONG KeExceptionDispatchCount;
        ULONG KeFirstLevelTbFills;
@@ -217,7 +218,7 @@ typedef struct _KPCR_TIB {
 typedef struct _KPCR {
   KPCR_TIB  Tib;                /* 00 */
   struct _KPCR  *Self;          /* 1C */
-  struct _KPRCB  *PCRCB;        /* 20 */
+  struct _KPRCB  *Prcb;         /* 20 */
   KIRQL  Irql;                  /* 24 */
   ULONG  IRR;                   /* 28 */
   ULONG  IrrActive;             /* 2C */
@@ -269,9 +270,28 @@ static inline PKPCR KeGetCurrentKPCR(VOID)
   return((PKPCR)value);
 }
 
+static inline PKPRCB KeGetCurrentPrcb(VOID)
+{
+  ULONG value;
+
+#if defined(__GNUC__)
+  __asm__ __volatile__ ("movl %%fs:0x20, %0\n\t"
+         : "=r" (value)
+    : /* no inputs */
+    );
+#elif defined(_MSC_VER)
+  __asm mov eax, fs:0x20;
+  __asm mov value, eax;
+#else
+#error Unknown compiler for inline assembler
+#endif
+  return((PKPRCB)value);
+}
+
 #else
 
 #define KeGetCurrentKPCR(X) ((PKPCR)KPCR_BASE)
+#define KeGetCurrentPrcb() (((PKPCR)KPCR_BASE)->Prcb)
 
 #endif
 
diff --git a/reactos/ntoskrnl/include/internal/id.h b/reactos/ntoskrnl/include/internal/id.h
deleted file mode 100644 (file)
index 43a2958..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Structure ids
- */
-
-#define InternalBaseType                      (0xcc)
-#define InternalNotificationEvent             (InternalBaseType + 1)
-#define InternalSynchronizationEvent          (InternalBaseType + 2)
-#define InternalSemaphoreType                 (InternalBaseType + 3)
-#define InternalProcessType                   (InternalBaseType + 4)
-#define InternalThreadType                    (InternalBaseType + 5)
-#define InternalFileType                      (InternalBaseType + 6)
-#define InternalDriverType                    (InternalBaseType + 7)
-#define InternalDeviceType                    (InternalBaseType + 8)
-#define InternalMutexType                     (InternalBaseType + 9)
-#define InternalNotificationTimer             (InternalBaseType + 10)
-#define InternalSynchronizationTimer          (InternalBaseType + 11)
-#define InternalQueueType                     (InternalBaseType + 12)
-
-
index b23f612..3d2c432 100644 (file)
@@ -412,7 +412,7 @@ IoDestroyDriverList(VOID);
 /* bootlog.c */
 
 VOID
-IopInitBootLog(VOID);
+IopInitBootLog(BOOLEAN StartBootLog);
 
 VOID
 IopStartBootLog(VOID);
index 4594dd4..e74855b 100644 (file)
@@ -16,7 +16,7 @@
 #define KD_DEBUG_SCREEN                0x04
 #define KD_DEBUG_SERIAL                0x08
 #define KD_DEBUG_BOCHS         0x10
-#define KD_DEBUG_BOOTLOG       0x20
+#define KD_DEBUG_FILELOG       0x20
 #define KD_DEBUG_MDA            0x40
 #define KD_DEBUG_KDB            0x80
 #define KD_DEBUG_KDSERIAL       0x100
@@ -98,9 +98,6 @@ KdGdbDebugPrint (LPSTR Message);
 VOID
 KdDebugPrint (LPSTR Message);
 
-VOID
-KdbCreateThreadHook(PCONTEXT Context);
-
 KD_CONTINUE_TYPE
 KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
                         PCONTEXT Context,
@@ -110,7 +107,6 @@ VOID KdPrintMda(PCH pch);
 
 #if !defined(KDBG) && !defined(DBG)
 # define KDB_LOADUSERMODULE_HOOK(LDRMOD)       do { } while (0)
-# define KDB_DELETEPROCESS_HOOK(PROCESS)       do { } while (0)
 # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) do { } while (0)
 # define KDB_UNLOADDRIVER_HOOK(MODULE)         do { } while (0)
 # define KDB_LOADERINIT_HOOK(NTOS, HAL)                do { } while (0)
@@ -118,7 +114,6 @@ VOID KdPrintMda(PCH pch);
 # define KDB_CREATE_THREAD_HOOK(CONTEXT)       do { } while (0)
 #else
 # define KDB_LOADUSERMODULE_HOOK(LDRMOD)       KdbSymLoadUserModuleSymbols(LDRMOD)
-# define KDB_DELETEPROCESS_HOOK(PROCESS)       KdbSymFreeProcessSymbols(PROCESS)
 # define KDB_LOADDRIVER_HOOK(FILENAME, MODULE) KdbSymLoadDriverSymbols(FILENAME, MODULE)
 # define KDB_UNLOADDRIVER_HOOK(MODULE)         KdbSymUnloadDriverSymbols(MODULE)
 # define KDB_LOADERINIT_HOOK(NTOS, HAL)                KdbSymInit(NTOS, HAL)
@@ -126,6 +121,7 @@ VOID KdPrintMda(PCH pch);
 /*#define KDB_CREATE_THREAD_HOOK(CONTEXT) \
         KdbCreateThreadHook(CONTEXT)
 */
+
 VOID
 KdbSymLoadUserModuleSymbols(IN PLDR_MODULE LdrModule);
 
@@ -155,10 +151,18 @@ KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
                          KPROCESSOR_MODE PreviousMode,
                           PCONTEXT Context,
                           PKTRAP_FRAME TrapFrame,
-                         BOOLEAN HandleAlways);
+                         BOOLEAN FirstChance);
 
 #endif /* KDBG || DBG */
 
+#if !defined(KDBG)
+# define KDB_DELETEPROCESS_HOOK(PROCESS)       do { } while (0)
+#else
+# define KDB_DELETEPROCESS_HOOK(PROCESS)       KdbDeleteProcessHook(PROCESS)
+VOID
+KdbDeleteProcessHook(IN PEPROCESS Process);
+#endif /* KDBG */
+
 VOID
 DebugLogDumpMessages(VOID);
 
index e9e78f6..305d46f 100644 (file)
@@ -41,11 +41,42 @@ VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2);
 struct _KTHREAD;
 struct _KIRQ_TRAPFRAME;
 struct _KPCR;
+struct _KPRCB;
 struct _KEXCEPTION_FRAME;
 
 #define IPI_REQUEST_FUNCTIONCALL    0
 #define IPI_REQUEST_APC                    1
 #define IPI_REQUEST_DPC                    2
+#define IPI_REQUEST_FREEZE         3
+
+/* threadsch.c ********************************************************************/
+
+/* Thread Scheduler Functions */
+
+/* Readies a Thread for Execution. */
+VOID 
+STDCALL
+KiDispatchThreadNoLock(ULONG NewThreadStatus);
+
+/* Readies a Thread for Execution. */
+VOID 
+STDCALL
+KiDispatchThread(ULONG NewThreadStatus);
+
+/* Puts a Thread into a block state. */
+VOID
+STDCALL
+KiBlockThread(PNTSTATUS Status, 
+              UCHAR Alertable, 
+              ULONG WaitMode,
+              UCHAR WaitReason);
+    
+/* Removes a thread out of a block state. */        
+VOID
+STDCALL
+KiUnblockThread(PKTHREAD Thread, 
+                PNTSTATUS WaitStatus, 
+                KPRIORITY Increment);
 
 /* ipi.c ********************************************************************/
 
@@ -63,60 +94,66 @@ KeIpiGenericCall(VOID (STDCALL *WorkerRoutine)(PVOID),
 
 /* next file ***************************************************************/
 
-typedef struct _KPROCESS_PROFILE
-/*
- * List of the profile data structures associated with a process.
- */
-{
-  LIST_ENTRY ProfileListHead;
-  LIST_ENTRY ListEntry;
-  HANDLE Pid;
-} KPROCESS_PROFILE, *PKPROCESS_PROFILE;
-
-typedef struct _KPROFILE
-/*
- * Describes a contiguous region of process memory that is being profiled.
- */
-{
-  CSHORT Type;
-  CSHORT Name;
-
-  /* Entry in the list of profile data structures for this process. */
-  LIST_ENTRY ListEntry; 
-
-  /* Base of the region being profiled. */
-  PVOID Base;
-
-  /* Size of the region being profiled. */
-  ULONG Size;
-
-  /* Shift of offsets from the region to buckets in the profiling buffer. */
-  ULONG BucketShift;
+typedef struct _KPROFILE_SOURCE_OBJECT {
+    KPROFILE_SOURCE Source;
+    LIST_ENTRY ListEntry;
+} KPROFILE_SOURCE_OBJECT, *PKPROFILE_SOURCE_OBJECT;
+
+typedef struct _KPROFILE {
+    CSHORT Type;
+    CSHORT Size;
+    LIST_ENTRY ListEntry;
+    PVOID RegionStart;
+    PVOID RegionEnd;
+    ULONG BucketShift;
+    PVOID Buffer;
+    CSHORT Source;
+    ULONG Affinity;
+    BOOLEAN Active;
+    struct _KPROCESS *Process;
+} KPROFILE, *PKPROFILE;
 
-  /* MDL which described the buffer that receives profiling data. */
-  struct _MDL *BufferMdl;
+/* Cached modules from the loader block */
+typedef enum _CACHED_MODULE_TYPE {
+    AnsiCodepage,
+    OemCodepage,
+    UnicodeCasemap,
+    SystemRegistry,
+    HardwareRegistry,
+    MaximumCachedModuleType,
+} CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
+extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
 
-  /* System alias for the profiling buffer. */
-  PULONG Buffer;
+VOID STDCALL 
+DbgBreakPointNoBugCheck(VOID);
 
-  /* Size of the buffer for profiling data. */
-  ULONG BufferSize;
+STDCALL
+VOID
+KeInitializeProfile(struct _KPROFILE* Profile,
+                    struct _KPROCESS* Process,
+                    PVOID ImageBase,
+                    ULONG ImageSize,
+                    ULONG BucketSize,
+                    KPROFILE_SOURCE ProfileSource,
+                    KAFFINITY Affinity);
 
-  /* 
-   * Mask of processors for which profiling data should be collected. 
-   * Currently unused.
-   */
-  ULONG ProcessorMask;
+STDCALL
+VOID
+KeStartProfile(struct _KPROFILE* Profile,
+               PVOID Buffer);
 
-  /* TRUE if profiling has been started for this region. */
-  BOOLEAN Started;
+STDCALL
+VOID
+KeStopProfile(struct _KPROFILE* Profile);
 
-  /* Pointer (and reference) to the process which is being profiled. */
-  struct _EPROCESS *Process;
-} KPROFILE, *PKPROFILE;
+STDCALL
+ULONG
+KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource);
 
-VOID STDCALL 
-DbgBreakPointNoBugCheck(VOID);
+STDCALL
+VOID
+KeSetIntervalProfile(KPROFILE_SOURCE ProfileSource,
+                     ULONG Interval);
 
 VOID
 STDCALL
@@ -131,43 +168,91 @@ KeProfileInterruptWithSource(
        IN KPROFILE_SOURCE              Source
 );
 
-VOID KiAddProfileEventToProcess(PLIST_ENTRY ListHead, PVOID Eip);
-VOID KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
-VOID KiInsertProfileIntoProcess(PLIST_ENTRY ListHead, PKPROFILE Profile);
-VOID KiInsertProfile(PKPROFILE Profile);
-VOID KiRemoveProfile(PKPROFILE Profile);
-VOID STDCALL KiDeleteProfile(PVOID ObjectBody);
-
 
 VOID STDCALL KeUpdateSystemTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 
 VOID STDCALL KiExpireTimers(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
 
-KIRQL KeAcquireDispatcherDatabaseLock(VOID);
-VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
-VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
-VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
+KIRQL inline FASTCALL KeAcquireDispatcherDatabaseLock(VOID);
+VOID inline FASTCALL KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
+VOID inline FASTCALL KeReleaseDispatcherDatabaseLock(KIRQL Irql);
+VOID inline FASTCALL KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
+
+VOID 
+STDCALL
+KeInitializeThread(struct _KPROCESS* Process, PKTHREAD Thread, BOOLEAN First);
+
+VOID
+STDCALL
+KeRundownThread(VOID);
+
+NTSTATUS KeReleaseThread(PKTHREAD Thread);
+
+VOID
+STDCALL
+KeStackAttachProcess (
+    IN struct _KPROCESS* Process,
+    OUT PKAPC_STATE ApcState
+    );
+
+VOID
+STDCALL
+KeUnstackDetachProcess (
+    IN PKAPC_STATE ApcState
+    );
 
 BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment);
 VOID STDCALL KeExpireTimers(PKDPC Apc,
                            PVOID Arg1,
                            PVOID Arg2,
                            PVOID Arg3);
-VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
-                                 ULONG Size, ULONG SignalState);
+VOID inline FASTCALL KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
+                                 ULONG Size, ULONG SignalState);
 VOID KeDumpStackFrames(PULONG Frame);
 BOOLEAN KiTestAlert(VOID);
 
-BOOLEAN KiAbortWaitThread(struct _KTHREAD* Thread, NTSTATUS WaitStatus);
+VOID
+FASTCALL 
+KiAbortWaitThread(PKTHREAD Thread, 
+                  NTSTATUS WaitStatus,
+                  KPRIORITY Increment);
+                  
+ULONG
+STDCALL
+KeForceResumeThread(IN PKTHREAD Thread);
+BOOLEAN STDCALL KiInsertTimer(PKTIMER Timer, LARGE_INTEGER DueTime);
+
+VOID inline FASTCALL KiSatisfyObjectWait(PDISPATCHER_HEADER Object, PKTHREAD Thread);
+
+BOOLEAN inline FASTCALL KiIsObjectSignaled(PDISPATCHER_HEADER Object, PKTHREAD Thread);
+
+VOID inline FASTCALL KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock);
+
+VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
 
 PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
 VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame);
 VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
                   PVOID Reserved,
                   PKTRAP_FRAME TrapFrame);
-                 
-VOID KiInitializeUserApc(IN PVOID Reserved,
+
+LONG 
+STDCALL 
+KiInsertQueue(IN PKQUEUE Queue, 
+              IN PLIST_ENTRY Entry, 
+              BOOLEAN Head);
+   
+ULONG
+STDCALL
+KeSetProcess(struct _KPROCESS* Process, 
+             KPRIORITY Increment);
+             
+                            
+VOID STDCALL KeInitializeEventPair(PKEVENT_PAIR EventPair);
+
+VOID STDCALL KiInitializeUserApc(IN PVOID Reserved,
                         IN PKTRAP_FRAME TrapFrame,
                         IN PKNORMAL_ROUTINE NormalRoutine,
                         IN PVOID NormalContext,
@@ -183,6 +268,7 @@ STDCALL
 KeTestAlertThread(IN KPROCESSOR_MODE AlertMode);
 
 BOOLEAN STDCALL KeRemoveQueueApc (PKAPC Apc);
+VOID FASTCALL KiWakeQueue(IN PKQUEUE Queue);
 PLIST_ENTRY STDCALL KeRundownQueue(IN PKQUEUE Queue);
 
 extern LARGE_INTEGER SystemBootTime;
@@ -192,11 +278,11 @@ extern LARGE_INTEGER SystemBootTime;
 VOID KeInitExceptions(VOID);
 VOID KeInitInterrupts(VOID);
 VOID KeInitTimer(VOID);
-VOID KeInitDpc(struct _KPCR* Pcr);
+VOID KeInitDpc(struct _KPRCB* Prcb);
 VOID KeInitDispatcher(VOID);
-VOID KeInitializeDispatcher(VOID);
+VOID inline FASTCALL KeInitializeDispatcher(VOID);
 VOID KiInitializeSystemClock(VOID);
-VOID KeInitializeBugCheck(VOID);
+VOID KiInitializeBugCheck(VOID);
 VOID Phase1Initialization(PVOID Context);
 
 VOID KeInit1(PCHAR CommandLine, PULONG LastKernelAddress);
index 31b0cac..91fc8d9 100644 (file)
@@ -628,6 +628,7 @@ PFN_TYPE MmGetLRUFirstUserPage(VOID);
 VOID MmSetLRULastPage(PFN_TYPE Page);
 
 VOID MmLockPage(PFN_TYPE Page);
+VOID MmLockPageUnsafe(PFN_TYPE Page);
 
 VOID MmUnlockPage(PFN_TYPE Page);
 
@@ -712,6 +713,7 @@ LONG MmAllocPagesSpecifyRange(ULONG Consumer,
 VOID MmDereferencePage(PFN_TYPE Page);
 
 VOID MmReferencePage(PFN_TYPE Page);
+VOID MmReferencePageUnsafe(PFN_TYPE Page);
 
 BOOLEAN MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
 
index 46906e3..84787cb 100644 (file)
@@ -29,6 +29,7 @@ extern ULONG NlsUnicodeTableOffset;
 extern PUSHORT NlsUnicodeUpcaseTable;
 extern PUSHORT NlsUnicodeLowercaseTable;
 
+VOID STDCALL RtlpInitNls(VOID);
 VOID RtlpImportAnsiCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportOemCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportUnicodeCasemap(PUSHORT TableBase, ULONG Size);
index a98537f..972b42a 100644 (file)
@@ -49,10 +49,12 @@ VOID ExpInitializeProfileImplementation(VOID);
  */
 VOID MmInitSystem(ULONG Phase, PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKernelAddress);
 VOID IoInit(VOID);
-VOID IoInit2(VOID);
+VOID IoInit2(BOOLEAN BootLog);
+VOID STDCALL IoInit3(VOID);
 VOID ObInit(VOID);
 VOID PsInit(VOID);
 VOID CmInitializeRegistry(VOID);
+VOID STDCALL CmInitHives(BOOLEAN SetupBoot);
 VOID CmInit2(PCHAR CommandLine);
 VOID CmShutdownRegistry(VOID);
 BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
index 59255ba..7e53906 100644 (file)
@@ -157,7 +157,6 @@ typedef struct _OBJECT_HEADER
    LIST_ENTRY Entry;
    LONG RefCount;
    LONG HandleCount;
-   BOOLEAN CloseInProcess;
    BOOLEAN Permanent;
    BOOLEAN Inherit;
    struct _DIRECTORY_OBJECT* Parent;
@@ -228,17 +227,22 @@ enum
    OBJTYP_MAX,
 };
 
+#define HEADER_TO_BODY(objhdr)                                                 \
+  (PVOID)((ULONG_PTR)objhdr + sizeof(OBJECT_HEADER) - sizeof(COMMON_BODY_HEADER))
+
+#define BODY_TO_HEADER(objbdy)                                                 \
+  CONTAINING_RECORD(&(((PCOMMON_BODY_HEADER)objbdy)->Type), OBJECT_HEADER, Type)
 
 #define OBJECT_ALLOC_SIZE(ObjectSize) ((ObjectSize)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER))
 
+#define HANDLE_TO_EX_HANDLE(handle)                                            \
+  (LONG)(((LONG)(handle) >> 2) - 1)
+#define EX_HANDLE_TO_HANDLE(exhandle)                                          \
+  (HANDLE)(((exhandle) + 1) << 2)
 
 extern PDIRECTORY_OBJECT NameSpaceRoot;
 extern POBJECT_TYPE ObSymbolicLinkType;
 
-
-POBJECT_HEADER BODY_TO_HEADER(PVOID body);
-PVOID HEADER_TO_BODY(POBJECT_HEADER obj);
-
 VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
                          POBJECT_HEADER Header,
                          PWSTR Name);
@@ -260,13 +264,11 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
                      PVOID* ReturnedObject,
                      PUNICODE_STRING RemainingPath,
                      POBJECT_TYPE ObjectType);
-VOID ObCloseAllHandles(struct _EPROCESS* Process);
 VOID ObDeleteHandleTable(struct _EPROCESS* Process);
 
 NTSTATUS
 ObDeleteHandle(PEPROCESS Process,
-              HANDLE Handle,
-              PVOID *ObjectBody);
+              HANDLE Handle);
 
 NTSTATUS
 ObpQueryHandleAttributes(HANDLE Handle,
@@ -300,7 +302,9 @@ ObQueryDeviceMapInformation(PEPROCESS Process, PPROCESS_DEVICEMAP_INFORMATION De
 VOID FASTCALL
 ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent);
 
-
+VOID
+STDCALL
+ObKillProcess(PEPROCESS Process);
 /* Security descriptor cache functions */
 
 NTSTATUS
@@ -326,7 +330,7 @@ typedef struct _CAPTURED_OBJECT_ATTRIBUTES
   HANDLE RootDirectory;
   ULONG Attributes;
   PSECURITY_DESCRIPTOR SecurityDescriptor;
-  /* PVOID SecurityQualityOfService; */
+  PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
 } CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
 
 NTSTATUS
@@ -377,10 +381,8 @@ typedef struct _INFORMATION_CLASS_INFO
     else if(ClassList[Class].RequiredSize##Mode > 0 &&                         \
             (BufferLen) != ClassList[Class].RequiredSize##Mode)                \
     {                                                                          \
-      if((!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) &&           \
-           (BufferLen) != ClassList[Class].RequiredSize##Mode) ||              \
-         ((ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) &&            \
-          (BufferLen) < ClassList[Class].RequiredSize##Mode))                  \
+      if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) &&            \
+           (BufferLen) != ClassList[Class].RequiredSize##Mode)                 \
       {                                                                        \
         *(StatusVar) = STATUS_INFO_LENGTH_MISMATCH;                            \
       }                                                                        \
index ffed376..19387eb 100644 (file)
@@ -18,7 +18,7 @@
 extern PDEVICE_NODE PopSystemPowerDeviceNode;
 
 VOID
-PoInit(VOID);
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock, BOOLEAN ForceAcpiDisable);
 
 NTSTATUS
 PopSetSystemPowerState(
index c987f67..4491247 100644 (file)
@@ -29,14 +29,6 @@ typedef struct _EPORT
   ULONG                MaxPoolUsage; /* size of NP zone */
 } EPORT, * PEPORT;
 
-
-typedef struct _EPORT_TERMINATION_REQUEST
-{
-       LIST_ENTRY      ThreadListEntry;
-       PEPORT          Port;   
-} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
-
-
 typedef struct _EPORT_CONNECT_REQUEST_MESSAGE
 {
   LPC_MESSAGE MessageHeader;
@@ -59,6 +51,11 @@ typedef struct _EPORT_CONNECT_REPLY_MESSAGE
   UCHAR ConnectData[0];
 } EPORT_CONNECT_REPLY_MESSAGE, *PEPORT_CONNECT_REPLY_MESSAGE;
 
+typedef struct _TERMINATION_PORT {
+    struct _TERMINATION_PORT *Next;
+    PVOID Port;
+} TERMINATION_PORT, *PTERMINATION_PORT;
+
 NTSTATUS STDCALL
 LpcRequestPort (PEPORT         Port,
                PLPC_MESSAGE    LpcMessage);
index 1be0eee..75e851a 100644 (file)
@@ -156,6 +156,7 @@ typedef struct
 
 #include <pshpack1.h>
 
+/* This needs to be fixed ASAP! */
 typedef struct _ETHREAD
 {
   KTHREAD Tcb;
@@ -169,7 +170,10 @@ typedef struct _ETHREAD
   NTSTATUS ExitStatus;
   PVOID OfsChain;
   LIST_ENTRY PostBlockList;
-  LIST_ENTRY TerminationPortList;
+  union {
+    struct _TERMINATION_PORT *TerminationPort;
+    struct _ETHREAD* ReaperLink;  
+  };
   KSPIN_LOCK ActiveTimerListLock;
   LIST_ENTRY ActiveTimerListHead;
   CLIENT_ID Cid;
@@ -201,6 +205,7 @@ typedef struct _ETHREAD
   UCHAR ActiveImpersonationInfo;
   ULONG PerformanceCountHigh;
   LIST_ENTRY ThreadListEntry;
+  BOOLEAN SystemThread;
 } ETHREAD;
 
 #include <poppack.h>
@@ -345,7 +350,7 @@ struct _EPROCESS
   LIST_ENTRY            SessionProcessLinks;
   struct _EPORT         *DebugPort;
   struct _EPORT         *ExceptionPort;
-  HANDLE_TABLE          HandleTable;
+  PHANDLE_TABLE         ObjectTable;
   PVOID                 Token;
   FAST_MUTEX            WorkingSetLock;
   ULONG                 WorkingSetPage;
@@ -416,13 +421,13 @@ struct _EPROCESS
   PRTL_BITMAP           VadPhysicalPagesBitMap;
   ULONG                 VadPhysicalPages;
   KSPIN_LOCK            AweLock;
+  ULONG                 Cookie;
 
   /*
    * FIXME - ReactOS specified - remove the following fields ASAP!!!
    */
   MADDRESS_SPACE        AddressSpace;
   LIST_ENTRY            ProcessListEntry;
-  FAST_MUTEX            TebLock;
   PVOID                 TebBlock;
   PVOID                 TebLastAllocated;
 };
@@ -436,7 +441,6 @@ VOID PiShutdownProcessManager(VOID);
 VOID PsInitThreadManagment(VOID);
 VOID PsInitProcessManagment(VOID);
 VOID PsInitIdleThread(VOID);
-VOID PsDispatchThreadNoLock(ULONG NewThreadStatus);
 VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
 VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
 VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus);
@@ -453,22 +457,27 @@ VOID PsQueueThreadReap(PETHREAD Thread);
 NTSTATUS 
 PsInitializeThread(PEPROCESS Process,
                   PETHREAD* ThreadPtr,
-                  PHANDLE ThreadHandle,
-                  ACCESS_MASK DesiredAccess,
                   POBJECT_ATTRIBUTES ObjectAttributes,
+                  KPROCESSOR_MODE AccessMode,
                   BOOLEAN First);
 
-PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
+PACCESS_TOKEN STDCALL PsReferenceEffectiveToken(PETHREAD Thread,
                                        PTOKEN_TYPE TokenType,
                                        PUCHAR b,
                                        PSECURITY_IMPERSONATION_LEVEL Level);
 
-NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
+NTSTATUS STDCALL PsOpenTokenOfProcess(HANDLE ProcessHandle,
                              PACCESS_TOKEN* Token);
-
+VOID
+STDCALL
+PspTerminateProcessThreads(PEPROCESS Process,
+                           NTSTATUS ExitStatus);
 NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
 NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
-
+NTSTATUS
+STDCALL
+PspAssignPrimaryToken(PEPROCESS Process,
+                      HANDLE TokenHandle);
 VOID STDCALL PsExitSpecialApc(PKAPC Apc, 
                      PKNORMAL_ROUTINE *NormalRoutine,
                      PVOID *NormalContext,
@@ -497,27 +506,25 @@ VOID STDCALL PsExitSpecialApc(PKAPC Apc,
 #define PROCESS_PRIO_RT                                18
 
 
+VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
+
 VOID 
-KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
-NTSTATUS KeReleaseThread(PKTHREAD Thread);
+STDCALL 
+PspReapRoutine(PVOID Context);
 
 VOID
 STDCALL
-KeStackAttachProcess (
-    IN PKPROCESS Process,
-    OUT PKAPC_STATE ApcState
-    );
+PspExitThread(NTSTATUS ExitStatus);
+
+extern LIST_ENTRY PspReaperListHead;
+extern WORK_QUEUE_ITEM PspReaperWorkItem;
+extern BOOLEAN PspReaping;
 
 VOID
 STDCALL
-KeUnstackDetachProcess (
-    IN PKAPC_STATE ApcState
-    );
+PspTerminateThreadByPointer(PETHREAD Thread,
+                            NTSTATUS ExitStatus);
 
-VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
-VOID PsReapThreads(VOID);
-VOID PsInitializeThreadReaper(VOID);
-VOID PsQueueThreadReap(PETHREAD Thread);
 VOID PsUnfreezeOtherThread(PETHREAD Thread);
 VOID PsFreezeOtherThread(PETHREAD Thread);
 VOID PsFreezeProcessThreads(PEPROCESS Process);
@@ -525,11 +532,6 @@ VOID PsUnfreezeProcessThreads(PEPROCESS Process);
 ULONG PsEnumThreadsByProcess(PEPROCESS Process);
 PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
 VOID
-PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, 
-             BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason);
-VOID
-PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment);
-VOID
 PsApplicationProcessorInit(VOID);
 VOID
 PsPrepareForApplicationProcessorInit(ULONG Id);
@@ -548,10 +550,19 @@ VOID STDCALL
 PiSuspendThreadNormalRoutine(PVOID NormalContext,
                             PVOID SystemArgument1,
                             PVOID SystemArgument2);
-VOID STDCALL
-PsDispatchThread(ULONG NewThreadStatus);
 VOID
 PsInitialiseSuspendImplementation(VOID);
+NTSTATUS 
+STDCALL
+PspExitProcess(PEPROCESS Process);
+
+VOID 
+STDCALL 
+PspDeleteProcess(PVOID ObjectBody);
+
+VOID 
+STDCALL
+PspDeleteThread(PVOID ObjectBody);
 
 extern LONG PiNrThreadsAwaitingReaping;
 
@@ -640,27 +651,13 @@ typedef struct _EJOB
 
 VOID INIT_FUNCTION PsInitJobManagment(VOID);
 
-/* CID */
-
-typedef struct _CID_OBJECT
-{
-  LONG ref;
-  HANDLE Handle;
-  LIST_ENTRY Entry;
-  FAST_MUTEX Lock;
-  union
-  {
-    struct _EPROCESS *Process;
-    struct _ETHREAD *Thread;
-    PVOID Object;
-  } Obj;
-} CID_OBJECT, *PCID_OBJECT;
+/* CLIENT ID */
 
 NTSTATUS PsCreateCidHandle(PVOID Object, POBJECT_TYPE ObjectType, PHANDLE Handle);
 NTSTATUS PsDeleteCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType);
-PCID_OBJECT PsLockCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType);
-VOID PsUnlockCidObject(PCID_OBJECT CidObject);
-NTSTATUS PsLockProcess(PEPROCESS Process, BOOL Timeout);
+PHANDLE_TABLE_ENTRY PsLookupCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType, PVOID *Object);
+VOID PsUnlockCidHandle(PHANDLE_TABLE_ENTRY CidEntry);
+NTSTATUS PsLockProcess(PEPROCESS Process, BOOLEAN Timeout);
 VOID PsUnlockProcess(PEPROCESS Process);
 
 #define ETHREAD_TO_KTHREAD(pEThread) (&(pEThread)->Tcb)
index 8d3e269..58e231a 100644 (file)
@@ -148,6 +148,60 @@ SepPrivilegeCheck(PTOKEN Token,
                  ULONG PrivilegeControl,
                  KPROCESSOR_MODE PreviousMode);
 
+NTSTATUS
+SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN POOL_TYPE PoolType,
+                                   IN BOOLEAN CaptureIfKernel,
+                                   OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+                                   OUT PBOOLEAN Present);
+
+VOID
+SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN BOOLEAN CaptureIfKernel);
+
+NTSTATUS
+SepCaptureSid(IN PSID InputSid,
+              IN KPROCESSOR_MODE AccessMode,
+              IN POOL_TYPE PoolType,
+              IN BOOLEAN CaptureIfKernel,
+              OUT PSID *CapturedSid);
+
+VOID
+SepReleaseSid(IN PSID CapturedSid,
+              IN KPROCESSOR_MODE AccessMode,
+              IN BOOLEAN CaptureIfKernel);
+
+NTSTATUS
+SepCaptureAcl(IN PACL InputAcl,
+              IN KPROCESSOR_MODE AccessMode,
+              IN POOL_TYPE PoolType,
+              IN BOOLEAN CaptureIfKernel,
+              OUT PACL *CapturedAcl);
+
+VOID
+SepReleaseAcl(IN PACL CapturedAcl,
+              IN KPROCESSOR_MODE AccessMode,
+              IN BOOLEAN CaptureIfKernel);
+
+#define SepAcquireTokenLockExclusive(Token)                                    \
+  do {                                                                         \
+    KeEnterCriticalRegion();                                                   \
+    ExAcquireResourceExclusive(((PTOKEN)Token)->TokenLock, TRUE);              \
+  while(0)
+
+#define SepAcquireTokenLockShared(Token)                                       \
+  do {                                                                         \
+    KeEnterCriticalRegion();                                                   \
+    ExAcquireResourceShared(((PTOKEN)Token)->TokenLock, TRUE);                 \
+  while(0)
+
+#define SepReleaseTokenLock(Token)                                             \
+  do {                                                                         \
+    ExReleaseResource(((PTOKEN)Token)->TokenLock);                             \
+    KeLeaveCriticalRegion();                                                   \
+  while(0)
 
 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */
 
index c4b8a1a..ef8e5ee 100755 (executable)
@@ -30,7 +30,6 @@
 #include <ntdll/ldr.h>
 #include <internal/ctype.h>
 #include <internal/ntoskrnl.h>
-#include <internal/id.h>
 #include <internal/ke.h>
 #include <internal/i386/segment.h>
 #include <internal/i386/mm.h>
index 71dc17b..9324dd9 100644 (file)
@@ -27,13 +27,14 @@ static ERESOURCE IopBootLogResource;
 /* FUNCTIONS ****************************************************************/
 
 VOID INIT_FUNCTION
-IopInitBootLog(VOID)
+IopInitBootLog(BOOLEAN StartBootLog)
 {
   ExInitializeResourceLite(&IopBootLogResource);
+  if (StartBootLog) IopStartBootLog();
 }
 
 
-VOID
+VOID INIT_FUNCTION
 IopStartBootLog(VOID)
 {
   IopBootLogCreate = TRUE;
index 99fdc41..8bfdf45 100644 (file)
@@ -37,7 +37,6 @@ NTSTATUS IoPrepareIrpBuffer(PIRP Irp,
          (PVOID)ExAllocatePoolWithTag(NonPagedPool,Length, TAG_SYS_BUF);
        if (Irp->AssociatedIrp.SystemBuffer==NULL)
          {
-            IoFreeIrp(Irp);
             return(STATUS_NOT_IMPLEMENTED);
          }
        /* FIXME: should copy buffer in on other ops */
@@ -121,13 +120,34 @@ IoBuildAsynchronousFsdRequest(ULONG MajorFunction,
    StackPtr->FileObject = NULL;
    StackPtr->CompletionRoutine = NULL;
 
-   if (Buffer != NULL)
+   if (Length > 0)
      {
-       IoPrepareIrpBuffer(Irp,
-                          DeviceObject,
-                          Buffer,
-                          Length,
-                          MajorFunction);
+        NTSTATUS Status = STATUS_SUCCESS;
+
+        _SEH_FILTER(FreeAndGoOn) 
+         {
+            IoFreeIrp(Irp);
+            return EXCEPTION_CONTINUE_SEARCH;
+          } 
+       _SEH_TRY_FILTER(FreeAndGoOn) 
+         {
+           Status = IoPrepareIrpBuffer(Irp,
+                                       DeviceObject,
+                                       Buffer,
+                                       Length,
+                                       MajorFunction);
+         }
+        _SEH_HANDLE
+         {
+           KEBUGCHECK(0);
+         }
+       _SEH_END;
+
+       if (!NT_SUCCESS(Status))
+         {
+           IoFreeIrp(Irp);
+           return NULL;
+         }
      }
 
    if (MajorFunction == IRP_MJ_READ)
@@ -296,7 +316,27 @@ IoBuildDeviceIoControlRequest(ULONG IoControlCode,
                                             FALSE,
                                             FALSE,
                                            Irp);
-            MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
+            if (Irp->MdlAddress == NULL)
+              {
+                IoFreeIrp(Irp);
+                return NULL;
+              }
+
+             _SEH_FILTER(FreeAndGoOn) 
+              {
+                 IoFreeIrp(Irp);
+                 return EXCEPTION_CONTINUE_SEARCH;
+               } 
+            _SEH_TRY_FILTER(FreeAndGoOn) 
+              {
+                MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoReadAccess);
+              }
+             _SEH_HANDLE
+              {
+                KEBUGCHECK(0);
+              }
+             _SEH_END;
+
          }
        break;
        
@@ -329,7 +369,26 @@ IoBuildDeviceIoControlRequest(ULONG IoControlCode,
                                             FALSE,
                                             FALSE,
                                            Irp);
-            MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
+            if (Irp->MdlAddress == NULL)
+              {
+                IoFreeIrp(Irp);
+                return NULL;
+              }
+
+             _SEH_FILTER(FreeAndGoOn) 
+              {
+                 IoFreeIrp(Irp);
+                 return EXCEPTION_CONTINUE_SEARCH;
+               } 
+            _SEH_TRY_FILTER(FreeAndGoOn) 
+              {
+                MmProbeAndLockPages(Irp->MdlAddress,UserMode,IoWriteAccess);
+              }
+             _SEH_HANDLE
+              {
+                KEBUGCHECK(0);
+              }
+            _SEH_END;
          }
        break;
        
@@ -352,12 +411,12 @@ IoBuildDeviceIoControlRequest(ULONG IoControlCode,
  */
 PIRP STDCALL
 IoBuildSynchronousFsdRequest(ULONG MajorFunction,
-                                 PDEVICE_OBJECT DeviceObject,
-                                 PVOID Buffer,
-                                 ULONG Length,
-                                 PLARGE_INTEGER StartingOffset,
-                                 PKEVENT Event,
-                                 PIO_STATUS_BLOCK IoStatusBlock)
+                            PDEVICE_OBJECT DeviceObject,
+                            PVOID Buffer,
+                            ULONG Length,
+                            PLARGE_INTEGER StartingOffset,
+                            PKEVENT Event,
+                            PIO_STATUS_BLOCK IoStatusBlock)
 /*
  * FUNCTION: Allocates and builds an IRP to be sent synchronously to lower
  * level driver(s)
index 1ce6919..252fbd2 100644 (file)
@@ -204,18 +204,23 @@ BOOLEAN STDCALL
 IoCancelIrp(PIRP Irp)
 {
    KIRQL oldlvl;
+   PDRIVER_CANCEL CancelRoutine;
    
    DPRINT("IoCancelIrp(Irp %x)\n",Irp);
    
    IoAcquireCancelSpinLock(&oldlvl);
+   
    Irp->Cancel = TRUE;
-   if (Irp->CancelRoutine == NULL)
+  
+   CancelRoutine = IoSetCancelRoutine(Irp, NULL);
+   if (CancelRoutine == NULL)
    {
       IoReleaseCancelSpinLock(oldlvl);
       return(FALSE);
    }
+   
    Irp->CancelIrql = oldlvl;
-   Irp->CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
+   CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
    return(TRUE);
 }
 
index c085eb1..ef2097c 100644 (file)
@@ -109,7 +109,10 @@ VOID IoReadWriteCompletion(PDEVICE_OBJECT DeviceObject,
 
    if (DeviceObject->Flags & DO_DIRECT_IO)
    {
-      IoFreeMdl(Irp->MdlAddress);
+      if (Irp->MdlAddress)
+      {
+         IoFreeMdl(Irp->MdlAddress);
+      }
    }
 }
 
index b507fc5..08d46b0 100644 (file)
@@ -176,7 +176,7 @@ IopCreateFile(PVOID                 ObjectBody,
         FileObject,
         DeviceObject);
   FileObject->Vpb = DeviceObject->Vpb;
-  FileObject->Type = InternalFileType;
+  FileObject->Type = IO_TYPE_FILE;
 
   return(STATUS_SUCCESS);
 }
@@ -240,7 +240,7 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
 
   CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
   CreatedFileObject->Vpb = DeviceObject->Vpb;
-  CreatedFileObject->Type = InternalFileType;
+  CreatedFileObject->Type = IO_TYPE_FILE;
   CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
 
   // shouldn't we initialize the lock event, and several other things here too?
@@ -448,9 +448,9 @@ IoCreateFile(OUT PHANDLE            FileHandle,
        return Status;
      }
 
-   RtlMapGenericMask(&DesiredAccess,
-                     BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
-
+   RtlMapGenericMask(&DesiredAccess,    
+                      BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
+                      
    Status = ObInsertObject ((PVOID)FileObject,
                            NULL,
                            DesiredAccess,
index d68f4d8..ca5a739 100644 (file)
@@ -82,7 +82,6 @@ IopInitializeDevice(
           return Status;
       }
 
-#ifdef ACPI
       if (Fdo->DeviceType == FILE_DEVICE_ACPI)
       {
          static BOOLEAN SystemPowerDeviceNodeCreated = FALSE;
@@ -94,7 +93,6 @@ IopInitializeDevice(
             SystemPowerDeviceNodeCreated = TRUE;
          }
       }
-#endif /* ACPI */
 
       if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER ||
           Fdo->DeviceType == FILE_DEVICE_ACPI)
@@ -126,7 +124,7 @@ IopCreateDevice(
       ObjectBody, Parent, RemainingPath);
    
    if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
-      return STATUS_UNSUCCESSFUL;
+      return STATUS_OBJECT_PATH_NOT_FOUND;
    
    return STATUS_SUCCESS;
 }
@@ -168,8 +166,11 @@ IoAttachDeviceToDeviceStackSafe(
     OUT PDEVICE_OBJECT *AttachedToDeviceObject
     )
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+   /* FIXME: IoAttachDeviceToDeviceStackSafe must not call
+    * IoAttachDeviceToDeviceStack, but the other way around! */
+   DPRINT1("IoAttachDeviceToDeviceStackSafe() badly implemented!\n");
+   *AttachedToDeviceObject = IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice);
+   return STATUS_SUCCESS;
 }
 
 /*
@@ -348,7 +349,10 @@ IoGetDeviceObjectPointer(
       FILE_NON_DIRECTORY_FILE);
 
    if (!NT_SUCCESS(Status))
+   {
+      DPRINT1("NtOpenFile failed, Status: 0x%x\n", Status);
       return Status;
+   }
 
    Status = ObReferenceObjectByHandle(
       FileHandle,
index 90b9180..7d09e47 100644 (file)
@@ -38,13 +38,41 @@ NtNotifyChangeDirectoryFile (
    PIRP Irp;
    PDEVICE_OBJECT DeviceObject;
    PFILE_OBJECT FileObject;
-   NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
    
    DPRINT("NtNotifyChangeDirectoryFile()\n");
+   
+   PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(IoStatusBlock,
+                     sizeof(IO_STATUS_BLOCK),
+                     sizeof(ULONG));
+       if(BufferSize != 0)
+       {
+         ProbeForWrite(Buffer,
+                       BufferSize,
+                       sizeof(ULONG));
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
 
    Status = ObReferenceObjectByHandle(FileHandle,
                                      FILE_LIST_DIRECTORY,
@@ -155,13 +183,38 @@ NtQueryDirectoryFile(
    PIRP Irp;
    PDEVICE_OBJECT DeviceObject;
    PFILE_OBJECT FileObject;
-   NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
    
    DPRINT("NtQueryDirectoryFile()\n");
+   
+   PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(IoStatusBlock,
+                     sizeof(IO_STATUS_BLOCK),
+                     sizeof(ULONG));
+       ProbeForWrite(FileInformation,
+                     Length,
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
 
    Status = ObReferenceObjectByHandle(FileHandle,
                                      FILE_LIST_DIRECTORY,
index 7cab4e6..e245267 100644 (file)
@@ -160,7 +160,7 @@ IopCreateDriver(
 
    RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
 
-   Object->Type = InternalDriverType;
+   Object->Type = IO_TYPE_DRIVER;
 
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
       Object->MajorFunction[i] = IopInvalidDeviceRequest;
@@ -960,7 +960,7 @@ IoCreateDriverList(VOID)
                             NULL);
 
   Status = ZwOpenKey(&KeyHandle,
-                    0x10001,
+                    KEY_ENUMERATE_SUB_KEYS,
                     &ObjectAttributes);
   if (!NT_SUCCESS(Status))
     {
@@ -1252,11 +1252,12 @@ IopInitializeBootDrivers(VOID)
     */
    for (i = 1; i < KeLoaderBlock.ModsCount; i++)
    {
-
        MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart,
                               KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
    }
 
+   KeLoaderBlock.ModsCount = 0;
+
    if (BootDriverCount == 0)
    {
       DbgPrint("No boot drivers available.\n");
index 21d4a11..f95a5fc 100644 (file)
@@ -50,7 +50,7 @@ NtQueryInformationFile(HANDLE FileHandle,
    PreviousMode = ExGetPreviousMode();
 
    Status = ObReferenceObjectByHandle(FileHandle,
-                                     FILE_READ_ATTRIBUTES,
+                                     0, /* FIXME - access depends on the information class! */
                                      IoFileObjectType,
                                      PreviousMode,
                                      (PVOID *)&FileObject,
@@ -402,7 +402,7 @@ NtSetInformationFile(HANDLE FileHandle,
 
    /*  Get the file object from the file handle  */
    Status = ObReferenceObjectByHandle(FileHandle,
-                                     FILE_WRITE_ATTRIBUTES,
+                                     0, /* FIXME - depends on the information class */
                                      IoFileObjectType,
                                      PreviousMode,
                                      (PVOID *)&FileObject,
index de412e5..fe54d18 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/iocomp.c
 
 POBJECT_TYPE ExIoCompletionType;
 
-NPAGED_LOOKASIDE_LIST  IoCompletionPacketLookaside;
+NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
 
 static GENERIC_MAPPING ExIoCompletionMapping = 
 {
-   STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
-   STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
-   STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
-   IO_COMPLETION_ALL_ACCESS
+    STANDARD_RIGHTS_READ    | IO_COMPLETION_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | IO_COMPLETION_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
+    IO_COMPLETION_ALL_ACCESS
 };
 
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS 
-STDCALL
-IopCreateIoCompletion(
-   PVOID                ObjectBody,
-   PVOID                Parent,
-   PWSTR                RemainingPath,
-   POBJECT_ATTRIBUTES   ObjectAttributes
-   )
-{
-   DPRINT("IopCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-      ObjectBody, Parent, RemainingPath);
+static const INFORMATION_CLASS_INFO ExIoCompletionInfoClass[] = {
 
-   if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
+     /* IoCompletionBasicInformation */
+    ICI_SQ_SAME( sizeof(IO_COMPLETION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
+};
 
-   return STATUS_SUCCESS;
-}
+/* FUNCTIONS *****************************************************************/
 
-VOID STDCALL
+VOID 
+STDCALL
 IopDeleteIoCompletion(PVOID ObjectBody)
 {
-   PKQUEUE Queue = ObjectBody;
-
-   DPRINT("IopDeleteIoCompletion()\n");
-
-   KeRundownQueue(Queue);
+    PKQUEUE Queue = ObjectBody;
+    PLIST_ENTRY FirstEntry;
+    PLIST_ENTRY CurrentEntry;
+    PIO_COMPLETION_PACKET Packet;
+
+    DPRINT("IopDeleteIoCompletion()\n");
+
+    /* Rundown the Queue */
+    FirstEntry = KeRundownQueue(Queue);
+    
+    /* Clean up the IRPs */
+    if (FirstEntry) {
+    
+        CurrentEntry = FirstEntry;
+        do {
+        
+            /* Get the Packet */
+            Packet = CONTAINING_RECORD(CurrentEntry, IO_COMPLETION_PACKET, ListEntry);
+            
+            /* Go to next Entry */
+            CurrentEntry = CurrentEntry->Flink;
+            
+            /* Free it */
+            ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+        } while (FirstEntry != CurrentEntry);
+    }
 }
 
-
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
-IoSetCompletionRoutineEx(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_COMPLETION_ROUTINE CompletionRoutine,
-    IN PVOID Context,
-    IN BOOLEAN InvokeOnSuccess,
-    IN BOOLEAN InvokeOnError,
-    IN BOOLEAN InvokeOnCancel
-    )
+IoSetIoCompletion(IN PVOID IoCompletion,
+                  IN PVOID KeyContext,
+                  IN PVOID ApcContext,
+                  IN NTSTATUS IoStatus,
+                  IN ULONG_PTR IoStatusInformation,
+                  IN BOOLEAN Quota)
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+    PKQUEUE Queue = (PKQUEUE)IoCompletion;
+    PIO_COMPLETION_PACKET Packet;
+
+    /* Allocate the Packet */
+    Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
+    if (NULL == Packet) return STATUS_NO_MEMORY;
+    
+    /* Set up the Packet */
+    Packet->Key = KeyContext;
+    Packet->Context = ApcContext;
+    Packet->IoStatus.Status = IoStatus;
+    Packet->IoStatus.Information = IoStatusInformation;
+    
+    /* Insert the Queue */
+    KeInsertQueue(Queue, &Packet->ListEntry);
+
+    /* Return Success */
+    return STATUS_SUCCESS;
 }
 
 /*
- * @implemented
+ * @unimplemented
  */
 NTSTATUS
 STDCALL
-IoSetIoCompletion (
-       IN PVOID IoCompletion,
-       IN PVOID KeyContext,
-       IN PVOID ApcContext,
-       IN NTSTATUS IoStatus,
-       IN ULONG_PTR IoStatusInformation,
-       IN BOOLEAN Quota
-       )
+IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
+                         IN PIRP Irp,
+                         IN PIO_COMPLETION_ROUTINE CompletionRoutine,
+                         IN PVOID Context,
+                         IN BOOLEAN InvokeOnSuccess,
+                         IN BOOLEAN InvokeOnError,
+                         IN BOOLEAN InvokeOnCancel)
 {
-   PKQUEUE Queue = (PKQUEUE) IoCompletion;
-   PIO_COMPLETION_PACKET   Packet;
-
-   Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
-   if (NULL == Packet)
-   {
-     return STATUS_NO_MEMORY;
-   }
-
-   Packet->Key = KeyContext;
-   Packet->Context = ApcContext;
-   Packet->IoStatus.Status = IoStatus;
-   Packet->IoStatus.Information = IoStatusInformation;
-   
-   KeInsertQueue(Queue, &Packet->ListEntry);
-
-   return STATUS_SUCCESS;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 VOID
 FASTCALL
 IopInitIoCompletionImplementation(VOID)
 {
-   ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion", NonPagedPool);
-   
-   ExIoCompletionType->Tag = IOC_TAG;
-   ExIoCompletionType->PeakObjects = 0;
-   ExIoCompletionType->PeakHandles = 0;
-   ExIoCompletionType->TotalObjects = 0;
-   ExIoCompletionType->TotalHandles = 0;
-   ExIoCompletionType->PagedPoolCharge = 0;
-   ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
-   ExIoCompletionType->Mapping = &ExIoCompletionMapping;
-   ExIoCompletionType->Dump = NULL;
-   ExIoCompletionType->Open = NULL;
-   ExIoCompletionType->Close = NULL;
-   ExIoCompletionType->Delete = IopDeleteIoCompletion;
-   ExIoCompletionType->Parse = NULL;
-   ExIoCompletionType->Security = NULL;
-   ExIoCompletionType->QueryName = NULL;
-   ExIoCompletionType->OkayToClose = NULL;
-   ExIoCompletionType->Create = IopCreateIoCompletion;
-   ExIoCompletionType->DuplicationNotify = NULL;
-
-   ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
-                                   NULL,
-                                   NULL,
-                                   0,
-                                   sizeof(IO_COMPLETION_PACKET),
-                                   IOC_TAG,
-                                   0);
+    /* Create the IO Completion Type */
+    ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));   
+    RtlInitUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion");
+    ExIoCompletionType->Tag = IOC_TAG;
+    ExIoCompletionType->PeakObjects = 0;
+    ExIoCompletionType->PeakHandles = 0;
+    ExIoCompletionType->TotalObjects = 0;
+    ExIoCompletionType->TotalHandles = 0;
+    ExIoCompletionType->PagedPoolCharge = 0;
+    ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
+    ExIoCompletionType->Mapping = &ExIoCompletionMapping;
+    ExIoCompletionType->Dump = NULL;
+    ExIoCompletionType->Open = NULL;
+    ExIoCompletionType->Close = NULL;
+    ExIoCompletionType->Delete = IopDeleteIoCompletion;
+    ExIoCompletionType->Parse = NULL;
+    ExIoCompletionType->Security = NULL;
+    ExIoCompletionType->QueryName = NULL;
+    ExIoCompletionType->OkayToClose = NULL;
+    ExIoCompletionType->Create = NULL;
+    ExIoCompletionType->DuplicationNotify = NULL;
+
+    /* Initialize the Lookaside List we'll use for packets */
+    ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
+                                    NULL,
+                                    NULL,
+                                    0,
+                                    sizeof(IO_COMPLETION_PACKET),
+                                    IOC_TAG,
+                                    0);
 }
 
-
 NTSTATUS
 STDCALL
-NtCreateIoCompletion(
-   OUT PHANDLE             IoCompletionHandle,
-   IN  ACCESS_MASK         DesiredAccess,
-   IN  POBJECT_ATTRIBUTES  ObjectAttributes,
-   IN  ULONG               NumberOfConcurrentThreads
-   )
+NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
+                     IN  ACCESS_MASK DesiredAccess,
+                     IN  POBJECT_ATTRIBUTES ObjectAttributes,
+                     IN  ULONG NumberOfConcurrentThreads)
 {
-   PKQUEUE     Queue;
-   NTSTATUS    Status;
-
-   Status = ObCreateObject(ExGetPreviousMode(),
-                           ExIoCompletionType,
-                           ObjectAttributes,
-                           ExGetPreviousMode(),
-                           NULL,
-                           sizeof(KQUEUE),
-                           0,
-                           0,
-                           (PVOID*)&Queue);
-   if (!NT_SUCCESS(Status))
-   {
-     return Status;
-   }
-
-   Status = ObInsertObject ((PVOID)Queue,
-                           NULL,
-                           DesiredAccess,
-                           0,
-                           NULL,
-                           IoCompletionHandle);
-   if (!NT_SUCCESS(Status))
-   {
-     ObDereferenceObject(Queue);
-     return Status;
-   }
-
-   KeInitializeQueue(Queue, NumberOfConcurrentThreads);
-   ObDereferenceObject(Queue);
+    PKQUEUE Queue;
+    HANDLE hIoCompletionHandle;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
 
-   return STATUS_SUCCESS;
-   /*
+    if (PreviousMode != KernelMode) {
 
-  CompletionPort = NULL OR ExistingCompletionPort
+        _SEH_TRY {
 
-  */
+            ProbeForWrite(IoCompletionHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
 
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+      
+        if (!NT_SUCCESS(Status)) {
+
+            return Status;
+        }
+    }
+
+    /* Create the Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExIoCompletionType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KQUEUE),
+                            0,
+                            0,
+                            (PVOID*)&Queue);
+    
+    /* Check for success */
+    if (NT_SUCCESS(Status)) {
+   
+        /* Initialize the Queue */
+        KeInitializeQueue(Queue, NumberOfConcurrentThreads);
+
+        /* Insert it */
+        Status = ObInsertObject(Queue,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                &hIoCompletionHandle);
+        ObDereferenceObject(Queue);
+        
+        if (NT_SUCCESS(Status)) {
+
+            _SEH_TRY {
+
+                *IoCompletionHandle = hIoCompletionHandle;
+            } _SEH_HANDLE {
+
+                Status = _SEH_GetExceptionCode();
+            } _SEH_END;
+        }
+   }
+   
+   /* Return Status */
+   return Status;
 }
 
-/*
-DesiredAccess:
-ZERO
-IO_COMPLETION_QUERY_STATE Query access
-IO_COMPLETION_MODIFY_STATE Modify access
-IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
-
-ObjectAttributes
-OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
-
-Return Value
-STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
-STATUS_OBJECT_NAME_NOT_FOUND.
-*/
 NTSTATUS
 STDCALL
-NtOpenIoCompletion(
-   OUT PHANDLE             IoCompletionHandle,
-   IN  ACCESS_MASK         DesiredAccess,
-   IN  POBJECT_ATTRIBUTES  ObjectAttributes
-   )
+NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
+                   IN ACCESS_MASK DesiredAccess,
+                   IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   NTSTATUS Status;
-   
-   Status = ObOpenObjectByName(ObjectAttributes,
-                               ExIoCompletionType,
-                               NULL,
-                               UserMode,
-                               DesiredAccess,
-                               NULL,
-                               IoCompletionHandle);  //<- ???
-   
-   return Status;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    HANDLE hIoCompletionHandle;
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
+    
+    if(PreviousMode != KernelMode) {
+
+        _SEH_TRY {
+
+            ProbeForWrite(IoCompletionHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) {
+
+            return Status;
+        }
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExIoCompletionType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hIoCompletionHandle);
+    if (NT_SUCCESS(Status)) {
+
+        _SEH_TRY {
+
+            *IoCompletionHandle = hIoCompletionHandle;
+        } _SEH_HANDLE {
+
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+    }
+    /* Return Status */  
+    return Status;
 }
 
 
 NTSTATUS
 STDCALL
-NtQueryIoCompletion(
-   IN  HANDLE                          IoCompletionHandle,
-   IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
-   OUT PVOID                           IoCompletionInformation,
-   IN  ULONG                           IoCompletionInformationLength,
-   OUT PULONG                          ResultLength OPTIONAL
-   )
+NtQueryIoCompletion(IN  HANDLE IoCompletionHandle,
+                    IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
+                    OUT PVOID IoCompletionInformation,
+                    IN  ULONG IoCompletionInformationLength,
+                    OUT PULONG ResultLength OPTIONAL)
 {
-   PKQUEUE  Queue;
-   NTSTATUS Status;
-
-   if (IoCompletionInformationClass != IoCompletionBasicInformation)
-   {
-      return STATUS_INVALID_INFO_CLASS;
-   }
-   if (IoCompletionInformationLength < sizeof(IO_COMPLETION_BASIC_INFORMATION))
-   {
-      return STATUS_INFO_LENGTH_MISMATCH;
-   }
-
-   Status = ObReferenceObjectByHandle( IoCompletionHandle,
+    PKQUEUE Queue;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
+
+    /* Check buffers and parameters */
+    DefaultQueryInfoBufferCheck(IoCompletionInformationClass,
+                                ExIoCompletionInfoClass,
+                                IoCompletionInformation,
+                                IoCompletionInformationLength,
+                                ResultLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+
+        DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
+
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                        IO_COMPLETION_QUERY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-   if (NT_SUCCESS(Status))
-   {
-      ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = 
-         Queue->Header.SignalState;
+    
+    /* Check for Success */
+   if (NT_SUCCESS(Status)) {
+      
+        _SEH_TRY {
 
-      ObDereferenceObject(Queue);
+            /* Return Info */
+            ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = KeReadStateQueue(Queue);
+            ObDereferenceObject(Queue);
 
-      if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
-   }
+            /* Return Result Length if needed */
+            if (ResultLength) {
 
-   return Status;
-}
+                *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
+            }
+        } _SEH_HANDLE {
 
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+    }
+
+    /* Return Status */
+    return Status;
+}
 
 /*
  * Dequeues an I/O completion message from an I/O completion object
  */
 NTSTATUS
 STDCALL
-NtRemoveIoCompletion(
-   IN  HANDLE           IoCompletionHandle,
-   OUT PVOID            *CompletionKey,
-   OUT PVOID            *CompletionContext,
-   OUT PIO_STATUS_BLOCK IoStatusBlock,
-   IN  PLARGE_INTEGER   Timeout OPTIONAL
-   )
+NtRemoveIoCompletion(IN  HANDLE IoCompletionHandle,
+                     OUT PVOID *CompletionKey,
+                     OUT PVOID *CompletionContext,
+                     OUT PIO_STATUS_BLOCK IoStatusBlock,
+                     IN  PLARGE_INTEGER Timeout OPTIONAL)
 {
-   PKQUEUE  Queue;
-   NTSTATUS Status;
-   PIO_COMPLETION_PACKET   Packet;
-   PLIST_ENTRY             ListEntry;
-
-   Status = ObReferenceObjectByHandle( IoCompletionHandle,
+    LARGE_INTEGER SafeTimeout;
+    PKQUEUE Queue;
+    PIO_COMPLETION_PACKET Packet;
+    PLIST_ENTRY ListEntry;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    PAGED_CODE();
+
+    if (PreviousMode != KernelMode) {
+
+        _SEH_TRY {
+
+            ProbeForWrite(CompletionKey,
+                          sizeof(PVOID),
+                          sizeof(ULONG));
+            ProbeForWrite(CompletionContext,
+                          sizeof(PVOID),
+                          sizeof(ULONG));
+            ProbeForWrite(IoStatusBlock,
+                          sizeof(IO_STATUS_BLOCK),
+                          sizeof(ULONG));
+            if (Timeout != NULL) {
+
+                ProbeForRead(Timeout,
+                             sizeof(LARGE_INTEGER),
+                             sizeof(ULONG));
+                SafeTimeout = *Timeout;
+                Timeout = &SafeTimeout;
+            }
+        } _SEH_HANDLE {
+
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+        
+        if (!NT_SUCCESS(Status)) {
+
+            return Status;
+        }
+    }
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                        IO_COMPLETION_MODIFY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      return Status;
-   }
-
-   /*
-   Try 2 remove packet from queue. Wait (optionaly) if
-   no packet in queue or max num of threads allready running.
-   */
-      
-   do {
-      
-      ListEntry = KeRemoveQueue(Queue, UserMode, Timeout );
-
-      /* Nebbets book says nothing about NtRemoveIoCompletion returning STATUS_USER_APC,
-      and the umode equivalent GetQueuedCompletionStatus says nothing about this either,
-      so my guess it we should restart the operation. Need further investigation. -Gunnar
-      */
-
-   } while((NTSTATUS)ListEntry == STATUS_USER_APC);
-
-   ObDereferenceObject(Queue);
-   
-   if ((NTSTATUS)ListEntry == STATUS_TIMEOUT)
-   {
-      return STATUS_TIMEOUT;
-   }
+    
+    /* Check for success */
+    if (NT_SUCCESS(Status)) {
+
+        /* Remove queue */
+        ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);
+
+        /* If we got a timeout or user_apc back, return the status */
+        if ((NTSTATUS)ListEntry == STATUS_TIMEOUT || (NTSTATUS)ListEntry == STATUS_USER_APC) {
+            
+            Status = (NTSTATUS)ListEntry; 
+            
+        } else {
+            
+            /* Get the Packet Data */
+            Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
+            
+            _SEH_TRY {
+
+                /* Return it */
+                *CompletionKey = Packet->Key;
+                *CompletionContext = Packet->Context;
+                *IoStatusBlock = Packet->IoStatus;
+           
+            } _SEH_HANDLE {
+
+                Status = _SEH_GetExceptionCode();
+            } _SEH_END;
+
+            /* Free packet */
+            ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+        }
    
-   ASSERT(ListEntry);
-   
-   Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
-
-   if (CompletionKey) *CompletionKey = Packet->Key;
-   if (CompletionContext) *CompletionContext = Packet->Context;
-   if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
-
-   ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
-
-   return STATUS_SUCCESS;
+        /* Dereference the Object */
+        ObDereferenceObject(Queue);
+    }
+    
+    /* Return status */
+    return Status;
 }
 
-
-/*
-ASSOSIERT MED FOB's IoCompletionContext
-
-typedef struct _IO_COMPLETION_CONTEXT {
-        PVOID Port; 
-        ULONG Key; 
-} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
-
-*/
-
-
 /*
  * Queues an I/O completion message to an I/O completion object
  */
 NTSTATUS
 STDCALL
-NtSetIoCompletion(
-   IN HANDLE   IoCompletionPortHandle,
-   IN PVOID    CompletionKey,
-   IN PVOID    CompletionContext,
-   IN NTSTATUS CompletionStatus,
-   IN ULONG    CompletionInformation
-   )
+NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
+                  IN PVOID CompletionKey,
+                  IN PVOID CompletionContext,
+                  IN NTSTATUS CompletionStatus,
+                  IN ULONG CompletionInformation)
 {
-   NTSTATUS                Status;
-   PKQUEUE                 Queue;
-
-   Status = ObReferenceObjectByHandle( IoCompletionPortHandle,
+    NTSTATUS Status;
+    PKQUEUE Queue;
+    
+    PAGED_CODE();
+    
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionPortHandle,
                                        IO_COMPLETION_MODIFY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       ExGetPreviousMode(),
                                        (PVOID*)&Queue,
                                        NULL);
-   if (NT_SUCCESS(Status))
-   {
-      Status = IoSetIoCompletion(Queue, CompletionKey, CompletionContext,
-                                 CompletionStatus, CompletionInformation, TRUE);
-      ObDereferenceObject(Queue);
-   }
-
-   return Status;
+    
+    /* Check for Success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Set the Completion */
+        Status = IoSetIoCompletion(Queue, 
+                                   CompletionKey, 
+                                   CompletionContext,
+                                   CompletionStatus, 
+                                   CompletionInformation, 
+                                   TRUE);
+        ObDereferenceObject(Queue);
+    }
+    
+    /* Return status */
+    return Status;
 }
index eff2a12..0cc528d 100644 (file)
@@ -11,6 +11,7 @@
 /* INCLUDES ****************************************************************/
 
 #include <ntoskrnl.h>
+#include "../dbg/kdb.h"
 #define NDEBUG
 #include <internal/debug.h>
 
@@ -34,9 +35,9 @@ ULONGLONG             IoOtherTransferCount = 0;
 KSPIN_LOCK   EXPORTED IoStatisticsLock = 0;
 
 static GENERIC_MAPPING IopFileMapping = {FILE_GENERIC_READ,
-                                        FILE_GENERIC_WRITE,
-                                        FILE_GENERIC_EXECUTE,
-                                        FILE_ALL_ACCESS};
+                FILE_GENERIC_WRITE,
+                FILE_GENERIC_EXECUTE,
+                FILE_ALL_ACCESS};
 
 /* FUNCTIONS ****************************************************************/
 
@@ -51,7 +52,7 @@ IopCloseFile(PVOID ObjectBody,
    
    DPRINT("IopCloseFile()\n");
    
-   if (HandleCount > 0 || FileObject->DeviceObject == NULL)
+   if (HandleCount > 1 || FileObject->DeviceObject == NULL)
      {
        return;
      }
@@ -562,14 +563,17 @@ IoInit (VOID)
 }
 
 
-VOID INIT_FUNCTION
-IoInit2(VOID)
+VOID 
+INIT_FUNCTION
+IoInit2(BOOLEAN BootLog)
 {
   PDEVICE_NODE DeviceNode;
   PDRIVER_OBJECT DriverObject;
   MODULE_OBJECT ModuleObject;
   NTSTATUS Status;
 
+  IoCreateDriverList();
+          
   KeInitializeSpinLock (&IoStatisticsLock);
 
   /* Initialize raw filesystem driver */
@@ -614,6 +618,56 @@ IoInit2(VOID)
   IopInvalidateDeviceRelations(
     IopRootDeviceNode,
     BusRelations);
+  
+     /* Start boot logging */
+    IopInitBootLog(BootLog);
+  
+    /* Load boot start drivers */
+    IopInitializeBootDrivers();
+}
+
+VOID
+STDCALL
+INIT_FUNCTION
+IoInit3(VOID)
+{
+    NTSTATUS Status;
+    
+    /* Create ARC names for boot devices */
+    IoCreateArcNames();
+
+    /* Create the SystemRoot symbolic link */
+    CPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
+    Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
+    if (!NT_SUCCESS(Status)) {
+        DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status);
+        DbgPrintErrorMessage (Status);
+        KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
+    }
+
+    /* Start Profiling on a Debug Build */
+#if defined(KDBG)
+    KdbInit();
+#endif /* KDBG */
+
+    /* I/O is now setup for disk access, so start the debugging logger thread. */
+    if (KdDebugState & KD_DEBUG_FILELOG) DebugLogInit2();
+
+    /* Load services for devices found by PnP manager */
+    IopInitializePnpServices(IopRootDeviceNode, FALSE);
+
+    /* Load system start drivers */
+    IopInitializeSystemDrivers();
+    IoDestroyDriverList();
+
+    /* Stop boot logging */
+    IopStopBootLog();
+
+    /* Assign drive letters */
+    IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
+                         NULL,
+                         NULL,
+                         NULL);    
 }
 
 /*
index ed98e86..7f3a770 100644 (file)
@@ -410,7 +410,16 @@ IofCompleteRequest(PIRP Irp,
 
       if (Irp->UserIosb)
       {
-         *Irp->UserIosb = Irp->IoStatus;
+         _SEH_TRY
+         {
+            *Irp->UserIosb = Irp->IoStatus;
+         }
+         _SEH_HANDLE
+         {
+           DPRINT1("Unable to set UserIosb (at 0x%x) to 0x%x, Error: 0x%x\n",
+                   Irp->UserIosb, Irp->IoStatus, _SEH_GetExceptionCode());
+         }
+         _SEH_END;
       }
 
       if (Irp->UserEvent)
index 0bb060b..6b0cd50 100644 (file)
@@ -121,7 +121,10 @@ IoConnectInterrupt(PKINTERRUPT* InterruptObject,
              {
               for (i = 0; i < count; i++)
                 {
-                  KeDisconnectInterrupt(&Interrupt[i]);
+                  if (ProcessorEnableMask & (1 << i))
+                    {
+                      KeDisconnectInterrupt(&Interrupt[i]);
+                    }
                 }
               ExFreePool(Interrupt);
               return STATUS_INVALID_PARAMETER;
index da6a4db..b4b423f 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/mdl.c
  * PURPOSE:         Io manager mdl functions
- * 
+ *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  */
 
@@ -32,7 +32,7 @@ IoAllocateMdl(PVOID VirtualAddress,
                   PIRP Irp)
 {
    PMDL Mdl;
-   
+
    if (ChargeQuota)
      {
 //     Mdl = ExAllocatePoolWithQuota(NonPagedPool,
@@ -48,27 +48,27 @@ IoAllocateMdl(PVOID VirtualAddress,
                                    TAG_MDL);
      }
    MmInitializeMdl(Mdl, (char*)VirtualAddress, Length);
-   
+
    if (Irp)
    {
       if (SecondaryBuffer)
       {
          ASSERT(Irp->MdlAddress);
-         
+
          /* FIXME: add to end of list maybe?? */
          Mdl->Next = Irp->MdlAddress->Next;
          Irp->MdlAddress->Next = Mdl;
       }
       else
       {
-         /* 
+         /*
           * What if there's allready an mdl at Irp->MdlAddress?
           * Is that bad and should we do something about it?
           */
          Irp->MdlAddress = Mdl;
       }
    }
-   
+
    return(Mdl);
 }
 
@@ -122,13 +122,16 @@ IoBuildPartialMdl(PMDL SourceMdl,
  */
 VOID STDCALL
 IoFreeMdl(PMDL Mdl)
-{   
-   /* 
+{
+   /*
     * This unmaps partial mdl's from kernel space but also asserts that non-partial
     * mdl's isn't still mapped into kernel space.
     */
+   ASSERT(Mdl);
+   ASSERT_IRQL(DISPATCH_LEVEL);
+
    MmPrepareMdlForReuse(Mdl);
-   
+
    ExFreePool(Mdl);
 }
 
index 9ee95cd..d706ba0 100644 (file)
@@ -508,7 +508,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
   DPRINT("ParentNode %x PhysicalDeviceObject %x\n",
     ParentNode, PhysicalDeviceObject);
 
-  Node = (PDEVICE_NODE)ExAllocatePool(PagedPool, sizeof(DEVICE_NODE));
+  Node = (PDEVICE_NODE)ExAllocatePool(NonPagedPool, sizeof(DEVICE_NODE));
   if (!Node)
     {
       return STATUS_INSUFFICIENT_RESOURCES;
@@ -764,16 +764,15 @@ IopCreateDeviceKeyPath(PWSTR Path,
     }
 
   wcsncpy (KeyBuffer, Path, MAX_PATH-1);
-  RtlInitUnicodeString (&KeyName, KeyBuffer);
 
   /* Skip \\Registry\\ */
-  Current = KeyName.Buffer;
-  Current = wcschr (Current, '\\') + 1;
-  Current = wcschr (Current, '\\') + 1;
+  Current = KeyBuffer;
+  Current = wcschr (Current, L'\\') + 1;
+  Current = wcschr (Current, L'\\') + 1;
 
   while (TRUE)
     {
-      Next = wcschr (Current, '\\');
+      Next = wcschr (Current, L'\\');
       if (Next == NULL)
        {
          /* The end */
@@ -783,6 +782,7 @@ IopCreateDeviceKeyPath(PWSTR Path,
          *Next = 0;
        }
 
+      RtlInitUnicodeString (&KeyName, KeyBuffer);
       InitializeObjectAttributes (&ObjectAttributes,
                                  &KeyName,
                                  OBJ_CASE_INSENSITIVE,
@@ -1740,10 +1740,13 @@ IopInvalidateDeviceRelations(
       &IoStatusBlock,
       0,
       0);
-   BootDrivers = NT_SUCCESS(Status) ? FALSE : TRUE;
-
-   ZwClose(Handle);
+   if(NT_SUCCESS(Status))
+   {
+     BootDrivers = FALSE;
+     ZwClose(Handle);
+   }
+   else
+     BootDrivers = TRUE;
 
    /*
     * Initialize services for discovered children. Only boot drivers will
index 95b06f0..775e1da 100644 (file)
 
 /* INCLUDES ******************************************************************/
 
+#define NDEBUG
 #include <ntoskrnl.h>
 #include <internal/debug.h>
 
 /* FUNCTIONS *****************************************************************/
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
@@ -30,8 +31,39 @@ IoReportDetectedDevice(
   IN BOOLEAN ResourceAssigned,
   IN OUT PDEVICE_OBJECT *DeviceObject)
 {
-  DPRINT("IoReportDetectedDevice called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+  PDEVICE_NODE DeviceNode;
+  PDEVICE_OBJECT Pdo;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
+    DeviceObject, DeviceObject ? *DeviceObject : NULL);
+  
+  /* if *DeviceObject is not NULL, we must use it as a PDO,
+   * and don't create a new one.
+   */
+  if (DeviceObject && *DeviceObject)
+    Pdo = *DeviceObject;
+  else
+  {
+    /* create a new PDO and return it in *DeviceObject */
+    Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
+    if (!NT_SUCCESS(Status))
+    {
+      DPRINT("IopCreateDeviceNode() failed (Status 0x%08lx)\n", Status);
+      return Status;
+    }
+    Pdo = DeviceNode->PhysicalDeviceObject;
+    if (DeviceObject)
+      *DeviceObject = Pdo;
+  }
+  
+  /* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
+  
+  /* FIXME: save this device into the root-enumerated list, so this
+   * device would be detected as a PnP device during next startups.
+   */
+  
+  return Status;
 }
 
 /*
@@ -48,8 +80,50 @@ IoReportResourceForDetection(
   IN ULONG DeviceListSize   OPTIONAL,
   OUT PBOOLEAN ConflictDetected)
 {
-  DPRINT("IoReportResourceForDetection called (UNIMPLEMENTED)\n");
-  return STATUS_NOT_IMPLEMENTED;
+  *ConflictDetected = FALSE;
+  DPRINT1("IoReportResourceForDetection unimplemented\n");
+  
+  /* HACK: check if serial debug output is enabled. If yes,
+   * prevent serial port driver to detect this serial port
+   * by indicating a conflict
+   */
+  if ((KdDebugState & KD_DEBUG_SERIAL) && DriverList != NULL)
+  {
+    ULONG ComPortBase = 0;
+    ULONG i;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
+    
+    switch (LogPortInfo.ComPort)
+    {
+      case 1: ComPortBase = 0x3f8; break;
+      case 2: ComPortBase = 0x2f8; break;
+      case 3: ComPortBase = 0x3e8; break;
+      case 4: ComPortBase = 0x2e8; break;
+    }
+    
+    /* search for this port address in DriverList */
+    for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
+    {
+      ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
+      if (ResourceDescriptor->Type == CmResourceTypePort)
+      {
+        if (ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase
+         && ResourceDescriptor->u.Port.Start.u.LowPart + ResourceDescriptor->u.Port.Length > ComPortBase)
+        {
+          *ConflictDetected = TRUE;
+          return STATUS_CONFLICTING_ADDRESSES;
+        }
+      }
+    }
+  }
+  
+  if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)
+  {
+    /* We hope legacy devices will be enumerated by ACPI */
+    *ConflictDetected = TRUE;
+    return STATUS_CONFLICTING_ADDRESSES;
+  }
+  return STATUS_SUCCESS;
 }
 
 /*
@@ -61,7 +135,7 @@ IoReportTargetDeviceChange(
   IN PDEVICE_OBJECT PhysicalDeviceObject,
   IN PVOID NotificationStructure)
 {
-  DPRINT("IoReportTargetDeviceChange called (UNIMPLEMENTED)\n");
+  DPRINT1("IoReportTargetDeviceChange called (UNIMPLEMENTED)\n");
   return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -76,7 +150,7 @@ IoReportTargetDeviceChangeAsynchronous(
   IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback  OPTIONAL,
   IN PVOID Context  OPTIONAL)
 {
-  DPRINT("IoReportTargetDeviceChangeAsynchronous called (UNIMPLEMENTED)\n");
+  DPRINT1("IoReportTargetDeviceChangeAsynchronous called (UNIMPLEMENTED)\n");
   return STATUS_NOT_IMPLEMENTED;
 }
 
index 07af4e5..8acddca 100644 (file)
@@ -44,7 +44,7 @@ NtReadFile (IN HANDLE FileHandle,
 {
   NTSTATUS Status;
   PFILE_OBJECT FileObject;
-  PIRP Irp;
+  PIRP Irp = NULL;
   PIO_STACK_LOCATION StackPtr;
   KPROCESSOR_MODE PreviousMode;
   PKEVENT EventObject = NULL;
@@ -92,24 +92,46 @@ NtReadFile (IN HANDLE FileHandle,
                                       PreviousMode,
                                       (PVOID*)&EventObject,
                                       NULL);
-      if (!NT_SUCCESS(Status))
-       {
-         ObDereferenceObject(FileObject);
-         return Status;
-       }
+    if (!NT_SUCCESS(Status))
+      {
+        ObDereferenceObject(FileObject);
+       return Status;
+      }
 
     KeClearEvent(EventObject);
   }
 
-  KeClearEvent(&FileObject->Event);
+  _SEH_TRY
+  {
+     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+                                       FileObject->DeviceObject,
+                                       Buffer,
+                                       Length,
+                                       ByteOffset,
+                                       EventObject,
+                                       IoStatusBlock);
+  }
+  _SEH_HANDLE
+  {
+     Status = _SEH_GetExceptionCode();
+  }
+  _SEH_END;
+
+  if (!NT_SUCCESS(Status) || Irp == NULL)
+  {
+     if (Event)
+     {
+        ObDereferenceObject(&EventObject);
+     }
+     ObDereferenceObject(FileObject);
+     if (Irp)
+     {
+        IoFreeIrp(Irp);
+     }
+     return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
+  }
 
-  Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
-                                    FileObject->DeviceObject,
-                                    Buffer,
-                                    Length,
-                                    ByteOffset,
-                                    EventObject,
-                                    IoStatusBlock);
+  KeClearEvent(&FileObject->Event);
 
   /* Trigger FileObject/Event dereferencing */
   Irp->Tail.Overlay.OriginalFileObject = FileObject;
@@ -172,7 +194,7 @@ NtWriteFile (IN HANDLE FileHandle,
   OBJECT_HANDLE_INFORMATION HandleInformation;
   NTSTATUS Status;
   PFILE_OBJECT FileObject;
-  PIRP Irp;
+  PIRP Irp = NULL;
   PIO_STACK_LOCATION StackPtr;
   KPROCESSOR_MODE PreviousMode;
   PKEVENT EventObject = NULL;
@@ -253,15 +275,37 @@ NtWriteFile (IN HANDLE FileHandle,
     KeClearEvent(EventObject);
   }
 
-  KeClearEvent(&FileObject->Event);
+  _SEH_TRY
+  {
+     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+                                       FileObject->DeviceObject,
+                                       Buffer,
+                                       Length,
+                                       ByteOffset,
+                                       EventObject,
+                                       IoStatusBlock);
+  }
+  _SEH_HANDLE
+  {
+     Status = _SEH_GetExceptionCode();
+  }
+  _SEH_END;
 
-  Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
-                                    FileObject->DeviceObject,
-                                    Buffer,
-                                    Length,
-                                    ByteOffset,
-                                    EventObject,
-                                    IoStatusBlock);
+  if (!NT_SUCCESS(Status) || Irp == NULL)
+  {
+     if (Event)
+     {
+        ObDereferenceObject(&EventObject);
+     }
+     ObDereferenceObject(FileObject);
+     if (Irp)
+     {
+        IoFreeIrp(Irp);
+     }
+     return NT_SUCCESS(Status) ? STATUS_INSUFFICIENT_RESOURCES : Status;
+  }
+
+  KeClearEvent(&FileObject->Event);
 
   /* Trigger FileObject/Event dereferencing */
   Irp->Tail.Overlay.OriginalFileObject = FileObject;
index cac060f..566561a 100644 (file)
@@ -22,43 +22,20 @@ VOID STDCALL
 IoUpdateShareAccess(PFILE_OBJECT FileObject,
                    PSHARE_ACCESS ShareAccess)
 {
-   if ((FileObject->ReadAccess == FALSE) &&
-       (FileObject->WriteAccess == FALSE) &&
-       (FileObject->DeleteAccess == FALSE))
-     {
-       return;
-     }
-
-   ShareAccess->OpenCount++;
-
-   if (FileObject->ReadAccess == TRUE)
-     {
-       ShareAccess->Readers++;
-     }
-
-   if (FileObject->WriteAccess == TRUE)
-     {
-       ShareAccess->Writers++;
-     }
-
-   if (FileObject->DeleteAccess == TRUE)
-     {
-       ShareAccess->Deleters++;
-     }
-
-   if (FileObject->SharedRead == TRUE)
-     {
-       ShareAccess->SharedRead++;
-     }
-
-   if (FileObject->SharedWrite == TRUE)
-     {
-       ShareAccess->SharedWrite++;
-     }
-
-   if (FileObject->SharedDelete == TRUE)
+   PAGED_CODE();
+   
+   if (FileObject->ReadAccess ||
+       FileObject->WriteAccess ||
+       FileObject->DeleteAccess)
      {
-       ShareAccess->SharedDelete++;
+       ShareAccess->OpenCount++;
+
+       ShareAccess->Readers += FileObject->ReadAccess;
+       ShareAccess->Writers += FileObject->WriteAccess;
+       ShareAccess->Deleters += FileObject->DeleteAccess;
+       ShareAccess->SharedRead += FileObject->SharedRead;
+       ShareAccess->SharedWrite += FileObject->SharedWrite;
+       ShareAccess->SharedDelete += FileObject->SharedDelete;
      }
 }
 
@@ -79,85 +56,48 @@ IoCheckShareAccess(IN ACCESS_MASK DesiredAccess,
   BOOLEAN SharedRead;
   BOOLEAN SharedWrite;
   BOOLEAN SharedDelete;
+  
+  PAGED_CODE();
 
-  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE));
-  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA));
-  DeleteAccess = (DesiredAccess & DELETE);
+  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
+  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
+  DeleteAccess = (DesiredAccess & DELETE) != 0;
 
   FileObject->ReadAccess = ReadAccess;
   FileObject->WriteAccess = WriteAccess;
   FileObject->DeleteAccess = DeleteAccess;
 
-  if (!ReadAccess && !WriteAccess && !DeleteAccess)
-    {
-      return(STATUS_SUCCESS);
-    }
-
-  SharedRead = (DesiredShareAccess & FILE_SHARE_READ);
-  SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE);
-  SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE);
-
-  FileObject->SharedRead = SharedRead;
-  FileObject->SharedWrite = SharedWrite;
-  FileObject->SharedDelete = SharedDelete;
-
-  if (ReadAccess)
-    {
-      if (ShareAccess->SharedRead < ShareAccess->OpenCount)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (WriteAccess)
-    {
-      if (ShareAccess->SharedWrite < ShareAccess->OpenCount)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (DeleteAccess)
-    {
-      if (ShareAccess->SharedDelete < ShareAccess->OpenCount)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (ShareAccess->Readers != 0)
-    {
-      if (SharedRead == FALSE)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (ShareAccess->Writers != 0)
-    {
-      if (SharedWrite == FALSE)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (ShareAccess->Deleters != 0)
+  if (ReadAccess || WriteAccess || DeleteAccess)
     {
-      if (SharedDelete == FALSE)
-       return(STATUS_SHARING_VIOLATION);
-    }
-
-  if (Update == TRUE)
-    {
-      ShareAccess->OpenCount++;
-
-      if (ReadAccess == TRUE)
-       ShareAccess->Readers++;
+      SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
+      SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
+      SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
 
-      if (WriteAccess == TRUE)
-       ShareAccess->Writers++;
-
-      if (DeleteAccess == TRUE)
-       ShareAccess->Deleters++;
-
-      if (SharedRead == TRUE)
-       ShareAccess->SharedRead++;
-
-      if (SharedWrite == TRUE)
-       ShareAccess->SharedWrite++;
+      FileObject->SharedRead = SharedRead;
+      FileObject->SharedWrite = SharedWrite;
+      FileObject->SharedDelete = SharedDelete;
 
-      if (SharedDelete == TRUE)
-       ShareAccess->SharedDelete++;
+      if ((ReadAccess && (ShareAccess->SharedRead < ShareAccess->OpenCount)) ||
+          (WriteAccess && (ShareAccess->SharedWrite < ShareAccess->OpenCount)) ||
+          (DeleteAccess && (ShareAccess->SharedDelete < ShareAccess->OpenCount)) ||
+          ((ShareAccess->Readers != 0) && !SharedRead) ||
+          ((ShareAccess->Writers != 0) && !SharedWrite) ||
+          ((ShareAccess->Deleters != 0) && !SharedDelete))
+        {
+          return(STATUS_SHARING_VIOLATION);
+        }
+
+      if (Update)
+        {
+          ShareAccess->OpenCount++;
+
+          ShareAccess->Readers += ReadAccess;
+          ShareAccess->Writers += WriteAccess;
+          ShareAccess->Deleters += DeleteAccess;
+          ShareAccess->SharedRead += SharedRead;
+          ShareAccess->SharedWrite += SharedWrite;
+          ShareAccess->SharedDelete += SharedDelete;
+        }
     }
 
   return(STATUS_SUCCESS);
@@ -171,43 +111,20 @@ VOID STDCALL
 IoRemoveShareAccess(IN PFILE_OBJECT FileObject,
                    IN PSHARE_ACCESS ShareAccess)
 {
-  if ((FileObject->ReadAccess == FALSE) &&
-      (FileObject->WriteAccess == FALSE) &&
-      (FileObject->DeleteAccess == FALSE))
-    {
-      return;
-    }
-
-  ShareAccess->OpenCount--;
+  PAGED_CODE();
 
-  if (FileObject->ReadAccess == TRUE)
+  if (FileObject->ReadAccess ||
+      FileObject->WriteAccess ||
+      FileObject->DeleteAccess)
     {
-      ShareAccess->Readers--;
-    }
-
-  if (FileObject->WriteAccess == TRUE)
-    {
-      ShareAccess->Writers--;
-    }
-
-  if (FileObject->DeleteAccess == TRUE)
-    {
-      ShareAccess->Deleters--;
-    }
-
-  if (FileObject->SharedRead == TRUE)
-    {
-      ShareAccess->SharedRead--;
-    }
-
-  if (FileObject->SharedWrite == TRUE)
-    {
-      ShareAccess->SharedWrite--;
-    }
-
-  if (FileObject->SharedDelete == TRUE)
-    {
-      ShareAccess->SharedDelete--;
+      ShareAccess->OpenCount--;
+
+      ShareAccess->Readers -= FileObject->ReadAccess;
+      ShareAccess->Writers -= FileObject->WriteAccess;
+      ShareAccess->Deleters -= FileObject->DeleteAccess;
+      ShareAccess->SharedRead -= FileObject->SharedRead;
+      ShareAccess->SharedWrite -= FileObject->SharedWrite;
+      ShareAccess->SharedDelete -= FileObject->SharedDelete;
     }
 }
 
@@ -227,10 +144,12 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess,
   BOOLEAN SharedRead;
   BOOLEAN SharedWrite;
   BOOLEAN SharedDelete;
+  
+  PAGED_CODE();
 
-  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE));
-  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA));
-  DeleteAccess = (DesiredAccess & DELETE);
+  ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
+  WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
+  DeleteAccess = (DesiredAccess & DELETE) != 0;
 
   FileObject->ReadAccess = ReadAccess;
   FileObject->WriteAccess = WriteAccess;
@@ -238,10 +157,6 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess,
 
   if (!ReadAccess && !WriteAccess && !DeleteAccess)
     {
-      FileObject->SharedRead = FALSE;
-      FileObject->SharedWrite = FALSE;
-      FileObject->SharedDelete = FALSE;
-
       ShareAccess->OpenCount = 0;
       ShareAccess->Readers = 0;
       ShareAccess->Writers = 0;
@@ -253,22 +168,22 @@ IoSetShareAccess(IN ACCESS_MASK DesiredAccess,
     }
   else
     {
-      SharedRead = (DesiredShareAccess & FILE_SHARE_READ);
-      SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE);
-      SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE);
+      SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
+      SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
+      SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
 
       FileObject->SharedRead = SharedRead;
       FileObject->SharedWrite = SharedWrite;
       FileObject->SharedDelete = SharedDelete;
 
       ShareAccess->OpenCount = 1;
-      ShareAccess->Readers = (ReadAccess) ? 1 : 0;
-      ShareAccess->Writers = (WriteAccess) ? 1 : 0;
-      ShareAccess->Deleters = (DeleteAccess) ? 1 : 0;
+      ShareAccess->Readers = ReadAccess;
+      ShareAccess->Writers = WriteAccess;
+      ShareAccess->Deleters = DeleteAccess;
 
-      ShareAccess->SharedRead = (SharedRead) ? 1 : 0;
-      ShareAccess->SharedWrite = (SharedWrite) ? 1 : 0;
-      ShareAccess->SharedDelete = (SharedDelete) ? 1 : 0;
+      ShareAccess->SharedRead = SharedRead;
+      ShareAccess->SharedWrite = SharedWrite;
+      ShareAccess->SharedDelete = SharedDelete;
     }
 }
 
@@ -280,12 +195,15 @@ NTSTATUS STDCALL
 IoCheckDesiredAccess(IN OUT PACCESS_MASK DesiredAccess,
                     IN ACCESS_MASK GrantedAccess)
 {
+  PAGED_CODE();
+  
   RtlMapGenericMask(DesiredAccess,
                    IoFileObjectType->Mapping);
-  if ((*DesiredAccess & GrantedAccess) != GrantedAccess)
-    return(STATUS_ACCESS_DENIED);
 
-  return(STATUS_SUCCESS);
+  if ((~(*DesiredAccess) & GrantedAccess) != 0)
+    return STATUS_ACCESS_DENIED;
+  else
+    return STATUS_SUCCESS;
 }
 
 
@@ -343,7 +261,7 @@ IoSetInformation(IN PFILE_OBJECT FileObject,
 
 
    Status = ObReferenceObjectByPointer(FileObject,
-                                      FILE_WRITE_ATTRIBUTES,
+                                      0, /* FIXME - depends on the information class */
                                       IoFileObjectType,
                                       KernelMode);
    if (!NT_SUCCESS(Status))
index df168e9..c6ff88d 100644 (file)
@@ -107,7 +107,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
    PreviousMode = ExGetPreviousMode();
 
    Status = ObReferenceObjectByHandle(FileHandle,
-                                     FILE_READ_ATTRIBUTES,
+                                     0, /* FIXME - depends on the information class! */
                                      IoFileObjectType,
                                      PreviousMode,
                                      (PVOID*)&FileObject,
index 8b90882..9d01c6b 100644 (file)
@@ -249,4 +249,18 @@ IoWMIDeviceObjectToInstanceName(
        return STATUS_NOT_IMPLEMENTED;
 }
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtTraceEvent(IN ULONG TraceHandle,
+             IN ULONG Flags,
+             IN ULONG TraceHeaderLength,
+             IN struct _EVENT_TRACE_HEADER* TraceHeader)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 /*Eof*/
index 2e86dcf..3b8e48a 100644 (file)
@@ -36,11 +36,11 @@ DebugLogDumpMessages(VOID)
   ULONG Offset;
   ULONG Length;
 
-  if (!(KdDebugState & KD_DEBUG_BOOTLOG))
+  if (!(KdDebugState & KD_DEBUG_FILELOG))
     {
       return;
     }
-  KdDebugState &= ~KD_DEBUG_BOOTLOG;
+  KdDebugState &= ~KD_DEBUG_FILELOG;
  
   Offset = (DebugLogEnd + 1) % DEBUGLOG_SIZE;
   do
index 9085cc7..498ddb0 100644 (file)
@@ -327,7 +327,9 @@ GspMem2Hex (PCHAR Address,
       ch = *Address;
       GspAccessLocation = NULL;
       if (MayFault && GspMemoryError)
-        return (Buffer);
+        {
+          return (Buffer);
+        }
       *Buffer++ = HexChars[(ch >> 4) & 0xf];
       *Buffer++ = HexChars[ch & 0xf];
       Address++;
@@ -377,7 +379,7 @@ GspHex2Mem (PCHAR Buffer,
           ch = (CHAR)(HexValue (*Buffer++) << 4);
           ch = (CHAR)(ch + HexValue (*Buffer++));
 
-          GspAccessLocation = Address;
+          GspAccessLocation = current;
           *current = ch;
           GspAccessLocation = NULL;
           current++;
@@ -386,7 +388,9 @@ GspHex2Mem (PCHAR Buffer,
         {
           MmSetPageProtect (NULL, page, oldprot);
           if (GspMemoryError)
-            return (Buffer);
+            {
+              return (Buffer);
+            }
         }
     }
 
@@ -1053,7 +1057,6 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
   LONG NewPC;
   PCHAR ptr;
   LONG Esp;
-  KIRQL OldIrql;
 
   /* FIXME: Stop on other CPUs too */
   /* Disable hardware debugging while we are inside the stub */
@@ -1072,16 +1075,11 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
     {
       GspAccessLocation = NULL;
       GspMemoryError = TRUE;
-      Context->Eip += 2;
+      TrapFrame->Eip += 2;
     }
   else
     {
       /* Don't switch threads */
-      OldIrql = KeGetCurrentIrql();
-      if (OldIrql < DISPATCH_LEVEL)
-        {
-          KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
-        }
           
       /* Always use the current thread when entering the exception handler */
       if (NULL != GspDbgThread)
@@ -1284,10 +1282,6 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
 #else
 #error Unknown compiler for inline assembler
 #endif
-                if (OldIrql < DISPATCH_LEVEL)
-                  {
-                    KeLowerIrql(OldIrql);
-                  }
 
                 KeContextToTrapFrame(Context, TrapFrame);
                 return ((SigVal == 5) ? (kdContinue) : (kdHandleException));
@@ -1425,17 +1419,17 @@ KdGdbStubInit(ULONG Phase)
 
   if (Phase == 0)
     {
-                 DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
-
-                 GspInitialized = TRUE;
-                 GspRunThread = PsGetCurrentThread();
+      GspInitialized = TRUE;
+      GspRunThread = PsGetCurrentThread();
      
-                  ObReferenceObject(GspRunThread);
+      ObReferenceObject(GspRunThread);
 
-/*               GspDbgThread = PsGetCurrentThread(); */
-                  GspDbgThread = NULL;
-                 GspEnumThread = NULL;
+/*      GspDbgThread = PsGetCurrentThread(); */
+      GspDbgThread = NULL;
+      GspEnumThread = NULL;
 
+      HalDisplayString("Waiting for GDB to attach\n");
+      DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
       DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
     }
   else if (Phase == 1)
@@ -1493,8 +1487,6 @@ KdGdbDebugPrint(LPSTR Message)
            GspOutBuffer[3 + Length] = '\0';
            GspPutPacketNoWait (&GspOutBuffer[0]);
          }
-#else
-  HalDisplayString(Message);
 #endif
 }
 
index 68004e5..6e823db 100644 (file)
@@ -118,13 +118,11 @@ KdInitSystem(ULONG BootPhase,
              if (!_strnicmp(p2, "SCREEN", 6) && BootPhase > 0)
                {
                  p2 += 6;
-                 KdDebuggerEnabled = TRUE;
                  KdDebugState |= KD_DEBUG_SCREEN;
                }
              else if (!_strnicmp(p2, "BOCHS", 5) && BootPhase == 0)
                {
                  p2 += 5;
-                 KdDebuggerEnabled = TRUE;
                  KdDebugState |= KD_DEBUG_BOCHS;
                }
              else if (!_strnicmp(p2, "GDB", 3) && BootPhase == 0)
@@ -150,21 +148,18 @@ KdInitSystem(ULONG BootPhase,
                  Value = (ULONG)atol(p2);
                  if (Value > 0 && Value < 5)
                    {
-                     KdDebuggerEnabled = TRUE;
-                         KdDebugState |= KD_DEBUG_SERIAL;
+                     KdDebugState |= KD_DEBUG_SERIAL;
                      LogPortInfo.ComPort = Value;
                    }
                }
-             else if (!_strnicmp(p2, "BOOTLOG", 4) && BootPhase > 0)
+             else if (!_strnicmp(p2, "FILE", 4) && BootPhase > 0)
                {
                  p2 += 4;
-                 KdDebuggerEnabled = TRUE;
-                 KdDebugState |= KD_DEBUG_BOOTLOG;
+                 KdDebugState |= KD_DEBUG_FILELOG;
                }
              else if (!_strnicmp(p2, "MDA", 3) && BootPhase > 0)
                {
                  p2 += 3;
-                 KdDebuggerEnabled = TRUE;
                  KdDebugState |= KD_DEBUG_MDA;
                }
            }
@@ -172,13 +167,11 @@ KdInitSystem(ULONG BootPhase,
       else if (!_strnicmp(p2, "KDSERIAL", 8) && BootPhase > 0)
         {
          p2 += 8;
-         KdDebuggerEnabled = TRUE;
          KdDebugState |= KD_DEBUG_SERIAL | KD_DEBUG_KDSERIAL;
         }
       else if (!_strnicmp(p2, "KDNOECHO", 8) && BootPhase > 0)
         {
          p2 += 8;
-         KdDebuggerEnabled = TRUE;
          KdDebugState |= KD_DEBUG_KDNOECHO;
         }
       else if (!_strnicmp(p2, "DEBUG", 5) && BootPhase == 0)
@@ -243,30 +236,21 @@ KdInitSystem(ULONG BootPhase,
                }
            }
        }
-#if defined(KDBG) || defined(DBG)
-    else if (!_strnicmp(p2, "PROFILE", 7)  && BootPhase > 0)
-      {
-        KdbInitProfiling();
-      }
-#endif /* KDBG */
       p1 = p2;
     }
 
   /* Perform any initialization nescessary */
-  if (KdDebuggerEnabled == TRUE)
-    {
       if (KdDebugState & KD_DEBUG_GDB && BootPhase == 0)
            KdPortInitializeEx(&GdbPortInfo, 0, 0);
 
       if (KdDebugState & KD_DEBUG_SERIAL  && BootPhase == 0)
            KdPortInitializeEx(&LogPortInfo, 0, 0);
 
-      if (KdDebugState & KD_DEBUG_BOOTLOG && BootPhase > 0)
+      if (KdDebugState & KD_DEBUG_FILELOG && BootPhase > 0)
            DebugLogInit();
 
       if (KdDebugState & KD_DEBUG_MDA && BootPhase > 0)
            KdInitializeMda();
-    }
 }
 
 
@@ -274,7 +258,7 @@ VOID INIT_FUNCTION
 KdInit1(VOID)
 {
   /* Initialize kernel debugger (phase 0) */
-  if ((KdDebuggerEnabled == TRUE) &&
+  if ((KdDebuggerEnabled) &&
       (KdDebugState & KD_DEBUG_GDB))
     {
       KdGdbStubInit(0);
@@ -286,7 +270,7 @@ VOID INIT_FUNCTION
 KdInit2(VOID)
 {
   /* Initialize kernel debugger (phase 1) */
-  if ((KdDebuggerEnabled == TRUE) &&
+  if ((KdDebuggerEnabled) &&
       (KdDebugState & KD_DEBUG_GDB))
     {
       KdGdbStubInit(1);
@@ -298,8 +282,6 @@ VOID INIT_FUNCTION
 KdInit3(VOID)
 {
   /* Print some information */
-  if (KdDebuggerEnabled == TRUE)
-    {
       if (KdDebugState & KD_DEBUG_GDB)
            PrintString("\n   GDB debugging enabled. COM%ld %ld Baud\n\n",
                        GdbPortInfo.ComPort, GdbPortInfo.BaudRate);
@@ -317,11 +299,10 @@ KdInit3(VOID)
            PrintString("\n   Serial debugging enabled. COM%ld %ld Baud\n\n",
                        LogPortInfo.ComPort, LogPortInfo.BaudRate);
 
-      if (KdDebugState & KD_DEBUG_BOOTLOG)
+      if (KdDebugState & KD_DEBUG_FILELOG)
            PrintString("\n   File log debugging enabled\n\n");
       if (KdDebugState & KD_DEBUG_MDA)
            PrintString("\n   MDA debugging enabled\n\n");
-    }
 }
 
 
@@ -374,7 +355,7 @@ KdpPrintString(PANSI_STRING String)
        if (KdDebugState & KD_DEBUG_BOCHS)
                KdBochsDebugPrint(pch);
 
-       if (KdDebugState & KD_DEBUG_BOOTLOG)
+       if (KdDebugState & KD_DEBUG_FILELOG)
                DebugLogWrite(pch);
 
        if (KdDebugState & KD_DEBUG_MDA)
@@ -455,7 +436,7 @@ KdSystemDebugControl(ULONG Code)
   /* B - Bug check the system. */
   else if (Code == 1)
     {
-      KEBUGCHECK(0xDEADDEAD);
+      KEBUGCHECK(MANUALLY_INITIATED_CRASH);
     }
   /* 
    * C -  Dump statistics about the distribution of tagged blocks in 
diff --git a/reactos/ntoskrnl/ke/alert.c b/reactos/ntoskrnl/ke/alert.c
deleted file mode 100644 (file)
index 99084a8..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $Id:$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/alert.c
- * PURPOSE:         Alerts
- * 
- * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-
-/* FUNCTIONS *****************************************************************/
-
-
-BOOLEAN
-STDCALL
-KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
-/*
- * FUNCTION: Tests whether there are any pending APCs for the current thread
- * and if so the APCs will be delivered on exit from kernel mode
- */
-{
-   KIRQL OldIrql;
-   PKTHREAD Thread = KeGetCurrentThread();
-   BOOLEAN OldState;
-   
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-   
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   KiAcquireSpinLock(&Thread->ApcQueueLock);
-   
-   OldState = Thread->Alerted[AlertMode];
-   
-   /* If the Thread is Alerted, Clear it */
-   if (OldState) {
-      Thread->Alerted[AlertMode] = FALSE;
-   } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) {
-      /* If the mode is User and the Queue isn't empty, set Pending */
-      Thread->ApcState.UserApcPending = TRUE;
-   }
-   
-   KiReleaseSpinLock(&Thread->ApcQueueLock);
-   KeReleaseDispatcherDatabaseLock(OldIrql);
-   return OldState;
-}
-
-
-VOID
-KeAlertThread(PKTHREAD Thread, KPROCESSOR_MODE AlertMode)
-{
-   KIRQL oldIrql;
-
-   
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-      
-
-   /* Return if thread is already alerted. */
-   if (Thread->Alerted[AlertMode] == FALSE)
-   {
-      if (Thread->State == THREAD_STATE_BLOCKED &&
-          (AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
-          Thread->Alertable)
-      {
-         KiAbortWaitThread(Thread, STATUS_ALERTED);
-      }
-      else
-      {
-         Thread->Alerted[AlertMode] = TRUE;
-      }
-   }
-   
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-}
-
-
-/* 
- *
- * NOT EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertResumeThread(IN  HANDLE ThreadHandle,
-          OUT PULONG SuspendCount)
-{
-   UNIMPLEMENTED;
-   return(STATUS_NOT_IMPLEMENTED);
-
-}
-
-/* 
- * @implemented
- *
- * EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertThread (IN HANDLE ThreadHandle)
-{
-   KPROCESSOR_MODE PreviousMode;
-   PETHREAD Thread;
-   NTSTATUS Status;
-   
-   PreviousMode = ExGetPreviousMode();
-
-   Status = ObReferenceObjectByHandle(ThreadHandle,
-                  THREAD_SUSPEND_RESUME,
-                  PsThreadType,
-                  PreviousMode,
-                  (PVOID*)&Thread,
-                  NULL);
-   if (!NT_SUCCESS(Status))
-     {
-   return(Status);
-     }
-
-   /* do an alert depending on the processor mode. If some kmode code wants to
-      enforce a umode alert it should call KeAlertThread() directly. If kmode
-      code wants to do a kmode alert it's sufficient to call it with Zw or just
-      use KeAlertThread() directly */
-
-   KeAlertThread(&Thread->Tcb, PreviousMode);
-   
-   ObDereferenceObject(Thread);
-   return(STATUS_SUCCESS);
-}
-
-
-/* 
- * NOT EXPORTED
- */
-NTSTATUS
-STDCALL
-NtTestAlert(VOID)
-{
-   KPROCESSOR_MODE PreviousMode;
-   
-   PreviousMode = ExGetPreviousMode();
-   
-   /* Check and Alert Thread if needed */
-   
-   return KeTestAlertThread(PreviousMode) ? STATUS_ALERTED : STATUS_SUCCESS;
-}
-
index 5b47908..b2f0626 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/apc.c
 #define NDEBUG
 #include <internal/debug.h>
 
-/* GLOBALS *******************************************************************/
-
-VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
-
-#define TAG_KAPC     TAG('K', 'A', 'P', 'C')
-
 /* FUNCTIONS *****************************************************************/
 
-/*
- * @implemented
- */
+/*++
+ * KeEnterCriticalRegion 
+ * @implemented NT4
+ *
+ *     The KeEnterCriticalRegion routine temporarily disables the delivery of 
+ *     normal kernel APCs; special kernel-mode APCs are still delivered.
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     Highest-level drivers can call this routine while running in the context
+ *     of the thread that requested the current I/O operation. Any caller of 
+ *     this routine should call KeLeaveCriticalRegion as quickly as possible.
+ *
+ *     Callers of KeEnterCriticalRegion must be running at IRQL <= APC_LEVEL.
+ *
+ *--*/
+VOID 
+STDCALL 
+KeEnterCriticalRegion(VOID)
+{
+    /* Disable Kernel APCs */
+    PKTHREAD Thread = KeGetCurrentThread();
+    if (Thread) Thread->KernelApcDisable--;
+}
+
+/*++
+ * KeInitializeApc 
+ * @implemented NT4
+ *
+ *     The The KeInitializeApc routine initializes an APC object, and registers
+ *     the Kernel, Rundown and Normal routines for that object.
+ *
+ * Params:
+ *     Apc - Pointer to a KAPC structure that represents the APC object to 
+ *           initialize. The caller must allocate storage for the structure
+ *           from resident memory.
+ *
+ *     Thread - Thread to which to deliver the APC.
+ *
+ *     TargetEnvironment - APC Environment to be used.
+ *
+ *     KernelRoutine - Points to the KernelRoutine to associate with the APC.
+ *                     This routine is executed for all APCs.
+ *
+ *     RundownRoutine - Points to the RundownRoutine to associate with the APC.
+ *                      This routine is executed when the Thread exists with
+ *                      the APC executing.
+ *
+ *     NormalRoutine - Points to the NormalRoutine to associate with the APC.
+ *                     This routine is executed at PASSIVE_LEVEL. If this is
+ *                     not specifed, the APC becomes a Special APC and the
+ *                     Mode and Context parameters are ignored.
+ *
+ *     Mode - Specifies the processor mode at which to run the Normal Routine.
+ *
+ *     Context - Specifices the value to pass as Context parameter to the 
+ *               registered routines.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     The caller can queue an initialized APC with KeInsertQueueApc.
+ *
+ *     Storage for the APC object must be resident, such as nonpaged pool 
+ *     allocated by the caller.
+ *
+ *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
 VOID
 STDCALL
-KeInitializeApc(
-       IN PKAPC  Apc,
-       IN PKTHREAD  Thread,
-       IN KAPC_ENVIRONMENT  TargetEnvironment,
-       IN PKKERNEL_ROUTINE  KernelRoutine,
-       IN PKRUNDOWN_ROUTINE  RundownRoutine OPTIONAL,
-       IN PKNORMAL_ROUTINE  NormalRoutine,
-       IN KPROCESSOR_MODE  Mode,
-       IN PVOID  Context)
-/*
- * FUNCTION: Initialize an APC object
- * ARGUMENTS:
- *       Apc = Pointer to the APC object to initialized
- *       Thread = Thread the APC is to be delivered to
- *       TargetEnvironment = APC environment to use
- *       KernelRoutine = Routine to be called for a kernel-mode APC
- *       RundownRoutine = Routine to be called if the thread has exited with
- *                        the APC being executed
- *       NormalRoutine = Routine to be called for a user-mode APC
- *       Mode = APC mode
- *       Context = Parameter to be passed to the APC routine
- */
+KeInitializeApc(IN PKAPC Apc,
+                IN PKTHREAD Thread,
+                IN KAPC_ENVIRONMENT TargetEnvironment,
+                IN PKKERNEL_ROUTINE KernelRoutine,
+                IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
+                IN PKNORMAL_ROUTINE NormalRoutine,
+                IN KPROCESSOR_MODE Mode,
+                IN PVOID Context)
 {
-       DPRINT ("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
-               "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
-               "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine,
-               NormalRoutine,Mode,Context);
-
-       /* Set up the basic APC Structure Data */
-       RtlZeroMemory(Apc, sizeof(KAPC));
-       Apc->Type = KApc;
-       Apc->Size = sizeof(KAPC);
-       
-       /* Set the Environment */
-       if (TargetEnvironment == CurrentApcEnvironment) {
-               Apc->ApcStateIndex = Thread->ApcStateIndex;
-       } else {
-               Apc->ApcStateIndex = TargetEnvironment;
-       }
-       
-       /* Set the Thread and Routines */
-       Apc->Thread = Thread;
-       Apc->KernelRoutine = KernelRoutine;
-       Apc->RundownRoutine = RundownRoutine;
-       Apc->NormalRoutine = NormalRoutine;
+    DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
+           "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
+           "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine,
+            NormalRoutine,Mode,Context);
+
+    /* Set up the basic APC Structure Data */
+    RtlZeroMemory(Apc, sizeof(KAPC));
+    Apc->Type = ApcObject;
+    Apc->Size = sizeof(KAPC);
+    
+    /* Set the Environment */
+    if (TargetEnvironment == CurrentApcEnvironment) {
+        
+        Apc->ApcStateIndex = Thread->ApcStateIndex;
+        
+    } else {
+        
+        Apc->ApcStateIndex = TargetEnvironment;
+    }
+    
+    /* Set the Thread and Routines */
+    Apc->Thread = Thread;
+    Apc->KernelRoutine = KernelRoutine;
+    Apc->RundownRoutine = RundownRoutine;
+    Apc->NormalRoutine = NormalRoutine;
    
-       /* Check if this is a Special APC, in which case we use KernelMode and no Context */
-       if (ARGUMENT_PRESENT(NormalRoutine)) {
-               Apc->ApcMode = Mode;
-               Apc->NormalContext = Context;
-       } else {
-               Apc->ApcMode = KernelMode;
-       }  
+    /* Check if this is a Special APC, in which case we use KernelMode and no Context */
+    if (ARGUMENT_PRESENT(NormalRoutine)) {
+        
+        Apc->ApcMode = Mode;
+        Apc->NormalContext = Context;
+        
+    } else {
+        
+        Apc->ApcMode = KernelMode;
+    }  
 }
 
-/*
- * @implemented
- */
+/*++
+ * KiInsertQueueApc 
+ *
+ *     The KiInsertQueueApc routine queues a APC for execution when the right
+ *     scheduler environment exists.
+ *
+ * Params:
+ *     Apc - Pointer to an initialized control object of type DPC for which the
+ *           caller provides the storage. 
+ *
+ *     PriorityBoost - Priority Boost to apply to the Thread.
+ *
+ * Returns:
+ *     If the APC is already inserted or APC queueing is disabled, FALSE.
+ *     Otherwise, TRUE.
+ *
+ * Remarks:
+ *     The APC will execute at APC_LEVEL for the KernelRoutine registered, and
+ *     at PASSIVE_LEVEL for the NormalRoutine registered.
+ *
+ *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
 BOOLEAN
 STDCALL
-KeInsertQueueApc (PKAPC        Apc,
-                 PVOID SystemArgument1,
-                 PVOID SystemArgument2,
-                 KPRIORITY PriorityBoost)
-/*
- * FUNCTION: Queues an APC for execution
- * ARGUMENTS:
- *         Apc = APC to be queued
- *         SystemArgument[1-2] = Arguments we ignore and simply pass on.
- *         PriorityBoost = Priority Boost to give to the Thread
- */
+KiInsertQueueApc(PKAPC Apc,
+                 KPRIORITY PriorityBoost)
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread;
-       PLIST_ENTRY ApcListEntry;
-       PKAPC QueuedApc;
-   
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-       DPRINT ("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
-               "SystemArgument2 %x)\n",Apc,SystemArgument1,
-               SystemArgument2);
-
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Get the Thread specified in the APC */
-       Thread = Apc->Thread;
-          
-       /* Make sure the thread allows APC Queues.
-    * The thread is not apc queueable, for instance, when it's (about to be) terminated.
+    PKTHREAD Thread = Apc->Thread;
+    PLIST_ENTRY ApcListEntry;
+    PKAPC QueuedApc;
+    
+    /* Don't do anything if the APC is already inserted */
+    if (Apc->Inserted) {
+        
+        return FALSE;
+    }
+    
+    /* Three scenarios: 
+       1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
+       2) User APC which is PsExitSpecialApc = Put it at the front of the List
+       3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
     */
-       if (Thread->ApcQueueable == FALSE) {
-               DPRINT("Thread doesn't allow APC Queues\n");
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return FALSE;
-       }
-       
-       /* Set the System Arguments */
-       Apc->SystemArgument1 = SystemArgument1;
-       Apc->SystemArgument2 = SystemArgument2;
-
-       /* Don't do anything if the APC is already inserted */
-       if (Apc->Inserted) {
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return FALSE;
-       }
-       
-       /* Three scenarios: 
-          1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
-          2) User APC which is PsExitSpecialApc = Put it at the front of the List
-          3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
-       */
-       if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
-               DPRINT ("Inserting the Process Exit APC into the Queue\n");
-               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
-               InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
-                              &Apc->ApcListEntry);
-       } else if (Apc->NormalRoutine == NULL) {
-               DPRINT ("Inserting Special APC %x into the Queue\n", Apc);
-               for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
-                    ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
-                    ApcListEntry = ApcListEntry->Flink) {
-
-                       QueuedApc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-                       if (Apc->NormalRoutine != NULL) break;
-               }
-               
-               /* We found the first "Normal" APC, so write right before it */
-               ApcListEntry = ApcListEntry->Blink;
-               InsertHeadList(ApcListEntry, &Apc->ApcListEntry);
-       } else {
-               DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
-               InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
-                              &Apc->ApcListEntry);
-       }
-       
-       /* Confirm Insertion */ 
-       Apc->Inserted = TRUE;
-
-       /* Three possibilites here again:
-          1) Kernel APC, The thread is Running: Request an Interrupt
-          2) Kernel APC, The Thread is Waiting at PASSIVE_LEVEL and APCs are enabled and not in progress: Unwait the Thread
-          3) User APC, Unwait the Thread if it is alertable
-       */ 
-       if (Apc->ApcMode == KernelMode) { 
-               Thread->ApcState.KernelApcPending = TRUE;
-               if (Thread->State == THREAD_STATE_RUNNING) { 
-                       /* FIXME: Use IPI */
-                       DPRINT ("Requesting APC Interrupt for Running Thread \n");
-                       HalRequestSoftwareInterrupt(APC_LEVEL);
-      } else if ((Thread->State == THREAD_STATE_BLOCKED) && 
-                 (Thread->WaitIrql < APC_LEVEL) && 
-                 (Apc->NormalRoutine == NULL)) 
-      {
-                       DPRINT ("Waking up Thread for Kernel-Mode APC Delivery \n");
-                       KiAbortWaitThread(Thread, STATUS_KERNEL_APC);
-               }
+    if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
+        
+        DPRINT ("Inserting the Process Exit APC into the Queue\n");
+        Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
+        InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
+                       &Apc->ApcListEntry);
+        
+    } else if (Apc->NormalRoutine == NULL) {
+        
+        DPRINT ("Inserting Special APC %x into the Queue\n", Apc);
+        
+        for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
+             ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
+             ApcListEntry = ApcListEntry->Flink) {
+
+            QueuedApc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+            if (Apc->NormalRoutine != NULL) break;
+        }
+        
+        /* We found the first "Normal" APC, so write right before it */
+        ApcListEntry = ApcListEntry->Blink;
+        InsertHeadList(ApcListEntry, &Apc->ApcListEntry);
+        
+    } else {
+        
+        DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
+        InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
+                       &Apc->ApcListEntry);
+    }
+    
+    /* Confirm Insertion */    
+    Apc->Inserted = TRUE;
+
+    /*
+     * Three possibilites here again:
+     *  1) Kernel APC, The thread is Running: Request an Interrupt
+     *  2) Kernel APC, The Thread is Waiting at PASSIVE_LEVEL and APCs are enabled and not in progress: Unwait the Thread
+     *  3) User APC, Unwait the Thread if it is alertable
+     */ 
+    if (Apc->ApcMode == KernelMode) { 
+        
+        /* Set Kernel APC pending */
+        Thread->ApcState.KernelApcPending = TRUE;
+        
+        /* Check the Thread State */
+        if (Thread->State == THREAD_STATE_RUNNING) { 
+            
+            /* FIXME: Use IPI */
+            DPRINT ("Requesting APC Interrupt for Running Thread \n");
+            HalRequestSoftwareInterrupt(APC_LEVEL);
+            
+        } else if ((Thread->State == THREAD_STATE_BLOCKED) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
+                   ((Apc->NormalRoutine == NULL) || 
+                   ((!Thread->KernelApcDisable) && (!Thread->ApcState.KernelApcInProgress)))) {
+          
+            DPRINT("Waking up Thread for Kernel-Mode APC Delivery \n");
+            KiAbortWaitThread(Thread, STATUS_KERNEL_APC, PriorityBoost);
+        }
+        
    } else if ((Thread->State == THREAD_STATE_BLOCKED) && 
               (Thread->WaitMode == UserMode) && 
-              (Thread->Alertable)) 
-   {
-               DPRINT ("Waking up Thread for User-Mode APC Delivery \n");
-               Thread->ApcState.UserApcPending = TRUE;
-      KiAbortWaitThread(Thread, STATUS_USER_APC);
-       }
-
-       /* Return Sucess if we are here */
-       KeReleaseDispatcherDatabaseLock(OldIrql);
-       return TRUE;
+              (Thread->Alertable)) {
+       
+        DPRINT("Waking up Thread for User-Mode APC Delivery \n");
+        Thread->ApcState.UserApcPending = TRUE;
+        KiAbortWaitThread(Thread, STATUS_USER_APC, PriorityBoost);
+    }
+    
+    return TRUE;
 }
+    
+/*++
+ * KeInsertQueueApc 
+ * @implemented NT4
+ *
+ *     The KeInsertQueueApc routine queues a APC for execution when the right
+ *     scheduler environment exists.
+ *
+ * Params:
+ *     Apc - Pointer to an initialized control object of type DPC for which the
+ *           caller provides the storage. 
+ *
+ *     SystemArgument[1,2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ *     PriorityBoost - Priority Boost to apply to the Thread.
+ *
+ * Returns:
+ *     If the APC is already inserted or APC queueing is disabled, FALSE.
+ *     Otherwise, TRUE.
+ *
+ * Remarks:
+ *     The APC will execute at APC_LEVEL for the KernelRoutine registered, and
+ *     at PASSIVE_LEVEL for the NormalRoutine registered.
+ *
+ *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
+BOOLEAN
+STDCALL
+KeInsertQueueApc(PKAPC Apc,
+                 PVOID SystemArgument1,
+                 PVOID SystemArgument2,
+                 KPRIORITY PriorityBoost)
 
-BOOLEAN STDCALL
-KeRemoveQueueApc (PKAPC Apc)
-/*
- * FUNCTION: Removes APC object from the apc queue
- * ARGUMENTS:
- *          Apc = APC to remove
- * RETURNS: TRUE if the APC was in the queue
- *          FALSE otherwise
- * NOTE: This function is not exported.
- */
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread = Apc->Thread;
-
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-       DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
-       
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-       
-       /* Remove it from the Queue if it's inserted */
-       if (!Apc->Inserted == FALSE) {
-               RemoveEntryList(&Apc->ApcListEntry);
-               Apc->Inserted = FALSE;
-               
-               /* If the Queue is completely empty, then no more APCs are pending */
-               if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) {
-                       if (Apc->ApcMode == KernelMode) {
-                               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->KernelApcPending = FALSE;
-                       } else {
-                               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = FALSE;
-                       }
-               }
-       } else {
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return(FALSE);
-       }
-       
-       /* Restore IRQL and Return */
-       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-       KeReleaseDispatcherDatabaseLock(OldIrql);
-       return(TRUE);
+    KIRQL OldIrql;
+    PKTHREAD Thread;
+    BOOLEAN Inserted;
+   
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+    DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
+           "SystemArgument2 %x)\n",Apc,SystemArgument1,
+            SystemArgument2);
+
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Get the Thread specified in the APC */
+    Thread = Apc->Thread;
+       
+    /* Make sure the thread allows APC Queues.
+    * The thread is not apc queueable, for instance, when it's (about to be) terminated.
+    */
+    if (Thread->ApcQueueable == FALSE) {
+        DPRINT("Thread doesn't allow APC Queues\n");
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        return FALSE;
+    }
+    
+    /* Set the System Arguments */
+    Apc->SystemArgument1 = SystemArgument1;
+    Apc->SystemArgument2 = SystemArgument2;
+
+    /* Call the Internal Function */
+    Inserted = KiInsertQueueApc(Apc, PriorityBoost);
+
+    /* Return Sucess if we are here */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return Inserted;
+}
+
+/*++
+ * KeLeaveCriticalRegion 
+ * @implemented NT4
+ *
+ *     The KeLeaveCriticalRegion routine reenables the delivery of normal 
+ *     kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion.
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     Highest-level drivers can call this routine while running in the context
+ *     of the thread that requested the current I/O operation. 
+ *
+ *     Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL.
+ *
+ *--*/
+VOID 
+STDCALL 
+KeLeaveCriticalRegion (VOID)
+{
+    PKTHREAD Thread = KeGetCurrentThread(); 
+
+    /* Check if Kernel APCs are now enabled */
+    if((Thread) && (++Thread->KernelApcDisable == 0)) { 
+        
+        /* Check if we need to request an APC Delivery */
+        if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) { 
+            
+            /* Set APC Pending */
+            Thread->ApcState.KernelApcPending = TRUE; 
+            HalRequestSoftwareInterrupt(APC_LEVEL); 
+        } 
+    } 
 }
 
+/*++
+ * KeRemoveQueueApc 
+ *
+ *     The KeRemoveQueueApc routine removes a given APC object from the system 
+ *     APC queue.
+ *
+ * Params:
+ *     APC - Pointer to an initialized APC object that was queued by calling
+ *           KeInsertQueueApc.
+ *
+ * Returns:
+ *     TRUE if the APC Object is in the APC Queue. If it isn't, no operation is
+ *     performed and FALSE is returned.
+ *
+ * Remarks:
+ *     If the given APC Object is currently queued, it is removed from the queue
+ *     and any calls to the registered routines are cancelled.
+ *
+ *     Callers of KeLeaveCriticalRegion can be running at any IRQL.
+ *
+ *--*/
+BOOLEAN 
+STDCALL
+KeRemoveQueueApc(PKAPC Apc)
+{
+    KIRQL OldIrql;
+    PKTHREAD Thread = Apc->Thread;
 
-/*
- * @implemented
- */
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+    DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
+    
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+    
+    /* Check if it's inserted */
+    if (Apc->Inserted) {
+        
+        /* Remove it from the Queue*/
+        RemoveEntryList(&Apc->ApcListEntry);
+        Apc->Inserted = FALSE;
+        
+        /* If the Queue is completely empty, then no more APCs are pending */
+        if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) {
+            
+            /* Set the correct State based on the Apc Mode */
+            if (Apc->ApcMode == KernelMode) {
+                
+                Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->KernelApcPending = FALSE;
+                
+            } else {
+                
+                Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = FALSE;
+            }
+        }
+        
+    } else {
+        
+        /* It's not inserted, fail */
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        return(FALSE);
+    }
+    
+    /* Restore IRQL and Return */
+    KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return(TRUE);
+}
+
+/*++
+ * KiDeliverApc 
+ * @implemented @NT4
+ *    
+ *     The KiDeliverApc routine is called from IRQL switching code if the
+ *     thread is returning from an IRQL >= APC_LEVEL and Kernel-Mode APCs are
+ *     pending. 
+ *
+ * Params:
+ *     DeliveryMode - Specifies the current processor mode.
+ *
+ *     Reserved - Pointer to the Exception Frame on non-i386 builds.
+ *
+ *     TrapFrame - Pointer to the Trap Frame.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     First, Special APCs are delivered, followed by Kernel-Mode APCs and
+ *     User-Mode APCs. Note that the TrapFrame is only valid if the previous
+ *     mode is User.
+ *
+ *     Upon entry, this routine executes at APC_LEVEL.
+ *
+ *--*/
 VOID 
 STDCALL
 KiDeliverApc(KPROCESSOR_MODE DeliveryMode,
              PVOID Reserved,
              PKTRAP_FRAME TrapFrame)
-/*
- * FUNCTION: Deliver an APC to the current thread.
- * NOTES: This is called from the IRQL switching code if the current thread
- * is returning from an IRQL greater than or equal to APC_LEVEL to 
- * PASSIVE_LEVEL and there are kernel-mode APCs pending. This means any
- * pending APCs will be delivered after a thread gets a new quantum and
- * after it wakes from a wait. Note that the TrapFrame is only valid if
- * the previous mode is User.
- */
 {
-       PKTHREAD Thread = KeGetCurrentThread();
-       PLIST_ENTRY ApcListEntry;
-       PKAPC Apc;
-       KIRQL OldIrql;
-       PKKERNEL_ROUTINE KernelRoutine;
-       PVOID NormalContext;
-       PKNORMAL_ROUTINE NormalRoutine;
-       PVOID SystemArgument1;
-       PVOID SystemArgument2;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PLIST_ENTRY ApcListEntry;
+    PKAPC Apc;
+    KIRQL OldIrql;
+    PKKERNEL_ROUTINE KernelRoutine;
+    PVOID NormalContext;
+    PKNORMAL_ROUTINE NormalRoutine;
+    PVOID SystemArgument1;
+    PVOID SystemArgument2;
    
-   ASSERT_IRQL_EQUAL(APC_LEVEL);
-
-       /* Lock the APC Queue and Raise IRQL to Synch */
-       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-
-       /* Clear APC Pending */
-       Thread->ApcState.KernelApcPending = FALSE;
-       
-       /* Do the Kernel APCs first */
-       while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) {
-       
-               /* Get the next Entry */
-               ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
-               Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-               
-               /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
-               NormalRoutine   = Apc->NormalRoutine;
-               KernelRoutine   = Apc->KernelRoutine;
-               NormalContext   = Apc->NormalContext;
-               SystemArgument1 = Apc->SystemArgument1;
-               SystemArgument2 = Apc->SystemArgument2;
+    ASSERT_IRQL_EQUAL(APC_LEVEL);
+
+    /* Lock the APC Queue and Raise IRQL to Synch */
+    KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+
+    /* Clear APC Pending */
+    Thread->ApcState.KernelApcPending = FALSE;
+    
+    /* Do the Kernel APCs first */
+    while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) {
+    
+        /* Get the next Entry */
+        ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
+        Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+        
+        /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
+        NormalRoutine   = Apc->NormalRoutine;
+        KernelRoutine   = Apc->KernelRoutine;
+        NormalContext   = Apc->NormalContext;
+        SystemArgument1 = Apc->SystemArgument1;
+        SystemArgument2 = Apc->SystemArgument2;
        
-               /* Special APC */
-       if (NormalRoutine == NULL) {
-                       /* Remove the APC from the list */
-                       Apc->Inserted = FALSE;
-                       RemoveEntryList(ApcListEntry);
-                       
-                       /* Go back to APC_LEVEL */
-                       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                       
-                       /* Call the Special APC */
-                       DPRINT("Delivering a Special APC: %x\n", Apc);
-                       KernelRoutine(Apc,
-                                     &NormalRoutine,
-                                     &NormalContext,
-                                     &SystemArgument1,
-                                     &SystemArgument2);
-
-                       /* Raise IRQL and Lock again */
-                       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-               } else {
-                        /* Normal Kernel APC */
-                       if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
+        /* Special APC */
+       if (NormalRoutine == NULL) {
+           
+            /* Remove the APC from the list */
+            Apc->Inserted = FALSE;
+            RemoveEntryList(ApcListEntry);
+            
+            /* Go back to APC_LEVEL */
+            KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+            
+            /* Call the Special APC */
+            DPRINT("Delivering a Special APC: %x\n", Apc);
+            KernelRoutine(Apc,
+                      &NormalRoutine,
+                      &NormalContext,
+                      &SystemArgument1,
+                      &SystemArgument2);
+
+            /* Raise IRQL and Lock again */
+            KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+            
+        } else {
+            
+             /* Normal Kernel APC */
+            if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
+            
+                /*
+                 * DeliveryMode must be KernelMode in this case, since one may not
+                 * return to umode while being inside a critical section or while 
+                 * a regular kmode apc is running (the latter should be impossible btw).
+                 * -Gunnar
+                 */
+                ASSERT(DeliveryMode == KernelMode);
+
+                KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+                return;
+            }
             
-            /*
-             * DeliveryMode must be KernelMode in this case, since one may not
-             * return to umode while being inside a critical section or while 
-             * a regular kmode apc is running (the latter should be impossible btw).
-             * -Gunnar
-             */
-            ASSERT(DeliveryMode == KernelMode);
-
-                               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                               return;
-                       }
-                       
-                       /* Dequeue the APC */
-                       RemoveEntryList(ApcListEntry);
-                       Apc->Inserted = FALSE;
-                       
-                       /* Go back to APC_LEVEL */
-                       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                       
-                       /* Call the Kernel APC */
-                       DPRINT("Delivering a Normal APC: %x\n", Apc);
-                       KernelRoutine(Apc,
-                                     &NormalRoutine,
-                                     &NormalContext,
-                                     &SystemArgument1,
-                                     &SystemArgument2);
-                       
-                       /* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */
-                       if (NormalRoutine != NULL) {
-                               /* At Passive Level, this APC can be prempted by a Special APC */
-                               Thread->ApcState.KernelApcInProgress = TRUE;
-                               KeLowerIrql(PASSIVE_LEVEL);
-                               
-                               /* Call and Raise IRQ back to APC_LEVEL */
-                               DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc);
-                               NormalRoutine(&NormalContext, &SystemArgument1, &SystemArgument2);
-                               KeRaiseIrql(APC_LEVEL, &OldIrql);
-                       }
-
-                       /* Raise IRQL and Lock again */
-                       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-                       Thread->ApcState.KernelApcInProgress = FALSE;
-               }
-       }
-       
-       /* Now we do the User APCs */
-       if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
-          (DeliveryMode == UserMode) &&
-                        (Thread->ApcState.UserApcPending == TRUE)) {
-                        
-               /* It's not pending anymore */
-               Thread->ApcState.UserApcPending = FALSE;
-
-               /* Get the APC Object */
-               ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
-               Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-               
-               /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
-               NormalRoutine   = Apc->NormalRoutine;
-               KernelRoutine   = Apc->KernelRoutine;
-               NormalContext   = Apc->NormalContext;
-               SystemArgument1 = Apc->SystemArgument1;
-               SystemArgument2 = Apc->SystemArgument2; 
-               
-               /* Remove the APC from Queue, restore IRQL and call the APC */
-               RemoveEntryList(ApcListEntry);
-      Apc->Inserted = FALSE;
+            /* Dequeue the APC */
+            RemoveEntryList(ApcListEntry);
+            Apc->Inserted = FALSE;
+            
+            /* Go back to APC_LEVEL */
+            KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+            
+            /* Call the Kernel APC */
+            DPRINT("Delivering a Normal APC: %x\n", Apc);
+            KernelRoutine(Apc,
+                      &NormalRoutine,
+                      &NormalContext,
+                      &SystemArgument1,
+                      &SystemArgument2);
+            
+            /* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */
+            if (NormalRoutine != NULL) {
+                
+                /* At Passive Level, this APC can be prempted by a Special APC */
+                Thread->ApcState.KernelApcInProgress = TRUE;
+                KeLowerIrql(PASSIVE_LEVEL);
+                
+                /* Call and Raise IRQ back to APC_LEVEL */
+                DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc);
+                NormalRoutine(&NormalContext, &SystemArgument1, &SystemArgument2);
+                KeRaiseIrql(APC_LEVEL, &OldIrql);
+            }
+
+            /* Raise IRQL and Lock again */
+            KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+            Thread->ApcState.KernelApcInProgress = FALSE;
+        }
+    }
+    
+    /* Now we do the User APCs */
+    if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
+        (DeliveryMode == UserMode) && (Thread->ApcState.UserApcPending == TRUE)) {
+             
+        /* It's not pending anymore */
+        Thread->ApcState.UserApcPending = FALSE;
+
+        /* Get the APC Object */
+        ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
+        Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+        
+        /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
+        NormalRoutine   = Apc->NormalRoutine;
+        KernelRoutine   = Apc->KernelRoutine;
+        NormalContext   = Apc->NormalContext;
+        SystemArgument1 = Apc->SystemArgument1;
+        SystemArgument2 = Apc->SystemArgument2; 
+        
+        /* Remove the APC from Queue, restore IRQL and call the APC */
+        RemoveEntryList(ApcListEntry);
+        Apc->Inserted = FALSE;
       
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-               DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
-               KernelRoutine(Apc,
-                             &NormalRoutine,
-                             &NormalContext,
-                             &SystemArgument1,
-                             &SystemArgument2);
-
-               if (NormalRoutine == NULL) {
-                       /* Check if more User APCs are Pending */
-                       KeTestAlertThread(UserMode);
-               } else {
-                       /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
-                       DPRINT("Delivering a User APC: %x\n", Apc);
-                       KiInitializeUserApc(Reserved, 
-                                           TrapFrame,
-                                           NormalRoutine,
-                                           NormalContext,
-                                           SystemArgument1,
-                                           SystemArgument2);
-               }
-       } else {
-               /* Go back to APC_LEVEL */
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-       }
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+        DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
+        KernelRoutine(Apc,
+                  &NormalRoutine,
+                  &NormalContext,
+                  &SystemArgument1,
+                  &SystemArgument2);
+
+        if (NormalRoutine == NULL) {
+            
+            /* Check if more User APCs are Pending */
+            KeTestAlertThread(UserMode);
+            
+        } else {
+            
+            /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
+            DPRINT("Delivering a User APC: %x\n", Apc);
+            KiInitializeUserApc(Reserved, 
+                        TrapFrame,
+                        NormalRoutine,
+                        NormalContext,
+                        SystemArgument1,
+                        SystemArgument2);
+        }
+        
+    } else {
+        
+        /* Go back to APC_LEVEL */
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    }
 }
 
 VOID 
 STDCALL
 KiFreeApcRoutine(PKAPC Apc,
-                PKNORMAL_ROUTINE* NormalRoutine,
-                PVOID* NormalContext,
-                PVOID* SystemArgument1,
-                PVOID* SystemArgument2)
+                 PKNORMAL_ROUTINE* NormalRoutine,
+                 PVOID* NormalContext,
+                 PVOID* SystemArgument1,
+                 PVOID* SystemArgument2)
 {
-       /* Free the APC and do nothing else */
-       ExFreePool(Apc);
+    /* Free the APC and do nothing else */
+    ExFreePool(Apc);
 }
 
-VOID 
+/*++
+ * KiInitializeUserApc 
+ *    
+ *     Prepares the Context for a User-Mode APC called through NTDLL.DLL
+ *
+ * Params:
+ *     Reserved - Pointer to the Exception Frame on non-i386 builds.
+ *
+ *     TrapFrame - Pointer to the Trap Frame.
+ *
+ *     NormalRoutine - Pointer to the NormalRoutine to call.
+ *
+ *     NormalContext - Pointer to the context to send to the Normal Routine.
+ *
+ *     SystemArgument[1-2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     None.
+ *
+ *--*/
+VOID
+STDCALL
 KiInitializeUserApc(IN PVOID Reserved,
-                   IN PKTRAP_FRAME TrapFrame,
-                   IN PKNORMAL_ROUTINE NormalRoutine,
-                   IN PVOID NormalContext,
-                   IN PVOID SystemArgument1,
-                   IN PVOID SystemArgument2)  
-/*
- * FUNCTION: Prepares the Context for a user mode APC through ntdll.dll
- */
+                    IN PKTRAP_FRAME TrapFrame,
+                    IN PKNORMAL_ROUTINE NormalRoutine,
+                    IN PVOID NormalContext,
+                    IN PVOID SystemArgument1,
+                    IN PVOID SystemArgument2)  
 {
-       PCONTEXT Context;
-       PULONG Esp;
+    PCONTEXT Context;
+    PULONG Esp;
 
-       DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, KeGetCurrentThread()->TrapFrame);
+    DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, KeGetCurrentThread()->TrapFrame);
    
-       /*
-        * Save the thread's current context (in other words the registers
-        * that will be restored when it returns to user mode) so the
-        * APC dispatcher can restore them later
-        */
-       Context = (PCONTEXT)(((PUCHAR)TrapFrame->Esp) - sizeof(CONTEXT));
-       RtlZeroMemory(Context, sizeof(CONTEXT));
-       Context->ContextFlags = CONTEXT_FULL;
-       Context->SegGs = TrapFrame->Gs;
-       Context->SegFs = TrapFrame->Fs;
-       Context->SegEs = TrapFrame->Es;
-       Context->SegDs = TrapFrame->Ds;
-       Context->Edi = TrapFrame->Edi;
-       Context->Esi = TrapFrame->Esi;
-       Context->Ebx = TrapFrame->Ebx;
-       Context->Edx = TrapFrame->Edx;
-       Context->Ecx = TrapFrame->Ecx;
-       Context->Eax = TrapFrame->Eax;
-       Context->Ebp = TrapFrame->Ebp;
-       Context->Eip = TrapFrame->Eip;
-       Context->SegCs = TrapFrame->Cs;
-       Context->EFlags = TrapFrame->Eflags;
-       Context->Esp = TrapFrame->Esp;
-       Context->SegSs = TrapFrame->Ss;
+    /*
+     * Save the thread's current context (in other words the registers
+     * that will be restored when it returns to user mode) so the
+     * APC dispatcher can restore them later
+     */
+    Context = (PCONTEXT)(((PUCHAR)TrapFrame->Esp) - sizeof(CONTEXT));
+    RtlZeroMemory(Context, sizeof(CONTEXT));
+    Context->ContextFlags = CONTEXT_FULL;
+    Context->SegGs = TrapFrame->Gs;
+    Context->SegFs = TrapFrame->Fs;
+    Context->SegEs = TrapFrame->Es;
+    Context->SegDs = TrapFrame->Ds;
+    Context->Edi = TrapFrame->Edi;
+    Context->Esi = TrapFrame->Esi;
+    Context->Ebx = TrapFrame->Ebx;
+    Context->Edx = TrapFrame->Edx;
+    Context->Ecx = TrapFrame->Ecx;
+    Context->Eax = TrapFrame->Eax;
+    Context->Ebp = TrapFrame->Ebp;
+    Context->Eip = TrapFrame->Eip;
+    Context->SegCs = TrapFrame->Cs;
+    Context->EFlags = TrapFrame->Eflags;
+    Context->Esp = TrapFrame->Esp;
+    Context->SegSs = TrapFrame->Ss;
        
-       /*
-        * Setup the trap frame so the thread will start executing at the
-        * APC Dispatcher when it returns to user-mode
-        */
-       Esp = (PULONG)(((PUCHAR)TrapFrame->Esp) - (sizeof(CONTEXT) + (6 * sizeof(ULONG))));
-       Esp[0] = 0xdeadbeef;
-       Esp[1] = (ULONG)NormalRoutine;
-       Esp[2] = (ULONG)NormalContext;
-       Esp[3] = (ULONG)SystemArgument1;
-       Esp[4] = (ULONG)SystemArgument2;
-       Esp[5] = (ULONG)Context;
-       TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
-       TrapFrame->Esp = (ULONG)Esp;
+    /*
+     * Setup the trap frame so the thread will start executing at the
+     * APC Dispatcher when it returns to user-mode
+     */
+    Esp = (PULONG)(((PUCHAR)TrapFrame->Esp) - (sizeof(CONTEXT) + (6 * sizeof(ULONG))));
+    Esp[0] = 0xdeadbeef;
+    Esp[1] = (ULONG)NormalRoutine;
+    Esp[2] = (ULONG)NormalContext;
+    Esp[3] = (ULONG)SystemArgument1;
+    Esp[4] = (ULONG)SystemArgument2;
+    Esp[5] = (ULONG)Context;
+    TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
+    TrapFrame->Esp = (ULONG)Esp;
 }
 
-/*
- * @implemented
- */
+/*++
+ * KeAreApcsDisabled 
+ * @implemented NT4
+ *    
+ *     Prepares the Context for a User-Mode APC called through NTDLL.DLL
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     KeAreApcsDisabled returns TRUE if the thread is within a critical region
+ *     or a guarded region, and FALSE otherwise.
+ *
+ * Remarks:
+ *     A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled to 
+ *     determine if normal kernel APCs are disabled. A thread that is inside a 
+ *     critical region has both user APCs and normal kernel APCs disabled, but 
+ *     not special kernel APCs. A thread that is inside a guarded region has 
+ *     all APCs disabled, including special kernel APCs.
+ *
+ *     Callers of this routine must be running at IRQL <= APC_LEVEL.
+ *
+ *--*/
 BOOLEAN
 STDCALL
-KeAreApcsDisabled(
-       VOID
-       )
+KeAreApcsDisabled(VOID)
 {
-       return KeGetCurrentThread()->KernelApcDisable ? TRUE : FALSE;
+    /* Return the Kernel APC State */
+    return KeGetCurrentThread()->KernelApcDisable ? TRUE : FALSE;
 }
 
+/*++
+ * NtQueueApcThread 
+ * NT4
+ *    
+ *    This routine is used to queue an APC from user-mode for the specified 
+ *    thread.
+ *
+ * Params:
+ *     Thread Handle - Handle to the Thread. This handle must have THREAD_SET_CONTEXT privileges.
+ *
+ *     ApcRoutine - Pointer to the APC Routine to call when the APC executes.
+ *
+ *     NormalContext - Pointer to the context to send to the Normal Routine.
+ *
+ *     SystemArgument[1-2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ * Returns:
+ *     STATUS_SUCCESS or failure cute from associated calls.
+ *
+ * Remarks:
+ *      The thread must enter an alertable wait before the APC will be 
+ *      delivered.
+ *
+ *--*/
 NTSTATUS 
 STDCALL
-NtQueueApcThread(HANDLE                        ThreadHandle,
-                PKNORMAL_ROUTINE       ApcRoutine,
-                PVOID                  NormalContext,
-                PVOID                  SystemArgument1,
-                PVOID                  SystemArgument2)
-/*
- * FUNCTION: 
- *           This function is used to queue an APC from user-mode for the specified thread.
- *           The thread must enter an alertable wait before the APC will be delivered.
- *
- * ARGUMENTS:
- *           Thread Handle - Handle to the Thread. This handle must have THREAD_SET_CONTEXT privileges.
- *           ApcRoutine - Pointer to the APC Routine to call when the APC executes.
- *           NormalContext - User-defined value to pass to the APC Routine
- *           SystemArgument1 - User-defined value to pass to the APC Routine
- *           SystemArgument2 - User-defined value to pass to the APC Routine
- *
- * RETURNS:  NTSTATUS SUCCESS or Failure Code from included calls.
- */
+NtQueueApcThread(HANDLE ThreadHandle,
+         PKNORMAL_ROUTINE ApcRoutine,
+         PVOID NormalContext,
+         PVOID SystemArgument1,
+         PVOID SystemArgument2)
 {
-
-       PKAPC Apc;
-       PETHREAD Thread;
-       KPROCESSOR_MODE PreviousMode;
-       NTSTATUS Status;
-       
-       PreviousMode = ExGetPreviousMode();
-
-       /* Get ETHREAD from Handle */
-       Status = ObReferenceObjectByHandle(ThreadHandle,
-                                          THREAD_SET_CONTEXT,
-                                          PsThreadType,
-                                          PreviousMode,
-                                          (PVOID)&Thread,
-                                          NULL);
-       
-       /* Fail if the Handle is invalid for some reason */
-       if (!NT_SUCCESS(Status)) {
-               return(Status);
-       }
-       
-       /* If this is a Kernel or System Thread, then fail */
-       if (Thread->Tcb.Teb == NULL) {
-               ObDereferenceObject(Thread);
-               return STATUS_INVALID_HANDLE;
-       }
+    PKAPC Apc;
+    PETHREAD Thread;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    /* Get ETHREAD from Handle */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                       THREAD_SET_CONTEXT,
+                       PsThreadType,
+                       PreviousMode,
+                       (PVOID)&Thread,
+                       NULL);
+    
+    /* Fail if the Handle is invalid for some reason */
+    if (!NT_SUCCESS(Status)) {
+        
+        return(Status);
+    }
+    
+    /* If this is a Kernel or System Thread, then fail */
+    if (Thread->Tcb.Teb == NULL) {
+        
+        ObDereferenceObject(Thread);
+        return STATUS_INVALID_HANDLE;
+    }
    
-       /* Allocate an APC */
-       Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_KAPC);
-       if (Apc == NULL) {
-               ObDereferenceObject(Thread);
-               return(STATUS_NO_MEMORY);
-       }
+    /* Allocate an APC */
+    Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('P', 's', 'a', 'p'));
+    if (Apc == NULL) {
+        
+        ObDereferenceObject(Thread);
+        return(STATUS_NO_MEMORY);
+    }
    
-       /* Initialize and Queue a user mode apc (always!) */
-       KeInitializeApc(Apc,
-                       &Thread->Tcb,
-                       OriginalApcEnvironment,
-                       KiFreeApcRoutine,
-                       NULL,
-                       ApcRoutine,
-                       UserMode,
-                       NormalContext);
-       if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) {
-               Status = STATUS_UNSUCCESSFUL;
-       } else {
-               Status = STATUS_SUCCESS;
-       }
+    /* Initialize and Queue a user mode apc (always!) */
+    KeInitializeApc(Apc,
+                    &Thread->Tcb,
+                    OriginalApcEnvironment,
+                    KiFreeApcRoutine,
+                    NULL,
+                    ApcRoutine,
+                    UserMode,
+                    NormalContext);
+    
+    if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) {
+        
+        Status = STATUS_UNSUCCESSFUL;
+        
+    } else {
+        
+        Status = STATUS_SUCCESS;
+    }
    
-       /* Dereference Thread and Return */
-       ObDereferenceObject(Thread);
-       return Status;
+    /* Dereference Thread and Return */
+    ObDereferenceObject(Thread);
+    return Status;
 }
 
-
-static inline VOID RepairList(PLIST_ENTRY Original, 
-                             PLIST_ENTRY Copy,
-                             KPROCESSOR_MODE Mode)
+static inline 
+VOID RepairList(PLIST_ENTRY Original, 
+                PLIST_ENTRY Copy,
+                KPROCESSOR_MODE Mode)
 {
-       /* Copy Source to Desination */
-       if (IsListEmpty(&Original[(int)Mode])) {
-               InitializeListHead(&Copy[(int)Mode]);
-       } else {
-               Copy[(int)Mode].Flink = Original[(int)Mode].Flink; 
-               Copy[(int)Mode].Blink = Original[(int)Mode].Blink;
-               Original[(int)Mode].Flink->Blink = &Copy[(int)Mode];
-               Original[(int)Mode].Blink->Flink = &Copy[(int)Mode];
-       }
+    /* Copy Source to Desination */
+    if (IsListEmpty(&Original[(int)Mode])) {
+        
+        InitializeListHead(&Copy[(int)Mode]);
+        
+    } else {
+        
+        Copy[(int)Mode].Flink = Original[(int)Mode].Flink; 
+        Copy[(int)Mode].Blink = Original[(int)Mode].Blink;
+        Original[(int)Mode].Flink->Blink = &Copy[(int)Mode];
+        Original[(int)Mode].Blink->Flink = &Copy[(int)Mode];
+    }
 }
 
 VOID
 STDCALL
-KiMoveApcState (PKAPC_STATE OldState,
-               PKAPC_STATE NewState)
+KiMoveApcState(PKAPC_STATE OldState,
+               PKAPC_STATE NewState)
 {
-       /* Restore backup of Original Environment */
-       *NewState = *OldState;
+    /* Restore backup of Original Environment */
+    *NewState = *OldState;
     
-       /* Repair Lists */
-       RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode);
-       RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode);
+    /* Repair Lists */
+    RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode);
+    RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode);
 }
 
index 2af3e26..2604b47 100644 (file)
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/bug.c
  * PURPOSE:         Graceful system shutdown if a bug is detected
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu - Rewrote Bugcheck Routines and implemented Reason Callbacks.
+ *                  David Welch (welch@cwcom.net)
  *                  Phillip Susi
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-#include <ntos/bootvid.h>
+#define NDEBUG
 #include <internal/debug.h>
-#include "../../hal/halx86/include/hal.h"
 
 /* GLOBALS ******************************************************************/
 
 static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL};
+static LIST_ENTRY BugcheckReasonCallbackListHead = {NULL,NULL};
 static ULONG InBugCheck;
+static PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
+static ULONG KeBugCheckCount = 1;
 
 /* FUNCTIONS *****************************************************************/
 
-VOID INIT_FUNCTION
-KeInitializeBugCheck(VOID)
+VOID
+INIT_FUNCTION
+KiInitializeBugCheck(VOID)
 {
-  InitializeListHead(&BugcheckCallbackListHead);
-  InBugCheck = 0;
+    PRTL_MESSAGE_RESOURCE_DATA BugCheckData;
+    LDR_RESOURCE_INFO ResourceInfo;
+    PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
+    NTSTATUS Status;
+
+    /* Initialize Callbadk Listhead and State */
+    InitializeListHead(&BugcheckCallbackListHead);
+    InitializeListHead(&BugcheckReasonCallbackListHead);
+    InBugCheck = 0;
+
+    /* Cache the Bugcheck Message Strings. Prepare the Lookup Data */
+    ResourceInfo.Type = 11;
+    ResourceInfo.Name = 1;
+    ResourceInfo.Language = 9;
+    
+    /* Do the lookup. */
+    Status = LdrFindResource_U((PVOID)KERNEL_BASE,
+                               &ResourceInfo,
+                               RESOURCE_DATA_LEVEL,
+                               &ResourceDataEntry);
+    
+    /* Make sure it worked */
+    if (NT_SUCCESS(Status)) {
+        
+        DPRINT1("Found Bugcheck Resource Data!\n");
+        
+        /* Now actually get a pointer to it */
+        Status = LdrAccessResource((PVOID)KERNEL_BASE,
+                                   ResourceDataEntry,
+                                   (PVOID*)&BugCheckData,
+                                   NULL);
+        
+        /* Make sure it worked */
+        if (NT_SUCCESS(Status)) {
+
+            DPRINT1("Got Pointer to Bugcheck Resource Data!\n");
+            KiBugCodeMessages = BugCheckData;
+        }
+    }
 }
 
 /*
  * @implemented
  */
-BOOLEAN STDCALL
+BOOLEAN 
+STDCALL
 KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
 {
-       /* Check the Current State */
-       if (CallbackRecord->State == BufferInserted) {
-               CallbackRecord->State = BufferEmpty;
-               RemoveEntryList(&CallbackRecord->Entry);
-               return TRUE;
-       }
-       
-       /* The callback wasn't registered */
-       return FALSE;
+    KIRQL OldIrql;
+    BOOLEAN Status = FALSE;
+    
+    /* Raise IRQL to High */
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check the Current State */
+    if (CallbackRecord->State == BufferInserted) {
+
+        /* Reset state and remove from list */
+        CallbackRecord->State = BufferEmpty;
+        RemoveEntryList(&CallbackRecord->Entry);
+        
+        Status = TRUE;
+    }
+
+    /* Lower IRQL and return */
+    KeLowerIrql(OldIrql);
+    return Status;
 }
 
 /*
  * @implemented
  */
-BOOLEAN STDCALL
-KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
-                          PKBUGCHECK_CALLBACK_ROUTINE  CallbackRoutine,
-                          PVOID Buffer,
-                          ULONG Length,
-                          PUCHAR Component)
+BOOLEAN
+STDCALL
+KeDeregisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord)
 {
+    KIRQL OldIrql;
+    BOOLEAN Status = FALSE;
+    
+    /* Raise IRQL to High */
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check the Current State */
+    if (CallbackRecord->State == BufferInserted) {
+
+        /* Reset state and remove from list */
+        CallbackRecord->State = BufferEmpty;
+        RemoveEntryList(&CallbackRecord->Entry);
+        
+        Status = TRUE;
+    }
 
-       /* Check the Current State first so we don't double-register */
-       if (CallbackRecord->State == BufferEmpty) {
-               CallbackRecord->Length = Length;
-               CallbackRecord->Buffer = Buffer;
-               CallbackRecord->Component = Component;
-               CallbackRecord->CallbackRoutine = CallbackRoutine;
-               CallbackRecord->State = BufferInserted;
-               InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
-               
-               return TRUE;
-       }
-  
-       /* The Callback was already registered */
-       return(FALSE);
+    /* Lower IRQL and return */
+    KeLowerIrql(OldIrql);
+    return Status;
 }
 
-VOID STDCALL
-KeBugCheckWithTf(ULONG BugCheckCode,        
-                ULONG BugCheckParameter1,
-                ULONG BugCheckParameter2,
-                ULONG BugCheckParameter3,
-                ULONG BugCheckParameter4,
-                PKTRAP_FRAME Tf)
+/*
+ * @implemented
+ */
+BOOLEAN 
+STDCALL
+KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
+                           PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
+                           PVOID Buffer,
+                           ULONG Length,
+                           PUCHAR Component)
 {
-  PRTL_MESSAGE_RESOURCE_ENTRY Message;
-  NTSTATUS Status;
-  ULONG Mask;
-  KIRQL OldIrql;
-
-  /* Make sure we're switching back to the blue screen and print messages on it */
-  HalReleaseDisplayOwnership();
-  if (0 == (KdDebugState & KD_DEBUG_GDB))
-    {
-      KdDebugState |= KD_DEBUG_SCREEN;
+    KIRQL OldIrql;
+    BOOLEAN Status = FALSE;
+    
+    /* Raise IRQL to High */
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check the Current State first so we don't double-register */
+    if (CallbackRecord->State == BufferEmpty) {
+        
+        /* Set the Callback Settings and insert into the list */
+        CallbackRecord->Length = Length;
+        CallbackRecord->Buffer = Buffer;
+        CallbackRecord->Component = Component;
+        CallbackRecord->CallbackRoutine = CallbackRoutine;
+        CallbackRecord->State = BufferInserted;
+        InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
+    
+        Status = TRUE;
     }
 
-  Ke386DisableInterrupts();
-  DebugLogDumpMessages();
+    /* Lower IRQL and return */
+    KeLowerIrql(OldIrql);
+    return Status;
+}
 
-  if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
-    {
-      MmUnlockAddressSpace(MmGetKernelAddressSpace());
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+KeRegisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
+                                 IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
+                                 IN KBUGCHECK_CALLBACK_REASON Reason,
+                                 IN PUCHAR Component)
+{
+    KIRQL OldIrql;
+    BOOLEAN Status = FALSE;
+    
+    /* Raise IRQL to High */
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check the Current State first so we don't double-register */
+    if (CallbackRecord->State == BufferEmpty) {
+        
+        /* Set the Callback Settings and insert into the list */
+        CallbackRecord->Component = Component;
+        CallbackRecord->CallbackRoutine = CallbackRoutine;
+        CallbackRecord->State = BufferInserted;
+        CallbackRecord->Reason = Reason;
+        InsertTailList(&BugcheckReasonCallbackListHead, &CallbackRecord->Entry);
+    
+        Status = TRUE;
     }
 
-  if (KeGetCurrentIrql() < DISPATCH_LEVEL)
-    {
-      KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+    /* Lower IRQL and return */
+    KeLowerIrql(OldIrql);
+    return Status;
+}
+
+VOID
+STDCALL
+KeGetBugMessageText(ULONG BugCheckCode, PANSI_STRING OutputString)
+{
+    ULONG i;
+    ULONG IdOffset;
+    ULONG_PTR MessageEntry;
+    PCHAR BugCode;
+    
+    /* Find the message. This code is based on RtlFindMesssage -- Alex */
+    for (i = 0; i < KiBugCodeMessages->NumberOfBlocks; i++)  {
+        
+        /* Check if the ID Matches */
+        if ((BugCheckCode >= KiBugCodeMessages->Blocks[i].LowId) &&
+            (BugCheckCode <= KiBugCodeMessages->Blocks[i].HighId)) {
+            
+            /* Get Offset to Entry */
+            MessageEntry = (ULONG_PTR)KiBugCodeMessages + KiBugCodeMessages->Blocks[i].OffsetToEntries;
+            IdOffset = BugCheckCode - KiBugCodeMessages->Blocks[i].LowId;
+            
+            /* Get offset to ID */
+            for (i = 0; i < IdOffset; i++) {
+             
+                /* Advance in the Entries */   
+                MessageEntry += ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Length;
+            }
+            
+            /* Get the final Code */
+            BugCode = ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
+            
+            /* Return it in the OutputString */
+            if (OutputString) {
+            
+                OutputString->Buffer = BugCode;
+                OutputString->Length = strlen(BugCode) + 1;
+                OutputString->MaximumLength = strlen(BugCode) + 1;
+            
+            } else {
+            
+                /* Direct Output to Screen */
+                DbgPrint("%s\n", BugCode);
+                break;
+            }
+        }
     }
-  DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
-          BugCheckCode,
-          BugCheckParameter1,
-          BugCheckParameter2,
-          BugCheckParameter3,
-          BugCheckParameter4);
-
-  Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
-                         11, //RT_MESSAGETABLE,
-                         0x09, //0x409,
-                         BugCheckCode,
-                         &Message);
-  if (NT_SUCCESS(Status))
-    {
-      if (Message->Flags == 0)
-       DbgPrint("  %s\n", Message->Text);
-      else
-       DbgPrint("  %S\n", (PWSTR)Message->Text);
+}
+
+VOID
+STDCALL
+KiDoBugCheckCallbacks(VOID)
+{
+    PKBUGCHECK_CALLBACK_RECORD CurrentRecord;
+    PLIST_ENTRY ListHead;
+    PLIST_ENTRY NextEntry;
+    
+    /* FIXME: Check Checksum and add support for WithReason Callbacks */
+    
+    /* First make sure that the list is Initialized... it might not be */
+    ListHead = &BugcheckCallbackListHead;
+    if (ListHead->Flink && ListHead->Blink) {
+    
+        /* Loop the list */
+        NextEntry = ListHead->Flink;
+        while (NextEntry != ListHead) {
+        
+            /* Get the Callback Record */
+            CurrentRecord = CONTAINING_RECORD(NextEntry, 
+                                              KBUGCHECK_CALLBACK_RECORD,
+                                              Entry);
+            
+            /* Make sure it's inserted */
+            if (CurrentRecord->State == BufferInserted) {
+            
+                /* Call the routine */
+                CurrentRecord->State = BufferStarted;
+                (CurrentRecord->CallbackRoutine)(CurrentRecord->Buffer, 
+                                                 CurrentRecord->Length);
+                CurrentRecord->State = BufferFinished;
+            }
+            
+            /* Move to next Entry */
+            NextEntry = NextEntry->Flink;
+        }
     }
-  else
-    {
-      DbgPrint("  No message text found!\n\n");
+}
+
+VOID 
+STDCALL
+KeBugCheckWithTf(ULONG BugCheckCode,
+                 ULONG BugCheckParameter1,
+                 ULONG BugCheckParameter2,
+                 ULONG BugCheckParameter3,
+                 ULONG BugCheckParameter4,
+                 PKTRAP_FRAME Tf)
+{
+    KIRQL OldIrql;
+    BOOLEAN GotExtendedCrashInfo = FALSE;
+    PVOID Address = 0;
+    PLIST_ENTRY CurrentEntry;
+    MODULE_TEXT_SECTION* CurrentSection = NULL;
+    extern LIST_ENTRY ModuleTextListHead;
+     
+    /* Make sure we're switching back to the blue screen and print messages on it */
+    HalReleaseDisplayOwnership();
+    if (0 == (KdDebugState & KD_DEBUG_GDB)) KdDebugState |= KD_DEBUG_SCREEN;
+    /* Try to find out who did this. For this, we need a Trap Frame.
+     * Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the
+     * info so it eventually needs to be supported. 
+     */
+    if (Tf) {
+        
+        /* For now, get Address from EIP */
+        Address = (PVOID)Tf->Eip;
+        
+        /* Try to get information on the module */
+        CurrentEntry = ModuleTextListHead.Flink;
+        while (CurrentEntry != &ModuleTextListHead && CurrentEntry != NULL) {
+            
+            /* Get the current Section */
+            CurrentSection = CONTAINING_RECORD(CurrentEntry, 
+                                               MODULE_TEXT_SECTION, 
+                                               ListEntry);
+
+            /* Check if this is the right one */
+            if ((Address != NULL && (Address >= (PVOID)CurrentSection->Base &&
+                 Address < (PVOID)(CurrentSection->Base + CurrentSection->Length)))) {
+
+                /* We got it */            
+                GotExtendedCrashInfo = TRUE;
+                break;
+            }
+            
+            /* Loop again */
+            CurrentEntry = CurrentEntry->Flink;
+        }
     }
-  Mask = 1 << KeGetCurrentProcessorNumber();
-  if (InBugCheck & Mask)
-    {
-#ifdef MP
-      DbgPrint("Recursive bug check on CPU%d, halting now\n", KeGetCurrentProcessorNumber());
-      /*
-       * FIXME:
-       *   Send an ipi to all other processors which halt them too.
-       */
-#else
-      DbgPrint("Recursive bug check halting now\n");
-#endif
-      Ke386HaltProcessor();
+       
+    /* Raise IRQL to HIGH_LEVEL */
+    Ke386DisableInterrupts();
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+
+    /* Disable Interrupts, Dump Debug Messages */
+    DebugLogDumpMessages();
+
+    /* Unload the Kernel Adress Space if we own it */
+    if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
+        MmUnlockAddressSpace(MmGetKernelAddressSpace());
+     
+    /* FIXMEs: Use inbv to clear, fill and write to screen. */
+    
+    /* Show the STOP Message */
+    DbgPrint("A problem has been detected and ReactOS has been shut down to prevent "
+             "damage to your computer.\n\n");
+    /* Show the module name of who caused this */
+    if (GotExtendedCrashInfo) {
+    
+        DbgPrint("The problem seems to be caused by the following file: %S\n\n", CurrentSection->Name);
     }
-  /* 
-   * FIXME:
-   *   Use InterlockedOr or InterlockedBitSet.
-   */
-  InBugCheck |= Mask;
-  if (Tf != NULL)
-    {
-      KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
+
+    /* Find the Bug Code String */
+    KeGetBugMessageText(BugCheckCode, NULL);
+
+    /* Show the techincal Data */
+    DbgPrint("Technical information:\n\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n\n",
+             BugCheckCode,
+             BugCheckParameter1,
+             BugCheckParameter2,
+             BugCheckParameter3,
+             BugCheckParameter4);
+
+    /* Show the module name and more data of who caused this */
+    if (GotExtendedCrashInfo) {
+    
+        DbgPrint("***    %S - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n", 
+                 CurrentSection->Name,
+                 Address,
+                 CurrentSection->Base,
+                 0);
     }
-  else
-    {
+    
+    /* There can only be one Bugcheck per Bootup */
+    if (!InterlockedDecrement(&KeBugCheckCount)) {
+
+#ifdef CONFIG_SMP
+        ULONG i;
+        /* Freeze the other CPUs */
+        for (i = 0; i < KeNumberProcessors; i++) {    
+            if (i != KeGetCurrentProcessorNumber()) {
+                
+                /* Send the IPI and give them one second to catch up */
+                KiIpiSendRequest(1 << i, IPI_REQUEST_FREEZE);
+                KeStallExecutionProcessor(1000000);
+            }
+        }
+#endif
+
+        /* Check if we got a Trap Frame */
+        if (Tf) {
+        
+            /* Dump it */
+            KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
+    
+        } else {
+        
+            /* We can only dump the frames */
 #if defined(__GNUC__)
-      KeDumpStackFrames((PULONG)__builtin_frame_address(0));
+            KeDumpStackFrames((PULONG)__builtin_frame_address(0));
 #elif defined(_MSC_VER)
-      __asm push ebp
-      __asm call KeDumpStackFrames
-      __asm add esp, 4
+            __asm push ebp
+            __asm call KeDumpStackFrames
+            __asm add esp, 4
 #else
 #error Unknown compiler for inline assembler
 #endif
-    }
-  MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, 
-                    BugCheckParameter2, BugCheckParameter3,
-                    BugCheckParameter4, Tf);
-
-  if (KdDebuggerEnabled)
-    {
-      Ke386EnableInterrupts();
-      DbgBreakPointNoBugCheck();
-      Ke386DisableInterrupts();
-    }
+        }
+        
+        /* Call the Callbacks */;
+        KiDoBugCheckCallbacks();
 
-  for (;;)
-    {
-      /*
-       * FIXME:
-       *   Send an ipi to all other processors which halt them too.
-       */
-      Ke386HaltProcessor();
+        /* Dump the BSOD to the Paging File */
+        MmDumpToPagingFile(BugCheckCode, 
+                           BugCheckParameter1, 
+                           BugCheckParameter2, 
+                           BugCheckParameter3,
+                           BugCheckParameter4, 
+                           Tf);
+
+        /* Wake up the Debugger */
+        if (KdDebuggerEnabled) {
+            Ke386EnableInterrupts();
+            DbgBreakPointWithStatus(DBG_STATUS_BUGCHECK_SECOND);
+            Ke386DisableInterrupts();
+        }
     }
+
+    /* Halt this CPU now */
+    for (;;) Ke386HaltProcessor();
 }
 
 /*
  * @implemented
- */
-VOID STDCALL
-KeBugCheckEx(ULONG BugCheckCode,
-            ULONG BugCheckParameter1,
-            ULONG BugCheckParameter2,
-            ULONG BugCheckParameter3,
-            ULONG BugCheckParameter4)
-/*
+ *
  * FUNCTION: Brings the system down in a controlled manner when an 
  * inconsistency that might otherwise cause corruption has been detected
  * ARGUMENTS:
@@ -202,23 +447,34 @@ KeBugCheckEx(ULONG BugCheckCode,
  *           BugCheckParameter[1-4] = Additional information about bug
  * RETURNS: Doesn't
  */
+VOID 
+STDCALL
+KeBugCheckEx(ULONG BugCheckCode,
+             ULONG BugCheckParameter1,
+             ULONG BugCheckParameter2,
+             ULONG BugCheckParameter3,
+             ULONG BugCheckParameter4)
 {
-  KeBugCheckWithTf(BugCheckCode, BugCheckParameter1, BugCheckParameter2,
-                  BugCheckParameter3, BugCheckParameter4, NULL);
+    /* Call the Trap Frame version without a Trap Frame */
+    KeBugCheckWithTf(BugCheckCode, 
+                     BugCheckParameter1, 
+                     BugCheckParameter2,
+                     BugCheckParameter3, 
+                     BugCheckParameter4, 
+                     NULL);
 }
 
 /*
  * @implemented
- */
-VOID STDCALL
-KeBugCheck(ULONG BugCheckCode)
-/*
+ *
  * FUNCTION: Brings the system down in a controlled manner when an 
  * inconsistency that might otherwise cause corruption has been detected
  * ARGUMENTS:
  *           BugCheckCode = Specifies the reason for the bug check
  * RETURNS: Doesn't
  */
+VOID STDCALL
+KeBugCheck(ULONG BugCheckCode)
 {
   KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
 }
index 1d4ca92..50bf4c7 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/catch.c
  * PURPOSE:         Exception handling
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Anich Gregor
+ *                  David Welch (welch@mcmail.com)
  *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
 
 ULONG
 RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
-       IN PCONTEXT  Context);
+                      IN PCONTEXT  Context);
 
+/*
+ * @unimplemented
+ */
 VOID
-KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
-                   PCONTEXT Context,
-                   PKTRAP_FRAME Tf,
-                   KPROCESSOR_MODE PreviousMode,
-                   BOOLEAN SearchFrames)
+STDCALL
+KiCoprocessorError(VOID)
+{
+    UNIMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+KiUnexpectedInterrupt(VOID)
 {
-  EXCEPTION_DISPOSITION Value;
-  CONTEXT TContext;
-  KD_CONTINUE_TYPE Action = kdHandleException;
+    UNIMPLEMENTED;
+}
 
-  DPRINT("KiDispatchException() called\n");
+VOID
+KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
+                    PCONTEXT Context,
+                    PKTRAP_FRAME Tf,
+                    KPROCESSOR_MODE PreviousMode,
+                    BOOLEAN SearchFrames)
+{
+    EXCEPTION_DISPOSITION Value;
+    CONTEXT TContext;
+    KD_CONTINUE_TYPE Action = kdHandleException;
 
+    DPRINT("KiDispatchException() called\n");
 
-  /* PCR->KeExceptionDispatchCount++; */
+    /* Increase number of Exception Dispatches */
+    KeGetCurrentPrcb()->KeExceptionDispatchCount++;
 
-  if (Context == NULL)
+    if (!Context)    
     {
-      TContext.ContextFlags = CONTEXT_FULL;
-      if (PreviousMode == UserMode)
-       {
-         TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
-       }
+        
+        /* Assume Full context */
+        TContext.ContextFlags = CONTEXT_FULL;
+        
+        /* Check the mode */
+        if (PreviousMode == UserMode) 
+        {
+            
+            /* Add Debugger Registers if this is User Mode */
+            TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
+        }
   
-      KeTrapFrameToContext(Tf, &TContext);
+        /* Convert the Trapframe into a Context */
+        KeTrapFrameToContext(Tf, &TContext);
 
-      Context = &TContext;
+        /* Use local stack context */
+        Context = &TContext;
     }
 
-#if 0
-  if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) 
+#if 0 /* FIXME: Isn't this right? With a break after? */
+    if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) 
     {
-      Context->Eip--;
+        Context->Eip--;
     }
 #endif
-      
-  if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
-    {
-      Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
-    }
 
-  if (Action == kdContinue)
+    /* Check if a Debugger is enabled */
+    if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) 
     {
-      return;
+    
+        /* Break into it */
+        Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
     }
-
-  if (Action != kdDoNotHandleException)
+    
+    /* If the debugger said continue, then continue */
+    if (Action == kdContinue) return;
+    
+    /* If the Debugger couldn't handle it... */
+    if (Action != kdDoNotHandleException) 
     {
-      if (PreviousMode == UserMode)
-       {
-         if (SearchFrames)
-           {
-             PULONG Stack;
-             ULONG CDest;
-             char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
-             PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
-             NTSTATUS StatusOfCopy;
+        
+        /* See what kind of Exception this is */
+        if (PreviousMode == UserMode) 
+        {
+            
+            /* User mode exception, search the frames if we have to */
+            if (SearchFrames) 
+            {
+
+                PULONG Stack;
+                ULONG CDest;
+                char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
+                PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
+                NTSTATUS StatusOfCopy;
 
 #ifdef KDBG
-             Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                                 Context, Tf, FALSE);
-              if (Action == kdContinue)
-                {
-                  return;
-                }
+                /* Enter KDB if available */
+                Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                   PreviousMode,
+                                                   Context, 
+                                                   Tf, 
+                                                   TRUE);
+
+                /* Exit if we're continuing */
+                if (Action == kdContinue) return;
 #endif
 
-             /* FIXME: Forward exception to user mode debugger */
-
-             /* FIXME: Check user mode stack for enough space */
-         
-             /*
-              * Let usermode try and handle the exception
-              */
-             Stack = (PULONG)temp_space;
-             CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
-             /* Return address */
-             Stack[0] = 0;    
-             /* Pointer to EXCEPTION_RECORD structure */
-             Stack[1] = (ULONG)&pNewUserStack[3];
-             /* Pointer to CONTEXT structure */
-             Stack[2] = (ULONG)&pNewUserStack[CDest];
-             memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
-             memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
-
-             StatusOfCopy = MmCopyToCaller(pNewUserStack,
-                                           temp_space,
-                                           (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
-             if (NT_SUCCESS(StatusOfCopy))
-               {
-                 Tf->Esp = (ULONG)pNewUserStack;
-               }
-             else
-               {
-                 /* Now it really hit the ventilation device. Sorry,
-                  * can do nothing but kill the sucker.
-                  */
-                 ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
-                 DPRINT1("User-mode stack was invalid. Terminating target thread\n");
-               }
-             Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
-             return;
-           }
+                /* FIXME: Forward exception to user mode debugger */
+
+                /* FIXME: Check user mode stack for enough space */
+        
+                /* Let usermode try and handle the exception. Setup Stack */
+                Stack = (PULONG)temp_space;
+                CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
+                /* Return Address */
+                Stack[0] = 0;
+                /* Pointer to EXCEPTION_RECORD structure */
+                Stack[1] = (ULONG)&pNewUserStack[3];
+                /* Pointer to CONTEXT structure */
+                Stack[2] = (ULONG)&pNewUserStack[CDest];
+                memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
+                memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
+                
+                /* Copy Stack */
+                StatusOfCopy = MmCopyToCaller(pNewUserStack,
+                                              temp_space,
+                                              (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
+                
+                /* Check for success */
+                if (NT_SUCCESS(StatusOfCopy)) 
+                {
+                    
+                    /* Set new Stack Pointer */
+                    Tf->Esp = (ULONG)pNewUserStack;
+                    
+                } 
+                else 
+                {
+                    
+                    /*
+                     * Now it really hit the ventilation device. Sorry,
+                     * can do nothing but kill the sucker.
+                     */
+                    ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+                    DPRINT1("User-mode stack was invalid. Terminating target thread\n");
+                }
+                
+                /* Set EIP to the User-mode Dispathcer */
+                Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
+                return;
+            }
 
-         /* FIXME: Forward the exception to the debugger */
+            /* FIXME: Forward the exception to the debugger */
 
-         /* FIXME: Forward the exception to the process exception port */
+            /* FIXME: Forward the exception to the process exception port */
 
 #ifdef KDBG
-         Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                             Context, Tf, TRUE);
-          if (Action == kdContinue)
-            {
-              return;
-            }
+            /* Enter KDB if available */
+            Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                PreviousMode,
+                                                Context, 
+                                                Tf, 
+                                                FALSE);
+
+            /* Exit if we're continuing */
+            if (Action == kdContinue) return;
 #endif
 
-         /* Terminate the offending thread */
-         DPRINT1("Unhandled UserMode exception, terminating thread\n");
-         ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
-       }
-      else
-       {
-         /* PreviousMode == KernelMode */
+            /* Terminate the offending thread */
+            DPRINT1("Unhandled UserMode exception, terminating thread\n");
+            ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+        
+        } 
+        else 
+        {
+
+            /* This is Kernel Mode */            
 #ifdef KDBG
-         Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                             Context, Tf, FALSE);
-          if (Action == kdContinue)
-            {
-              return;
-            }
+            /* Enter KDB if available */
+            Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                PreviousMode,
+                                                Context, 
+                                                Tf, 
+                                                TRUE);
+
+            /* Exit if we're continuing */
+            if (Action == kdContinue) return;
 #endif
 
-         Value = RtlpDispatchException (ExceptionRecord, Context);
-         
-         DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
-         /* 
-          * If RtlpDispatchException() does not handle the exception then 
-          * bugcheck 
-          */
-         if (Value != ExceptionContinueExecution ||
-             0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
-           {
-             DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n",
-                    ExceptionRecord->ExceptionAddress );
+            /* Dispatch the Exception */
+            Value = RtlpDispatchException (ExceptionRecord, Context);
+            DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
+        
+            /* If RtlpDispatchException() did not handle the exception then bugcheck */
+            if (Value != ExceptionContinueExecution ||
+                0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))    
+            {
+            
+                DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress);
 #ifdef KDBG
-              Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                                  Context, Tf, TRUE);
-              if (Action == kdContinue)
-                {
-                  return;
-                }
+                /* Enter KDB if available */
+                Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                   PreviousMode,
+                                                   Context, 
+                                                   Tf, 
+                                                   FALSE);
+
+                /* Exit if we're continuing */
+                if (Action == kdContinue) return;
 #endif
-             KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf);
-           }
-       }
+                KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, 
+                                 ExceptionRecord->ExceptionCode, 
+                                 (ULONG)ExceptionRecord->ExceptionAddress,
+                                 ExceptionRecord->ExceptionInformation[0],
+                                 ExceptionRecord->ExceptionInformation[1],
+                                 Tf);
+            }
+        }
     }
 }
 
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseAccessViolation (VOID)
-{
-  ExRaiseStatus (STATUS_ACCESS_VIOLATION);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseDatatypeMisalignment (VOID)
-{
-  ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseStatus (IN NTSTATUS Status)
-{
-  EXCEPTION_RECORD ExceptionRecord;
-
-  DPRINT("ExRaiseStatus(%x)\n", Status);
-
-  ExceptionRecord.ExceptionRecord = NULL;
-  ExceptionRecord.NumberParameters = 0;
-  ExceptionRecord.ExceptionCode = Status;
-  ExceptionRecord.ExceptionFlags = 0;
-
-  RtlRaiseException(&ExceptionRecord);
-}
-
-
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-ExRaiseException (
-       PEXCEPTION_RECORD ExceptionRecord
-       )
-{
-    RtlRaiseException(ExceptionRecord);
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-ExSystemExceptionFilter(VOID)
-{
-  return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-ExRaiseHardError (
-       IN NTSTATUS ErrorStatus,
-       IN ULONG NumberOfParameters, 
-       IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
-       IN PVOID *Parameters, 
-       IN HARDERROR_RESPONSE_OPTION ResponseOption, 
-       OUT PHARDERROR_RESPONSE Response 
-       )
-{
-       UNIMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-BOOLEAN
-STDCALL
-KeDeregisterBugCheckReasonCallback(
-    IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
-    )
-{
-       UNIMPLEMENTED;
-       return FALSE;
-}
-
-/*
- * @unimplemented
- */
-ULONG
-STDCALL
-KeGetRecommendedSharedDataAlignment(
-       VOID
-       )
-{
-       UNIMPLEMENTED;
-       return 0;
-}
-
-/*
- * @unimplemented
- */
-BOOLEAN
-STDCALL
-KeRegisterBugCheckReasonCallback(
-    IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
-    IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
-    IN KBUGCHECK_CALLBACK_REASON Reason,
-    IN PUCHAR Component
-    )
-{
-       UNIMPLEMENTED;
-       return FALSE;
-}
-
 /* EOF */
index e9424cb..4a03c0e 100644 (file)
@@ -242,22 +242,22 @@ KeUpdateRunTime(
     IN KIRQL  Irql
     )
 {
-   PKPCR Pcr;
+   PKPRCB Prcb;
    PKTHREAD CurrentThread;
    PKPROCESS CurrentProcess;
 #if 0
    ULONG DpcLastCount;
 #endif
 
-   Pcr = KeGetCurrentKPCR();
+   Prcb = KeGetCurrentPrcb();
 
    /* Make sure we don't go further if we're in early boot phase. */
-   if (Pcr == NULL || Pcr->PrcbData.CurrentThread == NULL)
+   if (Prcb == NULL || Prcb->CurrentThread == NULL)
       return;
 
-   DPRINT("KernelTime  %u, UserTime %u \n", Pcr->PrcbData.KernelTime, Pcr->PrcbData.UserTime);
+   DPRINT("KernelTime  %u, UserTime %u \n", Prcb->KernelTime, Prcb->UserTime);
 
-   CurrentThread = Pcr->PrcbData.CurrentThread;
+   CurrentThread = Prcb->CurrentThread;
    CurrentProcess = CurrentThread->ApcState.Process;
 
    /* 
@@ -269,36 +269,36 @@ KeUpdateRunTime(
    {
       InterlockedIncrementUL(&CurrentThread->UserTime);
       InterlockedIncrementUL(&CurrentProcess->UserTime);
-      Pcr->PrcbData.UserTime++;
+      Prcb->UserTime++;
    }
    else
    {
       if (Irql > DISPATCH_LEVEL)
       {
-         Pcr->PrcbData.InterruptTime++;
+         Prcb->InterruptTime++;
       }
       else if (Irql == DISPATCH_LEVEL)
       {
-         Pcr->PrcbData.DpcTime++;
+         Prcb->DpcTime++;
       }
       else
       {
          InterlockedIncrementUL(&CurrentThread->KernelTime);
          InterlockedIncrementUL(&CurrentProcess->KernelTime);
-        Pcr->PrcbData.KernelTime++;
+         Prcb->KernelTime++;
       }
    }
 
 #if 0
-   DpcLastCount = Pcr->PrcbData.DpcLastCount;
-   Pcr->PrcbData.DpcLastCount = Pcr->PrcbData.DpcCount;
-   Pcr->PrcbData.DpcRequestRate = ((Pcr->PrcbData.DpcCount - DpcLastCount) +
-                                   Pcr->PrcbData.DpcRequestRate) / 2;
+   DpcLastCount = Prcb->DpcLastCount;
+   Prcb->DpcLastCount = Prcb->DpcCount;
+   Prcb->DpcRequestRate = ((Prcb->DpcCount - DpcLastCount) +
+                                   Prcb->DpcRequestRate) / 2;
 #endif
 
-   if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0 &&
-       Pcr->PrcbData.DpcRoutineActive == FALSE &&
-       Pcr->PrcbData.DpcInterruptRequested == FALSE)
+   if (Prcb->DpcData[0].DpcQueueDepth > 0 &&
+       Prcb->DpcRoutineActive == FALSE &&
+       Prcb->DpcInterruptRequested == FALSE)
    {
       HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
    }
@@ -311,7 +311,7 @@ KeUpdateRunTime(
     */
    if ((CurrentThread->Quantum -= 3) <= 0)
    {
-     Pcr->PrcbData.QuantumEnd = TRUE;
+     Prcb->QuantumEnd = TRUE;
      HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
    }
 }
diff --git a/reactos/ntoskrnl/ke/critical.c b/reactos/ntoskrnl/ke/critical.c
deleted file mode 100644 (file)
index e242854..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/critical.c
- * PURPOSE:         Implement critical regions
- * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-VOID STDCALL KeEnterCriticalRegion (VOID)
-{
-   PKTHREAD Thread = KeGetCurrentThread(); 
-   
-   DPRINT("KeEnterCriticalRegion()\n");
-   
-   if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
-
-   Thread->KernelApcDisable--;
-}
-
-/*
- * @implemented
- */
-VOID STDCALL KeLeaveCriticalRegion (VOID)
-{
-  PKTHREAD Thread = KeGetCurrentThread(); 
-
-  DPRINT("KeLeaveCriticalRegion()\n");
-  
-  if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
-
-  /* Reference: http://www.ntfsd.org/archive/ntfsd0104/msg0203.html */
-  if(++Thread->KernelApcDisable == 0) 
-  { 
-    if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) 
-    { 
-      Thread->ApcState.KernelApcPending = TRUE; 
-      HalRequestSoftwareInterrupt(APC_LEVEL); 
-    } 
-  } 
-
-}
-
-/* EOF */
index ad1c8bd..31c9555 100644 (file)
@@ -57,17 +57,17 @@ KeFlushEntireTb(
 {
        KIRQL OldIrql;
        PKPROCESS Process = NULL;
-       PKPCR Pcr = NULL;
+       PKPRCB Prcb = NULL;
        
        /* Raise the IRQL for the TB Flush */
        OldIrql = KeRaiseIrqlToSynchLevel();
        
        /* All CPUs need to have the TB flushed. */
        if (CurrentCpuOnly == FALSE) {
-               Pcr = KeGetCurrentKPCR();
+               Prcb = KeGetCurrentPrcb();
                
                /* How many CPUs is our caller using? */
-               Process = Pcr->PrcbData.CurrentThread->ApcState.Process;
+               Process = Prcb->CurrentThread->ApcState.Process;
                
                /* More then one, so send an IPI */
                if (Process->ActiveProcessors > 1) {
@@ -83,7 +83,7 @@ KeFlushEntireTb(
                /* Did we send an IPI? If so, wait for completion */
                if (Process->ActiveProcessors > 1) {
                        do {
-                       } while (Pcr->PrcbData.TargetSet != 0);
+                       } while (Prcb->TargetSet != 0);
                } 
        } 
        
index 2aee866..b65e961 100644 (file)
 /* TYPES *******************************************************************/
 
 #define MAX_QUANTUM 0x7F
-/* GLOBALS ******************************************************************/
 
 /* FUNCTIONS ****************************************************************/
 
-VOID INIT_FUNCTION
-KeInitDpc(PKPCR Pcr)
 /*
  * FUNCTION: Initialize DPC handling
  */
+VOID
+INIT_FUNCTION
+KeInitDpc(PKPRCB Prcb)
 {
-   InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead);
-   KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0);
-   KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-   Pcr->PrcbData.MaximumDpcQueueDepth = 4;
-   Pcr->PrcbData.MinimumDpcRate = 3;
-   Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0;    
+   InitializeListHead(&Prcb->DpcData[0].DpcListHead);
+#if 0   
+   /*
+    * FIXME:
+    *   Prcb->DpcEvent is a NULL pointer.
+    */
+   KeInitializeEvent(Prcb->DpcEvent, 0, 0);
+#endif
+   KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock);
+   Prcb->MaximumDpcQueueDepth = 4;
+   Prcb->MinimumDpcRate = 3;
+   Prcb->DpcData[0].DpcQueueDepth = 0;
 }
 
 /*
@@ -47,9 +53,9 @@ KeInitDpc(PKPCR Pcr)
  */
 VOID
 STDCALL
-KeInitializeThreadedDpc(PKDPC                  Dpc,
-                       PKDEFERRED_ROUTINE      DeferredRoutine,
-                       PVOID                   DeferredContext)
+KeInitializeThreadedDpc(PKDPC Dpc,
+                        PKDEFERRED_ROUTINE DeferredRoutine,
+                        PVOID DeferredContext)
 /*
  * FUNCTION: 
  *          Initalizes a Threaded DPC and registers the DeferredRoutine for it.
@@ -60,24 +66,18 @@ KeInitializeThreadedDpc(PKDPC                       Dpc,
  * NOTE: Callers can be running at any IRQL.
  */
 {
-       DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
-       //Dpc->Type = KThreadedDpc;
-       Dpc->Number= 0;
-       Dpc->Importance= MediumImportance;
-       Dpc->DeferredRoutine = DeferredRoutine;
-       Dpc->DeferredContext = DeferredContext;
-       Dpc->DpcData = NULL;
+    DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
+    Dpc->Type = ThreadedDpcObject;
+    Dpc->Number= 0;
+    Dpc->Importance= MediumImportance;
+    Dpc->DeferredRoutine = DeferredRoutine;
+    Dpc->DeferredContext = DeferredContext;
+    Dpc->DpcData = NULL;
 }
 
 /*
  * @implemented
- */
-VOID
-STDCALL
-KeInitializeDpc (PKDPC                 Dpc,
-                PKDEFERRED_ROUTINE     DeferredRoutine,
-                PVOID                  DeferredContext)
-/*
+ *
  * FUNCTION: 
  *          Initalizes a DPC and registers the DeferredRoutine for it.
  * ARGUMENTS:
@@ -86,24 +86,24 @@ KeInitializeDpc (PKDPC                      Dpc,
  *          DeferredContext = Parameter to be passed to the callback routine.
  * NOTE: Callers can be running at any IRQL.
  */
+VOID
+STDCALL
+KeInitializeDpc(PKDPC Dpc,
+                PKDEFERRED_ROUTINE DeferredRoutine,
+                PVOID DeferredContext)
 {
-       DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
-       Dpc->Type = KDpc;
-       Dpc->Number= 0;
-       Dpc->Importance= MediumImportance;
-       Dpc->DeferredRoutine = DeferredRoutine;
-       Dpc->DeferredContext = DeferredContext;
-       Dpc->DpcData = NULL;
+    DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
+    Dpc->Type = DpcObject;
+    Dpc->Number= 0;
+    Dpc->Importance= MediumImportance;
+    Dpc->DeferredRoutine = DeferredRoutine;
+    Dpc->DeferredContext = DeferredContext;
+    Dpc->DpcData = NULL;
 }
 
 /*
  * @implemented
- */
-BOOLEAN STDCALL
-KeInsertQueueDpc (PKDPC        Dpc,
-                 PVOID SystemArgument1,
-                 PVOID SystemArgument2)
-/*
+ *
  * FUNCTION: 
  *          Queues a DPC for execution when the IRQL of a processor
  *          drops below DISPATCH_LEVEL
@@ -155,124 +155,141 @@ KeInsertQueueDpc (PKDPC Dpc,
  * is greater that the target depth or the minimum DPC rate is less than the
  * target rate.
  */
+BOOLEAN 
+STDCALL
+KeInsertQueueDpc(PKDPC Dpc,
+                 PVOID SystemArgument1,
+                 PVOID SystemArgument2)
 {
-       KIRQL OldIrql;
-       PKPCR Pcr;
-
-       DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
-               Dpc, SystemArgument1, SystemArgument2);
-
-       /* Check IRQL and Raise it to HIGH_LEVEL */
-       ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-       
-       /* Check if this is a Thread DPC, which we don't support (yet) */
-       //if (Dpc->Type == KThreadedDpc) {
-       //      return FALSE;
-       //      KeLowerIrql(OldIrql);
-       //}
+    KIRQL OldIrql;
+    PKPRCB Prcb;
+
+    DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
+        Dpc, SystemArgument1, SystemArgument2);
+
+    /* Check IRQL and Raise it to HIGH_LEVEL */
+    ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check if this is a Thread DPC, which we don't support (yet) */
+    if (Dpc->Type == ThreadedDpcObject) {
+        return FALSE;
+        KeLowerIrql(OldIrql);
+    }
 
 #ifdef CONFIG_SMP
-       /* Get the right PCR for this CPU */
-       if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-               ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
-               Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
-       } else {
-               ASSERT (Dpc->Number < KeNumberProcessors);
-               Pcr = KeGetCurrentKPCR();
-               Dpc->Number = KeGetCurrentProcessorNumber();
-       }
-       KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    /* Get the right PCR for this CPU */
+    if (Dpc->Number >= MAXIMUM_PROCESSORS) {
+    
+        ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
+        Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb;
+        
+    } else {
+        
+        ASSERT (Dpc->Number < KeNumberProcessors);
+        Prcb = KeGetCurrentPrcb();
+        Dpc->Number = KeGetCurrentProcessorNumber();
+    }
+    
+    KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
 #else
-       Pcr = (PKPCR)KPCR_BASE;
+    Prcb = ((PKPCR)KPCR_BASE)->Prcb;
 #endif
 
-       /* Get the DPC Data */
-       if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) {
-               DPRINT("DPC Already Inserted");
+    /* Get the DPC Data */
+    if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) {
+    
+        DPRINT("DPC Already Inserted");
 #ifdef CONFIG_SMP
-               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+        KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
 #endif
-               KeLowerIrql(OldIrql);
-               return(FALSE);
-       }
-       
-       /* Make sure the lists are free if the Queue is 0 */
-       if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) {
-               ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
-       } else {
-               ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));    
-       }
-
-       /* Now we can play with the DPC safely */
-       Dpc->SystemArgument1=SystemArgument1;
-       Dpc->SystemArgument2=SystemArgument2;
-       Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
-       Pcr->PrcbData.DpcData[0].DpcCount++;
-       
-       /* Insert the DPC into the list. HighImportance DPCs go at the beginning  */
-       if (Dpc->Importance == HighImportance) {
-               InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
-       } else { 
-               InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
-       }
-       DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
+        KeLowerIrql(OldIrql);
+        return(FALSE);
+    }
+    
+    /* Make sure the lists are free if the Queue is 0 */
+    if (Prcb->DpcData[0].DpcQueueDepth == 0) {
+        
+        ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead));
+    } else {
+        
+        ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead));
+    }
+
+    /* Now we can play with the DPC safely */
+    Dpc->SystemArgument1=SystemArgument1;
+    Dpc->SystemArgument2=SystemArgument2;
+    Prcb->DpcData[0].DpcQueueDepth++;
+    Prcb->DpcData[0].DpcCount++;
+    
+    /* Insert the DPC into the list. HighImportance DPCs go at the beginning  */
+    if (Dpc->Importance == HighImportance) {
+        
+        InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
+    } else { 
+        
+        InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
+    }
+    DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
    
-       /* Make sure a DPC isn't executing already and respect rules outlined above. */
-       if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) {
-               
-#ifdef CONFIG_SMP      
-               /* Check if this is the same CPU */
-               if (Pcr != KeGetCurrentKPCR()) {
-                       /* Send IPI if High Importance */
-                       if ((Dpc->Importance == HighImportance) ||
-                           (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) {
-                               if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-                                   KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
-                               } else {
-                                   KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
-                               }
-
-                       }
-               } else {
-                       /* Request an Interrupt only if the DPC isn't low priority */
-                       if ((Dpc->Importance != LowImportance) || 
-                            (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
-                               (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
-                       
-                               /* Request Interrupt */
-                               HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-                               Pcr->PrcbData.DpcInterruptRequested = TRUE;
-                       }
-               }
+    /* Make sure a DPC isn't executing already and respect rules outlined above. */
+    if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) {
+        
+#ifdef CONFIG_SMP    
+        /* Check if this is the same CPU */
+        if (Prcb != KeGetCurrentPrcb()) {
+    
+            /* Send IPI if High Importance */
+            if ((Dpc->Importance == HighImportance) ||
+                (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) {
+                
+                if (Dpc->Number >= MAXIMUM_PROCESSORS) {
+                    
+                    KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
+                } else {
+                    
+                    KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
+                }
+
+            }
+        } else {
+            
+            /* Request an Interrupt only if the DPC isn't low priority */
+            if ((Dpc->Importance != LowImportance) || 
+                 (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
+                (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
+            
+                /* Request Interrupt */
+                HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+                Prcb->DpcInterruptRequested = TRUE;
+            }
+        }
 #else
-               DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate);
-               /* Request an Interrupt only if the DPC isn't low priority */
-               if ((Dpc->Importance != LowImportance) || 
-                    (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
-                       (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
-                       
-                       /* Request Interrupt */
-                       DPRINT("Requesting Interrupt\n");
-                       HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-                       Pcr->PrcbData.DpcInterruptRequested = TRUE;
-               }
+        DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Prcb->DpcData[0].DpcQueueDepth, Prcb->MaximumDpcQueueDepth, Prcb->DpcRequestRate, Prcb->MinimumDpcRate);
+        
+        /* Request an Interrupt only if the DPC isn't low priority */
+        if ((Dpc->Importance != LowImportance) || 
+            (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
+            (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
+            
+            /* Request Interrupt */
+            DPRINT("Requesting Interrupt\n");
+            HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+            Prcb->DpcInterruptRequested = TRUE;
+        }
 #endif
-       }
+    }
 #ifdef CONFIG_SMP
-       KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
 #endif
-       /* Lower IRQL */        
-       KeLowerIrql(OldIrql);
-       return(TRUE);
+    /* Lower IRQL */    
+    KeLowerIrql(OldIrql);
+    return(TRUE);
 }
 
 /*
  * @implemented
- */
-BOOLEAN STDCALL
-KeRemoveQueueDpc (PKDPC        Dpc)
-/*
+ *
  * FUNCTION: 
  *          Removes DPC object from the system dpc queue
  * ARGUMENTS:
@@ -281,33 +298,36 @@ KeRemoveQueueDpc (PKDPC   Dpc)
  *          TRUE if the DPC was in the queue
  *          FALSE otherwise
  */
+BOOLEAN 
+STDCALL
+KeRemoveQueueDpc(PKDPC Dpc)
 {
-       BOOLEAN WasInQueue;
-       KIRQL OldIrql;
-       
-       /* Raise IRQL */
-       DPRINT("Removing DPC: %x\n", Dpc);
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    BOOLEAN WasInQueue;
+    KIRQL OldIrql;
+    
+    /* Raise IRQL */
+    DPRINT("Removing DPC: %x\n", Dpc);
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
 #ifdef CONFIG_SMP
-       KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
+    KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
 #endif
-       
-       /* First make sure the DPC lock isn't being held */
-       WasInQueue = Dpc->DpcData ? TRUE : FALSE;
-       if (Dpc->DpcData) {     
-               
-               /* Remove the DPC */
-               ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
-               RemoveEntryList(&Dpc->DpcListEntry);
-
-       }
+    
+    /* First make sure the DPC lock isn't being held */
+    WasInQueue = Dpc->DpcData ? TRUE : FALSE;
+    if (Dpc->DpcData) {    
+        
+        /* Remove the DPC */
+        ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
+        RemoveEntryList(&Dpc->DpcListEntry);
+
+    }
 #ifdef CONFIG_SMP
         KiReleaseSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
 #endif
 
-       /* Return if the DPC was in the queue or not */
-       KeLowerIrql(OldIrql);
-       return WasInQueue;
+    /* Return if the DPC was in the queue or not */
+    KeLowerIrql(OldIrql);
+    return WasInQueue;
 }
 
 /*
@@ -323,7 +343,8 @@ KeFlushQueuedDpcs(VOID)
  *          Called when deleting a Driver.
  */
 {
-       if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+    /* Request an interrupt if needed */
+    if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
 }
 
 /*
@@ -332,10 +353,11 @@ KeFlushQueuedDpcs(VOID)
 BOOLEAN 
 STDCALL
 KeIsExecutingDpc(
-       VOID
+    VOID
 )
 {
-       return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive;
+    /* Return if the Dpc Routine is active */
+    return KeGetCurrentPrcb()->DpcRoutineActive;
 }
 
 /*
@@ -349,39 +371,41 @@ KeIsExecutingDpc(
  */
 VOID 
 STDCALL
-KeSetImportanceDpc (IN PKDPC           Dpc,
-                   IN  KDPC_IMPORTANCE Importance)
+KeSetImportanceDpc (IN PKDPC Dpc,
+            IN KDPC_IMPORTANCE Importance)
 {
-       Dpc->Importance = Importance;
+    /* Set the DPC Importance */
+    Dpc->Importance = Importance;
 }
 
 /*
+ * @implemented
+ *
  * FUNCTION: Specifies on which processor the DPC will run
  * ARGUMENTS:
  *          Dpc = Initalizes DPC
  *          Number = Processor number
  * RETURNS: None
- *
- * @implemented
  */
-VOID STDCALL
-KeSetTargetProcessorDpc (IN    PKDPC   Dpc,
-                        IN     CCHAR   Number)
+VOID 
+STDCALL
+KeSetTargetProcessorDpc(IN PKDPC Dpc,
+                        IN CCHAR Number)
 {
-   if (Number >= MAXIMUM_PROCESSORS)
-   {
-      Dpc->Number = 0;
-   }
-   else
-   {
-      ASSERT(Number < KeNumberProcessors);
-      Dpc->Number = Number + MAXIMUM_PROCESSORS;
-   }
+    /* Check how many CPUs are on the system */
+    if (Number >= MAXIMUM_PROCESSORS) {
+        
+        /* No CPU Number */
+        Dpc->Number = 0;
+        
+    } else {
+       
+        /* Set the Number Specified */
+        ASSERT(Number < KeNumberProcessors);
+        Dpc->Number = Number + MAXIMUM_PROCESSORS;
+    }
 }
 
-VOID
-STDCALL
-KiQuantumEnd(VOID)
 /*
  * FUNCTION: 
  *          Called when a quantum end occurs to check if priority should be changed
@@ -389,152 +413,178 @@ KiQuantumEnd(VOID)
  * NOTES:
  *          Called when deleting a Driver.
  */
+VOID
+STDCALL
+KiQuantumEnd(VOID)
 {
-       PKPRCB Prcb;
-       PKTHREAD CurrentThread;
-       KIRQL OldIrql;
-       PKPROCESS Process;
-       KPRIORITY OldPriority;
-       KPRIORITY NewPriority;
-       
-       /* Lock dispatcher, get current thread */
-       Prcb = &KeGetCurrentKPCR()->PrcbData;
-       CurrentThread = KeGetCurrentThread();
-       OldIrql = KeRaiseIrqlToSynchLevel();
-       
-       /* Get the Thread's Process */
-       Process = CurrentThread->ApcState.Process;
-       
-       /* Set DPC Event if requested */
-       if (Prcb->DpcSetEventRequest) {
-               KeSetEvent(Prcb->DpcEvent, 0, 0);
-       }
-       
-       /* Check if Quantum expired */
-       if (CurrentThread->Quantum <= 0) {
-               /* Set the new Quantum */
-               CurrentThread->Quantum = Process->ThreadQuantum;
-               
-               /* Calculate new priority */
-               OldPriority = CurrentThread->Priority;
-               if (OldPriority < LOW_REALTIME_PRIORITY) {
-                       NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
-                       if (NewPriority < CurrentThread->BasePriority) {
-                               NewPriority = CurrentThread->BasePriority;
-                       }
-                       CurrentThread->PriorityDecrement = 0;
-                       if (OldPriority != NewPriority) {
-                               /* Set new Priority */
-                               CurrentThread->Priority = NewPriority;
-                       } else {
-                               /* Queue new thread if none is already */
-                               if (Prcb->NextThread == NULL) {
-                                       /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
-                               } else {
-                                       /* Make the current thread non-premeptive if a new thread is queued */
-                                       CurrentThread->Preempted = FALSE;
-                               }
-                       }
-               } else {
-                       /* Set the Quantum back to Maximum */
-                       //if (CurrentThread->DisableQuantum) {
-                       //      CurrentThread->Quantum = MAX_QUANTUM;
-                       //}
-               }
-       }
-       /* Dispatch the Thread */
-       KeLowerIrql(DISPATCH_LEVEL);
-       PsDispatchThread(THREAD_STATE_READY);
-}      
+    PKPRCB Prcb;
+    PKTHREAD CurrentThread;
+    KIRQL OldIrql;
+    PKPROCESS Process;
+    KPRIORITY OldPriority;
+    KPRIORITY NewPriority;
+    
+    /* Lock dispatcher, get current thread */
+    Prcb = KeGetCurrentPrcb();
+    CurrentThread = KeGetCurrentThread();
+    OldIrql = KeRaiseIrqlToSynchLevel();
+    
+    /* Get the Thread's Process */
+    Process = CurrentThread->ApcState.Process;
+    
+    /* Set DPC Event if requested */
+    if (Prcb->DpcSetEventRequest) {
+        /*
+         * FIXME:
+         *   Prcb->DpcEvent is not initialized.
+         */
+        KEBUGCHECK(0);
+        KeSetEvent(Prcb->DpcEvent, 0, 0);
+    }
+    
+    /* Check if Quantum expired */
+    if (CurrentThread->Quantum <= 0) {
+        /* Set the new Quantum */
+        CurrentThread->Quantum = Process->ThreadQuantum;
+        
+        /* Calculate new priority */
+        OldPriority = CurrentThread->Priority;
+        if (OldPriority < LOW_REALTIME_PRIORITY) {
+            
+            /* Set the New Priority and add the Priority Decrement */
+            NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
+            
+            /* Don't go out of bounds */
+            if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority;
+            
+            /* Reset the priority decrement */
+            CurrentThread->PriorityDecrement = 0;
+            
+            /* Set a new priority if needed */
+            if (OldPriority != NewPriority) {
+                
+                /* Set new Priority */
+                CurrentThread->Priority = NewPriority;
+            
+            } else {
+                
+                /* Queue new thread if none is already */
+                if (Prcb->NextThread == NULL) {
+                    
+                    /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
+                               
+                } else {
+                           
+                    /* Make the current thread non-premeptive if a new thread is queued */
+                    CurrentThread->Preempted = FALSE;
+                }
+            }
+
+            
+        } else {
+            /* Set the Quantum back to Maximum */
+            //if (CurrentThread->DisableQuantum) {
+            //    CurrentThread->Quantum = MAX_QUANTUM;
+            //}
+        }
+    }
+
+    /* Dispatch the Thread */
+    KeLowerIrql(DISPATCH_LEVEL);
+    KiDispatchThread(THREAD_STATE_READY);
+}    
 
 /*
  * @implemented
- */
-VOID
-STDCALL
-KiDispatchInterrupt(VOID)
-/*
+ *
  * FUNCTION: 
  *          Called whenever a system interrupt is generated at DISPATCH_LEVEL.
  *          It delivers queued DPCs and dispatches a new thread if need be.
  */
+VOID
+STDCALL
+KiDispatchInterrupt(VOID)
 {
-       PLIST_ENTRY DpcEntry;
-       PKDPC Dpc;
-       KIRQL OldIrql;
-       PKPCR Pcr;
-
-       DPRINT("Dispatching Interrupts\n");
-       ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
-       /* Set DPC Deliver to Active */
-       Pcr = KeGetCurrentKPCR();
-
-       if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) {
-               /* Raise IRQL */
-               KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-#ifdef CONFIG_SMP              
-               KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    PLIST_ENTRY DpcEntry;
+    PKDPC Dpc;
+    KIRQL OldIrql;
+    PKPRCB Prcb;
+
+    DPRINT("Dispatching Interrupts\n");
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+    /* Set DPC Deliver to Active */
+    Prcb = KeGetCurrentPrcb();
+
+    if (Prcb->DpcData[0].DpcQueueDepth > 0) {
+        /* Raise IRQL */
+        KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+#ifdef CONFIG_SMP        
+        KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
 #endif
-               Pcr->PrcbData.DpcRoutineActive = TRUE;
-
-               DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead);
-               /* Loop while we have entries */
-               while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) {
-                       ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
-                       DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth);
-                       
-                       /* Get the DPC call it */
-                       DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead);
-                       Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
-                       DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
-                       Dpc->DpcData = NULL;
-                       Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
+            Prcb->DpcRoutineActive = TRUE;
+
+        DPRINT("&Prcb->DpcData[0].DpcListHead: %x\n", &Prcb->DpcData[0].DpcListHead);
+        /* Loop while we have entries */
+        while (!IsListEmpty(&Prcb->DpcData[0].DpcListHead)) {
+            
+            ASSERT(Prcb->DpcData[0].DpcQueueDepth > 0);
+            DPRINT("Queue Depth: %x\n", Prcb->DpcData[0].DpcQueueDepth);
+            
+            /* Get the DPC call it */
+            DpcEntry = RemoveHeadList(&Prcb->DpcData[0].DpcListHead);
+            Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
+            DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
+            Dpc->DpcData = NULL;
+            Prcb->DpcData[0].DpcQueueDepth--;
 #ifdef CONFIG_SMP
-                       KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+            KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
 #endif
-                       /* Disable/Enabled Interrupts and Call the DPC */
-                       KeLowerIrql(OldIrql);
-                       DPRINT("Calling DPC: %x\n", Dpc);
-                       Dpc->DeferredRoutine(Dpc,
-                                            Dpc->DeferredContext,
-                                            Dpc->SystemArgument1,
-                                            Dpc->SystemArgument2);
-                       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-                       
+            /* Disable/Enabled Interrupts and Call the DPC */
+            KeLowerIrql(OldIrql);
+            DPRINT("Calling DPC: %x\n", Dpc);
+            Dpc->DeferredRoutine(Dpc,
+                         Dpc->DeferredContext,
+                         Dpc->SystemArgument1,
+                         Dpc->SystemArgument2);
+            KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+            
 #ifdef CONFIG_SMP
-                       KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                       /* 
-                        * If the dpc routine drops the irql below DISPATCH_LEVEL,
-                        * a thread switch can occur and after the next thread switch 
-                        * the execution may start on an other processor.
-                        */
-                       if (Pcr != KeGetCurrentKPCR()) {
-                               Pcr->PrcbData.DpcRoutineActive = FALSE;
-                               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                               Pcr = KeGetCurrentKPCR();
-                               KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                               Pcr->PrcbData.DpcRoutineActive = TRUE;
-                       }
+            KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
+            /* 
+             * If the dpc routine drops the irql below DISPATCH_LEVEL,
+             * a thread switch can occur and after the next thread switch 
+             * the execution may start on an other processor.
+             */
+            if (Prcb != KeGetCurrentPrcb()) {
+                
+                Prcb->DpcRoutineActive = FALSE;
+                KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
+                Prcb = KeGetCurrentPrcb();
+                KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
+                Prcb->DpcRoutineActive = TRUE;
+            }
 #endif
-               }
-               /* Clear DPC Flags */
-               Pcr->PrcbData.DpcRoutineActive = FALSE;
-               Pcr->PrcbData.DpcInterruptRequested = FALSE;
+        }
+        /* Clear DPC Flags */
+        Prcb->DpcRoutineActive = FALSE;
+        Prcb->DpcInterruptRequested = FALSE;
 #ifdef CONFIG_SMP
-               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+        KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
 #endif
-               
-               /* DPC Dispatching Ended, re-enable interrupts */
-               KeLowerIrql(OldIrql);
-       }
-       
-       DPRINT("Checking for Quantum End\n");
-       /* If we have Quantum End, call the function */
-       if (Pcr->PrcbData.QuantumEnd) {
-               Pcr->PrcbData.QuantumEnd = FALSE;
-               KiQuantumEnd();
-       }
+        
+        /* DPC Dispatching Ended, re-enable interrupts */
+        KeLowerIrql(OldIrql);
+    }
+    
+    DPRINT("Checking for Quantum End\n");
+    
+    /* If we have Quantum End, call the function */
+    if (Prcb->QuantumEnd) {
+        
+        Prcb->QuantumEnd = FALSE;
+        KiQuantumEnd();
+    }
 }
 
 /* EOF */
diff --git a/reactos/ntoskrnl/ke/error.c b/reactos/ntoskrnl/ke/error.c
deleted file mode 100644 (file)
index d6172aa..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/error.c
- * PURPOSE:         Error reason setting/getting
- *
- * PROGRAMMERS:     David Welch
- */
-
-/* INCLUDE *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-BOOLEAN ExReadyForErrors = FALSE;
-PEPORT ExpDefaultErrorPort = NULL;
-PEPROCESS ExpDefaultErrorPortProcess = NULL;
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-KiCoprocessorError(
-    VOID
-)
-{
-       UNIMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-KiUnexpectedInterrupt(
-    VOID
-)
-{
-       UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL 
-NtRaiseHardError(IN NTSTATUS ErrorStatus,
-                 IN ULONG NumberOfParameters,
-                 IN PUNICODE_STRING UnicodeStringParameterMask  OPTIONAL,
-                 IN PVOID *Parameters,
-                 IN HARDERROR_RESPONSE_OPTION ResponseOption,
-                 OUT PHARDERROR_RESPONSE Response)
-{
-  DPRINT1("Hard error %x\n", ErrorStatus);
-  return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL 
-NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
-{
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                             PreviousMode))
-  {
-    DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n");
-    return STATUS_PRIVILEGE_NOT_HELD;
-  }
-  
-  /* serialization shouldn't be required here as it usually is just called once
-     during startup */
-  
-  if(!ExReadyForErrors)
-  {
-    Status = ObReferenceObjectByHandle(PortHandle,
-                                       0,
-                                       LpcPortObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&ExpDefaultErrorPort,
-                                       NULL);
-    if(NT_SUCCESS(Status))
-    {
-      ExpDefaultErrorPortProcess = PsGetCurrentProcess();
-      ExReadyForErrors = TRUE;
-    }
-  }
-  else
-  {
-    Status = STATUS_UNSUCCESSFUL;
-  }
-  
-  return Status;
-}
-
-/* EOF */
index 5ef0e62..6dd6533 100644 (file)
@@ -1,11 +1,12 @@
-/* $Id$
+/*
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/event.c
  * PURPOSE:         Implements events
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES *****************************************************************/
 /*
  * @implemented
  */
-VOID STDCALL KeClearEvent (PKEVENT Event)
+VOID 
+STDCALL 
+KeClearEvent(PKEVENT Event)
 {
-   DPRINT("KeClearEvent(Event %x)\n", Event);
-   Event->Header.SignalState = FALSE;
+    DPRINT("KeClearEvent(Event %x)\n", Event);
+    
+    /* Reset Signal State */
+    Event->Header.SignalState = FALSE;
 }
 
 /*
  * @implemented
  */
-VOID STDCALL KeInitializeEvent (PKEVENT                Event,
-                               EVENT_TYPE      Type,
-                               BOOLEAN         State)
+VOID 
+STDCALL 
+KeInitializeEvent(PKEVENT Event,
+                  EVENT_TYPE Type,
+                  BOOLEAN State)
 {
-   ULONG IType;
-   
-   if (Type == NotificationEvent)
-     {
-       IType = InternalNotificationEvent;
-     }
-   else if (Type == SynchronizationEvent)
-     {
-       IType = InternalSynchronizationEvent;
-     }
-   else
-     {
-       ASSERT(FALSE);
-       return;
-     }
-   
-   KeInitializeDispatcherHeader(&(Event->Header),
-                               IType,
-                               sizeof(Event)/sizeof(ULONG),State);
-   InitializeListHead(&(Event->Header.WaitListHead));
+    DPRINT("KeInitializeEvent(Event %x)\n", Event);
+    
+    /* Initialize the Dispatcher Header */
+    KeInitializeDispatcherHeader(&Event->Header,
+                                 Type,
+                                 sizeof(Event) / sizeof(ULONG),
+                                 State);
 }
 
 /*
  * @implemented
  */
-LONG STDCALL KeReadStateEvent (PKEVENT Event)
+VOID 
+STDCALL 
+KeInitializeEventPair(PKEVENT_PAIR EventPair)
 {
-   return(Event->Header.SignalState);
+    DPRINT("KeInitializeEventPair(Event %x)\n", EventPair);
+    
+    /* Initialize the Event Pair Type and Size */
+    EventPair->Type = EventPairObject;
+    EventPair->Size = sizeof(KEVENT_PAIR);
+    
+    /* Initialize the two Events */
+    KeInitializeEvent(&EventPair->LowEvent, SynchronizationEvent, FALSE);
+    KeInitializeEvent(&EventPair->HighEvent, SynchronizationEvent, FALSE);
 }
 
 /*
  * @implemented
  */
-LONG STDCALL KeResetEvent (PKEVENT Event)
+LONG STDCALL
+KePulseEvent(IN PKEVENT Event,
+             IN KPRIORITY Increment,
+             IN BOOLEAN Wait)
 {
-  /* FIXME: must use interlocked func. everywhere! (wait.c)
-   * or use dispather lock instead
-   * -Gunnar */
-   return(InterlockedExchange(&(Event->Header.SignalState),0));
+    KIRQL OldIrql;
+    LONG PreviousState;
+
+    DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
+    
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Save the Old State */
+    PreviousState = Event->Header.SignalState;
+    
+    /* Check if we are non-signaled and we have stuff in the Wait Queue */
+    if (!PreviousState && !IsListEmpty(&Event->Header.WaitListHead)) {
+        
+        /* Set the Event to Signaled */
+        Event->Header.SignalState = 1;
+    
+        /* Wake the Event */
+        KiWaitTest(&Event->Header, Increment);
+    }
+    
+    /* Unsignal it */
+    Event->Header.SignalState = 0;
+    
+    /* Check what wait state was requested */
+    if (Wait == FALSE) {
+    
+        /* Wait not requested, release Dispatcher Database and return */    
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        
+    } else {
+        
+        /* Return Locked and with a Wait */
+        KTHREAD *Thread = KeGetCurrentThread();
+        Thread->WaitNext = TRUE;
+        Thread->WaitIrql = OldIrql;
+    }
+
+    /* Return the previous State */
+    return PreviousState;
 }
 
 /*
  * @implemented
  */
-LONG STDCALL KeSetEvent (PKEVENT               Event,
-                        KPRIORITY      Increment,
-                        BOOLEAN                Wait)
+LONG 
+STDCALL 
+KeReadStateEvent(PKEVENT Event)
 {
-  KIRQL OldIrql;
-  int ret;
-
-  DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
-
-  OldIrql = KeAcquireDispatcherDatabaseLock();
-
-  ret = InterlockedExchange(&Event->Header.SignalState,1);
-
-  KiDispatcherObjectWake(&Event->Header, Increment);
-
-  if (Wait == FALSE)
-    {
-      KeReleaseDispatcherDatabaseLock(OldIrql);
-    }
-  else
-    {
-      KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = TRUE;
-      Thread->WaitIrql = OldIrql;
-    }
+    /* Return the Signal State */
+    return Event->Header.SignalState;
+}
 
-  return(ret);
+/*
+ * @implemented
+ */
+LONG 
+STDCALL 
+KeResetEvent(PKEVENT Event)
+{
+    KIRQL OldIrql;
+    LONG PreviousState;
+    
+    DPRINT("KeResetEvent(Event %x)\n",Event);
+    
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Save the Previous State */
+    PreviousState = Event->Header.SignalState;
+    
+    /* Set it to zero */
+    Event->Header.SignalState = 0;
+    
+    /* Release Dispatcher Database and return previous state */    
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return PreviousState;
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KePulseEvent (IN PKEVENT       Event,
-              IN KPRIORITY     Increment,
-              IN BOOLEAN       Wait)
+LONG
+STDCALL 
+KeSetEvent(PKEVENT Event,
+           KPRIORITY Increment,
+           BOOLEAN Wait)
 {
-   KIRQL OldIrql;
-   LONG Ret;
-
-   DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   Ret = InterlockedExchange(&Event->Header.SignalState,1);
-   KiDispatcherObjectWake(&Event->Header, Increment);
-   InterlockedExchange(&(Event->Header.SignalState),0);
-
-  if (Wait == FALSE)
-    {
-      KeReleaseDispatcherDatabaseLock(OldIrql);
+    KIRQL OldIrql;
+    LONG PreviousState;
+    PKWAIT_BLOCK WaitBlock;
+
+    DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
+
+    /* Lock the Dispathcer Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Save the Previous State */
+    PreviousState = Event->Header.SignalState;
+    
+    /* Check if we have stuff in the Wait Queue */
+    if (IsListEmpty(&Event->Header.WaitListHead)) {
+        
+        /* Set the Event to Signaled */
+        DPRINT("Empty Wait Queue, Signal the Event\n");
+        Event->Header.SignalState = 1;
+        
+    } else {
+    
+        /* Get the Wait Block */
+        WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
+                                      KWAIT_BLOCK,
+                                      WaitListEntry);
+        
+        
+        /* Check the type of event */
+        if (Event->Header.Type == NotificationEvent || WaitBlock->WaitType == WaitAll) {
+            
+            if (PreviousState == 0) {
+                
+                /* We must do a full wait satisfaction */
+                DPRINT("Notification Event or WaitAll, Wait on the Event and Signal\n");
+                Event->Header.SignalState = 1;
+                KiWaitTest(&Event->Header, Increment);
+            }
+                
+        } else {
+        
+            /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */        
+            DPRINT("WaitAny or Sync Event, just unwait the thread\n");
+            KiAbortWaitThread(WaitBlock->Thread, WaitBlock->WaitKey, Increment);
+        }
     }
-  else
-    {
-      KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = TRUE;
-      Thread->WaitIrql = OldIrql;
+    
+    /* Check what wait state was requested */
+    if (Wait == FALSE) {
+    
+        /* Wait not requested, release Dispatcher Database and return */    
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        
+    } else {
+        
+        /* Return Locked and with a Wait */
+        KTHREAD *Thread = KeGetCurrentThread();
+        Thread->WaitNext = TRUE;
+        Thread->WaitIrql = OldIrql;
     }
 
-   return Ret;
+    /* Return the previous State */
+    DPRINT("Done: %d\n", PreviousState);
+    return PreviousState;
 }
 
 /*
@@ -141,27 +232,39 @@ KePulseEvent (IN PKEVENT  Event,
  */
 VOID
 STDCALL
-KeSetEventBoostPriority(
-       IN PKEVENT Event,
-       IN PKTHREAD *Thread OPTIONAL
-)
+KeSetEventBoostPriority(IN PKEVENT Event,
+                        IN PKTHREAD *Thread OPTIONAL)
 {
-       PKTHREAD WaitingThread;
-   KIRQL OldIrql;
-       
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   
-       /* Get Thread that is currently waiting. First get the Wait Block, then the Thread */
-       WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, KWAIT_BLOCK, WaitListEntry)->Thread;
-       
-       /* Return it to caller if requested */
-       if ARGUMENT_PRESENT(Thread) *Thread = WaitingThread;
-       
-       /* Reset the Quantum and Unwait the Thread */
-       WaitingThread->Quantum = WaitingThread->ApcState.Process->ThreadQuantum;
-       KiAbortWaitThread(WaitingThread, STATUS_SUCCESS);
+    PKTHREAD WaitingThread;
+    KIRQL OldIrql;
+
+    DPRINT("KeSetEventBoostPriority(Event %x, Thread %x)\n",Event,Thread);
+    
+    /* Acquire Dispatcher Database Lock */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* If our wait list is empty, then signal the event and return */
+    if (IsListEmpty(&Event->Header.WaitListHead)) {
+    
+        Event->Header.SignalState = 1;
+    
+    } else {
+        
+        /* Get Thread that is currently waiting. First get the Wait Block, then the Thread */
+        WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, 
+                                          KWAIT_BLOCK, 
+                                          WaitListEntry)->Thread;
+
+        /* Return it to caller if requested */
+        if ARGUMENT_PRESENT(Thread) *Thread = WaitingThread;
+
+        /* Reset the Quantum and Unwait the Thread */
+        WaitingThread->Quantum = WaitingThread->ApcState.Process->ThreadQuantum;
+        KiAbortWaitThread(WaitingThread, STATUS_SUCCESS, EVENT_INCREMENT);
+    }
    
-   KeReleaseDispatcherDatabaseLock(OldIrql);
+    /* Release the Dispatcher Database Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
 }
 
 /* EOF */
index e2c668a..c967fae 100644 (file)
@@ -34,10 +34,10 @@ DbgBreakPoint(VOID)
  * @implemented
  */
 #if defined(__GNUC__)
-__asm__(".globl _DbgBreakPointNoBugCheck@0\n\t"
-       "_DbgBreakPointNoBugCheck@0:\n\t"
-       "int $3\n\t"
-       "ret\n\t");
+ __asm__(".globl _DbgBreakPointNoBugCheck@0\n\t"
+         "_DbgBreakPointNoBugCheck@0:\n\t"
+         "int $3\n\t"
+         "ret\n\t");
 #endif
 
 /*
index 5f8c9a8..e907280 100644 (file)
@@ -1,9 +1,9 @@
-/* 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/i386/exp.c
  * PURPOSE:         Handling exceptions
- * 
+ *
  * PROGRAMMERS:     David Welch (welch@cwcom.net)
  *                  Skywing (skywing@valhallalegends.com)
  */
@@ -120,24 +120,31 @@ KeRosPrintAddress(PVOID address)
    MODULE_TEXT_SECTION* current;
    extern LIST_ENTRY ModuleTextListHead;
    ULONG_PTR RelativeAddress;
+   ULONG i = 0;
 
-   current_entry = ModuleTextListHead.Flink;
-
-   while (current_entry != &ModuleTextListHead &&
-         current_entry != NULL)
-     {
-       current =
-         CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
+   do
+   {
+     current_entry = ModuleTextListHead.Flink;
+
+     while (current_entry != &ModuleTextListHead &&
+            current_entry != NULL)
+       {
+          current =
+            CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
+
+          if (address >= (PVOID)current->Base &&
+              address < (PVOID)(current->Base + current->Length))
+            {
+              RelativeAddress = (ULONG_PTR) address - current->Base;
+              DbgPrint("<%ws: %x>", current->Name, RelativeAddress);
+              return(TRUE);
+            }
+          current_entry = current_entry->Flink;
+       }
+
+     address = (PVOID)((ULONG_PTR)address & ~0xC0000000);
+   } while(++i <= 1);
 
-       if (address >= (PVOID)current->Base &&
-           address < (PVOID)(current->Base + current->Length))
-         {
-            RelativeAddress = (ULONG_PTR) address - current->Base;
-           DbgPrint("<%ws: %x>", current->Name, RelativeAddress);
-           return(TRUE);
-         }
-       current_entry = current_entry->Flink;
-     }
    return(FALSE);
 }
 #endif /* KDBG */
@@ -509,6 +516,21 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
        ExceptionNr = 12;
      }
 
+   if (ExceptionNr == 15)
+     {
+       /*
+        * FIXME:
+        *   This exception should never occur. The P6 has a bug, which does sometimes deliver
+        *   the apic spurious interrupt as exception 15. On an athlon64, I get one exception
+        *   in the early boot phase in apic mode (using the smp build). I've looked to the linux
+        *   sources. Linux does ignore this exception.
+        *
+        *   Hartmut Birr
+        */
+       DPRINT1("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
+       return(0);
+     }
+
    /*
     * Maybe handle the page fault and return
     */
@@ -566,6 +588,125 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
     }
 }
 
+VOID
+KeContextToTrapFrame(PCONTEXT Context,
+                    PKTRAP_FRAME TrapFrame)
+{
+   if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+     {
+       TrapFrame->Esp = Context->Esp;
+       TrapFrame->Ss = Context->SegSs;
+       TrapFrame->Cs = Context->SegCs;
+       TrapFrame->Eip = Context->Eip;
+       TrapFrame->Eflags = Context->EFlags;    
+       TrapFrame->Ebp = Context->Ebp;
+     }
+   if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+     {
+       TrapFrame->Eax = Context->Eax;
+       TrapFrame->Ebx = Context->Ebx;
+       TrapFrame->Ecx = Context->Ecx;
+       TrapFrame->Edx = Context->Edx;
+       TrapFrame->Esi = Context->Esi;
+       TrapFrame->Edi = Context->Edi;
+     }
+   if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+     {
+       TrapFrame->Ds = Context->SegDs;
+       TrapFrame->Es = Context->SegEs;
+       TrapFrame->Fs = Context->SegFs;
+       TrapFrame->Gs = Context->SegGs;
+     }
+   if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
+     {
+       /*
+        * Not handled
+        *
+        * This should be handled separately I think.
+        *  - blight
+        */
+     }
+   if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+     {
+       /*
+        * Not handled
+        */
+     }
+}
+
+VOID
+KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
+                    PCONTEXT Context)
+{
+   if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+     {
+       Context->SegSs = TrapFrame->Ss;
+       Context->Esp = TrapFrame->Esp;
+       Context->SegCs = TrapFrame->Cs;
+       Context->Eip = TrapFrame->Eip;
+       Context->EFlags = TrapFrame->Eflags;
+       Context->Ebp = TrapFrame->Ebp;
+     }
+   if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+     {
+       Context->Eax = TrapFrame->Eax;
+       Context->Ebx = TrapFrame->Ebx;
+       Context->Ecx = TrapFrame->Ecx;
+       /*
+        * NOTE: In the trap frame which is built on entry to a system
+        * call TrapFrame->Edx will actually hold the address of the
+        * previous TrapFrame. I don't believe leaking this information
+        * has security implications. Also EDX holds the address of the
+        * arguments to the system call in progress so it isn't of much
+        * interest to the debugger.
+        */
+       Context->Edx = TrapFrame->Edx;
+       Context->Esi = TrapFrame->Esi;
+       Context->Edi = TrapFrame->Edi;
+     }
+   if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+     {
+       Context->SegDs = TrapFrame->Ds;
+       Context->SegEs = TrapFrame->Es;
+       Context->SegFs = TrapFrame->Fs;
+       Context->SegGs = TrapFrame->Gs;
+     }
+   if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+     {
+       /*
+        * FIXME: Implement this case
+        */     
+       Context->ContextFlags &= (~CONTEXT_DEBUG_REGISTERS) | CONTEXT_i386;
+     }
+   if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
+     {
+       /*
+        * FIXME: Implement this case
+        *
+        * I think this should only be filled for FPU exceptions, otherwise I
+         * would not know where to get it from as it can be the current state
+        * of the FPU or already saved in the thread's FPU save area.
+        *  -blight
+        */
+       Context->ContextFlags &= (~CONTEXT_FLOATING_POINT) | CONTEXT_i386;
+     }
+#if 0
+   if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
+     {
+       /*
+        * FIXME: Investigate this
+        *
+        * This is the XMM state (first 512 bytes of FXSAVE_FORMAT/FX_SAVE_AREA)
+        * This should only be filled in case of a SIMD exception I think, so
+        * this is not the right place (like for FPU the state could already be
+        * saved in the thread's FX_SAVE_AREA or still be in the CPU)
+        *  -blight
+        */
+        Context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS;
+     }
+#endif
+}
+
 VOID
 KeDumpStackFrames(PULONG Frame)
 {
@@ -807,7 +948,7 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode)
     } _SEH_HANDLE {
         return(ExceptionCode);
     } _SEH_END;
-            
+
    OldEip = Thread->TrapFrame->Eip;
    Thread->TrapFrame->Eip = (ULONG_PTR)LdrpGetSystemDllRaiseExceptionDispatcher();
    return((NTSTATUS)OldEip);
@@ -838,7 +979,7 @@ NtRaiseException (
     /* Restore the user context */
     Thread->TrapFrame = PrevTrapFrame;
     __asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
-    
+
     /* We never get here */
     return(STATUS_SUCCESS);
 }
index cb94a70..59195b4 100644 (file)
@@ -228,7 +228,7 @@ KiCheckFPU(VOID)
    unsigned short int status;
    int cr0;
    ULONG Flags;
-   PKPCR Pcr = KeGetCurrentKPCR();
+   PKPRCB Prcb = KeGetCurrentPrcb();
 
    Ke386SaveFlags(Flags);
    Ke386DisableInterrupts();
@@ -275,7 +275,7 @@ KiCheckFPU(VOID)
    HardwareMathSupport = 1;
 
    /* check for and enable MMX/SSE support if possible */
-   if ((Pcr->PrcbData.FeatureBits & X86_FEATURE_FXSR) != 0)
+   if ((Prcb->FeatureBits & X86_FEATURE_FXSR) != 0)
      {
         BYTE DummyArea[sizeof(FX_SAVE_AREA) + 15];
         PFX_SAVE_AREA FxSaveArea;
@@ -300,7 +300,7 @@ KiCheckFPU(VOID)
           }
      }
    /* FIXME: Check for SSE3 in Ke386CpuidFlags2! */
-   if (Pcr->PrcbData.FeatureBits & (X86_FEATURE_SSE | X86_FEATURE_SSE2))
+   if (Prcb->FeatureBits & (X86_FEATURE_SSE | X86_FEATURE_SSE2))
      {
         Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
         
@@ -401,7 +401,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
 
       CurrentThread = KeGetCurrentThread();
 #ifndef CONFIG_SMP
-      NpxThread = KeGetCurrentKPCR()->PrcbData.NpxThread;
+      NpxThread = KeGetCurrentPrcb()->NpxThread;
 #endif
 
       ASSERT(CurrentThread != NULL);
@@ -414,7 +414,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
           /* save the FPU state into the owner's save area */
           if (NpxThread != NULL)
             {
-              KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
+              KeGetCurrentPrcb()->NpxThread = NULL;
               FxSaveArea = (PFX_SAVE_AREA)((char *)NpxThread->InitialStack - sizeof (FX_SAVE_AREA));
               /* the fnsave might raise a delayed #MF exception */
               if (FxsrSupport)
@@ -463,7 +463,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
                   asm volatile("finit");
                 }
             }
-          KeGetCurrentKPCR()->PrcbData.NpxThread = CurrentThread;
+          KeGetCurrentPrcb()->NpxThread = CurrentThread;
 #ifndef CONFIG_SMP
         }
 #endif
@@ -487,7 +487,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
 
       KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
 
-      NpxThread = KeGetCurrentKPCR()->PrcbData.NpxThread;
+      NpxThread = KeGetCurrentPrcb()->NpxThread;
       CurrentThread = KeGetCurrentThread();
       if (NpxThread == NULL)
         {
index cf90d44..22d269b 100644 (file)
@@ -315,7 +315,7 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
     * the PIC.
     */
     
-   KeGetCurrentKPCR()->PrcbData.InterruptCount++;
+   KeGetCurrentPrcb()->InterruptCount++;
 
    /*
     * Notify the rest of the kernel of the raised irq level. For the
@@ -340,9 +340,6 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
    {
       KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
       KeUpdateSystemTime(&KernelTrapFrame, old_level);
-#if defined(KDBG) || defined(DBG)
-      KdbProfileInterrupt(Trapframe->Eip);
-#endif /* KDBG */
    }
    else
 #endif
index 37852a5..1d07b53 100644 (file)
@@ -18,7 +18,7 @@
 
 ULONG KiPcrInitDone = 0;
 static ULONG PcrsAllocated = 0;
-static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags;
+static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags, Ke386CpuidExMisc;
 ULONG Ke386CacheAlignment;
 CHAR Ke386CpuidModel[49] = {0,};
 ULONG Ke386L1CacheSize;
@@ -34,7 +34,7 @@ Ki386GetCpuId(VOID)
 {
    ULONG OrigFlags, Flags, FinalFlags;
    ULONG MaxCpuidLevel;
-   ULONG Dummy, Eax, Ebx, Ecx, Edx;
+   ULONG Dummy, Eax, Ecx, Edx;
    PKPCR Pcr = KeGetCurrentKPCR();
 
    Ke386CpuidFlags2 =  Ke386CpuidExFlags = 0;
@@ -45,6 +45,10 @@ Ki386GetCpuId(VOID)
    Flags = OrigFlags ^ X86_EFLAGS_ID;
    Ke386RestoreFlags(Flags);
    Ke386SaveFlags(FinalFlags);
+   
+   Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor = 1;
+   Pcr->PrcbData.InitialApicId = 0xff;
+   
    if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
    {
       /* No cpuid supported. */
@@ -59,14 +63,24 @@ Ki386GetCpuId(VOID)
    if (MaxCpuidLevel > 0)
    { 
       /* Get the feature flags. */
-      Ki386Cpuid(1, &Eax, &Ebx, &Ke386CpuidFlags2, &Pcr->PrcbData.FeatureBits);
+      Ki386Cpuid(1, &Eax, &Ke386CpuidExMisc, &Ke386CpuidFlags2, &Pcr->PrcbData.FeatureBits);
       /* Get the cache alignment, if it is available */
       if (Pcr->PrcbData.FeatureBits & (1<<19))
       {
-         Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8;
+         Ke386CacheAlignment = ((Ke386CpuidExMisc >> 8) & 0xff) * 8;
       }
       Pcr->PrcbData.CpuType = (Eax >> 8) & 0xf;
       Pcr->PrcbData.CpuStep = (Eax & 0xf) | ((Eax << 4) & 0xf00);
+      
+      Pcr->PrcbData.InitialApicId = (Ke386CpuidExMisc >> 24) & 0xff;
+
+      /* detect Hyper-Threading on Pentium 4 CPUs or later */
+      if ((Pcr->PrcbData.CpuType == 0xf || (Eax & 0x0f00000)) &&
+          !strncmp(Pcr->PrcbData.VendorString, "GenuineIntel", 12) &&
+          Pcr->PrcbData.FeatureBits & X86_FEATURE_HT)
+      {
+        Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor = (Ke386CpuidExMisc >> 16) & 0xff;
+      }
    }
    else
    {
@@ -132,6 +146,7 @@ KePrepareForApplicationProcessorInit(ULONG Id)
   Pcr->ProcessorNumber = Id;
   Pcr->Tib.Self = &Pcr->Tib;
   Pcr->Self = Pcr;
+  Pcr->Prcb = &Pcr->PrcbData;
   Pcr->Irql = SYNCH_LEVEL;
 
   Pcr->PrcbData.MHz = BootPcr->PrcbData.MHz;
@@ -172,7 +187,7 @@ KeApplicationProcessorInit(VOID)
   /* Check FPU/MMX/SSE support. */
   KiCheckFPU();
 
-  KeInitDpc(Pcr);
+  KeInitDpc(Pcr->Prcb);
 
   if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
   {
@@ -224,6 +239,7 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
    KPCR = (PKPCR)KPCR_BASE;
    memset(KPCR, 0, PAGE_SIZE);
    KPCR->Self = KPCR;
+   KPCR->Prcb = &KPCR->PrcbData;
    KPCR->Irql = SYNCH_LEVEL;
    KPCR->Tib.Self  = &KPCR->Tib;
    KPCR->GDT = KiBootGdt;
@@ -246,7 +262,7 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
    /* Mark the end of the exception handler list */
    KPCR->Tib.ExceptionList = (PVOID)-1;
 
-   KeInitDpc(KPCR);
+   KeInitDpc(KPCR->Prcb);
 
    KeInitExceptions ();
    KeInitInterrupts ();
@@ -339,7 +355,7 @@ KeInit2(VOID)
 {
    PKPCR Pcr = KeGetCurrentKPCR();
 
-   KeInitializeBugCheck();
+   KiInitializeBugCheck();
    KeInitializeDispatcher();
    KiInitializeSystemClock();
 
index 280720d..5e24374 100644 (file)
@@ -26,7 +26,9 @@
 
 /* INCLUDES ******************************************************************/
        
+#include <roscfg.h>
 #include <ddk/status.h>
+#include <internal/i386/ke.h>
 #include <internal/i386/segment.h>
 #include <internal/ps.h>
 #include <ddk/defines.h>
@@ -74,6 +76,29 @@ _KiTrapRet:
        popl    %edi
        popl    %esi
        popl    %ebx
+
+#ifdef DBG
+        /*
+         * Cleanup the stack which was used to setup a trapframe with SS:ESP when called
+         * from kmode.
+         */
+        movw    0xC(%esp), %bp             /* Get CS from trapframe */
+        cmpw    $KERNEL_CS, %bp
+        jne     0f
+
+        /* Copy EBP, CS:EIP and EFLAGS from the trapframe back onto the top of our stack. */
+        movl    0x00(%esp), %ebp            /* EBP */
+        movl    %ebp, 0x24(%esp)
+        movl    0x08(%esp), %ebp            /* EIP */
+        movl    %ebp, 0x2C(%esp)
+        movl    0x0C(%esp), %ebp            /* CS */
+        movl    %ebp, 0x30(%esp)
+        movl    0x10(%esp), %ebp            /* EFLAGS */
+        movl    %ebp, 0x34(%esp)
+
+        addl    $0x24, %esp
+0:
+#endif /* DBG */
        popl    %ebp
        addl    $0x4, %esp  /* Ignore error code */
                
@@ -81,10 +106,32 @@ _KiTrapRet:
 
 .globl _KiTrapProlog
 _KiTrapProlog: 
+#ifdef DBG
+        /*
+         * If we were called from kmode we start setting up a new trapframe (with SS:ESP at the end)
+         */
+        movw    0x14(%esp), %bx             /* Get old CS */
+        cmpw    $KERNEL_CS, %bx
+        
+        jne     0f
+
+        leal    0x1C(%esp), %ebp
+        pushl   %ss                          /* Old SS */
+        pushl   %ebp                         /* Old ESP */
+        pushl   0x20(%esp)                   /* Old EFLAGS */
+        pushl   0x20(%esp)                   /* Old CS */
+        pushl   0x20(%esp)                   /* Old EIP */
+        pushl   0x20(%esp)                   /* ErrorCode */
+        pushl   0x20(%esp)                   /* Ebp */
+        pushl   0x20(%esp)                   /* Ebx */
+        pushl   0x20(%esp)                   /* Esi */
+0:
+#endif /* DBG */
+
        pushl   %edi
        pushl   %fs
 
-       /* 
+       /*
         * Check that the PCR exists, very early in the boot process it may 
         * not 
         */
index a97577f..4084b18 100644 (file)
@@ -45,6 +45,10 @@ _Ki386ContextSwitch:
  *     Thread = Thread to switch to
  *     OldThread = Thread to switch from
  */
+#ifdef KDBG
+       jmp     SaveTrapFrameForKDB
+SaveTrapFrameForKDB_Return:
+#endif
        pushl   %ebp
        movl    %esp, %ebp
 
@@ -200,12 +204,7 @@ _Ki386ContextSwitch:
         */
        sti
 
-       call    _KeReleaseDispatcherDatabaseLockFromDpcLevel
-
-       cmpl    $0, _PiNrThreadsAwaitingReaping
-       je      5f
-       call    _PiWakeupReaperThread@0
-5:
+       call    @KeReleaseDispatcherDatabaseLockFromDpcLevel@0
 
        /*
         * Restore the saved register and exit
@@ -218,3 +217,128 @@ _Ki386ContextSwitch:
        ret
 .endfunc
 
+
+
+#ifdef KDBG
+
+SaveTrapFrameForKDB:
+       /*
+        * Set up a trap frame.
+        */
+                               /* Ss - space already reserved by return EIP */
+       pushl   %esp            /* Esp */
+       pushfl                  /* Eflags */
+       pushl   %cs             /* Cs */
+       pushl   12(%esp)        /* Eip */
+       movl    %ss, 16(%esp)   /* Save Ss */
+       pushl   $0              /* ErrorCode */
+       pushl   %ebp            /* Ebp */
+       pushl   %ebx            /* Ebx */
+       pushl   %esi            /* Esi */
+       pushl   %edi            /* Edi */
+       pushl   %fs             /* Fs */
+       pushl   $0              /* ExceptionList */
+       pushl   $0              /* PreviousMode */
+       pushl   %eax            /* Eax */
+       pushl   %ecx            /* Ecx */
+       pushl   %edx            /* Edx */
+       pushl   %ds             /* Ds */
+       pushl   %es             /* Es */
+       pushl   %gs             /* Gs */
+       movl    %dr7, %eax
+       pushl   %eax            /* Dr7 */
+       /* Clear breakpoint enables in dr7. */
+       andl    $~0xffff, %eax
+       movl    %eax, %dr7
+       movl    %dr6, %eax
+       pushl   %eax            /* Dr6 */
+       movl    %dr3, %eax
+       pushl   %eax            /* Dr3 */
+       movl    %dr2, %eax
+       pushl   %eax            /* Dr2 */
+       movl    %dr1, %eax
+       pushl   %eax            /* Dr1 */
+       movl    %dr0, %eax
+       pushl   %eax            /* Dr0 */
+       pushl   $0              /* TempEip */
+       pushl   $0              /* TempCs */
+       pushl   $0              /* DebugPointer */
+       pushl   $0xffffffff     /* DebugArgMark (Exception number) */
+       pushl   0x60(%esp)      /* DebugEip */
+       pushl   %ebp            /* DebugEbp */
+
+       movl    %esp, %ebp      /* Save pointer to new TrapFrame */
+
+       /* Save the old trapframe and set pointer to the new one */
+       movl    0x80(%esp), %ebx        /* Get pointer to OldThread */
+       pushl   KTHREAD_TRAP_FRAME(%ebx)
+       movl    %ebp, KTHREAD_TRAP_FRAME(%ebx)
+
+       /* Copy the arguments which were passed to Ki386ContextSwitch */
+       pushl   0x80(%ebp)              /* OldThread */
+       pushl   0x7c(%ebp)              /* NewThread */
+       pushl   $RestoreTrapFrameForKDB /* Return address */
+
+       /* Restore clobbered registers */
+       movl    KTRAP_FRAME_EBX(%ebp), %ebx
+       movl    KTRAP_FRAME_EBP(%ebp), %ebp
+
+       /* Return */
+       jmp     SaveTrapFrameForKDB_Return
+
+
+RestoreTrapFrameForKDB:
+       addl    $8, %esp                /* Remove NewThread and OldThread arguments from the stack */
+       movl    0x84(%esp), %ebx        /* Get pointer to OldThread */
+
+       /* Restore the old trapframe */
+       popl    KTHREAD_TRAP_FRAME(%ebx)
+        
+       /*
+        * Pop unused portions of the trap frame:
+        *   DebugEbp
+        *   DebugEip
+        *   DebugArgMark
+        *   DebugPointer
+        *   TempCs
+        *   TempEip
+        *   Dr0-3
+        *   Dr6-7
+        */
+       addl    $(12*4), %esp
+
+       /*
+        * Restore registers including any that might have been changed
+        * inside the debugger.
+        */
+       popl    %gs             /* Gs */
+       popl    %es             /* Es */
+       popl    %ds             /* Ds */
+       popl    %edx            /* Edx */
+       popl    %ecx            /* Ecx */
+       popl    %eax            /* Eax */
+       addl    $4, %esp        /* PreviousMode */
+       addl    $4, %esp        /* ExceptionList */
+       popl    %fs             /* Fs */
+       popl    %edi            /* Edi */
+       popl    %esi            /* Esi */
+       popl    %ebx            /* Ebx */
+
+        /* Remove SS:ESP from the stack */
+       movl    16(%esp), %ebp
+       movl    %ebp, 24(%esp)
+       movl    12(%esp), %ebp
+       movl    %ebp, 20(%esp)
+       movl    8(%esp), %ebp
+       movl    %ebp, 16(%esp)
+
+       popl    %ebp            /* Ebp */
+       addl    $12, %esp       /* ErrorCode and SS:ESP */
+
+       /*
+        * Return to the caller.
+        */
+       iret
+
+#endif /* KDBG */
+
diff --git a/reactos/ntoskrnl/ke/i386/usercall.S b/reactos/ntoskrnl/ke/i386/usercall.S
new file mode 100644 (file)
index 0000000..ad5dd5f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ke/i386s/usercall.S
+ * PURPOSE:         User-Mode callbacks and return.
+ * 
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <roscfg.h>
+#include <internal/i386/segment.h>
+#include <internal/i386/ke.h>
+#include <internal/i386/fpu.h>
+#include <internal/ps.h>
+#include <ntos/tss.h>
+#include <internal/ntoskrnl.h>
+.intel_syntax noprefix
+
+/* GLOBALS ****************************************************************/
+.extern PVOID _SystemDllCallbackDispatcher
+
+#define CBSTACK_BUFFER_ADDRESS 0x20
+#define CBSTACK_BUFFER_LENGTH  0x24
+/* FUNCTIONS ****************************************************************/
+
+/*++
+ * KiSwitchToUserMode 
+ *
+ *     The KiSwitchToUserMode routine sets up a Trap Frame and a Callback stack
+ *     for the purpose of switching to user mode. The actual final jump is done
+ *     by KiServiceExit which will treat this as a syscall return.
+ *
+ * Params:
+ *     OutputBuffer - Pointer to a caller-allocated buffer where to receive 
+ *                    the return data from the user-mode function
+ *
+ *     OutputLength - Size of the Output Buffer described above.
+ *
+ * Returns:
+ *     Jumps into KiServiceExit.
+ *
+ * Remarks:
+ *     If there is not enough Kernel Stack space, the routine will increase the
+ *     Kernel Stack.
+ *
+ *     User mode execution resumes at ntdll!KiUserCallbackDispatcher.
+ *
+ *     This call MUST be paired by interrupt 0x2B or NtCallbackReturn.
+ *
+ *--*/
+.globl _KiSwitchToUserMode@8
+.func KiSwitchToUserMode@8
+_KiSwitchToUserMode@8:
+
+.endfunc
+
+
diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c
deleted file mode 100644 (file)
index 46aa853..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/i386/usercall.c
- * PURPOSE:         2E interrupt handler
- * 
- * PROGRAMMERS:     David Welch (david.welch@seh.ox.ac.uk)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-KeUserModeCallback(
-    IN ULONG   FunctionID,
-    IN PVOID   InputBuffer,
-    IN ULONG   InputLength,
-    OUT PVOID  *OutputBuffer,
-    OUT PULONG OutputLength
-)
-{
-       UNIMPLEMENTED;
-       return 0;
-}
-
-/* EOF */
index 3798d44..2584386 100644 (file)
@@ -32,7 +32,7 @@ KiIpiSendRequest(ULONG TargetSet, ULONG IpiRequest)
       if (TargetSet & (1 << i))
       {
          Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-        Ke386TestAndSetBit(IpiRequest, &Pcr->PrcbData.IpiFrozen);
+        Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen);
         HalRequestIpi(i);
       }
    }
@@ -50,34 +50,34 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
    LARGE_INTEGER StartTime, CurrentTime, Frequency;
    ULONG Count = 5;
 #endif   
-   PKPCR Pcr;
+   PKPRCB Prcb;
 
    ASSERT(KeGetCurrentIrql() == IPI_LEVEL);
 
    DPRINT("KiIpiServiceRoutine\n");
 
-   Pcr = KeGetCurrentKPCR();
+   Prcb = KeGetCurrentPrcb();
 
-   if (Ke386TestAndClearBit(IPI_REQUEST_APC, &Pcr->PrcbData.IpiFrozen))
+   if (Ke386TestAndClearBit(IPI_REQUEST_APC, &Prcb->IpiFrozen))
    {
       HalRequestSoftwareInterrupt(APC_LEVEL);
    }
 
-   if (Ke386TestAndClearBit(IPI_REQUEST_DPC, &Pcr->PrcbData.IpiFrozen))
+   if (Ke386TestAndClearBit(IPI_REQUEST_DPC, &Prcb->IpiFrozen))
    {
-      Pcr->PrcbData.DpcInterruptRequested = TRUE;
+      Prcb->DpcInterruptRequested = TRUE;
       HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
    }
 
-   if (Ke386TestAndClearBit(IPI_REQUEST_FUNCTIONCALL, &Pcr->PrcbData.IpiFrozen))
+   if (Ke386TestAndClearBit(IPI_REQUEST_FUNCTIONCALL, &Prcb->IpiFrozen))
    {
-      InterlockedDecrementUL(&Pcr->PrcbData.SignalDone->CurrentPacket[1]);
-      if (InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->CurrentPacket[2], 0, 0))
+      InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
+      if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
       {
 #ifdef DBG             
          StartTime = KeQueryPerformanceCounter(&Frequency);
 #endif         
-         while (0 != InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->CurrentPacket[1], 0, 0))
+         while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0))
         {
 #ifdef DBG             
             CurrentTime = KeQueryPerformanceCounter(NULL);
@@ -89,14 +89,14 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
 #endif  
          }
       }
-      ((VOID STDCALL(*)(PVOID))(Pcr->PrcbData.SignalDone->WorkerRoutine))(Pcr->PrcbData.SignalDone->CurrentPacket[0]);
-      Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), &Pcr->PrcbData.SignalDone->TargetSet);
-      if (InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->CurrentPacket[2], 0, 0))
+      ((VOID STDCALL(*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
+      Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), &Prcb->SignalDone->TargetSet);
+      if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
       {
 #ifdef DBG             
          StartTime = KeQueryPerformanceCounter(&Frequency);
 #endif         
-         while (0 != InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->TargetSet, 0, 0))
+         while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0))
          {
 #ifdef DBG             
            CurrentTime = KeQueryPerformanceCounter(NULL);
@@ -108,7 +108,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
 #endif  
          }
       }
-      InterlockedExchangePointer(&Pcr->PrcbData.SignalDone, NULL);
+      InterlockedExchangePointer(&Prcb->SignalDone, NULL);
    }
    DPRINT("KiIpiServiceRoutine done\n");
    return TRUE;
@@ -119,18 +119,18 @@ STDCALL
 KiIpiSendPacket(ULONG TargetSet, VOID STDCALL (*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize)
 {
     ULONG i, Processor, CurrentProcessor;
-    PKPCR Pcr, CurrentPcr;
+    PKPRCB Prcb, CurrentPrcb;
     KIRQL oldIrql;
 
 
     ASSERT(KeGetCurrentIrql() == SYNCH_LEVEL);
 
-    CurrentPcr = KeGetCurrentKPCR();
-    InterlockedExchangeUL(&CurrentPcr->PrcbData.TargetSet, TargetSet);
-    InterlockedExchangeUL(&CurrentPcr->PrcbData.WorkerRoutine, (ULONG_PTR)WorkerRoutine);
-    InterlockedExchangePointer(&CurrentPcr->PrcbData.CurrentPacket[0], Argument);
-    InterlockedExchangeUL(&CurrentPcr->PrcbData.CurrentPacket[1], Count);
-    InterlockedExchangeUL(&CurrentPcr->PrcbData.CurrentPacket[2], Synchronize ? 1 : 0);
+    CurrentPrcb = KeGetCurrentPrcb();
+    InterlockedExchangeUL(&CurrentPrcb->TargetSet, TargetSet);
+    InterlockedExchangeUL(&CurrentPrcb->WorkerRoutine, (ULONG_PTR)WorkerRoutine);
+    InterlockedExchangePointer(&CurrentPrcb->CurrentPacket[0], Argument);
+    InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
+    InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
 
     CurrentProcessor = 1 << KeGetCurrentProcessorNumber();
 
@@ -138,9 +138,9 @@ KiIpiSendPacket(ULONG TargetSet, VOID STDCALL (*WorkerRoutine)(PVOID), PVOID Arg
     {
        if (TargetSet & Processor)
        {
-          Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-          while(0 != InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone, (LONG)&CurrentPcr->PrcbData, 0));
-         Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Pcr->PrcbData.IpiFrozen);
+         Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
+         while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
+         Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Prcb->IpiFrozen);
          if (Processor != CurrentProcessor)
          {
             HalRequestIpi(i);
index b19a315..ebd1b74 100644 (file)
@@ -1,11 +1,13 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PURPOSE:         ReactOS kernel
  * FILE:            ntoskrnl/ke/kqueue.c
  * PURPOSE:         Implement device queues
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Several optimizations and implement
+ *                                                    usage of Inserted flag + reformat and
+ *                                                    add debug output.
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES ****************************************************************/
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ *
+ * FUNCTION: Intializes a device queue
+ * ARGUMENTS:
+ *       DeviceQueue = Device queue to initialize
+ */
+VOID
+STDCALL
+KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
+{
+
+    /* Initialize the Header */
+    DeviceQueue->Type = DeviceQueueObject;
+    DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
+    
+    /* Initialize the Listhead and Spinlock */
+    InitializeListHead(&DeviceQueue->DeviceListHead);
+    KeInitializeSpinLock(&DeviceQueue->Lock);
+    
+    /* Set it as busy */
+    DeviceQueue->Busy=FALSE;
+}
 
 /*
  * @implemented
+ *
+ * FUNCTION: Inserts an entry in a device queue
+ * ARGUMENTS:
+ *        DeviceQueue = Queue to insert the entry in
+ *        DeviceQueueEntry = Entry to insert
+ * RETURNS: False is the device queue wasn't busy
+ *          True otherwise
  */
-BOOLEAN STDCALL
-KeInsertByKeyDeviceQueue (
-  IN PKDEVICE_QUEUE            DeviceQueue,
-  IN PKDEVICE_QUEUE_ENTRY      DeviceQueueEntry,
-  IN ULONG                     SortKey)
+BOOLEAN
+STDCALL
+KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
+                    IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
 {
-  DPRINT("KeInsertByKeyDeviceQueue()\n");
-  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    BOOLEAN Inserted;
+    
+    DPRINT("KeInsertDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-  DeviceQueueEntry->SortKey=SortKey;
+    /* Lock the Queue */
+    KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+   
+    if (!DeviceQueue->Busy) {
+        
+        /* Set it as busy */
+        Inserted = FALSE;
+        DeviceQueue->Busy = TRUE;
+    
+    } else {
 
-  KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+        /* Insert it into the list */
+        Inserted = TRUE;        
+        InsertTailList(&DeviceQueue->DeviceListHead, 
+                       &DeviceQueueEntry->DeviceListEntry);
+    
+    
+    }
    
-  if (!DeviceQueue->Busy)
-  {
-    DeviceQueue->Busy=TRUE;
-    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-    return(FALSE);
-  }
-  
-  /* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */
-  InsertAscendingListFIFO(&DeviceQueue->DeviceListHead,
-                          KDEVICE_QUEUE_ENTRY,
-                          DeviceListEntry,
-                          DeviceQueueEntry,
-                          SortKey);
+    /* Sert the Insert state into the entry */
+    DeviceQueueEntry->Inserted = Inserted;
    
-  KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-  return(TRUE);
+    /* Release lock and return */
+    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
+    return Inserted;
 }
 
 /*
  * @implemented
  */
-PKDEVICE_QUEUE_ENTRY
+BOOLEAN 
 STDCALL
-KeRemoveByKeyDeviceQueue (
-       IN PKDEVICE_QUEUE       DeviceQueue,
-       IN ULONG                SortKey
-       )
+KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
+                         IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
+                         IN ULONG SortKey)
 {
-  PLIST_ENTRY current;
-  PKDEVICE_QUEUE_ENTRY entry;
-
-  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-  ASSERT(DeviceQueue!=NULL);
-  ASSERT(DeviceQueue->Busy);
+    BOOLEAN Inserted;
+    
+    DPRINT("KeInsertByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
-  KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    /* Acquire the Lock */
+    KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    
+    /* Set the Sort Key */
+    DeviceQueueEntry->SortKey=SortKey;
    
-  /* an attempt to remove an entry from an empty (and busy) queue sets the queue to idle */
-  if (IsListEmpty(&DeviceQueue->DeviceListHead))
-  {
-    DeviceQueue->Busy = FALSE;
-    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-    return NULL;
-  }
-   
-  /* find entry with SortKey greater than or equal to the passed-in SortKey */
-  current = DeviceQueue->DeviceListHead.Flink;
-  while (current != &DeviceQueue->DeviceListHead)
-  {
-    entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
-    if (entry->SortKey >= SortKey)
-    {
-       RemoveEntryList(current);
-       KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-       return entry;
+    if (!DeviceQueue->Busy) {
+        
+        DeviceQueue->Busy=TRUE;
+        Inserted = FALSE;
+  
+    } else {
+  
+        /* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */
+        InsertAscendingListFIFO(&DeviceQueue->DeviceListHead,
+                                KDEVICE_QUEUE_ENTRY,
+                                DeviceListEntry,
+                                DeviceQueueEntry,
+                                SortKey);
+        Inserted = TRUE;
     }
-    current = current->Flink;
-  }
+   
+    /* Reset the Inserted State */
+    DeviceQueueEntry->Inserted = Inserted;
   
-  /* if we didn't find a match, return the first entry */
-  current = RemoveHeadList(&DeviceQueue->DeviceListHead);
-  KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-
-  return CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
+    /* Release Lock and Return */
+    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
+    return Inserted;
 }
 
 /*
  * @implemented
- */
-PKDEVICE_QUEUE_ENTRY
-STDCALL
-KeRemoveDeviceQueue (
-  IN PKDEVICE_QUEUE    DeviceQueue)
-/*
+ *
  * FUNCTION: Removes an entry from a device queue
  * ARGUMENTS:
  *        DeviceQueue = Queue to remove the entry
  * RETURNS: The removed entry
  */
+PKDEVICE_QUEUE_ENTRY
+STDCALL
+KeRemoveDeviceQueue(IN PKDEVICE_QUEUE  DeviceQueue)
 {
-   PLIST_ENTRY list_entry;
-   
-   DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue);
+    PLIST_ENTRY ListEntry;
+    PKDEVICE_QUEUE_ENTRY ReturnEntry;
    
-   ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-   ASSERT(DeviceQueue!=NULL);
-   ASSERT(DeviceQueue->Busy);
+    DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    
-   KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    /* Acquire the Lock */
+    KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    ASSERT(DeviceQueue->Busy);
    
-   /* an attempt to remove an entry from an empty (and busy) queue sets the queue idle */
-   if (IsListEmpty(&DeviceQueue->DeviceListHead))
-   {
-     DeviceQueue->Busy = FALSE;
-     KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-     return NULL;
-   }
+    /* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
+    if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
+        DeviceQueue->Busy = FALSE;
+        ReturnEntry = NULL;
    
-   list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead);
-   KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
+   } else {
    
-   return CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
-}
+        /* Remove the Entry from the List */
+        ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
+        ReturnEntry = CONTAINING_RECORD(ListEntry, 
+                                        KDEVICE_QUEUE_ENTRY,
+                                        DeviceListEntry);
+        
+        /* Set it as non-inserted */
+        ReturnEntry->Inserted = FALSE;
+    }
 
-/*
- * @implemented
- */
-VOID
-STDCALL
-KeInitializeDeviceQueue (
-  IN PKDEVICE_QUEUE    DeviceQueue
-       )
-/*
- * FUNCTION: Intializes a device queue
- * ARGUMENTS:
- *       DeviceQueue = Device queue to initialize
- */
-{
-   ASSERT(DeviceQueue!=NULL);
-   InitializeListHead(&DeviceQueue->DeviceListHead);
-   DeviceQueue->Busy=FALSE;
-   KeInitializeSpinLock(&DeviceQueue->Lock);
+    /* Release lock and Return */
+    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
+    return ReturnEntry;
 }
 
 /*
  * @implemented
  */
-BOOLEAN
+PKDEVICE_QUEUE_ENTRY
 STDCALL
-KeInsertDeviceQueue (
-  IN PKDEVICE_QUEUE            DeviceQueue,
-  IN PKDEVICE_QUEUE_ENTRY      DeviceQueueEntry
-       )
-/*
- * FUNCTION: Inserts an entry in a device queue
- * ARGUMENTS:
- *        DeviceQueue = Queue to insert the entry in
- *        DeviceQueueEntry = Entry to insert
- * RETURNS: False is the device queue wasn't busy
- *          True otherwise
- */
+KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue,
+                          IN ULONG SortKey)
 {
-  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-   
-  KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    PLIST_ENTRY ListEntry;
+    PKDEVICE_QUEUE_ENTRY ReturnEntry;
+
+    DPRINT("KeRemoveByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+    
+    /* Acquire the Lock */
+    KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
+    ASSERT(DeviceQueue->Busy);
+
+    /* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
+    if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
+        
+        DeviceQueue->Busy = FALSE;
+        ReturnEntry = NULL;
    
-  if (!DeviceQueue->Busy)
-  {
-    DeviceQueue->Busy=TRUE;
-    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-    return(FALSE);
-  }
+   } else {
    
-  DeviceQueueEntry->SortKey=0;
-  InsertTailList(&DeviceQueue->DeviceListHead, &DeviceQueueEntry->DeviceListEntry);
+        /* Find entry with SortKey greater than or equal to the passed-in SortKey */
+        ListEntry = DeviceQueue->DeviceListHead.Flink;
+        while (ListEntry != &DeviceQueue->DeviceListHead) {
+
+            /* Get Entry */
+            ReturnEntry = CONTAINING_RECORD(ListEntry, 
+                                            KDEVICE_QUEUE_ENTRY,
+                                            DeviceListEntry);
+            
+            /* Check if keys match */
+            if (ReturnEntry->SortKey >= SortKey) break;
+            
+            /* Move to next item */
+            ListEntry = ListEntry->Flink;
+        }
+        
+        /* Check if we found something */
+        if (ListEntry == &DeviceQueue->DeviceListHead) {
+        
+            /*  Not found, return the first entry */
+            ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
+            ReturnEntry = CONTAINING_RECORD(ListEntry, 
+                                            KDEVICE_QUEUE_ENTRY,
+                                            DeviceListEntry);
+        } else {
+        
+            /* We found it, so just remove it */
+            RemoveEntryList(&ReturnEntry->DeviceListEntry);
+        }
+        
+        /* Set it as non-inserted */
+        ReturnEntry->Inserted = FALSE;
+    }
    
-  KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
-  return(TRUE);
+    /* Release lock and Return */
+    KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
+    return ReturnEntry;
 }
 
-
 /*
  * @implemented
  */
 BOOLEAN STDCALL
-KeRemoveEntryDeviceQueue(
-  IN PKDEVICE_QUEUE DeviceQueue,
-  IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
+KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
+                         IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
 {
-  PLIST_ENTRY current;
-  KIRQL oldIrql;
-  PKDEVICE_QUEUE_ENTRY entry;
-  
-  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+    KIRQL OldIrql;
+    BOOLEAN OldState;
+    
+    DPRINT("KeRemoveEntryDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
+    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
   
-  KeAcquireSpinLock(&DeviceQueue->Lock, &oldIrql);
-  
-  current = DeviceQueue->DeviceListHead.Flink;
-  while (current != &DeviceQueue->DeviceListHead)
-  {
-    entry = CONTAINING_RECORD(current, KDEVICE_QUEUE_ENTRY, DeviceListEntry);
-    if (DeviceQueueEntry == entry)
-    {
-       RemoveEntryList(current);
-       KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
-       /* entry was in the queue (but not anymore) */
-       return TRUE;
+    /* Acquire the Lock */
+    KeAcquireSpinLock(&DeviceQueue->Lock, &OldIrql);
+    
+    /* Check/Set Old State */
+    if ((OldState = DeviceQueueEntry->Inserted)) {
+    
+        /* Remove it */
+        DeviceQueueEntry->Inserted = FALSE;
+        RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
     }
-    current = current->Flink;
-  }
-  
-  KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
   
-  /* entry wasn't in the queue */
-  return FALSE;
+    /* Unlock and return old state */
+    KeReleaseSpinLock(&DeviceQueue->Lock, OldIrql);
+    return OldState;
 }
index 40b352f..dbfd3b5 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Microkernel thread support
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 #define NDEBUG
 #include <internal/debug.h>
 
+#define THREAD_ALERT_INCREMENT 2
+
+extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
+
+/*
+ * PURPOSE: List of threads associated with each priority level
+ */
+LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
+static ULONG PriorityListMask = 0;
+ULONG IdleProcessorMask = 0;
+extern BOOLEAN DoneInitYet;
+extern PETHREAD PspReaperList;
+
 /* FUNCTIONS *****************************************************************/
 
+STATIC 
 VOID
-KiServiceCheck (VOID)
+KiRequestReschedule(CCHAR Processor)
+{
+    PKPCR Pcr;
+
+    Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE);
+    Pcr->Prcb->QuantumEnd = TRUE;
+    KiIpiSendRequest(1 << Processor, IPI_REQUEST_DPC);
+}
+
+STATIC 
+VOID
+KiInsertIntoThreadList(KPRIORITY Priority, 
+                       PKTHREAD Thread)
+{
+    ASSERT(THREAD_STATE_READY == Thread->State);
+    ASSERT(Thread->Priority == Priority);
+    
+    if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) {
+        
+        DPRINT1("Invalid thread priority (%d)\n", Priority);
+        KEBUGCHECK(0);
+    }
+    
+    InsertTailList(&PriorityListHead[Priority], &Thread->QueueListEntry);
+    PriorityListMask |= (1 << Priority);
+}
+
+STATIC
+VOID 
+KiRemoveFromThreadList(PKTHREAD Thread)
+{
+    ASSERT(THREAD_STATE_READY == Thread->State);
+    RemoveEntryList(&Thread->QueueListEntry);
+    if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) {
+        
+        PriorityListMask &= ~(1 << Thread->Priority);
+    }
+}
+
+STATIC
+PKTHREAD 
+KiScanThreadList(KPRIORITY Priority, 
+                 KAFFINITY Affinity)
+{
+    PLIST_ENTRY current_entry;
+    PKTHREAD current;
+    ULONG Mask;
+
+    Mask = (1 << Priority);
+    
+    if (PriorityListMask & Mask) {
+        
+        current_entry = PriorityListHead[Priority].Flink;
+        
+        while (current_entry != &PriorityListHead[Priority]) {
+           
+            current = CONTAINING_RECORD(current_entry, KTHREAD, QueueListEntry);
+            
+            if (current->State != THREAD_STATE_READY) {
+                
+                DPRINT1("%d/%d\n", &current, current->State);
+            }
+            
+            ASSERT(current->State == THREAD_STATE_READY);
+            
+            if (current->Affinity & Affinity) {
+                
+                KiRemoveFromThreadList(current);
+                return(current);
+            }
+            
+            current_entry = current_entry->Flink;
+        }
+    }
+    
+    return(NULL);
+}
+
+VOID 
+STDCALL
+KiDispatchThreadNoLock(ULONG NewThreadStatus)
+{
+    KPRIORITY CurrentPriority;
+    PKTHREAD Candidate;
+    ULONG Affinity;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+
+    DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
+            CurrentThread, NewThreadStatus, CurrentThread->State);
+
+    CurrentThread->State = (UCHAR)NewThreadStatus;
+    
+    if (NewThreadStatus == THREAD_STATE_READY) {
+            
+        KiInsertIntoThreadList(CurrentThread->Priority,
+                               CurrentThread);
+    }
+
+    Affinity = 1 << KeGetCurrentProcessorNumber();
+    
+    for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) {
+        
+        Candidate = KiScanThreadList(CurrentPriority, Affinity);
+        
+        if (Candidate == CurrentThread) {
+
+            Candidate->State = THREAD_STATE_RUNNING;
+            KeReleaseDispatcherDatabaseLockFromDpcLevel();     
+            return;
+        }
+        
+        if (Candidate != NULL) {
+            
+            PKTHREAD OldThread;
+            PKTHREAD IdleThread;
+
+            DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
+
+            Candidate->State = THREAD_STATE_RUNNING;
+
+            OldThread = CurrentThread;
+            CurrentThread = Candidate;
+            IdleThread = KeGetCurrentPrcb()->IdleThread;
+
+            if (OldThread == IdleThread) {
+                
+                IdleProcessorMask &= ~Affinity;
+                
+            } else if (CurrentThread == IdleThread) {
+                
+                IdleProcessorMask |= Affinity;
+            }
+
+            MmUpdatePageDir(PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS));
+
+            /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
+            KiArchContextSwitch(CurrentThread, OldThread);
+            return;
+        }
+    }
+    
+    DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
+    KEBUGCHECK(0);
+}
+
+VOID
+STDCALL
+KiBlockThread(PNTSTATUS Status, 
+              UCHAR Alertable, 
+              ULONG WaitMode,
+              UCHAR WaitReason)
+{
+    PKTHREAD Thread = KeGetCurrentThread();
+    PKWAIT_BLOCK WaitBlock;
+
+    if (Thread->ApcState.KernelApcPending) {
+    
+        DPRINT("Dispatching Thread as ready (APC!)\n");
+        
+        /* Remove Waits */
+        WaitBlock = Thread->WaitBlockList;
+        while (WaitBlock) {
+            RemoveEntryList (&WaitBlock->WaitListEntry);
+            WaitBlock = WaitBlock->NextWaitBlock;
+        }
+        Thread->WaitBlockList = NULL;
+        
+        /* Dispatch it and return status */
+        KiDispatchThreadNoLock (THREAD_STATE_READY);
+        if (Status != NULL) *Status = STATUS_KERNEL_APC;
+
+    } else {
+
+        /* Set the Thread Data as Requested */
+        DPRINT("Dispatching Thread as blocked\n");
+        Thread->Alertable = Alertable;
+        Thread->WaitMode = (UCHAR)WaitMode;
+        Thread->WaitReason = WaitReason;
+        
+        /* Dispatch it and return status */
+        KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
+        if (Status != NULL) *Status = Thread->WaitStatus;
+    }
+    
+    DPRINT("Releasing Dispatcher Lock\n");
+    KfLowerIrql(Thread->WaitIrql);
+}
+
+VOID 
+STDCALL
+KiDispatchThread(ULONG NewThreadStatus)
+{
+    KIRQL OldIrql;
+
+    if (!DoneInitYet || KeGetCurrentPrcb()->IdleThread == NULL) {
+        return;
+    }
+    
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    KiDispatchThreadNoLock(NewThreadStatus);
+    KeLowerIrql(OldIrql);
+}
+
+VOID
+STDCALL
+KiUnblockThread(PKTHREAD Thread, 
+                PNTSTATUS WaitStatus, 
+                KPRIORITY Increment)
+{
+    if (THREAD_STATE_TERMINATED_1 == Thread->State ||
+        THREAD_STATE_TERMINATED_2 == Thread->State) {
+
+        DPRINT("Can't unblock thread 0x%x because it's terminating\n",
+               Thread);
+    
+    } else if (THREAD_STATE_READY == Thread->State ||
+               THREAD_STATE_RUNNING == Thread->State) {
+        
+        DPRINT("Can't unblock thread 0x%x because it's %s\n",
+               Thread, (Thread->State == THREAD_STATE_READY ? "ready" : "running"));
+    
+    } else {
+        
+        ULONG Processor;
+        KAFFINITY Affinity;
+
+        /* FIXME: This propably isn't the right way to do it... */
+        /* No it's not... i'll fix it later-- Alex */
+        if (Thread->Priority < LOW_REALTIME_PRIORITY &&
+            Thread->BasePriority < LOW_REALTIME_PRIORITY - 2) {
+          
+            if (!Thread->PriorityDecrement && !Thread->DisableBoost) {
+                
+                Thread->Priority = Thread->BasePriority + Increment;
+                Thread->PriorityDecrement = Increment;
+            }
+            
+        } else {
+            
+            Thread->Quantum = Thread->ApcState.Process->ThreadQuantum;
+        }
+     
+        if (WaitStatus != NULL) {
+            
+            Thread->WaitStatus = *WaitStatus;
+        }
+        
+        Thread->State = THREAD_STATE_READY;
+        KiInsertIntoThreadList(Thread->Priority, Thread);
+        Processor = KeGetCurrentProcessorNumber();
+        Affinity = Thread->Affinity;
+        
+        if (!(IdleProcessorMask & (1 << Processor) & Affinity) &&
+             (IdleProcessorMask & ~(1 << Processor) & Affinity)) {
+            
+            ULONG i;
+            
+            for (i = 0; i < KeNumberProcessors - 1; i++) {
+            
+                Processor++;
+                
+                if (Processor >= KeNumberProcessors) {
+                    
+                    Processor = 0;
+                }
+                
+                if (IdleProcessorMask & (1 << Processor) & Affinity) {
+#if 0          
+                    /* FIXME:
+                     *   Reschedule the threads on an other processor 
+                     */
+                    KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                    KiRequestReschedule(Processor);
+                    KeAcquireDispatcherDatabaseLockAtDpcLevel();
+#endif
+                    break;
+                }
+            }
+        } 
+    }
+}
+
+VOID 
+STDCALL
+KiSuspendThreadKernelRoutine(PKAPC Apc,
+                             PKNORMAL_ROUTINE* NormalRoutine,
+                             PVOID* NormalContext,
+                             PVOID* SystemArgument1,
+                             PVOID* SystemArguemnt2)
+{
+}
+
+VOID 
+STDCALL
+KiSuspendThreadNormalRoutine(PVOID NormalContext,
+                             PVOID SystemArgument1,
+                             PVOID SystemArgument2)
+{
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    
+    /* Non-alertable kernel-mode suspended wait */
+    DPRINT("Waiting...\n");
+    KeWaitForSingleObject(&CurrentThread->SuspendSemaphore,
+                          Suspended,
+                          KernelMode,
+                          FALSE,
+                          NULL);
+    DPRINT("Done Waiting\n");
+}
+
+VOID
+STDCALL
+KeRundownThread(VOID)
+{
+    KIRQL OldIrql;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PLIST_ENTRY CurrentEntry;
+    PKMUTANT Mutant;
+    
+    DPRINT("KeRundownThread: %x\n", Thread);
+
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    while (!IsListEmpty(&Thread->MutantListHead)) {
+    
+        /* Get the Mutant */
+       CurrentEntry = RemoveHeadList(&Thread->MutantListHead);
+        Mutant = CONTAINING_RECORD(CurrentEntry, KMUTANT, MutantListEntry);
+        ASSERT(Mutant->ApcDisable == 0);
+    
+        /* Uncondtionally abandon it */
+        DPRINT("Abandonning the Mutant\n");
+        Mutant->Header.SignalState = 1;
+        Mutant->Abandoned = TRUE;
+        Mutant->OwnerThread = NULL;
+        RemoveEntryList(&Mutant->MutantListEntry);
+        
+        /* Check if the Wait List isn't empty */
+        DPRINT("Checking whether to wake the Mutant\n");
+        if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
+            
+            /* Wake the Mutant */
+            DPRINT("Waking the Mutant\n");
+            KiWaitTest(&Mutant->Header, MUTANT_INCREMENT);
+        }
+    }
+   
+    /* Release the Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+}
+
+ULONG
+STDCALL
+KeResumeThread(PKTHREAD Thread)
 {
-  PETHREAD Thread;
+    ULONG PreviousCount;
+    KIRQL OldIrql;
+    
+    DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
 
-  Thread = PsGetCurrentThread();
+    /* Lock the Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
 
-  if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow)
-    {
-      PsInitWin32Thread (Thread);
+    /* Save the Old Count */
+    PreviousCount = Thread->SuspendCount;
 
-      Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow;
+    /* Check if it existed */
+    if (PreviousCount) {
+        
+        Thread->SuspendCount--;
+        
+        /* Decrease the current Suspend Count and Check Freeze Count */
+        if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) {
+            
+            /* Signal the Suspend Semaphore */
+            Thread->SuspendSemaphore.Header.SignalState++;
+            KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
+        }
     }
+            
+    /* Release Lock and return the Old State */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return PreviousCount;
+}
+
+BOOLEAN
+STDCALL
+KiInsertQueueApc(PKAPC Apc,
+                 KPRIORITY PriorityBoost);
+                 
+NTSTATUS
+STDCALL
+KeSuspendThread(PKTHREAD Thread)
+{
+    ULONG PreviousCount;
+    KIRQL OldIrql;
+
+    DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
+    
+    /* Lock the Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Save the Old Count */
+    PreviousCount = Thread->SuspendCount;
+    
+    /* Increment it */
+    Thread->SuspendCount++;
+    
+    /* Check if we should suspend it */
+    if (!PreviousCount && !Thread->FreezeCount) {
+    
+        /* Insert the APC */
+        if (!KiInsertQueueApc(&Thread->SuspendApc, IO_NO_INCREMENT)) {
+            
+            /* Unsignal the Semaphore, the APC already got inserted */
+            Thread->SuspendSemaphore.Header.SignalState--;
+        }
+    }
+    
+    /* Release Lock and return the Old State */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return PreviousCount;
+}
+
+ULONG
+STDCALL
+KeForceResumeThread(IN PKTHREAD Thread)
+{
+    KIRQL OldIrql;
+    ULONG PreviousCount;
+    
+    /* Lock the Dispatcher Database and the APC Queue */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Save the old Suspend Count */
+    PreviousCount = Thread->SuspendCount + Thread->FreezeCount;  
+    
+    /* If the thread is suspended, wake it up!!! */
+    if (PreviousCount) {
+            
+        /* Unwait it completely */
+        Thread->SuspendCount = 0;
+        Thread->FreezeCount = 0;
+            
+        /* Signal and satisfy */
+        Thread->SuspendSemaphore.Header.SignalState++;
+        KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
+    }
+    
+    /* Release Lock and return the Old State */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return PreviousCount;
+}
+
+ULONG
+STDCALL
+KeAlertResumeThread(IN PKTHREAD Thread)
+{
+    ULONG PreviousCount;
+    KIRQL OldIrql;
+
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+   
+    /* Lock the Dispatcher Database and the APC Queue */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    KiAcquireSpinLock(&Thread->ApcQueueLock);
+
+    /* Return if Thread is already alerted. */
+    if (Thread->Alerted[KernelMode] == FALSE) {
+       
+        /* If it's Blocked, unblock if it we should */
+        if (Thread->State == THREAD_STATE_BLOCKED &&  Thread->Alertable) {
+            
+            DPRINT("Aborting Wait\n");
+            KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
+       
+        } else {
+           
+            /* If not, simply Alert it */
+            Thread->Alerted[KernelMode] = TRUE;
+        }
+    }
+    
+    /* Save the old Suspend Count */
+    PreviousCount = Thread->SuspendCount;    
+    
+    /* If the thread is suspended, decrease one of the suspend counts */
+    if (PreviousCount) {
+            
+        /* Decrease count. If we are now zero, unwait it completely */
+        if (--Thread->SuspendCount) {
+            
+            /* Signal and satisfy */
+            Thread->SuspendSemaphore.Header.SignalState++;
+            KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
+        }
+    }
+
+    /* Release Locks and return the Old State */
+    KiReleaseSpinLock(&Thread->ApcQueueLock);
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return PreviousCount;
+}
+
+BOOLEAN
+STDCALL
+KeAlertThread(PKTHREAD Thread, 
+              KPROCESSOR_MODE AlertMode)
+{
+    KIRQL OldIrql;
+    BOOLEAN PreviousState;
+
+    /* Acquire the Dispatcher Database Lock */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+   
+    /* Save the Previous State */
+    PreviousState = Thread->Alerted[AlertMode];
+      
+    /* Return if Thread is already alerted. */
+    if (PreviousState == FALSE) {
+       
+        /* If it's Blocked, unblock if it we should */
+        if (Thread->State == THREAD_STATE_BLOCKED && 
+            (AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
+            Thread->Alertable) {
+            
+            DPRINT("Aborting Wait\n");
+            KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
+       
+        } else {
+           
+            /* If not, simply Alert it */
+            Thread->Alerted[AlertMode] = TRUE;
+        }
+    }
+    
+    /* Release the Dispatcher Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    /* Return the old state */
+    return PreviousState;
 }
 
 /*
@@ -36,28 +580,232 @@ KiServiceCheck (VOID)
  */
 VOID
 STDCALL
-KeCapturePersistentThreadState(
-       IN PVOID        CurrentThread,
-       IN ULONG        Setting1,
-       IN ULONG        Setting2,
-       IN ULONG        Setting3,
-       IN ULONG        Setting4,
-       IN ULONG        Setting5,
-       IN PVOID        ThreadState
-)
+KeCapturePersistentThreadState(IN PVOID CurrentThread,
+                               IN ULONG Setting1,
+                               IN ULONG Setting2,
+                               IN ULONG Setting3,
+                               IN ULONG Setting4,
+                               IN ULONG Setting5,
+                               IN PVOID ThreadState)
 {
-       UNIMPLEMENTED;
+    UNIMPLEMENTED;
 }
 
+/*
+ * FUNCTION: Initialize the microkernel state of the thread
+ */
 VOID
-KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
-               PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
+STDCALL
+KeInitializeThread(PKPROCESS Process, 
+                   PKTHREAD Thread, 
+                   BOOLEAN First)
 {
-  ASSERT(SwapEntry == 0);
-  if (Page != 0)
-    {
-      MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
+    PVOID KernelStack;
+    NTSTATUS Status;
+    extern unsigned int init_stack_top;
+    extern unsigned int init_stack;
+    PMEMORY_AREA StackArea;
+    ULONG i;
+    PHYSICAL_ADDRESS BoundaryAddressMultiple;
+  
+    /* Initialize the Boundary Address */
+    BoundaryAddressMultiple.QuadPart = 0;
+  
+    /* Initalize the Dispatcher Header */
+    KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
+                                 ThreadObject,
+                                 sizeof(KTHREAD),
+                                 FALSE);
+    InitializeListHead(&Thread->MutantListHead);
+    
+    /* If this is isn't the first thread, allocate the Kernel Stack */
+    if (!First) {
+        
+        PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
+        KernelStack = NULL;
+      
+        MmLockAddressSpace(MmGetKernelAddressSpace());
+        Status = MmCreateMemoryArea(NULL,
+                                    MmGetKernelAddressSpace(),
+                                    MEMORY_AREA_KERNEL_STACK,
+                                    &KernelStack,
+                                    MM_STACK_SIZE,
+                                    0,
+                                    &StackArea,
+                                    FALSE,
+                                    FALSE,
+                                    BoundaryAddressMultiple);
+        MmUnlockAddressSpace(MmGetKernelAddressSpace());
+      
+        /* Check for Success */
+        if (!NT_SUCCESS(Status)) {
+            
+            DPRINT1("Failed to create thread stack\n");
+            KEBUGCHECK(0);
+        }
+        
+        /* Mark the Stack */
+        for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++) {
+
+            Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
+            
+            /* Check for success */
+            if (!NT_SUCCESS(Status)) {
+                
+                KEBUGCHECK(0);
+            }
+        }
+        
+        /* Create a Virtual Mapping for it */
+        Status = MmCreateVirtualMapping(NULL,
+                                        KernelStack,
+                                        PAGE_READWRITE,
+                                        Page,
+                                        MM_STACK_SIZE / PAGE_SIZE);
+        
+        /* Check for success */
+        if (!NT_SUCCESS(Status)) {
+            
+            KEBUGCHECK(0);
+        }
+        
+        /* Set the Kernel Stack */
+        Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE;
+        Thread->StackBase    = (PCHAR)KernelStack + MM_STACK_SIZE;
+        Thread->StackLimit   = (ULONG_PTR)KernelStack;
+        Thread->KernelStack  = (PCHAR)KernelStack + MM_STACK_SIZE;
+        
+    } else {
+        
+        /* Use the Initial Stack */
+        Thread->InitialStack = (PCHAR)init_stack_top;
+        Thread->StackBase = (PCHAR)init_stack_top;
+        Thread->StackLimit = (ULONG_PTR)init_stack;
+        Thread->KernelStack = (PCHAR)init_stack_top;
     }
+
+    /* 
+     * Establish the pde's for the new stack and the thread structure within the 
+     * address space of the new process. They are accessed while taskswitching or
+     * while handling page faults. At this point it isn't possible to call the 
+     * page fault handler for the missing pde's. 
+     */
+    MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
+    MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
+
+    /* Set the Thread to initalized */
+    Thread->State = THREAD_STATE_INITIALIZED;
+    
+    /* The Native API function will initialize the TEB field later */
+    Thread->Teb = NULL;
+    
+    /* Initialize stuff to zero */
+    Thread->TlsArray = NULL;
+    Thread->DebugActive = 0;
+    Thread->Alerted[0] = 0;
+    Thread->Alerted[1] = 0;
+    Thread->Iopl = 0;
+    
+    /* Set up FPU/NPX Stuff */
+    Thread->NpxState = NPX_STATE_INVALID;
+    Thread->NpxIrql = 0;
+   
+    /* Setup APC Fields */
+    InitializeListHead(&Thread->ApcState.ApcListHead[0]);
+    InitializeListHead(&Thread->ApcState.ApcListHead[1]);
+    Thread->ApcState.Process = Process;
+    Thread->ApcState.KernelApcInProgress = 0;
+    Thread->ApcState.KernelApcPending = 0;
+    Thread->ApcState.UserApcPending = 0;
+    Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
+    Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
+    Thread->ApcStateIndex = OriginalApcEnvironment;
+    Thread->ApcQueueable = TRUE;
+    RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE));
+    KeInitializeSpinLock(&Thread->ApcQueueLock);
+    
+    /* Setup Wait Fields */
+    Thread->WaitStatus = STATUS_SUCCESS;
+    Thread->WaitIrql = PASSIVE_LEVEL;
+    Thread->WaitMode = 0;
+    Thread->WaitNext = FALSE;
+    Thread->WaitListEntry.Flink = NULL;
+    Thread->WaitListEntry.Blink = NULL;
+    Thread->WaitTime = 0;
+    Thread->WaitBlockList = NULL;
+    RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK) * 4);
+    RtlZeroMemory(&Thread->Timer, sizeof(KTIMER));
+    KeInitializeTimer(&Thread->Timer);
+    
+    /* Setup scheduler Fields */
+    Thread->BasePriority = Process->BasePriority;
+    Thread->DecrementCount = 0;
+    Thread->PriorityDecrement = 0;
+    Thread->Quantum = Process->ThreadQuantum;
+    Thread->Saturation = 0;
+    Thread->Priority = Process->BasePriority; 
+    Thread->UserAffinity = Process->Affinity;
+    Thread->SystemAffinityActive = 0;
+    Thread->Affinity = Process->Affinity;
+    Thread->Preempted = 0;
+    Thread->ProcessReadyQueue = 0;
+    Thread->KernelStackResident = 1;
+    Thread->NextProcessor = 0;
+    Thread->ContextSwitches = 0;
+    
+    /* Setup Queue Fields */
+    Thread->Queue = NULL;
+    Thread->QueueListEntry.Flink = NULL;
+    Thread->QueueListEntry.Blink = NULL;
+
+    /* Setup Misc Fields */
+    Thread->LegoData = 0; 
+    Thread->PowerState = 0;
+    Thread->ServiceTable = KeServiceDescriptorTable;
+    Thread->CallbackStack = NULL;
+    Thread->Win32Thread = NULL;
+    Thread->TrapFrame = NULL;
+    Thread->EnableStackSwap = 0;
+    Thread->LargeStack = 0;
+    Thread->ResourceIndex = 0;
+    Thread->PreviousMode = KernelMode;
+    Thread->KernelTime = 0;
+    Thread->UserTime = 0;
+    Thread->AutoAlignment = Process->AutoAlignment;
+   
+  /* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */
+#if 0
+  Thread->WaitBlock[3].Object = (PVOID)&Thread->Timer;
+  Thread->WaitBlock[3].Thread = Thread;
+  Thread->WaitBlock[3].WaitKey = STATUS_TIMEOUT;
+  Thread->WaitBlock[3].WaitType = WaitAny;
+  Thread->WaitBlock[3].NextWaitBlock = NULL;
+  InsertTailList(&Thread->Timer.Header.WaitListHead,
+                 &Thread->WaitBlock[3].WaitListEntry);
+#endif
+
+    /* Initialize the Suspend APC */  
+    KeInitializeApc(&Thread->SuspendApc,
+                    Thread,
+                    OriginalApcEnvironment,
+                    KiSuspendThreadKernelRoutine,
+                    NULL,
+                    KiSuspendThreadNormalRoutine,
+                    KernelMode,
+                    NULL);
+     
+    /* Initialize the Suspend Semaphore */
+    KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
+    
+    /* Insert the Thread into the Process's Thread List */
+    InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
+  
+    /* Set up the Suspend Counts */
+    Thread->FreezeCount = 0;
+    Thread->SuspendCount = 0;
+    ((PETHREAD)Thread)->ReaperLink = NULL; /* Union. Will also clear termination port */
+   
+    /* Do x86 specific part */
 }
 
 /*
@@ -65,11 +813,9 @@ KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
  */
 KPRIORITY
 STDCALL
-KeQueryPriorityThread (
-    IN PKTHREAD Thread
-    )
+KeQueryPriorityThread (IN PKTHREAD Thread)
 {
-       return Thread->Priority;
+    return Thread->Priority;
 }
 
 /*
@@ -77,19 +823,29 @@ KeQueryPriorityThread (
  */
 ULONG
 STDCALL
-KeQueryRuntimeThread(
-       IN PKTHREAD Thread,
-       OUT PULONG UserTime
-       )
+KeQueryRuntimeThread(IN PKTHREAD Thread,
+                     OUT PULONG UserTime)
 {
-       /* Return the User Time */
-       *UserTime = Thread->UserTime;
-       
-       /* Return the Kernel Time */
-       return Thread->KernelTime;
+    /* Return the User Time */
+    *UserTime = Thread->UserTime;
+    
+    /* Return the Kernel Time */
+    return Thread->KernelTime;
 }
 
-NTSTATUS 
+VOID
+KeFreeStackPage(PVOID Context, 
+                MEMORY_AREA* MemoryArea, 
+                PVOID Address, 
+                PFN_TYPE Page, 
+                SWAPENTRY SwapEntry, 
+                BOOLEAN Dirty)
+{
+    ASSERT(SwapEntry == 0);
+    if (Page) MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
+}
+
+NTSTATUS
 KeReleaseThread(PKTHREAD Thread)
 /*
  * FUNCTION: Releases the resource allocated for a thread by
@@ -123,198 +879,89 @@ KeReleaseThread(PKTHREAD Thread)
  */
 BOOLEAN
 STDCALL
-KeSetKernelStackSwapEnable(
-       IN BOOLEAN Enable
-       )
+KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
 {
-       PKTHREAD Thread;
-       BOOLEAN PreviousState;
-       
-       Thread = KeGetCurrentThread();
-       
-       /* Save Old State */
-       PreviousState = Thread->EnableStackSwap;
-       
-       /* Set New State */
-       Thread->EnableStackSwap = Enable;
+    PKTHREAD Thread = KeGetCurrentThread();
+    BOOLEAN PreviousState;
+    KIRQL OldIrql;
+     /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Save Old State */
+    PreviousState = Thread->EnableStackSwap;
+
+    /* Set New State */
+    Thread->EnableStackSwap = Enable;
 
-       /* Return Old State */
-       return PreviousState;
+    /* No, Release Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+        
+    /* Return Old State */
+    return PreviousState;
 }
 
-VOID
-KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
 /*
- * FUNCTION: Initialize the microkernel state of the thread
+ * @implemented
  */
+VOID
+STDCALL
+KeRevertToUserAffinityThread(VOID)
 {
-  PVOID KernelStack;
-  NTSTATUS Status;
-  extern unsigned int init_stack_top;
-  extern unsigned int init_stack;
-  PMEMORY_AREA StackArea;
-  ULONG i;
-  PHYSICAL_ADDRESS BoundaryAddressMultiple;
-  
-  BoundaryAddressMultiple.QuadPart = 0;
-  
-  KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
-                              InternalThreadType,
-                              sizeof(ETHREAD),
-                              FALSE);
-  InitializeListHead(&Thread->MutantListHead);
-  if (!First)
-    {
-      PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
-      KernelStack = NULL;
-      
-      MmLockAddressSpace(MmGetKernelAddressSpace());
-      Status = MmCreateMemoryArea(NULL,
-                                 MmGetKernelAddressSpace(),
-                                 MEMORY_AREA_KERNEL_STACK,
-                                 &KernelStack,
-                                 MM_STACK_SIZE,
-                                 0,
-                                 &StackArea,
-                                 FALSE,
-                                 FALSE,
-                                 BoundaryAddressMultiple);
-      MmUnlockAddressSpace(MmGetKernelAddressSpace());
-      
-      if (!NT_SUCCESS(Status))
-       {
-         DPRINT1("Failed to create thread stack\n");
-         KEBUGCHECK(0);
-       }
-      for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
-       {
-         Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
-         if (!NT_SUCCESS(Status))
-           {
-             KEBUGCHECK(0);
-           }
-       }
-      Status = MmCreateVirtualMapping(NULL,
-                                     KernelStack,
-                                     PAGE_READWRITE,
-                                     Page,
-                                     MM_STACK_SIZE / PAGE_SIZE);
-      if (!NT_SUCCESS(Status))
-        {
-          KEBUGCHECK(0);
-       }
-      Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE;
-      Thread->StackBase    = (PCHAR)KernelStack + MM_STACK_SIZE;
-      Thread->StackLimit   = (ULONG_PTR)KernelStack;
-      Thread->KernelStack  = (PCHAR)KernelStack + MM_STACK_SIZE;
-    }
-  else
-    {
-      Thread->InitialStack = (PCHAR)init_stack_top;
-      Thread->StackBase = (PCHAR)init_stack_top;
-      Thread->StackLimit = (ULONG_PTR)init_stack;
-      Thread->KernelStack = (PCHAR)init_stack_top;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    KIRQL OldIrql;
+
+    ASSERT(CurrentThread->SystemAffinityActive != FALSE);
+        
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Return to User Affinity */
+    CurrentThread->Affinity = CurrentThread->UserAffinity;
+
+    /* Disable System Affinity */
+    CurrentThread->SystemAffinityActive = FALSE;
+    
+    /* Check if we need to Dispatch a New thread */
+    if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) {
+        
+        /* No, just release */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    } else {
+        
+        /* We need to dispatch a new thread */
+        CurrentThread->WaitIrql = OldIrql;
+        KiDispatchThreadNoLock(THREAD_STATE_READY);
+        KeLowerIrql(OldIrql);
     }
+}
 
-  /* 
-   * Establish the pde's for the new stack and the thread structure within the 
-   * address space of the new process. They are accessed while taskswitching or
-   * while handling page faults. At this point it isn't possible to call the 
-   * page fault handler for the missing pde's. 
-   */
-  
-  MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
-  MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
-
-  /* 
-   * The Native API function will initialize the TEB field later 
-   */
-  Thread->Teb = NULL;
-  Thread->TlsArray = NULL;
-  Thread->DebugActive = 0;
-  Thread->State = THREAD_STATE_INITIALIZED;
-  Thread->Alerted[0] = 0;
-  Thread->Alerted[1] = 0;
-  Thread->Iopl = 0;
-  /*
-   * FIXME: Think how this might work
-   */
-  Thread->NpxState = 0;
-  
-  Thread->Saturation = 0;
-  Thread->Priority = Process->BasePriority; 
-  InitializeListHead(&Thread->ApcState.ApcListHead[0]);
-  InitializeListHead(&Thread->ApcState.ApcListHead[1]);
-  Thread->ApcState.Process = Process;
-  Thread->ApcState.KernelApcInProgress = 0;
-  Thread->ApcState.KernelApcPending = 0;
-  Thread->ApcState.UserApcPending = 0;
-  Thread->ContextSwitches = 0;
-  Thread->WaitStatus = STATUS_SUCCESS;
-  Thread->WaitIrql = PASSIVE_LEVEL;
-  Thread->WaitMode = 0;
-  Thread->WaitNext = FALSE;
-  Thread->WaitBlockList = NULL;
-  Thread->WaitListEntry.Flink = NULL;
-  Thread->WaitListEntry.Blink = NULL;
-  Thread->WaitTime = 0;
-  Thread->BasePriority = Process->BasePriority;
-  Thread->DecrementCount = 0;
-  Thread->PriorityDecrement = 0;
-  Thread->Quantum = Process->ThreadQuantum;
-  memset(Thread->WaitBlock, 0, sizeof(KWAIT_BLOCK)*4);
-  Thread->LegoData = 0; 
-  Thread->UserAffinity = Process->Affinity;
-  Thread->SystemAffinityActive = 0;
-  Thread->PowerState = 0;
-  Thread->NpxIrql = 0;
-  Thread->ServiceTable = KeServiceDescriptorTable;
-  Thread->Queue = NULL;
-  KeInitializeSpinLock(&Thread->ApcQueueLock);
-  memset(&Thread->Timer, 0, sizeof(KTIMER));
-  KeInitializeTimer(&Thread->Timer);
-  Thread->QueueListEntry.Flink = NULL;
-  Thread->QueueListEntry.Blink = NULL;
-  Thread->Affinity = Process->Affinity;
-  Thread->Preempted = 0;
-  Thread->ProcessReadyQueue = 0;
-  Thread->KernelStackResident = 1;
-  Thread->NextProcessor = 0;
-  Thread->CallbackStack = NULL;
-  Thread->Win32Thread = NULL;
-  Thread->TrapFrame = NULL;
-  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
-  Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
-  Thread->EnableStackSwap = 0;
-  Thread->LargeStack = 0;
-  Thread->ResourceIndex = 0;
-  Thread->PreviousMode = KernelMode;
-  Thread->KernelTime = 0;
-  Thread->UserTime = 0;
-  memset(&Thread->SavedApcState, 0, sizeof(KAPC_STATE));
-   
-  Thread->ApcStateIndex = OriginalApcEnvironment;
-  Thread->ApcQueueable = TRUE;
-  Thread->AutoAlignment = Process->AutoAlignment;
-  
-  KeInitializeApc(&Thread->SuspendApc,
-                 Thread,
-                 OriginalApcEnvironment,
-                 PiSuspendThreadKernelRoutine,
-                 PiSuspendThreadRundownRoutine,
-                 PiSuspendThreadNormalRoutine,
-                 KernelMode,
-                 NULL);
-  KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
-  
-  InsertTailList(&Process->ThreadListHead,
-                 &Thread->ThreadListEntry);
-  Thread->FreezeCount = 0;
-  Thread->SuspendCount = 0;
-   
-   /*
-    * Do x86 specific part
-    */
+/*
+ * @implemented
+ */
+CCHAR
+STDCALL
+KeSetIdealProcessorThread(IN PKTHREAD Thread,
+                          IN CCHAR Processor)
+{
+    CCHAR PreviousIdealProcessor;
+    KIRQL OldIrql;
+    
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Save Old Ideal Processor */
+    PreviousIdealProcessor = Thread->IdealProcessor;
+
+    /* Set New Ideal Processor */
+    Thread->IdealProcessor = Processor;
+    
+    /* Release Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);   
+    
+    /* Return Old Ideal Processor */
+    return PreviousIdealProcessor;
 }
 
 /*
@@ -322,145 +969,463 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
  */
 VOID
 STDCALL
-KeRevertToUserAffinityThread(VOID)
+KeSetSystemAffinityThread(IN KAFFINITY Affinity)
 {
-#ifdef CONFIG_SMP
-       PKTHREAD CurrentThread;
-       KIRQL oldIrql;
-
-        oldIrql = KeAcquireDispatcherDatabaseLock();
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    KIRQL OldIrql;
 
-       CurrentThread = KeGetCurrentThread();
+    ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
+        
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
 
-       ASSERT(CurrentThread->SystemAffinityActive != FALSE);
+    /* Set the System Affinity Specified */
+    CurrentThread->Affinity = Affinity;
 
-       /* Return to User Affinity */
-       CurrentThread->Affinity = CurrentThread->UserAffinity;
-       
-       /* Disable System Affinity */
-       CurrentThread->SystemAffinityActive = FALSE;
+    /* Enable System Affinity */
+    CurrentThread->SystemAffinityActive = TRUE;
+    
+    /* Check if we need to Dispatch a New thread */
+    if (Affinity & (1 << KeGetCurrentProcessorNumber())) {
+        
+        /* No, just release */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    } else {
+        
+        /* We need to dispatch a new thread */
+        CurrentThread->WaitIrql = OldIrql;
+        KiDispatchThreadNoLock(THREAD_STATE_READY);
+        KeLowerIrql(OldIrql);
+    }
+}
 
-       if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber()))
-       {
-          KeReleaseDispatcherDatabaseLock(oldIrql);
-       }
-       else
-       {
-          CurrentThread->WaitIrql = oldIrql;
-           PsDispatchThreadNoLock(THREAD_STATE_READY);
-           KeLowerIrql(oldIrql);
-       }
-#endif
+/*
+ * @implemented
+ */
+LONG STDCALL
+KeSetBasePriorityThread (PKTHREAD      Thread,
+                        LONG           Increment)
+/*
+ * Sets thread's base priority relative to the process' base priority
+ * Should only be passed in THREAD_PRIORITY_ constants in pstypes.h
+ */
+{
+   KPRIORITY Priority;
+   if (Increment < -2)
+     {
+       Increment = -2;
+     }
+   else if (Increment > 2)
+     {
+       Increment = 2;
+     }
+   Priority = ((PETHREAD)Thread)->ThreadsProcess->Pcb.BasePriority + Increment;
+   if (Priority < LOW_PRIORITY)
+   {
+     Priority = LOW_PRIORITY;
+   }
+   else if (Priority >= MAXIMUM_PRIORITY)
+     {
+       Thread->BasePriority = HIGH_PRIORITY;
+     }
+   KeSetPriorityThread(Thread, Priority);
+   return 1;
 }
 
 /*
  * @implemented
  */
-CCHAR
+KPRIORITY 
 STDCALL
-KeSetIdealProcessorThread (
-       IN PKTHREAD Thread,
-       IN CCHAR Processor)
+KeSetPriorityThread(PKTHREAD Thread, 
+                    KPRIORITY Priority)
 {
-       CCHAR PreviousIdealProcessor;
+    KPRIORITY OldPriority;
+    KIRQL OldIrql;
+    PKTHREAD CurrentThread;
+    ULONG Mask;
+    int i;
+    PKPCR Pcr;
+
+    if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY) {
+        
+        KEBUGCHECK(0);
+    }
+
+    OldIrql = KeAcquireDispatcherDatabaseLock();
 
-       /* Save Old Ideal Processor */
-       PreviousIdealProcessor = Thread->IdealProcessor;
-       
-       /* Set New Ideal Processor */
-       Thread->IdealProcessor = Processor;
-       
-       /* Return Old Ideal Processor */
-       return PreviousIdealProcessor;
+    OldPriority = Thread->Priority;
+
+    if (OldPriority != Priority) {
+        
+        CurrentThread = KeGetCurrentThread();
+        
+        if (Thread->State == THREAD_STATE_READY) {
+            
+            KiRemoveFromThreadList(Thread);
+            Thread->BasePriority = Thread->Priority = (CHAR)Priority;
+            KiInsertIntoThreadList(Priority, Thread);
+            
+            if (CurrentThread->Priority < Priority) {
+                
+                KiDispatchThreadNoLock(THREAD_STATE_READY);
+                KeLowerIrql(OldIrql);
+                return (OldPriority);
+            }
+        
+        } else if (Thread->State == THREAD_STATE_RUNNING)  {
+            
+            Thread->BasePriority = Thread->Priority = (CHAR)Priority;
+            
+            if (Priority < OldPriority) {
+                
+                /* Check for threads with a higher priority */
+                Mask = ~((1 << (Priority + 1)) - 1);
+                if (PriorityListMask & Mask) {
+                    
+                    if (Thread == CurrentThread) {
+                        
+                        KiDispatchThreadNoLock(THREAD_STATE_READY);
+                        KeLowerIrql(OldIrql);
+                        return (OldPriority);
+                        
+                    } else {
+                        
+                        for (i = 0; i < KeNumberProcessors; i++) {
+                            
+                            Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
+                            
+                            if (Pcr->Prcb->CurrentThread == Thread) {
+
+                                KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                                KiRequestReschedule(i);
+                                KeLowerIrql(OldIrql);
+                                return (OldPriority);
+                            }
+                        }
+                    }
+                }
+            }
+        }  else  {
+            
+            Thread->BasePriority = Thread->Priority = (CHAR)Priority;
+        }
+    }
+    
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return(OldPriority);
 }
 
 /*
  * @implemented
+ *
+ * Sets thread's affinity
  */
-VOID
+NTSTATUS 
 STDCALL
-KeSetSystemAffinityThread(IN KAFFINITY Affinity)
+KeSetAffinityThread(PKTHREAD Thread,
+                    KAFFINITY Affinity)
 {
-#ifdef CONFIG_SMP
-       PKTHREAD CurrentThread;
-       KIRQL oldIrql;
-
-        oldIrql = KeAcquireDispatcherDatabaseLock();
-
-       CurrentThread = KeGetCurrentThread();
-
-       ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
-       
-        /* Set the System Affinity Specified */
-       CurrentThread->Affinity = Affinity;
-       
-       /* Enable System Affinity */
-       CurrentThread->SystemAffinityActive = TRUE;
-
-       if (Affinity & (1 << KeGetCurrentProcessorNumber()))
-       {
-          KeReleaseDispatcherDatabaseLock(oldIrql);
-       }
-       else
-       {
-          CurrentThread->WaitIrql = oldIrql;
-           PsDispatchThreadNoLock(THREAD_STATE_READY);
-           KeLowerIrql(oldIrql);
-       }
-#endif
+    KIRQL OldIrql;
+    ULONG i;
+    PKPCR Pcr;
+    KAFFINITY ProcessorMask;
+
+    DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity);
+
+    ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
+
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    Thread->UserAffinity = Affinity;
+    
+    if (Thread->SystemAffinityActive == FALSE) {
+        
+        Thread->Affinity = Affinity;
+        
+        if (Thread->State == THREAD_STATE_RUNNING) {
+            
+            ProcessorMask = 1 << KeGetCurrentKPCR()->ProcessorNumber;
+            if (Thread == KeGetCurrentThread()) {
+                
+                if (!(Affinity & ProcessorMask)) {
+                    
+                    KiDispatchThreadNoLock(THREAD_STATE_READY);
+                    KeLowerIrql(OldIrql);
+                    return STATUS_SUCCESS;
+                }
+                
+            } else {
+                
+                for (i = 0; i < KeNumberProcessors; i++) {
+                    
+                    Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
+                    if (Pcr->Prcb->CurrentThread == Thread) {
+                        
+                        if (!(Affinity & ProcessorMask)) {
+                            
+                            KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                            KiRequestReschedule(i);
+                            KeLowerIrql(OldIrql);
+                            return STATUS_SUCCESS;
+                        }
+                        
+                        break;
+                    }
+                }
+
+                ASSERT (i < KeNumberProcessors);
+            }
+        }
+    }
+    
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return STATUS_SUCCESS;
 }
 
 /*
  * @implemented
  */
+ /* The Increment Argument seems to be ignored by NT and always 0 when called */
 VOID
 STDCALL
 KeTerminateThread(IN KPRIORITY Increment)
 {
-       /* The Increment Argument seems to be ignored by NT and always 0 when called */
-       
-       /* Call our own internal routine */
-       PsTerminateCurrentThread(0);
+    KIRQL OldIrql;
+    PKTHREAD Thread = KeGetCurrentThread();
+    
+    /* Lock the Dispatcher Database and the APC Queue */
+    DPRINT("Terminating\n");
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Insert into the Reaper List */
+    DPRINT("List: %p\n", PspReaperList);
+    ((PETHREAD)Thread)->ReaperLink = PspReaperList;
+    PspReaperList = (PETHREAD)Thread;
+    DPRINT("List: %p\n", PspReaperList);
+    
+    /* Check if it's active */
+    if (PspReaping == FALSE) {
+        
+        /* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */
+        PspReaping = TRUE;
+        DPRINT("Terminating\n");
+        KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
+                      &PspReaperWorkItem.List,
+                      FALSE);
+    }
+    
+    /* Handle Kernel Queues */
+    if (Thread->Queue) {
+                 
+        DPRINT("Waking Queue\n");
+        RemoveEntryList(&Thread->QueueListEntry);
+        KiWakeQueue(Thread->Queue);
+    }
+    
+    /* Signal the thread */
+    Thread->DispatcherHeader.SignalState = TRUE;
+    if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) {
+        
+        /* Satisfy waits */
+        KiWaitTest((PVOID)Thread, Increment);
+    }
+    
+    /* Find a new Thread */
+    KiDispatchThreadNoLock(THREAD_STATE_TERMINATED_1);
 }
 
+/*
+ * FUNCTION: Tests whether there are any pending APCs for the current thread
+ * and if so the APCs will be delivered on exit from kernel mode
+ */
+BOOLEAN
+STDCALL
+KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
+{
+    KIRQL OldIrql;
+    PKTHREAD Thread = KeGetCurrentThread();
+    BOOLEAN OldState;
+   
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+   
+    /* Lock the Dispatcher Database and the APC Queue */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    KiAcquireSpinLock(&Thread->ApcQueueLock);
+   
+    /* Save the old State */
+    OldState = Thread->Alerted[AlertMode];
+   
+    /* If the Thread is Alerted, Clear it */
+    if (OldState) {
+            
+        Thread->Alerted[AlertMode] = FALSE;
+        
+    } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) {
+        
+        /* If the mode is User and the Queue isn't empty, set Pending */
+        Thread->ApcState.UserApcPending = TRUE;
+    }
+   
+    /* Release Locks and return the Old State */
+    KiReleaseSpinLock(&Thread->ApcQueueLock);
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return OldState;
+}
+
+VOID
+KiServiceCheck (VOID)
+{
+    PKTHREAD Thread = KeGetCurrentThread();
+    
+    /* Check if we need to inialize Win32 for this Thread */
+    if (Thread->ServiceTable != KeServiceDescriptorTableShadow) {
+    
+        /* We do. Initialize it and save the new table */  
+        PsInitWin32Thread((PETHREAD)Thread);
+        Thread->ServiceTable = KeServiceDescriptorTableShadow;
+    }
+}
+
+/* 
+ *
+ * NOT EXPORTED
+ */
+NTSTATUS 
+STDCALL
+NtAlertResumeThread(IN  HANDLE ThreadHandle,
+                    OUT PULONG SuspendCount)
+{
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PETHREAD Thread;
+    NTSTATUS Status;
+    ULONG PreviousState;
+
+    /* Check if parameters are valid */
+    if(PreviousMode != KernelMode) {
+     
+        _SEH_TRY {
+            
+            ProbeForWrite(SuspendCount,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+       
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
+   
+    /* Reference the Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_SUSPEND_RESUME,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+   
+    /* Check for Success */ 
+    if (NT_SUCCESS(Status)) {
+   
+        /* Call the Kernel Function */
+        PreviousState = KeAlertResumeThread(&Thread->Tcb);
+   
+        /* Dereference Object */
+        ObDereferenceObject(Thread);
+        
+        if (SuspendCount) {
+        
+            _SEH_TRY {
+        
+                *SuspendCount = PreviousState;
+            
+            } _SEH_HANDLE {
+            
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
+    }
+    
+    /* Return status */
+    return Status;
+}
+
+/* 
+ * @implemented
+ *
+ * EXPORTED
+ */
+NTSTATUS 
+STDCALL
+NtAlertThread (IN HANDLE ThreadHandle)
+{
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PETHREAD Thread;
+    NTSTATUS Status;
+
+    /* Reference the Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_SUSPEND_RESUME,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+   
+    /* Check for Success */ 
+    if (NT_SUCCESS(Status)) {
+   
+        /* 
+         * Do an alert depending on the processor mode. If some kmode code wants to
+         * enforce a umode alert it should call KeAlertThread() directly. If kmode
+         * code wants to do a kmode alert it's sufficient to call it with Zw or just
+         * use KeAlertThread() directly 
+         */
+        KeAlertThread(&Thread->Tcb, PreviousMode);
+   
+        /* Dereference Object */
+        ObDereferenceObject(Thread);
+    }
+    
+    /* Return status */
+    return Status;
+}
 
 NTSTATUS 
 STDCALL
 NtDelayExecution(IN BOOLEAN Alertable,
                  IN PLARGE_INTEGER DelayInterval)
 {
-   KPROCESSOR_MODE PreviousMode;
-   LARGE_INTEGER SafeInterval;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    LARGE_INTEGER SafeInterval;
+    NTSTATUS Status;
    
-   PreviousMode = ExGetPreviousMode();
-   
-   if(PreviousMode != KernelMode)
-   {
-     NTSTATUS Status = STATUS_SUCCESS;
+    /* Check if parameters are valid */
+    if(PreviousMode != KernelMode) {
      
-     _SEH_TRY
-     {
-       ProbeForRead(DelayInterval,
-                    sizeof(LARGE_INTEGER),
-                    sizeof(ULONG));
-       /* make a copy on the kernel stack and let DelayInterval point to it so
-          we don't need to wrap KeDelayExecutionThread in SEH! */
-       SafeInterval = *DelayInterval;
-       DelayInterval = &SafeInterval;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
+        _SEH_TRY {
+            
+            ProbeForRead(DelayInterval,
+                         sizeof(LARGE_INTEGER),
+                         sizeof(ULONG));
+            
+            /* make a copy on the kernel stack and let DelayInterval point to it so
+               we don't need to wrap KeDelayExecutionThread in SEH! */
+            SafeInterval = *DelayInterval;
+       
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
    }
 
-   return KeDelayExecutionThread(PreviousMode,
-                                 Alertable,
-                                 DelayInterval);
+   /* Call the Kernel Function */
+   Status = KeDelayExecutionThread(PreviousMode,
+                                   Alertable,
+                                   &SafeInterval);
+   
+   /* Return Status */
+   return Status;
 }
index eef694b..0efcd83 100644 (file)
@@ -1,37 +1,24 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c
  * PURPOSE:         Initalizes the kernel
  *
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (cleaned up code, moved Executiv stuff to ex/init.c)
+ *                  David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
-#include "../dbg/kdb.h"
-#include <ntos/bootvid.h>
-#include <napi/core.h>
-
-#ifdef HALDBG
-#include <internal/ntosdbg.h>
-#else
-#if defined(_MSC_VER) && (_MSC_VER <= 1200)
-#define ps
-#else
-#define ps(args...)
-#endif /* HALDBG */
-
-#endif
-
 #define NDEBUG
 #include <internal/debug.h>
 
 /* GLOBALS *******************************************************************/
 
 #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
+
+
 ULONG NtMajorVersion = 4;
 ULONG NtMinorVersion = 0;
 ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(6, 0);
@@ -58,19 +45,17 @@ EXPORTED ULONG KiDmaIoCoherency = 0; /* RISC Architectures only */
 EXPORTED ULONG InitSafeBootMode = 0; /* KB83764 */
 #endif /* __GNUC__ */
 
-static LOADER_MODULE KeLoaderModules[64];
+LOADER_MODULE KeLoaderModules[64];
 static CHAR KeLoaderModuleStrings[64][256];
 static CHAR KeLoaderCommandLine[256];
-static ADDRESS_RANGE KeMemoryMap[64];
-static ULONG KeMemoryMapRangeCount;
-static ULONG_PTR FirstKrnlPhysAddr;
-static ULONG_PTR LastKrnlPhysAddr;
-static ULONG_PTR LastKernelAddress;
+ADDRESS_RANGE KeMemoryMap[64];
+ULONG KeMemoryMapRangeCount;
+ULONG_PTR FirstKrnlPhysAddr;
+ULONG_PTR LastKrnlPhysAddr;
+ULONG_PTR LastKernelAddress;
 volatile BOOLEAN Initialized = FALSE;
-extern ULONG MmCoreDumpType;
-extern CHAR KiTimerSystemAuditing;
 
-extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+ULONG KeLargestCacheLine = 0x40; /* FIXME: Arch-specific */
 
 /* We allocate 4 pages, but we only use 3. The 4th is to guarantee page alignment */
 ULONG kernel_stack[4096];
@@ -82,793 +67,60 @@ ULONG init_stack_top;
 ULONG trap_stack;
 ULONG trap_stack_top;
 
-/* FUNCTIONS ****************************************************************/
-
-static VOID INIT_FUNCTION
-InitSystemSharedUserPage (PCSZ ParameterLine)
-{
-   UNICODE_STRING ArcDeviceName;
-   UNICODE_STRING ArcName;
-   UNICODE_STRING BootPath;
-   UNICODE_STRING DriveDeviceName;
-   UNICODE_STRING DriveName;
-   WCHAR DriveNameBuffer[20];
-   PCHAR ParamBuffer;
-   PWCHAR ArcNameBuffer;
-   PCHAR p;
-   NTSTATUS Status;
-   ULONG Length;
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   HANDLE Handle;
-   ULONG i;
-   BOOLEAN BootDriveFound;
-
-   /*
-    * NOTE:
-    *   The shared user page has been zeroed-out right after creation.
-    *   There is NO need to do this again.
-    */
-
-   Ki386SetProcessorFeatures();
-
-   SharedUserData->NtProductType = NtProductWinNt;
-   SharedUserData->ProductTypeIsValid = TRUE;
-   SharedUserData->NtMajorVersion = 5;
-   SharedUserData->NtMinorVersion = 0;
-
-   BootDriveFound = FALSE;
-
-   /*
-    * Retrieve the current dos system path
-    * (e.g.: C:\reactos) from the given arc path
-    * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
-    * Format: "<arc_name>\<path> [options...]"
-    */
-
-   /* create local parameter line copy */
-   ParamBuffer = ExAllocatePool (PagedPool, 256);
-   strcpy (ParamBuffer, (char *)ParameterLine);
-   DPRINT("%s\n", ParamBuffer);
-
-   /* cut options off */
-   p = strchr (ParamBuffer, ' ');
-   if (p)
-     {
-       *p = 0;
-     }
-   DPRINT("%s\n", ParamBuffer);
-
-   /* extract path */
-   p = strchr (ParamBuffer, '\\');
-   if (p)
-     {
-       DPRINT("Boot path: %s\n", p);
-       RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
-       *p = 0;
-     }
-   else
-     {
-       DPRINT("Boot path: %s\n", "\\");
-       RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
-     }
-   DPRINT("Arc name: %s\n", ParamBuffer);
-   
-   /* Only arc name left - build full arc name */
-   ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-   swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
-   RtlInitUnicodeString (&ArcName, ArcNameBuffer);
-   DPRINT("Arc name: %wZ\n", &ArcName);
-
-   /* free ParamBuffer */
-   ExFreePool (ParamBuffer);
-
-   /* allocate arc device name string */
-   ArcDeviceName.Length = 0;
-   ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
-   ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
-   InitializeObjectAttributes (&ObjectAttributes,
-                              &ArcName,
-                              OBJ_OPENLINK,
-                              NULL,
-                              NULL);
-
-   Status = NtOpenSymbolicLinkObject (&Handle,
-                                     SYMBOLIC_LINK_ALL_ACCESS,
-                                     &ObjectAttributes);
-   RtlFreeUnicodeString (&ArcName);
-   if (!NT_SUCCESS(Status))
-     {
-       RtlFreeUnicodeString (&BootPath);
-       RtlFreeUnicodeString (&ArcDeviceName);
-       CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
-                Status);
-
-       KEBUGCHECK (0x0);
-     }
-
-   Status = NtQuerySymbolicLinkObject (Handle,
-                                      &ArcDeviceName,
-                                      &Length);
-   NtClose (Handle);
-   if (!NT_SUCCESS(Status))
-     {
-       RtlFreeUnicodeString (&BootPath);
-       RtlFreeUnicodeString (&ArcDeviceName);
-       CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
-                Status);
-
-       KEBUGCHECK (0x0);
-     }
-   DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
-
-
-   /* allocate device name string */
-   DriveDeviceName.Length = 0;
-   DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
-   DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
-
-   for (i = 0; i < 26; i++)
-     {
-       swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
-       RtlInitUnicodeString (&DriveName,
-                             DriveNameBuffer);
-
-       InitializeObjectAttributes (&ObjectAttributes,
-                                   &DriveName,
-                                   OBJ_OPENLINK,
-                                   NULL,
-                                   NULL);
-
-       Status = NtOpenSymbolicLinkObject (&Handle,
-                                          SYMBOLIC_LINK_ALL_ACCESS,
-                                          &ObjectAttributes);
-       if (!NT_SUCCESS(Status))
-         {
-            DPRINT("Failed to open link %wZ\n",
-                   &DriveName);
-            continue;
-         }
-
-       Status = NtQuerySymbolicLinkObject (Handle,
-                                           &DriveDeviceName,
-                                           &Length);
-       if (!NT_SUCCESS(Status))
-         {
-            DPRINT("Failed query open link %wZ\n",
-                   &DriveName);
-            continue;
-         }
-       DPRINT("Opened link: %wZ ==> %wZ\n",
-              &DriveName, &DriveDeviceName);
-
-       if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
-         {
-            DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
-            swprintf(SharedUserData->NtSystemRoot,
-                     L"%C:%wZ", 'A' + i, &BootPath);
-            
-            BootDriveFound = TRUE;
-         }
-
-       NtClose (Handle);
-     }
-
-   RtlFreeUnicodeString (&BootPath);
-   RtlFreeUnicodeString (&DriveDeviceName);
-   RtlFreeUnicodeString (&ArcDeviceName);
-
-   if (BootDriveFound == FALSE)
-     {
-       DbgPrint("No system drive found!\n");
-       KEBUGCHECK (NO_BOOT_DEVICE);
-     }
-}
-
-VOID INIT_FUNCTION
-ExpInitializeExecutive(VOID)
-{
-  LARGE_INTEGER Timeout;
-  HANDLE ProcessHandle;
-  HANDLE ThreadHandle;
-  ULONG i;
-  ULONG start;
-  ULONG length;
-  PCHAR name;
-  CHAR str[50];
-  NTSTATUS Status;
-  BOOLEAN SetupBoot;
-  PCHAR p1, p2;
-  ULONG MaxMem;
-  BOOLEAN NoGuiBoot = FALSE;
-  UNICODE_STRING Name;
-  HANDLE InitDoneEventHandle;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-
-  /*
-   * Fail at runtime if someone has changed various structures without
-   * updating the offsets used for the assembler code.
-   */
-  ASSERT(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
-  ASSERT(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
-  ASSERT(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
-  ASSERT(FIELD_OFFSET(KTHREAD, NpxState) == KTHREAD_NPX_STATE);
-  ASSERT(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
-  ASSERT(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
-  ASSERT(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
-  ASSERT(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
-  ASSERT(FIELD_OFFSET(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
-  ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == 
-        KPROCESS_DIRECTORY_TABLE_BASE);
-  ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
-  ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
-  ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
-  ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
-  ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
-  ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
-
-  ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
-  ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
-  ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);  
-  ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
-
-  ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
-  ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
-  ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
-
-  ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
-
-  LdrInit1();
-
-  KeLowerIrql(DISPATCH_LEVEL);
-  
-  NtEarlyInitVdm();
-
-  p1 = (PCHAR)KeLoaderBlock.CommandLine;
-
-  MaxMem = 0;
-  while(*p1 && (p2 = strchr(p1, '/')))
-  {
-     p2++;
-     if (!_strnicmp(p2, "MAXMEM", 6))
-     {
-        p2 += 6;
-        while (isspace(*p2)) p2++;
-       if (*p2 == '=')
-       {
-          p2++;
-          while(isspace(*p2)) p2++;
-          if (isdigit(*p2))
-          {
-             while (isdigit(*p2))
-             {
-                MaxMem = MaxMem * 10 + *p2 - '0';
-                p2++;
-             }
-             break;
-          }
-       }
-     }
-     else if (!_strnicmp(p2, "NOGUIBOOT", 9))
-     {
-       p2 += 9;
-       NoGuiBoot = TRUE;
-     }
-     else if (!_strnicmp(p2, "CRASHDUMP", 9))
-     {
-       p2 += 9;
-       if (*p2 == ':')
-        {
-          p2++;
-          if (!_strnicmp(p2, "FULL", 4))
-            {
-              MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
-            }
-          else
-            {
-              MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
-            }
-        }
-     }
-     p1 = p2;
-  }
-
-  MmInit1(FirstKrnlPhysAddr,
-         LastKrnlPhysAddr,
-         LastKernelAddress,
-         (PADDRESS_RANGE)&KeMemoryMap,
-         KeMemoryMapRangeCount,
-         MaxMem > 8 ? MaxMem : 4096);
-
-  /* Import ANSI code page table */
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-
-      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
-      if (name == NULL)
-       {
-         name = (PCHAR)KeLoaderModules[i].String;
-       }
-      else
-       {
-         name++;
-       }
-
-      if (!_stricmp (name, "ansi.nls"))
-       {
-         RtlpImportAnsiCodePage((PUSHORT)start, length);
-       }
-    }
-
-  /* Import OEM code page table */
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-
-      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
-      if (name == NULL)
-       {
-         name = (PCHAR)KeLoaderModules[i].String;
-       }
-      else
-       {
-         name++;
-       }
-
-      if (!_stricmp (name, "oem.nls"))
-       {
-         RtlpImportOemCodePage((PUSHORT)start, length);
-       }
-    }
-
-  /* Import Unicode casemap table */
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-
-      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
-      if (name == NULL)
-       {
-         name = (PCHAR)KeLoaderModules[i].String;
-       }
-      else
-       {
-         name++;
-       }
-
-      if (!_stricmp (name, "casemap.nls"))
-       {
-         RtlpImportUnicodeCasemap((PUSHORT)start, length);
-       }
-    }
-
-  /* Create initial NLS tables */
-  RtlpCreateInitialNlsTables();
-
-  /*
-   * Initialize the kernel debugger
-   */
-  KdInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  KeInit2();
-  
-#if 0
-  if (KeMemoryMapRangeCount > 0)
-    {
-      DPRINT1("MemoryMap:\n");
-      for (i = 0; i < KeMemoryMapRangeCount; i++)
-        {
-          switch(KeMemoryMap[i].Type)
-            {
-              case 1:
-               strcpy(str, "(usable)");
-               break;
-             case 2:
-               strcpy(str, "(reserved)");
-               break;
-             case 3:
-               strcpy(str, "(ACPI data)");
-               break;
-             case 4:
-               strcpy(str, "(ACPI NVS)");
-               break;
-             default:
-               sprintf(str, "type %lu", KeMemoryMap[i].Type);
-            }
-          DPRINT1("%08x - %08x %s\n", KeMemoryMap[i].BaseAddrLow, KeMemoryMap[i].BaseAddrLow + KeMemoryMap[i].LengthLow, str);
-       }
-    }
-#endif
-
-  KeLowerIrql(PASSIVE_LEVEL);
-
-  if (!SeInit1())
-    KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
-
-  ObInit();
-  ExInit2();
-  MmInit2();
-
-  if (!SeInit2())
-    KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
-
-  KeNumberProcessors = 1;
-
-  PiInitProcessManager();
-
-  if (KdPollBreakIn ())
-    {
-      DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
-    }
-
-  /* Initialize all processors */
-  while (!HalAllProcessorsStarted())
-    {
-      PVOID ProcessorStack;
-
-      KePrepareForApplicationProcessorInit(KeNumberProcessors);
-      PsPrepareForApplicationProcessorInit(KeNumberProcessors);
-
-      /* Allocate a stack for use when booting the processor */
-      ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
-
-      HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
-      KeNumberProcessors++;
-    }
-
-  /*
-   * Initialize various critical subsystems
-   */
-  HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  ExInit3();
-  KdInit1();
-  IoInit();
-  PoInit();
-  CmInitializeRegistry();
-  MmInit3();
-  CcInit();
-  KdInit2();
-  FsRtlpInitFileLockingImplementation();
-
-  /* Report all resources used by hal */
-  HalReportResourceUsage();  
-
-  /*
-   * Clear the screen to blue
-   */
-  HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  /*
-   * Display version number and copyright/warranty message
-   */
-  HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
-                  KERNEL_VERSION_BUILD_STR")\n");
-  HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
-  HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
-                  "Public License, and you\n");
-  HalDisplayString("are welcome to change it and/or distribute copies of it "
-                  "under certain\n"); 
-  HalDisplayString("conditions. There is absolutely no warranty for "
-                  "ReactOS.\n\n");
-
-  if (KeNumberProcessors > 1)
-    {
-      sprintf(str,
-             "Found %d system processors. [%lu MB Memory]\n",
-             KeNumberProcessors,
-             (KeLoaderBlock.MemHigher + 1088)/ 1024);
-    }
-  else
-    {
-      sprintf(str,
-             "Found 1 system processor. [%lu MB Memory]\n",
-             (KeLoaderBlock.MemHigher + 1088)/ 1024);
-    }
-  HalDisplayString(str);
-
-  KdInit3();
+/* Cached modules from the loader block */
+PLOADER_MODULE CachedModules[MaximumCachedModuleType];
 
+/* FUNCTIONS ****************************************************************/
 
-  /* Create the NLS section */
-  RtlpCreateNlsSection();
-
-  /*
-   * Initalize services loaded at boot time
-   */
-  DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
-  for (i=0; i < KeLoaderBlock.ModsCount; i++)
-    {
-      CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
-       KeLoaderModules[i].String,
-       KeLoaderModules[i].ModStart,
-       KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
-    }
-
-  /* Pass 1: import system hive registry chunk */
-  SetupBoot = TRUE;
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-
-      DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String);
-      name = strrchr((PCHAR)KeLoaderModules[i].String, '\\');
-      if (name == NULL)
-       {
-         name = (PCHAR)KeLoaderModules[i].String;
-       }
-      else
-       {
-         name++;
-       }
-
-      if (!_stricmp (name, "system") ||
-         !_stricmp (name, "system.hiv"))
-       {
-         CPRINT("Process system hive registry chunk at %08lx\n", start);
-         SetupBoot = FALSE;
-         CmImportSystemHive((PCHAR)start, length);
-       }
-    }
-
-  /* Pass 2: import hardware hive registry chunk */
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {
-      start = KeLoaderModules[i].ModStart;
-      length = KeLoaderModules[i].ModEnd - start;
-      name = (PCHAR)KeLoaderModules[i].String;
-      if (!_stricmp (name, "hardware") ||
-         !_stricmp (name, "hardware.hiv"))
-       {
-         CPRINT("Process hardware hive registry chunk at %08lx\n", start);
-         CmImportHardwareHive((PCHAR)start, length);
-       }
-    }
-
-  /* Create dummy keys if no hardware hive was found */
-  CmImportHardwareHive (NULL, 0);
-
-  /* Initialize volatile registry settings */
-  if (SetupBoot == FALSE)
-    {
-      CmInit2((PCHAR)KeLoaderBlock.CommandLine);
-    }
-
-  /* Initialize the time zone information from the registry */
-  ExpInitTimeZoneInfo();
-
-  /*
-   * Enter the kernel debugger before starting up the boot drivers
-   */
-#ifdef KDBG
-  KdbEnter();
-#endif /* KDBG */
-
-  IoCreateDriverList();
-
-  IoInit2();
-
-  /* Initialize Callbacks before drivers */
-  ExpInitializeCallbacks();
-
-  /* Start boot logging */
-  IopInitBootLog();
-  p1 = (PCHAR)KeLoaderBlock.CommandLine;
-  while (*p1 && (p2 = strchr(p1, '/')))
-  {
-    p2++;
-    if (!_strnicmp(p2, "BOOTLOG", 7))
-    {
-      p2 += 7;
-      IopStartBootLog();
-    }
-
-    p1 = p2;
-  }
-
-  /*
-   * Load boot start drivers
-   */
-  IopInitializeBootDrivers();
-
-  /* Display the boot screen image if not disabled */
-  if (!NoGuiBoot)
-    {
-      InbvEnableBootDriver(TRUE);
-    }
-
-  /* Create ARC names for boot devices */
-  IoCreateArcNames();
-
-  /* Create the SystemRoot symbolic link */
-  CPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
-  DPRINT1("MmSystemRangeStart: 0x%x PageDir: 0x%x\n", MmSystemRangeStart, KeLoaderBlock.PageDirectoryStart);
-  Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
-  if (!NT_SUCCESS(Status))
-  {
-    DbgPrint ( "IoCreateSystemRootLink FAILED: (0x%x) - ", Status );
-    DbgPrintErrorMessage ( Status );
-    KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
-  }
-
-#if defined(KDBG) || defined(DBG)
-  KdbInitProfiling2();
-#endif /* KDBG */
-
-  /* On the assumption that we can now access disks start up the debug
-   * logger thread */
-  if ((KdDebuggerEnabled == TRUE) && (KdDebugState & KD_DEBUG_BOOTLOG))
-    {
-      DebugLogInit2();
-    }
-
-  PiInitDefaultLocale();
-
-  /*
-   * Load services for devices found by PnP manager
-   */
-  IopInitializePnpServices(IopRootDeviceNode, FALSE);
-
-  /*
-   * Load system start drivers
-   */
-  IopInitializeSystemDrivers();
-
-  IoDestroyDriverList();
-
-  /* Stop boot logging */
-  IopStopBootLog();
-
-  /*
-   * Assign drive letters
-   */
-  IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
-                       NULL,
-                       NULL,
-                       NULL);
-
-  /*
-   * Initialize shared user page:
-   *  - set dos system path, dos device map, etc.
-   */
-  InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
-
-  /* Create 'ReactOSInitDone' event */
-  RtlInitUnicodeString(&Name, L"\\ReactOSInitDone");
-  InitializeObjectAttributes(&ObjectAttributes,
-    &Name,
-    0,
-    NULL,
-    NULL);
-  Status = ZwCreateEvent(&InitDoneEventHandle,
-    EVENT_ALL_ACCESS,
-    &ObjectAttributes,
-    SynchronizationEvent,
-    FALSE);             /* Not signalled */
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
-      InitDoneEventHandle = INVALID_HANDLE_VALUE;
-    }
-
-  /*
-   *  Launch initial process
-   */
-  Status = LdrLoadInitialProcess(&ProcessHandle,
-                                &ThreadHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
-    }
-
-  if (InitDoneEventHandle != INVALID_HANDLE_VALUE)
-    {
-      HANDLE Handles[2]; /* Init event, Initial process */
-
-      Handles[0] = InitDoneEventHandle;
-      Handles[1] = ProcessHandle;
-
-      /* Wait for the system to be initialized */
-      Timeout.QuadPart = (LONGLONG)-1200000000;  /* 120 second timeout */
-      Status = ZwWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
-        Handles,
-        WaitAny,
-        FALSE,    /* Non-alertable */
-        &Timeout);
-      if (!NT_SUCCESS(Status))
-        {
-          DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
-        }
-      else if (Status == STATUS_TIMEOUT)
-        {
-          DPRINT1("WARNING: System not initialized after 120 seconds.\n");
-        }
-      else if (Status == STATUS_WAIT_0 + 1)
-        {
-          /*
-           * Crash the system if the initial process was terminated.
-           */
-          KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
-        }
-
-      if (!NoGuiBoot)
-        {
-          InbvEnableBootDriver(FALSE);
-        }
-
-      ZwSetEvent(InitDoneEventHandle, NULL);
-
-      ZwClose(InitDoneEventHandle);
-    }
-  else
-    {
-      /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
-      if (!NoGuiBoot)
-        {
-          InbvEnableBootDriver(FALSE);
-        }
-
-      /*
-       * Crash the system if the initial process terminates within 5 seconds.
-       */
-      Timeout.QuadPart = (LONGLONG)-50000000;  /* 5 second timeout */
-      Status = ZwWaitForSingleObject(ProcessHandle,
-                                FALSE,
-                                &Timeout);
-      if (Status != STATUS_TIMEOUT)
-        {
-          KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
-        }
-    }
 /*
- * Tell ke/timer.c it's okay to run.
+ * @implemented
  */
-
-  KiTimerSystemAuditing = 1;
-
-  ZwClose(ThreadHandle);
-  ZwClose(ProcessHandle);
+ULONG
+STDCALL
+KeGetRecommendedSharedDataAlignment(VOID)
+{
+    return KeLargestCacheLine;
 }
 
-VOID __attribute((noinline))
+VOID
+__attribute((noinline))
 KiSystemStartup(BOOLEAN BootProcessor)
 {
-  DPRINT1("KiSystemStartup(%d)\n", BootProcessor);
-  if (BootProcessor)
-  {
-  }
-  else
-  {
-     KeApplicationProcessorInit();
-  }
-
-  HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  if (BootProcessor)
-  {
-     ExpInitializeExecutive();
-     MiFreeInitMemory();
-     /* Never returns */
-     PsTerminateSystemThread(STATUS_SUCCESS);
-  }
-  else
-  {
-     /* Do application processor initialization */
-     PsApplicationProcessorInit();
-     KeLowerIrql(PASSIVE_LEVEL);
-     PsIdleThreadMain(NULL);
-  }
-  KEBUGCHECK(0);
-  for(;;);
+    DPRINT("KiSystemStartup(%d)\n", BootProcessor);
+    
+    /* Initialize the Application Processor */
+    if (!BootProcessor) KeApplicationProcessorInit();
+    
+    /* Initialize the Processor with HAL */
+    HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+    /* Load the Kernel if this is the Boot CPU, else inialize the App CPU only */
+    if (BootProcessor) {
+        
+        /* Initialize the Kernel Executive */
+        ExpInitializeExecutive();
+        
+        /* Free Initial Memory */
+        MiFreeInitMemory();
+        
+        /* Never returns */
+        PspExitThread(STATUS_SUCCESS);
+        
+    } else {
+        
+        /* Do application processor initialization */
+        PsApplicationProcessorInit();
+        
+        /* Lower IRQL and go to Idle Thread */
+        KeLowerIrql(PASSIVE_LEVEL);
+        PsIdleThreadMain(NULL);
+    }
+    
+    /* Bug Check and loop forever if anything failed */
+    KEBUGCHECK(0);
+    for(;;);
 }
 
-VOID INIT_FUNCTION
-_main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
 /*
  * FUNCTION: Called by the boot loader to start the kernel
  * ARGUMENTS:
@@ -877,173 +129,158 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
  * NOTE: The boot parameters are stored in low memory which will become
  * invalid after the memory managment is initialized so we make a local copy.
  */
+VOID 
+INIT_FUNCTION
+_main(ULONG MultiBootMagic, 
+      PLOADER_PARAMETER_BLOCK _LoaderBlock)
 {
-  ULONG i;
-  ULONG size;
-  ULONG HalBase;
-  ULONG DriverBase;
-  ULONG DriverSize;
-
-  /* Set up the Stacks */
-  trap_stack = PAGE_ROUND_UP(&double_trap_stack);
-  trap_stack_top = trap_stack + 3 * PAGE_SIZE;
-  init_stack = PAGE_ROUND_UP(&kernel_stack);
-  init_stack_top = init_stack + 3 * PAGE_SIZE;
+    ULONG i;
+    ULONG size;
+    ULONG HalBase;
+    ULONG DriverBase;
+    ULONG DriverSize;
+    PIMAGE_NT_HEADERS NtHeader;
+    PIMAGE_OPTIONAL_HEADER OptHead;
+    CHAR* s;
+
+    /* Set up the Stacks (Initial Kernel Stack and Double Trap Stack)*/
+    trap_stack = PAGE_ROUND_UP(&double_trap_stack);
+    trap_stack_top = trap_stack + 3 * PAGE_SIZE;
+    init_stack = PAGE_ROUND_UP(&kernel_stack);
+    init_stack_top = init_stack + 3 * PAGE_SIZE;
             
-  /*
-   * Copy the parameters to a local buffer because lowmem will go away
-   */
-  memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
-  memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
-        sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
-  KeLoaderBlock.ModsCount++;
-  KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
-
-  /* Save the Base Address */
-  MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
+    /* Copy the Loader Block Data locally since Low-Memory will be wiped */
+    memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+    memcpy(&KeLoaderModules[1], 
+           (PVOID)KeLoaderBlock.ModsAddr,
+           sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
+    KeLoaderBlock.ModsCount++;
+    KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
+
+    /* Save the Base Address */
+    MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
   
-  /*
-   * Convert a path specification in the grub format to one understood by the
-   * rest of the kernel.
-   */
-  if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
-    {
-      ULONG DiskNumber = 0, PartNumber = 0;
-      PCH p;
-      CHAR Temp[256];
-      PCH options;
-      PCH s1;
-
-      if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
-         ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
-       {
-         DiskNumber = ((PCHAR)_LoaderBlock->CommandLine)[3] - '0';
-         PartNumber = ((PCHAR)_LoaderBlock->CommandLine)[5] - '0';
-       }
-      strcpy(Temp, &((PCHAR)_LoaderBlock->CommandLine)[7]);
-      if ((options = strchr(Temp, ' ')) != NULL)
-       {
-         *options = 0;
-         options++;
-       }
-      else
-       {
-         options = "";
-       }
-      if ((s1 = strrchr(Temp, '/')) != NULL)
-       {
-         *s1 = 0;
-         if ((s1 = strrchr(Temp, '/')) != NULL)
-           {
-             *s1 = 0;
-           }
-       }
-      sprintf(KeLoaderCommandLine, 
-             "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s",
-             DiskNumber, PartNumber + 1, Temp, options);
-
-      p = KeLoaderCommandLine;
-      while (*p != 0 && *p != ' ')
-       {
-         if ((*p) == '/')
-           {
-             (*p) = '\\';
-           }
-         p++;
-       }
-      DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
-    }
-  else
-    {
-      strcpy(KeLoaderCommandLine, (PCHAR)_LoaderBlock->CommandLine);
-    }
-  KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
+    /* Set the Command Line */
+    strcpy(KeLoaderCommandLine, (PCHAR)_LoaderBlock->CommandLine);
+    KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
   
-  strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
-  KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
-  KeLoaderModules[0].ModStart = KERNEL_BASE;
-  /* Take this value from the PE... */
-    PIMAGE_NT_HEADERS      NtHeader = RtlImageNtHeader((PVOID)KeLoaderModules[0].ModStart);
-    PIMAGE_OPTIONAL_HEADER OptHead  = &NtHeader->OptionalHeader;
+    /* Write the first Module (the Kernel) */
+    strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
+    KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
+    KeLoaderModules[0].ModStart = KERNEL_BASE;
+    
+    /* Read PE Data */
+    NtHeader = RtlImageNtHeader((PVOID)KeLoaderModules[0].ModStart);
+    OptHead = &NtHeader->OptionalHeader;
+    
+    /* Set Kernel Ending */
     KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart + PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
-  for (i = 1; i < KeLoaderBlock.ModsCount; i++)
-    {      
-      CHAR* s;
-      if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0)
-       {
-         strcpy(KeLoaderModuleStrings[i], s + 1);
-       }
-      else
-       {
-         strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
-       }
-      KeLoaderModules[i].ModStart -= 0x200000;
-      KeLoaderModules[i].ModStart += KERNEL_BASE;
-      KeLoaderModules[i].ModEnd -= 0x200000;
-      KeLoaderModules[i].ModEnd += KERNEL_BASE;
-      KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
+    
+    /* Create a block for each module */
+    for (i = 1; i < KeLoaderBlock.ModsCount; i++) {      
+        
+        /* Check if we have to copy the path or not */
+        if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) {
+            
+            strcpy(KeLoaderModuleStrings[i], s + 1);
+            
+        } else {
+            
+            strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
+        }
+    
+        /* Substract the base Address in Physical Memory */    
+        KeLoaderModules[i].ModStart -= 0x200000;
+        
+        /* Add the Kernel Base Address in Virtual Memory */
+        KeLoaderModules[i].ModStart += KERNEL_BASE;
+        
+        /* Substract the base Address in Physical Memory */    
+        KeLoaderModules[i].ModEnd -= 0x200000;
+        
+        /* Add the Kernel Base Address in Virtual Memory */
+        KeLoaderModules[i].ModEnd += KERNEL_BASE;
+        
+        /* Select the proper String */
+        KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
     }
 
-  LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
-
-  /* Low level architecture specific initialization */
-  KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
-
-  HalBase = KeLoaderModules[1].ModStart;
-  DriverBase = LastKernelAddress;
-  LdrHalBase = (ULONG_PTR)DriverBase;
-
-  LdrInitModuleManagement();
-
-  /*
-   * Process hal.dll
-   */
-  LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)KERNEL_BASE, &DriverSize);
-
-  LastKernelAddress += PAGE_ROUND_UP(DriverSize);
-
-  /*
-   * Process ntoskrnl.exe
-   */
-  LdrSafePEProcessModule((PVOID)KERNEL_BASE, (PVOID)KERNEL_BASE, (PVOID)DriverBase, &DriverSize);
-
-  /* Now our imports from HAL are fixed. This is the first */
-  /* time in the boot process that we can use HAL          */
-
-  FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KERNEL_BASE + 0x200000;
-  LastKrnlPhysAddr = LastKernelAddress - KERNEL_BASE + 0x200000;
-
-  KeMemoryMapRangeCount = 0;
-  if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
-    {
-      /* We have a memory map from the nice BIOS */
-      size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
-      i = 0;
-      while (i < KeLoaderBlock.MmapLength)
-        {
-          memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
-            (PVOID)(KeLoaderBlock.MmapAddr + i),
-                 sizeof(ADDRESS_RANGE));
-          KeMemoryMapRangeCount++;
-          i += size;
+    /* Choose last module address as the final kernel address */
+    LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
+
+    /* Low level architecture specific initialization */
+    KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
+    
+    /* Select the HAL Base */
+    HalBase = KeLoaderModules[1].ModStart;
+    
+    /* Choose Driver Base */
+    DriverBase = LastKernelAddress;
+    LdrHalBase = (ULONG_PTR)DriverBase;
+    
+    /* Initialize Module Management */
+    LdrInitModuleManagement();
+    
+    /* Load HAL.DLL with the PE Loader */
+    LdrSafePEProcessModule((PVOID)HalBase, 
+                            (PVOID)DriverBase, 
+                            (PVOID)KERNEL_BASE, 
+                            &DriverSize);
+    
+    /* Increase the last kernel address with the size of HAL */
+    LastKernelAddress += PAGE_ROUND_UP(DriverSize);
+
+    /* Load the Kernel with the PE Loader */
+    LdrSafePEProcessModule((PVOID)KERNEL_BASE, 
+                           (PVOID)KERNEL_BASE, 
+                           (PVOID)DriverBase,
+                           &DriverSize);
+
+    /* Now select the final beginning and ending Kernel Addresses */
+    FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KERNEL_BASE + 0x200000;
+    LastKrnlPhysAddr = LastKernelAddress - KERNEL_BASE + 0x200000;
+
+    KeMemoryMapRangeCount = 0;
+    if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO) {
+        
+        /* We have a memory map from the nice BIOS */
+        size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
+        i = 0;
+      
+        /* Map it until we run out of size */
+        while (i < KeLoaderBlock.MmapLength) {
+            
+            /* Copy into the Kernel Memory Map */
+            memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
+                    (PVOID)(KeLoaderBlock.MmapAddr + i),
+                    sizeof(ADDRESS_RANGE));
+            
+            /* Increase Memory Map Count */
+            KeMemoryMapRangeCount++;
+          
+            /* Increase Size */
+            i += size;
         }
-      KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
-      KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
-    }
-  else
-    {
-      KeLoaderBlock.MmapLength = 0;
-      KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+        
+        /* Save data */
+        KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
+        KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+        
+    } else {
+        
+        /* Nothing from BIOS */
+        KeLoaderBlock.MmapLength = 0;
+        KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
     }
-
-  KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-  HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
-  DPRINT1("_main (%x, %x)\n", MultiBootMagic, _LoaderBlock);
-
-
-  KiSystemStartup(1);
+    
+    /* Initialize the Debugger */
+    KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize HAL */
+    HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+    /* Do general System Startup */
+    KiSystemStartup(1);
 }
 
 /* EOF */
-
index 3532781..2ff0507 100644 (file)
@@ -1,16 +1,20 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/mutex.c
- * PURPOSE:         Implements mutex
+ * PURPOSE:         Implements Mutexes and Mutants (that silly davec...)
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     
+ *                  Alex Ionescu (alex@relsoft.net) - Reorganized/commented some of the code.
+ *                                                    Simplified some functions, fixed some return values and
+ *                                                    corrected some minor bugs, added debug output.
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#define NDEBUG
 #include <internal/debug.h>
 
 /* FUNCTIONS *****************************************************************/
 /*
  * @implemented
  */
-VOID STDCALL
-KeInitializeMutex(IN PKMUTEX Mutex,
-                 IN ULONG Level)
+VOID 
+STDCALL
+KeInitializeMutant(IN PKMUTANT Mutant,
+                   IN BOOLEAN InitialOwner)
 {
-  KeInitializeDispatcherHeader(&Mutex->Header,
-                              InternalMutexType,
-                              sizeof(KMUTEX) / sizeof(ULONG),
-                              1);
-  Mutex->MutantListEntry.Flink = NULL;
-  Mutex->MutantListEntry.Blink = NULL;
-  Mutex->OwnerThread = NULL;
-  Mutex->Abandoned = FALSE;
-  Mutex->ApcDisable = 1;
+    ULONG Signaled = TRUE;
+    PKTHREAD CurrentThread = NULL;
+    KIRQL OldIrql;
+    
+    DPRINT("KeInitializeMutant: %x\n", Mutant);
+    
+    /* Check if we have an initial owner */
+    if (InitialOwner == TRUE) {
+    
+        /* In this case, the object is not signaled */
+        Signaled = FALSE;
+        
+        /* We also need to associate a thread */
+        CurrentThread = KeGetCurrentThread();
+        
+        /* We're about to touch the Thread, so lock the Dispatcher */
+        OldIrql = KeAcquireDispatcherDatabaseLock();
+        
+        /* And insert it into its list */
+        InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry);
+        
+        /* Release Dispatcher Lock */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        DPRINT("Mutant with Initial Owner\n");
+    
+    } else {
+        
+        /* In this case, we don't have an owner yet */
+        Mutant->OwnerThread = NULL;
+    }
+    
+    /* Now we set up the Dispatcher Header */
+    KeInitializeDispatcherHeader(&Mutant->Header,
+                                 MutantObject,
+                                 sizeof(KMUTANT) / sizeof(ULONG),
+                                 Signaled);
+
+    /* Initialize the default data */
+    Mutant->OwnerThread = CurrentThread;
+    Mutant->Abandoned = FALSE;
+    Mutant->ApcDisable = 0;
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KeReadStateMutex(IN PKMUTEX Mutex)
+VOID 
+STDCALL
+KeInitializeMutex(IN PKMUTEX Mutex,
+                  IN ULONG Level)
 {
-  return(Mutex->Header.SignalState);
+    DPRINT("KeInitializeMutex: %x\n", Mutex);
+        
+        
+    /* Set up the Dispatcher Header */
+    KeInitializeDispatcherHeader(&Mutex->Header,
+                                 MutantObject,
+                                 sizeof(KMUTEX) / sizeof(ULONG),
+                                 1);
+  
+    /* Initialize the default data */
+    Mutex->OwnerThread = NULL;
+    Mutex->Abandoned = FALSE;
+    Mutex->ApcDisable = 1;
+    InitializeListHead(&Mutex->Header.WaitListHead);
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KeReleaseMutex(IN PKMUTEX Mutex,
-              IN BOOLEAN Wait)
+LONG 
+STDCALL
+KeReadStateMutant(IN PKMUTANT Mutant)
 {
-  KIRQL OldIrql;
-
-  OldIrql = KeAcquireDispatcherDatabaseLock();
-  if (Mutex->OwnerThread != KeGetCurrentThread())
-    {
-      DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
-      KEBUGCHECK(THREAD_NOT_MUTEX_OWNER);
-    }
-  Mutex->Header.SignalState++;
-  ASSERT(Mutex->Header.SignalState <= 1);
-  if (Mutex->Header.SignalState == 1)
-    {
-      Mutex->OwnerThread = NULL;
-      if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
-       RemoveEntryList(&Mutex->MutantListEntry);
-      KiDispatcherObjectWake(&Mutex->Header, IO_NO_INCREMENT);
-    }
-
-  if (Wait == FALSE)
-    {
-      KeReleaseDispatcherDatabaseLock(OldIrql);
-    }
-  else
-    {
-      KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = TRUE;
-      Thread->WaitIrql = OldIrql;
-    }
-
-  return(0);
+    /* Return the Signal State */
+    return(Mutant->Header.SignalState);
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
-KeWaitForMutexObject(IN PKMUTEX Mutex,
-                    IN KWAIT_REASON WaitReason,
-                    IN KPROCESSOR_MODE WaitMode,
-                    IN BOOLEAN Alertable,
-                    IN PLARGE_INTEGER Timeout)
+LONG
+STDCALL
+KeReadStateMutex(IN PKMUTEX Mutex)
 {
-  return(KeWaitForSingleObject(Mutex,WaitReason,WaitMode,Alertable,Timeout));
+    /* Return the Signal State */
+    return(Mutex->Header.SignalState);
 }
 
-
 /*
  * @implemented
  */
-VOID STDCALL
-KeInitializeMutant(IN PKMUTANT Mutant,
-                  IN BOOLEAN InitialOwner)
+LONG 
+STDCALL
+KeReleaseMutant(IN PKMUTANT Mutant,
+                IN KPRIORITY Increment,
+                IN BOOLEAN Abandon,
+                IN BOOLEAN Wait)
 {
-  if (InitialOwner == TRUE)
-    {
-      KeInitializeDispatcherHeader(&Mutant->Header,
-                                  InternalMutexType,
-                                  sizeof(KMUTANT) / sizeof(ULONG),
-                                  0);
-      InsertTailList(&KeGetCurrentThread()->MutantListHead,
-                    &Mutant->MutantListEntry);
-      Mutant->OwnerThread = KeGetCurrentThread();
+    KIRQL OldIrql;
+    LONG PreviousState;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    
+    DPRINT("KeReleaseMutant: %x\n", Mutant);
+
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Save the Previous State */
+    PreviousState = Mutant->Header.SignalState;
+    
+    /* Check if it is to be abandonned */
+    if (Abandon == FALSE) {
+
+        /* Make sure that the Owner Thread is the current Thread */
+        if (Mutant->OwnerThread != CurrentThread) {
+            
+            KeReleaseDispatcherDatabaseLock(OldIrql);
+            
+            DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
+            ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
+        }
+
+        /* If the thread owns it, then increase the signal state */
+        Mutant->Header.SignalState++;
+    
+    } else  {
+        
+        /* It's going to be abandonned */
+        DPRINT("Abandonning the Mutant\n");
+        Mutant->Header.SignalState = 1;
+        Mutant->Abandoned = TRUE;
     }
-  else
-    {
-      KeInitializeDispatcherHeader(&Mutant->Header,
-                                  InternalMutexType,
-                                  sizeof(KMUTANT) / sizeof(ULONG),
-                                  1);
-      Mutant->MutantListEntry.Flink = NULL;
-      Mutant->MutantListEntry.Blink = NULL;
-      Mutant->OwnerThread = NULL;
+    
+    /* Check if the signal state is only single */
+    if (Mutant->Header.SignalState == 1) {
+        
+        /* Check if it's below 0 now */
+        if (PreviousState <= 0) {
+        
+            /* Remove the mutant from the list */
+            DPRINT("Removing Mutant\n");
+            RemoveEntryList(&Mutant->MutantListEntry);
+            
+            /* Reenable APCs */
+            DPRINT("Re-enabling APCs\n");
+            CurrentThread->KernelApcDisable += Mutant->ApcDisable;
+            
+            /* Force an Interrupt if Apcs are pending */
+            if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) {
+            
+                /* Make sure they aren't disabled though */
+                if (!CurrentThread->KernelApcDisable) {
+                
+                    /* Request the Interrupt */
+                    DPRINT("Requesting APC Interupt\n");
+                    HalRequestSoftwareInterrupt(APC_LEVEL);
+                }
+            }
+        }
+        
+        /* Remove the Owning Thread and wake it */
+        Mutant->OwnerThread = NULL;
+        
+        /* Check if the Wait List isn't empty */
+        DPRINT("Checking whether to wake the Mutant\n");
+        if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
+            
+            /* Wake the Mutant */
+            DPRINT("Waking the Mutant\n");
+            KiWaitTest(&Mutant->Header, Increment);
+        }
     }
-  Mutant->Abandoned = FALSE;
-  Mutant->ApcDisable = 0;
+
+    /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
+    if (Wait == FALSE) {
+        
+        /* Release the Lock */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    } else {
+        
+        /* Set a wait */
+        CurrentThread->WaitNext = TRUE;
+        CurrentThread->WaitIrql = OldIrql;
+    }
+
+    /* Return the previous state */
+    return PreviousState;
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KeReadStateMutant(IN PKMUTANT Mutant)
+LONG 
+STDCALL
+KeReleaseMutex(IN PKMUTEX Mutex,
+               IN BOOLEAN Wait)
 {
-  return(Mutant->Header.SignalState);
+
+    /* There's no difference at this level between the two */
+    return KeReleaseMutant(Mutex, IO_NO_INCREMENT, FALSE, Wait);
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KeReleaseMutant(IN PKMUTANT Mutant,
-               IN KPRIORITY Increment,
-               IN BOOLEAN Abandon,
-               IN BOOLEAN Wait)
+NTSTATUS 
+STDCALL
+KeWaitForMutexObject(IN PKMUTEX Mutex,
+                     IN KWAIT_REASON WaitReason,
+                     IN KPROCESSOR_MODE WaitMode,
+                     IN BOOLEAN Alertable,
+                     IN PLARGE_INTEGER Timeout)
 {
-  KIRQL OldIrql;
-
-  OldIrql = KeAcquireDispatcherDatabaseLock();
-  if (Abandon == FALSE)
-    {
-      if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
-       {
-         DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutant->OwnerThread %p CurrentThread %p\n",
-                  Mutant->OwnerThread,
-                  KeGetCurrentThread());
-         KEBUGCHECK(THREAD_NOT_MUTEX_OWNER);
-       }
-      Mutant->Header.SignalState++;
-      ASSERT(Mutant->Header.SignalState <= 1);
-    }
-  else
-    {
-      if (Mutant->OwnerThread != NULL)
-       {
-         Mutant->Header.SignalState = 1;
-         Mutant->Abandoned = TRUE;
-       }
-    }
-
-  if (Mutant->Header.SignalState == 1)
-    {
-      Mutant->OwnerThread = NULL;
-      if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
-       RemoveEntryList(&Mutant->MutantListEntry);
-      KiDispatcherObjectWake(&Mutant->Header, Increment);
-    }
-
-  if (Wait == FALSE)
-    {
-      KeReleaseDispatcherDatabaseLock(OldIrql);
-    }
-  else
-    {
-      KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = TRUE;
-      Thread->WaitIrql = OldIrql;
-    }
-
-  return(0);
+    /* This is a simple macro. Export the function here though */
+    return KeWaitForSingleObject(Mutex,
+                                 WaitReason,
+                                 WaitMode,
+                                 Alertable,
+                                 Timeout);
 }
 
 /* EOF */
index 15486ec..49b1aca 100644 (file)
@@ -1,34 +1,85 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/process.c
- * PURPOSE:         Microkernel process management
+ * PURPOSE:         Attaching/Detaching and System Call Tables
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable)
+ *                  Gregor Anich (Bugfixes to Attach Functions)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#include <ntdll/napi.h>
 #define NDEBUG
 #include <internal/debug.h>
 
+/* GLOBALS   *****************************************************************/
+
+SSDT_ENTRY
+__declspec(dllexport)
+KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
+    { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
+    { NULL,     NULL,   0,   NULL   },
+    { NULL,     NULL,   0,   NULL   },
+    { NULL,     NULL,   0,   NULL   }
+};
+
+SSDT_ENTRY 
+KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
+    { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
+    { NULL,     NULL,   0,   NULL   },
+    { NULL,     NULL,   0,   NULL   },
+    { NULL,     NULL,   0,   NULL   }
+};
+
 /* FUNCTIONS *****************************************************************/
 
 static inline void
 UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
 {
-   /* The stack and the thread structure of the current process may be 
-      located in a page which is not present in the page directory of 
-      the process we're attaching to. That would lead to a page fault 
-      when this function returns. However, since the processor can't 
-      call the page fault handler 'cause it can't push EIP on the stack, 
-      this will show up as a stack fault which will crash the entire system.
-      To prevent this, make sure the page directory of the process we're
-      attaching to is up-to-date. */
-   MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
-   MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
+    /* 
+     * The stack and the thread structure of the current process may be 
+     * located in a page which is not present in the page directory of 
+     * the process we're attaching to. That would lead to a page fault 
+     * when this function returns. However, since the processor can't 
+     * call the page fault handler 'cause it can't push EIP on the stack, 
+     * this will show up as a stack fault which will crash the entire system.
+     * To prevent this, make sure the page directory of the process we're
+     * attaching to is up-to-date. 
+     */
+    MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
+    MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
+}
+
+ULONG
+STDCALL
+KeSetProcess(PKPROCESS Process, 
+             KPRIORITY Increment)
+{
+    KIRQL OldIrql;
+    ULONG OldState;
+    
+    /* Lock Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Get Old State */
+    OldState = Process->DispatcherHeader.SignalState;
+    
+    /* Signal the Process */
+    Process->DispatcherHeader.SignalState = TRUE;
+    if ((OldState == 0) && IsListEmpty(&Process->DispatcherHeader.WaitListHead) != TRUE) {
+        
+        /* Satisfy waits */
+        KiWaitTest((PVOID)Process, Increment);
+    }
+    
+    /* Release Dispatcher Database */    
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    /* Return the previous State */
+    return OldState;           
 }
 
 /*
@@ -38,29 +89,33 @@ VOID
 STDCALL
 KeAttachProcess(PKPROCESS Process)
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread = KeGetCurrentThread();
-       
-       DPRINT("KeAttachProcess: %x\n", Process);
-
-       UpdatePageDirs(Thread, Process);
-
-       /* Lock Dispatcher */
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Crash system if DPC is being executed! */
-       if (KeIsExecutingDpc()) {
-               DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
-               KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
-       }
-       
-       /* Check if the Target Process is already attached */
-       if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
-               DPRINT("Process already Attached. Exitting\n");
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-       } else { 
-               KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
-       }
+    KIRQL OldIrql;
+    PKTHREAD Thread = KeGetCurrentThread();
+
+    DPRINT("KeAttachProcess: %x\n", Process);
+
+    /* Make sure that we are in the right page directory */
+    UpdatePageDirs(Thread, Process);
+
+    /* Lock Dispatcher */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Crash system if DPC is being executed! */
+    if (KeIsExecutingDpc()) {
+        
+        DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
+        KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
+    }
+
+    /* Check if the Target Process is already attached */
+    if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
+        
+        DPRINT("Process already Attached. Exitting\n");
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+    } else { 
+        
+        KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
+    }
 }
 
 VOID
@@ -68,52 +123,54 @@ STDCALL
 KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState)
 {
   
-       DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
+    DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
    
-       /* Increase Stack Count */
-       Process->StackCount++;
-       
-       /* Swap the APC Environment */
-       KiMoveApcState(&Thread->ApcState, SavedApcState);
-       
-       /* Reinitialize Apc State */
-       InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
-       InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
-       Thread->ApcState.Process = Process;
-       Thread->ApcState.KernelApcInProgress = FALSE;
-       Thread->ApcState.KernelApcPending = FALSE;
-       Thread->ApcState.UserApcPending = FALSE;
+    /* Increase Stack Count */
+    Process->StackCount++;
+
+    /* Swap the APC Environment */
+    KiMoveApcState(&Thread->ApcState, SavedApcState);
     
-       /* Update Environment Pointers if needed*/
-       if (SavedApcState == &Thread->SavedApcState) {
-               Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
-               Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
-               Thread->ApcStateIndex = AttachedApcEnvironment;
-       }
-       
-       /* Swap the Processes */
-       KiSwapProcess(Process, SavedApcState->Process);
-       
-       /* Return to old IRQL*/
-       KeReleaseDispatcherDatabaseLock(ApcLock);
-       
-       DPRINT("KiAttachProcess Completed Sucesfully\n");
+    /* Reinitialize Apc State */
+    InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
+    InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
+    Thread->ApcState.Process = Process;
+    Thread->ApcState.KernelApcInProgress = FALSE;
+    Thread->ApcState.KernelApcPending = FALSE;
+    Thread->ApcState.UserApcPending = FALSE;
+    
+    /* Update Environment Pointers if needed*/
+    if (SavedApcState == &Thread->SavedApcState) {
+        
+        Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
+        Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
+        Thread->ApcStateIndex = AttachedApcEnvironment;
+    }
+    
+    /* Swap the Processes */
+    KiSwapProcess(Process, SavedApcState->Process);
+    
+    /* Return to old IRQL*/
+    KeReleaseDispatcherDatabaseLock(ApcLock);
+    
+    DPRINT("KiAttachProcess Completed Sucesfully\n");
 }
 
 VOID
 STDCALL
 KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess) 
 {
-       //PKPCR Pcr = KeGetCurrentKpcr();
-
-       /* Do they have an LDT? */
-       if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
-               /* FIXME : SWitch GDT/IDT */
-       }
-       DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
-       Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
-       
-       /* FIXME: Set IopmOffset in TSS */
+    //PKPCR Pcr = KeGetCurrentKpcr();
+
+    /* Do they have an LDT? */
+    if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
+        
+        /* FIXME : SWitch GDT/IDT */
+    }
+    DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
+    Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
+    
+    /* FIXME: Set IopmOffset in TSS */
 }
 
 /*
@@ -121,11 +178,10 @@ KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
  */
 BOOLEAN
 STDCALL
-KeIsAttachedProcess(
-       VOID
-       )
+KeIsAttachedProcess(VOID)
 {
-       return KeGetCurrentThread()->ApcStateIndex;
+    /* Return the APC State */
+    return KeGetCurrentThread()->ApcStateIndex;
 }
 
 /*
@@ -133,36 +189,41 @@ KeIsAttachedProcess(
  */
 VOID
 STDCALL
-KeStackAttachProcess (
-    IN PKPROCESS Process,
-    OUT PRKAPC_STATE ApcState
-    )
+KeStackAttachProcess(IN PKPROCESS Process,
+                     OUT PRKAPC_STATE ApcState)
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread = KeGetCurrentThread();
-
-       UpdatePageDirs(Thread, Process);
-
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Crash system if DPC is being executed! */
-       if (KeIsExecutingDpc()) {
-               DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
-               KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
-       }
-       
-       /* Check if the Target Process is already attached */
-       if (Thread->ApcState.Process == Process) {
-               ApcState->Process = (PKPROCESS)1;  /* Meaning already attached to the same Process */
-       } else { 
-               /* Check if the Current Thread is already attached and call the Internal Function*/
-               if (Thread->ApcStateIndex != OriginalApcEnvironment) {
-                       KiAttachProcess(Thread, Process, OldIrql, ApcState);
-               } else {
-                       KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
-                       ApcState->Process = NULL; 
-               }
-       }
+    KIRQL OldIrql;
+    PKTHREAD Thread = KeGetCurrentThread();
+
+    /* Make sure that we are in the right page directory */
+    UpdatePageDirs(Thread, Process);
+
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Crash system if DPC is being executed! */
+    if (KeIsExecutingDpc()) {
+        
+        DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
+        KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
+    }
+    
+    /* Check if the Target Process is already attached */
+    if (Thread->ApcState.Process == Process) {
+        
+        ApcState->Process = (PKPROCESS)1;  /* Meaning already attached to the same Process */
+    
+    } else { 
+        
+        /* Check if the Current Thread is already attached and call the Internal Function*/
+        if (Thread->ApcStateIndex != OriginalApcEnvironment) {
+            
+            KiAttachProcess(Thread, Process, OldIrql, ApcState);
+        } else {
+            
+            KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
+            ApcState->Process = NULL; 
+        }
+    }
 }
 
 /*
@@ -171,38 +232,39 @@ KeStackAttachProcess (
 VOID STDCALL
 KeDetachProcess (VOID)
 {
-       PKTHREAD Thread;
-       KIRQL OldIrql;
+    PKTHREAD Thread;
+    KIRQL OldIrql;
    
-       DPRINT("KeDetachProcess()\n");
+    DPRINT("KeDetachProcess()\n");
    
-       /* Get Current Thread and Lock */
-       Thread = KeGetCurrentThread();
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Check if it's attached */
-       DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
-       
-       if (Thread->ApcStateIndex == OriginalApcEnvironment) {
-               DPRINT1("Invalid detach (thread was not attached)\n");
-               KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
-       }
+    /* Get Current Thread and Lock */
+    Thread = KeGetCurrentThread();
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Check if it's attached */
+    DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
+    
+    if (Thread->ApcStateIndex == OriginalApcEnvironment) {
+        
+        DPRINT1("Invalid detach (thread was not attached)\n");
+        KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
+    }
    
-       /* Decrease Stack Count */
-       Thread->ApcState.Process->StackCount--;
-       
-       /* Restore the APC State */
-       KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
-       Thread->SavedApcState.Process = NULL;
-       Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
-       Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
-       Thread->ApcStateIndex = OriginalApcEnvironment;
-       
-       /* Swap Processes */
-       KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
-
-       /* Unlock Dispatcher */
-       KeReleaseDispatcherDatabaseLock(OldIrql);
+    /* Decrease Stack Count */
+    Thread->ApcState.Process->StackCount--;
+    
+    /* Restore the APC State */
+    KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
+    Thread->SavedApcState.Process = NULL;
+    Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
+    Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
+    Thread->ApcStateIndex = OriginalApcEnvironment;
+    
+    /* Swap Processes */
+    KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
+
+    /* Unlock Dispatcher */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
 }
 
 /*
@@ -214,55 +276,56 @@ KeUnstackDetachProcess (
     IN PRKAPC_STATE ApcState
     )
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread;
-
-       /* If the special "We tried to attach to the process already being attached to" flag is there, don't do anything */
-       if (ApcState->Process == (PKPROCESS)1) return;
-       
-       Thread = KeGetCurrentThread();
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
-       if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
-               DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
-               KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
-       }
-       
-       /* Restore the Old APC State if a Process was present */
-       if (ApcState->Process) {
-               KiMoveApcState(ApcState, &Thread->ApcState);
-       } else {
-               /* The ApcState parameter is useless, so use the saved data and reset it */
-               KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
-               Thread->SavedApcState.Process = NULL;
-               Thread->ApcStateIndex = OriginalApcEnvironment;
-               Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
-               Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
-       }
-
-       /* Swap Processes */
-       KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
-
-       /* Return to old IRQL*/
-       KeReleaseDispatcherDatabaseLock(OldIrql);
+    KIRQL OldIrql;
+    PKTHREAD Thread;
+
+    /* 
+     * If the special "We tried to attach to the process already being 
+     * attached to" flag is there, don't do anything 
+     */
+    if (ApcState->Process == (PKPROCESS)1) return;
+    
+    Thread = KeGetCurrentThread();
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
+    if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
+        
+        DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
+        KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
+    }
+    
+    /* Restore the Old APC State if a Process was present */
+    if (ApcState->Process) {
+        
+        KiMoveApcState(ApcState, &Thread->ApcState);
+        
+    } else {
+        
+        /* The ApcState parameter is useless, so use the saved data and reset it */
+        KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
+        Thread->SavedApcState.Process = NULL;
+        Thread->ApcStateIndex = OriginalApcEnvironment;
+        Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
+        Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
+    }
+
+    /* Swap Processes */
+    KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
+
+    /* Return to old IRQL*/
+    KeReleaseDispatcherDatabaseLock(OldIrql);
 }
 
-/* This function should be used by win32k.sys to add its own user32/gdi32 services
- * TableIndex is 0 based
- * ServiceCountTable its not used at the moment
- */
 /*
  * @implemented
  */
 BOOLEAN STDCALL
-KeAddSystemServiceTable (
-       PSSDT   SSDT,
-       PULONG  ServiceCounterTable,
-       ULONG   NumberOfServices,
-       PSSPT   SSPT,
-       ULONG   TableIndex
-       )
+KeAddSystemServiceTable(PSSDT SSDT,
+                        PULONG ServiceCounterTable,
+                        ULONG NumberOfServices,
+                        PSSPT SSPT,
+                        ULONG TableIndex)
 {
     /* check if descriptor table entry is free */
     if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||    
@@ -280,15 +343,37 @@ KeAddSystemServiceTable (
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOLEAN
 STDCALL
-KeRemoveSystemServiceTable(
-    IN PUCHAR Number
-)
+KeRemoveSystemServiceTable(IN ULONG TableIndex)
 {
-       UNIMPLEMENTED;
-       return FALSE;
+    /* Make sure the Index is valid */
+    if (TableIndex > SSDT_MAX_ENTRIES - 1) return FALSE;
+    
+    /* Is there a Normal Descriptor Table? */
+    if (!KeServiceDescriptorTable[TableIndex].SSDT) {
+    
+        /* Not with the index, is there a shadow at least? */
+        if (!KeServiceDescriptorTableShadow[TableIndex].SSDT) return FALSE;
+    }
+    
+    /* Now clear from the Shadow Table. */
+    KeServiceDescriptorTableShadow[TableIndex].SSDT = NULL;
+    KeServiceDescriptorTableShadow[TableIndex].SSPT = NULL;
+    KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = 0;
+    KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = NULL;
+    
+    /* Check if we should clean from the Master one too */
+    if (TableIndex == 1) {
+        
+        KeServiceDescriptorTable[TableIndex].SSDT = NULL;
+        KeServiceDescriptorTable[TableIndex].SSPT = NULL;
+        KeServiceDescriptorTable[TableIndex].NumberOfServices = 0;
+        KeServiceDescriptorTable[TableIndex].ServiceCounterTable = NULL;
+    }
+
+    return TRUE;
 }
 /* EOF */
index 454e15c..cb2279b 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/profile.c
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  */
 
+/* INCLUDES *****************************************************************/
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
-extern LIST_ENTRY ProcessProfileListHashTable[PROFILE_HASH_TABLE_SIZE];
-extern LIST_ENTRY SystemProfileList;
-extern KSPIN_LOCK ProfileListLock;
-extern BOOLEAN ProfileInitDone;
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-KiAddProfileEventToProcess(PLIST_ENTRY ListHead, PVOID Eip)
-     /*
-      * Add a profile event to the profile objects for a particular process
-      * or the system
-      */
-{
-  PKPROFILE current;
-  PLIST_ENTRY current_entry;
-
-  current_entry = ListHead->Flink;
-  while (current_entry != ListHead)
-    {
-      current = CONTAINING_RECORD(current_entry, KPROFILE, ListEntry);
-
-      if (current->Base > Eip)
-       {
-         return;
-       }
+/* GLOBALS *******************************************************************/
 
-      if (current->Base <= Eip && ((char*)current->Base + current->Size) > (char*)Eip &&
-         current->Started)
-       {
-         ULONG Bucket;
+KIRQL KiProfileIrql = PROFILE_LEVEL;
+LIST_ENTRY KiProfileListHead;
+LIST_ENTRY KiProfileSourceListHead;
+KSPIN_LOCK KiProfileLock;
+ULONG KiProfileTimeInterval = 78125; /* Default resolution 7.8ms (sysinternals) */
 
-         Bucket = ((ULONG)((char*)Eip - (char*)current->Base)) >> current->BucketShift;
-
-         if ((Bucket*4) < current->BufferSize)
-           {
-             current->Buffer[Bucket]++;
-           }
-       }
-
-      current_entry = current_entry->Flink;
-    }
-}
+/* FUNCTIONS *****************************************************************/
 
+STDCALL 
 VOID
-KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip)
-     /*
-      * Add a profile event 
-      */
+KeInitializeProfile(PKPROFILE Profile,
+                    PKPROCESS Process,
+                    PVOID ImageBase,
+                    ULONG ImageSize,
+                    ULONG BucketSize,
+                    KPROFILE_SOURCE ProfileSource,
+                    KAFFINITY Affinity)
 {
-  HANDLE Pid;
-  PKPROCESS_PROFILE current;
-  PLIST_ENTRY current_entry;
-  PLIST_ENTRY ListHead;
-
-  if (!ProfileInitDone)
-    {
-      return;
-    }
-
-  Pid = PsGetCurrentProcessId();
-  ListHead = 
-    ProcessProfileListHashTable[(ULONG)Pid % PROFILE_HASH_TABLE_SIZE].Flink;
-
-  KeAcquireSpinLockAtDpcLevel(&ProfileListLock);
-
-  current_entry = ListHead;
-  while (current_entry != ListHead)
-    {
-      current = CONTAINING_RECORD(current_entry, KPROCESS_PROFILE, ListEntry);
-
-      if (current->Pid == Pid)
-       {
-         KiAddProfileEventToProcess(&current->ProfileListHead, (PVOID)Eip);
-         break;
-       }
-
-      current_entry = current_entry->Flink;
-    }
-
-  KiAddProfileEventToProcess(&SystemProfileList, (PVOID)Eip);
-
-  KeReleaseSpinLockFromDpcLevel(&ProfileListLock);
+    /* Initialize the Header */
+    Profile->Type = ProfileObject;
+    Profile->Size = sizeof(KPROFILE);
+    
+    /* Copy all the settings we were given */
+    Profile->Process = Process;
+    Profile->RegionStart = ImageBase;
+    Profile->BucketShift = BucketSize - 2; /* See ntinternals.net -- Alex */
+    Profile->RegionEnd = (PVOID)(ULONG_PTR)ImageBase + ImageSize;
+    Profile->Active = FALSE;
+    Profile->Source = ProfileSource;
+    Profile->Affinity = Affinity;    
 }
 
+STDCALL
 VOID
-KiInsertProfileIntoProcess(PLIST_ENTRY ListHead, PKPROFILE Profile)
-     /*
-      * Insert a profile object into the list for a process or the system
-      */
+KeStartProfile(PKPROFILE Profile,
+               PVOID Buffer)
 {
-  PKPROFILE current;
-  PLIST_ENTRY current_entry;
-
-  current_entry = ListHead;
-  while (current_entry != ListHead)
-    {
-      current = CONTAINING_RECORD(current_entry, KPROFILE, ListEntry);
-
-      if (current->Base > Profile->Base)
-       {
-         Profile->ListEntry.Flink = current_entry;
-         Profile->ListEntry.Blink = current_entry->Blink;
-         current_entry->Blink->Flink = &Profile->ListEntry;
-         current_entry->Blink = &Profile->ListEntry;
-         return;
-       }
-
-      current_entry = current_entry->Flink;
+    KIRQL OldIrql;
+    PKPROFILE_SOURCE_OBJECT SourceBuffer;
+    PKPROFILE_SOURCE_OBJECT Source = NULL;
+    PKPROFILE_SOURCE_OBJECT CurrentSource;
+    BOOLEAN FreeBuffer = TRUE;
+    PKPROCESS ProfileProcess;
+    PLIST_ENTRY ListEntry;
+    
+    /* Allocate a buffer first, before we raise IRQL */
+    SourceBuffer = ExAllocatePoolWithTag(NonPagedPool, 
+                                          sizeof(KPROFILE_SOURCE_OBJECT),
+                                          TAG('P', 'r', 'o', 'f'));
+    RtlZeroMemory(Source, sizeof(KPROFILE_SOURCE_OBJECT));
+    
+    /* Raise to PROFILE_LEVEL */
+    KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
+    KeAcquireSpinLockAtDpcLevel(&KiProfileLock);
+    
+    /* Make sure it's not running */
+    if (!Profile->Active) {
+    
+        /* Set it as active */
+        Profile->Buffer = Buffer;
+        Profile->Active = TRUE;
+        
+        /* Get the process, if any */
+        ProfileProcess = Profile->Process;
+        
+        /* Insert it into the Process List or Global List */
+        if (ProfileProcess) {
+        
+            InsertTailList(&ProfileProcess->ProfileListHead, &Profile->ListEntry);
+            
+        } else {
+        
+            InsertTailList(&KiProfileListHead, &Profile->ListEntry);
+        }
+        
+        /* Check if this type of profile (source) is already running */
+        for (ListEntry = KiProfileSourceListHead.Flink; 
+             ListEntry != &KiProfileSourceListHead; 
+             ListEntry = ListEntry->Flink) {
+                 
+            /* Get the Source Object */
+            CurrentSource = CONTAINING_RECORD(ListEntry, 
+                                              KPROFILE_SOURCE_OBJECT,
+                                              ListEntry);
+            
+            /* Check if it's the same as the one being requested now */
+            if (CurrentSource->Source == Profile->Source) {
+            
+                Source = CurrentSource;
+                break;
+            }
+        }
+        
+        /* See if the loop found something */
+        if (!Source) {
+            
+            /* Nothing found, use our allocated buffer */
+            Source = SourceBuffer;
+            
+            /* Set up the Source Object */
+            Source->Source = Profile->Source;
+            InsertHeadList(&KiProfileSourceListHead, &Source->ListEntry);
+            
+            /* Don't free the pool later on */
+            FreeBuffer = FALSE;
+        }
     }
-  InsertTailList(ListHead, &Profile->ListEntry);
+    
+    /* Lower the IRQL */
+    KeReleaseSpinLockFromDpcLevel(&KiProfileLock);
+    KeLowerIrql(OldIrql);
+    
+    /* FIXME: Tell HAL to Start the Profile Interrupt */
+    //HalStartProfileInterrupt(Profile->Source);
+    
+    /* Free the pool */
+    if (!FreeBuffer) ExFreePool(SourceBuffer);
 }
 
+STDCALL
 VOID
-KiInsertProfile(PKPROFILE Profile)
-     /*
-      * Insert a profile into the relevant data structures
-      */
+KeStopProfile(PKPROFILE Profile)
 {
-  KIRQL oldIrql;
-
-  KeAcquireSpinLock(&ProfileListLock, &oldIrql);
-
-  if (Profile->Process == NULL)
-    {
-      KiInsertProfileIntoProcess(&SystemProfileList, Profile);
-    }
-  else
-    {
-      HANDLE Pid;
-      PKPROCESS_PROFILE current;
-      PLIST_ENTRY current_entry;
-      PLIST_ENTRY ListHead;
-
-      Pid = Profile->Process->UniqueProcessId;
-      ListHead = &ProcessProfileListHashTable[(ULONG_PTR)Pid % PROFILE_HASH_TABLE_SIZE];
-
-      current_entry = ListHead;
-      while(current_entry != ListHead)
-       {
-         current = CONTAINING_RECORD(current_entry, KPROCESS_PROFILE, 
-                                     ListEntry);
-
-         if (current->Pid == Pid)
-           {
-             KiInsertProfileIntoProcess(&current->ProfileListHead, Profile);
-             KeReleaseSpinLock(&ProfileListLock, oldIrql);
-             return;
-           }
-
-         current_entry = current_entry->Flink;
-       }
-
-      current = ExAllocatePool(NonPagedPool, sizeof(KPROCESS_PROFILE));
-
-      current->Pid = Pid;
-      InitializeListHead(&current->ProfileListHead);
-      InsertTailList(ListHead, &current->ListEntry);
-
-      KiInsertProfileIntoProcess(&current->ProfileListHead, Profile);
+    KIRQL OldIrql;
+    PLIST_ENTRY ListEntry;
+    PKPROFILE_SOURCE_OBJECT CurrentSource = NULL;
+    
+    /* Raise to PROFILE_LEVEL and acquire spinlock */
+    KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
+    KeAcquireSpinLockAtDpcLevel(&KiProfileLock);
+    
+    /* Make sure it's running */
+    if (Profile->Active) {
+    
+        /* Remove it from the list and disable */
+        RemoveEntryList(&Profile->ListEntry);
+        Profile->Active = FALSE;
+        
+        /* Find the Source Object */
+        for (ListEntry = KiProfileSourceListHead.Flink; 
+             CurrentSource->Source != Profile->Source; 
+             ListEntry = ListEntry->Flink) {
+                 
+            /* Get the Source Object */
+            CurrentSource = CONTAINING_RECORD(ListEntry, 
+                                              KPROFILE_SOURCE_OBJECT,
+                                              ListEntry);
+        }
+        
+        /* Remove it */
+        RemoveEntryList(&CurrentSource->ListEntry);
     }
-
-  KeReleaseSpinLock(&ProfileListLock, oldIrql);
+    
+    /* Lower IRQL */
+    KeReleaseSpinLockFromDpcLevel(&KiProfileLock);
+    KeLowerIrql(OldIrql);
+    
+    /* Stop Profiling. FIXME: Implement in HAL */
+    //HalStopProfileInterrupt(Profile->Source);
+    
+    /* Free the Source Object */
+    if (CurrentSource) ExFreePool(CurrentSource);
 }
 
-VOID KiRemoveProfile(PKPROFILE Profile)
+STDCALL
+ULONG
+KeQueryIntervalProfile(KPROFILE_SOURCE ProfileSource)
 {
-  KIRQL oldIrql;
-
-  KeAcquireSpinLock(&ProfileListLock, &oldIrql);
-
-  if (Profile->Process == NULL)
-    {
-      RemoveEntryList(&Profile->ListEntry);
-    }
-  else
-    {
-      HANDLE Pid;
-      PLIST_ENTRY ListHead;
-      PKPROCESS_PROFILE current;
-      PLIST_ENTRY current_entry;
-      
-      RemoveEntryList(&Profile->ListEntry);
-
-      Pid = Profile->Process->UniqueProcessId;
-      ListHead = &ProcessProfileListHashTable[(ULONG_PTR)Pid % PROFILE_HASH_TABLE_SIZE];
-
-      current_entry = ListHead;
-      while(current_entry != ListHead)
-       {
-         current = CONTAINING_RECORD(current_entry, KPROCESS_PROFILE, 
-                                     ListEntry);
-
-         if (current->Pid == Pid)
-           {
-             if (IsListEmpty(&current->ProfileListHead))
-               {
-                 RemoveEntryList(&current->ListEntry);
-                 ExFreePool(current);
-               }
-             KeReleaseSpinLock(&ProfileListLock, oldIrql);
-             return;
-           }
-
-         current_entry = current_entry->Flink;
-       }
-      KEBUGCHECK(0);
+    /* Check if this is the timer profile */
+    if (ProfileSource == ProfileTime) {
+    
+        /* Return the good old 100ns sampling interval */
+        return KiProfileTimeInterval;
+    
+    } else {
+    
+        /* Request it from HAL. FIXME: What structure is used? */
+        HalQuerySystemInformation(HalProfileSourceInformation,
+                                  sizeof(NULL),
+                                  NULL,
+                                  NULL);
+        
+        return 0;
     }
-
-  KeReleaseSpinLock(&ProfileListLock, oldIrql);
 }
 
-VOID STDCALL
-KiDeleteProfile(PVOID ObjectBody)
+STDCALL    
+VOID 
+KeSetIntervalProfile(KPROFILE_SOURCE ProfileSource,
+                     ULONG Interval)
 {
-  PKPROFILE Profile;
-
-  Profile = (PKPROFILE)ObjectBody;
-
-  KiRemoveProfile(Profile);
-  if (Profile->Process != NULL)
-    {
-      ObDereferenceObject(Profile->Process);
-      Profile->Process = NULL;
-    }
-
-  if (Profile->BufferMdl->MappedSystemVa != NULL)
-    {       
-      MmUnmapLockedPages(Profile->BufferMdl->MappedSystemVa, 
-                        Profile->BufferMdl);
+    /* Check if this is the timer profile */
+    if (ProfileSource == ProfileTime) {
+    
+        /* Set the good old 100ns sampling interval */
+        KiProfileTimeInterval = Interval;
+    
+    } else {
+    
+        /* Set it with HAL. FIXME: What structure is used? */
+        HalSetSystemInformation(HalProfileSourceInformation,
+                                  sizeof(NULL),
+                                  NULL);
+        
     }
-  MmUnlockPages(Profile->BufferMdl);
-  ExFreePool(Profile->BufferMdl);
-  Profile->BufferMdl = NULL;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 STDCALL
 VOID
-KeProfileInterrupt(
-    PKTRAP_FRAME TrapFrame
-)
+KeProfileInterrupt(PKTRAP_FRAME TrapFrame)
 {
-       UNIMPLEMENTED;
+    /* Called from HAL for Timer Profiling */
+    KeProfileInterruptWithSource(TrapFrame, ProfileTime);
 }
 
-/*
- * @unimplemented
- */
-STDCALL
 VOID
-KeProfileInterruptWithSource(
-       IN PKTRAP_FRAME                 TrapFrame,
-       IN KPROFILE_SOURCE              Source
-)
+STDCALL
+KiParseProfileList(IN PKTRAP_FRAME TrapFrame,
+                   IN KPROFILE_SOURCE Source,
+                   IN PLIST_ENTRY ListHead)
 {
-       UNIMPLEMENTED;
+    PULONG BucketValue;
+    PKPROFILE Profile;
+    PLIST_ENTRY NextEntry;
+    
+    /* Loop the List */
+    for (NextEntry = ListHead->Flink; NextEntry != ListHead; NextEntry = NextEntry->Flink) {
+    
+        /* Get the Current Profile in the List */
+        Profile = CONTAINING_RECORD(NextEntry, KPROFILE, ListEntry);
+        
+        /* Check if the source is good, and if it's within the range */
+        if ((Profile->Source != Source) || 
+            (TrapFrame->Eip < (ULONG_PTR)Profile->RegionStart) || 
+            (TrapFrame->Eip > (ULONG_PTR)Profile->RegionEnd)) {
+            
+            continue;
+        }   
+
+        /* Get the Pointer to the Bucket Value representing this EIP */
+        BucketValue = (PULONG)(((ULONG_PTR)(Profile->Buffer + 
+                               (TrapFrame->Eip - (ULONG_PTR)Profile->RegionStart))
+                                >> Profile->BucketShift) &~ 0x3);
+        
+        /* Increment the value */
+        ++BucketValue;
+    }
 }
 
 /*
- * @unimplemented
+ * @implemented
+ *
+ * Remarks:
+ *         Called from HAL, this function looks up the process
+ *         entries, finds the proper source object, verifies the
+ *         ranges with the trapframe data, and inserts the information
+ *         from the trap frame into the buffer, while using buckets and
+ *         shifting like we specified. -- Alex
  */
 STDCALL
 VOID
-KeSetProfileIrql(
-    IN KIRQL ProfileIrql
-)
+KeProfileInterruptWithSource(IN PKTRAP_FRAME TrapFrame,
+                             IN KPROFILE_SOURCE Source)
 {
-       UNIMPLEMENTED;
+    PKPROCESS Process = KeGetCurrentThread()->ApcState.Process;
+    
+    /* We have to parse 2 lists. Per-Process and System-Wide */
+    KiParseProfileList(TrapFrame, Source, &Process->ProfileListHead);
+    KiParseProfileList(TrapFrame, Source, &KiProfileListHead);
 }
 
-NTSTATUS STDCALL
-NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
-                         OUT PLARGE_INTEGER PerformanceFrequency  OPTIONAL)
+/*
+ * @implemented
+ */
+STDCALL
+VOID
+KeSetProfileIrql(IN KIRQL ProfileIrql)
 {
-  LARGE_INTEGER PerfCounter;
-  LARGE_INTEGER PerfFrequency;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(PerformanceCounter,
-                    sizeof(LARGE_INTEGER),
-                    sizeof(ULONG));
-      if(PerformanceFrequency != NULL)
-      {
-        ProbeForWrite(PerformanceFrequency,
-                      sizeof(LARGE_INTEGER),
-                      sizeof(ULONG));
-      }
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-    
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  PerfCounter = KeQueryPerformanceCounter(&PerfFrequency);
-  
-  _SEH_TRY
-  {
-    *PerformanceCounter = PerfCounter;
-    if(PerformanceFrequency != NULL)
-    {
-      *PerformanceFrequency = PerfFrequency;
-    }
-  }
-  _SEH_HANDLE
-  {
-    Status = _SEH_GetExceptionCode();
-  }
-  _SEH_END;
-
-  return Status;
+    /* Set the IRQL at which Profiling will run */
+    KiProfileIrql = ProfileIrql;
 }
index 9c47870..5f2983d 100644 (file)
@@ -1,11 +1,12 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/queue.c
  * PURPOSE:         Implements kernel queues
  * 
- * PROGRAMMERS:     Eric Kohl (ekohl@rz-online.de)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Gunnar Dalsnes
+ *                  Eric Kohl (ekohl@rz-online.de)
  */
 
 /* INCLUDES *****************************************************************/
 
 /* FUNCTIONS *****************************************************************/
 
-
+LONG STDCALL KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head);
+              
 /*
  * @implemented
  */
-VOID STDCALL
+VOID 
+STDCALL
 KeInitializeQueue(IN PKQUEUE Queue,
-                 IN ULONG Count OPTIONAL)
+                  IN ULONG Count OPTIONAL)
 {
-  KeInitializeDispatcherHeader(&Queue->Header,
-                              InternalQueueType,
-                              sizeof(KQUEUE)/sizeof(ULONG),
-                              0);
-  InitializeListHead(&Queue->EntryListHead);
-  InitializeListHead(&Queue->ThreadListHead);
-  Queue->CurrentCount = 0;
-  Queue->MaximumCount = (Count == 0) ? (ULONG) KeNumberProcessors : Count;
+    DPRINT("KeInitializeQueue %x\n", Queue);
+    
+    /* Initialize the Header */
+    KeInitializeDispatcherHeader(&Queue->Header,
+                                 QueueObject,
+                                 sizeof(KQUEUE)/sizeof(ULONG),
+                                 0);
+    
+    /* Initialize the Lists */
+    InitializeListHead(&Queue->EntryListHead);
+    InitializeListHead(&Queue->ThreadListHead);
+    
+    /* Set the Current and Maximum Count */
+    Queue->CurrentCount = 0;
+    Queue->MaximumCount = (Count == 0) ? (ULONG) KeNumberProcessors : Count;
 }
 
-
 /*
  * @implemented
- *
- * Returns number of entries in the queue
- */
-LONG STDCALL
-KeReadStateQueue(IN PKQUEUE Queue)
-{
-  return(Queue->Header.SignalState);
-}
-
-/*
- * Returns the previous number of entries in the queue
  */
-LONG STDCALL
-KiInsertQueue(
-   IN PKQUEUE Queue,
-   IN PLIST_ENTRY Entry,
-   BOOLEAN Head
-   )
+LONG
+STDCALL
+KeInsertHeadQueue(IN PKQUEUE Queue,
+                  IN PLIST_ENTRY Entry)
 {
-   ULONG InitialState;
-  
-   DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
-   
-   InitialState = Queue->Header.SignalState;
-
-   if (Head)
-   {
-      InsertHeadList(&Queue->EntryListHead, Entry);
-   }
-   else
-   {
-      InsertTailList(&Queue->EntryListHead, Entry);
-   }
-   
-   //inc. num entries in queue
-   Queue->Header.SignalState++;
+    LONG PreviousState;
+    KIRQL OldIrql;
+    
+    DPRINT("KeInsertHeadQueue %x\n", Queue);
+    
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Insert the Queue */
+    PreviousState = KiInsertQueue(Queue, Entry, TRUE);
+    
+    /* Release the Dispatcher Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
    
-   /* Why the KeGetCurrentThread()->Queue != Queue?
-    * KiInsertQueue might be called from an APC for the current thread. 
-    * -Gunnar
-    */
-   if (Queue->CurrentCount < Queue->MaximumCount &&
-       !IsListEmpty(&Queue->Header.WaitListHead) &&
-       KeGetCurrentThread()->Queue != Queue)
-   {
-      KiDispatcherObjectWake(&Queue->Header, IO_NO_INCREMENT);
-   }
-
-   return InitialState;
+    /* Return previous State */
+    return PreviousState;
 }
 
-
-
 /*
  * @implemented
  */
 LONG STDCALL
-KeInsertHeadQueue(IN PKQUEUE Queue,
-                 IN PLIST_ENTRY Entry)
+KeInsertQueue(IN PKQUEUE Queue,
+              IN PLIST_ENTRY Entry)
 {
-   LONG Result;
-   KIRQL OldIrql;
-   
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   Result = KiInsertQueue(Queue,Entry,TRUE);
-   KeReleaseDispatcherDatabaseLock(OldIrql);
+    LONG PreviousState;
+    KIRQL OldIrql;
+    
+    DPRINT("KeInsertQueue %x\n", Queue);
+    
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Insert the Queue */
+    PreviousState = KiInsertQueue(Queue, Entry, FALSE);
+    
+    /* Release the Dispatcher Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
    
-   return Result;
+    /* Return previous State */
+    return PreviousState;
 }
 
-
 /*
  * @implemented
+ *
+ * Returns number of entries in the queue
  */
-LONG STDCALL
-KeInsertQueue(IN PKQUEUE Queue,
-             IN PLIST_ENTRY Entry)
+LONG
+STDCALL
+KeReadStateQueue(IN PKQUEUE Queue)
 {
-   LONG Result;
-   KIRQL OldIrql;
-   
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   Result = KiInsertQueue(Queue,Entry,FALSE);
-   KeReleaseDispatcherDatabaseLock(OldIrql);
-   
-   return Result;
+    /* Returns the Signal State */
+    return(Queue->Header.SignalState);
 }
 
-
 /*
  * @implemented
  */
-PLIST_ENTRY STDCALL
+PLIST_ENTRY 
+STDCALL
 KeRemoveQueue(IN PKQUEUE Queue,
-             IN KPROCESSOR_MODE WaitMode,
-             IN PLARGE_INTEGER Timeout OPTIONAL)
+              IN KPROCESSOR_MODE WaitMode,
+              IN PLARGE_INTEGER Timeout OPTIONAL)
 {
    
-   PLIST_ENTRY ListEntry;
-   NTSTATUS Status;
-   PKTHREAD Thread = KeGetCurrentThread();
-   KIRQL OldIrql;
-
-   OldIrql = KeAcquireDispatcherDatabaseLock ();
-
-   if (Thread->Queue != Queue)
-   {
-      /*
-       * INVESTIGATE: What is the Thread->QueueListEntry used for? It's linked it into the
-       * Queue->ThreadListHead when the thread registers with the queue and unlinked when
-       * the thread registers with a new queue. The Thread->Queue already tells us what
-       * queue the thread is registered with.
-       * -Gunnar
-       */
-
-      //unregister thread from previous queue (if any)
-      if (Thread->Queue)
-      {
-         RemoveEntryList(&Thread->QueueListEntry);
-         Thread->Queue->CurrentCount--;
-         
-         if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount && 
-             !IsListEmpty(&Thread->Queue->EntryListHead))
-         {
-            KiDispatcherObjectWake(&Thread->Queue->Header, 0);
-         }
+    PLIST_ENTRY ListEntry;
+    NTSTATUS Status;
+    PKTHREAD Thread = KeGetCurrentThread();
+    KIRQL OldIrql;
+    PKQUEUE PreviousQueue;
+    PKWAIT_BLOCK WaitBlock;
+    PKWAIT_BLOCK TimerWaitBlock;
+    PKTIMER Timer;
+
+    DPRINT("KeRemoveQueue %x\n", Queue);
+    
+    /* Check if the Lock is already held */
+    if (Thread->WaitNext) {
+    
+        DPRINT("Lock is already held\n");
+    
+    } else {
+        
+        /* Lock the Dispatcher Database */
+        DPRINT("Lock not held, acquiring\n");
+        OldIrql = KeAcquireDispatcherDatabaseLock();
+        Thread->WaitIrql = OldIrql;
+    }
+
+    /* This is needed so that we can set the new queue right here, before additional processing */
+    PreviousQueue = Thread->Queue;
+    Thread->Queue = Queue;
+
+    /* Check if this is a different queue */    
+    if (Queue != PreviousQueue) {
+        
+        /*
+         * INVESTIGATE: What is the Thread->QueueListEntry used for? It's linked it into the
+         * Queue->ThreadListHead when the thread registers with the queue and unlinked when
+         * the thread registers with a new queue. The Thread->Queue already tells us what
+         * queue the thread is registered with.
+         * -Gunnar
+         */
+        DPRINT("Different Queue\n");
+        if (PreviousQueue)  {
+          
+            /* Remove from this list */
+            DPRINT("Removing Old Queue\n");
+            RemoveEntryList(&Thread->QueueListEntry);
+            
+            /* Wake the queue */
+            DPRINT("Activating new thread\n");
+            KiWakeQueue(PreviousQueue);
       }
 
-      // register thread with this queue
-      InsertTailList(&Queue->ThreadListHead, &Thread->QueueListEntry);
-      Thread->Queue = Queue;
-   }
-   else /* if (Thread->Queue == Queue) */
-   {
-      //dec. num running threads
-      Queue->CurrentCount--;
-   }
-   
-   
+        /* Insert in this new Queue */
+        DPRINT("Inserting new Queue!\n");
+        InsertTailList(&Queue->ThreadListHead, &Thread->QueueListEntry);
    
-   
-   while (TRUE)
-   {
-      if (Queue->CurrentCount < Queue->MaximumCount && !IsListEmpty(&Queue->EntryListHead))
-      {
-         ListEntry = RemoveHeadList(&Queue->EntryListHead);
-         //dec. num entries in queue
-         Queue->Header.SignalState--;
-         //inc. num running threads
-         Queue->CurrentCount++;
-         
-         KeReleaseDispatcherDatabaseLock(OldIrql);
-         return ListEntry;
-      }
-      else
-      {
-         //inform KeWaitXxx that we are holding disp. lock
-         Thread->WaitNext = TRUE;
-         Thread->WaitIrql = OldIrql;
-
-         Status = KeWaitForSingleObject(Queue,
-                                        WrQueue,
-                                        WaitMode,
-                                        TRUE, //bAlertable
-                                        Timeout);
-
-         if (Status == STATUS_TIMEOUT || Status == STATUS_USER_APC)
-         {
-            return (PVOID)Status;
-         }
-         
-         OldIrql = KeAcquireDispatcherDatabaseLock ();
-      }
-   }
+    } else {
+      
+        /* Same queue, decrement waiting threads */
+        DPRINT("Same Queue!\n");
+        Queue->CurrentCount--;
+    }
+    
+    /* Loop until the queue is processed */
+    while (TRUE) {
+      
+        /* Get the Entry */
+        ListEntry = Queue->EntryListHead.Flink;
+        
+        /* Check if the counts are valid and if there is still a queued entry */
+        if ((Queue->CurrentCount < Queue->MaximumCount) && 
+             (ListEntry != &Queue->EntryListHead)) {
+          
+            /* Remove the Entry and Save it */
+            DPRINT("Removing Queue Entry. CurrentCount: %d, Maximum Count: %d\n", 
+                    Queue->CurrentCount, Queue->MaximumCount);
+            ListEntry = RemoveHeadList(&Queue->EntryListHead);
+            
+            /* Decrease the number of entries */
+            Queue->Header.SignalState--;
+            
+            /* Increase numbef of running threads */
+            Queue->CurrentCount++;
+            
+            /* Check if the entry is valid. If not, bugcheck */
+            if (!ListEntry->Flink || !ListEntry->Blink) {
+            
+                KEBUGCHECK(INVALID_WORK_QUEUE_ITEM);
+            }
+            
+            /* Remove the Entry */
+            RemoveEntryList(ListEntry);
+            ListEntry->Flink = NULL;
+            
+            /* Nothing to wait on */
+            break;
+            
+        } else {
+                       
+            /* Do the wait */
+            DPRINT("Waiting on Queue Entry. CurrentCount: %d, Maximum Count: %d\n", 
+                    Queue->CurrentCount, Queue->MaximumCount);
+            
+            /* Use the Thread's Wait Block, it's big enough */
+            Thread->WaitBlockList = &Thread->WaitBlock[0];
+            
+            /* Fail if there's an APC Pending */
+            if (WaitMode == UserMode && Thread->ApcState.UserApcPending) {
+            
+                /* Return the status and increase the pending threads */
+                ListEntry = (PLIST_ENTRY)STATUS_USER_APC;
+                Queue->CurrentCount++;
+                
+                /* Nothing to wait on */
+                break;
+            }
+            
+            /* Build the Wait Block */
+            WaitBlock = &Thread->WaitBlock[0];
+            WaitBlock->Object = (PVOID)Queue;
+            WaitBlock->WaitKey = STATUS_SUCCESS;
+            WaitBlock->WaitType = WaitAny;
+            WaitBlock->Thread = Thread;
+            WaitBlock->NextWaitBlock = NULL;
+            
+            Thread->WaitStatus = STATUS_SUCCESS;
+            
+            /* We need to wait for the object... check if we have a timeout */
+            if (Timeout) {
+        
+                /* If it's zero, then don't do any waiting */
+                if (!Timeout->QuadPart) {
+            
+                    /* Instant Timeout, return the status and increase the pending threads */
+                    DPRINT("Queue Wait has timed out\n");
+                    ListEntry = (PLIST_ENTRY)STATUS_TIMEOUT;
+                    Queue->CurrentCount++;
+                    
+                    /* Nothing to wait on */
+                    break;
+                }
+                
+                /* 
+                 * Set up the Timer. We'll use the internal function so that we can
+                 * hold on to the dispatcher lock.
+                 */
+                Timer = &Thread->Timer;
+                TimerWaitBlock = &Thread->WaitBlock[1];
+
+                /* Set up the Timer Wait Block */
+                TimerWaitBlock->Object = (PVOID)Timer;
+                TimerWaitBlock->Thread = Thread;
+                TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
+                TimerWaitBlock->WaitType = WaitAny;
+                TimerWaitBlock->NextWaitBlock = NULL;
+            
+                /* Link the timer to this Wait Block */
+                InitializeListHead(&Timer->Header.WaitListHead);
+                InsertTailList(&Timer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
+            
+                /* Create Timer */
+                DPRINT("Creating Timer with timeout %I64d\n", *Timeout);
+                KiInsertTimer(Timer, *Timeout);
+            }
+                            
+            /* Insert the wait block into the Queues's wait list */
+            WaitBlock = Thread->WaitBlockList;
+            InsertTailList(&Queue->Header.WaitListHead, &WaitBlock->WaitListEntry);
+            
+            /* Block the Thread */
+            DPRINT("Blocking the Thread: %x %x!\n", KeGetCurrentThread(), Thread);
+            KiBlockThread(&Status, 
+                          FALSE, 
+                          WaitMode,
+                          WrQueue);
+    
+            /* Reset the wait reason */
+            Thread->WaitReason = 0;
+            
+            /* Check if we were executing an APC */
+            if (Status != STATUS_KERNEL_APC) {
+             
+                /* Done Waiting  */
+                DPRINT("Done waking queue. Thread: %x %x!\n", KeGetCurrentThread(), Thread);
+                return (PLIST_ENTRY)Status;
+            }
+        
+            /* Acquire again the lock */
+            DPRINT("Looping again\n");
+            OldIrql = KeAcquireDispatcherDatabaseLock();
+            
+            /* Save the new IRQL and decrease number of waiting threads */
+            Thread->WaitIrql = OldIrql;
+            Queue->CurrentCount--;
+        }
+    }
+    
+    /* Unlock Database and return */
+    KeReleaseDispatcherDatabaseLock(Thread->WaitIrql);
+    DPRINT("Returning. CurrentCount: %d, Maximum Count: %d\n", 
+            Queue->CurrentCount, Queue->MaximumCount);
+    return ListEntry;
 }
 
-
 /*
  * @implemented
  */
-PLIST_ENTRY STDCALL
+PLIST_ENTRY 
+STDCALL
 KeRundownQueue(IN PKQUEUE Queue)
 {
-   PLIST_ENTRY EnumEntry;
-   PKTHREAD Thread;
-   KIRQL OldIrql;
-
-   DPRINT("KeRundownQueue(Queue %x)\n", Queue);
-
-   /* I'm just guessing how this should work:-/
-    * -Gunnar 
-    */
-     
-   OldIrql = KeAcquireDispatcherDatabaseLock ();
-
-   //no thread must wait on queue at rundown
-   ASSERT(IsListEmpty(&Queue->Header.WaitListHead));
+    PLIST_ENTRY EnumEntry;
+    PLIST_ENTRY FirstEntry;
+    PKTHREAD Thread;
+    KIRQL OldIrql;
+
+    DPRINT("KeRundownQueue(Queue %x)\n", Queue);
+
+    /* Get the Dispatcher Lock */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+
+    /* Get the First Empty Entry */
+    FirstEntry = Queue->EntryListHead.Flink;
+            
+    /* Make sure the list is not empty */
+    if (FirstEntry == &Queue->EntryListHead) {
+    
+        /* It is, so don't return anything */
+        EnumEntry = NULL;
    
-   // unlink threads and clear their Thread->Queue
-   while (!IsListEmpty(&Queue->ThreadListHead))
-   {
-      EnumEntry = RemoveHeadList(&Queue->ThreadListHead);
-      Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry);
-      Thread->Queue = NULL;
-   }
-
-   if (IsListEmpty(&Queue->EntryListHead))
-   {
-      EnumEntry = NULL;
-   }
-   else
-   {
-      EnumEntry = Queue->EntryListHead.Flink;
-   }
+    } else {
+       
+        /* Remove it */
+        RemoveEntryList(&Queue->EntryListHead);
+    }
+    
+    /* Unlink threads and clear their Thread->Queue */
+    while (!IsListEmpty(&Queue->ThreadListHead)) {
+        
+        /* Get the Entry and Remove it */
+        EnumEntry = RemoveHeadList(&Queue->ThreadListHead);
+        
+        /* Get the Entry's Thread */
+        Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry);
+        
+        /* Kill its Queue */
+        Thread->Queue = NULL;
+    }
+
+    /* Release the lock and return */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return FirstEntry;
+}
 
-   KeReleaseDispatcherDatabaseLock (OldIrql);
+/*
+ * Called when a thread which has a queue entry is entering a wait state
+ */
+VOID
+FASTCALL
+KiWakeQueue(IN PKQUEUE Queue)
+{
+    PLIST_ENTRY QueueEntry;
+    PLIST_ENTRY WaitEntry;
+    PKWAIT_BLOCK WaitBlock;
+    
+    /* Decrement the number of active threads */
+    DPRINT("KiWakeQueue: %x. Thread: %x\n", Queue, KeGetCurrentThread());
+    Queue->CurrentCount--;
+    
+    /* Make sure the counts are OK */
+    if (Queue->CurrentCount < Queue->MaximumCount) {
+    
+        /* Get the Queue Entry */
+        QueueEntry = Queue->EntryListHead.Flink;
+        
+        /* Get the Wait Entry */
+        WaitEntry = Queue->Header.WaitListHead.Blink;
+        DPRINT("Queue Count is ok, Queue entries: %x, %x\n", QueueEntry, WaitEntry);
+        
+        /* Make sure that the Queue List isn't empty and that this entry is valid */
+        if (!IsListEmpty(&Queue->Header.WaitListHead) && 
+            (QueueEntry != &Queue->EntryListHead)) {
+            
+            /* Remove this entry */
+            DPRINT("Queue in List, removing it\n");
+            RemoveEntryList(QueueEntry);
+            QueueEntry->Flink = NULL;
+            
+            /* Decrease the Signal State */
+            Queue->Header.SignalState--;
+            
+            /* Unwait the Thread */
+            DPRINT("Unwaiting Thread\n");
+            WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
+            KiAbortWaitThread(WaitBlock->Thread, (NTSTATUS)QueueEntry, IO_NO_INCREMENT);
+        }
+    }    
+}
 
-   return EnumEntry;
+/*
+ * Returns the previous number of entries in the queue
+ */
+LONG 
+STDCALL
+KiInsertQueue(IN PKQUEUE Queue,
+              IN PLIST_ENTRY Entry,
+              BOOLEAN Head)
+{
+    ULONG InitialState;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PKWAIT_BLOCK WaitBlock;
+    PLIST_ENTRY WaitEntry;
+  
+    DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
+   
+    /* Save the old state */
+    InitialState = Queue->Header.SignalState;
+     
+    /* Get the Entry */
+    WaitEntry = Queue->Header.WaitListHead.Blink;
+    DPRINT("Initial State, WaitEntry: %d, %x\n", InitialState, WaitEntry);
+    
+    /*
+     * Why the KeGetCurrentThread()->Queue != Queue?
+     * KiInsertQueue might be called from an APC for the current thread. 
+     * -Gunnar
+     */
+    if ((Queue->CurrentCount < Queue->MaximumCount) && 
+        (WaitEntry != &Queue->Header.WaitListHead) &&
+        ((Thread->Queue != Queue) || (Thread->WaitReason != WrQueue))) {
+       
+        /* Remove the wait entry */
+        DPRINT("Removing Entry\n");
+        RemoveEntryList(WaitEntry);
+        
+        /* Get the Wait Block and Thread */
+        WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
+        DPRINT("Got wait block: %x\n", WaitBlock);
+        Thread = WaitBlock->Thread;
+        
+        /* Reset the wait reason */
+        Thread->WaitReason = 0;
+        
+        /* Increase the waiting threads */
+        Queue->CurrentCount++;
+        
+        /* Check if there's a Thread Timer */
+        if (Thread->Timer.Header.Inserted) {
+    
+            /* Cancel the Thread Timer with the no-lock fastpath */
+            DPRINT("Removing the Thread's Timer\n");
+            Thread->Timer.Header.Inserted = FALSE;
+            RemoveEntryList(&Thread->Timer.TimerListEntry);
+        }
+        
+        /* Reschedule the Thread */
+        DPRINT("Unblocking the Thread\n");
+        KiUnblockThread(Thread, (PNTSTATUS)&Entry, 0);
+    
+    } else {
+    
+        /* Increase the Entries */
+        DPRINT("Adding new Queue Entry: %d %d\n", Head, Queue->Header.SignalState);
+        Queue->Header.SignalState++;
+        
+        if (Head) {
+        
+            InsertHeadList(&Queue->EntryListHead, Entry);
+        
+        } else {
+        
+            InsertTailList(&Queue->EntryListHead, Entry);
+        }
+    }
+
+    /* Return the previous state */
+    DPRINT("Returning\n");
+    return InitialState;
 }
 
 /* EOF */
index 9408e66..2d3fe4d 100644 (file)
 /*
  * @implemented
  */
-VOID STDCALL
-KeInitializeSemaphore (PKSEMAPHORE     Semaphore,
-                      LONG             Count,
-                      LONG             Limit)
+VOID
+STDCALL
+KeInitializeSemaphore(PKSEMAPHORE Semaphore,
+                      LONG Count,
+                      LONG Limit)
 {
-   KeInitializeDispatcherHeader(&Semaphore->Header,
-                               InternalSemaphoreType,
-                               sizeof(KSEMAPHORE)/sizeof(ULONG),
-                               Count);
-   Semaphore->Limit=Limit;
+
+    DPRINT("KeInitializeSemaphore Sem: %x\n", Semaphore);
+    
+    /* Simply Initialize the Header */
+    KeInitializeDispatcherHeader(&Semaphore->Header,
+                                 SemaphoreObject,
+                                 sizeof(KSEMAPHORE)/sizeof(ULONG),
+                                 Count);
+
+    /* Set the Limit */
+    Semaphore->Limit = Limit;  
 }
 
 /*
  * @implemented
  */
-LONG STDCALL
-KeReadStateSemaphore (PKSEMAPHORE      Semaphore)
+LONG 
+STDCALL
+KeReadStateSemaphore(PKSEMAPHORE Semaphore)
 {
-   return(Semaphore->Header.SignalState);
+    /* Just return the Signal State */
+    return(Semaphore->Header.SignalState);
 }
 
 /*
  * @implemented
- */
-LONG STDCALL
-KeReleaseSemaphore (PKSEMAPHORE        Semaphore,
-                   KPRIORITY   Increment,
-                   LONG                Adjustment,
-                   BOOLEAN             Wait)
-/*
+ *
  * FUNCTION: KeReleaseSemaphore releases a given semaphore object. This
  * routine supplies a runtime priority boost for waiting threads. If this
  * call sets the semaphore to the Signaled state, the semaphore count is
@@ -68,40 +71,65 @@ KeReleaseSemaphore (PKSEMAPHORE     Semaphore,
  * RETURNS: If the return value is zero, the previous state of the semaphore
  *          object is Not-Signaled.
  */
+LONG 
+STDCALL
+KeReleaseSemaphore(PKSEMAPHORE Semaphore,
+                   KPRIORITY Increment,
+                   LONG Adjustment,
+                   BOOLEAN Wait)
+
 {
-  ULONG InitialState;
-  KIRQL OldIrql;
+    ULONG InitialState;
+    KIRQL OldIrql;
+    PKTHREAD CurrentThread;
 
-  DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
-         "Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
+    DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, Wait %d)\n", 
+            Semaphore, 
+            Increment, 
+            Adjustment, 
+            Wait);
 
-  OldIrql = KeAcquireDispatcherDatabaseLock();
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
 
-  InitialState = Semaphore->Header.SignalState;
-  if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
-      InitialState > InitialState + Adjustment)
-    {
-      ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
+    /* Save the Old State */
+    InitialState = Semaphore->Header.SignalState;
+    
+    /* Check if the Limit was exceeded */
+    if (Semaphore->Limit < (LONG) InitialState + Adjustment || 
+        InitialState > InitialState + Adjustment) {
+        
+        /* Raise an error if it was exceeded */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
     }
 
-  Semaphore->Header.SignalState += Adjustment;
-  if (InitialState == 0)
-    {
-      KiDispatcherObjectWake(&Semaphore->Header, SEMAPHORE_INCREMENT);
+    /* Now set the new state */
+    Semaphore->Header.SignalState += Adjustment;
+    
+    /* Check if we should wake it */
+    if (InitialState == 0 && !IsListEmpty(&Semaphore->Header.WaitListHead)) {
+        
+        /* Wake the Semaphore */
+        KiWaitTest(&Semaphore->Header, Increment);
     }
 
-  if (Wait == FALSE)
-    {
-      KeReleaseDispatcherDatabaseLock(OldIrql);
-    }
-  else
-    {
-      KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = TRUE;
-      Thread->WaitIrql = OldIrql;
+    /* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
+    if (Wait == FALSE) {
+        
+        /* Release the Lock */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+    
+    } else {
+        
+        /* Set a wait */
+        CurrentThread = KeGetCurrentThread();
+        CurrentThread->WaitNext = TRUE;
+        CurrentThread->WaitIrql = OldIrql;
     }
 
-  return(InitialState);
+    /* Return the previous state */
+    return InitialState;
 }
 
 /* EOF */
index 15c3b13..258a15d 100644 (file)
@@ -178,11 +178,7 @@ KiAcquireSpinLock(PKSPIN_LOCK SpinLock)
    * FIXME: This depends on gcc assembling this test to a single load from
    * the spinlock's value.
    */
-  if (*SpinLock >= 2)
-  {
-    DbgPrint("Lock %x has bad value %x\n", SpinLock, *SpinLock);
-    KEBUGCHECK(0);
-  }
+  ASSERT(*SpinLock < 2);
    
   while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1)
   {
@@ -199,7 +195,7 @@ KiAcquireSpinLock(PKSPIN_LOCK SpinLock)
 #endif
 #else
     DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
-    KEBUGCHECK(0);
+    KEBUGCHECKEX(SPIN_LOCK_ALREADY_OWNED, (ULONG)SpinLock, 0, 0, 0);
 #endif /* CONFIG_SMP */
   }
 }
@@ -227,7 +223,7 @@ KiReleaseSpinLock(PKSPIN_LOCK SpinLock)
   if (*SpinLock != 1)
   {
     DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
-    KEBUGCHECK(0);
+    KEBUGCHECKEX(SPIN_LOCK_NOT_OWNED, (ULONG)SpinLock, 0, 0, 0);
   }
   (void)InterlockedExchangeUL(SpinLock, 0);
 }
index c46db9d..49504f9 100644 (file)
@@ -107,12 +107,11 @@ KeInitializeTimerEx (PKTIMER Timer,
     
     /* Initialize the Dispatch Header */
     KeInitializeDispatcherHeader(&Timer->Header,
-                                 InternalNotificationTimer + Type,
+                                 TimerNotificationObject + Type,
                                  sizeof(KTIMER) / sizeof(ULONG),
                                  FALSE);
    
-    /* Initalize the List Head and other data */
-    InitializeListHead(&Timer->Header.WaitListHead);
+    /* Initalize the Other data */
     Timer->DueTime.QuadPart = 0;
     Timer->Period = 0;
 }
@@ -196,7 +195,6 @@ KeSetTimerEx (PKTIMER Timer,
     Timer->Dpc = Dpc;
     Timer->Period = Period;
     Timer->Header.SignalState = FALSE;
-    Timer->Header.Absolute = FALSE;
     
     /* Insert it */
     if (!KiInsertTimer(Timer, DueTime)) {
@@ -219,7 +217,6 @@ KiExpireTimers(PKDPC Dpc,
                PVOID SystemArgument1,
                PVOID SystemArgument2)
 {
-    ULONG Eip = (ULONG)SystemArgument1;
     PKTIMER Timer;
     ULONGLONG InterruptTime;
     LIST_ENTRY ExpiredTimerList;
@@ -267,8 +264,6 @@ KiExpireTimers(PKDPC Dpc,
     }
 
     DPRINT("Timers expired\n");
-    /* Add a Profile Event */
-    KiAddProfileEvent(ProfileTime, Eip);
 
     /* Release Dispatcher Lock */
     KeReleaseDispatcherDatabaseLock(OldIrql);
@@ -296,7 +291,7 @@ KiHandleExpiredTimer(PKTIMER Timer)
     /* Set it as Signaled */
     DPRINT("Setting Timer as Signaled\n");
     Timer->Header.SignalState = TRUE;
-    KiDispatcherObjectWake(&Timer->Header, 0);   
+    KiWaitTest(&Timer->Header, IO_NO_INCREMENT);   
 
     /* If the Timer is periodic, reinsert the timer with the new due time */
     if (Timer->Period) {
@@ -306,7 +301,7 @@ KiHandleExpiredTimer(PKTIMER Timer)
         if (!KiInsertTimer(Timer, DueTime)) {
 
            /* FIXME: I will think about how to handle this and fix it ASAP -- Alex */
-           DPRINT1("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
+           DPRINT("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
         };
     }
     
@@ -338,8 +333,10 @@ KiInsertTimer(PKTIMER Timer,
     
     DPRINT("KiInsertTimer(Timer %x DueTime %I64d)\n", Timer, DueTime.QuadPart);
     
-    /* Set it as Inserted */
+    /* Set default data */
     Timer->Header.Inserted = TRUE;
+    Timer->Header.Absolute = FALSE;
+    if (!Timer->Period) Timer->Header.SignalState = FALSE;
     
     /* Convert to relative time if needed */
     if (DueTime.u.HighPart >= 0) {
similarity index 63%
rename from reactos/ntoskrnl/ps/w32call.c
rename to reactos/ntoskrnl/ke/usercall.c
index 455fd63..02573bf 100644 (file)
@@ -1,37 +1,28 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ps/w32call.c
- * PURPOSE:         Thread managment
+ * FILE:            ntoskrnl/ke/usercall.c
+ * PURPOSE:         User-Mode callbacks. Portable part.
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Phillip Susi
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
  */
 
-/*
- * NOTE:
- * 
- * All of the routines that manipulate the thread queue synchronize on
- * a single spinlock
- * 
- */
-
-/* INCLUDES ****************************************************************/
+/* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
 #include <internal/debug.h>
 
-#if defined(__GNUC__)
-/* void * alloca(size_t size); */
-#elif defined(_MSC_VER)
-void* _alloca(size_t size);
-#else
-#error Unknown compiler for alloca intrinsic stack allocation "function"
-#endif
+/* FUNCTIONS *****************************************************************/
+
+#if ALEX_CB_REWRITE
 
-/* TYPES *******************************************************************/
+NTSTATUS 
+STDCALL 
+KiSwitchToUserMode(IN PVOID *OutputBuffer,
+                   IN PULONG OutputLength);
+
+#else
 
 typedef struct _NTW32CALL_SAVED_STATE
 {
@@ -55,8 +46,6 @@ typedef struct
 KSPIN_LOCK CallbackStackListLock;
 static LIST_ENTRY CallbackStackListHead;
 
-/* FUNCTIONS ***************************************************************/
-
 VOID INIT_FUNCTION
 PsInitialiseW32Call(VOID)
 {
@@ -64,90 +53,6 @@ PsInitialiseW32Call(VOID)
   KeInitializeSpinLock(&CallbackStackListLock);
 }
 
-NTSTATUS STDCALL
-NtCallbackReturn (PVOID                Result,
-                 ULONG         ResultLength,
-                 NTSTATUS      Status)
-{
-  PULONG OldStack;
-  PETHREAD Thread;
-  PNTSTATUS CallbackStatus;
-  PULONG CallerResultLength;
-  PVOID* CallerResult;
-  PVOID InitialStack;
-  PVOID StackBase;
-  ULONG_PTR StackLimit;
-  KIRQL oldIrql;
-  PNTW32CALL_SAVED_STATE State;
-  PKTRAP_FRAME SavedTrapFrame;
-  PVOID SavedCallbackStack;
-  PVOID SavedExceptionStack;
-  
-  PAGED_CODE();
-
-  Thread = PsGetCurrentThread();
-  if (Thread->Tcb.CallbackStack == NULL)
-    {
-      return(STATUS_NO_CALLBACK_ACTIVE);
-    }
-
-  OldStack = (PULONG)Thread->Tcb.CallbackStack;
-
-  /*
-   * Get the values that NtW32Call left on the inactive stack for us.
-   */
-  State = (PNTW32CALL_SAVED_STATE)OldStack[0];  
-  CallbackStatus = State->CallbackStatus;
-  CallerResultLength = State->CallerResultLength;
-  CallerResult = State->CallerResult;
-  InitialStack = State->SavedInitialStack;
-  StackBase = State->SavedStackBase;
-  StackLimit = State->SavedStackLimit;
-  SavedTrapFrame = State->SavedTrapFrame;
-  SavedCallbackStack = State->SavedCallbackStack;
-  SavedExceptionStack = State->SavedExceptionStack;
-
-  /*
-   * Copy the callback status and the callback result to NtW32Call
-   */
-  *CallbackStatus = Status;
-  if (CallerResult != NULL && CallerResultLength != NULL)
-    {
-      if (Result == NULL)
-       {
-         *CallerResultLength = 0;
-       }
-      else
-       {
-         *CallerResultLength = min(ResultLength, *CallerResultLength);
-         memcpy(*CallerResult, Result, *CallerResultLength);
-       }
-    }
-
-  /*
-   * Restore the old stack.
-   */
-  KeRaiseIrql(HIGH_LEVEL, &oldIrql);
-  if ((Thread->Tcb.NpxState & NPX_STATE_VALID) &&
-      ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread)
-    {
-      memcpy((char*)InitialStack - sizeof(FX_SAVE_AREA),
-             (char*)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA),
-             sizeof(FX_SAVE_AREA));
-    }
-  Thread->Tcb.InitialStack = InitialStack;
-  Thread->Tcb.StackBase = StackBase;
-  Thread->Tcb.StackLimit = StackLimit;
-  Thread->Tcb.TrapFrame = SavedTrapFrame;
-  Thread->Tcb.CallbackStack = SavedCallbackStack;
-  KeGetCurrentKPCR()->TSS->Esp0 = (ULONG)SavedExceptionStack;
-  KeStackSwitchAndRet((PVOID)(OldStack + 1));
-
-  /* Should never return. */
-  KEBUGCHECK(0);
-  return(STATUS_UNSUCCESSFUL);
-}
-
 VOID STATIC
 PsFreeCallbackStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, 
                        PFN_TYPE Page, SWAPENTRY SwapEntry, 
@@ -244,14 +149,19 @@ PsAllocateCallbackStack(ULONG StackSize)
     }
   return(KernelStack);
 }
+#endif
 
-NTSTATUS STDCALL
-NtW32Call (IN ULONG RoutineIndex,
-          IN PVOID Argument,
-          IN ULONG ArgumentLength,
-          OUT PVOID* Result OPTIONAL,
-          OUT PULONG ResultLength OPTIONAL)
-{
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+KeUserModeCallback(IN ULONG RoutineIndex,
+                   IN PVOID Argument,
+                   IN ULONG ArgumentLength,
+                   OUT PVOID *Result,
+                   OUT PULONG ResultLength)
+{ 
   PETHREAD Thread;
   PVOID NewStack;
   ULONG_PTR StackSize;
@@ -264,7 +174,7 @@ NtW32Call (IN ULONG RoutineIndex,
   
   PAGED_CODE();
 
-  DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
+  DPRINT("KeUserModeCallback(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
          RoutineIndex, Argument, ArgumentLength);
 
   Thread = PsGetCurrentThread();
@@ -289,11 +199,11 @@ NtW32Call (IN ULONG RoutineIndex,
       AssignedStack = CONTAINING_RECORD(StackEntry, NTW32CALL_CALLBACK_STACK,
                                        ListEntry);
       NewStack = AssignedStack->BaseAddress;
-      memset(NewStack, 0, StackSize);
+      RtlZeroMemory(NewStack, StackSize);
     }
   /* FIXME: Need to check whether we were interrupted from v86 mode. */
-  memcpy((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA),
-         Thread->Tcb.TrapFrame, sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
+  RtlCopyMemory((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA),
+                Thread->Tcb.TrapFrame, sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
   NewFrame = (PKTRAP_FRAME)((char*)NewStack + StackSize - sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA));
   /* We need the stack pointer to remain 4-byte aligned */
   NewFrame->Esp -= (((ArgumentLength + 3) & (~ 0x3)) + (4 * sizeof(ULONG)));
@@ -303,7 +213,7 @@ NtW32Call (IN ULONG RoutineIndex,
   UserEsp[1] = RoutineIndex;
   UserEsp[2] = (ULONG)&UserEsp[4];
   UserEsp[3] = ArgumentLength;
-  memcpy((PVOID)&UserEsp[4], Argument, ArgumentLength);
+  RtlCopyMemory((PVOID)&UserEsp[4], Argument, ArgumentLength);
 
   /* Switch to the new environment and return to user-mode. */
   KeRaiseIrql(HIGH_LEVEL, &oldIrql);
@@ -317,11 +227,11 @@ NtW32Call (IN ULONG RoutineIndex,
   SavedState.SavedCallbackStack = Thread->Tcb.CallbackStack;
   SavedState.SavedExceptionStack = (PVOID)KeGetCurrentKPCR()->TSS->Esp0;
   if ((Thread->Tcb.NpxState & NPX_STATE_VALID) &&
-      ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentKPCR()->PrcbData.NpxThread)
+      ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentPrcb()->NpxThread)
     {
-      memcpy((char*)NewStack + StackSize - sizeof(FX_SAVE_AREA),
-             (char*)SavedState.SavedInitialStack - sizeof(FX_SAVE_AREA),
-             sizeof(FX_SAVE_AREA));
+      RtlCopyMemory((char*)NewStack + StackSize - sizeof(FX_SAVE_AREA),
+                    (char*)SavedState.SavedInitialStack - sizeof(FX_SAVE_AREA),
+                    sizeof(FX_SAVE_AREA));
     }
   Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)NewStack + StackSize;
   Thread->Tcb.StackLimit = (ULONG)NewStack;
@@ -338,6 +248,6 @@ NtW32Call (IN ULONG RoutineIndex,
   InsertTailList(&CallbackStackListHead, &AssignedStack->ListEntry);
   KeReleaseSpinLock(&CallbackStackListLock, PASSIVE_LEVEL);
   return(CallbackStatus);
-} 
-
+}
+  
 /* EOF */
index a6575e9..a4b51d4 100644 (file)
@@ -1,16 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS project
  * FILE:            ntoskrnl/ke/wait.c
  * PURPOSE:         Manages non-busy waiting
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Phillip Susi
- */
-
-/* NOTES ********************************************************************
- *
+ * PROGRAMMERS:     Alex Ionescu - Fixes and optimization.
+ *                  Gunnar Dalsnes - Implementation
  */
 
 /* INCLUDES ******************************************************************/
 
 static KSPIN_LOCK DispatcherDatabaseLock;
 
-#define KeDispatcherObjectWakeOne(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, FALSE)
-#define KeDispatcherObjectWakeAll(hdr, increment) KeDispatcherObjectWakeOneOrAll(hdr, increment, TRUE)
+/* Tells us if the Timer or Event is a Syncronization or Notification Object */
+#define TIMER_OR_EVENT_TYPE 0x7L
 
-extern POBJECT_TYPE EXPORTED ExMutantObjectType;
-extern POBJECT_TYPE EXPORTED ExSemaphoreObjectType;
-extern POBJECT_TYPE EXPORTED ExTimerType;
+/* One of the Reserved Wait Blocks, this one is for the Thread's Timer */
+#define TIMER_WAIT_BLOCK 0x3L
 
 /* FUNCTIONS *****************************************************************/
 
-VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
-                                 ULONG Type,
-                                 ULONG Size,
-                                 ULONG SignalState)
-{
-   Header->Type = (UCHAR)Type;
-   Header->Absolute = 0;
-   Header->Inserted = 0;
-   Header->Size = (UCHAR)Size;
-   Header->SignalState = SignalState;
-   InitializeListHead(&(Header->WaitListHead));
-}
-
-
-KIRQL
-KeAcquireDispatcherDatabaseLock(VOID)
-/*
- * PURPOSE: Acquires the dispatcher database lock for the caller
- */
-{
-   KIRQL OldIrql;
-
-   DPRINT("KeAcquireDispatcherDatabaseLock()\n");
-
-   KeAcquireSpinLock (&DispatcherDatabaseLock, &OldIrql);
-   return OldIrql;
-}
-
-
 VOID
-KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID)
-/*
- * PURPOSE: Acquires the dispatcher database lock for the caller
- */
-{
-   DPRINT("KeAcquireDispatcherDatabaseLockAtDpcLevel()\n");
-
-   KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
-}
-
-
-VOID
-KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
-{
-  DPRINT("KeReleaseDispatcherDatabaseLock(OldIrql %x)\n",OldIrql);
-  if (!KeIsExecutingDpc() && 
-      OldIrql < DISPATCH_LEVEL && 
-      KeGetCurrentThread() != NULL && 
-      KeGetCurrentThread() == KeGetCurrentKPCR()->PrcbData.IdleThread)
-  {
-    PsDispatchThreadNoLock(THREAD_STATE_READY);
-    KeLowerIrql(OldIrql);
-  }
-  else
-  {
-    KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
-  }
-}
-
-
-VOID
-KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID)
-{
-  DPRINT("KeReleaseDispatcherDatabaseLock()\n");
-
-  KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
-}
-
-
-static BOOLEAN
-KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
-                        PKTHREAD Thread)
-/*
- * FUNCTION: Perform side effects on object before a wait for a thread is
- *           satisfied
- */
-{
-   BOOLEAN Abandoned = FALSE;
-
-   switch (hdr->Type)
-   {
-      case InternalSynchronizationEvent:
-         hdr->SignalState = 0;
-         break;
-      
-      case InternalQueueType:
-         break;
-         
-      case InternalSemaphoreType:
-         hdr->SignalState--;
-         break;
-
-      case InternalProcessType:
-         break;
-
-      case InternalThreadType:
-         break;
-
-      case InternalNotificationEvent:
-         break;
-
-      case InternalSynchronizationTimer:
-         hdr->SignalState = FALSE;
-         break;
-
-      case InternalNotificationTimer:
-         break;
-
-      case InternalMutexType:
-      {
-         PKMUTEX Mutex;
-
-         Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
-         hdr->SignalState--;
-         ASSERT(hdr->SignalState <= 1);
-         if (hdr->SignalState == 0)
-         {
-            if (Thread == NULL)
-            {
-               DPRINT("Thread == NULL!\n");
-               KEBUGCHECK(0);
-            }
-            Abandoned = Mutex->Abandoned;
-            if (Thread != NULL)
-               InsertTailList(&Thread->MutantListHead, &Mutex->MutantListEntry);
-            Mutex->OwnerThread = Thread;
-            Mutex->Abandoned = FALSE;
-         }
-      }
-         break;
-
-      default:
-         DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", __FILE__, __LINE__, hdr);
-         KEBUGCHECK(0);
-   }
-
-   return Abandoned;
-}
-
-static BOOLEAN
-KiIsObjectSignalled(DISPATCHER_HEADER * hdr,
-                    PKTHREAD Thread)
-{
-   if (hdr->Type == InternalMutexType)
-   {
-      PKMUTEX Mutex;
-
-      Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
-
-      ASSERT(hdr->SignalState <= 1);
-
-      if ((hdr->SignalState < 1 && Mutex->OwnerThread == Thread) || hdr->SignalState == 1)
-      {
-         return (TRUE);
-      }
-      else
-      {
-         return (FALSE);
-      }
-   }
-
-   if (hdr->SignalState <= 0)
-   {
-      return (FALSE);
-   }
-   else
-   {
-      return (TRUE);
-   }
-}
-
-/* Must be called with the dispatcher lock held */
-BOOLEAN KiAbortWaitThread(PKTHREAD Thread, NTSTATUS WaitStatus)
-{
-   PKWAIT_BLOCK WaitBlock;
-   BOOLEAN WasWaiting;
-
-   /* if we are blocked, we must be waiting on something also */
-   ASSERT((Thread->State == THREAD_STATE_BLOCKED) == (Thread->WaitBlockList != NULL));
-
-   WaitBlock = (PKWAIT_BLOCK)Thread->WaitBlockList;
-   WasWaiting = (WaitBlock != NULL);
-   
-   while (WaitBlock)
-   {
-      RemoveEntryList(&WaitBlock->WaitListEntry);
-      WaitBlock = WaitBlock->NextWaitBlock;
-   }
-   
-   Thread->WaitBlockList = NULL;
-
-   if (WasWaiting)
-   {
-          PsUnblockThread((PETHREAD)Thread, &WaitStatus, 0);
-   }
-   return WasWaiting;
-}
-
-static BOOLEAN
-KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
-                               KPRIORITY increment,
-                               BOOLEAN WakeAll)
-{
-   PKWAIT_BLOCK Waiter;
-   PKWAIT_BLOCK WaiterHead;
-   PLIST_ENTRY EnumEntry;
-   NTSTATUS Status;
-   BOOLEAN Abandoned;
-   BOOLEAN AllSignaled;
-   BOOLEAN WakedAny = FALSE;
-
-   DPRINT("KeDispatcherObjectWakeOnOrAll(hdr %x)\n", hdr);
-   DPRINT ("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
-           hdr->WaitListHead.Flink, hdr->WaitListHead.Blink);
-
-   if (IsListEmpty(&hdr->WaitListHead))
-   {
-      return (FALSE);
-   }
-
-   //enum waiters for this dispatcher object
-   EnumEntry = hdr->WaitListHead.Flink;
-   while (EnumEntry != &hdr->WaitListHead && (WakeAll || !WakedAny))
-   {
-      WaiterHead = CONTAINING_RECORD(EnumEntry, KWAIT_BLOCK, WaitListEntry);
-      DPRINT("current_entry %x current %x\n", EnumEntry, WaiterHead);
-      EnumEntry = EnumEntry->Flink;
-      ASSERT(WaiterHead->Thread != NULL);
-      ASSERT(WaiterHead->Thread->WaitBlockList != NULL);
-
-      Abandoned = FALSE;
-
-      if (WaiterHead->WaitType == WaitAny)
-      {
-         DPRINT("WaitAny: Remove all wait blocks.\n");
-         for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
-         {
-            RemoveEntryList(&Waiter->WaitListEntry);
-         }
-
-         WaiterHead->Thread->WaitBlockList = NULL;
-
-         /*
-          * If a WakeAll KiSideEffectsBeforeWake(hdr,.. will be called several times,
-          * but thats ok since WakeAll objects has no sideeffects.
-          */
-         Abandoned |= KiSideEffectsBeforeWake(hdr, WaiterHead->Thread);
-      }
-      else
-      {
-         DPRINT("WaitAll: All WaitAll objects must be signaled.\n");
-
-         AllSignaled = TRUE;
-
-         //all WaitAll obj. for thread need to be signaled to satisfy a wake
-         for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
-         {
-            //no need to check hdr since it has to be signaled
-            if (Waiter->WaitType == WaitAll && Waiter->Object != hdr)
-            {
-               if (!KiIsObjectSignalled(Waiter->Object, Waiter->Thread))
-               {
-                  AllSignaled = FALSE;
-                  break;
-               }
-            }
-         }
-
-         if (AllSignaled)
-         {
-            for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
-            {
-               RemoveEntryList(&Waiter->WaitListEntry);
-         
-               if (Waiter->WaitType == WaitAll)
-               {
-                  Abandoned |= KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread);
-               }
-
-               //no WaitAny objects can possibly be signaled since we are here
-               ASSERT(!(Waiter->WaitType == WaitAny
-                                         && KiIsObjectSignalled(Waiter->Object, Waiter->Thread)));
-            }
-
-            WaiterHead->Thread->WaitBlockList = NULL;
-         }
-      }
-
-      if (WaiterHead->Thread->WaitBlockList == NULL)
-      {
-         Status = WaiterHead->WaitKey;
-         if (Abandoned)
-         {
-            DPRINT("Abandoned mutex among objects");
-            Status += STATUS_ABANDONED_WAIT_0;
-         }
-
-         WakedAny = TRUE;
-         DPRINT("Waking %x status = %x\n", WaiterHead->Thread, Status);
-         PsUnblockThread(CONTAINING_RECORD(WaiterHead->Thread, ETHREAD, Tcb),
-                         &Status, increment);
-      }
-   }
-
-   return WakedAny;
-}
-
-
-BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment)
-/*
- * FUNCTION: Wake threads waiting on a dispatcher object
- * NOTE: The exact semantics of waking are dependant on the type of object
- */
+inline
+FASTCALL
+KiCheckAlertability(BOOLEAN Alertable,
+                    PKTHREAD CurrentThread,
+                    KPROCESSOR_MODE WaitMode,
+                    PNTSTATUS Status)
 {
-   BOOL Ret;
-
-   DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr);
-//   DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n",
-//       &hdr->WaitListHead,hdr->WaitListHead.Flink);
-   DPRINT("hdr->Type %x\n",hdr->Type);
-   switch (hdr->Type)
-     {
-      case InternalNotificationEvent:
-       return(KeDispatcherObjectWakeAll(hdr, increment));
-
-      case InternalNotificationTimer:
-       return(KeDispatcherObjectWakeAll(hdr, increment));
-
-      case InternalSynchronizationEvent:
-       return(KeDispatcherObjectWakeOne(hdr, increment));
-
-      case InternalSynchronizationTimer:
-       return(KeDispatcherObjectWakeOne(hdr, increment));
-
-      case InternalQueueType:
-       return(KeDispatcherObjectWakeOne(hdr, increment));
-      
-      case InternalSemaphoreType:
-       DPRINT("hdr->SignalState %d\n", hdr->SignalState);
-       if(hdr->SignalState>0)
-         {
-           do
-             {
-               DPRINT("Waking one semaphore waiter\n");
-               Ret = KeDispatcherObjectWakeOne(hdr, increment);
-             } while(hdr->SignalState > 0 &&  Ret) ;
-           return(Ret);
-         }
-       else return FALSE;
-
-     case InternalProcessType:
-       return(KeDispatcherObjectWakeAll(hdr, increment));
-
-     case InternalThreadType:
-       return(KeDispatcherObjectWakeAll(hdr, increment));
-
-     case InternalMutexType:
-       return(KeDispatcherObjectWakeOne(hdr, increment));
-     }
-   DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type);
-   KEBUGCHECK(0);
-   return(FALSE);
+    /* At this point, we have to do a wait, so make sure we can make the thread Alertable if requested */
+    if (Alertable) {
+    
+        /* If the Thread is Alerted, set the Wait Status accordingly */    
+        if (CurrentThread->Alerted[(int)WaitMode]) {
+            
+            CurrentThread->Alerted[(int)WaitMode] = FALSE;
+            DPRINT("Thread was Alerted\n");
+            *Status = STATUS_ALERTED;
+            
+        /* If there are User APCs Pending, then we can't really be alertable */
+        } else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) && 
+                    (WaitMode == UserMode)) {
+            
+            DPRINT("APCs are Pending\n");
+            CurrentThread->ApcState.UserApcPending = TRUE;
+            *Status = STATUS_USER_APC;
+        }
+    
+    /* If there are User APCs Pending and we are waiting in usermode, then we must notify the caller */
+    } else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode == UserMode)) {
+            DPRINT("APCs are Pending\n");
+            *Status = STATUS_USER_APC;
+    }
 }
 
 /*
  * @implemented
- */
-NTSTATUS STDCALL
-KeDelayExecutionThread (KPROCESSOR_MODE        WaitMode,
-                       BOOLEAN         Alertable,
-                       PLARGE_INTEGER  Interval)
-/*
+ *
  * FUNCTION: Puts the current thread into an alertable or nonalertable 
  * wait state for a given internal
  * ARGUMENTS:
@@ -413,27 +72,103 @@ KeDelayExecutionThread (KPROCESSOR_MODE   WaitMode,
  *          Interval = Specifies the interval to wait
  * RETURNS: Status
  */
+NTSTATUS 
+STDCALL
+KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
+                       BOOLEAN Alertable,
+                       PLARGE_INTEGER Interval)
 {
-   PKTHREAD Thread = KeGetCurrentThread();
+    PKWAIT_BLOCK TimerWaitBlock;
+    PKTIMER ThreadTimer;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    NTSTATUS Status;
 
-   KeSetTimer(&Thread->Timer, *Interval, NULL);
-   return (KeWaitForSingleObject(&Thread->Timer,
-                                (WaitMode == KernelMode) ? Executive : UserRequest, /* TMN: Was unconditionally Executive */
-                                WaitMode, /* TMN: Was UserMode */
-                                Alertable,
-                                NULL));
+    DPRINT("Entering KeDelayExecutionThread\n");
+
+    /* Check if the lock is already held */
+    if (CurrentThread->WaitNext)  {
+        
+        /* Lock is held, disable Wait Next */
+        DPRINT("Lock is held\n");
+        CurrentThread->WaitNext = FALSE;
+        
+    } else {
+        
+        /* Lock not held, acquire it */
+        DPRINT("Lock is not held, acquiring\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    }
+    
+    /* Use built-in Wait block */
+    TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
+    
+    /* Start Wait Loop */
+    do {
+    
+        /* We are going to wait no matter what (that's the point), so test Alertability */
+        KiCheckAlertability(Alertable, CurrentThread, KernelMode, &Status);
+        
+        /* Set Timer */
+        ThreadTimer = &CurrentThread->Timer;
+        
+        /* Setup the Wait Block */
+        CurrentThread->WaitBlockList = TimerWaitBlock;
+        TimerWaitBlock->Object = (PVOID)ThreadTimer;
+        TimerWaitBlock->Thread = CurrentThread;
+        TimerWaitBlock->WaitKey = (USHORT)STATUS_TIMEOUT;
+        TimerWaitBlock->WaitType = WaitAny;         
+        TimerWaitBlock->NextWaitBlock = NULL;
+    
+        /* Link the timer to this Wait Block */
+        InitializeListHead(&ThreadTimer->Header.WaitListHead);
+        InsertTailList(&ThreadTimer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
+
+        /* Insert the Timer into the Timer Lists and enable it */
+        if (!KiInsertTimer(ThreadTimer, *Interval)) {    
+
+            /* FIXME: The timer already expired, we should find a new ready thread */
+            Status = STATUS_SUCCESS;
+            break;
+        }    
+        
+        /* Handle Kernel Queues */
+        if (CurrentThread->Queue) {
+                 
+            DPRINT("Waking Queue\n");
+            KiWakeQueue(CurrentThread->Queue);
+        }
+
+        /* Block the Thread */
+        DPRINT("Blocking the Thread: %d, %d, %x\n", Alertable, WaitMode, KeGetCurrentThread());
+        KiBlockThread(&Status, 
+                      Alertable, 
+                      WaitMode, 
+                      DelayExecution);
+    
+        /* Check if we were executing an APC or if we timed out */
+        if (Status != STATUS_KERNEL_APC) {
+           
+            /* This is a good thing */
+            if (Status == STATUS_TIMEOUT) Status = STATUS_SUCCESS;
+            
+            /* Return Status */
+            return Status;
+        }
+        
+        DPRINT("Looping Again\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    
+    } while (TRUE);
+    
+    /* Release the Lock, we are done */
+    DPRINT("Returning from KeDelayExecutionThread(), %x. Status: %d\n", KeGetCurrentThread(), Status);
+    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+    return Status;   
 }
 
 /*
  * @implemented
- */
-NTSTATUS STDCALL
-KeWaitForSingleObject(PVOID Object,
-                      KWAIT_REASON WaitReason,
-                      KPROCESSOR_MODE WaitMode,
-                      BOOLEAN Alertable,
-                      PLARGE_INTEGER Timeout)
-/*
+ *
  * FUNCTION: Puts the current thread into a wait state until the
  * given dispatcher object is set to signalled
  * ARGUMENTS:
@@ -446,52 +181,174 @@ KeWaitForSingleObject(PVOID Object,
  *         Timeout = Optional timeout value
  * RETURNS: Status
  */
+NTSTATUS 
+STDCALL
+KeWaitForSingleObject(PVOID Object,
+                      KWAIT_REASON WaitReason,
+                      KPROCESSOR_MODE WaitMode,
+                      BOOLEAN Alertable,
+                      PLARGE_INTEGER Timeout)
 {
-   return KeWaitForMultipleObjects(1,
-                                   &Object,
-                                   WaitAny,
-                                   WaitReason,
-                                   WaitMode,
-                                   Alertable,
-                                   Timeout,
-                                   NULL);
-}
+    PDISPATCHER_HEADER CurrentObject;
+    PKWAIT_BLOCK WaitBlock;
+    PKWAIT_BLOCK TimerWaitBlock;
+    PKTIMER ThreadTimer;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    NTSTATUS Status;
+    NTSTATUS WaitStatus;
+
+    DPRINT("Entering KeWaitForSingleObject\n");
+   
+    /* Check if the lock is already held */
+    if (CurrentThread->WaitNext)  {
+        
+        /* Lock is held, disable Wait Next */
+        DPRINT("Lock is held\n");
+        CurrentThread->WaitNext = FALSE;
+        
+    } else {
+        
+        /* Lock not held, acquire it */
+        DPRINT("Lock is not held, acquiring\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    }
 
+    /* Start the actual Loop */
+    do {
+        
+        /* Get the current Wait Status */
+        WaitStatus = CurrentThread->WaitStatus;
+    
+        /* Append wait block to the KTHREAD wait block list */
+        CurrentThread->WaitBlockList = WaitBlock = &CurrentThread->WaitBlock[0];
+           
+        /* Get the Current Object */
+        CurrentObject = (PDISPATCHER_HEADER)Object;
+            
+        /* FIXME: 
+         * Temporary hack until my Object Manager re-write. Basically some objects, like
+         * the File Object, but also LPCs and others, are actually waitable on their event.
+         * The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
+         * by using pretty much the same kind of hack as us. Normal objects point to themselves
+         * in that pointer. Then, NtWaitForXXX will populate the WaitList that gets sent to us by
+         * using ->DefaultObject, so the proper actual objects will be sent to us. Until then however,
+         * I will keep this hack here, since there's no need to make an interim hack until the rewrite
+         * -- Alex Ionescu 24/02/05
+         */
+        if (CurrentObject->Type == IO_TYPE_FILE) {
+                   
+            DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
+            CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
+        }
 
-inline
-PVOID
-KiGetWaitableObjectFromObject(PVOID Object)
-{
-   //special case when waiting on file objects
-   if ( ((PDISPATCHER_HEADER)Object)->Type == InternalFileType)
-   {
-      return &((PFILE_OBJECT)Object)->Event;
-   }
+        /* Check if the Object is Signaled */
+        if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
+                    
+            /* Just unwait this guy and exit */
+            if (CurrentObject->SignalState != MINLONG) {
+                    
+                /* It has a normal signal state, so unwait it and return */
+                KiSatisfyObjectWait(CurrentObject, CurrentThread);
+                Status = STATUS_WAIT_0;
+                goto WaitDone;
+                    
+            } else {
+                    
+                /* Is this a Mutant? */
+                if (CurrentObject->Type == MutantObject) {
+                        
+                    /* According to wasm.ru, we must raise this exception (tested and true) */
+                    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+                    ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);                    
+                } 
+            }
+        }
+        
+        /* Set up the Wait Block */
+        WaitBlock->Object = CurrentObject;
+        WaitBlock->Thread = CurrentThread;
+        WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0);
+        WaitBlock->WaitType = WaitAny;                       
+        WaitBlock->NextWaitBlock = NULL;
+                      
+        /* Make sure we can satisfy the Alertable request */
+        KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
+    
+        /* Set the Wait Status */
+        CurrentThread->WaitStatus = Status;
+           
+        /* Enable the Timeout Timer if there was any specified */
+        if (Timeout != NULL) {
+              
+            /* However if 0 timeout was specified, then we must fail since we need to peform a wait */
+            if (!Timeout->QuadPart) {
+                
+                /* Return a timeout */
+                Status = STATUS_TIMEOUT;
+                goto WaitDone;
+            }
+                       
+            /* Point to Timer Wait Block and Thread Timer */
+            TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
+            ThreadTimer = &CurrentThread->Timer;
 
-   return Object;
-}
+            /* Connect the Timer Wait Block */
+            WaitBlock->NextWaitBlock = TimerWaitBlock;
+            
+            /* Set up the Timer Wait Block */
+            TimerWaitBlock->Object = (PVOID)ThreadTimer;
+            TimerWaitBlock->Thread = CurrentThread;
+            TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
+            TimerWaitBlock->WaitType = WaitAny;
+            TimerWaitBlock->NextWaitBlock = NULL;
+            
+            /* Link the timer to this Wait Block */
+            InitializeListHead(&ThreadTimer->Header.WaitListHead);
+            InsertTailList(&ThreadTimer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
 
+            /* Insert the Timer into the Timer Lists and enable it */
+            if (!KiInsertTimer(ThreadTimer, *Timeout)) {    
 
-inline BOOL
-KiIsObjectWaitable(PVOID Object)
-{
-    POBJECT_HEADER Header;
-    Header = BODY_TO_HEADER(Object);
-    if (Header->ObjectType == ExEventObjectType ||
-       Header->ObjectType == ExIoCompletionType ||
-       Header->ObjectType == ExMutantObjectType ||
-       Header->ObjectType == ExSemaphoreObjectType ||
-       Header->ObjectType == ExTimerType ||
-       Header->ObjectType == PsProcessType ||
-       Header->ObjectType == PsThreadType ||
-       Header->ObjectType == IoFileObjectType)
-    {
-       return TRUE;
-    }
-    else
-    {
-       return FALSE;
-    }
+                /* Return a timeout if we couldn't insert the timer for some reason */
+                Status = STATUS_TIMEOUT;
+                goto WaitDone;
+            }    
+        }
+
+        /* Link the Object to this Wait Block */
+        InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);            
+        
+        /* Handle Kernel Queues */
+        if (CurrentThread->Queue) {
+                 
+            DPRINT("Waking Queue\n");
+            KiWakeQueue(CurrentThread->Queue);
+        }
+
+        /* Block the Thread */
+        DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
+        KiBlockThread(&Status, 
+                      Alertable, 
+                      WaitMode, 
+                      (UCHAR)WaitReason);
+    
+        /* Check if we were executing an APC */
+        if (Status != STATUS_KERNEL_APC) {
+           
+            /* Return Status */
+            return Status;
+        }
+        
+        DPRINT("Looping Again\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    
+    } while (TRUE);
+    
+WaitDone:
+    /* Release the Lock, we are done */
+    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
+    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+    return Status;       
 }
 
 /*
@@ -507,558 +364,543 @@ KeWaitForMultipleObjects(ULONG Count,
                          PLARGE_INTEGER Timeout,
                          PKWAIT_BLOCK WaitBlockArray)
 {
-   DISPATCHER_HEADER *hdr;
-   PKWAIT_BLOCK blk;
-   PKTHREAD CurrentThread;
-   ULONG CountSignaled;
-   ULONG i;
-   NTSTATUS Status;
-   KIRQL OldIrql;
-   BOOLEAN Abandoned;
-   NTSTATUS WaitStatus;
-
-   DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
-          "PsGetCurrentThread() %x\n", Count, Object, PsGetCurrentThread());
-
-   ASSERT(0 < Count && Count <= MAXIMUM_WAIT_OBJECTS);
-
-   CurrentThread = KeGetCurrentThread();
-
-   /*
-    * Work out where we are going to put the wait blocks
-    */
-   if (WaitBlockArray == NULL)
-   {
-      if (Count > THREAD_WAIT_OBJECTS)
-      {
-         DPRINT("(%s:%d) Too many objects!\n", __FILE__, __LINE__);
-         return (STATUS_UNSUCCESSFUL);
-      }
-      WaitBlockArray = &CurrentThread->WaitBlock[0];
-   }
-   else
-   {
-      if (Count > MAXIMUM_WAIT_OBJECTS)
-      {
-         DPRINT("(%s:%d) Too many objects!\n", __FILE__, __LINE__);
-         return (STATUS_UNSUCCESSFUL);
-      }
-   }
-
-
-
-   /*
-    * Set up the timeout if required
-    */
-   if (Timeout != NULL && Timeout->QuadPart != 0)
-   {
-      KeSetTimer(&CurrentThread->Timer, *Timeout, NULL);
-   }
-
-   do
-   {
-      if (CurrentThread->WaitNext)
-      {
-         CurrentThread->WaitNext = FALSE;
-         OldIrql = CurrentThread->WaitIrql;
-      }
-      else
-      {
-         OldIrql = KeAcquireDispatcherDatabaseLock ();
-      }
-
-    /* Get the current Wait Status */
-    WaitStatus = CurrentThread->WaitStatus;
-   
-    if (Alertable) {
+    PDISPATCHER_HEADER CurrentObject;
+    PKWAIT_BLOCK WaitBlock;
+    PKWAIT_BLOCK TimerWaitBlock;
+    PKTIMER ThreadTimer;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    ULONG AllObjectsSignaled;
+    ULONG WaitIndex;
+    NTSTATUS Status;
+    NTSTATUS WaitStatus;
+
+    DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
+            "PsGetCurrentThread() %x, Timeout %x\n", Count, Object, PsGetCurrentThread(), Timeout);
+
+    /* Set the Current Thread */
+    CurrentThread = KeGetCurrentThread();
     
-        /* If the Thread is Alerted, set the Wait Status accordingly */    
-        if (CurrentThread->Alerted[(int)WaitMode]) {
-            
-            CurrentThread->Alerted[(int)WaitMode] = FALSE;
-            DPRINT("Thread was Alerted\n");
-            WaitStatus = STATUS_ALERTED;
-            
-        /* If there are User APCs Pending, then we can't really be alertable */
-        } else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) && 
-                   (WaitMode == UserMode)) {
+    /* Check if the lock is already held */
+    if (CurrentThread->WaitNext)  {
+        
+        /* Lock is held, disable Wait Next */
+        DPRINT("Lock is held\n");
+        CurrentThread->WaitNext = FALSE;
+        
+    } else {
+        
+        /* Lock not held, acquire it */
+        DPRINT("Lock is not held, acquiring\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    }
+
+    /* Make sure the Wait Count is valid for the Thread and Maximum Wait Objects */
+    if (!WaitBlockArray) {
+       
+        /* Check in regards to the Thread Object Limit */
+        if (Count > THREAD_WAIT_OBJECTS) {
             
-            DPRINT1("APCs are Pending\n");
-            CurrentThread->ApcState.UserApcPending = TRUE;
-            WaitStatus = STATUS_USER_APC;
+            DPRINT1("(%s:%d) Too many objects!\n", __FILE__, __LINE__);
+            KEBUGCHECK(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
         }
         
-    /* If there are User APCs Pending and we are waiting in usermode, then we must notify the caller */
-    } else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode == UserMode)) {
-            DPRINT1("APCs are Pending\n");
-            WaitStatus = STATUS_USER_APC;
+        /* Use the Thread's Wait Block */
+        WaitBlockArray = &CurrentThread->WaitBlock[0];
+        
+    } else {
+      
+        /* Using our own Block Array. Check in regards to System Object Limit */
+        if (Count > MAXIMUM_WAIT_OBJECTS) {
+            
+            DPRINT1("(%s:%d) Too many objects!\n", __FILE__, __LINE__);
+            KEBUGCHECK(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
+        }
     }
-
-      /*
-       * Check if the wait is (already) satisfied
-       */
-      CountSignaled = 0;
-      Abandoned = FALSE;
-      for (i = 0; i < Count; i++)
-      {
-         hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]);
-
-         if (KiIsObjectSignalled(hdr, CurrentThread))
-         {
-            CountSignaled++;
-
-            if (WaitType == WaitAny)
-            {
-               Abandoned = KiSideEffectsBeforeWake(hdr, CurrentThread) ? TRUE : Abandoned;
-
-               KeReleaseDispatcherDatabaseLock(OldIrql);               
-               
-               if (Timeout != NULL && Timeout->QuadPart != 0)
-               {
-                  KeCancelTimer(&CurrentThread->Timer);
-               }
-
-               DPRINT("One object is (already) signaled!\n");
-               if (Abandoned == TRUE)
-               {
-                  return (STATUS_ABANDONED_WAIT_0 + i);
-               }
-
-               return (STATUS_WAIT_0 + i);
+    
+    /* Start the actual Loop */
+    do {
+        
+        /* Get the current Wait Status */
+        WaitStatus = CurrentThread->WaitStatus;
+    
+        /* Append wait block to the KTHREAD wait block list */
+        CurrentThread->WaitBlockList = WaitBlock = WaitBlockArray;
+      
+        /* Check if the wait is (already) satisfied */
+        AllObjectsSignaled = TRUE;
+        
+        /* First, we'll try to satisfy the wait directly */
+        for (WaitIndex = 0; WaitIndex < Count; WaitIndex++) {
+            
+            /* Get the Current Object */
+            CurrentObject = (PDISPATCHER_HEADER)Object[WaitIndex];
+            
+            /* FIXME: 
+             * Temporary hack until my Object Manager re-write. Basically some objects, like
+             * the File Object, but also LPCs and others, are actually waitable on their event.
+             * The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
+             * by using pretty much the same kind of hack as us. Normal objects point to themselves
+             * in that pointer. Then, NtWaitForXXX will populate the WaitList that gets sent to us by
+             * using ->DefaultObject, so the proper actual objects will be sent to us. Until then however,
+             * I will keep this hack here, since there's no need to make an interim hack until the rewrite
+             * -- Alex Ionescu 24/02/05
+             */
+            if (CurrentObject->Type == IO_TYPE_FILE) {
+                   
+                DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
+                CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
             }
-         }
-      }
-
-      Abandoned = FALSE;
-      if ((WaitType == WaitAll) && (CountSignaled == Count))
-      {
-         for (i = 0; i < Count; i++)
-         {
-            hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]);
-            Abandoned = KiSideEffectsBeforeWake(hdr, CurrentThread) ? TRUE : Abandoned;
-         }
 
-         KeReleaseDispatcherDatabaseLock(OldIrql);
-         
-         if (Timeout != NULL && Timeout->QuadPart != 0)
-         {
-            KeCancelTimer(&CurrentThread->Timer);
-         }
-
-         DPRINT("All objects are (already) signaled!\n");
-
-         if (Abandoned == TRUE)
-         {
-            return (STATUS_ABANDONED_WAIT_0);
-         }
+            /* Check if the Object is Signaled */
+            if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
+                
+                /* Check what kind of wait this is */ 
+                if (WaitType == WaitAny) {
+                    
+                    /* This is a Wait Any, so just unwait this guy and exit */
+                    if (CurrentObject->SignalState != MINLONG) {
+                        
+                        /* It has a normal signal state, so unwait it and return */
+                        KiSatisfyObjectWait(CurrentObject, CurrentThread);
+                        Status = STATUS_WAIT_0 | WaitIndex;
+                        goto WaitDone;
+                        
+                    } else {
+                        
+                        /* Is this a Mutant? */
+                        if (CurrentObject->Type == MutantObject) {
+                            
+                            /* According to wasm.ru, we must raise this exception (tested and true) */
+                            KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+                            ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);                    
+                        } 
+                    }
+                }
+                
+            } else {
+                    
+                /* One of the objects isn't signaled... if this is a WaitAll, we will fail later */
+                AllObjectsSignaled = FALSE;
+            }
 
-         return (STATUS_WAIT_0);
-      }
+            /* Set up a Wait Block for this Object */
+            WaitBlock->Object = CurrentObject;
+            WaitBlock->Thread = CurrentThread;
+            WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0 + WaitIndex);
+            WaitBlock->WaitType = (USHORT)WaitType;                       
+            WaitBlock->NextWaitBlock = WaitBlock + 1;
+                
+            /* Move to the next Wait Block */
+            WaitBlock = WaitBlock->NextWaitBlock;
+        }
+       
+        /* Return to the Root Wait Block */
+        WaitBlock--;
+        WaitBlock->NextWaitBlock = NULL;
+            
+        /* Check if this is a Wait All and all the objects are signaled */
+        if ((WaitType == WaitAll) && (AllObjectsSignaled)) {
+                                
+            /* Return to the Root Wait Block */
+            WaitBlock = CurrentThread->WaitBlockList;
+            
+            /* Satisfy their Waits and return to the caller */
+            KiSatisifyMultipleObjectWaits(WaitBlock);
+            Status = STATUS_WAIT_0;
+            goto WaitDone;
+        }
+   
+        /* Make sure we can satisfy the Alertable request */
+        KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
+    
+        /* Set the Wait Status */
+        CurrentThread->WaitStatus = Status;
+           
+        /* Enable the Timeout Timer if there was any specified */
+        if (Timeout != NULL) {
+              
+            /* However if 0 timeout was specified, then we must fail since we need to peform a wait */
+            if (!Timeout->QuadPart) {
+                
+                /* Return a timeout */
+                Status = STATUS_TIMEOUT;
+                goto WaitDone;
+            }
+            
+            /* Point to Timer Wait Block and Thread Timer */
+            TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
+            ThreadTimer = &CurrentThread->Timer;
 
-      //zero timeout is used for testing if the object(s) can be immediately acquired
-      if (Timeout != NULL && Timeout->QuadPart == 0)
-      {
-         KeReleaseDispatcherDatabaseLock(OldIrql);
-         return STATUS_TIMEOUT;
-      }
+            /* Connect the Timer Wait Block */
+            WaitBlock->NextWaitBlock = TimerWaitBlock;
+            
+            /* Set up the Timer Wait Block */
+            TimerWaitBlock->Object = (PVOID)ThreadTimer;
+            TimerWaitBlock->Thread = CurrentThread;
+            TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
+            TimerWaitBlock->WaitType = WaitAny;
+            TimerWaitBlock->NextWaitBlock = NULL;
+            
+            /* Link the timer to this Wait Block */
+            InitializeListHead(&ThreadTimer->Header.WaitListHead);
 
-      /*
-       * Check if we have already timed out
-       */
-      if (Timeout != NULL && KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread))
-      {
-         KiSideEffectsBeforeWake(&CurrentThread->Timer.Header, CurrentThread);
-         KeReleaseDispatcherDatabaseLock(OldIrql);
-         KeCancelTimer(&CurrentThread->Timer);
-         return (STATUS_TIMEOUT);
-      }
+            /* Insert the Timer into the Timer Lists and enable it */
+            if (!KiInsertTimer(ThreadTimer, *Timeout)) {    
 
-      /* Append wait block to the KTHREAD wait block list */
-      CurrentThread->WaitBlockList = blk = WaitBlockArray;
+                /* Return a timeout if we couldn't insert the timer for some reason */
+                Status = STATUS_TIMEOUT;
+                goto WaitDone;
+            }
+        }
 
-      /*
-       * Set up the wait
-       */
-      CurrentThread->WaitStatus = WaitStatus;;
+        /* Insert into Object's Wait List*/
+        WaitBlock = CurrentThread->WaitBlockList;
+        while (WaitBlock) {
+            
+            /* Get the Current Object */
+            CurrentObject = WaitBlock->Object;
+    
+            /* Link the Object to this Wait Block */
+            InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
+            
+            /* Move to the next Wait Block */
+            WaitBlock = WaitBlock->NextWaitBlock;
+        }
+        
+        /* Handle Kernel Queues */
+        if (CurrentThread->Queue) {
+                 
+            DPRINT("Waking Queue\n");
+            KiWakeQueue(CurrentThread->Queue);
+        }
 
-      for (i = 0; i < Count; i++)
-      {
-         hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]);
+        /* Block the Thread */
+        DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
+        KiBlockThread(&Status, 
+                      Alertable, 
+                      WaitMode,
+                      (UCHAR)WaitReason);
+    
+        /* Check if we were executing an APC */
+        if (Status != STATUS_KERNEL_APC) {
+           
+            /* Return Status */
+            return Status;
+        }
+        
+        DPRINT("Looping Again\n");
+        CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
+    
+    } while (TRUE);
+    
+WaitDone:
+    /* Release the Lock, we are done */
+    DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
+    KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
+    return Status;
+}
 
-         blk->Object = KiGetWaitableObjectFromObject(Object[i]);
-         blk->Thread = CurrentThread;
-         blk->WaitKey = (USHORT)(STATUS_WAIT_0 + i);
-         blk->WaitType = (USHORT)WaitType;
+VOID
+FASTCALL
+KiSatisfyObjectWait(PDISPATCHER_HEADER Object,
+                    PKTHREAD Thread)
 
-         if (i == (Count - 1))
-         {
-            if (Timeout != NULL)
-            {
-               blk->NextWaitBlock = &CurrentThread->WaitBlock[3];
-            }
-            else
-            {
-               blk->NextWaitBlock = NULL;
+{
+    /* Special case for Mutants */
+    if (Object->Type == MutantObject) {
+     
+        /* Decrease the Signal State */
+        Object->SignalState--;
+        
+        /* Check if it's now non-signaled */
+        if (Object->SignalState == 0) {
+        
+            /* Set the Owner Thread */
+            ((PKMUTANT)Object)->OwnerThread = Thread;
+            
+            /* Disable APCs if needed */
+            Thread->KernelApcDisable -= ((PKMUTANT)Object)->ApcDisable;
+            
+            /* Check if it's abandoned */
+            if (((PKMUTANT)Object)->Abandoned) {
+            
+                /* Unabandon it */
+                ((PKMUTANT)Object)->Abandoned = FALSE;
+                
+                /* Return Status */
+                Thread->WaitStatus = STATUS_ABANDONED;
             }
-         }
-         else
-         {
-            blk->NextWaitBlock = blk + 1;
-         }
-
-         /*
-          * add wait block to disp. obj. wait list
-          * Use FIFO for all waits except for queues which use LIFO
-          */
-         if (WaitReason == WrQueue)
-         {
-            InsertHeadList(&hdr->WaitListHead, &blk->WaitListEntry);
-         }
-         else
-         {
-            InsertTailList(&hdr->WaitListHead, &blk->WaitListEntry);
-         }
-
-         blk = blk->NextWaitBlock;
-      }
+            
+            /* Insert it into the Mutant List */
+            InsertHeadList(&Thread->MutantListHead, &((PKMUTANT)Object)->MutantListEntry);
+        }
+    
+    } else if ((Object->Type & TIMER_OR_EVENT_TYPE) == EventSynchronizationObject) {
+    
+        /* These guys (Syncronization Timers and Events) just get un-signaled */
+        Object->SignalState = 0;
+        
+    } else if (Object->Type == SemaphoreObject) {
 
-      if (Timeout != NULL)
-      {
-         CurrentThread->WaitBlock[3].Object = (PVOID) & CurrentThread->Timer;
-         CurrentThread->WaitBlock[3].Thread = CurrentThread;
-         CurrentThread->WaitBlock[3].WaitKey = STATUS_TIMEOUT;
-         CurrentThread->WaitBlock[3].WaitType = WaitAny;
-         CurrentThread->WaitBlock[3].NextWaitBlock = NULL;
+        /* These ones can have multiple signalings, so we only decrease it */
+        Object->SignalState--;
+    } 
+}
 
-         InsertTailList(&CurrentThread->Timer.Header.WaitListHead,
-                        &CurrentThread->WaitBlock[3].WaitListEntry);
-      }
+VOID
+FASTCALL
+KiWaitTest(PDISPATCHER_HEADER Object,
+           KPRIORITY Increment)
+{
+    PLIST_ENTRY WaitEntry;
+    PLIST_ENTRY WaitList;
+    PKWAIT_BLOCK CurrentWaitBlock;
+    PKWAIT_BLOCK NextWaitBlock;
+    
+    /* Loop the Wait Entries */
+    DPRINT("KiWaitTest for Object: %x\n", Object);
+    WaitList = &Object->WaitListHead;
+    WaitEntry = WaitList->Flink;
+    while ((WaitEntry != WaitList) && (Object->SignalState > 0)) {
+        
+        /* Get the current wait block */
+        CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
+        
+        /* Check the current Wait Mode */
+        if (CurrentWaitBlock->WaitType == WaitAny) {
+        
+            /* Easy case, satisfy only this wait */
+            DPRINT("Satisfiying a Wait any\n");
+            WaitEntry = WaitEntry->Blink;
+            KiSatisfyObjectWait(Object, CurrentWaitBlock->Thread);
+        
+        } else {
+        
+            /* Everything must be satisfied */
+            DPRINT("Checking for a Wait All\n");
+            NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
+            
+            /* Loop first to make sure they are valid */
+            while (NextWaitBlock) {
+            
+                /* Check if the object is signaled */
+                if (!KiIsObjectSignaled(Object, CurrentWaitBlock->Thread)) {
+                
+                    /* It's not, move to the next one */
+                    DPRINT1("One of the object is non-signaled, sorry.\n");
+                    goto SkipUnwait;
+                }
+                
+                /* Go to the next Wait block */
+                NextWaitBlock = NextWaitBlock->NextWaitBlock;
+            }
+                       
+            /* All the objects are signaled, we can satisfy */
+            DPRINT("Satisfiying a Wait All\n");
+            WaitEntry = WaitEntry->Blink;
+            KiSatisifyMultipleObjectWaits(CurrentWaitBlock);
+        }
+        
+        /* All waits satisfied, unwait the thread */
+        DPRINT("Unwaiting the Thread\n");
+        KiAbortWaitThread(CurrentWaitBlock->Thread, CurrentWaitBlock->WaitKey, Increment);
 
-      //kernel queues
-      if (CurrentThread->Queue && WaitReason != WrQueue)
-      {
-         DPRINT("queue: sleep on something else\n");
-         CurrentThread->Queue->CurrentCount--;  
-         
-         //wake another thread
-         if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
-             !IsListEmpty(&CurrentThread->Queue->EntryListHead))
-         {
-            KiDispatcherObjectWake(&CurrentThread->Queue->Header, IO_NO_INCREMENT);
-         }
-      }
+SkipUnwait:
+        /* Next entry */
+        WaitEntry = WaitEntry->Flink;
+    }
+    
+    DPRINT("Done\n");
+}               
 
-      PsBlockThread(&Status, Alertable, WaitMode, TRUE, OldIrql, (UCHAR)WaitReason);
+/* Must be called with the dispatcher lock held */
+VOID
+FASTCALL 
+KiAbortWaitThread(PKTHREAD Thread, 
+                  NTSTATUS WaitStatus,
+                  KPRIORITY Increment)
+{
+    PKWAIT_BLOCK WaitBlock;
 
-      //kernel queues
-      OldIrql = KeAcquireDispatcherDatabaseLock ();
-      if (CurrentThread->Queue && WaitReason != WrQueue)
-      {
-         DPRINT("queue: wake from something else\n");
-         CurrentThread->Queue->CurrentCount++;
-      }
-      if (Status == STATUS_KERNEL_APC)
-      {
-         CurrentThread->WaitNext = TRUE;
-         CurrentThread->WaitIrql = OldIrql;
-      }
-      else
-      {
-         KeReleaseDispatcherDatabaseLock(OldIrql);
-      }
-      
-   } while (Status == STATUS_KERNEL_APC);
-   
+    /* If we are blocked, we must be waiting on something also */
+    DPRINT("KiAbortWaitThread: %x, Status: %x, %x \n", Thread, WaitStatus, Thread->WaitBlockList);
+    ASSERT((Thread->State == THREAD_STATE_BLOCKED) == (Thread->WaitBlockList != NULL));
 
-   if (Timeout != NULL)
-   {
-      KeCancelTimer(&CurrentThread->Timer);
-   }
+    /* Remove the Wait Blocks from the list */
+    DPRINT("Removing waits\n");
+    WaitBlock = Thread->WaitBlockList;
+    while (WaitBlock) {
+        
+        /* Remove it */
+        DPRINT("Removing Waitblock: %x, %x\n", WaitBlock, WaitBlock->NextWaitBlock);
+        RemoveEntryList(&WaitBlock->WaitListEntry);
+        
+        /* Go to the next one */
+        WaitBlock = WaitBlock->NextWaitBlock;
+    };
+    
+    /* Check if there's a Thread Timer */
+    if (Thread->Timer.Header.Inserted) {
+    
+        /* Cancel the Thread Timer with the no-lock fastpath */
+        DPRINT("Removing the Thread's Timer\n");
+        Thread->Timer.Header.Inserted = FALSE;
+        RemoveEntryList(&Thread->Timer.TimerListEntry);
+    }
+    
+    /* Increment the Queue's active threads */
+    if (Thread->Queue) {
+    
+        DPRINT("Incrementing Queue's active threads\n");
+        Thread->Queue->CurrentCount++;
+    }
 
-   DPRINT("Returning from KeWaitForMultipleObjects()\n");
-   return (Status);
+    /* Reschedule the Thread */
+    DPRINT("Unblocking the Thread\n");
+    KiUnblockThread(Thread, &WaitStatus, 0);
 }
 
-VOID KeInitializeDispatcher(VOID)
+BOOLEAN
+inline
+FASTCALL
+KiIsObjectSignaled(PDISPATCHER_HEADER Object,
+                   PKTHREAD Thread)
 {
-   KeInitializeSpinLock(&DispatcherDatabaseLock);
+    /* Mutants are...well...mutants! */
+   if (Object->Type == MutantObject) {
+
+        /* 
+         * Because Cutler hates mutants, they are actually signaled if the Signal State is <= 0
+         * Well, only if they are recursivly acquired (i.e if we own it right now).
+         * Of course, they are also signaled if their signal state is 1.
+         */
+        if ((Object->SignalState <= 0 && ((PKMUTANT)Object)->OwnerThread == Thread) || 
+            (Object->SignalState == 1)) {
+            
+            /* Signaled Mutant */
+            return (TRUE);
+            
+        } else {
+            
+            /* Unsignaled Mutant */
+            return (FALSE);
+        }
+    }
+    
+    /* Any other object is not a mutated freak, so let's use logic */
+   return (!Object->SignalState <= 0);
 }
 
-NTSTATUS STDCALL
-NtWaitForMultipleObjects(IN ULONG ObjectCount,
-                        IN PHANDLE ObjectsArray,
-                        IN WAIT_TYPE WaitType,
-                        IN BOOLEAN Alertable,
-                        IN PLARGE_INTEGER TimeOut  OPTIONAL)
+BOOL
+inline
+FASTCALL
+KiIsObjectWaitable(PVOID Object)
 {
-   KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
-   HANDLE SafeObjectsArray[MAXIMUM_WAIT_OBJECTS];
-   PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
-   ULONG i, j;
-   KPROCESSOR_MODE PreviousMode;
-   LARGE_INTEGER SafeTimeOut;
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   DPRINT("NtWaitForMultipleObjects(ObjectCount %lu ObjectsArray[] %x, Alertable %d, "
-         "TimeOut %x)\n", ObjectCount,ObjectsArray,Alertable,TimeOut);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if (ObjectCount > MAXIMUM_WAIT_OBJECTS)
-     return STATUS_UNSUCCESSFUL;
-   if (0 == ObjectCount)
-     return STATUS_INVALID_PARAMETER;
-
-   if(PreviousMode != KernelMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForRead(ObjectsArray,
-                    ObjectCount * sizeof(ObjectsArray[0]),
-                    sizeof(ULONG));
-       /* make a copy so we don't have to guard with SEH later and keep track of
-          what objects we referenced in case dereferencing pointers suddenly fails */
-       RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount * sizeof(ObjectsArray[0]));
-       ObjectsArray = SafeObjectsArray;
-       
-       if(TimeOut != NULL)
-       {
-         ProbeForRead(TimeOut,
-                      sizeof(LARGE_INTEGER),
-                      sizeof(ULONG));
-         /* make a local copy of the timeout on the stack */
-         SafeTimeOut = *TimeOut;
-         TimeOut = &SafeTimeOut;
-       }
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   /* reference all objects */
-   for (i = 0; i < ObjectCount; i++)
-     {
-        Status = ObReferenceObjectByHandle(ObjectsArray[i],
-                                           SYNCHRONIZE,
-                                           NULL,
-                                           PreviousMode,
-                                           &ObjectPtrArray[i],
-                                           NULL);
-        if (!NT_SUCCESS(Status) || !KiIsObjectWaitable(ObjectPtrArray[i]))
-          {
-             if (NT_SUCCESS(Status))
-              {
-                DPRINT1("Waiting for object type '%wZ' is not supported\n", 
-                        &BODY_TO_HEADER(ObjectPtrArray[i])->ObjectType->TypeName);
-                Status = STATUS_HANDLE_NOT_WAITABLE;
-                i++;
-              }
-             /* dereference all referenced objects */
-             for (j = 0; j < i; j++)
-               {
-                  ObDereferenceObject(ObjectPtrArray[j]);
-               }
-
-             return(Status);
-          }
-     }
-
-   Status = KeWaitForMultipleObjects(ObjectCount,
-                                     ObjectPtrArray,
-                                     WaitType,
-                                     UserRequest,
-                                     PreviousMode,
-                                     Alertable,
-                                    TimeOut,
-                                     WaitBlockArray);
-
-   /* dereference all objects */
-   for (i = 0; i < ObjectCount; i++)
-     {
-        ObDereferenceObject(ObjectPtrArray[i]);
-     }
-
-   return(Status);
+    POBJECT_HEADER Header;
+    Header = BODY_TO_HEADER(Object);
+    
+    if (Header->ObjectType == ExEventObjectType ||
+        Header->ObjectType == ExIoCompletionType ||
+        Header->ObjectType == ExMutantObjectType ||
+        Header->ObjectType == ExSemaphoreObjectType ||
+        Header->ObjectType == ExTimerType ||
+        Header->ObjectType == PsProcessType ||
+        Header->ObjectType == PsThreadType ||
+        Header->ObjectType == IoFileObjectType) {
+        
+        return TRUE;
+    
+    } else {
+        
+        return FALSE;
+    }
 }
 
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-NtWaitForSingleObject(IN HANDLE ObjectHandle,
-                     IN BOOLEAN Alertable,
-                     IN PLARGE_INTEGER TimeOut  OPTIONAL)
+VOID
+inline
+FASTCALL
+KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock)
 {
-   PVOID ObjectPtr;
-   KPROCESSOR_MODE PreviousMode;
-   LARGE_INTEGER SafeTimeOut;
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n",
-         ObjectHandle,Alertable,TimeOut);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   if(TimeOut != NULL && PreviousMode != KernelMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForRead(TimeOut,
-                    sizeof(LARGE_INTEGER),
-                    sizeof(ULONG));
-       /* make a copy on the stack */
-       SafeTimeOut = *TimeOut;
-       TimeOut = &SafeTimeOut;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObReferenceObjectByHandle(ObjectHandle,
-                                     SYNCHRONIZE,
-                                     NULL,
-                                     PreviousMode,
-                                     &ObjectPtr,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   if (!KiIsObjectWaitable(ObjectPtr))
-     {
-       DPRINT1("Waiting for object type '%wZ' is not supported\n", 
-              &BODY_TO_HEADER(ObjectPtr)->ObjectType->TypeName);
-       Status = STATUS_HANDLE_NOT_WAITABLE;
-     }
-   else
-     {
-       Status = KeWaitForSingleObject(ObjectPtr,
-                                     UserRequest,
-                                     PreviousMode,
-                                     Alertable,
-                                     TimeOut);
-     }
-
-   ObDereferenceObject(ObjectPtr);
-
-   return(Status);
+    PKTHREAD WaitThread = WaitBlock->Thread;
+    
+    /* Loop through all the Wait Blocks, and wake each Object */
+    while (WaitBlock) {
+         
+        /* Wake the Object */
+        KiSatisfyObjectWait(WaitBlock->Object, WaitThread);
+        WaitBlock = WaitBlock->NextWaitBlock;
+    }      
 }
 
-
-NTSTATUS STDCALL
-NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
-                              IN HANDLE WaitableObjectHandle,
-                              IN BOOLEAN Alertable,
-                              IN PLARGE_INTEGER TimeOut  OPTIONAL)
+VOID
+inline
+FASTCALL
+KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
+                             ULONG Type,
+                             ULONG Size,
+                             ULONG SignalState)
 {
-   KPROCESSOR_MODE PreviousMode;
-   DISPATCHER_HEADER* hdr;
-   PVOID SignalObj;
-   PVOID WaitObj;
-   LARGE_INTEGER SafeTimeOut;
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   PreviousMode = ExGetPreviousMode();
-   
-   if(TimeOut != NULL && PreviousMode != KernelMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForRead(TimeOut,
-                    sizeof(LARGE_INTEGER),
-                    sizeof(ULONG));
-       /* make a copy on the stack */
-       SafeTimeOut = *TimeOut;
-       TimeOut = &SafeTimeOut;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-   
-   Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
-                                     0,
-                                     NULL,
-                                     PreviousMode,
-                                     &SignalObj,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   Status = ObReferenceObjectByHandle(WaitableObjectHandle,
-                                     SYNCHRONIZE,
-                                     NULL,
-                                     PreviousMode,
-                                     &WaitObj,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       ObDereferenceObject(SignalObj);
-       return Status;
-     }
-
-   hdr = (DISPATCHER_HEADER *)SignalObj;
-   switch (hdr->Type)
-     {
-      case InternalNotificationEvent:
-      case InternalSynchronizationEvent:
-       KeSetEvent(SignalObj,
-                  EVENT_INCREMENT,
-                  TRUE);
-       break;
+    Header->Type = (UCHAR)Type;
+    Header->Absolute = 0;
+    Header->Inserted = 0;
+    Header->Size = (UCHAR)Size;
+    Header->SignalState = SignalState;
+    InitializeListHead(&(Header->WaitListHead));
+}
 
-      case InternalMutexType:
-       KeReleaseMutex(SignalObj,
-                      TRUE);
-       break;
+KIRQL
+inline
+FASTCALL
+KeAcquireDispatcherDatabaseLock(VOID)
+{
+    KIRQL OldIrql;
 
-      case InternalSemaphoreType:
-       KeReleaseSemaphore(SignalObj,
-                          SEMAPHORE_INCREMENT,
-                          1,
-                          TRUE);
-       break;
+    KeAcquireSpinLock (&DispatcherDatabaseLock, &OldIrql);
+    return OldIrql;
+}
 
-      default:
-       ObDereferenceObject(SignalObj);
-       ObDereferenceObject(WaitObj);
-       return STATUS_OBJECT_TYPE_MISMATCH;
-     }
+VOID
+inline
+FASTCALL
+KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID)
+{
+    KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
+}
 
-   Status = KeWaitForSingleObject(WaitObj,
-                                 UserRequest,
-                                 PreviousMode,
-                                 Alertable,
-                                 TimeOut);
+VOID 
+inline
+FASTCALL
+KeInitializeDispatcher(VOID)
+{
+    /* Initialize the Dispatcher Lock */
+    KeInitializeSpinLock(&DispatcherDatabaseLock);
+}
 
-   ObDereferenceObject(SignalObj);
-   ObDereferenceObject(WaitObj);
+VOID
+inline
+FASTCALL
+KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
+{
+    /* If it's the idle thread, dispatch */
+    if (!KeIsExecutingDpc() && OldIrql < DISPATCH_LEVEL && KeGetCurrentThread() != NULL && 
+        KeGetCurrentThread() == KeGetCurrentPrcb()->IdleThread) {
+        
+        KiDispatchThreadNoLock(THREAD_STATE_READY);
+        KeLowerIrql(OldIrql);
+        
+    } else {
+        
+        /* Just release the spin lock */
+        KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
+    }
+}
 
-   return Status;
+VOID
+inline
+FASTCALL
+KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID)
+{
+    KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
 }
+
+/* EOF */
index 7b0d535..aaddd44 100644 (file)
 
 /* INCLUDES *****************************************************************/
 
+
 #include <ntoskrnl.h>
+
 #define NDEBUG
 #include <internal/debug.h>
 
 
-/* MACROS ******************************************************************/
-
-#define DENORMALIZE(x,addr) {if(x) x=(VOID*)((ULONG)(x)-(ULONG)(addr));}
-#define ALIGN(x,align)      (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
-
-
-/* FUNCTIONS *****************************************************************/
-
-static NTSTATUS
-LdrpMapProcessImage(PHANDLE SectionHandle,
-                   PUNICODE_STRING ImagePath)
-{
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  IO_STATUS_BLOCK IoStatusBlock;
-  HANDLE FileHandle;
-  NTSTATUS Status;
-
-  /* Open image file */
-  InitializeObjectAttributes(&ObjectAttributes,
-                            ImagePath,
-                            OBJ_CASE_INSENSITIVE,
-                            NULL,
-                            NULL);
-
-  DPRINT("Opening image file %S\n", ObjectAttributes.ObjectName->Buffer);
-  Status = NtOpenFile(&FileHandle,
-                     FILE_ALL_ACCESS,
-                     &ObjectAttributes,
-                     &IoStatusBlock,
-                     0,
-                     FILE_SYNCHRONOUS_IO_ALERT);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  /* Create a section for the image */
-  DPRINT("Creating section\n");
-  Status = NtCreateSection(SectionHandle,
-                          SECTION_ALL_ACCESS,
-                          NULL,
-                          NULL,
-                          PAGE_READWRITE,
-                          SEC_COMMIT | SEC_IMAGE,
-                          FileHandle);
-  NtClose(FileHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("NtCreateSection() failed (Status %lx)\n", Status);
-    }
-
-  return(Status);
-}
-
-
-static NTSTATUS
-LdrpCreateProcessEnvironment(HANDLE ProcessHandle,
-                            PUNICODE_STRING ImagePath,
-                            PVOID* ImageBaseAddress)
-{
-  PRTL_USER_PROCESS_PARAMETERS LocalPpb;
-  PRTL_USER_PROCESS_PARAMETERS ProcessPpb;
-  ULONG BytesWritten;
-  ULONG Offset;
-  ULONG Size;
-  ULONG RegionSize;
-  NTSTATUS Status;
-
-  /* Calculate the PPB size */
-  Size = sizeof(RTL_USER_PROCESS_PARAMETERS);
-  Size += ALIGN(ImagePath->Length + sizeof(WCHAR), sizeof(ULONG));
-  RegionSize = ROUND_UP(Size, PAGE_SIZE);
-  DPRINT("Size %lu  RegionSize %lu\n", Size, RegionSize);
-
-  /* Allocate the local PPB */
-  LocalPpb = NULL;
-  Status = NtAllocateVirtualMemory(NtCurrentProcess(),
-                                  (PVOID*)&LocalPpb,
-                                  0,
-                                  &RegionSize,
-                                  MEM_RESERVE | MEM_COMMIT,
-                                  PAGE_READWRITE);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  DPRINT("LocalPpb %p  AllocationSize %lu\n", LocalPpb, RegionSize);
-
-  /* Initialize the local PPB */
-  RtlZeroMemory(LocalPpb,
-               RegionSize);
-  LocalPpb->AllocationSize = RegionSize;
-  LocalPpb->Size = Size;
-  LocalPpb->ImagePathName.Length = ImagePath->Length;
-  LocalPpb->ImagePathName.MaximumLength = ImagePath->Length + sizeof(WCHAR);
-  LocalPpb->ImagePathName.Buffer = (PWCHAR)(LocalPpb + 1);
-
-  /* Copy image path */
-  RtlCopyMemory(LocalPpb->ImagePathName.Buffer,
-               ImagePath->Buffer,
-               ImagePath->Length);
-  LocalPpb->ImagePathName.Buffer[ImagePath->Length / sizeof(WCHAR)] = L'\0';
-
-  /* Denormalize the process parameter block */
-  DENORMALIZE(LocalPpb->ImagePathName.Buffer, LocalPpb);
-  LocalPpb->Flags &= ~PPF_NORMALIZED;
-
-  /* Create the process PPB */
-  ProcessPpb = NULL;
-  Status = NtAllocateVirtualMemory(ProcessHandle,
-                                  (PVOID*)&ProcessPpb,
-                                  0,
-                                  &RegionSize,
-                                  MEM_RESERVE | MEM_COMMIT,
-                                  PAGE_READWRITE);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
-
-      /* Release the local PPB */
-      RegionSize = 0;
-      NtFreeVirtualMemory(NtCurrentProcess(),
-                         (PVOID*)&LocalPpb,
-                         &RegionSize,
-                         MEM_RELEASE);
-      return(Status);
-    }
-
-  /* Copy local PPB into the process PPB */
-  NtWriteVirtualMemory(ProcessHandle,
-                      ProcessPpb,
-                      LocalPpb,
-                      LocalPpb->AllocationSize,
-                      &BytesWritten);
-
-  /* Update pointer to process PPB in the process PEB */
-  Offset = FIELD_OFFSET(PEB, ProcessParameters);
-  NtWriteVirtualMemory(ProcessHandle,
-                      (PVOID)(PEB_BASE + Offset),
-                      &ProcessPpb,
-                      sizeof(ProcessPpb),
-                      &BytesWritten);
-
-  /* Release local PPB */
-  RegionSize = 0;
-  NtFreeVirtualMemory(NtCurrentProcess(),
-                     (PVOID*)&LocalPpb,
-                     &RegionSize,
-                     MEM_RELEASE);
-
-  /* Read image base address. */
-  Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
-  NtReadVirtualMemory(ProcessHandle,
-                     (PVOID)(PEB_BASE + Offset),
-                     ImageBaseAddress,
-                     sizeof(PVOID),
-                     &BytesWritten);
-
-  return(STATUS_SUCCESS);
-}
-
-/*
- FIXME: this sucks. Sucks sucks sucks. This code was duplicated, if you can
- believe it, in four different places - excluding this, and twice in the two
- DLLs that contained it (kernel32.dll and ntdll.dll). As much as I'd like to
- rip the whole RTL out of ntdll.dll and ntoskrnl.exe and into its own static
- library, ntoskrnl.exe is built separatedly from the rest of ReactOS, coming
- with its own linker scripts and specifications, and, save for changes and fixes
- to make it at least compile, I'm not going to touch any of it. If you feel
- brave enough, you're welcome [KJK::Hyperion]
-*/
-static NTSTATUS LdrpCreateStack
-(
- HANDLE ProcessHandle,
- PINITIAL_TEB InitialTeb,
- PULONG_PTR StackReserve,
- PULONG_PTR StackCommit
-)
+/* 
+ * HACK! No matter what i did, i couldnt get it working when i put these into ntos\rtl.h
+ * (got redefinition problems, since ntdll\rtl.h somehow include ntos\rtl.h).
+ * We need to merge ntos\rtl.h and ntdll\rtl.h to get this working. -Gunnar
+ */
+typedef struct _RTL_PROCESS_INFO
 {
- PVOID pStackLowest = NULL;
- ULONG_PTR nSize = 0;
- NTSTATUS nErrCode;
-
- if(StackReserve == NULL || StackCommit == NULL)
-  return STATUS_INVALID_PARAMETER;
-
- /* FIXME: no SEH, no guard pages */
- *StackCommit = *StackReserve;
-
- InitialTeb->StackBase = NULL;
- InitialTeb->StackLimit =  NULL;
- InitialTeb->StackCommit = NULL;
- InitialTeb->StackCommitMax = NULL;
- InitialTeb->StackReserved = NULL;
-
- /* FIXME: this code assumes a stack growing downwards */
- /* fixed stack */
- if(*StackCommit == *StackReserve)
- {
-  DPRINT("Fixed stack\n");
-
-  InitialTeb->StackLimit = NULL;
-
-  /* allocate the stack */
-  nErrCode = NtAllocateVirtualMemory
-  (
-   ProcessHandle,
-   &(InitialTeb->StackLimit),
-   0,
-   StackReserve,
-   MEM_RESERVE | MEM_COMMIT,
-   PAGE_READWRITE
-  );
-
-  /* failure */
-  if(!NT_SUCCESS(nErrCode)) return nErrCode;
-
-  /* store the highest (first) address of the stack */
-  InitialTeb->StackBase =
-   (PUCHAR)(InitialTeb->StackLimit) + *StackReserve;
- }
- /* expandable stack */
- else
- {
-  ULONG_PTR nGuardSize = PAGE_SIZE;
-  PVOID pGuardBase;
-
-  DPRINT("Expandable stack\n");
-
-  InitialTeb->StackLimit = NULL;
-  InitialTeb->StackBase = NULL;
-  InitialTeb->StackReserved = NULL;
-
-  /* reserve the stack */
-  nErrCode = NtAllocateVirtualMemory
-  (
-   ProcessHandle,
-   &(InitialTeb->StackReserved),
-   0,
-   StackReserve,
-   MEM_RESERVE,
-   PAGE_READWRITE
-  );
+   ULONG Size;
+   HANDLE ProcessHandle;
+   HANDLE ThreadHandle;
+   CLIENT_ID ClientId;
+   SECTION_IMAGE_INFORMATION ImageInfo;
+} RTL_PROCESS_INFO, *PRTL_PROCESS_INFO;
+
+NTSTATUS
+STDCALL
+RtlCreateUserProcess (
+   IN PUNICODE_STRING         ImageFileName,
+   IN ULONG          Attributes,
+   IN PRTL_USER_PROCESS_PARAMETERS  ProcessParameters,
+   IN PSECURITY_DESCRIPTOR    ProcessSecutityDescriptor OPTIONAL,
+   IN PSECURITY_DESCRIPTOR    ThreadSecurityDescriptor OPTIONAL,
+   IN HANDLE            ParentProcess OPTIONAL,
+   IN BOOLEAN           CurrentDirectory,
+   IN HANDLE            DebugPort OPTIONAL,
+   IN HANDLE            ExceptionPort OPTIONAL,
+   OUT   PRTL_PROCESS_INFO    ProcessInfo
+   );
+
+NTSTATUS
+STDCALL
+RtlCreateProcessParameters (
+   OUT   PRTL_USER_PROCESS_PARAMETERS  *ProcessParameters,
+   IN PUNICODE_STRING   ImagePathName OPTIONAL,
+   IN PUNICODE_STRING   DllPath OPTIONAL,
+   IN PUNICODE_STRING   CurrentDirectory OPTIONAL,
+   IN PUNICODE_STRING   CommandLine OPTIONAL,
+   IN PWSTR    Environment OPTIONAL,
+   IN PUNICODE_STRING   WindowTitle OPTIONAL,
+   IN PUNICODE_STRING   DesktopInfo OPTIONAL,
+   IN PUNICODE_STRING   ShellInfo OPTIONAL,
+   IN PUNICODE_STRING   RuntimeInfo OPTIONAL
+   );
+NTSTATUS
+STDCALL
+RtlDestroyProcessParameters (
+   IN PRTL_USER_PROCESS_PARAMETERS  ProcessParameters
+   );
 
-  /* failure */
-  if(!NT_SUCCESS(nErrCode)) return nErrCode;
 
-  DPRINT("Reserved %08X bytes\n", *StackReserve);
 
-  /* expandable stack base - the highest address of the stack */
-  InitialTeb->StackCommit =
-   (PUCHAR)(InitialTeb->StackReserved) + *StackReserve;
-
-  /* expandable stack limit - the lowest committed address of the stack */
-  InitialTeb->StackCommitMax =
-   (PUCHAR)(InitialTeb->StackCommit) - *StackCommit;
-
-  DPRINT("Stack commit     %p\n", InitialTeb->StackCommit);
-  DPRINT("Stack commit max %p\n", InitialTeb->StackCommitMax);
-
-  /* commit as much stack as requested */
-  nErrCode = NtAllocateVirtualMemory
-  (
-   ProcessHandle,
-   &(InitialTeb->StackCommitMax),
-   0,
-   StackCommit,
-   MEM_COMMIT,
-   PAGE_READWRITE
-  );
-
-  /* failure */
-  if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
-
-  DPRINT("Stack commit max %p\n", InitialTeb->StackCommitMax);
-
-  pGuardBase = (PUCHAR)(InitialTeb->StackCommitMax) - PAGE_SIZE;
-
-  DPRINT("Guard base %p\n", InitialTeb->StackCommit);
-
-  /* set up the guard page */
-  nErrCode = NtAllocateVirtualMemory
-  (
-   ProcessHandle,
-   &pGuardBase,
-   0,
-   &nGuardSize,
-   MEM_COMMIT,
-   PAGE_READWRITE | PAGE_GUARD
-  );
-
-  /* failure */
-  if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
-
-  DPRINT("Guard base %p\n", InitialTeb->StackCommit);
- }
-
- return STATUS_SUCCESS;
-
- /* cleanup in case of failure */
-l_Cleanup:
-  if(InitialTeb->StackLimit)
-  pStackLowest = InitialTeb->StackLimit;
- else if(InitialTeb->StackReserved)
-  pStackLowest = InitialTeb->StackReserved;
-
- /* free the stack, if it was allocated */
- if(pStackLowest != NULL)
-  NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
+/* FUNCTIONS *****************************************************************/
 
- return nErrCode;
-}
 
 
-NTSTATUS INIT_FUNCTION
+INIT_FUNCTION
+NTSTATUS
 LdrLoadInitialProcess(PHANDLE ProcessHandle,
                      PHANDLE ThreadHandle)
 {
-  SECTION_IMAGE_INFORMATION Sii;
-  UNICODE_STRING ImagePath;
-  HANDLE SectionHandle;
-  CONTEXT Context;
-  INITIAL_TEB InitialTeb;
-  ULONG_PTR nStackReserve = 0;
-  ULONG_PTR nStackCommit = 0;
-  PVOID pStackLowest;
-  PVOID pStackBase;
-  ULONG ResultLength;
-  PVOID ImageBaseAddress;
-  ULONG InitialStack[5];
-  HANDLE SystemProcessHandle;
-  NTSTATUS Status;
-
-  /* Get the absolute path to smss.exe. */
-  RtlRosInitUnicodeStringFromLiteral(&ImagePath,
-                                 L"\\SystemRoot\\system32\\smss.exe");
-
-  /* Map process image */
-  Status = LdrpMapProcessImage(&SectionHandle,
-                              &ImagePath);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("LdrpMapImage() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  /* Get information about the process image. */
-   Status = NtQuerySection(SectionHandle,
-                          SectionImageInformation,
-                          &Sii,
-                          sizeof(Sii),
-                          &ResultLength);
-  if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
-    {
-      DPRINT("ZwQuerySection failed (Status %X)\n", Status);
-      NtClose(ProcessHandle);
-      NtClose(SectionHandle);
-      return(Status);
-    }
-
-  Status = ObCreateHandle(PsGetCurrentProcess(),
-                          PsInitialSystemProcess,
-                          PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
-                          FALSE,
-                          &SystemProcessHandle);
+   UNICODE_STRING ImagePath;
+   HANDLE SystemProcessHandle;
+   NTSTATUS Status;
+   PRTL_USER_PROCESS_PARAMETERS Params=NULL;
+   RTL_PROCESS_INFO Info;
+
+   /* Get the absolute path to smss.exe. */
+   RtlRosInitUnicodeStringFromLiteral(&ImagePath,
+      L"\\SystemRoot\\system32\\smss.exe");
+
+
+   Status = ObCreateHandle(
+      PsGetCurrentProcess(),
+      PsInitialSystemProcess,
+      PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
+      FALSE,
+      &SystemProcessHandle
+      );
+
+   if(!NT_SUCCESS(Status))
+   {
+      DPRINT1("Failed to create a handle for the system process!\n");
+      return Status;
+   }
+
+   
+   Status = RtlCreateProcessParameters(
+      &Params,
+      &ImagePath,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      NULL
+      );
+   
   if(!NT_SUCCESS(Status))
   {
-    DPRINT1("Failed to create a handle for the system process!\n");
+    DPRINT1("Failed to create ppb!\n");
+    ZwClose(SystemProcessHandle);
     return Status;
   }
-
-  DPRINT("Creating process\n");
-  Status = NtCreateProcess(ProcessHandle,
-                          PROCESS_ALL_ACCESS,
-                          NULL,
-                          SystemProcessHandle,
-                          FALSE,
-                          SectionHandle,
-                          NULL,
-                          NULL);
-  NtClose(SectionHandle);
-  NtClose(SystemProcessHandle);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("NtCreateProcess() failed (Status %lx)\n", Status);
-      return(Status);
-    }
-
-  /* Create process environment */
-  DPRINT("Creating the process environment\n");
-  Status = LdrpCreateProcessEnvironment(*ProcessHandle,
-                                       &ImagePath,
-                                       &ImageBaseAddress);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("LdrpCreateProcessEnvironment() failed (Status %lx)\n", Status);
-      NtClose(*ProcessHandle);
-      return(Status);
-    }
-  DPRINT("ImageBaseAddress: %p\n", ImageBaseAddress);
-
-
-  /* Calculate initial stack sizes */
-  if (Sii.StackReserve > 0x100000)
-    nStackReserve = Sii.StackReserve;
-  else
-    nStackReserve = 0x100000; /* 1MByte */
-
-  /* FIXME */
-#if 0
-  if (Sii.StackCommit > PAGE_SIZE)
-    nStackCommit =  Sii.StackCommit;
-  else
-    nStackCommit = PAGE_SIZE;
-#endif
-  nStackCommit = nStackReserve - PAGE_SIZE;
-
-  DPRINT("StackReserve 0x%lX  StackCommit 0x%lX\n",
-        nStackReserve, nStackCommit);
-
-
-  /* Create the process stack */
-  Status = LdrpCreateStack
-  (
-   *ProcessHandle,
-   &InitialTeb,
-   &nStackReserve,
-   &nStackCommit
-  );
-
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT("Failed to write initial stack.\n");
-      NtClose(ProcessHandle);
-      return(Status);
-    }
-
-  if(InitialTeb.StackBase && InitialTeb.StackLimit)
-  {
-   pStackBase = InitialTeb.StackBase;
-   pStackLowest = InitialTeb.StackLimit;
-  }
-  else
-  {
-   pStackBase = InitialTeb.StackCommit;
-   pStackLowest = InitialTeb.StackReserved;
-  }
-
-  DPRINT("pStackBase = %p\n", pStackBase);
-  DPRINT("pStackLowest = %p\n", pStackLowest);
-
-  /*
-   * Initialize context to point to LdrStartup
-   */
-#if defined(_M_IX86)
-  memset(&Context,0,sizeof(CONTEXT));
-  Context.ContextFlags = CONTEXT_FULL;
-  Context.FloatSave.ControlWord = 0xffff037f;
-  Context.FloatSave.StatusWord = 0xffff0000;
-  Context.FloatSave.TagWord = 0xffffffff;
-  Context.FloatSave.DataSelector = 0xffff0000;
-  Context.Eip = (ULONG_PTR)((char*)ImageBaseAddress + (ULONG_PTR)Sii.EntryPoint);
-  Context.SegCs = USER_CS;
-  Context.SegDs = USER_DS;
-  Context.SegEs = USER_DS;
-  Context.SegFs = TEB_SELECTOR;
-  Context.SegGs = USER_DS;
-  Context.SegSs = USER_DS;
-  Context.EFlags = 0x202;
-  Context.Esp = (ULONG_PTR)pStackBase - 20;
-#else
-#error Unsupported architecture
-#endif
-
-  /*
-   * Write in the initial stack.
-   */
-  InitialStack[0] = 0;
-  InitialStack[1] = PEB_BASE;
-  Status = NtWriteVirtualMemory(*ProcessHandle,
-                               (PVOID)Context.Esp,
-                               InitialStack,
-                               sizeof(InitialStack),
-                               &ResultLength);
-  if (!NT_SUCCESS(Status))
-    {
-      ULONG_PTR nSize = 0;
-
-      DPRINT("Failed to write initial stack.\n");
-
-      NtFreeVirtualMemory(*ProcessHandle,
-                         pStackLowest,
-                         &nSize,
-                         MEM_RELEASE);
-      NtClose(*ProcessHandle);
+   
+
+   DPRINT("Creating process\n");
+
+   Status = RtlCreateUserProcess(
+      &ImagePath,
+      OBJ_CASE_INSENSITIVE, //Valid are OBJ_INHERIT and OBJ_CASE_INSENSITIVE.
+      Params,
+      NULL,
+      NULL,
+      SystemProcessHandle,
+      FALSE,
+      NULL,
+      NULL,
+      &Info
+      );
+
+   ZwClose(SystemProcessHandle);
+   RtlDestroyProcessParameters(Params);
+  
+   if (!NT_SUCCESS(Status))
+   {
+      DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status);
       return(Status);
-    }
-
-  /* Create initial thread */
-  DPRINT("Creating thread for initial process\n");
-  Status = NtCreateThread(ThreadHandle,
-                         THREAD_ALL_ACCESS,
-                         NULL,
-                         *ProcessHandle,
-                         NULL,
-                         &Context,
-                         &InitialTeb,
-                         FALSE);
-  if (!NT_SUCCESS(Status))
-    {
-      ULONG_PTR nSize = 0;
+   }
 
-      DPRINT("NtCreateThread() failed (Status %lx)\n", Status);
+   ZwResumeThread(Info.ThreadHandle, NULL);
 
-      NtFreeVirtualMemory(*ProcessHandle,
-                         pStackLowest,
-                         &nSize,
-                         MEM_RELEASE);
-
-      NtClose(*ProcessHandle);
-      return(Status);
-    }
+   *ProcessHandle = Info.ProcessHandle;
+   *ThreadHandle= Info.ThreadHandle;
 
-  DPRINT("Process created successfully\n");
+   DPRINT("Process created successfully\n");
 
-  return(STATUS_SUCCESS);
+   return(STATUS_SUCCESS);
 }
 
 /* EOF */
index c1f7a8a..61ce65a 100644 (file)
@@ -1,5 +1,5 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ldr/loader.c
@@ -41,10 +41,13 @@ STATIC MODULE_TEXT_SECTION NtoskrnlTextSection;
 STATIC MODULE_TEXT_SECTION LdrHalTextSection;
 ULONG_PTR LdrHalBase;
 
-#define TAG_DRIVER_MEM  TAG('D', 'R', 'V', 'M')
+#define TAG_DRIVER_MEM  TAG('D', 'R', 'V', 'M') /* drvm */
+#define TAG_MODULE_OBJECT TAG('k', 'l', 'm', 'o') /* klmo - kernel ldr module object */
+#define TAG_LDR_WSTR TAG('k', 'l', 'w', 's') /* klws - kernel ldr wide string */
+#define TAG_MODULE_TEXT_SECTION TAG('k', 'l', 'm', 't') /* klmt - kernel ldr module text */
 
 #ifndef HIWORD
-#define HIWORD(X)   ((WORD) (((DWORD) (X) >> 16) & 0xFFFF)) 
+#define HIWORD(X)   ((WORD) (((DWORD) (X) >> 16) & 0xFFFF))
 #endif
 #ifndef LOWORD
 #define LOWORD(X)   ((WORD) (X))
@@ -53,1554 +56,1583 @@ ULONG_PTR LdrHalBase;
 /* FORWARD DECLARATIONS ******************************************************/
 
 NTSTATUS
-LdrProcessModule(PVOID ModuleLoadBase,
-                PUNICODE_STRING ModuleName,
-                PMODULE_OBJECT *ModuleObject);
+LdrProcessModule (
+    PVOID ModuleLoadBase,
+    PUNICODE_STRING ModuleName,
+    PMODULE_OBJECT *ModuleObject );
 
 static VOID
-LdrpBuildModuleBaseName(PUNICODE_STRING BaseName,
-                       PUNICODE_STRING FullName);
+LdrpBuildModuleBaseName (
+    PUNICODE_STRING BaseName,
+    PUNICODE_STRING FullName );
 
 static LONG
-LdrpCompareModuleNames(IN PUNICODE_STRING String1,
-                      IN PUNICODE_STRING String2);
+LdrpCompareModuleNames (
+    IN PUNICODE_STRING String1,
+    IN PUNICODE_STRING String2 );
 
 
 /*  PE Driver load support  */
-static NTSTATUS LdrPEProcessModule(PVOID ModuleLoadBase,
-                                   PUNICODE_STRING FileName,
-                                   PMODULE_OBJECT *ModuleObject);
+static NTSTATUS
+LdrPEProcessModule (
+    PVOID ModuleLoadBase,
+    PUNICODE_STRING FileName,
+    PMODULE_OBJECT *ModuleObject );
+
 static PVOID
-LdrPEGetExportByName(PVOID BaseAddress,
-                     PUCHAR SymbolName,
-                     WORD Hint);
+LdrPEGetExportByName (
+    PVOID BaseAddress,
+    PUCHAR SymbolName,
+    WORD Hint );
 
 static PVOID
-LdrPEFixupForward(PCHAR ForwardName);
+LdrPEFixupForward ( PCHAR ForwardName );
 
 static NTSTATUS
-LdrPEPerformRelocations(PVOID DriverBase, 
-                       ULONG DriverSize);
+LdrPEPerformRelocations (
+    PVOID DriverBase,
+    ULONG DriverSize );
 
 static NTSTATUS
-LdrPEFixupImports(PMODULE_OBJECT Module);
+LdrPEFixupImports ( PMODULE_OBJECT Module );
 
 /* FUNCTIONS *****************************************************************/
 
 VOID
-LdrInitDebug(PLOADER_MODULE Module, PWCH Name)
+LdrInitDebug ( PLOADER_MODULE Module, PWCH Name )
 {
-  PLIST_ENTRY current_entry;
-  MODULE_TEXT_SECTION* current;
+    PLIST_ENTRY current_entry;
+    MODULE_TEXT_SECTION* current;
 
-  current_entry = ModuleTextListHead.Flink;
-  while (current_entry != &ModuleTextListHead)
+    current_entry = ModuleTextListHead.Flink;
+    while (current_entry != &ModuleTextListHead)
     {
-      current = 
-       CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
-      if (wcscmp(current->Name, Name) == 0)
-       {
-         break;
-       }
-      current_entry = current_entry->Flink;
+        current =
+            CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
+        if (wcscmp(current->Name, Name) == 0)
+        {
+            break;
+        }
+        current_entry = current_entry->Flink;
     }
 
-  if (current_entry == &ModuleTextListHead)
+    if (current_entry == &ModuleTextListHead)
     {
-      return;
+        return;
     }
 }
 
 VOID INIT_FUNCTION
-LdrInit1(VOID)
+LdrInit1 ( VOID )
 {
-  PIMAGE_NT_HEADERS      NtHeader;
-  PIMAGE_SECTION_HEADER  SectionList;
-
-  InitializeListHead(&ModuleTextListHead);
-
-  /* Setup ntoskrnl.exe text section */
-  /*
-   * This isn't the base of the text segment, but the start of the
-   * full image (in memory)
-   * Also, the Length field isn't set to the length of the segment,
-   * but is more like the offset, from the image base, to the end
-   * of the segment.
-   */
-  NtHeader                   = RtlImageNtHeader((PVOID)KERNEL_BASE);
-  SectionList                = IMAGE_FIRST_SECTION(NtHeader);
-  NtoskrnlTextSection.Base   = KERNEL_BASE;
-  NtoskrnlTextSection.Length = SectionList[0].Misc.VirtualSize +
-                               SectionList[0].VirtualAddress;
-  NtoskrnlTextSection.Name = KERNEL_MODULE_NAME;
-  NtoskrnlTextSection.OptionalHeader = OPTHDROFFSET(KERNEL_BASE);
-  InsertTailList(&ModuleTextListHead, &NtoskrnlTextSection.ListEntry);
-
-  /* Setup hal.dll text section */
-  /* Same comment as above applies */
-  NtHeader                 = RtlImageNtHeader((PVOID)LdrHalBase);
-  SectionList              = IMAGE_FIRST_SECTION(NtHeader);
-  LdrHalTextSection.Base   = LdrHalBase;
-  LdrHalTextSection.Length = SectionList[0].Misc.VirtualSize +
-                             SectionList[0].VirtualAddress;
-  LdrHalTextSection.Name = HAL_MODULE_NAME;
-  LdrHalTextSection.OptionalHeader = OPTHDROFFSET(LdrHalBase);
-  InsertTailList(&ModuleTextListHead, &LdrHalTextSection.ListEntry);
-
-  /* Hook for KDB on initialization of the loader. */
-  KDB_LOADERINIT_HOOK(&NtoskrnlTextSection, &LdrHalTextSection);
+    PIMAGE_NT_HEADERS      NtHeader;
+    PIMAGE_SECTION_HEADER  SectionList;
+
+    InitializeListHead(&ModuleTextListHead);
+
+    /* Setup ntoskrnl.exe text section */
+    /*
+    * This isn't the base of the text segment, but the start of the
+    * full image (in memory)
+    * Also, the Length field isn't set to the length of the segment,
+    * but is more like the offset, from the image base, to the end
+    * of the segment.
+    */
+    NtHeader                   = RtlImageNtHeader((PVOID)KERNEL_BASE);
+    SectionList                = IMAGE_FIRST_SECTION(NtHeader);
+    NtoskrnlTextSection.Base   = KERNEL_BASE;
+    NtoskrnlTextSection.Length = SectionList[0].Misc.VirtualSize
+        + SectionList[0].VirtualAddress;
+    NtoskrnlTextSection.Name = KERNEL_MODULE_NAME;
+    NtoskrnlTextSection.OptionalHeader = OPTHDROFFSET(KERNEL_BASE);
+    InsertTailList(&ModuleTextListHead, &NtoskrnlTextSection.ListEntry);
+
+    /* Setup hal.dll text section */
+    /* Same comment as above applies */
+    NtHeader                 = RtlImageNtHeader((PVOID)LdrHalBase);
+    SectionList              = IMAGE_FIRST_SECTION(NtHeader);
+    LdrHalTextSection.Base   = LdrHalBase;
+    LdrHalTextSection.Length = SectionList[0].Misc.VirtualSize
+        + SectionList[0].VirtualAddress;
+    LdrHalTextSection.Name = HAL_MODULE_NAME;
+    LdrHalTextSection.OptionalHeader = OPTHDROFFSET(LdrHalBase);
+    InsertTailList(&ModuleTextListHead, &LdrHalTextSection.ListEntry);
+
+    /* Hook for KDB on initialization of the loader. */
+    KDB_LOADERINIT_HOOK(&NtoskrnlTextSection, &LdrHalTextSection);
 }
 
 VOID INIT_FUNCTION
-LdrInitModuleManagement(VOID)
+LdrInitModuleManagement ( VOID )
 {
-  PIMAGE_NT_HEADERS NtHeader;
-
-  /* Initialize the module list and spinlock */
-  InitializeListHead(&ModuleListHead);
-  KeInitializeSpinLock(&ModuleListLock);
-
-  /* Initialize ModuleObject for NTOSKRNL */
-  RtlZeroMemory(&NtoskrnlModuleObject, sizeof(MODULE_OBJECT));
-  NtoskrnlModuleObject.Base = (PVOID) KERNEL_BASE;
-  NtoskrnlModuleObject.Flags = MODULE_FLAG_PE;
-  RtlInitUnicodeString(&NtoskrnlModuleObject.FullName, KERNEL_MODULE_NAME);
-  LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseName, &NtoskrnlModuleObject.FullName);
-
-  NtHeader = RtlImageNtHeader((PVOID)KERNEL_BASE);
-  NtoskrnlModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
-  NtoskrnlModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
-  NtoskrnlModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
-  NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
-  DPRINT("ModuleObject:%08x  entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint);
-  NtoskrnlModuleObject.Length = NtoskrnlModuleObject.Image.PE.OptionalHeader->SizeOfImage;
-  NtoskrnlModuleObject.TextSection = &NtoskrnlTextSection;
-
-  InsertTailList(&ModuleListHead,
-                &NtoskrnlModuleObject.ListEntry);
-
-  /* Initialize ModuleObject for HAL */
-  RtlZeroMemory(&HalModuleObject, sizeof(MODULE_OBJECT));
-  HalModuleObject.Base = (PVOID) LdrHalBase;
-  HalModuleObject.Flags = MODULE_FLAG_PE;
-
-  RtlInitUnicodeString(&HalModuleObject.FullName, HAL_MODULE_NAME);
-  LdrpBuildModuleBaseName(&HalModuleObject.BaseName, &HalModuleObject.FullName);
-
-  NtHeader = RtlImageNtHeader((PVOID)LdrHalBase);
-  HalModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
-  HalModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
-  HalModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
-  HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
-  DPRINT("ModuleObject:%08x  entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint);
-  HalModuleObject.Length = HalModuleObject.Image.PE.OptionalHeader->SizeOfImage;
-  HalModuleObject.TextSection = &LdrHalTextSection;
-
-  InsertTailList(&ModuleListHead,
-                &HalModuleObject.ListEntry);
+    PIMAGE_NT_HEADERS NtHeader;
+
+    /* Initialize the module list and spinlock */
+    InitializeListHead(&ModuleListHead);
+    KeInitializeSpinLock(&ModuleListLock);
+
+    /* Initialize ModuleObject for NTOSKRNL */
+    RtlZeroMemory(&NtoskrnlModuleObject, sizeof(MODULE_OBJECT));
+    NtoskrnlModuleObject.Base = (PVOID) KERNEL_BASE;
+    NtoskrnlModuleObject.Flags = MODULE_FLAG_PE;
+    RtlInitUnicodeString(&NtoskrnlModuleObject.FullName, KERNEL_MODULE_NAME);
+    LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseName, &NtoskrnlModuleObject.FullName);
+
+    NtHeader = RtlImageNtHeader((PVOID)KERNEL_BASE);
+    NtoskrnlModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
+    NtoskrnlModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
+    NtoskrnlModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
+    NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
+    DPRINT("ModuleObject:%08x  entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint);
+    NtoskrnlModuleObject.Length = NtoskrnlModuleObject.Image.PE.OptionalHeader->SizeOfImage;
+    NtoskrnlModuleObject.TextSection = &NtoskrnlTextSection;
+
+    InsertTailList(&ModuleListHead,
+        &NtoskrnlModuleObject.ListEntry);
+
+    /* Initialize ModuleObject for HAL */
+    RtlZeroMemory(&HalModuleObject, sizeof(MODULE_OBJECT));
+    HalModuleObject.Base = (PVOID) LdrHalBase;
+    HalModuleObject.Flags = MODULE_FLAG_PE;
+
+    RtlInitUnicodeString(&HalModuleObject.FullName, HAL_MODULE_NAME);
+    LdrpBuildModuleBaseName(&HalModuleObject.BaseName, &HalModuleObject.FullName);
+
+    NtHeader = RtlImageNtHeader((PVOID)LdrHalBase);
+    HalModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
+    HalModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
+    HalModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
+    HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
+    DPRINT("ModuleObject:%08x  entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint);
+    HalModuleObject.Length = HalModuleObject.Image.PE.OptionalHeader->SizeOfImage;
+    HalModuleObject.TextSection = &LdrHalTextSection;
+
+    InsertTailList(&ModuleListHead,
+        &HalModuleObject.ListEntry);
 }
 
 NTSTATUS
-LdrpLoadImage(PUNICODE_STRING DriverName,
-             PVOID *ModuleBase,
-             PVOID *SectionPointer,
-             PVOID *EntryPoint,
-             PVOID *ExportSectionPointer)
+LdrpLoadImage (
+    PUNICODE_STRING DriverName,
+    PVOID *ModuleBase,
+    PVOID *SectionPointer,
+    PVOID *EntryPoint,
+    PVOID *ExportSectionPointer )
 {
-  PMODULE_OBJECT ModuleObject;
-  NTSTATUS Status;
+    PMODULE_OBJECT ModuleObject;
+    NTSTATUS Status;
 
-  ModuleObject = LdrGetModuleObject(DriverName);
-  if (ModuleObject == NULL)
+    ModuleObject = LdrGetModuleObject(DriverName);
+    if (ModuleObject == NULL)
     {
-      Status = LdrLoadModule(DriverName, &ModuleObject);
-      if (!NT_SUCCESS(Status))
-       {
-         return(Status);
-       }
+        Status = LdrLoadModule(DriverName, &ModuleObject);
+        if (!NT_SUCCESS(Status))
+        {
+            return(Status);
+        }
     }
 
-  if (ModuleBase)
-    *ModuleBase = ModuleObject->Base;
+    if (ModuleBase)
+        *ModuleBase = ModuleObject->Base;
 
-//  if (SectionPointer)
-//    *SectionPointer = ModuleObject->
+    //if (SectionPointer)
+    //    *SectionPointer = ModuleObject->
 
-  if (EntryPoint)
-    *EntryPoint = ModuleObject->EntryPoint;
+    if (EntryPoint)
+        *EntryPoint = ModuleObject->EntryPoint;
 
-//  if (ExportSectionPointer)
-//    *ExportSectionPointer = ModuleObject->
+    //if (ExportSectionPointer)
+    //    *ExportSectionPointer = ModuleObject->
 
-  return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 
 NTSTATUS
-LdrpUnloadImage(PVOID ModuleBase)
+LdrpUnloadImage ( PVOID ModuleBase )
 {
-  return(STATUS_NOT_IMPLEMENTED);
+    return(STATUS_NOT_IMPLEMENTED);
 }
 
 
 NTSTATUS
-LdrpLoadAndCallImage(PUNICODE_STRING ModuleName)
+LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName )
 {
-  PDRIVER_INITIALIZE DriverEntry;
-  PMODULE_OBJECT ModuleObject;
-  NTSTATUS Status;
+    PDRIVER_INITIALIZE DriverEntry;
+    PMODULE_OBJECT ModuleObject;
+    NTSTATUS Status;
 
-  ModuleObject = LdrGetModuleObject(ModuleName);
-  if (ModuleObject != NULL)
+    ModuleObject = LdrGetModuleObject(ModuleName);
+    if (ModuleObject != NULL)
     {
-      return(STATUS_IMAGE_ALREADY_LOADED);
+        return(STATUS_IMAGE_ALREADY_LOADED);
     }
 
-  Status = LdrLoadModule(ModuleName, &ModuleObject);
-  if (!NT_SUCCESS(Status))
+    Status = LdrLoadModule(ModuleName, &ModuleObject);
+    if (!NT_SUCCESS(Status))
     {
-      return(Status);
+        return(Status);
     }
 
-  DriverEntry = (PDRIVER_INITIALIZE)ModuleObject->EntryPoint;
+    DriverEntry = (PDRIVER_INITIALIZE)ModuleObject->EntryPoint;
 
-  Status = DriverEntry(NULL, NULL);
-  if (!NT_SUCCESS(Status))
+    Status = DriverEntry(NULL, NULL);
+    if (!NT_SUCCESS(Status))
     {
-      LdrUnloadModule(ModuleObject);
+        LdrUnloadModule(ModuleObject);
     }
 
-  return(Status);
+    return(Status);
 }
 
 
 NTSTATUS
-LdrLoadModule(PUNICODE_STRING Filename,
-             PMODULE_OBJECT *ModuleObject)
+LdrLoadModule(
+    PUNICODE_STRING Filename,
+    PMODULE_OBJECT *ModuleObject )
 {
-  PVOID ModuleLoadBase;
-  NTSTATUS Status;
-  HANDLE FileHandle;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  PMODULE_OBJECT Module;
-  FILE_STANDARD_INFORMATION FileStdInfo;
-  IO_STATUS_BLOCK IoStatusBlock;
-
-  *ModuleObject = NULL;
-
-  DPRINT("Loading Module %wZ...\n", Filename);
-
-  /*  Open the Module  */
-  InitializeObjectAttributes(&ObjectAttributes,
-                             Filename,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-  CHECKPOINT;
-  Status = ZwOpenFile(&FileHandle,
-                      FILE_ALL_ACCESS,
-                      &ObjectAttributes,
-                      &IoStatusBlock,
-                      0,
-                      FILE_SYNCHRONOUS_IO_NONALERT);
-  CHECKPOINT;
-  if (!NT_SUCCESS(Status))
-    {
-      CPRINT("Could not open module file: %wZ\n", Filename);
-      return(Status);
-    }
-  CHECKPOINT;
-
-  /*  Get the size of the file  */
-  Status = ZwQueryInformationFile(FileHandle,
-                                  &IoStatusBlock,
-                                  &FileStdInfo,
-                                  sizeof(FileStdInfo),
-                                  FileStandardInformation);
-  if (!NT_SUCCESS(Status))
-    {
-      CPRINT("Could not get file size\n");
-      NtClose(FileHandle);
-      return(Status);
-    }
-  CHECKPOINT;
-
-  /*  Allocate nonpageable memory for driver  */
-  ModuleLoadBase = ExAllocatePoolWithTag(NonPagedPool,
-                                        FileStdInfo.EndOfFile.u.LowPart,
-                                        TAG_DRIVER_MEM);
-  if (ModuleLoadBase == NULL)
-    {
-      CPRINT("Could not allocate memory for module");
-      NtClose(FileHandle);
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-  CHECKPOINT;
-
-  /*  Load driver into memory chunk  */
-  Status = ZwReadFile(FileHandle,
-                      0, 0, 0,
-                      &IoStatusBlock,
-                      ModuleLoadBase,
-                      FileStdInfo.EndOfFile.u.LowPart,
-                      0, 0);
-  if (!NT_SUCCESS(Status))
-    {
-      CPRINT("Could not read module file into memory");
-      ExFreePool(ModuleLoadBase);
-      NtClose(FileHandle);
-      return(Status);
-    }
-  CHECKPOINT;
-
-  ZwClose(FileHandle);
-
-  Status = LdrProcessModule(ModuleLoadBase,
-                            Filename,
-                            &Module);
-  if (!NT_SUCCESS(Status))
-    {
-      CPRINT("Could not process module\n");
-      ExFreePool(ModuleLoadBase);
-      return(Status);
-    }
-
-  /*  Cleanup  */
-  ExFreePool(ModuleLoadBase);
-
-  *ModuleObject = Module;
-
-  /* Hook for KDB on loading a driver. */
-  KDB_LOADDRIVER_HOOK(Filename, Module);
-
-  return(STATUS_SUCCESS);
+    PVOID ModuleLoadBase;
+    NTSTATUS Status;
+    HANDLE FileHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PMODULE_OBJECT Module;
+    FILE_STANDARD_INFORMATION FileStdInfo;
+    IO_STATUS_BLOCK IoStatusBlock;
+
+    *ModuleObject = NULL;
+
+    DPRINT("Loading Module %wZ...\n", Filename);
+
+    /*  Open the Module  */
+    InitializeObjectAttributes(&ObjectAttributes,
+        Filename,
+        OBJ_CASE_INSENSITIVE,
+        NULL,
+        NULL);
+    CHECKPOINT;
+    Status = ZwOpenFile(&FileHandle,
+        FILE_ALL_ACCESS,
+        &ObjectAttributes,
+        &IoStatusBlock,
+        0,
+        FILE_SYNCHRONOUS_IO_NONALERT);
+    CHECKPOINT;
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("Could not open module file: %wZ\n", Filename);
+        return(Status);
+    }
+    CHECKPOINT;
+
+    /*  Get the size of the file  */
+    Status = ZwQueryInformationFile(FileHandle,
+        &IoStatusBlock,
+        &FileStdInfo,
+        sizeof(FileStdInfo),
+        FileStandardInformation);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("Could not get file size\n");
+        NtClose(FileHandle);
+        return(Status);
+    }
+    CHECKPOINT;
+
+    /*  Allocate nonpageable memory for driver  */
+    ModuleLoadBase = ExAllocatePoolWithTag(NonPagedPool,
+        FileStdInfo.EndOfFile.u.LowPart,
+        TAG_DRIVER_MEM);
+    if (ModuleLoadBase == NULL)
+    {
+        CPRINT("Could not allocate memory for module");
+        NtClose(FileHandle);
+        return(STATUS_INSUFFICIENT_RESOURCES);
+    }
+    CHECKPOINT;
+
+    /*  Load driver into memory chunk  */
+    Status = ZwReadFile(FileHandle,
+        0, 0, 0,
+        &IoStatusBlock,
+        ModuleLoadBase,
+        FileStdInfo.EndOfFile.u.LowPart,
+        0, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("Could not read module file into memory");
+        ExFreePool(ModuleLoadBase);
+        NtClose(FileHandle);
+        return(Status);
+    }
+    CHECKPOINT;
+
+    ZwClose(FileHandle);
+
+    Status = LdrProcessModule(ModuleLoadBase,
+        Filename,
+        &Module);
+    if (!NT_SUCCESS(Status))
+    {
+        CPRINT("Could not process module\n");
+        ExFreePool(ModuleLoadBase);
+        return(Status);
+    }
+
+    /*  Cleanup  */
+    ExFreePool(ModuleLoadBase);
+
+    *ModuleObject = Module;
+
+    /* Hook for KDB on loading a driver. */
+    KDB_LOADDRIVER_HOOK(Filename, Module);
+
+    return(STATUS_SUCCESS);
 }
 
 
 NTSTATUS
-LdrUnloadModule(PMODULE_OBJECT ModuleObject)
+LdrUnloadModule ( PMODULE_OBJECT ModuleObject )
 {
-  KIRQL Irql;
+    KIRQL Irql;
 
-  /* Remove the module from the module list */
-  KeAcquireSpinLock(&ModuleListLock,&Irql);
-  RemoveEntryList(&ModuleObject->ListEntry);
-  KeReleaseSpinLock(&ModuleListLock, Irql);
+    /* Remove the module from the module list */
+    KeAcquireSpinLock(&ModuleListLock,&Irql);
+    RemoveEntryList(&ModuleObject->ListEntry);
+    KeReleaseSpinLock(&ModuleListLock, Irql);
 
-  /* Hook for KDB on unloading a driver. */
-  KDB_UNLOADDRIVER_HOOK(ModuleObject);
+    /* Hook for KDB on unloading a driver. */
+    KDB_UNLOADDRIVER_HOOK(ModuleObject);
 
-  /* Free text section */
-  if (ModuleObject->TextSection != NULL)
+    /* Free text section */
+    if (ModuleObject->TextSection != NULL)
     {
-      ExFreePool(ModuleObject->TextSection->Name);
-      RemoveEntryList(&ModuleObject->TextSection->ListEntry);
-      ExFreePool(ModuleObject->TextSection);
-      ModuleObject->TextSection = NULL;
+        ExFreePool(ModuleObject->TextSection->Name);
+        RemoveEntryList(&ModuleObject->TextSection->ListEntry);
+        ExFreePool(ModuleObject->TextSection);
+        ModuleObject->TextSection = NULL;
     }
 
-  /* Free module section */
-//  MmFreeSection(ModuleObject->Base);
+    /* Free module section */
+    //  MmFreeSection(ModuleObject->Base);
 
-  ExFreePool(ModuleObject->FullName.Buffer);
-  ExFreePool(ModuleObject);
+    ExFreePool(ModuleObject->FullName.Buffer);
+    ExFreePool(ModuleObject);
 
-  return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 
 NTSTATUS
-LdrProcessModule(PVOID ModuleLoadBase,
-                PUNICODE_STRING ModuleName,
-                PMODULE_OBJECT *ModuleObject)
+LdrProcessModule(
+    PVOID ModuleLoadBase,
+    PUNICODE_STRING ModuleName,
+    PMODULE_OBJECT *ModuleObject )
 {
-  PIMAGE_DOS_HEADER PEDosHeader;
+    PIMAGE_DOS_HEADER PEDosHeader;
 
-  /*  If MZ header exists  */
-  PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
-  if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L)
+    /*  If MZ header exists  */
+    PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
+    if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L)
     {
-      return LdrPEProcessModule(ModuleLoadBase,
-                               ModuleName,
-                               ModuleObject);
+        return LdrPEProcessModule(ModuleLoadBase,
+            ModuleName,
+            ModuleObject);
     }
 
-  CPRINT("Module wasn't PE\n");
-  return STATUS_UNSUCCESSFUL;
+    CPRINT("Module wasn't PE\n");
+    return STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
-LdrpQueryModuleInformation(PVOID Buffer,
-                          ULONG Size,
-                          PULONG ReqSize)
+LdrpQueryModuleInformation (
+    PVOID Buffer,
+    ULONG Size,
+    PULONG ReqSize )
 {
-  PLIST_ENTRY current_entry;
-  PMODULE_OBJECT current;
-  ULONG ModuleCount = 0;
-  PSYSTEM_MODULE_INFORMATION Smi;
-  ANSI_STRING AnsiName;
-  PCHAR p;
-  KIRQL Irql;
-
-  KeAcquireSpinLock(&ModuleListLock,&Irql);
-
-  /* calculate required size */
-  current_entry = ModuleListHead.Flink;
-  while (current_entry != (&ModuleListHead))
+    PLIST_ENTRY current_entry;
+    PMODULE_OBJECT current;
+    ULONG ModuleCount = 0;
+    PSYSTEM_MODULE_INFORMATION Smi;
+    ANSI_STRING AnsiName;
+    PCHAR p;
+    KIRQL Irql;
+
+    KeAcquireSpinLock(&ModuleListLock,&Irql);
+
+    /* calculate required size */
+    current_entry = ModuleListHead.Flink;
+    while (current_entry != (&ModuleListHead))
     {
-      ModuleCount++;
-      current_entry = current_entry->Flink;
+        ModuleCount++;
+        current_entry = current_entry->Flink;
     }
 
-  *ReqSize = sizeof(SYSTEM_MODULE_INFORMATION)+
-    (ModuleCount - 1) * sizeof(SYSTEM_MODULE_INFORMATION_ENTRY);
+    *ReqSize = sizeof(SYSTEM_MODULE_INFORMATION)+
+        (ModuleCount - 1) * sizeof(SYSTEM_MODULE_INFORMATION_ENTRY);
 
-  if (Size < *ReqSize)
+    if (Size < *ReqSize)
     {
-      KeReleaseSpinLock(&ModuleListLock, Irql);
-      return(STATUS_INFO_LENGTH_MISMATCH);
+        KeReleaseSpinLock(&ModuleListLock, Irql);
+        return(STATUS_INFO_LENGTH_MISMATCH);
     }
 
-  /* fill the buffer */
-  memset(Buffer, '=', Size);
+    /* fill the buffer */
+    memset(Buffer, '=', Size);
 
-  Smi = (PSYSTEM_MODULE_INFORMATION)Buffer;
-  Smi->Count = ModuleCount;
+    Smi = (PSYSTEM_MODULE_INFORMATION)Buffer;
+    Smi->Count = ModuleCount;
 
-  ModuleCount = 0;
-  current_entry = ModuleListHead.Flink;
-  while (current_entry != (&ModuleListHead))
+    ModuleCount = 0;
+    current_entry = ModuleListHead.Flink;
+    while (current_entry != (&ModuleListHead))
     {
-      current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
-
-      Smi->Module[ModuleCount].Unknown1 = 0;           /* Always 0 */
-      Smi->Module[ModuleCount].Unknown2 = 0;           /* Always 0 */
-      Smi->Module[ModuleCount].Base = current->Base;
-      Smi->Module[ModuleCount].Size = current->Length;
-      Smi->Module[ModuleCount].Flags = 0;              /* Flags ??? (GN) */
-      Smi->Module[ModuleCount].Index = (USHORT)ModuleCount;
-      Smi->Module[ModuleCount].NameLength = 0;
-      Smi->Module[ModuleCount].LoadCount = 0; /* FIXME */
-
-      AnsiName.Length = 0;
-      AnsiName.MaximumLength = 256;
-      AnsiName.Buffer = Smi->Module[ModuleCount].ImageName;
-      RtlUnicodeStringToAnsiString(&AnsiName,
-                                  &current->FullName,
-                                  FALSE);
-
-      p = strrchr(AnsiName.Buffer, '\\');
-      if (p == NULL)
-       {
-         Smi->Module[ModuleCount].PathLength = 0;
-       }
-      else
-       {
-         p++;
-         Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer;
-       }
+        current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
+
+        Smi->Module[ModuleCount].Unknown1 = 0;                /* Always 0 */
+        Smi->Module[ModuleCount].Unknown2 = 0;                /* Always 0 */
+        Smi->Module[ModuleCount].Base = current->Base;
+        Smi->Module[ModuleCount].Size = current->Length;
+        Smi->Module[ModuleCount].Flags = 0;                /* Flags ??? (GN) */
+        Smi->Module[ModuleCount].Index = (USHORT)ModuleCount;
+        Smi->Module[ModuleCount].NameLength = 0;
+        Smi->Module[ModuleCount].LoadCount = 0; /* FIXME */
+
+        AnsiName.Length = 0;
+        AnsiName.MaximumLength = 256;
+        AnsiName.Buffer = Smi->Module[ModuleCount].ImageName;
+        RtlUnicodeStringToAnsiString(&AnsiName,
+            &current->FullName,
+            FALSE);
+
+        p = strrchr(AnsiName.Buffer, '\\');
+        if (p == NULL)
+        {
+            Smi->Module[ModuleCount].PathLength = 0;
+        }
+        else
+        {
+            p++;
+            Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer;
+        }
 
-      ModuleCount++;
-      current_entry = current_entry->Flink;
+        ModuleCount++;
+        current_entry = current_entry->Flink;
     }
 
-  KeReleaseSpinLock(&ModuleListLock, Irql);
+    KeReleaseSpinLock(&ModuleListLock, Irql);
 
-  return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 
 static VOID
-LdrpBuildModuleBaseName(PUNICODE_STRING BaseName,
-                       PUNICODE_STRING FullName)
+LdrpBuildModuleBaseName (
+    PUNICODE_STRING BaseName,
+    PUNICODE_STRING FullName )
 {
-   PWCHAR p;
+    PWCHAR p;
 
-   DPRINT("LdrpBuildModuleBaseName()\n");
-   DPRINT("FullName %wZ\n", FullName);
+    DPRINT("LdrpBuildModuleBaseName()\n");
+    DPRINT("FullName %wZ\n", FullName);
 
-   p = wcsrchr(FullName->Buffer, L'\\');
-   if (p == NULL)
-     {
-       p = FullName->Buffer;
-     }
-   else
-     {
-       p++;
-     }
+    p = wcsrchr(FullName->Buffer, L'\\');
+    if (p == NULL)
+    {
+        p = FullName->Buffer;
+    }
+    else
+    {
+        p++;
+    }
 
-   DPRINT("p %S\n", p);
+    DPRINT("p %S\n", p);
 
-   RtlInitUnicodeString(BaseName, p);
+    RtlInitUnicodeString(BaseName, p);
 }
 
 
 static LONG
-LdrpCompareModuleNames(IN PUNICODE_STRING String1,
-                      IN PUNICODE_STRING String2)
+LdrpCompareModuleNames (
+    IN PUNICODE_STRING String1,
+    IN PUNICODE_STRING String2 )
 {
-  ULONG len1, len2, i;
-  PWCHAR s1, s2, p;
-  WCHAR  c1, c2;
-
-  if (String1 && String2)
-    {
-      /* Search String1 for last path component */
-      len1 = String1->Length / sizeof(WCHAR);
-      s1 = String1->Buffer;
-      for (i = 0, p = String1->Buffer; i < String1->Length; i = i + sizeof(WCHAR), p++)
-       {
-         if (*p == L'\\')
-           {
-             if (i == String1->Length - sizeof(WCHAR))
-               {
-                 s1 = NULL;
-                 len1 = 0;
-               }
-             else
-               {
-                 s1 = p + 1;
-                 len1 = (String1->Length - i) / sizeof(WCHAR);
-               }
-           }
-       }
-
-      /* Search String2 for last path component */
-      len2 = String2->Length / sizeof(WCHAR);
-      s2 = String2->Buffer;
-      for (i = 0, p = String2->Buffer; i < String2->Length; i = i + sizeof(WCHAR), p++)
-       {
-         if (*p == L'\\')
-           {
-             if (i == String2->Length - sizeof(WCHAR))
-               {
-                 s2 = NULL;
-                 len2 = 0;
-               }
-             else
-               {
-                 s2 = p + 1;
-                 len2 = (String2->Length - i) / sizeof(WCHAR);
-               }
-           }
-       }
-
-      /* Compare last path components */
-      if (s1 && s2)
-       {
-         while (1)
-           {
-             c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
-             c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
-             if ((c1 == 0 && c2 == L'.') || (c1 == L'.' && c2 == 0))
-               return(0);
-             if (!c1 || !c2 || c1 != c2)
-               return(c1 - c2);
-           }
-       }
-    }
-
-  return(0);
+    ULONG len1, len2, i;
+    PWCHAR s1, s2, p;
+    WCHAR  c1, c2;
+
+    if (String1 && String2)
+    {
+        /* Search String1 for last path component */
+        len1 = String1->Length / sizeof(WCHAR);
+        s1 = String1->Buffer;
+        for (i = 0, p = String1->Buffer; i < String1->Length; i = i + sizeof(WCHAR), p++)
+        {
+            if (*p == L'\\')
+            {
+                if (i == String1->Length - sizeof(WCHAR))
+                {
+                    s1 = NULL;
+                    len1 = 0;
+                }
+                else
+                {
+                    s1 = p + 1;
+                    len1 = (String1->Length - i) / sizeof(WCHAR);
+                }
+            }
+        }
+
+        /* Search String2 for last path component */
+        len2 = String2->Length / sizeof(WCHAR);
+        s2 = String2->Buffer;
+        for (i = 0, p = String2->Buffer; i < String2->Length; i = i + sizeof(WCHAR), p++)
+        {
+            if (*p == L'\\')
+            {
+                if (i == String2->Length - sizeof(WCHAR))
+                {
+                    s2 = NULL;
+                    len2 = 0;
+                }
+                else
+                {
+                    s2 = p + 1;
+                    len2 = (String2->Length - i) / sizeof(WCHAR);
+                }
+            }
+        }
+
+        /* Compare last path components */
+        if (s1 && s2)
+        {
+            while (1)
+            {
+                c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
+                c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
+                if ((c1 == 0 && c2 == L'.') || (c1 == L'.' && c2 == 0))
+                    return(0);
+                if (!c1 || !c2 || c1 != c2)
+                    return(c1 - c2);
+            }
+        }
+    }
+
+    return(0);
 }
 
 PMODULE_OBJECT
-LdrGetModuleObject(PUNICODE_STRING ModuleName)
+LdrGetModuleObject ( PUNICODE_STRING ModuleName )
 {
-  PMODULE_OBJECT Module;
-  PLIST_ENTRY Entry;
-  KIRQL Irql;
+    PMODULE_OBJECT Module;
+    PLIST_ENTRY Entry;
+    KIRQL Irql;
 
-  DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
+    DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
 
-  KeAcquireSpinLock(&ModuleListLock,&Irql);
+    KeAcquireSpinLock(&ModuleListLock,&Irql);
 
-  Entry = ModuleListHead.Flink;
-  while (Entry != &ModuleListHead)
+    Entry = ModuleListHead.Flink;
+    while (Entry != &ModuleListHead)
     {
-      Module = CONTAINING_RECORD(Entry, MODULE_OBJECT, ListEntry);
+        Module = CONTAINING_RECORD(Entry, MODULE_OBJECT, ListEntry);
 
-      DPRINT("Comparing %wZ and %wZ\n",
-            &Module->BaseName,
-            ModuleName);
+        DPRINT("Comparing %wZ and %wZ\n",
+            &Module->BaseName,
+            ModuleName);
 
-      if (!LdrpCompareModuleNames(&Module->BaseName, ModuleName))
-       {
-         DPRINT("Module %wZ\n", &Module->BaseName);
-         KeReleaseSpinLock(&ModuleListLock, Irql);
-         return(Module);
-       }
+        if (!LdrpCompareModuleNames(&Module->BaseName, ModuleName))
+        {
+            DPRINT("Module %wZ\n", &Module->BaseName);
+            KeReleaseSpinLock(&ModuleListLock, Irql);
+            return(Module);
+        }
 
-      Entry = Entry->Flink;
+        Entry = Entry->Flink;
     }
 
-  KeReleaseSpinLock(&ModuleListLock, Irql);
+    KeReleaseSpinLock(&ModuleListLock, Irql);
 
-  DPRINT("Could not find module '%wZ'\n", ModuleName);
+    DPRINT("Could not find module '%wZ'\n", ModuleName);
 
-  return(NULL);
+    return(NULL);
 }
 
 
 /*  ----------------------------------------------  PE Module support */
 
 static ULONG
-LdrLookupPageProtection(PVOID PageStart,
-                       PVOID DriverBase,
-                        PIMAGE_FILE_HEADER PEFileHeader,
-                        PIMAGE_SECTION_HEADER PESectionHeaders)
+LdrLookupPageProtection (
+    PVOID PageStart,
+    PVOID DriverBase,
+    PIMAGE_FILE_HEADER PEFileHeader,
+    PIMAGE_SECTION_HEADER PESectionHeaders )
 {
-   BOOLEAN Write = FALSE;
-   BOOLEAN Execute = FALSE;
-   ULONG Characteristics;
-   ULONG Idx;
-   ULONG Length;
-   PVOID BaseAddress;
-   
-   for (Idx = 0; Idx < PEFileHeader->NumberOfSections && (!Write || !Execute); Idx++)
-   {
-      Characteristics = PESectionHeaders[Idx].Characteristics;
-      if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-      {
-         Length = max(PESectionHeaders[Idx].Misc.VirtualSize, PESectionHeaders[Idx].SizeOfRawData);
-         BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
-         if (BaseAddress < (PVOID)((ULONG_PTR)PageStart + PAGE_SIZE) &&
-             PageStart < (PVOID)((ULONG_PTR)BaseAddress + Length))
-         {
-            if (Characteristics & IMAGE_SCN_CNT_CODE)
-           {
-              Execute = TRUE;
-           }
-           if (Characteristics & (IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_UNINITIALIZED_DATA))
-           {
-              Write = TRUE;
-           }
-         }
-      }
-   }
-   if (Write && Execute)
-   {
-      return PAGE_EXECUTE_READWRITE;
-   }
-   else if (Execute)
-   {
-      return PAGE_EXECUTE_READ;
-   }
-   else if (Write)
-   {
-      return PAGE_READWRITE;
-   }
-   else
-   {
-      return PAGE_READONLY;
-   }
+    BOOLEAN Write = FALSE;
+    BOOLEAN Execute = FALSE;
+    ULONG Characteristics;
+    ULONG Idx;
+    ULONG Length;
+    PVOID BaseAddress;
+
+    for (Idx = 0; Idx < PEFileHeader->NumberOfSections && (!Write || !Execute); Idx++)
+    {
+        Characteristics = PESectionHeaders[Idx].Characteristics;
+        if (!(Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+        {
+            Length = max(PESectionHeaders[Idx].Misc.VirtualSize, PESectionHeaders[Idx].SizeOfRawData);
+            BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
+            if (BaseAddress < (PVOID)((ULONG_PTR)PageStart + PAGE_SIZE) &&
+                PageStart < (PVOID)((ULONG_PTR)BaseAddress + Length))
+            {
+                if (Characteristics & IMAGE_SCN_CNT_CODE)
+                {
+                    Execute = TRUE;
+                }
+                if (Characteristics & (IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_UNINITIALIZED_DATA))
+                {
+                    Write = TRUE;
+                }
+            }
+        }
+    }
+    if (Write && Execute)
+    {
+        return PAGE_EXECUTE_READWRITE;
+    }
+    else if (Execute)
+    {
+        return PAGE_EXECUTE_READ;
+    }
+    else if (Write)
+    {
+        return PAGE_READWRITE;
+    }
+    else
+    {
+        return PAGE_READONLY;
+    }
 }
 
 static NTSTATUS
-LdrPEProcessModule(PVOID ModuleLoadBase,
-                  PUNICODE_STRING FileName,
-                  PMODULE_OBJECT *ModuleObject)
+LdrPEProcessModule(
+    PVOID ModuleLoadBase,
+    PUNICODE_STRING FileName,
+    PMODULE_OBJECT *ModuleObject )
 {
-  unsigned int DriverSize, Idx;
-  DWORD CurrentSize;
-  PVOID DriverBase;
-  PIMAGE_DOS_HEADER PEDosHeader;
-  PIMAGE_NT_HEADERS PENtHeaders;
-  PIMAGE_SECTION_HEADER PESectionHeaders;
-  PMODULE_OBJECT CreatedModuleObject;
-  MODULE_TEXT_SECTION* ModuleTextSection;
-  NTSTATUS Status;
-  KIRQL Irql;
-
-  DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
-
-  /*  Get header pointers  */
-  PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
-  PENtHeaders = RtlImageNtHeader(ModuleLoadBase);
-  PESectionHeaders = IMAGE_FIRST_SECTION(PENtHeaders);
-  CHECKPOINT;
-
-  /*  Check file magic numbers  */
-  if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+    unsigned int DriverSize, Idx;
+    DWORD CurrentSize;
+    PVOID DriverBase;
+    PIMAGE_DOS_HEADER PEDosHeader;
+    PIMAGE_NT_HEADERS PENtHeaders;
+    PIMAGE_SECTION_HEADER PESectionHeaders;
+    PMODULE_OBJECT CreatedModuleObject;
+    MODULE_TEXT_SECTION* ModuleTextSection;
+    NTSTATUS Status;
+    KIRQL Irql;
+
+    DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
+
+    /*  Get header pointers  */
+    PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
+    PENtHeaders = RtlImageNtHeader(ModuleLoadBase);
+    PESectionHeaders = IMAGE_FIRST_SECTION(PENtHeaders);
+    CHECKPOINT;
+
+    /*  Check file magic numbers  */
+    if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
     {
-      CPRINT("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
-      return STATUS_UNSUCCESSFUL;
+        CPRINT("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
+        return STATUS_UNSUCCESSFUL;
     }
-  if (PEDosHeader->e_lfanew == 0)
+    if (PEDosHeader->e_lfanew == 0)
     {
-      CPRINT("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
-      return STATUS_UNSUCCESSFUL;
+        CPRINT("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
+        return STATUS_UNSUCCESSFUL;
     }
-  if (PENtHeaders->Signature != IMAGE_NT_SIGNATURE)
+    if (PENtHeaders->Signature != IMAGE_NT_SIGNATURE)
     {
-      CPRINT("Incorrect PE magic: %08x\n", PENtHeaders->Signature);
-      return STATUS_UNSUCCESSFUL;
+        CPRINT("Incorrect PE magic: %08x\n", PENtHeaders->Signature);
+        return STATUS_UNSUCCESSFUL;
     }
-  if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
+    if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
     {
-      CPRINT("Incorrect Architechture: %04x\n", PENtHeaders->FileHeader.Machine);
-      return STATUS_UNSUCCESSFUL;
+        CPRINT("Incorrect Architechture: %04x\n", PENtHeaders->FileHeader.Machine);
+        return STATUS_UNSUCCESSFUL;
     }
-  CHECKPOINT;
+    CHECKPOINT;
+
+    /* FIXME: if image is fixed-address load, then fail  */
+
+    /* FIXME: check/verify OS version number  */
+
+    DPRINT("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
+        PENtHeaders->OptionalHeader.Magic,
+        PENtHeaders->OptionalHeader.MajorLinkerVersion,
+        PENtHeaders->OptionalHeader.MinorLinkerVersion);
+    DPRINT("Entry Point:%08lx\n", PENtHeaders->OptionalHeader.AddressOfEntryPoint);
 
-  /* FIXME: if image is fixed-address load, then fail  */
+    /*  Determine the size of the module  */
+    DriverSize = 0;
+    for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
+    {
+        if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+        {
+            CurrentSize = PESectionHeaders[Idx].VirtualAddress + PESectionHeaders[Idx].Misc.VirtualSize;
+            DriverSize = max(DriverSize, CurrentSize);
+        }
+    }
+    DriverSize = ROUND_UP(DriverSize, PENtHeaders->OptionalHeader.SectionAlignment);
+    DPRINT("DriverSize %x, SizeOfImage %x\n",DriverSize, PENtHeaders->OptionalHeader.SizeOfImage);
 
-  /* FIXME: check/verify OS version number  */
+    /*  Allocate a virtual section for the module  */
+    DriverBase = NULL;
+    DriverBase = MmAllocateSection(DriverSize, DriverBase);
+    if (DriverBase == 0)
+    {
+        CPRINT("Failed to allocate a virtual section for driver\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+    DbgPrint("DriverBase for %wZ: %x\n", FileName, DriverBase);
 
-  DPRINT("OptionalHdrMagic:%04x LinkVersion:%d.%d\n", 
-         PENtHeaders->OptionalHeader.Magic,
-         PENtHeaders->OptionalHeader.MajorLinkerVersion,
-         PENtHeaders->OptionalHeader.MinorLinkerVersion);
-  DPRINT("Entry Point:%08lx\n", PENtHeaders->OptionalHeader.AddressOfEntryPoint);
+    /*  Copy headers over */
+    memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
 
-  /*  Determine the size of the module  */
-  DriverSize = 0;
-  for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
-  {
-     if (!(PESectionHeaders[Idx].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-     {
+    /*  Copy image sections into virtual section  */
+    for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
+    {
         CurrentSize = PESectionHeaders[Idx].VirtualAddress + PESectionHeaders[Idx].Misc.VirtualSize;
-       DriverSize = max(DriverSize, CurrentSize);
-     }
-  }
-  DriverSize = ROUND_UP(DriverSize, PENtHeaders->OptionalHeader.SectionAlignment);
-  DPRINT("DriverSize %x, SizeOfImage %x\n",DriverSize, PENtHeaders->OptionalHeader.SizeOfImage);
-
-  /*  Allocate a virtual section for the module  */
-  DriverBase = NULL;
-  DriverBase = MmAllocateSection(DriverSize, DriverBase);
-  if (DriverBase == 0)
-    {
-      CPRINT("Failed to allocate a virtual section for driver\n");
-      return STATUS_UNSUCCESSFUL;
-    }
-  DbgPrint("DriverBase for %wZ: %x\n", FileName, DriverBase);
-  
-  /*  Copy headers over */
-  memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
-
-  /*  Copy image sections into virtual section  */
-  for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
-  {
-     CurrentSize = PESectionHeaders[Idx].VirtualAddress + PESectionHeaders[Idx].Misc.VirtualSize;
-     /* Copy current section into current offset of virtual section */
-     if (CurrentSize <= DriverSize &&
-         PESectionHeaders[Idx].SizeOfRawData)
-     {
-          DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
-                 PESectionHeaders[Idx].VirtualAddress + (ULONG_PTR)DriverBase);
-           memcpy((PVOID)((ULONG_PTR)DriverBase + PESectionHeaders[Idx].VirtualAddress),
-                  (PVOID)((ULONG_PTR)ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData),
-                  PESectionHeaders[Idx].Misc.VirtualSize > PESectionHeaders[Idx].SizeOfRawData
-                  ? PESectionHeaders[Idx].SizeOfRawData : PESectionHeaders[Idx].Misc.VirtualSize );
-     }
-  }
-
-  /*  Perform relocation fixups  */
-  Status = LdrPEPerformRelocations(DriverBase, DriverSize);
-  if (!NT_SUCCESS(Status))
-  {
-//   MmFreeSection(DriverBase);
-     return Status;
-  }
-
-  /* Create the module */
-  CreatedModuleObject = ExAllocatePool(NonPagedPool, sizeof(MODULE_OBJECT));
-  if (CreatedModuleObject == NULL)
-  {
-//   MmFreeSection(DriverBase);
-     return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  RtlZeroMemory(CreatedModuleObject, sizeof(MODULE_OBJECT));
-
-  /*  Initialize ModuleObject data  */
-  CreatedModuleObject->Base = DriverBase;
-  CreatedModuleObject->Flags = MODULE_FLAG_PE;
-  
-  CreatedModuleObject->FullName.Length = 0;
-  CreatedModuleObject->FullName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
-  CreatedModuleObject->FullName.Buffer = ExAllocatePool(PagedPool, CreatedModuleObject->FullName.MaximumLength);
-  if (CreatedModuleObject->FullName.Buffer == NULL)
-  {
-     ExFreePool(CreatedModuleObject);
-//   MmFreeSection(DriverBase);
-     return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  RtlCopyUnicodeString(&CreatedModuleObject->FullName, FileName);
-  LdrpBuildModuleBaseName(&CreatedModuleObject->BaseName,
-                         &CreatedModuleObject->FullName);
-  
-  CreatedModuleObject->EntryPoint = 
-    (PVOID)((ULONG_PTR)DriverBase + 
-           PENtHeaders->OptionalHeader.AddressOfEntryPoint);
-  CreatedModuleObject->Length = DriverSize;
-  DPRINT("EntryPoint at %x\n", CreatedModuleObject->EntryPoint);
-  
-  CreatedModuleObject->Image.PE.FileHeader =
-    (PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG));
-
-  DPRINT("FileHeader at %x\n", CreatedModuleObject->Image.PE.FileHeader);
-  CreatedModuleObject->Image.PE.OptionalHeader = 
-    (PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
-    sizeof(IMAGE_FILE_HEADER));
-  DPRINT("OptionalHeader at %x\n", CreatedModuleObject->Image.PE.OptionalHeader);
-  CreatedModuleObject->Image.PE.SectionList = 
-    (PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
-    sizeof(IMAGE_FILE_HEADER) + CreatedModuleObject->Image.PE.FileHeader->SizeOfOptionalHeader);
-  DPRINT("SectionList at %x\n", CreatedModuleObject->Image.PE.SectionList);
-
-  /*  Perform import fixups  */
-  Status = LdrPEFixupImports(CreatedModuleObject);
-  if (!NT_SUCCESS(Status))
-  {
-//   MmFreeSection(DriverBase);
-     ExFreePool(CreatedModuleObject->FullName.Buffer);
-     ExFreePool(CreatedModuleObject);
-     return Status;
-  }
-
-  MmSetPageProtect(NULL, DriverBase, PAGE_READONLY);
-  /* Set the protections for the various parts of the driver */
-  for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
-  {
-     ULONG Characteristics = PESectionHeaders[Idx].Characteristics;
-     ULONG Length;
-     PVOID BaseAddress;
-     PVOID PageAddress;
-     ULONG Protect;
-     Length = PESectionHeaders[Idx].Misc.VirtualSize;
-     BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
-     PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
-
-     Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders);
-#if 1
-     /* 
-      * FIXME:
-      *   This driver modifies a string in the first page of the text section while initialising.
-      */
-     if (0 == _wcsicmp(L"fireport.sys", FileName->Buffer))
-     {
-       Protect = PAGE_EXECUTE_READWRITE;
-     }
-#endif
-     if (PageAddress < DriverBase + DriverSize)
-     {
-        MmSetPageProtect(NULL, PageAddress, Protect);
-     }
-     
-     if (Characteristics & IMAGE_SCN_CNT_CODE)
-     {
-        if (Characteristics & IMAGE_SCN_MEM_WRITE)
-       {
-          Protect = PAGE_EXECUTE_READWRITE;
-       }
-       else
-       {
-          Protect = PAGE_EXECUTE_READ;
-       }
-     }
-     else if (Characteristics & (IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_UNINITIALIZED_DATA))
-     {
-        Protect = PAGE_READWRITE;
-     }
-     else
-     {
-        Protect = PAGE_READONLY;
-     }
-     PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
-     while ((ULONG_PTR)PageAddress + PAGE_SIZE < (ULONG_PTR)BaseAddress + Length)
-     {
-        if (PageAddress < DriverBase + DriverSize)
-       {
-           MmSetPageProtect(NULL, PageAddress, Protect);
-       }
-       PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
-     }
-     if (PageAddress < (PVOID)((ULONG_PTR)BaseAddress + Length) &&
-        PageAddress < DriverBase + DriverSize)
-     {
-        Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders);
-        MmSetPageProtect(NULL, PageAddress, Protect);
-     }
-  }
+        /* Copy current section into current offset of virtual section */
+        if (CurrentSize <= DriverSize &&
+            PESectionHeaders[Idx].SizeOfRawData)
+        {
+            DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
+                PESectionHeaders[Idx].VirtualAddress + (ULONG_PTR)DriverBase);
+            memcpy((PVOID)((ULONG_PTR)DriverBase + PESectionHeaders[Idx].VirtualAddress),
+                (PVOID)((ULONG_PTR)ModuleLoadBase + PESectionHeaders[Idx].PointerToRawData),
+                PESectionHeaders[Idx].Misc.VirtualSize > PESectionHeaders[Idx].SizeOfRawData
+                ? PESectionHeaders[Idx].SizeOfRawData : PESectionHeaders[Idx].Misc.VirtualSize );
+        }
+    }
 
-  /* Insert module */
-  KeAcquireSpinLock(&ModuleListLock, &Irql);
-  InsertTailList(&ModuleListHead,
-                &CreatedModuleObject->ListEntry);
-  KeReleaseSpinLock(&ModuleListLock, Irql);
+    /*  Perform relocation fixups  */
+    Status = LdrPEPerformRelocations(DriverBase, DriverSize);
+    if (!NT_SUCCESS(Status))
+    {
+        //   MmFreeSection(DriverBase);
+        return Status;
+    }
 
+    /* Create the module */
+    CreatedModuleObject = ExAllocatePoolWithTag (
+        NonPagedPool, sizeof(MODULE_OBJECT), TAG_MODULE_OBJECT );
+    if (CreatedModuleObject == NULL)
+    {
+        //   MmFreeSection(DriverBase);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
-  ModuleTextSection = ExAllocatePool(NonPagedPool, 
-                                    sizeof(MODULE_TEXT_SECTION));
-  ASSERT(ModuleTextSection);
-  RtlZeroMemory(ModuleTextSection, sizeof(MODULE_TEXT_SECTION));
-  ModuleTextSection->Base = (ULONG)DriverBase;
-  ModuleTextSection->Length = DriverSize;
-  ModuleTextSection->Name = ExAllocatePool(NonPagedPool, 
-       (CreatedModuleObject->BaseName.Length + 1) * sizeof(WCHAR));
-  RtlCopyMemory(ModuleTextSection->Name,
-                CreatedModuleObject->BaseName.Buffer,
-                CreatedModuleObject->BaseName.Length);
-  ModuleTextSection->Name[CreatedModuleObject->BaseName.Length / sizeof(WCHAR)] = 0;
-  ModuleTextSection->OptionalHeader = 
-    CreatedModuleObject->Image.PE.OptionalHeader;
-  InsertTailList(&ModuleTextListHead, &ModuleTextSection->ListEntry);
+    RtlZeroMemory(CreatedModuleObject, sizeof(MODULE_OBJECT));
 
-  CreatedModuleObject->TextSection = ModuleTextSection;
+    /*  Initialize ModuleObject data  */
+    CreatedModuleObject->Base = DriverBase;
+    CreatedModuleObject->Flags = MODULE_FLAG_PE;
 
-  *ModuleObject = CreatedModuleObject;
+    CreatedModuleObject->FullName.Length = 0;
+    CreatedModuleObject->FullName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
+    CreatedModuleObject->FullName.Buffer =
+        ExAllocatePoolWithTag(PagedPool, CreatedModuleObject->FullName.MaximumLength, TAG_LDR_WSTR);
+    if (CreatedModuleObject->FullName.Buffer == NULL)
+    {
+        ExFreePool(CreatedModuleObject);
+        //   MmFreeSection(DriverBase);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
-  DPRINT("Loading Module %wZ...\n", FileName);
+    RtlCopyUnicodeString(&CreatedModuleObject->FullName, FileName);
+    LdrpBuildModuleBaseName(&CreatedModuleObject->BaseName,
+        &CreatedModuleObject->FullName);
+
+    CreatedModuleObject->EntryPoint =
+        (PVOID)((ULONG_PTR)DriverBase +
+        PENtHeaders->OptionalHeader.AddressOfEntryPoint);
+    CreatedModuleObject->Length = DriverSize;
+    DPRINT("EntryPoint at %x\n", CreatedModuleObject->EntryPoint);
+
+    CreatedModuleObject->Image.PE.FileHeader =
+        (PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG));
+
+    DPRINT("FileHeader at %x\n", CreatedModuleObject->Image.PE.FileHeader);
+    CreatedModuleObject->Image.PE.OptionalHeader =
+        (PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
+        sizeof(IMAGE_FILE_HEADER));
+    DPRINT("OptionalHeader at %x\n", CreatedModuleObject->Image.PE.OptionalHeader);
+    CreatedModuleObject->Image.PE.SectionList =
+        (PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
+        sizeof(IMAGE_FILE_HEADER) + CreatedModuleObject->Image.PE.FileHeader->SizeOfOptionalHeader);
+    DPRINT("SectionList at %x\n", CreatedModuleObject->Image.PE.SectionList);
+
+    /*  Perform import fixups  */
+    Status = LdrPEFixupImports(CreatedModuleObject);
+    if (!NT_SUCCESS(Status))
+    {
+        //   MmFreeSection(DriverBase);
+        ExFreePool(CreatedModuleObject->FullName.Buffer);
+        ExFreePool(CreatedModuleObject);
+        return Status;
+    }
 
-  if (KdDebuggerEnabled && (KdDebugState & KD_DEBUG_GDB))
+    MmSetPageProtect(NULL, DriverBase, PAGE_READONLY);
+    /* Set the protections for the various parts of the driver */
+    for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
     {
-      DPRINT("Module %wZ loaded at 0x%.08x.\n",
-             FileName, CreatedModuleObject->Base);
+        ULONG Characteristics = PESectionHeaders[Idx].Characteristics;
+        ULONG Length;
+        PVOID BaseAddress;
+        PVOID PageAddress;
+        ULONG Protect;
+        Length = PESectionHeaders[Idx].Misc.VirtualSize;
+        BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
+        PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
+
+        Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders);
+#if 1
+        /*
+        * FIXME:
+        *   This driver modifies a string in the first page of the text section while initialising.
+        */
+        if (0 == _wcsicmp(L"fireport.sys", FileName->Buffer))
+        {
+            Protect = PAGE_EXECUTE_READWRITE;
+        }
+#endif
+        if (PageAddress < DriverBase + DriverSize)
+        {
+            MmSetPageProtect(NULL, PageAddress, Protect);
+        }
+
+        if (Characteristics & IMAGE_SCN_CNT_CODE)
+        {
+            if (Characteristics & IMAGE_SCN_MEM_WRITE)
+            {
+                Protect = PAGE_EXECUTE_READWRITE;
+            }
+            else
+            {
+                Protect = PAGE_EXECUTE_READ;
+            }
+        }
+        else if (Characteristics & (IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_UNINITIALIZED_DATA))
+        {
+            Protect = PAGE_READWRITE;
+        }
+        else
+        {
+            Protect = PAGE_READONLY;
+        }
+        PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
+        while ((ULONG_PTR)PageAddress + PAGE_SIZE < (ULONG_PTR)BaseAddress + Length)
+        {
+            if (PageAddress < DriverBase + DriverSize)
+            {
+                MmSetPageProtect(NULL, PageAddress, Protect);
+            }
+            PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
+        }
+        if (PageAddress < (PVOID)((ULONG_PTR)BaseAddress + Length) &&
+            PageAddress < DriverBase + DriverSize)
+        {
+            Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders);
+            MmSetPageProtect(NULL, PageAddress, Protect);
+        }
     }
 
-  return STATUS_SUCCESS;
+    /* Insert module */
+    KeAcquireSpinLock(&ModuleListLock, &Irql);
+    InsertTailList(&ModuleListHead,
+        &CreatedModuleObject->ListEntry);
+    KeReleaseSpinLock(&ModuleListLock, Irql);
+
+
+    ModuleTextSection = ExAllocatePoolWithTag (
+        NonPagedPool,
+        sizeof(MODULE_TEXT_SECTION),
+        TAG_MODULE_TEXT_SECTION );
+    ASSERT(ModuleTextSection);
+    RtlZeroMemory(ModuleTextSection, sizeof(MODULE_TEXT_SECTION));
+    ModuleTextSection->Base = (ULONG)DriverBase;
+    ModuleTextSection->Length = DriverSize;
+    ModuleTextSection->Name = ExAllocatePoolWithTag (
+        NonPagedPool,
+        (CreatedModuleObject->BaseName.Length + 1) * sizeof(WCHAR),
+        TAG_LDR_WSTR );
+    RtlCopyMemory(ModuleTextSection->Name,
+        CreatedModuleObject->BaseName.Buffer,
+        CreatedModuleObject->BaseName.Length);
+    ModuleTextSection->Name[CreatedModuleObject->BaseName.Length / sizeof(WCHAR)] = 0;
+    ModuleTextSection->OptionalHeader =
+        CreatedModuleObject->Image.PE.OptionalHeader;
+    InsertTailList(&ModuleTextListHead, &ModuleTextSection->ListEntry);
+
+    CreatedModuleObject->TextSection = ModuleTextSection;
+
+    *ModuleObject = CreatedModuleObject;
+
+    DPRINT("Loading Module %wZ...\n", FileName);
+
+    if (KdDebuggerEnabled && (KdDebugState & KD_DEBUG_GDB))
+    {
+        DPRINT("Module %wZ loaded at 0x%.08x.\n",
+            FileName, CreatedModuleObject->Base);
+    }
+
+    return STATUS_SUCCESS;
 }
 
 
 PVOID INIT_FUNCTION
-LdrSafePEProcessModule(PVOID ModuleLoadBase,
-                      PVOID DriverBase,
-                      PVOID ImportModuleBase,
-                      PULONG DriverSize)
+LdrSafePEProcessModule (
+    PVOID ModuleLoadBase,
+    PVOID DriverBase,
+    PVOID ImportModuleBase,
+    PULONG DriverSize)
 {
-  unsigned int Idx;
-  ULONG CurrentSize;
-  PIMAGE_DOS_HEADER PEDosHeader;
-  PIMAGE_NT_HEADERS PENtHeaders;
-  PIMAGE_SECTION_HEADER PESectionHeaders;
-  NTSTATUS Status;
-
-  ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
-
-  /*  Get header pointers  */
-  PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
-  PENtHeaders = RtlImageNtHeader(ModuleLoadBase);
-  PESectionHeaders = IMAGE_FIRST_SECTION(PENtHeaders); 
-  CHECKPOINT;
-
-  /*  Check file magic numbers  */
-  if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+    unsigned int Idx;
+    ULONG CurrentSize;
+    PIMAGE_DOS_HEADER PEDosHeader;
+    PIMAGE_NT_HEADERS PENtHeaders;
+    PIMAGE_SECTION_HEADER PESectionHeaders;
+    NTSTATUS Status;
+
+    ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
+
+    /*  Get header pointers  */
+    PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
+    PENtHeaders = RtlImageNtHeader(ModuleLoadBase);
+    PESectionHeaders = IMAGE_FIRST_SECTION(PENtHeaders);
+    CHECKPOINT;
+
+    /*  Check file magic numbers  */
+    if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
     {
-      return NULL;
+        return NULL;
     }
-  if (PEDosHeader->e_lfanew == 0)
+    if (PEDosHeader->e_lfanew == 0)
     {
-      return NULL;
+        return NULL;
     }
-  if (PENtHeaders->Signature != IMAGE_NT_SIGNATURE)
+    if (PENtHeaders->Signature != IMAGE_NT_SIGNATURE)
     {
-      return NULL;
+        return NULL;
     }
-  if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
+    if (PENtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
     {
-      return NULL;
+        return NULL;
     }
 
-  ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n", 
-         PENtHeaders->OptionalHeader.Magic,
-         PENtHeaders->OptionalHeader.MajorLinkerVersion,
-         PENtHeaders->OptionalHeader.MinorLinkerVersion);
-  ps("Entry Point:%08lx\n", PENtHeaders->OptionalHeader.AddressOfEntryPoint);
+    ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
+        PENtHeaders->OptionalHeader.Magic,
+        PENtHeaders->OptionalHeader.MajorLinkerVersion,
+        PENtHeaders->OptionalHeader.MinorLinkerVersion);
+    ps("Entry Point:%08lx\n", PENtHeaders->OptionalHeader.AddressOfEntryPoint);
 
-  /*  Determine the size of the module  */
-  *DriverSize = PENtHeaders->OptionalHeader.SizeOfImage;
-  ps("DriverSize %x\n",*DriverSize);
+    /*  Determine the size of the module  */
+    *DriverSize = PENtHeaders->OptionalHeader.SizeOfImage;
+    ps("DriverSize %x\n",*DriverSize);
 
-  /*  Copy headers over */
-  if (DriverBase != ModuleLoadBase)
+    /*  Copy headers over */
+    if (DriverBase != ModuleLoadBase)
     {
-      memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
+        memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
     }
 
-  ps("Hdr: 0x%X\n", PENtHeaders);
-  ps("Hdr->SizeOfHeaders: 0x%X\n", PENtHeaders->OptionalHeader.SizeOfHeaders);
-  ps("FileHdr->NumberOfSections: 0x%X\n", PENtHeaders->FileHeader.NumberOfSections);
+    ps("Hdr: 0x%X\n", PENtHeaders);
+    ps("Hdr->SizeOfHeaders: 0x%X\n", PENtHeaders->OptionalHeader.SizeOfHeaders);
+    ps("FileHdr->NumberOfSections: 0x%X\n", PENtHeaders->FileHeader.NumberOfSections);
+
+    /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same
+    address as it is mapped */
+    if (DriverBase != ModuleLoadBase)
+    {
+        CurrentSize = 0;
+
+        /*  Copy image sections into virtual section  */
+        for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
+        {
+            PIMAGE_SECTION_HEADER Section = &PESectionHeaders[Idx];
+            //  Copy current section into current offset of virtual section
+            if (Section->SizeOfRawData)
+            {
+                //            ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
+                //                PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase);
+                memcpy(Section->VirtualAddress   + (char*)DriverBase,
+                    Section->PointerToRawData + (char*)ModuleLoadBase,
+                    Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->SizeOfRawData : Section->Misc.VirtualSize);
+            }
+            if (Section->SizeOfRawData < Section->Misc.VirtualSize)
+            {
+                memset(Section->VirtualAddress + Section->SizeOfRawData + (char*)DriverBase,
+                    0,
+                    Section->Misc.VirtualSize - Section->SizeOfRawData);
+            }
+            CurrentSize += ROUND_UP(Section->Misc.VirtualSize,
+                PENtHeaders->OptionalHeader.SectionAlignment);
+        }
+
+        /*  Perform relocation fixups  */
+        Status = LdrPEPerformRelocations(DriverBase, *DriverSize);
+        if (!NT_SUCCESS(Status))
+        {
+            return NULL;
+        }
+    }
 
-  /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same
-     address as it is mapped */
-  if (DriverBase != ModuleLoadBase)
+    /*  Perform import fixups  */
+    Status = LdrPEFixupImports(DriverBase == ModuleLoadBase ? &NtoskrnlModuleObject : &HalModuleObject);
+    if (!NT_SUCCESS(Status))
     {
-      CurrentSize = 0;
+        return NULL;
+    }
 
-      /*  Copy image sections into virtual section  */
-      for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
+    /*  Set the page protection for the virtual sections */
+    MmSetPageProtect(NULL, DriverBase, PAGE_READONLY);
+    for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
+    {
+        ULONG Characteristics = PESectionHeaders[Idx].Characteristics;
+        ULONG Length;
+        PVOID BaseAddress;
+        PVOID PageAddress;
+        ULONG Protect;
+        Length = PESectionHeaders[Idx].Misc.VirtualSize;
+        BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
+        PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
+
+        if (Characteristics & IMAGE_SCN_MEM_EXECUTE)
         {
-          PIMAGE_SECTION_HEADER Section = &PESectionHeaders[Idx];
-          //  Copy current section into current offset of virtual section
-          if (Section->SizeOfRawData)
+            if (Characteristics & IMAGE_SCN_MEM_WRITE)
             {
-//            ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
-//                PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase);
-              memcpy(Section->VirtualAddress   + (char*)DriverBase,
-                     Section->PointerToRawData + (char*)ModuleLoadBase,
-                    Section->Misc.VirtualSize > Section->SizeOfRawData ? Section->SizeOfRawData : Section->Misc.VirtualSize);
+                Protect = PAGE_EXECUTE_READWRITE;
             }
-          if (Section->SizeOfRawData < Section->Misc.VirtualSize)
+            else
             {
-              memset(Section->VirtualAddress + Section->SizeOfRawData + (char*)DriverBase, 
-                     0,
-                     Section->Misc.VirtualSize - Section->SizeOfRawData);
+                Protect = PAGE_EXECUTE_READ;
             }
-          CurrentSize += ROUND_UP(Section->Misc.VirtualSize,
-                                  PENtHeaders->OptionalHeader.SectionAlignment);
         }
+        else if (Characteristics & IMAGE_SCN_MEM_WRITE)
+        {
+            Protect = PAGE_READWRITE;
+        }
+        else
+        {
+            Protect = PAGE_READONLY;
+        }
+        while ((ULONG_PTR)PageAddress < (ULONG_PTR)BaseAddress + Length)
+        {
+            MmSetPageProtect(NULL, PageAddress, Protect);
+            PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
+        }
+        if (DriverBase == ModuleLoadBase &&
+            Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+        {
+            /* For ntoskrnl, we must stop after the bss section */
+            break;
+        }
+
+    }
 
-      /*  Perform relocation fixups  */
-      Status = LdrPEPerformRelocations(DriverBase, *DriverSize);
-      if (!NT_SUCCESS(Status))
-      {
-         return NULL;
-      }
-  }
-
-  /*  Perform import fixups  */
-  Status = LdrPEFixupImports(DriverBase == ModuleLoadBase ? &NtoskrnlModuleObject : &HalModuleObject);
-  if (!NT_SUCCESS(Status))
-  {
-     return NULL;
-  }
-
-  /*  Set the page protection for the virtual sections */
-  MmSetPageProtect(NULL, DriverBase, PAGE_READONLY);
-  for (Idx = 0; Idx < PENtHeaders->FileHeader.NumberOfSections; Idx++)
-  {
-     ULONG Characteristics = PESectionHeaders[Idx].Characteristics;
-     ULONG Length;
-     PVOID BaseAddress;
-     PVOID PageAddress;
-     ULONG Protect;
-     Length = PESectionHeaders[Idx].Misc.VirtualSize;
-     BaseAddress = PESectionHeaders[Idx].VirtualAddress + (char*)DriverBase;
-     PageAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress);
-
-     if (Characteristics & IMAGE_SCN_MEM_EXECUTE)
-     {
-        if (Characteristics & IMAGE_SCN_MEM_WRITE)
-       {
-          Protect = PAGE_EXECUTE_READWRITE;
-       }
-       else
-       {
-          Protect = PAGE_EXECUTE_READ;
-       }
-     }
-     else if (Characteristics & IMAGE_SCN_MEM_WRITE)
-     {
-        Protect = PAGE_READWRITE;
-     }
-     else
-     {
-        Protect = PAGE_READONLY;
-     }
-     while ((ULONG_PTR)PageAddress < (ULONG_PTR)BaseAddress + Length)
-     {
-        MmSetPageProtect(NULL, PageAddress, Protect);
-       PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
-     }
-     if (DriverBase == ModuleLoadBase &&
-        Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
-     {
-        /* For ntoskrnl, we must stop after the bss section */
-       break;
-     }
-        
-  }
-     
-  return DriverBase;
+    return DriverBase;
 }
 
 static PVOID
-LdrPEFixupForward(PCHAR ForwardName)
+LdrPEFixupForward ( PCHAR ForwardName )
 {
-   CHAR NameBuffer[128];
-   UNICODE_STRING ModuleName;
-   PCHAR p;
-   PMODULE_OBJECT ModuleObject;
+    CHAR NameBuffer[128];
+    UNICODE_STRING ModuleName;
+    PCHAR p;
+    PMODULE_OBJECT ModuleObject;
 
-   DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
+    DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
 
-   strcpy(NameBuffer, ForwardName);
-   p = strchr(NameBuffer, '.');
-   if (p == NULL)
-     {
-       return NULL;
-     }
+    strcpy(NameBuffer, ForwardName);
+    p = strchr(NameBuffer, '.');
+    if (p == NULL)
+    {
+        return NULL;
+    }
 
-   *p = 0;
+    *p = 0;
 
-   DPRINT("Driver: %s  Function: %s\n", NameBuffer, p+1);
+    DPRINT("Driver: %s  Function: %s\n", NameBuffer, p+1);
 
-   RtlCreateUnicodeStringFromAsciiz(&ModuleName,
-                                   NameBuffer);
-   ModuleObject = LdrGetModuleObject(&ModuleName);
-   RtlFreeUnicodeString(&ModuleName);
+    RtlCreateUnicodeStringFromAsciiz(&ModuleName,
+        NameBuffer);
+    ModuleObject = LdrGetModuleObject(&ModuleName);
+    RtlFreeUnicodeString(&ModuleName);
 
-   DPRINT("ModuleObject: %p\n", ModuleObject);
+    DPRINT("ModuleObject: %p\n", ModuleObject);
 
-   if (ModuleObject == NULL)
-     {
-       CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
-       return NULL;
-     }
-  return LdrPEGetExportByName(ModuleObject->Base, (PUCHAR)(p+1), 0xffff);
+    if (ModuleObject == NULL)
+    {
+        CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
+        return NULL;
+    }
+    return LdrPEGetExportByName(ModuleObject->Base, (PUCHAR)(p+1), 0xffff);
 }
 
 static NTSTATUS
-LdrPEPerformRelocations(PVOID DriverBase, 
-                       ULONG DriverSize)
+LdrPEPerformRelocations (
+    PVOID DriverBase,
+    ULONG DriverSize)
 {
-   PIMAGE_NT_HEADERS NtHeaders;
-   PIMAGE_DATA_DIRECTORY RelocationDDir;
-   PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
-   ULONG Count, i;
-   PVOID Address, MaxAddress;
-   PUSHORT TypeOffset;
-   ULONG_PTR Delta;
-   SHORT Offset;
-   USHORT Type;
-   PUSHORT ShortPtr;
-   PULONG LongPtr;
-
-   NtHeaders = RtlImageNtHeader(DriverBase);
-
-   if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-
-   if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
-   {
-      return STATUS_SUCCESS;
-   }
-
-   Delta = (ULONG_PTR)DriverBase - NtHeaders->OptionalHeader.ImageBase;
-   RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)DriverBase + RelocationDDir->VirtualAddress);
-   RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
-   MaxAddress = DriverBase + DriverSize;
-
-   while (RelocationDir < RelocationEnd &&
-          RelocationDir->SizeOfBlock > 0)
-   {
-      Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
-      Address = DriverBase + RelocationDir->VirtualAddress;
-      TypeOffset = (PUSHORT)(RelocationDir + 1);
-
-      for (i = 0; i < Count; i++)
-      {
-         Offset = *TypeOffset & 0xFFF;
-         Type = *TypeOffset >> 12;
-        ShortPtr = (PUSHORT)(Address + Offset);
-
-        /* Don't relocate after the end of the loaded driver */
-        if ((PVOID)ShortPtr >= MaxAddress)
-        {
-           break;
-        }
-
-        /* 
-         * Don't relocate within the relocation section itself. 
-         * GCC/LD generates sometimes relocation records for the relecotion section.
-         * This is a bug in GCC/LD.
-         */
-        if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
-            (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd) 
-        {
-            switch (Type)
+    PIMAGE_NT_HEADERS NtHeaders;
+    PIMAGE_DATA_DIRECTORY RelocationDDir;
+    PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
+    ULONG Count, i;
+    PVOID Address, MaxAddress;
+    PUSHORT TypeOffset;
+    ULONG_PTR Delta;
+    SHORT Offset;
+    USHORT Type;
+    PUSHORT ShortPtr;
+    PULONG LongPtr;
+
+    NtHeaders = RtlImageNtHeader(DriverBase);
+
+    if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+
+    if (RelocationDDir->VirtualAddress == 0 || RelocationDDir->Size == 0)
+    {
+        return STATUS_SUCCESS;
+    }
+
+    Delta = (ULONG_PTR)DriverBase - NtHeaders->OptionalHeader.ImageBase;
+    RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)DriverBase + RelocationDDir->VirtualAddress);
+    RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
+    MaxAddress = DriverBase + DriverSize;
+
+    while (RelocationDir < RelocationEnd &&
+        RelocationDir->SizeOfBlock > 0)
+    {
+        Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
+        Address = DriverBase + RelocationDir->VirtualAddress;
+        TypeOffset = (PUSHORT)(RelocationDir + 1);
+
+        for (i = 0; i < Count; i++)
+        {
+            Offset = *TypeOffset & 0xFFF;
+            Type = *TypeOffset >> 12;
+            ShortPtr = (PUSHORT)(Address + Offset);
+
+            /* Don't relocate after the end of the loaded driver */
+            if ((PVOID)ShortPtr >= MaxAddress)
             {
-               case IMAGE_REL_BASED_ABSOLUTE:
-                  break;
-
-               case IMAGE_REL_BASED_HIGH:
-                  *ShortPtr += HIWORD(Delta);
-                  break;
-
-               case IMAGE_REL_BASED_LOW:
-                  *ShortPtr += LOWORD(Delta);
-                  break;
-
-               case IMAGE_REL_BASED_HIGHLOW:
-                  LongPtr = (PULONG)ShortPtr;
-                  *LongPtr += Delta;
-                  break;
-
-               case IMAGE_REL_BASED_HIGHADJ:
-               case IMAGE_REL_BASED_MIPS_JMPADDR:
-               default:
-                  DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
-                 DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset);
-                  return STATUS_UNSUCCESSFUL;
+                break;
             }
-        }
-         TypeOffset++;
-      }
-      RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
-   }
 
-   return STATUS_SUCCESS;
+            /*
+            * Don't relocate within the relocation section itself.
+            * GCC/LD generates sometimes relocation records for the relecotion section.
+            * This is a bug in GCC/LD.
+            */
+            if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
+                (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
+            {
+                switch (Type)
+                {
+                case IMAGE_REL_BASED_ABSOLUTE:
+                    break;
+
+                case IMAGE_REL_BASED_HIGH:
+                    *ShortPtr += HIWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_LOW:
+                    *ShortPtr += LOWORD(Delta);
+                    break;
+
+                case IMAGE_REL_BASED_HIGHLOW:
+                    LongPtr = (PULONG)ShortPtr;
+                    *LongPtr += Delta;
+                    break;
+
+                case IMAGE_REL_BASED_HIGHADJ:
+                case IMAGE_REL_BASED_MIPS_JMPADDR:
+                default:
+                    DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
+                    DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address, i, Count, *TypeOffset);
+                    return STATUS_UNSUCCESSFUL;
+                }
+            }
+            TypeOffset++;
+        }
+        RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
+    }
+
+    return STATUS_SUCCESS;
 }
 
 static NTSTATUS
-LdrPEGetOrLoadModule(PMODULE_OBJECT Module, 
-                    PCHAR ImportedName, 
-                    PMODULE_OBJECT* ImportedModule)
+LdrPEGetOrLoadModule (
+    PMODULE_OBJECT Module,
+    PCHAR ImportedName,
+    PMODULE_OBJECT* ImportedModule)
 {
-   UNICODE_STRING DriverName;
-   UNICODE_STRING NameString;
-   WCHAR  NameBuffer[PATH_MAX];
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   if (0 == _stricmp(ImportedName, "ntoskrnl") ||
-       0 == _stricmp(ImportedName, "ntoskrnl.exe"))
-   {
-     *ImportedModule = &NtoskrnlModuleObject;
-     return STATUS_SUCCESS;
-   }
-   
-   if (0 == _stricmp(ImportedName, "hal") ||
-       0 == _stricmp(ImportedName, "hal.dll"))
-   {
-     *ImportedModule = &HalModuleObject;
-     return STATUS_SUCCESS;
-   }
-
-   RtlCreateUnicodeStringFromAsciiz (&DriverName, ImportedName);
-   DPRINT("Import module: %wZ\n", &DriverName);
-
-   *ImportedModule = LdrGetModuleObject(&DriverName);
-   if (*ImportedModule == NULL)
-   {
-     PWCHAR PathEnd;
-     ULONG PathLength;
-
-     PathEnd = wcsrchr(Module->FullName.Buffer, L'\\');
-     if (NULL != PathEnd)
-     {
-        PathLength = (PathEnd - Module->FullName.Buffer + 1) * sizeof(WCHAR);
-        RtlCopyMemory(NameBuffer, Module->FullName.Buffer, PathLength);
-        RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer, DriverName.Length);
-        NameString.Buffer = NameBuffer;
-        NameString.MaximumLength = NameString.Length = PathLength + DriverName.Length;
-
-        /* NULL-terminate */
-        NameString.MaximumLength++;
-        NameBuffer[NameString.Length / sizeof(WCHAR)] = 0;
-
-        Status = LdrLoadModule(&NameString, ImportedModule);
-     }
-     else
-     {
-        DPRINT("Module '%wZ' not loaded yet\n", &DriverName);
-        wcscpy(NameBuffer, L"\\SystemRoot\\system32\\drivers\\");
-        wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
-        RtlInitUnicodeString(&NameString, NameBuffer);
-        Status = LdrLoadModule(&NameString, ImportedModule);
-     }
-     if (!NT_SUCCESS(Status))
-     {
-        wcscpy(NameBuffer, L"\\SystemRoot\\system32\\");
-        wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
-        RtlInitUnicodeString(&NameString, NameBuffer);
-        Status = LdrLoadModule(&NameString, ImportedModule);
+    UNICODE_STRING DriverName;
+    UNICODE_STRING NameString;
+    WCHAR  NameBuffer[PATH_MAX];
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    if (0 == _stricmp(ImportedName, "ntoskrnl") ||
+        0 == _stricmp(ImportedName, "ntoskrnl.exe"))
+    {
+        *ImportedModule = &NtoskrnlModuleObject;
+        return STATUS_SUCCESS;
+    }
+
+    if (0 == _stricmp(ImportedName, "hal") ||
+        0 == _stricmp(ImportedName, "hal.dll"))
+    {
+        *ImportedModule = &HalModuleObject;
+        return STATUS_SUCCESS;
+    }
+
+    RtlCreateUnicodeStringFromAsciiz (&DriverName, ImportedName);
+    DPRINT("Import module: %wZ\n", &DriverName);
+
+    *ImportedModule = LdrGetModuleObject(&DriverName);
+    if (*ImportedModule == NULL)
+    {
+        PWCHAR PathEnd;
+        ULONG PathLength;
+
+        PathEnd = wcsrchr(Module->FullName.Buffer, L'\\');
+        if (NULL != PathEnd)
+        {
+            PathLength = (PathEnd - Module->FullName.Buffer + 1) * sizeof(WCHAR);
+            RtlCopyMemory(NameBuffer, Module->FullName.Buffer, PathLength);
+            RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer, DriverName.Length);
+            NameString.Buffer = NameBuffer;
+            NameString.MaximumLength = NameString.Length = PathLength + DriverName.Length;
+
+            /* NULL-terminate */
+            NameString.MaximumLength++;
+            NameBuffer[NameString.Length / sizeof(WCHAR)] = 0;
+
+            Status = LdrLoadModule(&NameString, ImportedModule);
+        }
+        else
+        {
+            DPRINT("Module '%wZ' not loaded yet\n", &DriverName);
+            wcscpy(NameBuffer, L"\\SystemRoot\\system32\\drivers\\");
+            wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
+            RtlInitUnicodeString(&NameString, NameBuffer);
+            Status = LdrLoadModule(&NameString, ImportedModule);
+        }
         if (!NT_SUCCESS(Status))
         {
-           DPRINT1("Unknown import module: %wZ (Status %lx)\n", &DriverName, Status);
+            wcscpy(NameBuffer, L"\\SystemRoot\\system32\\");
+            wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
+            RtlInitUnicodeString(&NameString, NameBuffer);
+            Status = LdrLoadModule(&NameString, ImportedModule);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("Unknown import module: %wZ (Status %lx)\n", &DriverName, Status);
+            }
         }
-     }
-   }
-   RtlFreeUnicodeString(&DriverName);
-   return Status;   
+    }
+    RtlFreeUnicodeString(&DriverName);
+    return Status;
 }
 
 static PVOID
-LdrPEGetExportByName(PVOID BaseAddress,
-                     PUCHAR SymbolName,
-                     WORD Hint)
+LdrPEGetExportByName (
+    PVOID BaseAddress,
+    PUCHAR SymbolName,
+    WORD Hint )
 {
-   PIMAGE_EXPORT_DIRECTORY ExportDir;
-   PDWORD * ExFunctions;
-   PDWORD * ExNames;
-   USHORT * ExOrdinals;
-   ULONG i;
-   PVOID ExName;
-   ULONG Ordinal;
-   PVOID Function;
-   LONG minn, maxn;
-   ULONG ExportDirSize;
-
-   DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
-
-   ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
-                                                                     TRUE,
-                                                                    IMAGE_DIRECTORY_ENTRY_EXPORT,
-                                                                    &ExportDirSize);
-   if (ExportDir == NULL)
-   {
-      DPRINT1("LdrPEGetExportByName(): no export directory!\n");
-      return NULL;
-   }
-
-
-   /* The symbol names may be missing entirely */
-   if (ExportDir->AddressOfNames == 0)
-   {
-      DPRINT("LdrPEGetExportByName(): symbol names missing entirely\n");
-      return NULL;
-   }
-
-   /*
+    PIMAGE_EXPORT_DIRECTORY ExportDir;
+    PDWORD * ExFunctions;
+    PDWORD * ExNames;
+    USHORT * ExOrdinals;
+    ULONG i;
+    PVOID ExName;
+    ULONG Ordinal;
+    PVOID Function;
+    LONG minn, maxn;
+    ULONG ExportDirSize;
+
+    DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
+
+    ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
+        TRUE,
+        IMAGE_DIRECTORY_ENTRY_EXPORT,
+        &ExportDirSize);
+    if (ExportDir == NULL)
+    {
+        DPRINT1("LdrPEGetExportByName(): no export directory!\n");
+        return NULL;
+    }
+
+
+    /* The symbol names may be missing entirely */
+    if (ExportDir->AddressOfNames == 0)
+    {
+        DPRINT("LdrPEGetExportByName(): symbol names missing entirely\n");
+        return NULL;
+    }
+
+    /*
     * Get header pointers
     */
-   ExNames = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfNames);
-   ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
-   ExFunctions = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
+    ExNames = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfNames);
+    ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
+    ExFunctions = (PDWORD *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
 
-   /*
+    /*
     * Check the hint first
     */
-   if (Hint < ExportDir->NumberOfNames)
-   {
-      ExName = RVA(BaseAddress, ExNames[Hint]);
-      if (strcmp(ExName, (PCHAR)SymbolName) == 0)
-      {
-         Ordinal = ExOrdinals[Hint];
-         Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-         if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-             (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-         {
-            DPRINT("Forward: %s\n", (PCHAR)Function);
-            Function = LdrPEFixupForward((PCHAR)Function);
-            if (Function == NULL)
+    if (Hint < ExportDir->NumberOfNames)
+    {
+        ExName = RVA(BaseAddress, ExNames[Hint]);
+        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
+        {
+            Ordinal = ExOrdinals[Hint];
+            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
+            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
+                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
             {
-               DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
+                DPRINT("Forward: %s\n", (PCHAR)Function);
+                Function = LdrPEFixupForward((PCHAR)Function);
+                if (Function == NULL)
+                {
+                    DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
+                }
+                return Function;
             }
-            return Function;
-         }
-         if (Function != NULL)
-         {
-            return Function;
-         }
-      }
-   }
+            if (Function != NULL)
+            {
+                return Function;
+            }
+        }
+    }
 
-   /*
+    /*
     * Try a binary search first
     */
-   minn = 0;
-   maxn = ExportDir->NumberOfNames - 1;
-   while (minn <= maxn)
-   {
-      LONG mid;
-      LONG res;
-
-      mid = (minn + maxn) / 2;
-
-      ExName = RVA(BaseAddress, ExNames[mid]);
-      res = strcmp(ExName, (PCHAR)SymbolName);
-      if (res == 0)
-      {
-         Ordinal = ExOrdinals[mid];
-         Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-         if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-             (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-         {
-            DPRINT("Forward: %s\n", (PCHAR)Function);
-            Function = LdrPEFixupForward((PCHAR)Function);
-            if (Function == NULL)
+    minn = 0;
+    maxn = ExportDir->NumberOfNames - 1;
+    while (minn <= maxn)
+    {
+        LONG mid;
+        LONG res;
+
+        mid = (minn + maxn) / 2;
+
+        ExName = RVA(BaseAddress, ExNames[mid]);
+        res = strcmp(ExName, (PCHAR)SymbolName);
+        if (res == 0)
+        {
+            Ordinal = ExOrdinals[mid];
+            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
+            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
+                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
             {
-               DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
+                DPRINT("Forward: %s\n", (PCHAR)Function);
+                Function = LdrPEFixupForward((PCHAR)Function);
+                if (Function == NULL)
+                {
+                    DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
+                }
+                return Function;
             }
-            return Function;
-         }
-         if (Function != NULL)
-        {
-            return Function;
-        }
-      }
-      else if (minn == maxn)
-      {
-         DPRINT("LdrPEGetExportByName(): binary search failed\n");
-         break;
-      }
-      else if (res > 0)
-      {
-         maxn = mid - 1;
-      }
-      else
-      {
-         minn = mid + 1;
-      }
-   }
-
-   /*
+            if (Function != NULL)
+            {
+                return Function;
+            }
+        }
+        else if (minn == maxn)
+        {
+            DPRINT("LdrPEGetExportByName(): binary search failed\n");
+            break;
+        }
+        else if (res > 0)
+        {
+            maxn = mid - 1;
+        }
+        else
+        {
+            minn = mid + 1;
+        }
+    }
+
+    /*
     * Fall back on a linear search
     */
-   DPRINT("LdrPEGetExportByName(): Falling back on a linear search of export table\n");
-   for (i = 0; i < ExportDir->NumberOfNames; i++)
-   {
-      ExName = RVA(BaseAddress, ExNames[i]);
-      if (strcmp(ExName, (PCHAR)SymbolName) == 0)
-      {
-         Ordinal = ExOrdinals[i];
-         Function = RVA(BaseAddress, ExFunctions[Ordinal]);
-         DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
-         if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
-             (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
-         {
-            DPRINT("Forward: %s\n", (PCHAR)Function);
-            Function = LdrPEFixupForward((PCHAR)Function);
-         }
-         if (Function == NULL)
-         {
-            break;
-         }
-         return Function;
-      }
-   }
-   DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
-   return (PVOID)NULL;
+    DPRINT("LdrPEGetExportByName(): Falling back on a linear search of export table\n");
+    for (i = 0; i < ExportDir->NumberOfNames; i++)
+    {
+        ExName = RVA(BaseAddress, ExNames[i]);
+        if (strcmp(ExName, (PCHAR)SymbolName) == 0)
+        {
+            Ordinal = ExOrdinals[i];
+            Function = RVA(BaseAddress, ExFunctions[Ordinal]);
+            DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
+            if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
+                (ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
+            {
+                DPRINT("Forward: %s\n", (PCHAR)Function);
+                Function = LdrPEFixupForward((PCHAR)Function);
+            }
+            if (Function == NULL)
+            {
+                break;
+            }
+            return Function;
+        }
+    }
+    DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
+    return (PVOID)NULL;
 }
 
 static PVOID
-LdrPEGetExportByOrdinal (PVOID   BaseAddress,
-                      ULONG   Ordinal)
+LdrPEGetExportByOrdinal (
+    PVOID BaseAddress,
+    ULONG Ordinal )
 {
-   PIMAGE_EXPORT_DIRECTORY ExportDir;
-   ULONG ExportDirSize;
-   PDWORD * ExFunctions;
-   PVOID Function;
-
-   ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData (BaseAddress,
-                                                                      TRUE,
-                                                                     IMAGE_DIRECTORY_ENTRY_EXPORT,
-                                                                     &ExportDirSize);
-
-   ExFunctions = (PDWORD *)RVA(BaseAddress,
-                               ExportDir->AddressOfFunctions);
-   DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n",
-          Ordinal,
-          RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base]));
-
-   Function = 0 != ExFunctions[Ordinal - ExportDir->Base]
-                    ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
-                    : NULL;
-
-   if (((ULONG)Function >= (ULONG)ExportDir) &&
-       ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
-   {
-      DPRINT("Forward: %s\n", (PCHAR)Function);
-      Function = LdrPEFixupForward((PCHAR)Function);
-   }
-
-   return Function;
+    PIMAGE_EXPORT_DIRECTORY ExportDir;
+    ULONG ExportDirSize;
+    PDWORD * ExFunctions;
+    PVOID Function;
+
+    ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData (
+        BaseAddress,
+        TRUE,
+        IMAGE_DIRECTORY_ENTRY_EXPORT,
+        &ExportDirSize);
+
+    ExFunctions = (PDWORD *)RVA(BaseAddress,
+        ExportDir->AddressOfFunctions);
+    DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n",
+        Ordinal,
+        RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base]));
+
+    Function = 0 != ExFunctions[Ordinal - ExportDir->Base]
+        ? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
+        : NULL;
+
+    if (((ULONG)Function >= (ULONG)ExportDir) &&
+        ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+    {
+        DPRINT("Forward: %s\n", (PCHAR)Function);
+        Function = LdrPEFixupForward((PCHAR)Function);
+    }
+
+    return Function;
 }
 
 static NTSTATUS
-LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
-                                PMODULE_OBJECT ImportedModule,
-                                 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
+LdrPEProcessImportDirectoryEntry(
+    PVOID DriverBase,
+    PMODULE_OBJECT ImportedModule,
+    PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory )
 {
-   PVOID* ImportAddressList;
-   PULONG FunctionNameList;
-   ULONG Ordinal;
-
-   if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
-     {
-       return STATUS_UNSUCCESSFUL;
-     }
-
-   /* Get the import address list. */
-   ImportAddressList = (PVOID*)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
-
-   /* Get the list of functions to import. */
-   if (ImportModuleDirectory->OriginalFirstThunk != 0)
-     {
-       FunctionNameList = (PULONG) (DriverBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
-     }
-   else
-     {
-       FunctionNameList = (PULONG)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
-     }
-
-   /* Walk through function list and fixup addresses. */
-   while (*FunctionNameList != 0L)
-     {
-       if ((*FunctionNameList) & 0x80000000)
-         {
-           Ordinal = (*FunctionNameList) & 0x7fffffff;
-           *ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->Base, Ordinal);
-           if ((*ImportAddressList) == NULL)
-             {
-               DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullName);
-               return STATUS_UNSUCCESSFUL;
-             }
-         }
-       else
-         {
-           IMAGE_IMPORT_BY_NAME *pe_name;
-           pe_name = RVA(DriverBase, *FunctionNameList);
-           *ImportAddressList = LdrPEGetExportByName(ImportedModule->Base, pe_name->Name, pe_name->Hint);
-           if ((*ImportAddressList) == NULL)
-             {
-               DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullName);
-               return STATUS_UNSUCCESSFUL;
-             }
-         }
-       ImportAddressList++;
-       FunctionNameList++;
-     }
-   return STATUS_SUCCESS;
+    PVOID* ImportAddressList;
+    PULONG FunctionNameList;
+    ULONG Ordinal;
+
+    if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
+    {
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Get the import address list. */
+    ImportAddressList = (PVOID*)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+
+    /* Get the list of functions to import. */
+    if (ImportModuleDirectory->OriginalFirstThunk != 0)
+    {
+        FunctionNameList = (PULONG) (DriverBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
+    }
+    else
+    {
+        FunctionNameList = (PULONG)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+    }
+
+    /* Walk through function list and fixup addresses. */
+    while (*FunctionNameList != 0L)
+    {
+        if ((*FunctionNameList) & 0x80000000)
+        {
+            Ordinal = (*FunctionNameList) & 0x7fffffff;
+            *ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->Base, Ordinal);
+            if ((*ImportAddressList) == NULL)
+            {
+                DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullName);
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
+        else
+        {
+            IMAGE_IMPORT_BY_NAME *pe_name;
+            pe_name = RVA(DriverBase, *FunctionNameList);
+            *ImportAddressList = LdrPEGetExportByName(ImportedModule->Base, pe_name->Name, pe_name->Hint);
+            if ((*ImportAddressList) == NULL)
+            {
+                DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullName);
+                return STATUS_UNSUCCESSFUL;
+            }
+        }
+        ImportAddressList++;
+        FunctionNameList++;
+    }
+    return STATUS_SUCCESS;
 }
 
 static NTSTATUS
-LdrPEFixupImports(PMODULE_OBJECT Module)
+LdrPEFixupImports ( PMODULE_OBJECT Module )
 {
-   PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
-   PCHAR ImportedName;
-   PMODULE_OBJECT ImportedModule;
-   NTSTATUS Status;
-
-   /*  Process each import module  */
-   ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
-                              RtlImageDirectoryEntryToData(Module->Base,
-                                                           TRUE,
-                                                           IMAGE_DIRECTORY_ENTRY_IMPORT,
-                                                           NULL);
-   DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
-   while (ImportModuleDirectory->Name)
-   {
-      if (Module->Length <= ImportModuleDirectory->Name)
-      {
-         DPRINT1("Invalid import directory in %wZ\n", &Module->FullName);
-         return STATUS_SECTION_NOT_IMAGE;
-      }
-
-      /*  Check to make sure that import lib is kernel  */
-      ImportedName = (PCHAR) Module->Base + ImportModuleDirectory->Name;
-
-      Status = LdrPEGetOrLoadModule(Module, ImportedName, &ImportedModule);
-      if (!NT_SUCCESS(Status))
-      {
-         return Status;
-      }
-
-      Status = LdrPEProcessImportDirectoryEntry(Module->Base, ImportedModule, ImportModuleDirectory);
-      if (!NT_SUCCESS(Status))
-      {
-         return Status;
-      }
-
-      ImportModuleDirectory++;
-   }
-   return STATUS_SUCCESS;  
+    PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
+    PCHAR ImportedName;
+    PMODULE_OBJECT ImportedModule;
+    NTSTATUS Status;
+
+    /*  Process each import module  */
+    ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
+        RtlImageDirectoryEntryToData(Module->Base,
+        TRUE,
+        IMAGE_DIRECTORY_ENTRY_IMPORT,
+        NULL);
+    DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
+    while (ImportModuleDirectory->Name)
+    {
+        if (Module->Length <= ImportModuleDirectory->Name)
+        {
+            DPRINT1("Invalid import directory in %wZ\n", &Module->FullName);
+            return STATUS_SECTION_NOT_IMAGE;
+        }
+
+        /*  Check to make sure that import lib is kernel  */
+        ImportedName = (PCHAR) Module->Base + ImportModuleDirectory->Name;
+
+        Status = LdrPEGetOrLoadModule(Module, ImportedName, &ImportedModule);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+
+        Status = LdrPEProcessImportDirectoryEntry(Module->Base, ImportedModule, ImportModuleDirectory);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+
+        ImportModuleDirectory++;
+    }
+    return STATUS_SUCCESS;
 }
 
 /* EOF */
index 9af2d00..7e20b6b 100644 (file)
 
 /* GLOBALS *******************************************************************/
 
-static PVOID SystemDllEntryPoint = NULL;
-static PVOID SystemDllApcDispatcher = NULL;
-static PVOID SystemDllCallbackDispatcher = NULL;
-static PVOID SystemDllExceptionDispatcher = NULL;
-static PVOID SystemDllRaiseExceptionDispatcher = NULL;
+PVOID SystemDllEntryPoint = NULL;
+PVOID SystemDllApcDispatcher = NULL;
+PVOID SystemDllCallbackDispatcher = NULL;
+PVOID SystemDllExceptionDispatcher = NULL;
+PVOID SystemDllRaiseExceptionDispatcher = NULL;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -144,7 +144,7 @@ NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle,
                            SECTION_ALL_ACCESS,
                            NULL,
                            NULL,
-                           PAGE_READWRITE,
+                           PAGE_READONLY,
                            SEC_IMAGE | SEC_COMMIT,
                            FileHandle);
    if (!NT_SUCCESS(Status))
index 4f61c71..c73a8df 100644 (file)
@@ -41,8 +41,7 @@ NiClosePort (PVOID    ObjectBody, ULONG       HandleCount)
    * If the client has just closed its handle then tell the server what
    * happened and disconnect this port.
    */
-  if (HandleCount == 0 && Port->State == EPORT_CONNECTED_CLIENT && 
-      ObGetObjectPointerCount(Port) == 2)
+  if (HandleCount == 1 && Port->State == EPORT_CONNECTED_CLIENT)
     {
       DPRINT("Informing server\n");
       Message.MessageSize = sizeof(LPC_MESSAGE);
@@ -64,8 +63,7 @@ NiClosePort (PVOID    ObjectBody, ULONG       HandleCount)
    * If the server has closed all of its handles then disconnect the port,
    * don't actually notify the client until it attempts an operation.
    */
-  if (HandleCount == 0 && Port->State == EPORT_CONNECTED_SERVER && 
-      ObGetObjectPointerCount(Port) == 1)
+  if (HandleCount == 1 && Port->State == EPORT_CONNECTED_SERVER)
     {
         DPRINT("Cleaning up server\n");
        Port->OtherPort->OtherPort = NULL;
index dae429f..6d3a905 100644 (file)
@@ -805,8 +805,9 @@ try_again:
                        que_reclaimed = 1;
                        goto try_again;
                }
-               /*DPRINT1("Trying to allocate %lu bytes from paged pool - nothing suitable found, returning NULL\n",
-                       queBytes );*/
+               DPRINT1("Trying to allocate %lu bytes from paged pool - nothing suitable found, returning NULL\n",
+                       queBytes );
+               R_RELEASE_MUTEX(pool);
                return NULL;
        }
        /*
index 0e60384..02bcd73 100644 (file)
@@ -623,15 +623,15 @@ MmGetSavedSwapEntryPage(PFN_TYPE Pfn)
 }
 
 VOID
-MmReferencePage(PFN_TYPE Pfn)
+MmReferencePageUnsafe(PFN_TYPE Pfn)
 {
    KIRQL oldIrql;
 
-   DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+   DPRINT("MmReferencePageUnsafe(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
 
    if (Pfn == 0 || Pfn >= MmPageArraySize)
    {
-      KEBUGCHECK(0);
+      return;
    }
 
    KeAcquireSpinLock(&PageListLock, &oldIrql);
@@ -646,6 +646,19 @@ MmReferencePage(PFN_TYPE Pfn)
    KeReleaseSpinLock(&PageListLock, oldIrql);
 }
 
+VOID
+MmReferencePage(PFN_TYPE Pfn)
+{
+   DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+
+   if (Pfn == 0 || Pfn >= MmPageArraySize)
+   {
+      KEBUGCHECK(0);
+   }
+
+   MmReferencePageUnsafe(Pfn);
+}
+
 ULONG
 MmGetReferenceCountPage(PFN_TYPE Pfn)
 {
@@ -792,15 +805,15 @@ MmGetLockCountPage(PFN_TYPE Pfn)
 }
 
 VOID
-MmLockPage(PFN_TYPE Pfn)
+MmLockPageUnsafe(PFN_TYPE Pfn)
 {
    KIRQL oldIrql;
 
-   DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+   DPRINT("MmLockPageUnsafe(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
 
    if (Pfn == 0 || Pfn >= MmPageArraySize)
    {
-      KEBUGCHECK(0);
+      return;
    }
 
    KeAcquireSpinLock(&PageListLock, &oldIrql);
@@ -815,6 +828,19 @@ MmLockPage(PFN_TYPE Pfn)
    KeReleaseSpinLock(&PageListLock, oldIrql);
 }
 
+VOID
+MmLockPage(PFN_TYPE Pfn)
+{
+   DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
+
+   if (Pfn == 0 || Pfn >= MmPageArraySize)
+   {
+      KEBUGCHECK(0);
+   }
+   
+   MmLockPageUnsafe(Pfn);
+}
+
 VOID
 MmUnlockPage(PFN_TYPE Pfn)
 {
index 6830f99..65b3c9a 100644 (file)
@@ -491,7 +491,8 @@ MmFindGapBottomUp(
 
    /* Check if there is enough space after the last memory area. */
    AlignedAddress = MM_ROUND_UP(PreviousNode->EndingAddress, Granularity);
-   if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
+   if ((ULONG_PTR)HighestAddress > (ULONG_PTR)AlignedAddress &&
+       (ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
    {
       DPRINT("MmFindGapBottomUp: %p\n", AlignedAddress);
       return AlignedAddress;
index e3d7c2a..7f24286 100644 (file)
@@ -29,7 +29,7 @@ extern ULONG MmPageArraySize;
 /*
 MDL Flags desc.
 
-MDL_PAGES_LOCKED              MmProbelAndLockPages has been called for this mdl
+MDL_PAGES_LOCKED              MmProbeAndLockPages has been called for this mdl
 MDL_SOURCE_IS_NONPAGED_POOL   mdl has been build by MmBuildMdlForNonPagedPool
 MDL_PARTIAL                   mdl has been built by IoBuildPartialMdl
 MDL_MAPPING_CAN_FAIL          in case of an error, MmMapLockedPages will return NULL instead of to bugcheck
@@ -233,7 +233,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
    /* Unmap all the pages. */
    for (i = 0; i < PageCount; i++)
    {
-      MmDeleteVirtualMapping(NULL,
+      MmDeleteVirtualMapping(Mdl->Process,
                              (char*)BaseAddress + (i * PAGE_SIZE),
                              FALSE,
                              NULL,
@@ -300,7 +300,7 @@ MmBuildMdlFromPages(PMDL Mdl, PPFN_TYPE Pages)
 {
    memcpy(Mdl + 1, Pages, sizeof(PFN_TYPE) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
 
-   //FIXME: this flag should be set by the caller perhaps?
+   /* FIXME: this flag should be set by the caller perhaps? */
    Mdl->MdlFlags |= MDL_IO_PAGE_READ;
 }
 
@@ -361,6 +361,7 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
    KPROCESSOR_MODE Mode;
    PFN_TYPE Page;
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
+   PMADDRESS_SPACE AddressSpace;
 
    DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl);
 
@@ -374,8 +375,8 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
    ASSERT(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE));
 
 
-   if (Mdl->StartVa >= (PVOID)KERNEL_BASE && 
-       MmGetPfnForProcess(NULL, Mdl->StartVa) > MmPageArraySize)
+   if (Mdl->StartVa >= (PVOID)KERNEL_BASE &&
+       MmGetPfnForProcess(NULL, Mdl->StartVa) >= MmPageArraySize)
    {
        /* phys addr is not phys memory so this must be io memory */
        
@@ -391,22 +392,24 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
 
    if (Mdl->StartVa >= (PVOID)KERNEL_BASE)
    {
-      //FIXME: why isn't AccessMode used?
+      /* FIXME: why isn't AccessMode used? */
       Mode = KernelMode;
       Mdl->Process = NULL;
+      AddressSpace = MmGetKernelAddressSpace();
    }
    else
    {
-      //FIXME: why isn't AccessMode used?
+      /* FIXME: why isn't AccessMode used? */
       Mode = UserMode;
       Mdl->Process = CurrentProcess;      
+      AddressSpace = &CurrentProcess->AddressSpace;
    }
 
 
    /*
     * Lock the pages
     */
-   MmLockAddressSpace(&CurrentProcess->AddressSpace);
+   MmLockAddressSpace(AddressSpace);
 
    for (i = 0; i < NrPages; i++)
    {
@@ -427,10 +430,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
             for (j = 0; j < i; j++)
             {
               Page = MdlPages[j];
-               MmUnlockPage(Page);
-               MmDereferencePage(Page);
+               if (Page < MmPageArraySize)
+               {
+                  MmUnlockPage(Page);
+                  MmDereferencePage(Page);
+               }
             }
-            ExRaiseStatus(Status);
+            MmUnlockAddressSpace(AddressSpace);
+            ExRaiseStatus(STATUS_ACCESS_VIOLATION);
          }
       }
       else
@@ -447,18 +454,25 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
             for (j = 0; j < i; j++)
             {
               Page = MdlPages[j];
-               MmUnlockPage(Page);
-               MmDereferencePage(Page);
+               if (Page < MmPageArraySize)
+               {
+                  MmUnlockPage(Page);
+                  MmDereferencePage(Page);
+               }
             }
-            ExRaiseStatus(Status);
+            MmUnlockAddressSpace(AddressSpace);
+            ExRaiseStatus(STATUS_ACCESS_VIOLATION);
          }
       }
       Page = MmGetPfnForProcess(NULL, Address);
       MdlPages[i] = Page;
-      MmReferencePage(Page);
+      if (Page >= MmPageArraySize)
+         Mdl->MdlFlags |= MDL_IO_SPACE;
+      else
+         MmReferencePage(Page);
    }
    
-   MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
+   MmUnlockAddressSpace(AddressSpace);
    Mdl->MdlFlags |= MDL_PAGES_LOCKED;
 }
 
@@ -838,6 +852,8 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl,
       }
 
       KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
+      
+      Mdl->Process = NULL;
    }
 
    /* Set the virtual mappings for the MDL pages. */
@@ -848,11 +864,18 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl,
       Protect |= PAGE_NOCACHE;
    else if (CacheType == MmWriteCombined)
       DPRINT("CacheType MmWriteCombined not supported!\n");
-   Status = MmCreateVirtualMapping(CurrentProcess,
-                                   Base,
-                                   Protect,
-                                   MdlPages,
-                                   PageCount);
+   if (Mdl->MdlFlags & MDL_IO_SPACE)
+      Status = MmCreateVirtualMappingUnsafe(CurrentProcess,
+                                            Base,
+                                            Protect,
+                                            MdlPages,
+                                            PageCount);
+   else
+      Status = MmCreateVirtualMapping(CurrentProcess,
+                                      Base,
+                                      Protect,
+                                      MdlPages,
+                                      PageCount);
    if (!NT_SUCCESS(Status))
    {
       DbgPrint("Unable to create virtual mapping\n");
index 7c79739..f3ebeae 100644 (file)
@@ -386,10 +386,22 @@ MmInit1(ULONG_PTR FirstKrnlPhysAddr,
    /*
     * Unmap low memory
     */
-#ifndef CONFIG_SMP
-   /* In SMP mode we unmap the low memory in MmInit3.
+#ifdef CONFIG_SMP
+   /* In SMP mode we unmap the low memory pagetable in MmInit3.
       The APIC needs the mapping of the first pages
-      while the processors are starting up. */
+      while the processors are starting up. 
+      We unmap all pages except page 2 and 3. */
+   for (MappingAddress = 0;
+        MappingAddress < 1024 * PAGE_SIZE;
+        MappingAddress += PAGE_SIZE)
+   {
+      if (MappingAddress != 2 * PAGE_SIZE && 
+          MappingAddress != 3 * PAGE_SIZE)
+      {
+         MmRawDeleteVirtualMapping((PVOID)MappingAddress);
+      }
+   }
+#else
    MmDeletePageTable(NULL, 0);
 #endif
 
index 3587bff..2a6a35f 100644 (file)
@@ -727,6 +727,9 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
 
          MmSharePageEntrySectionSegment(Segment, Offset);
 
+         /* FIXME: Should we call MmCreateVirtualMappingUnsafe if
+          * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
+          */
          Status = MmCreateVirtualMapping(MemoryArea->Process,
                                          Address,
                                          Attributes,
@@ -829,14 +832,14 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
       * Just map the desired physical page
       */
       Page = (Offset + MemoryArea->Data.SectionData.ViewOffset) >> PAGE_SHIFT;
-      Status = MmCreateVirtualMapping(AddressSpace->Process,
-                                      Address,
-                                      Region->Protect,
-                                      &Page,
-                                      1);
+      Status = MmCreateVirtualMappingUnsafe(AddressSpace->Process,
+                                            Address,
+                                            Region->Protect,
+                                            &Page,
+                                            1);
       if (!NT_SUCCESS(Status))
       {
-         DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
+         DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
          KEBUGCHECK(0);
          return(Status);
       }
@@ -846,7 +849,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
       */
       if (Locked)
       {
-         MmLockPage(Page);
+         MmLockPageUnsafe(Page);
       }
 
       /*
index aadecb3..7398a8f 100644 (file)
@@ -463,11 +463,41 @@ NtReadVirtualMemory(IN HANDLE ProcessHandle,
                     IN ULONG NumberOfBytesToRead,
                     OUT PULONG NumberOfBytesRead OPTIONAL)
 {
-   NTSTATUS Status;
    PMDL Mdl;
    PVOID SystemAddress;
+   KPROCESSOR_MODE PreviousMode;
    PEPROCESS Process, CurrentProcess;
-
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PAGED_CODE();
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(Buffer,
+                     NumberOfBytesToRead,
+                     1);
+       if(NumberOfBytesRead != NULL)
+       {
+         ProbeForWrite(NumberOfBytesRead,
+                       sizeof(ULONG),
+                       sizeof(ULONG));
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
 
    DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, "
           "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress,
@@ -476,7 +506,7 @@ NtReadVirtualMemory(IN HANDLE ProcessHandle,
    Status = ObReferenceObjectByHandle(ProcessHandle,
                                       PROCESS_VM_WRITE,
                                       NULL,
-                                      UserMode,
+                                      PreviousMode,
                                       (PVOID*)(&Process),
                                       NULL);
    if (!NT_SUCCESS(Status))
@@ -488,7 +518,15 @@ NtReadVirtualMemory(IN HANDLE ProcessHandle,
 
    if (Process == CurrentProcess)
    {
-      memcpy(Buffer, BaseAddress, NumberOfBytesToRead);
+      _SEH_TRY
+      {
+        RtlCopyMemory(Buffer, BaseAddress, NumberOfBytesToRead);
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
    }
    else
    {
@@ -500,39 +538,62 @@ NtReadVirtualMemory(IN HANDLE ProcessHandle,
          ObDereferenceObject(Process);
          return(STATUS_NO_MEMORY);
       }
-      MmProbeAndLockPages(Mdl,
-                          UserMode,
-                          IoWriteAccess);
-
-      KeAttachProcess(&Process->Pcb);
-
-      SystemAddress = MmGetSystemAddressForMdl(Mdl);
-
-        Status = STATUS_SUCCESS;
-        _SEH_TRY {
-            ProbeForRead(BaseAddress, NumberOfBytesToRead, 1);
-            Status = STATUS_PARTIAL_COPY;
-            memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);
-            Status = STATUS_SUCCESS;
-        } _SEH_HANDLE {
-            if(Status != STATUS_PARTIAL_COPY)
-                Status = _SEH_GetExceptionCode();
-        } _SEH_END;
-
-      KeDetachProcess();
-
-      if (Mdl->MappedSystemVa != NULL)
+      _SEH_TRY
       {
-         MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+        MmProbeAndLockPages(Mdl,
+                            PreviousMode,
+                            IoWriteAccess);
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+      
+      if(NT_SUCCESS(Status))
+      {
+        KeAttachProcess(&Process->Pcb);
+
+        SystemAddress = MmGetSystemAddressForMdl(Mdl);
+
+          Status = STATUS_SUCCESS;
+          _SEH_TRY {
+              ProbeForRead(BaseAddress, NumberOfBytesToRead, 1);
+              Status = STATUS_PARTIAL_COPY;
+              RtlCopyMemory(SystemAddress, BaseAddress, NumberOfBytesToRead);
+              Status = STATUS_SUCCESS;
+          } _SEH_HANDLE {
+              if(Status != STATUS_PARTIAL_COPY)
+                  Status = _SEH_GetExceptionCode();
+          } _SEH_END;
+
+        KeDetachProcess();
+
+        if (Mdl->MappedSystemVa != NULL)
+        {
+           MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+        }
+        MmUnlockPages(Mdl);
       }
-      MmUnlockPages(Mdl);
       ExFreePool(Mdl);
    }
 
    ObDereferenceObject(Process);
 
-   if (NumberOfBytesRead)
-      *NumberOfBytesRead = NumberOfBytesToRead;
+   if((NT_SUCCESS(Status) || Status == STATUS_PARTIAL_COPY) &&
+      NumberOfBytesRead != NULL)
+   {
+     _SEH_TRY
+     {
+       *NumberOfBytesRead = NumberOfBytesToRead;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
+   
    return(Status);
 }
 
index 461ebe6..f7159de 100644 (file)
@@ -122,7 +122,6 @@ ExIsResourceAcquiredExclusiveLite@4
 ExIsResourceAcquiredSharedLite@4
 ExLocalTimeToSystemTime@8
 ExNotifyCallback@12
-ExPostSystemEvent@12
 ExQueryPoolBlockSize@8
 ExQueueWorkItem@8
 ExRaiseAccessViolation@0
@@ -153,24 +152,6 @@ ExUuidCreate@4
 ExVerifySuite@4
 @ExWaitForRundownProtectionRelease@4
 ExWindowStationObjectType DATA
-ExInitializeBinaryTree@12
-ExDeleteBinaryTree@4
-ExInsertBinaryTree@12
-ExSearchBinaryTree@12
-ExRemoveBinaryTree@12
-ExTraverseBinaryTree@16
-ExInitializeSplayTree@16
-ExDeleteSplayTree@4
-ExInsertSplayTree@12
-ExSearchSplayTree@12
-ExRemoveSplayTree@12
-ExWeightOfSplayTree@8
-ExTraverseSplayTree@16
-ExInitializeHashTable@16
-ExDeleteHashTable@4
-ExInsertHashTable@16
-ExSearchHashTable@16
-ExRemoveHashTable@16
 @ExfAcquirePushLockExclusive@4
 @ExfAcquirePushLockShared@4
 @ExfReleasePushLock@4
@@ -530,7 +511,7 @@ Ke386IoSetAccessProcess@8
 Ke386QueryIoAccessMap@8
 Ke386SetIoAccessMap@8
 KeAcquireSpinLockAtDpcLevel@4
-KeAcquireDispatcherDatabaseLockAtDpcLevel
+@KeAcquireDispatcherDatabaseLockAtDpcLevel@0
 @KeAcquireInStackQueuedSpinLockAtDpcLevel@8
 KeAcquireInterruptSpinLock@4
 KeAddSystemServiceTable@20
@@ -611,7 +592,7 @@ KeReadStateSemaphore@4
 KeReadStateTimer@4
 KeRegisterBugCheckCallback@20
 KeRegisterBugCheckReasonCallback@16
-KeReleaseDispatcherDatabaseLockFromDpcLevel
+@KeReleaseDispatcherDatabaseLockFromDpcLevel@0
 @KeReleaseInStackQueuedSpinLockFromDpcLevel@4
 KeReleaseInterruptSpinLock@8
 KeReleaseMutant@16
@@ -865,6 +846,7 @@ ObDereferenceObject@4
 ;PfxInsertPrefix
 ;PfxRemovePrefix
 PoCallDriver@8
+PoQueueShutdownWorkItem@4
 PoRegisterDeviceForIdleDetection@16
 PoRegisterSystemState@8
 PoRequestPowerIrp@24
@@ -1231,7 +1213,7 @@ RtlUpperString@8
 RtlValidRelativeSecurityDescriptor@12
 RtlValidSecurityDescriptor@4
 RtlValidSid@4
-;RtlVerifyVersionInfo@16
+RtlVerifyVersionInfo@16
 RtlVolumeDeviceToDosName@8
 RtlWalkFrameChain@12
 RtlWriteRegistryValue@24
@@ -1419,6 +1401,7 @@ ZwYieldExecution@0
 _abnormal_termination
 _alldiv
 _allmul
+_alloca_probe
 _allrem
 _allshl
 _allshr
index 1458a0e..4fcbae9 100644 (file)
@@ -987,6 +987,30 @@ Language=English
 INVALID_WORK_QUEUE_ITEM
 .
 
+MessageId=0xE1
+Severity=Success
+Facility=System
+SymbolicName=WORKER_THREAD_RETURNED_AT_BAD_IRQL
+Language=English
+WORKER_THREAD_RETURNED_AT_BAD_IRQL
+.
+
+MessageId=0xE2
+Severity=Success
+Facility=System
+SymbolicName=MANUALLY_INITIATED_CRASH
+Language=English
+MANUALLY_INITIATED_CRASH
+.
+
+MessageId=0xFA
+Severity=Success
+Facility=System
+SymbolicName=IMPERSONATING_WORKER_THREAD
+Language=English
+IMPERSONATING_WORKER_THREAD
+.
+
 MessageId=0x9A
 Severity=Informational
 Facility=System
index 7665b57..d9aa917 100644 (file)
@@ -11,8 +11,8 @@
        <library>hal</library>\r
        <library>kjs</library>\r
        <library>pseh</library>\r
-       <library>rosrtl</library>\r
        <library>rtl</library>\r
+       <library>rosrtl</library>\r
        <library>string</library>\r
        <library>rossym</library>\r
        <directory name="include">\r
                                <file>trap.s</file>\r
                                <file>tskswitch.S</file>\r
                                <file>tss.c</file>\r
-                               <file>usercall.c</file>\r
+                               <file>usercall.S</file>\r
                                <file>usertrap.c</file>\r
                                <file>v86m.c</file>\r
                                <file>v86m_sup.S</file>\r
                                <file>vdm.c</file>\r
                        </directory>\r
                </if>\r
-               <file>alert.c</file>\r
                <file>apc.c</file>\r
                <file>bug.c</file>\r
                <file>catch.c</file>\r
                <file>clock.c</file>\r
-               <file>critical.c</file>\r
                <file>device.c</file>\r
                <file>dpc.c</file>\r
-               <file>error.c</file>\r
                <file>event.c</file>\r
                <file>gmutex.c</file>\r
                <file>ipi.c</file>\r
@@ -70,6 +67,7 @@
                <file>sem.c</file>\r
                <file>spinlock.c</file>\r
                <file>timer.c</file>\r
+               <file>usercall.c</file>\r
                <file>wait.c</file>\r
        </directory>\r
        <directory name="cc">\r
                                <file>interlck.c</file>\r
                        </directory>\r
                </if>\r
-               <file>btree.c</file>\r
                <file>callback.c</file>\r
+               <file>error.c</file>\r
                <file>event.c</file>\r
                <file>evtpair.c</file>\r
                <file>fmutex.c</file>\r
-               <file>hashtab.c</file>\r
+               <file>handle.c</file>\r
                <file>init.c</file>\r
                <file>interlck.c</file>\r
                <file>list.c</file>\r
                <file>lookas.c</file>\r
                <file>mutant.c</file>\r
-               <file>napi.c</file>\r
                <file>power.c</file>\r
                <file>profile.c</file>\r
                <file>resource.c</file>\r
                <file>rundown.c</file>\r
                <file>sem.c</file>\r
-               <file>stree.c</file>\r
                <file>synch.c</file>\r
                <file>sysinfo.c</file>\r
                <file>time.c</file>\r
                <file>sdcache.c</file>\r
                <file>security.c</file>\r
                <file>symlink.c</file>\r
+               <file>wait.c</file>\r
        </directory>\r
        <directory name="po">\r
                <file>power.c</file>\r
                <file>locale.c</file>\r
                <file>process.c</file>\r
                <file>psmgr.c</file>\r
+               <file>query.c</file>\r
+               <file>security.c</file>\r
                <file>suspend.c</file>\r
                <file>thread.c</file>\r
-               <file>tinfo.c</file>\r
-               <file>w32call.c</file>\r
                <file>win32.c</file>\r
        </directory>\r
        <directory name="rtl">\r
index dcc90ef..bf59c50 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
-/* TYPES *******************************************************************/
+#define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) &                \
+  ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE |           \
+  EX_HANDLE_ENTRY_AUDITONCLOSE)))
+#define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->u1.Object) &   \
+  ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE |           \
+  EX_HANDLE_ENTRY_AUDITONCLOSE)))
 
-/*
- * PURPOSE: Defines a handle
- */
-typedef struct _HANDLE_ENTRY
-{
-  PVOID ObjectBody;
-  ACCESS_MASK GrantedAccess;
-} HANDLE_ENTRY, *PHANDLE_ENTRY;
-
-#define HANDLE_BLOCK_ENTRIES \
-       (((4 * PAGE_SIZE) - \
-         (sizeof(LIST_ENTRY) + sizeof(ULONG))) / sizeof(HANDLE_ENTRY))
-
-#define OB_HANDLE_FLAG_MASK    0x00000007
-#define OB_HANDLE_FLAG_AUDIT   0x00000004
-#define OB_HANDLE_FLAG_PROTECT 0x00000002
-#define OB_HANDLE_FLAG_INHERIT 0x00000001
-
-#define OB_POINTER_TO_ENTRY(Pointer) \
-  (PVOID)((ULONG_PTR)(Pointer) & ~OB_HANDLE_FLAG_MASK)
-
-#define OB_ENTRY_TO_POINTER(Entry) \
-  (PVOID)((ULONG_PTR)(Entry) & ~OB_HANDLE_FLAG_MASK)
-
-/*
- * PURPOSE: Defines a 4 page's worth of handles
- */
-typedef struct
-{
-   LIST_ENTRY entry;
-   ULONG allocation_hint;
-   ULONG allocation_count;
-   HANDLE_ENTRY handles[HANDLE_BLOCK_ENTRIES];
-} HANDLE_BLOCK, *PHANDLE_BLOCK;
-
-
-/* GLOBALS *******************************************************************/
-
-#define TAG_HANDLE_TABLE    TAG('H', 'T', 'B', 'L')
+#define GENERIC_ANY (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
 
 /* FUNCTIONS ***************************************************************/
 
+VOID
+STDCALL
+ObKillProcess(PEPROCESS Process)
+{
+    ObDeleteHandleTable(Process);
+}
 
-/*
- * FUNCTION: Get the data structure for a handle
- * ARGUMENTS:
- *         Process = Process to get the handle for
- *         h = Handle
- * ARGUMENTS: A pointer to the information about the handle on success,
- *            NULL on failure
- */
-static PHANDLE_ENTRY
-ObpGetObjectByHandle(PHANDLE_TABLE HandleTable,
-                    HANDLE h,
-                    HANDLE_BLOCK **Block)
+VOID
+ObpDecrementHandleCount(PVOID ObjectBody)
 {
-   PLIST_ENTRY current;
-   unsigned int handle = (((unsigned int)h) >> 2) - 1;
-   unsigned int count = handle / HANDLE_BLOCK_ENTRIES;
-   HANDLE_BLOCK* blk = NULL;
-   unsigned int i;
-   
-   DPRINT("ObpGetObjectByHandle(HandleTable %x, h %x)\n",HandleTable,h);
-   
-   current = HandleTable->ListHead.Flink;
-   DPRINT("current %x\n",current);
-   
-   for (i = 0; i < count; i++)
-     {
-       current = current->Flink;
-       if (current == (&(HandleTable->ListHead)))
-         {
-            return(NULL);
-         }
-     }
-   
-   blk = CONTAINING_RECORD(current,HANDLE_BLOCK,entry);
-   if (Block)
-      *Block = blk;
-   DPRINT("object: %p\n",&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
-   return(&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
+  POBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
+
+  if ((ObjectHeader->ObjectType != NULL) &&
+      (ObjectHeader->ObjectType->Close != NULL))
+  {
+    /* the handle count should be decremented but we pass the previous value
+       to the callback */
+    ObjectHeader->ObjectType->Close(ObjectBody, NewHandleCount + 1);
+  }
+
+  if(NewHandleCount == 0)
+  {
+    ObDereferenceObject(ObjectBody);
+  }
 }
 
 
@@ -124,29 +77,32 @@ ObpQueryHandleAttributes(HANDLE Handle,
                         POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
   PEPROCESS Process;
-  KIRQL oldIrql;
-  PHANDLE_ENTRY HandleEntry;
+  PHANDLE_TABLE_ENTRY HandleTableEntry;
+  LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  
+  PAGED_CODE();
 
   DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
 
+  KeEnterCriticalRegion();
+
   Process = PsGetCurrentProcess();
 
-  KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
-  HandleEntry = ObpGetObjectByHandle(&Process->HandleTable,
-                                    Handle,
-                                    NULL);
-  if (HandleEntry == NULL)
+  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
+                                          ExHandle);
+  if (HandleTableEntry == NULL)
     {
-      KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+      KeLeaveCriticalRegion();
       return STATUS_INVALID_HANDLE;
     }
 
-  HandleInfo->Inherit =
-    ((ULONG_PTR)HandleEntry->ObjectBody & OB_HANDLE_FLAG_INHERIT);
-  HandleInfo->ProtectFromClose =
-    ((ULONG_PTR)HandleEntry->ObjectBody & OB_HANDLE_FLAG_PROTECT);
+  HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
+  HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
+
+  ExUnlockHandleTableEntry(Process->ObjectTable,
+                           HandleTableEntry);
 
-  KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+  KeLeaveCriticalRegion();
 
   return STATUS_SUCCESS;
 }
@@ -156,37 +112,42 @@ NTSTATUS
 ObpSetHandleAttributes(HANDLE Handle,
                       POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
 {
-  PHANDLE_ENTRY HandleEntry;
   PEPROCESS Process;
-  KIRQL oldIrql;
+  PHANDLE_TABLE_ENTRY HandleTableEntry;
+  LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
+  
+  PAGED_CODE();
 
-  DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
+  DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
 
   Process = PsGetCurrentProcess();
+  
+  KeEnterCriticalRegion();
 
-  KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
-  HandleEntry = ObpGetObjectByHandle(&Process->HandleTable,
-                                    Handle,
-                                    NULL);
-  if (HandleEntry == NULL)
+  HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
+                                          ExHandle);
+  if (HandleTableEntry == NULL)
     {
-      KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+      KeLeaveCriticalRegion();
       return STATUS_INVALID_HANDLE;
     }
 
   if (HandleInfo->Inherit)
-    HandleEntry->ObjectBody = (PVOID)((ULONG_PTR)HandleEntry->ObjectBody | OB_HANDLE_FLAG_INHERIT);
+    HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
   else
-    HandleEntry->ObjectBody = (PVOID)((ULONG_PTR)HandleEntry->ObjectBody & ~OB_HANDLE_FLAG_INHERIT);
+    HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
 
   if (HandleInfo->ProtectFromClose)
-    HandleEntry->ObjectBody = (PVOID)((ULONG_PTR)HandleEntry->ObjectBody | OB_HANDLE_FLAG_PROTECT);
+    HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
   else
-    HandleEntry->ObjectBody = (PVOID)((ULONG_PTR)HandleEntry->ObjectBody & ~OB_HANDLE_FLAG_PROTECT);
+    HandleTableEntry->u1.ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE;
 
   /* FIXME: Do we need to set anything in the object header??? */
 
-  KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
+  ExUnlockHandleTableEntry(Process->ObjectTable,
+                           HandleTableEntry);
+
+  KeLeaveCriticalRegion();
 
   return STATUS_SUCCESS;
 }
@@ -201,46 +162,97 @@ ObDuplicateObject(PEPROCESS SourceProcess,
                  BOOLEAN InheritHandle,
                  ULONG Options)
 {
-  KIRQL oldIrql;
-  PHANDLE_ENTRY SourceHandleEntry;
+  PHANDLE_TABLE_ENTRY SourceHandleEntry;
+  HANDLE_TABLE_ENTRY NewHandleEntry;
   PVOID ObjectBody;
-
-  KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
-  SourceHandleEntry = ObpGetObjectByHandle(&SourceProcess->HandleTable,
-                                          SourceHandle,
-                                          NULL);
+  POBJECT_HEADER ObjectHeader;
+  LONG ExTargetHandle;
+  LONG ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
+  ULONG NewHandleCount;
+  
+  PAGED_CODE();
+  
+  KeEnterCriticalRegion();
+  
+  SourceHandleEntry = ExMapHandleToPointer(SourceProcess->ObjectTable,
+                                           ExSourceHandle);
   if (SourceHandleEntry == NULL)
     {
-      KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
+      KeLeaveCriticalRegion();
       return STATUS_INVALID_HANDLE;
     }
 
-  ObjectBody = OB_ENTRY_TO_POINTER(SourceHandleEntry->ObjectBody);
-  ObReferenceObjectByPointer(ObjectBody,
-                            0,
-                            NULL,
-                            UserMode);
-  
+  ObjectHeader = EX_HTE_TO_HDR(SourceHandleEntry);
+  ObjectBody = HEADER_TO_BODY(ObjectHeader);
+
+  NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
+  if(InheritHandle)
+    NewHandleEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
+  else
+    NewHandleEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
+  NewHandleEntry.u2.GrantedAccess = ((Options & DUPLICATE_SAME_ACCESS) ?
+                                     SourceHandleEntry->u2.GrantedAccess :
+                                     DesiredAccess);
   if (Options & DUPLICATE_SAME_ACCESS)
+  {
+    NewHandleEntry.u2.GrantedAccess = SourceHandleEntry->u2.GrantedAccess;
+  }
+  else
+  {
+    if (DesiredAccess & GENERIC_ANY)
     {
-      DesiredAccess = SourceHandleEntry->GrantedAccess;
+      RtlMapGenericMask(&DesiredAccess,
+                        ObjectHeader->ObjectType->Mapping);
     }
-
-  KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
-  ObCreateHandle(TargetProcess,
-                ObjectBody,
-                DesiredAccess,
-                InheritHandle,
-                TargetHandle);
+    NewHandleEntry.u2.GrantedAccess = DesiredAccess;
+  }
+  
+  /* reference the object so it doesn't get deleted after releasing the lock
+     and before creating a new handle for it */
+  ObReferenceObject(ObjectBody);
+  
+  /* increment the handle count of the object, it should always be >= 2 because
+     we're holding a handle lock to this object! if the new handle count was
+     1 here, we're in big trouble... it would've been safe to increment and
+     check the handle count without using interlocked functions because the
+     entry is locked, which means the handle count can't change. */
+  NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
+  ASSERT(NewHandleCount >= 2);
   
-  if (Options & DUPLICATE_CLOSE_SOURCE)
+  ExUnlockHandleTableEntry(SourceProcess->ObjectTable,
+                           SourceHandleEntry);
+
+  KeLeaveCriticalRegion();
+
+  /* attempt to create the new handle */
+  ExTargetHandle = ExCreateHandle(TargetProcess->ObjectTable,
+                                  &NewHandleEntry);
+  if (ExTargetHandle != EX_INVALID_HANDLE)
+  {
+    if (Options & DUPLICATE_CLOSE_SOURCE)
     {
-      ZwClose(SourceHandle);
+      ObDeleteHandle(SourceProcess,
+                     SourceHandle);
     }
+    
+    ObDereferenceObject(ObjectBody);
 
-  ObDereferenceObject(ObjectBody);
-
-  return STATUS_SUCCESS;
+    *TargetHandle = EX_HANDLE_TO_HANDLE(ExTargetHandle);
+    
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    /* decrement the handle count we previously incremented, but don't call the
+       closing procedure because we're not closing a handle! */
+    if(InterlockedDecrement(&ObjectHeader->HandleCount) == 0)
+    {
+      ObDereferenceObject(ObjectBody);
+    }
+    
+    ObDereferenceObject(ObjectBody);
+    return STATUS_UNSUCCESSFUL;
+  }
 }
 
 /*
@@ -250,7 +262,7 @@ NTSTATUS STDCALL
 NtDuplicateObject (IN  HANDLE          SourceProcessHandle,
                   IN   HANDLE          SourceHandle,
                   IN   HANDLE          TargetProcessHandle,
-                  OUT  PHANDLE         UnsafeTargetHandle,
+                  OUT  PHANDLE         TargetHandle,
                   IN   ACCESS_MASK     DesiredAccess,
                   IN   BOOLEAN         InheritHandle,
                   ULONG                Options)
@@ -281,18 +293,38 @@ NtDuplicateObject (IN     HANDLE          SourceProcessHandle,
 {
    PEPROCESS SourceProcess;
    PEPROCESS TargetProcess;
-   PHANDLE_ENTRY SourceHandleEntry;
-   KIRQL oldIrql;
-   PVOID ObjectBody;
-   HANDLE TargetHandle;
-   NTSTATUS Status;
+   HANDLE hTarget;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
    
    PAGED_CODE();
    
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(TargetHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+   
    Status = ObReferenceObjectByHandle(SourceProcessHandle,
                                      PROCESS_DUP_HANDLE,
                                      NULL,
-                                     UserMode,
+                                     PreviousMode,
                                      (PVOID*)&SourceProcess,
                                      NULL);
    if (!NT_SUCCESS(Status))
@@ -303,7 +335,7 @@ NtDuplicateObject (IN       HANDLE          SourceProcessHandle,
    Status = ObReferenceObjectByHandle(TargetProcessHandle,
                                      PROCESS_DUP_HANDLE,
                                      NULL,
-                                     UserMode,
+                                     PreviousMode,
                                      (PVOID*)&TargetProcess,
                                      NULL);
    if (!NT_SUCCESS(Status))
@@ -313,136 +345,95 @@ NtDuplicateObject (IN    HANDLE          SourceProcessHandle,
      }
 
    /* Check for magic handle first */
-   if (SourceHandle == NtCurrentThread())
+   if (SourceHandle == NtCurrentThread() ||
+       SourceHandle == NtCurrentProcess())
      {
-       ObReferenceObjectByHandle(SourceHandle,
-                                 PROCESS_DUP_HANDLE,
-                                 NULL,
-                                 UserMode,
-                                 &ObjectBody,
-                                 NULL);
-
-       ObCreateHandle(TargetProcess,
-                      ObjectBody,
-                      THREAD_ALL_ACCESS,
-                      InheritHandle,
-                      &TargetHandle);
+       PVOID ObjectBody;
+       POBJECT_TYPE ObjectType;
+       
+       ObjectType = (SourceHandle == NtCurrentThread()) ? PsThreadType : PsProcessType;
+
+       Status = ObReferenceObjectByHandle(SourceHandle,
+                                          0,
+                                          ObjectType,
+                                          PreviousMode,
+                                          &ObjectBody,
+                                          NULL);
+       if(NT_SUCCESS(Status))
+       {
+         if (Options & DUPLICATE_SAME_ACCESS)
+         {
+           /* grant all access rights */
+           DesiredAccess = ((ObjectType == PsThreadType) ? THREAD_ALL_ACCESS : PROCESS_ALL_ACCESS);
+         }
+         else
+         {
+           if (DesiredAccess & GENERIC_ANY)
+           {
+             RtlMapGenericMask(&DesiredAccess,
+                               ObjectType->Mapping);
+           }
+         }
+         Status = ObCreateHandle(TargetProcess,
+                                 ObjectBody,
+                                 DesiredAccess,
+                                 InheritHandle,
+                                 &hTarget);
+
+         ObDereferenceObject(ObjectBody);
+
+         if (Options & DUPLICATE_CLOSE_SOURCE)
+         {
+           ObDeleteHandle(SourceProcess,
+                          SourceHandle);
+         }
+       }
      }
    else
      {
-       KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
-       SourceHandleEntry = ObpGetObjectByHandle(&SourceProcess->HandleTable,
-                                               SourceHandle,
-                                               NULL);
-       if (SourceHandleEntry == NULL)
-        {
-          KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
-          ObDereferenceObject(SourceProcess);
-          ObDereferenceObject(TargetProcess);
-          return(STATUS_INVALID_HANDLE);
-        }
-       ObjectBody = OB_ENTRY_TO_POINTER(SourceHandleEntry->ObjectBody);
-       ObReferenceObjectByPointer(ObjectBody,
-                                 0,
-                                 NULL,
-                                 UserMode);
-
-       if (Options & DUPLICATE_SAME_ACCESS)
-        {
-          DesiredAccess = SourceHandleEntry->GrantedAccess;
-        }
-
-       KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
-
-       ObCreateHandle(TargetProcess,
-                     ObjectBody,
-                     DesiredAccess,
-                     InheritHandle,
-                     &TargetHandle);
+       Status = ObDuplicateObject(SourceProcess,
+                                  TargetProcess,
+                                  SourceHandle,
+                                  &hTarget,
+                                  DesiredAccess,
+                                  InheritHandle,
+                                  Options);
      }
-   
-   if (Options & DUPLICATE_CLOSE_SOURCE)
-     {
-       ZwClose(SourceHandle);
-     }
-   
+
    ObDereferenceObject(TargetProcess);
    ObDereferenceObject(SourceProcess);
-   ObDereferenceObject(ObjectBody);
-   
-   Status = MmCopyToCaller(UnsafeTargetHandle, &TargetHandle, sizeof(HANDLE));
-   if (!NT_SUCCESS(Status))
+
+   if(NT_SUCCESS(Status))
+   {
+     _SEH_TRY
      {
-       return(Status);
+       *TargetHandle = hTarget;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
      }
+     _SEH_END;
+   }
 
-   return(STATUS_SUCCESS);
+   return Status;
 }
 
-VOID ObCloseAllHandles(PEPROCESS Process)
+static VOID STDCALL
+DeleteHandleCallback(PHANDLE_TABLE HandleTable,
+                     PVOID Object,
+                     ULONG GrantedAccess,
+                     PVOID Context)
 {
-   KIRQL oldIrql;
-   PHANDLE_TABLE HandleTable;
-   PLIST_ENTRY current_entry;
-   PHANDLE_BLOCK current;
-   ULONG i;
-   PVOID ObjectBody;
-   
-   DPRINT("ObCloseAllHandles(Process %x)\n", Process);
-   
-   HandleTable = &Process->HandleTable;
-   
-   KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql);
-   
-   current_entry = HandleTable->ListHead.Flink;
-   
-   while (current_entry != &HandleTable->ListHead)
-     {
-       current = CONTAINING_RECORD(current_entry, HANDLE_BLOCK, entry);
-       
-       for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
-         {
-            ObjectBody = OB_ENTRY_TO_POINTER(current->handles[i].ObjectBody);
-            
-            if (ObjectBody != NULL)
-              {
-                 POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
-                 
-#if 0
-                  if (Header->ObjectType == PsProcessType ||
-                     Header->ObjectType == PsThreadType)
-                   {
-                      DPRINT("Deleting handle to %x\n", ObjectBody);
-                   }
-#endif
-                 
-                 ObReferenceObjectByPointer(ObjectBody,
-                                            0,
-                                            NULL,
-                                            UserMode);
-                 InterlockedDecrement(&Header->HandleCount);
-                 current->handles[i].ObjectBody = NULL;
-                 
-                 KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-                 if ((Header->ObjectType != NULL) &&
-                     (Header->ObjectType->Close != NULL))
-                   {
-                      Header->ObjectType->Close(ObjectBody,
-                                                Header->HandleCount);
-                   }
-                 
-                 ObDereferenceObject(ObjectBody);
-                 KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql);
-                 current_entry = &HandleTable->ListHead;
-                 break;
-              }
-         }
-       
-       current_entry = current_entry->Flink;
-     }
-   KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-   DPRINT("ObCloseAllHandles() finished\n");
-   DPRINT("Type %x\n", BODY_TO_HEADER(Process)->ObjectType);
+  POBJECT_HEADER ObjectHeader;
+  PVOID ObjectBody;
+  
+  PAGED_CODE();
+
+  ObjectHeader = EX_OBJ_TO_HDR(Object);
+  ObjectBody = HEADER_TO_BODY(ObjectHeader);
+  
+  ObpDecrementHandleCount(ObjectBody);
 }
 
 VOID ObDeleteHandleTable(PEPROCESS Process)
@@ -450,26 +441,38 @@ VOID ObDeleteHandleTable(PEPROCESS Process)
  * FUNCTION: Deletes the handle table associated with a process
  */
 {
-   PLIST_ENTRY current = NULL;
-   PHANDLE_TABLE HandleTable = NULL;
-   
-   ObCloseAllHandles(Process);
-   
-   HandleTable = &Process->HandleTable;
-   current = RemoveHeadList(&HandleTable->ListHead);
-   
-   while (current != &HandleTable->ListHead)
-     {
-       HANDLE_BLOCK* HandleBlock = CONTAINING_RECORD(current,
-                                                     HANDLE_BLOCK,
-                                                     entry);
-       DPRINT("Freeing %x\n", HandleBlock);
-       ExFreePool(HandleBlock);
-       
-       current = RemoveHeadList(&HandleTable->ListHead);
-     }
+   PAGED_CODE();
+
+   ExDestroyHandleTable(Process->ObjectTable,
+                        DeleteHandleCallback,
+                        Process);
 }
 
+static BOOLEAN STDCALL
+DuplicateHandleCallback(PHANDLE_TABLE HandleTable,
+                        PHANDLE_TABLE_ENTRY HandleTableEntry,
+                        PVOID Context)
+{
+  POBJECT_HEADER ObjectHeader;
+  BOOLEAN Ret = FALSE;
+  
+  PAGED_CODE();
+  
+  Ret = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
+  if(Ret)
+  {
+    ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry);
+    if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
+    {
+      ObReferenceObjectByPointer(HEADER_TO_BODY(ObjectHeader),
+                                0,
+                                NULL,
+                                UserMode);
+    }
+  }
+  
+  return Ret;
+}
 
 VOID ObCreateHandleTable(PEPROCESS Parent,
                         BOOLEAN Inherit,
@@ -482,133 +485,69 @@ VOID ObCreateHandleTable(PEPROCESS Parent,
  *       Process = Process whose handle table is to be created
  */
 {
-   PHANDLE_TABLE ParentHandleTable, HandleTable;
-   KIRQL oldIrql;
-   PLIST_ENTRY parent_current;
-   ULONG i;
-   PHANDLE_BLOCK current_block, new_block;   
-
+   PAGED_CODE();
+   
    DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
          Parent,Inherit,Process);
-   
-   InitializeListHead(&(Process->HandleTable.ListHead));
-   KeInitializeSpinLock(&(Process->HandleTable.ListLock));
-   
-   if (Parent != NULL)
-     {
-       ParentHandleTable = &Parent->HandleTable;
-       HandleTable = &Process->HandleTable;
-
-       KeAcquireSpinLock(&Parent->HandleTable.ListLock, &oldIrql);
-       KeAcquireSpinLockAtDpcLevel(&Process->HandleTable.ListLock);
-       
-       parent_current = ParentHandleTable->ListHead.Flink;
-       
-       while (parent_current != &ParentHandleTable->ListHead)
-         {
-            current_block = CONTAINING_RECORD(parent_current,
-                                              HANDLE_BLOCK,
-                                              entry);
-            new_block = ExAllocatePoolWithTag(NonPagedPool,
-                                              sizeof(HANDLE_BLOCK),
-                                              TAG_HANDLE_TABLE);
-            if (new_block == NULL)
-            {
-               break;
-            }
-            RtlZeroMemory(new_block, sizeof(HANDLE_BLOCK));
-
-            for (i=0; i<HANDLE_BLOCK_ENTRIES; i++)
-            {
-               if (current_block->handles[i].ObjectBody)
-               {
-                  if ((ULONG_PTR)current_block->handles[i].ObjectBody & OB_HANDLE_FLAG_INHERIT)
-                  {
-                     new_block->handles[i].ObjectBody = 
-                       current_block->handles[i].ObjectBody;
-                     new_block->handles[i].GrantedAccess = 
-                       current_block->handles[i].GrantedAccess;
-                     InterlockedIncrement(&(BODY_TO_HEADER(OB_ENTRY_TO_POINTER(current_block->handles[i].ObjectBody))->HandleCount));
-                  }
-               }
-            }
-            InsertTailList(&Process->HandleTable.ListHead, &new_block->entry);
-            parent_current = parent_current->Flink;
-         }
-       KeReleaseSpinLockFromDpcLevel(&Process->HandleTable.ListLock);
-       KeReleaseSpinLock(&Parent->HandleTable.ListLock, oldIrql);
-     }
+   if(Parent != NULL)
+   {
+     Process->ObjectTable = ExDupHandleTable(Process,
+                                             DuplicateHandleCallback,
+                                             NULL,
+                                             Parent->ObjectTable);
+   }
+   else
+   {
+     Process->ObjectTable = ExCreateHandleTable(Process);
+   }
 }
 
 
 NTSTATUS
 ObDeleteHandle(PEPROCESS Process,
-              HANDLE Handle,
-              PVOID *ObjectBody)
+              HANDLE Handle)
 {
-   PHANDLE_ENTRY HandleEntry;
+   PHANDLE_TABLE_ENTRY HandleEntry;
    PVOID Body;
-   KIRQL oldIrql;
-   PHANDLE_TABLE HandleTable;
-   POBJECT_HEADER Header;
-   HANDLE_BLOCK *Block;
+   POBJECT_HEADER ObjectHeader;
+   LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
    
    PAGED_CODE();
 
    DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
-
-   HandleTable = &Process->HandleTable;
-
-   KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql);
-
-   HandleEntry = ObpGetObjectByHandle(HandleTable, Handle, &Block);
-   if (HandleEntry == NULL)
+   
+   KeEnterCriticalRegion();
+   
+   HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
+                                      ExHandle);
+   if(HandleEntry != NULL)
+   {
+     if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
      {
-       KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-       *ObjectBody = NULL;
-       return STATUS_INVALID_HANDLE;
-     }
+       ExUnlockHandleTableEntry(Process->ObjectTable,
+                                HandleEntry);
 
-   if ((ULONG_PTR)HandleEntry->ObjectBody & OB_HANDLE_FLAG_PROTECT)
-     {
-       KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-       *ObjectBody = NULL;
-       return STATUS_HANDLE_NOT_CLOSABLE;
-     }
+       KeLeaveCriticalRegion();
 
-   Body = OB_ENTRY_TO_POINTER(HandleEntry->ObjectBody);
-   DPRINT("ObjectBody %x\n", Body);
-   if (Body == NULL)
-     {
-       KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-       *ObjectBody = NULL;
-       return STATUS_UNSUCCESSFUL;
+       return STATUS_HANDLE_NOT_CLOSABLE;
      }
 
-   Header = BODY_TO_HEADER(Body);
-   ObReferenceObjectByPointer(Body,
-                             0,
-                             NULL,
-                             UserMode);
-   InterlockedDecrement(&Header->HandleCount);
-   HandleEntry->ObjectBody = NULL;
-
-   Block->allocation_count--;
-   Block->allocation_hint = (ULONG_PTR)Handle % HANDLE_BLOCK_ENTRIES;
-
-   KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
-
-   if ((Header->ObjectType != NULL) &&
-       (Header->ObjectType->Close != NULL))
-     {
-       Header->ObjectType->Close(Body, Header->HandleCount);
-     }
-
-   *ObjectBody = Body;
-
-   DPRINT("Finished ObDeleteHandle()\n");
-
-   return STATUS_SUCCESS;
+     ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
+     Body = HEADER_TO_BODY(ObjectHeader);
+     
+     ObpDecrementHandleCount(Body);
+     
+     /* destroy and unlock the handle entry */
+     ExDestroyHandleByEntry(Process->ObjectTable,
+                            HandleEntry,
+                            ExHandle);
+     
+     KeLeaveCriticalRegion();
+     
+     return STATUS_SUCCESS;
+   }
+   KeLeaveCriticalRegion();
+   return STATUS_INVALID_HANDLE;
 }
 
 
@@ -626,94 +565,59 @@ ObCreateHandle(PEPROCESS Process,
  * NOTE: The handle is valid only in the context of the current process
  */
 {
-   LIST_ENTRY* current;
-   unsigned int handle=1;
-   unsigned int Loop, Index, MaxIndex;
-   HANDLE_BLOCK* new_blk = NULL;
-   PHANDLE_TABLE HandleTable;
-   KIRQL oldlvl;
+   HANDLE_TABLE_ENTRY NewEntry;
+   POBJECT_HEADER ObjectHeader;
+   LONG ExHandle;
    
    PAGED_CODE();
 
    DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
 
    ASSERT(Process);
+   ASSERT(ObjectBody);
+
+   ObjectHeader = BODY_TO_HEADER(ObjectBody);
 
-   if (ObjectBody != NULL)
+   ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
+   
+   if (GrantedAccess & MAXIMUM_ALLOWED)
      {
-       InterlockedIncrement(&(BODY_TO_HEADER(ObjectBody)->HandleCount));
+        GrantedAccess &= ~MAXIMUM_ALLOWED;
+        GrantedAccess |= GENERIC_ALL;
      }
-   HandleTable = &Process->HandleTable;
-   KeAcquireSpinLock(&HandleTable->ListLock, &oldlvl);
-   current = HandleTable->ListHead.Flink;
-   /*
-    * Scan through the currently allocated handle blocks looking for a free
-    * slot
-    */
-   while (current != (&HandleTable->ListHead))
-     {
-       HANDLE_BLOCK* blk = CONTAINING_RECORD(current,HANDLE_BLOCK,entry);
 
-       DPRINT("Current %x\n",current);
-
-       if (blk->allocation_count == HANDLE_BLOCK_ENTRIES)
-         {
-            handle = handle + HANDLE_BLOCK_ENTRIES;
-            current = current->Flink;
-            continue;
-         }
+   if (GrantedAccess & GENERIC_ANY)
+     {
+       RtlMapGenericMask(&GrantedAccess,
+                        ObjectHeader->ObjectType->Mapping);
+     }
 
-       Index = blk->allocation_hint;
-       MaxIndex = HANDLE_BLOCK_ENTRIES;
-       for (Loop = 0; Loop < 2; Loop++)
-         {
-            for (Index = 0; Index < MaxIndex; Index++)
-              {
-                DPRINT("Considering slot %d containing %x\n", Index, blk->handles[Index]);
-                if (blk->handles[Index].ObjectBody == NULL)
-                  {
-                    blk->handles[Index].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
-                    if (Inherit)
-                      blk->handles[Index].ObjectBody = (PVOID)((ULONG_PTR)blk->handles[Index].ObjectBody | OB_HANDLE_FLAG_INHERIT);
-                    blk->handles[Index].GrantedAccess = GrantedAccess;
-                    blk->allocation_hint = Index + 1;
-                    blk->allocation_count++;
-                    KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
-                    *HandleReturn = (HANDLE)((handle + Index) << 2);
-                    return(STATUS_SUCCESS);
-                  }
-              }
-            Index = 0;
-            MaxIndex = blk->allocation_hint;
-         }
-       
-       handle = handle + HANDLE_BLOCK_ENTRIES;
-       current = current->Flink;
+   NewEntry.u1.Object = ObjectHeader;
+   if(Inherit)
+     NewEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
+   else
+     NewEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
+   NewEntry.u2.GrantedAccess = GrantedAccess;
+   
+   ExHandle = ExCreateHandle(Process->ObjectTable,
+                             &NewEntry);
+   DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader, *HandleReturn, Process->ObjectTable);
+   if(ExHandle != EX_INVALID_HANDLE)
+   {
+     if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
+     {
+      ObReferenceObjectByPointer(ObjectBody,
+                                0,
+                                NULL,
+                                UserMode);
      }
+     
+     *HandleReturn = EX_HANDLE_TO_HANDLE(ExHandle);
 
-   /*
-    * Add a new handle block to the end of the list
-    */
-   new_blk = 
-     (HANDLE_BLOCK *)ExAllocatePoolWithTag(NonPagedPool,sizeof(HANDLE_BLOCK),
-                                          TAG_HANDLE_TABLE);
-   if (!new_blk)
-    {
-      *HandleReturn = (PHANDLE)NULL;
-      return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-   RtlZeroMemory(new_blk,sizeof(HANDLE_BLOCK));
-   InsertTailList(&(Process->HandleTable.ListHead),
-                 &new_blk->entry);
-   new_blk->handles[0].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
-   if (Inherit)
-     new_blk->handles[0].ObjectBody = (PVOID)((ULONG_PTR)new_blk->handles[0].ObjectBody | OB_HANDLE_FLAG_INHERIT);
-   new_blk->handles[0].GrantedAccess = GrantedAccess;
-   new_blk->allocation_hint = 1;
-   new_blk->allocation_count++;
-   KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
-   *HandleReturn = (HANDLE)(handle << 2);
-   return(STATUS_SUCCESS);
+     return STATUS_SUCCESS;
+   }
+
+   return STATUS_UNSUCCESSFUL;
 }
 
 
@@ -724,31 +628,35 @@ NTSTATUS STDCALL
 ObQueryObjectAuditingByHandle(IN HANDLE Handle,
                              OUT PBOOLEAN GenerateOnClose)
 {
+  PHANDLE_TABLE_ENTRY HandleEntry;
   PEPROCESS Process;
-  KIRQL oldIrql;
-  PHANDLE_ENTRY HandleEntry;
+  LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
   
   PAGED_CODE();
 
   DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
 
   Process = PsGetCurrentProcess();
-
-  KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
-  HandleEntry = ObpGetObjectByHandle(&Process->HandleTable,
-                                    Handle,
-                                    NULL);
-  if (HandleEntry == NULL)
-    {
-      KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
-      return STATUS_INVALID_HANDLE;
-    }
-
-  *GenerateOnClose = (BOOLEAN)((ULONG_PTR)HandleEntry->ObjectBody | OB_HANDLE_FLAG_AUDIT);
-
-  KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
-
-  return STATUS_SUCCESS;
+  
+  KeEnterCriticalRegion();
+
+  HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
+                                     ExHandle);
+  if(HandleEntry != NULL)
+  {
+    *GenerateOnClose = (HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_AUDITONCLOSE) != 0;
+    
+    ExUnlockHandleTableEntry(Process->ObjectTable,
+                             HandleEntry);
+
+    KeLeaveCriticalRegion();
+    
+    return STATUS_SUCCESS;
+  }
+  
+  KeLeaveCriticalRegion();
+  
+  return STATUS_INVALID_HANDLE;
 }
 
 
@@ -775,13 +683,13 @@ ObReferenceObjectByHandle(HANDLE Handle,
                          PVOID* Object,
                          POBJECT_HANDLE_INFORMATION HandleInformation)
 {
-   PHANDLE_ENTRY HandleEntry;
+   PHANDLE_TABLE_ENTRY HandleEntry;
    POBJECT_HEADER ObjectHeader;
-   KIRQL oldIrql;
    PVOID ObjectBody;
    ACCESS_MASK GrantedAccess;
    ULONG Attributes;
    NTSTATUS Status;
+   LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
    
    PAGED_CODE();
    
@@ -795,8 +703,6 @@ ObReferenceObjectByHandle(HANDLE Handle,
    if (Handle == NtCurrentProcess() && 
        (ObjectType == PsProcessType || ObjectType == NULL))
      {
-       DPRINT("Reference from %x\n", ((PULONG)&Handle)[-1]);
-       
        Status = ObReferenceObjectByPointer(PsGetCurrentProcess(),
                                            PROCESS_ALL_ACCESS,
                                            PsProcessType,
@@ -808,7 +714,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
 
        if (HandleInformation != NULL)
          {
-           HandleInformation->HandleAttributes = 0; /* FIXME? */
+           HandleInformation->HandleAttributes = 0;
            HandleInformation->GrantedAccess = PROCESS_ALL_ACCESS;
          }
 
@@ -836,7 +742,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
 
        if (HandleInformation != NULL)
          {
-           HandleInformation->HandleAttributes = 0; /* FIXME? */
+           HandleInformation->HandleAttributes = 0;
            HandleInformation->GrantedAccess = THREAD_ALL_ACCESS;
          }
 
@@ -850,56 +756,77 @@ ObReferenceObjectByHandle(HANDLE Handle,
        return(STATUS_OBJECT_TYPE_MISMATCH);
      }
    
-   KeAcquireSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,
-                    &oldIrql);
-   HandleEntry = ObpGetObjectByHandle(&PsGetCurrentProcess()->HandleTable,
-                                     Handle,
-                                     NULL);
-   if (HandleEntry == NULL || HandleEntry->ObjectBody == 0)
+   /* desire as much access rights as possible */
+   if (DesiredAccess & MAXIMUM_ALLOWED)
      {
-       KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,
-                         oldIrql);
-       return(STATUS_INVALID_HANDLE);
+        DesiredAccess &= ~MAXIMUM_ALLOWED;
+        DesiredAccess |= GENERIC_ALL;
      }
-   ObjectBody = OB_ENTRY_TO_POINTER(HandleEntry->ObjectBody);
-   DPRINT("ObjectBody %p\n",ObjectBody);
-   ObjectHeader = BODY_TO_HEADER(ObjectBody);
-   DPRINT("ObjectHeader->RefCount %lu\n",ObjectHeader->RefCount);
-   ObReferenceObjectByPointer(ObjectBody,
-                             0,
-                             NULL,
-                             UserMode);
-   Attributes = (ULONG_PTR)HandleEntry->ObjectBody & OB_HANDLE_FLAG_MASK;
-   GrantedAccess = HandleEntry->GrantedAccess;
-   KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,
-                    oldIrql);
    
-   ObjectHeader = BODY_TO_HEADER(ObjectBody);
-   DPRINT("ObjectHeader->RefCount %lu\n",ObjectHeader->RefCount);
+   KeEnterCriticalRegion();
+   
+   HandleEntry = ExMapHandleToPointer(PsGetCurrentProcess()->ObjectTable,
+                                     ExHandle);
+   if (HandleEntry == NULL)
+     {
+        KeLeaveCriticalRegion();
+        DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle);
+        return(STATUS_INVALID_HANDLE);
+     }
 
+   ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
+   ObjectBody = HEADER_TO_BODY(ObjectHeader);
+   
+   DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, PsGetCurrentProcess()->ObjectTable);
+   
    if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
      {
-       CHECKPOINT;
-       return(STATUS_OBJECT_TYPE_MISMATCH);
+        DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->ObjectType ? &ObjectHeader->ObjectType->TypeName : NULL, Handle);
+
+        ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+                                 HandleEntry);
+
+        KeLeaveCriticalRegion();
+
+        return(STATUS_OBJECT_TYPE_MISMATCH);
      }
-   
-   if (ObjectHeader->ObjectType == PsProcessType)
+
+   /* map the generic access masks if the caller asks for generic access */
+   if (DesiredAccess & GENERIC_ANY)
      {
-       DPRINT("Reference from %x\n", ((PULONG)&Handle)[-1]);
+        RtlMapGenericMask(&DesiredAccess,
+                          BODY_TO_HEADER(ObjectBody)->ObjectType->Mapping);
      }
    
-   if (DesiredAccess && AccessMode == UserMode)
+   GrantedAccess = HandleEntry->u2.GrantedAccess;
+   
+   /* Unless running as KernelMode, deny access if caller desires more access
+      rights than the handle can grant */
+   if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
      {
-       RtlMapGenericMask(&DesiredAccess, ObjectHeader->ObjectType->Mapping);
+        ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+                                 HandleEntry);
 
-       if (!(GrantedAccess & DesiredAccess) &&
-           !((~GrantedAccess) & DesiredAccess))
-         {
-            CHECKPOINT;
-            return(STATUS_ACCESS_DENIED);
-         }
+        KeLeaveCriticalRegion();
+        
+        DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
+
+        return(STATUS_ACCESS_DENIED);
      }
 
+   ObReferenceObjectByPointer(ObjectBody,
+                             0,
+                             NULL,
+                             UserMode);
+   Attributes = HandleEntry->u1.ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
+                                                EX_HANDLE_ENTRY_INHERITABLE |
+                                                EX_HANDLE_ENTRY_AUDITONCLOSE);
+
+   ExUnlockHandleTableEntry(PsGetCurrentProcess()->ObjectTable,
+                            HandleEntry);
+   
+   KeLeaveCriticalRegion();
+
    if (HandleInformation != NULL)
      {
        HandleInformation->HandleAttributes = Attributes;
@@ -908,7 +835,6 @@ ObReferenceObjectByHandle(HANDLE Handle,
 
    *Object = ObjectBody;
    
-   CHECKPOINT;
    return(STATUS_SUCCESS);
 }
 
@@ -932,17 +858,12 @@ ObReferenceObjectByHandle(HANDLE Handle,
 NTSTATUS STDCALL
 NtClose(IN HANDLE Handle)
 {
-   PVOID               ObjectBody;
-   POBJECT_HEADER      Header;
    NTSTATUS Status;
    
    PAGED_CODE();
    
-   DPRINT("NtClose(Handle %x)\n",Handle);
-   
    Status = ObDeleteHandle(PsGetCurrentProcess(),
-                          Handle,
-                          &ObjectBody);
+                          Handle);
    if (!NT_SUCCESS(Status))
      {
         if(((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->ExceptionPort)
@@ -950,11 +871,6 @@ NtClose(IN HANDLE Handle)
        return Status;
      }
    
-   Header = BODY_TO_HEADER(ObjectBody);
-   
-   DPRINT("Dereferencing %x\n", ObjectBody);
-   ObDereferenceObject(ObjectBody);
-   
    return(STATUS_SUCCESS);
 }
 
@@ -978,9 +894,6 @@ ObInsertObject(IN PVOID Object,
   Access = DesiredAccess;
   ObjectHeader = BODY_TO_HEADER(Object);
 
-  RtlMapGenericMask(&Access,
-                   ObjectHeader->ObjectType->Mapping);
-
   return(ObCreateHandle(PsGetCurrentProcess(),
                        Object,
                        Access,
@@ -992,42 +905,7 @@ ObInsertObject(IN PVOID Object,
 ULONG
 ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable)
 {
-  PHANDLE_BLOCK blk;
-  POBJECT_HEADER Header;
-  PVOID ObjectBody;
-  KIRQL OldIrql;
-  PLIST_ENTRY current;
-  ULONG i;
-  ULONG Count=0;
-
-  KeAcquireSpinLock(&HandleTable->ListLock, &OldIrql);
-
-  current = HandleTable->ListHead.Flink;
-  while (current != &HandleTable->ListHead)
-    {
-      blk = CONTAINING_RECORD(current, HANDLE_BLOCK, entry);
-
-      for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
-       {
-         ObjectBody = OB_ENTRY_TO_POINTER(blk->handles[i].ObjectBody);
-         if (ObjectBody != NULL)
-           {
-             Header = BODY_TO_HEADER(ObjectBody);
-
-             /* Make sure this is real. Okay! For real!*/
-             if ((Header->ObjectType != NULL) &&
-                     (Header->ObjectType->Close != NULL))
-               Count++;
-           }
-       }
-
-      current = current->Flink;
-    }
-
-  KeReleaseSpinLock(&HandleTable->ListLock,
-                   OldIrql);
-
-  return Count;
+  return HandleTable->HandleCount;
 }
 
 /*
@@ -1085,7 +963,7 @@ ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
                                int Count)
 {
       ULONG P;
-      KIRQL oldIrql;
+//      KIRQL oldIrql;
 
 //      pshi->HandleValue;
 
@@ -1097,14 +975,14 @@ ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
       P = (ULONG) Process->UniqueProcessId;
       pshi->UniqueProcessId = (USHORT) P;
 
-      KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
+//      KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
 
 //      pshi->GrantedAccess;
 //      pshi->Object;
 //      pshi->ObjectTypeIndex;
 //      pshi->HandleAttributes;
 
-      KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );
+//      KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );
 
       return;
 }
index f54fbf6..44a69c1 100644 (file)
@@ -25,18 +25,6 @@ typedef struct _RETENTION_CHECK_PARAMS
 
 /* FUNCTIONS ************************************************************/
 
-PVOID HEADER_TO_BODY(POBJECT_HEADER obj)
-{
-  return(((char*)obj)+sizeof(OBJECT_HEADER)-sizeof(COMMON_BODY_HEADER));
-}
-
-
-POBJECT_HEADER BODY_TO_HEADER(PVOID body)
-{
-  PCOMMON_BODY_HEADER chdr = (PCOMMON_BODY_HEADER)body;
-  return(CONTAINING_RECORD((&(chdr->Type)),OBJECT_HEADER,Type));
-}
-
 NTSTATUS
 ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
                            IN KPROCESSOR_MODE AccessMode,
@@ -102,6 +90,7 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
         CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
         CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
         CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
+        CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
       }
 
       return STATUS_SUCCESS;
@@ -147,6 +136,53 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
     {
       CapturedObjectAttributes->SecurityDescriptor = NULL;
     }
+
+    if(AttributesCopy.SecurityQualityOfService != NULL)
+    {
+      SECURITY_QUALITY_OF_SERVICE SafeQoS;
+
+      _SEH_TRY
+      {
+        ProbeForRead(AttributesCopy.SecurityQualityOfService,
+                     sizeof(SECURITY_QUALITY_OF_SERVICE),
+                     sizeof(ULONG));
+        SafeQoS = *(PSECURITY_QUALITY_OF_SERVICE)AttributesCopy.SecurityQualityOfService;
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if(!NT_SUCCESS(Status))
+      {
+        DPRINT1("Unable to capture QoS!!!\n");
+        goto failcleanupsdescriptor;
+      }
+
+      if(SafeQoS.Length != sizeof(SECURITY_QUALITY_OF_SERVICE))
+      {
+        DPRINT1("Unable to capture QoS, wrong size!!!\n");
+        Status = STATUS_INVALID_PARAMETER;
+        goto failcleanupsdescriptor;
+      }
+
+      CapturedObjectAttributes->SecurityQualityOfService = ExAllocatePool(PoolType,
+                                                                          sizeof(SECURITY_QUALITY_OF_SERVICE));
+      if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
+      {
+        *CapturedObjectAttributes->SecurityQualityOfService = SafeQoS;
+      }
+      else
+      {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto failcleanupsdescriptor;
+      }
+    }
+    else
+    {
+      CapturedObjectAttributes->SecurityQualityOfService = NULL;
+    }
   }
 
   if(ObjectName != NULL)
@@ -259,6 +295,8 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
     {
       ExFreePool(ObjectName->Buffer);
     }
+
+failcleanupsdescriptor:
     if(CapturedObjectAttributes != NULL)
     {
       /* cleanup allocated resources */
@@ -293,11 +331,18 @@ ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttribut
                to ObpCaptureObjectAttributes() to avoid memory leaks */
   if(AccessMode != KernelMode || CaptureIfKernel)
   {
-    if(CapturedObjectAttributes != NULL &&
-       CapturedObjectAttributes->SecurityDescriptor != NULL)
+    if(CapturedObjectAttributes != NULL)
     {
-      ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
-      CapturedObjectAttributes->SecurityDescriptor = NULL;
+      if(CapturedObjectAttributes->SecurityDescriptor != NULL)
+      {
+        ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
+        CapturedObjectAttributes->SecurityDescriptor = NULL;
+      }
+      if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
+      {
+        ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
+        CapturedObjectAttributes->SecurityQualityOfService = NULL;
+      }
     }
     if(ObjectName != NULL &&
        ObjectName->Length > 0)
@@ -367,7 +412,7 @@ ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
   else
     {
       Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory,
-                                        DIRECTORY_TRAVERSE,
+                                        0,
                                         NULL,
                                         UserMode,
                                         &CurrentObject,
@@ -677,7 +722,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
   RtlZeroMemory(Header, OBJECT_ALLOC_SIZE(ObjectSize));
 
   /* Initialize the object header */
-  DPRINT("Initalizing header\n");
+  DPRINT("Initalizing header 0x%x (%wZ)\n", Header, &Type->TypeName);
   Header->HandleCount = 0;
   Header->RefCount = 1;
   Header->ObjectType = Type;
@@ -849,7 +894,7 @@ ObReferenceObjectByPointer(IN PVOID Object,
        DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
      }
  
-   if (Header->CloseInProcess)
+   if (Header->RefCount == 0 && !Header->Permanent)
    {
       if (Header->ObjectType == PsProcessType)
         {
@@ -862,7 +907,10 @@ ObReferenceObjectByPointer(IN PVOID Object,
       return(STATUS_UNSUCCESSFUL);
    }
 
-   InterlockedIncrement(&Header->RefCount);
+   if (1 == InterlockedIncrement(&Header->RefCount) && !Header->Permanent)
+   {
+      KEBUGCHECK(0);
+   }
    
    return(STATUS_SUCCESS);
 }
@@ -978,12 +1026,6 @@ ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
       KEBUGCHECK(0);
     }
 
-  if (ObjectHeader->CloseInProcess)
-    {
-      KEBUGCHECK(0);
-      return STATUS_UNSUCCESSFUL;
-    }
-  ObjectHeader->CloseInProcess = TRUE;
   
   switch (KeGetCurrentIrql ())
     {
@@ -1049,12 +1091,11 @@ ObfReferenceObject(IN PVOID Object)
   Header = BODY_TO_HEADER(Object);
 
   /* No one should be referencing an object once we are deleting it. */
-  if (Header->CloseInProcess)
-    {
-      KEBUGCHECK(0);
-    }
+  if (InterlockedIncrement(&Header->RefCount) == 1 && !Header->Permanent)
+  {
+     KEBUGCHECK(0);
+  }
 
-  (VOID)InterlockedIncrement(&Header->RefCount);
 }
 
 
@@ -1080,25 +1121,23 @@ ObfDereferenceObject(IN PVOID Object)
   POBJECT_HEADER Header;
   LONG NewRefCount;
   BOOL Permanent;
-  ULONG HandleCount;
 
   ASSERT(Object);
 
   /* Extract the object header. */
   Header = BODY_TO_HEADER(Object);
   Permanent = Header->Permanent;
-  HandleCount = Header->HandleCount;
 
   /* 
      Drop our reference and get the new count so we can tell if this was the
      last reference.
   */
   NewRefCount = InterlockedDecrement(&Header->RefCount);
+  DPRINT("ObfDereferenceObject(0x%x)==%d (%wZ)\n", Object, NewRefCount, &Header->ObjectType->TypeName);
   ASSERT(NewRefCount >= 0);
 
   /* Check whether the object can now be deleted. */
   if (NewRefCount == 0 &&
-      HandleCount == 0 &&
       !Permanent)
     {
       ObpDeleteObjectDpcLevel(Header, NewRefCount);
diff --git a/reactos/ntoskrnl/ob/wait.c b/reactos/ntoskrnl/ob/wait.c
new file mode 100644 (file)
index 0000000..1b693c6
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * COPYRIGHT:          See COPYING in the top level directory
+ * PROJECT:            ReactOS kernel
+ * FILE:               ntoskrnl/ob/wait.c
+ * PURPOSE:            Handles Waiting on Objects
+ * 
+ * PROGRAMMERS:        Alex Ionescu (alex@relsoft.net) - Created file
+ *                     David Welch (welch@mcmail.com)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOL inline FASTCALL KiIsObjectWaitable(PVOID Object);
+
+NTSTATUS STDCALL
+NtWaitForMultipleObjects(IN ULONG ObjectCount,
+                        IN PHANDLE ObjectsArray,
+                        IN WAIT_TYPE WaitType,
+                        IN BOOLEAN Alertable,
+                        IN PLARGE_INTEGER TimeOut  OPTIONAL)
+{
+   KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
+   HANDLE SafeObjectsArray[MAXIMUM_WAIT_OBJECTS];
+   PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
+   ULONG i, j;
+   KPROCESSOR_MODE PreviousMode;
+   LARGE_INTEGER SafeTimeOut;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   DPRINT("NtWaitForMultipleObjects(ObjectCount %lu ObjectsArray[] %x, Alertable %d, "
+         "TimeOut %x)\n", ObjectCount,ObjectsArray,Alertable,TimeOut);
+
+   PreviousMode = ExGetPreviousMode();
+
+   if (ObjectCount > MAXIMUM_WAIT_OBJECTS)
+     return STATUS_UNSUCCESSFUL;
+   if (0 == ObjectCount)
+     return STATUS_INVALID_PARAMETER;
+
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForRead(ObjectsArray,
+                    ObjectCount * sizeof(ObjectsArray[0]),
+                    sizeof(ULONG));
+       /* make a copy so we don't have to guard with SEH later and keep track of
+          what objects we referenced in case dereferencing pointers suddenly fails */
+       RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount * sizeof(ObjectsArray[0]));
+       ObjectsArray = SafeObjectsArray;
+       
+       if(TimeOut != NULL)
+       {
+         ProbeForRead(TimeOut,
+                      sizeof(LARGE_INTEGER),
+                      sizeof(ULONG));
+         /* make a local copy of the timeout on the stack */
+         SafeTimeOut = *TimeOut;
+         TimeOut = &SafeTimeOut;
+       }
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
+   /* reference all objects */
+   for (i = 0; i < ObjectCount; i++)
+     {
+        Status = ObReferenceObjectByHandle(ObjectsArray[i],
+                                           SYNCHRONIZE,
+                                           NULL,
+                                           PreviousMode,
+                                           &ObjectPtrArray[i],
+                                           NULL);
+        if (!NT_SUCCESS(Status) || !KiIsObjectWaitable(ObjectPtrArray[i]))
+          {
+             if (NT_SUCCESS(Status))
+              {
+                DPRINT1("Waiting for object type '%wZ' is not supported\n", 
+                        &BODY_TO_HEADER(ObjectPtrArray[i])->ObjectType->TypeName);
+                Status = STATUS_HANDLE_NOT_WAITABLE;
+                i++;
+              }
+             /* dereference all referenced objects */
+             for (j = 0; j < i; j++)
+               {
+                  ObDereferenceObject(ObjectPtrArray[j]);
+               }
+
+             return(Status);
+          }
+     }
+
+   Status = KeWaitForMultipleObjects(ObjectCount,
+                                     ObjectPtrArray,
+                                     WaitType,
+                                     UserRequest,
+                                     PreviousMode,
+                                     Alertable,
+                                    TimeOut,
+                                     WaitBlockArray);
+
+   /* dereference all objects */
+   for (i = 0; i < ObjectCount; i++)
+     {
+        ObDereferenceObject(ObjectPtrArray[i]);
+     }
+
+   return(Status);
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+NtWaitForSingleObject(IN HANDLE ObjectHandle,
+                     IN BOOLEAN Alertable,
+                     IN PLARGE_INTEGER TimeOut  OPTIONAL)
+{
+   PVOID ObjectPtr;
+   KPROCESSOR_MODE PreviousMode;
+   LARGE_INTEGER SafeTimeOut;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n",
+         ObjectHandle,Alertable,TimeOut);
+
+   PreviousMode = ExGetPreviousMode();
+   
+   if(TimeOut != NULL && PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForRead(TimeOut,
+                    sizeof(LARGE_INTEGER),
+                    sizeof(ULONG));
+       /* make a copy on the stack */
+       SafeTimeOut = *TimeOut;
+       TimeOut = &SafeTimeOut;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
+   Status = ObReferenceObjectByHandle(ObjectHandle,
+                                     SYNCHRONIZE,
+                                     NULL,
+                                     PreviousMode,
+                                     &ObjectPtr,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   if (!KiIsObjectWaitable(ObjectPtr))
+     {
+       DPRINT1("Waiting for object type '%wZ' is not supported\n", 
+              &BODY_TO_HEADER(ObjectPtr)->ObjectType->TypeName);
+       Status = STATUS_HANDLE_NOT_WAITABLE;
+     }
+   else
+     {
+       Status = KeWaitForSingleObject(ObjectPtr,
+                                     UserRequest,
+                                     PreviousMode,
+                                     Alertable,
+                                     TimeOut);
+     }
+
+   ObDereferenceObject(ObjectPtr);
+
+   return(Status);
+}
+
+
+NTSTATUS STDCALL
+NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
+                              IN HANDLE WaitableObjectHandle,
+                              IN BOOLEAN Alertable,
+                              IN PLARGE_INTEGER TimeOut  OPTIONAL)
+{
+   KPROCESSOR_MODE PreviousMode;
+   DISPATCHER_HEADER* hdr;
+   PVOID SignalObj;
+   PVOID WaitObj;
+   LARGE_INTEGER SafeTimeOut;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   PreviousMode = ExGetPreviousMode();
+   
+   if(TimeOut != NULL && PreviousMode != KernelMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForRead(TimeOut,
+                    sizeof(LARGE_INTEGER),
+                    sizeof(ULONG));
+       /* make a copy on the stack */
+       SafeTimeOut = *TimeOut;
+       TimeOut = &SafeTimeOut;
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+     
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+   
+   Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
+                                     0,
+                                     NULL,
+                                     PreviousMode,
+                                     &SignalObj,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+
+   Status = ObReferenceObjectByHandle(WaitableObjectHandle,
+                                     SYNCHRONIZE,
+                                     NULL,
+                                     PreviousMode,
+                                     &WaitObj,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       ObDereferenceObject(SignalObj);
+       return Status;
+     }
+
+   hdr = (DISPATCHER_HEADER *)SignalObj;
+   switch (hdr->Type)
+     {
+      case EventNotificationObject:
+      case EventSynchronizationObject:
+       KeSetEvent(SignalObj,
+                  EVENT_INCREMENT,
+                  TRUE);
+       break;
+
+      case MutantObject:
+       KeReleaseMutex(SignalObj,
+                      TRUE);
+       break;
+
+      case SemaphoreObject:
+       KeReleaseSemaphore(SignalObj,
+                          SEMAPHORE_INCREMENT,
+                          1,
+                          TRUE);
+       break;
+
+      default:
+       ObDereferenceObject(SignalObj);
+       ObDereferenceObject(WaitObj);
+       return STATUS_OBJECT_TYPE_MISMATCH;
+     }
+
+   Status = KeWaitForSingleObject(WaitObj,
+                                 UserRequest,
+                                 PreviousMode,
+                                 Alertable,
+                                 TimeOut);
+
+   ObDereferenceObject(SignalObj);
+   ObDereferenceObject(WaitObj);
+
+   return Status;
+}
+
+/* EOF */
index b478b9c..2dc711b 100644 (file)
@@ -12,8 +12,8 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-
 PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
+BOOLEAN PopAcpiPresent = FALSE;
 
 /*
  * @implemented
@@ -133,10 +133,7 @@ PoUnregisterSystemState(
 NTSTATUS
 PopSetSystemPowerState(
   SYSTEM_POWER_STATE PowerState)
-{
-
-#ifdef ACPI
-
+{    
   IO_STATUS_BLOCK IoStatusBlock;
   PDEVICE_OBJECT DeviceObject;
   PIO_STACK_LOCATION IrpSp;
@@ -144,6 +141,8 @@ PopSetSystemPowerState(
   NTSTATUS Status;
   KEVENT Event;
   PIRP Irp;
+  
+  if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
 
   Status = IopGetSystemPowerDeviceObject(&DeviceObject);
   if (!NT_SUCCESS(Status)) {
@@ -190,15 +189,23 @@ PopSetSystemPowerState(
   ObDereferenceObject(Fdo);
 
   return Status;
-
-#endif /* ACPI */
-
-  return STATUS_NOT_IMPLEMENTED;
 }
 
-VOID INIT_FUNCTION
-PoInit(VOID)
+VOID 
+INIT_FUNCTION
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock, 
+       BOOLEAN ForceAcpiDisable)
 {
+  if (ForceAcpiDisable)
+    {
+      /* Set the ACPI State to False if it's been forced that way */
+      PopAcpiPresent = FALSE;
+    }
+  else
+    {
+      /* Otherwise check the LoaderBlock's Flag */
+      PopAcpiPresent = (LoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
+    }
 }
 
 /*
@@ -268,4 +275,19 @@ NtPowerInformation(
    return Status;
 }
 
+
+NTSTATUS
+STDCALL
+PoQueueShutdownWorkItem(
+       IN PWORK_QUEUE_ITEM WorkItem
+       )
+{
+  PAGED_CODE();
+  
+  DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+
 /* EOF */
index e388425..eece7f4 100644 (file)
 
 /* GLOBALS ******************************************************************/
 
-/*
- * FIXME - use a global handle table instead!
- */
-
-KSPIN_LOCK CidLock;
-LIST_ENTRY CidHead;
-KEVENT CidReleaseEvent;
-LONG CidCounter = 0;
-LARGE_INTEGER ShortDelay, LongDelay;
+PHANDLE_TABLE PspCidTable = NULL;
 
 #define TAG_CIDOBJECT TAG('C', 'I', 'D', 'O')
 
+#define CID_FLAG_PROCESS 0x1
+#define CID_FLAG_THREAD 0x2
+#define CID_FLAGS_MASK (CID_FLAG_PROCESS | CID_FLAG_THREAD)
+
 /* FUNCTIONS *****************************************************************/
 
 VOID INIT_FUNCTION
 PsInitClientIDManagment(VOID)
 {
-   InitializeListHead(&CidHead);
-   KeInitializeSpinLock(&CidLock);
-   KeInitializeEvent(&CidReleaseEvent, SynchronizationEvent, FALSE);
-   ShortDelay.QuadPart = -100LL;
-   LongDelay.QuadPart = -100000LL;
-}
-
-VOID
-PspReferenceCidObject(PCID_OBJECT Object)
-{
-  InterlockedIncrement(&Object->ref);
-}
-
-VOID
-PspDereferenceCidObject(PCID_OBJECT Object)
-{
-  if(InterlockedDecrement(&Object->ref) == 0)
-  {
-    ExFreePool(Object);
-  }
+  PspCidTable = ExCreateHandleTable(NULL);
+  ASSERT(PspCidTable);
 }
 
 NTSTATUS
 PsCreateCidHandle(PVOID Object, POBJECT_TYPE ObjectType, PHANDLE Handle)
 {
-  KIRQL oldIrql;
-  PCID_OBJECT cido = ExAllocatePoolWithTag(NonPagedPool,
-                                           sizeof(CID_OBJECT),
-                                           TAG_CIDOBJECT);
-  if(cido != NULL)
+  HANDLE_TABLE_ENTRY NewEntry;
+  LONG ExHandle;
+  
+  PAGED_CODE();
+  
+  NewEntry.u1.Object = Object;
+  if(ObjectType == PsThreadType)
+    NewEntry.u2.GrantedAccess = CID_FLAG_THREAD;
+  else if(ObjectType == PsProcessType)
+    NewEntry.u2.GrantedAccess = CID_FLAG_PROCESS;
+  else
   {
-    cido->ref = 1;
-    ExInitializeFastMutex(&cido->Lock);
-    cido->Obj.Object = Object;
-
-    KeAcquireSpinLock(&CidLock, &oldIrql);
-    cido->Handle = (HANDLE)((ULONG_PTR)(++CidCounter) << 2);
-    InsertTailList(&CidHead, &cido->Entry);
-    KeReleaseSpinLock(&CidLock, oldIrql);
-
-    *Handle = cido->Handle;
+    DPRINT1("Can't create CID handles for %wZ objects\n", &ObjectType->TypeName);
+    KEBUGCHECK(0);
+  }
+  
+  ExHandle = ExCreateHandle(PspCidTable,
+                            &NewEntry);
+  if(ExHandle != EX_INVALID_HANDLE)
+  {
+    *Handle = EX_HANDLE_TO_HANDLE(ExHandle);
     return STATUS_SUCCESS;
   }
   
-  return STATUS_INSUFFICIENT_RESOURCES;
+  return STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
 PsDeleteCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType)
 {
-  PCID_OBJECT cido, Found = NULL;
-  PLIST_ENTRY Current;
-  KIRQL oldIrql;
-  
-  if(CidHandle == NULL)
-  {
-    return STATUS_INVALID_PARAMETER;
-  }
+  PHANDLE_TABLE_ENTRY Entry;
+  LONG ExHandle = HANDLE_TO_EX_HANDLE(CidHandle);
   
-  KeAcquireSpinLock(&CidLock, &oldIrql);
-  Current = CidHead.Flink;
-  while(Current != &CidHead)
+  PAGED_CODE();
+
+  Entry = ExMapHandleToPointer(PspCidTable,
+                               ExHandle);
+  if(Entry != NULL)
   {
-    cido = CONTAINING_RECORD(Current, CID_OBJECT, Entry);
-    if(cido->Handle == CidHandle)
+    if((ObjectType == PsThreadType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_THREAD)) ||
+       (ObjectType == PsProcessType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_PROCESS)))
     {
-      RemoveEntryList(&cido->Entry);
-      cido->Handle = NULL;
-      Found = cido;
-      break;
+      ExDestroyHandleByEntry(PspCidTable,
+                             Entry,
+                             ExHandle);
+      return STATUS_SUCCESS;
+    }
+    else
+    {
+      ExUnlockHandleTableEntry(PspCidTable,
+                               Entry);
+      return STATUS_OBJECT_TYPE_MISMATCH;
     }
-    Current = Current->Flink;
-  }
-  KeReleaseSpinLock(&CidLock, oldIrql);
-
-  if(Found != NULL)
-  {
-    PspDereferenceCidObject(Found);
-    return STATUS_SUCCESS;
   }
 
-  return STATUS_UNSUCCESSFUL;
+  return STATUS_INVALID_HANDLE;
 }
 
-PCID_OBJECT
-PsLockCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType)
+PHANDLE_TABLE_ENTRY
+PsLookupCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType, PVOID *Object)
 {
-  PCID_OBJECT cido, Found = NULL;
-  PLIST_ENTRY Current;
-  KIRQL oldIrql;
+  PHANDLE_TABLE_ENTRY Entry;
   
-  if(CidHandle == NULL)
+  PAGED_CODE();
+
+  KeEnterCriticalRegion();
+  
+  Entry = ExMapHandleToPointer(PspCidTable,
+                               HANDLE_TO_EX_HANDLE(CidHandle));
+  if(Entry != NULL)
   {
-    return NULL;
+    if((ObjectType == PsProcessType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_PROCESS)) ||
+       (ObjectType == PsThreadType && ((Entry->u2.GrantedAccess & CID_FLAGS_MASK) == CID_FLAG_THREAD)))
+    {
+      *Object = Entry->u1.Object;
+      return Entry;
+    }
+    else
+    {
+      DPRINT1("CID Obj type mismatch handle 0x%x %wZ vs 0x%x\n", CidHandle,
+              &ObjectType->TypeName, Entry->u2.GrantedAccess);
+      ExUnlockHandleTableEntry(PspCidTable,
+                               Entry);
+    }
   }
   
-  KeAcquireSpinLock(&CidLock, &oldIrql);
-  Current = CidHead.Flink;
-  while(Current != &CidHead)
+  KeLeaveCriticalRegion();
+  
+  return NULL;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
+                          OUT PEPROCESS *Process OPTIONAL,
+                          OUT PETHREAD *Thread)
+{
+  PHANDLE_TABLE_ENTRY CidEntry;
+  PETHREAD FoundThread;
+
+  PAGED_CODE();
+
+  ASSERT(Thread);
+  ASSERT(Cid);
+
+  CidEntry = PsLookupCidHandle(Cid->UniqueThread, PsThreadType, (PVOID*)&FoundThread);
+  if(CidEntry != NULL)
   {
-    cido = CONTAINING_RECORD(Current, CID_OBJECT, Entry);
-    if(cido->Handle == CidHandle)
+    ObReferenceObject(FoundThread);
+
+    PsUnlockCidHandle(CidEntry);
+
+    if(Process != NULL)
     {
-      Found = cido;
-      PspReferenceCidObject(Found);
-      break;
+      *Process = FoundThread->ThreadsProcess;
     }
-    Current = Current->Flink;
+    *Thread = FoundThread;
+    return STATUS_SUCCESS;
   }
-  KeReleaseSpinLock(&CidLock, oldIrql);
-  
-  if(Found != NULL)
+
+  return STATUS_INVALID_PARAMETER;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+PsLookupThreadByThreadId(IN HANDLE ThreadId,
+                        OUT PETHREAD *Thread)
+{
+  PHANDLE_TABLE_ENTRY CidEntry;
+  PETHREAD FoundThread;
+
+  PAGED_CODE();
+
+  ASSERT(Thread);
+
+  CidEntry = PsLookupCidHandle(ThreadId, PsThreadType, (PVOID*)&FoundThread);
+  if(CidEntry != NULL)
   {
-    ExAcquireFastMutex(&Found->Lock);
+    ObReferenceObject(FoundThread);
+
+    PsUnlockCidHandle(CidEntry);
+
+    *Thread = FoundThread;
+    return STATUS_SUCCESS;
   }
 
-  return Found;
+  return STATUS_INVALID_PARAMETER;
 }
 
 VOID
-PsUnlockCidObject(PCID_OBJECT CidObject)
+PsUnlockCidHandle(PHANDLE_TABLE_ENTRY CidEntry)
 {
-  ExReleaseFastMutex(&CidObject->Lock);
-  PspDereferenceCidObject(CidObject);
+  PAGED_CODE();
+
+  ExUnlockHandleTableEntry(PspCidTable,
+                           CidEntry);
+  KeLeaveCriticalRegion();
 }
 
 /* EOF */
index 8c85ab4..957f6a4 100644 (file)
@@ -4,7 +4,7 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ps/create.c
  * PURPOSE:         Thread managment
- * 
+ *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  *                  Phillip Susi
  *                  Skywing
 
 /*
  * NOTE:
- * 
+ *
  * All of the routines that manipulate the thread queue synchronize on
  * a single spinlock
- * 
+ *
  */
 
 /* INCLUDES ****************************************************************/
 /* GLOBAL *******************************************************************/
 
 #define MAX_THREAD_NOTIFY_ROUTINE_COUNT    8
+#define TAG_KAPC TAG('k','p','a','p') /* kpap - kernel ps apc */
 
 static ULONG PiThreadNotifyRoutineCount = 0;
 static PCREATE_THREAD_NOTIFY_ROUTINE
 PiThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
 
+ULONG
+STDCALL
+KeSuspendThread(PKTHREAD Thread);
 /* FUNCTIONS ***************************************************************/
 
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-PsAssignImpersonationToken(PETHREAD Thread,
-                          HANDLE TokenHandle)
+VOID
+PiBeforeBeginThread(CONTEXT c)
 {
-   PACCESS_TOKEN Token;
-   SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
-   NTSTATUS Status;
-
-   if (TokenHandle != NULL)
-     {
-       Status = ObReferenceObjectByHandle(TokenHandle,
-                                          TOKEN_IMPERSONATE,
-                                          SepTokenObjectType,
-                                          KeGetPreviousMode(),
-                                          (PVOID*)&Token,
-                                          NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            return(Status);
-         }
-       ImpersonationLevel = SeTokenImpersonationLevel(Token);
-     }
-   else
-     {
-       Token = NULL;
-       ImpersonationLevel = 0;
-     }
-
-   PsImpersonateClient(Thread,
-                      Token,
-                      FALSE,
-                      FALSE,
-                      ImpersonationLevel);
-   if (Token != NULL)
-     {
-       ObDereferenceObject(Token);
-     }
-
-   return(STATUS_SUCCESS);
+    KeLowerIrql(PASSIVE_LEVEL);
 }
 
-
-/*
- * @implemented
- */
-VOID STDCALL
-PsRevertToSelf (VOID)
+NTSTATUS
+PsInitializeThread (
+    PEPROCESS Process,
+    PETHREAD* ThreadPtr,
+    POBJECT_ATTRIBUTES ObjectAttributes,
+    KPROCESSOR_MODE AccessMode,
+    BOOLEAN First )
 {
-    PsRevertThreadToSelf(PsGetCurrentThread());
-}
+    PETHREAD Thread;
+    NTSTATUS Status;
+    KIRQL oldIrql;
 
-/*
- * @implemented
- */
-VOID
-STDCALL
-PsRevertThreadToSelf(
-       IN PETHREAD Thread
-       )
-{
-  if (Thread->ActiveImpersonationInfo == TRUE)
-    {
-      ObDereferenceObject (Thread->ImpersonationInfo->Token);
-      Thread->ActiveImpersonationInfo = FALSE;
-    }
-}
+    PAGED_CODE();
 
-/*
- * @implemented
- */
-VOID STDCALL
-PsImpersonateClient (IN PETHREAD Thread,
-                    IN PACCESS_TOKEN Token,
-                    IN BOOLEAN CopyOnOpen,
-                    IN BOOLEAN EffectiveOnly,
-                    IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
-{
-  if (Token == NULL)
+    if (Process == NULL)
     {
-      if (Thread->ActiveImpersonationInfo == TRUE)
-       {
-         Thread->ActiveImpersonationInfo = FALSE;
-         if (Thread->ImpersonationInfo->Token != NULL)
-           {
-             ObDereferenceObject (Thread->ImpersonationInfo->Token);
-           }
-       }
-      return;
+        Process = PsInitialSystemProcess;
     }
 
-  if (Thread->ImpersonationInfo == NULL)
+    /*
+    * Create and initialize thread
+    */
+    Status = ObCreateObject(AccessMode,
+        PsThreadType,
+        ObjectAttributes,
+        KernelMode,
+        NULL,
+        sizeof(ETHREAD),
+        0,
+        0,
+        (PVOID*)&Thread);
+    if (!NT_SUCCESS(Status))
     {
-      Thread->ImpersonationInfo = ExAllocatePool (NonPagedPool,
-                                                 sizeof(PS_IMPERSONATION_INFORMATION));
+        return(Status);
     }
 
-  Thread->ImpersonationInfo->ImpersonationLevel = ImpersonationLevel;
-  Thread->ImpersonationInfo->CopyOnOpen = CopyOnOpen;
-  Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
-  Thread->ImpersonationInfo->Token = Token;
-  ObReferenceObjectByPointer (Token,
-                             0,
-                             SepTokenObjectType,
-                             KernelMode);
-  Thread->ActiveImpersonationInfo = TRUE;
-}
-
-
-PACCESS_TOKEN
-PsReferenceEffectiveToken(PETHREAD Thread,
-                         PTOKEN_TYPE TokenType,
-                         PBOOLEAN EffectiveOnly,
-                         PSECURITY_IMPERSONATION_LEVEL Level)
-{
-   PEPROCESS Process;
-   PACCESS_TOKEN Token;
-   
-   if (Thread->ActiveImpersonationInfo == FALSE)
-     {
-       Process = Thread->ThreadsProcess;
-       *TokenType = TokenPrimary;
-       *EffectiveOnly = FALSE;
-       Token = Process->Token;
-     }
-   else
-     {
-       Token = Thread->ImpersonationInfo->Token;
-       *TokenType = TokenImpersonation;
-       *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
-       *Level = Thread->ImpersonationInfo->ImpersonationLevel;
-     }
-   return(Token);
-}
-
-
-NTSTATUS STDCALL
-NtImpersonateThread(IN HANDLE ThreadHandle,
-                   IN HANDLE ThreadToImpersonateHandle,
-                   IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
-{
-  SECURITY_QUALITY_OF_SERVICE SafeServiceQoS;
-  SECURITY_CLIENT_CONTEXT ClientContext;
-  PETHREAD Thread;
-  PETHREAD ThreadToImpersonate;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForRead(SecurityQualityOfService,
-                   sizeof(SECURITY_QUALITY_OF_SERVICE),
-                   sizeof(ULONG));
-      SafeServiceQoS = *SecurityQualityOfService;
-      SecurityQualityOfService = &SafeServiceQoS;
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-    
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  Status = ObReferenceObjectByHandle(ThreadHandle,
-                                    THREAD_IMPERSONATE,
-                                    PsThreadType,
-                                    PreviousMode,
-                                    (PVOID*)&Thread,
-                                    NULL);
-  if(NT_SUCCESS(Status))
-  {
-    Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
-                                      THREAD_DIRECT_IMPERSONATION,
-                                      PsThreadType,
-                                      PreviousMode,
-                                      (PVOID*)&ThreadToImpersonate,
-                                      NULL);
-    if(NT_SUCCESS(Status))
-    {
-      Status = SeCreateClientSecurity(ThreadToImpersonate,
-                                     SecurityQualityOfService,
-                                     0,
-                                    &ClientContext);
-      if(NT_SUCCESS(Status))
-      {
-        SeImpersonateClient(&ClientContext,
-                           Thread);
-        if(ClientContext.ClientToken != NULL)
-        {
-          ObDereferenceObject (ClientContext.ClientToken);
-        }
-      }
-
-      ObDereferenceObject(ThreadToImpersonate);
-    }
-    ObDereferenceObject(Thread);
-  }
+    /*
+    * Reference process
+    */
+    ObReferenceObjectByPointer(Process,
+        PROCESS_CREATE_THREAD,
+        PsProcessType,
+        KernelMode);
 
-  return Status;
-}
+    Thread->ThreadsProcess = Process;
+    Thread->Cid.UniqueThread = NULL;
+    Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId;
 
-/*
- * @implemented
- */
-PACCESS_TOKEN STDCALL
-PsReferenceImpersonationToken(IN PETHREAD Thread,
-                             OUT PBOOLEAN CopyOnOpen,
-                             OUT PBOOLEAN EffectiveOnly,
-                             OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
-{
-  if (Thread->ActiveImpersonationInfo == FALSE)
-    {
-      return NULL;
-    }
+    DPRINT("Thread = %x\n",Thread);
 
-  *ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
-  *CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
-  *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
-  ObReferenceObjectByPointer (Thread->ImpersonationInfo->Token,
-                             TOKEN_ALL_ACCESS,
-                             SepTokenObjectType,
-                             KernelMode);
+    KeInitializeThread(&Process->Pcb, &Thread->Tcb, First);
+    InitializeListHead(&Thread->ActiveTimerListHead);
+    KeInitializeSpinLock(&Thread->ActiveTimerListLock);
+    InitializeListHead(&Thread->IrpList);
+    Thread->DeadThread = FALSE;
+    Thread->HasTerminated = FALSE;
+    Thread->Tcb.Win32Thread = NULL;
+    DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread);
 
-  return Thread->ImpersonationInfo->Token;
-}
 
-#ifdef PsDereferencePrimaryToken
-#undef PsDereferenceImpersonationToken
-#endif
-/*
- * @implemented
- */
-VOID
-STDCALL
-PsDereferenceImpersonationToken(
-    IN PACCESS_TOKEN ImpersonationToken
-    )
-{
-    if (ImpersonationToken) {
-        ObDereferenceObject(ImpersonationToken);
-    }
-}
+    Thread->Tcb.BasePriority = (CHAR)Process->Pcb.BasePriority;
+    Thread->Tcb.Priority = Thread->Tcb.BasePriority;
 
-#ifdef PsDereferencePrimaryToken
-#undef PsDereferencePrimaryToken
-#endif
-/*
- * @implemented
- */
-VOID
-STDCALL
-PsDereferencePrimaryToken(
-    IN PACCESS_TOKEN PrimaryToken
-    )
-{
-    ObDereferenceObject(PrimaryToken);
-}
+    /*
+    * Local Procedure Call facility (LPC)
+    */
+    KeInitializeSemaphore  (& Thread->LpcReplySemaphore, 0, LONG_MAX);
+    Thread->LpcReplyMessage = NULL;
+    Thread->LpcReplyMessageId = 0; /* not valid */
+    /* Thread->LpcReceiveMessageId = 0; */
+    Thread->LpcExitThreadCalled = FALSE;
+    Thread->LpcReceivedMsgIdValid = FALSE;
 
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-PsDisableImpersonation(
-    IN PETHREAD Thread,
-    IN PSE_IMPERSONATION_STATE ImpersonationState
-    )
-{
-   if (Thread->ActiveImpersonationInfo == FALSE)
-   {
-      ImpersonationState->Token = NULL;
-      ImpersonationState->CopyOnOpen = FALSE;
-      ImpersonationState->EffectiveOnly = FALSE;
-      ImpersonationState->Level = 0;
-      return TRUE;
-   }
-
-/* FIXME */
-/*   ExfAcquirePushLockExclusive(&Thread->ThreadLock); */
-
-   Thread->ActiveImpersonationInfo = FALSE;
-   ImpersonationState->Token = Thread->ImpersonationInfo->Token;
-   ImpersonationState->CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
-   ImpersonationState->EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
-   ImpersonationState->Level = Thread->ImpersonationInfo->ImpersonationLevel;
-
-/* FIXME */
-/*   ExfReleasePushLock(&Thread->ThreadLock); */
-
-   return TRUE;
-}
+    oldIrql = KeAcquireDispatcherDatabaseLock();
+    InsertTailList(&Process->ThreadListHead,
+        &Thread->ThreadListEntry);
+    KeReleaseDispatcherDatabaseLock(oldIrql);
 
-/*
- * @implemented
- */                       
-VOID
-STDCALL
-PsRestoreImpersonation(
-       IN PETHREAD      Thread,
-       IN PSE_IMPERSONATION_STATE      ImpersonationState
-       )
-{
-   PsImpersonateClient(Thread, ImpersonationState->Token,
-                       ImpersonationState->CopyOnOpen,
-                       ImpersonationState->EffectiveOnly,
-                       ImpersonationState->Level);
-   ObfDereferenceObject(ImpersonationState->Token);
-}
+    *ThreadPtr = Thread;
 
-VOID
-PiBeforeBeginThread(CONTEXT c)
-{
-   KeLowerIrql(PASSIVE_LEVEL);
+    return STATUS_SUCCESS;
 }
 
 
-VOID STDCALL
-PiDeleteThread(PVOID ObjectBody)
+static NTSTATUS
+PsCreateTeb (
+    HANDLE ProcessHandle,
+    PTEB *TebPtr,
+    PETHREAD Thread,
+    PINITIAL_TEB InitialTeb )
 {
-  PETHREAD Thread;
-  PEPROCESS Process;
-
-  Thread = (PETHREAD)ObjectBody;
-
-  DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
-
-  Process = Thread->ThreadsProcess;
-  Thread->ThreadsProcess = NULL;
+    PEPROCESS Process;
+    NTSTATUS Status;
+    ULONG ByteCount;
+    ULONG RegionSize;
+    ULONG TebSize;
+    PVOID TebBase;
+    TEB Teb;
 
-  PsDeleteCidHandle(Thread->Cid.UniqueThread, PsThreadType);
-  
-  if(Thread->Tcb.Win32Thread != NULL)
-  {
-    /* Free the W32THREAD structure if present */
-    ExFreePool (Thread->Tcb.Win32Thread);
-  }
-
-  KeReleaseThread(ETHREAD_TO_KTHREAD(Thread));
-  
-  ObDereferenceObject(Process);
-  
-  DPRINT("PiDeleteThread() finished\n");
-}
+    PAGED_CODE();
 
+    TebSize = PAGE_SIZE;
 
-NTSTATUS
-PsInitializeThread(PEPROCESS Process,
-                  PETHREAD* ThreadPtr,
-                  PHANDLE ThreadHandle,
-                  ACCESS_MASK  DesiredAccess,
-                  POBJECT_ATTRIBUTES ThreadAttributes,
-                  BOOLEAN First)
-{
-   PETHREAD Thread;
-   NTSTATUS Status;
-   KIRQL oldIrql;
-
-   if (Process == NULL)
-     {
-       Process = PsInitialSystemProcess;
-     }
+    if (NULL == Thread->ThreadsProcess)
+    {
+    /* We'll be allocating a 64k block here and only use 4k of it, but this
+    path should almost never be taken. Actually, I never saw it was taken,
+    so maybe we should just ASSERT(NULL != Thread->ThreadsProcess) and
+        move on */
+        TebBase = NULL;
+        Status = ZwAllocateVirtualMemory(ProcessHandle,
+            &TebBase,
+            0,
+            &TebSize,
+            MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
+            PAGE_READWRITE);
+        if (! NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to allocate virtual memory for TEB\n");
+            return Status;
+        }
+    }
+    else
+    {
+        Process = Thread->ThreadsProcess;
+        PsLockProcess(Process, FALSE);
+        if (NULL == Process->TebBlock ||
+            Process->TebBlock == Process->TebLastAllocated)
+        {
+            Process->TebBlock = NULL;
+            RegionSize = MM_VIRTMEM_GRANULARITY;
+            Status = ZwAllocateVirtualMemory(ProcessHandle,
+                &Process->TebBlock,
+                0,
+                &RegionSize,
+                MEM_RESERVE | MEM_TOP_DOWN,
+                PAGE_READWRITE);
+            if (! NT_SUCCESS(Status))
+            {
+                PsUnlockProcess(Process);
+                DPRINT1("Failed to reserve virtual memory for TEB\n");
+                return Status;
+            }
+            Process->TebLastAllocated = (PVOID) ((char *) Process->TebBlock + RegionSize);
+        }
+        TebBase = (PVOID) ((char *) Process->TebLastAllocated - PAGE_SIZE);
+        Status = ZwAllocateVirtualMemory(ProcessHandle,
+            &TebBase,
+            0,
+            &TebSize,
+            MEM_COMMIT,
+            PAGE_READWRITE);
+        if (! NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to commit virtual memory for TEB\n");
+            return Status;
+        }
+        Process->TebLastAllocated = TebBase;
+        PsUnlockProcess(Process);
+    }
 
-   /*
-    * Reference process
-    */
-   ObReferenceObjectByPointer(Process,
-                              PROCESS_CREATE_THREAD,
-                              PsProcessType,
-                              KernelMode);
-   
-   /*
-    * Create and initialize thread
-    */
-   Status = ObCreateObject(UserMode,
-                          PsThreadType,
-                          ThreadAttributes,
-                          KernelMode,
-                          NULL,
-                          sizeof(ETHREAD),
-                          0,
-                          0,
-                          (PVOID*)&Thread);
-   if (!NT_SUCCESS(Status))
-     {
-        ObDereferenceObject (Process);
-        return(Status);
-     }
+    DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
+    ASSERT(NULL != TebBase && PAGE_SIZE <= TebSize);
 
-  /* create a client id handle */
-  Status = PsCreateCidHandle(Thread, PsThreadType, &Thread->Cid.UniqueThread);
-  if (!NT_SUCCESS(Status))
+    RtlZeroMemory(&Teb, sizeof(TEB));
+    /* set all pointers to and from the TEB */
+    Teb.Tib.Self = TebBase;
+    if (Thread->ThreadsProcess)
     {
-      ObDereferenceObject (Thread);
-      ObDereferenceObject (Process);
-      return Status;
+        Teb.Peb = Thread->ThreadsProcess->Peb; /* No PEB yet!! */
     }
-  Thread->ThreadsProcess = Process;
-  Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId;
+    DPRINT("Teb.Peb %x\n", Teb.Peb);
 
-   DPRINT("Thread = %x\n",Thread);
+    /* store stack information from InitialTeb */
+    if(InitialTeb != NULL)
+    {
+        /* fixed-size stack */
+        if(InitialTeb->StackBase && InitialTeb->StackLimit)
+        {
+            Teb.Tib.StackBase = InitialTeb->StackBase;
+            Teb.Tib.StackLimit = InitialTeb->StackLimit;
+            Teb.DeallocationStack = InitialTeb->StackLimit;
+        }
+        /* expandable stack */
+        else
+        {
+            Teb.Tib.StackBase = InitialTeb->StackCommit;
+            Teb.Tib.StackLimit = InitialTeb->StackCommitMax;
+            Teb.DeallocationStack = InitialTeb->StackReserved;
+        }
+    }
 
-   KeInitializeThread(&Process->Pcb, &Thread->Tcb, First);
-   InitializeListHead(&Thread->TerminationPortList);
-   KeInitializeSpinLock(&Thread->ActiveTimerListLock);
-   InitializeListHead(&Thread->IrpList);
-   Thread->DeadThread = FALSE;
-   Thread->HasTerminated = FALSE;
-   Thread->Tcb.Win32Thread = NULL;
-   DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread);
-   
+    /* more initialization */
+    Teb.Cid.UniqueThread = Thread->Cid.UniqueThread;
+    Teb.Cid.UniqueProcess = Thread->Cid.UniqueProcess;
+    Teb.CurrentLocale = PsDefaultThreadLocaleId;
 
-   Thread->Tcb.BasePriority = (CHAR)Process->Pcb.BasePriority;
-   Thread->Tcb.Priority = Thread->Tcb.BasePriority;
+    /* Terminate the exception handler list */
+    Teb.Tib.ExceptionList = (PVOID)-1;
 
-   /*
-    * Local Procedure Call facility (LPC)
-    */
-   KeInitializeSemaphore  (& Thread->LpcReplySemaphore, 0, LONG_MAX);
-   Thread->LpcReplyMessage = NULL;
-   Thread->LpcReplyMessageId = 0; /* not valid */
-   /* Thread->LpcReceiveMessageId = 0; */
-   Thread->LpcExitThreadCalled = FALSE;
-   Thread->LpcReceivedMsgIdValid = FALSE;
-
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-   InsertTailList(&Process->ThreadListHead,
-                 &Thread->ThreadListEntry);
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-
-   *ThreadPtr = Thread;
-   
-   Status = ObInsertObject((PVOID)Thread,
-                          NULL,
-                          DesiredAccess,
-                          0,
-                          NULL,
-                          ThreadHandle);
-   return(Status);
-}
+    DPRINT("sizeof(TEB) %x\n", sizeof(TEB));
 
+    /* write TEB data into teb page */
+    Status = NtWriteVirtualMemory(ProcessHandle,
+        TebBase,
+        &Teb,
+        sizeof(TEB),
+        &ByteCount);
 
-static NTSTATUS
-PsCreateTeb(HANDLE ProcessHandle,
-           PTEB *TebPtr,
-           PETHREAD Thread,
-           PINITIAL_TEB InitialTeb)
-{
-   PEPROCESS Process;
-   NTSTATUS Status;
-   ULONG ByteCount;
-   ULONG RegionSize;
-   ULONG TebSize;
-   PVOID TebBase;
-   TEB Teb;
-   
-   PAGED_CODE();
-
-   TebSize = PAGE_SIZE;
-
-   if (NULL == Thread->ThreadsProcess)
-     {
-       /* We'll be allocating a 64k block here and only use 4k of it, but this
-          path should almost never be taken. Actually, I never saw it was taken,
-          so maybe we should just ASSERT(NULL != Thread->ThreadsProcess) and
-          move on */
-       TebBase = NULL;
-       Status = ZwAllocateVirtualMemory(ProcessHandle,
-                                        &TebBase,
-                                        0,
-                                        &TebSize,
-                                        MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
-                                        PAGE_READWRITE);
-       if (! NT_SUCCESS(Status))
-         {
-           DPRINT1("Failed to allocate virtual memory for TEB\n");
-           return Status;
-         }
-     }
-   else
-     {
-       Process = Thread->ThreadsProcess;
-       ExAcquireFastMutex(&Process->TebLock);
-       if (NULL == Process->TebBlock ||
-           Process->TebBlock == Process->TebLastAllocated)
-         {
-           Process->TebBlock = NULL;
-           RegionSize = MM_VIRTMEM_GRANULARITY;
-           Status = ZwAllocateVirtualMemory(ProcessHandle,
-                                            &Process->TebBlock,
-                                            0,
-                                            &RegionSize,
-                                            MEM_RESERVE | MEM_TOP_DOWN,
-                                            PAGE_READWRITE);
-           if (! NT_SUCCESS(Status))
-             {
-               ExReleaseFastMutex(&Process->TebLock);
-               DPRINT1("Failed to reserve virtual memory for TEB\n");
-               return Status;
-             }
-           Process->TebLastAllocated = (PVOID) ((char *) Process->TebBlock + RegionSize);
-         }
-       TebBase = (PVOID) ((char *) Process->TebLastAllocated - PAGE_SIZE);
-       Status = ZwAllocateVirtualMemory(ProcessHandle,
-                                        &TebBase,
-                                        0,
-                                        &TebSize,
-                                        MEM_COMMIT,
-                                        PAGE_READWRITE);
-       if (! NT_SUCCESS(Status))
-         {
-           DPRINT1("Failed to commit virtual memory for TEB\n");
-           return Status;
-         }
-       Process->TebLastAllocated = TebBase;
-       ExReleaseFastMutex(&Process->TebLock);
-     }
-
-   DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize);
-   ASSERT(NULL != TebBase && PAGE_SIZE <= TebSize);
-
-   RtlZeroMemory(&Teb, sizeof(TEB));
-   /* set all pointers to and from the TEB */
-   Teb.Tib.Self = TebBase;
-   if (Thread->ThreadsProcess)
-     {
-        Teb.Peb = Thread->ThreadsProcess->Peb; /* No PEB yet!! */
-     }
-   DPRINT("Teb.Peb %x\n", Teb.Peb);
-   
-   /* store stack information from InitialTeb */
-   if(InitialTeb != NULL)
-   {
-    /* fixed-size stack */
-    if(InitialTeb->StackBase && InitialTeb->StackLimit)
-    {
-     Teb.Tib.StackBase = InitialTeb->StackBase;
-     Teb.Tib.StackLimit = InitialTeb->StackLimit;
-     Teb.DeallocationStack = InitialTeb->StackLimit;
-    }
-    /* expandable stack */
-    else
+    if (!NT_SUCCESS(Status))
     {
-     Teb.Tib.StackBase = InitialTeb->StackCommit;
-     Teb.Tib.StackLimit = InitialTeb->StackCommitMax;
-     Teb.DeallocationStack = InitialTeb->StackReserved;
-    }
-   }
-
-   /* more initialization */
-   Teb.Cid.UniqueThread = Thread->Cid.UniqueThread;
-   Teb.Cid.UniqueProcess = Thread->Cid.UniqueProcess;
-   Teb.CurrentLocale = PsDefaultThreadLocaleId;
-
-   /* Terminate the exception handler list */
-   Teb.Tib.ExceptionList = (PVOID)-1;
-   
-   DPRINT("sizeof(TEB) %x\n", sizeof(TEB));
-   
-   /* write TEB data into teb page */
-   Status = NtWriteVirtualMemory(ProcessHandle,
-                                 TebBase,
-                                 &Teb,
-                                 sizeof(TEB),
-                                 &ByteCount);
-
-   if (!NT_SUCCESS(Status))
-     {
         /* free TEB */
         DPRINT1 ("Writing TEB failed!\n");
 
         RegionSize = 0;
         NtFreeVirtualMemory(ProcessHandle,
-                            TebBase,
-                            &RegionSize,
-                            MEM_RELEASE);
+            TebBase,
+            &RegionSize,
+            MEM_RELEASE);
 
         return Status;
-     }
+    }
 
-   if (TebPtr != NULL)
-     {
+    if (TebPtr != NULL)
+    {
         *TebPtr = (PTEB)TebBase;
-     }
+    }
 
-   DPRINT("TEB allocated at %p\n", TebBase);
+    DPRINT("TEB allocated at %p\n", TebBase);
 
-   return Status;
+    return Status;
 }
 
 
 VOID STDCALL
-LdrInitApcRundownRoutine(PKAPC Apc)
+LdrInitApcRundownRoutine ( PKAPC Apc )
 {
-   ExFreePool(Apc);
+    ExFreePool(Apc);
 }
 
 
 VOID STDCALL
-LdrInitApcKernelRoutine(PKAPC Apc,
-                       PKNORMAL_ROUTINE* NormalRoutine,
-                       PVOID* NormalContext,
-                       PVOID* SystemArgument1,
-                       PVOID* SystemArgument2)
+LdrInitApcKernelRoutine (
+    PKAPC Apc,
+    PKNORMAL_ROUTINE* NormalRoutine,
+    PVOID* NormalContext,
+    PVOID* SystemArgument1,
+    PVOID* SystemArgument2)
 {
-  ExFreePool(Apc);
+    ExFreePool(Apc);
 }
 
 
 NTSTATUS STDCALL
-NtCreateThread(OUT PHANDLE ThreadHandle,
-              IN ACCESS_MASK DesiredAccess,
-              IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-              IN HANDLE ProcessHandle,
-              OUT PCLIENT_ID ClientId,
-              IN PCONTEXT ThreadContext,
-              IN PINITIAL_TEB InitialTeb,
-              IN BOOLEAN CreateSuspended)
+NtCreateThread (
+    OUT PHANDLE ThreadHandle,
+    IN ACCESS_MASK DesiredAccess,
+    IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+    IN HANDLE ProcessHandle,
+    OUT PCLIENT_ID ClientId,
+    IN PCONTEXT ThreadContext,
+    IN PINITIAL_TEB InitialTeb,
+    IN BOOLEAN CreateSuspended )
 {
-  HANDLE hThread;
-  CONTEXT SafeContext;
-  INITIAL_TEB SafeInitialTeb;
-  PEPROCESS Process;
-  PETHREAD Thread;
-  PTEB TebBase;
-  PKAPC LdrInitApc;
-  KIRQL oldIrql;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-  
-  if(ThreadContext == NULL)
-  {
-    return STATUS_INVALID_PARAMETER;
-  }
-  
-  PreviousMode = ExGetPreviousMode();
-
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
+    HANDLE hThread;
+    CONTEXT SafeContext;
+    INITIAL_TEB SafeInitialTeb;
+    PEPROCESS Process;
+    PETHREAD Thread;
+    PTEB TebBase;
+    PKAPC LdrInitApc;
+    KIRQL oldIrql;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    if(ThreadContext == NULL)
     {
-      ProbeForWrite(ThreadHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-      if(ClientId != NULL)
-      {
-        ProbeForWrite(ClientId,
-                      sizeof(CLIENT_ID),
-                      sizeof(ULONG));
-      }
-      ProbeForRead(ThreadContext,
-                   sizeof(CONTEXT),
-                   sizeof(ULONG));
-      SafeContext = *ThreadContext;
-      ThreadContext = &SafeContext;
-      ProbeForRead(InitialTeb,
-                   sizeof(INITIAL_TEB),
-                   sizeof(ULONG));
-      SafeInitialTeb = *InitialTeb;
-      InitialTeb = &SafeInitialTeb;
+        return STATUS_INVALID_PARAMETER;
     }
-    _SEH_HANDLE
+
+    PreviousMode = ExGetPreviousMode();
+
+    if(PreviousMode != KernelMode)
     {
-      Status = _SEH_GetExceptionCode();
+        _SEH_TRY
+        {
+            ProbeForWrite(ThreadHandle,
+                sizeof(HANDLE),
+                sizeof(ULONG));
+            if(ClientId != NULL)
+            {
+                ProbeForWrite(ClientId,
+                    sizeof(CLIENT_ID),
+                    sizeof(ULONG));
+            }
+            ProbeForRead(ThreadContext,
+                sizeof(CONTEXT),
+                sizeof(ULONG));
+            SafeContext = *ThreadContext;
+            ThreadContext = &SafeContext;
+            ProbeForRead(InitialTeb,
+                sizeof(INITIAL_TEB),
+                sizeof(ULONG));
+            SafeInitialTeb = *InitialTeb;
+            InitialTeb = &SafeInitialTeb;
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
     }
-    _SEH_END;
 
+    DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
+        ThreadHandle,ThreadContext);
+
+    Status = ObReferenceObjectByHandle(
+        ProcessHandle,
+        PROCESS_CREATE_THREAD,
+        PsProcessType,
+        PreviousMode,
+        (PVOID*)&Process,
+        NULL);
     if(!NT_SUCCESS(Status))
     {
-      return Status;
+        return(Status);
+    }
+
+    Status = PsLockProcess(Process, FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(Process);
+        return(Status);
+    }
+
+    if(Process->ExitTime.QuadPart != 0)
+    {
+        PsUnlockProcess(Process);
+        return STATUS_PROCESS_IS_TERMINATING;
+    }
+
+    PsUnlockProcess(Process);
+
+    Status = PsInitializeThread(Process,
+        &Thread,
+        ObjectAttributes,
+        PreviousMode,
+        FALSE);
+
+    ObDereferenceObject(Process);
+
+    if (!NT_SUCCESS(Status))
+    {
+        return(Status);
     }
-  }
-
-  DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
-        ThreadHandle,ThreadContext);
-
-  Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     PROCESS_CREATE_THREAD,
-                                     PsProcessType,
-                                     PreviousMode,
-                                     (PVOID*)&Process,
-                                     NULL);
-  if(!NT_SUCCESS(Status))
-  {
-    return(Status);
-  }
-
-  Status = PsInitializeThread(Process,
-                             &Thread,
-                             &hThread,
-                             DesiredAccess,
-                             ObjectAttributes,
-                             FALSE);
-
-  ObDereferenceObject(Process);
-
-  if (!NT_SUCCESS(Status))
+
+    /* create a client id handle */
+    Status = PsCreateCidHandle (
+        Thread, PsThreadType, &Thread->Cid.UniqueThread);
+    if (!NT_SUCCESS(Status))
     {
-      return(Status);
+        ObDereferenceObject(Thread);
+        return Status;
     }
 
-  Status = KiArchInitThreadWithContext(&Thread->Tcb, ThreadContext);
-  if (!NT_SUCCESS(Status))
+    Status = KiArchInitThreadWithContext(&Thread->Tcb, ThreadContext);
+    if (!NT_SUCCESS(Status))
     {
-      return(Status);
+        PsDeleteCidHandle(Thread->Cid.UniqueThread, PsThreadType);
+        ObDereferenceObject(Thread);
+        return(Status);
     }
 
-  Status = PsCreateTeb(ProcessHandle,
-                      &TebBase,
-                      Thread,
-                      InitialTeb);
-  if (!NT_SUCCESS(Status))
+    Status = PsCreateTeb(ProcessHandle,
+        &TebBase,
+        Thread,
+        InitialTeb);
+    if (!NT_SUCCESS(Status))
     {
-      return(Status);
+        PsDeleteCidHandle(Thread->Cid.UniqueThread, PsThreadType);
+        ObDereferenceObject(Thread);
+        return(Status);
     }
-  Thread->Tcb.Teb = TebBase;
+    Thread->Tcb.Teb = TebBase;
 
-  Thread->StartAddress = NULL;
+    Thread->StartAddress = NULL;
 
-  /*
-   * Maybe send a message to the process's debugger
-   */
-  DbgkCreateThread((PVOID)ThreadContext->Eip);
+    /*
+    * Maybe send a message to the process's debugger
+    */
+    DbgkCreateThread((PVOID)ThreadContext->Eip);
 
-  /*
-   * First, force the thread to be non-alertable for user-mode alerts.
-   */
-  Thread->Tcb.Alertable = FALSE;
+    /*
+    * First, force the thread to be non-alertable for user-mode alerts.
+    */
+    Thread->Tcb.Alertable = FALSE;
 
-  /*
-   * If the thread is to be created suspended then queue an APC to
-   * do the suspend before we run any userspace code.
-   */
-  if (CreateSuspended)
+    /*
+    * If the thread is to be created suspended then queue an APC to
+    * do the suspend before we run any userspace code.
+    */
+    if (CreateSuspended)
     {
-      PsSuspendThread(Thread, NULL);
+        KeSuspendThread(&Thread->Tcb);
     }
 
-  /*
-   * Queue an APC to the thread that will execute the ntdll startup
-   * routine.
-   */
-  LdrInitApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
-  KeInitializeApc(LdrInitApc, &Thread->Tcb, OriginalApcEnvironment, LdrInitApcKernelRoutine,
-                 LdrInitApcRundownRoutine, LdrpGetSystemDllEntryPoint(), 
-                 UserMode, NULL);
-  KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
-  
-  /* 
-   * The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE. 
-   * We must do this manually. Do NOT attempt to set the Thread to Alertable before the call,
-   * doing so is a blatant and erronous hack.
-   */
-  Thread->Tcb.ApcState.UserApcPending = TRUE;
-  Thread->Tcb.Alerted[KernelMode] = TRUE;
-
-  oldIrql = KeAcquireDispatcherDatabaseLock ();
-  PsUnblockThread(Thread, NULL, 0);
-  KeReleaseDispatcherDatabaseLock(oldIrql);
-
-  _SEH_TRY
-  {
-    if(ClientId != NULL)
+    /*
+    * Queue an APC to the thread that will execute the ntdll startup
+    * routine.
+    */
+    LdrInitApc = ExAllocatePoolWithTag (
+        NonPagedPool, sizeof(KAPC), TAG_KAPC );
+    KeInitializeApc (
+        LdrInitApc,
+        &Thread->Tcb,
+        OriginalApcEnvironment,
+        LdrInitApcKernelRoutine,
+        LdrInitApcRundownRoutine,
+        LdrpGetSystemDllEntryPoint(),
+        UserMode,
+        NULL );
+    KeInsertQueueApc(LdrInitApc, NULL, NULL, IO_NO_INCREMENT);
+
+    /*
+    * The thread is non-alertable, so the APC we added did not set UserApcPending to TRUE.
+    * We must do this manually. Do NOT attempt to set the Thread to Alertable before the call,
+    * doing so is a blatant and erronous hack.
+    */
+    Thread->Tcb.ApcState.UserApcPending = TRUE;
+    Thread->Tcb.Alerted[KernelMode] = TRUE;
+
+    oldIrql = KeAcquireDispatcherDatabaseLock ();
+    KiUnblockThread(&Thread->Tcb, NULL, 0);
+    KeReleaseDispatcherDatabaseLock(oldIrql);
+
+    Status = ObInsertObject((PVOID)Thread,
+        NULL,
+        DesiredAccess,
+        0,
+        NULL,
+        &hThread);
+    if(NT_SUCCESS(Status))
     {
-      *ClientId = Thread->Cid;
+        _SEH_TRY
+        {
+            if(ClientId != NULL)
+            {
+                *ClientId = Thread->Cid;
+            }
+            *ThreadHandle = hThread;
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
     }
-    *ThreadHandle = hThread;
-  }
-  _SEH_HANDLE
-  {
-    Status = _SEH_GetExceptionCode();
-  }
-  _SEH_END;
-
-  return Status;
+
+    return Status;
 }
 
 
@@ -830,17 +517,18 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
  * @implemented
  */
 NTSTATUS STDCALL
-PsCreateSystemThread(PHANDLE ThreadHandle,
-                    ACCESS_MASK DesiredAccess,
-                    POBJECT_ATTRIBUTES ObjectAttributes,
-                    HANDLE ProcessHandle,
-                    PCLIENT_ID ClientId,
-                    PKSTART_ROUTINE StartRoutine,
-                    PVOID StartContext)
+PsCreateSystemThread (
+    PHANDLE ThreadHandle,
+    ACCESS_MASK DesiredAccess,
+    POBJECT_ATTRIBUTES ObjectAttributes,
+    HANDLE ProcessHandle,
+    PCLIENT_ID ClientId,
+    PKSTART_ROUTINE StartRoutine,
+    PVOID StartContext )
 /*
  * FUNCTION: Creates a thread which executes in kernel mode
  * ARGUMENTS:
- *       ThreadHandle (OUT) = Caller supplied storage for the returned thread 
+ *       ThreadHandle (OUT) = Caller supplied storage for the returned thread
  *                            handle
  *       DesiredAccess = Requested access to the thread
  *       ObjectAttributes = Object attributes (optional)
@@ -854,56 +542,82 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
  * RETURNS: Success or failure status
  */
 {
-   PETHREAD Thread;
-   NTSTATUS Status;
-   KIRQL oldIrql;
-   
-   PAGED_CODE();
-   
-   DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",
-           ThreadHandle,ProcessHandle);
-   
-   Status = PsInitializeThread(NULL,
-                              &Thread,
-                              ThreadHandle,
-                              DesiredAccess,
-                              ObjectAttributes,
-                              FALSE);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   
-   Thread->StartAddress = StartRoutine;
-   Status = KiArchInitThread(&Thread->Tcb, StartRoutine, StartContext);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   if (ClientId != NULL)
-     {
-       *ClientId=Thread->Cid;
-     }
-
-   oldIrql = KeAcquireDispatcherDatabaseLock ();
-   PsUnblockThread(Thread, NULL, 0);
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-   
-   return(STATUS_SUCCESS);
+    PETHREAD Thread;
+    NTSTATUS Status;
+    KIRQL oldIrql;
+
+    PAGED_CODE();
+
+    DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",
+        ThreadHandle,ProcessHandle);
+
+    Status = PsInitializeThread(
+        NULL,
+        &Thread,
+        ObjectAttributes,
+        KernelMode,
+        FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        return(Status);
+    }
+
+    /* Set the thread as a system thread */
+    Thread->SystemThread = TRUE;
+
+    Status = PsCreateCidHandle(Thread,
+        PsThreadType,
+        &Thread->Cid.UniqueThread);
+    if(!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(Thread);
+        return Status;
+    }
+
+    Thread->StartAddress = StartRoutine;
+    Status = KiArchInitThread (
+        &Thread->Tcb, StartRoutine, StartContext);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(Thread);
+        return(Status);
+    }
+
+    if (ClientId != NULL)
+    {
+        *ClientId=Thread->Cid;
+    }
+
+    oldIrql = KeAcquireDispatcherDatabaseLock ();
+    KiUnblockThread(&Thread->Tcb, NULL, 0);
+    KeReleaseDispatcherDatabaseLock(oldIrql);
+
+    Status = ObInsertObject(
+        (PVOID)Thread,
+        NULL,
+        DesiredAccess,
+        0,
+        NULL,
+        ThreadHandle);
+
+    /* don't dereference the thread, the initial reference serves as the keep-alive
+    reference which will be removed by the thread reaper */
+
+    return Status;
 }
 
 
 VOID STDCALL
-PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
-                                BOOLEAN Create)
+PspRunCreateThreadNotifyRoutines (
+    PETHREAD CurrentThread,
+    BOOLEAN Create )
 {
-  ULONG i;
-  CLIENT_ID Cid = CurrentThread->Cid;
+    ULONG i;
+    CLIENT_ID Cid = CurrentThread->Cid;
 
-  for (i = 0; i < PiThreadNotifyRoutineCount; i++)
+    for (i = 0; i < PiThreadNotifyRoutineCount; i++)
     {
-      PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
+        PiThreadNotifyRoutine[i](Cid.UniqueProcess, Cid.UniqueThread, Create);
     }
 }
 
@@ -912,17 +626,18 @@ PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
  * @implemented
  */
 NTSTATUS STDCALL
-PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
+PsSetCreateThreadNotifyRoutine (
+    IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine )
 {
-  if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
+    if (PiThreadNotifyRoutineCount >= MAX_THREAD_NOTIFY_ROUTINE_COUNT)
     {
-      return(STATUS_INSUFFICIENT_RESOURCES);
+        return(STATUS_INSUFFICIENT_RESOURCES);
     }
 
-  PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
-  PiThreadNotifyRoutineCount++;
+    PiThreadNotifyRoutine[PiThreadNotifyRoutineCount] = NotifyRoutine;
+    PiThreadNotifyRoutineCount++;
 
-  return(STATUS_SUCCESS);
+    return(STATUS_SUCCESS);
 }
 
 /* EOF */
index a028cdb..a901562 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ps/debug.c
@@ -9,13 +8,6 @@
  *                  Phillip Susi
  */
 
-/*
- * NOTE:
- * 
- * All of the routines that manipulate the thread queue synchronize on
- * a single spinlock
- * 
- */
 
 /* INCLUDES ****************************************************************/
 
 #define NDEBUG
 #include <internal/debug.h>
 
-/* FUNCTIONS ***************************************************************/
+/* GLOBALS *****************************************************************/
 
-VOID
-KeContextToTrapFrame(PCONTEXT Context,
-                    PKTRAP_FRAME TrapFrame)
-{
-   if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
-     {
-       TrapFrame->Esp = Context->Esp;
-       TrapFrame->Ss = Context->SegSs;
-       TrapFrame->Cs = Context->SegCs;
-       TrapFrame->Eip = Context->Eip;
-       TrapFrame->Eflags = Context->EFlags;    
-       TrapFrame->Ebp = Context->Ebp;
-     }
-   if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
-     {
-       TrapFrame->Eax = Context->Eax;
-       TrapFrame->Ebx = Context->Ebx;
-       TrapFrame->Ecx = Context->Ecx;
-       TrapFrame->Edx = Context->Edx;
-       TrapFrame->Esi = Context->Esi;
-       TrapFrame->Edi = Context->Edi;
-     }
-   if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
-     {
-       TrapFrame->Ds = Context->SegDs;
-       TrapFrame->Es = Context->SegEs;
-       TrapFrame->Fs = Context->SegFs;
-       TrapFrame->Gs = Context->SegGs;
-     }
-   if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
-     {
-       /*
-        * Not handled
-        *
-        * This should be handled separately I think.
-        *  - blight
-        */
-     }
-   if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
-     {
-       /*
-        * Not handled
-        */
-     }
-}
-
-VOID
-KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
-                    PCONTEXT Context)
-{
-   if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
-     {
-       Context->SegSs = TrapFrame->Ss;
-       Context->Esp = TrapFrame->Esp;
-       Context->SegCs = TrapFrame->Cs;
-       Context->Eip = TrapFrame->Eip;
-       Context->EFlags = TrapFrame->Eflags;
-       Context->Ebp = TrapFrame->Ebp;
-     }
-   if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
-     {
-       Context->Eax = TrapFrame->Eax;
-       Context->Ebx = TrapFrame->Ebx;
-       Context->Ecx = TrapFrame->Ecx;
-       /*
-        * NOTE: In the trap frame which is built on entry to a system
-        * call TrapFrame->Edx will actually hold the address of the
-        * previous TrapFrame. I don't believe leaking this information
-        * has security implications. Also EDX holds the address of the
-        * arguments to the system call in progress so it isn't of much
-        * interest to the debugger.
-        */
-       Context->Edx = TrapFrame->Edx;
-       Context->Esi = TrapFrame->Esi;
-       Context->Edi = TrapFrame->Edi;
-     }
-   if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
-     {
-       Context->SegDs = TrapFrame->Ds;
-       Context->SegEs = TrapFrame->Es;
-       Context->SegFs = TrapFrame->Fs;
-       Context->SegGs = TrapFrame->Gs;
-     }
-   if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
-     {
-       /*
-        * FIXME: Implement this case
-        */     
-       Context->ContextFlags &= (~CONTEXT_DEBUG_REGISTERS) | CONTEXT_i386;
-     }
-   if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
-     {
-       /*
-        * FIXME: Implement this case
-        *
-        * I think this should only be filled for FPU exceptions, otherwise I
-         * would not know where to get it from as it can be the current state
-        * of the FPU or already saved in the thread's FPU save area.
-        *  -blight
-        */
-       Context->ContextFlags &= (~CONTEXT_FLOATING_POINT) | CONTEXT_i386;
-     }
-#if 0
-   if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
-     {
-       /*
-        * FIXME: Investigate this
-        *
-        * This is the XMM state (first 512 bytes of FXSAVE_FORMAT/FX_SAVE_AREA)
-        * This should only be filled in case of a SIMD exception I think, so
-        * this is not the right place (like for FPU the state could already be
-        * saved in the thread's FX_SAVE_AREA or still be in the CPU)
-        *  -blight
-        */
-        Context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS;
-     }
-#endif
-}
+/* Thread "Set/Get Context" Context Structure */
+typedef struct _GET_SET_CTX_CONTEXT {
+    KAPC Apc;
+    KEVENT Event;
+    CONTEXT Context;
+} GET_SET_CTX_CONTEXT, *PGET_SET_CTX_CONTEXT;
 
-VOID STDCALL
-KeGetSetContextRundownRoutine(PKAPC Apc)
-{
-  PKEVENT Event;
-  PNTSTATUS Status;
 
-  Event = (PKEVENT)Apc->SystemArgument1;   
-  Status = (PNTSTATUS)Apc->SystemArgument2;
-  (*Status) = STATUS_THREAD_IS_TERMINATING;
-  KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
-}
+/* FUNCTIONS ***************************************************************/
 
-VOID STDCALL
-KeGetContextKernelRoutine(PKAPC Apc,
-                         PKNORMAL_ROUTINE* NormalRoutine,
-                         PVOID* NormalContext,
-                         PVOID* SystemArgument1,
-                         PVOID* SystemArgument2)
 /*
  * FUNCTION: This routine is called by an APC sent by NtGetContextThread to
  * copy the context of a thread into a buffer.
  */
+VOID 
+STDCALL
+PspGetOrSetContextKernelRoutine(PKAPC Apc,
+                                PKNORMAL_ROUTINE* NormalRoutine,
+                                PVOID* NormalContext,
+                                PVOID* SystemArgument1,
+                                PVOID* SystemArgument2)
 {
-  PKEVENT Event;
-  PCONTEXT Context;
-  PNTSTATUS Status;
-   
-  Context = (PCONTEXT)(*NormalContext);
-  Event = (PKEVENT)(*SystemArgument1);
-  Status = (PNTSTATUS)(*SystemArgument2);
+    PGET_SET_CTX_CONTEXT GetSetContext;
+    PKEVENT Event;
+    PCONTEXT Context;
    
-  KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
+    /* Get the Context Structure */
+    GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
+    Context = &GetSetContext->Context;
+    Event = &GetSetContext->Event;
+
+    /* Check if it's a set or get */
+    if (SystemArgument1) {
+        
+        /* Get the Context */ 
+        KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
+        
+    } else {
+        
+        /* Set the Context */
+        KeContextToTrapFrame(Context, KeGetCurrentThread()->TrapFrame);
+    }
    
-  *Status = STATUS_SUCCESS;
-  KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+    /* Notify the Native API that we are done */
+    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
 }
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtGetContextThread(IN HANDLE ThreadHandle,
-                  OUT PCONTEXT ThreadContext)
+                   OUT PCONTEXT ThreadContext)
 {
-  PETHREAD Thread;
-  CONTEXT Context;
-  KAPC Apc;
-  KEVENT Event;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
+    PETHREAD Thread;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    GET_SET_CTX_CONTEXT GetSetContext;
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PreviousMode = ExGetPreviousMode();
+    PAGED_CODE();
 
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(ThreadContext,
-                    sizeof(CONTEXT),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    /* Check the buffer to be OK */
+    if(PreviousMode != KernelMode) {
+    
+        _SEH_TRY {
+            
+            ProbeForWrite(ThreadContext,
+                          sizeof(CONTEXT),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
+        if(!NT_SUCCESS(Status)) return Status;
     }
-  }
   
-  Status = ObReferenceObjectByHandle(ThreadHandle,
-                                     THREAD_GET_CONTEXT,
-                                     PsThreadType,
-                                     PreviousMode,
-                                     (PVOID*)&Thread,
-                                     NULL);
-  if(NT_SUCCESS(Status))
-  {
-    if(Thread == PsGetCurrentThread())
-    {
-      /*
-       * I don't know if trying to get your own context makes much
-       * sense but we can handle it more efficently.
-       */
-       
-      KeTrapFrameToContext(Thread->Tcb.TrapFrame, &Context);
-    }
-    else
-    {
-      KeInitializeEvent(&Event,
-                        NotificationEvent,
-                        FALSE);
-
-      KeInitializeApc(&Apc,
-                      &Thread->Tcb,
-                      OriginalApcEnvironment,
-                      KeGetContextKernelRoutine,
-                      KeGetSetContextRundownRoutine,
-                      NULL,
-                      KernelMode,
-                      (PVOID)&Context);
-      if (!KeInsertQueueApc(&Apc,
-                           (PVOID)&Event,
-                           (PVOID)&Status,
-                           IO_NO_INCREMENT))
-       {
-         Status = STATUS_THREAD_IS_TERMINATING;
-       }
-      else
-       {
-         Status = KeWaitForSingleObject(&Event,
-                                        0,
-                                        KernelMode,
-                                        FALSE,
-                                        NULL);
-       }
-    }
-    ObDereferenceObject(Thread);
+    /* Get the Thread Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_GET_CONTEXT,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+    
+    /* Check success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Check if we're running in the same thread */
+        if(Thread == PsGetCurrentThread()) {
+      
+            /*
+             * I don't know if trying to get your own context makes much
+             * sense but we can handle it more efficently.
+             */
+            KeTrapFrameToContext(Thread->Tcb.TrapFrame, &GetSetContext.Context);
+        
+        } else {
+            
+            /* Use an APC... Initialize the Event */
+            KeInitializeEvent(&GetSetContext.Event,
+                              NotificationEvent,
+                              FALSE);
+            
+            /* Initialize the APC */
+            KeInitializeApc(&GetSetContext.Apc,
+                            &Thread->Tcb,
+                            OriginalApcEnvironment,
+                            PspGetOrSetContextKernelRoutine,
+                            NULL,
+                            NULL,
+                            KernelMode,
+                            NULL);
+            
+            /* Queue it as a Get APC */
+            if (!KeInsertQueueApc(&GetSetContext.Apc,
+                                  (PVOID)1,
+                                  NULL,
+                                  IO_NO_INCREMENT)) {
+                
+                Status = STATUS_THREAD_IS_TERMINATING;
+            
+            } else {
+            
+                /* Wait for the APC to complete */
+                Status = KeWaitForSingleObject(&GetSetContext.Event,
+                                               0,
+                                               KernelMode,
+                                               FALSE,
+                                               NULL);
+            }
+        }
+        
+        /* Dereference the thread */
+        ObDereferenceObject(Thread);
     
-    if(NT_SUCCESS(Status))
-    {
-      _SEH_TRY
-      {
-        *ThreadContext = Context;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
+        /* Check for success and return the Context */
+        if(NT_SUCCESS(Status)) {
+      
+            _SEH_TRY {
+                
+                *ThreadContext = GetSetContext.Context;
+          
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;          
+        }
     }
-  }
   
-  return Status;
+    /* Return status */        
+    return Status;
 }
 
-VOID STDCALL
-KeSetContextKernelRoutine(PKAPC Apc,
-                         PKNORMAL_ROUTINE* NormalRoutine,
-                         PVOID* NormalContext,
-                         PVOID* SystemArgument1,
-                         PVOID* SystemArgument2)
-/*
- * FUNCTION: This routine is called by an APC sent by NtSetContextThread to
- * set the context of a thread from a buffer.
- */
-{
-  PKEVENT Event;
-  PCONTEXT Context;
-  PNTSTATUS Status;
-   
-  Context = (PCONTEXT)(*NormalContext);
-  Event = (PKEVENT)(*SystemArgument1);
-  Status = (PNTSTATUS)(*SystemArgument2);
-   
-  KeContextToTrapFrame(Context, KeGetCurrentThread()->TrapFrame);
-   
-  *Status = STATUS_SUCCESS;
-  KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
-}
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtSetContextThread(IN HANDLE ThreadHandle,
-                  IN PCONTEXT ThreadContext)
+                   IN PCONTEXT ThreadContext)
 {
-  PETHREAD Thread;
-  KAPC Apc;
-  KEVENT Event;
-  CONTEXT Context;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
+    PETHREAD Thread;
+    GET_SET_CTX_CONTEXT GetSetContext;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
+    PAGED_CODE();
   
-  PreviousMode = ExGetPreviousMode();
-  
-  if(PreviousMode != KernelMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForRead(ThreadContext,
-                   sizeof(CONTEXT),
-                   sizeof(ULONG));
-      Context = *ThreadContext;
-      ThreadContext = &Context;
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    /* Check the buffer to be OK */
+    if(PreviousMode != KernelMode) {
+    
+        _SEH_TRY {
+            
+            ProbeForRead(ThreadContext,
+                         sizeof(CONTEXT),
+                         sizeof(ULONG));
+            
+            GetSetContext.Context = *ThreadContext;
+            ThreadContext = &GetSetContext.Context;
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        } _SEH_END;
     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
+        if(!NT_SUCCESS(Status)) return Status;
     }
-  }
 
-  Status = ObReferenceObjectByHandle(ThreadHandle,
-                                     THREAD_SET_CONTEXT,
-                                     PsThreadType,
-                                     PreviousMode,
-                                     (PVOID*)&Thread,
-                                     NULL);
-  if(NT_SUCCESS(Status))
-  {
-    if (Thread == PsGetCurrentThread())
-    {
-      /*
-       * I don't know if trying to set your own context makes much
-       * sense but we can handle it more efficently.
-       */
-       
-      KeContextToTrapFrame(&Context, Thread->Tcb.TrapFrame);
-    }
-    else
-    {
-      KeInitializeEvent(&Event,
-                        NotificationEvent,
-                        FALSE);        
-       
-      KeInitializeApc(&Apc,
-                      &Thread->Tcb,
-                      OriginalApcEnvironment,
-                      KeSetContextKernelRoutine,
-                      KeGetSetContextRundownRoutine,
-                      NULL,
-                      KernelMode,
-                      (PVOID)&Context);
-      if (!KeInsertQueueApc(&Apc,
-                           (PVOID)&Event,
-                           (PVOID)&Status,
-                           IO_NO_INCREMENT))
-       {
-         Status = STATUS_THREAD_IS_TERMINATING;
-       }
-      else
-       {
-         Status = KeWaitForSingleObject(&Event,
-                                        0,
-                                        KernelMode,
-                                        FALSE,
-                                         NULL);
-       }
+    /* Get the Thread Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_SET_CONTEXT,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+    
+    /* Check success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Check if we're running in the same thread */
+        if(Thread == PsGetCurrentThread()) {
+      
+            /*
+             * I don't know if trying to get your own context makes much
+             * sense but we can handle it more efficently.
+             */
+            KeContextToTrapFrame(&GetSetContext.Context, Thread->Tcb.TrapFrame);
+        
+        } else {
+            
+            /* Use an APC... Initialize the Event */
+            KeInitializeEvent(&GetSetContext.Event,
+                              NotificationEvent,
+                              FALSE);
+            
+            /* Initialize the APC */
+            KeInitializeApc(&GetSetContext.Apc,
+                            &Thread->Tcb,
+                            OriginalApcEnvironment,
+                            PspGetOrSetContextKernelRoutine,
+                            NULL,
+                            NULL,
+                            KernelMode,
+                            NULL);
+            
+            /* Queue it as a Get APC */
+            if (!KeInsertQueueApc(&GetSetContext.Apc,
+                                  NULL,
+                                  NULL,
+                                  IO_NO_INCREMENT)) {
+                
+                Status = STATUS_THREAD_IS_TERMINATING;
+            
+            } else {
+            
+                /* Wait for the APC to complete */
+                Status = KeWaitForSingleObject(&GetSetContext.Event,
+                                               0,
+                                               KernelMode,
+                                               FALSE,
+                                               NULL);
+            }
+        }
+        
+        /* Dereference the thread */
+        ObDereferenceObject(Thread);
     }
-    ObDereferenceObject(Thread);
-  }
   
-  return Status;
+    /* Return status */        
+    return Status;
 }
 
 /* EOF */
index 10d2c60..39064fd 100644 (file)
@@ -67,9 +67,9 @@ NtContinue (
           {
             Thread->NpxState = NPX_STATE_VALID;
             KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
-            if (KeGetCurrentKPCR()->PrcbData.NpxThread == Thread)
+            if (KeGetCurrentPrcb()->NpxThread == Thread)
               {
-                KeGetCurrentKPCR()->PrcbData.NpxThread = NULL;
+                KeGetCurrentPrcb()->NpxThread = NULL;
                 Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
               }
             else
index c1d0b09..b8d2598 100644 (file)
@@ -16,6 +16,8 @@
 
 /* GLOBALS *******************************************************************/
 
+extern PEPROCESS PsIdleProcess;
+
 /* FUNCTIONS *****************************************************************/
 
 /** System idle thread procedure
@@ -26,11 +28,11 @@ PsIdleThreadMain(PVOID Context)
 {
    KIRQL oldlvl;
 
-   PKPCR Pcr = KeGetCurrentKPCR();
+   PKPRCB Prcb = KeGetCurrentPrcb();
    
    for(;;)
      {
-       if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0)
+       if (Prcb->DpcData[0].DpcQueueDepth > 0)
         {
           KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
           KiDispatchInterrupt();
@@ -52,35 +54,35 @@ PsInitIdleThread(VOID)
 {
    NTSTATUS Status;
    PETHREAD IdleThread;
-   HANDLE IdleThreadHandle;
+   KIRQL oldIrql;
+
+   Status = PsInitializeThread(PsIdleProcess,
+                              &IdleThread,
+                              NULL,
+                              KernelMode,
+                              FALSE);
+   if (!NT_SUCCESS(Status))
+     {
+        DPRINT1("Couldn't create idle system thread! Status: 0x%x\n", Status);
+        KEBUGCHECK(0);
+        return;
+     }
    
-   Status = PsCreateSystemThread(&IdleThreadHandle,
-                       THREAD_ALL_ACCESS,
-                       NULL,
-                       NULL,
-                       NULL,
-                       PsIdleThreadMain,
-                       NULL);
-   if(!NT_SUCCESS(Status)) 
-   {
-       DPRINT("Couldn't create Idle System Thread!");
-       KEBUGCHECK(0);
-       return;
-   }   
-   Status = ObReferenceObjectByHandle(IdleThreadHandle,
-                                     THREAD_ALL_ACCESS,
-                                     PsThreadType,
-                                     KernelMode,
-                                     (PVOID*)&IdleThread,
-                                     NULL);
-   if(!NT_SUCCESS(Status)) 
-   {
-       DPRINT("Couldn't get pointer to Idle System Thread!");
-       KEBUGCHECK(0);
-       return;
-   }
-   NtClose(IdleThreadHandle);
-   KeGetCurrentKPCR()->PrcbData.IdleThread = &IdleThread->Tcb;
+   IdleThread->StartAddress = PsIdleThreadMain;
+   Status = KiArchInitThread(&IdleThread->Tcb, PsIdleThreadMain, NULL);
+   if (!NT_SUCCESS(Status))
+     {
+        DPRINT1("Couldn't initialize system idle thread! Status: 0x%x\n", Status);
+        ObDereferenceObject(IdleThread);
+        KEBUGCHECK(0);
+        return;
+     }
+
+   oldIrql = KeAcquireDispatcherDatabaseLock ();
+   KiUnblockThread(&IdleThread->Tcb, NULL, 0);
+   KeReleaseDispatcherDatabaseLock(oldIrql);
+
+   KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb;
    KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);
    KeSetAffinityThread(&IdleThread->Tcb, 1 << 0);
 
index 4e764b3..b28740c 100644 (file)
@@ -1,10 +1,10 @@
 /* $Id$
- * 
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ps/job.c
  * PURPOSE:         Job Native Functions
- * 
+ *
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) (stubs)
  *                  Thomas Weidenmueller <w3seek@reactos.com>
  */
 
 /* GLOBALS *******************************************************************/
 
+#define TAG_EJOB TAG('E', 'J', 'O', 'B') /* EJOB */
+
 POBJECT_TYPE EXPORTED PsJobType = NULL;
 
 LIST_ENTRY PsJobListHead;
 static FAST_MUTEX PsJobListLock;
 
-static GENERIC_MAPPING PiJobMapping = {STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
-                                       STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES,
-                                       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
-                                       STANDARD_RIGHTS_ALL | JOB_OBJECT_ALL_ACCESS};
+static GENERIC_MAPPING PiJobMapping =
+{
+    STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
+    STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
+    STANDARD_RIGHTS_ALL | JOB_OBJECT_ALL_ACCESS
+};
 
 /* FUNCTIONS *****************************************************************/
 
 VOID STDCALL
-PiDeleteJob(PVOID ObjectBody)
+PiDeleteJob ( PVOID ObjectBody )
 {
-  PEJOB Job = (PEJOB)ObjectBody;
-  
-  /* remove the reference to the completion port if associated */
-  if(Job->CompletionPort != NULL)
-  {
-    ObDereferenceObject(Job->CompletionPort);
-  }
-
-  /* unlink the job object */
-  if(Job->JobLinks.Flink != NULL)
-  {
-    ExAcquireFastMutex(&PsJobListLock);
-    RemoveEntryList(&Job->JobLinks);
-    ExReleaseFastMutex(&PsJobListLock);
-  }
-  
-  ExDeleteResource(&Job->JobLock);
+    PEJOB Job = (PEJOB)ObjectBody;
+
+    /* remove the reference to the completion port if associated */
+    if(Job->CompletionPort != NULL)
+    {
+        ObDereferenceObject(Job->CompletionPort);
+    }
+
+    /* unlink the job object */
+    if(Job->JobLinks.Flink != NULL)
+    {
+        ExAcquireFastMutex(&PsJobListLock);
+        RemoveEntryList(&Job->JobLinks);
+        ExReleaseFastMutex(&PsJobListLock);
+    }
+
+    ExDeleteResource(&Job->JobLock);
 }
 
 VOID INIT_FUNCTION
-PsInitJobManagment(VOID)
+PsInitJobManagment ( VOID )
 {
-  PsJobType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-
-  PsJobType->Tag = TAG('E', 'J', 'O', 'B');
-  PsJobType->TotalObjects = 0;
-  PsJobType->TotalHandles = 0;
-  PsJobType->PeakObjects = 0;
-  PsJobType->PeakHandles = 0;
-  PsJobType->PagedPoolCharge = 0;
-  PsJobType->NonpagedPoolCharge = sizeof(EJOB);
-  PsJobType->Mapping = &PiJobMapping;
-  PsJobType->Dump = NULL;
-  PsJobType->Open = NULL;
-  PsJobType->Close = NULL;
-  PsJobType->Delete = PiDeleteJob;
-  PsJobType->Parse = NULL;
-  PsJobType->Security = NULL;
-  PsJobType->QueryName = NULL;
-  PsJobType->OkayToClose = NULL;
-  PsJobType->Create = NULL;
-  PsJobType->DuplicationNotify = NULL;
-  
-  RtlInitUnicodeString(&PsJobType->TypeName, L"Job");
-  
-  ObpCreateTypeObject(PsJobType);
-  
-  InitializeListHead(&PsJobListHead);
-  ExInitializeFastMutex(&PsJobListLock);
+    PsJobType = ExAllocatePoolWithTag (
+        NonPagedPool, sizeof(OBJECT_TYPE), TAG_EJOB );
+
+    PsJobType->Tag = TAG_EJOB;
+    PsJobType->TotalObjects = 0;
+    PsJobType->TotalHandles = 0;
+    PsJobType->PeakObjects = 0;
+    PsJobType->PeakHandles = 0;
+    PsJobType->PagedPoolCharge = 0;
+    PsJobType->NonpagedPoolCharge = sizeof(EJOB);
+    PsJobType->Mapping = &PiJobMapping;
+    PsJobType->Dump = NULL;
+    PsJobType->Open = NULL;
+    PsJobType->Close = NULL;
+    PsJobType->Delete = PiDeleteJob;
+    PsJobType->Parse = NULL;
+    PsJobType->Security = NULL;
+    PsJobType->QueryName = NULL;
+    PsJobType->OkayToClose = NULL;
+    PsJobType->Create = NULL;
+    PsJobType->DuplicationNotify = NULL;
+
+    RtlInitUnicodeString(&PsJobType->TypeName, L"Job");
+
+    ObpCreateTypeObject(PsJobType);
+
+    InitializeListHead(&PsJobListHead);
+    ExInitializeFastMutex(&PsJobListLock);
 }
 
 NTSTATUS
-PspAssignProcessToJob(PEPROCESS Process,
-                      PEJOB Job)
+PspAssignProcessToJob (
+    PEPROCESS Process,
+    PEJOB Job)
 {
-  DPRINT("PspAssignProcessToJob() is unimplemented!\n");
-  return STATUS_NOT_IMPLEMENTED;
+    DPRINT("PspAssignProcessToJob() is unimplemented!\n");
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
-PspTerminateJobObject(PEJOB Job,
-                      KPROCESSOR_MODE AccessMode,
-                      NTSTATUS ExitStatus)
+PspTerminateJobObject (
+    PEJOB Job,
+    KPROCESSOR_MODE AccessMode,
+    NTSTATUS ExitStatus )
 {
-  DPRINT("PspTerminateJobObject() is unimplemented!\n");
-  return STATUS_NOT_IMPLEMENTED;
+    DPRINT("PspTerminateJobObject() is unimplemented!\n");
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
-NtAssignProcessToJobObject(HANDLE JobHandle,
-                           HANDLE ProcessHandle)
+NTSTATUS
+STDCALL
+NtAssignProcessToJobObject (
+    HANDLE JobHandle,
+    HANDLE ProcessHandle)
 {
-  PEPROCESS Process;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
-  
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  /* make sure we're having a handle with enough rights, especially the to
-     terminate the process. otherwise one could abuse the job objects to
-     terminate processes without having rights granted to do so! The reason
-     I open the process handle before the job handle is that a simple test showed
-     that it first complains about a invalid process handle! The other way around
-     would be simpler though... */
-  Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     PROCESS_TERMINATE,
-                                     PsProcessType,
-                                     PreviousMode,
-                                     (PVOID*)&Process,
-                                     NULL);
-  if(NT_SUCCESS(Status))
-  {
-    if(Process->Job == NULL)
+    PEPROCESS Process;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+    PreviousMode = ExGetPreviousMode();
+
+    /* make sure we're having a handle with enough rights, especially the to
+    terminate the process. otherwise one could abuse the job objects to
+    terminate processes without having rights granted to do so! The reason
+    I open the process handle before the job handle is that a simple test showed
+    that it first complains about a invalid process handle! The other way around
+    would be simpler though... */
+    Status = ObReferenceObjectByHandle(
+        ProcessHandle,
+        PROCESS_TERMINATE,
+        PsProcessType,
+        PreviousMode,
+        (PVOID*)&Process,
+        NULL);
+    if(NT_SUCCESS(Status))
     {
-      PEJOB Job;
-      
-      Status = ObReferenceObjectByHandle(JobHandle,
-                                         JOB_OBJECT_ASSIGN_PROCESS,
-                                         PsJobType,
-                                         PreviousMode,
-                                         (PVOID*)&Job,
-                                         NULL);
-      if(NT_SUCCESS(Status))
-      {
-        /* lock the process so we can safely assign the process. Note that in the
-           meanwhile another thread could have assigned this process to a job! */
-
-        Status = PsLockProcess(Process, FALSE);
-        if(NT_SUCCESS(Status))
+        if(Process->Job == NULL)
+        {
+            PEJOB Job;
+
+            Status = ObReferenceObjectByHandle(
+                JobHandle,
+                JOB_OBJECT_ASSIGN_PROCESS,
+                PsJobType,
+                PreviousMode,
+                (PVOID*)&Job,
+                NULL);
+            if(NT_SUCCESS(Status))
+            {
+                /* lock the process so we can safely assign the process. Note that in the
+                meanwhile another thread could have assigned this process to a job! */
+
+                Status = PsLockProcess(Process, FALSE);
+                if(NT_SUCCESS(Status))
+                {
+                    if(Process->Job == NULL && Process->SessionId == Job->SessionId)
+                    {
+                        /* Just store the pointer to the job object in the process, we'll
+                        assign it later. The reason we can't do this here is that locking
+                        the job object might require it to wait, which is a bad thing
+                        while holding the process lock! */
+                        Process->Job = Job;
+                    }
+                    else
+                    {
+                        /* process is already assigned to a job or session id differs! */
+                        Status = STATUS_ACCESS_DENIED;
+                    }
+                    PsUnlockProcess(Process);
+
+                    if(NT_SUCCESS(Status))
+                    {
+                        /* let's actually assign the process to the job as we're not holding
+                        the process lock anymore! */
+                        Status = PspAssignProcessToJob(Process, Job);
+                    }
+                }
+
+                ObDereferenceObject(Job);
+            }
+        }
+        else
         {
-          if(Process->Job == NULL && Process->SessionId == Job->SessionId)
-          {
-            /* Just store the pointer to the job object in the process, we'll
-               assign it later. The reason we can't do this here is that locking
-               the job object might require it to wait, which is a bad thing
-               while holding the process lock! */
-            Process->Job = Job;
-          }
-          else
-          {
             /* process is already assigned to a job or session id differs! */
             Status = STATUS_ACCESS_DENIED;
-          }
-          PsUnlockProcess(Process);
-          
-          if(NT_SUCCESS(Status))
-          {
-            /* let's actually assign the process to the job as we're not holding
-               the process lock anymore! */
-            Status = PspAssignProcessToJob(Process, Job);
-          }
         }
 
-        ObDereferenceObject(Job);
-      }
-    }
-    else
-    {
-      /* process is already assigned to a job or session id differs! */
-      Status = STATUS_ACCESS_DENIED;
+        ObDereferenceObject(Process);
     }
-    
-    ObDereferenceObject(Process);
-  }
 
-  return Status;
+    return Status;
 }
 
 
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
-NtCreateJobObject(PHANDLE JobHandle,
-                  ACCESS_MASK DesiredAccess,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
+NTSTATUS
+STDCALL
+NtCreateJobObject (
+    PHANDLE JobHandle,
+    ACCESS_MASK DesiredAccess,
+    POBJECT_ATTRIBUTES ObjectAttributes )
 {
-  HANDLE hJob;
-  PEJOB Job;
-  KPROCESSOR_MODE PreviousMode;
-  PEPROCESS CurrentProcess;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-
-  PreviousMode = ExGetPreviousMode();
-  CurrentProcess = PsGetCurrentProcess();
-
-  /* check for valid buffers */
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      /* probe with 32bit alignment */
-      ProbeForWrite(JobHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+    HANDLE hJob;
+    PEJOB Job;
+    KPROCESSOR_MODE PreviousMode;
+    PEPROCESS CurrentProcess;
+    NTSTATUS Status = STATUS_SUCCESS;
 
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-  
-  Status = ObCreateObject(PreviousMode,
-                          PsJobType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(EJOB),
-                          0,
-                          0,
-                          (PVOID*)&Job);
-  
-  if(NT_SUCCESS(Status))
-  {
-    /* FIXME - Zero all fields as we don't yet implement all of them */
-    RtlZeroMemory(Job, sizeof(EJOB));
-    
-    /* make sure that early destruction doesn't attempt to remove the object from
-       the list before it even gets added! */
-    Job->JobLinks.Flink = NULL;
-    
-    /* setup the job object */
-    InitializeListHead(&Job->ProcessListHead);
-    Job->SessionId = CurrentProcess->SessionId; /* inherit the session id from the caller */
-    
-    Status = ExInitializeResource(&Job->JobLock);
-    if(!NT_SUCCESS(Status))
+    PAGED_CODE();
+
+    PreviousMode = ExGetPreviousMode();
+    CurrentProcess = PsGetCurrentProcess();
+
+    /* check for valid buffers */
+    if(PreviousMode == UserMode)
     {
-      DPRINT1("Failed to initialize job lock!!!\n");
-      ObDereferenceObject(Job);
-      return Status;
+        _SEH_TRY
+        {
+            /* probe with 32bit alignment */
+            ProbeForWrite(JobHandle,
+                sizeof(HANDLE),
+                sizeof(ULONG));
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
     }
-    KeInitializeEvent(&Job->Event, NotificationEvent, FALSE);
-    
-    /* link the object into the global job list */
-    ExAcquireFastMutex(&PsJobListLock);
-    InsertTailList(&PsJobListHead, &Job->JobLinks);
-    ExReleaseFastMutex(&PsJobListLock);
-    
-    Status = ObInsertObject(Job,
-                            NULL,
-                            DesiredAccess,
-                            0,
-                            NULL,
-                            &hJob);
+
+    Status = ObCreateObject(PreviousMode,
+        PsJobType,
+        ObjectAttributes,
+        PreviousMode,
+        NULL,
+        sizeof(EJOB),
+        0,
+        0,
+        (PVOID*)&Job);
+
     if(NT_SUCCESS(Status))
     {
-      /* pass the handle back to the caller */
-      _SEH_TRY
-      {
-        /* NOTE: if the caller passed invalid buffers to receive the handle it's his
-                 own fault! the object will still be created and live... It's possible
-                 to find the handle using ObFindHandleForObject()! */
-        *JobHandle = hJob;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
+        /* FIXME - Zero all fields as we don't yet implement all of them */
+        RtlZeroMemory(Job, sizeof(EJOB));
+
+        /* make sure that early destruction doesn't attempt to remove the object from
+        the list before it even gets added! */
+        Job->JobLinks.Flink = NULL;
+
+        /* setup the job object */
+        InitializeListHead(&Job->ProcessListHead);
+        Job->SessionId = CurrentProcess->SessionId; /* inherit the session id from the caller */
+
+        Status = ExInitializeResource(&Job->JobLock);
+        if(!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to initialize job lock!!!\n");
+            ObDereferenceObject(Job);
+            return Status;
+        }
+        KeInitializeEvent(&Job->Event, NotificationEvent, FALSE);
+
+        /* link the object into the global job list */
+        ExAcquireFastMutex(&PsJobListLock);
+        InsertTailList(&PsJobListHead, &Job->JobLinks);
+        ExReleaseFastMutex(&PsJobListLock);
+
+        Status = ObInsertObject(Job,
+            NULL,
+            DesiredAccess,
+            0,
+            NULL,
+            &hJob);
+        if(NT_SUCCESS(Status))
+        {
+            /* pass the handle back to the caller */
+            _SEH_TRY
+            {
+                /* NOTE: if the caller passed invalid buffers to receive the handle it's his
+                own fault! the object will still be created and live... It's possible
+                to find the handle using ObFindHandleForObject()! */
+                *JobHandle = hJob;
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+        }
     }
-  }
-  
-  return Status;
+
+    return Status;
 }
 
 
@@ -300,195 +312,203 @@ NtCreateJobObject(PHANDLE JobHandle,
  */
 NTSTATUS
 STDCALL
-NtIsProcessInJob(IN HANDLE ProcessHandle,
-                 IN HANDLE JobHandle OPTIONAL)
+NtIsProcessInJob (
+    IN HANDLE ProcessHandle,
+    IN HANDLE JobHandle OPTIONAL )
 {
-  KPROCESSOR_MODE PreviousMode;
-  PEPROCESS Process;
-  NTSTATUS Status;
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  PAGED_CODE();
-  
-  Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     PROCESS_QUERY_INFORMATION,
-                                     PsProcessType,
-                                     PreviousMode,
-                                     (PVOID*)&Process,
-                                     NULL);
-  if(NT_SUCCESS(Status))
-  {
-    /* FIXME - make sure the job object doesn't get exchanged or deleted while trying to
-               reference it, e.g. by locking it somehow until it is referenced... */
-
-    PEJOB ProcessJob = Process->Job;
-    
-    if(ProcessJob != NULL)
+    KPROCESSOR_MODE PreviousMode;
+    PEPROCESS Process;
+    NTSTATUS Status;
+
+    PreviousMode = ExGetPreviousMode();
+
+    PAGED_CODE();
+
+    Status = ObReferenceObjectByHandle(
+        ProcessHandle,
+        PROCESS_QUERY_INFORMATION,
+        PsProcessType,
+        PreviousMode,
+        (PVOID*)&Process,
+        NULL);
+    if(NT_SUCCESS(Status))
     {
-      if(JobHandle == NULL)
-      {
-        /* the process is assigned to a job */
-        Status = STATUS_PROCESS_IN_JOB;
-      }
-      else /* JobHandle != NULL */
-      {
-        PEJOB JobObject;
-
-        /* get the job object and compare the object pointer with the one assigned to the process */
-        Status = ObReferenceObjectByHandle(JobHandle,
-                                           JOB_OBJECT_QUERY,
-                                           PsJobType,
-                                           PreviousMode,
-                                           (PVOID*)&JobObject,
-                                           NULL);
-        if(NT_SUCCESS(Status))
+        /* FIXME - make sure the job object doesn't get exchanged or deleted while trying to
+        reference it, e.g. by locking it somehow until it is referenced... */
+
+        PEJOB ProcessJob = Process->Job;
+
+        if(ProcessJob != NULL)
         {
-          Status = ((ProcessJob == JobObject) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB);
-          ObDereferenceObject(JobObject);
+            if(JobHandle == NULL)
+            {
+                /* the process is assigned to a job */
+                Status = STATUS_PROCESS_IN_JOB;
+            }
+            else /* JobHandle != NULL */
+            {
+                PEJOB JobObject;
+
+                /* get the job object and compare the object pointer with the one assigned to the process */
+                Status = ObReferenceObjectByHandle(JobHandle,
+                    JOB_OBJECT_QUERY,
+                    PsJobType,
+                    PreviousMode,
+                    (PVOID*)&JobObject,
+                    NULL);
+                if(NT_SUCCESS(Status))
+                {
+                    Status = ((ProcessJob == JobObject) ? STATUS_PROCESS_IN_JOB : STATUS_PROCESS_NOT_IN_JOB);
+                    ObDereferenceObject(JobObject);
+                }
+            }
         }
-      }
-    }
-    else
-    {
-      /* the process is not assigned to any job */
-      Status = STATUS_PROCESS_NOT_IN_JOB;
+        else
+        {
+            /* the process is not assigned to any job */
+            Status = STATUS_PROCESS_NOT_IN_JOB;
+        }
+        ObDereferenceObject(Process);
     }
-    ObDereferenceObject(Process);
-  }
 
-  return Status;
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS 
-STDCALL 
-NtOpenJobObject(PHANDLE JobHandle,
-                ACCESS_MASK DesiredAccess,
-                POBJECT_ATTRIBUTES ObjectAttributes)
+NTSTATUS
+STDCALL
+NtOpenJobObject (
+    PHANDLE JobHandle,
+    ACCESS_MASK DesiredAccess,
+    POBJECT_ATTRIBUTES ObjectAttributes)
 {
-  KPROCESSOR_MODE PreviousMode;
-  HANDLE hJob;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
-
-  PreviousMode = ExGetPreviousMode();
-
-  /* check for valid buffers */
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      /* probe with 32bit alignment */
-      ProbeForWrite(JobHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-    
-    if(!NT_SUCCESS(Status))
+    KPROCESSOR_MODE PreviousMode;
+    HANDLE hJob;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    PreviousMode = ExGetPreviousMode();
+
+    /* check for valid buffers */
+    if(PreviousMode == UserMode)
     {
-      return Status;
+        _SEH_TRY
+        {
+            /* probe with 32bit alignment */
+            ProbeForWrite(JobHandle,
+                sizeof(HANDLE),
+                sizeof(ULONG));
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
     }
-  }
-  
-  if(NT_SUCCESS(Status))
-  {
-    Status = ObOpenObjectByName(ObjectAttributes,
-                                PsJobType,
-                                NULL,
-                                PreviousMode,
-                                DesiredAccess,
-                                NULL,
-                                &hJob);
+
     if(NT_SUCCESS(Status))
     {
-      _SEH_TRY
-      {
-        *JobHandle = hJob;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
+        Status = ObOpenObjectByName(ObjectAttributes,
+            PsJobType,
+            NULL,
+            PreviousMode,
+            DesiredAccess,
+            NULL,
+            &hJob);
+        if(NT_SUCCESS(Status))
+        {
+            _SEH_TRY
+            {
+                *JobHandle = hJob;
+            }
+            _SEH_HANDLE
+            {
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+        }
     }
-  }
-  
-  return Status;
+
+    return Status;
 }
 
 
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
-NtQueryInformationJobObject(HANDLE JobHandle,
-                            JOBOBJECTINFOCLASS JobInformationClass,
-                            PVOID JobInformation,
-                            ULONG JobInformationLength,
-                            PULONG ReturnLength)
+NTSTATUS
+STDCALL
+NtQueryInformationJobObject (
+    HANDLE JobHandle,
+    JOBOBJECTINFOCLASS JobInformationClass,
+    PVOID JobInformation,
+    ULONG JobInformationLength,
+    PULONG ReturnLength )
 {
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
-NtSetInformationJobObject(HANDLE JobHandle,
-                          JOBOBJECTINFOCLASS JobInformationClass,
-                          PVOID JobInformation,
-                          ULONG JobInformationLength)
+NTSTATUS
+STDCALL
+NtSetInformationJobObject (
+    HANDLE JobHandle,
+    JOBOBJECTINFOCLASS JobInformationClass,
+    PVOID JobInformation,
+    ULONG JobInformationLength)
 {
-  UNIMPLEMENTED;
-  return STATUS_NOT_IMPLEMENTED;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 
 /*
  * @unimplemented
  */
-NTSTATUS 
-STDCALL 
-NtTerminateJobObject(HANDLE JobHandle,
-                     NTSTATUS ExitStatus)
+NTSTATUS
+STDCALL
+NtTerminateJobObject (
+    HANDLE JobHandle,
+    NTSTATUS ExitStatus )
 {
-  KPROCESSOR_MODE PreviousMode;
-  PEJOB Job;
-  NTSTATUS Status;
-  
-  PAGED_CODE();
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  Status = ObReferenceObjectByHandle(JobHandle,
-                                     JOB_OBJECT_TERMINATE,
-                                     PsJobType,
-                                     PreviousMode,
-                                     (PVOID*)&Job,
-                                     NULL);
-  if(NT_SUCCESS(Status))
-  {
-    Status = PspTerminateJobObject(Job,
-                                   PreviousMode,
-                                   ExitStatus);
-    ObDereferenceObject(Job);
-  }
-  
-  return Status;
+    KPROCESSOR_MODE PreviousMode;
+    PEJOB Job;
+    NTSTATUS Status;
+
+    PAGED_CODE();
+
+    PreviousMode = ExGetPreviousMode();
+
+    Status = ObReferenceObjectByHandle(
+        JobHandle,
+        JOB_OBJECT_TERMINATE,
+        PsJobType,
+        PreviousMode,
+        (PVOID*)&Job,
+        NULL);
+    if(NT_SUCCESS(Status))
+    {
+        Status = PspTerminateJobObject(
+            Job,
+            PreviousMode,
+            ExitStatus);
+        ObDereferenceObject(Job);
+    }
+
+    return Status;
 }
 
 
@@ -496,11 +516,11 @@ NtTerminateJobObject(HANDLE JobHandle,
  * @implemented
  */
 PVOID
-STDCALL 
-PsGetJobLock(PEJOB Job)
+STDCALL
+PsGetJobLock ( PEJOB Job )
 {
-  ASSERT(Job);
-  return (PVOID)&Job->JobLock;
+    ASSERT(Job);
+    return (PVOID)&Job->JobLock;
 }
 
 
@@ -509,10 +529,10 @@ PsGetJobLock(PEJOB Job)
  */
 PVOID
 STDCALL
-PsGetJobSessionId(PEJOB Job)
+PsGetJobSessionId ( PEJOB Job )
 {
-  ASSERT(Job);
-  return (PVOID)Job->SessionId;
+    ASSERT(Job);
+    return (PVOID)Job->SessionId;
 }
 
 
@@ -521,10 +541,10 @@ PsGetJobSessionId(PEJOB Job)
  */
 ULONG
 STDCALL
-PsGetJobUIRestrictionsClass(PEJOB Job)
+PsGetJobUIRestrictionsClass ( PEJOB Job )
 {
-  ASSERT(Job);
-  return Job->UIRestrictionsClass;
+    ASSERT(Job);
+    return Job->UIRestrictionsClass;
 }
 
 
@@ -533,12 +553,13 @@ PsGetJobUIRestrictionsClass(PEJOB Job)
  */
 VOID
 STDCALL
-PsSetJobUIRestrictionsClass(PEJOB Job,
-                            ULONG UIRestrictionsClass)
+PsSetJobUIRestrictionsClass (
+    PEJOB Job,
+    ULONG UIRestrictionsClass)
 {
-  ASSERT(Job);
-  InterlockedExchangeUL(&Job->UIRestrictionsClass, UIRestrictionsClass);
-  /* FIXME - walk through the job process list and update the restrictions? */
+    ASSERT(Job);
+    InterlockedExchangeUL(&Job->UIRestrictionsClass, UIRestrictionsClass);
+    /* FIXME - walk through the job process list and update the restrictions? */
 }
 
 /* EOF */
index acd9271..cda7b57 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ps/kill.c
- * PURPOSE:         Terminating a thread
+ * PURPOSE:         Thread Termination and Reaping
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 #include <internal/debug.h>
 
 /* GLOBALS *******************************************************************/
-
-VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
-NTSTATUS STDCALL NtCallTerminatePorts(PETHREAD Thread);
-
+      
 #define TAG_TERMINATE_APC   TAG('T', 'A', 'P', 'C')
 
-LIST_ENTRY ThreadsToReapHead;
-
-#define TERMINATE_PROC 0x1
-#define TERMINATE_APC  0x2
+PETHREAD PspReaperList = NULL;
+WORK_QUEUE_ITEM PspReaperWorkItem;
+BOOLEAN PspReaping = FALSE;
+extern LIST_ENTRY PsActiveProcessHead;
+extern FAST_MUTEX PspActiveProcessMutex;
 
 /* FUNCTIONS *****************************************************************/
 
+STDCALL
 VOID
-PsInitializeThreadReaper(VOID)
+PspReapRoutine(PVOID Context)
 {
-  InitializeListHead(&ThreadsToReapHead);
+    KIRQL OldIrql;
+    PETHREAD Thread, NewThread;
+    /* Acquire lock */
+    DPRINT("Evil reaper running!!\n");
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Get the first Thread Entry */
+    Thread = PspReaperList;
+    PspReaperList = NULL;
+    DPRINT("PspReaperList: %x\n", Thread);
+    
+    /* Check to see if the list is empty */
+    do {
+        
+        /* Unlock the Dispatcher */
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        
+        /* Is there a thread on the list? */
+        while (Thread) {
+            
+            /* Get the next Thread */
+            DPRINT("Thread: %x\n", Thread);
+            DPRINT("Thread: %x\n", Thread->ReaperLink);
+            NewThread = Thread->ReaperLink;
+            
+            /* Remove reference to current thread */
+            ObDereferenceObject(Thread);
+        
+            /* Move to next Thread */
+            Thread = NewThread;
+        }
+        
+        /* No more linked threads... Reacquire the Lock */
+        OldIrql = KeAcquireDispatcherDatabaseLock();
+        
+        /* Now try to get a new thread from the list */
+        Thread = PspReaperList;
+        PspReaperList = NULL;
+        DPRINT("PspReaperList: %x\n", Thread);
+        
+        /* Loop again if there is a new thread */
+    } while (Thread);
+    
+    PspReaping = FALSE;
+    DPRINT("Done reaping\n");
+    KeReleaseDispatcherDatabaseLock(OldIrql);
 }
 
 VOID
-PsReapThreads(VOID)
+STDCALL
+PspTerminateProcessThreads(PEPROCESS Process,
+                           NTSTATUS ExitStatus)
 {
-  KIRQL oldlvl;
-  PETHREAD Thread;
-  PLIST_ENTRY ListEntry;
-
-  oldlvl = KeAcquireDispatcherDatabaseLock();
-  while((ListEntry = RemoveHeadList(&ThreadsToReapHead)) != &ThreadsToReapHead)
-  {
-    PiNrThreadsAwaitingReaping--;
-    KeReleaseDispatcherDatabaseLock(oldlvl);
-    Thread = CONTAINING_RECORD(ListEntry, ETHREAD, TerminationPortList);
-
-    ObDereferenceObject(Thread);
-    oldlvl = KeAcquireDispatcherDatabaseLock();
-  }
-  KeReleaseDispatcherDatabaseLock(oldlvl);
+    PLIST_ENTRY CurrentEntry;
+    PETHREAD Thread, CurrentThread = PsGetCurrentThread();
+   
+    CurrentEntry = Process->ThreadListHead.Flink;
+    while (CurrentEntry != &Process->ThreadListHead) {
+       
+        /* Get the Current Thread */
+        Thread = CONTAINING_RECORD(CurrentEntry, ETHREAD, ThreadListEntry);
+        
+        /* Move to the Next Thread */
+        CurrentEntry = CurrentEntry->Flink;
+        
+        /* Make sure it's not the one we're in */
+        if (Thread != CurrentThread) {
+        
+            /* Make sure it didn't already terminate */
+            if (!Thread->HasTerminated) {
+
+                Thread->HasTerminated = TRUE;
+                
+                /* Terminate it by APC */
+                PspTerminateThreadByPointer(Thread, ExitStatus);
+            }
+        }
+    }
 }
 
-VOID
-PsQueueThreadReap(PETHREAD Thread)
+VOID 
+STDCALL 
+PspDeleteProcess(PVOID ObjectBody)
 {
-  InsertTailList(&ThreadsToReapHead, &Thread->TerminationPortList);
-  PiNrThreadsAwaitingReaping++;
+    PEPROCESS Process = (PEPROCESS)ObjectBody;
+
+    DPRINT("PiDeleteProcess(ObjectBody %x)\n",Process);
+
+    /* Delete the CID Handle */   
+    if(Process->UniqueProcessId != NULL) {
+    
+        PsDeleteCidHandle(Process->UniqueProcessId, PsProcessType);
+    }
+    
+    /* KDB hook */
+    KDB_DELETEPROCESS_HOOK(Process);
+    
+    /* Dereference the Token and release Memory Information */
+    ObDereferenceObject(Process->Token);
+    MmReleaseMmInfo(Process);
+    /* Delete the W32PROCESS structure if there's one associated */
+    if(Process->Win32Process != NULL) ExFreePool(Process->Win32Process);
 }
 
-VOID
-PiTerminateProcessThreads(PEPROCESS Process,
-                         NTSTATUS ExitStatus)
+VOID 
+STDCALL
+PspDeleteThread(PVOID ObjectBody)
 {
-   KIRQL oldlvl;
-   PLIST_ENTRY current_entry;
-   PETHREAD current, CurrentThread = PsGetCurrentThread();
-   
-   DPRINT("PiTerminateProcessThreads(Process %x, ExitStatus %x)\n",
-         Process, ExitStatus);
-         
-   oldlvl = KeAcquireDispatcherDatabaseLock();
-   
-   current_entry = Process->ThreadListHead.Flink;
-   while (current_entry != &Process->ThreadListHead)
-     {
-       current = CONTAINING_RECORD(current_entry, ETHREAD,
-                                   ThreadListEntry);
-       if (current != CurrentThread && current->HasTerminated == 0)
-         {
-            DPRINT("Terminating %x, current thread: %x, "
-                   "thread's process: %x\n", current, PsGetCurrentThread(), 
-                   current->ThreadsProcess);
-             KeReleaseDispatcherDatabaseLock(oldlvl);
-            PsTerminateOtherThread(current, ExitStatus);
-             oldlvl = KeAcquireDispatcherDatabaseLock();
-            current_entry = Process->ThreadListHead.Flink;
-         }
-       else
-         {
-            current_entry = current_entry->Flink;
-         }
-     }
-   KeReleaseDispatcherDatabaseLock(oldlvl);
-   DPRINT("Finished PiTerminateProcessThreads()\n");
-}
+    PETHREAD Thread = (PETHREAD)ObjectBody;
+    PEPROCESS Process = Thread->ThreadsProcess;
 
-VOID
-PsTerminateCurrentThread(NTSTATUS ExitStatus)
+    DPRINT("PiDeleteThread(ObjectBody 0x%x, process 0x%x)\n",ObjectBody, Thread->ThreadsProcess);
+
+    /* Deassociate the Process */
+    Thread->ThreadsProcess = NULL;
+
+    /* Delete the CID Handle */
+    if(Thread->Cid.UniqueThread != NULL) {
+        
+        PsDeleteCidHandle(Thread->Cid.UniqueThread, PsThreadType);
+    }
+  
+    /* Free the W32THREAD structure if present */
+    if(Thread->Tcb.Win32Thread != NULL) ExFreePool (Thread->Tcb.Win32Thread);
+
+    /* Release the Thread */
+    KeReleaseThread(ETHREAD_TO_KTHREAD(Thread)); 
+    
+    /* Dereference the Process */
+    ObDereferenceObject(Process);
+}
+              
 /*
  * FUNCTION: Terminates the current thread
+ * See "Windows Internals" - Chapter 13, Page 50-53
  */
+VOID
+STDCALL
+PspExitThread(NTSTATUS ExitStatus)
 {
-   KIRQL oldIrql;
-   PETHREAD CurrentThread;
-   PLIST_ENTRY current_entry;
-   PKMUTANT Mutant;
-   BOOLEAN Last;
-   PEPROCESS CurrentProcess;
-   SIZE_T Length = PAGE_SIZE;
-   PVOID TebBlock;
-
-   DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus);
-
-   CurrentThread = PsGetCurrentThread();
-
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-   if (CurrentThread->HasTerminated & TERMINATE_PROC)
-   {
-      KeReleaseDispatcherDatabaseLock(oldIrql);
-      return;
-   }
-   CurrentThread->HasTerminated |= TERMINATE_PROC;
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-
-   KeLowerIrql(PASSIVE_LEVEL);
-
-   CurrentProcess = CurrentThread->ThreadsProcess;
-
-   /* Can't terminate a thread if it attached another process */
-   if (AttachedApcEnvironment == CurrentThread->Tcb.ApcStateIndex)
-     {
+    PETHREAD CurrentThread;
+    BOOLEAN Last;
+    PEPROCESS CurrentProcess;
+    SIZE_T Length = PAGE_SIZE;
+    PVOID TebBlock;
+    PTERMINATION_PORT TerminationPort;
+
+    DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
+
+    /* Get the Current Thread and Process */
+    CurrentThread = PsGetCurrentThread();
+    CurrentProcess = CurrentThread->ThreadsProcess;
+    
+    /* Set the Exit Status and Exit Time */
+    CurrentThread->ExitStatus = ExitStatus;
+    KeQuerySystemTime(&CurrentThread->ExitTime);
+
+    /* Can't terminate a thread if it attached another process */
+    if (KeIsAttachedProcess()) {
+        
         KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT, (ULONG) CurrentProcess,
                      (ULONG) CurrentThread->Tcb.ApcState.Process,
                      (ULONG) CurrentThread->Tcb.ApcStateIndex,
                      (ULONG) CurrentThread);
-     }
+    }
+    
+    /* Lower to Passive Level */
+    KeLowerIrql(PASSIVE_LEVEL);
 
-   KeCancelTimer(&CurrentThread->Tcb.Timer);
+    /* Lock the Process before we modify its thread entries */
+    PsLockProcess(CurrentProcess, FALSE);
+    
+    /* wake up the thread so we don't deadlock on PsLockProcess */
+    KeForceResumeThread(&CurrentThread->Tcb);
+    
+    /* Run Thread Notify Routines before we desintegrate the thread */
+    PspRunCreateThreadNotifyRoutines(CurrentThread, FALSE);
 
-   oldIrql = KeAcquireDispatcherDatabaseLock();
+    /* Remove the thread from the thread list of its process */
+    RemoveEntryList(&CurrentThread->ThreadListEntry);
+    Last = IsListEmpty(&CurrentProcess->ThreadListHead);
+    
+    /* Set the last Thread Exit Status */
+    CurrentProcess->LastThreadExitStatus = ExitStatus;
+    
+    if (Last) {
 
-   DPRINT("terminating %x\n",CurrentThread);
+       /* Save the Exit Time if not already done by NtTerminateProcess. This
+          happens when the last thread just terminates without explicitly
+          terminating the process. */
+       CurrentProcess->ExitTime = CurrentThread->ExitTime;
+    }
+    
+    /* Check if the process has a debug port */
+    if (CurrentProcess->DebugPort) {
+    
+        /* Notify the Debug API. TODO */
+        //Last ? DbgkExitProcess(ExitStatus) : DbgkExitThread(ExitStatus);
+    }
+    
+    /* Process the Termination Ports */  
+    TerminationPort = CurrentThread->TerminationPort;
+    DPRINT("TerminationPort: %p\n", TerminationPort);
+    while (TerminationPort) {
+        
+        /* Send the LPC Message */
+        LpcSendTerminationPort(TerminationPort->Port, CurrentThread->CreateTime);
+        
+        /* Free the Port */
+        ExFreePool(TerminationPort);
+        
+        /* Get the next one */
+        TerminationPort = TerminationPort->Next;
+        DPRINT("TerminationPort: %p\n", TerminationPort);
+    }
+      
+    /* Rundown Win32 Structures */
+    PsTerminateWin32Thread(CurrentThread);
+    if (Last) PsTerminateWin32Process(CurrentProcess);
+   
+    /* Rundown Registry Notifications. TODO (refers to NtChangeNotify, not Cm callbacks) */
+    //CmNotifyRunDown(CurrentThread);
+    
+    /* Free the TEB */
+    if(CurrentThread->Tcb.Teb) {
 
-   CurrentThread->ExitStatus = ExitStatus;
-   KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime);
+        DPRINT("Decommit teb at %p\n", CurrentThread->Tcb.Teb);
+        TebBlock = MM_ROUND_DOWN(CurrentThread->Tcb.Teb, MM_VIRTMEM_GRANULARITY);
 
-   /* If the ProcessoR Control Block's NpxThread points to the current thread
-    * unset it.
-    */
-   InterlockedCompareExchangePointer(&KeGetCurrentKPCR()->PrcbData.NpxThread,
-                                     NULL, ETHREAD_TO_KTHREAD(CurrentThread));
+        ZwFreeVirtualMemory(NtCurrentProcess(),
+                           (PVOID *)&CurrentThread->Tcb.Teb,
+                           &Length,
+                           MEM_DECOMMIT);
 
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-   PsLockProcess(CurrentProcess, FALSE);
-
-   /* Cancel I/O for the thread. */
-   IoCancelThreadIo(CurrentThread);
-
-   /* Remove the thread from the thread list of its process */
-   RemoveEntryList(&CurrentThread->ThreadListEntry);
-   Last = IsListEmpty(&CurrentProcess->ThreadListHead);
-   PsUnlockProcess(CurrentProcess);
-
-   /* Notify subsystems of the thread termination */
-   PspRunCreateThreadNotifyRoutines(CurrentThread, FALSE);
-   PsTerminateWin32Thread(CurrentThread);
-
-   /* Free the TEB */
-   if(CurrentThread->Tcb.Teb)
-   {
-     DPRINT("Decommit teb at %p\n", CurrentThread->Tcb.Teb);
-     ExAcquireFastMutex(&CurrentProcess->TebLock);
-     TebBlock = MM_ROUND_DOWN(CurrentThread->Tcb.Teb, MM_VIRTMEM_GRANULARITY);
-     ZwFreeVirtualMemory(NtCurrentProcess(),
-                         (PVOID *)&CurrentThread->Tcb.Teb,
-                         &Length,
-                         MEM_DECOMMIT);
-     DPRINT("teb %p, TebBlock %p\n", CurrentThread->Tcb.Teb, TebBlock);
-     if (TebBlock != CurrentProcess->TebBlock ||
-         CurrentProcess->TebBlock == CurrentProcess->TebLastAllocated)
-       {
-         MmLockAddressSpace(&CurrentProcess->AddressSpace);
-         MmReleaseMemoryAreaIfDecommitted(CurrentProcess, &CurrentProcess->AddressSpace, TebBlock);
-         MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
-       }
-     CurrentThread->Tcb.Teb = NULL;
-     ExReleaseFastMutex(&CurrentProcess->TebLock);
-   }
-
-   /* abandon all owned mutants */
-   current_entry = CurrentThread->Tcb.MutantListHead.Flink;
-   while (current_entry != &CurrentThread->Tcb.MutantListHead)
-     {
-       Mutant = CONTAINING_RECORD(current_entry, KMUTANT,
-                                  MutantListEntry);
-       KeReleaseMutant(Mutant,
-                       MUTANT_INCREMENT,
-                       TRUE,
-                       FALSE);
-       current_entry = CurrentThread->Tcb.MutantListHead.Flink;
-     }
-
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-   CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
-   KiDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader, IO_NO_INCREMENT);
-   KeReleaseDispatcherDatabaseLock (oldIrql);
-
-   /* The last thread shall close the door on exit */
-   if(Last)
-   {
-    /* save the last thread exit status */
-    CurrentProcess->LastThreadExitStatus = ExitStatus;
-    
-    PspRunCreateProcessNotifyRoutines(CurrentProcess, FALSE);
-    PsTerminateWin32Process(CurrentProcess);
-    PiTerminateProcess(CurrentProcess, ExitStatus);
-   }
+        DPRINT("teb %p, TebBlock %p\n", CurrentThread->Tcb.Teb, TebBlock);
 
-   oldIrql = KeAcquireDispatcherDatabaseLock();
+        if (TebBlock != CurrentProcess->TebBlock ||
+            CurrentProcess->TebBlock == CurrentProcess->TebLastAllocated) {
 
-#ifdef _ENABLE_THRDEVTPAIR
-   ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */
-#endif /* _ENABLE_THRDEVTPAIR */
+            MmLockAddressSpace(&CurrentProcess->AddressSpace);
+            MmReleaseMemoryAreaIfDecommitted(CurrentProcess, &CurrentProcess->AddressSpace, TebBlock);
+            MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
+        }
 
-   ASSERT(CurrentThread->Tcb.WaitBlockList == NULL);
+        CurrentThread->Tcb.Teb = NULL;
+    }
    
-   PsDispatchThreadNoLock(THREAD_STATE_TERMINATED_1);
-   DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread());
-   KEBUGCHECK(0);
-}
+    /* The last Thread shuts down the Process */
+    if (Last) PspExitProcess(CurrentProcess);
+    
+    /* Unlock the Process */
+    PsUnlockProcess(CurrentProcess);
+    
+    /* Cancel I/O for the thread. */
+    IoCancelThreadIo(CurrentThread);
+    
+    /* Rundown Timers */
+    ExTimerRundown();
+    KeCancelTimer(&CurrentThread->Tcb.Timer);
+    
+    /* If the Processor Control Block's NpxThread points to the current thread
+     * unset it.
+     */
+    InterlockedCompareExchangePointer(&KeGetCurrentPrcb()->NpxThread,
+                                      NULL,
+                                      (PKPROCESS)CurrentThread);
+    
+    /* Rundown Mutexes */
+    KeRundownThread();
 
-VOID STDCALL
-PiTerminateThreadRundownRoutine(PKAPC Apc)
-{
-  ExFreePool(Apc);
+    /* Terminate the Thread from the Scheduler */
+    KeTerminateThread(0);
+    DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread());
+    KEBUGCHECK(0);
 }
 
-VOID STDCALL
-PiTerminateThreadKernelRoutine(PKAPC Apc,
-                              PKNORMAL_ROUTINE* NormalRoutine,
-                              PVOID* NormalContext,
-                              PVOID* SystemArgument1,
-                              PVOID* SystemArguemnt2)
+VOID 
+STDCALL
+PsExitSpecialApc(PKAPC Apc,
+                 PKNORMAL_ROUTINE* NormalRoutine,
+                 PVOID* NormalContext,
+                 PVOID* SystemArgument1,
+                 PVOID* SystemArguemnt2)
 {
-  ExFreePool(Apc);
+    NTSTATUS ExitStatus = (NTSTATUS)Apc->NormalContext;
+    
+    DPRINT("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n", PsGetCurrentThread(), PsGetCurrentProcess());
+    
+    /* Free the APC */
+    ExFreePool(Apc);
+    
+    /* Terminate the Thread */
+    PspExitThread(ExitStatus);
+    
+    /* we should never reach this point! */
+    KEBUGCHECK(0);
 }
 
-VOID STDCALL
-PiTerminateThreadNormalRoutine(PVOID NormalContext,
-                            PVOID SystemArgument1,
-                            PVOID SystemArgument2)
+VOID 
+STDCALL
+PspExitNormalApc(PVOID NormalContext,
+                 PVOID SystemArgument1,
+                 PVOID SystemArgument2)
 {
-  PsTerminateCurrentThread((NTSTATUS)SystemArgument1);
+    /* Not fully supported yet... must work out some issues that 
+     * I don't understand yet -- Alex 
+     */
+    DPRINT1("APC2\n");
+    PspExitThread((NTSTATUS)NormalContext);
+    
+    /* we should never reach this point! */
+    KEBUGCHECK(0);
 }
 
-VOID
-PsTerminateOtherThread(PETHREAD Thread,
-                      NTSTATUS ExitStatus)
 /*
- * FUNCTION: Terminate a thread when calling from another thread's context
- * NOTES: This function must be called with PiThreadLock held
+ * See "Windows Internals" - Chapter 13, Page 49
  */
+VOID
+STDCALL
+PspTerminateThreadByPointer(PETHREAD Thread,
+                            NTSTATUS ExitStatus)
 {
-  PKAPC Apc;
-  KIRQL OldIrql;
-
-  DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
-        Thread, ExitStatus);
-
-  OldIrql = KeAcquireDispatcherDatabaseLock();
-  if (Thread->HasTerminated & TERMINATE_APC)
-  {
-     KeReleaseDispatcherDatabaseLock (OldIrql);
-     return;
-  }
-  Thread->HasTerminated |= TERMINATE_APC;
-  KeReleaseDispatcherDatabaseLock (OldIrql);
-  Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
-  KeInitializeApc(Apc,
-                 &Thread->Tcb,
-                 OriginalApcEnvironment,
-                 PiTerminateThreadKernelRoutine,
-                 PiTerminateThreadRundownRoutine,
-                 PiTerminateThreadNormalRoutine,
-                 KernelMode,
-                 NULL);
-  KeInsertQueueApc(Apc,
-                  (PVOID)ExitStatus,
-                  NULL,
-                  IO_NO_INCREMENT);
-
-  OldIrql = KeAcquireDispatcherDatabaseLock();          
-  if (THREAD_STATE_BLOCKED == Thread->Tcb.State && UserMode == Thread->Tcb.WaitMode)
-    {
-      DPRINT("Unblocking thread\n");
-      KiAbortWaitThread((PKTHREAD)Thread, STATUS_THREAD_IS_TERMINATING);
+    PKAPC Apc;  
+    
+    DPRINT("PspTerminatedThreadByPointer(Thread %x, ExitStatus %x)\n",
+            Thread, ExitStatus);
+    
+    /* Check if we are already in the right context */
+    if (PsGetCurrentThread() == Thread) {
+
+        /* Directly terminate the thread */
+        PspExitThread(ExitStatus);
+
+        /* we should never reach this point! */
+        KEBUGCHECK(0);
     }
-  KeReleaseDispatcherDatabaseLock(OldIrql); 
+    
+    /* Allocate the APC */
+    Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
+    
+    /* Initialize a Kernel Mode APC to Kill the Thread */
+    KeInitializeApc(Apc,
+                    &Thread->Tcb,
+                    OriginalApcEnvironment,
+                    PsExitSpecialApc,
+                    NULL,
+                    PspExitNormalApc,
+                    KernelMode,
+                    (PVOID)ExitStatus);
+    
+    /* Insert it into the APC Queue */
+    KeInsertQueueApc(Apc,
+                     Apc,
+                     NULL,
+                     2);
+    
+    /* Forcefully resume the thread */
+    KeForceResumeThread(&Thread->Tcb);
 }
-
-NTSTATUS STDCALL
-PiTerminateProcess(PEPROCESS Process,
-                  NTSTATUS ExitStatus)
+   
+NTSTATUS 
+STDCALL
+PspExitProcess(PEPROCESS Process)
 {
-   KIRQL OldIrql;
-   PEPROCESS CurrentProcess;
+    DPRINT("PspExitProcess 0x%x\n", Process);
+           
+    PspRunCreateProcessNotifyRoutines(Process, FALSE);
+           
+    /* Remove it from the Active List */
+    ExAcquireFastMutex(&PspActiveProcessMutex);
+    RemoveEntryList(&Process->ProcessListEntry);
+    ExReleaseFastMutex(&PspActiveProcessMutex);
+    
+    /* close all handles associated with our process, this needs to be done
+       when the last thread still runs */
+    ObKillProcess(Process);
 
-   DPRINT("PiTerminateProcess(Process %x, ExitStatus %x) PC %d HC %d\n",
-          Process, ExitStatus, ObGetObjectPointerCount(Process),
-          ObGetObjectHandleCount(Process));
-   
-   ObReferenceObject(Process);
-   if (InterlockedExchangeUL(&Process->Pcb.State, 
-                            PROCESS_STATE_TERMINATED) == 
-       PROCESS_STATE_TERMINATED)
-     {
-        ObDereferenceObject(Process);
-       return(STATUS_SUCCESS);
-     }
-   CurrentProcess = PsGetCurrentProcess();
-   if (Process != CurrentProcess)
-   {
-      KeAttachProcess(&Process->Pcb);
-   }
-   ObCloseAllHandles(Process);
-   if (Process != CurrentProcess)
-   {
-      KeDetachProcess();
-   }
-   OldIrql = KeAcquireDispatcherDatabaseLock ();
-   Process->Pcb.DispatcherHeader.SignalState = TRUE;
-   KiDispatcherObjectWake(&Process->Pcb.DispatcherHeader, IO_NO_INCREMENT);
-   KeReleaseDispatcherDatabaseLock (OldIrql);
-   ObDereferenceObject(Process);
-   return(STATUS_SUCCESS);
+    KeSetProcess(&Process->Pcb, IO_NO_INCREMENT);
+    
+    return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL
-NtTerminateProcess(IN  HANDLE          ProcessHandle  OPTIONAL,
-                  IN   NTSTATUS        ExitStatus)
+NTSTATUS 
+STDCALL
+NtTerminateProcess(IN HANDLE ProcessHandle  OPTIONAL,
+                   IN NTSTATUS ExitStatus)
 {
-   NTSTATUS Status;
-   PEPROCESS Process;
-   
-   PAGED_CODE();
+    NTSTATUS Status;
+    PEPROCESS Process;
+    PETHREAD CurrentThread;
+    BOOLEAN KillByHandle;
    
-   DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
-          ProcessHandle, ExitStatus);
+    PAGED_CODE();
    
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                      PROCESS_TERMINATE,
-                                      PsProcessType,
-                                     KeGetCurrentThread()->PreviousMode,
-                                      (PVOID*)&Process,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   Process->ExitStatus = ExitStatus;
-   PiTerminateProcessThreads(Process, ExitStatus);
-   if (PsGetCurrentThread()->ThreadsProcess == Process)
-     {
-       ObDereferenceObject(Process);
-       PsTerminateCurrentThread(ExitStatus);
-       /*
-        * We should never get here!
-        */
-       return(STATUS_SUCCESS);
-     }
-   ObDereferenceObject(Process);
-   return(STATUS_SUCCESS);
-}
+    DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
+            ProcessHandle, ExitStatus);
+    
+    KillByHandle = (ProcessHandle != NULL);
+
+    /* Get the Process Object */
+    Status = ObReferenceObjectByHandle((KillByHandle ? ProcessHandle : NtCurrentProcess()),
+                                       PROCESS_TERMINATE,
+                                       PsProcessType,
+                                       KeGetPreviousMode(),
+                                       (PVOID*)&Process,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) {
+
+        DPRINT1("Invalid handle to Process\n");
+        return(Status);
+    }
+    
+    CurrentThread = PsGetCurrentThread();
+    
+    PsLockProcess(Process, FALSE);
+    
+    if(Process->ExitTime.QuadPart != 0)
+    {
+      PsUnlockProcess(Process);
+      return STATUS_PROCESS_IS_TERMINATING;
+    }
+    
+    /* Terminate all the Process's Threads */
+    PspTerminateProcessThreads(Process, ExitStatus);
+    
+    /* only kill the calling thread if it either passed a process handle or
+       NtCurrentProcess() */
+    if (KillByHandle) {
+
+        /* set the exit time as we're about to release the process lock before
+           we kill ourselves to prevent threads outside of our process trying
+           to kill us */
+        KeQuerySystemTime(&Process->ExitTime);
+
+        /* Only master thread remains... kill it off */
+        if (CurrentThread->ThreadsProcess == Process) {
+
+            /* mark our thread as terminating so attempts to terminate it, when
+               unlocking the process, fail */
+            CurrentThread->HasTerminated = TRUE;
+
+            PsUnlockProcess(Process);
+
+            /* we can safely dereference the process because the current thread
+               holds a reference to it until it gets reaped */
+            ObDereferenceObject(Process);
+
+            /* now the other threads get a chance to terminate, we don't wait but
+               just kill ourselves right now. The process will be run down when the
+               last thread terminates */
 
+            PspExitThread(ExitStatus);
 
-NTSTATUS STDCALL
-NtTerminateThread(IN   HANDLE          ThreadHandle,
-                 IN    NTSTATUS        ExitStatus)
+            /* we should never reach this point! */
+            KEBUGCHECK(0);
+        }
+    }
+
+    /* unlock and dereference the process so the threads can kill themselves */
+    PsUnlockProcess(Process);
+    ObDereferenceObject(Process);
+    
+    return(STATUS_SUCCESS);
+}
+
+NTSTATUS 
+STDCALL
+NtTerminateThread(IN HANDLE ThreadHandle,
+                  IN NTSTATUS ExitStatus)
 {
-   PETHREAD Thread;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
+    PETHREAD Thread;
+    NTSTATUS Status;
    
-   Status = ObReferenceObjectByHandle(ThreadHandle,
-                                     THREAD_TERMINATE,
-                                     PsThreadType,
-                                     KeGetCurrentThread()->PreviousMode,
-                                     (PVOID*)&Thread,
-                                     NULL);
-   if (Status != STATUS_SUCCESS)
-     {
-       return(Status);
-     }
+    PAGED_CODE();
+    
+    /* Get the Thread Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_TERMINATE,
+                                       PsThreadType,
+                                       KeGetPreviousMode(),
+                                       (PVOID*)&Thread,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) {
+        
+        DPRINT1("Could not reference thread object\n");
+        return(Status);
+    }
    
-   if (Thread == PsGetCurrentThread())
-     {
-        /* dereference the thread object before we kill our thread */
+    /* Make sure this is not a system thread */
+    if (PsIsSystemThread(Thread)) {
+    
+        DPRINT1("Trying to Terminate a system thread!\n");
         ObDereferenceObject(Thread);
-        PsTerminateCurrentThread(ExitStatus);
-        /*
-         * We should never get here!
-         */
-     }
-   else
-     {
-       PsTerminateOtherThread(Thread, ExitStatus);
-       ObDereferenceObject(Thread);
-     }
-   return(STATUS_SUCCESS);
-}
+        return STATUS_INVALID_PARAMETER;
+    }
+     
+    /* Check to see if we're running in the same thread */
+    if (Thread != PsGetCurrentThread())  {
+                 
+        /* we need to lock the process to make sure it's not already terminating */
+        PsLockProcess(Thread->ThreadsProcess, FALSE);
+        
+        /* This isn't our thread, terminate it if not already done */
+        if (!Thread->HasTerminated) {
+         
+             Thread->HasTerminated = TRUE;
+             
+             /* Terminate it */
+             PspTerminateThreadByPointer(Thread, ExitStatus);
+        }
+        
+        PsUnlockProcess(Thread->ThreadsProcess);
+        
+        /* Dereference the Thread and return */
+        ObDereferenceObject(Thread);
+        
+    } else {
+
+        Thread->HasTerminated = TRUE;
+        
+        /* it's safe to dereference thread, there's at least the keep-alive
+           reference which will be removed by the thread reaper causing the
+           thread to be finally destroyed */
+        ObDereferenceObject(Thread);
+            
+        /* Terminate him, he's ours */
+        PspExitThread(ExitStatus);
 
+        /* We do never reach this point */
+        KEBUGCHECK(0);
+    }
+    
+    return(STATUS_SUCCESS);
+}
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 PsTerminateSystemThread(NTSTATUS ExitStatus)
-/*
- * FUNCTION: Terminates the current thread
- * ARGUMENTS:
- *         ExitStatus = Status to pass to the creater
- * RETURNS: Doesn't
- */
-{
-   PsTerminateCurrentThread(ExitStatus);
-   return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL
-NtCallTerminatePorts(PETHREAD Thread)
 {
-   KIRQL oldIrql;
-   PLIST_ENTRY current_entry;
-   PEPORT_TERMINATION_REQUEST current;
-   
-   PAGED_CODE();
-   
-   KeAcquireSpinLock(&Thread->ActiveTimerListLock, &oldIrql);
-   while ((current_entry = RemoveHeadList(&Thread->TerminationPortList)) !=
-         &Thread->TerminationPortList);
-     {
-       current = CONTAINING_RECORD(current_entry,
-                                   EPORT_TERMINATION_REQUEST,
-                                   ThreadListEntry);
-       KeReleaseSpinLock(&Thread->ActiveTimerListLock, oldIrql);
-       LpcSendTerminationPort(current->Port, 
-                              Thread->CreateTime);
-       ExFreePool(current);
-       KeAcquireSpinLock(&Thread->ActiveTimerListLock, &oldIrql);
-     }
-   KeReleaseSpinLock(&Thread->ActiveTimerListLock, oldIrql);
-   return(STATUS_SUCCESS);
+    PETHREAD Thread = PsGetCurrentThread();
+    
+    /* Make sure this is a system thread */
+    if (!PsIsSystemThread(Thread)) {
+    
+        DPRINT1("Trying to Terminate a non-system thread!\n");
+        return STATUS_INVALID_PARAMETER;
+    }
+        
+    /* Terminate it for real */
+    PspExitThread(ExitStatus);
+    
+    /* we should never reach this point! */
+    KEBUGCHECK(0);
+    
+    return(STATUS_SUCCESS);
 }
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtRegisterThreadTerminatePort(HANDLE PortHandle)
 {
-   NTSTATUS Status;
-   PEPORT_TERMINATION_REQUEST Request;
-   PEPORT TerminationPort;
-   KIRQL oldIrql;
-   PETHREAD Thread;
+    NTSTATUS Status;
+    PTERMINATION_PORT TerminationPort;
+    PVOID TerminationLpcPort;
+    PETHREAD Thread;
    
-   PAGED_CODE();
+    PAGED_CODE();
+    
+    /* Get the Port */
+    Status = ObReferenceObjectByHandle(PortHandle,
+                                       PORT_ALL_ACCESS,
+                                       LpcPortObjectType,
+                                       KeGetPreviousMode(),
+                                       &TerminationLpcPort,
+                                       NULL);   
+    if (!NT_SUCCESS(Status)) {
+        
+        DPRINT1("Failed to reference Port\n");
+        return(Status);
+    }
    
-   Status = ObReferenceObjectByHandle(PortHandle,
-                                     PORT_ALL_ACCESS,
-                                     LpcPortObjectType,
-                                     KeGetCurrentThread()->PreviousMode,
-                                     (PVOID*)&TerminationPort,
-                                     NULL);   
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
+    /* Allocate the Port and make sure it suceeded */
+    if((TerminationPort = ExAllocatePoolWithTag(NonPagedPool, 
+                                                sizeof(PTERMINATION_PORT), 
+                                                TAG('P', 's', 'T', '=')))) {
+        
+        /* Associate the Port */
+        Thread = PsGetCurrentThread();
+        TerminationPort->Port = TerminationLpcPort;
+        DPRINT("TerminationPort: %p\n", TerminationPort);
+        TerminationPort->Next = Thread->TerminationPort;
+        Thread->TerminationPort = TerminationPort;
+        DPRINT("TerminationPort: %p\n", Thread->TerminationPort);
+
+        /* Return success */
+        return(STATUS_SUCCESS);
    
-   Request = ExAllocatePool(NonPagedPool, sizeof(EPORT_TERMINATION_REQUEST));
-   if(Request != NULL)
-   {
-     Request->Port = TerminationPort;
-     Thread = PsGetCurrentThread();
-     KeAcquireSpinLock(&Thread->ActiveTimerListLock, &oldIrql);
-     InsertTailList(&Thread->TerminationPortList, &Request->ThreadListEntry);
-     KeReleaseSpinLock(&Thread->ActiveTimerListLock, oldIrql);
-
-     return(STATUS_SUCCESS);
-   }
-   else
-   {
-     ObDereferenceObject(TerminationPort);
-     return(STATUS_INSUFFICIENT_RESOURCES);
-   }
+    } else {
+        
+        /* Dereference and Fail */
+        ObDereferenceObject(TerminationPort);
+        return(STATUS_INSUFFICIENT_RESOURCES);
+    }
 }
index ac2f018..6211a6a 100644 (file)
 
 /* GLOBALS ******************************************************************/
 
+VOID INIT_FUNCTION PsInitClientIDManagment(VOID);
+
 PEPROCESS EXPORTED PsInitialSystemProcess = NULL;
+PEPROCESS PsIdleProcess = NULL;
 
 POBJECT_TYPE EXPORTED PsProcessType = NULL;
 
@@ -31,44 +34,6 @@ static GENERIC_MAPPING PiProcessMapping = {STANDARD_RIGHTS_READ | PROCESS_QUERY_
                                           STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
                                           PROCESS_ALL_ACCESS};
 
-static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(PROCESS_BASIC_INFORMATION),     sizeof(ULONG), ICIF_QUERY ),                     /* ProcessBasicInformation */
-  ICI_SQ_SAME( sizeof(QUOTA_LIMITS),                  sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessQuotaLimits */
-  ICI_SQ_SAME( sizeof(IO_COUNTERS),                   sizeof(ULONG), ICIF_QUERY ),                     /* ProcessIoCounters */
-  ICI_SQ_SAME( sizeof(VM_COUNTERS),                   sizeof(ULONG), ICIF_QUERY ),                     /* ProcessVmCounters */
-  ICI_SQ_SAME( sizeof(KERNEL_USER_TIMES),             sizeof(ULONG), ICIF_QUERY ),                     /* ProcessTimes */
-  ICI_SQ_SAME( sizeof(KPRIORITY),                     sizeof(ULONG), ICIF_SET ),                       /* ProcessBasePriority */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_SET ),                       /* ProcessRaisePriority */
-  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessDebugPort */
-  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_SET ),                       /* ProcessExceptionPort */
-  ICI_SQ_SAME( sizeof(PROCESS_ACCESS_TOKEN),          sizeof(ULONG), ICIF_SET ),                       /* ProcessAccessToken */
-  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessLdtInformation */
-  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessLdtSize */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessDefaultHardErrorMode */
-  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessIoPortHandlers */
-  ICI_SQ_SAME( sizeof(POOLED_USAGE_AND_LIMITS),       sizeof(ULONG), ICIF_QUERY ),                     /* ProcessPooledUsageAndLimits */
-  ICI_SQ_SAME( sizeof(PROCESS_WS_WATCH_INFORMATION),  sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessWorkingSetWatch */
-  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessUserModeIOPL */
-  ICI_SQ_SAME( sizeof(BOOLEAN),                       sizeof(ULONG), ICIF_SET ),                       /* ProcessEnableAlignmentFaultFixup */
-  ICI_SQ_SAME( sizeof(PROCESS_PRIORITY_CLASS),        sizeof(USHORT), ICIF_QUERY | ICIF_SET ),         /* ProcessPriorityClass */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessWx86Information */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessHandleCount */
-  ICI_SQ_SAME( sizeof(KAFFINITY),                     sizeof(ULONG), ICIF_SET ),                       /* ProcessAffinityMask */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessPriorityBoost */
-
-  ICI_SQ(/*Q*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Query),                                   /* ProcessDeviceMap */
-         /*S*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Set),
-                                                /*Q*/ sizeof(ULONG),
-                                                /*S*/ sizeof(ULONG),
-                                                                     ICIF_QUERY | ICIF_SET ),
-
-  ICI_SQ_SAME( sizeof(PROCESS_SESSION_INFORMATION),   sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessSessionInformation */
-  ICI_SQ_SAME( sizeof(BOOLEAN),                       sizeof(ULONG), ICIF_SET ),                       /* ProcessForegroundInformation */
-  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessWow64Information */
-  ICI_SQ_SAME( sizeof(UNICODE_STRING),                sizeof(ULONG), ICIF_QUERY | ICIF_SIZE_VARIABLE), /* ProcessImageFileName */
-};
-
 #define MAX_PROCESS_NOTIFY_ROUTINE_COUNT    8
 #define MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT  8
 
@@ -78,26 +43,8 @@ static PLOAD_IMAGE_NOTIFY_ROUTINE
 PiLoadImageNotifyRoutine[MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT];
 
 
-typedef struct
-{
-    WORK_QUEUE_ITEM WorkQueueItem;
-    KEVENT Event;
-    PEPROCESS Process;
-    BOOLEAN IsWorkerQueue;
-} DEL_CONTEXT, *PDEL_CONTEXT;
-
 /* FUNCTIONS *****************************************************************/
 
-VOID
-STDCALL
-PsExitSpecialApc(PKAPC Apc, 
-                PKNORMAL_ROUTINE *NormalRoutine,
-                PVOID *NormalContext,
-                PVOID *SystemArgument1,
-                PVOID *SystemArgument2)
-{
-}
-
 PEPROCESS
 PsGetNextProcess(PEPROCESS OldProcess)
 {
@@ -106,34 +53,36 @@ PsGetNextProcess(PEPROCESS OldProcess)
    
    if (OldProcess == NULL)
      {
-       Status = ObReferenceObjectByPointer(PsInitialSystemProcess,
+       Status = ObReferenceObjectByPointer(PsIdleProcess,
                                           PROCESS_ALL_ACCESS,
                                           PsProcessType,
                                           KernelMode);   
        if (!NT_SUCCESS(Status))
          {
-          CPRINT("PsGetNextProcess(): ObReferenceObjectByPointer failed for PsInitialSystemProcess\n");
+          CPRINT("PsGetNextProcess(): ObReferenceObjectByPointer failed for PsIdleProcess\n");
           KEBUGCHECK(0);
         }
-       return PsInitialSystemProcess;
+       return PsIdleProcess;
      }
    
    ExAcquireFastMutex(&PspActiveProcessMutex);
    NextProcess = OldProcess;
    while (1)
      {
-       if (NextProcess->ProcessListEntry.Blink == &PsActiveProcessHead)
+       PLIST_ENTRY Flink = (NextProcess == PsIdleProcess ? PsActiveProcessHead.Flink :
+                                                           NextProcess->ProcessListEntry.Flink);
+       if (Flink != &PsActiveProcessHead)
          {
-          NextProcess = CONTAINING_RECORD(PsActiveProcessHead.Blink,
-                                          EPROCESS,
-                                          ProcessListEntry);
+           NextProcess = CONTAINING_RECORD(Flink,
+                                          EPROCESS,
+                                          ProcessListEntry);
          }
        else
          {
-          NextProcess = CONTAINING_RECORD(NextProcess->ProcessListEntry.Blink,
-                                          EPROCESS,
-                                          ProcessListEntry);
+           NextProcess = NULL;
+           break;
          }
+
        Status = ObReferenceObjectByPointer(NextProcess,
                                           PROCESS_ALL_ACCESS,
                                           PsProcessType,
@@ -148,8 +97,7 @@ PsGetNextProcess(PEPROCESS OldProcess)
         }
        else if (!NT_SUCCESS(Status))
          {
-          CPRINT("PsGetNextProcess(): ObReferenceObjectByPointer failed\n");
-          KEBUGCHECK(0);
+          continue;
         }
      }
 
@@ -159,126 +107,6 @@ PsGetNextProcess(PEPROCESS OldProcess)
    return(NextProcess);
 }
 
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL 
-NtOpenProcessToken(IN  HANDLE          ProcessHandle,
-                  IN   ACCESS_MASK     DesiredAccess,
-                  OUT  PHANDLE         TokenHandle)
-{
-  return NtOpenProcessTokenEx(ProcessHandle,
-                              DesiredAccess,
-                              0,
-                              TokenHandle);
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtOpenProcessTokenEx(
-    IN HANDLE ProcessHandle,
-    IN ACCESS_MASK DesiredAccess,
-    IN ULONG HandleAttributes,
-    OUT PHANDLE TokenHandle
-    )
-{
-   PACCESS_TOKEN Token;
-   HANDLE hToken;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
-   
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(TokenHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = PsOpenTokenOfProcess(ProcessHandle,
-                                &Token);
-   if(NT_SUCCESS(Status))
-   {
-     Status = ObCreateHandle(PsGetCurrentProcess(),
-                            Token,
-                            DesiredAccess,
-                            FALSE,
-                            &hToken);
-     ObDereferenceObject(Token);
-
-     _SEH_TRY
-     {
-       *TokenHandle = hToken;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
-   
-   return Status;
-}
-
-
-/*
- * @implemented
- */
-PACCESS_TOKEN STDCALL
-PsReferencePrimaryToken(PEPROCESS Process)
-{
-   ObReferenceObjectByPointer(Process->Token,
-                             TOKEN_ALL_ACCESS,
-                             SepTokenObjectType,
-                             KernelMode);
-   return(Process->Token);
-}
-
-
-NTSTATUS
-PsOpenTokenOfProcess(HANDLE ProcessHandle,
-                    PACCESS_TOKEN* Token)
-{
-   PEPROCESS Process;
-   NTSTATUS Status;
-   
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     PROCESS_QUERY_INFORMATION,
-                                     PsProcessType,
-                                     ExGetPreviousMode(),
-                                     (PVOID*)&Process,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     *Token = PsReferencePrimaryToken(Process);
-     ObDereferenceObject(Process);
-   }
-   
-   return Status;
-}
-
-
 VOID 
 PiKillMostProcesses(VOID)
 {
@@ -297,14 +125,13 @@ PiKillMostProcesses(VOID)
        if (current->UniqueProcessId != PsInitialSystemProcess->UniqueProcessId &&
            current->UniqueProcessId != PsGetCurrentProcessId())
          {
-            PiTerminateProcessThreads(current, STATUS_SUCCESS);
+            PspTerminateProcessThreads(current, STATUS_SUCCESS);
          }
      }
    
    ExReleaseFastMutex(&PspActiveProcessMutex);
 }
 
-
 VOID INIT_FUNCTION
 PsInitProcessManagment(VOID)
 {
@@ -330,7 +157,7 @@ PsInitProcessManagment(VOID)
    PsProcessType->Dump = NULL;
    PsProcessType->Open = NULL;
    PsProcessType->Close = NULL;
-   PsProcessType->Delete = PiDeleteProcess;
+   PsProcessType->Delete = PspDeleteProcess;
    PsProcessType->Parse = NULL;
    PsProcessType->Security = NULL;
    PsProcessType->QueryName = NULL;
@@ -348,6 +175,44 @@ PsInitProcessManagment(VOID)
    RtlZeroMemory(PiProcessNotifyRoutine, sizeof(PiProcessNotifyRoutine));
    RtlZeroMemory(PiLoadImageNotifyRoutine, sizeof(PiLoadImageNotifyRoutine));
    
+   /*
+    * Initialize the idle process
+    */
+   Status = ObCreateObject(KernelMode,
+                          PsProcessType,
+                          NULL,
+                          KernelMode,
+                          NULL,
+                          sizeof(EPROCESS),
+                          0,
+                          0,
+                          (PVOID*)&PsIdleProcess);
+   if (!NT_SUCCESS(Status))
+     {
+        DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
+        KEBUGCHECK(0);
+        return;
+     }
+
+   RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
+   
+   PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
+   PsIdleProcess->Pcb.IopmOffset = 0xffff;
+   PsIdleProcess->Pcb.LdtDescriptor[0] = 0;
+   PsIdleProcess->Pcb.LdtDescriptor[1] = 0;
+   PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
+   PsIdleProcess->Pcb.ThreadQuantum = 6;
+   InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
+   InitializeListHead(&PsIdleProcess->ThreadListHead);
+   InitializeListHead(&PsIdleProcess->ProcessListEntry);
+   KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.DispatcherHeader,
+                               ProcessObject,
+                               sizeof(EPROCESS),
+                               FALSE);
+   PsIdleProcess->Pcb.DirectoryTableBase =
+     (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
+   strcpy(PsIdleProcess->ImageFileName, "Idle");
+
    /*
     * Initialize the system process
     */
@@ -362,7 +227,9 @@ PsInitProcessManagment(VOID)
                           (PVOID*)&PsInitialSystemProcess);
    if (!NT_SUCCESS(Status))
      {
-       return;
+        DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
+        KEBUGCHECK(0);
+        return;
      }
    
    /* System threads may run on any processor. */
@@ -374,14 +241,13 @@ PsInitProcessManagment(VOID)
    PsInitialSystemProcess->Pcb.ThreadQuantum = 6;
    InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
    KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.DispatcherHeader,
-                               InternalProcessType,
+                               ProcessObject,
                                sizeof(EPROCESS),
                                FALSE);
    KProcess = &PsInitialSystemProcess->Pcb;
    
    MmInitializeAddressSpace(PsInitialSystemProcess,
                            &PsInitialSystemProcess->AddressSpace);
-   ObCreateHandleTable(NULL,FALSE,PsInitialSystemProcess);
    
    KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
    PsInitialSystemProcess->LockCount = 0;
@@ -400,15 +266,6 @@ PsInitProcessManagment(VOID)
 
    strcpy(PsInitialSystemProcess->ImageFileName, "System");
    
-   Status = PsCreateCidHandle(PsInitialSystemProcess,
-                              PsProcessType,
-                              &PsInitialSystemProcess->UniqueProcessId);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
-     return;
-   }
-   
    PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
    
    InsertHeadList(&PsActiveProcessHead,
@@ -418,80 +275,25 @@ PsInitProcessManagment(VOID)
    SepCreateSystemProcessToken(PsInitialSystemProcess);
 }
 
-VOID STDCALL
-PiDeleteProcessWorker(PVOID pContext)
-{
-  PDEL_CONTEXT Context;
-  PEPROCESS CurrentProcess;
-  PEPROCESS Process;
-
-  Context = (PDEL_CONTEXT)pContext;
-  Process = Context->Process;
-  CurrentProcess = PsGetCurrentProcess();
-
-  DPRINT("PiDeleteProcess(ObjectBody %x)\n",Process);
-
-  if (CurrentProcess != Process)
-    {
-      KeAttachProcess(&Process->Pcb);
-    }
-
-  ExAcquireFastMutex(&PspActiveProcessMutex);
-  RemoveEntryList(&Process->ProcessListEntry);
-  ExReleaseFastMutex(&PspActiveProcessMutex);
-
-  /* KDB hook */
-  KDB_DELETEPROCESS_HOOK(Process);
-
-  ObDereferenceObject(Process->Token);
-  ObDeleteHandleTable(Process);
-
-  if (CurrentProcess != Process)
-    {
-      KeDetachProcess();
-    }
-
-  MmReleaseMmInfo(Process);
-  if (Context->IsWorkerQueue)
-    {
-      KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
-    }
-}
-
-VOID STDCALL 
-PiDeleteProcess(PVOID ObjectBody)
+VOID
+PspPostInitSystemProcess(VOID)
 {
-  DEL_CONTEXT Context;
-
-  Context.Process = (PEPROCESS)ObjectBody;
-
-  if (PsGetCurrentProcess() == Context.Process ||
-      PsGetCurrentThread()->ThreadsProcess == Context.Process)
-    {
-       KEBUGCHECK(0);
-    }
-
-  if (PsGetCurrentThread()->ThreadsProcess == PsGetCurrentProcess())
-    {
-      Context.IsWorkerQueue = FALSE;
-      PiDeleteProcessWorker(&Context);
-    }
-  else
-    {
-      Context.IsWorkerQueue = TRUE;
-      KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
-      ExInitializeWorkItem (&Context.WorkQueueItem, PiDeleteProcessWorker, &Context);
-      ExQueueWorkItem(&Context.WorkQueueItem, HyperCriticalWorkQueue);
-      if (KeReadStateEvent(&Context.Event) == 0)
-        {
-          KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, NULL);
-       }
-    }
-
-  if(((PEPROCESS)ObjectBody)->Win32Process != NULL)
+  NTSTATUS Status;
+  
+  /* this routine is called directly after the exectuive handle tables were
+     initialized. We'll set up the Client ID handle table and assign the system
+     process a PID */
+  PsInitClientIDManagment();
+  
+  ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
+  
+  Status = PsCreateCidHandle(PsInitialSystemProcess,
+                             PsProcessType,
+                             &PsInitialSystemProcess->UniqueProcessId);
+  if(!NT_SUCCESS(Status))
   {
-    /* delete the W32PROCESS structure if there's one associated */
-    ExFreePool (((PEPROCESS)ObjectBody)->Win32Process);
+    DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
+    KEBUGCHECK(0);
   }
 }
 
@@ -823,7 +625,7 @@ exitdereferenceobjects:
    }
 
    KeInitializeDispatcherHeader(&KProcess->DispatcherHeader,
-                               InternalProcessType,
+                               ProcessObject,
                                sizeof(EPROCESS),
                                FALSE);
 
@@ -861,11 +663,10 @@ exitdereferenceobjects:
    Process->Win32WindowStation = (HANDLE)0;
 
    ExAcquireFastMutex(&PspActiveProcessMutex);
-   InsertHeadList(&PsActiveProcessHead, &Process->ProcessListEntry);
+   InsertTailList(&PsActiveProcessHead, &Process->ProcessListEntry);
    InitializeListHead(&Process->ThreadListHead);
    ExReleaseFastMutex(&PspActiveProcessMutex);
 
-   ExInitializeFastMutex(&Process->TebLock);
    Process->Pcb.State = PROCESS_STATE_ACTIVE;
    
    /*
@@ -1304,1050 +1105,6 @@ NtOpenProcess(OUT PHANDLE          ProcessHandle,
        DPRINT("NtOpenProcess() = STATUS_UNSUCCESSFUL\n");
        return(STATUS_UNSUCCESSFUL);
      }
-   return(STATUS_UNSUCCESSFUL);
-}
-
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtQueryInformationProcess(IN  HANDLE ProcessHandle,
-                         IN  PROCESSINFOCLASS ProcessInformationClass,
-                         OUT PVOID ProcessInformation,
-                         IN  ULONG ProcessInformationLength,
-                         OUT PULONG ReturnLength  OPTIONAL)
-{
-   PEPROCESS Process;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
-   
-   DefaultQueryInfoBufferCheck(ProcessInformationClass,
-                               PsProcessInfoClass,
-                               ProcessInformation,
-                               ProcessInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   /*
-    * TODO: Here we should probably check that ProcessInformationLength
-    * bytes indeed are writable at address ProcessInformation.
-    */
-
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     PROCESS_QUERY_INFORMATION,
-                                     PsProcessType,
-                                     PreviousMode,
-                                     (PVOID*)&Process,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   switch (ProcessInformationClass)
-     {
-      case ProcessBasicInformation:
-      {
-        PPROCESS_BASIC_INFORMATION ProcessBasicInformationP =
-         (PPROCESS_BASIC_INFORMATION)ProcessInformation;
-
-        _SEH_TRY
-        {
-         ProcessBasicInformationP->ExitStatus = Process->ExitStatus;
-         ProcessBasicInformationP->PebBaseAddress = Process->Peb;
-         ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
-         ProcessBasicInformationP->UniqueProcessId =
-           Process->UniqueProcessId;
-         ProcessBasicInformationP->InheritedFromUniqueProcessId =
-           Process->InheritedFromUniqueProcessId;
-         ProcessBasicInformationP->BasePriority =
-           Process->Pcb.BasePriority;
-
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(PROCESS_BASIC_INFORMATION);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-       break;
-      }
-
-      case ProcessQuotaLimits:
-      case ProcessIoCounters:
-       Status = STATUS_NOT_IMPLEMENTED;
-       break;
-
-      case ProcessTimes:
-      {
-         PKERNEL_USER_TIMES ProcessTimeP = (PKERNEL_USER_TIMES)ProcessInformation;
-         _SEH_TRY
-         {
-           ProcessTimeP->CreateTime = Process->CreateTime;
-            ProcessTimeP->UserTime.QuadPart = Process->Pcb.UserTime * 100000LL;
-            ProcessTimeP->KernelTime.QuadPart = Process->Pcb.KernelTime * 100000LL;
-           ProcessTimeP->ExitTime = Process->ExitTime;
-
-          if (ReturnLength)
-          {
-            *ReturnLength = sizeof(KERNEL_USER_TIMES);
-          }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-        break;
-      }
-
-      case ProcessDebugPort:
-      {
-        _SEH_TRY
-        {
-          *(PHANDLE)ProcessInformation = (Process->DebugPort != NULL ? (HANDLE)-1 : NULL);
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(HANDLE);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        break;
-      }
-      
-      case ProcessLdtInformation:
-      case ProcessWorkingSetWatch:
-      case ProcessWx86Information:
-       Status = STATUS_NOT_IMPLEMENTED;
-       break;
-
-      case ProcessHandleCount:
-      {
-       ULONG HandleCount = ObpGetHandleCountByHandleTable(&Process->HandleTable);
-         
-       _SEH_TRY
-       {
-          *(PULONG)ProcessInformation = HandleCount;
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(ULONG);
-         }
-       }
-       _SEH_HANDLE
-       {
-          Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-       break;
-      }
-
-      case ProcessSessionInformation:
-      {
-        PPROCESS_SESSION_INFORMATION SessionInfo = (PPROCESS_SESSION_INFORMATION)ProcessInformation;
-
-        _SEH_TRY
-        {
-          SessionInfo->SessionId = Process->SessionId;
-          if (ReturnLength)
-          {
-            *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION);
-          }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        break;
-      }
-      
-      case ProcessWow64Information:
-        DPRINT1("We currently don't support the ProcessWow64Information information class!\n");
-       Status = STATUS_NOT_IMPLEMENTED;
-       break;
-
-      case ProcessVmCounters:
-      {
-       PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation;
-         
-       _SEH_TRY
-       {
-         pOut->PeakVirtualSize            = Process->PeakVirtualSize;
-         /*
-          * Here we should probably use VirtualSize.LowPart, but due to
-          * incompatibilities in current headers (no unnamed union),
-          * I opted for cast.
-          */
-         pOut->VirtualSize                = (ULONG)Process->VirtualSize.QuadPart;
-         pOut->PageFaultCount             = Process->Vm.PageFaultCount;
-         pOut->PeakWorkingSetSize         = Process->Vm.PeakWorkingSetSize;
-         pOut->WorkingSetSize             = Process->Vm.WorkingSetSize;
-         pOut->QuotaPeakPagedPoolUsage    = Process->QuotaPeakPoolUsage[0]; // TODO: Verify!
-         pOut->QuotaPagedPoolUsage        = Process->QuotaPoolUsage[0];     // TODO: Verify!
-         pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeakPoolUsage[1]; // TODO: Verify!
-         pOut->QuotaNonPagedPoolUsage     = Process->QuotaPoolUsage[1];     // TODO: Verify!
-         pOut->PagefileUsage              = Process->PagefileUsage;
-         pOut->PeakPagefileUsage          = Process->PeakPagefileUsage;
-
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(VM_COUNTERS);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-       break;
-      }
-
-      case ProcessDefaultHardErrorMode:
-      {
-       PULONG HardErrMode = (PULONG)ProcessInformation;
-       _SEH_TRY
-       {
-         *HardErrMode = Process->DefaultHardErrorProcessing;
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(ULONG);
-         }
-       }
-       _SEH_HANDLE
-       {
-          Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-       break;
-      }
-
-      case ProcessPriorityBoost:
-      {
-       PULONG BoostEnabled = (PULONG)ProcessInformation;
-         
-       _SEH_TRY
-       {
-         *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE;
-
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(ULONG);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-       break;
-      }
-
-      case ProcessDeviceMap:
-      {
-        PROCESS_DEVICEMAP_INFORMATION DeviceMap;
-          
-        ObQueryDeviceMapInformation(Process, &DeviceMap);
-
-        _SEH_TRY
-        {
-          *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap;
-         if (ReturnLength)
-          {
-           *ReturnLength = sizeof(PROCESS_DEVICEMAP_INFORMATION);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-       break;
-      }
-
-      case ProcessPriorityClass:
-      {
-       PUSHORT Priority = (PUSHORT)ProcessInformation;
-
-       _SEH_TRY
-       {
-         *Priority = Process->PriorityClass;
-
-         if (ReturnLength)
-         {
-           *ReturnLength = sizeof(USHORT);
-         }
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-       break;
-      }
-
-      case ProcessImageFileName:
-      {
-        /*
-         * We DO NOT return the file name stored in the EPROCESS structure.
-         * Propably if we can't find a PEB or ProcessParameters structure for the
-         * process!
-         */
-        if(Process->Peb != NULL)
-        {
-          PRTL_USER_PROCESS_PARAMETERS ProcParams = NULL;
-          UNICODE_STRING LocalDest;
-          BOOLEAN Attached;
-          ULONG ImagePathLen = 0;
-          PUNICODE_STRING DstPath = (PUNICODE_STRING)ProcessInformation;
-
-          /* we need to attach to the process to make sure we're in the right context! */
-          Attached = Process != PsGetCurrentProcess();
-
-          if(Attached)
-            KeAttachProcess(&Process->Pcb);
-          
-          _SEH_TRY
-          {
-            ProcParams = Process->Peb->ProcessParameters;
-            ImagePathLen = ProcParams->ImagePathName.Length;
-          }
-          _SEH_HANDLE
-          {
-            Status = _SEH_GetExceptionCode();
-          }
-          _SEH_END;
-          
-          if(NT_SUCCESS(Status))
-          {
-            if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
-            {
-              Status = STATUS_INFO_LENGTH_MISMATCH;
-            }
-            else
-            {
-              PWSTR StrSource = NULL;
-
-              /* create a DstPath structure on the stack */
-              _SEH_TRY
-              {
-                LocalDest.Length = ImagePathLen;
-                LocalDest.MaximumLength = ImagePathLen + sizeof(WCHAR);
-                LocalDest.Buffer = (PWSTR)(DstPath + 1);
-
-                /* save a copy of the pointer to the source buffer */
-                StrSource = ProcParams->ImagePathName.Buffer;
-              }
-              _SEH_HANDLE
-              {
-                Status = _SEH_GetExceptionCode();
-              }
-              _SEH_END;
-
-              if(NT_SUCCESS(Status))
-              {
-                /* now, let's allocate some anonymous memory to copy the string to.
-                   we can't just copy it to the buffer the caller pointed as it might
-                   be user memory in another context */
-                PWSTR PathCopy = ExAllocatePool(PagedPool, LocalDest.Length + sizeof(WCHAR));
-                if(PathCopy != NULL)
-                {
-                  /* make a copy of the buffer to the temporary buffer */
-                  _SEH_TRY
-                  {
-                    RtlCopyMemory(PathCopy, StrSource, LocalDest.Length);
-                    PathCopy[LocalDest.Length / sizeof(WCHAR)] = L'\0';
-                  }
-                  _SEH_HANDLE
-                  {
-                    Status = _SEH_GetExceptionCode();
-                  }
-                  _SEH_END;
-
-                  /* detach from the process */
-                  if(Attached)
-                    KeDetachProcess();
-
-                  /* only copy the string back to the caller if we were able to
-                     copy it into the temporary buffer! */
-                  if(NT_SUCCESS(Status))
-                  {
-                    /* now let's copy the buffer back to the caller */
-                    _SEH_TRY
-                    {
-                      *DstPath = LocalDest;
-                      RtlCopyMemory(LocalDest.Buffer, PathCopy, LocalDest.Length + sizeof(WCHAR));
-                      if (ReturnLength)
-                      {
-                        *ReturnLength = sizeof(UNICODE_STRING) + LocalDest.Length + sizeof(WCHAR);
-                      }
-                    }
-                    _SEH_HANDLE
-                    {
-                      Status = _SEH_GetExceptionCode();
-                    }
-                    _SEH_END;
-                  }
-
-                  /* we're done with the copy operation, free the temporary kernel buffer */
-                  ExFreePool(PathCopy);
-
-                  /* we need to bail because we're already detached from the process */
-                  break;
-                }
-                else
-                {
-                  Status = STATUS_INSUFFICIENT_RESOURCES;
-                }
-              }
-            }
-          }
-          
-          /* don't forget to detach from the process!!! */
-          if(Attached)
-            KeDetachProcess();
-        }
-        else
-        {
-          /* FIXME - what to do here? */
-          Status = STATUS_UNSUCCESSFUL;
-        }
-        break;
-      }
-
-      /*
-       * Note: The following 10 information classes are verified to not be
-       * implemented on NT, and do indeed return STATUS_INVALID_INFO_CLASS;
-       */
-      case ProcessBasePriority:
-      case ProcessRaisePriority:
-      case ProcessExceptionPort:
-      case ProcessAccessToken:
-      case ProcessLdtSize:
-      case ProcessIoPortHandlers:
-      case ProcessUserModeIOPL:
-      case ProcessEnableAlignmentFaultFixup:
-      case ProcessAffinityMask:
-      case ProcessForegroundInformation:
-      default:
-       Status = STATUS_INVALID_INFO_CLASS;
-     }
-
-   ObDereferenceObject(Process);
-   return Status;
-}
-
-
-NTSTATUS
-PspAssignPrimaryToken(PEPROCESS Process,
-                     HANDLE TokenHandle)
-{
-   PACCESS_TOKEN Token;
-   PACCESS_TOKEN OldToken;
-   NTSTATUS Status;
-   
-   Status = ObReferenceObjectByHandle(TokenHandle,
-                                     0,
-                                     SepTokenObjectType,
-                                     UserMode,
-                                     (PVOID*)&Token,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   Status = SeExchangePrimaryToken(Process, Token, &OldToken);
-   if (NT_SUCCESS(Status))
-     {
-       ObDereferenceObject(OldToken);
-     }
-   ObDereferenceObject(Token);
-   return(Status);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtSetInformationProcess(IN HANDLE ProcessHandle,
-                       IN PROCESSINFOCLASS ProcessInformationClass,
-                       IN PVOID ProcessInformation,
-                       IN ULONG ProcessInformationLength)
-{
-   PEPROCESS Process;
-   KPROCESSOR_MODE PreviousMode;
-   ACCESS_MASK Access;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
-
-   DefaultSetInfoBufferCheck(ProcessInformationClass,
-                             PsProcessInfoClass,
-                             ProcessInformation,
-                             ProcessInformationLength,
-                             PreviousMode,
-                             &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtSetInformationProcess() %d %x  %x called\n", ProcessInformationClass, ProcessInformation, ProcessInformationLength);
-     DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-   
-   switch(ProcessInformationClass)
-   {
-     case ProcessSessionInformation:
-       Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
-       break;
-     case ProcessExceptionPort:
-     case ProcessDebugPort:
-       Access = PROCESS_SET_INFORMATION | PROCESS_SET_PORT;
-       break;
-
-     default:
-       Access = PROCESS_SET_INFORMATION;
-       break;
-   }
-   
-   Status = ObReferenceObjectByHandle(ProcessHandle,
-                                     Access,
-                                     PsProcessType,
-                                     PreviousMode,
-                                     (PVOID*)&Process,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-
-   switch (ProcessInformationClass)
-     {
-      case ProcessQuotaLimits:
-      case ProcessBasePriority:
-      case ProcessRaisePriority:
-       Status = STATUS_NOT_IMPLEMENTED;
-       break;
-
-      case ProcessDebugPort:
-      {
-        HANDLE PortHandle = NULL;
-
-        /* make a safe copy of the buffer on the stack */
-        _SEH_TRY
-        {
-          PortHandle = *(PHANDLE)ProcessInformation;
-          Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if(NT_SUCCESS(Status))
-        {
-          PEPORT DebugPort;
-
-          /* in case we had success reading from the buffer, verify the provided
-           * LPC port handle
-           */
-          Status = ObReferenceObjectByHandle(PortHandle,
-                                             0,
-                                             LpcPortObjectType,
-                                             PreviousMode,
-                                             (PVOID)&DebugPort,
-                                             NULL);
-          if(NT_SUCCESS(Status))
-          {
-            /* lock the process to be thread-safe! */
-
-            Status = PsLockProcess(Process, FALSE);
-            if(NT_SUCCESS(Status))
-            {
-              /*
-               * according to "NT Native API" documentation, setting the debug
-               * port is only permitted once!
-               */
-              if(Process->DebugPort == NULL)
-              {
-                /* keep the reference to the handle! */
-                Process->DebugPort = DebugPort;
-                
-                if(Process->Peb)
-                {
-                  /* we're now debugging the process, so set the flag in the PEB
-                     structure. However, to access it we need to attach to the
-                     process so we're sure we're in the right context! */
-
-                  KeAttachProcess(&Process->Pcb);
-                  _SEH_TRY
-                  {
-                    Process->Peb->BeingDebugged = TRUE;
-                  }
-                  _SEH_HANDLE
-                  {
-                    DPRINT1("Trying to set the Peb->BeingDebugged field of process 0x%x failed, exception: 0x%x\n", Process, _SEH_GetExceptionCode());
-                  }
-                  _SEH_END;
-                  KeDetachProcess();
-                }
-                Status = STATUS_SUCCESS;
-              }
-              else
-              {
-                ObDereferenceObject(DebugPort);
-                Status = STATUS_PORT_ALREADY_SET;
-              }
-              PsUnlockProcess(Process);
-            }
-            else
-            {
-              ObDereferenceObject(DebugPort);
-            }
-          }
-        }
-        break;
-      }
-
-      case ProcessExceptionPort:
-      {
-        HANDLE PortHandle = NULL;
-
-        /* make a safe copy of the buffer on the stack */
-        _SEH_TRY
-        {
-          PortHandle = *(PHANDLE)ProcessInformation;
-          Status = STATUS_SUCCESS;
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        
-        if(NT_SUCCESS(Status))
-        {
-          PEPORT ExceptionPort;
-          
-          /* in case we had success reading from the buffer, verify the provided
-           * LPC port handle
-           */
-          Status = ObReferenceObjectByHandle(PortHandle,
-                                             0,
-                                             LpcPortObjectType,
-                                             PreviousMode,
-                                             (PVOID)&ExceptionPort,
-                                             NULL);
-          if(NT_SUCCESS(Status))
-          {
-            /* lock the process to be thread-safe! */
-            
-            Status = PsLockProcess(Process, FALSE);
-            if(NT_SUCCESS(Status))
-            {
-              /*
-               * according to "NT Native API" documentation, setting the exception
-               * port is only permitted once!
-               */
-              if(Process->ExceptionPort == NULL)
-              {
-                /* keep the reference to the handle! */
-                Process->ExceptionPort = ExceptionPort;
-                Status = STATUS_SUCCESS;
-              }
-              else
-              {
-                ObDereferenceObject(ExceptionPort);
-                Status = STATUS_PORT_ALREADY_SET;
-              }
-              PsUnlockProcess(Process);
-            }
-            else
-            {
-              ObDereferenceObject(ExceptionPort);
-            }
-          }
-        }
-        break;
-      }
-
-      case ProcessAccessToken:
-      {
-        HANDLE TokenHandle = NULL;
-
-        /* make a safe copy of the buffer on the stack */
-        _SEH_TRY
-        {
-          TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
-          Status = STATUS_SUCCESS;
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-
-        if(NT_SUCCESS(Status))
-        {
-          /* in case we had success reading from the buffer, perform the actual task */
-          Status = PspAssignPrimaryToken(Process, TokenHandle);
-        }
-       break;
-      }
-
-      case ProcessDefaultHardErrorMode:
-      {
-        _SEH_TRY
-        {
-          InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
-                              *(PLONG)ProcessInformation);
-          Status = STATUS_SUCCESS;
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        break;
-      }
-      
-      case ProcessSessionInformation:
-      {
-        PROCESS_SESSION_INFORMATION SessionInfo;
-        Status = STATUS_SUCCESS;
-        
-        _SEH_TRY
-        {
-          /* copy the structure to the stack */
-          SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        
-        if(NT_SUCCESS(Status))
-        {
-          /* we successfully copied the structure to the stack, continue processing */
-          
-          /*
-           * setting the session id requires the SeTcbPrivilege!
-           */
-          if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                                     PreviousMode))
-          {
-            DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
-            /* can't set the session id, bail! */
-            Status = STATUS_PRIVILEGE_NOT_HELD;
-            break;
-          }
-          
-          /* FIXME - update the session id for the process token */
-
-          Status = PsLockProcess(Process, FALSE);
-          if(NT_SUCCESS(Status))
-          {
-            Process->SessionId = SessionInfo.SessionId;
-
-            /* Update the session id in the PEB structure */
-            if(Process->Peb != NULL)
-            {
-              /* we need to attach to the process to make sure we're in the right
-                 context to access the PEB structure */
-              KeAttachProcess(&Process->Pcb);
-
-              _SEH_TRY
-              {
-                /* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
-
-                Status = STATUS_SUCCESS;
-              }
-              _SEH_HANDLE
-              {
-                Status = _SEH_GetExceptionCode();
-              }
-              _SEH_END;
-
-              KeDetachProcess();
-            }
-
-            PsUnlockProcess(Process);
-          }
-        }
-        break;
-      }
-      
-      case ProcessPriorityClass:
-      {
-        PROCESS_PRIORITY_CLASS ppc;
-
-        _SEH_TRY
-        {
-          ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
-        }
-        _SEH_HANDLE
-        {
-          Status = _SEH_GetExceptionCode();
-        }
-        _SEH_END;
-        
-        if(NT_SUCCESS(Status))
-        {
-        }
-        
-        break;
-      }
-       
-      case ProcessLdtInformation:
-      case ProcessLdtSize:
-      case ProcessIoPortHandlers:
-      case ProcessWorkingSetWatch:
-      case ProcessUserModeIOPL:
-      case ProcessEnableAlignmentFaultFixup:
-      case ProcessAffinityMask:
-       Status = STATUS_NOT_IMPLEMENTED;
-       break;
-
-      case ProcessBasicInformation:
-      case ProcessIoCounters:
-      case ProcessTimes:
-      case ProcessPooledUsageAndLimits:
-      case ProcessWx86Information:
-      case ProcessHandleCount:
-      case ProcessWow64Information:
-      default:
-       Status = STATUS_INVALID_INFO_CLASS;
-     }
-   ObDereferenceObject(Process);
-   return(Status);
-}
-
-
-/**********************************************************************
- * NAME                                                        INTERNAL
- *     PiQuerySystemProcessInformation
- *
- * DESCRIPTION
- *     Compute the size of a process+thread snapshot as 
- *     expected by NtQuerySystemInformation.
- *
- * RETURN VALUE
- *     0 on error; otherwise the size, in bytes of the buffer
- *     required to write a full snapshot.
- *
- * NOTE
- *     We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
- */
-NTSTATUS
-PiQuerySystemProcessInformation(PVOID Buffer,
-                               ULONG Size,
-                               PULONG ReqSize)
-{
-   return STATUS_NOT_IMPLEMENTED;
-
-#if 0
-       PLIST_ENTRY     CurrentEntryP;
-       PEPROCESS       CurrentP;
-       PLIST_ENTRY     CurrentEntryT;
-       PETHREAD        CurrentT;
-       
-       ULONG           RequiredSize = 0L;
-       BOOLEAN         SizeOnly = FALSE;
-
-       ULONG           SpiSize = 0L;
-       
-       PSYSTEM_PROCESS_INFORMATION     pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
-       PSYSTEM_PROCESS_INFORMATION     pInfoPLast = NULL;
-       PSYSTEM_THREAD_INFO             pInfoT = NULL;
-       
-
-   /* Lock the process list. */
-   ExAcquireFastMutex(&PspActiveProcessMutex);
-
-       /*
-        * Scan the process list. Since the
-        * list is circular, the guard is false
-        * after the last process.
-        */
-       for (   CurrentEntryP = PsActiveProcessHead.Flink;
-               (CurrentEntryP != & PsActiveProcessHead);
-               CurrentEntryP = CurrentEntryP->Flink
-               )
-       {
-               /*
-                * Compute how much space is
-                * occupied in the snapshot
-                * by adding this process info.
-                * (at least one thread).
-                */
-               SpiSizeCurrent = sizeof (SYSTEM_PROCESS_INFORMATION);
-               RequiredSize += SpiSizeCurrent;
-               /*
-                * Do not write process data in the
-                * buffer if it is too small.
-                */
-               if (TRUE == SizeOnly) continue;
-               /*
-                * Check if the buffer can contain
-                * the full snapshot.
-                */
-               if (Size < RequiredSize)
-               {
-                       SizeOnly = TRUE;
-                       continue;
-               }
-               /* 
-                * Get a reference to the 
-                * process descriptor we are
-                * handling.
-                */
-               CurrentP = CONTAINING_RECORD(
-                               CurrentEntryP,
-                               EPROCESS, 
-                               ProcessListEntry
-                               );
-               /*
-                * Write process data in the buffer.
-                */
-               RtlZeroMemory (pInfoP, sizeof (SYSTEM_PROCESS_INFORMATION));
-               /* PROCESS */
-               pInfoP->ThreadCount = 0L;
-               pInfoP->ProcessId = CurrentP->UniqueProcessId;
-               RtlInitUnicodeString (
-                       & pInfoP->Name,
-                       CurrentP->ImageFileName
-                       );
-               /* THREAD */
-               for (   pInfoT = & CurrentP->ThreadSysInfo [0],
-                       CurrentEntryT = CurrentP->ThreadListHead.Flink;
-                       
-                       (CurrentEntryT != & CurrentP->ThreadListHead);
-                       
-                       pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount],
-                       CurrentEntryT = CurrentEntryT->Flink
-                       )
-               {
-                       /*
-                        * Recalculate the size of the
-                        * information block.
-                        */
-                       if (0 < pInfoP->ThreadCount)
-                       {
-                               RequiredSize += sizeof (SYSTEM_THREAD_INFORMATION);
-                       }
-                       /*
-                        * Do not write thread data in the
-                        * buffer if it is too small.
-                        */
-                       if (TRUE == SizeOnly) continue;
-                       /*
-                        * Check if the buffer can contain
-                        * the full snapshot.
-                        */
-                       if (Size < RequiredSize)
-                       {
-                               SizeOnly = TRUE;
-                               continue;
-                       }
-                       /* 
-                        * Get a reference to the 
-                        * thread descriptor we are
-                        * handling.
-                        */
-                       CurrentT = CONTAINING_RECORD(
-                                       CurrentEntryT,
-                                       KTHREAD, 
-                                       ThreadListEntry
-                                       );
-                       /*
-                        * Write thread data.
-                        */
-                       RtlZeroMemory (
-                               pInfoT,
-                               sizeof (SYSTEM_THREAD_INFORMATION)
-                               );
-                       pInfoT->KernelTime      = CurrentT-> ;  /* TIME */
-                       pInfoT->UserTime        = CurrentT-> ;  /* TIME */
-                       pInfoT->CreateTime      = CurrentT-> ;  /* TIME */
-                       pInfoT->TickCount       = CurrentT-> ;  /* ULONG */
-                       pInfoT->StartEIP        = CurrentT-> ;  /* ULONG */
-                       pInfoT->ClientId        = CurrentT-> ;  /* CLIENT_ID */
-                       pInfoT->ClientId        = CurrentT-> ;  /* CLIENT_ID */
-                       pInfoT->DynamicPriority = CurrentT-> ;  /* ULONG */
-                       pInfoT->BasePriority    = CurrentT-> ;  /* ULONG */
-                       pInfoT->nSwitches       = CurrentT-> ;  /* ULONG */
-                       pInfoT->State           = CurrentT-> ;  /* DWORD */
-                       pInfoT->WaitReason      = CurrentT-> ;  /* KWAIT_REASON */
-                       /*
-                        * Count the number of threads 
-                        * this process has.
-                        */
-                       ++ pInfoP->ThreadCount;
-               }
-               /*
-                * Save the size of information
-                * stored in the buffer for the
-                * current process.
-                */
-               pInfoP->RelativeOffset = SpiSize;
-               /*
-                * Save a reference to the last
-                * valid information block.
-                */
-               pInfoPLast = pInfoP;
-               /*
-                * Compute the offset of the 
-                * SYSTEM_PROCESS_INFORMATION
-                * descriptor in the snapshot 
-                * buffer for the next process.
-                */
-               (ULONG) pInfoP += SpiSize;
-       }
-       /*
-        * Unlock the process list.
-        */
-       ExReleaseFastMutex (
-               & PspActiveProcessMutex
-               );
-       /*
-        * Return the proper error status code,
-        * if the buffer was too small.
-        */
-       if (TRUE == SizeOnly)
-       {
-               if (NULL != RequiredSize)
-               {
-                       *pRequiredSize = RequiredSize;
-               }
-               return STATUS_INFO_LENGTH_MISMATCH;
-       }
-       /*
-        * Mark the end of the snapshot.
-        */
-       pInfoP->RelativeOffset = 0L;
-       /* OK */        
-       return STATUS_SUCCESS;
-#endif
 }
 
 /*
@@ -2561,30 +1318,25 @@ NTSTATUS STDCALL
 PsLookupProcessByProcessId(IN HANDLE ProcessId,
                           OUT PEPROCESS *Process)
 {
-  PLIST_ENTRY current_entry;
-  PEPROCESS current;
+  PHANDLE_TABLE_ENTRY CidEntry;
+  PEPROCESS FoundProcess;
 
-  ExAcquireFastMutex(&PspActiveProcessMutex);
+  PAGED_CODE();
 
-  current_entry = PsActiveProcessHead.Flink;
-  while (current_entry != &PsActiveProcessHead)
-    {
-      current = CONTAINING_RECORD(current_entry,
-                                 EPROCESS,
-                                 ProcessListEntry);
-      if (current->UniqueProcessId == ProcessId)
-       {
-         *Process = current;
-          ObReferenceObject(current);
-         ExReleaseFastMutex(&PspActiveProcessMutex);
-         return(STATUS_SUCCESS);
-       }
-      current_entry = current_entry->Flink;
-    }
+  ASSERT(Process);
 
-  ExReleaseFastMutex(&PspActiveProcessMutex);
+  CidEntry = PsLookupCidHandle(ProcessId, PsProcessType, (PVOID*)&FoundProcess);
+  if(CidEntry != NULL)
+  {
+    ObReferenceObject(FoundProcess);
 
-  return(STATUS_INVALID_PARAMETER);
+    PsUnlockCidHandle(CidEntry);
+
+    *Process = FoundProcess;
+    return STATUS_SUCCESS;
+  }
+
+  return STATUS_INVALID_PARAMETER;
 }
 
 VOID
@@ -2892,7 +1644,7 @@ PsReturnProcessPagedPoolQuota(
 }
 
 NTSTATUS
-PsLockProcess(PEPROCESS Process, BOOL Timeout)
+PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
 {
   ULONG Attempts = 0;
   PKTHREAD PrevLockOwner;
@@ -2906,12 +1658,6 @@ PsLockProcess(PEPROCESS Process, BOOL Timeout)
   
   for(;;)
   {
-    if(Process->Pcb.State == PROCESS_STATE_TERMINATED)
-    {
-      KeLeaveCriticalRegion();
-      return STATUS_PROCESS_IS_TERMINATING;
-    }
-
     PrevLockOwner = (PKTHREAD)InterlockedCompareExchangePointer(
       &Process->LockOwner, CallingThread, NULL);
     if(PrevLockOwner == NULL || PrevLockOwner == CallingThread)
@@ -2942,9 +1688,8 @@ PsLockProcess(PEPROCESS Process, BOOL Timeout)
           }
 #endif
           KeLeaveCriticalRegion();
-
+          break;
         }
-        break;
       }
       else
       {
index 051d6ae..d8070ab 100644 (file)
@@ -14,8 +14,6 @@
 #define NDEBUG
 #include <internal/debug.h>
 
-VOID INIT_FUNCTION PsInitClientIDManagment(VOID);
-
 /* FUNCTIONS ***************************************************************/
 
 VOID PiShutdownProcessManager(VOID)
@@ -28,12 +26,10 @@ VOID PiShutdownProcessManager(VOID)
 VOID INIT_FUNCTION
 PiInitProcessManager(VOID)
 {
-   PsInitClientIDManagment();
    PsInitJobManagment();
    PsInitProcessManagment();
    PsInitThreadManagment();
    PsInitIdleThread();
-   PsInitialiseSuspendImplementation();
    PsInitialiseW32Call();
 }
 
diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c
new file mode 100644 (file)
index 0000000..b6dbac1
--- /dev/null
@@ -0,0 +1,1414 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ps/query.c
+ * PURPOSE:         Set/Query Process/Thread Information APIs
+ *
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Created File
+ *                  David Welch
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+
+static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
+{
+  ICI_SQ_SAME( sizeof(PROCESS_BASIC_INFORMATION),     sizeof(ULONG), ICIF_QUERY ),                     /* ProcessBasicInformation */
+  ICI_SQ_SAME( sizeof(QUOTA_LIMITS),                  sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessQuotaLimits */
+  ICI_SQ_SAME( sizeof(IO_COUNTERS),                   sizeof(ULONG), ICIF_QUERY ),                     /* ProcessIoCounters */
+  ICI_SQ_SAME( sizeof(VM_COUNTERS),                   sizeof(ULONG), ICIF_QUERY ),                     /* ProcessVmCounters */
+  ICI_SQ_SAME( sizeof(KERNEL_USER_TIMES),             sizeof(ULONG), ICIF_QUERY ),                     /* ProcessTimes */
+  ICI_SQ_SAME( sizeof(KPRIORITY),                     sizeof(ULONG), ICIF_SET ),                       /* ProcessBasePriority */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_SET ),                       /* ProcessRaisePriority */
+  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessDebugPort */
+  ICI_SQ_SAME( sizeof(HANDLE),                        sizeof(ULONG), ICIF_SET ),                       /* ProcessExceptionPort */
+  ICI_SQ_SAME( sizeof(PROCESS_ACCESS_TOKEN),          sizeof(ULONG), ICIF_SET ),                       /* ProcessAccessToken */
+  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessLdtInformation */
+  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessLdtSize */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessDefaultHardErrorMode */
+  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessIoPortHandlers */
+  ICI_SQ_SAME( sizeof(POOLED_USAGE_AND_LIMITS),       sizeof(ULONG), ICIF_QUERY ),                     /* ProcessPooledUsageAndLimits */
+  ICI_SQ_SAME( sizeof(PROCESS_WS_WATCH_INFORMATION),  sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessWorkingSetWatch */
+  ICI_SQ_SAME( 0 /* FIXME */,                         sizeof(ULONG), ICIF_SET ),                       /* ProcessUserModeIOPL */
+  ICI_SQ_SAME( sizeof(BOOLEAN),                       sizeof(ULONG), ICIF_SET ),                       /* ProcessEnableAlignmentFaultFixup */
+  ICI_SQ_SAME( sizeof(PROCESS_PRIORITY_CLASS),        sizeof(USHORT), ICIF_QUERY | ICIF_SET ),         /* ProcessPriorityClass */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessWx86Information */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessHandleCount */
+  ICI_SQ_SAME( sizeof(KAFFINITY),                     sizeof(ULONG), ICIF_SET ),                       /* ProcessAffinityMask */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessPriorityBoost */
+
+  ICI_SQ(/*Q*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Query),                                   /* ProcessDeviceMap */
+         /*S*/ sizeof(((PPROCESS_DEVICEMAP_INFORMATION)0x0)->Set),
+                                                /*Q*/ sizeof(ULONG),
+                                                /*S*/ sizeof(ULONG),
+                                                                     ICIF_QUERY | ICIF_SET ),
+
+  ICI_SQ_SAME( sizeof(PROCESS_SESSION_INFORMATION),   sizeof(ULONG), ICIF_QUERY | ICIF_SET ),          /* ProcessSessionInformation */
+  ICI_SQ_SAME( sizeof(BOOLEAN),                       sizeof(ULONG), ICIF_SET ),                       /* ProcessForegroundInformation */
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY ),                     /* ProcessWow64Information */
+  ICI_SQ_SAME( sizeof(UNICODE_STRING),                sizeof(ULONG), ICIF_QUERY | ICIF_SIZE_VARIABLE), /* ProcessImageFileName */
+
+  /* FIXME */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessLUIDDeviceMapsEnabled */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessBreakOnTermination */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessDebugObjectHandle */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessDebugFlags */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessHandleTracing */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown33 */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown34 */
+  ICI_SQ_SAME( 0,                                     1,             0 ),                              /* ProcessUnknown35 */
+  
+  ICI_SQ_SAME( sizeof(ULONG),                         sizeof(ULONG), ICIF_QUERY),                      /* ProcessCookie */
+};
+
+/*
+ * FIXME:
+ *   Remove the Implemented value if all functions are implemented.
+ */
+
+static const struct
+{
+   BOOLEAN Implemented;
+   ULONG Size;
+} QueryInformationData[MaxThreadInfoClass + 1] = 
+{
+    {TRUE, sizeof(THREAD_BASIC_INFORMATION)},  // ThreadBasicInformation
+    {TRUE, sizeof(KERNEL_USER_TIMES)},         // ThreadTimes
+    {TRUE, 0},                                 // ThreadPriority
+    {TRUE, 0},                                 // ThreadBasePriority
+    {TRUE, 0},                                 // ThreadAffinityMask
+    {TRUE, 0},                                 // ThreadImpersonationToken
+    {FALSE, 0},                                        // ThreadDescriptorTableEntry
+    {TRUE, 0},                                 // ThreadEnableAlignmentFaultFixup
+    {TRUE, 0},                                 // ThreadEventPair
+    {TRUE, sizeof(PVOID)},                     // ThreadQuerySetWin32StartAddress
+    {TRUE, 0},                                 // ThreadZeroTlsCell
+    {TRUE, sizeof(LARGE_INTEGER)},             // ThreadPerformanceCount
+    {TRUE, sizeof(BOOLEAN)},                   // ThreadAmILastThread
+    {TRUE, 0},                                 // ThreadIdealProcessor
+    {FALSE, 0},                                        // ThreadPriorityBoost
+    {TRUE, 0},                                 // ThreadSetTlsArrayAddress
+    {FALSE, 0},                                        // ThreadIsIoPending
+    {TRUE, 0}                                  // ThreadHideFromDebugger
+};
+
+static const struct
+{
+   BOOLEAN Implemented;
+   ULONG Size;
+} SetInformationData[MaxThreadInfoClass + 1] = 
+{
+    {TRUE, 0},                 // ThreadBasicInformation
+    {TRUE, 0},                 // ThreadTimes
+    {TRUE, sizeof(KPRIORITY)}, // ThreadPriority
+    {TRUE, sizeof(LONG)},      // ThreadBasePriority
+    {TRUE, sizeof(KAFFINITY)}, // ThreadAffinityMask
+    {TRUE, sizeof(HANDLE)},    // ThreadImpersonationToken
+    {TRUE, 0},                 // ThreadDescriptorTableEntry
+    {FALSE, 0},                        // ThreadEnableAlignmentFaultFixup
+    {FALSE, 0},                        // ThreadEventPair
+    {TRUE, sizeof(PVOID)},     // ThreadQuerySetWin32StartAddress
+    {FALSE, 0},                        // ThreadZeroTlsCell
+    {TRUE, 0},                 // ThreadPerformanceCount
+    {TRUE, 0},                 // ThreadAmILastThread
+    {FALSE, 0},                        // ThreadIdealProcessor
+    {FALSE, 0},                        // ThreadPriorityBoost
+    {FALSE, 0},                        // ThreadSetTlsArrayAddress
+    {TRUE, 0},                 // ThreadIsIoPending
+    {FALSE, 0}                 // ThreadHideFromDebugger
+};
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtQueryInformationProcess(IN  HANDLE ProcessHandle,
+                         IN  PROCESSINFOCLASS ProcessInformationClass,
+                         OUT PVOID ProcessInformation,
+                         IN  ULONG ProcessInformationLength,
+                         OUT PULONG ReturnLength  OPTIONAL)
+{
+   PEPROCESS Process;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PAGED_CODE();
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   DefaultQueryInfoBufferCheck(ProcessInformationClass,
+                               PsProcessInfoClass,
+                               ProcessInformation,
+                               ProcessInformationLength,
+                               ReturnLength,
+                               PreviousMode,
+                               &Status);
+   if(!NT_SUCCESS(Status))
+   {
+     DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
+     return Status;
+   }
+   
+   if(ProcessInformationClass != ProcessCookie)
+   {
+     Status = ObReferenceObjectByHandle(ProcessHandle,
+                                     PROCESS_QUERY_INFORMATION,
+                                     PsProcessType,
+                                     PreviousMode,
+                                     (PVOID*)&Process,
+                                     NULL);
+     if (!NT_SUCCESS(Status))
+       {
+       return(Status);
+       }
+   }
+   else if(ProcessHandle != NtCurrentProcess())
+   {
+     /* retreiving the process cookie is only allowed for the calling process
+        itself! XP only allowes NtCurrentProcess() as process handles even if a
+        real handle actually represents the current process. */
+     return STATUS_INVALID_PARAMETER;
+   }
+   
+   switch (ProcessInformationClass)
+     {
+      case ProcessBasicInformation:
+      {
+        PPROCESS_BASIC_INFORMATION ProcessBasicInformationP =
+         (PPROCESS_BASIC_INFORMATION)ProcessInformation;
+
+        _SEH_TRY
+        {
+         ProcessBasicInformationP->ExitStatus = Process->ExitStatus;
+         ProcessBasicInformationP->PebBaseAddress = Process->Peb;
+         ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
+         ProcessBasicInformationP->UniqueProcessId =
+           Process->UniqueProcessId;
+         ProcessBasicInformationP->InheritedFromUniqueProcessId =
+           Process->InheritedFromUniqueProcessId;
+         ProcessBasicInformationP->BasePriority =
+           Process->Pcb.BasePriority;
+
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(PROCESS_BASIC_INFORMATION);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+       break;
+      }
+
+      case ProcessQuotaLimits:
+      case ProcessIoCounters:
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
+
+      case ProcessTimes:
+      {
+         PKERNEL_USER_TIMES ProcessTimeP = (PKERNEL_USER_TIMES)ProcessInformation;
+         _SEH_TRY
+         {
+           ProcessTimeP->CreateTime = Process->CreateTime;
+            ProcessTimeP->UserTime.QuadPart = Process->Pcb.UserTime * 100000LL;
+            ProcessTimeP->KernelTime.QuadPart = Process->Pcb.KernelTime * 100000LL;
+           ProcessTimeP->ExitTime = Process->ExitTime;
+
+          if (ReturnLength)
+          {
+            *ReturnLength = sizeof(KERNEL_USER_TIMES);
+          }
+         }
+         _SEH_HANDLE
+         {
+           Status = _SEH_GetExceptionCode();
+         }
+         _SEH_END;
+        break;
+      }
+
+      case ProcessDebugPort:
+      {
+        _SEH_TRY
+        {
+          *(PHANDLE)ProcessInformation = (Process->DebugPort != NULL ? (HANDLE)-1 : NULL);
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(HANDLE);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        break;
+      }
+      
+      case ProcessLdtInformation:
+      case ProcessWorkingSetWatch:
+      case ProcessWx86Information:
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
+
+      case ProcessHandleCount:
+      {
+       ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable);
+         
+       _SEH_TRY
+       {
+          *(PULONG)ProcessInformation = HandleCount;
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(ULONG);
+         }
+       }
+       _SEH_HANDLE
+       {
+          Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
+       break;
+      }
+
+      case ProcessSessionInformation:
+      {
+        PPROCESS_SESSION_INFORMATION SessionInfo = (PPROCESS_SESSION_INFORMATION)ProcessInformation;
+
+        _SEH_TRY
+        {
+          SessionInfo->SessionId = Process->SessionId;
+          if (ReturnLength)
+          {
+            *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION);
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        break;
+      }
+      
+      case ProcessWow64Information:
+        DPRINT1("We currently don't support the ProcessWow64Information information class!\n");
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
+
+      case ProcessVmCounters:
+      {
+       PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation;
+         
+       _SEH_TRY
+       {
+         pOut->PeakVirtualSize            = Process->PeakVirtualSize;
+         /*
+          * Here we should probably use VirtualSize.LowPart, but due to
+          * incompatibilities in current headers (no unnamed union),
+          * I opted for cast.
+          */
+         pOut->VirtualSize                = (ULONG)Process->VirtualSize.QuadPart;
+         pOut->PageFaultCount             = Process->Vm.PageFaultCount;
+         pOut->PeakWorkingSetSize         = Process->Vm.PeakWorkingSetSize;
+         pOut->WorkingSetSize             = Process->Vm.WorkingSetSize;
+         pOut->QuotaPeakPagedPoolUsage    = Process->QuotaPeakPoolUsage[0]; // TODO: Verify!
+         pOut->QuotaPagedPoolUsage        = Process->QuotaPoolUsage[0];     // TODO: Verify!
+         pOut->QuotaPeakNonPagedPoolUsage = Process->QuotaPeakPoolUsage[1]; // TODO: Verify!
+         pOut->QuotaNonPagedPoolUsage     = Process->QuotaPoolUsage[1];     // TODO: Verify!
+         pOut->PagefileUsage              = Process->PagefileUsage;
+         pOut->PeakPagefileUsage          = Process->PeakPagefileUsage;
+
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(VM_COUNTERS);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+       break;
+      }
+
+      case ProcessDefaultHardErrorMode:
+      {
+       PULONG HardErrMode = (PULONG)ProcessInformation;
+       _SEH_TRY
+       {
+         *HardErrMode = Process->DefaultHardErrorProcessing;
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(ULONG);
+         }
+       }
+       _SEH_HANDLE
+       {
+          Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
+       break;
+      }
+
+      case ProcessPriorityBoost:
+      {
+       PULONG BoostEnabled = (PULONG)ProcessInformation;
+         
+       _SEH_TRY
+       {
+         *BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE;
+
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(ULONG);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+       break;
+      }
+
+      case ProcessDeviceMap:
+      {
+        PROCESS_DEVICEMAP_INFORMATION DeviceMap;
+          
+        ObQueryDeviceMapInformation(Process, &DeviceMap);
+
+        _SEH_TRY
+        {
+          *(PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation = DeviceMap;
+         if (ReturnLength)
+          {
+           *ReturnLength = sizeof(PROCESS_DEVICEMAP_INFORMATION);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+       break;
+      }
+
+      case ProcessPriorityClass:
+      {
+       PUSHORT Priority = (PUSHORT)ProcessInformation;
+
+       _SEH_TRY
+       {
+         *Priority = Process->PriorityClass;
+
+         if (ReturnLength)
+         {
+           *ReturnLength = sizeof(USHORT);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+       break;
+      }
+
+      case ProcessImageFileName:
+      {
+        /*
+         * We DO NOT return the file name stored in the EPROCESS structure.
+         * Propably if we can't find a PEB or ProcessParameters structure for the
+         * process!
+         */
+        if(Process->Peb != NULL)
+        {
+          PRTL_USER_PROCESS_PARAMETERS ProcParams = NULL;
+          UNICODE_STRING LocalDest;
+          BOOLEAN Attached;
+          ULONG ImagePathLen = 0;
+          PUNICODE_STRING DstPath = (PUNICODE_STRING)ProcessInformation;
+
+          /* we need to attach to the process to make sure we're in the right context! */
+          Attached = Process != PsGetCurrentProcess();
+
+          if(Attached)
+            KeAttachProcess(&Process->Pcb);
+          
+          _SEH_TRY
+          {
+            ProcParams = Process->Peb->ProcessParameters;
+            ImagePathLen = ProcParams->ImagePathName.Length;
+          }
+          _SEH_HANDLE
+          {
+            Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+          
+          if(NT_SUCCESS(Status))
+          {
+            if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
+            {
+              Status = STATUS_INFO_LENGTH_MISMATCH;
+            }
+            else
+            {
+              PWSTR StrSource = NULL;
+
+              /* create a DstPath structure on the stack */
+              _SEH_TRY
+              {
+                LocalDest.Length = ImagePathLen;
+                LocalDest.MaximumLength = ImagePathLen + sizeof(WCHAR);
+                LocalDest.Buffer = (PWSTR)(DstPath + 1);
+
+                /* save a copy of the pointer to the source buffer */
+                StrSource = ProcParams->ImagePathName.Buffer;
+              }
+              _SEH_HANDLE
+              {
+                Status = _SEH_GetExceptionCode();
+              }
+              _SEH_END;
+
+              if(NT_SUCCESS(Status))
+              {
+                /* now, let's allocate some anonymous memory to copy the string to.
+                   we can't just copy it to the buffer the caller pointed as it might
+                   be user memory in another context */
+                PWSTR PathCopy = ExAllocatePool(PagedPool, LocalDest.Length + sizeof(WCHAR));
+                if(PathCopy != NULL)
+                {
+                  /* make a copy of the buffer to the temporary buffer */
+                  _SEH_TRY
+                  {
+                    RtlCopyMemory(PathCopy, StrSource, LocalDest.Length);
+                    PathCopy[LocalDest.Length / sizeof(WCHAR)] = L'\0';
+                  }
+                  _SEH_HANDLE
+                  {
+                    Status = _SEH_GetExceptionCode();
+                  }
+                  _SEH_END;
+
+                  /* detach from the process */
+                  if(Attached)
+                    KeDetachProcess();
+
+                  /* only copy the string back to the caller if we were able to
+                     copy it into the temporary buffer! */
+                  if(NT_SUCCESS(Status))
+                  {
+                    /* now let's copy the buffer back to the caller */
+                    _SEH_TRY
+                    {
+                      *DstPath = LocalDest;
+                      RtlCopyMemory(LocalDest.Buffer, PathCopy, LocalDest.Length + sizeof(WCHAR));
+                      if (ReturnLength)
+                      {
+                        *ReturnLength = sizeof(UNICODE_STRING) + LocalDest.Length + sizeof(WCHAR);
+                      }
+                    }
+                    _SEH_HANDLE
+                    {
+                      Status = _SEH_GetExceptionCode();
+                    }
+                    _SEH_END;
+                  }
+
+                  /* we're done with the copy operation, free the temporary kernel buffer */
+                  ExFreePool(PathCopy);
+
+                  /* we need to bail because we're already detached from the process */
+                  break;
+                }
+                else
+                {
+                  Status = STATUS_INSUFFICIENT_RESOURCES;
+                }
+              }
+            }
+          }
+          
+          /* don't forget to detach from the process!!! */
+          if(Attached)
+            KeDetachProcess();
+        }
+        else
+        {
+          /* FIXME - what to do here? */
+          Status = STATUS_UNSUCCESSFUL;
+        }
+        break;
+      }
+      
+      case ProcessCookie:
+      {
+        ULONG Cookie;
+        
+        /* receive the process cookie, this is only allowed for the current
+           process! */
+
+        Process = PsGetCurrentProcess();
+
+        Cookie = Process->Cookie;
+        if(Cookie == 0)
+        {
+          LARGE_INTEGER SystemTime;
+          ULONG NewCookie;
+          PKPRCB Prcb;
+          
+          /* generate a new cookie */
+          
+          KeQuerySystemTime(&SystemTime);
+          
+          Prcb = KeGetCurrentPrcb();
+
+          NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
+                      SystemTime.u.LowPart ^ SystemTime.u.HighPart;
+          
+          /* try to set the new cookie, return the current one if another thread
+             set it in the meanwhile */
+          Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie,
+                                              NewCookie,
+                                              Cookie);
+          if(Cookie == 0)
+          {
+            /* successfully set the cookie */
+            Cookie = NewCookie;
+          }
+        }
+        
+        _SEH_TRY
+        {
+          *(PULONG)ProcessInformation = Cookie;
+         if (ReturnLength)
+          {
+           *ReturnLength = sizeof(ULONG);
+         }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        break;
+      }
+
+      /*
+       * Note: The following 10 information classes are verified to not be
+       * implemented on NT, and do indeed return STATUS_INVALID_INFO_CLASS;
+       */
+      case ProcessBasePriority:
+      case ProcessRaisePriority:
+      case ProcessExceptionPort:
+      case ProcessAccessToken:
+      case ProcessLdtSize:
+      case ProcessIoPortHandlers:
+      case ProcessUserModeIOPL:
+      case ProcessEnableAlignmentFaultFixup:
+      case ProcessAffinityMask:
+      case ProcessForegroundInformation:
+      default:
+       Status = STATUS_INVALID_INFO_CLASS;
+     }
+
+   if(ProcessInformationClass != ProcessCookie)
+   {
+     ObDereferenceObject(Process);
+   }
+   
+   return Status;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtSetInformationProcess(IN HANDLE ProcessHandle,
+                       IN PROCESSINFOCLASS ProcessInformationClass,
+                       IN PVOID ProcessInformation,
+                       IN ULONG ProcessInformationLength)
+{
+   PEPROCESS Process;
+   KPROCESSOR_MODE PreviousMode;
+   ACCESS_MASK Access;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PAGED_CODE();
+   
+   PreviousMode = ExGetPreviousMode();
+
+   DefaultSetInfoBufferCheck(ProcessInformationClass,
+                             PsProcessInfoClass,
+                             ProcessInformation,
+                             ProcessInformationLength,
+                             PreviousMode,
+                             &Status);
+   if(!NT_SUCCESS(Status))
+   {
+     DPRINT1("NtSetInformationProcess() %d %x  %x called\n", ProcessInformationClass, ProcessInformation, ProcessInformationLength);
+     DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
+     return Status;
+   }
+   
+   switch(ProcessInformationClass)
+   {
+     case ProcessSessionInformation:
+       Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
+       break;
+     case ProcessExceptionPort:
+     case ProcessDebugPort:
+       Access = PROCESS_SET_INFORMATION | PROCESS_SET_PORT;
+       break;
+
+     default:
+       Access = PROCESS_SET_INFORMATION;
+       break;
+   }
+   
+   Status = ObReferenceObjectByHandle(ProcessHandle,
+                                     Access,
+                                     PsProcessType,
+                                     PreviousMode,
+                                     (PVOID*)&Process,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+
+   switch (ProcessInformationClass)
+     {
+      case ProcessQuotaLimits:
+      case ProcessBasePriority:
+      case ProcessRaisePriority:
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
+
+      case ProcessDebugPort:
+      {
+        HANDLE PortHandle = NULL;
+
+        /* make a safe copy of the buffer on the stack */
+        _SEH_TRY
+        {
+          PortHandle = *(PHANDLE)ProcessInformation;
+          Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(NT_SUCCESS(Status))
+        {
+          PEPORT DebugPort;
+
+          /* in case we had success reading from the buffer, verify the provided
+           * LPC port handle
+           */
+          Status = ObReferenceObjectByHandle(PortHandle,
+                                             0,
+                                             LpcPortObjectType,
+                                             PreviousMode,
+                                             (PVOID)&DebugPort,
+                                             NULL);
+          if(NT_SUCCESS(Status))
+          {
+            /* lock the process to be thread-safe! */
+
+            Status = PsLockProcess(Process, FALSE);
+            if(NT_SUCCESS(Status))
+            {
+              /*
+               * according to "NT Native API" documentation, setting the debug
+               * port is only permitted once!
+               */
+              if(Process->DebugPort == NULL)
+              {
+                /* keep the reference to the handle! */
+                Process->DebugPort = DebugPort;
+                
+                if(Process->Peb)
+                {
+                  /* we're now debugging the process, so set the flag in the PEB
+                     structure. However, to access it we need to attach to the
+                     process so we're sure we're in the right context! */
+
+                  KeAttachProcess(&Process->Pcb);
+                  _SEH_TRY
+                  {
+                    Process->Peb->BeingDebugged = TRUE;
+                  }
+                  _SEH_HANDLE
+                  {
+                    DPRINT1("Trying to set the Peb->BeingDebugged field of process 0x%x failed, exception: 0x%x\n", Process, _SEH_GetExceptionCode());
+                  }
+                  _SEH_END;
+                  KeDetachProcess();
+                }
+                Status = STATUS_SUCCESS;
+              }
+              else
+              {
+                ObDereferenceObject(DebugPort);
+                Status = STATUS_PORT_ALREADY_SET;
+              }
+              PsUnlockProcess(Process);
+            }
+            else
+            {
+              ObDereferenceObject(DebugPort);
+            }
+          }
+        }
+        break;
+      }
+
+      case ProcessExceptionPort:
+      {
+        HANDLE PortHandle = NULL;
+
+        /* make a safe copy of the buffer on the stack */
+        _SEH_TRY
+        {
+          PortHandle = *(PHANDLE)ProcessInformation;
+          Status = STATUS_SUCCESS;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        if(NT_SUCCESS(Status))
+        {
+          PEPORT ExceptionPort;
+          
+          /* in case we had success reading from the buffer, verify the provided
+           * LPC port handle
+           */
+          Status = ObReferenceObjectByHandle(PortHandle,
+                                             0,
+                                             LpcPortObjectType,
+                                             PreviousMode,
+                                             (PVOID)&ExceptionPort,
+                                             NULL);
+          if(NT_SUCCESS(Status))
+          {
+            /* lock the process to be thread-safe! */
+            
+            Status = PsLockProcess(Process, FALSE);
+            if(NT_SUCCESS(Status))
+            {
+              /*
+               * according to "NT Native API" documentation, setting the exception
+               * port is only permitted once!
+               */
+              if(Process->ExceptionPort == NULL)
+              {
+                /* keep the reference to the handle! */
+                Process->ExceptionPort = ExceptionPort;
+                Status = STATUS_SUCCESS;
+              }
+              else
+              {
+                ObDereferenceObject(ExceptionPort);
+                Status = STATUS_PORT_ALREADY_SET;
+              }
+              PsUnlockProcess(Process);
+            }
+            else
+            {
+              ObDereferenceObject(ExceptionPort);
+            }
+          }
+        }
+        break;
+      }
+
+      case ProcessAccessToken:
+      {
+        HANDLE TokenHandle = NULL;
+
+        /* make a safe copy of the buffer on the stack */
+        _SEH_TRY
+        {
+          TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
+          Status = STATUS_SUCCESS;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(NT_SUCCESS(Status))
+        {
+          /* in case we had success reading from the buffer, perform the actual task */
+          Status = PspAssignPrimaryToken(Process, TokenHandle);
+        }
+       break;
+      }
+
+      case ProcessDefaultHardErrorMode:
+      {
+        _SEH_TRY
+        {
+          InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
+                              *(PLONG)ProcessInformation);
+          Status = STATUS_SUCCESS;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        break;
+      }
+      
+      case ProcessSessionInformation:
+      {
+        PROCESS_SESSION_INFORMATION SessionInfo;
+        Status = STATUS_SUCCESS;
+        
+        _SEH_TRY
+        {
+          /* copy the structure to the stack */
+          SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        if(NT_SUCCESS(Status))
+        {
+          /* we successfully copied the structure to the stack, continue processing */
+          
+          /*
+           * setting the session id requires the SeTcbPrivilege!
+           */
+          if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
+                                     PreviousMode))
+          {
+            DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
+            /* can't set the session id, bail! */
+            Status = STATUS_PRIVILEGE_NOT_HELD;
+            break;
+          }
+          
+          /* FIXME - update the session id for the process token */
+
+          Status = PsLockProcess(Process, FALSE);
+          if(NT_SUCCESS(Status))
+          {
+            Process->SessionId = SessionInfo.SessionId;
+
+            /* Update the session id in the PEB structure */
+            if(Process->Peb != NULL)
+            {
+              /* we need to attach to the process to make sure we're in the right
+                 context to access the PEB structure */
+              KeAttachProcess(&Process->Pcb);
+
+              _SEH_TRY
+              {
+                /* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
+
+                Status = STATUS_SUCCESS;
+              }
+              _SEH_HANDLE
+              {
+                Status = _SEH_GetExceptionCode();
+              }
+              _SEH_END;
+
+              KeDetachProcess();
+            }
+
+            PsUnlockProcess(Process);
+          }
+        }
+        break;
+      }
+      
+      case ProcessPriorityClass:
+      {
+        PROCESS_PRIORITY_CLASS ppc;
+
+        _SEH_TRY
+        {
+          ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        if(NT_SUCCESS(Status))
+        {
+        }
+        
+        break;
+      }
+       
+      case ProcessLdtInformation:
+      case ProcessLdtSize:
+      case ProcessIoPortHandlers:
+      case ProcessWorkingSetWatch:
+      case ProcessUserModeIOPL:
+      case ProcessEnableAlignmentFaultFixup:
+      case ProcessAffinityMask:
+       Status = STATUS_NOT_IMPLEMENTED;
+       break;
+
+      case ProcessBasicInformation:
+      case ProcessIoCounters:
+      case ProcessTimes:
+      case ProcessPooledUsageAndLimits:
+      case ProcessWx86Information:
+      case ProcessHandleCount:
+      case ProcessWow64Information:
+      default:
+       Status = STATUS_INVALID_INFO_CLASS;
+     }
+   ObDereferenceObject(Process);
+   return(Status);
+}
+
+
+/**********************************************************************
+ * NAME                                                        INTERNAL
+ *     PiQuerySystemProcessInformation
+ *
+ * DESCRIPTION
+ *     Compute the size of a process+thread snapshot as 
+ *     expected by NtQuerySystemInformation.
+ *
+ * RETURN VALUE
+ *     0 on error; otherwise the size, in bytes of the buffer
+ *     required to write a full snapshot.
+ *
+ * NOTE
+ *     We assume (sizeof (PVOID) == sizeof (ULONG)) holds.
+ */
+NTSTATUS
+PiQuerySystemProcessInformation(PVOID Buffer,
+                               ULONG Size,
+                               PULONG ReqSize)
+{
+   return STATUS_NOT_IMPLEMENTED;
+
+#if 0
+       PLIST_ENTRY     CurrentEntryP;
+       PEPROCESS       CurrentP;
+       PLIST_ENTRY     CurrentEntryT;
+       PETHREAD        CurrentT;
+       
+       ULONG           RequiredSize = 0L;
+       BOOLEAN         SizeOnly = FALSE;
+
+       ULONG           SpiSize = 0L;
+       
+       PSYSTEM_PROCESS_INFORMATION     pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
+       PSYSTEM_PROCESS_INFORMATION     pInfoPLast = NULL;
+       PSYSTEM_THREAD_INFO             pInfoT = NULL;
+       
+
+   /* Lock the process list. */
+   ExAcquireFastMutex(&PspActiveProcessMutex);
+
+       /*
+        * Scan the process list. Since the
+        * list is circular, the guard is false
+        * after the last process.
+        */
+       for (   CurrentEntryP = PsActiveProcessHead.Flink;
+               (CurrentEntryP != & PsActiveProcessHead);
+               CurrentEntryP = CurrentEntryP->Flink
+               )
+       {
+               /*
+                * Compute how much space is
+                * occupied in the snapshot
+                * by adding this process info.
+                * (at least one thread).
+                */
+               SpiSizeCurrent = sizeof (SYSTEM_PROCESS_INFORMATION);
+               RequiredSize += SpiSizeCurrent;
+               /*
+                * Do not write process data in the
+                * buffer if it is too small.
+                */
+               if (TRUE == SizeOnly) continue;
+               /*
+                * Check if the buffer can contain
+                * the full snapshot.
+                */
+               if (Size < RequiredSize)
+               {
+                       SizeOnly = TRUE;
+                       continue;
+               }
+               /* 
+                * Get a reference to the 
+                * process descriptor we are
+                * handling.
+                */
+               CurrentP = CONTAINING_RECORD(
+                               CurrentEntryP,
+                               EPROCESS, 
+                               ProcessListEntry
+                               );
+               /*
+                * Write process data in the buffer.
+                */
+               RtlZeroMemory (pInfoP, sizeof (SYSTEM_PROCESS_INFORMATION));
+               /* PROCESS */
+               pInfoP->ThreadCount = 0L;
+               pInfoP->ProcessId = CurrentP->UniqueProcessId;
+               RtlInitUnicodeString (
+                       & pInfoP->Name,
+                       CurrentP->ImageFileName
+                       );
+               /* THREAD */
+               for (   pInfoT = & CurrentP->ThreadSysInfo [0],
+                       CurrentEntryT = CurrentP->ThreadListHead.Flink;
+                       
+                       (CurrentEntryT != & CurrentP->ThreadListHead);
+                       
+                       pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount],
+                       CurrentEntryT = CurrentEntryT->Flink
+                       )
+               {
+                       /*
+                        * Recalculate the size of the
+                        * information block.
+                        */
+                       if (0 < pInfoP->ThreadCount)
+                       {
+                               RequiredSize += sizeof (SYSTEM_THREAD_INFORMATION);
+                       }
+                       /*
+                        * Do not write thread data in the
+                        * buffer if it is too small.
+                        */
+                       if (TRUE == SizeOnly) continue;
+                       /*
+                        * Check if the buffer can contain
+                        * the full snapshot.
+                        */
+                       if (Size < RequiredSize)
+                       {
+                               SizeOnly = TRUE;
+                               continue;
+                       }
+                       /* 
+                        * Get a reference to the 
+                        * thread descriptor we are
+                        * handling.
+                        */
+                       CurrentT = CONTAINING_RECORD(
+                                       CurrentEntryT,
+                                       KTHREAD, 
+                                       ThreadListEntry
+                                       );
+                       /*
+                        * Write thread data.
+                        */
+                       RtlZeroMemory (
+                               pInfoT,
+                               sizeof (SYSTEM_THREAD_INFORMATION)
+                               );
+                       pInfoT->KernelTime      = CurrentT-> ;  /* TIME */
+                       pInfoT->UserTime        = CurrentT-> ;  /* TIME */
+                       pInfoT->CreateTime      = CurrentT-> ;  /* TIME */
+                       pInfoT->TickCount       = CurrentT-> ;  /* ULONG */
+                       pInfoT->StartEIP        = CurrentT-> ;  /* ULONG */
+                       pInfoT->ClientId        = CurrentT-> ;  /* CLIENT_ID */
+                       pInfoT->ClientId        = CurrentT-> ;  /* CLIENT_ID */
+                       pInfoT->DynamicPriority = CurrentT-> ;  /* ULONG */
+                       pInfoT->BasePriority    = CurrentT-> ;  /* ULONG */
+                       pInfoT->nSwitches       = CurrentT-> ;  /* ULONG */
+                       pInfoT->State           = CurrentT-> ;  /* DWORD */
+                       pInfoT->WaitReason      = CurrentT-> ;  /* KWAIT_REASON */
+                       /*
+                        * Count the number of threads 
+                        * this process has.
+                        */
+                       ++ pInfoP->ThreadCount;
+               }
+               /*
+                * Save the size of information
+                * stored in the buffer for the
+                * current process.
+                */
+               pInfoP->RelativeOffset = SpiSize;
+               /*
+                * Save a reference to the last
+                * valid information block.
+                */
+               pInfoPLast = pInfoP;
+               /*
+                * Compute the offset of the 
+                * SYSTEM_PROCESS_INFORMATION
+                * descriptor in the snapshot 
+                * buffer for the next process.
+                */
+               (ULONG) pInfoP += SpiSize;
+       }
+       /*
+        * Unlock the process list.
+        */
+       ExReleaseFastMutex (
+               & PspActiveProcessMutex
+               );
+       /*
+        * Return the proper error status code,
+        * if the buffer was too small.
+        */
+       if (TRUE == SizeOnly)
+       {
+               if (NULL != RequiredSize)
+               {
+                       *pRequiredSize = RequiredSize;
+               }
+               return STATUS_INFO_LENGTH_MISMATCH;
+       }
+       /*
+        * Mark the end of the snapshot.
+        */
+       pInfoP->RelativeOffset = 0L;
+       /* OK */        
+       return STATUS_SUCCESS;
+#endif
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS STDCALL
+NtSetInformationThread (IN HANDLE ThreadHandle,
+                       IN THREADINFOCLASS ThreadInformationClass,
+                       IN PVOID ThreadInformation,
+                       IN ULONG ThreadInformationLength)
+{
+  PETHREAD Thread;
+  NTSTATUS Status;
+  union
+  {
+     KPRIORITY Priority;
+     LONG Increment;
+     KAFFINITY Affinity;
+     HANDLE Handle;
+     PVOID Address;
+  }u;
+  
+  PAGED_CODE();
+
+  if (ThreadInformationClass <= MaxThreadInfoClass &&
+      !SetInformationData[ThreadInformationClass].Implemented)
+    {
+      return STATUS_NOT_IMPLEMENTED;
+    }
+  if (ThreadInformationClass > MaxThreadInfoClass ||
+      SetInformationData[ThreadInformationClass].Size == 0)
+    {
+      return STATUS_INVALID_INFO_CLASS;
+    }
+  if (ThreadInformationLength != SetInformationData[ThreadInformationClass].Size)
+    {
+      return STATUS_INFO_LENGTH_MISMATCH;
+    }
+
+  Status = ObReferenceObjectByHandle (ThreadHandle,
+                                     THREAD_SET_INFORMATION,
+                                     PsThreadType,
+                                     ExGetPreviousMode (),
+                                     (PVOID*)&Thread,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+
+   Status = MmCopyFromCaller(&u.Priority,
+                            ThreadInformation,
+                            SetInformationData[ThreadInformationClass].Size);
+   if (NT_SUCCESS(Status))
+     {
+       switch (ThreadInformationClass)
+         {
+           case ThreadPriority:
+            if (u.Priority < LOW_PRIORITY || u.Priority >= MAXIMUM_PRIORITY)
+              {
+                Status = STATUS_INVALID_PARAMETER;
+                break;
+              }
+            KeSetPriorityThread(&Thread->Tcb, u.Priority);
+            break;
+       
+           case ThreadBasePriority:
+            KeSetBasePriorityThread (&Thread->Tcb, u.Increment);
+            break;
+       
+           case ThreadAffinityMask:
+            Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
+            break;
+       
+           case ThreadImpersonationToken:
+            Status = PsAssignImpersonationToken (Thread, u.Handle);
+            break;
+               
+           case ThreadQuerySetWin32StartAddress:
+            Thread->Win32StartAddress = u.Address;
+            break;
+
+           default:
+            /* Shoult never occure if the data table is correct */
+            KEBUGCHECK(0);
+        }
+     }
+  ObDereferenceObject (Thread);
+
+  return Status;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+NtQueryInformationThread (IN   HANDLE          ThreadHandle,
+                         IN    THREADINFOCLASS ThreadInformationClass,
+                         OUT   PVOID           ThreadInformation,
+                         IN    ULONG           ThreadInformationLength,
+                         OUT   PULONG          ReturnLength  OPTIONAL)
+{
+   PETHREAD Thread;
+   NTSTATUS Status;
+   union
+   {
+      THREAD_BASIC_INFORMATION TBI;
+      KERNEL_USER_TIMES TTI;
+      PVOID Address;
+      LARGE_INTEGER Count;
+      BOOLEAN Last;
+   }u;
+   
+   PAGED_CODE();
+
+   if (ThreadInformationClass <= MaxThreadInfoClass &&
+       !QueryInformationData[ThreadInformationClass].Implemented)
+     {
+       return STATUS_NOT_IMPLEMENTED;
+     }
+   if (ThreadInformationClass > MaxThreadInfoClass ||
+       QueryInformationData[ThreadInformationClass].Size == 0)
+     {
+       return STATUS_INVALID_INFO_CLASS;
+     }
+   if (ThreadInformationLength != QueryInformationData[ThreadInformationClass].Size)
+     {
+       return STATUS_INFO_LENGTH_MISMATCH;
+     }
+
+   Status = ObReferenceObjectByHandle(ThreadHandle,
+                                     THREAD_QUERY_INFORMATION,
+                                     PsThreadType,
+                                     ExGetPreviousMode(),
+                                     (PVOID*)&Thread,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+
+   switch (ThreadInformationClass)
+     {
+       case ThreadBasicInformation:
+         /* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING
+          * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is 
+          * 0. So do the conversion here:
+          * -Gunnar     */
+         u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus;
+        u.TBI.TebBaseAddress = Thread->Tcb.Teb;
+        u.TBI.ClientId = Thread->Cid;
+        u.TBI.AffinityMask = Thread->Tcb.Affinity;
+        u.TBI.Priority = Thread->Tcb.Priority;
+        u.TBI.BasePriority = Thread->Tcb.BasePriority;
+        break;
+       
+       case ThreadTimes:
+        u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL;
+         u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL;
+         u.TTI.CreateTime = Thread->CreateTime;
+         /*This works*/
+        u.TTI.ExitTime = Thread->ExitTime;
+         break;
+
+       case ThreadQuerySetWin32StartAddress:
+         u.Address = Thread->Win32StartAddress;
+         break;
+
+       case ThreadPerformanceCount:
+         /* Nebbett says this class is always zero */
+         u.Count.QuadPart = 0;
+         break;
+
+       case ThreadAmILastThread:
+         if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
+            &Thread->ThreadsProcess->ThreadListHead)
+          {
+            u.Last = TRUE;
+          }
+         else
+          {
+            u.Last = FALSE;
+          }
+         break;
+       default:
+        /* Shoult never occure if the data table is correct */
+        KEBUGCHECK(0);
+     }
+   if (QueryInformationData[ThreadInformationClass].Size)
+     {
+       Status = MmCopyToCaller(ThreadInformation,
+                               &u.TBI,
+                              QueryInformationData[ThreadInformationClass].Size);
+     }
+   if (ReturnLength)
+     {
+       NTSTATUS Status2;
+       static ULONG Null = 0;
+       Status2 = MmCopyToCaller(ReturnLength,
+                               NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
+                               sizeof(ULONG));
+       if (NT_SUCCESS(Status))
+         {
+          Status = Status2;
+        }
+     }
+
+   ObDereferenceObject(Thread);
+   return(Status);
+}
+/* EOF */
diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c
new file mode 100644 (file)
index 0000000..ef076b3
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ps/security.c
+ * PURPOSE:         Process Manager Security (Tokens, Impersionation)
+ *
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS 
+STDCALL 
+NtOpenProcessToken(IN HANDLE ProcessHandle,
+                   IN ACCESS_MASK DesiredAccess,
+                   OUT PHANDLE TokenHandle)
+{
+    return NtOpenProcessTokenEx(ProcessHandle,
+                                DesiredAccess,
+                                0,
+                                TokenHandle);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+NtOpenProcessTokenEx(IN HANDLE ProcessHandle,
+                     IN ACCESS_MASK DesiredAccess,
+                     IN ULONG HandleAttributes,
+                     OUT PHANDLE TokenHandle)
+{
+   PACCESS_TOKEN Token;
+   HANDLE hToken;
+   KPROCESSOR_MODE PreviousMode;
+   NTSTATUS Status = STATUS_SUCCESS;
+   
+   PAGED_CODE();
+   
+   PreviousMode = ExGetPreviousMode();
+   
+   if(PreviousMode == UserMode)
+   {
+     _SEH_TRY
+     {
+       ProbeForWrite(TokenHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+     }
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
+     {
+       return Status;
+     }
+   }
+
+   Status = PsOpenTokenOfProcess(ProcessHandle,
+                                &Token);
+   if(NT_SUCCESS(Status))
+   {
+     Status = ObCreateHandle(PsGetCurrentProcess(),
+                            Token,
+                            DesiredAccess,
+                            FALSE,
+                            &hToken);
+     ObDereferenceObject(Token);
+
+     if(NT_SUCCESS(Status))
+     {
+       _SEH_TRY
+       {
+         *TokenHandle = hToken;
+       }
+       _SEH_HANDLE
+       {
+         Status = _SEH_GetExceptionCode();
+       }
+       _SEH_END;
+     }
+   }
+   
+   return Status;
+}
+
+/*
+ * @implemented
+ */
+PACCESS_TOKEN 
+STDCALL
+PsReferencePrimaryToken(PEPROCESS Process)
+{
+    /* Reference and return the Token */
+    ObReferenceObjectByPointer(Process->Token,
+                               TOKEN_ALL_ACCESS,
+                               SepTokenObjectType,
+                               KernelMode);
+    return(Process->Token);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+STDCALL
+PsOpenTokenOfProcess(HANDLE ProcessHandle,
+                     PACCESS_TOKEN* Token)
+{
+    PEPROCESS Process;
+    NTSTATUS Status;
+   
+    /* Get the Token */
+    Status = ObReferenceObjectByHandle(ProcessHandle,
+                                       PROCESS_QUERY_INFORMATION,
+                                       PsProcessType,
+                                       ExGetPreviousMode(),
+                                       (PVOID*)&Process,
+                                       NULL);
+    
+    /* Reference it */
+    if(NT_SUCCESS(Status)) {
+        
+        *Token = PsReferencePrimaryToken(Process);
+        ObDereferenceObject(Process);
+    }
+   
+    /* Return */
+    return Status;
+}
+
+NTSTATUS
+STDCALL
+PspAssignPrimaryToken(PEPROCESS Process,
+                      HANDLE TokenHandle)
+{
+    PACCESS_TOKEN Token;
+    PACCESS_TOKEN OldToken;
+    NTSTATUS Status;
+   
+    /* Reference the Token */
+    Status = ObReferenceObjectByHandle(TokenHandle,
+                                       0,
+                                       SepTokenObjectType,
+                                       KeGetPreviousMode(),
+                                       (PVOID*)&Token,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) {
+
+        return(Status);
+    }
+    
+    /* Exchange them */
+    Status = SeExchangePrimaryToken(Process, Token, &OldToken);
+        
+    /* Derefernece Tokens and Return */
+    if (NT_SUCCESS(Status)) ObDereferenceObject(OldToken);
+    ObDereferenceObject(Token);
+    return(Status);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS 
+STDCALL
+PsAssignImpersonationToken(PETHREAD Thread,
+                           HANDLE TokenHandle)
+{
+    PACCESS_TOKEN Token;
+    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+    NTSTATUS Status;
+
+    if (TokenHandle != NULL) {
+
+        Status = ObReferenceObjectByHandle(TokenHandle,
+                                           TOKEN_IMPERSONATE,
+                                           SepTokenObjectType,
+                                           KeGetPreviousMode(),
+                                           (PVOID*)&Token,
+                                           NULL);
+        
+        if (!NT_SUCCESS(Status)) {
+            
+            return(Status);
+        }
+        
+        ImpersonationLevel = SeTokenImpersonationLevel(Token);
+    
+    } else {
+        
+        Token = NULL;
+        ImpersonationLevel = 0;
+    }
+
+    PsImpersonateClient(Thread,
+                        Token,
+                        FALSE,
+                        FALSE,
+                        ImpersonationLevel);
+    
+    if (Token != NULL) ObDereferenceObject(Token);
+    return(STATUS_SUCCESS);
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+PsRevertToSelf (VOID)
+{
+    PsRevertThreadToSelf(PsGetCurrentThread());
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+PsRevertThreadToSelf(IN PETHREAD Thread)
+{
+    if (Thread->ActiveImpersonationInfo == TRUE) {
+        
+        ObDereferenceObject (Thread->ImpersonationInfo->Token);
+        Thread->ActiveImpersonationInfo = FALSE;
+    }
+}
+
+/*
+ * @implemented
+ */
+VOID 
+STDCALL
+PsImpersonateClient(IN PETHREAD Thread,
+                    IN PACCESS_TOKEN Token,
+                    IN BOOLEAN CopyOnOpen,
+                    IN BOOLEAN EffectiveOnly,
+                    IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
+{
+    
+    if (Token == NULL) {
+      
+        if (Thread->ActiveImpersonationInfo == TRUE) {
+            
+            Thread->ActiveImpersonationInfo = FALSE;
+            
+            if (Thread->ImpersonationInfo->Token != NULL) {
+                
+                ObDereferenceObject (Thread->ImpersonationInfo->Token);
+            }
+        }
+        
+        return;
+    }
+
+    if (Thread->ImpersonationInfo == NULL) {
+        
+        Thread->ImpersonationInfo = ExAllocatePool(NonPagedPool,
+                                                   sizeof(PS_IMPERSONATION_INFORMATION));
+    }
+
+    Thread->ImpersonationInfo->ImpersonationLevel = ImpersonationLevel;
+    Thread->ImpersonationInfo->CopyOnOpen = CopyOnOpen;
+    Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
+    Thread->ImpersonationInfo->Token = Token;
+    
+    ObReferenceObjectByPointer(Token,
+                               0,
+                               SepTokenObjectType,
+                               KernelMode);
+    
+    Thread->ActiveImpersonationInfo = TRUE;
+}
+
+
+PACCESS_TOKEN
+STDCALL
+PsReferenceEffectiveToken(PETHREAD Thread,
+                          PTOKEN_TYPE TokenType,
+                          PBOOLEAN EffectiveOnly,
+                          PSECURITY_IMPERSONATION_LEVEL Level)
+{
+    PEPROCESS Process;
+    PACCESS_TOKEN Token;
+   
+    if (Thread->ActiveImpersonationInfo == FALSE) {
+        
+        Process = Thread->ThreadsProcess;
+        *TokenType = TokenPrimary;
+        *EffectiveOnly = FALSE;
+        Token = Process->Token;
+    
+    } else {
+
+        Token = Thread->ImpersonationInfo->Token;
+        *TokenType = TokenImpersonation;
+        *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
+        *Level = Thread->ImpersonationInfo->ImpersonationLevel;
+    }
+    
+    return(Token);
+}
+
+NTSTATUS 
+STDCALL
+NtImpersonateThread(IN HANDLE ThreadHandle,
+                    IN HANDLE ThreadToImpersonateHandle,
+                    IN PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService)
+{
+  SECURITY_QUALITY_OF_SERVICE SafeServiceQoS;
+  SECURITY_CLIENT_CONTEXT ClientContext;
+  PETHREAD Thread;
+  PETHREAD ThreadToImpersonate;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  if(PreviousMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(SecurityQualityOfService,
+                   sizeof(SECURITY_QUALITY_OF_SERVICE),
+                   sizeof(ULONG));
+      SafeServiceQoS = *SecurityQualityOfService;
+      SecurityQualityOfService = &SafeServiceQoS;
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(!NT_SUCCESS(Status))
+    {
+      return Status;
+    }
+  }
+
+  Status = ObReferenceObjectByHandle(ThreadHandle,
+                                    THREAD_IMPERSONATE,
+                                    PsThreadType,
+                                    PreviousMode,
+                                    (PVOID*)&Thread,
+                                    NULL);
+  if(NT_SUCCESS(Status))
+  {
+    Status = ObReferenceObjectByHandle(ThreadToImpersonateHandle,
+                                      THREAD_DIRECT_IMPERSONATION,
+                                      PsThreadType,
+                                      PreviousMode,
+                                      (PVOID*)&ThreadToImpersonate,
+                                      NULL);
+    if(NT_SUCCESS(Status))
+    {
+      Status = SeCreateClientSecurity(ThreadToImpersonate,
+                                     SecurityQualityOfService,
+                                     0,
+                                    &ClientContext);
+      if(NT_SUCCESS(Status))
+      {
+        SeImpersonateClient(&ClientContext,
+                           Thread);
+        if(ClientContext.ClientToken != NULL)
+        {
+          ObDereferenceObject (ClientContext.ClientToken);
+        }
+      }
+
+      ObDereferenceObject(ThreadToImpersonate);
+    }
+    ObDereferenceObject(Thread);
+  }
+
+  return Status;
+}
+
+/*
+ * @implemented
+ */
+PACCESS_TOKEN 
+STDCALL
+PsReferenceImpersonationToken(IN PETHREAD Thread,
+                              OUT PBOOLEAN CopyOnOpen,
+                              OUT PBOOLEAN EffectiveOnly,
+                              OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
+{
+    
+    if (Thread->ActiveImpersonationInfo == FALSE) {
+        
+        return NULL;
+    }
+
+    *ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
+    *CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
+    *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
+    
+    ObReferenceObjectByPointer(Thread->ImpersonationInfo->Token,
+                               TOKEN_ALL_ACCESS,
+                               SepTokenObjectType,
+                               KernelMode);
+
+    return Thread->ImpersonationInfo->Token;
+}
+
+#ifdef PsDereferencePrimaryToken
+#undef PsDereferenceImpersonationToken
+#endif
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+PsDereferenceImpersonationToken(IN PACCESS_TOKEN ImpersonationToken)
+{
+    if (ImpersonationToken) {
+        
+        ObDereferenceObject(ImpersonationToken);
+    }
+}
+
+#ifdef PsDereferencePrimaryToken
+#undef PsDereferencePrimaryToken
+#endif
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+PsDereferencePrimaryToken(IN PACCESS_TOKEN PrimaryToken)
+{
+    ObDereferenceObject(PrimaryToken);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+PsDisableImpersonation(IN PETHREAD Thread,
+                       IN PSE_IMPERSONATION_STATE ImpersonationState)
+{
+    if (Thread->ActiveImpersonationInfo == FALSE) {
+        ImpersonationState->Token = NULL;
+        ImpersonationState->CopyOnOpen = FALSE;
+        ImpersonationState->EffectiveOnly = FALSE;
+        ImpersonationState->Level = 0;
+        return TRUE;
+    }
+
+/* FIXME */
+/*   ExfAcquirePushLockExclusive(&Thread->ThreadLock); */
+
+    Thread->ActiveImpersonationInfo = FALSE;
+    ImpersonationState->Token = Thread->ImpersonationInfo->Token;
+    ImpersonationState->CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
+    ImpersonationState->EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
+    ImpersonationState->Level = Thread->ImpersonationInfo->ImpersonationLevel;
+
+/* FIXME */
+/*   ExfReleasePushLock(&Thread->ThreadLock); */
+
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */                       
+VOID
+STDCALL
+PsRestoreImpersonation(IN PETHREAD Thread,
+                       IN PSE_IMPERSONATION_STATE ImpersonationState)
+{
+    
+    PsImpersonateClient(Thread, 
+                        ImpersonationState->Token,
+                        ImpersonationState->CopyOnOpen,
+                        ImpersonationState->EffectiveOnly,
+                        ImpersonationState->Level);
+    
+    ObfDereferenceObject(ImpersonationState->Token);
+}
+
+/* EOF */
index 7e1d56e..579a5c2 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
-/* NOTES **********************************************************************
- *
- */
-
-/* GLOBALS *******************************************************************/
-
-static FAST_MUTEX SuspendMutex;
+ULONG
+STDCALL
+KeResumeThread(PKTHREAD Thread);
 
+ULONG
+STDCALL
+KeSuspendThread(PKTHREAD Thread);
 /* FUNCTIONS *****************************************************************/
 
-VOID STDCALL
-PiSuspendThreadRundownRoutine(PKAPC Apc)
-{
-}
-
-
-VOID STDCALL
-PiSuspendThreadKernelRoutine(PKAPC Apc,
-                            PKNORMAL_ROUTINE* NormalRoutine,
-                            PVOID* NormalContext,
-                            PVOID* SystemArgument1,
-                            PVOID* SystemArguemnt2)
-{
-}
-
-
-VOID STDCALL
-PiSuspendThreadNormalRoutine(PVOID NormalContext,
-                            PVOID SystemArgument1,
-                            PVOID SystemArgument2)
-{
-  PETHREAD CurrentThread = PsGetCurrentThread();
-  while (CurrentThread->Tcb.SuspendCount > 0)
-    {
-      KeWaitForSingleObject(&CurrentThread->Tcb.SuspendSemaphore,
-                           0,
-                           UserMode,
-                           TRUE,
-                           NULL);
-    }
-}
-
-
-NTSTATUS
-PsResumeThread (PETHREAD Thread,
-               PULONG SuspendCount)
-{
-  DPRINT("PsResumeThread (Thread %p  SuspendCount %p) called\n");
-
-  ExAcquireFastMutex (&SuspendMutex);
-
-  if (SuspendCount != NULL)
-    {
-      *SuspendCount = Thread->Tcb.SuspendCount;
-    }
-
-  if (Thread->Tcb.SuspendCount > 0)
-    {
-      Thread->Tcb.SuspendCount--;
-      if (Thread->Tcb.SuspendCount == 0)
-       {
-         KeReleaseSemaphore (&Thread->Tcb.SuspendSemaphore,
-                             IO_NO_INCREMENT,
-                             1,
-                             FALSE);
-       }
-    }
-
-  ExReleaseFastMutex (&SuspendMutex);
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
-{
-  ULONG OldValue;
-
-  ExAcquireFastMutex(&SuspendMutex);
-  OldValue = Thread->Tcb.SuspendCount;
-  Thread->Tcb.SuspendCount++;
-  if (!Thread->Tcb.SuspendApc.Inserted)
-    {
-      if (!KeInsertQueueApc(&Thread->Tcb.SuspendApc,
-                           NULL,
-                           NULL,
-                           IO_NO_INCREMENT))
-       {
-         Thread->Tcb.SuspendCount--;
-         ExReleaseFastMutex(&SuspendMutex);
-         return(STATUS_THREAD_IS_TERMINATING);
-       }
-    }
-  ExReleaseFastMutex(&SuspendMutex);
-  if (PreviousSuspendCount != NULL)
-    {
-      *PreviousSuspendCount = OldValue;
-    }
-  return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL
-NtResumeThread(IN HANDLE ThreadHandle,
-              IN PULONG SuspendCount  OPTIONAL)
 /*
  * FUNCTION: Decrements a thread's resume count
  * ARGUMENTS: 
@@ -127,48 +30,74 @@ NtResumeThread(IN HANDLE ThreadHandle,
  *        ResumeCount =  The resulting resume count.
  * RETURNS: Status
  */
+NTSTATUS
+STDCALL
+NtResumeThread(IN HANDLE ThreadHandle,
+               IN PULONG SuspendCount  OPTIONAL)
 {
-  PETHREAD Thread;
-  NTSTATUS Status;
-  ULONG Count;
+    PETHREAD Thread;
+    ULONG Prev;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
-
-  DPRINT("NtResumeThead(ThreadHandle %lx  SuspendCount %p)\n",
-        ThreadHandle, SuspendCount);
-
-  Status = ObReferenceObjectByHandle (ThreadHandle,
-                                     THREAD_SUSPEND_RESUME,
-                                     PsThreadType,
-                                     UserMode,
-                                     (PVOID*)&Thread,
-                                     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return Status;
+    PAGED_CODE();
+    
+    PreviousMode = ExGetPreviousMode();
+
+    DPRINT("NtResumeThead(ThreadHandle %lx  SuspendCount %p)\n",
+           ThreadHandle, SuspendCount);
+    
+    /* Check buffer validity */
+    if(SuspendCount && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(SuspendCount,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
     }
 
-  Status = PsResumeThread (Thread, &Count);
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject ((PVOID)Thread);
-      return Status;
+    /* Get the Thread Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_SUSPEND_RESUME,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) {
+        
+        return Status;
     }
-
-  if (SuspendCount != NULL)
-    {
-      *SuspendCount = Count;
+    
+    /* Call the Kernel Function */
+    Prev = KeResumeThread(&Thread->Tcb);
+    
+    /* Return it */        
+    if(SuspendCount) {
+            
+        _SEH_TRY {
+                
+            *SuspendCount = Prev;
+            
+        } _SEH_HANDLE {
+                
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
     }
 
-  ObDereferenceObject ((PVOID)Thread);
-
-  return STATUS_SUCCESS;
+    /* Dereference and Return */
+    ObDereferenceObject ((PVOID)Thread);
+    return Status;
 }
 
-
-NTSTATUS STDCALL
-NtSuspendThread(IN HANDLE ThreadHandle,
-               IN PULONG PreviousSuspendCount  OPTIONAL)
 /*
  * FUNCTION: Increments a thread's suspend count
  * ARGUMENTS: 
@@ -182,45 +111,69 @@ NtSuspendThread(IN HANDLE ThreadHandle,
  *        MAXIMUM_SUSPEND_COUNT.
  * RETURNS: Status
  */
+NTSTATUS 
+STDCALL
+NtSuspendThread(IN HANDLE ThreadHandle,
+                IN PULONG PreviousSuspendCount  OPTIONAL)
 {
-  PETHREAD Thread;
-  NTSTATUS Status;
-  ULONG Count;
+    PETHREAD Thread;
+    ULONG Prev;
+    KPROCESSOR_MODE PreviousMode;
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
-
-  Status = ObReferenceObjectByHandle(ThreadHandle,
-                                    THREAD_SUSPEND_RESUME,
-                                    PsThreadType,
-                                    UserMode,
-                                    (PVOID*)&Thread,
-                                    NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
+    PAGED_CODE();
+    
+    PreviousMode = ExGetPreviousMode();
+    
+    /* Check buffer validity */
+    if(PreviousSuspendCount && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousSuspendCount,
+                          sizeof(ULONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
     }
 
-  Status = PsSuspendThread(Thread, &Count);
-  if (!NT_SUCCESS(Status))
-    {
-      ObDereferenceObject ((PVOID)Thread);
-      return Status;
+    /* Get the Thread Object */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                                       THREAD_SUSPEND_RESUME,
+                                       PsThreadType,
+                                       PreviousMode,
+                                       (PVOID*)&Thread,
+                                       NULL);
+    if (!NT_SUCCESS(Status)) {
+        
+        return Status;
     }
-
-  if (PreviousSuspendCount != NULL)
-    {
-      *PreviousSuspendCount = Count;
+    
+    /* Call the Kernel Function */
+    Prev = KeSuspendThread(&Thread->Tcb);
+    
+    /* Return it */        
+    if(PreviousSuspendCount) {
+            
+        _SEH_TRY {
+                
+            *PreviousSuspendCount = Prev;
+            
+        } _SEH_HANDLE {
+                
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
     }
 
-  ObDereferenceObject ((PVOID)Thread);
-
-  return STATUS_SUCCESS;
-}
-
-VOID INIT_FUNCTION
-PsInitialiseSuspendImplementation(VOID)
-{
-  ExInitializeFastMutex(&SuspendMutex);
+    /* Dereference and Return */
+    ObDereferenceObject((PVOID)Thread);
+    return Status;
 }
 
 /* EOF */
index ee9ad92..952ff73 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
-/* TYPES *******************************************************************/
-
 /* GLOBALS ******************************************************************/
 
 extern LIST_ENTRY PsActiveProcessHead;
+extern PEPROCESS PsIdleProcess;
 
 POBJECT_TYPE EXPORTED PsThreadType = NULL;
 
-LONG PiNrThreadsAwaitingReaping = 0;
-
 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+extern ULONG IdleProcessorMask;
+extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
 
-/*
- * PURPOSE: List of threads associated with each priority level
- */
-static LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
-static ULONG PriorityListMask = 0;
-static ULONG IdleProcessorMask = 0;
-static BOOLEAN DoneInitYet = FALSE;
-static KEVENT PiReaperThreadEvent;
-static BOOLEAN PiReaperThreadShouldTerminate = FALSE;
 
+BOOLEAN DoneInitYet = FALSE;
 static GENERIC_MAPPING PiThreadMapping = {STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
                                          STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_ALERT |
                       THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
@@ -63,11 +54,11 @@ PKTHREAD STDCALL KeGetCurrentThread(VOID)
    PKTHREAD Thread;
    Ke386SaveFlags(Flags);
    Ke386DisableInterrupts();
-   Thread = KeGetCurrentKPCR()->PrcbData.CurrentThread;
+   Thread = KeGetCurrentPrcb()->CurrentThread;
    Ke386RestoreFlags(Flags);
    return Thread;
 #else
-   return(KeGetCurrentKPCR()->PrcbData.CurrentThread);
+   return(KeGetCurrentPrcb()->CurrentThread);
 #endif
 }
 
@@ -221,21 +212,18 @@ PsIsThreadTerminating(IN PETHREAD Thread)
 }
 
 /*
- * @unimplemented
- */             
+ * @implemented
+ */
 BOOLEAN
 STDCALL
-PsIsSystemThread(
-    PETHREAD Thread
-    )
+PsIsSystemThread(PETHREAD Thread)
 {
-       UNIMPLEMENTED;
-       return FALSE;   
+    return (Thread->SystemThread ? TRUE: FALSE);
 }
 
 /*
  * @implemented
- */                       
+ */
 BOOLEAN
 STDCALL
 PsIsThreadImpersonating(
@@ -245,41 +233,6 @@ PsIsThreadImpersonating(
   return Thread->ActiveImpersonationInfo;
 }
 
-static VOID
-KiRequestReschedule(CCHAR Processor)
-{
-   PKPCR Pcr;
-
-   Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE);
-   Pcr->PrcbData.QuantumEnd = TRUE;
-   KiIpiSendRequest(1 << Processor, IPI_REQUEST_DPC);
-}
-
-static VOID
-PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
-{
-   ASSERT(THREAD_STATE_READY == Thread->Tcb.State);
-   ASSERT(Thread->Tcb.Priority == Priority);
-   if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY)
-     {
-       DPRINT1("Invalid thread priority (%d)\n", Priority);
-       KEBUGCHECK(0);
-     }
-   InsertTailList(&PriorityListHead[Priority], &Thread->Tcb.QueueListEntry);
-   PriorityListMask |= (1 << Priority);
-}
-
-static VOID PsRemoveFromThreadList(PETHREAD Thread)
-{
-   ASSERT(THREAD_STATE_READY == Thread->Tcb.State);
-   RemoveEntryList(&Thread->Tcb.QueueListEntry);
-   if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Tcb.Priority]))
-     {
-        PriorityListMask &= ~(1 << Thread->Tcb.Priority);
-     }
-}
-
-
 VOID PsDumpThreads(BOOLEAN IncludeSystem)
 {
    PLIST_ENTRY AThread, AProcess;
@@ -334,262 +287,6 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem)
    }
 }
 
-static PETHREAD PsScanThreadList(KPRIORITY Priority, ULONG Affinity)
-{
-   PLIST_ENTRY current_entry;
-   PETHREAD current;
-   ULONG Mask;
-
-   Mask = (1 << Priority);
-   if (PriorityListMask & Mask)
-     {
-       current_entry = PriorityListHead[Priority].Flink;
-       while (current_entry != &PriorityListHead[Priority])
-         {
-           current = CONTAINING_RECORD(current_entry, ETHREAD,
-                                      Tcb.QueueListEntry);
-          if (current->Tcb.State != THREAD_STATE_READY)
-            {
-              DPRINT1("%d/%d\n", current->Cid.UniqueThread, current->Tcb.State);
-            }
-           ASSERT(current->Tcb.State == THREAD_STATE_READY);
-           DPRINT("current->Tcb.Affinity %x Affinity %x PID %d %d\n",
-                 current->Tcb.Affinity, Affinity, current->Cid.UniqueThread,
-                 Priority);
-           if (current->Tcb.Affinity & Affinity)
-            {
-              PsRemoveFromThreadList(current);
-              return(current);
-            }
-           current_entry = current_entry->Flink;
-        }
-     }
-   return(NULL);
-}
-
-VOID STDCALL
-PiWakeupReaperThread(VOID)
-{
-  KeSetEvent(&PiReaperThreadEvent, 0, FALSE);
-}
-
-VOID STDCALL
-PiReaperThreadMain(PVOID Ignored)
-{
-  for(;;)
-  {
-    KeWaitForSingleObject(&PiReaperThreadEvent,
-                         Executive,
-                         KernelMode,
-                         FALSE,
-                         NULL);
-    if (PiReaperThreadShouldTerminate)
-       {
-         PsTerminateSystemThread(0);
-       }
-    PsReapThreads();
-  }
-}
-
-VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
-{
-   KPRIORITY CurrentPriority;
-   PETHREAD Candidate;
-   ULONG Affinity;
-   PKTHREAD KCurrentThread = KeGetCurrentThread();
-   PETHREAD CurrentThread = CONTAINING_RECORD(KCurrentThread, ETHREAD, Tcb);
-
-   DPRINT("PsDispatchThread() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
-          CurrentThread->Cid.UniqueThread, NewThreadStatus, CurrentThread->Tcb.State);
-
-   CurrentThread->Tcb.State = (UCHAR)NewThreadStatus;
-   switch(NewThreadStatus)
-   {
-     case THREAD_STATE_READY:
-       PsInsertIntoThreadList(CurrentThread->Tcb.Priority,
-                              CurrentThread);
-       break;
-     case THREAD_STATE_TERMINATED_1:
-       PsQueueThreadReap(CurrentThread);
-       break;
-   }
-
-   Affinity = 1 << KeGetCurrentProcessorNumber();
-   for (CurrentPriority = HIGH_PRIORITY;
-       CurrentPriority >= LOW_PRIORITY;
-       CurrentPriority--)
-     {
-       Candidate = PsScanThreadList(CurrentPriority, Affinity);
-       if (Candidate == CurrentThread)
-         {
-            Candidate->Tcb.State = THREAD_STATE_RUNNING;
-            KeReleaseDispatcherDatabaseLockFromDpcLevel();     
-            return;
-         }
-       if (Candidate != NULL)
-         {
-           PETHREAD OldThread;
-           PKTHREAD IdleThread;
-
-           DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
-
-           Candidate->Tcb.State = THREAD_STATE_RUNNING;
-
-           OldThread = CurrentThread;
-           CurrentThread = Candidate;
-           IdleThread = KeGetCurrentKPCR()->PrcbData.IdleThread;
-
-           if (&OldThread->Tcb == IdleThread)
-           {
-              IdleProcessorMask &= ~Affinity;
-           }
-           else if (&CurrentThread->Tcb == IdleThread)
-           {
-              IdleProcessorMask |= Affinity;
-           }
-
-           MmUpdatePageDir(PsGetCurrentProcess(),(PVOID)CurrentThread->ThreadsProcess, sizeof(EPROCESS));
-
-           KiArchContextSwitch(&CurrentThread->Tcb, &OldThread->Tcb);
-           return;
-         }
-     }
-   CPRINT("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
-   PsDumpThreads(TRUE);
-   KEBUGCHECK(0);
-}
-
-VOID STDCALL
-PsDispatchThread(ULONG NewThreadStatus)
-{
-   KIRQL oldIrql;
-
-   if (!DoneInitYet || KeGetCurrentKPCR()->PrcbData.IdleThread == NULL)
-     {
-       return;
-     }
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-   PsDispatchThreadNoLock(NewThreadStatus);
-   KeLowerIrql(oldIrql);
-}
-
-VOID
-PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment)
-{
-  if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
-      THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
-    {
-       DPRINT("Can't unblock thread %d because it's terminating\n",
-              Thread->Cid.UniqueThread);
-    }
-  else if (THREAD_STATE_READY == Thread->Tcb.State ||
-           THREAD_STATE_RUNNING == Thread->Tcb.State)
-    {
-       DPRINT("Can't unblock thread %d because it's ready or running\n",
-              Thread->Cid.UniqueThread);
-    }
-  else
-    {
-      ULONG Processor;
-      KAFFINITY Affinity;
-
-      /* FIXME: This propably isn't the right way to do it... */
-      if (Thread->Tcb.Priority < LOW_REALTIME_PRIORITY &&
-          Thread->Tcb.BasePriority < LOW_REALTIME_PRIORITY - 2)
-        {
-          if (!Thread->Tcb.PriorityDecrement && !Thread->Tcb.DisableBoost)
-            {
-              Thread->Tcb.Priority = Thread->Tcb.BasePriority + Increment;
-              Thread->Tcb.PriorityDecrement = Increment;
-            }
-        }
-      else
-        {
-          Thread->Tcb.Quantum = Thread->Tcb.ApcState.Process->ThreadQuantum;
-        }
-     
-      if (WaitStatus != NULL)
-       {
-         Thread->Tcb.WaitStatus = *WaitStatus;
-       }
-      Thread->Tcb.State = THREAD_STATE_READY;
-      PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
-      Processor = KeGetCurrentProcessorNumber();
-      Affinity = Thread->Tcb.Affinity;
-      if (!(IdleProcessorMask & (1 << Processor) & Affinity) &&
-          (IdleProcessorMask & ~(1 << Processor) & Affinity))
-        {
-         ULONG i;
-         for (i = 0; i < KeNumberProcessors - 1; i++)
-           {
-             Processor++;
-             if (Processor >= KeNumberProcessors)
-               {
-                 Processor = 0;
-               }
-             if (IdleProcessorMask & (1 << Processor) & Affinity)
-               {
-#if 0          
-                  /* FIXME:
-                   *   Reschedule the threads on an other processor 
-                   */
-                 KeReleaseDispatcherDatabaseLockFromDpcLevel();
-                  KiRequestReschedule(Processor);
-                 KeAcquireDispatcherDatabaseLockAtDpcLevel();
-#endif
-                 break;
-               }
-           }
-       } 
-    }
-}
-
-VOID
-PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
-             BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason)
-{
-  KIRQL oldIrql;
-  PKTHREAD KThread;
-  PETHREAD Thread;
-  PKWAIT_BLOCK WaitBlock;
-
-  if (!DispatcherLock)
-    {
-      oldIrql = KeAcquireDispatcherDatabaseLock();
-    }
-
-  KThread = KeGetCurrentThread();
-  Thread = CONTAINING_RECORD (KThread, ETHREAD, Tcb);
-  if (KThread->ApcState.KernelApcPending)
-  {
-    WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
-    while (WaitBlock)
-      {
-       RemoveEntryList (&WaitBlock->WaitListEntry);
-       WaitBlock = WaitBlock->NextWaitBlock;
-      }
-    Thread->Tcb.WaitBlockList = NULL;
-    PsDispatchThreadNoLock (THREAD_STATE_READY);
-    if (Status != NULL)
-      {
-       *Status = STATUS_KERNEL_APC;
-      }
-  }
-  else
-    {
-      Thread->Tcb.Alertable = Alertable;
-      Thread->Tcb.WaitMode = (UCHAR)WaitMode;
-      Thread->Tcb.WaitReason = WaitReason;
-      PsDispatchThreadNoLock(THREAD_STATE_BLOCKED);
-
-      if (Status != NULL)
-       {
-         *Status = Thread->Tcb.WaitStatus;
-       }
-    }
-  KeLowerIrql(WaitIrql);
-}
-
 VOID
 PsFreezeAllThreads(PEPROCESS Process)
      /*
@@ -641,7 +338,7 @@ PsEnumThreadsByProcess(PEPROCESS Process)
 
 /*
  * @unimplemented
- */                       
+ */
 NTSTATUS
 STDCALL
 PsRemoveCreateThreadNotifyRoutine (
@@ -704,14 +401,12 @@ VOID INIT_FUNCTION
 PsPrepareForApplicationProcessorInit(ULONG Id)
 {
   PETHREAD IdleThread;
-  HANDLE IdleThreadHandle;
-  PKPCR Pcr = (PKPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE);
+  PKPRCB Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE))->Prcb;
 
-  PsInitializeThread(NULL,
+  PsInitializeThread(PsIdleProcess,
                     &IdleThread,
-                    &IdleThreadHandle,
-                    THREAD_ALL_ACCESS,
                     NULL,
+                    KernelMode,
                     FALSE);
   IdleThread->Tcb.State = THREAD_STATE_RUNNING;
   IdleThread->Tcb.FreezeCount = 0;
@@ -719,12 +414,11 @@ PsPrepareForApplicationProcessorInit(ULONG Id)
   IdleThread->Tcb.UserAffinity = 1 << Id;
   IdleThread->Tcb.Priority = LOW_PRIORITY;
   IdleThread->Tcb.BasePriority = LOW_PRIORITY;
-  Pcr->PrcbData.IdleThread = &IdleThread->Tcb;
-  Pcr->PrcbData.CurrentThread = &IdleThread->Tcb;
+  Prcb->IdleThread = &IdleThread->Tcb;
+  Prcb->CurrentThread = &IdleThread->Tcb;
 
   Ki386InitialStackArray[Id] = (PVOID)IdleThread->Tcb.StackLimit;
 
-  NtClose(IdleThreadHandle);
   DPRINT("IdleThread for Processor %d has PID %d\n",
           Id, IdleThread->Cid.UniqueThread);
 }
@@ -735,11 +429,8 @@ PsInitThreadManagment(VOID)
  * FUNCTION: Initialize thread managment
  */
 {
-   HANDLE PiReaperThreadHandle;
    PETHREAD FirstThread;
    ULONG i;
-   HANDLE FirstThreadHandle;
-   NTSTATUS Status;
 
    for (i=0; i < MAXIMUM_PRIORITY; i++)
      {
@@ -759,7 +450,7 @@ PsInitThreadManagment(VOID)
    PsThreadType->Dump = NULL;
    PsThreadType->Open = NULL;
    PsThreadType->Close = NULL;
-   PsThreadType->Delete = PiDeleteThread;
+   PsThreadType->Delete = PspDeleteThread;
    PsThreadType->Parse = NULL;
    PsThreadType->Security = NULL;
    PsThreadType->QueryName = NULL;
@@ -771,341 +462,161 @@ PsInitThreadManagment(VOID)
 
    ObpCreateTypeObject(PsThreadType);
 
-   PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,
-                     THREAD_ALL_ACCESS,NULL, TRUE);
+   PsInitializeThread(NULL, &FirstThread, NULL, KernelMode, TRUE);
    FirstThread->Tcb.State = THREAD_STATE_RUNNING;
    FirstThread->Tcb.FreezeCount = 0;
    FirstThread->Tcb.UserAffinity = (1 << 0);   /* Set the affinity of the first thread to the boot processor */
    FirstThread->Tcb.Affinity = (1 << 0);
-   KeGetCurrentKPCR()->PrcbData.CurrentThread = (PVOID)FirstThread;
-   NtClose(FirstThreadHandle);
+   KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread;
 
    DPRINT("FirstThread %x\n",FirstThread);
 
    DoneInitYet = TRUE;
-
-   /*
-    * Create the reaper thread
-    */
-   PsInitializeThreadReaper();
-   KeInitializeEvent(&PiReaperThreadEvent, SynchronizationEvent, FALSE);
-   Status = PsCreateSystemThread(&PiReaperThreadHandle,
-                                THREAD_ALL_ACCESS,
-                                NULL,
-                                NULL,
-                                NULL,
-                                PiReaperThreadMain,
-                                NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       DPRINT1("PS: Failed to create reaper thread.\n");
-       KEBUGCHECK(0);
-     }
-
-   NtClose(PiReaperThreadHandle);
+   
+   ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
 }
 
-/*
- * @implemented
- */
-LONG STDCALL
-KeSetBasePriorityThread (PKTHREAD      Thread,
-                        LONG           Increment)
-/*
- * Sets thread's base priority relative to the process' base priority
- * Should only be passed in THREAD_PRIORITY_ constants in pstypes.h
+/**********************************************************************
+ *     NtOpenThread/4
+ *
+ *     @implemented
  */
+NTSTATUS STDCALL
+NtOpenThread(OUT PHANDLE ThreadHandle,
+            IN ACCESS_MASK DesiredAccess,
+            IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+            IN PCLIENT_ID ClientId  OPTIONAL)
 {
-   KPRIORITY Priority;
-   if (Increment < -2)
+   KPROCESSOR_MODE PreviousMode;
+   CLIENT_ID SafeClientId;
+   HANDLE hThread;
+   NTSTATUS Status = STATUS_SUCCESS;
+
+   PAGED_CODE();
+
+   PreviousMode = ExGetPreviousMode();
+
+   if(PreviousMode != KernelMode)
+   {
+     _SEH_TRY
      {
-       Increment = -2;
+       ProbeForWrite(ThreadHandle,
+                     sizeof(HANDLE),
+                     sizeof(ULONG));
+       if(ClientId != NULL)
+       {
+         ProbeForRead(ClientId,
+                      sizeof(CLIENT_ID),
+                      sizeof(ULONG));
+         SafeClientId = *ClientId;
+         ClientId = &SafeClientId;
+       }
      }
-   else if (Increment > 2)
+     _SEH_HANDLE
      {
-       Increment = 2;
+       Status = _SEH_GetExceptionCode();
      }
-   Priority = ((PETHREAD)Thread)->ThreadsProcess->Pcb.BasePriority + Increment;
-   if (Priority < LOW_PRIORITY)
-   {
-     Priority = LOW_PRIORITY;
-   }
-   else if (Priority >= MAXIMUM_PRIORITY)
+     _SEH_END;
+
+     if(!NT_SUCCESS(Status))
      {
-       Thread->BasePriority = HIGH_PRIORITY;
+       return Status;
      }
-   KeSetPriorityThread(Thread, Priority);
-   return 1;
-}
+   }
 
+   if(!((ObjectAttributes == NULL) ^ (ClientId == NULL)))
+   {
+     DPRINT("NtOpenThread should be called with either ObjectAttributes or ClientId!\n");
+     return STATUS_INVALID_PARAMETER;
+   }
 
-/*
- * @implemented
- */
-KPRIORITY STDCALL
-KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority)
-{
-   KPRIORITY OldPriority;
-   KIRQL oldIrql;
-   PKTHREAD CurrentThread;
-   ULONG Mask;
-   int i;
-   PKPCR Pcr;
+   if(ClientId != NULL)
+   {
+     PETHREAD Thread;
 
-   if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
+     Status = PsLookupThreadByThreadId(ClientId->UniqueThread,
+                                       &Thread);
+     if(NT_SUCCESS(Status))
      {
-       KEBUGCHECK(0);
+       Status = ObInsertObject(Thread,
+                               NULL,
+                               DesiredAccess,
+                               0,
+                               NULL,
+                               &hThread);
+
+       ObDereferenceObject(Thread);
      }
+   }
+   else
+   {
+     Status = ObOpenObjectByName(ObjectAttributes,
+                                 PsThreadType,
+                                 NULL,
+                                 PreviousMode,
+                                 DesiredAccess,
+                                 NULL,
+                                 &hThread);
+   }
 
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-
-   OldPriority = Thread->Priority;
-
-   if (OldPriority != Priority)
+   if(NT_SUCCESS(Status))
+   {
+     _SEH_TRY
      {
-       CurrentThread = KeGetCurrentThread();
-       if (Thread->State == THREAD_STATE_READY)
-         {
-          PsRemoveFromThreadList((PETHREAD)Thread);
-           Thread->BasePriority = Thread->Priority = (CHAR)Priority;
-          PsInsertIntoThreadList(Priority, (PETHREAD)Thread);
-          if (CurrentThread->Priority < Priority)
-            {
-               PsDispatchThreadNoLock(THREAD_STATE_READY);
-               KeLowerIrql(oldIrql);
-              return (OldPriority);
-            }
-        }
-       else if (Thread->State == THREAD_STATE_RUNNING)
-         {
-           Thread->BasePriority = Thread->Priority = (CHAR)Priority;
-          if (Priority < OldPriority)
-            {
-              /* Check for threads with a higher priority */
-              Mask = ~((1 << (Priority + 1)) - 1);
-              if (PriorityListMask & Mask)
-                {
-                  if (Thread == CurrentThread)
-                    {
-                       PsDispatchThreadNoLock(THREAD_STATE_READY);
-                       KeLowerIrql(oldIrql);
-                      return (OldPriority);
-                    }
-                  else
-                    {
-                      for (i = 0; i < KeNumberProcessors; i++)
-                      {
-                         Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-                         if (Pcr->PrcbData.CurrentThread == Thread)
-                         {
-                           KeReleaseDispatcherDatabaseLockFromDpcLevel();
-                            KiRequestReschedule(i);
-                            KeLowerIrql(oldIrql);
-                           return (OldPriority);
-                         }
-                      }
-                    }
-                }
-            }
-        }
-       else
-         {
-            Thread->BasePriority = Thread->Priority = (CHAR)Priority;
-         }
+       *ThreadHandle = hThread;
      }
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-   return(OldPriority);
+     _SEH_HANDLE
+     {
+       Status = _SEH_GetExceptionCode();
+     }
+     _SEH_END;
+   }
+
+   return Status;
 }
 
-/*
- * @unimplemented
- */
 NTSTATUS STDCALL
-KeSetAffinityThread(PKTHREAD   Thread,
-                   KAFFINITY   Affinity)
-/*
- * Sets thread's affinity
- */
+NtYieldExecution(VOID)
 {
-    KIRQL oldIrql;
-    ULONG i;
-    PKPCR Pcr;
-    KAFFINITY ProcessorMask;
-
-    DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity);
-
-    ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
-
-    oldIrql = KeAcquireDispatcherDatabaseLock();
-
-    Thread->UserAffinity = Affinity;
-    if (Thread->SystemAffinityActive == FALSE)
-    {
-       Thread->Affinity = Affinity;
-       if (Thread->State == THREAD_STATE_RUNNING)
-       {
-          ProcessorMask = 1 << KeGetCurrentKPCR()->ProcessorNumber;
-          if (Thread == KeGetCurrentThread())
-         {
-            if (!(Affinity & ProcessorMask))
-            {
-                PsDispatchThreadNoLock(THREAD_STATE_READY);
-                KeLowerIrql(oldIrql);
-               return STATUS_SUCCESS;
-            }
-         }
-         else
-         {
-            for (i = 0; i < KeNumberProcessors; i++)
-            {
-               Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-               if (Pcr->PrcbData.CurrentThread == Thread)
-               {
-                  if (!(Affinity & ProcessorMask))
-                  {
-                     KeReleaseDispatcherDatabaseLockFromDpcLevel();
-                      KiRequestReschedule(i);
-                      KeLowerIrql(oldIrql);
-                     return STATUS_SUCCESS;
-                  }
-                  break;
-               }
-            }
-            ASSERT (i < KeNumberProcessors);
-         }
-       }
-    }
-    KeReleaseDispatcherDatabaseLock(oldIrql);
-    return STATUS_SUCCESS;
+  KiDispatchThread(THREAD_STATE_READY);
+  return(STATUS_SUCCESS);
 }
 
 
-/**********************************************************************
- *     NtOpenThread/4
- *
- *     @implemented
+/*
+ * NOT EXPORTED
  */
 NTSTATUS STDCALL
-NtOpenThread(OUT PHANDLE ThreadHandle,
-            IN ACCESS_MASK DesiredAccess,
-            IN POBJECT_ATTRIBUTES ObjectAttributes,
-            IN PCLIENT_ID ClientId)
+NtTestAlert(VOID)
 {
-   NTSTATUS Status = STATUS_INVALID_PARAMETER;
-   
-   PAGED_CODE();
-
-   if((NULL != ThreadHandle)&&(NULL != ObjectAttributes))
-   {
-      PETHREAD EThread = NULL;
-
-      if((ClientId)
-       && (ClientId->UniqueThread))
-      {
-         // It is an error to specify both
-        // ObjectAttributes.ObjectName
-         // and ClientId.
-         if((ObjectAttributes)
-          && (ObjectAttributes->ObjectName)
-          && (0 < ObjectAttributes->ObjectName->Length))
-        {
-            return(STATUS_INVALID_PARAMETER_MIX);
-        }
-        // Parameters mix OK
-         Status = PsLookupThreadByThreadId(ClientId->UniqueThread,
-                     & EThread);
-      }
-      else if((ObjectAttributes)
-            && (ObjectAttributes->ObjectName)
-            && (0 < ObjectAttributes->ObjectName->Length))
-      {
-         // Three Ob attributes are forbidden
-         if(!(ObjectAttributes->Attributes &
-            (OBJ_PERMANENT | OBJ_EXCLUSIVE | OBJ_OPENIF)))
-        {
-            Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
-                        ObjectAttributes->Attributes,
-                        NULL,
-                        DesiredAccess,
-                        PsThreadType,
-                        UserMode,
-                        NULL,
-                        (PVOID*) & EThread);
-        }
-      }
-      // EThread may be OK...
-      if(STATUS_SUCCESS == Status)
-      {
-         Status = ObCreateHandle(PsGetCurrentProcess(),
-                     EThread,
-                     DesiredAccess,
-                     FALSE,
-                     ThreadHandle);
-         ObDereferenceObject(EThread);
-      }
-   }
-   return(Status);
+  /* Check and Alert Thread if needed */
+  return KeTestAlertThread(ExGetPreviousMode()) ? STATUS_ALERTED : STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL
-NtYieldExecution(VOID)
+VOID
+KeSetPreviousMode (ULONG Mode)
 {
-  PsDispatchThread(THREAD_STATE_READY);
-  return(STATUS_SUCCESS);
+  PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
-PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
-                          OUT PEPROCESS *Process OPTIONAL,
-                          OUT PETHREAD *Thread)
+KPROCESSOR_MODE STDCALL
+KeGetPreviousMode (VOID)
 {
-  PCID_OBJECT CidObject;
-  PETHREAD FoundThread;
-
-  CidObject = PsLockCidHandle((HANDLE)Cid->UniqueThread, PsThreadType);
-  if(CidObject != NULL)
-  {
-    FoundThread = CidObject->Obj.Thread;
-    ObReferenceObject(FoundThread);
-    
-    if(Process != NULL)
-    {
-      *Process = FoundThread->ThreadsProcess;
-      ObReferenceObject(FoundThread->ThreadsProcess);
-    }
-
-    PsUnlockCidObject(CidObject);
-    return STATUS_SUCCESS;
-  }
-
-  return STATUS_INVALID_PARAMETER;
+  return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
-PsLookupThreadByThreadId(IN HANDLE ThreadId,
-                        OUT PETHREAD *Thread)
+KPROCESSOR_MODE STDCALL
+ExGetPreviousMode (VOID)
 {
-  PCID_OBJECT CidObject;
-  
-  CidObject = PsLockCidHandle(ThreadId, PsThreadType);
-  if(CidObject != NULL)
-  {
-    *Thread = CidObject->Obj.Thread;
-    ObReferenceObject(*Thread);
-    
-    PsUnlockCidObject(CidObject);
-    return STATUS_SUCCESS;
-  }
-
-  return STATUS_INVALID_PARAMETER;
+  return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
 }
 
 /* EOF */
diff --git a/reactos/ntoskrnl/ps/tinfo.c b/reactos/ntoskrnl/ps/tinfo.c
deleted file mode 100644 (file)
index c9ca051..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ps/tinfo.c
- * PURPOSE:         Getting/setting thread information
- * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Skywing (skywing@valhallalegends.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* GLOBALS *****************************************************************/
-
-/*
- * FIXME:
- *   Remove the Implemented value if all functions are implemented.
- */
-
-static const struct
-{
-   BOOLEAN Implemented;
-   ULONG Size;
-} QueryInformationData[MaxThreadInfoClass + 1] = 
-{
-    {TRUE, sizeof(THREAD_BASIC_INFORMATION)},  // ThreadBasicInformation
-    {TRUE, sizeof(KERNEL_USER_TIMES)},         // ThreadTimes
-    {TRUE, 0},                                 // ThreadPriority
-    {TRUE, 0},                                 // ThreadBasePriority
-    {TRUE, 0},                                 // ThreadAffinityMask
-    {TRUE, 0},                                 // ThreadImpersonationToken
-    {FALSE, 0},                                        // ThreadDescriptorTableEntry
-    {TRUE, 0},                                 // ThreadEnableAlignmentFaultFixup
-    {TRUE, 0},                                 // ThreadEventPair
-    {TRUE, sizeof(PVOID)},                     // ThreadQuerySetWin32StartAddress
-    {TRUE, 0},                                 // ThreadZeroTlsCell
-    {TRUE, sizeof(LARGE_INTEGER)},             // ThreadPerformanceCount
-    {TRUE, sizeof(BOOLEAN)},                   // ThreadAmILastThread
-    {TRUE, 0},                                 // ThreadIdealProcessor
-    {FALSE, 0},                                        // ThreadPriorityBoost
-    {TRUE, 0},                                 // ThreadSetTlsArrayAddress
-    {FALSE, 0},                                        // ThreadIsIoPending
-    {TRUE, 0}                                  // ThreadHideFromDebugger
-};
-
-static const struct
-{
-   BOOLEAN Implemented;
-   ULONG Size;
-} SetInformationData[MaxThreadInfoClass + 1] = 
-{
-    {TRUE, 0},                 // ThreadBasicInformation
-    {TRUE, 0},                 // ThreadTimes
-    {TRUE, sizeof(KPRIORITY)}, // ThreadPriority
-    {TRUE, sizeof(LONG)},      // ThreadBasePriority
-    {TRUE, sizeof(KAFFINITY)}, // ThreadAffinityMask
-    {TRUE, sizeof(HANDLE)},    // ThreadImpersonationToken
-    {TRUE, 0},                 // ThreadDescriptorTableEntry
-    {FALSE, 0},                        // ThreadEnableAlignmentFaultFixup
-#ifdef _ENABLE_THRDEVTPAIR
-    {TRUE, sizeof(HANDLE)},    // ThreadEventPair
-#else
-    {FALSE, 0},                        // ThreadEventPair
-#endif
-    {TRUE, sizeof(PVOID)},     // ThreadQuerySetWin32StartAddress
-    {FALSE, 0},                        // ThreadZeroTlsCell
-    {TRUE, 0},                 // ThreadPerformanceCount
-    {TRUE, 0},                 // ThreadAmILastThread
-    {FALSE, 0},                        // ThreadIdealProcessor
-    {FALSE, 0},                        // ThreadPriorityBoost
-    {FALSE, 0},                        // ThreadSetTlsArrayAddress
-    {TRUE, 0},                 // ThreadIsIoPending
-    {FALSE, 0}                 // ThreadHideFromDebugger
-};
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @unimplemented
- */
-NTSTATUS STDCALL
-NtSetInformationThread (IN HANDLE ThreadHandle,
-                       IN THREADINFOCLASS ThreadInformationClass,
-                       IN PVOID ThreadInformation,
-                       IN ULONG ThreadInformationLength)
-{
-  PETHREAD Thread;
-  NTSTATUS Status;
-  union
-  {
-     KPRIORITY Priority;
-     LONG Increment;
-     KAFFINITY Affinity;
-     HANDLE Handle;
-     PVOID Address;
-  }u;
-  
-  PAGED_CODE();
-
-  if (ThreadInformationClass <= MaxThreadInfoClass &&
-      !SetInformationData[ThreadInformationClass].Implemented)
-    {
-      return STATUS_NOT_IMPLEMENTED;
-    }
-  if (ThreadInformationClass > MaxThreadInfoClass ||
-      SetInformationData[ThreadInformationClass].Size == 0)
-    {
-      return STATUS_INVALID_INFO_CLASS;
-    }
-  if (ThreadInformationLength != SetInformationData[ThreadInformationClass].Size)
-    {
-      return STATUS_INFO_LENGTH_MISMATCH;
-    }
-
-  Status = ObReferenceObjectByHandle (ThreadHandle,
-                                     THREAD_SET_INFORMATION,
-                                     PsThreadType,
-                                     ExGetPreviousMode (),
-                                     (PVOID*)&Thread,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   Status = MmCopyFromCaller(&u.Priority,
-                            ThreadInformation,
-                            SetInformationData[ThreadInformationClass].Size);
-   if (NT_SUCCESS(Status))
-     {
-       switch (ThreadInformationClass)
-         {
-           case ThreadPriority:
-            if (u.Priority < LOW_PRIORITY || u.Priority >= MAXIMUM_PRIORITY)
-              {
-                Status = STATUS_INVALID_PARAMETER;
-                break;
-              }
-            KeSetPriorityThread(&Thread->Tcb, u.Priority);
-            break;
-       
-           case ThreadBasePriority:
-            KeSetBasePriorityThread (&Thread->Tcb, u.Increment);
-            break;
-       
-           case ThreadAffinityMask:
-            Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
-            break;
-       
-           case ThreadImpersonationToken:
-            Status = PsAssignImpersonationToken (Thread, u.Handle);
-            break;
-               
-#ifdef _ENABLE_THRDEVTPAIR
-           case ThreadEventPair:
-            {
-              PKEVENT_PAIR EventPair;
-
-              Status = ObReferenceObjectByHandle(u.Handle,
-                                                 STANDARD_RIGHTS_ALL,
-                                                 ExEventPairObjectType,
-                                                 ExGetPreviousMode(),
-                                                 (PVOID*)&EventPair,
-                                                 NULL);
-              if (NT_SUCCESS(Status))
-                {
-                   ExpSwapThreadEventPair(Thread, EventPair); /* Note that the extra reference is kept intentionally */
-                }
-               break;
-            }
-#endif /* _ENABLE_THRDEVTPAIR */
-       
-           case ThreadQuerySetWin32StartAddress:
-            Thread->Win32StartAddress = u.Address;
-            break;
-
-           default:
-            /* Shoult never occure if the data table is correct */
-            KEBUGCHECK(0);
-        }
-     }
-  ObDereferenceObject (Thread);
-
-  return Status;
-}
-
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-NtQueryInformationThread (IN   HANDLE          ThreadHandle,
-                         IN    THREADINFOCLASS ThreadInformationClass,
-                         OUT   PVOID           ThreadInformation,
-                         IN    ULONG           ThreadInformationLength,
-                         OUT   PULONG          ReturnLength  OPTIONAL)
-{
-   PETHREAD Thread;
-   NTSTATUS Status;
-   union
-   {
-      THREAD_BASIC_INFORMATION TBI;
-      KERNEL_USER_TIMES TTI;
-      PVOID Address;
-      LARGE_INTEGER Count;
-      BOOLEAN Last;
-   }u;
-   
-   PAGED_CODE();
-
-   if (ThreadInformationClass <= MaxThreadInfoClass &&
-       !QueryInformationData[ThreadInformationClass].Implemented)
-     {
-       return STATUS_NOT_IMPLEMENTED;
-     }
-   if (ThreadInformationClass > MaxThreadInfoClass ||
-       QueryInformationData[ThreadInformationClass].Size == 0)
-     {
-       return STATUS_INVALID_INFO_CLASS;
-     }
-   if (ThreadInformationLength != QueryInformationData[ThreadInformationClass].Size)
-     {
-       return STATUS_INFO_LENGTH_MISMATCH;
-     }
-
-   Status = ObReferenceObjectByHandle(ThreadHandle,
-                                     THREAD_QUERY_INFORMATION,
-                                     PsThreadType,
-                                     ExGetPreviousMode(),
-                                     (PVOID*)&Thread,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-
-   switch (ThreadInformationClass)
-     {
-       case ThreadBasicInformation:
-         /* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING
-          * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is 
-          * 0. So do the conversion here:
-          * -Gunnar     */
-         u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus;
-        u.TBI.TebBaseAddress = Thread->Tcb.Teb;
-        u.TBI.ClientId = Thread->Cid;
-        u.TBI.AffinityMask = Thread->Tcb.Affinity;
-        u.TBI.Priority = Thread->Tcb.Priority;
-        u.TBI.BasePriority = Thread->Tcb.BasePriority;
-        break;
-       
-       case ThreadTimes:
-        u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL;
-         u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL;
-         u.TTI.CreateTime = Thread->CreateTime;
-         /*This works*/
-        u.TTI.ExitTime = Thread->ExitTime;
-         break;
-
-       case ThreadQuerySetWin32StartAddress:
-         u.Address = Thread->Win32StartAddress;
-         break;
-
-       case ThreadPerformanceCount:
-         /* Nebbett says this class is always zero */
-         u.Count.QuadPart = 0;
-         break;
-
-       case ThreadAmILastThread:
-         if (Thread->ThreadsProcess->ThreadListHead.Flink->Flink ==
-            &Thread->ThreadsProcess->ThreadListHead)
-          {
-            u.Last = TRUE;
-          }
-         else
-          {
-            u.Last = FALSE;
-          }
-         break;
-       default:
-        /* Shoult never occure if the data table is correct */
-        KEBUGCHECK(0);
-     }
-   if (QueryInformationData[ThreadInformationClass].Size)
-     {
-       Status = MmCopyToCaller(ThreadInformation,
-                               &u.TBI,
-                              QueryInformationData[ThreadInformationClass].Size);
-     }
-   if (ReturnLength)
-     {
-       NTSTATUS Status2;
-       static ULONG Null = 0;
-       Status2 = MmCopyToCaller(ReturnLength,
-                               NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
-                               sizeof(ULONG));
-       if (NT_SUCCESS(Status))
-         {
-          Status = Status2;
-        }
-     }
-
-   ObDereferenceObject(Thread);
-   return(Status);
-}
-
-
-VOID
-KeSetPreviousMode (ULONG Mode)
-{
-  PsGetCurrentThread()->Tcb.PreviousMode = (UCHAR)Mode;
-}
-
-
-/*
- * @implemented
- */
-KPROCESSOR_MODE STDCALL
-KeGetPreviousMode (VOID)
-{
-  return (ULONG)PsGetCurrentThread()->Tcb.PreviousMode;
-}
-
-
-/*
- * @implemented
- */
-KPROCESSOR_MODE STDCALL
-ExGetPreviousMode (VOID)
-{
-  return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
-}
-
-/* EOF */
index 6e9ef4d..29b3192 100644 (file)
@@ -11,8 +11,8 @@
 /* INCLUDES ****************************************************************/
 
 #include <ntoskrnl.h>
-
-/* TYPES *******************************************************************/
+#define NDEBUG
+#include <internal/debug.h>
 
 /* GLOBALS ******************************************************************/
 
@@ -21,6 +21,28 @@ static PW32_THREAD_CALLBACK PspWin32ThreadCallback = NULL;
 static ULONG PspWin32ProcessSize = 0;
 static ULONG PspWin32ThreadSize = 0;
 
+extern OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate;
+extern OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse;
+extern OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete;
+extern OBJECT_FIND_ROUTINE ExpWindowStationObjectFind;
+extern OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate;
+extern OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete;
+
+#ifndef ALEX_CB_REWRITE
+typedef struct _NTW32CALL_SAVED_STATE
+{
+  ULONG_PTR SavedStackLimit;
+  PVOID SavedStackBase;
+  PVOID SavedInitialStack;
+  PVOID CallerResult;
+  PULONG CallerResultLength;
+  PNTSTATUS CallbackStatus;
+  PKTRAP_FRAME SavedTrapFrame;
+  PVOID SavedCallbackStack;
+  PVOID SavedExceptionStack;
+} NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
+#endif
+
 /* FUNCTIONS ***************************************************************/
 
 PW32THREAD STDCALL
@@ -59,7 +81,7 @@ PsCreateWin32Process(PEPROCESS Process)
 VOID STDCALL
 PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
                          PW32_THREAD_CALLBACK W32ThreadCallback,
-                         PVOID Param3,
+                         PW32_OBJECT_CALLBACK W32ObjectCallback,
                          PVOID Param4,
                          ULONG W32ThreadSize,
                          ULONG W32ProcessSize)
@@ -69,9 +91,15 @@ PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback,
 
   PspWin32ProcessSize = W32ProcessSize;
   PspWin32ThreadSize = W32ThreadSize;
+  
+  ExpWindowStationObjectCreate = W32ObjectCallback->WinStaCreate;
+  ExpWindowStationObjectParse = W32ObjectCallback->WinStaParse;
+  ExpWindowStationObjectDelete = W32ObjectCallback->WinStaDelete;
+  ExpWindowStationObjectFind = W32ObjectCallback->WinStaFind;
+  ExpDesktopObjectCreate = W32ObjectCallback->DesktopCreate;
+  ExpDesktopObjectDelete = W32ObjectCallback->DesktopDelete;
 }
 
-
 NTSTATUS
 PsInitWin32Thread (PETHREAD Thread)
 {
@@ -149,4 +177,182 @@ PsTerminateWin32Thread (PETHREAD Thread)
   }
 }
 
+VOID
+STDCALL
+DumpEspData(ULONG Esp, ULONG ThLimit, ULONG ThStack, ULONG PcrLimit, ULONG PcrStack, ULONG Esp0)
+{
+    DPRINT1("Current Esp: %p\n Thread Stack Limit: %p\n Thread Stack: %p\n Pcr Limit: %p, Pcr Stack: %p\n Esp0 :%p\n",Esp, ThLimit, ThStack, PcrLimit, PcrStack, Esp0)   ;
+}
+
+ PVOID
+STDCALL
+ PsAllocateCallbackStack(ULONG StackSize)
+ {
+   PVOID KernelStack = NULL;
+   NTSTATUS Status;
+   PMEMORY_AREA StackArea;
+   ULONG i, j;
+   PHYSICAL_ADDRESS BoundaryAddressMultiple;
+   PPFN_TYPE Pages = alloca(sizeof(PFN_TYPE) * (StackSize /PAGE_SIZE));
+    DPRINT1("PsAllocateCallbackStack\n");
+   BoundaryAddressMultiple.QuadPart = 0;
+   StackSize = PAGE_ROUND_UP(StackSize);
+   MmLockAddressSpace(MmGetKernelAddressSpace());
+   Status = MmCreateMemoryArea(NULL,
+                               MmGetKernelAddressSpace(),
+                               MEMORY_AREA_KERNEL_STACK,
+                               &KernelStack,
+                               StackSize,
+                               0,
+                               &StackArea,
+                               FALSE,
+                               FALSE,
+                               BoundaryAddressMultiple);
+   MmUnlockAddressSpace(MmGetKernelAddressSpace());
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT1("Failed to create thread stack\n");
+       return(NULL);
+     }
+   for (i = 0; i < (StackSize / PAGE_SIZE); i++)
+     {
+       Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pages[i]);
+       if (!NT_SUCCESS(Status))
+         {
+           for (j = 0; j < i; j++)
+           {
+             MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[j]);
+           }
+           return(NULL);
+         }
+     }
+   Status = MmCreateVirtualMapping(NULL,
+                                  KernelStack,
+                                  PAGE_READWRITE,
+                                   Pages,
+                                   StackSize / PAGE_SIZE);
+   if (!NT_SUCCESS(Status))
+     {
+      for (i = 0; i < (StackSize / PAGE_SIZE); i++)
+         {
+           MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[i]);
+         }
+       return(NULL);
+     }
+     DPRINT1("PsAllocateCallbackStack %x\n", KernelStack);
+   return(KernelStack);
+}
+
+NTSTATUS 
+STDCALL
+NtW32Call(IN ULONG RoutineIndex,
+          IN PVOID Argument,
+          IN ULONG ArgumentLength,
+          OUT PVOID* Result OPTIONAL,
+          OUT PULONG ResultLength OPTIONAL)
+{
+    NTSTATUS CallbackStatus;
+    
+    DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
+            RoutineIndex, Argument, ArgumentLength);
+    
+    /* FIXME: SEH!!! */
+  
+    /* Call kernel function */
+    CallbackStatus = KeUserModeCallback(RoutineIndex,
+                                        Argument,
+                                        ArgumentLength,
+                                        Result,
+                                        ResultLength);
+    
+    /* Return the result */
+    return(CallbackStatus);
+} 
+
+#ifndef ALEX_CB_REWRITE
+NTSTATUS STDCALL
+NtCallbackReturn (PVOID                Result,
+                 ULONG         ResultLength,
+                 NTSTATUS      Status)
+{
+  PULONG OldStack;
+  PETHREAD Thread;
+  PNTSTATUS CallbackStatus;
+  PULONG CallerResultLength;
+  PVOID* CallerResult;
+  PVOID InitialStack;
+  PVOID StackBase;
+  ULONG_PTR StackLimit;
+  KIRQL oldIrql;
+  PNTW32CALL_SAVED_STATE State;
+  PKTRAP_FRAME SavedTrapFrame;
+  PVOID SavedCallbackStack;
+  PVOID SavedExceptionStack;
+  
+  PAGED_CODE();
+
+  Thread = PsGetCurrentThread();
+  if (Thread->Tcb.CallbackStack == NULL)
+    {
+      return(STATUS_NO_CALLBACK_ACTIVE);
+    }
+
+  OldStack = (PULONG)Thread->Tcb.CallbackStack;
+
+  /*
+   * Get the values that NtW32Call left on the inactive stack for us.
+   */
+  State = (PNTW32CALL_SAVED_STATE)OldStack[0];  
+  CallbackStatus = State->CallbackStatus;
+  CallerResultLength = State->CallerResultLength;
+  CallerResult = State->CallerResult;
+  InitialStack = State->SavedInitialStack;
+  StackBase = State->SavedStackBase;
+  StackLimit = State->SavedStackLimit;
+  SavedTrapFrame = State->SavedTrapFrame;
+  SavedCallbackStack = State->SavedCallbackStack;
+  SavedExceptionStack = State->SavedExceptionStack;
+
+  /*
+   * Copy the callback status and the callback result to NtW32Call
+   */
+  *CallbackStatus = Status;
+  if (CallerResult != NULL && CallerResultLength != NULL)
+    {
+      if (Result == NULL)
+       {
+         *CallerResultLength = 0;
+       }
+      else
+       {
+         *CallerResultLength = min(ResultLength, *CallerResultLength);
+         RtlCopyMemory(*CallerResult, Result, *CallerResultLength);
+       }
+    }
+
+  /*
+   * Restore the old stack.
+   */
+  KeRaiseIrql(HIGH_LEVEL, &oldIrql);
+  if ((Thread->Tcb.NpxState & NPX_STATE_VALID) &&
+      ETHREAD_TO_KTHREAD(Thread) != KeGetCurrentPrcb()->NpxThread)
+    {
+      RtlCopyMemory((char*)InitialStack - sizeof(FX_SAVE_AREA),
+                    (char*)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA),
+                    sizeof(FX_SAVE_AREA));
+    }
+  Thread->Tcb.InitialStack = InitialStack;
+  Thread->Tcb.StackBase = StackBase;
+  Thread->Tcb.StackLimit = StackLimit;
+  Thread->Tcb.TrapFrame = SavedTrapFrame;
+  Thread->Tcb.CallbackStack = SavedCallbackStack;
+  KeGetCurrentKPCR()->TSS->Esp0 = (ULONG)SavedExceptionStack;
+  KeStackSwitchAndRet((PVOID)(OldStack + 1));
+
+  /* Should never return. */
+  KEBUGCHECK(0);
+  return(STATUS_UNSUCCESSFUL);
+#endif
+}
 /* EOF */
index bfc592a..900ba74 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
+
+KPROCESSOR_MODE
+RtlpGetMode()
+{ 
+   return KernelMode; 
+}
+
 /*
  * @implemented
  */
@@ -38,11 +45,12 @@ RtlReleasePebLock(VOID)
 
 }
 
+
 PPEB
 STDCALL
 RtlpCurrentPeb(VOID)
 {
-    return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
+   return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
 }
 
 NTSTATUS 
index c56345c..82e6729 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/rtl/nls.c
@@ -36,7 +35,32 @@ ULONG NlsUnicodeTableOffset = 0;
 
 /* FUNCTIONS *****************************************************************/
 
-
+VOID 
+INIT_FUNCTION
+STDCALL
+RtlpInitNls(VOID)
+{
+    ULONG_PTR BaseAddress;
+    
+    /* Import NLS Data */ 
+    BaseAddress = CachedModules[AnsiCodepage]->ModStart;
+    RtlpImportAnsiCodePage((PUSHORT)BaseAddress,
+                           CachedModules[AnsiCodepage]->ModEnd - BaseAddress);
+    
+    BaseAddress = CachedModules[OemCodepage]->ModStart;
+    RtlpImportOemCodePage((PUSHORT)BaseAddress,
+                          CachedModules[OemCodepage]->ModEnd - BaseAddress);
+    
+    BaseAddress = CachedModules[UnicodeCasemap]->ModStart;
+    RtlpImportUnicodeCasemap((PUSHORT)BaseAddress,
+                             CachedModules[UnicodeCasemap]->ModEnd - BaseAddress);
+    
+    /* Create initial NLS tables */
+    RtlpCreateInitialNlsTables();
+    
+    /* Create the NLS section */
+    RtlpCreateNlsSection();    
+}
 
 VOID INIT_FUNCTION
 RtlpImportAnsiCodePage(PUSHORT TableBase,
index 1e49fce..62687de 100644 (file)
@@ -72,7 +72,7 @@ RtlMapGenericMask (
        if (*AccessMask & GENERIC_ALL)
                *AccessMask |= GenericMapping->GenericAll;
 
-       *AccessMask &= 0x0FFFFFFF;
+       *AccessMask &= ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
 }
 
 /*
index 8f1bbd5..2d2e50f 100644 (file)
@@ -263,4 +263,105 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
   return STATUS_SUCCESS;
 }
 
+NTSTATUS
+SepCaptureAcl(IN PACL InputAcl,
+              IN KPROCESSOR_MODE AccessMode,
+              IN POOL_TYPE PoolType,
+              IN BOOLEAN CaptureIfKernel,
+              OUT PACL *CapturedAcl)
+{
+  PACL NewAcl;
+  ULONG AclSize = 0;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  PAGED_CODE();
+
+  if(AccessMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(InputAcl,
+                   sizeof(ACL),
+                   sizeof(ULONG));
+      AclSize = InputAcl->AclSize;
+      ProbeForRead(InputAcl,
+                   AclSize,
+                   sizeof(ULONG));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if(NT_SUCCESS(Status))
+    {
+      NewAcl = ExAllocatePool(PoolType,
+                              AclSize);
+      if(NewAcl != NULL)
+      {
+        _SEH_TRY
+        {
+          RtlCopyMemory(NewAcl,
+                        InputAcl,
+                        AclSize);
+
+          *CapturedAcl = NewAcl;
+        }
+        _SEH_HANDLE
+        {
+          ExFreePool(NewAcl);
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+      }
+      else
+      {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+      }
+    }
+  }
+  else if(!CaptureIfKernel)
+  {
+    *CapturedAcl = InputAcl;
+  }
+  else
+  {
+    AclSize = InputAcl->AclSize;
+
+    NewAcl = ExAllocatePool(PoolType,
+                            AclSize);
+
+    if(NewAcl != NULL)
+    {
+      RtlCopyMemory(NewAcl,
+                    InputAcl,
+                    AclSize);
+
+      *CapturedAcl = NewAcl;
+    }
+    else
+    {
+      Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+  }
+
+  return Status;
+}
+
+VOID
+SepReleaseAcl(IN PACL CapturedAcl,
+              IN KPROCESSOR_MODE AccessMode,
+              IN BOOLEAN CaptureIfKernel)
+{
+  PAGED_CODE();
+
+  if(CapturedAcl != NULL &&
+     (AccessMode == UserMode ||
+      (AccessMode == KernelMode && CaptureIfKernel)))
+  {
+    ExFreePool(CapturedAcl);
+  }
+}
+
 /* EOF */
index 1b5d653..a7c516e 100644 (file)
@@ -102,32 +102,4 @@ NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
   return Status;
 }
 
-
-/*
- * @implemented
- */
-VOID STDCALL
-RtlCopyLuid(IN PLUID LuidDest,
-           IN PLUID LuidSrc)
-{
-  PAGED_CODE_RTL();
-
-  LuidDest->LowPart = LuidSrc->LowPart;
-  LuidDest->HighPart = LuidSrc->HighPart;
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-RtlEqualLuid(IN PLUID Luid1,
-            IN PLUID Luid2)
-{
-  PAGED_CODE_RTL();
-  
-  return (Luid1->LowPart == Luid2->LowPart &&
-         Luid1->HighPart == Luid2->HighPart);
-}
-
 /* EOF */
index 47ec5ba..3e12f80 100644 (file)
@@ -108,6 +108,174 @@ SepInitSDs(VOID)
   return TRUE;
 }
 
+
+NTSTATUS
+SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN POOL_TYPE PoolType,
+                                   IN BOOLEAN CaptureIfKernel,
+                                   OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+                                   OUT PBOOLEAN Present)
+{
+  PSECURITY_QUALITY_OF_SERVICE CapturedQos;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  PAGED_CODE();
+
+  ASSERT(CapturedSecurityQualityOfService);
+  ASSERT(Present);
+
+  if(ObjectAttributes != NULL)
+  {
+    if(AccessMode != KernelMode)
+    {
+      SECURITY_QUALITY_OF_SERVICE SafeQos;
+
+      _SEH_TRY
+      {
+        ProbeForRead(ObjectAttributes,
+                     sizeof(ObjectAttributes),
+                     sizeof(ULONG));
+        if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+        {
+          if(ObjectAttributes->SecurityQualityOfService != NULL)
+          {
+            ProbeForRead(ObjectAttributes->SecurityQualityOfService,
+                         sizeof(SECURITY_QUALITY_OF_SERVICE),
+                         sizeof(ULONG));
+
+            if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+               sizeof(SECURITY_QUALITY_OF_SERVICE))
+            {
+              /* don't allocate memory here because ExAllocate should bugcheck
+                 the system if it's buggy, SEH would catch that! So make a local
+                 copy of the qos structure.*/
+              RtlCopyMemory(&SafeQos,
+                            ObjectAttributes->SecurityQualityOfService,
+                            sizeof(SECURITY_QUALITY_OF_SERVICE));
+              *Present = TRUE;
+            }
+            else
+            {
+              Status = STATUS_INVALID_PARAMETER;
+            }
+          }
+          else
+          {
+            *CapturedSecurityQualityOfService = NULL;
+            *Present = FALSE;
+          }
+        }
+        else
+        {
+          Status = STATUS_INVALID_PARAMETER;
+        }
+      }
+      _SEH_HANDLE
+      {
+        Status = _SEH_GetExceptionCode();
+      }
+      _SEH_END;
+
+      if(NT_SUCCESS(Status))
+      {
+        if(*Present)
+        {
+          CapturedQos = ExAllocatePool(PoolType,
+                                       sizeof(SECURITY_QUALITY_OF_SERVICE));
+          if(CapturedQos != NULL)
+          {
+            RtlCopyMemory(CapturedQos,
+                          &SafeQos,
+                          sizeof(SECURITY_QUALITY_OF_SERVICE));
+            *CapturedSecurityQualityOfService = CapturedQos;
+          }
+          else
+          {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+          }
+        }
+        else
+        {
+          *CapturedSecurityQualityOfService = NULL;
+        }
+      }
+    }
+    else
+    {
+      if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+      {
+        if(CaptureIfKernel)
+        {
+          if(ObjectAttributes->SecurityQualityOfService != NULL)
+          {
+            if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
+               sizeof(SECURITY_QUALITY_OF_SERVICE))
+            {
+              CapturedQos = ExAllocatePool(PoolType,
+                                           sizeof(SECURITY_QUALITY_OF_SERVICE));
+              if(CapturedQos != NULL)
+              {
+                RtlCopyMemory(CapturedQos,
+                              ObjectAttributes->SecurityQualityOfService,
+                              sizeof(SECURITY_QUALITY_OF_SERVICE));
+                *CapturedSecurityQualityOfService = CapturedQos;
+                *Present = TRUE;
+              }
+              else
+              {
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+              }
+            }
+            else
+            {
+              Status = STATUS_INVALID_PARAMETER;
+            }
+          }
+          else
+          {
+            *CapturedSecurityQualityOfService = NULL;
+            *Present = FALSE;
+          }
+        }
+        else
+        {
+          *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
+          *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
+        }
+      }
+      else
+      {
+        Status = STATUS_INVALID_PARAMETER;
+      }
+    }
+  }
+  else
+  {
+    *CapturedSecurityQualityOfService = NULL;
+    *Present = FALSE;
+  }
+
+  return Status;
+}
+
+
+VOID
+SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService  OPTIONAL,
+                                   IN KPROCESSOR_MODE AccessMode,
+                                   IN BOOLEAN CaptureIfKernel)
+{
+  PAGED_CODE();
+
+  if(CapturedSecurityQualityOfService != NULL &&
+     (AccessMode == UserMode ||
+      (AccessMode == KernelMode && CaptureIfKernel)))
+  {
+    ExFreePool(CapturedSecurityQualityOfService);
+  }
+}
+
+
 /*
  * @implemented
  */
@@ -572,6 +740,8 @@ SeReleaseSecurityDescriptor(
        IN BOOLEAN CaptureIfKernelMode
        )
 {
+  PAGED_CODE();
+
   /* WARNING! You need to call this function with the same value for CurrentMode
               and CaptureIfKernelMode that you previously passed to
               SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
index d925ee3..019072a 100644 (file)
@@ -466,4 +466,107 @@ SepInitSecurityIDs(VOID)
   return(TRUE);
 }
 
+NTSTATUS
+SepCaptureSid(IN PSID InputSid,
+              IN KPROCESSOR_MODE AccessMode,
+              IN POOL_TYPE PoolType,
+              IN BOOLEAN CaptureIfKernel,
+              OUT PSID *CapturedSid)
+{
+  ULONG SidSize = 0;
+  PISID NewSid, Sid = (PISID)InputSid;
+  NTSTATUS Status = STATUS_SUCCESS;
+  
+  PAGED_CODE();
+
+  if(AccessMode != KernelMode)
+  {
+    _SEH_TRY
+    {
+      ProbeForRead(Sid,
+                   sizeof(*Sid) - sizeof(Sid->SubAuthority),
+                   sizeof(UCHAR));
+      SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+      ProbeForRead(Sid,
+                   SidSize,
+                   sizeof(UCHAR));
+    }
+    _SEH_HANDLE
+    {
+      Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if(NT_SUCCESS(Status))
+    {
+      /* allocate a SID and copy it */
+      NewSid = ExAllocatePool(PoolType,
+                              SidSize);
+      if(NewSid != NULL)
+      {
+        _SEH_TRY
+        {
+          RtlCopyMemory(NewSid,
+                        Sid,
+                        SidSize);
+
+          *CapturedSid = NewSid;
+        }
+        _SEH_HANDLE
+        {
+          ExFreePool(NewSid);
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+      }
+      else
+      {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+      }
+    }
+  }
+  else if(!CaptureIfKernel)
+  {
+    *CapturedSid = InputSid;
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
+
+    /* allocate a SID and copy it */
+    NewSid = ExAllocatePool(PoolType,
+                            SidSize);
+    if(NewSid != NULL)
+    {
+      RtlCopyMemory(NewSid,
+                    Sid,
+                    SidSize);
+
+      *CapturedSid = NewSid;
+    }
+    else
+    {
+      Status = STATUS_INSUFFICIENT_RESOURCES;
+    }
+  }
+
+  return Status;
+}
+
+VOID
+SepReleaseSid(IN PSID CapturedSid,
+              IN KPROCESSOR_MODE AccessMode,
+              IN BOOLEAN CaptureIfKernel)
+{
+  PAGED_CODE();
+  
+  if(CapturedSid != NULL &&
+     (AccessMode == UserMode ||
+      (AccessMode == KernelMode && CaptureIfKernel)))
+  {
+    ExFreePool(CapturedSid);
+  }
+}
+
 /* EOF */
index 28605d6..7ff0e25 100644 (file)
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE SepTokenObjectType = NULL;
+ERESOURCE SepTokenLock;
 
 static GENERIC_MAPPING SepTokenMapping = {TOKEN_READ,
                                          TOKEN_WRITE,
                                          TOKEN_EXECUTE,
                                          TOKEN_ALL_ACCESS};
 
+static const INFORMATION_CLASS_INFO SeTokenInformationClass[] = {
+
+    /* Class 0 not used, blame M$! */
+    ICI_SQ_SAME( 0, 0, 0),
+
+    /* TokenUser */
+    ICI_SQ_SAME( sizeof(TOKEN_USER),                   sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenGroups */
+    ICI_SQ_SAME( sizeof(TOKEN_GROUPS),                 sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenPrivileges */
+    ICI_SQ_SAME( sizeof(TOKEN_PRIVILEGES),             sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenOwner */
+    ICI_SQ_SAME( sizeof(TOKEN_OWNER),                  sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenPrimaryGroup */
+    ICI_SQ_SAME( sizeof(TOKEN_PRIMARY_GROUP),          sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenDefaultDacl */
+    ICI_SQ_SAME( sizeof(TOKEN_DEFAULT_DACL),           sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenSource */
+    ICI_SQ_SAME( sizeof(TOKEN_SOURCE),                 sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenType */
+    ICI_SQ_SAME( sizeof(TOKEN_TYPE),                   sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenImpersonationLevel */
+    ICI_SQ_SAME( sizeof(SECURITY_IMPERSONATION_LEVEL), sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenStatistics */
+    ICI_SQ_SAME( sizeof(TOKEN_STATISTICS),             sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE | ICIF_SET | ICIF_SET_SIZE_VARIABLE ),
+    /* TokenRestrictedSids */
+    ICI_SQ_SAME( sizeof(TOKEN_GROUPS),                 sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenSessionId */
+    ICI_SQ_SAME( sizeof(ULONG),                        sizeof(ULONG), ICIF_QUERY | ICIF_SET ),
+    /* TokenGroupsAndPrivileges */
+    ICI_SQ_SAME( sizeof(TOKEN_GROUPS_AND_PRIVILEGES),  sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenSessionReference */
+    ICI_SQ_SAME( /* FIXME */0,                         sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenSandBoxInert */
+    ICI_SQ_SAME( sizeof(ULONG),                        sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenAuditPolicy */
+    ICI_SQ_SAME( /* FIXME */0,                         sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+    /* TokenOrigin */
+    ICI_SQ_SAME( sizeof(TOKEN_ORIGIN),                 sizeof(ULONG), ICIF_QUERY | ICIF_QUERY_SIZE_VARIABLE ),
+};
+
 /* FUNCTIONS *****************************************************************/
 
 VOID SepFreeProxyData(PVOID ProxyData)
@@ -140,6 +182,8 @@ SepDuplicateToken(PTOKEN Token,
   PVOID EndMem;
   PTOKEN AccessToken;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   Status = ObCreateObject(PreviousMode,
                          SepTokenObjectType,
@@ -170,6 +214,8 @@ SepDuplicateToken(PTOKEN Token,
       return(Status);
     }
 
+  AccessToken->TokenLock = &SepTokenLock;
+
   AccessToken->TokenInUse = 0;
   AccessToken->TokenType  = TokenType;
   AccessToken->ImpersonationLevel = Level;
@@ -189,7 +235,7 @@ SepDuplicateToken(PTOKEN Token,
     uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
 
   AccessToken->UserAndGroups = 
-    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                               uLength,
                                               TAG('T', 'O', 'K', 'u'));
 
@@ -216,7 +262,7 @@ SepDuplicateToken(PTOKEN Token,
 
       uLength = AccessToken->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
       AccessToken->Privileges =
-       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                                    uLength,
                                                    TAG('T', 'O', 'K', 'p'));
 
@@ -231,7 +277,7 @@ SepDuplicateToken(PTOKEN Token,
       if ( Token->DefaultDacl )
        {
          AccessToken->DefaultDacl =
-           (PACL) ExAllocatePoolWithTag(NonPagedPool,
+           (PACL) ExAllocatePoolWithTag(PagedPool,
                                         Token->DefaultDacl->AclSize,
                                         TAG('T', 'O', 'K', 'd'));
          memcpy(AccessToken->DefaultDacl,
@@ -534,6 +580,8 @@ SepDeleteToken(PVOID ObjectBody)
 VOID INIT_FUNCTION
 SepInitializeTokenImplementation(VOID)
 {
+  ExInitializeResource(&SepTokenLock);
+
   SepTokenObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
 
   SepTokenObjectType->Tag = TAG('T', 'O', 'K', 'T');
@@ -555,8 +603,7 @@ SepInitializeTokenImplementation(VOID)
   SepTokenObjectType->Create = NULL;
   SepTokenObjectType->DuplicationNotify = NULL;
 
-  RtlpCreateUnicodeString(&SepTokenObjectType->TypeName,
-          L"Token", NonPagedPool);
+  RtlInitUnicodeString(&SepTokenObjectType->TypeName, L"Token");
   ObpCreateTypeObject (SepTokenObjectType);
 }
 
@@ -571,265 +618,455 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
                        IN ULONG TokenInformationLength,
                        OUT PULONG ReturnLength)
 {
-  NTSTATUS Status, LengthStatus;
-  PVOID UnusedInfo;
-  PVOID EndMem;
+  union
+  {
+    PVOID Ptr;
+    ULONG Ulong;
+  } Unused;
   PTOKEN Token;
-  ULONG Length;
-  PTOKEN_GROUPS PtrTokenGroups;
-  PTOKEN_DEFAULT_DACL PtrDefaultDacl;
-  PTOKEN_STATISTICS PtrTokenStatistics;
+  ULONG RequiredLength;
+  KPROCESSOR_MODE PreviousMode;
+  NTSTATUS Status = STATUS_SUCCESS;
   
   PAGED_CODE();
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  /* Check buffers and class validity */
+  DefaultQueryInfoBufferCheck(TokenInformationClass,
+                              SeTokenInformationClass,
+                              TokenInformation,
+                              TokenInformationLength,
+                              ReturnLength,
+                              PreviousMode,
+                              &Status);
+
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT("NtQueryInformationToken() failed, Status: 0x%x\n", Status);
+    return Status;
+  }
 
   Status = ObReferenceObjectByHandle(TokenHandle,
                                     (TokenInformationClass == TokenSource) ? TOKEN_QUERY_SOURCE : TOKEN_QUERY,
                                     SepTokenObjectType,
-                                    UserMode,
+                                    PreviousMode,
                                     (PVOID*)&Token,
                                     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  switch (TokenInformationClass)
+  if (NT_SUCCESS(Status))
+  {
+    switch (TokenInformationClass)
     {
       case TokenUser:
-       DPRINT("NtQueryInformationToken(TokenUser)\n");
-       Length = RtlLengthSidAndAttributes(1, Token->UserAndGroups);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = RtlCopySidAndAttributesArray(1,
-                                                 Token->UserAndGroups,
-                                                 TokenInformationLength,
-                                                 TokenInformation,
-                                                 (char*)TokenInformation + 8,
-                                                 &UnusedInfo,
-                                                 &Length);
-           if (NT_SUCCESS(Status))
-             {
-               Length = TokenInformationLength - Length;
-               Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-             }
-         }
-       break;
+      {
+        PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
+        
+        DPRINT("NtQueryInformationToken(TokenUser)\n");
+        RequiredLength = sizeof(TOKEN_USER) +
+                         RtlLengthSid(Token->UserAndGroups[0].Sid);
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            Status = RtlCopySidAndAttributesArray(1,
+                                                  &Token->UserAndGroups[0],
+                                                  RequiredLength - sizeof(TOKEN_USER),
+                                                  &tu->User,
+                                                  (PSID)(tu + 1),
+                                                  &Unused.Ptr,
+                                                  &Unused.Ulong);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+          
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        break;
+      }
        
       case TokenGroups:
-       DPRINT("NtQueryInformationToken(TokenGroups)\n");
-       Length = RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]) + sizeof(ULONG);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           EndMem = (char*)TokenInformation + Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES);
-           PtrTokenGroups = (PTOKEN_GROUPS)TokenInformation;
-           PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1;
-           Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
-                                                 &Token->UserAndGroups[1],
-                                                 TokenInformationLength,
-                                                 PtrTokenGroups->Groups,
-                                                 EndMem,
-                                                 &UnusedInfo,
-                                                 &Length);
-           if (NT_SUCCESS(Status))
-             {
-               Length = TokenInformationLength - Length;
-               Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-             }
-         }
-       break;
+      {
+        PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
+        
+        DPRINT("NtQueryInformationToken(TokenGroups)\n");
+        RequiredLength = sizeof(tg->GroupCount) +
+                         RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
 
-      case TokenPrivileges:
-       DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
-       Length = sizeof(ULONG) + Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           ULONG i;
-           TOKEN_PRIVILEGES* pPriv = (TOKEN_PRIVILEGES*)TokenInformation;
-
-           pPriv->PrivilegeCount = Token->PrivilegeCount;
-           for (i = 0; i < Token->PrivilegeCount; i++)
-             {
-               RtlCopyLuid(&pPriv->Privileges[i].Luid, &Token->Privileges[i].Luid);
-               pPriv->Privileges[i].Attributes = Token->Privileges[i].Attributes;
-             }
-           Status = STATUS_SUCCESS;
-         }
-       break;
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            ULONG SidLen = RequiredLength - sizeof(tg->GroupCount) -
+                           ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES));
+            PSID_AND_ATTRIBUTES Sid = (PSID_AND_ATTRIBUTES)((ULONG_PTR)TokenInformation + sizeof(tg->GroupCount) +
+                                                            ((Token->UserAndGroupCount - 1) * sizeof(SID_AND_ATTRIBUTES)));
+
+            tg->GroupCount = Token->UserAndGroupCount - 1;
+            Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
+                                                  &Token->UserAndGroups[1],
+                                                  SidLen,
+                                                  &tg->Groups[0],
+                                                  (PSID)Sid,
+                                                  &Unused.Ptr,
+                                                  &Unused.Ulong);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
 
-      case TokenOwner:
-       DPRINT("NtQueryInformationToken(TokenOwner)\n");
-       Length = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid) + sizeof(TOKEN_OWNER);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           ((PTOKEN_OWNER)TokenInformation)->Owner = 
-             (PSID)(((PTOKEN_OWNER)TokenInformation) + 1);
-           RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
-                      ((PTOKEN_OWNER)TokenInformation)->Owner,
-                      Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
-           Status = STATUS_SUCCESS;
-         }
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
        break;
+      }
+      
+      case TokenPrivileges:
+      {
+        PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
+        
+        DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
+        RequiredLength = sizeof(tp->PrivilegeCount) +
+                         (Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
 
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            tp->PrivilegeCount = Token->PrivilegeCount;
+            RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
+                                          Token->Privileges,
+                                          &tp->Privileges[0]);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+          
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        break;
+      }
+      
+      case TokenOwner:
+      {
+        ULONG SidLen;
+        PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+        
+        DPRINT("NtQueryInformationToken(TokenOwner)\n");
+        SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+        RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            to->Owner = (PSID)(to + 1);
+            Status = RtlCopySid(SidLen,
+                                to->Owner,
+                                Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+          
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+        
+        break;
+      }
+      
       case TokenPrimaryGroup:
-       DPRINT("NtQueryInformationToken(TokenPrimaryGroup),"
-              "Token->PrimaryGroup = 0x%08x\n", Token->PrimaryGroup);
-       Length = RtlLengthSid(Token->PrimaryGroup) + sizeof(TOKEN_PRIMARY_GROUP);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup = 
-             (PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1);
-           RtlCopySid(TokenInformationLength - sizeof(TOKEN_PRIMARY_GROUP),
-                      ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup,
-                      Token->PrimaryGroup);
-           Status = STATUS_SUCCESS;
-         }
-       break;
+      {
+        ULONG SidLen;
+        PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenPrimaryGroup)\n");
+        SidLen = RtlLengthSid(Token->PrimaryGroup);
+        RequiredLength = sizeof(TOKEN_PRIMARY_GROUP) + SidLen;
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            tpg->PrimaryGroup = (PSID)(tpg + 1);
+            Status = RtlCopySid(SidLen,
+                                tpg->PrimaryGroup,
+                                Token->PrimaryGroup);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
 
+        break;
+      }
+      
       case TokenDefaultDacl:
-       DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
-       PtrDefaultDacl = (PTOKEN_DEFAULT_DACL) TokenInformation;
-       Length = (Token->DefaultDacl ? Token->DefaultDacl->AclSize : 0) + sizeof(TOKEN_DEFAULT_DACL);
-       if (TokenInformationLength < Length)
-         {
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else if (!Token->DefaultDacl)
-         {
-           PtrDefaultDacl->DefaultDacl = 0;
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-         }
-       else
-         {
-           PtrDefaultDacl->DefaultDacl = (PACL) (PtrDefaultDacl + 1);
-           memmove(PtrDefaultDacl->DefaultDacl,
-                   Token->DefaultDacl,
-                   Token->DefaultDacl->AclSize);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-         }
-       break;
+      {
+        PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
+        RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
+        
+        if(Token->DefaultDacl != NULL)
+        {
+          RequiredLength += Token->DefaultDacl->AclSize;
+        }
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            if(Token->DefaultDacl != NULL)
+            {
+              tdd->DefaultDacl = (PACL)(tdd + 1);
+              RtlCopyMemory(tdd->DefaultDacl,
+                            Token->DefaultDacl,
+                            Token->DefaultDacl->AclSize);
+            }
+            else
+            {
+              tdd->DefaultDacl = NULL;
+            }
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
 
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
+      
       case TokenSource:
-       DPRINT("NtQueryInformationToken(TokenSource)\n");
-       if (TokenInformationLength < sizeof(TOKEN_SOURCE))
-         {
-           Length = sizeof(TOKEN_SOURCE);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = MmCopyToCaller(TokenInformation, &Token->TokenSource, sizeof(TOKEN_SOURCE));
-         }
-       break;
+      {
+        PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenSource)\n");
+        RequiredLength = sizeof(TOKEN_SOURCE);
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            *ts = Token->TokenSource;
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
 
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
+      
       case TokenType:
-       DPRINT("NtQueryInformationToken(TokenType)\n");
-       if (TokenInformationLength < sizeof(TOKEN_TYPE))
-         {
-           Length = sizeof(TOKEN_TYPE);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = MmCopyToCaller(TokenInformation, &Token->TokenType, sizeof(TOKEN_TYPE));
-         }
-       break;
+      {
+        PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenType)\n");
+        RequiredLength = sizeof(TOKEN_TYPE);
 
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            *tt = Token->TokenType;
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
+      
       case TokenImpersonationLevel:
-       DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
-       if (TokenInformationLength < sizeof(SECURITY_IMPERSONATION_LEVEL))
-         {
-           Length = sizeof(SECURITY_IMPERSONATION_LEVEL);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = MmCopyToCaller(TokenInformation, &Token->ImpersonationLevel, sizeof(SECURITY_IMPERSONATION_LEVEL));
-         }
-       break;
+      {
+        PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenImpersonationLevel)\n");
+        RequiredLength = sizeof(SECURITY_IMPERSONATION_LEVEL);
 
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            *sil = Token->ImpersonationLevel;
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
+      
       case TokenStatistics:
-       DPRINT("NtQueryInformationToken(TokenStatistics)\n");
-       if (TokenInformationLength < sizeof(TOKEN_STATISTICS))
-         {
-           Length = sizeof(TOKEN_STATISTICS);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           PtrTokenStatistics = (PTOKEN_STATISTICS)TokenInformation;
-           PtrTokenStatistics->TokenId = Token->TokenId;
-           PtrTokenStatistics->AuthenticationId = Token->AuthenticationId;
-           PtrTokenStatistics->ExpirationTime = Token->ExpirationTime;
-           PtrTokenStatistics->TokenType = Token->TokenType;
-           PtrTokenStatistics->ImpersonationLevel = Token->ImpersonationLevel;
-           PtrTokenStatistics->DynamicCharged = Token->DynamicCharged;
-           PtrTokenStatistics->DynamicAvailable = Token->DynamicAvailable;
-           PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1;
-           PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount;
-           PtrTokenStatistics->ModifiedId = Token->ModifiedId;
-
-           Status = STATUS_SUCCESS;
-         }
-       break;
+      {
+        PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenStatistics)\n");
+        RequiredLength = sizeof(TOKEN_STATISTICS);
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            ts->TokenId = Token->TokenId;
+            ts->AuthenticationId = Token->AuthenticationId;
+            ts->ExpirationTime = Token->ExpirationTime;
+            ts->TokenType = Token->TokenType;
+            ts->ImpersonationLevel = Token->ImpersonationLevel;
+            ts->DynamicCharged = Token->DynamicCharged;
+            ts->DynamicAvailable = Token->DynamicAvailable;
+            ts->GroupCount = Token->UserAndGroupCount - 1;
+            ts->PrivilegeCount = Token->PrivilegeCount;
+            ts->ModifiedId = Token->ModifiedId;
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
 
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
+      
       case TokenOrigin:
-       DPRINT("NtQueryInformationToken(TokenOrigin)\n");
-       if (TokenInformationLength < sizeof(TOKEN_ORIGIN))
-         {
-           Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = MmCopyToCaller(&((PTOKEN_ORIGIN)TokenInformation)->OriginatingLogonSession,
-                                   &Token->AuthenticationId, sizeof(LUID));
-         }
-       Length = sizeof(TOKEN_ORIGIN);
-       LengthStatus = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-       if (NT_SUCCESS(Status))
-         {
-           Status = LengthStatus;
-         }
-       break;
+      {
+        PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
+
+        DPRINT("NtQueryInformationToken(TokenOrigin)\n");
+        RequiredLength = sizeof(TOKEN_ORIGIN);
+
+        _SEH_TRY
+        {
+          if(TokenInformationLength >= RequiredLength)
+          {
+            RtlCopyLuid(&to->OriginatingLogonSession,
+                        &Token->AuthenticationId);
+          }
+          else
+          {
+            Status = STATUS_BUFFER_TOO_SMALL;
+          }
+
+          if(ReturnLength != NULL)
+          {
+            *ReturnLength = RequiredLength;
+          }
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        break;
+      }
 
       case TokenGroupsAndPrivileges:
        DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
@@ -847,27 +1084,44 @@ NtQueryInformationToken(IN HANDLE TokenHandle,
        break;
 
       case TokenSessionId:
-       DPRINT("NtQueryInformationToken(TokenSessionId)\n");
-       if (TokenInformationLength < sizeof(ULONG))
-         {
-           Length = sizeof(ULONG);
-           Status = MmCopyToCaller(ReturnLength, &Length, sizeof(ULONG));
-           if (NT_SUCCESS(Status))
-             Status = STATUS_BUFFER_TOO_SMALL;
-         }
-       else
-         {
-           Status = MmCopyToCaller(TokenInformation, &Token->SessionId, sizeof(ULONG));
-         }
-       break;
+      {
+        ULONG SessionId = 0;
+
+        DPRINT("NtQueryInformationToken(TokenSessionId)\n");
+        
+        Status = SeQuerySessionIdToken(Token,
+                                       &SessionId);
+
+        if(NT_SUCCESS(Status))
+        {
+          _SEH_TRY
+          {
+            /* buffer size was already verified, no need to check here again */
+            *(PULONG)TokenInformation = SessionId;
+
+            if(ReturnLength != NULL)
+            {
+              *ReturnLength = sizeof(ULONG);
+            }
+          }
+          _SEH_HANDLE
+          {
+            Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+        }
+        
+        break;
+      }
 
       default:
-       DPRINT1("NtQueryInformationToken(%d) invalid parameter\n");
-       Status = STATUS_INVALID_PARAMETER;
+       DPRINT1("NtQueryInformationToken(%d) invalid information class\n", TokenInformationClass);
+       Status = STATUS_INVALID_INFO_CLASS;
        break;
     }
 
-  ObDereferenceObject(Token);
+    ObDereferenceObject(Token);
+  }
 
   return(Status);
 }
@@ -888,7 +1142,7 @@ SeQueryInformationToken(
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
@@ -897,14 +1151,14 @@ SeQuerySessionIdToken(
        IN PULONG pSessionId
        )
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+  *pSessionId = ((PTOKEN)Token)->SessionId;
+  return STATUS_SUCCESS;
 }
 
 /*
  * NtSetTokenInformation: Partly implemented.
  * Unimplemented:
- *  TokenOrigin, TokenDefaultDacl, TokenSessionId
+ *  TokenOrigin, TokenDefaultDacl
  */
 
 NTSTATUS STDCALL
@@ -913,123 +1167,229 @@ NtSetInformationToken(IN HANDLE TokenHandle,
                      OUT PVOID TokenInformation,
                      IN ULONG TokenInformationLength)
 {
-  NTSTATUS Status;
   PTOKEN Token;
-  TOKEN_OWNER TokenOwnerSet = { 0 };
-  TOKEN_PRIMARY_GROUP TokenPrimaryGroupSet = { 0 };
-  DWORD NeededAccess = 0;
+  KPROCESSOR_MODE PreviousMode;
+  ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
+  NTSTATUS Status = STATUS_SUCCESS;
   
   PAGED_CODE();
-
-  switch (TokenInformationClass) 
-    {
-    case TokenOwner:
-    case TokenPrimaryGroup:
-      NeededAccess = TOKEN_ADJUST_DEFAULT;
-      break;
-
-    case TokenDefaultDacl:
-      if (TokenInformationLength < sizeof(TOKEN_DEFAULT_DACL))
-        return STATUS_BUFFER_TOO_SMALL;
-      NeededAccess = TOKEN_ADJUST_DEFAULT;
-      break;
-
-    default:
-      DPRINT1("NtSetInformationToken: lying about success (stub) - %x\n", TokenInformationClass);
-      return STATUS_SUCCESS;  
-
-    }
+  
+  PreviousMode = ExGetPreviousMode();
+  
+  DefaultSetInfoBufferCheck(TokenInformationClass,
+                            SeTokenInformationClass,
+                            TokenInformation,
+                            TokenInformationLength,
+                            PreviousMode,
+                            &Status);
+
+  if(!NT_SUCCESS(Status))
+  {
+    /* Invalid buffers */
+    DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
+    return Status;
+  }
+  
+  if(TokenInformationClass == TokenSessionId)
+  {
+    NeededAccess |= TOKEN_ADJUST_SESSIONID;
+  }
 
   Status = ObReferenceObjectByHandle(TokenHandle,
                                     NeededAccess,
                                     SepTokenObjectType,
-                                    UserMode,
+                                    PreviousMode,
                                     (PVOID*)&Token,
                                     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      return(Status);
-    }
-
-  switch (TokenInformationClass)
+  if (NT_SUCCESS(Status))
+  {
+    switch (TokenInformationClass)
     {
-    case TokenOwner:
-      MmCopyFromCaller( &TokenOwnerSet, TokenInformation,
-                       min(sizeof(TokenOwnerSet),TokenInformationLength) );
-      RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
-                Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
-                TokenOwnerSet.Owner);
-      Status = STATUS_SUCCESS;
-      DPRINT("NtSetInformationToken(TokenOwner)\n");
-      break;
+      case TokenOwner:
+      {
+        if(TokenInformationLength >= sizeof(TOKEN_OWNER))
+        {
+          PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
+          PSID InputSid = NULL;
+          
+          _SEH_TRY
+          {
+            InputSid = to->Owner;
+          }
+          _SEH_HANDLE
+          {
+            Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
+          
+          if(NT_SUCCESS(Status))
+          {
+            PSID CapturedSid;
+            
+            Status = SepCaptureSid(InputSid,
+                                   PreviousMode,
+                                   PagedPool,
+                                   FALSE,
+                                   &CapturedSid);
+            if(NT_SUCCESS(Status))
+            {
+              RtlCopySid(RtlLengthSid(CapturedSid),
+                         Token->UserAndGroups[Token->DefaultOwnerIndex].Sid,
+                         CapturedSid);
+              SepReleaseSid(CapturedSid,
+                            PreviousMode,
+                            FALSE);
+            }
+          }
+        }
+        else
+        {
+          Status = STATUS_INFO_LENGTH_MISMATCH;
+        }
+        break;
+      }
       
-    case TokenPrimaryGroup:
-      MmCopyFromCaller( &TokenPrimaryGroupSet, TokenInformation, 
-                       min(sizeof(TokenPrimaryGroupSet),
-                           TokenInformationLength) );
-      RtlCopySid(TokenInformationLength - sizeof(TOKEN_PRIMARY_GROUP),
-                Token->PrimaryGroup,
-                TokenPrimaryGroupSet.PrimaryGroup);
-      Status = STATUS_SUCCESS;
-      DPRINT("NtSetInformationToken(TokenPrimaryGroup),"
-            "Token->PrimaryGroup = 0x%08x\n", Token->PrimaryGroup);
-      break;
-
-    case TokenDefaultDacl:
+      case TokenPrimaryGroup:
       {
-        TOKEN_DEFAULT_DACL TokenDefaultDacl = { 0 };
-        ACL OldAcl;
-        PACL NewAcl;
+        if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
+        {
+          PTOKEN_PRIMARY_GROUP tpg = (PTOKEN_PRIMARY_GROUP)TokenInformation;
+          PSID InputSid = NULL;
 
-        Status = MmCopyFromCaller( &TokenDefaultDacl, TokenInformation, 
-                                   sizeof(TOKEN_DEFAULT_DACL) );
-        if (!NT_SUCCESS(Status))
+          _SEH_TRY
           {
-            Status = STATUS_INVALID_PARAMETER;
-            break;
+            InputSid = tpg->PrimaryGroup;
           }
-
-        Status = MmCopyFromCaller( &OldAcl, TokenDefaultDacl.DefaultDacl,
-                                   sizeof(ACL) );
-        if (!NT_SUCCESS(Status))
+          _SEH_HANDLE
           {
-            Status = STATUS_INVALID_PARAMETER;
-            break;
+            Status = _SEH_GetExceptionCode();
           }
+          _SEH_END;
 
-        NewAcl = ExAllocatePool(NonPagedPool, sizeof(ACL));
-        if (NewAcl == NULL)
+          if(NT_SUCCESS(Status))
           {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            break;
+            PSID CapturedSid;
+
+            Status = SepCaptureSid(InputSid,
+                                   PreviousMode,
+                                   PagedPool,
+                                   FALSE,
+                                   &CapturedSid);
+            if(NT_SUCCESS(Status))
+            {
+              RtlCopySid(RtlLengthSid(CapturedSid),
+                         Token->PrimaryGroup,
+                         CapturedSid);
+              SepReleaseSid(CapturedSid,
+                            PreviousMode,
+                            FALSE);
+            }
           }
+        }
+        else
+        {
+          Status = STATUS_INFO_LENGTH_MISMATCH;
+        }
+        break;
+      }
+      
+      case TokenDefaultDacl:
+      {
+        if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
+        {
+          PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
+          PACL InputAcl = NULL;
 
-        Status = MmCopyFromCaller( NewAcl, TokenDefaultDacl.DefaultDacl,
-                                   OldAcl.AclSize );
-        if (!NT_SUCCESS(Status))
+          _SEH_TRY
           {
-            Status = STATUS_INVALID_PARAMETER;
-            ExFreePool(NewAcl);
-            break;
+            InputAcl = tdd->DefaultDacl;
           }
+          _SEH_HANDLE
+          {
+            Status = _SEH_GetExceptionCode();
+          }
+          _SEH_END;
 
-        if (Token->DefaultDacl)
+          if(NT_SUCCESS(Status))
           {
-            ExFreePool(Token->DefaultDacl);
+            if(InputAcl != NULL)
+            {
+              PACL CapturedAcl;
+
+              /* capture and copy the dacl */
+              Status = SepCaptureAcl(InputAcl,
+                                     PreviousMode,
+                                     PagedPool,
+                                     TRUE,
+                                     &CapturedAcl);
+              if(NT_SUCCESS(Status))
+              {
+                /* free the previous dacl if present */
+                if(Token->DefaultDacl != NULL)
+                {
+                  ExFreePool(Token->DefaultDacl);
+                }
+                
+                /* set the new dacl */
+                Token->DefaultDacl = CapturedAcl;
+              }
+            }
+            else
+            {
+              /* clear and free the default dacl if present */
+              if(Token->DefaultDacl != NULL)
+              {
+                ExFreePool(Token->DefaultDacl);
+                Token->DefaultDacl = NULL;
+              }
+            }
           }
+        }
+        else
+        {
+          Status = STATUS_INFO_LENGTH_MISMATCH;
+        }
+        break;
+      }
+      
+      case TokenSessionId:
+      {
+        ULONG SessionId = 0;
 
-        Token->DefaultDacl = NewAcl;
+        _SEH_TRY
+        {
+          /* buffer size was already verified, no need to check here again */
+          SessionId = *(PULONG)TokenInformation;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(NT_SUCCESS(Status))
+        {
+          if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
+                                     PreviousMode))
+          {
+            Status = STATUS_PRIVILEGE_NOT_HELD;
+            break;
+          }
 
-        Status = STATUS_SUCCESS;
+          Token->SessionId = SessionId;
+        }
         break;
       }
 
-    default:
-      Status = STATUS_NOT_IMPLEMENTED;
-      break;
+      default:
+      {
+        Status = STATUS_NOT_IMPLEMENTED;
+        break;
+      }
     }
 
-  ObDereferenceObject(Token);
+    ObDereferenceObject(Token);
+  }
 
   return(Status);
 }
@@ -1045,16 +1405,18 @@ NtSetInformationToken(IN HANDLE TokenHandle,
  */
 NTSTATUS STDCALL
 NtDuplicateToken(IN HANDLE ExistingTokenHandle,
-                IN ACCESS_MASK DesiredAccess,
-       IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL /*is it really optional?*/,
-       IN BOOLEAN EffectiveOnly,
-                IN TOKEN_TYPE TokenType,
-                OUT PHANDLE NewTokenHandle)
+                 IN ACCESS_MASK DesiredAccess,
+                 IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                 IN BOOLEAN EffectiveOnly,
+                 IN TOKEN_TYPE TokenType,
+                 OUT PHANDLE NewTokenHandle)
 {
   KPROCESSOR_MODE PreviousMode;
   HANDLE hToken;
   PTOKEN Token;
   PTOKEN NewToken;
+  PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
+  BOOLEAN QoSPresent;
   NTSTATUS Status = STATUS_SUCCESS;
   
   PAGED_CODE();
@@ -1081,57 +1443,66 @@ NtDuplicateToken(IN HANDLE ExistingTokenHandle,
     }
   }
   
+  Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
+                                              PreviousMode,
+                                              PagedPool,
+                                              FALSE,
+                                              &CapturedSecurityQualityOfService,
+                                              &QoSPresent);
+  if(!NT_SUCCESS(Status))
+  {
+    DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
+    return Status;
+  }
+  
   Status = ObReferenceObjectByHandle(ExistingTokenHandle,
                                     TOKEN_DUPLICATE,
                                     SepTokenObjectType,
                                     PreviousMode,
                                     (PVOID*)&Token,
                                     NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("Failed to reference token (Status %lx)\n", Status);
-      return Status;
-    }
-
-  Status = SepDuplicateToken(Token,
-                            ObjectAttributes,
-                            EffectiveOnly,
-                            TokenType,
-              ObjectAttributes->SecurityQualityOfService ? 
-                  ((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->ImpersonationLevel : 
-                  0 /*SecurityAnonymous*/,
-                            PreviousMode,
-                            &NewToken);
+  if (NT_SUCCESS(Status))
+  {
+    Status = SepDuplicateToken(Token,
+                               ObjectAttributes,
+                               EffectiveOnly,
+                               TokenType,
+                               (QoSPresent ? CapturedSecurityQualityOfService->ImpersonationLevel : SecurityAnonymous),
+                              PreviousMode,
+                              &NewToken);
 
-  ObDereferenceObject(Token);
+    ObDereferenceObject(Token);
 
-  if (!NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status))
     {
-      DPRINT1("Failed to duplicate token (Status %lx)\n", Status);
-      return Status;
-    }
+      Status = ObInsertObject((PVOID)NewToken,
+                         NULL,
+                         DesiredAccess,
+                         0,
+                         NULL,
+                         &hToken);
 
-  Status = ObInsertObject((PVOID)NewToken,
-                         NULL,
-                         DesiredAccess,
-                         0,
-                         NULL,
-                         &hToken);
-
-  ObDereferenceObject(NewToken);
+      ObDereferenceObject(NewToken);
 
-  if (NT_SUCCESS(Status))
-    {
-      _SEH_TRY
+      if (NT_SUCCESS(Status))
       {
-        *NewTokenHandle = hToken;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
+        _SEH_TRY
+        {
+          *NewTokenHandle = hToken;
+        }
+        _SEH_HANDLE
+        {
+          Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
       }
-      _SEH_END;
     }
+  }
+  
+  /* free the captured structure */
+  SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
+                                     PreviousMode,
+                                     FALSE);
 
   return Status;
 }
@@ -1261,7 +1632,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
 {
 //  PLUID_AND_ATTRIBUTES Privileges;
   KPROCESSOR_MODE PreviousMode;
-//  ULONG PrivilegeCount;
+  ULONG PrivilegeCount;
   PTOKEN Token;
 //  ULONG Length;
   ULONG i;
@@ -1292,7 +1663,7 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
 //                               &Length);
 
   Status = ObReferenceObjectByHandle (TokenHandle,
-                                     TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+                                     TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
                                      SepTokenObjectType,
                                      PreviousMode,
                                      (PVOID*)&Token,
@@ -1319,6 +1690,12 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                       &c);
 #endif
 
+  PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) /
+                   sizeof(LUID_AND_ATTRIBUTES);
+
+  if (PreviousState != NULL)
+    PreviousState->PrivilegeCount = 0;
+
   k = 0;
   if (DisableAllPrivileges == TRUE)
     {
@@ -1329,11 +1706,22 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
              DPRINT ("Attributes differ\n");
 
              /* Save current privilege */
-             if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
+             if (PreviousState != NULL)
                {
-                 PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
-                 PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
-                 k++;
+                  if (k < PrivilegeCount)
+                    {
+                      PreviousState->PrivilegeCount++;
+                      PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+                      PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+                    }
+                  else
+                    {
+                      /* FIXME: Should revert all the changes, calculate how
+                       * much space would be needed, set ResultLength
+                       * accordingly and fail.
+                       */
+                    }
+                  k++;
                }
 
              /* Update current privlege */
@@ -1363,11 +1751,22 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
                              NewState->Privileges[j].Attributes);
 
                      /* Save current privilege */
-                     if (PreviousState != NULL && k < PreviousState->PrivilegeCount)
+                     if (PreviousState != NULL)
                        {
-                         PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
-                         PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
-                         k++;
+                          if (k < PrivilegeCount)
+                            {
+                              PreviousState->PrivilegeCount++;
+                              PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
+                              PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
+                            }
+                          else
+                            {
+                              /* FIXME: Should revert all the changes, calculate how
+                               * much space would be needed, set ResultLength
+                               * accordingly and fail.
+                               */
+                            }
+                          k++;
                        }
 
                      /* Update current privlege */
@@ -1408,6 +1807,8 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
   NTSTATUS Status;
   ULONG uSize;
   ULONG i;
+  
+  PAGED_CODE();
 
   ULONG uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
   ULONG uWorldLength       = RtlLengthSid(SeWorldSid);
@@ -1456,6 +1857,8 @@ SepCreateSystemProcessToken(struct _EPROCESS* Process)
       return Status;
     }
 
+  AccessToken->TokenLock = &SepTokenLock;
+
   AccessToken->TokenType = TokenPrimary;
   AccessToken->ImpersonationLevel = SecurityDelegation;
   AccessToken->TokenSource.SourceIdentifier.LowPart = 0;
@@ -1706,6 +2109,8 @@ NtCreateToken(OUT PHANDLE TokenHandle,
       return(Status);
     }
 
+  AccessToken->TokenLock = &SepTokenLock;
+
   RtlCopyLuid(&AccessToken->TokenSource.SourceIdentifier,
              &TokenSource->SourceIdentifier);
   memcpy(AccessToken->TokenSource.SourceName,
@@ -1738,7 +2143,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
     uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
 
   AccessToken->UserAndGroups = 
-    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+    (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                               uLength,
                                               TAG('T', 'O', 'K', 'u'));
 
@@ -1774,7 +2179,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
     {
       uLength = TokenPrivileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
       AccessToken->Privileges =
-       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
+       (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
                                                    uLength,
                                                    TAG('T', 'O', 'K', 'p'));
 
@@ -1791,7 +2196,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
   if (NT_SUCCESS(Status))
     {
       AccessToken->DefaultDacl =
-       (PACL) ExAllocatePoolWithTag(NonPagedPool,
+       (PACL) ExAllocatePoolWithTag(PagedPool,
                                     TokenDefaultDacl->DefaultDacl->AclSize,
                                     TAG('T', 'O', 'K', 'd'));
       memcpy(AccessToken->DefaultDacl,
index 8ea5ef9..49f51cc 100755 (executable)
@@ -6,7 +6,7 @@ TARGET_TYPE = dynlink
 
 TARGET_NAME = regtests
 
-TARGET_CFLAGS = -Wall -Werror
+TARGET_CFLAGS = -D__USE_W32API -Wall -Werror
 
 TARGET_OBJECTS = \
   regtests.o
index 6a0cbc4..aee66c5 100644 (file)
@@ -1,6 +1,7 @@
 <module name="regtests" type="win32dll" baseaddress="${BASEADDRESS_REGTESTS}">\r
        <importlibrary definition="regtests.def" />\r
        <include base="regtests">.</include>\r
+       <define name="__USE_W32API" />\r
        <library>kernel32</library>\r
        <file>regtests.c</file>\r
 </module>\r
index ec3b877..93147eb 100644 (file)
@@ -14,7 +14,7 @@ TARGET_SDKLIBS = kernel32.a advapi32.a
 
 TARGET_OBJECTS = $(TARGET_NAME).o endpoint.o
 
-TARGET_CFLAGS = -Wall -Werror
+TARGET_CFLAGS = -D__USE_W32API -Wall -Werror
 
 include $(PATH_TO_TOP)/rules.mak
 
index 28474b0..2775a2b 100644 (file)
@@ -1,5 +1,6 @@
 <module name="rpcss" type="win32cui">\r
        <include base="rpcss">.</include>\r
+       <define name="__USE_W32API" />\r
        <library>kernel32</library>\r
        <library>advapi32</library>\r
        <file>rpcss.c</file>\r
index f96bb8b..d935174 100644 (file)
@@ -12,12 +12,25 @@ TARGET_INSTALLDIR = system32
 \r
 TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a rpcrt4.a\r
 \r
-TARGET_OBJECTS = umpnpmgr.o\r
+TARGET_OBJECTS = pnp_s.o umpnpmgr.o\r
 \r
-TARGET_CFLAGS = -Wall -Werror -D__USE_W32API\r
+TARGET_CFLAGS = -Wall -Werror -D__USE_W32API -DUNICODE -D_UNICODE\r
+\r
+TARGET_CLEAN = pnp_s.c pnp.h\r
+\r
+DEP_OBJECTS = $(TARGET_OBJECTS)\r
 \r
 include $(PATH_TO_TOP)/rules.mak\r
 \r
 include $(TOOLS_PATH)/helper.mk\r
 \r
+include $(TOOLS_PATH)/depend.mk\r
+\r
+WIDL_FLAGS = \\r
+             -D _X86_ -D MIDL_PASS \\r
+             -I $(PATH_TO_TOP)/w32api/include\r
+\r
+pnp_s.c pnp.h: $(PATH_TO_TOP)/include/idl/pnp.idl\r
+       $(WIDL) $(WIDL_FLAGS) -h -H pnp.h -s -S pnp_s.c $(PATH_TO_TOP)/include/idl/pnp.idl\r
+\r
 # EOF\r
index b9b5659..a4b0b15 100644 (file)
@@ -27,9 +27,6 @@
 \r
 /* INCLUDES *****************************************************************/\r
 \r
-#define UNICODE\r
-#define _UNICODE\r
-\r
 #define NTOS_MODE_USER\r
 #include <ntos.h>\r
 #include <ntos/ntpnp.h>\r
@@ -41,6 +38,8 @@
 #include <rpc.h>\r
 #include <rpcdce.h>\r
 \r
+#include "pnp_s.h"\r
+\r
 #define DBG\r
 #define NDEBUG\r
 #include <debug.h>\r
@@ -61,6 +60,66 @@ static SERVICE_TABLE_ENTRY ServiceTable[2] =
 \r
 /* FUNCTIONS *****************************************************************/\r
 \r
+static DWORD WINAPI\r
+RpcServerThread(LPVOID lpParameter)\r
+{\r
+  RPC_STATUS Status;\r
+\r
+  DPRINT("RpcServerThread() called\n");\r
+\r
+  Status = RpcServerUseProtseqEpW(L"ncacn_np",\r
+                                  20,\r
+                                  L"\\pipe\\umpnpmgr",\r
+                                  NULL);  // Security descriptor\r
+  if (Status != RPC_S_OK)\r
+  {\r
+    DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);\r
+    return 0;\r
+  }\r
+\r
+  Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,\r
+                               NULL,\r
+                               NULL);\r
+  if (Status != RPC_S_OK)\r
+  {\r
+    DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);\r
+    return 0;\r
+  }\r
+\r
+  Status = RpcServerListen(1,\r
+                           20,\r
+                           FALSE);\r
+  if (Status != RPC_S_OK)\r
+  {\r
+    DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);\r
+    return 0;\r
+  }\r
+\r
+  DPRINT("RpcServerThread() done\n");\r
+\r
+  return 0;\r
+}\r
+\r
+\r
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)\r
+{\r
+  return GlobalAlloc(GPTR, len);\r
+}\r
+\r
+\r
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr)\r
+{\r
+  GlobalFree(ptr);\r
+}\r
+\r
+\r
+//WORD PNP_GetVersion(RPC_BINDING_HANDLE BindingHandle)\r
+WORD PNP_GetVersion(handle_t BindingHandle)\r
+{\r
+  return 0x0400;\r
+}\r
+\r
+\r
 static DWORD WINAPI\r
 PnpEventThread(LPVOID lpParameter)\r
 {\r
@@ -134,6 +193,15 @@ ServiceMain(DWORD argc, LPTSTR *argv)
   if (hThread != NULL)\r
     CloseHandle(hThread);\r
 \r
+  hThread = CreateThread(NULL,\r
+                        0,\r
+                        RpcServerThread,\r
+                        NULL,\r
+                        0,\r
+                        &dwThreadId);\r
+  if (hThread != NULL)\r
+    CloseHandle(hThread);\r
+\r
   DPRINT("ServiceMain() done\n");\r
 }\r
 \r
index 20c6130..84ff6f9 100644 (file)
@@ -1,6 +1,10 @@
 <module name="umpnpmgr" type="win32cui" installbase="system32" installname="umpnpmgr.exe">\r
        <include base="umpnpmgr">.</include>\r
+       <include base="pnp_server">.</include>\r
        <define name="__USE_W32API" />\r
+       <define name="UNICODE" />\r
+       <define name="_UNICODE" />\r
+       <library>pnp_server</library>\r
        <library>ntdll</library>\r
        <library>kernel32</library>\r
        <library>advapi32</library>\r
index 7a5bd60..24dacee 100644 (file)
@@ -59,6 +59,9 @@ PCSRSS_PROCESS_DATA STDCALL CsrCreateProcessData(HANDLE ProcessId)
 {
    ULONG hash;
    PCSRSS_PROCESS_DATA pProcessData;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   CLIENT_ID ClientId;
+   NTSTATUS Status;
 
    hash = (ULONG_PTR)ProcessId % (sizeof(ProcessData) / sizeof(*ProcessData));
    
@@ -80,6 +83,27 @@ PCSRSS_PROCESS_DATA STDCALL CsrCreateProcessData(HANDLE ProcessId)
         pProcessData->ProcessId = ProcessId;
         pProcessData->next = ProcessData[hash];
         ProcessData[hash] = pProcessData;
+
+         ClientId.UniqueThread = NULL;
+         ClientId.UniqueProcess = pProcessData->ProcessId;
+         InitializeObjectAttributes(&ObjectAttributes,
+                                    NULL,
+                                    0,
+                                    NULL,
+                                    NULL);
+
+         /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
+         Status = NtOpenProcess(&pProcessData->Process,
+                                PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION |
+                                PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | SYNCHRONIZE,
+                                &ObjectAttributes,
+                                &ClientId);
+         if (!NT_SUCCESS(Status))
+         {
+            ProcessData[hash] = pProcessData->next;
+           RtlFreeHeap(CsrssApiHeap, 0, pProcessData);
+           pProcessData = NULL;
+        }
       }
    }
    else
@@ -115,6 +139,10 @@ NTSTATUS STDCALL CsrFreeProcessData(HANDLE Pid)
   if (pProcessData)
     {
       DPRINT("CsrFreeProcessData pid: %d\n", Pid);
+      if (pProcessData->Process)
+      {
+         NtClose(pProcessData->Process);
+      }
       if (pProcessData->Console)
         {
           RtlEnterCriticalSection(&ProcessDataLock);
@@ -167,7 +195,6 @@ CSR_API(CsrCreateProcess)
 {
    PCSRSS_PROCESS_DATA NewProcessData;
    NTSTATUS Status;
-   HANDLE Process;
    CSRSS_API_REQUEST ApiRequest;
    CSRSS_API_REPLY ApiReply;
 
@@ -212,8 +239,6 @@ CSR_API(CsrCreateProcess)
      }
    else
      {
-       CLIENT_ID ClientId;
-
        NewProcessData->Console = ProcessData->Console;
        InterlockedIncrement( &(ProcessData->Console->Header.ReferenceCount) );
        CsrInsertObject(NewProcessData,
@@ -225,27 +250,15 @@ CSR_API(CsrCreateProcess)
           &(NewProcessData->Console->ActiveBuffer->Header) );
 
        RtlLeaveCriticalSection(&ProcessDataLock);
-       ClientId.UniqueProcess = (HANDLE)NewProcessData->ProcessId;
-       Status = NtOpenProcess( &Process, PROCESS_DUP_HANDLE, 0, &ClientId );
-       if( !NT_SUCCESS( Status ) )
-        {
-          DbgPrint( "CSR: NtOpenProcess() failed for handle duplication\n" );
-          InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
-          CsrFreeProcessData( NewProcessData->ProcessId );
-          Reply->Status = Status;
-          return Status;
-        }
-       Status = NtDuplicateObject( NtCurrentProcess(), NewProcessData->Console->ActiveEvent, Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
+       Status = NtDuplicateObject( NtCurrentProcess(), NewProcessData->Console->ActiveEvent, NewProcessData->Process, &NewProcessData->ConsoleEvent, SYNCHRONIZE, FALSE, 0 );
        if( !NT_SUCCESS( Status ) )
         {
           DbgPrint( "CSR: NtDuplicateObject() failed: %x\n", Status );
-          NtClose( Process );
           InterlockedDecrement( &(NewProcessData->Console->Header.ReferenceCount) );
           CsrFreeProcessData( NewProcessData->ProcessId );
           Reply->Status = Status;
           return Status;
         }
-       NtClose( Process );
        NewProcessData->CtrlDispatcher = Request->Data.CreateProcessRequest.CtrlDispatcher;
        RtlEnterCriticalSection(&ProcessDataLock );
        InsertHeadList(&NewProcessData->Console->ProcessList, &NewProcessData->ProcessEntry);
index 0852c0a..406f5ea 100644 (file)
 
 /* INCLUDES ******************************************************************/
 
+#define NTOS_MODE_USER
+#include <ntos.h>
 #include <csrss/csrss.h>
 #include <ddk/ntddk.h>
-#include <ntdll/rtl.h>
+
+
+
+#define NDEBUG
 #include <debug.h>
 
 #include "api.h"
 
 /* GLOBALS *******************************************************************/
 
-HANDLE CsrssApiHeap;
+HANDLE CsrssApiHeap = (HANDLE) 0;
 
 static unsigned ApiDefinitionsCount = 0;
 static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
@@ -33,6 +38,8 @@ CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions)
   PCSRSS_API_DEFINITION Scan;
   PCSRSS_API_DEFINITION New;
 
+       DPRINT("CSR: %s called", __FUNCTION__);
+
   NewCount = 0;
   for (Scan = NewDefinitions; 0 != Scan->Handler; Scan++)
     {
@@ -107,6 +114,8 @@ ClientConnectionThread(HANDLE ServerPort)
   PCSRSS_PROCESS_DATA ProcessData;
   PCSRSS_API_REPLY Reply;
    
+       DPRINT("CSR: %s called", __FUNCTION__);
+
   Reply = NULL;
    
   for (;;)
@@ -153,34 +162,37 @@ ClientConnectionThread(HANDLE ServerPort)
  *     Handle connection requests from clients to the port
  *     "\Windows\ApiPort".
  */
-void STDCALL
+DWORD STDCALL
 ServerApiPortThread (PVOID PortHandle)
 {
-   NTSTATUS Status;
+   NTSTATUS Status = STATUS_SUCCESS;
    LPC_MAX_MESSAGE Request;
-   HANDLE ServerPort;
-   HANDLE ServerThread;
-   PCSRSS_PROCESS_DATA ProcessData;
+   HANDLE hApiListenPort = * (PHANDLE) PortHandle;
+   HANDLE ServerPort = (HANDLE) 0;
+   HANDLE ServerThread = (HANDLE) 0;
+   PCSRSS_PROCESS_DATA ProcessData = NULL;
    
    CsrInitProcessData();
    
+       DPRINT("CSR: %s called", __FUNCTION__);
+
    for (;;)
      {
         LPC_SECTION_READ LpcRead;
         ServerPort = NULL;
 
-       Status = NtListenPort(PortHandle, &Request.Header);
+       Status = NtListenPort (hApiListenPort, & Request.Header);
        if (!NT_SUCCESS(Status))
          {
             DPRINT1("CSR: NtListenPort() failed\n");
             break;
          }
-       Status = NtAcceptConnectPort(&ServerPort,
-                                    PortHandle,
+       Status = NtAcceptConnectPort(& ServerPort,
+                                    hApiListenPort,
                                     NULL,
                                     TRUE,
                                     0,
-                                    &LpcRead);
+                                    & LpcRead);
        if (!NT_SUCCESS(Status))
          {
             DPRINT1("CSR: NtAcceptConnectPort() failed\n");
@@ -215,7 +227,7 @@ ServerApiPortThread (PVOID PortHandle)
                                     NULL,
                                     (PTHREAD_START_ROUTINE)ClientConnectionThread,
                                     ServerPort,
-                                    &ServerThread,
+                                    & ServerThread,
                                     NULL);
        if (!NT_SUCCESS(Status))
          {
@@ -230,6 +242,7 @@ ServerApiPortThread (PVOID PortHandle)
      }
    NtClose(PortHandle);
    NtTerminateThread(NtCurrentThread(), Status);
+   return 0;
 }
 
 /**********************************************************************
@@ -238,45 +251,88 @@ ServerApiPortThread (PVOID PortHandle)
  *
  * DESCRIPTION
  *     Handle connection requests from SM to the port
- *     "\Windows\SbApiPort".
+ *     "\Windows\SbApiPort". We will accept only one
+ *     connection request (from the SM).
  */
-VOID STDCALL
+DWORD STDCALL
 ServerSbApiPortThread (PVOID PortHandle)
 {
-       HANDLE          hSbApiPortListen = (HANDLE) PortHandle;
+       HANDLE          hSbApiPortListen = * (PHANDLE) PortHandle;
        HANDLE          hConnectedPort = (HANDLE) 0;
        LPC_MAX_MESSAGE Request = {{0}};
+       PVOID           Context = NULL;
        NTSTATUS        Status = STATUS_SUCCESS;
 
-       while (TRUE)
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       Status = NtListenPort (hSbApiPortListen, & Request.Header);
+       if (!NT_SUCCESS(Status))
        {
-               Status = NtListenPort (hSbApiPortListen, & Request.Header);
-               if (!NT_SUCCESS(Status))
-               {
-                       DPRINT1("CSR: %s: NtListenPort(SB) failed\n", __FUNCTION__);
-                       break;
-               }
+               DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
+                       __FUNCTION__, Status);
+       } else {
+DPRINT("-- 1\n");
                Status = NtAcceptConnectPort (& hConnectedPort,
                                                hSbApiPortListen,
-                                               NULL,
-                                               TRUE,
-                                               NULL,
+                                               NULL,
+                                               TRUE,
+                                               NULL,
                                                NULL);
                if(!NT_SUCCESS(Status))
                {
-                       DPRINT1("CSR: %s: NtAcceptConnectPort() failed\n", __FUNCTION__);
-                       break;
-               }
-               Status = NtCompleteConnectPort (hConnectedPort);
-               if(!NT_SUCCESS(Status))
-               {
-                       DPRINT1("CSR: %s: NtCompleteConnectPort() failed\n", __FUNCTION__);
-                       break;
+                       DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
+                               __FUNCTION__, Status);
+               } else {
+DPRINT("-- 2\n");
+                       Status = NtCompleteConnectPort (hConnectedPort);
+                       if(!NT_SUCCESS(Status))
+                       {
+                               DPRINT1("CSR: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
+                                       __FUNCTION__, Status);
+                       } else {
+DPRINT("-- 3\n");
+                               PLPC_MESSAGE Reply = NULL;
+                               /* 
+                                * Tell the init thread the SM gave the
+                                * green light for boostrapping.
+                                */
+                               Status = NtSetEvent (hBootstrapOk, NULL);
+                               if(!NT_SUCCESS(Status))
+                               {
+                                       DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
+                                               __FUNCTION__, Status);
+                               }
+                               /* Wait for messages from the SM */
+DPRINT("-- 4\n");
+                               while (TRUE)
+                               {
+                                       Status = NtReplyWaitReceivePort(hConnectedPort,
+                                                                       Context,
+                                                                       Reply,
+                                                                       & Request.Header);
+                                       if(!NT_SUCCESS(Status))
+                                       {
+                                               DPRINT1("CSR: %s: NtReplyWaitReceivePort failed (Status=0x%08lx)\n",
+                                                       __FUNCTION__, Status);
+                                               break;
+                                       }
+                                       switch (Request.Header.MessageType)//fix .h PORT_MESSAGE_TYPE(Request))
+                                       {
+                                               /* TODO */
+                                       default:
+                                               DPRINT1("CSR: %s received message (type=%d)\n",
+                                                       __FUNCTION__, Request.Header.MessageType);
+                                       }
+DPRINT("-- 5\n");
+                               }
+                       }
                }
-               /* TODO: create thread for the connected port */
        }
+       DPRINT1("CSR: %s: terminating!\n", __FUNCTION__);
+       if(hConnectedPort) NtClose (hConnectedPort);
        NtClose (hSbApiPortListen);
        NtTerminateThread (NtCurrentThread(), Status);
+       return 0;
 }
 
 /* EOF */
index b2b885e..9a2abea 100644 (file)
@@ -35,6 +35,7 @@
 #include <ntdll/rtl.h>
 #include <csrss/csrss.h>
 #include <rosrtl/string.h>
+#include <reactos/buildno.h>
 
 #include "api.h"
 
@@ -145,78 +146,37 @@ CsrpFreeCommandLine (HANDLE                 ProcessHeap,
 }
 
 
-/**********************************************************************
- * NAME                                                        PRIVATE
- *     CsrpOpenSmInitDoneEvent/0
- */
-static NTSTATUS STDCALL
-CsrpOpenSmInitDoneEvent (PHANDLE CsrssInitEvent)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING    EventName;
-
-   DPRINT("CSR: %s called\n", __FUNCTION__);
-
-   RtlInitUnicodeString(& EventName,
-                       L"\\CsrssInitDone");
-   InitializeObjectAttributes (& ObjectAttributes,
-                               & EventName,
-                               EVENT_ALL_ACCESS,
-                               0,
-                               NULL);
-   return NtOpenEvent (CsrssInitEvent,
-                       EVENT_ALL_ACCESS,
-                       & ObjectAttributes);
-}
-
 /* Native process' entry point */
 
 VOID STDCALL NtProcessStartup(PPEB Peb)
 {
    PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL;
    COMMAND_LINE_ARGUMENT        CmdLineArg = {0};
-   HANDLE                       CsrssInitEvent = (HANDLE) 0;
    NTSTATUS                     Status = STATUS_SUCCESS;
 
-   DPRINT("CSR: %s\n", __FUNCTION__);
+   PrintString("ReactOS Client/Server Run-Time %s (Build %s)\n",
+            KERNEL_RELEASE_STR,
+            KERNEL_VERSION_BUILD_STR);
 
    RtlProcessParameters = RtlNormalizeProcessParams (Peb->ProcessParameters);
 
    /*==================================================================
-    * Parse the command line.
+    * Parse the command line: TODO actually parse the cl, because
+    * it is required to load hosted server DLLs.
     *================================================================*/
    Status = CsrpParseCommandLine (Peb->ProcessHeap,
                                  RtlProcessParameters,
                                  & CmdLineArg);
    if(STATUS_SUCCESS != Status)
    {
-          DbgPrint("CSR: CsrpParseCommandLine failed (Status=0x%08lx)\n",
-               Status);
+          DPRINT1("CSR: %s: CsrpParseCommandLine failed (Status=0x%08lx)\n",
+               __FUNCTION__, Status);
    }
-   /*
-    * Open the SM notification event to notify we are OK after
-    * subsystem server initialization.
-    */
-   Status = CsrpOpenSmInitDoneEvent(& CsrssInitEvent);
-   if (!NT_SUCCESS(Status))
-     {
-       DbgPrint("CSR: CsrpOpenSmInitDoneEvent failed (Status=0x%08lx)\n",
-                       Status);
-     }
    /*==================================================================
     *  Initialize the Win32 environment subsystem server.
     *================================================================*/
    if (CsrServerInitialization (CmdLineArg.Count, CmdLineArg.Vector) == TRUE)
      {
-       /*=============================================================
-        * Tell SM we are up and safe. If we fail to notify SM, it will
-        * die and the kernel will bugcheck with
-        * SESSION5_INITIALIZATION_FAILED.
-        * TODO: this won't be necessary, because CSR will call SM
-        * API SM_SESSION_COMPLETE.
-        *===========================================================*/
-       NtSetEvent (CsrssInitEvent, NULL);
-
        CsrpFreeCommandLine (Peb->ProcessHeap, & CmdLineArg);   
        /*
         * Terminate the current thread only.
index 0f8610e..06b358f 100644 (file)
@@ -37,6 +37,7 @@ typedef struct _CSRSS_PROCESS_DATA
   ULONG HandleTableSize;
   Object_t ** HandleTable;
   HANDLE ProcessId;
+  HANDLE Process;
   ULONG ShutdownLevel;
   ULONG ShutdownFlags;
   HANDLE ConsoleEvent;
@@ -82,6 +83,9 @@ PCSRSS_PROCESS_DATA ProcessData,\
 PCSRSS_API_REQUEST Request,\
 PCSRSS_API_REPLY Reply)
 
+/* init.c */
+extern HANDLE hBootstrapOk;
+
 /* api/process.c */
 CSR_API(CsrConnectProcess);
 CSR_API(CsrCreateProcess);
@@ -96,9 +100,9 @@ NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION NewDefinitions
 VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
                                 PCSRSS_API_REQUEST Request,
                                 PCSRSS_API_REPLY Reply);
-VOID STDCALL ServerApiPortThread (PVOID PortHandle);
-VOID STDCALL ServerSbApiPortThread (PVOID PortHandle);
-VOID Console_Api( DWORD Ignored );
+DWORD STDCALL ServerApiPortThread (PVOID PortHandle);
+DWORD STDCALL ServerSbApiPortThread (PVOID PortHandle);
+DWORD STDCALL Console_Api( PVOID unused );
 
 extern HANDLE CsrssApiHeap;
 
index 106ad69..e8c0076 100644 (file)
 
 /* GLOBALS ******************************************************************/
 
-HANDLE CsrInitEvent = INVALID_HANDLE_VALUE;
-HANDLE CsrHeap = INVALID_HANDLE_VALUE;
+HANDLE CsrHeap = (HANDLE) 0;
 
-HANDLE CsrObjectDirectory = INVALID_HANDLE_VALUE;
+HANDLE CsrObjectDirectory = (HANDLE) 0;
 
 UNICODE_STRING CsrDirectoryName;
 
@@ -39,11 +38,24 @@ extern HANDLE CsrssApiHeap;
 static unsigned InitCompleteProcCount;
 static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
 
+HANDLE hSbApiPort = (HANDLE) 0;
+
+HANDLE hBootstrapOk = (HANDLE) 0;
+
+HANDLE hSmApiPort = (HANDLE) 0;
+
+HANDLE hApiPort = (HANDLE) 0;
+
+/**********************************************************************
+ * CsrpAddInitCompleteProc/1
+ */
 static NTSTATUS FASTCALL
-AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
+CsrpAddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
 {
   CSRPLUGIN_INIT_COMPLETE_PROC *NewProcs;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
                              (InitCompleteProcCount + 1)
                              * sizeof(CSRPLUGIN_INIT_COMPLETE_PROC));
@@ -64,12 +76,17 @@ AddInitCompleteProc(CSRPLUGIN_INIT_COMPLETE_PROC Proc)
   return STATUS_SUCCESS;
 }
 
+/**********************************************************************
+ * CallInitComplete/0
+ */
 static BOOL FASTCALL
 CallInitComplete(void)
 {
   BOOL Ok;
   unsigned i;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   Ok = TRUE;
   if (0 != InitCompleteProcCount)
     {
@@ -86,8 +103,11 @@ CallInitComplete(void)
 ULONG
 InitializeVideoAddressSpace(VOID);
 
+/**********************************************************************
+ * CsrpParseCommandLine/2
+ */
 static NTSTATUS
-CsrParseCommandLine (
+CsrpParseCommandLine (
        ULONG ArgumentCount,
        PWSTR *ArgumentArray
        )
@@ -95,6 +115,8 @@ CsrParseCommandLine (
    NTSTATUS Status;
    OBJECT_ATTRIBUTES Attributes;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
 
    /*   DbgPrint ("Arguments: %ld\n", ArgumentCount);
    for (i = 0; i < ArgumentCount; i++)
@@ -114,21 +136,28 @@ CsrParseCommandLine (
                                    NULL);
 
        Status = NtCreateDirectoryObject(&CsrObjectDirectory,
-                                        0xF000F,
+                                        0xF000F, /* ea:??? */
                                         &Attributes);
 
        return Status;
 }
 
-
-static VOID
-CsrInitVideo(VOID)
+/**********************************************************************
+ * CsrpInitVideo/0
+ *
+ * TODO: we need a virtual device for sessions other than
+ * TODO: the console one
+ */
+static NTSTATUS
+CsrpInitVideo (ULONG argc, PWSTR* argv)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING DeviceName;
   IO_STATUS_BLOCK Iosb;
-  HANDLE VideoHandle;
-  NTSTATUS Status;
+  HANDLE VideoHandle = (HANDLE) 0;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  DPRINT("CSR: %s called\n", __FUNCTION__);
 
   InitializeVideoAddressSpace();
 
@@ -148,10 +177,23 @@ CsrInitVideo(VOID)
     {
       NtClose(VideoHandle);
     }
+  return Status;
 }
 
-static NTSTATUS FASTCALL
-InitWin32Csr()
+/**********************************************************************
+ * CsrpInitWin32Csr/0
+ *
+ * TODO: this function should be turned more general to load an
+ * TODO: hosted server DLL as received from the command line;
+ * TODO: for instance: ServerDll=winsrv:ConServerDllInitialization,2
+ * TODO:               ^method   ^dll   ^api                       ^sid
+ * TODO:
+ * TODO: CsrpHostServerDll (LPWSTR DllName,
+ * TODO:                    LPWSTR ApiName,
+ * TODO:                    DWORD  ServerId)
+ */
+static NTSTATUS
+CsrpInitWin32Csr (ULONG argc, PWSTR* argv)
 {
   NTSTATUS Status;
   UNICODE_STRING DllName;
@@ -163,6 +205,8 @@ InitWin32Csr()
   PCSRSS_OBJECT_DEFINITION ObjectDefinitions;
   CSRPLUGIN_INIT_COMPLETE_PROC InitCompleteProc;
 
+  DPRINT("CSR: %s called\n", __FUNCTION__);
+
   RtlInitUnicodeString(&DllName, L"win32csr.dll");
   Status = LdrLoadDll(NULL, 0, &DllName, (PVOID *) &hInst);
   if (! NT_SUCCESS(Status))
@@ -196,7 +240,7 @@ InitWin32Csr()
     }
   if (NULL != InitCompleteProc)
     {
-      Status = AddInitCompleteProc(InitCompleteProc);
+      Status = CsrpAddInitCompleteProc(InitCompleteProc);
     }
 
   return Status;
@@ -219,157 +263,293 @@ CSRSS_API_DEFINITION NativeDefinitions[] =
     { 0, 0, 0, NULL }
   };
 
+static NTSTATUS STDCALL
+CsrpCreateListenPort (IN     LPWSTR  Name,
+                     IN OUT PHANDLE Port,
+                     IN     PTHREAD_START_ROUTINE ListenThread)
+{
+       NTSTATUS           Status = STATUS_SUCCESS;
+       OBJECT_ATTRIBUTES  PortAttributes;
+       UNICODE_STRING     PortName;
+
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       RtlInitUnicodeString (& PortName, Name);
+       InitializeObjectAttributes (& PortAttributes,
+                                   & PortName,
+                                   0,
+                                   NULL,
+                                   NULL);
+       Status = NtCreatePort ( Port,
+                               & PortAttributes,
+                               260, /* TODO: make caller set it*/
+                               328, /* TODO: make caller set it*/
+                               0); /* TODO: make caller set it*/
+       if(!NT_SUCCESS(Status))
+       {
+               DPRINT1("CSR: %s: NtCreatePort failed (Status=%08lx)\n",
+                       __FUNCTION__, Status);
+               return Status;
+       }
+       Status = RtlCreateUserThread(NtCurrentProcess(),
+                               NULL,
+                               FALSE,
+                               0,
+                               NULL,
+                               NULL,
+                               (PTHREAD_START_ROUTINE) ListenThread,
+                               Port,
+                               NULL,
+                               NULL);
+       return Status;
+}
+
+/* === INIT ROUTINES === */
+
 /**********************************************************************
- * NAME
- *     CsrpRegisterSubsystem/0
- *
- * DESCRIPTION
- *     Register CSRSS in the SM to manage IMAGE_SUBSYSTEM_WINDOWS_CUI 
- *     processes (environment subsystem server).
- *
- * RETURN VALUE
- *     STATUS_SUCCESS on success.
+ * CsrpCreateCallbackPort/0
  */
-static NTSTATUS FASTCALL
-CsrpRegisterSubsystem(PHANDLE hSmApiPort)
+static NTSTATUS
+CsrpCreateHeap (ULONG argc, PWSTR* argv)
 {
-       NTSTATUS Status = STATUS_SUCCESS;
-       UNICODE_STRING SbApiPortName;
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
+                                      NULL,
+                                      65536,
+                                      65536,
+                                      NULL,
+                                      NULL);
+       if (CsrssApiHeap == NULL)
+       {
+               return STATUS_UNSUCCESSFUL;
+       }
+       return STATUS_SUCCESS;
+}
 
-       RtlInitUnicodeString (& SbApiPortName, L"\\Windows\\SbApiPort");
-       Status = SmConnectApiPort (& SbApiPortName,
-                                  (HANDLE)-1, //unused
+/**********************************************************************
+ * CsrpCreateCallbackPort/0
+ */
+static NTSTATUS
+CsrpCreateCallbackPort (ULONG argc, PWSTR* argv)
+{
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       return CsrpCreateListenPort (L"\\Windows\\SbApiPort",
+                                    & hSbApiPort,
+                                    ServerSbApiPortThread);
+}
+
+/**********************************************************************
+ * CsrpRegisterSubsystem/2
+ */
+static NTSTATUS
+CsrpRegisterSubsystem (ULONG argc, PWSTR* argv)
+{
+       NTSTATUS           Status = STATUS_SUCCESS;
+       OBJECT_ATTRIBUTES  BootstrapOkAttributes;
+       UNICODE_STRING     Name;
+
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       /*
+        * Create the event object the callback port
+        * thread will signal *if* the SM will
+        * authorize us to bootstrap.
+        */
+       RtlInitUnicodeString (& Name, L"\\CsrssBooting");
+       InitializeObjectAttributes(& BootstrapOkAttributes,
+                                  & Name,
+                                  0, NULL, NULL);
+       Status = NtCreateEvent (& hBootstrapOk,
+                               EVENT_ALL_ACCESS,
+                               & BootstrapOkAttributes,
+                               SynchronizationEvent,
+                               FALSE);
+       if(!NT_SUCCESS(Status))
+       {
+               DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
+                       __FUNCTION__, Status);
+               return Status;
+       }
+       /*
+        * Let's tell the SM a new environment
+        * subsystem server is in the system.
+        */
+       RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
+       DPRINT("CSR: %s: registering with SM for\n  IMAGE_SUBSYSTEM_WINDOWS_CUI == 3\n", __FUNCTION__);
+       Status = SmConnectApiPort (& Name,
+                                  hSbApiPort,
                                   IMAGE_SUBSYSTEM_WINDOWS_CUI,
-                                  hSmApiPort);
+                                  hSmApiPort);
        if(!NT_SUCCESS(Status))
        {
-               DPRINT("CSR: unable to connect to the SM (Status=0x%lx)\n", Status);
+               DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
+                       __FUNCTION__, Status);
+               NtClose (hBootstrapOk);
                return Status;
        }
-       DisplayString(L"CSR: registered with SM\n");
+       /*
+        *  Wait for SM to reply OK... If the SM
+        *  won't answer, we hang here forever!
+        */
+       DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__);
+       Status = NtWaitForSingleObject (hBootstrapOk,
+                                       FALSE,
+                                       NULL);
+       NtClose (hBootstrapOk);
        return Status;  
 }
 
+/**********************************************************************
+ * CsrpCreateApiPort/0
+ */
+static NTSTATUS
+CsrpCreateApiPort (ULONG argc, PWSTR* argv)
+{
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       return CsrpCreateListenPort (L"\\Windows\\ApiPort",
+                                    & hApiPort,
+                                    ServerApiPortThread);
+}
+
+/**********************************************************************
+ * CsrpApiRegisterDef/0
+ */
+static NTSTATUS
+CsrpApiRegisterDef (ULONG argc, PWSTR* argv)
+{
+       return CsrApiRegisterDefinitions(NativeDefinitions);
+}
+
+/**********************************************************************
+ * CsrpCCTS/2
+ */
+static NTSTATUS
+CsrpCCTS (ULONG argc, PWSTR* argv)
+{
+       return CsrClientConnectToServer();
+}
+
+/**********************************************************************
+ * CsrpRunWinlogon/0
+ *
+ * Start the logon process (winlogon.exe).
+ *
+ * TODO: this should be moved in CsrpCreateSession/x (one per session)
+ * TODO: in its own desktop (one logon desktop per winstation).
+ */
+static NTSTATUS
+CsrpRunWinlogon (ULONG argc, PWSTR* argv)
+{
+       NTSTATUS                      Status = STATUS_SUCCESS;
+       UNICODE_STRING                ImagePath;
+       UNICODE_STRING                CommandLine;
+       PRTL_USER_PROCESS_PARAMETERS  ProcessParameters = NULL;
+       RTL_PROCESS_INFO              ProcessInfo;
+
+
+       DPRINT("CSR: %s called\n", __FUNCTION__);
+
+       /* initialize the process parameters */
+       RtlInitUnicodeString (& ImagePath, L"\\SystemRoot\\system32\\winlogon.exe");
+       RtlInitUnicodeString (& CommandLine, L"");
+       RtlCreateProcessParameters(& ProcessParameters,
+                                  & ImagePath,
+                                  NULL,
+                                  NULL,
+                                  & CommandLine,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL);
+       /* Create the winlogon process */
+       Status = RtlCreateUserProcess (& ImagePath,
+                                      OBJ_CASE_INSENSITIVE,
+                                      ProcessParameters,
+                                      NULL,
+                                      NULL,
+                                      NULL,
+                                      FALSE,
+                                      NULL,
+                                      NULL,
+                                      & ProcessInfo);
+       /* Cleanup */
+       RtlDestroyProcessParameters (ProcessParameters);
+       if (!NT_SUCCESS(Status))
+       {
+               DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
+                               __FUNCTION__, Status);
+       }
+   ZwResumeThread(ProcessInfo.ThreadHandle, NULL);
+       return Status;
+}
+
+
+
+typedef NTSTATUS (* CSR_INIT_ROUTINE)(ULONG, PWSTR*);
+
+struct {
+       BOOL Required;
+       CSR_INIT_ROUTINE EntryPoint;
+       PCHAR ErrorMessage;
+} InitRoutine [] = {
+       {TRUE, CsrpCreateCallbackPort, "create the callback port \\Windows\\SbApiPort"},
+       {TRUE, CsrpRegisterSubsystem,  "register with SM"},
+       {TRUE, CsrpCreateHeap,         "create the CSR heap"},
+       {TRUE, CsrpCreateApiPort,      "create the api port \\Windows\\ApiPort"},
+       {TRUE, CsrpParseCommandLine,   "parse the command line"},
+       {TRUE, CsrpInitVideo,          "initialize video"},
+       {TRUE, CsrpApiRegisterDef,     "initialize api definitions"},
+       {TRUE, CsrpCCTS,               "connect client to server"},
+       {TRUE, CsrpInitWin32Csr,       "load usermode dll"},
+       {TRUE, CsrpRunWinlogon,        "run WinLogon"},
+};
 
 /**********************************************************************
  * NAME
  *     CsrServerInitialization
  *
  * DESCRIPTION
- *     Create a directory object (\windows) and a named LPC port
- *     (\windows\ApiPort)
+ *     Initialize the Win32 environment subsystem server.
  *
  * RETURN VALUE
  *     TRUE: Initialization OK; otherwise FALSE.
  */
-BOOL
-STDCALL
+BOOL STDCALL
 CsrServerInitialization (
        ULONG ArgumentCount,
        PWSTR *ArgumentArray
        )
 {
-  NTSTATUS Status;
-  HANDLE hSmApiPort = (HANDLE) 0;
-  OBJECT_ATTRIBUTES ObAttributes;
-  UNICODE_STRING PortName;
-  HANDLE ApiPortHandle;
-//  HANDLE hSbApiPort = (HANDLE) 0;
-
-DisplayString(L"CSR: CsrServerInitialization\n");
-
-  Status = CsrpRegisterSubsystem(& hSmApiPort);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to register subsystem (Status: %x)\n", Status);
-      return FALSE;
-    }
-
-  Status = CsrParseCommandLine (ArgumentCount, ArgumentArray);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to parse the command line (Status: %x)\n", Status);
-      return FALSE;
-    }
+       INT       i = 0;
+       NTSTATUS  Status = STATUS_SUCCESS;
 
-  CsrInitVideo();
+       DPRINT("CSR: %s called\n", __FUNCTION__);
 
-  CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
-                               NULL,
-                               65536,
-                               65536,
-                               NULL,
-                               NULL);
-  if (CsrssApiHeap == NULL)
-    {
-      DPRINT1("CSR: Failed to create private heap, aborting\n");
-      return FALSE;
-    }
-
-  Status = CsrApiRegisterDefinitions(NativeDefinitions);
-  if (! NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-
-  /* NEW NAMED PORT: \Windows\ApiPort */
-  RtlRosInitUnicodeStringFromLiteral(&PortName, L"\\Windows\\ApiPort");
-  InitializeObjectAttributes(&ObAttributes,
-                             &PortName,
-                             0,
-                             NULL,
-                             NULL);
-  Status = NtCreatePort(&ApiPortHandle,
-                        &ObAttributes,
-                        260,
-                        328,
-                        0);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to create \\Windows\\ApiPort (Status %x)\n", Status);
-      return FALSE;
-    }
-  Status = RtlCreateUserThread(NtCurrentProcess(),
-                               NULL,
-                               FALSE,
-                               0,
-                               NULL,
-                               NULL,
-                               (PTHREAD_START_ROUTINE)ServerApiPortThread,
-                               ApiPortHandle,
-                               NULL,
-                               NULL);
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to create server thread\n");
-      NtClose(ApiPortHandle);
-      return FALSE;
-    }
-
-  /* TODO: create \Windows\SbApiPort */
-  
-  Status = CsrClientConnectToServer();
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("CsrClientConnectToServer() failed (Status %x)\n", Status);
-      return FALSE;
-    }
-  Status = InitWin32Csr();
-  if (! NT_SUCCESS(Status))
-    {
-      DPRINT1("CSR: Unable to load usermode dll (Status %x)\n", Status);
-      return FALSE;
-    }
-
-  if (CallInitComplete())
-  {
-#if 0
-         Status = SmCompleteSession (hSmApiPort,hSbApiPort,ApiPortHandle);
-#endif
-         NtClose (hSmApiPort);
-         return TRUE;
-  }
-  return FALSE;
+       for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
+       {
+               Status = InitRoutine[i].EntryPoint(ArgumentCount,ArgumentArray);
+               if(!NT_SUCCESS(Status))
+               {
+                       DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n", 
+                               __FUNCTION__,
+                               InitRoutine[i].ErrorMessage,
+                               Status);
+                       if (InitRoutine[i].Required)
+                       {
+                               return FALSE;
+                       }
+               }
+       }
+       if (CallInitComplete())
+       {
+               Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort);
+               return TRUE;
+       }
+       return FALSE;
 }
 
 /* EOF */
index 4c82d87..da5c7a3 100644 (file)
@@ -74,48 +74,22 @@ ConioConsoleFromProcessData(PCSRSS_PROCESS_DATA ProcessData, PCSRSS_CONSOLE *Con
 VOID FASTCALL
 ConioConsoleCtrlEvent(DWORD Event, PCSRSS_PROCESS_DATA ProcessData)
 {
-  HANDLE Process, Thread;
+  HANDLE Thread;
        
   DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n",      ProcessData->ProcessId);
 
   if (ProcessData->CtrlDispatcher)
     {
-      OBJECT_ATTRIBUTES ObjectAttributes;
-      CLIENT_ID ClientId;
-      NTSTATUS Status;
-      
-      ClientId.UniqueThread = NULL;
-      ClientId.UniqueProcess = ProcessData->ProcessId;
-      InitializeObjectAttributes(&ObjectAttributes,
-                                 NULL,
-                                 0,
-                                 NULL,
-                                 NULL);
-
-      /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
-      Status = NtOpenProcess(&Process,
-                             PROCESS_DUP_HANDLE,
-                             &ObjectAttributes,
-                             &ClientId);
-      if (!NT_SUCCESS(Status))
-        {
-          DPRINT1("Failed for handle duplication, Status: 0x%x\n", Status);
-          return;
-        }
 
-      DPRINT("ConioConsoleCtrlEvent Process Handle = %x\n", Process);
-
-      Thread = CreateRemoteThread(Process, NULL, 0,
+      Thread = CreateRemoteThread(ProcessData->Process, NULL, 0,
                                   (LPTHREAD_START_ROUTINE) ProcessData->CtrlDispatcher,
                                   (PVOID) Event, 0, NULL);
       if (NULL == Thread)
         {
-          DPRINT1("Failed thread creation\n");
-          CloseHandle(Process);
+          DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
           return;
         }
       CloseHandle(Thread);
-      CloseHandle(Process);
     }
 }
 
@@ -264,9 +238,6 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
 CSR_API(CsrAllocConsole)
 {
   PCSRSS_CONSOLE Console;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  CLIENT_ID ClientId;
-  HANDLE Process;
   NTSTATUS Status;
 
   DPRINT("CsrAllocConsole\n");
@@ -319,35 +290,10 @@ CSR_API(CsrAllocConsole)
       return Reply->Status = Status;
     }
 
-  ClientId.UniqueThread = NULL;
-  ClientId.UniqueProcess = ProcessData->ProcessId;
-  InitializeObjectAttributes(&ObjectAttributes,
-                             NULL,
-                             0,
-                             NULL,
-                             NULL);
-
-  /* using OpenProcess is not optimal due to HANDLE vs. DWORD PIDs... */
-  Status = NtOpenProcess(&Process,
-                         PROCESS_DUP_HANDLE,
-                         &ObjectAttributes,
-                         &ClientId);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT1("NtOpenProcess() failed for handle duplication, Status: 0x%x\n", Status);
-      Console->Header.ReferenceCount--;
-      ProcessData->Console = 0;
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
-      Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
-      Reply->Status = Status;
-      return Status;
-    }
-
   if (! DuplicateHandle(GetCurrentProcess(), ProcessData->Console->ActiveEvent,
-                        Process, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, FALSE, 0))
+                        ProcessData->Process, &ProcessData->ConsoleEvent, EVENT_ALL_ACCESS, FALSE, 0))
     {
       DPRINT1("DuplicateHandle() failed: %d\n", GetLastError);
-      CloseHandle(Process);
       Console->Header.ReferenceCount--;
       Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.OutputHandle);
       Win32CsrReleaseObject(ProcessData, Reply->Data.AllocConsoleReply.InputHandle);
@@ -355,7 +301,6 @@ CSR_API(CsrAllocConsole)
       Reply->Status = Status;
       return Status;
     }
-  CloseHandle(Process);
   ProcessData->CtrlDispatcher = Request->Data.AllocConsoleRequest.CtrlDispatcher;
   DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);      
   InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ProcessEntry);
@@ -1381,8 +1326,8 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
     }
 }
 
-VOID
-Console_Api(DWORD RefreshEvent)
+DWORD STDCALL
+Console_Api (PVOID unused)
 {
   /* keep reading events from the keyboard and stuffing them into the current
      console's input queue */
@@ -1409,6 +1354,7 @@ Console_Api(DWORD RefreshEvent)
     }
 
   PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
+  return 0;
 }
 
 CSR_API(CsrGetScreenBufferInfo)
index 18f81fe..33dc6bf 100644 (file)
@@ -42,39 +42,6 @@ struct _SM_CLIENT_DIRECTORY
 \r
 } SmpClientDirectory;\r
 \r
-#if 0\r
-/**********************************************************************\r
- *     SmpRegisterSmss/0\r
- */\r
-static NTSTATUS\r
-SmpRegisterSmss(VOID)\r
-{\r
-       NTSTATUS Status = STATUS_SUCCESS;\r
-       UNICODE_STRING SbApiPortName = {0,0,NULL};\r
-       HANDLE hSmApiPort = (HANDLE) 0;\r
-\r
-       DPRINT("SM: %s called\n",__FUNCTION__);\r
-       \r
-       Status = SmConnectApiPort(& SbApiPortName,\r
-                                 (HANDLE) -1,\r
-                                 IMAGE_SUBSYSTEM_NATIVE,\r
-                                 & hSmApiPort);\r
-       if(!NT_SUCCESS(Status))\r
-       {\r
-               DPRINT("SM: %s: SMDLL!SmConnectApiPort failed (Status=0x%08lx)\n",__FUNCTION__,Status);\r
-               return Status;\r
-       }\r
-       Status = SmCompleteSession (hSmApiPort, (HANDLE)0, hSmApiPort);\r
-       if(!NT_SUCCESS(Status))\r
-       {\r
-               DPRINT("SM: %s: SMDLL!SmCompleteSession failed (Status=0x%08lx)\n",__FUNCTION__,Status);\r
-               return Status;\r
-       }\r
-       NtClose(hSmApiPort);\r
-       return Status;\r
-}\r
-#endif\r
-\r
 /**********************************************************************\r
  *     SmInitializeClientManagement/0\r
  */\r
@@ -85,16 +52,46 @@ SmInitializeClientManagement (VOID)
        RtlInitializeCriticalSection(& SmpClientDirectory.Lock);\r
        SmpClientDirectory.Count = 0;\r
        SmpClientDirectory.Client = NULL;\r
-#if 0\r
-       /* Register IMAGE_SUBSYSTE_NATIVE to be managed by SM */\r
-       return SmpRegisterSmss();\r
-#endif\r
        return STATUS_SUCCESS;\r
 \r
 }\r
 \r
 /**********************************************************************\r
- *     SmpLookupClient/1\r
+ *     SmCompleteClientInitialization/1\r
+ *\r
+ * DESCRIPTION\r
+ *     Lookup the subsystem server descriptor given the process handle\r
+ *     of the subsystem server process.\r
+ */\r
+NTSTATUS STDCALL\r
+SmCompleteClientInitialization (HANDLE hProcess)\r
+{\r
+       NTSTATUS        Status = STATUS_SUCCESS;\r
+       PSM_CLIENT_DATA Client = NULL;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       if (SmpClientDirectory.Count > 0)\r
+       {\r
+               Client = SmpClientDirectory.Client;\r
+               while (NULL != Client)\r
+               {\r
+                       if (hProcess == Client->ServerProcess)\r
+                       {\r
+                               Client->Initialized = TRUE;\r
+                               break;\r
+                       }\r
+                       Client = Client->Next;\r
+               }\r
+               Status = STATUS_NOT_FOUND;\r
+       }\r
+       RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
+       return Status;\r
+}\r
+\r
+/**********************************************************************\r
+ *     SmpLookupClient/1                                       PRIVATE\r
  *\r
  * DESCRIPTION\r
  *     Lookup the subsystem server descriptor given its image ID.\r
@@ -102,14 +99,18 @@ SmInitializeClientManagement (VOID)
  * SIDE EFFECTS\r
  *     SmpClientDirectory.Lock is released only on success.\r
  */\r
-static PSM_CLIENT_DATA STDCALL\r
-SmpLookupClient (USHORT SubsystemId)\r
+static PSM_CLIENT_DATA FASTCALL\r
+SmpLookupClientUnsafe (USHORT           SubsystemId,\r
+                      PSM_CLIENT_DATA  * Parent)\r
 {\r
        PSM_CLIENT_DATA Client = NULL;\r
 \r
-       DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
-       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);\r
+       \r
+       if(NULL != Parent)\r
+       {\r
+               *Parent = NULL;\r
+       }\r
        if (SmpClientDirectory.Count > 0)\r
        {\r
                Client = SmpClientDirectory.Client;\r
@@ -117,12 +118,31 @@ SmpLookupClient (USHORT SubsystemId)
                {\r
                        if (SubsystemId == Client->SubsystemId)\r
                        {\r
-                               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-                               return Client;\r
+                               break;\r
+                       }\r
+                       if(NULL != Parent)\r
+                       {\r
+                               *Parent = Client;\r
                        }\r
                        Client = Client->Next;\r
                }\r
        }\r
+       return Client;\r
+}\r
+\r
+static PSM_CLIENT_DATA STDCALL\r
+SmpLookupClient (USHORT SubsystemId)\r
+{\r
+       PSM_CLIENT_DATA Client = NULL;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       Client = SmpLookupClientUnsafe (SubsystemId, NULL);\r
+       if(NULL != Client)\r
+       {\r
+               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
+       }\r
        /*\r
         * Note that we do *not* release SmpClientDirectory.Lock here\r
         * because SmpLookupClient is called to FAIL when SubsystemId\r
@@ -138,7 +158,7 @@ NTSTATUS STDCALL
 SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)\r
 {\r
        PSM_CLIENT_DATA pClient = NULL;\r
-       PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);\r
+       PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);\r
        ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);\r
 \r
        DPRINT("SM: %s called\n", __FUNCTION__);\r
@@ -148,7 +168,7 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
         */\r
        if (SmpLookupClient(ConnectData->Subsystem))\r
        {\r
-               DPRINT("SMSS: %s: attempt to register again subsystem %d.\n",\r
+               DPRINT("SM: %s: attempt to register again subsystem %d.\n",\r
                        __FUNCTION__,\r
                        ConnectData->Subsystem);\r
                return STATUS_UNSUCCESSFUL;\r
@@ -209,16 +229,51 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
 \r
 /**********************************************************************\r
  *     SmpDestroyClient/1\r
+ *\r
+ *     1. close any handle\r
+ *     2. kill client process\r
+ *     3. release resources\r
  */\r
 NTSTATUS STDCALL\r
 SmDestroyClient (ULONG SubsystemId)\r
 {\r
+       NTSTATUS         Status = STATUS_SUCCESS;\r
+       PSM_CLIENT_DATA  Parent = NULL;\r
+       PSM_CLIENT_DATA  Client = NULL;\r
+\r
        DPRINT("SM: %s called\n", __FUNCTION__);\r
 \r
        RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
-       /* TODO */\r
+       Client = SmpLookupClientUnsafe (SubsystemId, & Parent);\r
+       if(NULL == Client)\r
+       {\r
+               DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n",\r
+                       __FUNCTION__, SubsystemId);\r
+               Status = STATUS_NOT_FOUND;\r
+       }\r
+       else\r
+       {\r
+               /* 1st in the list? */\r
+               if(NULL == Parent)\r
+               {\r
+                       SmpClientDirectory.Client = Client->Next;\r
+               }\r
+               else\r
+               {\r
+                       if(NULL != Parent)\r
+                       {\r
+                               Parent->Next = Client->Next;\r
+                       } else {\r
+                               DPRINT1("SM: %s: n-th has no parent!\n", __FUNCTION__);\r
+                               Status = STATUS_UNSUCCESSFUL; /* FIXME */\r
+                       }\r
+               }\r
+               /* TODO: send shutdown or kill */\r
+               RtlFreeHeap (SmpHeap, 0, Client);\r
+               -- SmpClientDirectory.Count;\r
+       }\r
        RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-       return STATUS_SUCCESS;\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r
index f3a1126..a8880e2 100644 (file)
@@ -39,7 +39,7 @@ SmpSignalInitEvent(VOID)
   NTSTATUS          Status = STATUS_SUCCESS;
   OBJECT_ATTRIBUTES ObjectAttributes = {0};
   UNICODE_STRING    EventName ={0};
-  HANDLE            ReactOSInitEvent = NULL;
+  HANDLE            ReactOSInitEvent = (HANDLE) 0;
 
   RtlInitUnicodeString (& EventName, L"\\ReactOSInitDone");
   InitializeObjectAttributes(&ObjectAttributes,
@@ -92,16 +92,13 @@ struct {
        {TRUE,  SmInitializeClientManagement, "initialize client management"},
        {TRUE,  SmLoadSubsystems,             "load subsystems"},
        {FALSE, SmpSignalInitEvent,           "open ReactOS init notification event"},
-       {TRUE,  SmRunCsrss,                   "run csrss"},
-       {TRUE,  SmRunWinlogon,                "run winlogon"},
-       {TRUE,  SmInitializeDbgSs,            "initialize DbgSs"}
 };
 
 NTSTATUS
 InitSessionManager(VOID)
 {
-  int i;
-  NTSTATUS Status;
+  INT i = 0;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
   {
@@ -118,8 +115,6 @@ InitSessionManager(VOID)
       }
     }
   }
-
-
   return(STATUS_SUCCESS);
 }
 
index e24035a..464cfe6 100644 (file)
 HANDLE hSmApiPort = (HANDLE) 0;\r
 \r
 \r
-/* TODO: this file should be totally rewritten\r
+/* TODO:\r
  *\r
  * a) look if a special option is set for smss.exe in\r
  *    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\r
+ */\r
+\r
+/**********************************************************************\r
+ *     SmpRegisterSmss/0\r
  *\r
- * b) make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
- *    (programmatically)\r
- *\r
- * d) make smss initialize Debug (DBGSS) and Windows (CSRSS) as described\r
- *    in the registry key Required="Debug Windows"\r
- *    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\r
- *\r
- * e) make optional subsystems loadable (again: they must be described in the registry\r
- *    key Optional="Posix Os2" to be allowed to run)\r
+ * DESCRIPTION\r
+ *     Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
+ *     (programmatically). This also opens hSmApiPort to be used\r
+ *     in loading required subsystems.\r
  */\r
 \r
+static NTSTATUS\r
+SmpRegisterSmss(VOID)\r
+{\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+       UNICODE_STRING SbApiPortName = {0,0,NULL};\r
+\r
+       \r
+       DPRINT("SM: %s called\n",__FUNCTION__);\r
+\r
+       RtlInitUnicodeString (& SbApiPortName, L"");    \r
+       Status = SmConnectApiPort(& SbApiPortName,\r
+                                 (HANDLE) -1, /* SM has no SB port */\r
+                                 IMAGE_SUBSYSTEM_NATIVE,\r
+                                 & hSmApiPort);\r
+       if(!NT_SUCCESS(Status))\r
+       {\r
+               DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",\r
+                       __FUNCTION__,Status);\r
+               return Status;\r
+       }\r
+       DPRINT("SM self registered\n");\r
+       /*\r
+        * Note that you don't need to call complete session\r
+        * because connection handling code autocompletes\r
+        * the client structure for IMAGE_SUBSYSTEM_NATIVE.\r
+        */\r
+       return Status;\r
+}\r
+\r
+\r
 /**********************************************************************\r
+ *     SmpLoadKernelModeSubsystem/0\r
  */\r
-NTSTATUS\r
-SmLoadSubsystems(VOID)\r
+static NTSTATUS\r
+SmpLoadKernelModeSubsystem (VOID)\r
 {\r
-       SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
-       NTSTATUS                   Status = STATUS_SUCCESS;\r
-       WCHAR                      Data [MAX_PATH + 1];\r
-       ULONG                      DataLength = sizeof Data;\r
-       ULONG                      DataType = 0;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
 \r
 \r
-       DPRINT("SM: loading subsystems\n");\r
\r
-       /* Load Kmode subsystem (aka win32k.sys) */\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
        Status = SmLookupSubsystem (L"Kmode",\r
                                    Data,\r
                                    & DataLength,\r
@@ -74,121 +102,101 @@ SmLoadSubsystems(VOID)
                                    TRUE);\r
        if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
        {\r
-               WCHAR ImagePath [MAX_PATH + 1] = {0};\r
+               WCHAR                      ImagePath [MAX_PATH + 1] = {0};\r
+               SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
 \r
                wcscpy (ImagePath, L"\\??\\");\r
                wcscat (ImagePath, Data);\r
                RtlZeroMemory (& ImageInfo, sizeof ImageInfo);\r
                RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);\r
                Status = NtSetSystemInformation(SystemLoadAndCallImage,\r
-                                         & ImageInfo,\r
-                                         sizeof ImageInfo);\r
+                                               & ImageInfo,\r
+                                               sizeof ImageInfo);\r
                if(!NT_SUCCESS(Status))\r
                {\r
-                       DPRINT("SM: loading Kmode failed (Status=0x%08lx)\n",\r
-                               Status);\r
-                       return Status;\r
+                       DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",\r
+                               __FUNCTION__, Status);\r
                }\r
        }\r
-       /* TODO: load Required subsystems (Debug Windows) */\r
        return Status;\r
 }\r
 \r
-NTSTATUS\r
-SmRunCsrss(VOID)\r
+/**********************************************************************\r
+ *     SmpLoadRequiredSubsystems/0\r
+ */\r
+static NTSTATUS\r
+SmpLoadRequiredSubsystems (VOID)\r
 {\r
-  NTSTATUS Status;\r
-  UNICODE_STRING UnicodeString;\r
-  OBJECT_ATTRIBUTES ObjectAttributes;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  HANDLE CsrssInitEvent;\r
-  WCHAR ImagePath [MAX_PATH];\r
-\r
-  DPRINT("SM: initializing csrss\n");\r
-\r
-  /* Run csrss.exe */\r
-  RtlRosInitUnicodeStringFromLiteral(&UnicodeString,\r
-                                 L"\\CsrssInitDone");\r
-  InitializeObjectAttributes(&ObjectAttributes,\r
-                            &UnicodeString,\r
-                            EVENT_ALL_ACCESS,\r
-                            0,\r
-                            NULL);\r
-  Status = NtCreateEvent(&CsrssInitEvent,\r
-                        EVENT_ALL_ACCESS,\r
-                        &ObjectAttributes,\r
-                        NotificationEvent,\r
-                        FALSE);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DbgPrint("Failed to create csrss notification event\n");\r
-    }\r
-\r
-  /*\r
-   * Start the Win32 subsystem (csrss.exe)\r
-   */\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\csrss.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  \r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading csrss.exe failed!\n", __FUNCTION__);\r
-      return(Status);\r
-    }\r
-\r
-  Status = NtWaitForSingleObject(CsrssInitEvent,\r
-                       FALSE,\r
-                       NULL);\r
-\r
-  Children[CHILD_CSRSS] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+       WCHAR     Data [MAX_PATH + 1];\r
+       ULONG     DataLength = sizeof Data;\r
+       ULONG     DataType = 0;\r
+\r
+       \r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlZeroMemory (Data, DataLength);\r
+       Status = SmLookupSubsystem (L"Required",\r
+                                   Data,\r
+                                   & DataLength,\r
+                                   & DataType,\r
+                                   FALSE);\r
+       if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
+       {\r
+               PWCHAR Name = NULL;\r
+               ULONG Offset = 0;\r
+               \r
+               for (Name = Data; (Offset < DataLength); )\r
+               {\r
+                       if(L'\0' != *Name)\r
+                       {\r
+                               UNICODE_STRING Program;\r
+\r
+                               /* Run the current program */\r
+                               RtlInitUnicodeString (& Program, Name);\r
+                               Status = SmExecuteProgram (hSmApiPort, & Program);\r
+                               if(!NT_SUCCESS(Status))\r
+                               {\r
+                                       DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",\r
+                                               __FUNCTION__, Name, Status);\r
+                               }\r
+                               /* Look for the next program */\r
+                               while ((L'\0' != *Name) && (Offset < DataLength))\r
+                               {\r
+                                       ++ Name;\r
+                                       ++ Offset;\r
+                               }\r
+                       }\r
+                       ++ Name;\r
+                       ++ Offset;\r
+               }\r
+       }\r
+\r
+       return Status;\r
 }\r
 \r
+/**********************************************************************\r
+ *     SmLoadSubsystems/0\r
+ */\r
 NTSTATUS\r
-SmRunWinlogon(VOID)\r
+SmLoadSubsystems(VOID)\r
 {\r
-  NTSTATUS         Status = STATUS_SUCCESS;\r
-  RTL_PROCESS_INFO ProcessInfo;\r
-  WCHAR            ImagePath [MAX_PATH];\r
-\r
-  /*\r
-   * Start the logon process (winlogon.exe)\r
-   */\r
-\r
-  DPRINT("SM: starting winlogon\n");\r
-\r
-  /* initialize executable path */\r
-  wcscpy(ImagePath, L"\\??\\");\r
-  wcscat(ImagePath, SharedUserData->NtSystemRoot);\r
-  wcscat(ImagePath, L"\\system32\\winlogon.exe");\r
-\r
-  Status = SmCreateUserProcess(ImagePath,\r
-                               L"",\r
-                               FALSE, /* wait */\r
-                               NULL,\r
-                               FALSE, /* terminate */\r
-                               & ProcessInfo);\r
-  if (!NT_SUCCESS(Status))\r
-    {\r
-      DPRINT("SM: %s: Loading winlogon.exe failed!\n", __FUNCTION__);\r
-      NtTerminateProcess(Children[CHILD_CSRSS], 0);\r
-      return(Status);\r
-    }\r
-\r
-  Children[CHILD_WINLOGON] = ProcessInfo.ProcessHandle;\r
-\r
-  return Status;\r
+       NTSTATUS  Status = STATUS_SUCCESS;\r
+\r
+       \r
+       DPRINT("SM: loading subsystems\n");\r
+\r
+       /* SM self registers */\r
+       Status = SmpRegisterSmss();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Kmode subsystem (aka win32k.sys) */\r
+       Status = SmpLoadKernelModeSubsystem();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* Load Required subsystems (Debug Windows) */\r
+       Status = SmpLoadRequiredSubsystems();\r
+       if(!NT_SUCCESS(Status)) return Status;\r
+       /* done */\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r
index e853d8b..df35724 100644 (file)
@@ -60,7 +60,7 @@ SmpKnownDllsQueryRoutine(PWSTR ValueName,
                             (HANDLE)Context,\r
                             NULL);\r
   Status = NtOpenFile(&FileHandle,\r
-                     SYNCHRONIZE | FILE_EXECUTE,\r
+                     SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,\r
                      &ObjectAttributes,\r
                      &IoStatusBlock,\r
                      FILE_SHARE_READ,\r
index 823310e..3845a34 100644 (file)
@@ -6,7 +6,7 @@ TARGET_TYPE = program
 
 TARGET_APPTYPE = native
 
-TARGET_SDKLIBS = ntdll.a smdll.a
+TARGET_SDKLIBS = smlib.a ntdll.a
 
 TARGET_NAME = smss
 
@@ -21,7 +21,7 @@ TARGET_OBJECTS = $(TARGET_NAME).o \
                 init.o initheap.o initenv.o initobdir.o initdosdev.o \
                 initrun.o initmv.o initwkdll.o initpage.o initss.o \
                 initreg.o \
-                smapi.o smapicomp.o smapiexec.o \
+                smapi.o smapicomp.o smapiexec.o smapiquery.o \
                 client.o debug.o print.o
 
 include $(PATH_TO_TOP)/rules.mak
index 78cac41..a157850 100644 (file)
@@ -34,14 +34,63 @@ SM_PORT_API SmApi [] =
        SmCompSes,      /* smapicomp.c */
        SmInvalid,      /* obsolete */
        SmInvalid,      /* unknown */
-       SmExecPgm       /* smapiexec.c */
+       SmExecPgm,      /* smapiexec.c */
+       SmQryInfo       /* smapyqry.c */
 };
 
+/* TODO: optimize this address computation (it should be done 
+ * with a macro) */
+PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE Request)
+{
+       PLPC_MAX_MESSAGE LpcMaxMessage = (PLPC_MAX_MESSAGE) Request;
+       return (PSM_CONNECT_DATA) & LpcMaxMessage->Data[0];
+}
+
 #if !defined(__USE_NT_LPC__)
 NTSTATUS STDCALL
 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
 #endif
 
+/**********************************************************************
+ * SmpCallback/2
+ *
+ * The SM calls back a previously connected subsystem process to
+ * authorizes it to bootstrap (initialize). The SM connects to a
+ * named LPC port which name was sent in the connection data by the
+ * candidate subsystem server process.
+ */
+static NTSTATUS
+SmpCallbackServer (PSM_PORT_MESSAGE Request,
+                  PSM_CLIENT_DATA ClientData)
+{
+       NTSTATUS          Status = STATUS_SUCCESS;
+       PSM_CONNECT_DATA  ConnectData = SmpGetConnectData (Request);
+       UNICODE_STRING    CallbackPortName;
+       ULONG             CallbackPortNameLength = SM_SB_NAME_MAX_LENGTH; /* TODO: compute length */
+       
+       DPRINT("SM: %s called\n", __FUNCTION__);
+
+       if(IMAGE_SUBSYSTEM_NATIVE == ConnectData->Subsystem)
+       {
+               DPRINT("SM: %s: we do not need calling back SM!\n",
+                               __FUNCTION__);
+               return STATUS_SUCCESS;
+       }
+       RtlCopyMemory (ClientData->SbApiPortName,
+                      ConnectData->SbName,
+                      CallbackPortNameLength);
+       RtlInitUnicodeString (& CallbackPortName,
+                             ClientData->SbApiPortName);
+       Status = NtConnectPort (& ClientData->SbApiPort,
+                               & CallbackPortName,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+       return Status;
+}
 
 /**********************************************************************
  * NAME
@@ -51,20 +100,21 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
  *     Entry point for the listener thread of LPC port "\SmApiPort".
  */
 VOID STDCALL
-SmpApiConnectedThread(PVOID dummy)
+SmpApiConnectedThread(PVOID pConnectedPort)
 {
        NTSTATUS        Status = STATUS_SUCCESS;
        PVOID           Unknown = NULL;
        PLPC_MESSAGE    Reply = NULL;
        SM_PORT_MESSAGE Request = {{0}};
+       HANDLE          ConnectedPort = * (PHANDLE) pConnectedPort;
 
-       DPRINT("SM: %s running\n",__FUNCTION__);
+       DPRINT("SM: %s called\n", __FUNCTION__);
 
        while (TRUE)
        {
                DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
 
-               Status = NtReplyWaitReceivePort(SmApiPort,
+               Status = NtReplyWaitReceivePort(ConnectedPort,
                                                (PULONG) & Unknown,
                                                Reply,
                                                (PLPC_MESSAGE) & Request);
@@ -98,8 +148,13 @@ SmpApiConnectedThread(PVOID dummy)
                                        Reply = (PLPC_MESSAGE) & Request;
                                }
                        }
+               } else {
+                       /* LPC failed */
+                       break;
                }
        }
+       NtClose (ConnectedPort);
+       NtTerminateThread (NtCurrentThread(), Status);
 }
 
 /**********************************************************************
@@ -115,75 +170,112 @@ SmpApiConnectedThread(PVOID dummy)
 NTSTATUS STDCALL
 SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
 {
-#if defined(__USE_NT_LPC__)
+       PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
        NTSTATUS         Status = STATUS_SUCCESS;
+       BOOL             Accept = FALSE;
        PSM_CLIENT_DATA  ClientData = NULL;
+       HANDLE           hClientDataApiPort = (HANDLE) 0;
+       PHANDLE          ClientDataApiPort = & hClientDataApiPort;
+       HANDLE           hClientDataApiPortThread = (HANDLE) 0;
+       PHANDLE          ClientDataApiPortThread = & hClientDataApiPortThread;
        PVOID            Context = NULL;
        
-       DPRINT("SM: %s called\n",__FUNCTION__);
+       DPRINT("SM: %s called:\n  SubSystemID=%d\n  SbName=\"%S\"\n",
+                       __FUNCTION__, ConnectData->Subsystem, ConnectData->SbName);
 
-       /*
-        * SmCreateClient/2 is called here explicitly to *fail*.
-        * If it succeeds, there is something wrong in the
-        * connection request. An environment subsystem *never*
-        * registers twice. (Security issue: maybe we will
-        * write this event into the security log).
-        */
-       Status = SmCreateClient (Request, & ClientData);
-       if(STATUS_SUCCESS == Status)
+       if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize)
        {
-               /* OK: the client is an environment subsystem
-                * willing to manage a free image type.
-                * Accept it.
-                */
-               Status = NtAcceptConnectPort (& ClientData->ApiPort,
-                                             Context,
-                                             (PLPC_MESSAGE) Request,
-                                             TRUE, //accept
-                                             NULL,
-                                             NULL);
-               if(NT_SUCCESS(Status))
+               if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->Subsystem)
                {
-                       Status = NtCompleteConnectPort(ClientData->ApiPort);
+                       /*
+                        * This is not a call to register an image set,
+                        * but a simple connection request from a process
+                        * that will use the SM API.
+                        */
+                       DPRINT("SM: %s: simple request\n", __FUNCTION__);
+                       ClientDataApiPort = & hClientDataApiPort;
+                       ClientDataApiPortThread = & hClientDataApiPortThread;
+                       Accept = TRUE;
+               } else {
+                       DPRINT("SM: %s: request to register an image set\n", __FUNCTION__);
+                       /*
+                        *  Reject GUIs classes: only odd subsystem IDs are
+                        *  allowed to register here (tty mode images).
+                        */
+                       if(1 == (ConnectData->Subsystem % 2))
+                       {
+                               DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->Subsystem);
+                               /*
+                                * SmCreateClient/2 is called here explicitly to *fail*.
+                                * If it succeeds, there is something wrong in the
+                                * connection request. An environment subsystem *never*
+                                * registers twice. (security issue)
+                                */
+                               Status = SmCreateClient (Request, & ClientData);
+                               if(STATUS_SUCCESS == Status)
+                               {
+                                       DPRINT("SM: %s: ClientData = 0x%08lx\n",
+                                               __FUNCTION__, ClientData);
+                                       /*
+                                        * OK: the client is an environment subsystem
+                                        * willing to manage a free image type.
+                                        */
+                                       ClientDataApiPort = & ClientData->ApiPort;
+                                       ClientDataApiPortThread = & ClientData->ApiPortThread;
+                                       /*
+                                        * Call back the candidate environment subsystem
+                                        * server (use the port name sent in in the 
+                                        * connection request message).
+                                        */
+                                       Status = SmpCallbackServer (Request, ClientData);
+                                       if(NT_SUCCESS(Status))
+                                       {
+                                               DPRINT("SM: %s: SmpCallbackServer OK\n",
+                                                       __FUNCTION__);
+                                               Accept = TRUE;
+                                       } else {
+                                               DPRINT("SM: %s: SmpCallbackServer failed (Status=%08lx)\n",
+                                                       __FUNCTION__, Status);
+                                               Status = SmDestroyClient (ConnectData->Subsystem);
+                                       }
+                               }
+                       }
                }
-               return STATUS_SUCCESS;
-       } else {
-               /* Reject the subsystem */
-               Status = NtAcceptConnectPort (& ClientData->ApiPort,
-                                             Context,
-                                             (PLPC_MESSAGE) Request,
-                                             FALSE, //reject
-                                             NULL,
-                                             NULL);
        }
+       DPRINT("SM: %s: before NtAcceptConnectPort\n", __FUNCTION__);
+#if defined(__USE_NT_LPC__)
+       Status = NtAcceptConnectPort (ClientDataApiPort,
+                                     Context,
+                                     (PLPC_MESSAGE) Request,
+                                     Accept,
+                                     NULL,
+                                     NULL);
 #else /* ReactOS LPC */
-       NTSTATUS         Status = STATUS_SUCCESS;
-       PSM_CLIENT_DATA  ClientData = NULL;
-       
-       DPRINT("SM: %s called\n",__FUNCTION__);
-
-       Status = SmCreateClient (Request, & ClientData);
-       if(STATUS_SUCCESS == Status)
+       Status = NtAcceptConnectPort (ClientDataApiPort,
+                                     SmApiPort, // ROS LPC requires the listen port here
+                                     Context,
+                                     Accept,
+                                     NULL,
+                                     NULL);
+#endif
+       if(Accept)
        {
-               Status = NtAcceptConnectPort (& ClientData->ApiPort,
-                                             SmApiPort,
-                                             NULL,
-                                             TRUE, //accept
-                                             NULL,
-                                             NULL);
-               if (!NT_SUCCESS(Status))
+               if(!NT_SUCCESS(Status))
                {
                        DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
-                                       __FUNCTION__, Status);
+                               __FUNCTION__, Status);
                        return Status;
                } else {
-                       Status = NtCompleteConnectPort(ClientData->ApiPort);
+                       DPRINT("SM: %s: completing conn req\n", __FUNCTION__);
+                       Status = NtCompleteConnectPort (*ClientDataApiPort);
                        if (!NT_SUCCESS(Status))
                        {
                                DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
                                        __FUNCTION__, Status);
                                return Status;
                        }
+#if !defined(__USE_NT_LPC__) /* ReactOS LPC */
+                       DPRINT("SM: %s: server side comm port thread (ROS LPC)\n", __FUNCTION__);
                        Status = RtlCreateUserThread(NtCurrentProcess(),
                                             NULL,
                                             FALSE,
@@ -191,8 +283,8 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
                                             NULL,
                                             NULL,
                                             (PTHREAD_START_ROUTINE) SmpApiConnectedThread,
-                                            ClientData->ApiPort,
-                                            & ClientData->ApiPortThread,
+                                            ClientDataApiPort,
+                                            ClientDataApiPortThread,
                                             NULL);
                        if (!NT_SUCCESS(Status))
                        {
@@ -200,18 +292,11 @@ SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
                                        __FUNCTION__, Status);
                                return Status;
                        }
+#endif
                }
-               return STATUS_SUCCESS;
-       } else {
-               /* Reject the subsystem */
-               Status = NtAcceptConnectPort (& ClientData->ApiPort,
-                                             SmApiPort,
-                                             NULL,
-                                             FALSE, //reject
-                                             NULL,
-                                             NULL);
+               Status = STATUS_SUCCESS;
        }
-#endif /* defined __USE_NT_LPC__ */
+       DPRINT("SM: %s done\n", __FUNCTION__);
        return Status;
 }
 
@@ -231,6 +316,8 @@ SmpApiThread (HANDLE ListeningPort)
 {
        NTSTATUS        Status = STATUS_SUCCESS;
        LPC_MAX_MESSAGE Request = {{0}};
+
+       DPRINT("SM: %s called\n", __FUNCTION__);
     
        while (TRUE)
        {
index a655ef7..52ef961 100644 (file)
@@ -4,10 +4,26 @@
  *\r
  * Reactos Session Manager\r
  *\r
+ * --------------------------------------------------------------------\r
+ *\r
+ * This software is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version.\r
+ *\r
+ * This software is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this software; see the file COPYING.LIB. If not, write\r
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
+ * MA 02139, USA.  \r
+ *\r
+ * --------------------------------------------------------------------\r
  */\r
-\r
 #include "smss.h"\r
-#include <rosrtl/string.h>\r
 \r
 #define NDEBUG\r
 #include <debug.h>\r
  */\r
 SMAPI(SmCompSes)\r
 {\r
-       DPRINT("SM: %s called\n",__FUNCTION__);\r
-       Request->Status = STATUS_NOT_IMPLEMENTED;\r
-       return STATUS_SUCCESS;\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+       DPRINT("SM: %s called from [%lx|%lx]\n",\r
+               __FUNCTION__,\r
+               Request->ClientId.UniqueProcessId,\r
+               Request->ClientId.UniqueThreadId);\r
+       \r
+       Status = SmCompleteClientInitialization (Request->Header.ClientId.UniqueProcess);\r
+       if(!NT_SUCCESS(Status))\r
+       {\r
+               Request->Status = STATUS_UNSUCCESSFUL;\r
+       }\r
+       return Status;\r
 }\r
 \r
 \r
index 9d1f119..7efc800 100644 (file)
@@ -81,22 +81,18 @@ SmCreateUserProcess (LPWSTR ImagePath,
                                       NULL,\r
                                       NULL,\r
                                       pProcessInfo);\r
+                   \r
+   RtlDestroyProcessParameters (ProcessParameters);\r
+   \r
        if (!NT_SUCCESS(Status))\r
        {\r
-               CHAR AnsiBuffer [MAX_PATH];\r
-               INT i = 0;\r
-               for(i=0;ImagePathString.Buffer[i];i++)\r
-               {\r
-                       /* raw U -> A */\r
-                       AnsiBuffer [i] = (CHAR) (ImagePathString.Buffer[i] & 0xff);\r
-               }\r
-\r
-               DPRINT1("SM: %s: Running \"%s\" failed (Status=0x%08lx)\n",\r
-                       AnsiBuffer, __FUNCTION__, Status);\r
+               DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",\r
+                       __FUNCTION__, ImagePathString.Buffer, Status);\r
                return Status;\r
        }\r
 \r
-       RtlDestroyProcessParameters (ProcessParameters);\r
+   ZwResumeThread(pProcessInfo->ThreadHandle, NULL);\r
+\r
 \r
        /* Wait for process termination */\r
        if(WaitForIt)\r
@@ -145,7 +141,7 @@ SmLookupSubsystem (IN     PWSTR   Name,
        OBJECT_ATTRIBUTES  Oa = {0};\r
        HANDLE             hKey = (HANDLE) 0;\r
 \r
-       DPRINT("SM: %s called\n", __FUNCTION__);\r
+       DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);\r
        /*\r
         * Prepare the key name to scan and\r
         * related object attributes.\r
@@ -268,7 +264,7 @@ SMAPI(SmExecPgm)
                RtlCopyMemory (Name,\r
                               ExecPgm->Name,\r
                               (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));\r
-               DPRINT("SM: %s: Name=[%wZ]\n", __FUNCTION__, Name);\r
+               DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name);\r
                /*\r
                 * Check if program name is internal\r
                 * (Is this correct? Debug is in the registry too)\r
@@ -285,18 +281,23 @@ SMAPI(SmExecPgm)
                }\r
                else\r
                {\r
-                       WCHAR ImagePath [1024] = {0};\r
-                       ULONG ImagePathLength = sizeof ImagePath;\r
-                       ULONG ImagePathType = REG_EXPAND_SZ;\r
+                       WCHAR Data [MAX_PATH + 1] = {0};\r
+                       ULONG DataLength = sizeof Data;\r
+                       ULONG DataType = REG_EXPAND_SZ;\r
 \r
                        /* Lookup Name in the registry */\r
                        Status = SmLookupSubsystem (Name,\r
-                                                   ImagePath,\r
-                                                   & ImagePathLength,\r
-                                                   & ImagePathType,\r
+                                                   Data,\r
+                                                   & DataLength,\r
+                                                   & DataType,\r
                                                    TRUE); /* expand */\r
                        if(NT_SUCCESS(Status))\r
                        {\r
+                               WCHAR ImagePath [MAX_PATH + 1] = {0};\r
+\r
+                               wcscpy (ImagePath, L"\\??\\");\r
+                               wcscat (ImagePath, Data);\r
+                       \r
                                /* Create native process */\r
                                Request->Status = SmCreateUserProcess(ImagePath,\r
                                                                      L"", /* FIXME */\r
diff --git a/reactos/subsys/smss/smapiquery.c b/reactos/subsys/smss/smapiquery.c
new file mode 100644 (file)
index 0000000..e93e593
--- /dev/null
@@ -0,0 +1,46 @@
+/* $Id: $\r
+ *\r
+ * smapiquery.c - SM_API_QUERY_INFORMATION\r
+ *\r
+ * Reactos Session Manager\r
+ *\r
+ * --------------------------------------------------------------------\r
+ *\r
+ * This software is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version.\r
+ *\r
+ * This software is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this software; see the file COPYING.LIB. If not, write\r
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
+ * MA 02139, USA.  \r
+ *\r
+ * --------------------------------------------------------------------\r
+ */\r
+#include "smss.h"\r
+\r
+#define NDEBUG\r
+#include <debug.h>\r
+\r
+\r
+/**********************************************************************\r
+ * SmQryInfo/1                                                 API\r
+ */\r
+SMAPI(SmQryInfo)\r
+{\r
+       NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+       \r
+       Request->Status = STATUS_NOT_IMPLEMENTED;\r
+       return Status;\r
+}\r
+\r
+\r
+/* EOF */\r
index d95e54a..b03197c 100644 (file)
@@ -40,7 +40,6 @@ NtProcessStartup(PPEB Peb)
   NTSTATUS Status;
   PROCESS_BASIC_INFORMATION PBI = {0};
   
-  DisplayString(L"SMSS\n");
   PrintString("ReactOS Session Manager %s (Build %s)\n",
             KERNEL_RELEASE_STR,
             KERNEL_VERSION_BUILD_STR);
@@ -57,6 +56,7 @@ NtProcessStartup(PPEB Peb)
   }
   /* Initialize the system */
   Status = InitSessionManager();
+#if 0
   if (!NT_SUCCESS(Status))
     {
       int i;
@@ -91,6 +91,8 @@ ByeBye:
                   0,0,0,0,0);
 
 //   NtTerminateProcess(NtCurrentProcess(), 0);
+#endif
+       NtTerminateThread(NtCurrentThread(), Status);
 }
 
 /* EOF */
index 2bd3480..eae6143 100644 (file)
@@ -49,12 +49,14 @@ NTSTATUS SmInitializeRegistry(VOID);
 
 /* initss.c */
 NTSTATUS SmLoadSubsystems(VOID);
-NTSTATUS SmRunCsrss(VOID);
-NTSTATUS SmRunWinlogon(VOID);
 
 /* smapi.c */
 #define SMAPI(n) \
 NTSTATUS FASTCALL n (PSM_PORT_MESSAGE Request)
+PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE);
+NTSTATUS SmCreateApiPort(VOID);
+VOID STDCALL SmpApiThread(PVOID);
+
 
 /* smapiexec.c */
 NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
@@ -74,8 +76,8 @@ NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
 /* smapicomp.c */
 NTSTATUS FASTCALL SmCompSes(PSM_PORT_MESSAGE);
 
-NTSTATUS SmCreateApiPort(VOID);
-VOID STDCALL SmpApiThread(PVOID);
+/* smapiquery.c */
+NTSTATUS FASTCALL SmQryInfo(PSM_PORT_MESSAGE);
 
 /* client.c */
 typedef struct _SM_CLIENT_DATA
@@ -91,9 +93,9 @@ typedef struct _SM_CLIENT_DATA
        
 } SM_CLIENT_DATA, *PSM_CLIENT_DATA;
 NTSTATUS SmInitializeClientManagement(VOID);
-NTSTATUS SmpRegisterSmss(VOID);
 NTSTATUS STDCALL SmCreateClient(PSM_PORT_MESSAGE,PSM_CLIENT_DATA*);
 NTSTATUS STDCALL SmDestroyClient(ULONG);
+NTSTATUS STDCALL SmCompleteClientInitialization (HANDLE hProcess);
 
 /* debug.c */
 extern HANDLE DbgSsApiPort;
index 6d6ba16..626b1c2 100644 (file)
@@ -21,6 +21,7 @@
        <file>smapi.c</file>\r
        <file>smapicomp.c</file>\r
        <file>smapiexec.c</file>\r
+       <file>smapiquery.c</file>\r
        <file>smss.c</file>\r
        <file>smss.rc</file>\r
 </module>\r
index aac23e3..2f0146d 100644 (file)
-/*\r
- * WineCalc (DE.rc)\r
- *\r
- * Copyright 2005 Rouven Wessling\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-#include "windows.h"\r
-#include "resource.h"\r
-#include "winecalc.h"\r
-\r
-LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT\r
-\r
-STRINGTABLE DISCARDABLE\r
-{\r
-   IDS_APPNAME,            "Rechner"\r
-\r
-   IDS_COPYRIGHT1,         "Calculator 5.0. Lizensiert unter der LGPL 2"\r
-   IDS_COPYRIGHT2          "Copyright 2003, James Briggs"\r
-   IDS_COPYRIGHT3          "San Jose, California, USA"\r
-   IDS_COPYRIGHT4          "james@ActionMessage.com"\r
-   IDS_COPYRIGHT5          "http://www.ActionMessage.com/winecalc/"\r
-\r
-   IDS_BTN_BACKSPACE,      "Rücktaste"\r
-   IDS_BTN_CLEAR_ENTRY,    "CE"\r
-   IDS_BTN_CLEAR_ALL,      "C"\r
-   IDS_BTN_MEM_CLEAR,      "MC"\r
-   IDS_BTN_MEM_RECALL,     "MR"\r
-   IDS_BTN_MEM_STORE,      "MS"\r
-   IDS_BTN_MEM_PLUS,       "M+"\r
-   IDS_BTN_MEM_STATUS_M,   "M"\r
-   IDS_BTN_SQRT,           "sqrt"\r
-   IDS_ERR_INVALID_INPUT,  "Ungültige Eingabe für funktion."\r
-   IDS_ERR_DIVIDE_BY_ZERO, "Teilen durch 0 unmöglich."\r
-   IDS_ERR_UNDEFINED,      "Das Ergebnis der funktion is undefiniert."\r
-}\r
-\r
-MAIN_MENU MENU DISCARDABLE\r
-{\r
-   POPUP "&Bearbeiten" {\r
-      MENUITEM "&Kopieren Ctrl+C",     IDM_COPY\r
-      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE\r
-   }\r
-   POPUP "&Ansicht" {\r
-      MENUITEM "&Standard",         IDM_MODE_STANDARD\r
-      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Zifferngruppierung",   IDM_DIGIT_GROUPING\r
-   }\r
-   POPUP "&?" {\r
-      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Info", IDM_ABOUT\r
-   }\r
-}\r
-\r
-SCIMS_MENU MENU DISCARDABLE\r
-{\r
-   POPUP "&Bearbeiten" {\r
-      MENUITEM "&Kopiren Ctrl+C",     IDM_COPY\r
-      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE\r
-   }\r
-   POPUP "&Anzeige" {\r
-      MENUITEM "&Standard",         IDM_MODE_STANDARD\r
-      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC\r
-      MENUITEM SEPARATOR\r
-         MENUITEM "&Hex\tF5",          ID_CALC_NS_HEX\r
-         MENUITEM "De&zimal\tF6",      ID_CALC_NS_DEC\r
-         MENUITEM "O&ktal\tF7",        ID_CALC_NS_OCT\r
-         MENUITEM "&Binär\tF8",       ID_CALC_NS_BIN\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Deg\tF2",      ID_CALC_MS_DEGREES\r
-      MENUITEM "&Rad\tF3",      ID_CALC_MS_RADIANS\r
-         MENUITEM "&Grad\tF4",        ID_CALC_MS_GRADS\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "Zifferngr&uppierung",   IDM_DIGIT_GROUPING\r
-   }\r
-   POPUP "&?" {\r
-      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Info", IDM_ABOUT\r
-   }\r
-}\r
-\r
-SCIWS_MENU MENU DISCARDABLE\r
-{\r
-   POPUP "&Bearbeiten" {\r
-      MENUITEM "&Kopieren Ctrl+C",     IDM_COPY\r
-      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE\r
-   }\r
-   POPUP "&Anzeige" {\r
-      MENUITEM "&Standard",         IDM_MODE_STANDARD\r
-      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC\r
-      MENUITEM SEPARATOR\r
-         MENUITEM "&Hex\tF5",          ID_CALC_NS_HEX\r
-         MENUITEM "De&zimal\tF6",      ID_CALC_NS_DEC\r
-         MENUITEM "O&ktal\tF7",        ID_CALC_NS_OCT\r
-         MENUITEM "&Binär\tF8",       ID_CALC_NS_BIN\r
-      MENUITEM SEPARATOR\r
-         MENUITEM "&Qword\tF12",       ID_CALC_WS_QWORD\r
-         MENUITEM "Dw&ord\tF2",        ID_CALC_WS_DWORD\r
-         MENUITEM "Wo&rd\tF3",         ID_CALC_WS_WORD\r
-         MENUITEM "&Byte\tF4",         ID_CALC_WS_BYTE\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Zifferngruppierung",   IDM_DIGIT_GROUPING\r
-   }\r
-   POPUP "&?" {\r
-      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS\r
-      MENUITEM SEPARATOR\r
-      MENUITEM "&Info", IDM_ABOUT\r
-   }\r
-}\r
-\r
-MAIN_MENU ACCELERATORS\r
-BEGIN\r
-   VK_F1, IDV_HELP,     VIRTKEY\r
-END\r
-\r
-DLG_ABOUT DIALOG 12,0,120,82\r
-CAPTION "Info über GNU winecalc"\r
-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
-BEGIN\r
-   DEFPUSHBUTTON "OK", IDOK,       42, 60, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
-END\r
-\r
-WHATS_THIS_MENU MENU DISCARDABLE\r
-{\r
-    POPUP "" {\r
-      MENUITEM "Was ist das?",     IDM_WHATS_THIS\r
-   }\r
-}\r
-\r
-DLG_STATS DIALOG 12,0,125,78\r
-CAPTION "Statistics Box"\r
-FONT 9, "Tahoma"\r
-STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE\r
-BEGIN\r
-   DEFPUSHBUTTON "&RET",  ID_STATS_RET,   4, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
-   PUSHBUTTON    "&LOAD", ID_STATS_LOAD, 34, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
-   PUSHBUTTON    "&CD"    ID_STATS_CD,   64, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
-   PUSHBUTTON    "C&AD",  ID_STATS_CAD,  94, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
-END\r
+/*
+ * WineCalc (DE.rc)
+ *
+ * Copyright 2005 Rouven Wessling
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "windows.h"
+#include "resource.h"
+#include "winecalc.h"
+
+LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+   IDS_APPNAME,            "Rechner"
+
+   IDS_COPYRIGHT1,         "Rechner 5.0. Lizenziert unter der LGPL 2"
+   IDS_COPYRIGHT2          "Copyright 2003, James Briggs"
+   IDS_COPYRIGHT3          "San Jose, California, USA"
+   IDS_COPYRIGHT4          "james@ActionMessage.com"
+   IDS_COPYRIGHT5          "http://www.ActionMessage.com/winecalc/"
+
+   IDS_BTN_BACKSPACE,      "Rücktaste"
+   IDS_BTN_CLEAR_ENTRY,    "CE"
+   IDS_BTN_CLEAR_ALL,      "C"
+   IDS_BTN_MEM_CLEAR,      "MC"
+   IDS_BTN_MEM_RECALL,     "MR"
+   IDS_BTN_MEM_STORE,      "MS"
+   IDS_BTN_MEM_PLUS,       "M+"
+   IDS_BTN_MEM_STATUS_M,   "M"
+   IDS_BTN_SQRT,           "sqrt"
+   IDS_ERR_INVALID_INPUT,  "Ungültige Eingabe für Funktion."
+   IDS_ERR_DIVIDE_BY_ZERO, "Teilen durch 0 unmöglich."
+   IDS_ERR_UNDEFINED,      "Das Ergebnis der Funktion is undefiniert."
+}
+
+MAIN_MENU MENU DISCARDABLE
+{
+   POPUP "&Bearbeiten" {
+      MENUITEM "&Kopieren Ctrl+C",     IDM_COPY
+      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE
+   }
+   POPUP "&Ansicht" {
+      MENUITEM "&Standard",         IDM_MODE_STANDARD
+      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC
+      MENUITEM SEPARATOR
+      MENUITEM "&Zifferngruppierung",   IDM_DIGIT_GROUPING
+   }
+   POPUP "&?" {
+      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS
+      MENUITEM SEPARATOR
+      MENUITEM "&Info", IDM_ABOUT
+   }
+}
+
+SCIMS_MENU MENU DISCARDABLE
+{
+   POPUP "&Bearbeiten" {
+      MENUITEM "&Kopieren Ctrl+C",     IDM_COPY
+      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE
+   }
+   POPUP "&Anzeige" {
+      MENUITEM "&Standard",         IDM_MODE_STANDARD
+      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC
+      MENUITEM SEPARATOR
+         MENUITEM "&Hex\tF5",          ID_CALC_NS_HEX
+         MENUITEM "De&zimal\tF6",      ID_CALC_NS_DEC
+         MENUITEM "O&ktal\tF7",        ID_CALC_NS_OCT
+         MENUITEM "&Binär\tF8",       ID_CALC_NS_BIN
+      MENUITEM SEPARATOR
+      MENUITEM "&Deg\tF2",      ID_CALC_MS_DEGREES
+      MENUITEM "&Rad\tF3",      ID_CALC_MS_RADIANS
+         MENUITEM "&Grad\tF4",        ID_CALC_MS_GRADS
+      MENUITEM SEPARATOR
+      MENUITEM "Zifferngr&uppierung",   IDM_DIGIT_GROUPING
+   }
+   POPUP "&?" {
+      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS
+      MENUITEM SEPARATOR
+      MENUITEM "&Info", IDM_ABOUT
+   }
+}
+
+SCIWS_MENU MENU DISCARDABLE
+{
+   POPUP "&Bearbeiten" {
+      MENUITEM "&Kopieren Ctrl+C",     IDM_COPY
+      MENUITEM "&Einfügen Ctrl+V",    IDM_PASTE
+   }
+   POPUP "&Anzeige" {
+      MENUITEM "&Standard",         IDM_MODE_STANDARD
+      MENUITEM "&Wissenschaftlich",       IDM_MODE_SCIENTIFIC
+      MENUITEM SEPARATOR
+         MENUITEM "&Hex\tF5",          ID_CALC_NS_HEX
+         MENUITEM "De&zimal\tF6",      ID_CALC_NS_DEC
+         MENUITEM "O&ktal\tF7",        ID_CALC_NS_OCT
+         MENUITEM "&Binär\tF8",       ID_CALC_NS_BIN
+      MENUITEM SEPARATOR
+         MENUITEM "&Qword\tF12",       ID_CALC_WS_QWORD
+         MENUITEM "Dw&ord\tF2",        ID_CALC_WS_DWORD
+         MENUITEM "Wo&rd\tF3",         ID_CALC_WS_WORD
+         MENUITEM "&Byte\tF4",         ID_CALC_WS_BYTE
+      MENUITEM SEPARATOR
+      MENUITEM "&Zifferngruppierung",   IDM_DIGIT_GROUPING
+   }
+   POPUP "&?" {
+      MENUITEM "&Hilfethemen",      IDM_HELP_TOPICS
+      MENUITEM SEPARATOR
+      MENUITEM "&Info", IDM_ABOUT
+   }
+}
+
+MAIN_MENU ACCELERATORS
+BEGIN
+   VK_F1, IDV_HELP,     VIRTKEY
+END
+
+DLG_ABOUT DIALOG 12,0,120,82
+CAPTION "Info über GNU winecalc"
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+BEGIN
+   DEFPUSHBUTTON "OK", IDOK,       42, 60, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
+
+WHATS_THIS_MENU MENU DISCARDABLE
+{
+    POPUP "" {
+      MENUITEM "Was ist das?",     IDM_WHATS_THIS
+   }
+}
+
+DLG_STATS DIALOG 12,0,125,78
+CAPTION "Statistics Box"
+FONT 9, "Tahoma"
+STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
+BEGIN
+   DEFPUSHBUTTON "&RET",  ID_STATS_RET,   4, 52, 25, 13, WS_TABSTOP | WS_GROUP
+   PUSHBUTTON    "&LOAD", ID_STATS_LOAD, 34, 52, 25, 13, WS_TABSTOP | WS_GROUP
+   PUSHBUTTON    "&CD"    ID_STATS_CD,   64, 52, 25, 13, WS_TABSTOP | WS_GROUP
+   PUSHBUTTON    "C&AD",  ID_STATS_CAD,  94, 52, 25, 13, WS_TABSTOP | WS_GROUP
+END
diff --git a/reactos/subsys/system/calc/Sv.rc b/reactos/subsys/system/calc/Sv.rc
new file mode 100644 (file)
index 0000000..a1f3355
--- /dev/null
@@ -0,0 +1,155 @@
+/*\r
+ * WineCalc (En.rc)\r
+ *\r
+ * Copyright 2005 David Nordenberg\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
+\r
+#include "windows.h"\r
+#include "resource.h"\r
+#include "winecalc.h"\r
+\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+STRINGTABLE DISCARDABLE\r
+{\r
+   IDS_APPNAME,            "Kalkylatorn"\r
+\r
+   IDS_COPYRIGHT1,         "Kalkylatorn 5.0. Licenserad under LGPL 2"\r
+   IDS_COPYRIGHT2          "Copyright 2003, James Briggs"\r
+   IDS_COPYRIGHT3          "San Jose, California, USA"\r
+   IDS_COPYRIGHT4          "james@ActionMessage.com"\r
+   IDS_COPYRIGHT5          "http://www.ActionMessage.com/winecalc/"\r
+\r
+   IDS_BTN_BACKSPACE,      "Backsteg"\r
+   IDS_BTN_CLEAR_ENTRY,    "CE"\r
+   IDS_BTN_CLEAR_ALL,      "C"\r
+   IDS_BTN_MEM_CLEAR,      "MC"\r
+   IDS_BTN_MEM_RECALL,     "MR"\r
+   IDS_BTN_MEM_STORE,      "MS"\r
+   IDS_BTN_MEM_PLUS,       "M+"\r
+   IDS_BTN_MEM_STATUS_M,   "M"\r
+   IDS_BTN_SQRT,           "sqrt"\r
+   IDS_ERR_INVALID_INPUT,  "Felaktig indata för funktion."\r
+   IDS_ERR_DIVIDE_BY_ZERO, "Kan inte dividera med noll."\r
+   IDS_ERR_UNDEFINED,      "Funktionens resultat är odefinerat."\r
+}\r
+\r
+MAIN_MENU MENU DISCARDABLE\r
+{\r
+   POPUP "&Redigera" {\r
+      MENUITEM "&Kopiera\tCtrl+C",     IDM_COPY\r
+      MENUITEM "K&listra in\tCtrl+V",    IDM_PASTE\r
+   }\r
+   POPUP "&Visa" {\r
+      MENUITEM "Standard",         IDM_MODE_STANDARD\r
+      MENUITEM "Vetenskaplig",       IDM_MODE_SCIENTIFIC\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Siffergruppering",   IDM_DIGIT_GROUPING\r
+   }\r
+   POPUP "&Hjälp" {\r
+      MENUITEM "Hjälpavsnitt",      IDM_HELP_TOPICS\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Om Kalkylatorn", IDM_ABOUT\r
+   }\r
+}\r
+\r
+SCIMS_MENU MENU DISCARDABLE\r
+{\r
+   POPUP "&Redigera" {\r
+      MENUITEM "&Kopiera\tCtrl+C",     IDM_COPY\r
+      MENUITEM "K&listra in\tCtrl+V",    IDM_PASTE\r
+   }\r
+   POPUP "&Visa" {\r
+      MENUITEM "Standard",         IDM_MODE_STANDARD\r
+      MENUITEM "Vetenskaplig",       IDM_MODE_SCIENTIFIC\r
+      MENUITEM SEPARATOR\r
+         MENUITEM "Hex\tF5",          ID_CALC_NS_HEX\r
+         MENUITEM "Decimal\tF6",      ID_CALC_NS_DEC\r
+         MENUITEM "Oktal\tF7",        ID_CALC_NS_OCT\r
+         MENUITEM "Binär\tF8",       ID_CALC_NS_BIN\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Grader\tF2",      ID_CALC_MS_DEGREES\r
+      MENUITEM "Radianer\tF3",      ID_CALC_MS_RADIANS\r
+         MENUITEM "Gradienter\tF4",        ID_CALC_MS_GRADS\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Siffergruppering",   IDM_DIGIT_GROUPING\r
+   }\r
+   POPUP "&Hjälp" {\r
+      MENUITEM "Hjälpavsnitt",      IDM_HELP_TOPICS\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Om Kalkylatorn", IDM_ABOUT\r
+   }\r
+}\r
+\r
+SCIWS_MENU MENU DISCARDABLE\r
+{\r
+   POPUP "&Redigera" {\r
+      MENUITEM "&Kopiera\tCtrl+C",     IDM_COPY\r
+      MENUITEM "K&listra in\tCtrl+V",    IDM_PASTE\r
+   }\r
+   POPUP "&Visa" {\r
+      MENUITEM "Standard",         IDM_MODE_STANDARD\r
+      MENUITEM "Vetenskaplig",       IDM_MODE_SCIENTIFIC\r
+      MENUITEM SEPARATOR\r
+         MENUITEM "Hex\tF5",          ID_CALC_NS_HEX\r
+         MENUITEM "Decimal\tF6",      ID_CALC_NS_DEC\r
+         MENUITEM "Oktal\tF7",        ID_CALC_NS_OCT\r
+         MENUITEM "Binär\tF8",       ID_CALC_NS_BIN\r
+      MENUITEM SEPARATOR\r
+         MENUITEM "Qword\tF12",       ID_CALC_WS_QWORD\r
+         MENUITEM "Dword\tF2",        ID_CALC_WS_DWORD\r
+         MENUITEM "Word\tF3",         ID_CALC_WS_WORD\r
+         MENUITEM "Byte\tF4",         ID_CALC_WS_BYTE\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Siffergruppering",   IDM_DIGIT_GROUPING\r
+   }\r
+   POPUP "&Hjälp" {\r
+      MENUITEM "Hjälpavsnitt",      IDM_HELP_TOPICS\r
+      MENUITEM SEPARATOR\r
+      MENUITEM "Om Kalkylatorn", IDM_ABOUT\r
+   }\r
+}\r
+\r
+MAIN_MENU ACCELERATORS\r
+BEGIN\r
+   VK_F1, IDV_HELP,     VIRTKEY\r
+END\r
+\r
+DLG_ABOUT DIALOG 12,0,120,82\r
+CAPTION "Om GNU Kalkylatorn (winecalc)"\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+BEGIN\r
+   DEFPUSHBUTTON "OK", IDOK,       42, 60, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP\r
+END\r
+\r
+WHATS_THIS_MENU MENU DISCARDABLE\r
+{\r
+    POPUP "" {\r
+      MENUITEM "Vad är det här?",     IDM_WHATS_THIS\r
+   }\r
+}\r
+\r
+DLG_STATS DIALOG 12,0,125,78\r
+CAPTION "Statistikruta"\r
+FONT 9, "Tahoma"\r
+STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE\r
+BEGIN\r
+   DEFPUSHBUTTON "&RET",  ID_STATS_RET,   4, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
+   PUSHBUTTON    "&LOAD", ID_STATS_LOAD, 34, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
+   PUSHBUTTON    "&CD"    ID_STATS_CD,   64, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
+   PUSHBUTTON    "C&AD",  ID_STATS_CAD,  94, 52, 25, 13, WS_TABSTOP | WS_GROUP\r
+END\r
index 734bca2..27069ea 100644 (file)
@@ -4,5 +4,3 @@
 #include <reactos/resource.h>
 
 #include "rsrc.rc"
-#include "De.rc"
-
index 53f73bf..221463a 100644 (file)
@@ -22,6 +22,7 @@
 #include "resource.h"
 
 #include "En.rc"
+#include "De.rc"
 #include "Es.rc"
 #include "Fr.rc"
 #include "It.rc"
@@ -29,5 +30,5 @@
 #include "Pt.rc"
 #include "Ru.rc"
 #include "Si.rc"
-
+#include "Sv.rc"
 LANGUAGE LANG_NEUTRAL,SUBLANG_NEUTRAL
diff --git a/reactos/subsys/system/cmd/En.rc b/reactos/subsys/system/cmd/En.rc
new file mode 100644 (file)
index 0000000..74b9aaa
--- /dev/null
@@ -0,0 +1,273 @@
+#include "resource.h"\r
+/* Start move all hard code string to En.rc \r
+ * By Magnus Olsen  2005\r
+ */\r
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\r
+STRINGTABLE DISCARDABLE\r
+{\r
+STRING_ATTRIB_HELP,    "Displays or changes file attributes.\n\n \\r
+ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] file ...\n \\r
+       [/S [/D]]\n\n \\r
+  +   Sets an attribute\n \\r
+  -   Clears an attribute\n \\r
+  R   Read-only file attribute\n \\r
+  A   Archive file attribute\n \\r
+  S   System file attribute\n \\r
+  H   Hidden file attribute\n \\r
+  /S  Processes matching files in the current directory\n \\r
+      and all subdirectories\n \\r
+  /D  Processes direcories as well\n\n \\r
+Type ATTRIB without a parameter to display the attributes of all files."\r
+\r
+STRING_ALIAS_HELP,  "Sets, removes or shows aliases.\n\n \\r
+ALIAS [alias=[command]]\n\n \\r
+  alias    Name for an alias.\n \\r
+  command  Text to be substituted for an alias.\n\n \\r
+To list all aliases:\n \\r
+  ALIAS\n\n \\r
+To set a new or replace an existing alias:\n \\r
+  ALIAS da=dir a:\n\n \\r
+To remove an alias from the alias list:\n \\r
+  ALIAS da="\r
+\r
+STRING_BEEP_HELP, "Beep the speaker.\n\nBEEP"\r
+\r
+STRING_CALL_HELP, "Calls one batch program from another.\n\n \\r
+CALL [drive:][path]filename [batch-parameter]\n\n \\r
+  batch-parameter  Specifies any command-line information required by the\n \\r
+                   batch program."\r
+\r
+STRING_CD_HELP,      "Changes the current directory or displays it's name\n\n \\r
+CHDIR [drive:][path]\n \\r
+CHDIR[..|-]\n \\r
+CD [drive:][path]\n \\r
+CD[..|-]\n\n \\r
+  ..   parent directory\n \\r
+  -    previous directory\n\n \\r
+Type CD drive: to display the current directory on the specified drive.\n \\r
+Type CD without a parameter to display the current drive and directory. "\r
+\r
+STRING_CHCP_HELP,   "Displays or sets the active code page number.\n\n \\r
+CHCP [nnn]\n\n \\r
+  nnn   Specifies the active code page number.\n\n \\r
+Type CHCP without a parameter to display the active code page number."\r
+\r
+STRING_CHOICE_HELP, "Waits for the user to choose one of a set of choices.\n\n \\r
+CHOICE  [/C[:]choices][/N][/S][/T[:]c,nn][text]\n\n \\r
+  /C[:]choices  Specifies allowable keys. Default is YN.\n \\r
+  /N            Do not display choices and ? at the end of the prompt string.\n \\r
+  /S            Treat choice keys as case sensitive.\n \\r
+  /T[:]c,nn     Default choice to c after nn seconds.\n \\r
+  text          Prompt string to display.\n\n \\r
+ERRORLEVEL is set to offset of key user presses in choices."\r
+\r
+STRING_CLS_HELP, "Clears the screen.\n\nCLS"\r
+\r
+STRING_CMD_HELP1, "\nInternal commands available:\n"\r
+\r
+STRING_CMD_HELP2, "\nFeatures available:"\r
+\r
+STRING_CMD_HELP3,"  [aliases]"\r
+\r
+STRING_CMD_HELP4,"  [history]"\r
+\r
+STRING_CMD_HELP5,"  [unix filename completion]"\r
+\r
+STRING_CMD_HELP6,"  [directory stack]"\r
+\r
+STRING_CMD_HELP7,"  [redirections and piping]"\r
+\r
+STRING_CMD_HELP8, "Starts a new instance of the ReactOS command line interpreter.\n\n \\r
+CMD [/[C|K] command][/P][/Q][/T:bf]\n\n \\r
+  /C command  Runs the specified command and terminates.\n \\r
+  /K command  Runs the specified command and remains.\n \\r
+  /P          CMD becomes permanent and runs autoexec.bat\n \\r
+              (cannot be terminated).\n \\r
+  /T:bf       Sets the background/foreground color (see COLOR command)."\r
+\r
+STRING_COLOR_HELP1, "Sets the default foreground and background colors.\n\n \\r
+COLOR [attr [/F]] \n\n \\r
+  attr        Specifies color attribute of console output\n \\r
+  /F          fill the console with color attribute\n\n \\r
+There are three ways to specify the colors:\n \\r
+1) [bright] name on [bright] name  (only the first three letters are required)\n \\r
+2) decimal on decimal\n \\r
+3) two hex digits\n\n \\r
+Colors are:\n \\r
+dec  hex  name       dec  hex  name\n \\r
+0    0    Black       8   8    Gray(Bright black)\n \\r
+1    1    Blue        9   9    Bright Blue\n \\r
+2    2    Green      10   A    Bright Green\n \\r
+3    3    Cyan       11   B    Bright Cyan\n \\r
+4    4    Red        12   C    Bright Red\n \\r
+5    5    Magenta    13   D    Bright Magenta\n \\r
+6    6    Yellow     14   E    Bright Yellow\n \\r
+7    7    White      15   F    Bright White"\r
+\r
+STRING_COPY_HELP1,  "Overwrite %s (Yes/No/All)? "\r
+\r
+STRING_COPY_HELP2, "Copies one or more files to another location.\n\n \\r
+COPY [/V][/Y|/-Y][/A|/B] source [/A|/B]\n \\r
+     [+ source [/A|/B] [+ ...]] [destination [/A|/B]]\n\n \\r
+  source       Specifies the file or files to be copied.\n \\r
+  /A           Indicates an ASCII text file.\n \\r
+  /B           Indicates a binary file.\n \\r
+  destination  Specifies the directory and/or filename for the new file(s).\n \\r
+  /V           Verifies that new files are written correctly.\n \\r
+  /Y           Suppresses prompting to confirm you want to overwrite an\n \\r
+               existing destination file.\n \\r
+  /-Y          Causes prompting to confirm you want to overwrite an\n \\r
+               existing destination file.\n\n \\r
+The switch /Y may be present in the COPYCMD environment variable.\n \\r
+..."\r
+\r
+STRING_DATE_HELP1, "\nEnter new date (mm%cdd%cyyyy): "\r
+\r
+STRING_DATE_HELP2, "\nEnter new date (dd%cmm%cyyyy): "\r
+\r
+STRING_DATE_HELP3, "\nEnter new date (yyyy%cmm%cdd): "\r
+\r
+STRING_DATE_HELP4, "Displays or sets the date.\n\n \\r
+DATE [/T][date]\n\n \\r
+  /T    display only\n\n \\r
+Type DATE without parameters to display the current date setting and\n \\r
+a prompt for a new one.  Press ENTER to keep the same date."\r
+                               \r
+STRING_DEL_HELP1,  "Deletes one or more files.\n\n \\r
+DEL [/%c /%c /%c /%c /%c /%c /%c] file ...\n \\r
+DELETE [/%c /%c /%c /%c /%c /%c /%c] file ...\n \\r
+ERASE [/%c /%c /%c /%c /%c /%c /%c] file ...\n\n \\r
+  file  Specifies the file(s) to delete.\n\n \\r
+  /%c    Nothing.\n \\r
+  /%c    Prompt. Ask before deleting each file.\n \\r
+  /%c    Total. Display total number of deleted files and freed disk space.\n \\r
+  /%c    Quiet.\n \\r
+  /%c    Wipe. Overwrite the file with random numbers before deleting it.\n \\r
+  /%c    Yes. Kill even *.* without asking.\n \\r
+  /%c    Zap. Delete hidden, read-only and system files).\n"\r
+\r
+STRING_DEL_HELP2, "All files in the directory will be deleted!\nAre you sure (Y/N)?"\r
+STRING_DEL_HELP3, "    %lu file deleted\n"\r
+STRING_DEL_HELP4, "    %lu files deleted\n"\r
+\r
+STRING_DELAY_HELP, "pause for n seconds or milliseconds\n \\r
+DELAY [/m]n\n\n \\r
+  /m          specifiy than n are milliseconds\n \\r
+              otherwise n are seconds"\r
+\r
+STRING_DIR_HELP1, "DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]\n \\r
+  [/O[[:]sortorder]] [/P] [/Q] [/S] [/T[[:]timefield]] [/W] [/X] [/4]\n\n \\r
+  [drive:][path][filename]\n \\r
+              Specifies drive, directory, and/or files to list.\n\n \\r
+  /A          Displays files with specified attributes.\n \\r
+  attributes   D  Directories                R  Read-only files\n \\r
+               H  Hidden files               A  Files ready for archiving\n \\r
+               S  System files               -  Prefix meaning not\n \\r
+  /B          Uses bare format (no heading information or summary).\n \\r
+  /C          Display the thousand separator in file sizes.  This is the\n \\r
+              default.  Use /-C to disable display of separator.\n \\r
+  /D          Same as wide but files are list sorted by column.\n \\r
+  /L          Uses lowercase.\n \\r
+  /N          New long list format where filenames are on the far right.\n \\r
+  /O          List by files in sorted order.\n \\r
+  sortorder    N  By name (alphabetic)       S  By size (smallest first)\n \\r
+               E  By extension (alphabetic)  D  By date/time (oldest first)\n \\r
+               G  Group directories first    -  Prefix to reverse order\n \\r
+  /P          Pauses after each screenful of information.\n \\r
+  /Q          Display the owner of the file.\n \\r
+  /S          Displays files in specified directory and all subdirectories.\n \\r
+  /T          Controls which time field displayed or used for sorting\n \\r
+  timefield   C  Creation\n \\r
+              A  Last Access\n \\r
+              W  Last Written\n \\r
+  /W          Uses wide list format.\n \\r
+  /X          This displays the short names generated for non-8dot3 file\n \\r
+              names.  The format is that of /N with the short name inserted\n \\r
+              before the long name. If no short name is present, blanks are\n \\r
+              displayed in its place.\n \\r
+  /4          Displays four-digit years\n\n \\r
+Switches may be preset in the DIRCMD environment variable.  Override\n \\r
+preset switches by prefixing any switch with - (hyphen)--for example, /-W.\n "\r
+\r
+STRING_DIR_HELP2, " Volume in drive %c is %s"\r
+STRING_DIR_HELP3, " Volume in drive %c has no label"\r
+STRING_DIR_HELP4, " Volume Serial Number is %04X-%04X\n"\r
+STRING_DIR_HELP5, "\n     Total Files Listed:\n%16i File(s)% 14s bytes\n"\r
+STRING_DIR_HELP6, "%16i Dir(s)% 15s bytes\n"\r
+STRING_DIR_HELP7, "\n Directory of %s\n\n"\r
+STRING_DIR_HELP8, "%16i Dir(s)% 14s bytes\n"\r
+\r
+STRING_DIRSTACK_HELP1, "Stores the current directory for use by the POPD command, then\n \\r
+changes to the specified directory.\n\n \\r
+PUSHD [path | ..]\n\n \\r
+  path        Specifies the directory to make the current directory"\r
+\r
+STRING_DIRSTACK_HELP2, "Changes to the directory stored by the PUSHD command.\n\nPOPD"\r
+\r
+STRING_DIRSTACK_HELP3, "Prints the contents of the directory stack.\n\nDIRS"\r
+\r
+STRING_DIRSTACK_HELP4, "Directory stack empty"\r
+\r
+\r
+STRING_EXIT_HELP, "Exits the command line interpreter.\n\nEXIT"\r
+\r
+STRING_MKDIR_HELP,   "Creates a directory.\n\n \\r
+MKDIR [drive:]path\nMD [drive:]path"\r
+\r
+STRING_RMDIR_HELP,   "Removes a directory.\n\n \\r
+RMDIR [drive:]path\nRD [drive:]path"  \r
+\r
+STRING_REM_HELP, "Starts a comment line in a batch file.\n\nREM [Comment]"\r
+\r
+\r
+\r
+\r
+       \r
+\r
+\r
+\r
+\r
+\r
+\r
+STRING_CHOICE_OPTION,         "YN"\r
+STRING_COPY_OPTION,           "YNA"\r
+STRING_DEL_OPTION,            "AENPQSTWXYZ"\r
+\r
+\r
+STRING_ALIAS_ERROR,          "Command line too long after alias expansion!\n"\r
+STRING_BATCH_ERROR,          "Error opening batch file\n"\r
+STRING_CHCP_ERROR1,          "Active code page: %u\n"\r
+STRING_CHCP_ERROR2,          "Invalid parameter format - %s\n"\r
+STRING_CHCP_ERROR3,          "Parameter format incorrect - %s\n"\r
+STRING_CHCP_ERROR4,          "Invalid code page\n"\r
+STRING_CHOICE_ERROR,         "Invalid option. Expected format: /C[:]options"\r
+STRING_CHOICE_ERROR_TXT,     "Invalid option. Expected format: /T[:]c,nn"\r
+STRING_CHOICE_ERROR_OPTION,  "Illegal Option: %s"\r
+STRING_CMD_ERROR1,           "Can't redirect input from file %s\n"\r
+STRING_CMD_ERROR2,           "Error creating temporary file for pipe data\n"\r
+STRING_CMD_ERROR3,           "Can't redirect to file %s\n"\r
+STRING_CMD_ERROR4,           "Running %s...\n"\r
+STRING_CMD_ERROR5,           "Running cmdexit.bat...\n"\r
+STRING_COLOR_ERROR1,         "Same colors error! (Background and foreground can't be the same color)"\r
+STRING_COLOR_ERROR2,         "error in color specification"\r
+STRING_COLOR_ERROR3,         "Color %x\n"\r
+STRING_COLOR_ERROR4,         "same colors error!"\r
+STRING_CONSOLE_ERROR,        "Unknown error: %d\n"\r
+STRING_COPY_ERROR1,          "Error: Cannot open source - %s!\n"\r
+STRING_COPY_ERROR2,          "Error: Can't copy onto itself!\n"\r
+STRING_COPY_ERROR3,          "Error writing destination!\n"\r
+STRING_COPY_ERROR4,          "Error: Not implemented yet!\n"\r
+STRING_DATE_ERROR,           "Invalid date."\r
+STRING_DEL_ERROR1,           "Wildcards!\n\n"\r
+STRING_DEL_ERROR2,           "Full path: %s\n"\r
+STRING_DEL_ERROR3,           "File part: %s\n"\r
+STRING_DEL_ERROR4,           "Full filename: %s\n"\r
+STRING_DEL_ERROR5,           "The file %s will be deleted! "\r
+STRING_DEL_ERROR6,           "Are you sure (Y/N)?"\r
+STRING_DEL_ERROR7,           "Deleting: %s\n"\r
+STRING_DEL_ERROR8,           "No Wildcards!\n"\r
+STRING_PARAM_ERROR,          "Required parameter missing\n"\r
+\r
+\r
+}\r
index 820d26b..8c69eef 100644 (file)
  *
  *    24-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Redirection safe!
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef FEATURE_ALIASES
 
@@ -233,6 +237,7 @@ VOID DestroyAlias (VOID)
 /* specified routines */
 VOID ExpandAlias (LPTSTR cmd, INT maxlen)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
        unsigned n = 0,
                m,
                i,
@@ -276,7 +281,8 @@ VOID ExpandAlias (LPTSTR cmd, INT maxlen)
                                m = _tcslen (ptr->lpSubst);
                                if ((int)(_tcslen (cmd) - len + m - n) > maxlen)
                                {
-                                       ConErrPrintf (_T("Command line too long after alias expansion!\n"));
+                                       LoadString( GetModuleHandle(NULL), STRING_ALIAS_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+                    ConErrPrintf (_T((LPTSTR)szMsg));                                  
                                        /* the parser won't cause any problems with an empty line */
                                        cmd[0] = _T('\0');
                                }
@@ -300,25 +306,12 @@ VOID ExpandAlias (LPTSTR cmd, INT maxlen)
 INT CommandAlias (LPTSTR cmd, LPTSTR param)
 {
        LPTSTR ptr;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Sets, removes or shows aliases.\n"
-                              "\n"
-                              "ALIAS [alias=[command]]\n"
-                              "\n"
-                              "  alias    Name for an alias.\n"
-                              "  command  Text to be substituted for an alias.\n"
-                              "\n"
-//                                        "For example:\n"
-                                          "To list all aliases:\n"
-                                          "  ALIAS\n\n"
-                                          "To set a new or replace an existing alias:\n"
-                                          "  ALIAS da=dir a:\n\n"
-                                          "To remove an alias from the alias list:\n"
-                                          "  ALIAS da="
-//                                        "Type ALIAS without a parameter to display the alias list.\n"
-                                          ));
+               LoadString( GetModuleHandle(NULL), STRING_ALIAS_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
index e21f3a0..3354877 100644 (file)
  *
  *    23-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Added handling of multiple filenames.
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_ATTRIB
 
@@ -40,7 +44,7 @@ PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse)
        WIN32_FIND_DATA findData;
        HANDLE hFind;
        TCHAR  szFullName[MAX_PATH];
-       LPTSTR pszFileName;
+       LPTSTR pszFileName;      
 
        /* prepare full file name buffer */
        _tcscpy (szFullName, pszPath);
@@ -116,6 +120,7 @@ ChangeAttribute (LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask,
        TCHAR  szFullName[MAX_PATH];
        LPTSTR pszFileName;
 
+
        /* prepare full file name buffer */
        _tcscpy (szFullName, pszPath);
        pszFileName = szFullName + _tcslen (szFullName);
@@ -192,6 +197,7 @@ INT CommandAttrib (LPTSTR cmd, LPTSTR param)
        BOOL   bDirectories = FALSE;
        DWORD  dwAttrib = 0;
        DWORD  dwMask = 0;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        /* initialize strings */
        szPath[0] = _T('\0');
@@ -200,19 +206,8 @@ INT CommandAttrib (LPTSTR cmd, LPTSTR param)
        /* print help */
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Displays or changes file attributes.\n\n"
-                                          "ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] file ...\n"
-                                          "       [/S [/D]]\n\n"
-                                          "  +   Sets an attribute\n"
-                                          "  -   Clears an attribute\n"
-                                          "  R   Read-only file attribute\n"
-                                          "  A   Archive file attribute\n"
-                                          "  S   System file attribute\n"
-                                          "  H   Hidden file attribute\n"
-                                          "  /S  Processes matching files in the current directory\n"
-                                          "      and all subdirectories\n"
-                                          "  /D  Processes direcories as well\n\n"
-                                          "Type ATTRIB without a parameter to display the attributes of all files."));
+               LoadString( GetModuleHandle(NULL), STRING_ATTRIB_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
index 36da188..3362275 100644 (file)
  *    
  *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.es>)
  *        Fixes made to get "for" working.
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 
 /* The stack of current batch contexts.
@@ -215,6 +219,7 @@ VOID ExitBatch (LPTSTR msg)
 BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
 {
        HANDLE hFile;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_READ, NULL,
                                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
@@ -227,7 +232,8 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param)
 
        if (hFile == INVALID_HANDLE_VALUE)
        {
-               ConErrPrintf (_T("Error opening batch file\n"));
+               LoadString( GetModuleHandle(NULL), STRING_BATCH_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));
                return FALSE;
        }
 
index 687f0b1..ae0c9bc 100644 (file)
  *
  *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Redirection ready!
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_BEEP
 
 
 INT cmd_beep (LPTSTR cmd, LPTSTR param)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        if (_tcsncmp (param, _T("/?"), 2) == 0)
        {
-               ConOutPuts (_T("Beep the speaker.\n\nBEEP"));
+               LoadString( GetModuleHandle(NULL), STRING_ALIAS_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
index 05e728b..32ca9f8 100644 (file)
  *
  *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Unicode and redirection safe!
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 
 /*
 INT cmd_call (LPTSTR cmd, LPTSTR param)
 {
        LPBATCH_CONTEXT n = NULL;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
 #ifdef _DEBUG
        DebugPrintf (_T("cmd_call: (\'%s\',\'%s\')\n"), cmd, param);
 #endif
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Calls one batch program from another.\n\n"
-                                          "CALL [drive:][path]filename [batch-parameter]\n\n"
-                                          "  batch-parameter  Specifies any command-line information required by the\n"
-                                          "                   batch program."));
+               LoadString( GetModuleHandle(NULL), STRING_CALL_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+
                return 0;
        }
 
index 3ebd03f..d21c9b1 100644 (file)
@@ -7,9 +7,12 @@
  *    23-Dec-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Started.
  *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_CHCP
 
@@ -19,14 +22,13 @@ INT CommandChcp (LPTSTR cmd, LPTSTR param)
        INT    args;
        UINT uOldCodePage;
        UINT uNewCodePage;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        /* print help */
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Displays or sets the active code page number.\n\n"
-                              "CHCP [nnn]\n\n"
-                              "  nnn   Specifies the active code page number.\n\n"
-                              "Type CHCP without a parameter to display the active code page number."));
+               LoadString( GetModuleHandle(NULL), STRING_CHCP_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
@@ -36,14 +38,18 @@ INT CommandChcp (LPTSTR cmd, LPTSTR param)
        if (args == 0)
        {
                /* display active code page number */
-               ConOutPrintf (_T("Active code page: %u\n"), GetConsoleCP ());
+               LoadString( GetModuleHandle(NULL), STRING_CHCP_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg), GetConsoleCP ());
+
                return 0;
        }
 
        if (args >= 2)
        {
                /* too many parameters */
-               ConErrPrintf (_T("Invalid parameter format - %s\n"), param);
+               LoadString( GetModuleHandle(NULL), STRING_CHCP_ERROR2, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg), param);
+
                return 1;
        }
 
@@ -55,14 +61,16 @@ INT CommandChcp (LPTSTR cmd, LPTSTR param)
 
        if (uNewCodePage == 0)
        {
-               ConErrPrintf (_T("Parameter format incorrect - %s\n"), arg[0]);
+               LoadString( GetModuleHandle(NULL), STRING_CHCP_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg), arg[0]);
                freep (arg);
                return 1;
        }
 
        if (!SetConsoleCP (uNewCodePage))
        {
-               ConErrPrintf (_T("Invalid code page\n"));
+               LoadString( GetModuleHandle(NULL), STRING_CHCP_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));              
        }
        else
        {
index 6cc6426..16f216f 100644 (file)
  *
  *    26 Sep 1999 (Paolo Pantaleo)
  *        Fixed timeout.
+ *
+ *    02 Apr 2005 (Magnus Olsen
+ *        Remove Hardcode string so
+ *        they can be translate
+ *
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_CHOICE
 
@@ -97,7 +103,8 @@ IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
 INT
 CommandChoice (LPTSTR cmd, LPTSTR param)
 {
-       LPTSTR lpOptions = _T("YN");
+       LPTSTR lpOptions;
+       TCHAR Options[2];
        LPTSTR lpText    = NULL;
        BOOL   bNoPrompt = FALSE;
        BOOL   bCaseSensitive = FALSE;
@@ -114,21 +121,17 @@ CommandChoice (LPTSTR cmd, LPTSTR param)
        INT GCret;
        TCHAR Ch;
        DWORD amount,clk;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
+    LoadString( GetModuleHandle(NULL), STRING_CHOICE_OPTION, (LPTSTR) Options,sizeof(lpOptions));
+    lpOptions = _T(Options);
 
        if (_tcsncmp (param, _T("/?"), 2) == 0)
        {
-               ConOutPuts (_T("Waits for the user to choose one of a set of choices.\n"
-                              "\n"
-                              "CHOICE  [/C[:]choices][/N][/S][/T[:]c,nn][text]\n"
-                              "\n"
-                              "  /C[:]choices  Specifies allowable keys. Default is YN.\n"
-                              "  /N            Do not display choices and ? at the end of the prompt string.\n"
-                              "  /S            Treat choice keys as case sensitive.\n"
-                              "  /T[:]c,nn     Default choice to c after nn seconds.\n"
-                              "  text          Prompt string to display.\n"
-                              "\n"
-                              "ERRORLEVEL is set to offset of key user presses in choices."));
-               return 0;
+        LoadString( GetModuleHandle(NULL), STRING_CHOICE_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+     ConOutPuts (_T((LPTSTR)szMsg));
+
+        return 0;
        }
 
        /* retrieve text */
@@ -167,7 +170,9 @@ CommandChoice (LPTSTR cmd, LPTSTR param)
 
                                if (_tcslen (lpOptions) == 0)
                                {
-                                       ConErrPuts (_T("Invalid option. Expected format: /C[:]options"));
+                                       
+                                       LoadString( GetModuleHandle(NULL), STRING_CHOICE_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+                                       ConErrPuts (_T((LPTSTR)szMsg));
                                        freep (arg);
                                        return 1;
                                }
@@ -197,7 +202,8 @@ CommandChoice (LPTSTR cmd, LPTSTR param)
 
                                if (*s != _T(','))
                                {
-                                       ConErrPuts (_T("Invalid option. Expected format: /T[:]c,nn"));
+                                       LoadString( GetModuleHandle(NULL), STRING_CHOICE_ERROR_TXT, (LPTSTR) szMsg,sizeof(szMsg));
+                    ConErrPuts (_T((LPTSTR)szMsg));
                                        freep (arg);
                                        return 1;
                                }
@@ -208,7 +214,8 @@ CommandChoice (LPTSTR cmd, LPTSTR param)
                        }
                        else if (arg[i][0] == _T('/'))
                        {
-                               ConErrPrintf (_T("Illegal Option: %s"), arg[i]);
+                               LoadString( GetModuleHandle(NULL), STRING_CHOICE_ERROR_OPTION, (LPTSTR) szMsg,sizeof(szMsg));               
+                               ConErrPrintf (_T((LPTSTR)szMsg), arg[i]);
                                freep (arg);
                                return 1;
                        }
index d1dfd3d..d44cddf 100644 (file)
  *
  *    20-Jan-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Redirection ready!
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_CLS
 
@@ -32,10 +36,12 @@ INT cmd_cls (LPTSTR cmd, LPTSTR param)
        DWORD dwWritten;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        COORD coPos;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Clears the screen.\n\nCLS"));
+               LoadString( GetModuleHandle(NULL), STRING_CLS_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
index 6a84fe6..a868f56 100644 (file)
  *
  *    12-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
  *       Added ShellExecute call when all else fails to be able to "launch" any file.
+ *
+ *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifndef NT_SUCCESS
 #define NT_SUCCESS(StatCode)  ((NTSTATUS)(StatCode) >= 0)
@@ -548,6 +552,7 @@ VOID ParseCommandLine (LPTSTR cmd)
 {
        TCHAR cmdline[CMDLINE_LENGTH];
        LPTSTR s;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 #ifdef FEATURE_REDIRECTION
        TCHAR in[CMDLINE_LENGTH] = _T("");
        TCHAR out[CMDLINE_LENGTH] = _T("");
@@ -629,13 +634,15 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), in);
                        return;
                }
 
                if (!SetStdHandle (STD_INPUT_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), in);
                        return;
                }
 #ifdef _DEBUG
@@ -659,7 +666,9 @@ VOID ParseCommandLine (LPTSTR cmd)
                                       TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
 
       if (hFile[1] == INVALID_HANDLE_VALUE){
-         ConErrPrintf (_T("Error creating temporary file for pipe data\n"));
+
+         LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR2, (LPTSTR) szMsg,sizeof(szMsg));
+         ConErrPrintf (_T((LPTSTR)szMsg));
          return;
       }
 
@@ -711,13 +720,16 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), out);
+
                        return;
                }
 
                if (!SetStdHandle (STD_OUTPUT_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), out);
                        return;
                }
 
@@ -770,13 +782,17 @@ VOID ParseCommandLine (LPTSTR cmd)
                                            NULL);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
-                               ConErrPrintf (_T("Can't redirect to file %s\n"), err);
+                               LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+                ConErrPrintf (_T((LPTSTR)szMsg), err);
+
                                return;
                        }
                }
                if (!SetStdHandle (STD_ERROR_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), err);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), err);
+
                        return;
                }
 
@@ -906,6 +922,7 @@ ProcessInput (BOOL bFlag)
        LPTSTR ip;
        LPTSTR cp;
        BOOL bEchoThisLine;
+       
 
        do
        {
@@ -1018,6 +1035,7 @@ ProcessInput (BOOL bFlag)
  */
 BOOL WINAPI BreakHandler (DWORD dwCtrlType)
 {
+       
        if ((dwCtrlType != CTRL_C_EVENT) &&
            (dwCtrlType != CTRL_BREAK_EVENT))
                return FALSE;
@@ -1058,26 +1076,36 @@ VOID RemoveBreakHandler (VOID)
 static VOID
 ShowCommands (VOID)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        /* print command list */
-       ConOutPrintf (_T("\nInternal commands available:\n"));
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPrintf (_T((LPTSTR)szMsg));
        PrintCommandList ();
 
        /* print feature list */
-       ConOutPuts (_T("\nFeatures available:"));
-#ifdef FEATURE_ALIASES
-       ConOutPuts (_T("  [aliases]"));
+        LoadString( GetModuleHandle(NULL), STRING_CMD_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+     ConOutPuts (_T((LPTSTR)szMsg));
+
+#ifdef FEATURE_ALIASES 
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP3, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 #endif
 #ifdef FEATURE_HISTORY
-       ConOutPuts (_T("  [history]"));
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP4, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 #endif
 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
-       ConOutPuts (_T("  [unix filename completion]"));
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP5, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 #endif
 #ifdef FEATURE_DIRECTORY_STACK
-       ConOutPuts (_T("  [directory stack]"));
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP6, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 #endif
 #ifdef FEATURE_REDIRECTION
-       ConOutPuts (_T("  [redirections and piping]"));
+       LoadString( GetModuleHandle(NULL), STRING_CMD_HELP7, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 #endif
        ConOutChar (_T('\n'));
 }
@@ -1096,6 +1124,8 @@ Initialize (int argc, TCHAR* argv[])
        TCHAR commandline[CMDLINE_LENGTH];
        TCHAR ModuleName[_MAX_PATH + 1];
        INT i;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        //INT len;
        //TCHAR *ptr, *cmdLine;
 
@@ -1124,15 +1154,8 @@ Initialize (int argc, TCHAR* argv[])
 
        if (argc >= 2 && !_tcsncmp (argv[1], _T("/?"), 2))
        {
-               ConOutPuts (_T("Starts a new instance of the ReactOS command line interpreter.\n"
-                              "\n"
-                              "CMD [/[C|K] command][/P][/Q][/T:bf]\n"
-                              "\n"
-                              "  /C command  Runs the specified command and terminates.\n"
-                              "  /K command  Runs the specified command and remains.\n"
-                              "  /P          CMD becomes permanent and runs autoexec.bat\n"
-                              "              (cannot be terminated).\n"
-                              "  /T:bf       Sets the background/foreground color (see COLOR command)."));
+               LoadString( GetModuleHandle(NULL), STRING_CMD_HELP8, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                ExitProcess (0);
        }
        SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
@@ -1236,7 +1259,8 @@ Initialize (int argc, TCHAR* argv[])
 
                if (IsExistingFile (_T("commandline")))
                {
-                       ConErrPrintf (_T("Running %s...\n", commandline));
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), commandline);
                        ParseCommandLine (commandline);
                }
        }
@@ -1267,15 +1291,20 @@ Initialize (int argc, TCHAR* argv[])
 
 static VOID Cleanup (int argc, TCHAR *argv[])
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        /* run cmdexit.bat */
        if (IsExistingFile (_T("cmdexit.bat")))
        {
-               ConErrPrintf (_T("Running cmdexit.bat...\n"));
+               LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR5, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));
+
                ParseCommandLine (_T("cmdexit.bat"));
        }
        else if (IsExistingFile (_T("\\cmdexit.bat")))
        {
-               ConErrPrintf (_T("Running \\cmdexit.bat...\n"));
+               LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR5, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));
                ParseCommandLine (_T("\\cmdexit.bat"));
        }
 #ifndef __REACTOS__
@@ -1291,7 +1320,8 @@ static VOID Cleanup (int argc, TCHAR *argv[])
 
                if (IsExistingFile (_T("commandline")))
                {
-                       ConErrPrintf (_T("Running %s...\n"), commandline);
+                       LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), commandline);
                        ParseCommandLine (commandline);
                }
        }
index f9aab35..4beb814 100644 (file)
@@ -228,6 +228,7 @@ VOID error_sfile_not_found (LPTSTR);
 VOID error_file_not_found (VOID);
 VOID error_path_not_found (VOID);
 VOID error_too_many_parameters (LPTSTR);
+VOID error_parameter_format(TCHAR);
 VOID error_invalid_switch (TCHAR);
 VOID error_invalid_parameter_format (LPTSTR);
 VOID error_out_of_memory (VOID);
index 448bcd9..ad10b0d 100644 (file)
@@ -7,5 +7,13 @@
 #define REACTOS_STR_ORIGINAL_COPYRIGHT "Copyright (C) 1994-1998 Tim Norman and others\0"
 #define REACTOS_STR_LEGAL_COPYRIGHT     "Copyright (C) 1998-2001 Eric Kohl and others\0"
 #include <reactos/version.rc>
+#include "En.rc"
+
+
 
 1      ICON    DISCARDABLE     res/terminal.ico
+
+
+
+
+
index 61cb290..a409149 100644 (file)
  *
  *    14-Oct-1999 (Paolo Pantaleo <paolopan@freemail.it>)
  *        4nt's syntax implemented
+ *
+ *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_COLOR
 
 
 static VOID ColorHelp (VOID)
 {
-               ConOutPuts (_T(
-                       "Sets the default foreground and background colors.\n"
-                       "\n"
-                       "COLOR [attr [/F]] \n\n"
-                       "  attr        Specifies color attribute of console output\n"
-                       "  /F          fill the console with color attribute\n"
-                       "\n"                    
-                       "There are three ways to specify the colors:"
-                       ));
-
-               ConOutPuts (_T(
-                       "\n"
-                       "1) [bright] name on [bright] name  (only the first three letters are required)\n"
-                       "2) decimal on decimal\n"
-                       "3) two hex digits\n"
-                       "\n"
-                       "Colors are:"
-                       ));
-
-               ConOutPuts (_T(
-                       "dec  hex  name       dec  hex  name\n"
-                       "0    0    Black       8   8    Gray(Bright black)\n"
-                       "1    1    Blue        9   9    Bright Blue\n"
-                       "2    2    Green      10   A    Bright Green\n"
-                       "3    3    Cyan       11   B    Bright Cyan\n"
-                       "4    4    Red        12   C    Bright Red\n"
-                       "5    5    Magenta    13   D    Bright Magenta\n"
-                       "6    6    Yellow     14   E    Bright Yellow\n"
-                       "7    7    White      15   F    Bright White"));
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+       LoadString( GetModuleHandle(NULL), STRING_COLOR_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
+
 }
 
 
@@ -62,10 +41,12 @@ VOID SetScreenColor (WORD wColor, BOOL bFill)
        DWORD dwWritten;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        COORD coPos;
+    WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if ((wColor & 0xF) == (wColor &0xF0) >> 4)
        {
-         ConErrPuts (_T("Same colors error! (Background and foreground can't be the same color)")); 
+         LoadString( GetModuleHandle(NULL), STRING_COLOR_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+      ConErrPuts (_T((LPTSTR)szMsg));
     }
     else 
     {
@@ -93,6 +74,8 @@ VOID SetScreenColor (WORD wColor, BOOL bFill)
  */
 INT CommandColor (LPTSTR first, LPTSTR rest)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        if (_tcsncmp (rest, _T("/?"), 2) == 0)
        {
                ColorHelp ();
@@ -109,15 +92,18 @@ INT CommandColor (LPTSTR first, LPTSTR rest)
 
        if (StringToColor (&wColor, &rest) == FALSE)
        {
-               ConErrPuts(_T("error in color specification"));
+               LoadString( GetModuleHandle(NULL), STRING_COLOR_ERROR2, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPuts (_T((LPTSTR)szMsg));
                return 1;
        }
 
-       ConErrPrintf (_T("Color %x\n"), wColor);
+       LoadString( GetModuleHandle(NULL), STRING_COLOR_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+    ConErrPrintf (_T((LPTSTR)szMsg), wColor);
 
        if ((wColor & 0xF) == (wColor &0xF0) >> 4)
        {
-               ConErrPuts (_T("same colors error!"));
+               LoadString( GetModuleHandle(NULL), STRING_COLOR_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg), wColor);              
                return 1;
        }
 
index 65f8dac..7f026b7 100644 (file)
 /* Define one of these to select the used locale. */
 /*  (date and time formats etc.) used in DATE, TIME, */
 /*  DIR, PROMPT etc. */
-#ifdef __REACTOS__
-#define LOCALE_DEFAULT
-#else
 #define LOCALE_WINDOWS   /* System locale */
 /* #define LOCALE_GERMAN */    /* German locale */
 /* #define LOCALE_DEFAULT */   /* United States locale */
-#endif
 
 #ifndef __REACTOS__
 #define INCLUDE_CMD_ACTIVATE
index 5d77e35..4c72ad4 100644 (file)
@@ -7,9 +7,13 @@
  *
  *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        started
+ *
+ *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 
 #define OUTPUT_BUFFER_SIZE  4096
@@ -210,6 +214,7 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
        DWORD ret;
        LPTSTR text;
        va_list arg_ptr;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
        
        va_start (arg_ptr, MessageId);
        ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
@@ -228,7 +233,8 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
        }
        else
        {
-               ConErrPrintf (_T("Unknown error: %d\n"), MessageId);
+               LoadString( GetModuleHandle(NULL), STRING_CONSOLE_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));
        }
 }
 
index 091b461..c7a7848 100644 (file)
  *
  *    27-Oct-1998 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Disabled prompting when used in batch mode.
+ *
+ *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_COPY
 
@@ -294,8 +298,17 @@ Overwrite (LPTSTR fn)
 {
        TCHAR inp[10];
        LPTSTR p;
+       
+       LPTSTR lpOptions;
+       TCHAR Options[3];
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
+    LoadString( GetModuleHandle(NULL), STRING_COPY_OPTION, (LPTSTR) Options,sizeof(Options)+sizeof(WCHAR));
+    lpOptions = _T(Options);
 
-       ConOutPrintf (_T("Overwrite %s (Yes/No/All)? "), fn);
+    LoadString( GetModuleHandle(NULL), STRING_COPY_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPrintf (_T((LPTSTR)szMsg));
+       
        ConInString (inp, 10);
        ConOutPuts (_T(""));
 
@@ -303,9 +316,9 @@ Overwrite (LPTSTR fn)
        for (p = inp; _istspace (*p); p++)
                ;
 
-       if (*p != _T('Y') && *p != _T('A'))
+       if (*p != lpOptions[0] && *p != lpOptions[2])
                return 0;
-       if (*p == _T('A'))
+       if (*p == lpOptions[2])
                return 2;
 
        return 1;
@@ -326,6 +339,7 @@ int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags)
        DWORD  dwWritten;
        DWORD  i;
        BOOL   bEof = FALSE;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
 #ifdef _DEBUG
        DebugPrintf (_T("checking mode\n"));
@@ -337,7 +351,8 @@ int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags)
                                                   NULL, OPEN_EXISTING, 0, NULL);
        if (hFileSrc == INVALID_HANDLE_VALUE)
        {
-               ConErrPrintf (_T("Error: Cannot open source - %s!\n"), source);
+                 LoadString( GetModuleHandle(NULL), STRING_COPY_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+          ConErrPrintf (_T((LPTSTR)szMsg), source);
                return 0;
        }
 
@@ -364,7 +379,9 @@ int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags)
        {
                if (!_tcscmp (dest, source))
                {
-                       ConErrPrintf (_T("Error: Can't copy onto itself!\n"));
+                       LoadString( GetModuleHandle(NULL), STRING_COPY_ERROR2, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg), source);
+                       
                        CloseHandle (hFileSrc);
                        return 0;
                }
@@ -438,7 +455,10 @@ int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags)
                WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
                if (dwWritten != dwRead)
                {
-                       ConErrPrintf (_T("Error writing destination!\n"));
+                       
+                       LoadString( GetModuleHandle(NULL), STRING_COPY_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+            ConErrPrintf (_T((LPTSTR)szMsg));
+
                        free (buffer);
                        CloseHandle (hFileDest);
                        CloseHandle (hFileSrc);
@@ -618,6 +638,7 @@ INT cmd_copy (LPTSTR first, LPTSTR rest)
        TCHAR dir_d[_MAX_DIR];
        TCHAR file_d[_MAX_FNAME];
        TCHAR ext_d[_MAX_EXT];
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        int argc;
        int append;
@@ -634,23 +655,8 @@ INT cmd_copy (LPTSTR first, LPTSTR rest)
 
        if (!_tcsncmp (rest, _T("/?"), 2))
        {
-               ConOutPuts (_T("Copies one or more files to another location.\n"
-                                          "\n"
-                                          "COPY [/V][/Y|/-Y][/A|/B] source [/A|/B]\n"
-                                          "     [+ source [/A|/B] [+ ...]] [destination [/A|/B]]\n"
-                                          "\n"
-                                          "  source       Specifies the file or files to be copied.\n"
-                                          "  /A           Indicates an ASCII text file.\n"
-                                          "  /B           Indicates a binary file.\n"
-                                          "  destination  Specifies the directory and/or filename for the new file(s).\n"
-                                          "  /V           Verifies that new files are written correctly.\n"
-                                          "  /Y           Suppresses prompting to confirm you want to overwrite an\n"
-                                          "               existing destination file.\n"
-                                          "  /-Y          Causes prompting to confirm you want to overwrite an\n"
-                                          "               existing destination file.\n"
-                                          "\n"
-                                          "The switch /Y may be present in the COPYCMD environment variable.\n"
-                                          "..."));
+               LoadString( GetModuleHandle(NULL), STRING_COPY_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 1;
        }
 
@@ -722,7 +728,9 @@ INT cmd_copy (LPTSTR first, LPTSTR rest)
        }
        else if (bDestFound && bWildcards)
        {
-               ConErrPrintf (_T("Error: Not implemented yet!\n"));
+               LoadString( GetModuleHandle(NULL), STRING_COPY_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPrintf (_T((LPTSTR)szMsg));
+
                DeleteFileList (sources);
                freep (p);
                return 0;
index 90b9d71..994614f 100644 (file)
  *
  *    04-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Fixed date input bug.
+ *
+ *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc  
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_DATE
 
@@ -43,22 +47,24 @@ static WORD awMonths[2][13] =
 static VOID
 PrintDateString (VOID)
 {
+  WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        switch (nDateFormat)
        {
                case 0: /* mmddyy */
                default:
-                       ConOutPrintf (_T("\nEnter new date (mm%cdd%cyyyy): "),
-                                       cDateSeparator, cDateSeparator);
+                       LoadString( GetModuleHandle(NULL), STRING_DATE_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+            ConOutPrintf (_T((LPTSTR)szMsg), cDateSeparator, cDateSeparator);
                        break;
 
                case 1: /* ddmmyy */
-                       ConOutPrintf (_T("\nEnter new date (dd%cmm%cyyyy): "),
-                                         cDateSeparator, cDateSeparator);
+                       LoadString( GetModuleHandle(NULL), STRING_DATE_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+            ConOutPrintf (_T((LPTSTR)szMsg), cDateSeparator, cDateSeparator);
                        break;
 
                case 2: /* yymmdd */
-                       ConOutPrintf (_T("\nEnter new date (yyyy%cmm%cdd): "),
-                                         cDateSeparator, cDateSeparator);
+                       LoadString( GetModuleHandle(NULL), STRING_DATE_HELP3, (LPTSTR) szMsg,sizeof(szMsg));
+            ConOutPrintf (_T((LPTSTR)szMsg), cDateSeparator, cDateSeparator);
                        break;
        }
 }
@@ -183,14 +189,12 @@ INT cmd_date (LPTSTR cmd, LPTSTR param)
        INT    i;
        BOOL   bPrompt = TRUE;
        INT    nDateString = -1;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Displays or sets the date.\n\n"
-                                  "DATE [/T][date]\n\n"
-                                  "  /T    display only\n\n"
-                                  "Type DATE without parameters to display the current date setting and\n"
-                                  "a prompt for a new one.  Press ENTER to keep the same date."));
+               LoadString( GetModuleHandle(NULL), STRING_DATE_HELP4, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
@@ -243,7 +247,9 @@ INT cmd_date (LPTSTR cmd, LPTSTR param)
                        freep (arg);
                        return 0;
                }
-               ConErrPuts (_T("Invalid date."));
+               LoadString( GetModuleHandle(NULL), STRING_DATE_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+        ConErrPuts (_T((LPTSTR)szMsg));
+               
        }
 
        freep (arg);
index 1483bb4..aed01ad 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_DEL
 
@@ -108,29 +109,30 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
        HANDLE hFile;
        WIN32_FIND_DATA f;
 
+       LPTSTR lpOptions;
+       TCHAR Options[11];
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+       LONG ch;
+       
+       
+
+       LoadString( GetModuleHandle(NULL), STRING_DEL_OPTION, (LPTSTR) Options,sizeof(Options)+sizeof(WCHAR));
+    lpOptions = _T(Options);
+
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Deletes one or more files.\n"
-                              "\n"
-                              "DEL [/N /P /T /Q /W /Y /Z] file ...\n"
-                              "DELETE [/N /P /T /Q /W /Y /Z] file ...\n"
-                              "ERASE [/N /P /T /Q /W /Y /Z] file ...\n"
-                              "\n"
-                              "  file  Specifies the file(s) to delete.\n"
-                              "\n"
-                              "  /N    Nothing.\n"
-                              "  /P    Prompt. Ask before deleting each file.\n"
-                              "  /T    Total. Display total number of deleted files and freed disk space.\n"
-                              "  /Q    Quiet.\n"
-                              "  /W    Wipe. Overwrite the file with random numbers before deleting it.\n"
-                              "  /Y    Yes. Kill even *.* without asking.\n"
-                              "  /Z    Zap. Delete hidden, read-only and system files).\n"));
-
+                LoadString( GetModuleHandle(NULL), STRING_DEL_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+         ConOutPrintf (_T((LPTSTR)szMsg),
+                                          lpOptions[2],Options[3],lpOptions[6],lpOptions[4],lpOptions[7],lpOptions[9],lpOptions[10],
+                       lpOptions[2],Options[3],lpOptions[6],lpOptions[4],lpOptions[7],lpOptions[9],lpOptions[10],
+                              lpOptions[2],Options[3],lpOptions[6],lpOptions[4],lpOptions[7],lpOptions[9],lpOptions[10],
+                       lpOptions[2],Options[3],lpOptions[6],lpOptions[4],lpOptions[7],lpOptions[9],lpOptions[10]                                          
+                                          );                   
                return 0;
        }
 
        arg = split (param, &args, FALSE);
-
+       
        if (args > 0)
        {
                /* check for options anywhere in command line */
@@ -140,38 +142,48 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                        {
                                if (_tcslen (arg[i]) >= 2)
                                {
-                                       switch (_totupper (arg[i][1]))
-                                       {
-                                               case _T('N'):
-                                                       dwFlags |= DEL_NOTHING;
-                                                       break;
-
-                                               case _T('P'):
-                                                       dwFlags |= DEL_PROMPT;
-                                                       break;
-
-                                               case _T('Q'):
-                                                       dwFlags |= DEL_QUIET;
-                                                       break;
-
-                                               case _T('S'):
-                                                       dwFlags |= DEL_SUBDIR;
-                                                       break;
-
-                                               case _T('T'):
-                                                       dwFlags |= DEL_TOTAL;
-                                                       break;
-
-                                               case _T('W'):
-                                                       dwFlags |= DEL_WIPE;
-                                                       break;
-                                               case _T('Y'):
-                                                       dwFlags |= DEL_YES;
-                                                       break;
-                                               case _T('Z'):
-                                                       dwFlags |= DEL_ZAP;
-                                                       break;
-                                       }
+                                       
+                                 ch =  _totupper (arg[i][1]);
+                                                                 
+                  if (_totupper (lpOptions[2]) == ch)
+                                    {
+                      dwFlags |= DEL_NOTHING;
+                                        }
+
+                                 else if (_totupper (lpOptions[3]) == ch)
+                                    {
+                     dwFlags |= DEL_PROMPT;
+                                        }
+                 
+                                 else if (_totupper (lpOptions[4]) == ch)
+                                    {
+                      dwFlags |= DEL_QUIET;
+                                        }
+
+                                 else if (_totupper (lpOptions[5]) == ch)
+                                    {
+                      dwFlags |= DEL_SUBDIR;
+                                        }
+
+                                 else if (_totupper (lpOptions[6]) == ch)
+                                    {
+                      dwFlags |= DEL_TOTAL;
+                                        }
+
+                                 else if (_totupper (lpOptions[7]) == ch)
+                                    {
+                      dwFlags |= DEL_WIPE;
+                                        }
+
+                  else if (_totupper (lpOptions[9]) == ch)
+                                    {
+                      dwFlags |= DEL_YES;
+                                        }
+
+                                 else if (_totupper (lpOptions[10]) == ch)
+                                    {
+                      dwFlags |= DEL_ZAP;
+                                        }                              
 
                                }
 
@@ -199,8 +211,10 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                        {
                                if (!((dwFlags & DEL_YES) || (dwFlags & DEL_QUIET) || (dwFlags & DEL_PROMPT)))
                                {
-                                       res = FilePromptYN (_T("All files in the directory will be deleted!\n"
-                                                              "Are you sure (Y/N)?"));
+                                       
+                                       LoadString( GetModuleHandle(NULL), STRING_DEL_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+
+                                       res = FilePromptYN (_T( (LPTSTR) szMsg));
 
                                        if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
                                                break;
@@ -217,7 +231,8 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                {
                                        /* wildcards in filespec */
 #ifdef _DEBUG
-                                       ConErrPrintf (_T("Wildcards!\n\n"));
+                                       LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR1, (LPTSTR) szMsg,sizeof(szMsg));
+                    ConErrPrintf (_T((LPTSTR)szMsg));
 #endif
 
                                        GetFullPathName (arg[i],
@@ -226,8 +241,12 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                                         &pFilePart);
 
 #ifdef _DEBUG
-                                       ConErrPrintf (_T("Full path: %s\n"), szFullPath);
-                                       ConErrPrintf (_T("File part: %s\n"), pFilePart);
+                                        LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR2, (LPTSTR) szMsg,sizeof(szMsg));
+                     ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);
+
+                                        LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+                     ConErrPrintf (_T((LPTSTR)szMsg), pFilePart);
+                                       
 #endif
 
                                        hFile = FindFirstFile (szFullPath, &f);
@@ -249,13 +268,18 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                                _tcscpy (pFilePart, f.cFileName);
 
 #ifdef _DEBUG
-                                               ConErrPrintf (_T("Full filename: %s\n"), szFullPath);
+                                               LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR4, (LPTSTR) szMsg,sizeof(szMsg));
+                        ConErrPrintf (_T((LPTSTR)szMsg));
+
 #endif
                                                /* ask for deleting */
                                                if (dwFlags & DEL_PROMPT) 
-                                               {
-                                                       ConErrPrintf (_T("The file %s will be deleted! "), szFullPath);
-                                                       res = FilePromptYN (_T("Are you sure (Y/N)?"));
+                                               {                                                       
+                                                       LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR5, (LPTSTR) szMsg,sizeof(szMsg));
+                            ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);
+                                                       
+                                                       LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR6, (LPTSTR) szMsg,sizeof(szMsg));
+                                                       res = FilePromptYN (_T((LPTSTR)szMsg));
 
                                                        if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
                                                        {
@@ -264,7 +288,10 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                                }
 
                                                if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL))
-                                                       ConErrPrintf (_T("Deleting: %s\n"), szFullPath);
+                                                   {
+                                                        LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR7, (LPTSTR) szMsg,sizeof(szMsg));
+                             ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);                                                             
+                                                       }
 
                                                /* delete the file */
                                                if (!(dwFlags & DEL_NOTHING))
@@ -307,7 +334,8 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                {
                                        /* no wildcards in filespec */
 #ifdef _DEBUG
-                                       ConErrPrintf (_T("No Wildcards!\n"));
+                                       LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR8, (LPTSTR) szMsg,sizeof(szMsg));
+                    ConErrPrintf (_T((LPTSTR)szMsg));
 #endif
                                        GetFullPathName (arg[i],
                                                         MAX_PATH,
@@ -317,8 +345,11 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                        /*ask for deleting */
                                        if((dwFlags & DEL_PROMPT) && (FindFirstFile(szFullPath, &f) != INVALID_HANDLE_VALUE)) //Don't ask if the file doesn't exist, the following code will make the error-msg 
                                        {
-                                               ConErrPrintf (_T("The file %s will be deleted! "), szFullPath);
-                                               res = FilePromptYN (_T("Are you sure (Y/N)?"));
+                                               LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR5, (LPTSTR) szMsg,sizeof(szMsg));
+                        ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);
+                                               
+                                               LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR6, (LPTSTR) szMsg,sizeof(szMsg));
+                                               res = FilePromptYN (_T((LPTSTR)szMsg));
 
                                                if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
                                                {
@@ -327,10 +358,14 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
                                        }
 
 #ifdef _DEBUG
-                                       ConErrPrintf (_T("Full path: %s\n"), szFullPath);
+                                       LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR3, (LPTSTR) szMsg,sizeof(szMsg));
+                    ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);
 #endif
                                        if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL))
-                                               ConOutPrintf (_T("Deleting %s\n"), szFullPath);
+                                          {
+                                            LoadString( GetModuleHandle(NULL), STRING_DEL_ERROR7, (LPTSTR) szMsg,sizeof(szMsg));
+                         ConErrPrintf (_T((LPTSTR)szMsg), szFullPath);
+                                           }
 
                                        if (!(dwFlags & DEL_NOTHING))
                                        {
@@ -380,12 +415,16 @@ INT CommandDelete (LPTSTR cmd, LPTSTR param)
 
        if (!(dwFlags & DEL_QUIET))
        {
-               if (dwFiles == 0)
-                       ConOutPrintf (_T("    0 files deleted\n"));
+               if (dwFiles < 2)
+                  {
+                   LoadString( GetModuleHandle(NULL), STRING_DEL_HELP3, (LPTSTR) szMsg,sizeof(szMsg));
+                  }
                else
-                       ConOutPrintf (_T("    %lu file%s deleted\n"),
-                                     dwFiles,
-                                     (dwFiles == 1) ? _T("") : _T("s"));
+                  {
+             LoadString( GetModuleHandle(NULL), STRING_DEL_HELP4, (LPTSTR) szMsg,sizeof(szMsg));
+                  }
+               
+          ConOutPrintf (_T((LPTSTR)szMsg), dwFiles);                   
        }
 
        return 0;
index 241baa9..6848f29 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_DELAY
 
@@ -18,17 +19,14 @@ INT CommandDelay (LPTSTR cmd, LPTSTR param)
 {
        DWORD val;
        DWORD mul=1000;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (_tcsncmp (param, _T("/?"), 2) == 0)
        {
-               ConOutPuts(_T(
-                             "pause for n seconds or milliseconds"
-                             "\n"
-                             "DELAY [/m]n\n"
-                             "\n"
-                             "  /m          specifiy than n are milliseconds\n"
-                             "              otherwise n are seconds"));
-               return 0;
+         LoadString( GetModuleHandle(NULL), STRING_DELAY_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+      ConOutPuts (_T((LPTSTR)szMsg));
+       
+         return 0;
        }
 
        if (*param==0)
index 31e8b4e..84fd529 100644 (file)
  *
  *    30-Apr-2004 (Filip Navara <xnavara@volny.cz>)
  *        Fix /w to print long names.
+ *
+ *    27-Feb-2005 (Konstantinos Paliouras <squarious@gmail.com>)
+ *        Implemented all the switches that were missing, and made
+ *        the ros dir very similar to windows dir. Major part of
+ *        the code is rewritten. /p is removed, to be rewriten in
+ *        the main cmd code.
+ *        
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_DIR
 
 
-/* flag definitions */
-enum
+
+/* Time Field enumeration */
+enum ETimeField
 {
-       DIR_RECURSE = 0x0001,
-       DIR_PAGE    = 0x0002,
-       DIR_WIDE    = 0x0004,        /* Rob Lake */
-       DIR_BARE    = 0x0008,        /* Rob Lake */
-       DIR_ALL     = 0x0010,        /* Rob Lake */
-       DIR_LWR     = 0x0020,        /* Rob Lake */
-       DIR_SORT    = 0x0040,        /* /O sort */
-       DIR_NEW     = 0x0080,        /* /N new style */
-       DIR_FOUR    = 0x0100         /* /4 four digit year */
+       TF_CREATIONDATE         = 0,
+       TF_MODIFIEDDATE         = 1,
+       TF_LASTACCESSEDDATE     = 2
 };
 
+/* Ordered by enumeration */
+enum EOrderBy
+{
+       ORDER_NAME              = 0,
+       ORDER_SIZE              = 1,
+       ORDER_DIRECTORY = 2,
+       ORDER_EXTENSION = 3,
+       ORDER_TIME              = 4
+};
+
+/* The struct for holding the switches */
+typedef struct TDirSwitchesFlags
+{
+       BOOL bBareFormat;       /* Bare Format */
+       BOOL bTSeperator;       /* Thousands seperator */
+       BOOL bWideList;         /* Wide list format     */
+       BOOL bWideListColSort;  /* Wide list format but sorted by column */
+       BOOL bLowerCase;        /* Uses lower case */
+       BOOL bNewLongList;      /* New long list */
+       BOOL bPause;            /* Pause per page */
+       BOOL bUser;                     /* Displays the owner of file */
+       BOOL bRecursive;        /* Displays files in specified directory and all sub */
+       BOOL bShortName;        /* Displays the sort name of files if exist     */
+       BOOL b4Digit;           /* Four digit year      */
+       struct
+       {
+               DWORD dwAttribVal;      /* The desired state of attribute */
+               DWORD dwAttribMask;     /* Which attributes to check */
+               BOOL bUnSet;            /* A helper flag if "-" was given with the switch */
+               BOOL bParSetted;        /* A helper flag if parameters of switch were given */
+       } stAttribs;            /* Displays files with this attributes only */
+       struct
+       {
+               enum EOrderBy eCriteria[3];     /* Criterias used to order by */
+               BOOL bCriteriaRev[3];           /* If the criteria is in reversed order */
+               short sCriteriaCount;           /* The quantity of criterias */
+               BOOL bUnSet;                            /* A helper flag if "-" was given with the switch */
+               BOOL bParSetted;                        /* A helper flag if parameters of switch were given */
+       } stOrderBy;            /* Ordered by criterias */
+       struct
+       {
+               enum ETimeField eTimeField;     /* The time field that will be used for */
+               BOOL bUnSet;                            /* A helper flag if "-" was given with the switch */
+               BOOL bParSetted;                        /* A helper flag if parameters of switch were given */
+       } stTimeField;          /* The time field to display or use for sorting */
+}DIRSWITCHFLAGS, * LPDIRSWITCHFLAGS;
 
 typedef BOOL STDCALL
 (*PGETFREEDISKSPACEEX)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
@@ -158,177 +207,347 @@ static ULARGE_INTEGER recurse_bytes;
  * displays help screen for dir
  * Rob Lake
  */
-static VOID Help (VOID)
+static VOID
+       DirHelp (VOID)
 {
-  ConOutPuts(_T("Displays a list of files and subdirectories in a directory.\n"
-       "\n"
-       "DIR [drive:][path][filename] [/A] [/B] [/L] [/N] [/S] [/P] [/W] [/4]\n"
-       "\n"
-       "  [drive:][path][filename]\n"
-       "              Specifies drive, directory, and/or files to list.\n"
-       "\n"
-       "  /A          Displays files with HIDDEN SYSTEM attributes\n"
-       "              default is ARCHIVE and READ ONLY\n"
-       "  /B          Uses bare format (no heading information or summary).\n"
-       "  /L          Uses lowercase.\n"
-       "  /N          New long list format where filenames are on the far right.\n"
-       "  /S          Displays files in specified directory and all subdirectories\n"
-       "  /P          Pauses after each screen full\n"
-       "  /W          Prints in wide format\n"
-       "  /4          Display four digit years.\n"
-       "\n"
-       "Switches may be present in the DIRCMD environment variable.  Use\n"
-       "of the - (hyphen) can turn off defined swtiches.  Ex. /-W would\n"
-       "turn off printing in wide format.\n"
-      ));
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+       LoadString( GetModuleHandle(NULL), STRING_DIR_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPuts (_T((LPTSTR)szMsg));
 }
 
 
+
 /*
- * DirReadParam
+ * DirReadParameters
  *
- * read the parameters from the command line
+ * Parse the parameters and switches of the command line and exports them
  */
-static BOOL
-DirReadParam (LPTSTR line, LPTSTR *param, LPDWORD lpFlags)
+static BOOL 
+DirReadParam (LPTSTR line,                             /* [IN] The line with the parameters & switches */
+                         LPTSTR *param,                        /* [OUT] The parameters after parsing */
+                         LPDIRSWITCHFLAGS lpFlags      /* [IN/OUT] The flags after calculating switches */
+                         )
 {
-       INT slash = 0;
-
-       if (!line)
-               return TRUE;
-
+TCHAR cCurSwitch;      /* The current switch */
+TCHAR cCurChar;                /* Current examing character */
+TCHAR cCurUChar;       /* Current upper examing character */
+BOOL bNegative;                /* Negative switch */
+BOOL bPNegative;       /* Negative switch parameter */
+BOOL bIntoQuotes;      /* A flag showing if we are in quotes (") */
+LPTSTR ptrLast;                /* A pointer to the last character of param */
+
+       /* Initialize variables; */
+       cCurSwitch = _T(' ');
+       bNegative = FALSE;
+       bPNegative = FALSE;
+       bIntoQuotes = FALSE;
+
+       /* No parameters yet  */
        *param = NULL;
-
-       /* scan the command line, processing switches */
+       ptrLast = NULL;
+       
+       /* We suppose that switch parameters
+          were given to avoid setting them to default
+          if the switch was not given */
+       lpFlags->stAttribs.bParSetted = TRUE;
+       lpFlags->stOrderBy.bParSetted = TRUE;
+       lpFlags->stTimeField.bParSetted = TRUE;
+
+       /* Main Loop (see README_DIR.txt) */
+       /* scan the command line char per char, and we process its char */
        while (*line)
        {
-               /* process switch */
-               if (*line == _T('/') || slash)
+               /* we save current character as it is and its upper case */
+               cCurChar = *line;
+               cCurUChar = _toupper(*line);
+               
+               /* 1st section (see README_DIR.txt) */
+               /* When a switch is expecting */
+               if (cCurSwitch == _T('/'))
                {
-                       if (!slash)
-                               line++;
-                       slash = 0;
-                       if (*line == _T('-'))
-                       {
-                               line++;
-                               if (_totupper (*line) == _T('S'))
-                                       *lpFlags &= ~DIR_RECURSE;
-                               else if (_totupper (*line) == _T('P'))
-                                       *lpFlags &= ~DIR_PAGE;
-                               else if (_totupper (*line) == _T('W'))
-                                       *lpFlags &= ~DIR_WIDE;
-                               else if (_totupper (*line) == _T('B'))
-                                       *lpFlags &= ~DIR_BARE;
-                               else if (_totupper (*line) == _T('A'))
-                                       *lpFlags &= ~DIR_ALL;
-                               else if (_totupper (*line) == _T('L'))
-                                       *lpFlags &= ~DIR_LWR;
-                               else if (_totupper (*line) == _T('N'))
-                                       *lpFlags &= ~DIR_NEW;
-                               else if (_totupper (*line) == _T('O'))
-                                       *lpFlags &= ~DIR_SORT;
-                               else if (_totupper (*line) == _T('4'))
-                                       *lpFlags &= ~DIR_FOUR;
-                               else
+                       if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O')))
+                       {                       
+                               cCurSwitch = cCurUChar;
+                               switch (cCurUChar)
                                {
-                                       error_invalid_switch ((TCHAR)_totupper (*line));
-                                       return FALSE;
+                               case _T('A'):
+                                       lpFlags->stAttribs.bUnSet = bNegative;
+                                       lpFlags->stAttribs.bParSetted = FALSE;
+                                       break;
+                               case _T('T'):
+                                       lpFlags->stTimeField.bUnSet = bNegative;
+                                       lpFlags->stTimeField.bParSetted = FALSE;
+                                       break;
+                               case _T('O'):
+                                       lpFlags->stOrderBy.bUnSet = bNegative;
+                                       lpFlags->stOrderBy.bParSetted = FALSE;
+                                       break;
                                }
-                               line++;
-                               continue;
                        }
-                       else
+                       else if (cCurUChar ==  _T('L'))
+                               lpFlags->bLowerCase = ! bNegative;
+                       else if (cCurUChar ==  _T('B'))                 
+                               lpFlags->bBareFormat = ! bNegative;
+                       else if (cCurUChar ==  _T('C'))
+                               lpFlags->bTSeperator = ! bNegative;
+                       else if (cCurUChar ==  _T('W'))
+                               lpFlags->bWideList = ! bNegative;                               
+                       else if (cCurUChar ==  _T('D'))
+                               lpFlags->bWideListColSort = ! bNegative;                                
+                       else if (cCurUChar ==  _T('N'))
+                               lpFlags->bNewLongList = ! bNegative;
+                       else if (cCurUChar ==  _T('P'))
+                               lpFlags->bPause = ! bNegative;
+                       else if (cCurUChar ==  _T('Q'))
+                               lpFlags->bUser = ! bNegative;
+                       else if (cCurUChar ==  _T('S'))
+                               lpFlags->bRecursive = ! bNegative;
+                       else if (cCurUChar ==  _T('X'))
+                               lpFlags->bShortName = ! bNegative;
+                       else if (cCurChar == _T('4'))
+                               lpFlags->b4Digit = ! bNegative;
+                       else if (cCurChar ==  _T('?'))
                        {
-                               if (_totupper (*line) == _T('S'))
-                                       *lpFlags |= DIR_RECURSE;
-                               else if (_totupper (*line) == _T('P'))
-                                       *lpFlags |= DIR_PAGE;
-                               else if (_totupper (*line) == _T('W'))
-                                       *lpFlags |= DIR_WIDE;
-                               else if (_totupper (*line) == _T('B'))
-                                       *lpFlags |= DIR_BARE;
-                               else if (_totupper (*line) == _T('A'))
-                                       *lpFlags |= DIR_ALL;
-                               else if (_totupper (*line) == _T('L'))
-                                       *lpFlags |= DIR_LWR;
-                               else if (_totupper (*line) == _T('N'))
-                                       *lpFlags |= DIR_NEW;
-                               else if (_totupper (*line) == _T('O'))
-                                       *lpFlags |= DIR_SORT;
-                               else if (_totupper (*line) == _T('4'))
-                                       *lpFlags |= DIR_FOUR;
-                               else if (*line == _T('?'))
-                               {
-                                       Help();
-                                       return FALSE;
-                               }
-                               else
-                               {
-                                       error_invalid_switch ((TCHAR)_totupper (*line));
-                                       return FALSE;
-                               }
-                               line++;
-                               continue;
+                               DirHelp();
+                               return FALSE;                
                        }
-               }
-
-               /* process parameter */
-               if (!_istspace (*line))
-               {
-                       if (*param)
+                       else if (cCurChar ==  _T('-'))
+                               bNegative = TRUE;
+                       else 
                        {
-                               error_too_many_parameters (line);
+                               error_invalid_switch ((TCHAR)_totupper (*line));
                                return FALSE;
                        }
 
-                       *param = line;
+                       /* We check if we calculated the negative value and realese the flag */
+                       if ((cCurChar != _T('-')) && bNegative)
+                               bNegative = FALSE;
 
-                       /* skip to end of line or next whitespace or next / */
-                       if (*line != _T('\"'))
-                       {
-                               while (*line && !_istspace (*line) && *line != _T('/'))
-                                       line++;
+                       /* if not a,o,t or - option then next parameter is not a switch */
+                       if ((cCurSwitch == _T('/')) && (!bNegative))
+                               cCurSwitch = _T(' ');
+
+               }
+               /* 2nd section (see README_DIR.txt) */
+               /* We are expecting parameter or the unknown */
+               else if ((cCurSwitch == _T(' ')) || (cCurSwitch == _T('P')))
+               {
+                       if (cCurChar == _T('/'))
+                               cCurSwitch = _T('/');
 
-                               /* if end of line, return */
-                               if (!*line)
-                                       return TRUE;
+                       /* Process a spacer */
+                       else if (cCurChar == _T(' '))
+                       {
+                               if (!bIntoQuotes)
+                               {
+                                       cCurSwitch = _T(' ');
+                                       if ((*param) && !(ptrLast))
+                                               ptrLast = line;
+                               }                               
+                                       
                        }
-                       else
+                       /* Process a quote */
+                       else if (cCurChar == _T('\"'))
                        {
-                               /* skip over the initial quote */
-                               (*param)++;
-                               line++;
+                               bIntoQuotes = !bIntoQuotes;
+                               if (!bIntoQuotes) ptrLast = line;
+                       }
+                       /* Process a character for parameter */
+                       else                    
+                       {
+                               if ((cCurSwitch == _T(' ')) && (*param))
+                               {
+                                       error_too_many_parameters(line);
+                                       return FALSE;
+                               }
+                               cCurSwitch = _T('P');
+                               if (!(*param))
+                                       *param = line;
+                       }
 
-                               while (*line && *line != _T('"'))
-                                       line++;
+               }
+               /* 3rd section (see README_DIR.txt) */
+               /* We are waiting for switch parameters */
+               else
+               {
+                       /* Check if there are no more switch parameters */
+                       if ((cCurChar == _T('/')) || ( cCurChar == _T(' ')))
+                       {
+                               /* Wrong desicion path, reprocess current character */
+                               cCurSwitch = cCurChar;
+                               continue;
+                       }
+                       /* Process parameter switch */
+                       switch(cCurSwitch)
+                       {
+                       case _T('A'):   /* Switch parameters for /A (attributes filter) */
+                               /* Ok a switch parameter was given */
+                               lpFlags->stAttribs.bParSetted = TRUE;
+
+                               if (cCurChar == _T(':'))
+                                       /* =V= dead command, used to make the "if" work */
+                                       cCurChar = cCurChar;
+                               else if(cCurChar == _T('-'))
+                                       bPNegative = TRUE;
+                               else if(cCurUChar == _T('D'))
+                               {
+                                       lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_DIRECTORY;
+                                       if (bPNegative)
+                                               lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_DIRECTORY;
+                                       else
+                                               lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_DIRECTORY;
+                               }
+                               else if(cCurUChar == _T('R'))
+                               {
+                                       lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_READONLY;
+                                       if (bPNegative)
+                                               lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_READONLY;
+                                       else
+                                               lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_READONLY;
+                               }
+                               else if(cCurUChar == _T('H'))
+                               {
+                                       lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_HIDDEN;
+                                       if (bPNegative)
+                                               lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_HIDDEN;
+                                       else
+                                               lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_HIDDEN;
+                               }
+                               else if(cCurUChar == _T('A'))
+                               {
+                                       lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_ARCHIVE;
+                                       if (bPNegative)
+                                               lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_ARCHIVE;
+                                       else
+                                               lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_ARCHIVE;
+                               }
+                               else if(cCurUChar == _T('S'))
+                               {
+                                       lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_SYSTEM;
+                                       if (bPNegative)
+                                               lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_SYSTEM;
+                                       else
+                                               lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_SYSTEM;
+                               }
+                               else
+                               {
+                                       error_parameter_format((TCHAR)_totupper (*line));
+                                       return FALSE;
+                               }
+                               break;
+                       case _T('T'):   /* Switch parameters for /T (time field) */
+
+                               /* Ok a switch parameter was given */
+                               lpFlags->stTimeField.bParSetted = TRUE;
+
+                               if (cCurChar == _T(':'))
+                                       /* =V= dead command, used to make the "if" work */
+                                       cCurChar = cCurChar;
+                               else if(cCurUChar == _T('C'))
+                                       lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ;
+                               else if(cCurUChar == _T('A'))
+                                       lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ;
+                               else if(cCurUChar == _T('W'))
+                                       lpFlags->stTimeField.eTimeField= TF_MODIFIEDDATE  ;
+                               else
+                               {
+                                       error_parameter_format((TCHAR)_totupper (*line));
+                                       return FALSE;
+                               }
+                               break;
+                       case _T('O'):   /* Switch parameters for /O (order) */
+                               /* Ok a switch parameter was given */
+                               lpFlags->stOrderBy.bParSetted = TRUE;
+
+                               if (cCurChar == _T(':'))
+                                       /* <== dead command, used to make the "if" work */
+                                       cCurChar = cCurChar;
+                               else if(cCurChar == _T('-'))
+                                       bPNegative = TRUE;
+                               else if(cCurUChar == _T('N'))
+                               {
+                                       if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
+                                       lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
+                                       lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_NAME;
+                               }
+                               else if(cCurUChar == _T('S'))
+                               {
+                                       if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
+                                       lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
+                                       lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_SIZE;
+                               }
+                               else if(cCurUChar == _T('G'))
+                               {
+                                       if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
+                                       lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
+                                       lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_DIRECTORY;
+                               }
+                               else if(cCurUChar == _T('E'))
+                               {
+                                       if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
+                                       lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
+                                       lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_EXTENSION;
+                               }
+                               else if(cCurUChar == _T('D'))
+                               {
+                                       if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
+                                       lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
+                                       lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_TIME;
+                               }
 
-                               if (*line == _T('"'))
-                                       *line = 0;
                                else
-                                       return TRUE;
-                       }
+                               {
+                                       error_parameter_format((TCHAR)_totupper (*line));
+                                       return FALSE;
+                               }
 
-                       /* if parameter, remember to process it later */
-                       if (*line == _T('/'))
-                               slash = 1;
 
-                       *line++ = 0;
-                       continue;
+                       }
+                       /* We check if we calculated the negative value and realese the flag */
+                       if ((cCurChar != _T('-')) && bPNegative)
+                               bPNegative = FALSE;
                }
-
+       
                line++;
        }
+       /* Terminate the parameters */
+       if (ptrLast) *ptrLast = 0;
 
-       if (slash)
+       /* Calculate the switches with no switch paramater  */
+       if (!(lpFlags->stAttribs.bParSetted))
        {
-               error_invalid_switch ((TCHAR)_totupper (*line));
-               return FALSE;
+               lpFlags->stAttribs.dwAttribVal = 0L;
+               lpFlags->stAttribs.dwAttribMask = lpFlags->stAttribs.dwAttribVal;
+       }
+       if (!(lpFlags->stOrderBy.bParSetted))
+       {
+               lpFlags->stOrderBy.sCriteriaCount = 1;
+               lpFlags->stOrderBy.eCriteria[0] = ORDER_NAME;
+               lpFlags->stOrderBy.bCriteriaRev[0] = FALSE;
        }
+       if (!(lpFlags->stOrderBy.bParSetted))
+               lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE ;
 
+       /* Calculate the unsetted switches (the "-" prefixed)*/
+       if (lpFlags->stAttribs.bUnSet)
+       {
+               lpFlags->stAttribs.bUnSet = FALSE;
+               lpFlags->stAttribs.dwAttribVal = 0L;
+               lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
+       }
+       if (lpFlags->stOrderBy.bUnSet)
+       {
+               lpFlags->stOrderBy.bUnSet = FALSE;
+               lpFlags->stOrderBy.sCriteriaCount = 0;
+       }
+       if (lpFlags->stTimeField.bUnSet )
+       {
+               lpFlags->stTimeField.bUnSet = FALSE;
+               lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE;
+       }
        return TRUE;
 }
 
-
 /*
  * ExtendFilespec
  *
@@ -507,9 +726,9 @@ DirParsePathspec (LPTSTR szPathspec, LPTSTR szPath, LPTSTR szFilespec)
  * incline
  *
  * increment our line if paginating, display message at end of screen
- */
+ *//*Maybe needed in future
 static BOOL
-IncLine (LPINT pLine, DWORD dwFlags)
+IncLine (LPINT pLine, LPDIRSWITCHFLAGS lpFlags)
 {
        BOOL error;
        CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo;
@@ -518,16 +737,21 @@ IncLine (LPINT pLine, DWORD dwFlags)
        
        WindowHeight= lpConsoleScreenBufferInfo.srWindow.Bottom - lpConsoleScreenBufferInfo.srWindow.Top;
 
-       if (!WindowHeight)  //That prevents bad behave if WindowHeight couln't calc
+       //That prevents bad behave if WindowHeight couln't calc 
+       if (!WindowHeight)  
        {
                 WindowHeight= 1000000;
        }
-       if (!(dwFlags & DIR_PAGE))
+       if (!(lpFlags->bPause))
                return FALSE;
 
        (*pLine)++;
 
-       if (*pLine >= (int)maxy - 2 || *pLine >= WindowHeight) //Because I don't know if WindowsHeight work under all cases, perhaps then maxy is the right value
+       // Because I don't know if WindowsHeight
+          work under all cases, perhaps then maxy
+          is the right value 
+   
+       if (*pLine >= (int)maxy - 2 || *pLine >= WindowHeight) 
        {
                *pLine = 0;
                return (PagePrompt () == PROMPT_BREAK);
@@ -535,7 +759,7 @@ IncLine (LPINT pLine, DWORD dwFlags)
 
        return FALSE;
 }
-
+*/
 
 /*
  * PrintDirectoryHeader
@@ -543,14 +767,15 @@ IncLine (LPINT pLine, DWORD dwFlags)
  * print the header for the dir command
  */
 static BOOL
-PrintDirectoryHeader (LPTSTR szPath, LPINT pLine, DWORD dwFlags)
+PrintDirectoryHeader (LPTSTR szPath, LPINT pLine, LPDIRSWITCHFLAGS lpFlags)
 {
   TCHAR szRootName[MAX_PATH];
   TCHAR szVolName[80];
   DWORD dwSerialNr;
   LPTSTR p;
+  WCHAR szMsg[RC_STRING_MAX_SIZE];
 
-  if (dwFlags & DIR_BARE)
+  if (lpFlags->bBareFormat)
     return(TRUE);
 
   /* build usable root path */
@@ -600,22 +825,27 @@ PrintDirectoryHeader (LPTSTR szPath, LPINT pLine, DWORD dwFlags)
     }
 
   /* print drive info */
-  ConOutPrintf(_T(" Volume in drive %c"), szRootName[0]);
-
+   
   if (szVolName[0] != _T('\0'))
-    ConOutPrintf(_T(" is %s\n"), szVolName);
+     {
+         LoadString( GetModuleHandle(NULL), STRING_DIR_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+      ConOutPrintf (_T((LPTSTR)szMsg), szRootName[0], szVolName);
+        }
   else
-    ConOutPrintf(_T(" has no label\n"));
+     {
+         LoadString( GetModuleHandle(NULL), STRING_DIR_HELP3, (LPTSTR) szMsg,sizeof(szMsg));
+      ConOutPrintf (_T((LPTSTR)szMsg), szRootName[0]);
+        }
+
+  
 
-  if (IncLine(pLine, dwFlags))
-    return(FALSE);
 
   /* print the volume serial number if the return was successful */
-  ConOutPrintf(_T(" Volume Serial Number is %04X-%04X\n"),
-              HIWORD(dwSerialNr),
-              LOWORD(dwSerialNr));
-  if (IncLine(pLine, dwFlags))
-    return(FALSE);
+        
+  LoadString( GetModuleHandle(NULL), STRING_DIR_HELP4, (LPTSTR) szMsg,sizeof(szMsg));
+  ConOutPrintf (_T((LPTSTR)szMsg),
+                   HIWORD(dwSerialNr),
+                   LOWORD(dwSerialNr));
 
   return(TRUE);
 }
@@ -625,7 +855,7 @@ PrintDirectoryHeader (LPTSTR szPath, LPINT pLine, DWORD dwFlags)
  * convert
  *
  * insert commas into a number
- */
+ *//* Maybe needed in future
 static INT
 ConvertULong (ULONG num, LPTSTR des, INT len)
 {
@@ -656,10 +886,10 @@ ConvertULong (ULONG num, LPTSTR des, INT len)
 
        return n;
 }
-
+*/
 
 static INT
-ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len)
+ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len, BOOL bPutSeperator)
 {
        TCHAR temp[32];
        INT c = 0;
@@ -676,7 +906,7 @@ ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len)
                temp[31] = 0;
                while (num.QuadPart > 0)
                {
-                       if (((c + 1) % (nNumberGroups + 1)) == 0)
+                       if ((((c + 1) % (nNumberGroups + 1)) == 0) && (bPutSeperator))
                                temp[30 - c++] = cThousandSeparator;
                        temp[30 - c++] = (TCHAR)(num.QuadPart % 10) + _T('0');
                        num.QuadPart /= 10;
@@ -691,44 +921,80 @@ ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len)
 
 
 static VOID
-PrintFileDateTime (LPSYSTEMTIME dt, DWORD dwFlags)
+DirPrintFileDateTime (TCHAR * lpDate,
+                                         TCHAR * lpTime,
+                                         LPWIN32_FIND_DATA lpFile,
+                                         LPDIRSWITCHFLAGS lpFlags)
 {
-       WORD wYear = (dwFlags & DIR_FOUR) ? dt->wYear : dt->wYear%100;
+FILETIME ft;
+SYSTEMTIME dt;
+TCHAR szDate[30];
+TCHAR szTime[30];
+WORD wYear;
+
+       /* Select the right time field */
+       switch (lpFlags->stTimeField.eTimeField)
+       {
+       case TF_CREATIONDATE:
+               if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft))
+                       return;
+               FileTimeToSystemTime(&ft, &dt);         
+               break;
+       case TF_LASTACCESSEDDATE :
+               if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft))
+                       return;
+               FileTimeToSystemTime(&ft, &dt);         
+               break;
+       case TF_MODIFIEDDATE:
+               if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft))
+                       return;
+               FileTimeToSystemTime(&ft, &dt);         
+               break;
+       }
 
+       /* Format date */
+       wYear = (lpFlags->b4Digit) ? dt.wYear : dt.wYear%100;
        switch (nDateFormat)
        {
                case 0: /* mmddyy */
                default:
-                       ConOutPrintf (_T("%.2d%c%.2d%c%d"),
-                                       dt->wMonth, cDateSeparator, dt->wDay, cDateSeparator, wYear);
+                       _stprintf (szDate,_T("%02d%c%02d%c%0*d"),
+                                       dt.wMonth, cDateSeparator,
+                                       dt.wDay, cDateSeparator,
+                                       lpFlags->b4Digit?4:2, wYear);
                        break;
 
                case 1: /* ddmmyy */
-                       ConOutPrintf (_T("%.2d%c%.2d%c%d"),
-                                       dt->wDay, cDateSeparator, dt->wMonth, cDateSeparator, wYear);
+                       _stprintf (szDate, _T("%02d%c%02d%c%0*d"),
+                                       dt.wDay, cDateSeparator, dt.wMonth,
+                                       cDateSeparator,lpFlags->b4Digit?4:2, wYear);
                        break;
 
                case 2: /* yymmdd */
-                       ConOutPrintf (_T("%d%c%.2d%c%.2d"),
-                                       wYear, cDateSeparator, dt->wMonth, cDateSeparator, dt->wDay);
+                       _stprintf (szDate, _T("%0*d%c%02d%c%02d"),
+                                       lpFlags->b4Digit?4:2, wYear, cDateSeparator,
+                                       dt.wMonth, cDateSeparator, dt.wDay);
                        break;
        }
-
+       /* Format Time */
        switch (nTimeFormat)
        {
                case 0: /* 12 hour format */
                default:
-                       ConOutPrintf (_T("  %2d%c%.2u%c"),
-                                       (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)),
+                       _stprintf (szTime,_T("  %02d%c%02u%c"),
+                                       (dt.wHour == 0 ? 12 : (dt.wHour <= 12 ? dt.wHour : dt.wHour - 12)),
                                        cTimeSeparator,
-                                        dt->wMinute, (dt->wHour <= 11 ? 'a' : 'p'));
+                                        dt.wMinute, (dt.wHour <= 11 ? 'a' : 'p'));
                        break;
 
                case 1: /* 24 hour format */
-                       ConOutPrintf (_T("  %2d%c%.2u"),
-                                       dt->wHour, cTimeSeparator, dt->wMinute);
+                       _stprintf (szTime, _T("  %02d%c%02u"),
+                                       dt.wHour, cTimeSeparator, dt.wMinute);
                        break;
        }
+       /* Copy results */
+       _tcscpy(lpDate, szDate);
+       _tcscpy(lpTime, szTime);
 }
 
 
@@ -783,457 +1049,739 @@ static INT
 PrintSummary(LPTSTR szPath,
             ULONG ulFiles,
             ULONG ulDirs,
-            ULARGE_INTEGER bytes,
+            ULARGE_INTEGER u64Bytes,
             LPINT pLine,
-            DWORD dwFlags)
+            LPDIRSWITCHFLAGS lpFlags)
 {
-  TCHAR buffer[64];
-  ULARGE_INTEGER uliFree;
-  TCHAR szRoot[] = _T("A:\\");
-
-  if (dwFlags & DIR_BARE)
-    return(0);
+TCHAR szBuffer[64];
+ULARGE_INTEGER uliFree;
+TCHAR szRoot[] = _T("A:\\");
+WCHAR szMsg[RC_STRING_MAX_SIZE];
 
-  /* Print number of files and bytes */
-  ConvertULong (ulFiles, buffer, sizeof(buffer));
-  ConOutPrintf (_T("          %6s File%c"),
-                buffer, ulFiles == 1 ? _T(' ') : _T('s'));
 
-  ConvertULargeInteger (bytes, buffer, sizeof(buffer));
-  ConOutPrintf (_T("  %15s byte%c\n"),
-                buffer, bytes.QuadPart == 1 ? _T(' ') : _T('s'));
-
-  if (IncLine (pLine, dwFlags))
-    return 1;
-
-  /* Print number of dirs and bytes free */
-  ConvertULong (ulDirs, buffer, sizeof(buffer));
-  ConOutPrintf (_T("          %6s Dir%c"),
-                buffer, ulDirs == 1 ? _T(' ') : _T('s'));
-
-  if (!(dwFlags & DIR_RECURSE))
-    {
-      szRoot[0] = szPath[0];
-      GetUserDiskFreeSpace(szRoot, &uliFree);
-      ConvertULargeInteger (uliFree, buffer, sizeof(buffer));
-      ConOutPrintf (_T("   %15s bytes free\n"), buffer);
-      if (IncLine (pLine, dwFlags))
-        return 1;
-    }
-  else
-    {
-      if ((dwFlags & DIR_BARE) == 0)
-        {
-         ConOutPrintf (_T("\n"));
-          if (IncLine (pLine, dwFlags))
-            return 1;
-          ConOutPrintf (_T("\n"));
+       /* Here we check if we didn't find anything */
+       if (!(ulFiles + ulDirs))
+       {
+               error_file_not_found();
+               return 1;
        }
-      if (IncLine (pLine, dwFlags))
-         return 1;
+       /* In bare format we don't print results */
+       if (lpFlags->bBareFormat)
+               return 0;
+
+       /* Print recursive specific results */
+       if (lpFlags->bRecursive)
+       {
+               ConvertULargeInteger (u64Bytes, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator);
+               
+               LoadString( GetModuleHandle(NULL), STRING_DIR_HELP5, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPrintf (_T((LPTSTR)szMsg),ulFiles, szBuffer);
     }
 
+       /* Print total  directories and freespace */
+       szRoot[0] = szPath[0];
+       GetUserDiskFreeSpace(szRoot, &uliFree);
+       ConvertULargeInteger (uliFree, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator);
+       LoadString( GetModuleHandle(NULL), STRING_DIR_HELP6, (LPTSTR) szMsg,sizeof(szMsg));
+    ConOutPrintf (_T((LPTSTR)szMsg),ulDirs, szBuffer);
+
   return 0;
 }
 
+/*
+ * getExt
+ *
+ * Get the extension of a filename 
+ */
+TCHAR* getExt(const TCHAR* file)
+{
+       
+       TCHAR* tmp = _tcsrchr(file,'.');
+       return tmp?tmp+1:"";
+}
 
 /*
- * dir_list
+ * getName
  *
- * list the files in the directory
+ * Get the name of the file without extension
  */
-static INT
-DirList (LPTSTR szPath, LPTSTR szFilespec, LPINT pLine, DWORD dwFlags)
+TCHAR * getName(const TCHAR* file, TCHAR * dest)
 {
-       TCHAR szFullPath[MAX_PATH];
-       WIN32_FIND_DATA file;
-       ULARGE_INTEGER bytecount;
-       FILETIME   ft;
-       SYSTEMTIME dt;
-       HANDLE hFile;
-       TCHAR  buffer[32];
-       ULONG filecount = 0;
-       ULONG dircount = 0;
-       INT count = 0;
-       SHORT screenwidth;
-       INT longestfname = 0;
-
-       bytecount.QuadPart = 0;
+int iLen;
+TCHAR* end;
+       
+       /* Check for "." and ".." folders */
+       if ((_tcscmp(file, _T(".")) == 0)
+               || (_tcscmp(file, _T("..")) == 0))
+       {
+               _tcscpy(dest,file);
+               return dest;
+       }
 
-       _tcscpy (szFullPath, szPath);
-       if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\'))
-               _tcscat (szFullPath, _T("\\"));
-       _tcscat (szFullPath, szFilespec);
+       end = _tcsrchr(file,'.');
+       if (!end)
+               iLen = _tcslen(file);   
+       else                    
+               iLen = (end - file);
+       
 
-       hFile = FindFirstFile (szFullPath, &file);
-       if (hFile == INVALID_HANDLE_VALUE)
+       _tcsncpy(dest, file, iLen);
+       *(dest + iLen) = _T('\0');
+       
+       return dest;
+}
+/*
+ *  DirPrintNewList
+ *
+ * The function that prints in new style
+ */
+static int
+DirPrintNewList(LPWIN32_FIND_DATA ptrFiles[],  /* [IN]Files' Info */
+                               DWORD dwCount,                                  /* [IN] The quantity of files */
+                               TCHAR * szCurPath,                              /* [IN] Full path of current directory */
+                               LPDIRSWITCHFLAGS lpFlags)               /* [IN] The flags used */
+{
+DWORD i;                                               /* An indexer for "for"s */
+TCHAR szSize[30];                              /* The size of file */
+TCHAR szShortName[15];                 /* The sort name */
+TCHAR szDate[20], szTime[20];  /* Date and time strings */
+int iSizeFormat;                               /* The format of size field */
+ULARGE_INTEGER u64FileSize;            /* The file size */
+
+       for(i = 0;i < dwCount;i++)
        {
-               /* Don't want to print anything if scanning recursively
-                * for a file. RL
-                */
-               if ((dwFlags & DIR_RECURSE) == 0)
+
+               /* Calculate size */            
+               if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+               /* Directory */
                {
-                       FindClose (hFile);
-                       error_file_not_found ();
-                       if (IncLine (pLine, dwFlags))
-                               return 0;
-                       return 1;
+                       iSizeFormat = -14;
+                       _tcscpy(szSize, _T("<DIR>"));
                }
-               FindClose (hFile);
-               return 0;
+               else
+               /* File */
+               {
+                       iSizeFormat = 14;
+                       u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh;
+                       u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow;
+                       ConvertULargeInteger(u64FileSize, szSize, 20,lpFlags->bTSeperator);
+               }
+               /* Calculate short name */
+               szShortName[0] = _T('\0');
+               if (lpFlags->bShortName)                
+                       _stprintf(szShortName," %-12s", ptrFiles[i]->cAlternateFileName);
+               
+               /* Format date and time */
+               DirPrintFileDateTime(szDate,szTime,ptrFiles[i],lpFlags);
+
+               /* Print the line */
+               ConOutPrintf("%10s  %-8s    %*s%s %s\n",
+                       szDate,
+                       szTime,
+                       iSizeFormat,
+                       szSize,                 
+                       szShortName,
+                       ptrFiles[i]->cFileName );
+                       
        }
-
-       /* Get the size of longest filename for wide listing. FN */
-       if (dwFlags & DIR_WIDE && (dwFlags & DIR_BARE) == 0)
+       return 0;
+}
+/*
+ *  DirPrintWideList
+ *
+ * The function that prints in wide list
+ */
+static int
+DirPrintWideList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */
+                               DWORD dwCount,                                  /* [IN] The quantity of files */
+                               TCHAR * szCurPath,                              /* [IN] Full path of current directory */
+                               LPDIRSWITCHFLAGS lpFlags)               /* [IN] The flags used */
+{
+DWORD i,j;                                             /* An indexer for "for"s */
+short iScreenWidth;                            /* The screen width */
+short iColumns;                                        /* The columns (used by wide list) */
+short iLines;                                  /* The lines (used by the wide list /d) */
+int iBiggestName;                              /* The biggest name, used for wide list */
+TCHAR szTempFname[MAX_PATH];   /* Temporary string */
+
+       /* Calculate biggest name */
+       iBiggestName = 1;
+       for(i = 0;i < dwCount;i++)
        {
-               do
+               if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
-                       if (_tcslen(file.cFileName) > longestfname)
-                       {
-                               longestfname = _tcslen(file.cFileName);
-                               /* Directories get extra brackets around them. */
-                               if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                                       longestfname += 2;
-                       }
+                       /* Directories need 2 additinal characters for brackets */
+                       if ((_tcslen(ptrFiles[i]->cFileName) + 2) > iBiggestName)
+                               iBiggestName = _tcslen(ptrFiles[i]->cFileName) + 2;
                }
-               while (FindNextFile (hFile, &file));
-               FindClose (hFile);
-
-               hFile = FindFirstFile (szFullPath, &file);
-
-               /* Count the highest number of columns */
-               GetScreenSize(&screenwidth, 0);
+               else
+               {
+                       if (_tcslen(ptrFiles[i]->cFileName)  > iBiggestName)
+                               iBiggestName = _tcslen(ptrFiles[i]->cFileName);
+               }
+       }
+               
+       /* Count the highest number of columns */
+       GetScreenSize(&iScreenWidth, 0);
+       iColumns = iScreenWidth / iBiggestName;
+
+       /* Check if there is enough space for spaces between names */
+       if (((iBiggestName * iColumns) + iColumns) >= iScreenWidth)
+               iColumns --;
+       /* A last check at iColumns to avoid division by zero */
+       if (!(iColumns)) iColumns = 1;
+
+       /* Print Column sorted */
+       if (lpFlags->bWideListColSort)
+       {
+               /* Calculate the lines that will be printed */                  
+               iLines = ceil((float)dwCount/(float)iColumns);
 
-               /* For counting columns of output */
-               count = 0;
+               for (i = 0;i < iLines;i++)
+               {
+                       for (j = 0;j < iColumns;j++)
+                       {
+                               DWORD temp = (j*iLines)+i;
+                               if (temp >= dwCount) break;
+                               if (ptrFiles[temp]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                                       _stprintf(szTempFname, "[%s]", ptrFiles[temp]->cFileName);
+                               else
+                                       _stprintf(szTempFname, "%s", ptrFiles[temp]->cFileName);
 
-               /* Increase by the number of spaces behind file name */
-               longestfname += 3;
+                               ConOutPrintf("%-*s",iBiggestName + 1 , szTempFname );
+                       }                               
+                       ConOutPrintf("\n");
+               }
        }
-
-       /* moved down here because if we are recursively searching and
-        * don't find any files, we don't want just to print
-        * Directory of C:\SOMEDIR
-        * with nothing else
-        * Rob Lake 06/13/98
-        */
-       if ((dwFlags & DIR_BARE) == 0)
+       /* Print Line sorted */
+       else
        {
-               ConOutPrintf (_T(" Directory of %s\n"), szPath);
-               if (IncLine (pLine, dwFlags))
-                       return 1;
-               ConOutPrintf (_T("\n"));
-               if (IncLine (pLine, dwFlags))
-                       return 1;
-       }
+               for (i = 0;i < dwCount;i++)
+               {
+                       if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                               _stprintf(szTempFname, "[%s]", ptrFiles[i]->cFileName);
+                       else
+                               _stprintf(szTempFname, "%s", ptrFiles[i]->cFileName);
 
-       do
+                               ConOutPrintf("%-*s", iBiggestName + 1, szTempFname );
+                       /* We print a new line at the end of each column
+                          except for the case that it is the last item.*/
+                       if (!((i+1)%iColumns) && (i < (dwCount-1)))
+                               ConOutPrintf("\n");
+               }
+               /* Add a new line after the last item */
+               ConOutPrintf("\n");
+       }
+       return 0;
+}
+/*
+ *  DirPrintOldList
+ *
+ * The function that prints in old style
+ */
+static int
+DirPrintOldList(LPWIN32_FIND_DATA ptrFiles[],  /* [IN] Files' Info */
+                               DWORD dwCount,                                  /* [IN] The quantity of files */
+                               TCHAR * szCurPath,                              /* [IN] Full path of current directory */
+                               LPDIRSWITCHFLAGS lpFlags)               /* [IN] The flags used */
+{
+DWORD i;                                               /* An indexer for "for"s */
+TCHAR szName[10];                              /* The name of file */
+TCHAR szExt[5];                                        /* The extension of file */
+TCHAR szDate[30],szTime[30];   /* Used to format time and date */
+TCHAR szSize[30];                              /* The size of file */
+int iSizeFormat;                               /* The format of size field */
+ULARGE_INTEGER u64FileSize;            /* The file size */
+
+       for(i = 0;i < dwCount;i++)
        {
-               /* next file, if user doesn't want all files */
-               if (!(dwFlags & DIR_ALL) &&
-                       ((file.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ||
-                        (file.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)))
-                       continue;
-
-               if (dwFlags & DIR_LWR)
+               /* Broke 8.3 format */
+               if (*ptrFiles[i]->cAlternateFileName )
                {
-                       _tcslwr (file.cAlternateFileName);
+                       /* If the file is long named then we read the alter name */
+                       getName( ptrFiles[i]->cAlternateFileName, szName);
+                       _tcscpy(szExt, getExt( ptrFiles[i]->cAlternateFileName));
                }
-
-               if (dwFlags & DIR_WIDE && (dwFlags & DIR_BARE) == 0)
+               else
                {
-                       ULARGE_INTEGER uliSize;
-
-                       if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                       {
-                               _stprintf (buffer, _T("[%s]"), file.cFileName);
-                               dircount++;
-                       }
-                       else
-                       {
-                               _stprintf (buffer, _T("%s"), file.cFileName);
-                               filecount++;
-                       }
-
-                       ConOutPrintf (_T("%*s"), - longestfname, buffer);
-                       count++;
-                       /* output as much columns as fits on the screen */
-                       if (count >= (screenwidth / longestfname))
-                       {
-                               /* print the new line only if we aren't on the
-                                * last column, in this case it wraps anyway */
-                               if (count * longestfname != screenwidth)
-                                       ConOutPrintf (_T("\n"));
-                               if (IncLine (pLine, dwFlags))
-                                       return 1;
-                               count = 0;
-                       }
+                       /* If the file is not long name we read its original name */
+                       getName( ptrFiles[i]->cFileName, szName);
+                       _tcscpy(szExt, getExt( ptrFiles[i]->cFileName));
+               }
 
-                       uliSize.LowPart = file.nFileSizeLow;
-                       uliSize.HighPart = file.nFileSizeHigh;
-                       bytecount.QuadPart += uliSize.QuadPart;
+               /* Calculate size */            
+               if (ptrFiles[i]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)           
+               {
+                       /* Directory, no size it's a directory*/
+                       iSizeFormat = -17;
+                       _tcscpy(szSize, _T("<DIR>"));
                }
-               else if (dwFlags & DIR_BARE)
+               else            
                {
-                       ULARGE_INTEGER uliSize;
-
-                       if (_tcscmp (file.cFileName, _T(".")) == 0 ||
-                               _tcscmp (file.cFileName, _T("..")) == 0)
-                               continue;
-
-                       if (dwFlags & DIR_RECURSE)
-                       {
-                               TCHAR dir[MAX_PATH];
-
-                               _tcscpy (dir, szPath);
-                               _tcscat (dir, _T("\\"));
-                               if (dwFlags & DIR_LWR)
-                                       _tcslwr (dir);
-                               ConOutPrintf (dir);
-                       }
-
-                       ConOutPrintf (_T("%-13s\n"), file.cFileName);
-                       if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                               dircount++;
-                       else
-                               filecount++;
-                       if (IncLine (pLine, dwFlags))
-                               return 1;
+                       /* File */
+                       iSizeFormat = 17;
+                       u64FileSize.HighPart = ptrFiles[i]->nFileSizeHigh;
+                       u64FileSize.LowPart = ptrFiles[i]->nFileSizeLow;
+                       ConvertULargeInteger(u64FileSize, szSize, 20, lpFlags->bTSeperator);
+               }
+               
+               /* Format date and time */
+               DirPrintFileDateTime(szDate,szTime,ptrFiles[i],lpFlags);
+
+               /* Print the line */
+               ConOutPrintf("%-8s %-3s  %*s %s  %s\n",
+                       szName,                 /* The file's 8.3 name */
+                       szExt,                  /* The file's 8.3 extension */
+                       iSizeFormat,    /* print format for size column */
+                       szSize,                 /* The size of file or "<DIR>" for dirs */
+                       szDate,                 /* The date of file/dir */
+                       szTime);                /* The time of file/dir */
+       }
+       return 0;
+}
 
-                       uliSize.LowPart = file.nFileSizeLow;
-                       uliSize.HighPart = file.nFileSizeHigh;
-                       bytecount.QuadPart += uliSize.QuadPart;
+/*
+ *  DirPrintBareList
+ *
+ * The function that prints in bare format
+ */
+static int
+DirPrintBareList(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */
+                               DWORD dwCount,                                  /* [IN] The quantity of files */
+                               TCHAR * szCurPath,                              /* [IN] Full path of current directory */
+                               LPDIRSWITCHFLAGS lpFlags)               /* [IN] The flags used */
+{
+DWORD i;                                               /* An indexer for "for"s */
+TCHAR szFullName[MAX_PATH];            /* The fullpath name of file */
+               
+       for(i = 0;i < dwCount;i++)
+       {
+               if ((_tcscmp(ptrFiles[i]->cFileName, _T(".")) == 0) ||
+                       (_tcscmp(ptrFiles[i]->cFileName, _T("..")) == 0))
+               {
+               /* at bare format we don't print "." and ".." folder */
+                       continue;
                }
-               else
+               /* at recursive mode we print full path of file */
+               if (lpFlags->bRecursive)
                {
-                       if (dwFlags & DIR_NEW)
-                       {
-                               /* print file date and time */
-                               if (FileTimeToLocalFileTime (&file.ftLastWriteTime, &ft))
-                               {
-                                       FileTimeToSystemTime (&ft, &dt);
-                                       PrintFileDateTime (&dt, dwFlags);
-                               }
-
-                               /* print file size */
-                               if (file.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
-                               {
-                                       ConOutPrintf (_T("         <JUNCTION>    "));
-                                       if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                                               dircount++;
-                               }
-                               else if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                               {
-                                       ConOutPrintf (_T("         <DIR>         "));
-                                       dircount++;
-                               }
-                               else
-                               {
-                                       ULARGE_INTEGER uliSize;
+                       _tcscpy(szFullName, szCurPath);
+                       _tcscat(szFullName, ptrFiles[i]->cFileName);
+                       ConOutPrintf("%s\n", szFullName);
+               }
+               /* if we are not in recursive mode we print the file names */
+               else
+                       ConOutPrintf("%s\n",ptrFiles[i]->cFileName);    
+       }
+       return 0;
+}
 
-                                       uliSize.LowPart = file.nFileSizeLow;
-                                       uliSize.HighPart = file.nFileSizeHigh;
+/*
+ * DirPrintFiles
+ * 
+ * The functions that prints the files list
+ */
+static int
+DirPrintFiles(LPWIN32_FIND_DATA ptrFiles[],    /* [IN] Files' Info */
+                               DWORD dwCount,                          /* [IN] The quantity of files */
+                               TCHAR * szCurPath,                      /* [IN] Full path of current directory */
+                               LPDIRSWITCHFLAGS lpFlags)       /* [IN] The flags used */
+{
+TCHAR szTemp[MAX_PATH];                        /* A buffer to format the directory header */
+WCHAR szMsg[RC_STRING_MAX_SIZE];
+
+       /* Print directory header */
+       _tcscpy(szTemp, szCurPath);
+       /* We cut the trailing \ of the full path */
+       szTemp[_tcslen(szTemp)-1] = _T('\0');
+       /* Condition to print header:
+          We are not printing in bare format
+          and if we are in recursive mode... we must have results */
+       if (!(lpFlags->bBareFormat ) && !((lpFlags->bRecursive) && (dwCount <= 0)))
+       {
+               LoadString( GetModuleHandle(NULL), STRING_DIR_HELP7, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPrintf (_T( (LPTSTR)szMsg), szTemp);
+       }
 
-                                       ConvertULargeInteger (uliSize, buffer, sizeof(buffer));
-                                       ConOutPrintf (_T("   %20s"), buffer);
+       /* Bare format */
+       if (lpFlags->bBareFormat)
+       {
+               DirPrintBareList(ptrFiles, dwCount, szCurPath, lpFlags);
+       }
+       /* New list style / Short names */
+       else if(lpFlags->bShortName)
+       {
+               DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
+       }
+       /* Wide list */
+       else if(lpFlags->bWideListColSort || lpFlags->bWideList)
+       {
+               DirPrintWideList(ptrFiles, dwCount, szCurPath, lpFlags);
+       }
+       /* New list style*/
+       else if (lpFlags->bNewLongList )
+       {
+               DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
+       }
+       /* If nothing is selected old list is the default */
+       else
+       {
+               DirPrintOldList(ptrFiles, dwCount, szCurPath, lpFlags);
+       }
+       return 0;
+}
 
-                                       bytecount.QuadPart += uliSize.QuadPart;
-                                       filecount++;
-                               }
 
-                               /* print long filename */
-                               ConOutPrintf (_T(" %s\n"), file.cFileName);
-                       }
-                       else
-                       {
-                               if (file.cFileName[0] == _T('.'))
-                                       ConOutPrintf (_T("%-13s "), file.cFileName);
-                               else if (file.cAlternateFileName[0] == _T('\0'))
-                               {
-                                       TCHAR szShortName[13];
-                                       LPTSTR ext;
 
-                                       _tcsncpy (szShortName, file.cFileName, 13);
-                                       ext = _tcschr (szShortName, _T('.'));
-                                       if (!ext)
-                                               ext = _T("");
-                                       else
-                                               *ext++ = _T('\0');
-                                       ConOutPrintf (_T("%-8s %-3s  "), szShortName, ext);
-                               }
-                               else
-                               {
-                                       LPTSTR ext;
+/*
+ * CompareFiles
+ *
+ * Compares 2 files based on the order criteria
+ */
+static int
+       CompareFiles(
+               LPWIN32_FIND_DATA lpFile1,      /* [IN] A pointer to WIN32_FIND_DATA of file 1 */
+               LPWIN32_FIND_DATA lpFile2,      /* [IN] A pointer to WIN32_FIND_DATA of file 2 */
+               LPDIRSWITCHFLAGS lpFlags)       /* [IN] The flags that we use to list */
+{
+/* u64 variables used to translate some broken 32bit info */
+ULARGE_INTEGER u64File1, u64File2;
+int i;                                                         /* An indexer for "for"s */
+long iComp = 0;                                        /* The comparison result */
 
-                                       ext = _tcschr (file.cAlternateFileName, _T('.'));
-                                       if (!ext)
-                                               ext = _T("");
-                                       else
-                                               *ext++ = _T('\0');
-                                       ConOutPrintf (_T("%-8s %-3s  "), file.cAlternateFileName, ext);
-                               }
+       /* Calculate critiries by order given from user */
+       for (i = 0;i < lpFlags->stOrderBy.sCriteriaCount;i++)
+       {
 
-                               /* print file size */
-                               if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-                               {
-                                       ConOutPrintf (_T("%-14s"), _T("<DIR>"));
-                                       dircount++;
-                               }
-                               else
-                               {
-                                       ULARGE_INTEGER uliSize;
-
-                                       uliSize.LowPart = file.nFileSizeLow;
-                                       uliSize.HighPart = file.nFileSizeHigh;
-                                       ConvertULargeInteger (uliSize, buffer, sizeof(buffer));
-                                       ConOutPrintf (_T("   %10s "), buffer);
-                                       bytecount.QuadPart += uliSize.QuadPart;
-                                       filecount++;
-                               }
+               /* Calculate criteria */
+               switch(lpFlags->stOrderBy.eCriteria[i])
+               {
+               case ORDER_SIZE:                /* Order by size /o:s */
+                       /* concat the 32bit integers to a 64bit */
+                       u64File1.LowPart = lpFile1->nFileSizeLow;
+                       u64File1.HighPart = lpFile1->nFileSizeHigh;
+                       u64File2.LowPart = lpFile2->nFileSizeLow;
+                       u64File2.HighPart = lpFile2->nFileSizeHigh;
+
+                       /* In case that differnce is too big for a long */
+                       if (u64File1.QuadPart < u64File2.QuadPart)
+                               iComp = -1;
+                       else if (u64File1.QuadPart > u64File2.QuadPart)
+                               iComp = 1;
+                       else
+                               iComp = 0;
+                       break;
 
-                               /* print file date and time */
-                               if (FileTimeToLocalFileTime (&file.ftLastWriteTime, &ft))
-                               {
-                                       FileTimeToSystemTime (&ft, &dt);
-                                       PrintFileDateTime (&dt, dwFlags);
-                               }
+                       break;
+               case ORDER_DIRECTORY:   /* Order by directory attribute /o:g */
+                       iComp = ((lpFile2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)-
+                               (lpFile1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
+                       break;
+               case ORDER_EXTENSION:   /* Order by extension name /o:e */
+                       iComp = _stricmp(getExt(lpFile1->cFileName),getExt(lpFile2->cFileName));
+                       break;
+               case ORDER_NAME:                /* Order by filename /o:n */
+                       iComp = _stricmp(lpFile1->cFileName, lpFile2->cFileName);
+                       break;
+               case ORDER_TIME:                /* Order by file's time /o:t */
 
-                               /* print long filename */
-                               ConOutPrintf (_T(" %s\n"), file.cFileName);
+                       /* We compare files based on the time field selected by /t */
+                       switch(lpFlags->stTimeField.eTimeField)
+                       {
+                       case TF_CREATIONDATE:
+                               /* concat the 32bit integers to a 64bit */
+                               u64File1.LowPart = lpFile1->ftCreationTime.dwLowDateTime;
+                               u64File1.HighPart = lpFile1->ftCreationTime.dwHighDateTime ;
+                               u64File2.LowPart = lpFile2->ftCreationTime.dwLowDateTime;
+                               u64File2.HighPart = lpFile2->ftCreationTime.dwHighDateTime ;
+                               break;
+                       case TF_LASTACCESSEDDATE :
+                               /* concat the 32bit integers to a 64bit */
+                               u64File1.LowPart = lpFile1->ftLastAccessTime.dwLowDateTime;
+                               u64File1.HighPart = lpFile1->ftLastAccessTime.dwHighDateTime ;
+                               u64File2.LowPart = lpFile2->ftLastAccessTime.dwLowDateTime;
+                               u64File2.HighPart = lpFile2->ftLastAccessTime.dwHighDateTime ;
+                               break;
+                       case TF_MODIFIEDDATE:
+                               /* concat the 32bit integers to a 64bit */
+                               u64File1.LowPart = lpFile1->ftLastWriteTime.dwLowDateTime;
+                               u64File1.HighPart = lpFile1->ftLastWriteTime.dwHighDateTime ;
+                               u64File2.LowPart = lpFile2->ftLastWriteTime.dwLowDateTime;
+                               u64File2.HighPart = lpFile2->ftLastWriteTime.dwHighDateTime ;
+                               break;                  
                        }
-
-                       if (IncLine (pLine, dwFlags))
-                               return 1;
+                       
+                       /* In case that differnce is too big for a long */
+                       if (u64File1.QuadPart < u64File2.QuadPart)
+                               iComp = -1;
+                       else if (u64File1.QuadPart > u64File2.QuadPart)
+                               iComp = 1;
+                       else
+                               iComp = 0;
+                       break;
                }
-       }
-       while (FindNextFile (hFile, &file));
-       FindClose (hFile);
+               /* Reverse if desired */
+               if (lpFlags->stOrderBy.bCriteriaRev[i])
+                       iComp *= -1;
 
-       /* Rob Lake, need to make clean output */
-       /* JPP 07/08/1998 added check for count != 0 */
-       if ((dwFlags & DIR_WIDE) && (count != 0))
-       {
-               ConOutPrintf (_T("\n"));
-               if (IncLine (pLine, dwFlags))
-                       return 1;
+               /* If that criteria was enough for distinguishing
+                  the files/dirs,there is no need to calculate the others*/
+               if (iComp != 0) break;          
        }
+       
+       /* Translate the value of iComp to boolean */
+       if (iComp > 0)
+               return TRUE;
+       else
+               return FALSE;
+}
 
-       if (filecount || dircount)
-       {
-               recurse_dir_cnt += dircount;
-               recurse_file_cnt += filecount;
-               recurse_bytes.QuadPart += bytecount.QuadPart;
+/*
+ * QsortFiles
+ *
+ * Sort files by the order criterias using quicksort method
+ */
+static void
+QsortFiles(
+       LPWIN32_FIND_DATA ptrArray[],   /* [IN/OUT] The array with file info pointers */
+       int i,                                                  /* [IN]     The index of first item in array */
+       int j,                                                  /* [IN]     The index to last item in array */
+       LPDIRSWITCHFLAGS lpFlags)               /* [IN]     The flags that we will use to sort */
+{
+LPWIN32_FIND_DATA lpTemp;      /* A temporary pointer */
+                                                       /* used for exchangin pointers */
+int First, Last, Temp;
+BOOL Way;
 
-               /* print_summary */
-               if (PrintSummary (szPath, filecount, dircount, bytecount, pLine, dwFlags))
-                       return 1;
-       }
-       else
+       if (i < j)
        {
-               error_file_not_found ();
-               return 1;
-       }
+               First = i, Last = j, Way = TRUE;
+               while (i != j)
+               {
+                       if (Way == CompareFiles(ptrArray[i], ptrArray[j], lpFlags))
+                       {
+                               /* Swap the pointers of the array */
+                               lpTemp = ptrArray[i];
+                               ptrArray[i]= ptrArray[j];
+                               ptrArray[j] = lpTemp;
+                               /* Swap the indexers for inverting sorting */
+                               Temp = i, i=j,j =Temp;
+                               Way = !Way;
+                       }
+                       j += (!Way - Way);                      
 
-       return 0;
+               }
+               QsortFiles(ptrArray,First, i-1, lpFlags);
+               QsortFiles(ptrArray,i+1,Last, lpFlags);
+       }
 }
 
 
+
 /*
- * _Read_Dir: Actual function that does recursive listing
+ * DirList
+ *
+ * The functions that does everything except for printing results
  */
-static INT
-DirRead (LPTSTR szPath, LPTSTR szFilespec, LPINT pLine, DWORD dwFlags)
+static INT DirList (LPTSTR szPath,                             /* [IN] The path that dir starts */
+                                        LPTSTR szFilespec,                     /* [IN] The type of file that we are looking for */
+                                        LPINT pLine,                           /* FIXME: Maybe used for paginating */
+                                        LPDIRSWITCHFLAGS lpFlags)      /* [IN] The flags of the listing */
 {
-       TCHAR szFullPath[MAX_PATH];
-       WIN32_FIND_DATA file;
-       HANDLE hFile;
 
+/* Internal linked list */
+struct TDirFindListNode
+       {
+       WIN32_FIND_DATA stFindInfo;
+       struct TDirFindListNode * ptrNext;
+};
+
+HANDLE hSearch;                                                        /* The handle of the search */
+HANDLE hRecSearch;                                             /* The handle for searching recursivly */
+WIN32_FIND_DATA wfdFileInfo;                   /* The info of file that found */
+LPWIN32_FIND_DATA * ptrFileArray;              /* An array of pointers with all the files */
+struct TDirFindListNode * ptrStartNode;        /* The pointer to the first node */
+struct TDirFindListNode * ptrNextNode; /* A pointer used for relatives refernces */
+TCHAR szFullPath[MAX_PATH];                            /* The full path that we are listing with trailing \ */
+TCHAR szFullFileSpec[MAX_PATH];                        /* The full path with file specs that we ll request\ */
+TCHAR szBytes[20];                                             /* A string for converting ULARGE integer */
+DWORD dwCount;                                                 /* A counter of files found in directory */
+DWORD dwCountFiles;                                            /* Counter for files */
+DWORD dwCountDirs;                                             /* Counter for directories */
+ULARGE_INTEGER u64CountBytes;                  /* Counter for bytes */
+ULARGE_INTEGER u64Temp;                                        /* A temporary counter */
+WCHAR szMsg[RC_STRING_MAX_SIZE];
+
+       /* Initialize Variables */
+       ptrStartNode = NULL;
+       ptrNextNode = NULL;
+       dwCount = 0;
+       dwCountFiles = 0;
+       dwCountDirs = 0;
+       u64CountBytes.QuadPart = 0;     
+
+       /* Create szFullPath and szFullFileSpec */
        _tcscpy (szFullPath, szPath);
-       if (szFullPath[_tcslen (szFullPath) - 1] != _T('\\'))
+       if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\'))
                _tcscat (szFullPath, _T("\\"));
-       _tcscat (szFullPath, _T("*"));
+       _tcscpy (szFullFileSpec, szFullPath);
+       _tcscat (szFullFileSpec, szFilespec);
 
-       hFile = FindFirstFile (szFullPath, &file);
-       if (hFile == INVALID_HANDLE_VALUE)
-               return 1;
+       /* Prepare the linked list, first node is allocated */
+       if ((ptrStartNode = malloc(sizeof(struct TDirFindListNode))) == NULL)
+       {
+#ifdef _DEBUG
+               ConErrPrintf("DEBUG: Cannot allocate memory for ptrStartNode!\n");
+#endif
+               return 1;       /* Error cannot allocate memory for 1st object */
+       }
+       ptrNextNode = ptrStartNode;
 
+       /* Collect the results for the current folder */
+       hSearch = FindFirstFile (szFullFileSpec, &wfdFileInfo);
        do
        {
-               /* don't list "." and ".." */
-               if (_tcscmp (file.cFileName, _T(".")) == 0 ||
-                       _tcscmp (file.cFileName, _T("..")) == 0)
-                       continue;
-
-               if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+               if (hSearch != INVALID_HANDLE_VALUE)
                {
-                       _tcscpy (szFullPath, szPath);
-                       if (szFullPath[_tcslen (szFullPath) - 1] != _T('\\'))
-                               _tcscat (szFullPath, _T("\\"));
-                       _tcscat (szFullPath, file.cFileName);
-                       
-                       if (DirList (szFullPath, szFilespec, pLine, dwFlags))
-                       {
-                               FindClose (hFile);
-                               return 1;
-                       }
-                       if (DirRead (szFullPath, szFilespec, pLine, dwFlags) == 1)
+                       /* Here we filter all the specified attributes */
+                       if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask )
+                               == (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal ))
                        {
-                               FindClose (hFile);
-                               return 1;
+                               ptrNextNode->ptrNext = malloc(sizeof(struct TDirFindListNode));
+                               /* If malloc fails we go to next file in hope it works,
+                                  without braking the linked list! */
+                               if (ptrNextNode->ptrNext)
+                               {
+                                       /* Copy the info of search at linked list */
+                                       memcpy((void *)&ptrNextNode->ptrNext->stFindInfo,
+                                               (void *)&wfdFileInfo,sizeof(WIN32_FIND_DATA));
+                                               
+                                       /* If lower case is selected do it here */
+                                       if (lpFlags->bLowerCase)
+                                       {
+                                               _tcslwr(ptrNextNode->ptrNext->stFindInfo.cAlternateFileName);
+                                               _tcslwr(ptrNextNode->ptrNext->stFindInfo.cFileName);
+                                       }
+
+                                       /* Continue at next node at linked list */
+                                       ptrNextNode = ptrNextNode->ptrNext;
+                                       dwCount ++;
+                               
+                                       /* Grab statistics */
+                                       if (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                                       {
+                                               /* Directory */
+                                               dwCountDirs++;
+                                       }
+                                       else
+                                       {
+                                               /* File */
+                                               dwCountFiles++;                                                 
+                                               u64Temp.HighPart = wfdFileInfo.nFileSizeHigh;
+                                               u64Temp.LowPart = wfdFileInfo.nFileSizeLow;
+                                               u64CountBytes.QuadPart += u64Temp.QuadPart;
+                                       }                                               
+                               }
                        }
-               }
-       }
-       while (FindNextFile (hFile, &file));
+                       
+               }               
+       }while(FindNextFile(hSearch,&wfdFileInfo));
+       FindClose(hSearch);
 
-       if (!FindClose (hFile))
-               return 1;
+       /* Terminate list */
+       ptrNextNode->ptrNext = NULL;
 
-       return 0;
-}
+       /* Calculate and allocate space need for making an array of pointers */ 
+       ptrFileArray = malloc(sizeof(LPWIN32_FIND_DATA)*dwCount);
+       if (!(ptrFileArray))
+       {
+#ifdef _DEBUG
+               ConErrPrintf("DEBUG: Cannot allocate memory for ptrFileArray!\n");
+#endif
+               goto _DirList_clear_n_exit;
+       }
 
+       /* Create an array of pointers from the linked list
+          this will be used to sort and print data, rather than the list */
+       ptrNextNode = ptrStartNode;
+       dwCount = 0;
+       while(ptrNextNode->ptrNext)
+       {       
+               *(ptrFileArray + dwCount) = &ptrNextNode->ptrNext->stFindInfo;
+               ptrNextNode = ptrNextNode->ptrNext;
+               dwCount++;
+       }
 
-/*
- * do_recurse: Sets up for recursive directory listing
- */
-static INT
-DirRecurse (LPTSTR szPath, LPTSTR szSpec, LPINT pLine, DWORD dwFlags)
-{
-       if (!PrintDirectoryHeader (szPath, pLine, dwFlags))
-               return 1;
+       /* Sort Data if requested*/
+       if (lpFlags->stOrderBy.sCriteriaCount > 0)
+               QsortFiles(ptrFileArray, 0, dwCount-1,lpFlags);
 
-       if (DirList (szPath, szSpec, pLine, dwFlags))
-               return 1;
+       /* Print Data */
+       DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags);
+       
+       /* Free array */
+       free(ptrFileArray);
 
-       if ((dwFlags & DIR_BARE) == 0)
+       /* Print Directory Summary */
+       /* Condition to print summary is:
+          If we are not in bare format and if we have results! */
+       if (!(lpFlags->bBareFormat) && (dwCount > 0))
        {
-               ConOutPrintf (_T("\n"));
-               if (IncLine (pLine, dwFlags))
-                       return 1;
+               ConvertULargeInteger(u64CountBytes, szBytes, 20, lpFlags->bTSeperator);
+               LoadString( GetModuleHandle(NULL), STRING_DIR_HELP8, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPrintf (_T((LPTSTR)szMsg),dwCountFiles, szBytes);
        }
 
-       if (DirRead (szPath, szSpec, pLine, dwFlags))
-               return 1;
-
-       if ((dwFlags & DIR_BARE) == 0)
-               ConOutPrintf (_T("Total files listed:\n"));
-
-       dwFlags &= ~DIR_RECURSE;
+       /* Add statistics to recursive statistics*/
+       recurse_dir_cnt += dwCountDirs;
+       recurse_file_cnt += dwCountFiles;
+       recurse_bytes.QuadPart += u64CountBytes.QuadPart;
 
-       if (PrintSummary (szPath, recurse_file_cnt,
-                                         recurse_dir_cnt, recurse_bytes, pLine, dwFlags))
-               return 1;
+       /* Do the recursive job if requested
+          the recursive is be done on ALL(indepent of their attribs)
+          directoried of the current one.*/
+       if (lpFlags->bRecursive)
+       {
+               /* The new search is involving any *.* file */
+               _tcscpy(szFullFileSpec, szFullPath);
+               _tcscat(szFullFileSpec, _T("*.*"));
+               hRecSearch = FindFirstFile (szFullFileSpec, &wfdFileInfo);
+               do
+               {
+                       if (hRecSearch != INVALID_HANDLE_VALUE)
+                       {
+                               /* We search for directories other than "." and ".." */
+                               if ((_stricmp(wfdFileInfo.cFileName, _T(".")) != 0)
+                                       && (_stricmp(wfdFileInfo.cFileName, _T("..")) != 0 )
+                                       && (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+                               {
+                                       /* Concat the path and the directory to do recursive */
+                                       _tcscpy(szFullFileSpec, szFullPath);
+                                       _tcscat(szFullFileSpec, wfdFileInfo.cFileName);
+                                       /* We do the same for tha folder */
+                                       DirList(szFullFileSpec, szFilespec, pLine,lpFlags);
+                               }
+                       }
+               }while(FindNextFile(hRecSearch,&wfdFileInfo));
+               FindClose(hRecSearch);
+       }
 
-       if ((dwFlags & DIR_BARE) == 0)
+_DirList_clear_n_exit: 
+/* Deallocate memory */
+       /* Free linked list */
+       while (ptrStartNode)
        {
-               ConOutPrintf (_T("\n"));
-               if (IncLine (pLine, dwFlags))
-                       return 1;
+               ptrNextNode = ptrStartNode->ptrNext;
+               free(ptrStartNode);
+               ptrStartNode = ptrNextNode;
+               dwCount --;
        }
 
        return 0;
 }
 
 
+
 /*
  * dir
  *
@@ -1241,27 +1789,45 @@ DirRecurse (LPTSTR szPath, LPTSTR szSpec, LPINT pLine, DWORD dwFlags)
  */
 INT CommandDir (LPTSTR first, LPTSTR rest)
 {
-       DWORD  dwFlags = DIR_NEW | DIR_FOUR;
-       TCHAR  dircmd[256];
+       TCHAR  dircmd[256];                                                     /* A variable to store the DIRCMD enviroment variable */
        TCHAR  szPath[MAX_PATH];
        TCHAR  szFilespec[MAX_PATH];
        LPTSTR param;
        INT    nLine = 0;
+       DIRSWITCHFLAGS stFlags;
 
-
+       /* Initialize variables */
        recurse_dir_cnt = 0L;
        recurse_file_cnt = 0L;
        recurse_bytes.QuadPart = 0;
 
+       /* Initialize Switch Flags < Default switches are setted here!> */
+       stFlags.b4Digit = TRUE;
+       stFlags.bBareFormat = FALSE;
+       stFlags.bLowerCase = FALSE;
+       stFlags.bNewLongList = TRUE;
+       stFlags.bPause = FALSE;
+       stFlags.bRecursive = FALSE;
+       stFlags.bShortName = FALSE;
+       stFlags.bTSeperator = TRUE;
+       stFlags.bUser = FALSE;
+       stFlags.bWideList = FALSE;
+       stFlags.bWideListColSort = FALSE;
+       stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE;
+       stFlags.stTimeField.bUnSet = FALSE;
+       stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
+       stFlags.stAttribs.dwAttribVal = 0L;
+       stFlags.stAttribs.bUnSet = FALSE;
+       stFlags.stOrderBy.sCriteriaCount = 0;
+       stFlags.stOrderBy.bUnSet = FALSE;
+
        /* read the parameters from the DIRCMD environment variable */
-       if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256))
-       {
-               if (!DirReadParam (dircmd, &param, &dwFlags))
-                       return 1;
-       }
+       if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) 
+               if (!DirReadParam(dircmd, &param, &stFlags))
+                       return 1;       
 
        /* read the parameters */
-       if (!DirReadParam (rest, &param, &dwFlags))
+       if (!DirReadParam(rest, &param, &stFlags))
                return 1;
 
        /* default to current directory */
@@ -1272,21 +1838,44 @@ INT CommandDir (LPTSTR first, LPTSTR rest)
        if (DirParsePathspec (param, szPath, szFilespec))
                return 1;
 
-       if (dwFlags & DIR_RECURSE)
-       {
-               if (IncLine (&nLine, dwFlags))
-                       return 0;
-               if (DirRecurse (szPath, szFilespec, &nLine, dwFlags))
+/* <Debug :>
+   Uncomment this to show the final state of switch flags*/
+/*
+       ConOutPrintf("Attributes mask/value %x/%x\n",stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal  );
+       ConOutPrintf("(B) Bare format : %i\n", stFlags.bBareFormat );
+       ConOutPrintf("(C) Thousand : %i\n", stFlags.bTSeperator );
+       ConOutPrintf("(W) Wide list : %i\n", stFlags.bWideList );
+       ConOutPrintf("(D) Wide list sort by column : %i\n", stFlags.bWideListColSort );
+       ConOutPrintf("(L) Lowercase : %i\n", stFlags.bLowerCase );
+       ConOutPrintf("(N) New : %i\n", stFlags.bNewLongList );
+       ConOutPrintf("(O) Order : %i\n", stFlags.stOrderBy.sCriteriaCount );
+       int i;
+       for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
+               ConOutPrintf(" Order Criteria [%i]: %i (Reversed: %i)\n",i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] );
+       ConOutPrintf("(P) Pause : %i\n", stFlags.bPause  );
+       ConOutPrintf("(Q) Owner : %i\n", stFlags.bUser );
+       ConOutPrintf("(S) Recursive : %i\n", stFlags.bRecursive );
+       ConOutPrintf("(T) Time field : %i\n", stFlags.stTimeField.eTimeField );
+       ConOutPrintf("(X) Short names : %i\n", stFlags.bShortName );
+       ConOutPrintf("Parameter : %s\n", param );
+*/
+
+       /* print the header  */
+       if (!stFlags.bBareFormat)
+               if (!PrintDirectoryHeader (szPath, &nLine, &stFlags))
                        return 1;
-               return 0;
-       }
 
-       /* print the header */
-       if (!PrintDirectoryHeader (szPath, &nLine, dwFlags))
+       /* do the actual dir */
+       if (DirList (szPath, szFilespec, &nLine, &stFlags))
                return 1;
 
-       if (DirList (szPath, szFilespec, &nLine, dwFlags))
-               return 1;
+       /* print the footer */  
+       PrintSummary(szPath,
+               recurse_file_cnt,
+               recurse_dir_cnt,
+               recurse_bytes,
+               &nLine,
+               &stFlags);
 
        return 0;
 }
index 8d5b7a8..abe60d2 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "precomp.h"
+#include "resource.h"
 
 #ifdef FEATURE_DIRECTORY_STACK
 
@@ -139,13 +140,13 @@ INT CommandPushd (LPTSTR first, LPTSTR rest)
        TCHAR curPath[MAX_PATH];
        TCHAR newPath[MAX_PATH];
        BOOL  bChangePath = FALSE;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp (rest, _T("/?"), 2))
        {
-               ConOutPuts (_T("Stores the current directory for use by the POPD command, then\n"
-                              "changes to the specified directory.\n\n"
-                              "PUSHD [path | ..]\n\n"
-                              "  path        Specifies the directory to make the current directory"));
+               LoadString( GetModuleHandle(NULL), STRING_DIRSTACK_HELP1, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+               
                return 0;
        }
 
@@ -172,11 +173,13 @@ INT CommandPushd (LPTSTR first, LPTSTR rest)
 INT CommandPopd (LPTSTR first, LPTSTR rest)
 {
        TCHAR szPath[MAX_PATH];
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp(rest, _T("/?"), 2))
-       {
-               ConOutPuts (_T("Changes to the directory stored by the PUSHD command.\n\n"
-                              "POPD"));
+       {   
+               LoadString( GetModuleHandle(NULL), STRING_DIRSTACK_HELP2, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+               
                return 0;
        }
 
@@ -198,12 +201,13 @@ INT CommandPopd (LPTSTR first, LPTSTR rest)
 INT CommandDirs (LPTSTR first, LPTSTR rest)
 {
        LPDIRENTRY lpDir;
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp(rest, _T("/?"), 2))
        {
-               ConOutPuts (_T("Prints the contents of the directory stack.\n"
-                              "\n"
-                              "DIRS"));
+               LoadString( GetModuleHandle(NULL), STRING_DIRSTACK_HELP3, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+               
                return 0;
        }
 
@@ -212,7 +216,9 @@ INT CommandDirs (LPTSTR first, LPTSTR rest)
 
        if (lpDir == NULL)
        {
-               ConOutPuts (_T("Directory stack empty"));
+               LoadString( GetModuleHandle(NULL), STRING_DIRSTACK_HELP4, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+               
                return 0;
        }
 
index cf383c5..34ae60f 100644 (file)
@@ -20,6 +20,7 @@
 #include "precomp.h"
 
 
+#define PARAMETERF_ERROR       _T("Parameter format not correct - %c\n")
 #define INVALID_SWITCH         _T("Invalid switch - /%c\n")
 #define TOO_MANY_PARAMETERS    _T("Too many parameters - %s\n")
 #define PATH_NOT_FOUND         _T("Path not found\n")
@@ -95,6 +96,10 @@ VOID ErrorMessage (DWORD dwErrorCode, LPTSTR szFormat, ...)
 #endif
 }
 
+VOID error_parameter_format(TCHAR ch)
+{
+       ConErrPrintf (PARAMETERF_ERROR, ch);
+}
 
 
 VOID error_invalid_switch (TCHAR ch)
index 62ab3b9..9d3bafe 100644 (file)
  *
  *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
  *        Improved chdir/cd command.
+ *
+ *    02-Apr-2004 (Magnus Olsen <magnus@greatlord.com>)
+ *        Remove all hard code string so they can be 
+ *               translate to other langues.
  */
 
 #include "precomp.h"
-
+#include "resource.h"
 
 #ifdef INCLUDE_CMD_CHDIR
 
@@ -154,21 +158,15 @@ INT cmd_chdir (LPTSTR cmd, LPTSTR param)
        LPTSTR lpOldPath;
        LPTSTR endofstring; /* pointer to the null character in the directory to change to */
        LPTSTR lastquote; /* pointer to the last quotation mark in the directory to change to */
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        /*Should we better declare a variable containing _tsclen(dir) ? It's used a few times,
          but on the other hand paths are generally not very long*/
 
        if (!_tcsncmp (param, _T("/?"), 2))
-       {
-               ConOutPuts (_T("Changes the current directory or displays it's name\n\n"
-                                          "CHDIR [drive:][path]\n"
-                                          "CHDIR[..|-]\n"
-                                          "CD [drive:][path]\n"
-                                          "CD[..|-]\n\n"
-                                          "  ..   parent directory\n"
-                                          "  -    previous directory\n\n"
-                                          "Type CD drive: to display the current directory on the specified drive.\n"
-                                          "Type CD without a parameter to display the current drive and directory."));
+       {               
+               LoadString( GetModuleHandle(NULL), STRING_CD_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
@@ -281,12 +279,13 @@ INT cmd_mkdir (LPTSTR cmd, LPTSTR param)
        LPTSTR place;   /* used to search for the \ when no space is used */
        LPTSTR *p = NULL;
        INT argc;
-
+    WCHAR szMsg[RC_STRING_MAX_SIZE];
 
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Creates a directory.\n\n"
-                                          "MKDIR [drive:]path\nMD [drive:]path"));
+               LoadString( GetModuleHandle(NULL), STRING_MKDIR_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
+
                return 0;
        }
 
@@ -321,7 +320,8 @@ INT cmd_mkdir (LPTSTR cmd, LPTSTR param)
 
        if (!dir)
        {
-               ConErrPrintf (_T("Required parameter missing\n"));
+               LoadString( GetModuleHandle(NULL), STRING_PARAM_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+               ConErrPrintf (_T((LPTSTR)szMsg));
                return 1;
        }
 
@@ -357,10 +357,15 @@ INT cmd_rmdir (LPTSTR cmd, LPTSTR param)
        LPTSTR *p = NULL;
        INT argc;
 
+       
+    WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Removes a directory.\n\n"
-                                          "RMDIR [drive:]path\nRD [drive:]path"));
+               LoadString( GetModuleHandle(NULL), STRING_RMDIR_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+
+               ConOutPuts (_T((LPTSTR)szMsg));
+
                return 0;
        }
 
@@ -394,7 +399,9 @@ INT cmd_rmdir (LPTSTR cmd, LPTSTR param)
 
        if (!dir)
        {
-               ConErrPrintf (_T("Required parameter missing\n"));
+               LoadString( GetModuleHandle(NULL), STRING_PARAM_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
+               ConErrPrintf (_T((LPTSTR)szMsg));
+
                return 1;
        }
 
@@ -423,9 +430,12 @@ INT cmd_rmdir (LPTSTR cmd, LPTSTR param)
  */
 INT CommandExit (LPTSTR cmd, LPTSTR param)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Exits the command line interpreter.\n\nEXIT"));
+               LoadString( GetModuleHandle(NULL), STRING_EXIT_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+        ConOutPuts (_T((LPTSTR)szMsg));
                return 0;
        }
 
@@ -441,10 +451,12 @@ INT CommandExit (LPTSTR cmd, LPTSTR param)
  */
 INT CommandRem (LPTSTR cmd, LPTSTR param)
 {
+       WCHAR szMsg[RC_STRING_MAX_SIZE];
+
        if (!_tcsncmp (param, _T("/?"), 2))
        {
-               ConOutPuts (_T("Starts a comment line in a batch file.\n\n"
-                              "REM [Comment]"));
+         LoadString( GetModuleHandle(NULL), STRING_REM_HELP, (LPTSTR) szMsg,sizeof(szMsg));
+      ConOutPuts (_T((LPTSTR)szMsg));
        }
 
        return 0;
index d2e970a..d8991b3 100644 (file)
@@ -9,6 +9,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <math.h>
 
 #include "cmd.h"
 #include "config.h"
index c3f80a0..f3252f6 100644 (file)
Binary files a/reactos/subsys/system/cmd/res/terminal.ico and b/reactos/subsys/system/cmd/res/terminal.ico differ
diff --git a/reactos/subsys/system/cmd/resource.h b/reactos/subsys/system/cmd/resource.h
new file mode 100644 (file)
index 0000000..5a8814c
--- /dev/null
@@ -0,0 +1,95 @@
+#define RC_STRING_MAX_SIZE                 2048\r
+\r
+#define STRING_CHOICE_OPTION               200\r
+#define STRING_COPY_OPTION                 201\r
+#define STRING_DEL_OPTION                  202\r
+\r
+#define STRING_ALIAS_ERROR                 300\r
+#define STRING_BATCH_ERROR                 301\r
+#define STRING_CHCP_ERROR1                 302 \r
+#define STRING_CHCP_ERROR2                 303\r
+#define STRING_CHCP_ERROR3                 304\r
+#define STRING_CHCP_ERROR4                 305\r
+#define STRING_CHOICE_ERROR                306\r
+#define STRING_CHOICE_ERROR_TXT            307\r
+#define STRING_CHOICE_ERROR_OPTION         308\r
+#define STRING_CMD_ERROR1                  309\r
+#define STRING_CMD_ERROR2                  310\r
+#define STRING_CMD_ERROR3                  311\r
+#define STRING_CMD_ERROR4                  312\r
+#define STRING_CMD_ERROR5                  313\r
+#define STRING_COLOR_ERROR1                314\r
+#define STRING_COLOR_ERROR2                315\r
+#define STRING_COLOR_ERROR3                316\r
+#define STRING_COLOR_ERROR4                317\r
+#define STRING_CONSOLE_ERROR               318\r
+#define STRING_COPY_ERROR1                 319\r
+#define STRING_COPY_ERROR2                 320\r
+#define STRING_COPY_ERROR3                 321\r
+#define STRING_COPY_ERROR4                 322\r
+#define STRING_DATE_ERROR                  323\r
+#define STRING_DEL_ERROR1                  324\r
+#define STRING_DEL_ERROR2                  325\r
+#define STRING_DEL_ERROR3                  326\r
+#define STRING_DEL_ERROR4                  327\r
+#define STRING_DEL_ERROR5                  328\r
+#define STRING_DEL_ERROR6                  329\r
+#define STRING_DEL_ERROR7                  330\r
+#define STRING_DEL_ERROR8                  331\r
+#define STRING_PARAM_ERROR                 332\r
+\r
+#define STRING_ATTRIB_HELP                 400\r
+#define STRING_ALIAS_HELP                  401\r
+#define STRING_BEEP_HELP                   402\r
+#define STRING_CALL_HELP                   403\r
+#define STRING_CD_HELP                     404\r
+#define STRING_CHCP_HELP                   405\r
+#define STRING_CHOICE_HELP                 406\r
+#define STRING_CLS_HELP                    407\r
+#define STRING_CMD_HELP1                   408 \r
+#define STRING_CMD_HELP2                   409\r
+#define STRING_CMD_HELP3                   410\r
+#define STRING_CMD_HELP4                   411\r
+#define STRING_CMD_HELP5                   412\r
+#define STRING_CMD_HELP6                   413\r
+#define STRING_CMD_HELP7                   414\r
+#define STRING_CMD_HELP8                   415\r
+#define STRING_COLOR_HELP1                 416\r
+#define STRING_COPY_HELP1                  417\r
+#define STRING_COPY_HELP2                  418\r
+#define STRING_DATE_HELP1                  419\r
+#define STRING_DATE_HELP2                  420\r
+#define STRING_DATE_HELP3                  421\r
+#define STRING_DATE_HELP4                  422\r
+#define STRING_DEL_HELP1                   423\r
+#define STRING_DEL_HELP2                      424\r
+#define STRING_DEL_HELP3                   425\r
+#define STRING_DEL_HELP4                   426\r
+#define STRING_DELAY_HELP                  427 \r
+\r
+#define STRING_DIR_HELP1                   428 \r
+#define STRING_DIR_HELP2                   429\r
+#define STRING_DIR_HELP3                   430\r
+#define STRING_DIR_HELP4                   431\r
+#define STRING_DIR_HELP5                   432\r
+#define STRING_DIR_HELP6                   433\r
+#define STRING_DIR_HELP7                   434\r
+#define STRING_DIR_HELP8                   435\r
+\r
+#define STRING_DIRSTACK_HELP1              436\r
+#define STRING_DIRSTACK_HELP2              437\r
+#define STRING_DIRSTACK_HELP3              438\r
+#define STRING_DIRSTACK_HELP4              439\r
+\r
+#define STRING_EXIT_HELP                   440\r
+#define STRING_MKDIR_HELP                  441\r
+#define STRING_RMDIR_HELP                  442\r
+#define STRING_REM_HELP                    443\r
+\r
+\r
+\r
+  \r
+\r
+\r
+\r
+\r
index c125759..3a9826f 100644 (file)
@@ -5,8 +5,6 @@ Fix bugs :)
 Optimize the code!  For size and speed.  There are numerous places
 where the code is hardly optimal for either.
 
-Sorting in DIR command ("dir /o...").
-
 ^S and ^Q to pause/resume displays.
 
 Improve DEL, COPY and MOVE commands.
diff --git a/reactos/subsys/system/dhcp/Makefile b/reactos/subsys/system/dhcp/Makefile
new file mode 100644 (file)
index 0000000..34974ee
--- /dev/null
@@ -0,0 +1,30 @@
+#
+
+PATH_TO_TOP = ../../..
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE =  windows
+
+TARGET_NAME = dhcp
+
+TARGET_CFLAGS = -D__REACTOS__ -D_WIN32_WINNT=0x0501 -D__USE_W32API -Iinclude
+
+TARGET_OBJECTS = adapter.o alloc.o compat.o dhclient.o dispatch.o hash.o \
+               options.o privsep.o socket.o tables.o timer.o util.o
+
+TARGET_SDKLIBS = iphlpapi.a ws2_32.a ntdll.a
+
+TARGET_RC_SRCS = dhcp.rc
+
+TARGET_RC_BINSRC = 
+
+TARGET_RC_BINARIES = 
+
+default: all
+DEP_OBJECTS = $(TARGET_OBJECTS)
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+include $(TOOLS_PATH)/depend.mk
diff --git a/reactos/subsys/system/dhcp/adapter.c b/reactos/subsys/system/dhcp/adapter.c
new file mode 100644 (file)
index 0000000..9edbfc2
--- /dev/null
@@ -0,0 +1,165 @@
+#include "rosdhcp.h"
+
+static LIST_ENTRY AdapterList;
+static WSADATA wsd;
+extern struct interface_info *ifi;
+
+DWORD GetAddress( PDHCP_ADAPTER Adapter ) {
+    PMIB_IPADDRTABLE AddressTable = NULL;
+    ULONG i, Size = 0, NumAddressRows;
+    DWORD Error = GetIpAddrTable( AddressTable, &Size, FALSE );
+
+    while( Error == ERROR_INSUFFICIENT_BUFFER ) {
+        free( AddressTable );
+        AddressTable = malloc( Size );
+        if( AddressTable ) 
+            Error = GetIpAddrTable( AddressTable, &Size, FALSE );
+    }
+    if( Error != ERROR_SUCCESS ) {
+        free( AddressTable );
+        return Error;
+    }
+
+    NumAddressRows = Size / sizeof(MIB_IPADDRTABLE);
+    for( i = 0; i < AddressTable->dwNumEntries; i++ ) {
+        DH_DbgPrint(MID_TRACE,
+                    ("Finding address for adapter %d: (%d -> %x)\n", 
+                     Adapter->IfMib.dwIndex, 
+                     AddressTable->table[i].dwIndex,
+                     AddressTable->table[i].dwAddr));
+        if( Adapter->IfMib.dwIndex == AddressTable->table[i].dwIndex ) {
+            memcpy( &Adapter->IfAddr, &AddressTable->table[i],
+                    sizeof( MIB_IPADDRROW ) );
+        }
+    }
+}
+
+void AdapterInit() {
+    PMIB_IFTABLE Table = malloc(sizeof(MIB_IFTABLE));
+    DWORD Error, Size, i;
+    PDHCP_ADAPTER Adapter = NULL;
+
+    WSAStartup(0x0101,&wsd);
+
+    InitializeListHead( &AdapterList );
+
+    DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
+
+    while( (Error = GetIfTable(Table, &Size, 0 )) == 
+           ERROR_INSUFFICIENT_BUFFER ) {
+        DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
+        free( Table );
+        Table = malloc( Size );
+    }
+
+    if( Error != NO_ERROR ) goto term;
+
+    DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
+
+    for( i = 0; i < Table->dwNumEntries; i++ ) {
+        DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n", i));
+        Adapter = calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
+        
+        if( Adapter ) {
+            memcpy( &Adapter->IfMib, &Table->table[i], 
+                    sizeof(Adapter->IfMib) );
+            GetAddress( Adapter );
+            InsertTailList( &AdapterList, &Adapter->ListEntry );
+            Adapter->DhclientInfo.next = ifi;
+            Adapter->DhclientInfo.client = &Adapter->DhclientState;
+            Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
+            Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
+            Adapter->DhclientInfo.rbuf_len = 
+                Adapter->DhclientInfo.rbuf_offset = 0;
+            Adapter->DhclientInfo.rfdesc = 
+                Adapter->DhclientInfo.wfdesc =
+                socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+            Adapter->ListenAddr.sin_family = AF_INET;
+            Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
+            Adapter->BindStatus = 
+                (bind( Adapter->DhclientInfo.rfdesc,
+                       (struct sockaddr *)&Adapter->ListenAddr,
+                       sizeof(Adapter->ListenAddr) ) == 0) ?
+                0 : WSAGetLastError();
+            Adapter->DhclientState.config = &Adapter->DhclientConfig;
+            Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
+            Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
+            Adapter->DhclientConfig.select_interval = 1;
+            Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
+            Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
+            Adapter->DhclientState.interval = 
+                Adapter->DhclientConfig.retry_interval;
+            strncpy(Adapter->DhclientInfo.name, Adapter->IfMib.bDescr,
+                    sizeof(Adapter->DhclientInfo.name));
+            DH_DbgPrint(MID_TRACE,("Adapter Name: [%s] (Bind Status %x)\n", 
+                                   Adapter->DhclientInfo.name,
+                                   Adapter->BindStatus));
+            ifi = &Adapter->DhclientInfo;
+        }
+    }
+
+    DH_DbgPrint(MID_TRACE,("done with AdapterInit\n"));
+
+term:
+    if( Table ) free( Table );
+}
+
+void AdapterStop() {
+    PLIST_ENTRY ListEntry;
+    PDHCP_ADAPTER Adapter;
+    while( !IsListEmpty( &AdapterList ) ) {
+        ListEntry = (PLIST_ENTRY)RemoveHeadList( &AdapterList );
+        Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
+        free( Adapter );
+    }
+    WSACleanup();
+}
+
+PDHCP_ADAPTER AdapterFindIndex( unsigned int indx ) {
+    PDHCP_ADAPTER Adapter;
+    PLIST_ENTRY ListEntry;
+
+    for( ListEntry = AdapterList.Flink;
+         ListEntry != &AdapterList;
+         ListEntry = ListEntry->Flink ) {
+        Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
+        if( Adapter->IfMib.dwIndex == indx ) return Adapter;
+    }
+
+    return NULL;
+}
+
+PDHCP_ADAPTER AdapterFindName( const WCHAR *name ) {
+    PDHCP_ADAPTER Adapter;
+    PLIST_ENTRY ListEntry;
+
+    for( ListEntry = AdapterList.Flink;
+         ListEntry != &AdapterList;
+         ListEntry = ListEntry->Flink ) {
+        Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
+        if( !wcsicmp( Adapter->IfMib.wszName, name ) ) return Adapter;
+    }
+
+    return NULL;
+}
+
+PDHCP_ADAPTER AdapterGetFirst() {
+    if( IsListEmpty( &AdapterList ) ) return NULL; else {
+        return CONTAINING_RECORD
+            ( AdapterList.Flink, DHCP_ADAPTER, ListEntry );
+    }
+}
+
+PDHCP_ADAPTER AdapterGetNext( PDHCP_ADAPTER This ) 
+{ 
+    if( This->ListEntry.Flink == &AdapterList ) return NULL;
+    return CONTAINING_RECORD
+        ( This->ListEntry.Flink, DHCP_ADAPTER, ListEntry );
+}
+
+void if_register_send(struct interface_info *ip) {
+    
+}
+
+void if_register_receive(struct interface_info *ip) {
+}
diff --git a/reactos/subsys/system/dhcp/alloc.c b/reactos/subsys/system/dhcp/alloc.c
new file mode 100644 (file)
index 0000000..5894a96
--- /dev/null
@@ -0,0 +1,79 @@
+/*     $OpenBSD: alloc.c,v 1.9 2004/05/04 20:28:40 deraadt Exp $       */
+
+/* Memory allocation... */
+
+/*
+ * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#include "rosdhcp.h"
+#include "dhcpd.h"
+
+struct string_list *
+new_string_list(size_t size)
+{
+       struct string_list *rval;
+
+       rval = calloc(1, sizeof(struct string_list) + size);
+       if (rval != NULL)
+               rval->string = ((char *)rval) + sizeof(struct string_list);
+       return (rval);
+}
+
+struct hash_table *
+new_hash_table(int count)
+{
+       struct hash_table *rval;
+
+       rval = calloc(1, sizeof(struct hash_table) -
+           (DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *)) +
+           (count * sizeof(struct hash_bucket *)));
+       if (rval == NULL)
+               return (NULL);
+       rval->hash_count = count;
+       return (rval);
+}
+
+struct hash_bucket *
+new_hash_bucket(void)
+{
+       struct hash_bucket *rval = calloc(1, sizeof(struct hash_bucket));
+
+       return (rval);
+}
+
+void free_hash_bucket(struct hash_bucket *hb) { free(hb); }
diff --git a/reactos/subsys/system/dhcp/compat.c b/reactos/subsys/system/dhcp/compat.c
new file mode 100644 (file)
index 0000000..34ed1d4
--- /dev/null
@@ -0,0 +1,40 @@
+#include "rosdhcp.h"
+#include "dhcpd.h"
+#include "stdint.h"
+
+size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+        size_t len = strlen(s);
+        size_t ret = len;
+        if (bufsize > 0) {
+                if (len >= bufsize)
+                        len = bufsize-1;
+                memcpy(d, s, len);
+                d[len] = 0;
+        }
+        return ret;
+}
+
+// not really random :(
+u_int32_t arc4random()
+{
+       static int did_srand = 0;
+       u_int32_t ret;
+
+       if (!did_srand) {
+               srand(0);
+               did_srand = 1;
+       }
+
+       ret = rand() << 10 ^ rand();
+       return ret;
+}
+
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+       inp->S_un.S_addr = inet_addr(cp);
+       if (INADDR_NONE == inp->S_un.S_addr)
+               return 0;
+
+       return 1;
+}
diff --git a/reactos/subsys/system/dhcp/design.txt b/reactos/subsys/system/dhcp/design.txt
new file mode 100644 (file)
index 0000000..17c9a29
--- /dev/null
@@ -0,0 +1,33 @@
+Acknowledgements:
+
+       Tinus provided the initial port of these dhclient file.
+
+Ok I need these things:
+
+1) Adapter concept thingy
+
+  Needs a name and index
+  Current IP address etc
+  interface_info
+
+  Must be able to get one from an adapter index or name
+  Must query the ip address and such
+  Must be able to set the address
+
+2) System state doodad
+
+  List of adapters
+  List of parameter changes
+  List of persistent stuff
+  
+  Must be able to initialize from the registry 
+  (persistent stuff, some adapter info)
+  Save changes to persistent set
+
+3) Parameter change set
+
+  TODO  
+
+4) Persistent queries
+
+  TODO
\ No newline at end of file
diff --git a/reactos/subsys/system/dhcp/dhclient.c b/reactos/subsys/system/dhcp/dhclient.c
new file mode 100644 (file)
index 0000000..9ead8b8
--- /dev/null
@@ -0,0 +1,2308 @@
+/*     $OpenBSD: dhclient.c,v 1.62 2004/12/05 18:35:51 deraadt Exp $   */
+
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+
+#include <winsock2.h>
+#include "rosdhcp.h"
+#include "dhcpd.h"
+#include "privsep.h"
+
+#define        PERIOD 0x2e
+#define        hyphenchar(c) ((c) == 0x2d)
+#define        bslashchar(c) ((c) == 0x5c)
+#define        periodchar(c) ((c) == PERIOD)
+#define        asterchar(c) ((c) == 0x2a)
+#define        alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \
+           ((c) >= 0x61 && (c) <= 0x7a))
+#define        digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define        borderchar(c) (alphachar(c) || digitchar(c))
+#define        middlechar(c) (borderchar(c) || hyphenchar(c))
+#define        domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+unsigned long debug_trace_level = DEBUG_ULTRA;
+time_t cur_time;
+time_t default_lease_time = 43200; /* 12 hours... */
+
+char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
+char *path_dhclient_db = NULL;
+
+int log_perror = 1;
+int privfd;
+//int nullfd = -1;
+
+struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
+struct in_addr inaddr_any;
+struct sockaddr_in sockaddr_broadcast;
+
+/*
+ * ASSERT_STATE() does nothing now; it used to be
+ * assert (state_is == state_shouldbe).
+ */
+#define ASSERT_STATE(state_is, state_shouldbe) {}
+
+#define TIME_MAX 2147483647
+
+int            log_priority;
+int            no_daemon;
+int            unknown_ok = 1;
+int            routefd;
+
+struct interface_info  *ifi = NULL;
+
+void            usage(void);
+int             check_option(struct client_lease *l, int option);
+int             ipv4addrs(char * buf);
+int             res_hnok(const char *dn);
+char           *option_as_string(unsigned int code, unsigned char *data, int len);
+int             fork_privchld(int, int);
+
+#define        ROUNDUP(a) \
+           ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define        ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+time_t scripttime;
+
+#if 0
+
+int
+findproto(char *cp, int n)
+{
+       struct sockaddr *sa;
+       int i;
+
+       if (n == 0)
+               return -1;
+       for (i = 1; i; i <<= 1) {
+               if (i & n) {
+                       sa = (struct sockaddr *)cp;
+                       switch (i) {
+                       case RTA_IFA:
+                       case RTA_DST:
+                       case RTA_GATEWAY:
+                       case RTA_NETMASK:
+                               if (sa->sa_family == AF_INET)
+                                       return AF_INET;
+                               if (sa->sa_family == AF_INET6)
+                                       return AF_INET6;
+                               break;
+                       case RTA_IFP:
+                               break;
+                       }
+                       ADVANCE(cp, sa);
+               }
+       }
+       return (-1);
+}
+
+
+struct sockaddr *
+get_ifa(char *cp, int n)
+{
+       struct sockaddr *sa;
+       int i;
+
+       if (n == 0)
+               return (NULL);
+       for (i = 1; i; i <<= 1)
+               if (i & n) {
+                       sa = (struct sockaddr *)cp;
+                       if (i == RTA_IFA)
+                               return (sa);
+                       ADVANCE(cp, sa);
+               }
+
+       return (NULL);
+}
+struct iaddr defaddr = { 4 };
+
+/* ARGSUSED */
+void
+routehandler(struct protocol *p)
+{
+       char msg[2048];
+       struct rt_msghdr *rtm;
+       struct if_msghdr *ifm;
+       struct ifa_msghdr *ifam;
+       struct if_announcemsghdr *ifan;
+       struct client_lease *l;
+       time_t t = time(NULL);
+       struct sockaddr *sa;
+       struct iaddr a;
+       ssize_t n;
+
+       n = read(routefd, &msg, sizeof(msg));
+       rtm = (struct rt_msghdr *)msg;
+       if (n < sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen ||
+           rtm->rtm_version != RTM_VERSION)
+               return;
+
+       switch (rtm->rtm_type) {
+       case RTM_NEWADDR:
+               ifam = (struct ifa_msghdr *)rtm;
+               if (ifam->ifam_index != ifi->index)
+                       break;
+               if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
+                       break;
+               if (ifi == NULL)
+                       goto die;
+               sa = get_ifa((char *)(ifam + 1), ifam->ifam_addrs);
+               if (sa == NULL)
+                       goto die;
+
+               if ((a.len = sizeof(struct in_addr)) > sizeof(a.iabuf))
+                       error("king bula sez: len mismatch");
+               memcpy(a.iabuf, &((struct sockaddr_in *)sa)->sin_addr, a.len);
+               if (addr_eq(a, defaddr))
+                       break;
+
+               for (l = ifi->client->active; l != NULL; l = l->next)
+                       if (addr_eq(a, l->address))
+                               break;
+
+               if (l != NULL)  /* new addr is the one we set */
+                       break;
+
+               goto die;
+       case RTM_DELADDR:
+               ifam = (struct ifa_msghdr *)rtm;
+               if (ifam->ifam_index != ifi->index)
+                       break;
+               if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
+                       break;
+               if (scripttime == 0 || t < scripttime + 10)
+                       break;
+               goto die;
+       case RTM_IFINFO:
+               ifm = (struct if_msghdr *)rtm;
+               if (ifm->ifm_index != ifi->index)
+                       break;
+               if ((rtm->rtm_flags & RTF_UP) == 0)
+                       goto die;
+               break;
+       case RTM_IFANNOUNCE:
+               ifan = (struct if_announcemsghdr *)rtm;
+               if (ifan->ifan_what == IFAN_DEPARTURE &&
+                   ifan->ifan_index == ifi->index)
+                       goto die;
+               break;
+       default:
+               break;
+       }
+       return;
+
+die:
+       script_init("FAIL", NULL);
+       if (ifi->client->alias)
+               script_write_params("alias_", ifi->client->alias);
+       script_go();
+       exit(1);
+}
+#endif
+
+int
+main(int argc, char *argv[])
+{
+       extern char             *__progname;
+       int                      ch, fd, quiet = 0, i = 0;
+       int                      pipe_fd[2];
+       struct passwd           *pw;
+
+        AdapterInit();
+
+       tzset();
+       time(&cur_time);
+
+       memset(&sockaddr_broadcast, 0, sizeof(sockaddr_broadcast));
+       sockaddr_broadcast.sin_family = AF_INET;
+       sockaddr_broadcast.sin_port = htons(REMOTE_PORT);
+       sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
+       inaddr_any.s_addr = INADDR_ANY;
+
+        DH_DbgPrint(MID_TRACE,("DHCP Service Started\n"));
+
+       read_client_conf();
+
+       if (!interface_link_status(ifi->name)) {
+            DH_DbgPrint(MID_TRACE,("%s: no link ", ifi->name));
+            Sleep(1000);
+            while (!interface_link_status(ifi->name)) {
+                DH_DbgPrint(MID_TRACE,("."));
+                if (++i > 10) {
+                    DH_DbgPrint(MID_TRACE,("Giving up for now on adapter [%s]\n", ifi->name));
+                }
+                Sleep(1000);
+            }
+            DH_DbgPrint(MID_TRACE,("Got link on [%s]\n", ifi->name));
+       }
+
+        DH_DbgPrint(MID_TRACE,("Discover Interfaces\n"));
+
+       /* set up the interface */
+       discover_interfaces(ifi);
+
+        DH_DbgPrint
+            (MID_TRACE,
+             ("Setting init state and restarting interface %p\n",ifi));
+
+       ifi->client->state = S_INIT;
+       state_reboot(ifi);
+
+       bootp_packet_handler = do_packet;
+
+        DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
+
+       dispatch();
+
+       /* not reached */
+       return (0);
+}
+
+void
+usage(void)
+{
+//     extern char     *__progname;
+
+//     fprintf(stderr, "usage: %s [-dqu] ", __progname);
+       fprintf(stderr, "usage: dhclient [-dqu] ");
+       fprintf(stderr, "[-c conffile] [-l leasefile] interface\n");
+       exit(1);
+}
+
+/*
+ * Individual States:
+ *
+ * Each routine is called from the dhclient_state_machine() in one of
+ * these conditions:
+ * -> entering INIT state
+ * -> recvpacket_flag == 0: timeout in this state
+ * -> otherwise: received a packet in this state
+ *
+ * Return conditions as handled by dhclient_state_machine():
+ * Returns 1, sendpacket_flag = 1: send packet, reset timer.
+ * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
+ * Returns 0: finish the nap which was interrupted for no good reason.
+ *
+ * Several per-interface variables are used to keep track of the process:
+ *   active_lease: the lease that is being used on the interface
+ *                 (null pointer if not configured yet).
+ *   offered_leases: leases corresponding to DHCPOFFER messages that have
+ *                   been sent to us by DHCP servers.
+ *   acked_leases: leases corresponding to DHCPACK messages that have been
+ *                 sent to us by DHCP servers.
+ *   sendpacket: DHCP packet we're trying to send.
+ *   destination: IP address to send sendpacket to
+ * In addition, there are several relevant per-lease variables.
+ *   T1_expiry, T2_expiry, lease_expiry: lease milestones
+ * In the active lease, these control the process of renewing the lease;
+ * In leases on the acked_leases list, this simply determines when we
+ * can no longer legitimately use the lease.
+ */
+
+void
+state_reboot(void *ipp)
+{
+       struct interface_info *ip = ipp;
+
+       /* If we don't remember an active lease, go straight to INIT. */
+       if (!ip->client->active || ip->client->active->is_bootp) {
+               state_init(ip);
+               return;
+       }
+
+       /* We are in the rebooting state. */
+       ip->client->state = S_REBOOTING;
+
+       /* make_request doesn't initialize xid because it normally comes
+          from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
+          so pick an xid now. */
+       ip->client->xid = arc4random();
+
+       /* Make a DHCPREQUEST packet, and set appropriate per-interface
+          flags. */
+       make_request(ip, ip->client->active);
+       ip->client->destination = iaddr_broadcast;
+       ip->client->first_sending = cur_time;
+       ip->client->interval = ip->client->config->initial_interval;
+
+       /* Zap the medium list... */
+       ip->client->medium = NULL;
+
+       /* Send out the first DHCPREQUEST packet. */
+       send_request(ip);
+}
+
+/*
+ * Called when a lease has completely expired and we've
+ * been unable to renew it.
+ */
+void
+state_init(void *ipp)
+{
+       struct interface_info *ip = ipp;
+
+       ASSERT_STATE(state, S_INIT);
+
+       /* Make a DHCPDISCOVER packet, and set appropriate per-interface
+          flags. */
+       make_discover(ip, ip->client->active);
+       ip->client->xid = ip->client->packet.xid;
+       ip->client->destination = iaddr_broadcast;
+       ip->client->state = S_SELECTING;
+       ip->client->first_sending = cur_time;
+       ip->client->interval = ip->client->config->initial_interval;
+
+       /* Add an immediate timeout to cause the first DHCPDISCOVER packet
+          to go out. */
+       send_discover(ip);
+}
+
+/*
+ * state_selecting is called when one or more DHCPOFFER packets
+ * have been received and a configurable period of time has passed.
+ */
+void
+state_selecting(void *ipp)
+{
+       struct interface_info *ip = ipp;
+       struct client_lease *lp, *next, *picked;
+
+       ASSERT_STATE(state, S_SELECTING);
+
+       /* Cancel state_selecting and send_discover timeouts, since either
+          one could have got us here. */
+       cancel_timeout(state_selecting, ip);
+       cancel_timeout(send_discover, ip);
+
+       /* We have received one or more DHCPOFFER packets.   Currently,
+          the only criterion by which we judge leases is whether or
+          not we get a response when we arp for them. */
+       picked = NULL;
+       for (lp = ip->client->offered_leases; lp; lp = next) {
+               next = lp->next;
+
+               /* Check to see if we got an ARPREPLY for the address
+                  in this particular lease. */
+               if (!picked) {
+                       script_init("ARPCHECK", lp->medium);
+                       script_write_params("check_", lp);
+
+                       /* If the ARPCHECK code detects another
+                          machine using the offered address, it exits
+                          nonzero.  We need to send a DHCPDECLINE and
+                          toss the lease. */
+                       if (script_go()) {
+                               make_decline(ip, lp);
+                               send_decline(ip);
+                               goto freeit;
+                       }
+                       picked = lp;
+                       picked->next = NULL;
+               } else {
+freeit:
+                       free_client_lease(lp);
+               }
+       }
+       ip->client->offered_leases = NULL;
+
+       /* If we just tossed all the leases we were offered, go back
+          to square one. */
+       if (!picked) {
+               ip->client->state = S_INIT;
+               state_init(ip);
+               return;
+       }
+
+       /* If it was a BOOTREPLY, we can just take the address right now. */
+       if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
+               ip->client->new = picked;
+
+               /* Make up some lease expiry times
+                  XXX these should be configurable. */
+               ip->client->new->expiry = cur_time + 12000;
+               ip->client->new->renewal += cur_time + 8000;
+               ip->client->new->rebind += cur_time + 10000;
+
+               ip->client->state = S_REQUESTING;
+
+               /* Bind to the address we received. */
+               bind_lease(ip);
+               return;
+       }
+
+       /* Go to the REQUESTING state. */
+       ip->client->destination = iaddr_broadcast;
+       ip->client->state = S_REQUESTING;
+       ip->client->first_sending = cur_time;
+       ip->client->interval = ip->client->config->initial_interval;
+
+       /* Make a DHCPREQUEST packet from the lease we picked. */
+       make_request(ip, picked);
+       ip->client->xid = ip->client->packet.xid;
+
+       /* Toss the lease we picked - we'll get it back in a DHCPACK. */
+       free_client_lease(picked);
+
+       /* Add an immediate timeout to send the first DHCPREQUEST packet. */
+       send_request(ip);
+}
+
+/* state_requesting is called when we receive a DHCPACK message after
+   having sent out one or more DHCPREQUEST packets. */
+
+void
+dhcpack(struct packet *packet)
+{
+       struct interface_info *ip = packet->interface;
+       struct client_lease *lease;
+
+       /* If we're not receptive to an offer right now, or if the offer
+          has an unrecognizable transaction id, then just drop it. */
+       if (packet->interface->client->xid != packet->raw->xid ||
+           (packet->interface->hw_address.hlen != packet->raw->hlen) ||
+           (memcmp(packet->interface->hw_address.haddr,
+           packet->raw->chaddr, packet->raw->hlen)))
+               return;
+
+       if (ip->client->state != S_REBOOTING &&
+           ip->client->state != S_REQUESTING &&
+           ip->client->state != S_RENEWING &&
+           ip->client->state != S_REBINDING)
+               return;
+
+       note("DHCPACK from %s", piaddr(packet->client_addr));
+
+       lease = packet_to_lease(packet);
+       if (!lease) {
+               note("packet_to_lease failed.");
+               return;
+       }
+
+       ip->client->new = lease;
+
+       /* Stop resending DHCPREQUEST. */
+       cancel_timeout(send_request, ip);
+
+       /* Figure out the lease time. */
+       if (ip->client->new->options[DHO_DHCP_LEASE_TIME].data)
+               ip->client->new->expiry = getULong(
+                   ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
+       else
+               ip->client->new->expiry = default_lease_time;
+       /* A number that looks negative here is really just very large,
+          because the lease expiry offset is unsigned. */
+       if (ip->client->new->expiry < 0)
+               ip->client->new->expiry = TIME_MAX;
+       /* XXX should be fixed by resetting the client state */
+       if (ip->client->new->expiry < 60)
+               ip->client->new->expiry = 60;
+
+       /* Take the server-provided renewal time if there is one;
+          otherwise figure it out according to the spec. */
+       if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len)
+               ip->client->new->renewal = getULong(
+                   ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
+       else
+               ip->client->new->renewal = ip->client->new->expiry / 2;
+
+       /* Same deal with the rebind time. */
+       if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len)
+               ip->client->new->rebind = getULong(
+                   ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
+       else
+               ip->client->new->rebind = ip->client->new->renewal +
+                   ip->client->new->renewal / 2 + ip->client->new->renewal / 4;
+
+       ip->client->new->expiry += cur_time;
+       /* Lease lengths can never be negative. */
+       if (ip->client->new->expiry < cur_time)
+               ip->client->new->expiry = TIME_MAX;
+       ip->client->new->renewal += cur_time;
+       if (ip->client->new->renewal < cur_time)
+               ip->client->new->renewal = TIME_MAX;
+       ip->client->new->rebind += cur_time;
+       if (ip->client->new->rebind < cur_time)
+               ip->client->new->rebind = TIME_MAX;
+
+       bind_lease(ip);
+}
+
+void
+bind_lease(struct interface_info *ip)
+{
+       /* Remember the medium. */
+       ip->client->new->medium = ip->client->medium;
+
+       /* Write out the new lease. */
+       write_client_lease(ip, ip->client->new, 0);
+
+       /* Run the client script with the new parameters. */
+       script_init((ip->client->state == S_REQUESTING ? "BOUND" :
+           (ip->client->state == S_RENEWING ? "RENEW" :
+           (ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
+           ip->client->new->medium);
+       if (ip->client->active && ip->client->state != S_REBOOTING)
+               script_write_params("old_", ip->client->active);
+       script_write_params("new_", ip->client->new);
+       if (ip->client->alias)
+               script_write_params("alias_", ip->client->alias);
+       script_go();
+
+       /* Replace the old active lease with the new one. */
+       if (ip->client->active)
+               free_client_lease(ip->client->active);
+       ip->client->active = ip->client->new;
+       ip->client->new = NULL;
+
+       /* Set up a timeout to start the renewal process. */
+       add_timeout(ip->client->active->renewal, state_bound, ip);
+
+       note("bound to %s -- renewal in %d seconds.",
+           piaddr(ip->client->active->address),
+           ip->client->active->renewal - cur_time);
+       ip->client->state = S_BOUND;
+       reinitialize_interfaces();
+//     go_daemon();
+}
+
+/*
+ * state_bound is called when we've successfully bound to a particular
+ * lease, but the renewal time on that lease has expired.   We are
+ * expected to unicast a DHCPREQUEST to the server that gave us our
+ * original lease.
+ */
+void
+state_bound(void *ipp)
+{
+       struct interface_info *ip = ipp;
+
+       ASSERT_STATE(state, S_BOUND);
+
+       /* T1 has expired. */
+       make_request(ip, ip->client->active);
+       ip->client->xid = ip->client->packet.xid;
+
+       if (ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
+               memcpy(ip->client->destination.iabuf, ip->client->active->
+                   options[DHO_DHCP_SERVER_IDENTIFIER].data, 4);
+               ip->client->destination.len = 4;
+       } else
+               ip->client->destination = iaddr_broadcast;
+
+       ip->client->first_sending = cur_time;
+       ip->client->interval = ip->client->config->initial_interval;
+       ip->client->state = S_RENEWING;
+
+       /* Send the first packet immediately. */
+       send_request(ip);
+}
+
+void
+bootp(struct packet *packet)
+{
+       struct iaddrlist *ap;
+
+       if (packet->raw->op != BOOTREPLY)
+               return;
+
+       /* If there's a reject list, make sure this packet's sender isn't
+          on it. */
+       for (ap = packet->interface->client->config->reject_list;
+           ap; ap = ap->next) {
+               if (addr_eq(packet->client_addr, ap->addr)) {
+                       note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
+                       return;
+               }
+       }
+       dhcpoffer(packet);
+}
+
+void
+dhcp(struct packet *packet)
+{
+       struct iaddrlist *ap;
+       void (*handler)(struct packet *);
+       char *type;
+
+       switch (packet->packet_type) {
+       case DHCPOFFER:
+               handler = dhcpoffer;
+               type = "DHCPOFFER";
+               break;
+       case DHCPNAK:
+               handler = dhcpnak;
+               type = "DHCPNACK";
+               break;
+       case DHCPACK:
+               handler = dhcpack;
+               type = "DHCPACK";
+               break;
+       default:
+               return;
+       }
+
+       /* If there's a reject list, make sure this packet's sender isn't
+          on it. */
+       for (ap = packet->interface->client->config->reject_list;
+           ap; ap = ap->next) {
+               if (addr_eq(packet->client_addr, ap->addr)) {
+                       note("%s from %s rejected.", type, piaddr(ap->addr));
+                       return;
+               }
+       }
+       (*handler)(packet);
+}
+
+void
+dhcpoffer(struct packet *packet)
+{
+       struct interface_info *ip = packet->interface;
+       struct client_lease *lease, *lp;
+       int i;
+       int arp_timeout_needed, stop_selecting;
+       char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
+           "DHCPOFFER" : "BOOTREPLY";
+
+       /* If we're not receptive to an offer right now, or if the offer
+          has an unrecognizable transaction id, then just drop it. */
+       if (ip->client->state != S_SELECTING ||
+           packet->interface->client->xid != packet->raw->xid ||
+           (packet->interface->hw_address.hlen != packet->raw->hlen) ||
+           (memcmp(packet->interface->hw_address.haddr,
+           packet->raw->chaddr, packet->raw->hlen)))
+               return;
+
+       note("%s from %s", name, piaddr(packet->client_addr));
+
+
+       /* If this lease doesn't supply the minimum required parameters,
+          blow it off. */
+       for (i = 0; ip->client->config->required_options[i]; i++) {
+               if (!packet->options[ip->client->config->
+                   required_options[i]].len) {
+                       note("%s isn't satisfactory.", name);
+                       return;
+               }
+       }
+
+       /* If we've already seen this lease, don't record it again. */
+       for (lease = ip->client->offered_leases;
+           lease; lease = lease->next) {
+               if (lease->address.len == sizeof(packet->raw->yiaddr) &&
+                   !memcmp(lease->address.iabuf,
+                   &packet->raw->yiaddr, lease->address.len)) {
+                       debug("%s already seen.", name);
+                       return;
+               }
+       }
+
+       lease = packet_to_lease(packet);
+       if (!lease) {
+               note("packet_to_lease failed.");
+               return;
+       }
+
+       /* If this lease was acquired through a BOOTREPLY, record that
+          fact. */
+       if (!packet->options[DHO_DHCP_MESSAGE_TYPE].len)
+               lease->is_bootp = 1;
+
+       /* Record the medium under which this lease was offered. */
+       lease->medium = ip->client->medium;
+
+       /* Send out an ARP Request for the offered IP address. */
+       script_init("ARPSEND", lease->medium);
+       script_write_params("check_", lease);
+       /* If the script can't send an ARP request without waiting,
+          we'll be waiting when we do the ARPCHECK, so don't wait now. */
+       if (script_go())
+               arp_timeout_needed = 0;
+       else
+               arp_timeout_needed = 2;
+
+       /* Figure out when we're supposed to stop selecting. */
+       stop_selecting =
+           ip->client->first_sending + ip->client->config->select_interval;
+
+       /* If this is the lease we asked for, put it at the head of the
+          list, and don't mess with the arp request timeout. */
+       if (lease->address.len == ip->client->requested_address.len &&
+           !memcmp(lease->address.iabuf,
+           ip->client->requested_address.iabuf,
+           ip->client->requested_address.len)) {
+               lease->next = ip->client->offered_leases;
+               ip->client->offered_leases = lease;
+       } else {
+               /* If we already have an offer, and arping for this
+                  offer would take us past the selection timeout,
+                  then don't extend the timeout - just hope for the
+                  best. */
+               if (ip->client->offered_leases &&
+                   (cur_time + arp_timeout_needed) > stop_selecting)
+                       arp_timeout_needed = 0;
+
+               /* Put the lease at the end of the list. */
+               lease->next = NULL;
+               if (!ip->client->offered_leases)
+                       ip->client->offered_leases = lease;
+               else {
+                       for (lp = ip->client->offered_leases; lp->next;
+                           lp = lp->next)
+                               ;       /* nothing */
+                       lp->next = lease;
+               }
+       }
+
+       /* If we're supposed to stop selecting before we've had time
+          to wait for the ARPREPLY, add some delay to wait for
+          the ARPREPLY. */
+       if (stop_selecting - cur_time < arp_timeout_needed)
+               stop_selecting = cur_time + arp_timeout_needed;
+
+       /* If the selecting interval has expired, go immediately to
+          state_selecting().  Otherwise, time out into
+          state_selecting at the select interval. */
+       if (stop_selecting <= 0)
+               state_selecting(ip);
+       else {
+               add_timeout(stop_selecting, state_selecting, ip);
+               cancel_timeout(send_discover, ip);
+       }
+}
+
+/* Allocate a client_lease structure and initialize it from the parameters
+   in the specified packet. */
+
+struct client_lease *
+packet_to_lease(struct packet *packet)
+{
+       struct client_lease *lease;
+       int i;
+
+       lease = malloc(sizeof(struct client_lease));
+
+       if (!lease) {
+               warning("dhcpoffer: no memory to record lease.");
+               return (NULL);
+       }
+
+       memset(lease, 0, sizeof(*lease));
+
+       /* Copy the lease options. */
+       for (i = 0; i < 256; i++) {
+               if (packet->options[i].len) {
+                       lease->options[i].data =
+                           malloc(packet->options[i].len + 1);
+                       if (!lease->options[i].data) {
+                               warning("dhcpoffer: no memory for option %d", i);
+                               free_client_lease(lease);
+                               return (NULL);
+                       } else {
+                               memcpy(lease->options[i].data,
+                                   packet->options[i].data,
+                                   packet->options[i].len);
+                               lease->options[i].len =
+                                   packet->options[i].len;
+                               lease->options[i].data[lease->options[i].len] =
+                                   0;
+                       }
+                       if (!check_option(lease,i)) {
+                               /* ignore a bogus lease offer */
+                               warning("Invalid lease option - ignoring offer");
+                               free_client_lease(lease);
+                               return (NULL);
+                       }
+               }
+       }
+
+       lease->address.len = sizeof(packet->raw->yiaddr);
+       memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
+
+       /* If the server name was filled out, copy it. */
+       if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
+           !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
+           packet->raw->sname[0]) {
+               lease->server_name = malloc(DHCP_SNAME_LEN + 1);
+               if (!lease->server_name) {
+                       warning("dhcpoffer: no memory for server name.");
+                       free_client_lease(lease);
+                       return (NULL);
+               }
+               memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
+               lease->server_name[DHCP_SNAME_LEN]='\0';
+               if (!res_hnok(lease->server_name) ) {
+                       warning("Bogus server name %s",  lease->server_name );
+                       free_client_lease(lease);
+                       return (NULL);
+               }
+
+       }
+
+       /* Ditto for the filename. */
+       if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
+           !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
+           packet->raw->file[0]) {
+               /* Don't count on the NUL terminator. */
+               lease->filename = malloc(DHCP_FILE_LEN + 1);
+               if (!lease->filename) {
+                       warning("dhcpoffer: no memory for filename.");
+                       free_client_lease(lease);
+                       return (NULL);
+               }
+               memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
+               lease->filename[DHCP_FILE_LEN]='\0';
+       }
+       return lease;
+}
+
+void
+dhcpnak(struct packet *packet)
+{
+       struct interface_info *ip = packet->interface;
+
+       /* If we're not receptive to an offer right now, or if the offer
+          has an unrecognizable transaction id, then just drop it. */
+       if (packet->interface->client->xid != packet->raw->xid ||
+           (packet->interface->hw_address.hlen != packet->raw->hlen) ||
+           (memcmp(packet->interface->hw_address.haddr,
+           packet->raw->chaddr, packet->raw->hlen)))
+               return;
+
+       if (ip->client->state != S_REBOOTING &&
+           ip->client->state != S_REQUESTING &&
+           ip->client->state != S_RENEWING &&
+           ip->client->state != S_REBINDING)
+               return;
+
+       note("DHCPNAK from %s", piaddr(packet->client_addr));
+
+       if (!ip->client->active) {
+               note("DHCPNAK with no active lease.\n");
+               return;
+       }
+
+       free_client_lease(ip->client->active);
+       ip->client->active = NULL;
+
+       /* Stop sending DHCPREQUEST packets... */
+       cancel_timeout(send_request, ip);
+
+       ip->client->state = S_INIT;
+       state_init(ip);
+}
+
+/* Send out a DHCPDISCOVER packet, and set a timeout to send out another
+   one after the right interval has expired.  If we don't get an offer by
+   the time we reach the panic interval, call the panic function. */
+
+void
+send_discover(void *ipp)
+{
+       struct interface_info *ip = ipp;
+       int interval, increase = 1;
+
+        DH_DbgPrint(MID_TRACE,("Doing discover on interface %p\n",ip));
+
+       /* Figure out how long it's been since we started transmitting. */
+       interval = cur_time - ip->client->first_sending;
+
+       /* If we're past the panic timeout, call the script and tell it
+          we haven't found anything for this interface yet. */
+       if (interval > ip->client->config->timeout) {
+               state_panic(ip);
+               return;
+       }
+
+       /* If we're selecting media, try the whole list before doing
+          the exponential backoff, but if we've already received an
+          offer, stop looping, because we obviously have it right. */
+       if (!ip->client->offered_leases &&
+           ip->client->config->media) {
+               int fail = 0;
+again:
+               if (ip->client->medium) {
+                       ip->client->medium = ip->client->medium->next;
+                       increase = 0;
+               }
+               if (!ip->client->medium) {
+                       if (fail)
+                               error("No valid media types for %s!", ip->name);
+                       ip->client->medium = ip->client->config->media;
+                       increase = 1;
+               }
+
+               note("Trying medium \"%s\" %d", ip->client->medium->string,
+                   increase);
+               script_init("MEDIUM", ip->client->medium);
+               if (script_go())
+                       goto again;
+       }
+
+       /*
+        * If we're supposed to increase the interval, do so.  If it's
+        * currently zero (i.e., we haven't sent any packets yet), set
+        * it to one; otherwise, add to it a random number between zero
+        * and two times itself.  On average, this means that it will
+        * double with every transmission.
+        */
+       if (increase) {
+               if (!ip->client->interval)
+                       ip->client->interval =
+                           ip->client->config->initial_interval;
+               else {
+                       ip->client->interval += (arc4random() >> 2) %
+                           (2 * ip->client->interval);
+               }
+
+               /* Don't backoff past cutoff. */
+               if (ip->client->interval >
+                   ip->client->config->backoff_cutoff)
+                       ip->client->interval =
+                               ((ip->client->config->backoff_cutoff / 2)
+                                + ((arc4random() >> 2) %
+                                   ip->client->config->backoff_cutoff));
+       } else if (!ip->client->interval)
+               ip->client->interval =
+                       ip->client->config->initial_interval;
+
+       /* If the backoff would take us to the panic timeout, just use that
+          as the interval. */
+       if (cur_time + ip->client->interval >
+           ip->client->first_sending + ip->client->config->timeout)
+               ip->client->interval =
+                       (ip->client->first_sending +
+                        ip->client->config->timeout) - cur_time + 1;
+
+       /* Record the number of seconds since we started sending. */
+       if (interval < 65536)
+               ip->client->packet.secs = htons(interval);
+       else
+               ip->client->packet.secs = htons(65535);
+       ip->client->secs = ip->client->packet.secs;
+
+       note("DHCPDISCOVER on %s to %s port %d interval %d",
+           ip->name, inet_ntoa(sockaddr_broadcast.sin_addr),
+           ntohs(sockaddr_broadcast.sin_port), ip->client->interval);
+
+       /* Send out a packet. */
+       (void)send_packet(ip, &ip->client->packet, ip->client->packet_length,
+           inaddr_any, &sockaddr_broadcast, NULL);
+
+        DH_DbgPrint(MID_TRACE,("discover timeout: now %x -> then %x\n",
+                               cur_time, cur_time + ip->client->interval));
+
+       add_timeout(cur_time + ip->client->interval, send_discover, ip);
+}
+
+/*
+ * state_panic gets called if we haven't received any offers in a preset
+ * amount of time.   When this happens, we try to use existing leases
+ * that haven't yet expired, and failing that, we call the client script
+ * and hope it can do something.
+ */
+void
+state_panic(void *ipp)
+{
+       struct interface_info *ip = ipp;
+       struct client_lease *loop = ip->client->active;
+       struct client_lease *lp;
+
+       note("No DHCPOFFERS received.");
+
+       /* We may not have an active lease, but we may have some
+          predefined leases that we can try. */
+       if (!ip->client->active && ip->client->leases)
+               goto activate_next;
+
+       /* Run through the list of leases and see if one can be used. */
+       while (ip->client->active) {
+               if (ip->client->active->expiry > cur_time) {
+                       note("Trying recorded lease %s",
+                           piaddr(ip->client->active->address));
+                       /* Run the client script with the existing
+                          parameters. */
+                       script_init("TIMEOUT",
+                           ip->client->active->medium);
+                       script_write_params("new_", ip->client->active);
+                       if (ip->client->alias)
+                               script_write_params("alias_",
+                                   ip->client->alias);
+
+                       /* If the old lease is still good and doesn't
+                          yet need renewal, go into BOUND state and
+                          timeout at the renewal time. */
+                       if (!script_go()) {
+                               if (cur_time <
+                                   ip->client->active->renewal) {
+                                       ip->client->state = S_BOUND;
+                                       note("bound: renewal in %d seconds.",
+                                           ip->client->active->renewal -
+                                           cur_time);
+                                       add_timeout(
+                                           ip->client->active->renewal,
+                                           state_bound, ip);
+                               } else {
+                                       ip->client->state = S_BOUND;
+                                       note("bound: immediate renewal.");
+                                       state_bound(ip);
+                               }
+                               reinitialize_interfaces();
+                               //go_daemon();
+                               return;
+                       }
+               }
+
+               /* If there are no other leases, give up. */
+               if (!ip->client->leases) {
+                       ip->client->leases = ip->client->active;
+                       ip->client->active = NULL;
+                       break;
+               }
+
+activate_next:
+               /* Otherwise, put the active lease at the end of the
+                  lease list, and try another lease.. */
+               for (lp = ip->client->leases; lp->next; lp = lp->next)
+                       ;
+               lp->next = ip->client->active;
+               if (lp->next)
+                       lp->next->next = NULL;
+               ip->client->active = ip->client->leases;
+               ip->client->leases = ip->client->leases->next;
+
+               /* If we already tried this lease, we've exhausted the
+                  set of leases, so we might as well give up for
+                  now. */
+               if (ip->client->active == loop)
+                       break;
+               else if (!loop)
+                       loop = ip->client->active;
+       }
+
+       /* No leases were available, or what was available didn't work, so
+          tell the shell script that we failed to allocate an address,
+          and try again later. */
+       note("No working leases in persistent database - sleeping.\n");
+       script_init("FAIL", NULL);
+       if (ip->client->alias)
+               script_write_params("alias_", ip->client->alias);
+       script_go();
+       ip->client->state = S_INIT;
+       add_timeout(cur_time + ip->client->config->retry_interval, state_init,
+           ip);
+//     go_daemon();
+}
+
+void
+send_request(void *ipp)
+{
+       struct interface_info *ip = ipp;
+       struct sockaddr_in destination;
+       struct in_addr from;
+       int interval;
+
+       /* Figure out how long it's been since we started transmitting. */
+       interval = cur_time - ip->client->first_sending;
+
+       /* If we're in the INIT-REBOOT or REQUESTING state and we're
+          past the reboot timeout, go to INIT and see if we can
+          DISCOVER an address... */
+       /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
+          means either that we're on a network with no DHCP server,
+          or that our server is down.  In the latter case, assuming
+          that there is a backup DHCP server, DHCPDISCOVER will get
+          us a new address, but we could also have successfully
+          reused our old address.  In the former case, we're hosed
+          anyway.  This is not a win-prone situation. */
+       if ((ip->client->state == S_REBOOTING ||
+           ip->client->state == S_REQUESTING) &&
+           interval > ip->client->config->reboot_timeout) {
+cancel:
+               ip->client->state = S_INIT;
+               cancel_timeout(send_request, ip);
+               state_init(ip);
+               return;
+       }
+
+       /* If we're in the reboot state, make sure the media is set up
+          correctly. */
+       if (ip->client->state == S_REBOOTING &&
+           !ip->client->medium &&
+           ip->client->active->medium ) {
+               script_init("MEDIUM", ip->client->active->medium);
+
+               /* If the medium we chose won't fly, go to INIT state. */
+               if (script_go())
+                       goto cancel;
+
+               /* Record the medium. */
+               ip->client->medium = ip->client->active->medium;
+       }
+
+       /* If the lease has expired, relinquish the address and go back
+          to the INIT state. */
+       if (ip->client->state != S_REQUESTING &&
+           cur_time > ip->client->active->expiry) {
+               /* Run the client script with the new parameters. */
+               script_init("EXPIRE", NULL);
+               script_write_params("old_", ip->client->active);
+               if (ip->client->alias)
+                       script_write_params("alias_", ip->client->alias);
+               script_go();
+
+               /* Now do a preinit on the interface so that we can
+                  discover a new address. */
+               script_init("PREINIT", NULL);
+               if (ip->client->alias)
+                       script_write_params("alias_", ip->client->alias);
+               script_go();
+
+               ip->client->state = S_INIT;
+               state_init(ip);
+               return;
+       }
+
+       /* Do the exponential backoff... */
+       if (!ip->client->interval)
+               ip->client->interval = ip->client->config->initial_interval;
+       else
+               ip->client->interval += ((arc4random() >> 2) %
+                   (2 * ip->client->interval));
+
+       /* Don't backoff past cutoff. */
+       if (ip->client->interval >
+           ip->client->config->backoff_cutoff)
+               ip->client->interval =
+                   ((ip->client->config->backoff_cutoff / 2) +
+                   ((arc4random() >> 2) % ip->client->interval));
+
+       /* If the backoff would take us to the expiry time, just set the
+          timeout to the expiry time. */
+       if (ip->client->state != S_REQUESTING &&
+           cur_time + ip->client->interval >
+           ip->client->active->expiry)
+               ip->client->interval =
+                   ip->client->active->expiry - cur_time + 1;
+
+       /* If the lease T2 time has elapsed, or if we're not yet bound,
+          broadcast the DHCPREQUEST rather than unicasting. */
+       memset(&destination, 0, sizeof(destination));
+       if (ip->client->state == S_REQUESTING ||
+           ip->client->state == S_REBOOTING ||
+           cur_time > ip->client->active->rebind)
+               destination.sin_addr.s_addr = INADDR_BROADCAST;
+       else
+               memcpy(&destination.sin_addr.s_addr,
+                   ip->client->destination.iabuf,
+                   sizeof(destination.sin_addr.s_addr));
+       destination.sin_port = htons(REMOTE_PORT);
+       destination.sin_family = AF_INET;
+//     destination.sin_len = sizeof(destination);
+
+       if (ip->client->state != S_REQUESTING)
+               memcpy(&from, ip->client->active->address.iabuf,
+                   sizeof(from));
+       else
+               from.s_addr = INADDR_ANY;
+
+       /* Record the number of seconds since we started sending. */
+       if (ip->client->state == S_REQUESTING)
+               ip->client->packet.secs = ip->client->secs;
+       else {
+               if (interval < 65536)
+                       ip->client->packet.secs = htons(interval);
+               else
+                       ip->client->packet.secs = htons(65535);
+       }
+
+       note("DHCPREQUEST on %s to %s port %d", ip->name,
+           inet_ntoa(destination.sin_addr), ntohs(destination.sin_port));
+
+       /* Send out a packet. */
+       (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
+           from, &destination, NULL);
+
+       add_timeout(cur_time + ip->client->interval, send_request, ip);
+}
+
+void
+send_decline(void *ipp)
+{
+       struct interface_info *ip = ipp;
+
+       note("DHCPDECLINE on %s to %s port %d", ip->name,
+           inet_ntoa(sockaddr_broadcast.sin_addr),
+           ntohs(sockaddr_broadcast.sin_port));
+
+       /* Send out a packet. */
+       (void) send_packet(ip, &ip->client->packet, ip->client->packet_length,
+           inaddr_any, &sockaddr_broadcast, NULL);
+}
+
+void
+make_discover(struct interface_info *ip, struct client_lease *lease)
+{
+       unsigned char discover = DHCPDISCOVER;
+       struct tree_cache *options[256];
+       struct tree_cache option_elements[256];
+       int i;
+
+       memset(option_elements, 0, sizeof(option_elements));
+       memset(options, 0, sizeof(options));
+       memset(&ip->client->packet, 0, sizeof(ip->client->packet));
+
+       /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
+       i = DHO_DHCP_MESSAGE_TYPE;
+       options[i] = &option_elements[i];
+       options[i]->value = &discover;
+       options[i]->len = sizeof(discover);
+       options[i]->buf_size = sizeof(discover);
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* Request the options we want */
+       i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
+       options[i] = &option_elements[i];
+       options[i]->value = ip->client->config->requested_options;
+       options[i]->len = ip->client->config->requested_option_count;
+       options[i]->buf_size =
+               ip->client->config->requested_option_count;
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* If we had an address, try to get it again. */
+       if (lease) {
+               ip->client->requested_address = lease->address;
+               i = DHO_DHCP_REQUESTED_ADDRESS;
+               options[i] = &option_elements[i];
+               options[i]->value = lease->address.iabuf;
+               options[i]->len = lease->address.len;
+               options[i]->buf_size = lease->address.len;
+               options[i]->timeout = 0xFFFFFFFF;
+       } else
+               ip->client->requested_address.len = 0;
+
+       /* Send any options requested in the config file. */
+       for (i = 0; i < 256; i++)
+               if (!options[i] &&
+                   ip->client->config->send_options[i].data) {
+                       options[i] = &option_elements[i];
+                       options[i]->value =
+                           ip->client->config->send_options[i].data;
+                       options[i]->len =
+                           ip->client->config->send_options[i].len;
+                       options[i]->buf_size =
+                           ip->client->config->send_options[i].len;
+                       options[i]->timeout = 0xFFFFFFFF;
+               }
+
+       /* Set up the option buffer... */
+       ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
+           options, 0, 0, 0, NULL, 0);
+       if (ip->client->packet_length < BOOTP_MIN_LEN)
+               ip->client->packet_length = BOOTP_MIN_LEN;
+
+       ip->client->packet.op = BOOTREQUEST;
+       ip->client->packet.htype = ip->hw_address.htype;
+       ip->client->packet.hlen = ip->hw_address.hlen;
+       ip->client->packet.hops = 0;
+       ip->client->packet.xid = arc4random();
+       ip->client->packet.secs = 0; /* filled in by send_discover. */
+       ip->client->packet.flags = 0;
+
+       memset(&(ip->client->packet.ciaddr),
+           0, sizeof(ip->client->packet.ciaddr));
+       memset(&(ip->client->packet.yiaddr),
+           0, sizeof(ip->client->packet.yiaddr));
+       memset(&(ip->client->packet.siaddr),
+           0, sizeof(ip->client->packet.siaddr));
+       memset(&(ip->client->packet.giaddr),
+           0, sizeof(ip->client->packet.giaddr));
+       memcpy(ip->client->packet.chaddr,
+           ip->hw_address.haddr, ip->hw_address.hlen);
+}
+
+
+void
+make_request(struct interface_info *ip, struct client_lease * lease)
+{
+       unsigned char request = DHCPREQUEST;
+       struct tree_cache *options[256];
+       struct tree_cache option_elements[256];
+       int i;
+
+       memset(options, 0, sizeof(options));
+       memset(&ip->client->packet, 0, sizeof(ip->client->packet));
+
+       /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
+       i = DHO_DHCP_MESSAGE_TYPE;
+       options[i] = &option_elements[i];
+       options[i]->value = &request;
+       options[i]->len = sizeof(request);
+       options[i]->buf_size = sizeof(request);
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* Request the options we want */
+       i = DHO_DHCP_PARAMETER_REQUEST_LIST;
+       options[i] = &option_elements[i];
+       options[i]->value = ip->client->config->requested_options;
+       options[i]->len = ip->client->config->requested_option_count;
+       options[i]->buf_size =
+               ip->client->config->requested_option_count;
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* If we are requesting an address that hasn't yet been assigned
+          to us, use the DHCP Requested Address option. */
+       if (ip->client->state == S_REQUESTING) {
+               /* Send back the server identifier... */
+               i = DHO_DHCP_SERVER_IDENTIFIER;
+               options[i] = &option_elements[i];
+               options[i]->value = lease->options[i].data;
+               options[i]->len = lease->options[i].len;
+               options[i]->buf_size = lease->options[i].len;
+               options[i]->timeout = 0xFFFFFFFF;
+       }
+       if (ip->client->state == S_REQUESTING ||
+           ip->client->state == S_REBOOTING) {
+               ip->client->requested_address = lease->address;
+               i = DHO_DHCP_REQUESTED_ADDRESS;
+               options[i] = &option_elements[i];
+               options[i]->value = lease->address.iabuf;
+               options[i]->len = lease->address.len;
+               options[i]->buf_size = lease->address.len;
+               options[i]->timeout = 0xFFFFFFFF;
+       } else
+               ip->client->requested_address.len = 0;
+
+       /* Send any options requested in the config file. */
+       for (i = 0; i < 256; i++)
+               if (!options[i] &&
+                   ip->client->config->send_options[i].data) {
+                       options[i] = &option_elements[i];
+                       options[i]->value =
+                           ip->client->config->send_options[i].data;
+                       options[i]->len =
+                           ip->client->config->send_options[i].len;
+                       options[i]->buf_size =
+                           ip->client->config->send_options[i].len;
+                       options[i]->timeout = 0xFFFFFFFF;
+               }
+
+       /* Set up the option buffer... */
+       ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
+           options, 0, 0, 0, NULL, 0);
+       if (ip->client->packet_length < BOOTP_MIN_LEN)
+               ip->client->packet_length = BOOTP_MIN_LEN;
+
+       ip->client->packet.op = BOOTREQUEST;
+       ip->client->packet.htype = ip->hw_address.htype;
+       ip->client->packet.hlen = ip->hw_address.hlen;
+       ip->client->packet.hops = 0;
+       ip->client->packet.xid = ip->client->xid;
+       ip->client->packet.secs = 0; /* Filled in by send_request. */
+
+       /* If we own the address we're requesting, put it in ciaddr;
+          otherwise set ciaddr to zero. */
+       if (ip->client->state == S_BOUND ||
+           ip->client->state == S_RENEWING ||
+           ip->client->state == S_REBINDING) {
+               memcpy(&ip->client->packet.ciaddr,
+                   lease->address.iabuf, lease->address.len);
+               ip->client->packet.flags = 0;
+       } else {
+               memset(&ip->client->packet.ciaddr, 0,
+                   sizeof(ip->client->packet.ciaddr));
+               ip->client->packet.flags = 0;
+       }
+
+       memset(&ip->client->packet.yiaddr, 0,
+           sizeof(ip->client->packet.yiaddr));
+       memset(&ip->client->packet.siaddr, 0,
+           sizeof(ip->client->packet.siaddr));
+       memset(&ip->client->packet.giaddr, 0,
+           sizeof(ip->client->packet.giaddr));
+       memcpy(ip->client->packet.chaddr,
+           ip->hw_address.haddr, ip->hw_address.hlen);
+}
+
+void
+make_decline(struct interface_info *ip, struct client_lease *lease)
+{
+       struct tree_cache *options[256], message_type_tree;
+       struct tree_cache requested_address_tree;
+       struct tree_cache server_id_tree, client_id_tree;
+       unsigned char decline = DHCPDECLINE;
+       int i;
+
+       memset(options, 0, sizeof(options));
+       memset(&ip->client->packet, 0, sizeof(ip->client->packet));
+
+       /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
+       i = DHO_DHCP_MESSAGE_TYPE;
+       options[i] = &message_type_tree;
+       options[i]->value = &decline;
+       options[i]->len = sizeof(decline);
+       options[i]->buf_size = sizeof(decline);
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* Send back the server identifier... */
+       i = DHO_DHCP_SERVER_IDENTIFIER;
+       options[i] = &server_id_tree;
+       options[i]->value = lease->options[i].data;
+       options[i]->len = lease->options[i].len;
+       options[i]->buf_size = lease->options[i].len;
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* Send back the address we're declining. */
+       i = DHO_DHCP_REQUESTED_ADDRESS;
+       options[i] = &requested_address_tree;
+       options[i]->value = lease->address.iabuf;
+       options[i]->len = lease->address.len;
+       options[i]->buf_size = lease->address.len;
+       options[i]->timeout = 0xFFFFFFFF;
+
+       /* Send the uid if the user supplied one. */
+       i = DHO_DHCP_CLIENT_IDENTIFIER;
+       if (ip->client->config->send_options[i].len) {
+               options[i] = &client_id_tree;
+               options[i]->value = ip->client->config->send_options[i].data;
+               options[i]->len = ip->client->config->send_options[i].len;
+               options[i]->buf_size = ip->client->config->send_options[i].len;
+               options[i]->timeout = 0xFFFFFFFF;
+       }
+
+
+       /* Set up the option buffer... */
+       ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
+           options, 0, 0, 0, NULL, 0);
+       if (ip->client->packet_length < BOOTP_MIN_LEN)
+               ip->client->packet_length = BOOTP_MIN_LEN;
+
+       ip->client->packet.op = BOOTREQUEST;
+       ip->client->packet.htype = ip->hw_address.htype;
+       ip->client->packet.hlen = ip->hw_address.hlen;
+       ip->client->packet.hops = 0;
+       ip->client->packet.xid = ip->client->xid;
+       ip->client->packet.secs = 0; /* Filled in by send_request. */
+       ip->client->packet.flags = 0;
+
+       /* ciaddr must always be zero. */
+       memset(&ip->client->packet.ciaddr, 0,
+           sizeof(ip->client->packet.ciaddr));
+       memset(&ip->client->packet.yiaddr, 0,
+           sizeof(ip->client->packet.yiaddr));
+       memset(&ip->client->packet.siaddr, 0,
+           sizeof(ip->client->packet.siaddr));
+       memset(&ip->client->packet.giaddr, 0,
+           sizeof(ip->client->packet.giaddr));
+       memcpy(ip->client->packet.chaddr,
+           ip->hw_address.haddr, ip->hw_address.hlen);
+}
+
+void
+free_client_lease(struct client_lease *lease)
+{
+       int i;
+
+       if (lease->server_name)
+               free(lease->server_name);
+       if (lease->filename)
+               free(lease->filename);
+       for (i = 0; i < 256; i++) {
+               if (lease->options[i].len)
+                       free(lease->options[i].data);
+       }
+       free(lease);
+}
+
+FILE *leaseFile;
+
+void
+rewrite_client_leases(void)
+{
+       struct client_lease *lp;
+
+       if (!leaseFile) {
+               leaseFile = fopen(path_dhclient_db, "w");
+               if (!leaseFile)
+                       error("can't create %s: %m", path_dhclient_db);
+       } else {
+               fflush(leaseFile);
+               rewind(leaseFile);
+       }
+
+       for (lp = ifi->client->leases; lp; lp = lp->next)
+               write_client_lease(ifi, lp, 1);
+       if (ifi->client->active)
+               write_client_lease(ifi, ifi->client->active, 1);
+
+       fflush(leaseFile);
+//     ftruncate(fileno(leaseFile), ftello(leaseFile));
+//     fsync(fileno(leaseFile));
+}
+
+void
+write_client_lease(struct interface_info *ip, struct client_lease *lease,
+    int rewrite)
+{
+       static int leases_written;
+       struct tm *t;
+       int i;
+
+       if (!rewrite) {
+               if (leases_written++ > 20) {
+                       rewrite_client_leases();
+                       leases_written = 0;
+               }
+       }
+
+       /* If the lease came from the config file, we don't need to stash
+          a copy in the lease database. */
+       if (lease->is_static)
+               return;
+
+       if (!leaseFile) {       /* XXX */
+               leaseFile = fopen(path_dhclient_db, "w");
+               if (!leaseFile)
+                       error("can't create %s: %m", path_dhclient_db);
+       }
+
+       fprintf(leaseFile, "lease {\n");
+       if (lease->is_bootp)
+               fprintf(leaseFile, "  bootp;\n");
+       fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
+       fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
+       if (lease->filename)
+               fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
+       if (lease->server_name)
+               fprintf(leaseFile, "  server-name \"%s\";\n",
+                   lease->server_name);
+       if (lease->medium)
+               fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
+       for (i = 0; i < 256; i++)
+               if (lease->options[i].len)
+                       fprintf(leaseFile, "  option %s %s;\n",
+                           dhcp_options[i].name,
+                           pretty_print_option(i, lease->options[i].data,
+                           lease->options[i].len, 1, 1));
+
+       t = gmtime(&lease->renewal);
+       fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
+           t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+           t->tm_hour, t->tm_min, t->tm_sec);
+       t = gmtime(&lease->rebind);
+       fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
+           t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+           t->tm_hour, t->tm_min, t->tm_sec);
+       t = gmtime(&lease->expiry);
+       fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
+           t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+           t->tm_hour, t->tm_min, t->tm_sec);
+       fprintf(leaseFile, "}\n");
+       fflush(leaseFile);
+}
+
+void
+script_init(char *reason, struct string_list *medium)
+{
+       size_t           len, mediumlen = 0;
+       struct imsg_hdr  hdr;
+       struct buf      *buf;
+       int              errs;
+
+       if (medium != NULL && medium->string != NULL)
+               mediumlen = strlen(medium->string);
+
+       hdr.code = IMSG_SCRIPT_INIT;
+       hdr.len = sizeof(struct imsg_hdr) +
+           sizeof(size_t) + mediumlen +
+           sizeof(size_t) + strlen(reason);
+
+       if ((buf = buf_open(hdr.len)) == NULL)
+               error("buf_open: %m");
+
+       errs = 0;
+       errs += buf_add(buf, &hdr, sizeof(hdr));
+       errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
+       if (mediumlen > 0)
+               errs += buf_add(buf, medium->string, mediumlen);
+       len = strlen(reason);
+       errs += buf_add(buf, &len, sizeof(len));
+       errs += buf_add(buf, reason, len);
+
+       if (errs)
+               error("buf_add: %m");
+
+       if (buf_close(privfd, buf) == -1)
+               error("buf_close: %m");
+}
+
+void
+priv_script_init(char *reason, char *medium)
+{
+       struct interface_info *ip = ifi;
+
+       if (ip) {
+            // XXX Do we need to do anything? 
+        }
+}
+
+void
+priv_script_write_params(char *prefix, struct client_lease *lease)
+{
+       struct interface_info *ip = ifi;
+       u_int8_t dbuf[1500];
+       int i, len = 0;
+       char tbuf[128];
+
+#if 0
+       script_set_env(ip->client, prefix, "ip_address",
+           piaddr(lease->address));
+#endif
+
+       if (lease->options[DHO_SUBNET_MASK].len &&
+           (lease->options[DHO_SUBNET_MASK].len <
+           sizeof(lease->address.iabuf))) {
+               struct iaddr netmask, subnet, broadcast;
+
+               memcpy(netmask.iabuf, lease->options[DHO_SUBNET_MASK].data,
+                   lease->options[DHO_SUBNET_MASK].len);
+               netmask.len = lease->options[DHO_SUBNET_MASK].len;
+
+               subnet = subnet_number(lease->address, netmask);
+               if (subnet.len) {
+#if 0
+                       script_set_env(ip->client, prefix, "network_number",
+                           piaddr(subnet));
+#endif
+                       if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
+                               broadcast = broadcast_addr(subnet, netmask);
+                               if (broadcast.len)
+#if 0
+                                       script_set_env(ip->client, prefix,
+                                           "broadcast_address",
+                                           piaddr(broadcast));
+#else
+                                ;
+#endif
+                       }
+               }
+       }
+
+#if 0
+       if (lease->filename)
+               script_set_env(ip->client, prefix, "filename", lease->filename);
+       if (lease->server_name)
+               script_set_env(ip->client, prefix, "server_name",
+                   lease->server_name);
+#endif
+
+       for (i = 0; i < 256; i++) {
+               u_int8_t *dp = NULL;
+
+               if (ip->client->config->defaults[i].len) {
+                       if (lease->options[i].len) {
+                               switch (
+                                   ip->client->config->default_actions[i]) {
+                               case ACTION_DEFAULT:
+                                       dp = lease->options[i].data;
+                                       len = lease->options[i].len;
+                                       break;
+                               case ACTION_SUPERSEDE:
+supersede:
+                                       dp = ip->client->
+                                               config->defaults[i].data;
+                                       len = ip->client->
+                                               config->defaults[i].len;
+                                       break;
+                               case ACTION_PREPEND:
+                                       len = ip->client->
+                                           config->defaults[i].len +
+                                           lease->options[i].len;
+                                       if (len > sizeof(dbuf)) {
+                                               warning("no space to %s %s",
+                                                   "prepend option",
+                                                   dhcp_options[i].name);
+                                               goto supersede;
+                                       }
+                                       dp = dbuf;
+                                       memcpy(dp,
+                                               ip->client->
+                                               config->defaults[i].data,
+                                               ip->client->
+                                               config->defaults[i].len);
+                                       memcpy(dp + ip->client->
+                                               config->defaults[i].len,
+                                               lease->options[i].data,
+                                               lease->options[i].len);
+                                       dp[len] = '\0';
+                                       break;
+                               case ACTION_APPEND:
+                                       len = ip->client->
+                                           config->defaults[i].len +
+                                           lease->options[i].len;
+                                       if (len > sizeof(dbuf)) {
+                                               warning("no space to %s %s",
+                                                   "append option",
+                                                   dhcp_options[i].name);
+                                               goto supersede;
+                                       }
+                                       dp = dbuf;
+                                       memcpy(dp,
+                                               lease->options[i].data,
+                                               lease->options[i].len);
+                                       memcpy(dp + lease->options[i].len,
+                                               ip->client->
+                                               config->defaults[i].data,
+                                               ip->client->
+                                               config->defaults[i].len);
+                                       dp[len] = '\0';
+                               }
+                       } else {
+                               dp = ip->client->
+                                       config->defaults[i].data;
+                               len = ip->client->
+                                       config->defaults[i].len;
+                       }
+               } else if (lease->options[i].len) {
+                       len = lease->options[i].len;
+                       dp = lease->options[i].data;
+               } else {
+                       len = 0;
+               }
+#if 0
+               if (len) {
+                       char name[256];
+
+                       if (dhcp_option_ev_name(name, sizeof(name),
+                           &dhcp_options[i]))
+                               script_set_env(ip->client, prefix, name,
+                                   pretty_print_option(i, dp, len, 0, 0));
+               }
+#endif
+       }
+#if 0
+       snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
+       script_set_env(ip->client, prefix, "expiry", tbuf);
+#endif
+}
+
+void
+script_write_params(char *prefix, struct client_lease *lease)
+{
+       size_t           fn_len = 0, sn_len = 0, pr_len = 0;
+       struct imsg_hdr  hdr;
+       struct buf      *buf;
+       int              errs, i;
+
+       if (lease->filename != NULL)
+               fn_len = strlen(lease->filename);
+       if (lease->server_name != NULL)
+               sn_len = strlen(lease->server_name);
+       if (prefix != NULL)
+               pr_len = strlen(prefix);
+
+       hdr.code = IMSG_SCRIPT_WRITE_PARAMS;
+       hdr.len = sizeof(hdr) + sizeof(struct client_lease) +
+           sizeof(size_t) + fn_len + sizeof(size_t) + sn_len +
+           sizeof(size_t) + pr_len;
+
+       for (i = 0; i < 256; i++)
+               hdr.len += sizeof(int) + lease->options[i].len;
+
+       scripttime = time(NULL);
+
+       if ((buf = buf_open(hdr.len)) == NULL)
+               error("buf_open: %m");
+
+       errs = 0;
+       errs += buf_add(buf, &hdr, sizeof(hdr));
+       errs += buf_add(buf, lease, sizeof(struct client_lease));
+       errs += buf_add(buf, &fn_len, sizeof(fn_len));
+       errs += buf_add(buf, lease->filename, fn_len);
+       errs += buf_add(buf, &sn_len, sizeof(sn_len));
+       errs += buf_add(buf, lease->server_name, sn_len);
+       errs += buf_add(buf, &pr_len, sizeof(pr_len));
+       errs += buf_add(buf, prefix, pr_len);
+
+       for (i = 0; i < 256; i++) {
+               errs += buf_add(buf, &lease->options[i].len,
+                   sizeof(lease->options[i].len));
+               errs += buf_add(buf, lease->options[i].data,
+                   lease->options[i].len);
+       }
+
+       if (errs)
+               error("buf_add: %m");
+
+       if (buf_close(privfd, buf) == -1)
+               error("buf_close: %m");
+}
+
+int
+script_go(void)
+{
+       struct imsg_hdr  hdr;
+       struct buf      *buf;
+       int              ret;
+
+       scripttime = time(NULL);
+
+       hdr.code = IMSG_SCRIPT_GO;
+       hdr.len = sizeof(struct imsg_hdr);
+
+       if ((buf = buf_open(hdr.len)) == NULL)
+               error("buf_open: %m");
+
+       if (buf_add(buf, &hdr, sizeof(hdr)))
+               error("buf_add: %m");
+
+       if (buf_close(privfd, buf) == -1)
+               error("buf_close: %m");
+
+       memset(&hdr, 0, sizeof(hdr));
+       //bzero(&hdr, sizeof(hdr));
+       buf_read(privfd, &hdr, sizeof(hdr));
+       if (hdr.code != IMSG_SCRIPT_GO_RET)
+               error("unexpected msg type %u", hdr.code);
+       if (hdr.len != sizeof(hdr) + sizeof(int))
+               error("received corrupted message");
+       buf_read(privfd, &ret, sizeof(ret));
+
+       return (ret);
+}
+
+#if 0
+int
+priv_script_go(void)
+{
+       char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI";
+       static char client_path[] = CLIENT_PATH;
+       struct interface_info *ip = ifi;
+       int pid, wpid, wstatus;
+
+       scripttime = time(NULL);
+
+       if (ip) {
+               scriptName = ip->client->config->script_name;
+               envp = ip->client->scriptEnv;
+       } else {
+               scriptName = top_level_config.script_name;
+               epp[0] = reason;
+               epp[1] = client_path;
+               epp[2] = NULL;
+               envp = epp;
+       }
+
+       argv[0] = scriptName;
+       argv[1] = NULL;
+
+       pid = fork();
+       if (pid < 0) {
+               error("fork: %m");
+               wstatus = 0;
+       } else if (pid) {
+               do {
+                       wpid = wait(&wstatus);
+               } while (wpid != pid && wpid > 0);
+               if (wpid < 0) {
+                       error("wait: %m");
+                       wstatus = 0;
+               }
+       } else {
+               execve(scriptName, argv, envp);
+               error("execve (%s, ...): %m", scriptName);
+       }
+
+       if (ip)
+               script_flush_env(ip->client);
+
+       return (wstatus & 0xff);
+}
+#endif
+
+#if 0
+void
+script_set_env(struct client_state *client, const char *prefix,
+    const char *name, const char *value)
+{
+       int i, j, namelen;
+
+       namelen = strlen(name);
+
+       for (i = 0; client->scriptEnv[i]; i++)
+               if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
+                   client->scriptEnv[i][namelen] == '=')
+                       break;
+
+       if (client->scriptEnv[i])
+               /* Reuse the slot. */
+               free(client->scriptEnv[i]);
+       else {
+               /* New variable.  Expand if necessary. */
+               if (i >= client->scriptEnvsize - 1) {
+                       char **newscriptEnv;
+                       int newscriptEnvsize = client->scriptEnvsize + 50;
+
+                       newscriptEnv = realloc(client->scriptEnv,
+                           newscriptEnvsize);
+                       if (newscriptEnv == NULL) {
+                               free(client->scriptEnv);
+                               client->scriptEnv = NULL;
+                               client->scriptEnvsize = 0;
+                               error("script_set_env: no memory for variable");
+                       }
+                       client->scriptEnv = newscriptEnv;
+                       client->scriptEnvsize = newscriptEnvsize;
+               }
+               /* need to set the NULL pointer at end of array beyond
+                  the new slot. */
+               client->scriptEnv[i + 1] = NULL;
+       }
+       /* Allocate space and format the variable in the appropriate slot. */
+       client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
+           strlen(value) + 1);
+       if (client->scriptEnv[i] == NULL)
+               error("script_set_env: no memory for variable assignment");
+
+       /* No `` or $() command substitution allowed in environment values! */
+       for (j=0; j < strlen(value); j++)
+               switch (value[j]) {
+               case '`':
+               case '$':
+                       error("illegal character (%c) in value '%s'", value[j],
+                           value);
+                       /* not reached */
+               }
+       snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
+           1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
+}
+
+void
+script_flush_env(struct client_state *client)
+{
+       int i;
+
+       for (i = 0; client->scriptEnv[i]; i++) {
+               free(client->scriptEnv[i]);
+               client->scriptEnv[i] = NULL;
+       }
+       client->scriptEnvsize = 0;
+}
+#endif
+
+int
+dhcp_option_ev_name(char *buf, size_t buflen, struct dhcp_option *option)
+{
+       int i;
+
+       for (i = 0; option->name[i]; i++) {
+               if (i + 1 == buflen)
+                       return 0;
+               if (option->name[i] == '-')
+                       buf[i] = '_';
+               else
+                       buf[i] = option->name[i];
+       }
+
+       buf[i] = 0;
+       return 1;
+}
+
+#if 0
+void
+go_daemon(void)
+{
+       static int state = 0;
+
+       if (no_daemon || state)
+               return;
+
+       state = 1;
+
+       /* Stop logging to stderr... */
+       log_perror = 0;
+
+       if (daemon(1, 0) == -1)
+               error("daemon");
+
+       /* we are chrooted, daemon(3) fails to open /dev/null */
+       if (nullfd != -1) {
+               dup2(nullfd, STDIN_FILENO);
+               dup2(nullfd, STDOUT_FILENO);
+               dup2(nullfd, STDERR_FILENO);
+               close(nullfd);
+               nullfd = -1;
+       }
+}
+#endif
+
+int
+check_option(struct client_lease *l, int option)
+{
+       char *opbuf;
+       char *sbuf;
+
+       /* we use this, since this is what gets passed to dhclient-script */
+
+       opbuf = pretty_print_option(option, l->options[option].data,
+           l->options[option].len, 0, 0);
+
+       sbuf = option_as_string(option, l->options[option].data,
+           l->options[option].len);
+
+       switch (option) {
+       case DHO_SUBNET_MASK:
+       case DHO_TIME_SERVERS:
+       case DHO_NAME_SERVERS:
+       case DHO_ROUTERS:
+       case DHO_DOMAIN_NAME_SERVERS:
+       case DHO_LOG_SERVERS:
+       case DHO_COOKIE_SERVERS:
+       case DHO_LPR_SERVERS:
+       case DHO_IMPRESS_SERVERS:
+       case DHO_RESOURCE_LOCATION_SERVERS:
+       case DHO_SWAP_SERVER:
+       case DHO_BROADCAST_ADDRESS:
+       case DHO_NIS_SERVERS:
+       case DHO_NTP_SERVERS:
+       case DHO_NETBIOS_NAME_SERVERS:
+       case DHO_NETBIOS_DD_SERVER:
+       case DHO_FONT_SERVERS:
+       case DHO_DHCP_SERVER_IDENTIFIER:
+               if (!ipv4addrs(opbuf)) {
+                       warning("Invalid IP address in option: %s", opbuf);
+                       return (0);
+               }
+               return (1)  ;
+       case DHO_HOST_NAME:
+       case DHO_DOMAIN_NAME:
+       case DHO_NIS_DOMAIN:
+               if (!res_hnok(sbuf)) {
+                       warning("Bogus Host Name option %d: %s (%s)", option,
+                           sbuf, opbuf);
+                       return (0);
+               }
+               return (1);
+       case DHO_PAD:
+       case DHO_TIME_OFFSET:
+       case DHO_BOOT_SIZE:
+       case DHO_MERIT_DUMP:
+       case DHO_ROOT_PATH:
+       case DHO_EXTENSIONS_PATH:
+       case DHO_IP_FORWARDING:
+       case DHO_NON_LOCAL_SOURCE_ROUTING:
+       case DHO_POLICY_FILTER:
+       case DHO_MAX_DGRAM_REASSEMBLY:
+       case DHO_DEFAULT_IP_TTL:
+       case DHO_PATH_MTU_AGING_TIMEOUT:
+       case DHO_PATH_MTU_PLATEAU_TABLE:
+       case DHO_INTERFACE_MTU:
+       case DHO_ALL_SUBNETS_LOCAL:
+       case DHO_PERFORM_MASK_DISCOVERY:
+       case DHO_MASK_SUPPLIER:
+       case DHO_ROUTER_DISCOVERY:
+       case DHO_ROUTER_SOLICITATION_ADDRESS:
+       case DHO_STATIC_ROUTES:
+       case DHO_TRAILER_ENCAPSULATION:
+       case DHO_ARP_CACHE_TIMEOUT:
+       case DHO_IEEE802_3_ENCAPSULATION:
+       case DHO_DEFAULT_TCP_TTL:
+       case DHO_TCP_KEEPALIVE_INTERVAL:
+       case DHO_TCP_KEEPALIVE_GARBAGE:
+       case DHO_VENDOR_ENCAPSULATED_OPTIONS:
+       case DHO_NETBIOS_NODE_TYPE:
+       case DHO_NETBIOS_SCOPE:
+       case DHO_X_DISPLAY_MANAGER:
+       case DHO_DHCP_REQUESTED_ADDRESS:
+       case DHO_DHCP_LEASE_TIME:
+       case DHO_DHCP_OPTION_OVERLOAD:
+       case DHO_DHCP_MESSAGE_TYPE:
+       case DHO_DHCP_PARAMETER_REQUEST_LIST:
+       case DHO_DHCP_MESSAGE:
+       case DHO_DHCP_MAX_MESSAGE_SIZE:
+       case DHO_DHCP_RENEWAL_TIME:
+       case DHO_DHCP_REBINDING_TIME:
+       case DHO_DHCP_CLASS_IDENTIFIER:
+       case DHO_DHCP_CLIENT_IDENTIFIER:
+       case DHO_DHCP_USER_CLASS_ID:
+       case DHO_END:
+               return (1);
+       default:
+               warning("unknown dhcp option value 0x%x", option);
+               return (unknown_ok);
+       }
+}
+
+int
+res_hnok(const char *dn)
+{
+       int pch = PERIOD, ch = *dn++;
+
+       while (ch != '\0') {
+               int nch = *dn++;
+
+               if (periodchar(ch)) {
+                       ;
+               } else if (periodchar(pch)) {
+                       if (!borderchar(ch))
+                               return (0);
+               } else if (periodchar(nch) || nch == '\0') {
+                       if (!borderchar(ch))
+                               return (0);
+               } else {
+                       if (!middlechar(ch))
+                               return (0);
+               }
+               pch = ch, ch = nch;
+       }
+       return (1);
+}
+
+/* Does buf consist only of dotted decimal ipv4 addrs?
+ * return how many if so,
+ * otherwise, return 0
+ */
+int
+ipv4addrs(char * buf)
+{
+       struct in_addr jnk;
+       int count = 0;
+
+       while (inet_aton(buf, &jnk) == 1){
+               count++;
+               while (periodchar(*buf) || digitchar(*buf))
+                       buf++;
+               if (*buf == '\0')
+                       return (count);
+               while (*buf ==  ' ')
+                       buf++;
+       }
+       return (0);
+}
+
+
+char *
+option_as_string(unsigned int code, unsigned char *data, int len)
+{
+       static char optbuf[32768]; /* XXX */
+       char *op = optbuf;
+       int opleft = sizeof(optbuf);
+       unsigned char *dp = data;
+
+       if (code > 255)
+               error("option_as_string: bad code %d", code);
+
+       for (; dp < data + len; dp++) {
+               if (!isascii(*dp) || !isprint(*dp)) {
+                       if (dp + 1 != data + len || *dp != 0) {
+                               snprintf(op, opleft, "\\%03o", *dp);
+                               op += 4;
+                               opleft -= 4;
+                       }
+               } else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
+                   *dp == '`' || *dp == '\\') {
+                       *op++ = '\\';
+                       *op++ = *dp;
+                       opleft -= 2;
+               } else {
+                       *op++ = *dp;
+                       opleft--;
+               }
+       }
+       if (opleft < 1)
+               goto toobig;
+       *op = 0;
+       return optbuf;
+toobig:
+       warning("dhcp option too large");
+       return "<error>";
+}
+
+#if 0
+int
+fork_privchld(int fd, int fd2)
+{
+       struct pollfd pfd[1];
+       int nfds;
+
+       switch (fork()) {
+       case -1:
+               error("cannot fork");
+       case 0:
+               break;
+       default:
+               return (0);
+       }
+
+       setproctitle("%s [priv]", ifi->name);
+
+       dup2(nullfd, STDIN_FILENO);
+       dup2(nullfd, STDOUT_FILENO);
+       dup2(nullfd, STDERR_FILENO);
+       close(nullfd);
+       close(fd2);
+
+       for (;;) {
+               pfd[0].fd = fd;
+               pfd[0].events = POLLIN;
+               if ((nfds = poll(pfd, 1, INFTIM)) == -1)
+                       if (errno != EINTR)
+                               error("poll error");
+
+               if (nfds == 0 || !(pfd[0].revents & POLLIN))
+                       continue;
+
+               dispatch_imsg(fd);
+       }
+}
+#endif
diff --git a/reactos/subsys/system/dhcp/dhcp.rc b/reactos/subsys/system/dhcp/dhcp.rc
new file mode 100644 (file)
index 0000000..35e404f
--- /dev/null
@@ -0,0 +1,6 @@
+/* $Id: regsvr32.rc 12852 2005-01-06 13:58:04Z mf $ */
+
+#define REACTOS_STR_FILE_DESCRIPTION   "DHCP Client Service"
+#define REACTOS_STR_INTERNAL_NAME      "dhcp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "dhcp.exe\0"
+#include <reactos/version.rc>
diff --git a/reactos/subsys/system/dhcp/dhcpmain.c b/reactos/subsys/system/dhcp/dhcpmain.c
new file mode 100644 (file)
index 0000000..ea88fc8
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id:$
+ * 
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Service
+ * FILE:            subsys/system/dhcp
+ * PURPOSE:         DHCP client service entry point
+ * PROGRAMMER:      Art Yerkes (arty@users.sf.net)
+ * UPDATE HISTORY:
+ *                  Created 03/08/2005
+ */
+
+#include <windows.h>
+#include "dhcpd.h"
+#include "version.h"
+
+typedef struct _DHCP_API_REQUEST {
+    int type;
+    UINT flags;
+    LPDHCPAPI_CLASSID class_id;
+    DHCP_API_PARAMS_ARRAY vendor_params;
+    DHCP_API_PARAMS_ARRAY general_params;
+    LPWSTR request_id, adapter_name;
+} DHCP_API_REQUEST;
+
+typedef struct _DHCP_MANAGED_ADAPTER {
+    LPWSTR adapter_name, hostname, dns_server;
+    UINT   adapter_index;
+    struct sockaddr_in address, netmask;
+    struct interface_info *dhcp_info;
+} DHCP_MANAGED_ADAPTER;
+
+#define DHCP_REQUESTPARAM    WM_USER + 0
+#define DHCP_PARAMCHANGE     WM_USER + 1
+#define DHCP_CANCELREQUEST   WM_USER + 2
+#define DHCP_NOPARAMCHANGE   WM_USER + 3
+#define DHCP_MANAGEADAPTER   WM_USER + 4
+#define DHCP_UNMANAGEADAPTER WM_USER + 5
+
+UINT DhcpEventTimer;
+HANDLE DhcpServiceThread;
+DWORD  DhcpServiceThreadId;
+LIST_ENTRY ManagedAdapters;
+
+LRESULT WINAPI ServiceThread( PVOID Data ) {
+    MSG msg;
+
+    while( GetMessage( &msg, 0, 0, 0 ) ) {
+        switch( msg.message ) {
+        case DHCP_MANAGEADAPTER:
+            
+            break;
+
+        case DHCP_UNMANAGEADAPTER:
+            break;
+            
+        case DHCP_REQUESTPARAM:
+            break;
+
+        case DHCP_CANCELREQUEST:
+            break;
+
+        case DHCP_PARAMCHANGE:
+            break;
+
+        case DHCP_NOPARAMCHANGE:
+            break;
+        }
+    }
+}
+
+int main( int argc, char **argv ) {
+}
diff --git a/reactos/subsys/system/dhcp/dispatch.c b/reactos/subsys/system/dhcp/dispatch.c
new file mode 100644 (file)
index 0000000..19f806a
--- /dev/null
@@ -0,0 +1,579 @@
+/*     $OpenBSD: dispatch.c,v 1.31 2004/09/21 04:07:03 david Exp $     */
+
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#include "rosdhcp.h"
+#include "dhcpd.h"
+//#include <sys/ioctl.h>
+
+//#include <net/if_media.h>
+//#include <ifaddrs.h>
+//#include <poll.h>
+
+struct protocol *protocols = NULL;
+struct timeout *timeouts = NULL;
+static struct timeout *free_timeouts = NULL;
+static int interfaces_invalidated = FALSE;
+void (*bootp_packet_handler)(struct interface_info *,
+                             struct dhcp_packet *, int, unsigned int,
+                             struct iaddr, struct hardware *);
+
+static int interface_status(struct interface_info *ifinfo);
+
+/*
+ * Use getifaddrs() to get a list of all the attached interfaces.  For
+ * each interface that's of type INET and not the loopback interface,
+ * register that interface with the network I/O software, figure out
+ * what subnet it's on, and add it to the list of interfaces.
+ */
+#if 0
+void
+discover_interfaces(struct interface_info *iface)
+{
+    struct ifaddrs *ifap, *ifa;
+    struct sockaddr_in foo;
+    struct ifreq *tif;
+
+    if (getifaddrs(&ifap) != 0)
+        error("getifaddrs failed");
+
+    for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+        if ((ifa->ifa_flags & IFF_LOOPBACK) ||
+            (ifa->ifa_flags & IFF_POINTOPOINT) ||
+            (!(ifa->ifa_flags & IFF_UP)))
+            continue;
+
+
+        if (strcmp(iface->name, ifa->ifa_name))
+            continue;
+
+        /*
+         * If we have the capability, extract link information
+         * and record it in a linked list.
+         */
+        if (ifa->ifa_addr->sa_family == AF_LINK) {
+            struct sockaddr_dl *foo =
+                (struct sockaddr_dl *)ifa->ifa_addr;
+
+            iface->index = foo->sdl_index;
+            iface->hw_address.hlen = foo->sdl_alen;
+            iface->hw_address.htype = HTYPE_ETHER; /* XXX */
+            memcpy(iface->hw_address.haddr,
+                   LLADDR(foo), foo->sdl_alen);
+        } else if (ifa->ifa_addr->sa_family == AF_INET) {
+            struct iaddr addr;
+
+            memcpy(&foo, ifa->ifa_addr, sizeof(foo));
+            if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
+                continue;
+            if (!iface->ifp) {
+                int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
+                if ((tif = malloc(len)) == NULL)
+                    error("no space to remember ifp");
+                strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
+                memcpy(&tif->ifr_addr, ifa->ifa_addr,
+                       ifa->ifa_addr->sa_len);
+                iface->ifp = tif;
+                iface->primary_address = foo.sin_addr;
+            }
+            addr.len = 4;
+            memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len);
+        }
+    }
+
+    if (!iface->ifp)
+        error("%s: not found", iface->name);
+
+    /* Register the interface... */
+    if_register_receive(iface);
+    if_register_send(iface);
+    add_protocol(iface->name, iface->rfdesc, got_one, iface);
+    freeifaddrs(ifap);
+}
+#else
+void
+discover_interfaces(struct interface_info *iface)
+{
+    NTSTATUS Status;
+    ULONG dim;
+    char TmpName [IFNAMSIZ];
+
+    PIP_ADAPTER_INFO pAdapterInfo;
+    PIP_ADAPTER_INFO pAdapter = NULL;
+
+    pAdapterInfo = malloc(sizeof(IP_ADAPTER_INFO));
+    dim = sizeof(IP_ADAPTER_INFO);
+
+    if (GetAdaptersInfo( pAdapterInfo, &dim) != ERROR_SUCCESS) {
+        free(pAdapterInfo);
+        pAdapterInfo = (IP_ADAPTER_INFO *) malloc (dim);
+    }
+
+    if ((Status = GetAdaptersInfo( pAdapterInfo, &dim)) != NO_ERROR) {
+        note("Error %x", Status);
+        free (pAdapterInfo);
+        return;
+    }
+
+    for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
+        /* we only do ethernet */
+        note("found: %s %x\n", pAdapter->AdapterName, pAdapter->Address);
+        if (pAdapter->Type != MIB_IF_TYPE_ETHERNET) {
+            continue;
+        }
+        note ("found ethernet\n");
+
+        iface->hw_address.hlen = pAdapter->AddressLength;
+        iface->hw_address.htype = HTYPE_ETHER;
+        memcpy (&iface->hw_address.haddr[0],
+                pAdapter->Address, iface->hw_address.hlen);
+
+        if (pAdapter->IpAddressList.IpAddress.String)
+            iface->primary_address.S_un.S_addr = inet_addr(pAdapter->IpAddressList.IpAddress.String);
+
+    }
+    if (iface) {
+        if_register_receive(iface);
+        if_register_send(iface);
+        add_protocol(iface->name, iface->rfdesc, got_one, iface);
+    }
+    free (pAdapterInfo);
+}
+#endif
+
+void
+reinitialize_interfaces(void)
+{
+    interfaces_invalidated = 1;
+}
+
+/*
+ * Wait for packets to come in using poll().  When a packet comes in,
+ * call receive_packet to receive the packet and possibly strip hardware
+ * addressing information from it, and then call through the
+ * bootp_packet_handler hook to try to do something with it.
+ */
+void
+dispatch(void)
+{
+    int count, i, to_msec, nfds = 0;
+    struct protocol *l;
+    fd_set fds;
+    time_t howlong;
+    struct timeval timeval;
+
+    for (l = protocols; l; l = l->next)
+        nfds++;
+
+    FD_ZERO(&fds);
+
+//     fds = malloc(nfds * sizeof(struct pollfd));
+//     if (fds == NULL)
+//             error("Can't allocate poll structures.");
+
+    do {
+        DH_DbgPrint(MID_TRACE,("Cycling dispatch()\n"));
+        /*
+         * Call any expired timeouts, and then if there's still
+         * a timeout registered, time out the select call then.
+         */
+    another:
+        if (timeouts) {
+            DH_DbgPrint(MID_TRACE,("Some timeouts are available\n"));
+            
+            struct timeout *t;
+
+            if (timeouts->when <= cur_time) {
+                DH_DbgPrint(MID_TRACE,("Calling timeout %x %p %x\n", 
+                                       timeouts->when,
+                                       timeouts->func,
+                                       timeouts->what));
+                t = timeouts;
+                timeouts = timeouts->next;
+                (*(t->func))(t->what);
+                t->next = free_timeouts;
+                free_timeouts = t;
+                goto another;
+            }
+
+            /*
+             * Figure timeout in milliseconds, and check for
+             * potential overflow, so we can cram into an
+             * int for poll, while not polling with a
+             * negative timeout and blocking indefinitely.
+             */
+            howlong = timeouts->when - cur_time;
+            if (howlong > INT_MAX / 1000)
+                howlong = INT_MAX / 1000;
+            to_msec = howlong * 1000;
+        } else
+            to_msec = -1;
+
+        /* Set up the descriptors to be polled. */
+        for (i = 0, l = protocols; l; l = l->next) {
+            struct interface_info *ip = l->local;
+
+            if (ip && (l->handler != got_one || !ip->dead)) {
+                DH_DbgPrint(MID_TRACE,("l->fd %d\n", l->fd));
+                        
+                FD_SET(l->fd, &fds);
+//                             fds[i].fd = l->fd;
+//                             fds[i].events = POLLIN;
+//                             fds[i].revents = 0;
+                i++;
+            }
+        }
+
+        if (i == 0)
+            error("No live interfaces to poll on - exiting.");
+
+        /* Wait for a packet or a timeout... XXX */
+        timeval.tv_sec = to_msec / 1000;
+        timeval.tv_usec = (to_msec % 1000) * 1000;
+        DH_DbgPrint(MID_TRACE,("select(%d,%d.%03d) =>\n", 
+                 nfds,timeval.tv_sec,timeval.tv_usec/1000));
+        count = select(nfds, &fds, NULL, NULL, &timeval);
+        DH_DbgPrint(MID_TRACE,(" => %d\n", count));
+
+        /* Not likely to be transitory... */
+        if (count == SOCKET_ERROR) {
+            if (errno == EAGAIN || errno == EINTR) {
+                time(&cur_time);
+                continue;
+            } else
+                error("poll: %m");
+        }
+
+        /* Get the current time... */
+        time(&cur_time);
+        
+        i = 0;
+        for (l = protocols; l; l = l->next) {
+            struct interface_info *ip;
+            ip = l->local;
+            if (!FD_ISSET(l->fd, &fds)) {
+//.revents & (POLLIN | POLLHUP))) {
+//                             fds[i].revents = 0;
+                if (ip && (l->handler != got_one ||
+                           !ip->dead)) {
+                    DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
+                    (*(l->handler))(l);
+                    if (interfaces_invalidated)
+                        break;
+                }
+                i++;
+            }
+            interfaces_invalidated = 0;
+        }
+        DH_DbgPrint(MID_TRACE,("Done\n"));
+    } while (1);
+}
+
+void
+got_one(struct protocol *l)
+{
+    struct sockaddr_in from;
+    struct hardware hfrom;
+    struct iaddr ifrom;
+    ssize_t result;
+    union {
+        /*
+         * Packet input buffer.  Must be as large as largest
+         * possible MTU.
+         */
+        unsigned char packbuf[4095];
+        struct dhcp_packet packet;
+    } u;
+    struct interface_info *ip = l->local;
+
+    if ((result = receive_packet(ip, u.packbuf, sizeof(u), &from,
+                                 &hfrom)) == -1) {
+        warning("receive_packet failed on %s: %s", ip->name,
+                strerror(errno));
+        ip->errors++;
+        if ((!interface_status(ip)) ||
+            (ip->noifmedia && ip->errors > 20)) {
+            /* our interface has gone away. */
+            warning("Interface %s no longer appears valid.",
+                    ip->name);
+            ip->dead = 1;
+            interfaces_invalidated = 1;
+            close(l->fd);
+            remove_protocol(l);
+            free(ip);
+        }
+        return;
+    }
+    if (result == 0)
+        return;
+
+    if (bootp_packet_handler) {
+        ifrom.len = 4;
+        memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
+
+        (*bootp_packet_handler)(ip, &u.packet, result,
+                                from.sin_port, ifrom, &hfrom);
+    }
+}
+
+#if 0
+int
+interface_status(struct interface_info *ifinfo)
+{
+    char *ifname = ifinfo->name;
+    int ifsock = ifinfo->rfdesc;
+    struct ifreq ifr;
+    struct ifmediareq ifmr;
+
+    /* get interface flags */
+    memset(&ifr, 0, sizeof(ifr));
+    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+    if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) {
+        syslog(LOG_ERR, "ioctl(SIOCGIFFLAGS) on %s: %m", ifname);
+        goto inactive;
+    }
+
+    /*
+     * if one of UP and RUNNING flags is dropped,
+     * the interface is not active.
+     */
+    if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+        goto inactive;
+
+    /* Next, check carrier on the interface, if possible */
+    if (ifinfo->noifmedia)
+        goto active;
+    memset(&ifmr, 0, sizeof(ifmr));
+    strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+    if (ioctl(ifsock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+        if (errno != EINVAL) {
+            syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
+                   ifname);
+
+            ifinfo->noifmedia = 1;
+            goto active;
+        }
+        /*
+         * EINVAL (or ENOTTY) simply means that the interface
+         * does not support the SIOCGIFMEDIA ioctl. We regard it alive.
+         */
+        ifinfo->noifmedia = 1;
+        goto active;
+    }
+    if (ifmr.ifm_status & IFM_AVALID) {
+        switch (ifmr.ifm_active & IFM_NMASK) {
+        case IFM_ETHER:
+            if (ifmr.ifm_status & IFM_ACTIVE)
+                goto active;
+            else
+                goto inactive;
+            break;
+        default:
+            goto inactive;
+        }
+    }
+inactive:
+    return (0);
+active:
+    return (1);
+}
+#else
+int
+interface_status(struct interface_info *ifinfo)
+{
+    return (1);
+}
+#endif
+
+void
+add_timeout(time_t when, void (*where)(void *), void *what)
+{
+    struct timeout *t, *q;
+
+    DH_DbgPrint(MID_TRACE,("Adding timeout %x %p %x\n", when, where, what));
+    /* See if this timeout supersedes an existing timeout. */
+    t = NULL;
+    for (q = timeouts; q; q = q->next) {
+        if (q->func == where && q->what == what) {
+            if (t)
+                t->next = q->next;
+            else
+                timeouts = q->next;
+            break;
+        }
+        t = q;
+    }
+
+    /* If we didn't supersede a timeout, allocate a timeout
+       structure now. */
+    if (!q) {
+        if (free_timeouts) {
+            q = free_timeouts;
+            free_timeouts = q->next;
+            q->func = where;
+            q->what = what;
+        } else {
+            q = malloc(sizeof(struct timeout));
+            if (!q)
+                error("Can't allocate timeout structure!");
+            q->func = where;
+            q->what = what;
+        }
+    }
+
+    q->when = when;
+
+    /* Now sort this timeout into the timeout list. */
+
+    /* Beginning of list? */
+    if (!timeouts || timeouts->when > q->when) {
+        q->next = timeouts;
+        timeouts = q;
+        return;
+    }
+
+    /* Middle of list? */
+    for (t = timeouts; t->next; t = t->next) {
+        if (t->next->when > q->when) {
+            q->next = t->next;
+            t->next = q;
+            return;
+        }
+    }
+
+    /* End of list. */
+    t->next = q;
+    q->next = NULL;
+}
+
+void
+cancel_timeout(void (*where)(void *), void *what)
+{
+    struct timeout *t, *q;
+
+    /* Look for this timeout on the list, and unlink it if we find it. */
+    t = NULL;
+    for (q = timeouts; q; q = q->next) {
+        if (q->func == where && q->what == what) {
+            if (t)
+                t->next = q->next;
+            else
+                timeouts = q->next;
+            break;
+        }
+        t = q;
+    }
+
+    /* If we found the timeout, put it on the free list. */
+    if (q) {
+        q->next = free_timeouts;
+        free_timeouts = q;
+    }
+}
+
+/* Add a protocol to the list of protocols... */
+void
+add_protocol(char *name, int fd, void (*handler)(struct protocol *),
+             void *local)
+{
+    struct protocol *p;
+
+    p = malloc(sizeof(*p));
+    if (!p)
+        error("can't allocate protocol struct for %s", name);
+
+    p->fd = fd;
+    p->handler = handler;
+    p->local = local;
+    p->next = protocols;
+    protocols = p;
+}
+
+void
+remove_protocol(struct protocol *proto)
+{
+    struct protocol *p, *next, *prev;
+
+    prev = NULL;
+    for (p = protocols; p; p = next) {
+        next = p->next;
+        if (p == proto) {
+            if (prev)
+                prev->next = p->next;
+            else
+                protocols = p->next;
+            free(p);
+        }
+    }
+}
+
+int
+interface_link_status(char *ifname)
+{
+#if 0
+    struct ifmediareq ifmr;
+    int sock;
+
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+        error("Can't create socket");
+
+    memset(&ifmr, 0, sizeof(ifmr));
+    strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+    if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
+        /* EINVAL -> link state unknown. treat as active */
+        if (errno != EINVAL)
+            syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
+                   ifname);
+        close(sock);
+        return (1);
+    }
+    close(sock);
+
+    if (ifmr.ifm_status & IFM_AVALID) {
+        if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) {
+            if (ifmr.ifm_status & IFM_ACTIVE)
+                return (1);
+            else
+                return (0);
+        }
+    }
+#endif
+    return (1);
+}
diff --git a/reactos/subsys/system/dhcp/hash.c b/reactos/subsys/system/dhcp/hash.c
new file mode 100644 (file)
index 0000000..c47c562
--- /dev/null
@@ -0,0 +1,164 @@
+/* hash.c
+
+   Routines for manipulating hash tables... */
+
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: hash.c,v 1.9.2.3 1999/04/09 17:39:41 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "rosdhcp.h"
+
+static INLINE int do_hash PROTO ((unsigned char *, int, int));
+
+struct hash_table *new_hash ()
+{
+       struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE);
+       if (!rv)
+               return rv;
+       memset (&rv -> buckets [0], 0,
+               DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
+       return rv;
+}
+
+static INLINE int do_hash (name, len, size)
+       unsigned char *name;
+       int len;
+       int size;
+{
+       register int accum = 0;
+       register unsigned char *s = name;
+       int i = len;
+       while (i--) {
+               /* Add the character in... */
+               accum += *s++;
+               /* Add carry back in... */
+               while (accum > 255) {
+                       accum = (accum & 255) + (accum >> 8);
+               }
+       }
+       return accum % size;
+}
+
+void add_hash (table, name, len, pointer)
+       struct hash_table *table;
+       int len;
+       unsigned char *name;
+       unsigned char *pointer;
+{
+       int hashno;
+       struct hash_bucket *bp;
+
+       if (!table)
+               return;
+       if (!len)
+               len = strlen ((char *)name);
+
+       hashno = do_hash (name, len, table -> hash_count);
+       bp = new_hash_bucket ();
+
+       if (!bp) {
+               warn ("Can't add %s to hash table.", name);
+               return;
+       }
+       bp -> name = name;
+       bp -> value = pointer;
+       bp -> next = table -> buckets [hashno];
+       bp -> len = len;
+       table -> buckets [hashno] = bp;
+}
+
+void delete_hash_entry (table, name, len)
+       struct hash_table *table;
+       int len;
+       unsigned char *name;
+{
+       int hashno;
+       struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
+
+       if (!table)
+               return;
+       if (!len)
+               len = strlen ((char *)name);
+
+       hashno = do_hash (name, len, table -> hash_count);
+
+       /* Go through the list looking for an entry that matches;
+          if we find it, delete it. */
+       for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
+               if ((!bp -> len &&
+                    !strcmp ((char *)bp -> name, (char *)name)) ||
+                   (bp -> len == len &&
+                    !memcmp (bp -> name, name, len))) {
+                       if (pbp) {
+                               pbp -> next = bp -> next;
+                       } else {
+                               table -> buckets [hashno] = bp -> next;
+                       }
+                       free_hash_bucket (bp, "delete_hash_entry");
+                       break;
+               }
+               pbp = bp;       /* jwg, 9/6/96 - nice catch! */
+       }
+}
+
+unsigned char *hash_lookup (table, name, len)
+       struct hash_table *table;
+       unsigned char *name;
+       int len;
+{
+       int hashno;
+       struct hash_bucket *bp;
+
+       if (!table)
+               return (unsigned char *)0;
+
+       if (!len)
+               len = strlen ((char *)name);
+
+       hashno = do_hash (name, len, table -> hash_count);
+
+       for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
+               if (len == bp -> len && !memcmp (bp -> name, name, len))
+                       return bp -> value;
+       }
+       return (unsigned char *)0;
+}
diff --git a/reactos/subsys/system/dhcp/include/cdefs.h b/reactos/subsys/system/dhcp/include/cdefs.h
new file mode 100644 (file)
index 0000000..2bc67a5
--- /dev/null
@@ -0,0 +1,57 @@
+/* cdefs.h
+
+   Standard C definitions... */
+
+/*
+ * Copyright (c) 1996 The Internet Software Consortium.
+ * All Rights Reserved.
+ * Copyright (c) 1995 RadioMail Corporation.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of RadioMail Corporation, the Internet Software
+ *    Consortium nor the names of its contributors may be used to endorse
+ *    or promote products derived from this software without specific
+ *    prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION, THE INTERNET
+ * SOFTWARE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL RADIOMAIL CORPORATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for RadioMail Corporation by Ted Lemon
+ * under a contract with Vixie Enterprises.   Further modifications have
+ * been made for the Internet Software Consortium under a contract
+ * with Vixie Laboratories.
+ */
+
+#if (defined (__GNUC__) || defined (__STDC__)) && !defined (BROKEN_ANSI)
+#define PROTO(x)       x
+#define KandR(x)
+#define ANSI_DECL(x)   x
+#if defined (__GNUC__)
+#define INLINE         inline
+#else
+#define INLINE
+#endif /* __GNUC__ */
+#else
+#define PROTO(x)       ()
+#define KandR(x)       x
+#define ANSI_DECL(x)
+#define INLINE
+#endif /* __GNUC__ || __STDC__ */
diff --git a/reactos/subsys/system/dhcp/include/debug.h b/reactos/subsys/system/dhcp/include/debug.h
new file mode 100644 (file)
index 0000000..2cac974
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        include/debug.h
+ * PURPOSE:     Debugging support macros
+ * DEFINES:     DBG     - Enable debug output
+ *              NASSERT - Disable assertions
+ */
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#define NORMAL_MASK    0x000000FF
+#define SPECIAL_MASK   0xFFFFFF00
+#define MIN_TRACE      0x00000001
+#define MID_TRACE      0x00000002
+#define MAX_TRACE      0x00000003
+
+#define DEBUG_ADAPTER  0x00000100
+#define DEBUG_ULTRA    0xFFFFFFFF
+
+#ifdef DBG
+
+extern unsigned long debug_trace_level;
+
+#ifdef _MSC_VER
+
+#define DH_DbgPrint(_t_, _x_) \
+    if (((debug_trace_level & NORMAL_MASK) >= _t_) || \
+        ((debug_trace_level & _t_) > NORMAL_MASK)) { \
+        DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
+        DbgPrint _x_ ; \
+    }
+
+#else /* _MSC_VER */
+
+#define DH_DbgPrint(_t_, _x_) \
+    if (((debug_trace_level & NORMAL_MASK) >= _t_) || \
+        ((debug_trace_level & _t_) > NORMAL_MASK)) { \
+        DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
+        DbgPrint _x_ ; \
+    }
+
+#endif /* _MSC_VER */
+
+#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
+
+#else /* DBG */
+
+#define DH_DbgPrint(_t_, _x_)
+
+#endif /* DBG */
+
+
+#define assert(x) ASSERT(x)
+#define assert_irql(x) ASSERT_IRQL(x)
+
+
+#ifdef _MSC_VER
+
+#define UNIMPLEMENTED \
+    TI_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
+        but come back another day.\n", __FILE__, __LINE__));
+
+#else /* _MSC_VER */
+
+#define UNIMPLEMENTED \
+    TI_DbgPrint(MIN_TRACE, ("(%s:%d)(%s) is unimplemented, \
+        but come back another day.\n", __FILE__, __LINE__, __FUNCTION__));
+
+#endif /* _MSC_VER */
+
+
+#define CHECKPOINT \
+    do { TI_DbgPrint(DEBUG_CHECK, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0);
+
+#define CP CHECKPOINT
+
+#define ASSERT_KM_POINTER(_x) \
+   ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \
+   ASSERT(((PVOID)_x) >= (PVOID)0x80000000);
+
+#endif /* __DEBUG_H */
+
+/* EOF */
diff --git a/reactos/subsys/system/dhcp/include/dhcp.h b/reactos/subsys/system/dhcp/include/dhcp.h
new file mode 100644 (file)
index 0000000..8ac8ed3
--- /dev/null
@@ -0,0 +1,169 @@
+/*     $OpenBSD: dhcp.h,v 1.5 2004/05/04 15:49:49 deraadt Exp $        */
+
+/* Protocol structures... */
+
+/*
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DHCP_UDP_OVERHEAD      (14 + /* Ethernet header */     \
+                                20 + /* IP header */           \
+                                8)   /* UDP header */
+#define DHCP_SNAME_LEN         64
+#define DHCP_FILE_LEN          128
+#define DHCP_FIXED_NON_UDP     236
+#define DHCP_FIXED_LEN         (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
+                                               /* Everything but options. */
+#define DHCP_MTU_MAX           1500
+#define DHCP_OPTION_LEN                (DHCP_MTU_MAX - DHCP_FIXED_LEN)
+
+#define BOOTP_MIN_LEN          300
+#define DHCP_MIN_LEN           548
+
+struct dhcp_packet {
+       u_int8_t  op;           /* Message opcode/type */
+       u_int8_t  htype;        /* Hardware addr type (see net/if_types.h) */
+       u_int8_t  hlen;         /* Hardware addr length */
+       u_int8_t  hops;         /* Number of relay agent hops from client */
+       u_int32_t xid;          /* Transaction ID */
+       u_int16_t secs;         /* Seconds since client started looking */
+       u_int16_t flags;        /* Flag bits */
+       struct in_addr ciaddr;  /* Client IP address (if already in use) */
+       struct in_addr yiaddr;  /* Client IP address */
+       struct in_addr siaddr;  /* IP address of next server to talk to */
+       struct in_addr giaddr;  /* DHCP relay agent IP address */
+       unsigned char chaddr[16];       /* Client hardware address */
+       char sname[DHCP_SNAME_LEN];     /* Server name */
+       char file[DHCP_FILE_LEN];       /* Boot filename */
+       unsigned char options[DHCP_OPTION_LEN];
+                               /* Optional parameters
+                                  (actual length dependent on MTU). */
+};
+
+/* BOOTP (rfc951) message types */
+#define BOOTREQUEST    1
+#define BOOTREPLY      2
+
+/* Possible values for flags field... */
+#define BOOTP_BROADCAST 32768L
+
+/* Possible values for hardware type (htype) field... */
+#define HTYPE_ETHER    1               /* Ethernet                     */
+#define HTYPE_IEEE802  6               /* IEEE 802.2 Token Ring...     */
+#define HTYPE_FDDI     8               /* FDDI...                      */
+
+/* Magic cookie validating dhcp options field (and bootp vendor
+   extensions field). */
+#define DHCP_OPTIONS_COOKIE    "\143\202\123\143"
+
+
+/* DHCP Option codes: */
+
+#define DHO_PAD                                0
+#define DHO_SUBNET_MASK                        1
+#define DHO_TIME_OFFSET                        2
+#define DHO_ROUTERS                    3
+#define DHO_TIME_SERVERS               4
+#define DHO_NAME_SERVERS               5
+#define DHO_DOMAIN_NAME_SERVERS                6
+#define DHO_LOG_SERVERS                        7
+#define DHO_COOKIE_SERVERS             8
+#define DHO_LPR_SERVERS                        9
+#define DHO_IMPRESS_SERVERS            10
+#define DHO_RESOURCE_LOCATION_SERVERS  11
+#define DHO_HOST_NAME                  12
+#define DHO_BOOT_SIZE                  13
+#define DHO_MERIT_DUMP                 14
+#define DHO_DOMAIN_NAME                        15
+#define DHO_SWAP_SERVER                        16
+#define DHO_ROOT_PATH                  17
+#define DHO_EXTENSIONS_PATH            18
+#define DHO_IP_FORWARDING              19
+#define DHO_NON_LOCAL_SOURCE_ROUTING   20
+#define DHO_POLICY_FILTER              21
+#define DHO_MAX_DGRAM_REASSEMBLY       22
+#define DHO_DEFAULT_IP_TTL             23
+#define DHO_PATH_MTU_AGING_TIMEOUT     24
+#define DHO_PATH_MTU_PLATEAU_TABLE     25
+#define DHO_INTERFACE_MTU              26
+#define DHO_ALL_SUBNETS_LOCAL          27
+#define DHO_BROADCAST_ADDRESS          28
+#define DHO_PERFORM_MASK_DISCOVERY     29
+#define DHO_MASK_SUPPLIER              30
+#define DHO_ROUTER_DISCOVERY           31
+#define DHO_ROUTER_SOLICITATION_ADDRESS        32
+#define DHO_STATIC_ROUTES              33
+#define DHO_TRAILER_ENCAPSULATION      34
+#define DHO_ARP_CACHE_TIMEOUT          35
+#define DHO_IEEE802_3_ENCAPSULATION    36
+#define DHO_DEFAULT_TCP_TTL            37
+#define DHO_TCP_KEEPALIVE_INTERVAL     38
+#define DHO_TCP_KEEPALIVE_GARBAGE      39
+#define DHO_NIS_DOMAIN                 40
+#define DHO_NIS_SERVERS                        41
+#define DHO_NTP_SERVERS                        42
+#define DHO_VENDOR_ENCAPSULATED_OPTIONS        43
+#define DHO_NETBIOS_NAME_SERVERS       44
+#define DHO_NETBIOS_DD_SERVER          45
+#define DHO_NETBIOS_NODE_TYPE          46
+#define DHO_NETBIOS_SCOPE              47
+#define DHO_FONT_SERVERS               48
+#define DHO_X_DISPLAY_MANAGER          49
+#define DHO_DHCP_REQUESTED_ADDRESS     50
+#define DHO_DHCP_LEASE_TIME            51
+#define DHO_DHCP_OPTION_OVERLOAD       52
+#define DHO_DHCP_MESSAGE_TYPE          53
+#define DHO_DHCP_SERVER_IDENTIFIER     54
+#define DHO_DHCP_PARAMETER_REQUEST_LIST        55
+#define DHO_DHCP_MESSAGE               56
+#define DHO_DHCP_MAX_MESSAGE_SIZE      57
+#define DHO_DHCP_RENEWAL_TIME          58
+#define DHO_DHCP_REBINDING_TIME                59
+#define DHO_DHCP_CLASS_IDENTIFIER      60
+#define DHO_DHCP_CLIENT_IDENTIFIER     61
+#define DHO_DHCP_USER_CLASS_ID         77
+#define DHO_END                                255
+
+/* DHCP message types. */
+#define DHCPDISCOVER   1
+#define DHCPOFFER      2
+#define DHCPREQUEST    3
+#define DHCPDECLINE    4
+#define DHCPACK                5
+#define DHCPNAK                6
+#define DHCPRELEASE    7
+#define DHCPINFORM     8
diff --git a/reactos/subsys/system/dhcp/include/dhcpd.h b/reactos/subsys/system/dhcp/include/dhcpd.h
new file mode 100644 (file)
index 0000000..7754d6d
--- /dev/null
@@ -0,0 +1,487 @@
+/*     $OpenBSD: dhcpd.h,v 1.33 2004/05/06 22:29:15 deraadt Exp $      */
+
+/*
+ * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef DHCPD_H
+#define DHCPD_H
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+#include "stdint.h"
+
+#define IFNAMSIZ MAX_INTERFACE_NAME_LEN
+
+#define ETH_ALEN 6
+#define ETHER_ADDR_LEN  ETH_ALEN
+struct ether_header
+{
+  u_int8_t  ether_dhost[ETH_ALEN];      /* destination eth addr */
+  u_int8_t  ether_shost[ETH_ALEN];      /* source ether addr    */
+  u_int16_t ether_type;                 /* packet type ID field */
+} __attribute__ ((__packed__));
+
+struct ip
+  {
+    unsigned int ip_hl:4;               /* header length */
+    unsigned int ip_v:4;                /* version */
+    u_int8_t ip_tos;                    /* type of service */
+    u_short ip_len;                     /* total length */
+    u_short ip_id;                      /* identification */
+    u_short ip_off;                     /* fragment offset field */
+#define IP_RF 0x8000                    /* reserved fragment flag */
+#define IP_DF 0x4000                    /* dont fragment flag */
+#define IP_MF 0x2000                    /* more fragments flag */
+#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
+    u_int8_t ip_ttl;                    /* time to live */
+    u_int8_t ip_p;                      /* protocol */
+    u_short ip_sum;                     /* checksum */
+    struct in_addr ip_src, ip_dst;      /* source and dest address */
+  };
+
+struct udphdr {
+       u_int16_t uh_sport;           /* source port */
+       u_int16_t uh_dport;           /* destination port */
+       u_int16_t uh_ulen;            /* udp length */
+       u_int16_t uh_sum;             /* udp checksum */
+};
+
+#define ETHERTYPE_IP 0x0800
+#define IPTOS_LOWDELAY 0x10
+#define ARPHRD_ETHER 1
+
+// FIXME: I have no idea what this should be!
+#define SIZE_T_MAX 1600
+
+#define USE_SOCKET_RECEIVE
+#define USE_SOCKET_SEND
+
+#include <sys/types.h>
+
+//#include <sys/socket.h>
+//#include <sys/sockio.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+//#include <sys/un.h>
+//#include <sys/wait.h>
+
+//#include <net/if.h>
+//#include <net/if_dl.h>
+//#include <net/route.h>
+
+//#include <netinet/in.h>
+//#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+//#include <netdb.h>
+//#include <paths.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "dhcp.h"
+#include "tree.h"
+
+#define        LOCAL_PORT      68
+#define        REMOTE_PORT     67
+
+struct option_data {
+       int              len;
+       u_int8_t        *data;
+};
+
+struct string_list {
+       struct string_list      *next;
+       char                    *string;
+};
+
+struct iaddr {
+       int len;
+       unsigned char iabuf[16];
+};
+
+struct iaddrlist {
+       struct iaddrlist *next;
+       struct iaddr addr;
+};
+
+struct packet {
+       struct dhcp_packet      *raw;
+       int                      packet_length;
+       int                      packet_type;
+       int                      options_valid;
+       int                      client_port;
+       struct iaddr             client_addr;
+       struct interface_info   *interface;
+       struct hardware         *haddr;
+       struct option_data       options[256];
+};
+
+struct hardware {
+       u_int8_t htype;
+       u_int8_t hlen;
+       u_int8_t haddr[16];
+};
+
+struct client_lease {
+       struct client_lease     *next;
+       time_t                   expiry, renewal, rebind;
+       struct iaddr             address;
+       char                    *server_name;
+       char                    *filename;
+       struct string_list      *medium;
+       unsigned int             is_static : 1;
+       unsigned int             is_bootp : 1;
+       struct option_data       options[256];
+};
+
+/* Possible states in which the client can be. */
+enum dhcp_state {
+       S_REBOOTING,
+       S_INIT,
+       S_SELECTING,
+       S_REQUESTING,
+       S_BOUND,
+       S_RENEWING,
+       S_REBINDING
+};
+
+struct client_config {
+       struct option_data      defaults[256];
+       enum {
+               ACTION_DEFAULT,
+               ACTION_SUPERSEDE,
+               ACTION_PREPEND,
+               ACTION_APPEND
+       } default_actions[256];
+
+       struct option_data       send_options[256];
+       u_int8_t                 required_options[256];
+       u_int8_t                 requested_options[256];
+       int                      requested_option_count;
+       time_t                   timeout;
+       time_t                   initial_interval;
+       time_t                   retry_interval;
+       time_t                   select_interval;
+       time_t                   reboot_timeout;
+       time_t                   backoff_cutoff;
+       struct string_list      *media;
+       char                    *script_name;
+       enum { IGNORE, ACCEPT, PREFER }
+                                bootp_policy;
+       struct string_list      *medium;
+       struct iaddrlist        *reject_list;
+};
+
+struct client_state {
+       struct client_lease      *active;
+       struct client_lease      *new;
+       struct client_lease      *offered_leases;
+       struct client_lease      *leases;
+       struct client_lease      *alias;
+       enum dhcp_state           state;
+       struct iaddr              destination;
+       u_int32_t                 xid;
+       u_int16_t                 secs;
+       time_t                    first_sending;
+       time_t                    interval;
+       struct string_list       *medium;
+       struct dhcp_packet        packet;
+       int                       packet_length;
+       struct iaddr              requested_address;
+       struct client_config     *config;
+};
+
+struct interface_info {
+       struct interface_info   *next;
+       struct hardware          hw_address;
+       struct in_addr           primary_address;
+       char                     name[IFNAMSIZ];
+       int                      rfdesc;
+       int                      wfdesc;
+       unsigned char           *rbuf;
+       size_t                   rbuf_max;
+       size_t                   rbuf_offset;
+       size_t                   rbuf_len;
+       struct client_state     *client;
+       int                      noifmedia;
+       int                      errors;
+       int                      dead;
+       u_int16_t                index;
+};
+
+struct timeout {
+       struct timeout  *next;
+       time_t           when;
+       void             (*func)(void *);
+       void            *what;
+};
+
+struct protocol {
+       struct protocol *next;
+       int fd;
+       void (*handler)(struct protocol *);
+       void *local;
+};
+
+#define DEFAULT_HASH_SIZE 97
+
+struct hash_bucket {
+       struct hash_bucket *next;
+       unsigned char *name;
+       int len;
+       unsigned char *value;
+};
+
+struct hash_table {
+       int hash_count;
+       struct hash_bucket *buckets[DEFAULT_HASH_SIZE];
+};
+
+/* Default path to dhcpd config file. */
+#define        _PATH_DHCLIENT_CONF     "/etc/dhclient.conf"
+#define        _PATH_DHCLIENT_DB       "/var/db/dhclient.leases"
+#define        DHCPD_LOG_FACILITY      LOG_DAEMON
+
+#define        MAX_TIME 0x7fffffff
+#define        MIN_TIME 0
+
+/* External definitions... */
+
+/* options.c */
+int cons_options(struct packet *, struct dhcp_packet *, int,
+    struct tree_cache **, int, int, int, u_int8_t *, int);
+char *pretty_print_option(unsigned int,
+    unsigned char *, int, int, int);
+void do_packet(struct interface_info *, struct dhcp_packet *,
+    int, unsigned int, struct iaddr, struct hardware *);
+
+/* errwarn.c */
+extern int warnings_occurred;
+void error(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+int warning(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+int note(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+int debug(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+int parse_warn(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+
+/* conflex.c */
+extern int lexline, lexchar;
+extern char *token_line, *tlname;
+extern char comments[4096];
+extern int comment_index;
+extern int eol_token;
+void new_parse(char *);
+int next_token(char **, FILE *);
+int peek_token(char **, FILE *);
+
+/* parse.c */
+void skip_to_semi(FILE *);
+int parse_semi(FILE *);
+char *parse_string(FILE *);
+int parse_ip_addr(FILE *, struct iaddr *);
+void parse_hardware_param(FILE *, struct hardware *);
+void parse_lease_time(FILE *, time_t *);
+unsigned char *parse_numeric_aggregate(FILE *, unsigned char *, int *,
+    int, int, int);
+void convert_num(unsigned char *, char *, int, int);
+time_t parse_date(FILE *);
+
+/* tree.c */
+pair cons(caddr_t, pair);
+
+/* alloc.c */
+struct string_list     *new_string_list(size_t size);
+struct hash_table      *new_hash_table(int);
+struct hash_bucket     *new_hash_bucket(void);
+
+/* bpf.c */
+int if_register_bpf(struct interface_info *);
+void if_register_send(struct interface_info *);
+void if_register_receive(struct interface_info *);
+ssize_t send_packet(struct interface_info *, struct dhcp_packet *, size_t,
+    struct in_addr, struct sockaddr_in *, struct hardware *);
+ssize_t receive_packet(struct interface_info *, unsigned char *, size_t,
+    struct sockaddr_in *, struct hardware *);
+
+/* dispatch.c */
+extern void (*bootp_packet_handler)(struct interface_info *,
+    struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *);
+void discover_interfaces(struct interface_info *);
+void reinitialize_interfaces(void);
+void dispatch(void);
+void got_one(struct protocol *);
+void add_timeout(time_t, void (*)(void *), void *);
+void cancel_timeout(void (*)(void *), void *);
+void add_protocol(char *, int, void (*)(struct protocol *), void *);
+void remove_protocol(struct protocol *);
+int interface_link_status(char *);
+
+/* hash.c */
+struct hash_table *new_hash(void);
+void add_hash(struct hash_table *, unsigned char *, int, unsigned char *);
+unsigned char *hash_lookup(struct hash_table *, unsigned char *, int);
+
+/* tables.c */
+extern struct dhcp_option dhcp_options[256];
+extern unsigned char dhcp_option_default_priority_list[];
+extern int sizeof_dhcp_option_default_priority_list;
+extern struct hash_table universe_hash;
+extern struct universe dhcp_universe;
+void initialize_universes(void);
+
+/* convert.c */
+u_int32_t getULong(unsigned char *);
+int32_t getLong(unsigned char *);
+u_int16_t getUShort(unsigned char *);
+int16_t getShort(unsigned char *);
+void putULong(unsigned char *, u_int32_t);
+void putLong(unsigned char *, int32_t);
+void putUShort(unsigned char *, unsigned int);
+void putShort(unsigned char *, int);
+
+/* inet.c */
+struct iaddr subnet_number(struct iaddr, struct iaddr);
+struct iaddr broadcast_addr(struct iaddr, struct iaddr);
+int addr_eq(struct iaddr, struct iaddr);
+char *piaddr(struct iaddr);
+
+/* dhclient.c */
+extern char *path_dhclient_conf;
+extern char *path_dhclient_db;
+extern time_t cur_time;
+extern int log_priority;
+extern int log_perror;
+
+extern struct client_config top_level_config;
+
+void dhcpoffer(struct packet *);
+void dhcpack(struct packet *);
+void dhcpnak(struct packet *);
+
+void send_discover(void *);
+void send_request(void *);
+void send_decline(void *);
+
+void state_reboot(void *);
+void state_init(void *);
+void state_selecting(void *);
+void state_requesting(void *);
+void state_bound(void *);
+void state_panic(void *);
+
+void bind_lease(struct interface_info *);
+
+void make_discover(struct interface_info *, struct client_lease *);
+void make_request(struct interface_info *, struct client_lease *);
+void make_decline(struct interface_info *, struct client_lease *);
+
+void free_client_lease(struct client_lease *);
+void rewrite_client_leases(void);
+void write_client_lease(struct interface_info *, struct client_lease *, int);
+
+void    priv_script_init(char *, char *);
+void    priv_script_write_params(char *, struct client_lease *);
+int     priv_script_go(void);
+
+void script_init(char *, struct string_list *);
+void script_write_params(char *, struct client_lease *);
+int script_go(void);
+void client_envadd(struct client_state *,
+    const char *, const char *, const char *, ...);
+void script_set_env(struct client_state *, const char *, const char *,
+    const char *);
+void script_flush_env(struct client_state *);
+int dhcp_option_ev_name(char *, size_t, struct dhcp_option *);
+
+struct client_lease *packet_to_lease(struct packet *);
+void go_daemon(void);
+void client_location_changed(void);
+
+void bootp(struct packet *);
+void dhcp(struct packet *);
+
+/* packet.c */
+void assemble_hw_header(struct interface_info *, unsigned char *,
+    int *, struct hardware *);
+void assemble_udp_ip_header(unsigned char *, int *, u_int32_t, u_int32_t,
+    unsigned int, unsigned char *, int);
+ssize_t decode_hw_header(unsigned char *, int, struct hardware *);
+ssize_t decode_udp_ip_header(unsigned char *, int, struct sockaddr_in *,
+    unsigned char *, int);
+
+/* ethernet.c */
+void assemble_ethernet_header(struct interface_info *, unsigned char *,
+    int *, struct hardware *);
+ssize_t decode_ethernet_header(struct interface_info *, unsigned char *,
+    int, struct hardware *);
+
+/* clparse.c */
+int read_client_conf(void);
+void read_client_leases(void);
+void parse_client_statement(FILE *, struct interface_info *,
+    struct client_config *);
+int parse_X(FILE *, u_int8_t *, int);
+int parse_option_list(FILE *, u_int8_t *);
+void parse_interface_declaration(FILE *, struct client_config *);
+struct interface_info *interface_or_dummy(char *);
+void make_client_state(struct interface_info *);
+void make_client_config(struct interface_info *, struct client_config *);
+void parse_client_lease_statement(FILE *, int);
+void parse_client_lease_declaration(FILE *, struct client_lease *,
+    struct interface_info **);
+struct dhcp_option *parse_option_decl(FILE *, struct option_data *);
+void parse_string_list(FILE *, struct string_list **, int);
+void parse_reject_statement(FILE *, struct client_config *);
+
+/* privsep.c */
+struct buf     *buf_open(size_t);
+int             buf_add(struct buf *, void *, size_t);
+int             buf_close(int, struct buf *);
+ssize_t                 buf_read(int, void *, size_t);
+void            dispatch_imsg(int);
+
+#endif/*DHCPD_H*/
diff --git a/reactos/subsys/system/dhcp/include/dhctoken.h b/reactos/subsys/system/dhcp/include/dhctoken.h
new file mode 100644 (file)
index 0000000..2aeb530
--- /dev/null
@@ -0,0 +1,136 @@
+/* dhctoken.h
+
+   Tokens for config file lexer and parser. */
+
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define SEMI ';'
+#define DOT '.'
+#define COLON ':'
+#define COMMA ','
+#define SLASH '/'
+#define LBRACE '{'
+#define RBRACE '}'
+
+#define FIRST_TOKEN    HOST
+#define HOST           256
+#define HARDWARE       257
+#define FILENAME       258
+#define FIXED_ADDR     259
+#define OPTION         260
+#define ETHERNET       261
+#define STRING         262
+#define NUMBER         263
+#define NUMBER_OR_NAME 264
+#define NAME           265
+#define TIMESTAMP      266
+#define STARTS         267
+#define ENDS           268
+#define UID            269
+#define CLASS          270
+#define LEASE          271
+#define RANGE          272
+#define PACKET         273
+#define CIADDR         274
+#define YIADDR         275
+#define SIADDR         276
+#define GIADDR         277
+#define SUBNET         278
+#define NETMASK                279
+#define DEFAULT_LEASE_TIME 280
+#define MAX_LEASE_TIME 281
+#define VENDOR_CLASS   282
+#define USER_CLASS     283
+#define SHARED_NETWORK 284
+#define SERVER_NAME    285
+#define DYNAMIC_BOOTP  286
+#define SERVER_IDENTIFIER 287
+#define DYNAMIC_BOOTP_LEASE_CUTOFF 288
+#define DYNAMIC_BOOTP_LEASE_LENGTH 289
+#define BOOT_UNKNOWN_CLIENTS 290
+#define NEXT_SERVER    291
+#define TOKEN_RING     292
+#define GROUP          293
+#define ONE_LEASE_PER_CLIENT 294
+#define GET_LEASE_HOSTNAMES 295
+#define USE_HOST_DECL_NAMES 296
+#define SEND           297
+#define CLIENT_IDENTIFIER 298
+#define REQUEST                299
+#define REQUIRE                300
+#define TIMEOUT                301
+#define RETRY          302
+#define SELECT_TIMEOUT 303
+#define SCRIPT         304
+#define INTERFACE      305
+#define RENEW          306
+#define        REBIND          307
+#define EXPIRE         308
+#define UNKNOWN_CLIENTS        309
+#define        ALLOW           310
+#define BOOTP          311
+#define DENY           312
+#define BOOTING                313
+#define DEFAULT                314
+#define MEDIA          315
+#define MEDIUM         316
+#define ALIAS          317
+#define REBOOT         318
+#define ABANDONED      319
+#define        BACKOFF_CUTOFF  320
+#define        INITIAL_INTERVAL 321
+#define NAMESERVER     322
+#define        DOMAIN          323
+#define SEARCH         324
+#define SUPERSEDE      325
+#define APPEND         326
+#define PREPEND                327
+#define HOSTNAME       328
+#define CLIENT_HOSTNAME        329
+#define REJECT         330
+#define FDDI           331
+#define USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 332
+#define AUTHORITATIVE  333
+#define TOKEN_NOT      334
+#define ALWAYS_REPLY_RFC1048 335
+
+#define is_identifier(x)       ((x) >= FIRST_TOKEN &&  \
+                                (x) != STRING &&       \
+                                (x) != NUMBER &&       \
+                                (x) != EOF)
diff --git a/reactos/subsys/system/dhcp/include/hash.h b/reactos/subsys/system/dhcp/include/hash.h
new file mode 100644 (file)
index 0000000..1bebb31
--- /dev/null
@@ -0,0 +1,56 @@
+/* hash.h
+
+   Definitions for hashing... */
+
+/*
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define DEFAULT_HASH_SIZE      97
+
+struct hash_bucket {
+       struct hash_bucket *next;
+       unsigned char *name;
+       int len;
+       unsigned char *value;
+};
+
+struct hash_table {
+       int hash_count;
+       struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
+};
+
diff --git a/reactos/subsys/system/dhcp/include/inet.h b/reactos/subsys/system/dhcp/include/inet.h
new file mode 100644 (file)
index 0000000..a45f922
--- /dev/null
@@ -0,0 +1,52 @@
+/* inet.h
+
+   Portable definitions for internet addresses */
+
+/*
+ * Copyright (c) 1996 The Internet Software Consortium.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+/* An internet address of up to 128 bits. */
+
+typedef struct _iaddr {
+       int len;
+       unsigned char iabuf [16];
+} iaddr;
+
+typedef struct _iaddrlist {
+       struct _iaddrlist *next;
+       iaddr addr;
+} iaddrlist;
diff --git a/reactos/subsys/system/dhcp/include/osdep.h b/reactos/subsys/system/dhcp/include/osdep.h
new file mode 100644 (file)
index 0000000..71a9859
--- /dev/null
@@ -0,0 +1,294 @@
+/* osdep.h
+
+   Operating system dependencies... */
+
+/*
+ * Copyright (c) 1996, 1997, 1998, 1999 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software was written for the Internet Software Consortium by Ted Lemon
+ * under a contract with Vixie Laboratories.
+ */
+
+#include "site.h"
+
+/* Porting::
+
+   If you add a new network API, you must add a check for it below: */
+
+#if !defined (USE_SOCKETS) && \
+    !defined (USE_SOCKET_SEND) && \
+    !defined (USE_SOCKET_RECEIVE) && \
+    !defined (USE_RAW_SOCKETS) && \
+    !defined (USE_RAW_SEND) && \
+    !defined (USE_SOCKET_RECEIVE) && \
+    !defined (USE_BPF) && \
+    !defined (USE_BPF_SEND) && \
+    !defined (USE_BPF_RECEIVE) && \
+    !defined (USE_LPF) && \
+    !defined (USE_LPF_SEND) && \
+    !defined (USE_LPF_RECEIVE) && \
+    !defined (USE_NIT) && \
+    !defined (USE_NIT_SEND) && \
+    !defined (USE_NIT_RECEIVE) && \
+    !defined (USR_DLPI_SEND) && \
+    !defined (USE_DLPI_RECEIVE)
+#  define USE_DEFAULT_NETWORK
+#endif
+
+
+/* Porting::
+
+   If you add a new system configuration file, include it here: */
+
+#if defined (sun)
+# if defined (__svr4__) || defined (__SVR4)
+#  include "cf/sunos5-5.h"
+# else
+#  include "cf/sunos4.h"
+# endif
+#endif
+
+#ifdef aix
+#  include "cf/aix.h"
+#endif
+
+#ifdef bsdi
+#  include "cf/bsdos.h"
+#endif
+
+#ifdef __NetBSD__
+#  include "cf/netbsd.h"
+#endif
+
+#ifdef __FreeBSD__
+#  include "cf/freebsd.h"
+#endif
+
+#if defined (__osf__) && defined (__alpha)
+#  include "cf/alphaosf.h"
+#endif
+
+#ifdef ultrix
+#  include "cf/ultrix.h"
+#endif
+
+#ifdef linux
+#  include "cf/linux.h"
+#endif
+
+#ifdef SCO
+#  include "cf/sco.h"
+#endif
+
+#if defined (hpux) || defined (__hpux)
+#  include "cf/hpux.h"
+#endif
+
+#ifdef __QNX__
+#  include "cf/qnx.h"
+#endif
+
+#ifdef __CYGWIN32__
+#  include "cf/cygwin32.h"
+#endif
+
+#ifdef __APPLE__
+# include "cf/rhapsody.h"
+#else
+# if defined (NeXT)
+#  include "cf/nextstep.h"
+# endif
+#endif
+
+#if defined(IRIX) || defined(__sgi)
+# include "cf/irix.h"
+#endif
+
+#if !defined (TIME_MAX)
+# define TIME_MAX 2147483647
+#endif
+
+/* Porting::
+
+   If you add a new network API, and have it set up so that it can be
+   used for sending or receiving, but doesn't have to be used for both,
+   then set up an ifdef like the ones below: */
+
+#ifdef USE_SOCKETS
+#  define USE_SOCKET_SEND
+#  define USE_SOCKET_RECEIVE
+#endif
+
+#ifdef USE_RAW_SOCKETS
+#  define USE_RAW_SEND
+#  define USE_SOCKET_RECEIVE
+#endif
+
+#ifdef USE_BPF
+#  define USE_BPF_SEND
+#  define USE_BPF_RECEIVE
+#endif
+
+#ifdef USE_LPF
+#  define USE_LPF_SEND
+#  define USE_LPF_RECEIVE
+#endif
+
+#ifdef USE_NIT
+#  define USE_NIT_SEND
+#  define USE_NIT_RECEIVE
+#endif
+
+#ifdef USE_DLPI
+#  define USE_DLPI_SEND
+#  define USE_DLPI_RECEIVE
+#endif
+
+#ifdef USE_UPF
+#  define USE_UPF_SEND
+#  define USE_UPF_RECEIVE
+#endif
+
+/* Porting::
+
+   If you add support for sending packets directly out an interface,
+   and your support does not do ARP or routing, you must use a fallback
+   mechanism to deal with packets that need to be sent to routers.
+   Currently, all low-level packet interfaces use BSD sockets as a
+   fallback. */
+
+#if defined (USE_BPF_SEND) || defined (USE_NIT_SEND) || \
+    defined (USE_DLPI_SEND) || defined (USE_UPF_SEND) || defined (USE_LPF_SEND)
+#  define USE_SOCKET_FALLBACK
+#  define USE_FALLBACK
+#endif
+
+/* Porting::
+
+   If you add support for sending packets directly out an interface
+   and need to be able to assemble packets, add the USE_XXX_SEND
+   definition for your interface to the list tested below. */
+
+#if defined (USE_RAW_SEND) || defined (USE_BPF_SEND) || \
+               defined (USE_NIT_SEND) || defined (USE_UPF_SEND) || \
+               defined (USE_DLPI_SEND) || defined (USE_LPF_SEND)
+#  define PACKET_ASSEMBLY
+#endif
+
+/* Porting::
+
+   If you add support for receiving packets directly from an interface
+   and need to be able to decode raw packets, add the USE_XXX_RECEIVE
+   definition for your interface to the list tested below. */
+
+#if defined (USE_RAW_RECEIVE) || defined (USE_BPF_SEND) || \
+               defined (USE_NIT_RECEIVE) || defined (USE_UPF_RECEIVE) || \
+               defined (USE_DLPI_RECEIVE) || \
+    defined (USE_LPF_SEND) || \
+    (defined (USE_SOCKET_SEND) && defined (SO_BINDTODEVICE))
+#  define PACKET_DECODING
+#endif
+
+/* If we don't have a DLPI packet filter, we have to filter in userland.
+   Probably not worth doing, actually. */
+#if defined (USE_DLPI_RECEIVE) && !defined (USE_DLPI_PFMOD)
+#  define USERLAND_FILTER
+#endif
+
+/* jmp_buf is assumed to be a struct unless otherwise defined in the
+   system header. */
+#ifndef jbp_decl
+# define jbp_decl(x)   jmp_buf *x
+#endif
+#ifndef jref
+# define jref(x)       (&(x))
+#endif
+#ifndef jdref
+# define jdref(x)      (*(x))
+#endif
+#ifndef jrefproto
+# define jrefproto     jmp_buf *
+#endif
+
+#ifndef BPF_FORMAT
+# define BPF_FORMAT "/dev/bpf%d"
+#endif
+
+#if defined (IFF_POINTOPOINT) && !defined (HAVE_IFF_POINTOPOINT)
+# define HAVE_IFF_POINTOPOINT
+#endif
+
+#if defined (AF_LINK) && !defined (HAVE_AF_LINK)
+# define HAVE_AF_LINK
+#endif
+
+#if defined (ARPHRD_TUNNEL) && !defined (HAVE_ARPHRD_TUNNEL)
+# define HAVE_ARPHRD_TUNNEL
+#endif
+
+#if defined (ARPHRD_LOOPBACK) && !defined (HAVE_ARPHRD_LOOPBACK)
+# define HAVE_ARPHRD_LOOPBACK
+#endif
+
+#if defined (ARPHRD_ROSE) && !defined (HAVE_ARPHRD_ROSE)
+# define HAVE_ARPHRD_ROSE
+#endif
+
+#if defined (ARPHRD_IEEE802) && !defined (HAVE_ARPHRD_IEEE802)
+# define HAVE_ARPHRD_IEEE802
+#endif
+
+#if defined (ARPHRD_FDDI) && !defined (HAVE_ARPHRD_FDDI)
+# define HAVE_ARPHRD_FDDI
+#endif
+
+#if defined (ARPHRD_AX25) && !defined (HAVE_ARPHRD_AX25)
+# define HAVE_ARPHRD_AX25
+#endif
+
+#if defined (ARPHRD_NETROM) && !defined (HAVE_ARPHRD_NETROM)
+# define HAVE_ARPHRD_NETROM
+#endif
+
+#if defined (ARPHRD_METRICOM) && !defined (HAVE_ARPHRD_METRICOM)
+# define HAVE_ARPHRD_METRICOM
+#endif
+
+#if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
+# define HAVE_SO_BINDTODEVICE
+#endif
+
+#if defined (SIOCGIFHWADDR) && !defined (HAVE_SIOCGIFHWADDR)
+# define HAVE_SIOCGIFHWADDR
+#endif
+
+#if defined (AF_LINK) && !defined (HAVE_AF_LINK)
+# define HAVE_AF_LINK
+#endif
diff --git a/reactos/subsys/system/dhcp/include/predec.h b/reactos/subsys/system/dhcp/include/predec.h
new file mode 100644 (file)
index 0000000..7f2515b
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef REACTOS_PREDEC_H
+#define REACTOS_PREDEC_H
+
+struct iaddr;
+struct interface_info;
+
+#endif
diff --git a/reactos/subsys/system/dhcp/include/privsep.h b/reactos/subsys/system/dhcp/include/privsep.h
new file mode 100644 (file)
index 0000000..e1fc52d
--- /dev/null
@@ -0,0 +1,47 @@
+/*     $OpenBSD: privsep.h,v 1.2 2004/05/04 18:51:18 henning Exp $ */
+
+/*
+ * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+//#include <poll.h>
+//#include <pwd.h>
+
+struct buf {
+       u_char                  *buf;
+       size_t                   size;
+       size_t                   wpos;
+       size_t                   rpos;
+};
+
+enum imsg_code {
+       IMSG_NONE,
+       IMSG_SCRIPT_INIT,
+       IMSG_SCRIPT_WRITE_PARAMS,
+       IMSG_SCRIPT_GO,
+       IMSG_SCRIPT_GO_RET
+};
+
+struct imsg_hdr {
+       enum imsg_code  code;
+       size_t          len;
+};
+
+struct buf     *buf_open(size_t);
+int             buf_add(struct buf *, void *, size_t);
+int             buf_close(int, struct buf *);
+ssize_t                 buf_read(int sock, void *, size_t);
diff --git a/reactos/subsys/system/dhcp/include/rosdhcp.h b/reactos/subsys/system/dhcp/include/rosdhcp.h
new file mode 100644 (file)
index 0000000..6c093ec
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef ROSDHCP_H
+#define ROSDHCP_H
+
+#include <roscfg.h>
+#include <windows.h>
+#include <winnt.h>
+#include <iprtrmib.h>
+#include <iphlpapi.h>
+#include <winsock2.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include "stdint.h"
+#include "predec.h"
+#include "debug.h"
+#define IFNAMSIZ MAX_INTERFACE_NAME_LEN
+#undef interface /* wine/objbase.h -- Grrr */
+
+#undef IGNORE
+#undef ACCEPT
+#undef PREFER
+#define DHCP_DISCOVER_INTERVAL 15
+#define DHCP_REBOOT_TIMEOUT 300
+#define DHCP_BACKOFF_MAX 300
+#define _PATH_DHCLIENT_PID "\\systemroot\\system32\\drivers\\etc\\dhclient.pid"
+
+typedef void *VOIDPTR;
+
+#define NTOS_MODE_USER
+#include <ntos.h>
+typedef u_int32_t uintTIME;
+#define TIME uintTIME
+#include "dhcpd.h"
+
+#define INLINE inline
+#define PROTO(x) x
+
+typedef void (*handler_t) PROTO ((struct packet *));
+
+typedef struct _DHCP_ADAPTER {
+    LIST_ENTRY     ListEntry;
+    MIB_IFROW      IfMib;
+    MIB_IPADDRROW  IfAddr;
+    SOCKADDR       Address;
+    struct interface_info DhclientInfo;
+    struct client_state DhclientState;
+    struct client_config DhclientConfig;
+    struct sockaddr_in ListenAddr;
+    unsigned int BindStatus;
+    char recv_buf[1];
+} DHCP_ADAPTER, *PDHCP_ADAPTER;
+
+#define random rand
+#define srandom srand
+
+#endif/*ROSDHCP_H*/
diff --git a/reactos/subsys/system/dhcp/include/site.h b/reactos/subsys/system/dhcp/include/site.h
new file mode 100644 (file)
index 0000000..30fdb70
--- /dev/null
@@ -0,0 +1,100 @@
+/* Site-specific definitions.
+
+   For supported systems, you shouldn't need to make any changes here.
+   However, you may want to, in order to deal with site-specific
+   differences. */
+
+/* Add any site-specific definitions and inclusions here... */
+
+/* #include <site-foo-bar.h> */
+/* #define SITE_FOOBAR */
+
+/* Define this if you don't want dhcpd to run as a daemon and do want
+   to see all its output printed to stdout instead of being logged via
+   syslog().   This also makes dhcpd use the dhcpd.conf in its working
+   directory and write the dhcpd.leases file there. */
+
+/* #define DEBUG */
+
+/* Define this to see what the parser is parsing.   You probably don't
+   want to see this. */
+
+/* #define DEBUG_TOKENS */
+
+/* Define this to see dumps of incoming and outgoing packets.    This
+   slows things down quite a bit... */
+
+/* #define DEBUG_PACKET */
+
+/* Define this if you want to see dumps of tree evaluations.   The most
+   common reason for doing this is to watch what happens with DNS name
+   lookups. */
+
+/* #define DEBUG_EVAL */
+
+/* Define this if you want the dhcpd.pid file to go somewhere other than
+   the default (which varies from system to system, but is usually either
+   /etc or /var/run. */
+
+/* #define _PATH_DHCPD_PID     "/var/run/dhcpd.pid" */
+
+/* Define this if you want the dhcpd.leases file (the dynamic lease database)
+   to go somewhere other than the default location, which is normally
+   /etc/dhcpd.leases. */
+
+/* #define _PATH_DHCPD_DB      "/etc/dhcpd.leases" */
+
+/* Define this if you want the dhcpd.conf file to go somewhere other than
+   the default location.   By default, it goes in /etc/dhcpd.conf. */
+
+/* #define _PATH_DHCPD_CONF    "/etc/dhcpd.conf" */
+
+/* Network API definitions.   You do not need to choose one of these - if
+   you don't choose, one will be chosen for you in your system's config
+   header.    DON'T MESS WITH THIS UNLESS YOU KNOW WHAT YOU'RE DOING!!! */
+
+/* Define this to use the standard BSD socket API.
+
+   On many systems, the BSD socket API does not provide the ability to
+   send packets to the 255.255.255.255 broadcast address, which can
+   prevent some clients (e.g., Win95) from seeing replies.   This is
+   not a problem on Solaris.
+
+   In addition, the BSD socket API will not work when more than one
+   network interface is configured on the server.
+
+   However, the BSD socket API is about as efficient as you can get, so if
+   the aforementioned problems do not matter to you, or if no other
+   API is supported for your system, you may want to go with it. */
+
+/* #define USE_SOCKETS */
+
+/* Define this to use the Sun Streams NIT API.
+
+   The Sun Streams NIT API is only supported on SunOS 4.x releases. */
+
+/* #define USE_NIT */
+
+/* Define this to use the Berkeley Packet Filter API.
+
+   The BPF API is available on all 4.4-BSD derivatives, including
+   NetBSD, FreeBSD and BSDI's BSD/OS.   It's also available on
+   DEC Alpha OSF/1 in a compatibility mode supported by the Alpha OSF/1
+   packetfilter interface. */
+
+/* #define USE_BPF */
+
+/* Define this to use the raw socket API.
+
+   The raw socket API is provided on many BSD derivatives, and provides
+   a way to send out raw IP packets.   It is only supported for sending
+   packets - packets must be received with the regular socket API.
+   This code is experimental - I've never gotten it to actually transmit
+   a packet to the 255.255.255.255 broadcast address - so use it at your
+   own risk. */
+
+/* #define USE_RAW_SOCKETS */
+
+/* Define this to change the logging facility used by dhcpd. */
+
+/* #define DHCPD_LOG_FACILITY LOG_DAEMON */
diff --git a/reactos/subsys/system/dhcp/include/stdint.h b/reactos/subsys/system/dhcp/include/stdint.h
new file mode 100644 (file)
index 0000000..988c303
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef REACTOS_STDINT_H
+#define REACTOS_STDINT_H
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+
+typedef char *caddr_t;
+
+#endif
diff --git a/reactos/subsys/system/dhcp/include/sysconf.h b/reactos/subsys/system/dhcp/include/sysconf.h
new file mode 100644 (file)
index 0000000..5feb4c7
--- /dev/null
@@ -0,0 +1,52 @@
+/* systat.h
+
+   Definitions for systat protocol... */
+
+/*
+ * Copyright (c) 1997 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#define SYSCONF_SOCKET "/var/run/sysconf"
+
+struct sysconf_header {
+       u_int32_t type;         /* Type of status message... */
+       u_int32_t length;       /* Length of message. */
+};
+
+/* Message types... */
+#define        NETWORK_LOCATION_CHANGED        1
+
diff --git a/reactos/subsys/system/dhcp/include/tree.h b/reactos/subsys/system/dhcp/include/tree.h
new file mode 100644 (file)
index 0000000..367ffa7
--- /dev/null
@@ -0,0 +1,66 @@
+/*     $OpenBSD: tree.h,v 1.5 2004/05/06 22:29:15 deraadt Exp $        */
+
+/* Definitions for address trees... */
+
+/*
+ * Copyright (c) 1995 The Internet Software Consortium.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+/* A pair of pointers, suitable for making a linked list. */
+typedef struct _pair {
+       caddr_t car;
+       struct _pair *cdr;
+} *pair;
+
+struct tree_cache {
+       unsigned char *value;
+       int len;
+       int buf_size;
+       time_t timeout;
+};
+
+struct universe {
+       char *name;
+       struct hash_table *hash;
+       struct dhcp_option *options[256];
+};
+
+struct dhcp_option {
+       char *name;
+       char *format;
+       struct universe *universe;
+       unsigned char code;
+};
diff --git a/reactos/subsys/system/dhcp/include/version.h b/reactos/subsys/system/dhcp/include/version.h
new file mode 100644 (file)
index 0000000..303fbfa
--- /dev/null
@@ -0,0 +1,3 @@
+/* Current version of ISC DHCP Distribution. */
+
+#define DHCP_VERSION   "2.0pl5"
diff --git a/reactos/subsys/system/dhcp/memory.c b/reactos/subsys/system/dhcp/memory.c
new file mode 100644 (file)
index 0000000..3673948
--- /dev/null
@@ -0,0 +1,915 @@
+/* memory.c
+
+   Memory-resident database... */
+
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: memory.c,v 1.35.2.4 1999/05/27 17:47:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "rosdhcp.h"
+#include "dhcpd.h"
+
+struct subnet *subnets;
+struct shared_network *shared_networks;
+static struct hash_table *host_hw_addr_hash;
+static struct hash_table *host_uid_hash;
+static struct hash_table *lease_uid_hash;
+static struct hash_table *lease_ip_addr_hash;
+static struct hash_table *lease_hw_addr_hash;
+struct lease *dangling_leases;
+
+static struct hash_table *vendor_class_hash;
+static struct hash_table *user_class_hash;
+
+void enter_host (hd)
+       struct host_decl *hd;
+{
+       struct host_decl *hp = (struct host_decl *)0;
+       struct host_decl *np = (struct host_decl *)0;
+
+       hd -> n_ipaddr = (struct host_decl *)0;
+
+       if (hd -> interface.hlen) {
+               if (!host_hw_addr_hash)
+                       host_hw_addr_hash = new_hash ();
+               else
+                       hp = (struct host_decl *)
+                               hash_lookup (host_hw_addr_hash,
+                                            hd -> interface.haddr,
+                                            hd -> interface.hlen);
+
+               /* If there isn't already a host decl matching this
+                  address, add it to the hash table. */
+               if (!hp)
+                       add_hash (host_hw_addr_hash,
+                                 hd -> interface.haddr, hd -> interface.hlen,
+                                 (unsigned char *)hd);
+       }
+
+       /* If there was already a host declaration for this hardware
+          address, add this one to the end of the list. */
+
+       if (hp) {
+               for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr)
+                       ;
+               np -> n_ipaddr = hd;
+       }
+
+
+       if (hd -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) {
+               if (!tree_evaluate (hd -> group -> options
+                                   [DHO_DHCP_CLIENT_IDENTIFIER]))
+                       return;
+                       
+               /* If there's no uid hash, make one; otherwise, see if
+                  there's already an entry in the hash for this host. */
+               if (!host_uid_hash) {
+                       host_uid_hash = new_hash ();
+                       hp = (struct host_decl *)0;
+               } else
+                       hp = (struct host_decl *) hash_lookup
+                               (host_uid_hash,
+                                hd -> group -> options
+                                [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
+                                hd -> group -> options
+                                [DHO_DHCP_CLIENT_IDENTIFIER] -> len);
+
+               /* If there's already a host declaration for this
+                  client identifier, add this one to the end of the
+                  list.  Otherwise, add it to the hash table. */
+               if (hp) {
+                       /* Don't link it in twice... */
+                       if (!np) {
+                               for (np = hp; np -> n_ipaddr;
+                                    np = np -> n_ipaddr)
+                                       ;
+                               np -> n_ipaddr = hd;
+                       }
+               } else {
+                       add_hash (host_uid_hash,
+                                 hd -> group -> options
+                                 [DHO_DHCP_CLIENT_IDENTIFIER] -> value,
+                                 hd -> group -> options
+                                 [DHO_DHCP_CLIENT_IDENTIFIER] -> len,
+                                 (unsigned char *)hd);
+               }
+       }
+}
+
+struct host_decl *find_hosts_by_haddr (htype, haddr, hlen)
+       int htype;
+       unsigned char *haddr;
+       int hlen;
+{
+       struct host_decl *foo;
+
+       foo = (struct host_decl *)hash_lookup (host_hw_addr_hash,
+                                              haddr, hlen);
+       return foo;
+}
+
+struct host_decl *find_hosts_by_uid (data, len)
+       unsigned char *data;
+       int len;
+{
+       struct host_decl *foo;
+
+       foo = (struct host_decl *)hash_lookup (host_uid_hash, data, len);
+       return foo;
+}
+
+/* More than one host_decl can be returned by find_hosts_by_haddr or
+   find_hosts_by_uid, and each host_decl can have multiple addresses.
+   Loop through the list of hosts, and then for each host, through the
+   list of addresses, looking for an address that's in the same shared
+   network as the one specified.    Store the matching address through
+   the addr pointer, update the host pointer to point at the host_decl
+   that matched, and return the subnet that matched. */
+
+subnet *find_host_for_network (struct host_decl **host, iaddr *addr, 
+                               shared_network *share)
+{
+       int i;
+       subnet *subnet;
+       iaddr ip_address;
+       struct host_decl *hp;
+
+       for (hp = *host; hp; hp = hp -> n_ipaddr) {
+               if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr))
+                       continue;
+               for (i = 0; i < hp -> fixed_addr -> len; i += 4) {
+                       ip_address.len = 4;
+                       memcpy (ip_address.iabuf,
+                               hp -> fixed_addr -> value + i, 4);
+                       subnet = find_grouped_subnet (share, ip_address);
+                       if (subnet) {
+                               *addr = ip_address;
+                               *host = hp;
+                               return subnet;
+                       }
+               }
+       }
+       return (struct _subnet *)0;
+}
+
+void new_address_range (iaddr low, iaddr high, subnet *subnet, int dynamic)
+{
+       lease *address_range, *lp, *plp;
+        iaddr net;
+       int min, max, i;
+       char lowbuf [16], highbuf [16], netbuf [16];
+       shared_network *share = subnet -> shared_network;
+       struct hostent *h;
+       struct in_addr ia;
+
+       /* All subnets should have attached shared network structures. */
+       if (!share) {
+               strcpy (netbuf, piaddr (subnet -> net));
+               error ("No shared network for network %s (%s)",
+                      netbuf, piaddr (subnet -> netmask));
+       }
+
+       /* Initialize the hash table if it hasn't been done yet. */
+       if (!lease_uid_hash)
+               lease_uid_hash = new_hash ();
+       if (!lease_ip_addr_hash)
+               lease_ip_addr_hash = new_hash ();
+       if (!lease_hw_addr_hash)
+               lease_hw_addr_hash = new_hash ();
+
+       /* Make sure that high and low addresses are in same subnet. */
+       net = subnet_number (low, subnet -> netmask);
+       if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
+               strcpy (lowbuf, piaddr (low));
+               strcpy (highbuf, piaddr (high));
+               strcpy (netbuf, piaddr (subnet -> netmask));
+               error ("Address range %s to %s, netmask %s spans %s!",
+                      lowbuf, highbuf, netbuf, "multiple subnets");
+       }
+
+       /* Make sure that the addresses are on the correct subnet. */
+       if (!addr_eq (net, subnet -> net)) {
+               strcpy (lowbuf, piaddr (low));
+               strcpy (highbuf, piaddr (high));
+               strcpy (netbuf, piaddr (subnet -> netmask));
+               error ("Address range %s to %s not on net %s/%s!",
+                      lowbuf, highbuf, piaddr (subnet -> net), netbuf);
+       }
+
+       /* Get the high and low host addresses... */
+       max = host_addr (high, subnet -> netmask);
+       min = host_addr (low, subnet -> netmask);
+
+       /* Allow range to be specified high-to-low as well as low-to-high. */
+       if (min > max) {
+               max = min;
+               min = host_addr (high, subnet -> netmask);
+       }
+
+       /* Get a lease structure for each address in the range. */
+       address_range = new_leases (max - min + 1, "new_address_range");
+       if (!address_range) {
+               strcpy (lowbuf, piaddr (low));
+               strcpy (highbuf, piaddr (high));
+               error ("No memory for address range %s-%s.", lowbuf, highbuf);
+       }
+       memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
+
+       /* Fill in the last lease if it hasn't been already... */
+       if (!share -> last_lease) {
+               share -> last_lease = &address_range [0];
+       }
+
+       /* Fill out the lease structures with some minimal information. */
+       for (i = 0; i < max - min + 1; i++) {
+               address_range [i].ip_addr =
+                       ip_addr (subnet -> net, subnet -> netmask, i + min);
+               address_range [i].starts =
+                       address_range [i].timestamp = MIN_TIME;
+               address_range [i].ends = MIN_TIME;
+               address_range [i].subnet = subnet;
+               address_range [i].shared_network = share;
+               address_range [i].flags = dynamic ? DYNAMIC_BOOTP_OK : 0;
+
+               memcpy (&ia, address_range [i].ip_addr.iabuf, 4);
+
+               if (subnet -> group -> get_lease_hostnames) {
+                       h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
+                       if (!h)
+                               warn ("No hostname for %s", inet_ntoa (ia));
+                       else {
+                               address_range [i].hostname =
+                                       malloc (strlen (h -> h_name) + 1);
+                               if (!address_range [i].hostname)
+                                       error ("no memory for hostname %s.",
+                                              h -> h_name);
+                               strcpy (address_range [i].hostname,
+                                       h -> h_name);
+                       }
+               }
+
+               /* Link this entry into the list. */
+               address_range [i].next = share -> leases;
+               address_range [i].prev = (struct lease *)0;
+               share -> leases = &address_range [i];
+               if (address_range [i].next)
+                       address_range [i].next -> prev = share -> leases;
+               add_hash (lease_ip_addr_hash,
+                         address_range [i].ip_addr.iabuf,
+                         address_range [i].ip_addr.len,
+                         (unsigned char *)&address_range [i]);
+       }
+
+       /* Find out if any dangling leases are in range... */
+       plp = (struct lease *)0;
+       for (lp = dangling_leases; lp; lp = lp -> next) {
+               iaddr lnet;
+               int lhost;
+
+               lnet = subnet_number (lp -> ip_addr, subnet -> netmask);
+               lhost = host_addr (lp -> ip_addr, subnet -> netmask);
+
+               /* If it's in range, fill in the real lease structure with
+                  the dangling lease's values, and remove the lease from
+                  the list of dangling leases. */
+               if (addr_eq (lnet, subnet -> net) &&
+                   lhost >= i && lhost <= max) {
+                       if (plp) {
+                               plp -> next = lp -> next;
+                       } else {
+                               dangling_leases = lp -> next;
+                       }
+                       lp -> next = (struct lease *)0;
+                       address_range [lhost - i].hostname = lp -> hostname;
+                       address_range [lhost - i].client_hostname =
+                               lp -> client_hostname;
+                       supersede_lease (&address_range [lhost - i], lp, 0);
+                       free_lease (lp, "new_address_range");
+               } else
+                       plp = lp;
+       }
+}
+
+subnet *find_subnet (iaddr addr)
+{
+        subnet *rv;
+
+       for (rv = subnets; rv; rv = rv -> next_subnet) {
+               if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
+                       return rv;
+       }
+       return (subnet *)0;
+}
+
+subnet *find_grouped_subnet (shared_network *share, iaddr addr)
+{
+        subnet *rv;
+
+       for (rv = share -> subnets; rv; rv = rv -> next_sibling) {
+               if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
+                       return rv;
+       }
+       return (subnet *)0;
+}
+
+int subnet_inner_than (struct _subnet *subnet, struct _subnet *scan, int warnp)
+{
+       if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
+                    scan -> net) ||
+           addr_eq (subnet_number (scan -> net, subnet -> netmask),
+                    subnet -> net)) {
+               char n1buf [16];
+               int i, j;
+               for (i = 0; i < 32; i++)
+                       if (subnet -> netmask.iabuf [3 - (i >> 3)]
+                           & (1 << (i & 7)))
+                               break;
+               for (j = 0; j < 32; j++)
+                       if (scan -> netmask.iabuf [3 - (j >> 3)] &
+                           (1 << (j & 7)))
+                               break;
+               strcpy (n1buf, piaddr (subnet -> net));
+               if (warnp)
+                       warn ("%ssubnet %s/%d conflicts with subnet %s/%d",
+                             "Warning: ", n1buf, 32 - i,
+                             piaddr (scan -> net), 32 - j);
+               if (i < j)
+                       return 1;
+       }
+       return 0;
+}
+
+/* Enter a new subnet into the subnet list. */
+
+void enter_subnet (struct _subnet *subnet)
+{
+       struct _subnet *scan, *prev = (struct _subnet *)0;
+
+       /* Check for duplicates... */
+       for (scan = subnets; scan; scan = scan -> next_subnet) {
+               /* When we find a conflict, make sure that the
+                  subnet with the narrowest subnet mask comes
+                  first. */
+               if (subnet_inner_than (subnet, scan, 1)) {
+                       if (prev) {
+                               prev -> next_subnet = subnet; 
+                       } else
+                               subnets = subnet;
+                       subnet -> next_subnet = scan;
+                       return;
+               }
+               prev = scan;
+       }
+
+       /* XXX use the BSD radix tree code instead of a linked list. */
+       subnet -> next_subnet = subnets;
+       subnets = subnet;
+}
+       
+/* Enter a new shared network into the shared network list. */
+
+void enter_shared_network (shared_network *share)
+{
+       /* XXX Sort the nets into a balanced tree to make searching quicker. */
+       share -> next = shared_networks;
+       shared_networks = share;
+}
+       
+/* Enter a lease into the system.   This is called by the parser each
+   time it reads in a new lease.   If the subnet for that lease has
+   already been read in (usually the case), just update that lease;
+   otherwise, allocate temporary storage for the lease and keep it around
+   until we're done reading in the config file. */
+
+void enter_lease (struct _lease *lease)
+{
+        struct _lease *comp = find_lease_by_ip_addr (lease -> ip_addr);
+
+       /* If we don't have a place for this lease yet, save it for
+          later. */
+       if (!comp) {
+               comp = new_lease ("enter_lease");
+               if (!comp) {
+                       error ("No memory for lease %s\n",
+                              piaddr (lease -> ip_addr));
+               }
+               *comp = *lease;
+               comp -> next = dangling_leases;
+               comp -> prev = (struct lease *)0;
+               dangling_leases = comp;
+       } else {
+               /* Record the hostname information in the lease. */
+               comp -> hostname = lease -> hostname;
+               comp -> client_hostname = lease -> client_hostname;
+               supersede_lease (comp, lease, 0);
+       }
+}
+
+/* Replace the data in an existing lease with the data in a new lease;
+   adjust hash tables to suit, and insertion sort the lease into the
+   list of leases by expiry time so that we can always find the oldest
+   lease. */
+
+int supersede_lease (struct _lease *comp, struct _lease *lease, int commit)
+{
+       int enter_uid = 0;
+       int enter_hwaddr = 0;
+       struct _lease *lp;
+
+       /* Static leases are not currently kept in the database... */
+       if (lease -> flags & STATIC_LEASE)
+               return 1;
+
+       /* If the existing lease hasn't expired and has a different
+          unique identifier or, if it doesn't have a unique
+          identifier, a different hardware address, then the two
+          leases are in conflict.  If the existing lease has a uid
+          and the new one doesn't, but they both have the same
+          hardware address, and dynamic bootp is allowed on this
+          lease, then we allow that, in case a dynamic BOOTP lease is
+          requested *after* a DHCP lease has been assigned. */
+
+       if (!(lease -> flags & ABANDONED_LEASE) &&
+           comp -> ends > cur_time &&
+           (((comp -> uid && lease -> uid) &&
+             (comp -> uid_len != lease -> uid_len ||
+              memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
+            (!comp -> uid &&
+             ((comp -> hardware_addr.htype !=
+               lease -> hardware_addr.htype) ||
+              (comp -> hardware_addr.hlen !=
+               lease -> hardware_addr.hlen) ||
+              memcmp (comp -> hardware_addr.haddr,
+                      lease -> hardware_addr.haddr,
+                      comp -> hardware_addr.hlen))))) {
+               warn ("Lease conflict at %s",
+                     piaddr (comp -> ip_addr));
+               return 0;
+       } else {
+               /* If there's a Unique ID, dissociate it from the hash
+                  table and free it if necessary. */
+               if (comp -> uid) {
+                       uid_hash_delete (comp);
+                       enter_uid = 1;
+                       if (comp -> uid != &comp -> uid_buf [0]) {
+                               free (comp -> uid);
+                               comp -> uid_max = 0;
+                               comp -> uid_len = 0;
+                       }
+                       comp -> uid = (unsigned char *)0;
+               } else
+                       enter_uid = 1;
+
+               if (comp -> hardware_addr.htype &&
+                   ((comp -> hardware_addr.hlen !=
+                     lease -> hardware_addr.hlen) ||
+                    (comp -> hardware_addr.htype !=
+                     lease -> hardware_addr.htype) ||
+                    memcmp (comp -> hardware_addr.haddr,
+                            lease -> hardware_addr.haddr,
+                            comp -> hardware_addr.hlen))) {
+                       hw_hash_delete (comp);
+                       enter_hwaddr = 1;
+               } else if (!comp -> hardware_addr.htype)
+                       enter_hwaddr = 1;
+
+               /* Copy the data files, but not the linkages. */
+               comp -> starts = lease -> starts;
+               if (lease -> uid) {
+                       if (lease -> uid_len < sizeof (lease -> uid_buf)) {
+                               memcpy (comp -> uid_buf,
+                                       lease -> uid, lease -> uid_len);
+                               comp -> uid = &comp -> uid_buf [0];
+                               comp -> uid_max = sizeof comp -> uid_buf;
+                       } else if (lease -> uid != &lease -> uid_buf [0]) {
+                               comp -> uid = lease -> uid;
+                               comp -> uid_max = lease -> uid_max;
+                               lease -> uid = (unsigned char *)0;
+                               lease -> uid_max = 0;
+                       } else {
+                               error ("corrupt lease uid."); /* XXX */
+                       }
+               } else {
+                       comp -> uid = (unsigned char *)0;
+                       comp -> uid_max = 0;
+               }
+               comp -> uid_len = lease -> uid_len;
+               comp -> host = lease -> host;
+               comp -> hardware_addr = lease -> hardware_addr;
+               comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
+                                (comp -> flags & ~EPHEMERAL_FLAGS));
+
+               /* Record the lease in the uid hash if necessary. */
+               if (enter_uid && lease -> uid) {
+                       uid_hash_add (comp);
+               }
+
+               /* Record it in the hardware address hash if necessary. */
+               if (enter_hwaddr && lease -> hardware_addr.htype) {
+                       hw_hash_add (comp);
+               }
+
+               /* Remove the lease from its current place in the 
+                  timeout sequence. */
+               if (comp -> prev) {
+                       comp -> prev -> next = comp -> next;
+               } else {
+                       comp -> shared_network -> leases = comp -> next;
+               }
+               if (comp -> next) {
+                       comp -> next -> prev = comp -> prev;
+               }
+               if (comp -> shared_network -> last_lease == comp) {
+                       comp -> shared_network -> last_lease = comp -> prev;
+               }
+
+               /* Find the last insertion point... */
+               if (comp == comp -> shared_network -> insertion_point ||
+                   !comp -> shared_network -> insertion_point) {
+                       lp = comp -> shared_network -> leases;
+               } else {
+                       lp = comp -> shared_network -> insertion_point;
+               }
+
+               if (!lp) {
+                       /* Nothing on the list yet?    Just make comp the
+                          head of the list. */
+                       comp -> shared_network -> leases = comp;
+                       comp -> shared_network -> last_lease = comp;
+               } else if (lp -> ends > lease -> ends) {
+                       /* Skip down the list until we run out of list
+                          or find a place for comp. */
+                       while (lp -> next && lp -> ends > lease -> ends) {
+                               lp = lp -> next;
+                       }
+                       if (lp -> ends > lease -> ends) {
+                               /* If we ran out of list, put comp
+                                  at the end. */
+                               lp -> next = comp;
+                               comp -> prev = lp;
+                               comp -> next = (struct lease *)0;
+                               comp -> shared_network -> last_lease = comp;
+                       } else {
+                               /* If we didn't, put it between lp and
+                                  the previous item on the list. */
+                               if ((comp -> prev = lp -> prev))
+                                       comp -> prev -> next = comp;
+                               comp -> next = lp;
+                               lp -> prev = comp;
+                       }
+               } else {
+                       /* Skip up the list until we run out of list
+                          or find a place for comp. */
+                       while (lp -> prev && lp -> ends < lease -> ends) {
+                               lp = lp -> prev;
+                       }
+                       if (lp -> ends < lease -> ends) {
+                               /* If we ran out of list, put comp
+                                  at the beginning. */
+                               lp -> prev = comp;
+                               comp -> next = lp;
+                               comp -> prev = (struct lease *)0;
+                               comp -> shared_network -> leases = comp;
+                       } else {
+                               /* If we didn't, put it between lp and
+                                  the next item on the list. */
+                               if ((comp -> next = lp -> next))
+                                       comp -> next -> prev = comp;
+                               comp -> prev = lp;
+                               lp -> next = comp;
+                       }
+               }
+               comp -> shared_network -> insertion_point = comp;
+               comp -> ends = lease -> ends;
+       }
+
+       /* Return zero if we didn't commit the lease to permanent storage;
+          nonzero if we did. */
+       return commit && write_lease (comp) && commit_leases ();
+}
+
+/* Release the specified lease and re-hash it as appropriate. */
+
+void release_lease (struct _lease *lease)
+{
+        struct _lease lt;
+
+       lt = *lease;
+       if (lt.ends > cur_time) {
+               lt.ends = cur_time;
+               supersede_lease (lease, &lt, 1);
+       }
+}
+
+/* Abandon the specified lease (set its timeout to infinity and its
+   particulars to zero, and re-hash it as appropriate. */
+
+void abandon_lease (struct _lease *lease, char *message)
+{
+       struct _lease lt;
+
+       lease -> flags |= ABANDONED_LEASE;
+       lt = *lease;
+       lt.ends = cur_time;
+       warn ("Abandoning IP address %s: %s",
+             piaddr (lease -> ip_addr), message);
+       lt.hardware_addr.htype = 0;
+       lt.hardware_addr.hlen = 0;
+       lt.uid = (unsigned char *)0;
+       lt.uid_len = 0;
+       supersede_lease (lease, &lt, 1);
+}
+
+/* Locate the lease associated with a given IP address... */
+
+lease *find_lease_by_ip_addr (iaddr addr)
+{
+       lease *lease = (struct _lease *)hash_lookup (lease_ip_addr_hash,
+                                                     addr.iabuf,
+                                                     addr.len);
+       return lease;
+}
+
+lease *find_lease_by_uid (unsigned char *uid, int len)
+{
+        lease *lease = (struct lease *)hash_lookup (lease_uid_hash,
+                                                    uid, len);
+       return lease;
+}
+
+lease *find_lease_by_hw_addr (unsigned char *hwaddr, int hwlen)
+{
+        struct _lease *lease = 
+            (struct _lease *)hash_lookup (lease_hw_addr_hash,
+                                          hwaddr, hwlen);
+       return lease;
+}
+
+/* Add the specified lease to the uid hash. */
+
+void uid_hash_add (lease *lease)
+{
+        struct _lease *head = find_lease_by_uid (lease -> uid, lease -> uid_len);
+       struct _lease *scan;
+
+#ifdef DEBUG
+       if (lease -> n_uid)
+               abort ();
+#endif
+
+       /* If it's not in the hash, just add it. */
+       if (!head)
+               add_hash (lease_uid_hash, lease -> uid,
+                         lease -> uid_len, (unsigned char *)lease);
+       else {
+               /* Otherwise, attach it to the end of the list. */
+               for (scan = head; scan -> n_uid; scan = scan -> n_uid)
+#ifdef DEBUG
+                       if (scan == lease)
+                               abort ()
+#endif
+                                       ;
+               scan -> n_uid = lease;
+       }
+}
+
+/* Delete the specified lease from the uid hash. */
+
+void uid_hash_delete (lease *lease)
+{
+        struct _lease *head = 
+            find_lease_by_uid (lease -> uid, lease -> uid_len);
+       struct _lease *scan;
+
+       /* If it's not in the hash, we have no work to do. */
+       if (!head) {
+               lease -> n_uid = (struct lease *)0;
+               return;
+       }
+
+       /* If the lease we're freeing is at the head of the list,
+          remove the hash table entry and add a new one with the
+          next lease on the list (if there is one). */
+       if (head == lease) {
+               delete_hash_entry (lease_uid_hash,
+                                  lease -> uid, lease -> uid_len);
+               if (lease -> n_uid)
+                       add_hash (lease_uid_hash,
+                                 lease -> n_uid -> uid,
+                                 lease -> n_uid -> uid_len,
+                                 (unsigned char *)(lease -> n_uid));
+       } else {
+               /* Otherwise, look for the lease in the list of leases
+                  attached to the hash table entry, and remove it if
+                  we find it. */
+               for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
+                       if (scan -> n_uid == lease) {
+                               scan -> n_uid = scan -> n_uid -> n_uid;
+                               break;
+                       }
+               }
+       }
+       lease -> n_uid = (struct lease *)0;
+}
+
+/* Add the specified lease to the hardware address hash. */
+
+void hw_hash_add (lease *lease)
+{
+        struct _lease *head =
+               find_lease_by_hw_addr (lease -> hardware_addr.haddr,
+                                      lease -> hardware_addr.hlen);
+       struct _lease *scan;
+
+       /* If it's not in the hash, just add it. */
+       if (!head)
+               add_hash (lease_hw_addr_hash,
+                         lease -> hardware_addr.haddr,
+                         lease -> hardware_addr.hlen,
+                         (unsigned char *)lease);
+       else {
+               /* Otherwise, attach it to the end of the list. */
+               for (scan = head; scan -> n_hw; scan = scan -> n_hw)
+                       ;
+               scan -> n_hw = lease;
+       }
+}
+
+/* Delete the specified lease from the hardware address hash. */
+
+void hw_hash_delete (lease *lease)
+{
+        struct _lease *head =
+               find_lease_by_hw_addr (lease -> hardware_addr.haddr,
+                                      lease -> hardware_addr.hlen);
+        struct _lease *scan;
+
+       /* If it's not in the hash, we have no work to do. */
+       if (!head) {
+               lease -> n_hw = (struct lease *)0;
+               return;
+       }
+
+       /* If the lease we're freeing is at the head of the list,
+          remove the hash table entry and add a new one with the
+          next lease on the list (if there is one). */
+       if (head == lease) {
+               delete_hash_entry (lease_hw_addr_hash,
+                                  lease -> hardware_addr.haddr,
+                                  lease -> hardware_addr.hlen);
+               if (lease -> n_hw)
+                       add_hash (lease_hw_addr_hash,
+                                 lease -> n_hw -> hardware_addr.haddr,
+                                 lease -> n_hw -> hardware_addr.hlen,
+                                 (unsigned char *)(lease -> n_hw));
+       } else {
+               /* Otherwise, look for the lease in the list of leases
+                  attached to the hash table entry, and remove it if
+                  we find it. */
+               for (scan = head; scan -> n_hw; scan = scan -> n_hw) {
+                       if (scan -> n_hw == lease) {
+                               scan -> n_hw = scan -> n_hw -> n_hw;
+                               break;
+                       }
+               }
+       }
+       lease -> n_hw = (struct lease *)0;
+}
+
+
+struct class *add_class (type, name)
+       int type;
+       char *name;
+{
+       struct class *class = new_class ("add_class");
+       char *tname = (char *)malloc (strlen (name) + 1);
+
+       if (!vendor_class_hash)
+               vendor_class_hash = new_hash ();
+       if (!user_class_hash)
+               user_class_hash = new_hash ();
+
+       if (!tname || !class || !vendor_class_hash || !user_class_hash)
+               return (struct class *)0;
+
+       memset (class, 0, sizeof *class);
+       strcpy (tname, name);
+       class -> name = tname;
+
+       if (type)
+               add_hash (user_class_hash,
+                         (unsigned char *)tname, strlen (tname),
+                         (unsigned char *)class);
+       else
+               add_hash (vendor_class_hash,
+                         (unsigned char *)tname, strlen (tname),
+                         (unsigned char *)class);
+       return class;
+}
+
+struct class *find_class (type, name, len)
+       int type;
+       unsigned char *name;
+       int len;
+{
+       struct class *class =
+               (struct class *)hash_lookup (type
+                                            ? user_class_hash
+                                            : vendor_class_hash, name, len);
+       return class;
+}      
+
+struct group *clone_group (group, caller)
+       struct group *group;
+       char *caller;
+{
+       struct group *g = new_group (caller);
+       if (!g)
+               error ("%s: can't allocate new group", caller);
+       *g = *group;
+       return g;
+}
+
+/* Write all interesting leases to permanent storage. */
+
+void write_leases ()
+{
+       lease *l;
+       shared_network *s;
+
+       for (s = shared_networks; s; s = (shared_network *)s -> next) {
+               for (l = s -> leases; l; l = l -> next) {
+                       if (l -> hardware_addr.hlen ||
+                           l -> uid_len ||
+                           (l -> flags & ABANDONED_LEASE))
+                               if (!write_lease (l))
+                                       error ("Can't rewrite lease database");
+               }
+       }
+       if (!commit_leases ())
+               error ("Can't commit leases to new database: %m");
+}
+
+void dump_subnets ()
+{
+       struct _lease *l;
+       shared_network *s;
+        subnet *n;
+
+       note ("Subnets:");
+       for (n = subnets; n; n = n -> next_subnet) {
+               debug ("  Subnet %s", piaddr (n -> net));
+               debug ("     netmask %s",
+                      piaddr (n -> netmask));
+       }
+       note ("Shared networks:");
+       for (s = shared_networks; s; s = (shared_network *)s -> next) {
+               note ("  %s", s -> name);
+               for (l = s -> leases; l; l = l -> next) {
+                       print_lease (l);
+               }
+               if (s -> last_lease) {
+                       debug ("    Last Lease:");
+                       print_lease (s -> last_lease);
+               }
+       }
+}
diff --git a/reactos/subsys/system/dhcp/options.c b/reactos/subsys/system/dhcp/options.c
new file mode 100644 (file)
index 0000000..a037712
--- /dev/null
@@ -0,0 +1,718 @@
+/*     $OpenBSD: options.c,v 1.15 2004/12/26 03:17:07 deraadt Exp $    */
+
+/* DHCP options parsing and reassembly. */
+
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#include <ctype.h>
+
+#define DHCP_OPTION_DATA
+#include "rosdhcp.h"
+#include "dhcpd.h"
+
+int bad_options = 0;
+int bad_options_max = 5;
+
+void   parse_options(struct packet *);
+void   parse_option_buffer(struct packet *, unsigned char *, int);
+int    store_options(unsigned char *, int, struct tree_cache **,
+           unsigned char *, int, int, int, int);
+
+
+/*
+ * Parse all available options out of the specified packet.
+ */
+void
+parse_options(struct packet *packet)
+{
+       /* Initially, zero all option pointers. */
+       memset(packet->options, 0, sizeof(packet->options));
+
+       /* If we don't see the magic cookie, there's nothing to parse. */
+       if (memcmp(packet->raw->options, DHCP_OPTIONS_COOKIE, 4)) {
+               packet->options_valid = 0;
+               return;
+       }
+
+       /*
+        * Go through the options field, up to the end of the packet or
+        * the End field.
+        */
+       parse_option_buffer(packet, &packet->raw->options[4],
+           packet->packet_length - DHCP_FIXED_NON_UDP - 4);
+
+       /*
+        * If we parsed a DHCP Option Overload option, parse more
+        * options out of the buffer(s) containing them.
+        */
+       if (packet->options_valid &&
+           packet->options[DHO_DHCP_OPTION_OVERLOAD].data) {
+               if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)
+                       parse_option_buffer(packet,
+                           (unsigned char *)packet->raw->file,
+                           sizeof(packet->raw->file));
+               if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)
+                       parse_option_buffer(packet,
+                           (unsigned char *)packet->raw->sname,
+                           sizeof(packet->raw->sname));
+       }
+}
+
+/*
+ * Parse options out of the specified buffer, storing addresses of
+ * option values in packet->options and setting packet->options_valid if
+ * no errors are encountered.
+ */
+void
+parse_option_buffer(struct packet *packet,
+    unsigned char *buffer, int length)
+{
+       unsigned char *s, *t, *end = buffer + length;
+       int len, code;
+
+       for (s = buffer; *s != DHO_END && s < end; ) {
+               code = s[0];
+
+               /* Pad options don't have a length - just skip them. */
+               if (code == DHO_PAD) {
+                       s++;
+                       continue;
+               }
+               if (s + 2 > end) {
+                       len = 65536;
+                       goto bogus;
+               }
+
+               /*
+                * All other fields (except end, see above) have a
+                * one-byte length.
+                */
+               len = s[1];
+
+               /*
+                * If the length is outrageous, silently skip the rest,
+                * and mark the packet bad. Unfortunately some crappy
+                * dhcp servers always seem to give us garbage on the
+                * end of a packet. so rather than keep refusing, give
+                * up and try to take one after seeing a few without
+                * anything good.
+                */
+               if (s + len + 2 > end) {
+                   bogus:
+                       bad_options++;
+                       warning("option %s (%d) %s.",
+                           dhcp_options[code].name, len,
+                           "larger than buffer");
+                       if (bad_options == bad_options_max) {
+                               packet->options_valid = 1;
+                               bad_options = 0;
+                               warning("Many bogus options seen in offers. "
+                                   "Taking this offer in spite of bogus "
+                                   "options - hope for the best!");
+                       } else {
+                               warning("rejecting bogus offer.");
+                               packet->options_valid = 0;
+                       }
+                       return;
+               }
+               /*
+                * If we haven't seen this option before, just make
+                * space for it and copy it there.
+                */
+               if (!packet->options[code].data) {
+                       if (!(t = calloc(1, len + 1)))
+                               error("Can't allocate storage for option %s.",
+                                   dhcp_options[code].name);
+                       /*
+                        * Copy and NUL-terminate the option (in case
+                        * it's an ASCII string.
+                        */
+                       memcpy(t, &s[2], len);
+                       t[len] = 0;
+                       packet->options[code].len = len;
+                       packet->options[code].data = t;
+               } else {
+                       /*
+                        * If it's a repeat, concatenate it to whatever
+                        * we last saw.   This is really only required
+                        * for clients, but what the heck...
+                        */
+                       t = calloc(1, len + packet->options[code].len + 1);
+                       if (!t)
+                               error("Can't expand storage for option %s.",
+                                   dhcp_options[code].name);
+                       memcpy(t, packet->options[code].data,
+                               packet->options[code].len);
+                       memcpy(t + packet->options[code].len,
+                               &s[2], len);
+                       packet->options[code].len += len;
+                       t[packet->options[code].len] = 0;
+                       free(packet->options[code].data);
+                       packet->options[code].data = t;
+               }
+               s += len + 2;
+       }
+       packet->options_valid = 1;
+}
+
+/*
+ * cons options into a big buffer, and then split them out into the
+ * three separate buffers if needed.  This allows us to cons up a set of
+ * vendor options using the same routine.
+ */
+int
+cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
+    int mms, struct tree_cache **options,
+    int overload, /* Overload flags that may be set. */
+    int terminate, int bootpp, u_int8_t *prl, int prl_len)
+{
+       unsigned char priority_list[300], buffer[4096];
+       int priority_len, main_buffer_size, mainbufix, bufix;
+       int option_size, length;
+
+       /*
+        * If the client has provided a maximum DHCP message size, use
+        * that; otherwise, if it's BOOTP, only 64 bytes; otherwise use
+        * up to the minimum IP MTU size (576 bytes).
+        *
+        * XXX if a BOOTP client specifies a max message size, we will
+        * honor it.
+        */
+       if (!mms &&
+           inpacket &&
+           inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data &&
+           (inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].len >=
+           sizeof(u_int16_t)))
+               mms = getUShort(
+                   inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data);
+
+       if (mms)
+               main_buffer_size = mms - DHCP_FIXED_LEN;
+       else if (bootpp)
+               main_buffer_size = 64;
+       else
+               main_buffer_size = 576 - DHCP_FIXED_LEN;
+
+       if (main_buffer_size > sizeof(buffer))
+               main_buffer_size = sizeof(buffer);
+
+       /* Preload the option priority list with mandatory options. */
+       priority_len = 0;
+       priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE;
+       priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
+       priority_list[priority_len++] = DHO_DHCP_LEASE_TIME;
+       priority_list[priority_len++] = DHO_DHCP_MESSAGE;
+
+       /*
+        * If the client has provided a list of options that it wishes
+        * returned, use it to prioritize.  Otherwise, prioritize based
+        * on the default priority list.
+        */
+       if (inpacket &&
+           inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
+               int prlen =
+                   inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].len;
+               if (prlen + priority_len > sizeof(priority_list))
+                       prlen = sizeof(priority_list) - priority_len;
+
+               memcpy(&priority_list[priority_len],
+                   inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data,
+                   prlen);
+               priority_len += prlen;
+               prl = priority_list;
+       } else if (prl) {
+               if (prl_len + priority_len > sizeof(priority_list))
+                       prl_len = sizeof(priority_list) - priority_len;
+
+               memcpy(&priority_list[priority_len], prl, prl_len);
+               priority_len += prl_len;
+               prl = priority_list;
+       } else {
+               memcpy(&priority_list[priority_len],
+                   dhcp_option_default_priority_list,
+                   sizeof_dhcp_option_default_priority_list);
+               priority_len += sizeof_dhcp_option_default_priority_list;
+       }
+
+       /* Copy the options into the big buffer... */
+       option_size = store_options(
+           buffer,
+           (main_buffer_size - 7 + ((overload & 1) ? DHCP_FILE_LEN : 0) +
+               ((overload & 2) ? DHCP_SNAME_LEN : 0)),
+           options, priority_list, priority_len, main_buffer_size,
+           (main_buffer_size + ((overload & 1) ? DHCP_FILE_LEN : 0)),
+           terminate);
+
+       /* Put the cookie up front... */
+       memcpy(outpacket->options, DHCP_OPTIONS_COOKIE, 4);
+       mainbufix = 4;
+
+       /*
+        * If we're going to have to overload, store the overload option
+        * at the beginning.  If we can, though, just store the whole
+        * thing in the packet's option buffer and leave it at that.
+        */
+       if (option_size <= main_buffer_size - mainbufix) {
+               memcpy(&outpacket->options[mainbufix],
+                   buffer, option_size);
+               mainbufix += option_size;
+               if (mainbufix < main_buffer_size)
+                       outpacket->options[mainbufix++] = DHO_END;
+               length = DHCP_FIXED_NON_UDP + mainbufix;
+       } else {
+               outpacket->options[mainbufix++] = DHO_DHCP_OPTION_OVERLOAD;
+               outpacket->options[mainbufix++] = 1;
+               if (option_size >
+                   main_buffer_size - mainbufix + DHCP_FILE_LEN)
+                       outpacket->options[mainbufix++] = 3;
+               else
+                       outpacket->options[mainbufix++] = 1;
+
+               memcpy(&outpacket->options[mainbufix],
+                   buffer, main_buffer_size - mainbufix);
+               bufix = main_buffer_size - mainbufix;
+               length = DHCP_FIXED_NON_UDP + mainbufix;
+               if (overload & 1) {
+                       if (option_size - bufix <= DHCP_FILE_LEN) {
+                               memcpy(outpacket->file,
+                                   &buffer[bufix], option_size - bufix);
+                               mainbufix = option_size - bufix;
+                               if (mainbufix < DHCP_FILE_LEN)
+                                       outpacket->file[mainbufix++] = (char)DHO_END;
+                               while (mainbufix < DHCP_FILE_LEN)
+                                       outpacket->file[mainbufix++] = (char)DHO_PAD;
+                       } else {
+                               memcpy(outpacket->file,
+                                   &buffer[bufix], DHCP_FILE_LEN);
+                               bufix += DHCP_FILE_LEN;
+                       }
+               }
+               if ((overload & 2) && option_size < bufix) {
+                       memcpy(outpacket->sname,
+                           &buffer[bufix], option_size - bufix);
+
+                       mainbufix = option_size - bufix;
+                       if (mainbufix < DHCP_SNAME_LEN)
+                               outpacket->file[mainbufix++] = (char)DHO_END;
+                       while (mainbufix < DHCP_SNAME_LEN)
+                               outpacket->file[mainbufix++] = (char)DHO_PAD;
+               }
+       }
+       return (length);
+}
+
+/*
+ * Store all the requested options into the requested buffer.
+ */
+int
+store_options(unsigned char *buffer, int buflen, struct tree_cache **options,
+    unsigned char *priority_list, int priority_len, int first_cutoff,
+    int second_cutoff, int terminate)
+{
+       int bufix = 0, option_stored[256], i, ix, tto;
+
+       /* Zero out the stored-lengths array. */
+       memset(option_stored, 0, sizeof(option_stored));
+
+       /*
+        * Copy out the options in the order that they appear in the
+        * priority list...
+        */
+       for (i = 0; i < priority_len; i++) {
+               /* Code for next option to try to store. */
+               int code = priority_list[i];
+               int optstart;
+
+               /*
+                * Number of bytes left to store (some may already have
+                * been stored by a previous pass).
+                */
+               int length;
+
+               /* If no data is available for this option, skip it. */
+               if (!options[code]) {
+                       continue;
+               }
+
+               /*
+                * The client could ask for things that are mandatory,
+                * in which case we should avoid storing them twice...
+                */
+               if (option_stored[code])
+                       continue;
+               option_stored[code] = 1;
+
+               /* We should now have a constant length for the option. */
+               length = options[code]->len;
+
+               /* Do we add a NUL? */
+               if (terminate && dhcp_options[code].format[0] == 't') {
+                       length++;
+                       tto = 1;
+               } else
+                       tto = 0;
+
+               /* Try to store the option. */
+
+               /*
+                * If the option's length is more than 255, we must
+                * store it in multiple hunks.   Store 255-byte hunks
+                * first.  However, in any case, if the option data will
+                * cross a buffer boundary, split it across that
+                * boundary.
+                */
+               ix = 0;
+
+               optstart = bufix;
+               while (length) {
+                       unsigned char incr = length > 255 ? 255 : length;
+
+                       /*
+                        * If this hunk of the buffer will cross a
+                        * boundary, only go up to the boundary in this
+                        * pass.
+                        */
+                       if (bufix < first_cutoff &&
+                           bufix + incr > first_cutoff)
+                               incr = first_cutoff - bufix;
+                       else if (bufix < second_cutoff &&
+                           bufix + incr > second_cutoff)
+                               incr = second_cutoff - bufix;
+
+                       /*
+                        * If this option is going to overflow the
+                        * buffer, skip it.
+                        */
+                       if (bufix + 2 + incr > buflen) {
+                               bufix = optstart;
+                               break;
+                       }
+
+                       /* Everything looks good - copy it in! */
+                       buffer[bufix] = code;
+                       buffer[bufix + 1] = incr;
+                       if (tto && incr == length) {
+                               memcpy(buffer + bufix + 2,
+                                   options[code]->value + ix, incr - 1);
+                               buffer[bufix + 2 + incr - 1] = 0;
+                       } else
+                               memcpy(buffer + bufix + 2,
+                                   options[code]->value + ix, incr);
+                       length -= incr;
+                       ix += incr;
+                       bufix += 2 + incr;
+               }
+       }
+       return (bufix);
+}
+
+/*
+ * Format the specified option so that a human can easily read it.
+ */
+char *
+pretty_print_option(unsigned int code, unsigned char *data, int len,
+    int emit_commas, int emit_quotes)
+{
+       static char optbuf[32768]; /* XXX */
+       int hunksize = 0, numhunk = -1, numelem = 0;
+       char fmtbuf[32], *op = optbuf;
+       int i, j, k, opleft = sizeof(optbuf);
+       unsigned char *dp = data;
+       struct in_addr foo;
+       char comma;
+
+       /* Code should be between 0 and 255. */
+       if (code > 255)
+               error("pretty_print_option: bad code %d", code);
+
+       if (emit_commas)
+               comma = ',';
+       else
+               comma = ' ';
+
+       /* Figure out the size of the data. */
+       for (i = 0; dhcp_options[code].format[i]; i++) {
+               if (!numhunk) {
+                       warning("%s: Excess information in format string: %s",
+                           dhcp_options[code].name,
+                           &(dhcp_options[code].format[i]));
+                       break;
+               }
+               numelem++;
+               fmtbuf[i] = dhcp_options[code].format[i];
+               switch (dhcp_options[code].format[i]) {
+               case 'A':
+                       --numelem;
+                       fmtbuf[i] = 0;
+                       numhunk = 0;
+                       break;
+               case 'X':
+                       for (k = 0; k < len; k++)
+                               if (!isascii(data[k]) ||
+                                   !isprint(data[k]))
+                                       break;
+                       if (k == len) {
+                               fmtbuf[i] = 't';
+                               numhunk = -2;
+                       } else {
+                               fmtbuf[i] = 'x';
+                               hunksize++;
+                               comma = ':';
+                               numhunk = 0;
+                       }
+                       fmtbuf[i + 1] = 0;
+                       break;
+               case 't':
+                       fmtbuf[i] = 't';
+                       fmtbuf[i + 1] = 0;
+                       numhunk = -2;
+                       break;
+               case 'I':
+               case 'l':
+               case 'L':
+                       hunksize += 4;
+                       break;
+               case 's':
+               case 'S':
+                       hunksize += 2;
+                       break;
+               case 'b':
+               case 'B':
+               case 'f':
+                       hunksize++;
+                       break;
+               case 'e':
+                       break;
+               default:
+                       warning("%s: garbage in format string: %s",
+                           dhcp_options[code].name,
+                           &(dhcp_options[code].format[i]));
+                       break;
+               }
+       }
+
+       /* Check for too few bytes... */
+       if (hunksize > len) {
+               warning("%s: expecting at least %d bytes; got %d",
+                   dhcp_options[code].name, hunksize, len);
+               return ("<error>");
+       }
+       /* Check for too many bytes... */
+       if (numhunk == -1 && hunksize < len)
+               warning("%s: %d extra bytes",
+                   dhcp_options[code].name, len - hunksize);
+
+       /* If this is an array, compute its size. */
+       if (!numhunk)
+               numhunk = len / hunksize;
+       /* See if we got an exact number of hunks. */
+       if (numhunk > 0 && numhunk * hunksize < len)
+               warning("%s: %d extra bytes at end of array",
+                   dhcp_options[code].name, len - numhunk * hunksize);
+
+       /* A one-hunk array prints the same as a single hunk. */
+       if (numhunk < 0)
+               numhunk = 1;
+
+       /* Cycle through the array (or hunk) printing the data. */
+       for (i = 0; i < numhunk; i++) {
+               for (j = 0; j < numelem; j++) {
+                       int opcount;
+                       switch (fmtbuf[j]) {
+                       case 't':
+                               if (emit_quotes) {
+                                       *op++ = '"';
+                                       opleft--;
+                               }
+                               for (; dp < data + len; dp++) {
+                                       if (!isascii(*dp) ||
+                                           !isprint(*dp)) {
+                                               if (dp + 1 != data + len ||
+                                                   *dp != 0) {
+                                                       snprintf(op, opleft,
+                                                           "\\%03o", *dp);
+                                                       op += 4;
+                                                       opleft -= 4;
+                                               }
+                                       } else if (*dp == '"' ||
+                                           *dp == '\'' ||
+                                           *dp == '$' ||
+                                           *dp == '`' ||
+                                           *dp == '\\') {
+                                               *op++ = '\\';
+                                               *op++ = *dp;
+                                               opleft -= 2;
+                                       } else {
+                                               *op++ = *dp;
+                                               opleft--;
+                                       }
+                               }
+                               if (emit_quotes) {
+                                       *op++ = '"';
+                                       opleft--;
+                               }
+
+                               *op = 0;
+                               break;
+                       case 'I':
+                               foo.s_addr = htonl(getULong(dp));
+                               opcount = strlcpy(op, inet_ntoa(foo), opleft);
+                               if (opcount >= opleft)
+                                       goto toobig;
+                               opleft -= opcount;
+                               dp += 4;
+                               break;
+                       case 'l':
+                               opcount = snprintf(op, opleft, "%ld",
+                                   (long)getLong(dp));
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               dp += 4;
+                               break;
+                       case 'L':
+                               opcount = snprintf(op, opleft, "%ld",
+                                   (unsigned long)getULong(dp));
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               dp += 4;
+                               break;
+                       case 's':
+                               opcount = snprintf(op, opleft, "%d",
+                                   getShort(dp));
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               dp += 2;
+                               break;
+                       case 'S':
+                               opcount = snprintf(op, opleft, "%d",
+                                   getUShort(dp));
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               dp += 2;
+                               break;
+                       case 'b':
+                               opcount = snprintf(op, opleft, "%d",
+                                   *(char *)dp++);
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               break;
+                       case 'B':
+                               opcount = snprintf(op, opleft, "%d", *dp++);
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               break;
+                       case 'x':
+                               opcount = snprintf(op, opleft, "%x", *dp++);
+                               if (opcount >= opleft || opcount == -1)
+                                       goto toobig;
+                               opleft -= opcount;
+                               break;
+                       case 'f':
+                               opcount = strlcpy(op,
+                                   *dp++ ? "true" : "false", opleft);
+                               if (opcount >= opleft)
+                                       goto toobig;
+                               opleft -= opcount;
+                               break;
+                       default:
+                               warning("Unexpected format code %c", fmtbuf[j]);
+                       }
+                       op += strlen(op);
+                       opleft -= strlen(op);
+                       if (opleft < 1)
+                               goto toobig;
+                       if (j + 1 < numelem && comma != ':') {
+                               *op++ = ' ';
+                               opleft--;
+                       }
+               }
+               if (i + 1 < numhunk) {
+                       *op++ = comma;
+                       opleft--;
+               }
+               if (opleft < 1)
+                       goto toobig;
+
+       }
+       return (optbuf);
+ toobig:
+       warning("dhcp option too large");
+       return ("<error>");
+}
+
+void
+do_packet(struct interface_info *interface, struct dhcp_packet *packet,
+    int len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
+{
+       struct packet tp;
+       int i;
+
+       if (packet->hlen > sizeof(packet->chaddr)) {
+               note("Discarding packet with invalid hlen.");
+               return;
+       }
+
+       memset(&tp, 0, sizeof(tp));
+       tp.raw = packet;
+       tp.packet_length = len;
+       tp.client_port = from_port;
+       tp.client_addr = from;
+       tp.interface = interface;
+       tp.haddr = hfrom;
+
+       parse_options(&tp);
+       if (tp.options_valid &&
+           tp.options[DHO_DHCP_MESSAGE_TYPE].data)
+               tp.packet_type = tp.options[DHO_DHCP_MESSAGE_TYPE].data[0];
+       if (tp.packet_type)
+               dhcp(&tp);
+       else
+               bootp(&tp);
+
+       /* Free the data associated with the options. */
+       for (i = 0; i < 256; i++)
+               if (tp.options[i].len && tp.options[i].data)
+                       free(tp.options[i].data);
+}
diff --git a/reactos/subsys/system/dhcp/privsep.c b/reactos/subsys/system/dhcp/privsep.c
new file mode 100644 (file)
index 0000000..9f36a94
--- /dev/null
@@ -0,0 +1,237 @@
+/*     $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "rosdhcp.h"
+#include "dhcpd.h"
+#include "privsep.h"
+
+struct buf *
+buf_open(size_t len)
+{
+       struct buf      *buf;
+
+       if ((buf = calloc(1, sizeof(struct buf))) == NULL)
+               return (NULL);
+       if ((buf->buf = malloc(len)) == NULL) {
+               free(buf);
+               return (NULL);
+       }
+       buf->size = len;
+
+       return (buf);
+}
+
+int
+buf_add(struct buf *buf, void *data, size_t len)
+{
+       if (buf->wpos + len > buf->size)
+               return (-1);
+
+       memcpy(buf->buf + buf->wpos, data, len);
+       buf->wpos += len;
+       return (0);
+}
+
+int
+buf_close(int sock, struct buf *buf)
+{
+       ssize_t n;
+
+       do {
+               n = write(sock, buf->buf + buf->rpos, buf->size - buf->rpos);
+               if (n != -1)
+                       buf->rpos += n;
+               if (n == 0) {                   /* connection closed */
+                       errno = 0;
+                       return (-1);
+               }
+       } while (n == -1 && (errno == EAGAIN || errno == EINTR));
+
+       if (buf->rpos < buf->size)
+               error("short write: wanted %lu got %ld bytes",
+                   (unsigned long)buf->size, (long)buf->rpos);
+
+       free(buf->buf);
+       free(buf);
+       return (n);
+}
+
+ssize_t
+buf_read(int sock, void *buf, size_t nbytes)
+{
+       ssize_t n, r = 0;
+       char *p = buf;
+
+       do {
+               n = read(sock, p, nbytes);
+               if (n == 0)
+                       error("connection closed");
+               if (n != -1) {
+                       r += n;
+                       p += n;
+                       nbytes -= n;
+               }
+       } while (n == -1 && (errno == EINTR || errno == EAGAIN));
+
+       if (n == -1)
+               error("buf_read: %m");
+
+       if (r < nbytes)
+               error("short read: wanted %lu got %ld bytes",
+                   (unsigned long)nbytes, (long)r);
+
+       return (r);
+}
+
+void
+dispatch_imsg(int fd)
+{
+       struct imsg_hdr          hdr;
+       char                    *medium, *reason, *filename,
+                               *servername, *prefix;
+       size_t                   medium_len, reason_len, filename_len,
+                                servername_len, prefix_len, totlen;
+       struct client_lease      lease;
+       int                      ret, i, optlen;
+       struct buf              *buf;
+
+       buf_read(fd, &hdr, sizeof(hdr));
+
+       switch (hdr.code) {
+       case IMSG_SCRIPT_INIT:
+               if (hdr.len < sizeof(hdr) + sizeof(size_t))
+                       error("corrupted message received");
+               buf_read(fd, &medium_len, sizeof(medium_len));
+               if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr)
+                   + sizeof(size_t) || medium_len == SIZE_T_MAX)
+                       error("corrupted message received");
+               if (medium_len > 0) {
+                       if ((medium = calloc(1, medium_len + 1)) == NULL)
+                               error("%m");
+                       buf_read(fd, medium, medium_len);
+               } else
+                       medium = NULL;
+
+               buf_read(fd, &reason_len, sizeof(reason_len));
+               if (hdr.len < medium_len + reason_len + sizeof(hdr) ||
+                   reason_len == SIZE_T_MAX)
+                       error("corrupted message received");
+               if (reason_len > 0) {
+                       if ((reason = calloc(1, reason_len + 1)) == NULL)
+                               error("%m");
+                       buf_read(fd, reason, reason_len);
+               } else
+                       reason = NULL;
+
+//             priv_script_init(reason, medium);
+               free(reason);
+               free(medium);
+               break;
+       case IMSG_SCRIPT_WRITE_PARAMS:
+               //bzero(&lease, sizeof lease);
+               memset(&lease, 0, sizeof(lease));
+               totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t);
+               if (hdr.len < totlen)
+                       error("corrupted message received");
+               buf_read(fd, &lease, sizeof(lease));
+
+               buf_read(fd, &filename_len, sizeof(filename_len));
+               totlen += filename_len + sizeof(size_t);
+               if (hdr.len < totlen || filename_len == SIZE_T_MAX)
+                       error("corrupted message received");
+               if (filename_len > 0) {
+                       if ((filename = calloc(1, filename_len + 1)) == NULL)
+                               error("%m");
+                       buf_read(fd, filename, filename_len);
+               } else
+                       filename = NULL;
+
+               buf_read(fd, &servername_len, sizeof(servername_len));
+               totlen += servername_len + sizeof(size_t);
+               if (hdr.len < totlen || servername_len == SIZE_T_MAX)
+                       error("corrupted message received");
+               if (servername_len > 0) {
+                       if ((servername =
+                           calloc(1, servername_len + 1)) == NULL)
+                               error("%m");
+                       buf_read(fd, servername, servername_len);
+               } else
+                       servername = NULL;
+
+               buf_read(fd, &prefix_len, sizeof(prefix_len));
+               totlen += prefix_len;
+               if (hdr.len < totlen || prefix_len == SIZE_T_MAX)
+                       error("corrupted message received");
+               if (prefix_len > 0) {
+                       if ((prefix = calloc(1, prefix_len + 1)) == NULL)
+                               error("%m");
+                       buf_read(fd, prefix, prefix_len);
+               } else
+                       prefix = NULL;
+
+               for (i = 0; i < 256; i++) {
+                       totlen += sizeof(optlen);
+                       if (hdr.len < totlen)
+                               error("corrupted message received");
+                       buf_read(fd, &optlen, sizeof(optlen));
+                       lease.options[i].data = NULL;
+                       lease.options[i].len = optlen;
+                       if (optlen > 0) {
+                               totlen += optlen;
+                               if (hdr.len < totlen || optlen == SIZE_T_MAX)
+                                       error("corrupted message received");
+                               lease.options[i].data =
+                                   calloc(1, optlen + 1);
+                               if (lease.options[i].data == NULL)
+                                   error("%m");
+                               buf_read(fd, lease.options[i].data, optlen);
+                       }
+               }
+               lease.server_name = servername;
+               lease.filename = filename;
+
+//             priv_script_write_params(prefix, &lease);
+
+               free(servername);
+               free(filename);
+               free(prefix);
+               for (i = 0; i < 256; i++)
+                       if (lease.options[i].len > 0)
+                               free(lease.options[i].data);
+               break;
+       case IMSG_SCRIPT_GO:
+               if (hdr.len != sizeof(hdr))
+                       error("corrupted message received");
+
+//             ret = priv_script_go();
+
+               hdr.code = IMSG_SCRIPT_GO_RET;
+               hdr.len = sizeof(struct imsg_hdr) + sizeof(int);
+               if ((buf = buf_open(hdr.len)) == NULL)
+                       error("buf_open: %m");
+               if (buf_add(buf, &hdr, sizeof(hdr)))
+                       error("buf_add: %m");
+               if (buf_add(buf, &ret, sizeof(ret)))
+                       error("buf_add: %m");
+               if (buf_close(fd, buf) == -1)
+                       error("buf_close: %m");
+               break;
+       default:
+               error("received unknown message, code %d", hdr.code);
+       }
+}
diff --git a/reactos/subsys/system/dhcp/socket.c b/reactos/subsys/system/dhcp/socket.c
new file mode 100644 (file)
index 0000000..3c7d398
--- /dev/null
@@ -0,0 +1,39 @@
+#include "rosdhcp.h"
+
+SOCKET ServerSocket;
+
+void SocketInit() {
+    ServerSocket = socket( AF_INET, SOCK_DGRAM, 0 );
+}
+
+ssize_t send_packet( struct interface_info *ip, 
+                     struct dhcp_packet *p,
+                     size_t size,
+                     struct in_addr addr,
+                     struct sockaddr_in *broadcast,
+                     struct hardware *hardware ) {
+    int result = 
+        sendto( ip->wfdesc, (char *)p, size, 0,
+                (struct sockaddr *)broadcast, sizeof(*broadcast) );
+    
+    if (result < 0) {
+        note ("send_packet: %x", result);
+        if (result == WSAENETUNREACH)
+            note ("send_packet: please consult README file%s",
+                  " regarding broadcast address.");
+    }
+
+    return result;
+}
+
+ssize_t receive_packet(struct interface_info *ip, 
+                       unsigned char *packet_data,
+                       size_t packet_len,
+                       struct sockaddr_in *dest, 
+                       struct hardware *hardware ) {
+    int recv_addr_size = sizeof(*dest);
+    int result = 
+        recvfrom (ip -> rfdesc, (char *)packet_data, packet_len, 0,
+                  (struct sockaddr *)dest, &recv_addr_size );
+    return result;
+}
diff --git a/reactos/subsys/system/dhcp/tables.c b/reactos/subsys/system/dhcp/tables.c
new file mode 100644 (file)
index 0000000..7eb9c76
--- /dev/null
@@ -0,0 +1,692 @@
+/* tables.c
+
+   Tables of information... */
+
+/*
+ * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: tables.c,v 1.13.2.4 1999/04/24 16:46:44 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "rosdhcp.h"
+
+/* DHCP Option names, formats and codes, from RFC1533.
+
+   Format codes:
+
+   e - end of data
+   I - IP address
+   l - 32-bit signed integer
+   L - 32-bit unsigned integer
+   s - 16-bit signed integer
+   S - 16-bit unsigned integer
+   b - 8-bit signed integer
+   B - 8-bit unsigned integer
+   t - ASCII text
+   f - flag (true or false)
+   A - array of whatever precedes (e.g., IA means array of IP addresses)
+*/
+
+struct universe dhcp_universe;
+struct dhcp_option dhcp_options [256] = {
+       { "pad", "",                                    &dhcp_universe, 0 },
+       { "subnet-mask", "I",                           &dhcp_universe, 1 },
+       { "time-offset", "l",                           &dhcp_universe, 2 },
+       { "routers", "IA",                              &dhcp_universe, 3 },
+       { "time-servers", "IA",                         &dhcp_universe, 4 },
+       { "ien116-name-servers", "IA",                  &dhcp_universe, 5 },
+       { "domain-name-servers", "IA",                  &dhcp_universe, 6 },
+       { "log-servers", "IA",                          &dhcp_universe, 7 },
+       { "cookie-servers", "IA",                       &dhcp_universe, 8 },
+       { "lpr-servers", "IA",                          &dhcp_universe, 9 },
+       { "impress-servers", "IA",                      &dhcp_universe, 10 },
+       { "resource-location-servers", "IA",            &dhcp_universe, 11 },
+       { "host-name", "X",                             &dhcp_universe, 12 },
+       { "boot-size", "S",                             &dhcp_universe, 13 },
+       { "merit-dump", "t",                            &dhcp_universe, 14 },
+       { "domain-name", "t",                           &dhcp_universe, 15 },
+       { "swap-server", "I",                           &dhcp_universe, 16 },
+       { "root-path", "t",                             &dhcp_universe, 17 },
+       { "extensions-path", "t",                       &dhcp_universe, 18 },
+       { "ip-forwarding", "f",                         &dhcp_universe, 19 },
+       { "non-local-source-routing", "f",              &dhcp_universe, 20 },
+       { "policy-filter", "IIA",                       &dhcp_universe, 21 },
+       { "max-dgram-reassembly", "S",                  &dhcp_universe, 22 },
+       { "default-ip-ttl", "B",                        &dhcp_universe, 23 },
+       { "path-mtu-aging-timeout", "L",                &dhcp_universe, 24 },
+       { "path-mtu-plateau-table", "SA",               &dhcp_universe, 25 },
+       { "interface-mtu", "S",                         &dhcp_universe, 26 },
+       { "all-subnets-local", "f",                     &dhcp_universe, 27 },
+       { "broadcast-address", "I",                     &dhcp_universe, 28 },
+       { "perform-mask-discovery", "f",                &dhcp_universe, 29 },
+       { "mask-supplier", "f",                         &dhcp_universe, 30 },
+       { "router-discovery", "f",                      &dhcp_universe, 31 },
+       { "router-solicitation-address", "I",           &dhcp_universe, 32 },
+       { "static-routes", "IIA",                       &dhcp_universe, 33 },
+       { "trailer-encapsulation", "f",                 &dhcp_universe, 34 },
+       { "arp-cache-timeout", "L",                     &dhcp_universe, 35 },
+       { "ieee802-3-encapsulation", "f",               &dhcp_universe, 36 },
+       { "default-tcp-ttl", "B",                       &dhcp_universe, 37 },
+       { "tcp-keepalive-interval", "L",                &dhcp_universe, 38 },
+       { "tcp-keepalive-garbage", "f",                 &dhcp_universe, 39 },
+       { "nis-domain", "t",                            &dhcp_universe, 40 },
+       { "nis-servers", "IA",                          &dhcp_universe, 41 },
+       { "ntp-servers", "IA",                          &dhcp_universe, 42 },
+       { "vendor-encapsulated-options", "X",           &dhcp_universe, 43 },
+       { "netbios-name-servers", "IA",                 &dhcp_universe, 44 },
+       { "netbios-dd-server", "IA",                    &dhcp_universe, 45 },
+       { "netbios-node-type", "B",                     &dhcp_universe, 46 },
+       { "netbios-scope", "t",                         &dhcp_universe, 47 },
+       { "font-servers", "IA",                         &dhcp_universe, 48 },
+       { "x-display-manager", "IA",                    &dhcp_universe, 49 },
+       { "dhcp-requested-address", "I",                &dhcp_universe, 50 },
+       { "dhcp-lease-time", "L",                       &dhcp_universe, 51 },
+       { "dhcp-option-overload", "B",                  &dhcp_universe, 52 },
+       { "dhcp-message-type", "B",                     &dhcp_universe, 53 },
+       { "dhcp-server-identifier", "I",                &dhcp_universe, 54 },
+       { "dhcp-parameter-request-list", "BA",          &dhcp_universe, 55 },
+       { "dhcp-message", "t",                          &dhcp_universe, 56 },
+       { "dhcp-max-message-size", "S",                 &dhcp_universe, 57 },
+       { "dhcp-renewal-time", "L",                     &dhcp_universe, 58 },
+       { "dhcp-rebinding-time", "L",                   &dhcp_universe, 59 },
+       { "dhcp-class-identifier", "t",                 &dhcp_universe, 60 },
+       { "dhcp-client-identifier", "X",                &dhcp_universe, 61 },
+       { "option-62", "X",                             &dhcp_universe, 62 },
+       { "option-63", "X",                             &dhcp_universe, 63 },
+       { "nisplus-domain", "t",                        &dhcp_universe, 64 },
+       { "nisplus-servers", "IA",                      &dhcp_universe, 65 },
+       { "tftp-server-name", "t",                      &dhcp_universe, 66 },
+       { "bootfile-name", "t",                         &dhcp_universe, 67 },
+       { "mobile-ip-home-agent", "IA",                 &dhcp_universe, 68 },
+       { "smtp-server", "IA",                          &dhcp_universe, 69 },
+       { "pop-server", "IA",                           &dhcp_universe, 70 },
+       { "nntp-server", "IA",                          &dhcp_universe, 71 },
+       { "www-server", "IA",                           &dhcp_universe, 72 },
+       { "finger-server", "IA",                        &dhcp_universe, 73 },
+       { "irc-server", "IA",                           &dhcp_universe, 74 },
+       { "streettalk-server", "IA",                    &dhcp_universe, 75 },
+       { "streettalk-directory-assistance-server", "IA", &dhcp_universe, 76 },
+       { "user-class", "t",                            &dhcp_universe, 77 },
+       { "option-78", "X",                             &dhcp_universe, 78 },
+       { "option-79", "X",                             &dhcp_universe, 79 },
+       { "option-80", "X",                             &dhcp_universe, 80 },
+       { "option-81", "X",                             &dhcp_universe, 81 },
+       { "option-82", "X",                             &dhcp_universe, 82 },
+       { "option-83", "X",                             &dhcp_universe, 83 },
+       { "option-84", "X",                             &dhcp_universe, 84 },
+       { "nds-servers", "IA",                          &dhcp_universe, 85 },
+       { "nds-tree-name", "X",                         &dhcp_universe, 86 },
+       { "nds-context", "X",                           &dhcp_universe, 87 },
+       { "option-88", "X",                             &dhcp_universe, 88 },
+       { "option-89", "X",                             &dhcp_universe, 89 },
+       { "option-90", "X",                             &dhcp_universe, 90 },
+       { "option-91", "X",                             &dhcp_universe, 91 },
+       { "option-92", "X",                             &dhcp_universe, 92 },
+       { "option-93", "X",                             &dhcp_universe, 93 },
+       { "option-94", "X",                             &dhcp_universe, 94 },
+       { "option-95", "X",                             &dhcp_universe, 95 },
+       { "option-96", "X",                             &dhcp_universe, 96 },
+       { "option-97", "X",                             &dhcp_universe, 97 },
+       { "option-98", "X",                             &dhcp_universe, 98 },
+       { "option-99", "X",                             &dhcp_universe, 99 },
+       { "option-100", "X",                            &dhcp_universe, 100 },
+       { "option-101", "X",                            &dhcp_universe, 101 },
+       { "option-102", "X",                            &dhcp_universe, 102 },
+       { "option-103", "X",                            &dhcp_universe, 103 },
+       { "option-104", "X",                            &dhcp_universe, 104 },
+       { "option-105", "X",                            &dhcp_universe, 105 },
+       { "option-106", "X",                            &dhcp_universe, 106 },
+       { "option-107", "X",                            &dhcp_universe, 107 },
+       { "option-108", "X",                            &dhcp_universe, 108 },
+       { "option-109", "X",                            &dhcp_universe, 109 },
+       { "option-110", "X",                            &dhcp_universe, 110 },
+       { "option-111", "X",                            &dhcp_universe, 111 },
+       { "option-112", "X",                            &dhcp_universe, 112 },
+       { "option-113", "X",                            &dhcp_universe, 113 },
+       { "option-114", "X",                            &dhcp_universe, 114 },
+       { "option-115", "X",                            &dhcp_universe, 115 },
+       { "option-116", "X",                            &dhcp_universe, 116 },
+       { "option-117", "X",                            &dhcp_universe, 117 },
+       { "option-118", "X",                            &dhcp_universe, 118 },
+       { "option-119", "X",                            &dhcp_universe, 119 },
+       { "option-120", "X",                            &dhcp_universe, 120 },
+       { "option-121", "X",                            &dhcp_universe, 121 },
+       { "option-122", "X",                            &dhcp_universe, 122 },
+       { "option-123", "X",                            &dhcp_universe, 123 },
+       { "option-124", "X",                            &dhcp_universe, 124 },
+       { "option-125", "X",                            &dhcp_universe, 125 },
+       { "option-126", "X",                            &dhcp_universe, 126 },
+       { "option-127", "X",                            &dhcp_universe, 127 },
+       { "option-128", "X",                            &dhcp_universe, 128 },
+       { "option-129", "X",                            &dhcp_universe, 129 },
+       { "option-130", "X",                            &dhcp_universe, 130 },
+       { "option-131", "X",                            &dhcp_universe, 131 },
+       { "option-132", "X",                            &dhcp_universe, 132 },
+       { "option-133", "X",                            &dhcp_universe, 133 },
+       { "option-134", "X",                            &dhcp_universe, 134 },
+       { "option-135", "X",                            &dhcp_universe, 135 },
+       { "option-136", "X",                            &dhcp_universe, 136 },
+       { "option-137", "X",                            &dhcp_universe, 137 },
+       { "option-138", "X",                            &dhcp_universe, 138 },
+       { "option-139", "X",                            &dhcp_universe, 139 },
+       { "option-140", "X",                            &dhcp_universe, 140 },
+       { "option-141", "X",                            &dhcp_universe, 141 },
+       { "option-142", "X",                            &dhcp_universe, 142 },
+       { "option-143", "X",                            &dhcp_universe, 143 },
+       { "option-144", "X",                            &dhcp_universe, 144 },
+       { "option-145", "X",                            &dhcp_universe, 145 },
+       { "option-146", "X",                            &dhcp_universe, 146 },
+       { "option-147", "X",                            &dhcp_universe, 147 },
+       { "option-148", "X",                            &dhcp_universe, 148 },
+       { "option-149", "X",                            &dhcp_universe, 149 },
+       { "option-150", "X",                            &dhcp_universe, 150 },
+       { "option-151", "X",                            &dhcp_universe, 151 },
+       { "option-152", "X",                            &dhcp_universe, 152 },
+       { "option-153", "X",                            &dhcp_universe, 153 },
+       { "option-154", "X",                            &dhcp_universe, 154 },
+       { "option-155", "X",                            &dhcp_universe, 155 },
+       { "option-156", "X",                            &dhcp_universe, 156 },
+       { "option-157", "X",                            &dhcp_universe, 157 },
+       { "option-158", "X",                            &dhcp_universe, 158 },
+       { "option-159", "X",                            &dhcp_universe, 159 },
+       { "option-160", "X",                            &dhcp_universe, 160 },
+       { "option-161", "X",                            &dhcp_universe, 161 },
+       { "option-162", "X",                            &dhcp_universe, 162 },
+       { "option-163", "X",                            &dhcp_universe, 163 },
+       { "option-164", "X",                            &dhcp_universe, 164 },
+       { "option-165", "X",                            &dhcp_universe, 165 },
+       { "option-166", "X",                            &dhcp_universe, 166 },
+       { "option-167", "X",                            &dhcp_universe, 167 },
+       { "option-168", "X",                            &dhcp_universe, 168 },
+       { "option-169", "X",                            &dhcp_universe, 169 },
+       { "option-170", "X",                            &dhcp_universe, 170 },
+       { "option-171", "X",                            &dhcp_universe, 171 },
+       { "option-172", "X",                            &dhcp_universe, 172 },
+       { "option-173", "X",                            &dhcp_universe, 173 },
+       { "option-174", "X",                            &dhcp_universe, 174 },
+       { "option-175", "X",                            &dhcp_universe, 175 },
+       { "option-176", "X",                            &dhcp_universe, 176 },
+       { "option-177", "X",                            &dhcp_universe, 177 },
+       { "option-178", "X",                            &dhcp_universe, 178 },
+       { "option-179", "X",                            &dhcp_universe, 179 },
+       { "option-180", "X",                            &dhcp_universe, 180 },
+       { "option-181", "X",                            &dhcp_universe, 181 },
+       { "option-182", "X",                            &dhcp_universe, 182 },
+       { "option-183", "X",                            &dhcp_universe, 183 },
+       { "option-184", "X",                            &dhcp_universe, 184 },
+       { "option-185", "X",                            &dhcp_universe, 185 },
+       { "option-186", "X",                            &dhcp_universe, 186 },
+       { "option-187", "X",                            &dhcp_universe, 187 },
+       { "option-188", "X",                            &dhcp_universe, 188 },
+       { "option-189", "X",                            &dhcp_universe, 189 },
+       { "option-190", "X",                            &dhcp_universe, 190 },
+       { "option-191", "X",                            &dhcp_universe, 191 },
+       { "option-192", "X",                            &dhcp_universe, 192 },
+       { "option-193", "X",                            &dhcp_universe, 193 },
+       { "option-194", "X",                            &dhcp_universe, 194 },
+       { "option-195", "X",                            &dhcp_universe, 195 },
+       { "option-196", "X",                            &dhcp_universe, 196 },
+       { "option-197", "X",                            &dhcp_universe, 197 },
+       { "option-198", "X",                            &dhcp_universe, 198 },
+       { "option-199", "X",                            &dhcp_universe, 199 },
+       { "option-200", "X",                            &dhcp_universe, 200 },
+       { "option-201", "X",                            &dhcp_universe, 201 },
+       { "option-202", "X",                            &dhcp_universe, 202 },
+       { "option-203", "X",                            &dhcp_universe, 203 },
+       { "option-204", "X",                            &dhcp_universe, 204 },
+       { "option-205", "X",                            &dhcp_universe, 205 },
+       { "option-206", "X",                            &dhcp_universe, 206 },
+       { "option-207", "X",                            &dhcp_universe, 207 },
+       { "option-208", "X",                            &dhcp_universe, 208 },
+       { "option-209", "X",                            &dhcp_universe, 209 },
+       { "option-210", "X",                            &dhcp_universe, 210 },
+       { "option-211", "X",                            &dhcp_universe, 211 },
+       { "option-212", "X",                            &dhcp_universe, 212 },
+       { "option-213", "X",                            &dhcp_universe, 213 },
+       { "option-214", "X",                            &dhcp_universe, 214 },
+       { "option-215", "X",                            &dhcp_universe, 215 },
+       { "option-216", "X",                            &dhcp_universe, 216 },
+       { "option-217", "X",                            &dhcp_universe, 217 },
+       { "option-218", "X",                            &dhcp_universe, 218 },
+       { "option-219", "X",                            &dhcp_universe, 219 },
+       { "option-220", "X",                            &dhcp_universe, 220 },
+       { "option-221", "X",                            &dhcp_universe, 221 },
+       { "option-222", "X",                            &dhcp_universe, 222 },
+       { "option-223", "X",                            &dhcp_universe, 223 },
+       { "option-224", "X",                            &dhcp_universe, 224 },
+       { "option-225", "X",                            &dhcp_universe, 225 },
+       { "option-226", "X",                            &dhcp_universe, 226 },
+       { "option-227", "X",                            &dhcp_universe, 227 },
+       { "option-228", "X",                            &dhcp_universe, 228 },
+       { "option-229", "X",                            &dhcp_universe, 229 },
+       { "option-230", "X",                            &dhcp_universe, 230 },
+       { "option-231", "X",                            &dhcp_universe, 231 },
+       { "option-232", "X",                            &dhcp_universe, 232 },
+       { "option-233", "X",                            &dhcp_universe, 233 },
+       { "option-234", "X",                            &dhcp_universe, 234 },
+       { "option-235", "X",                            &dhcp_universe, 235 },
+       { "option-236", "X",                            &dhcp_universe, 236 },
+       { "option-237", "X",                            &dhcp_universe, 237 },
+       { "option-238", "X",                            &dhcp_universe, 238 },
+       { "option-239", "X",                            &dhcp_universe, 239 },
+       { "option-240", "X",                            &dhcp_universe, 240 },
+       { "option-241", "X",                            &dhcp_universe, 241 },
+       { "option-242", "X",                            &dhcp_universe, 242 },
+       { "option-243", "X",                            &dhcp_universe, 243 },
+       { "option-244", "X",                            &dhcp_universe, 244 },
+       { "option-245", "X",                            &dhcp_universe, 245 },
+       { "option-246", "X",                            &dhcp_universe, 246 },
+       { "option-247", "X",                            &dhcp_universe, 247 },
+       { "option-248", "X",                            &dhcp_universe, 248 },
+       { "option-249", "X",                            &dhcp_universe, 249 },
+       { "option-250", "X",                            &dhcp_universe, 250 },
+       { "option-251", "X",                            &dhcp_universe, 251 },
+       { "option-252", "X",                            &dhcp_universe, 252 },
+       { "option-253", "X",                            &dhcp_universe, 253 },
+       { "option-254", "X",                            &dhcp_universe, 254 },
+       { "option-end", "e",                            &dhcp_universe, 255 },
+};
+
+/* Default dhcp option priority list (this is ad hoc and should not be
+   mistaken for a carefully crafted and optimized list). */
+unsigned char dhcp_option_default_priority_list [] = {
+       DHO_DHCP_REQUESTED_ADDRESS,
+       DHO_DHCP_OPTION_OVERLOAD,
+       DHO_DHCP_MAX_MESSAGE_SIZE,
+       DHO_DHCP_RENEWAL_TIME,
+       DHO_DHCP_REBINDING_TIME,
+       DHO_DHCP_CLASS_IDENTIFIER,
+       DHO_DHCP_CLIENT_IDENTIFIER,
+       DHO_SUBNET_MASK,
+       DHO_TIME_OFFSET,
+       DHO_ROUTERS,
+       DHO_TIME_SERVERS,
+       DHO_NAME_SERVERS,
+       DHO_DOMAIN_NAME_SERVERS,
+       DHO_HOST_NAME,
+       DHO_LOG_SERVERS,
+       DHO_COOKIE_SERVERS,
+       DHO_LPR_SERVERS,
+       DHO_IMPRESS_SERVERS,
+       DHO_RESOURCE_LOCATION_SERVERS,
+       DHO_HOST_NAME,
+       DHO_BOOT_SIZE,
+       DHO_MERIT_DUMP,
+       DHO_DOMAIN_NAME,
+       DHO_SWAP_SERVER,
+       DHO_ROOT_PATH,
+       DHO_EXTENSIONS_PATH,
+       DHO_IP_FORWARDING,
+       DHO_NON_LOCAL_SOURCE_ROUTING,
+       DHO_POLICY_FILTER,
+       DHO_MAX_DGRAM_REASSEMBLY,
+       DHO_DEFAULT_IP_TTL,
+       DHO_PATH_MTU_AGING_TIMEOUT,
+       DHO_PATH_MTU_PLATEAU_TABLE,
+       DHO_INTERFACE_MTU,
+       DHO_ALL_SUBNETS_LOCAL,
+       DHO_BROADCAST_ADDRESS,
+       DHO_PERFORM_MASK_DISCOVERY,
+       DHO_MASK_SUPPLIER,
+       DHO_ROUTER_DISCOVERY,
+       DHO_ROUTER_SOLICITATION_ADDRESS,
+       DHO_STATIC_ROUTES,
+       DHO_TRAILER_ENCAPSULATION,
+       DHO_ARP_CACHE_TIMEOUT,
+       DHO_IEEE802_3_ENCAPSULATION,
+       DHO_DEFAULT_TCP_TTL,
+       DHO_TCP_KEEPALIVE_INTERVAL,
+       DHO_TCP_KEEPALIVE_GARBAGE,
+       DHO_NIS_DOMAIN,
+       DHO_NIS_SERVERS,
+       DHO_NTP_SERVERS,
+       DHO_VENDOR_ENCAPSULATED_OPTIONS,
+       DHO_NETBIOS_NAME_SERVERS,
+       DHO_NETBIOS_DD_SERVER,
+       DHO_NETBIOS_NODE_TYPE,
+       DHO_NETBIOS_SCOPE,
+       DHO_FONT_SERVERS,
+       DHO_X_DISPLAY_MANAGER,
+       DHO_DHCP_PARAMETER_REQUEST_LIST,
+
+       /* Presently-undefined options... */
+       62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+       78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+       93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+       107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+       119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+       131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+       143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+       155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+       167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
+       179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
+       191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
+       203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
+       215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
+       227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
+       239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
+       251, 252, 253, 254,
+};
+
+int sizeof_dhcp_option_default_priority_list =
+       sizeof dhcp_option_default_priority_list;
+
+
+char *hardware_types [] = {
+       "unknown-0",
+       "ethernet",
+       "unknown-2",
+       "unknown-3",
+       "unknown-4",
+       "unknown-5",
+       "token-ring",
+       "unknown-7",
+       "fddi",
+       "unknown-9",
+       "unknown-10",
+       "unknown-11",
+       "unknown-12",
+       "unknown-13",
+       "unknown-14",
+       "unknown-15",
+       "unknown-16",
+       "unknown-17",
+       "unknown-18",
+       "unknown-19",
+       "unknown-20",
+       "unknown-21",
+       "unknown-22",
+       "unknown-23",
+       "unknown-24",
+       "unknown-25",
+       "unknown-26",
+       "unknown-27",
+       "unknown-28",
+       "unknown-29",
+       "unknown-30",
+       "unknown-31",
+       "unknown-32",
+       "unknown-33",
+       "unknown-34",
+       "unknown-35",
+       "unknown-36",
+       "unknown-37",
+       "unknown-38",
+       "unknown-39",
+       "unknown-40",
+       "unknown-41",
+       "unknown-42",
+       "unknown-43",
+       "unknown-44",
+       "unknown-45",
+       "unknown-46",
+       "unknown-47",
+       "unknown-48",
+       "unknown-49",
+       "unknown-50",
+       "unknown-51",
+       "unknown-52",
+       "unknown-53",
+       "unknown-54",
+       "unknown-55",
+       "unknown-56",
+       "unknown-57",
+       "unknown-58",
+       "unknown-59",
+       "unknown-60",
+       "unknown-61",
+       "unknown-62",
+       "unknown-63",
+       "unknown-64",
+       "unknown-65",
+       "unknown-66",
+       "unknown-67",
+       "unknown-68",
+       "unknown-69",
+       "unknown-70",
+       "unknown-71",
+       "unknown-72",
+       "unknown-73",
+       "unknown-74",
+       "unknown-75",
+       "unknown-76",
+       "unknown-77",
+       "unknown-78",
+       "unknown-79",
+       "unknown-80",
+       "unknown-81",
+       "unknown-82",
+       "unknown-83",
+       "unknown-84",
+       "unknown-85",
+       "unknown-86",
+       "unknown-87",
+       "unknown-88",
+       "unknown-89",
+       "unknown-90",
+       "unknown-91",
+       "unknown-92",
+       "unknown-93",
+       "unknown-94",
+       "unknown-95",
+       "unknown-96",
+       "unknown-97",
+       "unknown-98",
+       "unknown-99",
+       "unknown-100",
+       "unknown-101",
+       "unknown-102",
+       "unknown-103",
+       "unknown-104",
+       "unknown-105",
+       "unknown-106",
+       "unknown-107",
+       "unknown-108",
+       "unknown-109",
+       "unknown-110",
+       "unknown-111",
+       "unknown-112",
+       "unknown-113",
+       "unknown-114",
+       "unknown-115",
+       "unknown-116",
+       "unknown-117",
+       "unknown-118",
+       "unknown-119",
+       "unknown-120",
+       "unknown-121",
+       "unknown-122",
+       "unknown-123",
+       "unknown-124",
+       "unknown-125",
+       "unknown-126",
+       "unknown-127",
+       "unknown-128",
+       "unknown-129",
+       "unknown-130",
+       "unknown-131",
+       "unknown-132",
+       "unknown-133",
+       "unknown-134",
+       "unknown-135",
+       "unknown-136",
+       "unknown-137",
+       "unknown-138",
+       "unknown-139",
+       "unknown-140",
+       "unknown-141",
+       "unknown-142",
+       "unknown-143",
+       "unknown-144",
+       "unknown-145",
+       "unknown-146",
+       "unknown-147",
+       "unknown-148",
+       "unknown-149",
+       "unknown-150",
+       "unknown-151",
+       "unknown-152",
+       "unknown-153",
+       "unknown-154",
+       "unknown-155",
+       "unknown-156",
+       "unknown-157",
+       "unknown-158",
+       "unknown-159",
+       "unknown-160",
+       "unknown-161",
+       "unknown-162",
+       "unknown-163",
+       "unknown-164",
+       "unknown-165",
+       "unknown-166",
+       "unknown-167",
+       "unknown-168",
+       "unknown-169",
+       "unknown-170",
+       "unknown-171",
+       "unknown-172",
+       "unknown-173",
+       "unknown-174",
+       "unknown-175",
+       "unknown-176",
+       "unknown-177",
+       "unknown-178",
+       "unknown-179",
+       "unknown-180",
+       "unknown-181",
+       "unknown-182",
+       "unknown-183",
+       "unknown-184",
+       "unknown-185",
+       "unknown-186",
+       "unknown-187",
+       "unknown-188",
+       "unknown-189",
+       "unknown-190",
+       "unknown-191",
+       "unknown-192",
+       "unknown-193",
+       "unknown-194",
+       "unknown-195",
+       "unknown-196",
+       "unknown-197",
+       "unknown-198",
+       "unknown-199",
+       "unknown-200",
+       "unknown-201",
+       "unknown-202",
+       "unknown-203",
+       "unknown-204",
+       "unknown-205",
+       "unknown-206",
+       "unknown-207",
+       "unknown-208",
+       "unknown-209",
+       "unknown-210",
+       "unknown-211",
+       "unknown-212",
+       "unknown-213",
+       "unknown-214",
+       "unknown-215",
+       "unknown-216",
+       "unknown-217",
+       "unknown-218",
+       "unknown-219",
+       "unknown-220",
+       "unknown-221",
+       "unknown-222",
+       "unknown-223",
+       "unknown-224",
+       "unknown-225",
+       "unknown-226",
+       "unknown-227",
+       "unknown-228",
+       "unknown-229",
+       "unknown-230",
+       "unknown-231",
+       "unknown-232",
+       "unknown-233",
+       "unknown-234",
+       "unknown-235",
+       "unknown-236",
+       "unknown-237",
+       "unknown-238",
+       "unknown-239",
+       "unknown-240",
+       "unknown-241",
+       "unknown-242",
+       "unknown-243",
+       "unknown-244",
+       "unknown-245",
+       "unknown-246",
+       "unknown-247",
+       "unknown-248",
+       "unknown-249",
+       "unknown-250",
+       "unknown-251",
+       "unknown-252",
+       "unknown-253",
+       "unknown-254",
+       "unknown-255" };
+
+
+
+struct hash_table universe_hash;
+
+void initialize_universes()
+{
+       int i;
+
+       dhcp_universe.name = "dhcp";
+       dhcp_universe.hash = new_hash ();
+       if (!dhcp_universe.hash)
+               error ("Can't allocate dhcp option hash table.");
+       for (i = 0; i < 256; i++) {
+               dhcp_universe.options [i] = &dhcp_options [i];
+               add_hash (dhcp_universe.hash,
+                         (unsigned char *)dhcp_options [i].name, 0,
+                         (unsigned char *)&dhcp_options [i]);
+       }
+       universe_hash.hash_count = DEFAULT_HASH_SIZE;
+       add_hash (&universe_hash,
+                 (unsigned char *)dhcp_universe.name, 0,
+                 (unsigned char *)&dhcp_universe);
+}
diff --git a/reactos/subsys/system/dhcp/timer.c b/reactos/subsys/system/dhcp/timer.c
new file mode 100644 (file)
index 0000000..ccd8171
--- /dev/null
@@ -0,0 +1,2 @@
+#include "rosdhcp.h"
+
diff --git a/reactos/subsys/system/dhcp/tree.c b/reactos/subsys/system/dhcp/tree.c
new file mode 100644 (file)
index 0000000..9a49e5e
--- /dev/null
@@ -0,0 +1,412 @@
+/* tree.c
+
+   Routines for manipulating parse trees... */
+
+/*
+ * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ */
+
+#ifndef lint
+static char copyright[] =
+"$Id: tree.c,v 1.10 1997/05/09 08:14:57 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.  All rights reserved.\n";
+#endif /* not lint */
+
+#include "rosdhcp.h"
+
+static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
+                                         struct tree *));
+static TIME do_host_lookup PROTO ((int *, unsigned char **, int *,
+                                         struct dns_host_entry *));
+static void do_data_copy PROTO ((int *, unsigned char **, int *,
+                                unsigned char *, int));
+
+pair cons (car, cdr)
+       caddr_t car;
+       pair cdr;
+{
+       pair foo = (pair)dmalloc (sizeof *foo, "cons");
+       if (!foo)
+               error ("no memory for cons.");
+       foo -> car = car;
+       foo -> cdr = cdr;
+       return foo;
+}
+
+struct tree_cache *tree_cache (tree)
+       struct tree *tree;
+{
+       struct tree_cache *tc;
+
+       tc = new_tree_cache ("tree_cache");
+       if (!tc)
+               return 0;
+       tc -> value = (unsigned char *)0;
+       tc -> len = tc -> buf_size = 0;
+       tc -> timeout = 0;
+       tc -> tree = tree;
+       return tc;
+}
+
+struct tree *tree_host_lookup (name)
+       char *name;
+{
+       struct tree *nt;
+       nt = new_tree ("tree_host_lookup");
+       if (!nt)
+               error ("No memory for host lookup tree node.");
+       nt -> op = TREE_HOST_LOOKUP;
+       nt -> data.host_lookup.host = enter_dns_host (name);
+       return nt;
+}
+
+struct dns_host_entry *enter_dns_host (name)
+       char *name;
+{
+       struct dns_host_entry *dh;
+
+       if (!(dh = (struct dns_host_entry *)dmalloc
+             (sizeof (struct dns_host_entry), "enter_dns_host"))
+           || !(dh -> hostname = dmalloc (strlen (name) + 1,
+                                          "enter_dns_host")))
+               error ("Can't allocate space for new host.");
+       strcpy (dh -> hostname, name);
+       dh -> data = (unsigned char *)0;
+       dh -> data_len = 0;
+       dh -> buf_len = 0;
+       dh -> timeout = 0;
+       return dh;
+}
+
+struct tree *tree_const (data, len)
+       unsigned char *data;
+       int len;
+{
+       struct tree *nt;
+       if (!(nt = new_tree ("tree_const"))
+           || !(nt -> data.const_val.data =
+                (unsigned char *)dmalloc (len, "tree_const")))
+               error ("No memory for constant data tree node.");
+       nt -> op = TREE_CONST;
+       memcpy (nt -> data.const_val.data, data, len);
+       nt -> data.const_val.len = len;
+       return nt;
+}
+
+struct tree *tree_concat (left, right)
+       struct tree *left, *right;
+{
+       struct tree *nt;
+
+       /* If we're concatenating a null tree to a non-null tree, just
+          return the non-null tree; if both trees are null, return
+          a null tree. */
+       if (!left)
+               return right;
+       if (!right)
+               return left;
+
+       /* If both trees are constant, combine them. */
+       if (left -> op == TREE_CONST && right -> op == TREE_CONST) {
+               unsigned char *buf = dmalloc (left -> data.const_val.len
+                                             + right -> data.const_val.len,
+                                             "tree_concat");
+               if (!buf)
+                       error ("No memory to concatenate constants.");
+               memcpy (buf, left -> data.const_val.data,
+                       left -> data.const_val.len);
+               memcpy (buf + left -> data.const_val.len,
+                       right -> data.const_val.data,
+                       right -> data.const_val.len);
+               dfree (left -> data.const_val.data, "tree_concat");
+               dfree (right -> data.const_val.data, "tree_concat");
+               left -> data.const_val.data = buf;
+               left -> data.const_val.len += right -> data.const_val.len;
+               free_tree (right, "tree_concat");
+               return left;
+       }
+                       
+       /* Otherwise, allocate a new node to concatenate the two. */
+       if (!(nt = new_tree ("tree_concat")))
+               error ("No memory for data tree concatenation node.");
+       nt -> op = TREE_CONCAT;
+       nt -> data.concat.left = left;
+       nt -> data.concat.right = right;
+       return nt;
+}
+
+struct tree *tree_limit (tree, limit)
+       struct tree *tree;
+       int limit;
+{
+       struct tree *rv;
+
+       /* If the tree we're limiting is constant, limit it now. */
+       if (tree -> op == TREE_CONST) {
+               if (tree -> data.const_val.len > limit)
+                       tree -> data.const_val.len = limit;
+               return tree;
+       }
+
+       /* Otherwise, put in a node which enforces the limit on evaluation. */
+       rv = new_tree ("tree_limit");
+       if (!rv)
+               return (struct tree *)0;
+       rv -> op = TREE_LIMIT;
+       rv -> data.limit.tree = tree;
+       rv -> data.limit.limit = limit;
+       return rv;
+}
+
+int tree_evaluate (tree_cache)
+       struct tree_cache *tree_cache;
+{
+       unsigned char *bp = tree_cache -> value;
+       int bc = tree_cache -> buf_size;
+       int bufix = 0;
+
+       /* If there's no tree associated with this cache, it evaluates
+          to a constant and that was detected at startup. */
+       if (!tree_cache -> tree)
+               return 1;
+
+       /* Try to evaluate the tree without allocating more memory... */
+       tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc,
+                                                      tree_cache -> tree);
+
+       /* No additional allocation needed? */
+       if (bufix <= bc) {
+               tree_cache -> len = bufix;
+               return 1;
+       }
+
+       /* If we can't allocate more memory, return with what we
+          have (maybe nothing). */
+       if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate")))
+               return 0;
+
+       /* Record the change in conditions... */
+       bc = bufix;
+       bufix = 0;
+
+       /* Note that the size of the result shouldn't change on the
+          second call to tree_evaluate_recurse, since we haven't
+          changed the ``current'' time. */
+       tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree);
+
+       /* Free the old buffer if needed, then store the new buffer
+          location and size and return. */
+       if (tree_cache -> value)
+               dfree (tree_cache -> value, "tree_evaluate");
+       tree_cache -> value = bp;
+       tree_cache -> len = bufix;
+       tree_cache -> buf_size = bc;
+       return 1;
+}
+
+static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree)
+       int *bufix;
+       unsigned char **bufp;
+       int *bufcount;
+       struct tree *tree;
+{
+       int limit;
+       TIME t1, t2;
+
+       switch (tree -> op) {
+             case TREE_CONCAT:
+               t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+                                          tree -> data.concat.left);
+               t2 = tree_evaluate_recurse (bufix, bufp, bufcount,
+                                          tree -> data.concat.right);
+               if (t1 > t2)
+                       return t2;
+               return t1;
+
+             case TREE_HOST_LOOKUP:
+               return do_host_lookup (bufix, bufp, bufcount,
+                                      tree -> data.host_lookup.host);
+
+             case TREE_CONST:
+               do_data_copy (bufix, bufp, bufcount,
+                             tree -> data.const_val.data,
+                             tree -> data.const_val.len);
+               t1 = MAX_TIME;
+               return t1;
+
+             case TREE_LIMIT:
+               limit = *bufix + tree -> data.limit.limit;
+               t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
+                                           tree -> data.limit.tree);
+               *bufix = limit;
+               return t1;
+
+             default:
+               warn ("Bad node id in tree: %d.");
+               t1 = MAX_TIME;
+               return t1;
+       }
+}
+
+static TIME do_host_lookup (bufix, bufp, bufcount, dns)
+       int *bufix;
+       unsigned char **bufp;
+       int *bufcount;
+       struct dns_host_entry *dns;
+{
+       struct hostent *h;
+       int i;
+       int new_len;
+
+#ifdef DEBUG_EVAL
+       debug ("time: now = %d  dns = %d %d  diff = %d",
+              cur_time, dns -> timeout, cur_time - dns -> timeout);
+#endif
+
+       /* If the record hasn't timed out, just copy the data and return. */
+       if (cur_time <= dns -> timeout) {
+#ifdef DEBUG_EVAL
+               debug ("easy copy: %x %d %x",
+                      dns -> data, dns -> data_len,
+                      dns -> data ? *(int *)(dns -> data) : 0);
+#endif
+               do_data_copy (bufix, bufp, bufcount,
+                             dns -> data, dns -> data_len);
+               return dns -> timeout;
+       }
+#ifdef DEBUG_EVAL
+       debug ("Looking up %s", dns -> hostname);
+#endif
+
+       /* Otherwise, look it up... */
+       h = gethostbyname (dns -> hostname);
+       if (!h) {
+#ifndef NO_H_ERRNO
+               switch (h_errno) {
+                     case HOST_NOT_FOUND:
+#endif
+                       warn ("%s: host unknown.", dns -> hostname);
+#ifndef NO_H_ERRNO
+                       break;
+                     case TRY_AGAIN:
+                       warn ("%s: temporary name server failure",
+                             dns -> hostname);
+                       break;
+                     case NO_RECOVERY:
+                       warn ("%s: name server failed", dns -> hostname);
+                       break;
+                     case NO_DATA:
+                       warn ("%s: no A record associated with address",
+                             dns -> hostname);
+               }
+#endif /* !NO_H_ERRNO */
+
+               /* Okay to try again after a minute. */
+               return cur_time + 60;
+       }
+
+#ifdef DEBUG_EVAL
+       debug ("Lookup succeeded; first address is %x",
+              h -> h_addr_list [0]);
+#endif
+
+       /* Count the number of addresses we got... */
+       for (i = 0; h -> h_addr_list [i]; i++)
+               ;
+       
+       /* Do we need to allocate more memory? */
+       new_len = i * h -> h_length;
+       if (dns -> buf_len < i) {
+               unsigned char *buf =
+                       (unsigned char *)dmalloc (new_len, "do_host_lookup");
+               /* If we didn't get more memory, use what we have. */
+               if (!buf) {
+                       new_len = dns -> buf_len;
+                       if (!dns -> buf_len) {
+                               dns -> timeout = cur_time + 60;
+                               return dns -> timeout;
+                       }
+               } else {
+                       if (dns -> data)
+                               dfree (dns -> data, "do_host_lookup");
+                       dns -> data = buf;
+                       dns -> buf_len = new_len;
+               }
+       }
+
+       /* Addresses are conveniently stored one to the buffer, so we
+          have to copy them out one at a time... :'( */
+       for (i = 0; i < new_len / h -> h_length; i++) {
+               memcpy (dns -> data + h -> h_length * i,
+                       h -> h_addr_list [i], h -> h_length);
+       }
+#ifdef DEBUG_EVAL
+       debug ("dns -> data: %x  h -> h_addr_list [0]: %x",
+              *(int *)(dns -> data), h -> h_addr_list [0]);
+#endif
+       dns -> data_len = new_len;
+
+       /* Set the timeout for an hour from now.
+          XXX This should really use the time on the DNS reply. */
+       dns -> timeout = cur_time + 3600;
+
+#ifdef DEBUG_EVAL
+       debug ("hard copy: %x %d %x",
+              dns -> data, dns -> data_len, *(int *)(dns -> data));
+#endif
+       do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len);
+       return dns -> timeout;
+}
+
+static void do_data_copy (bufix, bufp, bufcount, data, len)
+       int *bufix;
+       unsigned char **bufp;
+       int *bufcount;
+       unsigned char *data;
+       int len;
+{
+       int space = *bufcount - *bufix;
+
+       /* If there's more space than we need, use only what we need. */
+       if (space > len)
+               space = len;
+
+       /* Copy as much data as will fit, then increment the buffer index
+          by the amount we actually had to copy, which could be more. */
+       if (space > 0)
+               memcpy (*bufp + *bufix, data, space);
+       *bufix += len;
+}
diff --git a/reactos/subsys/system/dhcp/util.c b/reactos/subsys/system/dhcp/util.c
new file mode 100644 (file)
index 0000000..22d3948
--- /dev/null
@@ -0,0 +1,106 @@
+#include <stdarg.h>
+#include "rosdhcp.h"
+
+char *piaddr( struct iaddr addr ) {
+    struct sockaddr_in *sa = (struct sockaddr_in *)addr.iabuf;
+    return inet_ntoa( sa->sin_addr );
+}
+
+int note( char *format, ... ) {
+    va_list arg_begin;
+    va_start( arg_begin, format );
+    char buf[0x100];
+    int ret;
+
+    ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
+    
+    DbgPrint("NOTE: %s\n", buf);
+
+    return ret;
+}
+
+int debug( char *format, ... ) {
+    va_list arg_begin;
+    va_start( arg_begin, format );
+    char buf[0x100];
+    int ret;
+
+    ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
+    
+    DbgPrint("DEBUG: %s\n", buf);
+
+    return ret;
+}    
+
+int warn( char *format, ... ) {
+    va_list arg_begin;
+    va_start( arg_begin, format );
+    char buf[0x100];
+    int ret;
+
+    ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
+    
+    DbgPrint("WARN: %s\n", buf);
+
+    return ret;
+}    
+
+int warning( char *format, ... ) {
+    va_list arg_begin;
+    va_start( arg_begin, format );
+    char buf[0x100];
+    int ret;
+
+    ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
+    
+    DbgPrint("WARNING: %s\n", buf);
+
+    return ret;
+}
+
+void error( char *format, ... ) {
+    va_list arg_begin;
+    va_start( arg_begin, format );
+    char buf[0x100];
+
+    vsnprintf( buf, sizeof(buf), format, arg_begin );
+    
+    DbgPrint("ERROR: %s\n", buf);
+}    
+
+int16_t getShort( unsigned char *data ) {
+    return 0;
+}
+
+u_int16_t getUShort( unsigned char *data ) {
+    return 0;
+}
+
+int32_t getLong( unsigned char *data ) {
+    return 0;
+}
+
+u_int32_t getULong( unsigned char *data ) {
+    return 0;
+}
+
+int addr_eq( struct iaddr a, struct iaddr b ) {
+    return a.len == b.len && !memcmp( a.iabuf, b.iabuf, a.len );
+}
+
+void *dmalloc( int size, char *name ) { return malloc( size ); }
+void dfree( void *v, char *name ) { free( v ); }
+
+int read_client_conf(void) {
+    return 0;
+}
+
+struct iaddr broadcast_addr( struct iaddr addr, struct iaddr mask ) {
+    struct iaddr bcast = { 0 };
+    return bcast;
+}
+
+struct iaddr subnet_number( struct iaddr addr, struct iaddr mask ) {
+    struct iaddr bcast = { 0 };
+    return bcast;
+}
index 7f4de0d..643c9ad 100644 (file)
@@ -24,7 +24,8 @@ exe explorer :
        shell/regfs.cpp
        shell/fatfs.cpp
        shell/webchild.cpp
-       shell/startup.c
+       services/startup.c
+       services/shellservices.cpp
        taskbar/desktopbar.cpp
        taskbar/quicklaunch.cpp
        taskbar/startmenu.cpp
index 27f6852..e8ccaca 100644 (file)
@@ -17,7 +17,7 @@ TARGET_INSTALLDIR := .
 TARGET_CFLAGS := \
        -D__USE_W32API -DWIN32 -D_ROS_ \
        -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -DWINVER=0x0500 \
-       -DUNICODE -fexceptions -Wall \
+       -DUNICODE -fexceptions -Wall -g \
        -I../../../include/expat
 
 TARGET_CPPFLAGS := $(TARGET_CFLAGS)
@@ -25,7 +25,7 @@ TARGET_CPPFLAGS := $(TARGET_CFLAGS)
 TARGET_RCFLAGS := -D__USE_W32API -DWIN32 -D_ROS_ -D__WINDRES__
 
 TARGET_SDKLIBS := \
-       gdi32.a comctl32.a ole32.a oleaut32.a shell32.a expat.a \
+       gdi32.a user32.a comctl32.a ole32.a oleaut32.a shell32.a expat.a \
        notifyhook.a ws2_32.a msimg32.a
 
 TARGET_GCCLIBS := stdc++ uuid
@@ -45,10 +45,11 @@ TARGET_OBJECTS := \
        shell/pane.o \
        shell/regfs.o \
        shell/shellbrowser.o \
-       shell/startup.o \
        shell/unixfs.o \
        shell/webchild.o \
        shell/winfs.o \
+       services/startup.o \
+       services/shellservices.o \
        taskbar/desktopbar.o \
        taskbar/taskbar.o \
        taskbar/startmenu.o \
index 569efe1..a75dc2d 100644 (file)
@@ -38,7 +38,7 @@ CXXFLAGS = $(CFLAGS)
 EXEC_SUFFIX = .exe
 RES_SUFFIX = .coff
 
-VPATH = shell utility taskbar desktop dialogs
+VPATH = shell utility taskbar desktop dialogs services
 
 PROGRAM = explorer
 
@@ -51,6 +51,7 @@ OBJECTS = \
        window.o \
        dragdropimpl.o \
        shellbrowserimpl.o \
+       shellservices.o \
        explorer.o \
        entries.o \
        winfs.o \
index 35c1a6d..496831b 100644 (file)
@@ -39,7 +39,7 @@ CXXFLAGS = $(CFLAGS)
 EXEC_SUFFIX = .exe
 RES_SUFFIX = .coff
 
-VPATH = shell utility taskbar desktop dialogs
+VPATH = shell utility taskbar desktop dialogs services
 
 PROGRAM = explorer
 
@@ -69,6 +69,7 @@ OBJECTS = \
        desktopbar.o \
        taskbar.o \
        startmenu.o \
+       shellservices.o \
        traynotify.o \
        quicklaunch.o \
        favorites.o \
index 39d0deb..70e36d0 100644 (file)
@@ -10,7 +10,7 @@ EXTRA_OBJS = notifyhook.dll libexpat.dll
 EXTRALIBS = $(LIBUUID)
 
 C_SRCS = \
-       shell/startup.c \
+       services/startup.c \
        utility/splitpath.c
 
 CPP_SRCS = \
@@ -34,6 +34,7 @@ CPP_SRCS = \
        shell/regfs.cpp \
        shell/fatfs.cpp \
        shell/webchild.cpp \
+       services/shellservices.cpp \
        taskbar/desktopbar.cpp \
        taskbar/taskbar.cpp \
        taskbar/startmenu.cpp \
diff --git a/reactos/subsys/system/explorer/bak/shellhook.cpp b/reactos/subsys/system/explorer/bak/shellhook.cpp
deleted file mode 100644 (file)
index 750ea7f..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright 2003 Martin Fuchs
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
- //
- // Explorer clone
- //
- // shellhook.cpp
- //
- // Martin Fuchs, 17.08.2003
- //
-
-
-#include "../utility/utility.h"
-
-#include "shellhook.h"
-
-
-static HINSTANCE s_hInstance;
-
-struct SharedMem {
-       HWND    _callback_hwnd;
-       UINT    _callback_msg;
-       HHOOK   _hshellHook;
-};
-
-static HANDLE s_hMapObject;
-static SharedMem* s_pSharedMem;
-
-
-BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID)
-{
-       switch(dwReason) {
-         case DLL_PROCESS_ATTACH: {
-               s_hInstance = hInst;
-               DisableThreadLibraryCalls(hInst);
-               s_hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
-                                                                                               0, sizeof(SharedMem), _T("ROSExplorerShellHookSharedMem"));
-               if (!s_hMapObject)
-                       return FALSE;
-
-                // The first process to attach initializes memory.
-               BOOL bInit = GetLastError()!=ERROR_ALREADY_EXISTS;
-
-                // Get a pointer to the file-mapped shared memory.
-               s_pSharedMem = (SharedMem*) MapViewOfFile(s_hMapObject, FILE_MAP_WRITE, 0, 0, 0);
-               if (!s_pSharedMem)
-                       return FALSE;
-
-                // Initialize memory if this is the first process.
-               if (bInit)
-                       memset(s_pSharedMem, 0, sizeof(SharedMem));
-               break;}
-
-         case DLL_PROCESS_DETACH:
-               UnmapViewOfFile(s_pSharedMem);
-               s_pSharedMem = NULL;
-               CloseHandle(s_hMapObject);
-               break;
-       }
-
-    return TRUE;
-}
-
-
-static void DoCallBack(int code, WPARAM wparam, LPARAM lparam)
-{
-       UINT callback_msg = s_pSharedMem->_callback_msg;
-       HWND callback_hwnd = s_pSharedMem->_callback_hwnd;
-
-       if (callback_msg)
-               PostMessage(callback_hwnd, callback_msg, wparam, code); // lparam unused
-}
-
-
-LRESULT CALLBACK ShellHookProc(int code, WPARAM wparam, LPARAM lparam)
-{
-       DoCallBack(code, wparam, lparam);
-
-       return CallNextHookEx(s_pSharedMem->_hshellHook, code, wparam, lparam);
-}
-
-
-void InstallShellHook(HWND callback_hwnd, UINT callback_msg)
-{
-       s_pSharedMem->_callback_hwnd = callback_hwnd;
-       s_pSharedMem->_callback_msg = callback_msg;
-
-       s_pSharedMem->_hshellHook = SetWindowsHookEx(WH_SHELL, ShellHookProc, s_hInstance, 0);
-}
-
-void DeinstallShellHook()
-{
-       s_pSharedMem->_callback_hwnd = 0;
-       s_pSharedMem->_callback_msg = 0;
-
-       UnhookWindowsHookEx(s_pSharedMem->_hshellHook);
-       s_pSharedMem->_hshellHook = 0;
-}
diff --git a/reactos/subsys/system/explorer/bak/shellhook.dsp b/reactos/subsys/system/explorer/bak/shellhook.dsp
deleted file mode 100644 (file)
index e19daca..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# Microsoft Developer Studio Project File - Name="shellhook" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=shellhook - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "shellhook.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "shellhook.mak" CFG="shellhook - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "shellhook - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "shellhook - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.cmd
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "shellhook - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "shellhook___Win32_Release"
-# PROP BASE Intermediate_Dir "shellhook___Win32_Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /D "_SHELLHOOK_IMPL" /FD /c
-# SUBTRACT CPP /YX
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.cmd
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 /nologo /subsystem:windows /dll /machine:I386
-
-!ELSEIF  "$(CFG)" == "shellhook - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "shellhook___Win32_Debug"
-# PROP BASE Intermediate_Dir "shellhook___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /D "_SHELLHOOK_IMPL" /FR /FD /GZ /c
-# SUBTRACT CPP /YX
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.cmd
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "shellhook - Win32 Release"
-# Name "shellhook - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\taskbar\shellhook.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\utility\utility.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\utility\window.h
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\taskbar\shellhook.cpp
-# End Source File
-# End Target
-# End Project
index 41b08b2..2c0cbad 100644 (file)
@@ -155,8 +155,8 @@ static BOOL CALLBACK SwitchDesktopEnumFct(HWND hwnd, LPARAM lparam)
 {
        WindowSet& windows = *(WindowSet*)lparam;
 
-       if (IsWindowVisible(hwnd))
-               if (hwnd!=g_Globals._hwndDesktopBar && hwnd!=g_Globals._hwndDesktop)
+       if (hwnd!=g_Globals._hwndDesktopBar && hwnd!=g_Globals._hwndDesktop)
+               if (IsWindowVisible(hwnd))
                        windows.insert(hwnd);
 
        return TRUE;
@@ -212,12 +212,17 @@ static BOOL CALLBACK MinimizeDesktopEnumFct(HWND hwnd, LPARAM lparam)
 {
        list<MinimizeStruct>& minimized = *(list<MinimizeStruct>*)lparam;
 
-       if (IsWindowVisible(hwnd))
-               if (hwnd!=g_Globals._hwndDesktopBar && hwnd!=g_Globals._hwndDesktop)
-                       if (!IsIconic(hwnd)) {
+       if (hwnd!=g_Globals._hwndDesktopBar && hwnd!=g_Globals._hwndDesktop)
+               if (IsWindowVisible(hwnd) && !IsIconic(hwnd)) {
+                       RECT rect;
+
+                       if (GetWindowRect(hwnd,&rect))
+                               if (rect.right>0 && rect.bottom>0 &&
+                                       rect.right>rect.left && rect.bottom>rect.top) {
                                minimized.push_back(MinimizeStruct(hwnd, GetWindowStyle(hwnd)));
                                ShowWindowAsync(hwnd, SW_MINIMIZE);
                        }
+               }
 
        return TRUE;
 }
@@ -436,7 +441,7 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
          case WM_DESTROY:
 
                ///@todo use IShellBrowser::GetViewStateStream() and _pShellView->SaveViewState() to store view state
-               
+
                if (SetShellWindow)
                        SetShellWindow(0);
                break;
@@ -526,7 +531,7 @@ LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
        switch(nmsg) {
          case WM_CONTEXTMENU:
-               if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), _cm_ifs))
+               if (!DoContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)))
                        DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
                break;
 
@@ -558,7 +563,7 @@ int DesktopShellView::Notify(int id, NMHDR* pnmh)
        return super::Notify(id, pnmh);
 }
 
-bool DesktopShellView::DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs)
+bool DesktopShellView::DoContextMenu(int x, int y)
 {
        IDataObject* selection;
 
@@ -588,7 +593,7 @@ bool DesktopShellView::DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs)
        for(int i=pida->cidl; i>0; --i)
                apidl[i-1] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i]);
 
-       hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y, cm_ifs);
+       hr = ShellFolderContextMenu(ShellFolder(parent_pidl), _hwnd, pida->cidl, apidl, x, y, _cm_ifs);
 
        selection->Release();
 
@@ -612,7 +617,6 @@ HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
                        hr = pcm->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST-1, CMF_NORMAL|CMF_EXPLORE);
 
                        if (SUCCEEDED(hr)) {
-                               AppendMenu(hmenu, 0, FCIDM_SHVIEWLAST-3, ResString(IDS_PROPERTIES_EXPLORER));
                                AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
                                AppendMenu(hmenu, 0, FCIDM_SHVIEWLAST-1, ResString(IDS_ABOUT_EXPLORER));
 
@@ -620,24 +624,6 @@ HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
 
                                _cm_ifs.reset();
 
-                               if (idCmd == FCIDM_SHVIEWLAST-3) {
-                                       ShellExecute (_hwnd, _T("open"), _T("c:\\reactos\\system32\\rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0"), NULL, NULL, SW_SHOWNORMAL);
-
-
-                                       //explorer_about(_hwnd);
-                                       //system("c:\\reactos\\system32\\cmd.exe");
-                                       
-                                       //ShellExecute (_hwnd, _T("open"), _T("%SystemRoot%\\system32\\cmd.exe"), NULL, NULL, SW_SHOWNORMAL);
-                                       
-                                         //ShellExecute(NULL,"open","c:\\windows\\system32\\cmd.exe",NULL,NULL,SW_SHOWNORMAL);
-                                       //WCHAR* pFile="%SystemRoot%\system32\cmd.exe";
-                                       //int rcode;
-                                        //TCHAR pFile[256];
-                                        //strcopy("%SystemRoot%\\system32\\cmd.exe",pFile);
-                                        //ShellExecute(NULL, NULL, pFile, NULL, "C:\\", SW_SHOW);
-                                       //HINSTANCE rcode=ShellExecute(NULL, "open", pFile, NULL, "C:\\", SW_SHOW);
-                                       //ShellExecute(hwnd, __TEXT("open"), __TEXT("%SystemRoot%\system32\cmd.exe"), __TEXT("c:\"), SH_SHOW); 
-                               }
                                if (idCmd == FCIDM_SHVIEWLAST-1) {
                                        explorer_about(_hwnd);
                                } else if (idCmd) {
index 751ffe4..00e9dca 100644 (file)
@@ -180,7 +180,7 @@ protected:
        int             Command(int id, int code);
        int             Notify(int id, NMHDR* pnmh);
 
-       bool    DoContextMenu(int x, int y, CtxMenuInterfaces& cm_ifs);
+       bool    DoContextMenu(int x, int y);
        HRESULT DoDesktopContextMenu(int x, int y);
        void    PositionIcons(int dir=1);
 
index 5db205a..f9ad962 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -42,10 +42,11 @@ int CollectProgramsThread::Run()
        } catch(COMException&) {
        }
 
-       try {
-               collect_programs(SpecialFolderPath(CSIDL_PROGRAMS, _hwnd));
-       } catch(COMException&) {
-       }
+       if (_alive)
+               try {
+                       collect_programs(SpecialFolderPath(CSIDL_PROGRAMS, _hwnd));
+               } catch(COMException&) {
+               }
 
        if (_alive)
                _cache_valid = true;
@@ -60,16 +61,13 @@ void CollectProgramsThread::collect_programs(const ShellPath& path)
 
        dir->smart_scan(SORT_NONE, /*SCAN_EXTRACT_ICONS|*/SCAN_FILESYSTEM);
 
-       for(Entry*entry=dir->_down; entry; entry=entry->_next) {
-               if (!_alive)
-                       break;
-
+       for(Entry*entry=dir->_down; _alive && entry; entry=entry->_next) {
                if (entry->_shell_attribs & SFGAO_HIDDEN)
                        continue;
 
-               if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+               if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                        collect_programs(entry->create_absolute_pidl());
-               else if (entry->_shell_attribs & SFGAO_LINK)
+               else if (entry->_shell_attribs & SFGAO_LINK)
                        if (_alive)
                                _callback(entry, _para);
        }
@@ -95,7 +93,7 @@ FindProgramDlg::FindProgramDlg(HWND hwnd)
        _thread(collect_programs_callback, hwnd, this),
        _sort(_list_ctrl, CompareFunc/*, (LPARAM)this*/)
 {
-       SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/);
+       SetWindowIcon(hwnd, IDI_SEARCH);
 
        _resize_mgr.Add(IDC_FILTER,                     RESIZE_X);
        _resize_mgr.Add(IDC_CHECK_ENTRIES,      MOVE_X);
@@ -139,6 +137,8 @@ FindProgramDlg::FindProgramDlg(HWND hwnd)
 
 FindProgramDlg::~FindProgramDlg()
 {
+       _thread.Stop();
+
        unregister_pretranslate(_hwnd);
 }
 
@@ -262,6 +262,10 @@ void FindProgramDlg::add_entry(const FPDEntry& cache_entry)
 LRESULT FindProgramDlg::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
        switch(nmsg) {
+         case WM_CLOSE:
+               ListView_SetImageList(_list_ctrl, 0, LVSIL_SMALL);      // detach system image list
+               goto def;
+
          case PM_TRANSLATE_MSG: {
                MSG* pmsg = (MSG*) lparam;
 
@@ -270,7 +274,7 @@ LRESULT FindProgramDlg::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 
                return FALSE;}
 
-         default:
+         default: def:
                return super::WndProc(nmsg, wparam, lparam);
        }
 
index 06d29af..572ce5c 100644 (file)
@@ -28,3 +28,9 @@
 
 - Search Programs -> performance monitor.msv -> Abort
 
+
+<Nonvo> Martin, I would have a whish concerning explorer: I often want to start a program and give it some parameters. So nice featue: "Start with param..."
+<tinus_> Nonvo: shell extension
+<m-fuchs> tinus: we should think about installing some default shell extensions
+<tinus_> m-fuchs: perhaps, but it'd be nice if they actually were shell extensions
+
index 90e91ef..e2e0b94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 #include "dialogs/settings.h"  // for MdiSdiDlg
 
+#include "services/shellservices.h"
+
 
 extern "C" int initialize_gdb_stub();  // start up GDB stub
 
 
+DynamicLoadLibFct<void(__stdcall*)(BOOL)> g_SHDOCVW_ShellDDEInit(TEXT("SHDOCVW"), 118);
+
+
 ExplorerGlobals g_Globals;
 
 
@@ -382,7 +387,7 @@ const Icon& IconCache::extract(const String& path)
 
        SHFILEINFO sfi;
 
-#if 1  // use system image list
+#if 1  // use system image list - the "search program dialog" needs it
        HIMAGELIST himlSys = (HIMAGELIST) SHGetFileInfo(path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
 
        if (himlSys) {
@@ -705,6 +710,19 @@ int main(int argc, char* argv[])
 #endif // __MINGW && UNICODE
 
 
+static bool SetShellReadyEvent(LPCTSTR evtName)
+{
+       HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, evtName);
+       if (!hEvent)
+               return false;
+
+       SetEvent(hEvent);
+       CloseHandle(hEvent);
+
+       return true;
+}
+
+
 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
 {
        CONTEXT("WinMain()");
@@ -729,6 +747,14 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
                                RegSetValueEx(hkey, TEXT("Shell"), 0, REG_SZ, (LPBYTE)path, l*sizeof(TCHAR));
                                RegCloseKey(hkey);
                        }
+
+                       if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hkey)) {
+
+                               ///@todo save previous shell application in config file
+
+                               RegSetValueEx(hkey, TEXT("Shell"), 0, REG_SZ, (LPBYTE)TEXT(""), l*sizeof(TCHAR));
+                               RegCloseKey(hkey);
+                       }
                }
 
                HWND shellWindow = GetShellWindow();
@@ -750,10 +776,14 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
                }
 
                startup_desktop = TRUE;
-       } else
+       } else {
                 // create desktop window and task bar only, if there is no other shell and we are
                 // the first explorer instance
+                // MS Explorer looks additionally into the registry entry HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\shell,
+                // to decide wether it is currently configured as shell application.
                startup_desktop = !any_desktop_running;
+       }
+
 
        bool autostart = !any_desktop_running;
 
@@ -795,6 +825,21 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
        }
 #endif
 
+
+       if (startup_desktop) {
+                // hide the XP login screen (Credit to Nicolas Escuder)
+                // another undocumented event: "Global\\msgina: ReturnToWelcome"
+               if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
+                       SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
+       }
+
+       if (!any_desktop_running) {
+                // launch the shell DDE server
+               if (g_SHDOCVW_ShellDDEInit)
+                       (*g_SHDOCVW_ShellDDEInit)(TRUE);
+       }
+
+
        bool use_gdb_stub = false;      // !IsDebuggerPresent();
 
        if (_tcsstr(lpCmdLine,TEXT("-debug")))
@@ -827,17 +872,31 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
        g_Globals.read_persistent();
 
        if (startup_desktop) {
+               WaitCursor wait;
+
                g_Globals._desktops.init();
 
                g_Globals._hwndDesktop = DesktopWindow::Create();
 #ifdef _USE_HDESK
                g_Globals._desktops.get_current_Desktop()->_hwndDesktop = g_Globals._hwndDesktop;
 #endif
+       }
 
-               if (autostart) {
-                       char* argv[] = {"", "s"};       // call startup routine in SESSION_START mode
-                       startup(2, argv);
-               }
+       if (g_Globals._hwndDesktop)
+               g_Globals._desktop_mode = true;
+
+       Thread* pSSOThread = NULL;
+
+       if (startup_desktop) {
+                // launch SSO thread to allow message processing independent from the explorer main thread
+               pSSOThread = new SSOThread;
+               pSSOThread->Start();
+       }
+
+       /**TODO launching autostart programs can be moved into a background thread. */
+       if (autostart) {
+               char* argv[] = {"", "s"};       // call startup routine in SESSION_START mode
+               startup(2, argv);
        }
 
        /**TODO fix command line handling */
@@ -846,13 +905,21 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
                lpCmdLine[_tcslen(lpCmdLine)-1] = '\0';
        }
 
-       if (g_Globals._hwndDesktop)
-               g_Globals._desktop_mode = true;
-
        int ret = explorer_main(hInstance, lpCmdLine, nShowCmd);
 
         // write configuration file
        g_Globals.write_persistent();
 
+       if (pSSOThread) {
+               pSSOThread->Stop();
+               delete pSSOThread;
+       }
+
+       if (!any_desktop_running) {
+                // shutdown the shell DDE server
+               if (g_SHDOCVW_ShellDDEInit)
+                       (*g_SHDOCVW_ShellDDEInit)(FALSE);
+       }
+
        return ret;
 }
index eb97632..8035c7f 100644 (file)
@@ -702,11 +702,6 @@ SOURCE=.\shell\shellfs.h
 # End Source File\r
 # Begin Source File\r
 \r
-SOURCE=.\shell\startup.c\r
-# SUBTRACT CPP /YX /Yc /Yu\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\shell\unixfs.cpp\r
 # PROP Exclude_From_Build 1\r
 # End Source File\r
@@ -785,5 +780,22 @@ SOURCE=.\precomp.cpp
 SOURCE=.\precomp.h\r
 # End Source File\r
 # End Group\r
+# Begin Group "services"\r
+\r
+# PROP Default_Filter ""\r
+# Begin Source File\r
+\r
+SOURCE=.\services\shellservices.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\services\shellservices.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\services\startup.c\r
+# SUBTRACT CPP /YX /Yc /Yu\r
+# End Source File\r
+# End Group\r
 # End Target\r
 # End Project\r
index 525be8a..3a4d3a8 100644 (file)
@@ -1,4 +1,6 @@
 <module name="explorer" type="win32gui" installbase="system32" installname="explorer.exe">\r
+       <linkerflag>-luuid</linkerflag>\r
+       <linkerflag>-lstdc++</linkerflag>\r
        <linkerflag>-fexceptions</linkerflag>\r
        <include base="explorer">.</include>\r
        <include base="ReactOS">include/expat</include>\r
@@ -10,9 +12,9 @@
        <define name="_WIN32_WINNT">0x0501</define>\r
        <define name="WINVER">0x0500</define>\r
        <define name="__WINDRES__" />\r
-       <library>uuid</library>\r
        <library>kernel32</library>\r
        <library>gdi32</library>\r
+       <library>user32</library>\r
        <library>ws2_32</library>\r
        <library>msimg32</library>\r
        <library>comctl32</library>\r
                <file>pane.cpp</file>\r
                <file>regfs.cpp</file>\r
                <file>shellbrowser.cpp</file>\r
-               <file>startup.c</file>\r
                <file>unixfs.cpp</file>\r
                <file>webchild.cpp</file>\r
                <file>winfs.cpp</file>\r
        </directory>\r
+       <directory name="services">\r
+               <file>shellservices.cpp</file>\r
+               <file>startup.c</file>\r
+       </directory>\r
        <directory name="taskbar">\r
                <file>desktopbar.cpp</file>\r
                <file>favorites.cpp</file>\r
index 94f13f4..4bb9e8f 100644 (file)
@@ -46,7 +46,7 @@
 #define IDS_NOTIFY_AUTOHIDE             42
 #define IDS_SHOW_HIDDEN_ICONS           43
 #define IDS_HIDE_ICONS                  44
-#define IDS_PROPERTIES_EXPLORER         45
+#define IDS_TERMINATE                   45
 #define IDI_REACTOS                     100
 #define IDI_EXPLORER                    101
 #define IDI_STARTMENU                   102
index cd25356..e52dea5 100644 (file)
@@ -126,6 +126,7 @@ BEGIN
     IDS_TITLE               "ReactOS Explorer"
     IDS_START               "Începe"
     IDS_LOGOFF              "Închide sesiunea ..."
+    IDS_TERMINATE           "Închide sesiunea"
     IDS_SHUTDOWN            "Oprire calculator ..."
     IDS_LAUNCH              "Pornire ..."
     IDS_START_HELP          "Ajutor"
@@ -583,6 +584,7 @@ BEGIN
     IDS_TITLE               "Reactos Explorer"
     IDS_START               "Start"
     IDS_LOGOFF              "Abmelden..."
+    IDS_TERMINATE           "ROS Explorer beenden"
     IDS_SHUTDOWN            "Herunterfahren..."
     IDS_LAUNCH              "Starten..."
     IDS_START_HELP          "Hilfe"
@@ -736,7 +738,7 @@ BEGIN
     BEGIN
         MENUITEM "&Next Level\t+",              301
         MENUITEM "Expand &Tree\t*",             302
-        MENUITEM "Expand &all\tStrg+*",         303
+        MENUITEM "Expand &all\tCtrl+*",         303
         MENUITEM "Collapse &Tree\t-",           304
         MENUITEM SEPARATOR
         MENUITEM "&Mark Childs",                505
@@ -1075,6 +1077,7 @@ BEGIN
     IDS_TITLE               "Reactos Explorer"
     IDS_START               "Start"
     IDS_LOGOFF              "Log Off..."
+    IDS_TERMINATE           "Terminate ROS Explorer"
     IDS_SHUTDOWN            "Turn Off..."
     IDS_LAUNCH              "Run..."
     IDS_START_HELP          "Help"
@@ -1103,7 +1106,6 @@ BEGIN
     IDS_ALL_USERS           "All Users\\"
     IDS_SEARCH              "Search"
     IDS_ABOUT_EXPLORER      "&About Explorer..."
-    IDS_PROPERTIES_EXPLORER "&Properties"
     IDS_LAUNCH_MANY_PROGRAMS 
                             "You have selected more than one program.\nAre you sure you want to launch all of them?"
     IDS_DESKTOPBAR_SETTINGS "Desktop Settings"
@@ -1539,6 +1541,7 @@ BEGIN
     IDS_TITLE               "Reactos Explorer"
     IDS_START               "Iniciar"
     IDS_LOGOFF              "Salir..."
+    IDS_TERMINATE           "Salir"
     IDS_SHUTDOWN            "Apagar..."
     IDS_LAUNCH              "Ejecutar..."
     IDS_START_HELP          "Ayuda"
@@ -1709,6 +1712,7 @@ BEGIN
     IDS_TITLE               "Explorateur Reactos"
     IDS_START               "Démarrer"
     IDS_LOGOFF              "Déconnexion ..."
+    IDS_TERMINATE           "Déconnexion"
     IDS_SHUTDOWN            "Arrêter..."
     IDS_LAUNCH              "Exécuter..."
     IDS_START_HELP          "Aide"
@@ -1922,6 +1926,7 @@ BEGIN
     IDS_TITLE               "Explorador do Reactos"
     IDS_START               "Iniciar"
     IDS_LOGOFF              "Terminar sessão..."
+    IDS_TERMINATE           "Terminar ROS Explorador"
     IDS_SHUTDOWN            "Desligar..."
     IDS_LAUNCH              "Executar..."
     IDS_START_HELP          "Ajuda"
@@ -1977,6 +1982,497 @@ END
 #endif    // Portuguese (Portugal) resources
 /////////////////////////////////////////////////////////////////////////////
 
+/////////////////////////////////////////////////////////////////////////////
+// Swedish (SE) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SWE)
+#ifdef _WIN32
+LANGUAGE LANG_SWEDISH, SUBLANG_SWEDISH
+#pragma code_page(850)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDM_MDIFRAME MENU PRELOAD DISCARDABLE 
+BEGIN
+    POPUP "&Arkiv"
+    BEGIN
+        MENUITEM "&Avsluta",                       ID_FILE_EXIT
+    END
+    POPUP "&Visa"
+    BEGIN
+        MENUITEM "&Verktygsfält",                    ID_VIEW_TOOL_BAR
+        MENUITEM "&Extrafält",                  ID_VIEW_EXTRA_BAR
+        MENUITEM "E&nhetsfält",                   ID_VIEW_DRIVE_BAR, CHECKED
+        MENUITEM "S&idfält",                   ID_VIEW_SIDE_BAR
+        MENUITEM "&Statusfält",                 ID_VIEW_STATUSBAR
+        MENUITEM SEPARATOR
+        MENUITEM "&Uppdatera\tF5",                ID_REFRESH
+        MENUITEM "F&ullskärm\tCtrl+Shift+S",  ID_VIEW_FULLSCREEN
+        MENUITEM "SDI",                         ID_VIEW_SDI
+    END
+    POPUP "&Fönster"
+    BEGIN
+        MENUITEM "Nytt &fönster",                 ID_WINDOW_NEW
+        MENUITEM "Överlappande\tShift+F5",         ID_WINDOW_CASCADE
+        MENUITEM "Ordna &horizontellt",          ID_WINDOW_TILE_HORZ
+        MENUITEM "Ordna &vertikalt\tShift+F4",  ID_WINDOW_TILE_VERT
+        MENUITEM "Ordna automatiskt",       ID_WINDOW_AUTOSORT
+        MENUITEM "Ordna &symboler",            ID_WINDOW_ARRANGE
+    END
+    POPUP "&Verktyg"
+    BEGIN
+        MENUITEM "&Alternativ",                    ID_TOOLS_OPTIONS
+    END
+    POPUP "&Hjälp"
+    BEGIN
+        MENUITEM "Explorer &FAQ...",            ID_EXPLORER_FAQ
+        MENUITEM "&Om Explorer...",          ID_ABOUT_EXPLORER
+        MENUITEM "Om &OS...",                ID_ABOUT_WINDOWS
+    END
+END
+
+IDM_WINEFILE MENU FIXED IMPURE 
+BEGIN
+    POPUP "&Arkiv"
+    BEGIN
+        MENUITEM "&Öppna\tEnter",                101
+        MENUITEM "&Flytta...\tF7",                106
+        MENUITEM "&Kopiera...\tF8",                107
+        MENUITEM "&I urklipp...\tF9",        118
+        MENUITEM "&Ta bort\tDel",                108
+        MENUITEM "&Byt namn...",                  109
+        MENUITEM "&Egenskaper...\tAlt+Enter",   ID_EDIT_PROPERTIES
+        MENUITEM SEPARATOR
+        MENUITEM "&Komprimera...",                119
+        MENUITEM "Packa &upp...",              120
+        MENUITEM SEPARATOR
+        MENUITEM "&Kör...",                     ID_EXECUTE
+        MENUITEM "&Skriv ut...",                   102
+        MENUITEM "Associera...",                103
+        MENUITEM SEPARATOR
+        MENUITEM "Skapa mapp...",        ID_EXECUTE
+        MENUITEM "&Sök...",                  104
+        MENUITEM "&Välj filer...",            116
+        MENUITEM SEPARATOR
+        MENUITEM "&Avsluta\tAlt+X",                ID_FILE_EXIT
+    END
+    POPUP "&Disk"
+    BEGIN
+        MENUITEM "&Kopiera disk...",               201
+        MENUITEM "&Namnge disk...",              202
+        MENUITEM SEPARATOR
+        MENUITEM "&Formatera disk...",             203
+        MENUITEM SEPARATOR
+        MENUITEM "Anslut &Nätverksenhet",      252
+        MENUITEM "&Koppla ifrån Nätverksenhet",   253
+        MENUITEM SEPARATOR
+        MENUITEM "Dela ut...",                 254
+        MENUITEM "&Ta bort utdelning...",            255
+        MENUITEM SEPARATOR
+        MENUITEM "&Välj enhet...",            251
+    END
+    POPUP "&Mappar"
+    BEGIN
+        MENUITEM "&Nästa nivå\t+",              301
+        MENUITEM "Utöka &träd\t*",             302
+        MENUITEM "Utöka &alla\tCtrl+*",         303
+        MENUITEM "Kollapsa &träd\t-",           304
+        MENUITEM SEPARATOR
+        MENUITEM "&Markera undermappar",                505
+    END
+    POPUP "&Visa"
+    BEGIN
+        MENUITEM "&Träd och mapp",         413
+        MENUITEM "Bara tr&äd",                  411
+        MENUITEM "Bara &mapp",             412
+        MENUITEM SEPARATOR
+        MENUITEM "De&la",                      414
+        MENUITEM SEPARATOR
+        MENUITEM "&Namn",                       ID_VIEW_NAME
+        MENUITEM "&Alla Fildetaljer",           ID_VIEW_ALL_ATTRIBUTES
+        , CHECKED
+        MENUITEM "&Vissa detaljer...",         ID_VIEW_SELECTED_ATTRIBUTES
+        MENUITEM SEPARATOR
+        MENUITEM "&Sortera efter namn",               404
+        MENUITEM "Sortera efter t&yp",               405
+        MENUITEM "Sortera efter st&orlek",               406
+        MENUITEM "Sortera efter &datum",               407
+        MENUITEM SEPARATOR
+        MENUITEM "Sortera efter &...",                409
+    END
+    POPUP "&Inställningar"
+    BEGIN
+        MENUITEM "&Bekräftelse...",            65535
+        MENUITEM "&Teckensnitt...",                    65535
+        MENUITEM "&Konfigurera verktygsfält...",       65535
+        MENUITEM SEPARATOR
+        MENUITEM "&Verktygsfält",                    ID_VIEW_TOOL_BAR, CHECKED
+        MENUITEM "&Enhetsfält",                   ID_VIEW_DRIVE_BAR, CHECKED
+        MENUITEM "&Sidfält",                   ID_VIEW_SIDE_BAR
+        MENUITEM "St&atusfält",                 ID_VIEW_STATUSBAR, CHECKED
+        MENUITEM "F&ullskärm\tCtrl+Shift+S",  ID_VIEW_FULLSCREEN
+        MENUITEM SEPARATOR
+        MENUITEM "&Symbol efter körning",  65535
+        MENUITEM "&Spara ändringar vid stängning", 511
+    END
+    POPUP "&Säkerhet"
+    BEGIN
+        MENUITEM "&Åtkomst...",                  605
+        MENUITEM "&Loggning...",                 606
+        MENUITEM "&Ägare...",                   607
+    END
+    POPUP "&Fönster"
+    BEGIN
+        MENUITEM "Nytt &fönster",                 ID_WINDOW_NEW
+        MENUITEM "Överlappande\tCtrl+F5",          ID_WINDOW_CASCADE
+        MENUITEM "Ordna &horizontellt",          ID_WINDOW_TILE_HORZ
+        MENUITEM "Ordna &vertikalt\tCtrl+F4",   ID_WINDOW_TILE_VERT
+        MENUITEM "Ordna automatiskt",       ID_WINDOW_AUTOSORT
+        MENUITEM "Ordna &symboler",            ID_WINDOW_ARRANGE
+        MENUITEM "&Uppdatera\tF5",                ID_REFRESH
+    END
+    POPUP "&?"
+    BEGIN
+        MENUITEM "&Hjälpavsnitt\tF1",            ID_HELP
+        MENUITEM "Hjälp &sök...\tF1",         ID_HELP
+        MENUITEM "&Använda hjälpen\tF1",             ID_HELP_USING
+        MENUITEM SEPARATOR
+        MENUITEM "Information om &Winefile...",     ID_ABOUT_WINEFILE
+    END
+END
+
+IDM_DESKTOPBAR MENU DISCARDABLE 
+BEGIN
+    POPUP ""
+    BEGIN
+        MENUITEM "&Inställningar...",                ID_DESKTOPBAR_SETTINGS
+        MENUITEM "&Aktivitetshanteraren...",            ID_TASKMGR
+        MENUITEM SEPARATOR
+        MENUITEM "&Om Explorer...",          ID_ABOUT_EXPLORER
+    END
+END
+
+IDM_VOLUME MENU DISCARDABLE 
+BEGIN
+    POPUP ""
+    BEGIN
+        MENUITEM "Öppna volymkontroll",         ID_TRAY_VOLUME
+        MENUITEM "Justera ljudinställningar",     ID_VOLUME_PROPERTIES
+    END
+END
+
+IDM_NOTIFYAREA MENU DISCARDABLE 
+BEGIN
+    POPUP ""
+    BEGIN
+        MENUITEM "&Visa dolda ikoner",          ID_SHOW_HIDDEN_ICONS
+        MENUITEM "Visa &ikonknapp",           ID_SHOW_ICON_BUTTON
+        MENUITEM "&Konfigurera meddelanden...", ID_CONFIG_NOTIFYAREA
+        MENUITEM "Justera &datum och &tid...",        ID_CONFIG_TIME
+        MENUITEM SEPARATOR
+        MENUITEM "&Om Explorer...",          ID_ABOUT_EXPLORER
+    END
+END
+
+IDM_SDIFRAME MENU PRELOAD DISCARDABLE 
+BEGIN
+    POPUP "&Arkiv"
+    BEGIN
+        MENUITEM "&Avsluta",                       ID_FILE_EXIT
+    END
+    POPUP "&Visa"
+    BEGIN
+        MENUITEM "&Verktygsfält",                    ID_VIEW_TOOL_BAR
+        MENUITEM "&Sidfält",                   ID_VIEW_SIDE_BAR, GRAYED
+        MENUITEM "&Statusfält",                 ID_VIEW_STATUSBAR
+        MENUITEM SEPARATOR
+        MENUITEM "&Uppdatera\tF5",                ID_REFRESH
+        MENUITEM "&Fullskärm\tCtrl+Shift+S",  ID_VIEW_FULLSCREEN
+        MENUITEM "&MDI",                        ID_VIEW_MDI
+    END
+    POPUP "&Verktyg"
+    BEGIN
+        MENUITEM "&Alternativ",                    ID_TOOLS_OPTIONS
+    END
+    POPUP "&Hjälp"
+    BEGIN
+        MENUITEM "Explorer &FAQ...",            ID_EXPLORER_FAQ
+        MENUITEM "&Om Explorer...",          ID_ABOUT_EXPLORER
+        MENUITEM "Om &OS...",                ID_ABOUT_WINDOWS
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_EXECUTE DIALOG FIXED IMPURE  15, 13, 210, 63
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Kör"
+FONT 8, "MS Shell Dlg"
+BEGIN
+    CONTROL         "",101,"Static",SS_SIMPLE | SS_NOPREFIX,3,6,162,10
+    CONTROL         "&Kommando:",-1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,3,
+                    18,60,10
+    EDITTEXT        201,3,29,134,12,ES_AUTOHSCROLL
+    CONTROL         "&Som symbol",214,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,
+                    45,71,12
+    DEFPUSHBUTTON   "&OK",1,158,6,47,14
+    PUSHBUTTON      "&Avbryt",2,158,23,47,14
+    PUSHBUTTON      "&Hjälp",254,158,43,47,14
+END
+
+IDD_SEARCH_PROGRAM DIALOGEX 0, 0, 200, 65
+STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Sök program på startmenyn"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    LTEXT           "&Filter:",IDC_STATIC,7,9,18,8
+    EDITTEXT        IDC_FILTER,34,7,100,14,ES_AUTOHSCROLL
+    CONTROL         "List1",IDC_PROGRAMS_FOUND,"SysListView32",LVS_REPORT | 
+                    LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | 
+                    WS_TABSTOP,7,25,186,33
+    PUSHBUTTON      "&Kontrollera poster",IDC_CHECK_ENTRIES,143,7,50,14
+END
+
+IDD_DESKBAR_DESKTOP DIALOG DISCARDABLE  0, 0, 212, 194
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Skrivbordsinställningar"
+FONT 8, "MS Sans Serif"
+BEGIN
+    LTEXT           "Välj från vilket hörn ock åt vilket håll du föredrar att rada upp ikonerna:",
+                    IDC_STATIC,7,7,166,8
+    CONTROL         "vä. och neråt",IDC_ICON_ALIGN_0,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,7,25,46,44
+    CONTROL         "övre åt hö.",IDC_ICON_ALIGN_1,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,57,25,46,44
+    CONTROL         "övre åt vä.",IDC_ICON_ALIGN_2,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,110,25,46,44
+    CONTROL         "hö. och neråt",IDC_ICON_ALIGN_3,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,159,25,46,44
+    CONTROL         "vä. och uppåt",IDC_ICON_ALIGN_4,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,7,73,46,44
+    CONTROL         "nedre åt hö.",IDC_ICON_ALIGN_5,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,57,73,46,44
+    CONTROL         "nedre åt vä.",IDC_ICON_ALIGN_6,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,110,73,46,44
+    CONTROL         "hö. och uppåt",IDC_ICON_ALIGN_7,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,159,73,46,44
+    CONTROL         "sidor och ner",IDC_ICON_ALIGN_8,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,7,121,46,44
+    CONTROL         "kanter",IDC_ICON_ALIGN_9,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,57,121,46,44
+    CONTROL         "runt om",IDC_ICON_ALIGN_10,"Button",BS_OWNERDRAW | 
+                    BS_BOTTOM | WS_TABSTOP,110,121,46,44
+    CONTROL         "",IDC_ICON_ALIGN_11,"Button",BS_OWNERDRAW | BS_BOTTOM | 
+                    WS_TABSTOP,159,121,46,44
+    CONTROL         "Visa &versionsnummer",ID_DESKTOP_VERSION,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,177,91,10
+END
+
+IDD_DESKBAR_TASKBAR DIALOG DISCARDABLE  0, 0, 210, 194
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Aktivitetsfältsinställningar"
+FONT 8, "MS Sans Serif"
+BEGIN
+    CONTROL         "visa &klockan",ID_SHOW_CLOCK,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,7,152,52,10
+    CONTROL         "&Göm inaktiva meddelandeikoner",
+                    ID_HIDE_INACTIVE_ICONS,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,7,174,111,10
+    PUSHBUTTON      "&Meddelanden...",ID_CONFIG_NOTIFYAREA,153,173,50,14
+END
+
+IDD_DESKBAR_STARTMENU DIALOG DISCARDABLE  0, 0, 210, 194
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Startmenyinställningar"
+FONT 8, "MS Sans Serif"
+BEGIN
+END
+
+IDD_NOTIFYAREA DIALOGEX 0, 0, 208, 174
+STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | 
+    WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Inställningar för meddelandeikoner"
+FONT 8, "MS Sans Serif"
+BEGIN
+    CONTROL         "Tree1",IDC_NOTIFY_ICONS,"SysTreeView32",TVS_HASLINES | 
+                    TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,194,31
+    LTEXT           "&Hjälptext:",IDC_LABEL1,7,44,40,8
+    EDITTEXT        IDC_NOTIFY_TOOLTIP,58,42,143,14,ES_AUTOHSCROLL
+    LTEXT           "&Fönstertitel:",IDC_LABEL2,7,63,44,8
+    EDITTEXT        IDC_NOTIFY_TITLE,58,60,143,14,ES_AUTOHSCROLL
+    LTEXT           "&Modulsökväg:",IDC_LABEL3,7,81,43,8
+    EDITTEXT        IDC_NOTIFY_MODULE,58,78,143,14,ES_AUTOHSCROLL
+    GROUPBOX        "&Visningsläge",IDC_LABEL4,7,96,157,28
+    CONTROL         "v&isa",IDC_NOTIFY_SHOW,"Button",BS_AUTORADIOBUTTON | 
+                    WS_TABSTOP,15,108,33,10
+    CONTROL         "&dölj",IDC_NOTIFY_HIDE,"Button",BS_AUTORADIOBUTTON,66,
+                    108,29,10
+    CONTROL         "dölj a&utomatiskt",IDC_NOTIFY_AUTOHIDE,"Button",
+                    BS_AUTORADIOBUTTON,112,108,43,10
+    ICON            "",IDC_PICTURE,173,101,21,20
+    LTEXT           "&Senast ändrad:",IDC_LABEL6,7,132,43,8
+    EDITTEXT        IDC_LAST_CHANGE,59,129,105,14,ES_AUTOHSCROLL | 
+                    ES_READONLY
+    CONTROL         "visa d&olda",ID_SHOW_HIDDEN_ICONS,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,154,56,10
+    DEFPUSHBUTTON   "&OK",IDOK,91,153,50,14,WS_GROUP
+    PUSHBUTTON      "&Avbryt",IDCANCEL,151,153,50,14
+END
+
+IDD_MDI_SDI DIALOGEX 0, 0, 188, 126
+STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Välj MDI / SDI Läge"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    LTEXT           "Välj det gränssnitt du föredrar:",
+                    IDC_STATIC,7,7,160,8
+    CONTROL         "&MDI (multiple document interface)",IDC_MDI,"Button",
+                    BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,30,121,10
+    CONTROL         "&SDI (single document interface)",IDC_SDI,"Button",
+                    BS_AUTORADIOBUTTON,7,53,115,10
+    LTEXT           "Den här inställningen kommer att gälla som standard i alla nya explorer-fönster.",
+                    IDC_STATIC,7,76,174,22
+    DEFPUSHBUTTON   "&OK",IDOK,29,105,50,14,WS_GROUP
+    PUSHBUTTON      "&Avbryt",IDCANCEL,106,105,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_SEARCH_PROGRAM, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 193
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 58
+    END
+
+    IDD_DESKBAR_DESKTOP, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 205
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 187
+    END
+
+    IDD_DESKBAR_TASKBAR, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 203
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 187
+    END
+
+    IDD_DESKBAR_STARTMENU, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 203
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 187
+    END
+
+    IDD_NOTIFYAREA, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 201
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 167
+    END
+
+    IDD_MDI_SDI, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 181
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 119
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_TITLE               "Reactos Explorer"
+    IDS_START               "Start"
+    IDS_LOGOFF              "Logga ut..."
+    IDS_TERMINATE           "Logga ut"
+    IDS_SHUTDOWN            "Stäng av..."
+    IDS_LAUNCH              "Kör..."
+    IDS_START_HELP          "Hjälp"
+    IDS_SEARCH_FILES        "Sök..."
+    IDS_DOCUMENTS           "Dokument"
+    IDS_FAVORITES           "Favoriter"
+    IDS_PROGRAMS            "Program"
+    IDS_SETTINGS            "Inställningar"
+    IDS_EXPLORE             "Utforska"
+    IDS_EMPTY               "(tom)"
+    IDS_RECENT              "Senaste dokumenten"
+    IDS_ADMIN               "Administration"
+END
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_NETWORK             "Nätverk"
+    IDS_CONNECTIONS         "Nätverksanslutningar"
+    IDS_DRIVES              "Enheter"
+    IDS_SEARCH_COMPUTER     "Sök dator..."
+    IDS_SETTINGS_MENU       "Inställningsmeny"
+    IDS_CONTROL_PANEL       "Kontrollpanelen"
+    IDS_PRINTERS            "Skrivare"
+    IDS_BROWSE              "Utforska filer"
+    IDS_SEARCH_PRG          "Sök program..."
+    IDS_ALL_USERS           "Alla användare\\"
+    IDS_SEARCH              "Sök"
+    IDS_ABOUT_EXPLORER      "&Om Explorer..."
+    IDS_LAUNCH_MANY_PROGRAMS 
+                            "Du har valt fler än ett program.\nÄr du säker på att du vill öppna dem alla?"
+    IDS_DESKTOPBAR_SETTINGS "Skrivbordsinställningar"
+    IDS_DESKTOP             "Skrivbord"
+    IDS_TASKBAR             "Aktivitetsfält"
+END
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_STARTMENU           "Startmeny"
+    IDS_MINIMIZE_ALL        "minimera alla fönster"
+    IDS_DESKTOP_NUM         "Skrivbord %d"
+    IDS_VOLUME              "Volym"
+    IDS_ITEMS_CUR           "aktuella meddelanden"
+    IDS_ITEMS_CONFIGURED    "konfiguration"
+    IDS_ITEMS_VISIBLE       "synlig"
+    IDS_ITEMS_HIDDEN        "dold"
+    IDS_NOTIFY_SHOW         "visa"
+    IDS_NOTIFY_HIDE         "dölj"
+    IDS_NOTIFY_AUTOHIDE     "dölj automatiskt"
+    IDS_SHOW_HIDDEN_ICONS   "Visa dolda ikoner"
+    IDS_HIDE_ICONS          "Dölj ikoner"
+END
+
+#endif    // Swedish (SE) resources
+/////////////////////////////////////////////////////////////////////////////
 
 
 #ifndef APSTUDIO_INVOKED
index eee4274..50e7650 100644 (file)
@@ -31,9 +31,6 @@ extern "C" {
 #endif
 
 
- // launch start programs
-extern int startup(int argc, char *argv[]);
-
  // explorer main routine
 extern int explorer_main(HINSTANCE hinstance, LPTSTR lpCmdLine, int cmdshow);
 
index ac74928..ad36411 100644 (file)
@@ -183,10 +183,6 @@ CFG=make_explorer - Win32 bjam
 \r
 # Begin Source File\r
 \r
-SOURCE=..\..\..\ChangeLog\r
-# End Source File\r
-# Begin Source File\r
-\r
 SOURCE=.\Jamfile\r
 # End Source File\r
 # Begin Source File\r
index beb28a6..d62870d 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/computer.ico and b/reactos/subsys/system/explorer/res/computer.ico differ
index 8aa5104..09e4a52 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/explorer.ico and b/reactos/subsys/system/explorer/res/explorer.ico differ
index c8cb74f..11ac83d 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/folder.ico and b/reactos/subsys/system/explorer/res/folder.ico differ
index 58e1603..6e9b865 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/logov.bmp and b/reactos/subsys/system/explorer/res/logov.bmp differ
index 9de7508..16cebc5 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/reactos.ico and b/reactos/subsys/system/explorer/res/reactos.ico differ
index 7721efe..4c9642e 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/ros-big.ico and b/reactos/subsys/system/explorer/res/ros-big.ico differ
index 4dbf601..52411bf 100644 (file)
Binary files a/reactos/subsys/system/explorer/res/startmenu.ico and b/reactos/subsys/system/explorer/res/startmenu.ico differ
diff --git a/reactos/subsys/system/explorer/services/shellservices.cpp b/reactos/subsys/system/explorer/services/shellservices.cpp
new file mode 100644 (file)
index 0000000..4b47ce8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2005 Martin Fuchs
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+ //
+ // Explorer clone
+ //
+ // shellservices.cpp
+ //
+ // Martin Fuchs, 28.03.2005
+ //
+
+
+#include "precomp.h"
+
+#include "shellservices.h"
+
+
+int SSOThread::Run()
+{
+       ComInit usingCOM(COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE|COINIT_SPEED_OVER_MEMORY);
+
+       HKEY hkey;
+       CLSID clsid;
+       WCHAR name[MAX_PATH], value[MAX_PATH];
+
+       typedef vector<SIfacePtr<IOleCommandTarget>*> SSOVector;
+       SSOVector sso_ptrs;
+
+       if (!RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad"), &hkey)) {
+               for(int idx=0; ; ++idx) {
+                       DWORD name_len = MAX_PATH;
+                       DWORD value_len = sizeof(value);
+
+                       if (RegEnumValueW(hkey, idx, name, &name_len, 0, NULL, (LPBYTE)&value, &value_len))
+                               break;
+
+                       if (!_alive)
+                               break;
+
+                       SIfacePtr<IOleCommandTarget>* sso_ptr = new SIfacePtr<IOleCommandTarget>;
+
+                       if (CLSIDFromString(value, &clsid) == NOERROR) {
+                               if (SUCCEEDED(sso_ptr->CreateInstance(clsid, IID_IOleCommandTarget))) {
+                                       if (SUCCEEDED((*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL)))
+                                               sso_ptrs.push_back(sso_ptr);
+                               }
+                       }
+               }
+
+               RegCloseKey(hkey);
+       }
+
+       if (!sso_ptrs.empty()) {
+               MSG msg;
+
+               while(_alive) {
+                       if (MsgWaitForMultipleObjects(1, &_evtFinish, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0+0)
+                               break;  // _evtFinish has been set.
+
+                       while(_alive) {
+                               if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+                                       break;
+
+                               if (msg.message == WM_QUIT)
+                                       break;
+
+                               TranslateMessage(&msg);
+                               DispatchMessage(&msg);
+                       }
+               }
+
+                // shutdown all running Shell Service Objects
+               for(SSOVector::iterator it=sso_ptrs.begin(); it!=sso_ptrs.end(); ++it) {
+                       SIfacePtr<IOleCommandTarget>* sso_ptr = *it;
+                       (*sso_ptr)->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
+                       delete sso_ptr;
+               }
+       }
+
+       return 0;
+}
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Martin Fuchs
+ * Copyright 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 
  //
- // Explorer and Desktop clone
+ // Explorer clone
  //
- // shellhook.h
+ // shellservices.h
  //
- // Martin Fuchs, 17.08.2003
+ // Martin Fuchs, 28.03.2005
  //
 
 
-#ifdef _SHELLHOOK_IMPL
-#define        DECL_SHELLHOOK __declspec(dllexport)
-#else
-#define        DECL_SHELLHOOK __declspec(dllimport)
-#endif
+ // launch start programs
+extern "C" int startup(int argc, char *argv[]);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-DECL_SHELLHOOK void InstallShellHook(HWND callback_hwnd, UINT callback_msg);
-DECL_SHELLHOOK void DeinstallShellHook();
-
-#ifdef __cplusplus
+ // load Shell Service Objects (volume control, printer/network icons, ...)
+struct SSOThread : public Thread
+{
+       int     Run();
 };
-#endif
index 4f12f01..3dfff9e 100644 (file)
@@ -323,7 +323,7 @@ void Entry::extract_icon()
 
        ICON_ID icon_id = ICID_NONE;
 
-       if (get_path(path))
+       if (get_path(path) && _tcsncmp(path,TEXT("::{"),3))
                icon_id = g_Globals._icon_cache.extract(path);
 
        if (icon_id == ICID_NONE) {
index 10699aa..e046265 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -40,19 +40,19 @@ extern HWND create_webchildwindow(const WebChildWndInfo& info);
 
 HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
 {
-       HWND hMainFrame;
+       HWND hFrame;
 
 #ifndef _NO_MDI        ///@todo implement command line option to switch between MDI and SDI
        if (mdi)
-               hMainFrame = MDIMainFrame::Create();
+               hFrame = MDIMainFrame::Create();
        else
 #endif
-               hMainFrame = SDIMainFrame::Create();
+               hFrame = SDIMainFrame::Create();
 
-       if (hMainFrame) {
+       if (hFrame) {
                HWND hwndOld = g_Globals._hMainWnd;
 
-               g_Globals._hMainWnd = hMainFrame;
+               g_Globals._hMainWnd = hFrame;
 
                if (path) {
                        static String sPath = path;     // copy path to avoid accessing freed memory
@@ -62,8 +62,8 @@ HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
                if (hwndOld)
                        DestroyWindow(hwndOld);
 
-               ShowWindow(hMainFrame, cmdshow);
-               UpdateWindow(hMainFrame);
+               ShowWindow(hFrame, cmdshow);
+               UpdateWindow(hFrame);
 
                bool valid_dir = false;
 
@@ -78,12 +78,12 @@ HWND MainFrameBase::Create(LPCTSTR path, bool mdi, UINT cmdshow)
 
                 // Open the first child window after initializing the application
                if (valid_dir)
-                       PostMessage(hMainFrame, PM_OPEN_WINDOW, 0, (LPARAM)path);
+                       PostMessage(hFrame, PM_OPEN_WINDOW, 0, (LPARAM)path);
                else
-                       PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
+                       PostMessage(hFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
        }
 
-       return hMainFrame;
+       return hFrame;
 }
 
 
@@ -736,7 +736,6 @@ MDIMainFrame::MDIMainFrame(HWND hwnd)
        extraBtns.idCommand = ID_WEB_WINDOW;
        SendMessage(_hextrabar, TB_INSERTBUTTON, INT_MAX, (LPARAM)&extraBtns);
 
-#define        W_VER_NT 0
        if ((HIWORD(GetVersion())>>14) == W_VER_NT) {
                 // insert NT object namespace button
                extraBtns.iString = SendMessage(_hextrabar, TB_ADDSTRING, 0, (LPARAM)TEXT("NT Obj\0"));
@@ -843,34 +842,34 @@ HWND MDIMainFrame::Create()
 
 HWND MDIMainFrame::Create(LPCTSTR path, int mode)
 {
-       HWND hMainFrame = Create();
-       if (!hMainFrame)
+       HWND hFrame = Create();
+       if (!hFrame)
                return 0;
 
-       ShowWindow(hMainFrame, SW_SHOW);
+       ShowWindow(hFrame, SW_SHOW);
 
-       MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hMainFrame);
+       MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
 
        if (pMainFrame)
                pMainFrame->CreateChild(path, mode);
 
-       return hMainFrame;
+       return hFrame;
 }
 
 HWND MDIMainFrame::Create(LPCITEMIDLIST pidl, int mode)
 {
-       HWND hMainFrame = Create();
-       if (!hMainFrame)
+       HWND hFrame = Create();
+       if (!hFrame)
                return 0;
 
-       ShowWindow(hMainFrame, SW_SHOW);
+       ShowWindow(hFrame, SW_SHOW);
 
-       MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hMainFrame);
+       MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
 
        if (pMainFrame)
                pMainFrame->CreateChild(pidl, mode);
 
-       return hMainFrame;
+       return hFrame;
 }
 
 
@@ -1316,6 +1315,22 @@ HWND SDIMainFrame::Create(LPCITEMIDLIST pidl, int mode)
        return hFrame;
 }
 
+HWND SDIMainFrame::Create(LPCTSTR path, int mode)
+{
+       HWND hFrame = Create();
+       if (!hFrame)
+               return 0;
+
+       ShowWindow(hFrame, SW_SHOW);
+
+       MDIMainFrame* pMainFrame = GET_WINDOW(MDIMainFrame, hFrame);
+
+       if (pMainFrame)
+               pMainFrame->CreateChild(path, mode);
+
+       return hFrame;
+}
+
 LRESULT SDIMainFrame::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
        switch(nmsg) {
@@ -1637,17 +1652,16 @@ void SDIMainFrame::jump_to(LPCTSTR path, int mode)
 
 void SDIMainFrame::jump_to(LPCITEMIDLIST path, int mode)
 {
-/*@@todo
        if (_shellBrowser.get() && (_shellpath_info._open_mode&~OWM_PIDL)==(mode&~OWM_PIDL)) {
                ShellPath shell_path = path;
 
                _shellBrowser->jump_to(shell_path);
 
                _shellpath_info._shell_path = shell_path;
-       } else */{
+       } else {
                _shellpath_info._open_mode = mode;
                _shellpath_info._shell_path = path;
-               _shellpath_info._root_shell_path = DesktopFolderPath(); //@@
+               _shellpath_info._root_shell_path = SpecialFolderPath(CSIDL_DRIVES, _hwnd);      //@@
 
                update_shell_browser();
        }
index 5cdc320..f8e02cd 100644 (file)
@@ -135,6 +135,7 @@ struct SDIMainFrame : public ExtContextMenuHandlerT<
        SDIMainFrame(HWND hwnd);
 
        static HWND Create();
+       static HWND Create(LPCTSTR path, int mode=OWM_EXPLORE|OWM_DETAILS);
        static HWND Create(LPCITEMIDLIST pidl, int mode=OWM_EXPLORE|OWM_DETAILS|OWM_PIDL);
 
 protected:
index 9753799..ea72acb 100644 (file)
@@ -163,7 +163,7 @@ void Pane::init()
        HKEY hkeyExplorer = 0;
        DWORD len = sizeof(_clrCompressed);
 
-       if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) ||
+       if (RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) ||
                RegQueryValueEx(hkeyExplorer, TEXT("AltColor"), 0, NULL, (LPBYTE)&_clrCompressed, &len) || len!=sizeof(_clrCompressed))
                _clrCompressed = RGB(0,0,255);
 
index e804dfd..1f6506d 100644 (file)
@@ -43,9 +43,9 @@ void RegDirectory::read_directory(int scan_flags)
        _tcscpy(buffer, (LPCTSTR)_path);
        LPTSTR pname = buffer + _tcslen(buffer);
 
-       HKEY hKey;
+       HKEY hkey;
 
-       if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey)) {
+       if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hkey)) {
                if (pname[-1] != '\\')
                        *pname++ = '\\';
 
@@ -60,7 +60,7 @@ void RegDirectory::read_directory(int scan_flags)
                        DWORD name_len = MAX_PATH;
                        DWORD class_len = MAX_PATH;
 
-                       if (RegEnumKeyEx(hKey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime))
+                       if (RegEnumKeyEx(hkey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime))
                                break;
 
                        w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
@@ -88,7 +88,7 @@ void RegDirectory::read_directory(int scan_flags)
                TCHAR value[MAX_PATH];
                LONG value_len = sizeof(value);
 
-               if (!RegQueryValue(hKey, NULL, value, &value_len) && value_len>1) {
+               if (!RegQueryValue(hkey, NULL, value, &value_len) && value_len>1) {
                        memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
 
                        lstrcpy(w32fd.cFileName, TEXT("(Default)"));
@@ -114,7 +114,7 @@ void RegDirectory::read_directory(int scan_flags)
                for(int idx=0; ; ++idx) {
                        DWORD name_len = MAX_PATH;
 
-                       if (RegEnumValue(hKey, idx, name, &name_len, 0, &type, NULL, NULL))
+                       if (RegEnumValue(hkey, idx, name, &name_len, 0, &type, NULL, NULL))
                                break;
 
                        memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
@@ -147,7 +147,7 @@ void RegDirectory::read_directory(int scan_flags)
                        TCHAR value[MAX_PATH];
                        DWORD value_len = sizeof(value);
 
-                       if (!RegQueryValueEx(hKey, name, NULL, NULL, (LPBYTE)value, &value_len)) {
+                       if (!RegQueryValueEx(hkey, name, NULL, NULL, (LPBYTE)value, &value_len)) {
                                if (type==REG_SZ || type==REG_EXPAND_SZ || type==REG_LINK)
                                        entry->_content = _tcsdup(value);
                                else if (type == REG_DWORD) {
@@ -171,7 +171,7 @@ void RegDirectory::read_directory(int scan_flags)
                if (last)
                        last->_next = NULL;
 
-               RegCloseKey(hKey);
+               RegCloseKey(hkey);
        }
 
        _down = first_entry;
index 91a4dd4..61bc2dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -50,6 +50,8 @@ ShellBrowser::ShellBrowser(HWND hwnd, HWND left_hwnd, WindowHandle& right_hwnd,
 
 ShellBrowser::~ShellBrowser()
 {
+       TreeView_SetImageList(_left_hwnd, 0, TVSIL_NORMAL);
+
        if (_pShellView)
                _pShellView->Release();
 
@@ -71,7 +73,7 @@ LRESULT ShellBrowser::Init(HWND hWndFrame)
 
        _hWndFrame = hWndFrame;
 
-       const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORPARSING);
+       const String& root_name = GetDesktopFolder().get_name(_create_info._root_shell_path, SHGDN_FORADDRESSBAR);
 
        _root._drive_type = DRIVE_UNKNOWN;
        lstrcpy(_root._volname, root_name);
@@ -483,6 +485,9 @@ MDIShellBrowserChild::MDIShellBrowserChild(HWND hwnd, const ShellChildWndInfo& i
        _shellpath_info(info)   //@@ copies info -> no referenz to _create_info !
 {
 /**todo Conversion of shell path into path string -> store into URL history
+       const String& path = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORADDRESSBAR);
+       const String& parsingpath = GetDesktopFolder().get_name(info._shell_path, SHGDN_FORPARSING);
+
         // store path into history
        if (info._path && *info._path)
                _url_history.push(info._path);
index d256a6b..8d554c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -135,6 +135,9 @@ struct ShellBrowser : public IShellBrowserImpl
        void    UpdateFolderView(IShellFolder* folder);
        HTREEITEM select_entry(HTREEITEM hitem, Entry* entry, bool expand=true);
 
+        // for SDIMainFrame
+       void    jump_to(LPCITEMIDLIST pidl);
+
 protected:
        HWND    _hwnd;
        HWND    _left_hwnd;
@@ -158,9 +161,6 @@ protected:
 
        void    InitializeTree(HIMAGELIST himl);
        bool    InitDragDrop();
-
-        // for SDIMainFrame
-       void    jump_to(LPCITEMIDLIST pidl);
 };
 
 
index d636097..afb0e9e 100644 (file)
@@ -235,7 +235,7 @@ void ShellDirectory::read_directory(int scan_flags)
 
        TCHAR buffer[MAX_PATH];
 
-       if ((scan_flags&SCAN_FILESYSTEM) && get_path(buffer)) {
+       if ((scan_flags&SCAN_FILESYSTEM) && get_path(buffer) && _tcsncmp(buffer,TEXT("::{"),3)) {
                Entry* entry = NULL;    // eliminate useless GCC warning by initializing entry
 
                LPTSTR p = buffer + _tcslen(buffer);
index 9f8276d..34f8af8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -58,7 +58,7 @@ struct ShellDirectory : public ShellEntry, public Directory
        {
                CONTEXT("ShellDirectory::ShellDirectory()");
 
-               lstrcpy(_data.cFileName, root_folder.get_name(shell_path, SHGDN_FORPARSING));
+               lstrcpy(_data.cFileName, root_folder.get_name(shell_path, SHGDN_FORADDRESSBAR));
                _data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
                _shell_attribs = SFGAO_FOLDER;
 
index 651420d..be20039 100644 (file)
 
 DesktopBar::DesktopBar(HWND hwnd)
  :     super(hwnd),
+#ifdef _ROS_
        _trayIcon(hwnd, ID_TRAY_VOLUME)
+#else
+       WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
+#endif
 {
-       SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/); // icon in for TrayNotifyDlg
+       SetWindowIcon(hwnd, IDI_REACTOS);
 
        SystemParametersInfo(SPI_GETWORKAREA, 0, &_work_area_org, 0);
 }
@@ -107,6 +111,12 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
                 // create tray notification area
                _hwndNotify = NotifyArea::Create(_hwnd);
 
+
+        // notify all top level windows about the successfully created desktop bar
+        //@@ Use SendMessage() instead of PostMessage() to avoid problems with delayed created shell service objects?
+       PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
+
+
        _hwndQuickLaunch = QuickLaunchBar::Create(_hwnd);
 
         // create rebar window to manage task and quick launch bar
@@ -147,10 +157,8 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs)
        SendMessage(_hwndrebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
 #endif
 
-       RegisterHotkeys();
 
-        // notify all top level windows about the successfully created desktop bar
-       PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
+       RegisterHotkeys();
 
         // prepare Startmenu, but hide it for now
        _startMenuRoot = GET_WINDOW(StartMenuRoot, StartMenuRoot::Create(_hwnd));
@@ -332,6 +340,7 @@ int DesktopBar::Command(int id, int code)
                        PostMessage(_hwndQuickLaunch, PM_UPDATE_DESKTOP, desktop_idx, 0);
                break;}
 
+#ifdef _ROS_
          case ID_TRAY_VOLUME:
                launch_file(_hwnd, TEXT("sndvol32.exe"), SW_SHOWNORMAL);        // launch volume control application
                break;
@@ -339,6 +348,7 @@ int DesktopBar::Command(int id, int code)
          case ID_VOLUME_PROPERTIES:
                launch_cpanel(_hwnd, TEXT("mmsys.cpl"));
                break;
+#endif
 
          default:
                if (_hwndQuickLaunch)
@@ -381,6 +391,8 @@ LRESULT DesktopBar::ProcessCopyData(COPYDATASTRUCT* pcd)
 }
 
 
+#ifdef _ROS_
+
 void DesktopBar::AddTrayIcons()
 {
        _trayIcon.Add(SmallIcon(IDI_SPEAKER), ResString(IDS_VOLUME));
@@ -410,3 +422,5 @@ void DesktopBar::TrayDblClick(UINT id, int btn)
                break;
        }
 }
+
+#endif
index beb8467..c0d8e1c 100644 (file)
 #define        IDC_NETWORK                             0x100E
 #define        IDC_CONNECTIONS                 0x100F
 #define        IDC_DRIVES                              0x1010
-#define        IDC_SETTINGS_MENU               0x1011
-#define        IDC_CONTROL_PANEL               0x1012
+#define        IDC_CONTROL_PANEL               0x1011
+#define        IDC_SETTINGS_MENU               0x1012
 #define        IDC_PRINTERS                    0x1013
-#define        IDC_BROWSE                              0x1014
-#define        IDC_SEARCH_PROGRAM              0x1015
-#define        IDC_SEARCH                              0x1016
+#define        IDC_PRINTERS_MENU               0x1014
+#define        IDC_BROWSE                              0x1015
+#define        IDC_SEARCH_PROGRAM              0x1016
+#define        IDC_SEARCH                              0x1017
+#define        IDC_TERMINATE                   0x1018
 
 #define        IDC_FIRST_MENU                  0x3000
 
 
  /// desktop bar window, also known as "system tray"
-struct DesktopBar : public TrayIconControllerTemplate<
-                                               OwnerDrawParent<Window> >
+struct DesktopBar : public
+#ifdef _ROS_
+       TrayIconControllerTemplate<
+                               OwnerDrawParent<Window> >
+#else
+       OwnerDrawParent<Window>
+#endif
 {
+#ifdef _ROS_
        typedef TrayIconControllerTemplate<
                                OwnerDrawParent<Window> > super;
+#else
+       typedef OwnerDrawParent<Window> super;
+#endif
 
        DesktopBar(HWND hwnd);
        ~DesktopBar();
@@ -93,9 +104,13 @@ protected:
 
        struct StartMenuRoot* _startMenuRoot;
 
+#ifdef _ROS_
        TrayIcon        _trayIcon;
 
        void    AddTrayIcons();
        virtual void TrayClick(UINT id, int btn);
        virtual void TrayDblClick(UINT id, int btn);
+#else
+       const UINT WM_TASKBARCREATED;
+#endif
 };
index f10fb26..af8d6b5 100644 (file)
@@ -286,6 +286,10 @@ int QuickLaunchBar::Notify(int id, NMHDR* pnmh)
 #ifdef TTF_DI_SETITEM
                ttdi->uFlags |= TTF_DI_SETITEM;
 #endif
+
+                // enable multiline tooltips (break at CR/LF and for very long one-line strings)
+               SendMessage(pnmh->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 400);
+
                break;}
 
                return super::Notify(id, pnmh);
index a113bfb..bb3664c 100644 (file)
@@ -425,7 +425,7 @@ LRESULT StartMenu::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
                break;
 
          case PM_SELECT_ENTRY:
-               SelectButtonIndex(0, wparam?true:false);
+               SelectButtonIndex(0, wparam!=0);
                break;
 
 #ifdef _LIGHT_STARTMENU
@@ -1690,6 +1690,9 @@ LRESULT   StartMenuRoot::Init(LPCREATESTRUCT pcs)
                AddButton(ResString(IDS_SHUTDOWN),      ICID_LOGOFF, false, IDC_SHUTDOWN);
 
 
+       AddButton(ResString(IDS_TERMINATE),     ICID_LOGOFF, false, IDC_TERMINATE);
+
+
 #ifdef __MINGW32__
        RegCloseKey(hkeyAdv);
        RegCloseKey(hkey);
@@ -1830,9 +1833,11 @@ int StartMenuHandler::Command(int id, int code)
                break;
 
          case IDC_LOGOFF:
-               /* The shell32 Dialog prompts about some system setting change. This is not what we want to display here.
                CloseStartMenu(id);
-               ShowRestartDialog(g_Globals._hwndDesktopBar, EWX_LOGOFF);*/
+               ShowLogoffDialog(g_Globals._hwndDesktopBar);
+               break;
+
+         case IDC_TERMINATE:
                DestroyWindow(GetParent(_hwnd));
                break;
 
@@ -1849,21 +1854,50 @@ int StartMenuHandler::Command(int id, int code)
                ExplorerPropertySheet(g_Globals._hwndDesktopBar);
                break;
 
+         case IDC_CONTROL_PANEL: {
+               CloseStartMenu(id);
+#ifndef _NO_MDI
+               XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
+               bool mdi = XMLBool(explorer_options, "mdi", true);
+
+               if (mdi)
+                       MDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+               else
+#endif
+                       SDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+               break;}
+
          case IDC_SETTINGS_MENU:
                CreateSubmenu(id, CSIDL_CONTROLS, ResString(IDS_SETTINGS_MENU));
                break;
 
-         case IDC_PRINTERS:
+         case IDC_PRINTERS: {
+               CloseStartMenu(id);
 #ifdef _ROS_   // to be removed when printer folder will be implemented
                MessageBox(0, TEXT("printer folder not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
 #else
-               CreateSubmenu(id, CSIDL_PRINTERS, CSIDL_PRINTHOOD, ResString(IDS_PRINTERS));
+#ifndef _NO_MDI
+               XMLPos explorer_options = g_Globals.get_cfg("general/explorer");
+               bool mdi = XMLBool(explorer_options, "mdi", true);
+
+               if (mdi)
+                       MDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"), 0);
+               else
 #endif
-               break;
+                       SDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"), 0);
+#endif
+               break;}
 
-         case IDC_CONTROL_PANEL:
-               CloseStartMenu(id);
-               //@@SDIMainFrame::Create(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"), 0);
+         case IDC_PRINTERS_MENU:
+               CreateSubmenu(id, CSIDL_PRINTERS, CSIDL_PRINTHOOD, ResString(IDS_PRINTERS));
+/*             StartMenuFolders new_folders;
+
+               try {
+                       new_folders.push_back(ShellPath(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}")));
+               } catch(COMException&) {
+               }
+
+               CreateSubmenu(id, new_folders, ResString(IDS_PRINTERS));*/
                break;
 
          case IDC_ADMIN:
@@ -1890,7 +1924,7 @@ int StartMenuHandler::Command(int id, int code)
                break;
 
          case IDC_DRIVES:
-               ///@todo exclude removeable drives
+               ///@todo exclude removable drives
                CreateSubmenu(id, CSIDL_DRIVES, ResString(IDS_DRIVES));
                break;
 
@@ -1952,7 +1986,6 @@ void StartMenuHandler::ShowLaunchDialog(HWND hwndOwner)
         // Show "Run..." dialog
        if (RunFileDlg) {
 #ifndef _ROS_ /* FIXME: our shell32 always expects Ansi strings */
-#define        W_VER_NT 0
                if ((HIWORD(GetVersion())>>14) == W_VER_NT) {
                        WCHAR wTitle[40], wText[256];
 
@@ -1967,24 +2000,29 @@ void StartMenuHandler::ShowLaunchDialog(HWND hwndOwner)
        }
 }
 
-void StartMenuHandler::ShowRestartDialog(HWND hwndOwner, UINT flags)
+void StartMenuHandler::ShowLogoffDialog(HWND hwndOwner)
 {
-       static DynamicFct<RESTARTWINDOWSDLG> RestartDlg(TEXT("SHELL32"), 59);
+       static DynamicFct<LOGOFFWINDOWSDIALOG> LogoffWindowsDialog(TEXT("SHELL32"), 54);
+//     static DynamicFct<RESTARTWINDOWSDLG> RestartDialog(TEXT("SHELL32"), 59);
 
-       if (RestartDlg)
-               (*RestartDlg)(hwndOwner, (LPWSTR)L"You selected <Log Off>.\n\n", flags);        ///@todo ANSI string conversion if needed
+       if (LogoffWindowsDialog)
+               (*LogoffWindowsDialog)(0);
+/* The RestartDialog function prompts about some system setting change. This is not what we want to display here.
+       else if (RestartDialog)
+               return (*RestartDialog)(hwndOwner, (LPWSTR)L"You selected <Log Off>.\n\n", EWX_LOGOFF) == 1;    ///@todo ANSI string conversion if needed
+*/
        else
-               MessageBox(hwndOwner, TEXT("RestartDlg() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+               MessageBox(hwndOwner, TEXT("LogoffWindowsDialog() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
 }
 
 void ShowExitWindowsDialog(HWND hwndOwner)
 {
-       static DynamicFct<EXITWINDOWSDLG> ExitWindowsDlg(TEXT("SHELL32"), 60);
+       static DynamicFct<EXITWINDOWSDLG> ExitWindowsDialog(TEXT("SHELL32"), 60);
 
-       if (ExitWindowsDlg)
-               (*ExitWindowsDlg)(hwndOwner);
+       if (ExitWindowsDialog)
+               (*ExitWindowsDialog)(hwndOwner);
        else
-               MessageBox(hwndOwner, TEXT("ExitWindowsDlg() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
+               MessageBox(hwndOwner, TEXT("ExitWindowsDialog() not yet implemented in SHELL32"), ResString(IDS_TITLE), MB_OK);
 }
 
 
@@ -1992,16 +2030,11 @@ void SettingsMenu::AddEntries()
 {
        super::AddEntries();
 
-#ifndef __MINGW32__    // SHRestricted() missing in MinGW (as of 29.10.2003)
-       if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL))
-#endif
-               AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONFIG, false, IDC_CONTROL_PANEL);
-
 #ifdef _ROS_   // to be removed when printer/network will be implemented
-       AddButton(ResString(IDS_PRINTERS),                      ICID_PRINTER, false, IDC_PRINTERS);
+       AddButton(ResString(IDS_PRINTERS),                      ICID_PRINTER, false, IDC_PRINTERS_MENU);
        AddButton(ResString(IDS_CONNECTIONS),           ICID_NETWORK, false, IDC_CONNECTIONS);
 #else
-       AddButton(ResString(IDS_PRINTERS),                      ICID_PRINTER, true, IDC_PRINTERS);
+       AddButton(ResString(IDS_PRINTERS),                      ICID_PRINTER, true, IDC_PRINTERS_MENU);
        AddButton(ResString(IDS_CONNECTIONS),           ICID_NETWORK, true, IDC_CONNECTIONS);
 #endif
        AddButton(ResString(IDS_ADMIN),                         ICID_CONFIG, true, IDC_ADMIN);
@@ -2012,6 +2045,13 @@ void SettingsMenu::AddEntries()
                AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU);
 
        AddButton(ResString(IDS_DESKTOPBAR_SETTINGS), ICID_CONFIG, false, ID_DESKTOPBAR_SETTINGS);
+
+       AddButton(ResString(IDS_PRINTERS),                      ICID_PRINTER, false, IDC_PRINTERS);
+
+#ifndef __MINGW32__    // SHRestricted() missing in MinGW (as of 29.10.2003)
+       if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL))
+#endif
+               AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONFIG, false, IDC_CONTROL_PANEL);
 }
 
 void BrowseMenu::AddEntries()
index 21bb72d..1840bc9 100644 (file)
@@ -321,9 +321,11 @@ typedef    void (WINAPI* RUNFILEDLG)(HWND hwndOwner, HICON hIcon, LPCSTR lpstrDirec
 #define        RFF_NOSEPARATEMEM       0x20    // Removes the Separate Memory Space check box (Windows NT only).
 
 
- // declare more undocumented shell32 functions
+ // declare more previously undocumented shell32 functions
 typedef        void (WINAPI* EXITWINDOWSDLG)(HWND hwndOwner);
+typedef        int (WINAPI* LOGOFFWINDOWSDIALOG)(UINT flags);
 typedef        int (WINAPI* RESTARTWINDOWSDLG)(HWND hwndOwner, LPCWSTR reason, UINT flags);
+typedef        int (WINAPI* RESTARTWINDOWSDLGEX)(HWND hWndOwner, LPCWSTR lpwstrReason, DWORD uFlags, DWORD uReason);
 typedef        BOOL (WINAPI* SHFINDFILES)(LPCITEMIDLIST pidlRoot, LPCITEMIDLIST pidlSavedSearch);
 typedef        BOOL (WINAPI* SHFINDCOMPUTER)(LPCITEMIDLIST pidlRoot, LPCITEMIDLIST pidlSavedSearch);
 
@@ -347,7 +349,7 @@ protected:
        int             Command(int id, int code);
 
        static void     ShowLaunchDialog(HWND hwndOwner);
-       static void     ShowRestartDialog(HWND hwndOwner, UINT flags);
+       static void     ShowLogoffDialog(HWND hwndOwner);
        static void     ShowSearchDialog();
        static void     ShowSearchComputer();
 };
index c18f1a1..4cf42dd 100644 (file)
 #include "traynotify.h"        // for NOTIFYAREA_WIDTH_DEF
 
 
+DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_SetTaskmanWindow(TEXT("user32"), "SetTaskmanWindow");
+DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_RegisterShellHookWindow(TEXT("user32"), "RegisterShellHookWindow");
+DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_DeregisterShellHookWindow(TEXT("user32"), "DeregisterShellHookWindow");
+
+/*
+DynamicFct<BOOL (WINAPI*)(HWND hWnd, DWORD dwType)> g_RegisterShellHook(TEXT("shell32"), (LPCSTR)0xb5);
+
+ // constants for RegisterShellHook()
+#define RSH_UNREGISTER                 0
+#define RSH_REGISTER                   1
+#define RSH_REGISTER_PROGMAN   2
+#define RSH_REGISTER_TASKMAN   3
+*/
+
+
 TaskBarEntry::TaskBarEntry()
 {
        _id = 0;
@@ -53,16 +68,40 @@ TaskBarMap::~TaskBarMap()
 
 
 TaskBar::TaskBar(HWND hwnd)
- :     super(hwnd)
+ :     super(hwnd),
+       WM_SHELLHOOK(RegisterWindowMessage(WINMSG_SHELLHOOK))
 {
        _last_btn_width = 0;
+
+       _mmMetrics_org.cbSize = sizeof(MINIMIZEDMETRICS);
+
+       SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(_mmMetrics_org), &_mmMetrics_org, 0);
+
+        // configure the window manager to hide windows when they are minimized
+        // This is neccessary to enable shell hook messages.
+       if (!(_mmMetrics_org.iArrange & ARW_HIDE)) {
+               MINIMIZEDMETRICS _mmMetrics_new = _mmMetrics_org;
+
+               _mmMetrics_new.iArrange |= ARW_HIDE;
+
+               SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(_mmMetrics_new), &_mmMetrics_new, 0);
+       }
 }
 
 TaskBar::~TaskBar()
 {
-       KillTimer(_hwnd, 0);
+//     if (g_RegisterShellHook)
+//             (*g_RegisterShellHook)(_hwnd, RSH_UNREGISTER);
 
-       //DeinstallShellHook();
+       if (g_DeregisterShellHookWindow)
+               (*g_DeregisterShellHookWindow)(_hwnd);
+       else
+               KillTimer(_hwnd, 0);
+
+       if (g_SetTaskmanWindow)
+               (*g_SetTaskmanWindow)(0);
+
+       SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(_mmMetrics_org), &_mmMetrics_org, 0);
 }
 
 HWND TaskBar::Create(HWND hwndParent)
@@ -95,11 +134,31 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs)
 
        _next_id = IDC_FIRST_APP;
 
-       //InstallShellHook(_hwnd, PM_SHELLHOOK_NOTIFY);
+        // register the taskbar window as task manager window to make the following call to RegisterShellHookWindow working
+       if (g_SetTaskmanWindow)
+               (*g_SetTaskmanWindow)(_hwnd);
 
-       Refresh();
+       if (g_RegisterShellHookWindow) {
+               LOG(TEXT("Using shell hooks for notification of shell events."));
+
+               (*g_RegisterShellHookWindow)(_hwnd);
+       } else {
+               LOG(TEXT("Shell hooks not available."));
 
-       SetTimer(_hwnd, 0, 200, NULL);
+               SetTimer(_hwnd, 0, 200, NULL);
+       }
+
+/* Alternatively we could use the RegisterShellHook() function in SHELL32, but this is not yet implemented in the WINE code.
+       if (g_RegisterShellHook) {
+               (*g_RegisterShellHook)(0, RSH_REGISTER);
+
+               if ((HIWORD(GetVersion())>>14) == W_VER_NT)
+                       (*g_RegisterShellHook)(_hwnd, RSH_REGISTER_TASKMAN);
+               else
+                       (*g_RegisterShellHook)(_hwnd, RSH_REGISTER);
+       }
+*/
+       Refresh();
 
        return 0;
 }
@@ -124,28 +183,27 @@ LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
                        break;  // avoid displaying context menu for application button _and_ desktop bar at the same time
 
                goto def;}
-/*
-//#define PM_SHELLHOOK_NOTIFY          (WM_APP+0x10)
-
-         case PM_SHELLHOOK_NOTIFY: {
-               int code = lparam;
-
-               switch(code) {
-                 case HSHELL_WINDOWCREATED:
-                 case HSHELL_WINDOWDESTROYED:
-                 case HSHELL_WINDOWACTIVATED:
-                 case HSHELL_WINDOWREPLACED:
-                       Refresh();
-                       break;
-               }
-               Refresh();
-               break;}
-*/
+
          case PM_GET_LAST_ACTIVE:
                return (LRESULT)(HWND)_last_foreground_wnd;
 
          default: def:
-               return super::WndProc(nmsg, wparam, lparam);
+               if (nmsg == WM_SHELLHOOK) {
+                       switch(wparam) {
+                         case HSHELL_WINDOWCREATED:
+                         case HSHELL_WINDOWDESTROYED:
+                         case HSHELL_WINDOWACTIVATED:
+                         case HSHELL_REDRAW:
+#ifdef HSHELL_FLASH
+                         case HSHELL_FLASH:
+                         case HSHELL_RUDEAPPACTIVATED:
+#endif
+                               Refresh();
+                               break;
+                       }
+               } else {
+                       return super::WndProc(nmsg, wparam, lparam);
+               }
        }
 
        return 0;
@@ -393,6 +451,7 @@ BOOL CALLBACK TaskBar::EnumWndProc(HWND hwnd, LPARAM lparam)
 
                entry._fsState = btn.fsState;
 
+#ifdef _ROS_   // now handled by activating the ARW_HIDE flag with SystemParametersInfo(SPI_SETMINIMIZEDMETRICS)
                 // move minimized windows out of sight
                if (IsIconic(hwnd)) {
                        RECT rect;
@@ -402,6 +461,7 @@ BOOL CALLBACK TaskBar::EnumWndProc(HWND hwnd, LPARAM lparam)
                        if (rect.bottom > 0)
                                SetWindowPos(hwnd, 0, -32000, -32000, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
                }
+#endif
        }
 
        return TRUE;
index bc1d4e0..76512ee 100644 (file)
@@ -84,7 +84,10 @@ protected:
        TaskBarMap      _map;
        int                     _next_id;
        WindowHandle _last_foreground_wnd;
-       int             _last_btn_width;
+       int                     _last_btn_width;
+       MINIMIZEDMETRICS _mmMetrics_org;
+
+       const UINT WM_SHELLHOOK;
 
        LRESULT Init(LPCREATESTRUCT pcs);
        LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
index 072e387..b77e639 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -104,13 +104,23 @@ NotifyInfo::NotifyInfo()
 #define        NID_SIZE_A5     (sizeof(NOTIFYICONDATAA)-sizeof(GUID))
 #define        NID_SIZE_A3     (sizeof(NOTIFYICONDATAA)-sizeof(GUID)-(128-64)*sizeof(CHAR))
 
-NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
+bool NotifyInfo::modify(NOTIFYICONDATA* pnid)
 {
-       _hWnd = pnid->hWnd;
-       _uID = pnid->uID;
+       bool changes = false;
 
-       if (pnid->uFlags & NIF_MESSAGE)
-               _uCallbackMessage = pnid->uCallbackMessage;
+       if (_hWnd!=pnid->hWnd || _uID!=pnid->uID) {
+               _hWnd = pnid->hWnd;
+               _uID = pnid->uID;
+
+               changes = true;
+       }
+
+       if (pnid->uFlags & NIF_MESSAGE) {
+               if (_uCallbackMessage != pnid->uCallbackMessage) {
+                       _uCallbackMessage = pnid->uCallbackMessage;
+                       changes = true;
+               }
+       }
 
        if (pnid->uFlags & NIF_ICON) {
                 // Some applications destroy the icon immediatelly after completing the
@@ -119,15 +129,25 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
                        DestroyIcon(_hIcon);
 
                _hIcon = (HICON) CopyImage(pnid->hIcon, IMAGE_ICON, NOTIFYICON_SIZE, NOTIFYICON_SIZE, 0);
+
+               changes = true; ///@todo compare icon
        }
 
 #ifdef NIF_STATE       // as of 21.08.2003 missing in MinGW headers
-       if (pnid->uFlags & NIF_STATE)
-               _dwState = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask);
+       if (pnid->uFlags & NIF_STATE) {
+               DWORD new_state = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask);
+
+               if (_dwState != new_state) {
+                       _dwState = new_state;
+                       changes = true;
+               }
+       }
 #endif
 
         // store tool tip text
-       if (pnid->uFlags & NIF_TIP)
+       if (pnid->uFlags & NIF_TIP) {
+               String new_text;
+
                if (pnid->cbSize==NID_SIZE_W6 || pnid->cbSize==NID_SIZE_W5 || pnid->cbSize==NID_SIZE_W3) {
                         // UNICODE version of NOTIFYICONDATA structure
                        LPCWSTR txt = (LPCWSTR)pnid->szTip;
@@ -139,7 +159,12 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
                                if (!txt[l])
                                        break;
 
-                       _tipText.assign(txt, l);
+                       new_text.assign(txt, l);
+
+                       if (new_text != _tipText) {
+                               _tipText = new_text;
+                               changes = true;
+                       }
                } else if (pnid->cbSize==NID_SIZE_A6 || pnid->cbSize==NID_SIZE_A5 || pnid->cbSize==NID_SIZE_A3) {
                        LPCSTR txt = (LPCSTR)pnid->szTip;
                        int max_len = pnid->cbSize==NID_SIZE_A3? 64: 128;
@@ -149,20 +174,35 @@ NotifyInfo& NotifyInfo::operator=(NOTIFYICONDATA* pnid)
                                if (!txt[l])
                                        break;
 
-                       _tipText.assign(txt, l);
+                       new_text.assign(txt, l);
+
+                       if (new_text != _tipText) {
+                               _tipText = new_text;
+                               changes = true;
+                       }
                }
+       }
 
        TCHAR title[MAX_PATH];
 
-       if (GetWindowText(_hWnd, title, MAX_PATH))
-               _windowTitle = title;
+       DWORD pid;
+       GetWindowThreadProcessId(_hWnd, &pid);
 
-       create_name();
+        // avoid to send WM_GETTEXT messages to the own process
+       if (pid != GetCurrentProcessId())
+               if (GetWindowText(_hWnd, title, MAX_PATH)) {
+                       if (_windowTitle != title) {
+                               _windowTitle = title;
+                               changes = true;
+                       }
+               }
 
-       ///@todo test for real changes
-       _lastChange = GetTickCount();
+       if (changes) {
+               create_name();
+               _lastChange = GetTickCount();
+       }
 
-       return *this;
+       return changes;
 }
 
 
@@ -194,7 +234,7 @@ static bool get_hide_clock_from_registry()
        bool hide_clock = false;
 
         // check if the clock should be hidden
-       if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) &&
+       if (!RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"), &hkeyStuckRects) &&
                !RegQueryValueEx(hkeyStuckRects, TEXT("Settings"), 0, NULL, (LPBYTE)buffer, &len) &&
                len==sizeof(buffer) && buffer[0]==sizeof(buffer))
                hide_clock = buffer[2] & 0x08? true: false;
@@ -338,7 +378,7 @@ HWND NotifyArea::Create(HWND hwndParent)
        ClientRect clnt(hwndParent);
 
        return Window::Create(WINDOW_CREATOR(NotifyArea), WS_EX_STATICEDGE,
-                                                       wcTrayNotify, TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE,
+                                                       wcTrayNotify, TITLE_TRAYNOTIFY, WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN,
                                                        clnt.right-(NOTIFYAREA_WIDTH_DEF+1), 1, NOTIFYAREA_WIDTH_DEF, clnt.bottom-2, hwndParent);
 }
 
@@ -448,7 +488,11 @@ LRESULT NotifyArea::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
                                                                (*AllowSetForegroundWindow)(pid);
                                                }
 
-                                               SendMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg);
+                                                // use PostMessage() for notifcation icons of Shell Service Objects in the own process
+                                               if (pid == GetCurrentProcessId())
+                                                       PostMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg);
+                                               else
+                                                       SendMessage(entry._hWnd, entry._uCallbackMessage, entry._uID, nmsg);
                                        }
                                }
                                else if (_icon_map.erase(entry))        // delete icons without valid owner window
@@ -511,13 +555,16 @@ int NotifyArea::Notify(int id, NMHDR* pnmh)
                        static ResString sShowIcons(IDS_SHOW_HIDDEN_ICONS);
                        static ResString sHideIcons(IDS_HIDE_ICONS);
 
-                       pdi->lpszText = (LPTSTR)(_show_hidden?sHideIcons:sShowIcons).c_str();
+                       pdi->lpszText = (LPTSTR)(_show_hidden? sHideIcons: sShowIcons).c_str();
                } else {
                        NotifyIconSet::iterator found = IconHitTest(pt);
 
                        if (found != _sorted_icons.end()) {
                                NotifyInfo& entry = const_cast<NotifyInfo&>(*found);    // Why does GCC 3.3 need this additional const_cast ?!
 
+                                // enable multiline tooltips (break at CR/LF and for very long one-line strings)
+                               SendMessage(pnmh->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 400);
+
                                pdi->lpszText = (LPTSTR)entry._tipText.c_str();
                        }
                }
@@ -540,18 +587,34 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni
          case NIM_ADD:
          case NIM_MODIFY:
                if ((int)pnid->uID >= 0) {      ///@todo This is a fix for Windows Task Manager.
-                       NotifyInfo& entry = _icon_map[pnid] = pnid;
+                       NotifyInfo& entry = _icon_map[pnid];
 
                         // a new entry?
                        if (entry._idx == -1)
                                entry._idx = ++_next_idx;
+               /* equivalent code using iterator::find();
+                       NotifyIconMap::iterator found = _icon_map.find(pnid);
+                       NotifyInfo* pentry;
+                        // a new entry?
+                       if (found == _icon_map.end()) {
+                               pentry = &_icon_map[pnid];
+                               pentry->_idx = ++_next_idx;
+                       } else {
+                               pentry = &found->second;
+                       }
+                       NotifyInfo& entry = *pentry;
+               */
+                       bool changes = entry.modify(pnid);
 
 #if NOTIFYICON_VERSION>=3      // as of 21.08.2003 missing in MinGW headers
-                       if (DetermineHideState(entry) && entry._mode==NIM_HIDE)
+                       if (DetermineHideState(entry) && entry._mode==NIM_HIDE) {
                                entry._dwState |= NIS_HIDDEN;
+                               changes = true;
+                       }
 #endif
 
-                       UpdateIcons();  ///@todo call only if really changes occurred
+                       if (changes)
+                               UpdateIcons();  ///@todo call only if really changes occurred
 
                        return TRUE;
                }
@@ -842,7 +905,7 @@ TrayNotifyDlg::TrayNotifyDlg(HWND hwnd)
                _show_hidden_org = _pNotifyArea->_show_hidden;
        }
 
-       SetWindowIcon(hwnd, IDI_REACTOS/*IDI_SEARCH*/);
+       SetWindowIcon(hwnd, IDI_REACTOS);
 
        _haccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_TRAYNOTIFY));
 
@@ -990,7 +1053,7 @@ void TrayNotifyDlg::InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyI
 void TrayNotifyDlg::InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyIconDlgInfo& entry,
                                                                HDC hdc, HICON hicon, NOTIFYICONMODE mode)
 {
-       int idx = _info.size();
+       int idx = _info.size() + 1;
        _info[idx] = entry;
 
        String mode_str = string_from_mode(mode);
@@ -1100,42 +1163,10 @@ int TrayNotifyDlg::Notify(int id, NMHDR* pnmh)
        switch(pnmh->code) {
          case TVN_SELCHANGED: {
                NMTREEVIEW* pnmtv = (NMTREEVIEW*)pnmh;
-               LPARAM lparam = pnmtv->itemNew.lParam;
-
-               if (lparam) {
-                       const NotifyIconDlgInfo& entry = _info[lparam];
-
-                       SetDlgItemText(_hwnd, IDC_NOTIFY_TOOLTIP, entry._tipText);
-                       SetDlgItemText(_hwnd, IDC_NOTIFY_TITLE, entry._windowTitle);
-                       SetDlgItemText(_hwnd, IDC_NOTIFY_MODULE, entry._modulePath);
-
-                       CheckRadioButton(_hwnd, IDC_NOTIFY_SHOW, IDC_NOTIFY_AUTOHIDE, IDC_NOTIFY_SHOW+entry._mode);
-
-                       String change_str;
-                       if (entry._lastChange)
-                               change_str.printf(TEXT("before %d s"), (GetTickCount()-entry._lastChange+500)/1000);
-                       SetDlgItemText(_hwnd, IDC_LAST_CHANGE, change_str);
-
-                       HICON hicon = 0; //get_window_icon_big(entry._hWnd, false);
-
-                        // If we could not find an icon associated with the owner window, try to load one from the owning module.
-                       if (!hicon && !entry._modulePath.empty()) {
-                               hicon = ExtractIcon(g_Globals._hInstance, entry._modulePath, 0);
-
-                               if (!hicon) {
-                                       SHFILEINFO sfi;
-
-                                       if (SHGetFileInfo(entry._modulePath, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_LARGEICON))
-                                               hicon = sfi.hIcon;
-                               }
-                       }
-
-                       if (hicon) {
-                               SendMessage(GetDlgItem(_hwnd, IDC_PICTURE), STM_SETICON, (LPARAM)hicon, 0);
-                               DestroyIcon(hicon);
-                       } else
-                               SendMessage(GetDlgItem(_hwnd, IDC_PICTURE), STM_SETICON, 0, 0);
+               int idx = pnmtv->itemNew.lParam;
 
+               if (idx) {
+                       RefreshProperties(_info[idx]);
                        _selectedItem = pnmtv->itemNew.hItem;
                } else {
                        /*
@@ -1151,14 +1182,48 @@ int TrayNotifyDlg::Notify(int id, NMHDR* pnmh)
        return 0;
 }
 
+void TrayNotifyDlg::RefreshProperties(const NotifyIconDlgInfo& entry)
+{
+       SetDlgItemText(_hwnd, IDC_NOTIFY_TOOLTIP, entry._tipText);
+       SetDlgItemText(_hwnd, IDC_NOTIFY_TITLE, entry._windowTitle);
+       SetDlgItemText(_hwnd, IDC_NOTIFY_MODULE, entry._modulePath);
+
+       CheckRadioButton(_hwnd, IDC_NOTIFY_SHOW, IDC_NOTIFY_AUTOHIDE, IDC_NOTIFY_SHOW+entry._mode);
+
+       String change_str;
+       if (entry._lastChange)
+               change_str.printf(TEXT("before %d s"), (GetTickCount()-entry._lastChange+500)/1000);
+       SetDlgItemText(_hwnd, IDC_LAST_CHANGE, change_str);
+
+       HICON hicon = 0; //get_window_icon_big(entry._hWnd, false);
+
+        // If we could not find an icon associated with the owner window, try to load one from the owning module.
+       if (!hicon && !entry._modulePath.empty()) {
+               hicon = ExtractIcon(g_Globals._hInstance, entry._modulePath, 0);
+
+               if (!hicon) {
+                       SHFILEINFO sfi;
+
+                       if (SHGetFileInfo(entry._modulePath, 0, &sfi, sizeof(sfi), SHGFI_ICON|SHGFI_LARGEICON))
+                               hicon = sfi.hIcon;
+               }
+       }
+
+       if (hicon) {
+               SendMessage(GetDlgItem(_hwnd, IDC_PICTURE), STM_SETICON, (LPARAM)hicon, 0);
+               DestroyIcon(hicon);
+       } else
+               SendMessage(GetDlgItem(_hwnd, IDC_PICTURE), STM_SETICON, 0, 0);
+}
+
 void TrayNotifyDlg::SetIconMode(NOTIFYICONMODE mode)
 {
-       LPARAM lparam = TreeView_GetItemData(_tree_ctrl, _selectedItem);
+       int idx = TreeView_GetItemData(_tree_ctrl, _selectedItem);
 
-       if (!lparam)
+       if (!idx)
                return;
 
-       NotifyIconConfig& entry = _info[lparam];
+       NotifyIconConfig& entry = _info[idx];
 
        if (entry._mode != mode) {
                entry._mode = mode;
@@ -1290,6 +1355,8 @@ void ClockWindow::Paint()
 {
        PaintCanvas canvas(_hwnd);
 
+       FillRect(canvas, &canvas.rcPaint, GetSysColorBrush(COLOR_BTNFACE));
+
        BkMode bkmode(canvas, TRANSPARENT);
        FontSelection font(canvas, GetStockFont(ANSI_VAR_FONT));
 
index 40dda6b..7d90406 100644 (file)
@@ -98,7 +98,7 @@ struct NotifyInfo : public NotifyIconIndex, public NotifyIconConfig
        friend bool operator<(const NotifyInfo& a, const NotifyInfo& b)
                {return a._idx < b._idx;}
 
-       NotifyInfo& operator=(NOTIFYICONDATA* pnid);
+       bool    modify(NOTIFYICONDATA* pnid);
 
        int             _idx;   // display index
        HICON   _hIcon;
@@ -230,6 +230,7 @@ protected:
        void    InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyInfo&, HDC);
        void    InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyIconDlgInfo&, HDC, HICON, NOTIFYICONMODE);
        void    SetIconMode(NOTIFYICONMODE mode);
+       void    RefreshProperties(const NotifyIconDlgInfo& entry);
 };
 
 
index 5e8f63d..8d6f9ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -281,11 +281,11 @@ String get_windows_version_str()
                } else {
                        TCHAR type[80];
                        DWORD dwBufLen;
-                       HKEY hKey;
+                       HKEY hkey;
 
-                       if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey)) {
-                               RegQueryValueEx(hKey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen);
-                               RegCloseKey(hKey);
+                       if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hkey)) {
+                               RegQueryValueEx(hkey, TEXT("ProductType"), NULL, NULL, (LPBYTE)type, &dwBufLen);
+                               RegCloseKey(hkey);
 
                                if (!_tcsicmp(TEXT("WINNT"), type))
                                   str += TEXT(" Workstation");
index c5de709..db8af0f 100644 (file)
@@ -59,6 +59,8 @@
 #define _MAX_PATH      260
 #endif
 
+#define        W_VER_NT 0      // constant for HIWORD(GetVersion())>>14
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -315,16 +317,22 @@ protected:
 struct Thread
 {
        Thread()
-        :      _alive(false)
+        :      _alive(false),
+               _destroy(false)
        {
                _hThread = INVALID_HANDLE_VALUE;
+               _evtFinish = CreateEvent(NULL, TRUE, FALSE, NULL);
        }
 
        virtual ~Thread()
        {
                Stop();
 
+               CloseHandle(_evtFinish);
                CloseHandle(_hThread);
+
+               if (_destroy)
+                       delete this;
        }
 
        void Start()
@@ -337,6 +345,8 @@ struct Thread
 
        void Stop()
        {
+               SetEvent(_evtFinish);
+
                if (_alive) {
                        {
                        Lock lock(_crit_sect);
@@ -358,7 +368,9 @@ protected:
        static DWORD WINAPI ThreadProc(void* para);
 
        HANDLE  _hThread;
+       HANDLE  _evtFinish;
        bool    _alive;
+       bool    _destroy;
 };
 
 
index bbeba49..11673f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003, 2004 Martin Fuchs
+ * Copyright 2003, 2004, 2005 Martin Fuchs
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -277,7 +277,7 @@ LRESULT CALLBACK Window::WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPAR
 
 LRESULT Window::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
-/*@@TODO: replaced by StartMenu::TrackStartmenu()
+/**@todo: replaced by StartMenu::TrackStartmenu()
        HWND hwnd = _hwnd;
 
         // close startup menu and other popup menus
@@ -352,7 +352,7 @@ LRESULT CALLBACK SubclassedWindow::SubclassedWndProc(HWND hwnd, UINT nmsg, WPARA
 
 LRESULT SubclassedWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
 {
-/*@@TODO: replaced by StartMenu::TrackStartmenu()
+/**@todo: replaced by StartMenu::TrackStartmenu()
         // close startup menu and other popup menus
         // This functionality is for tray notification icons missing in MS Windows.
        if (nmsg == WM_SETFOCUS)
index 4f71608..1e60a73 100644 (file)
@@ -984,6 +984,8 @@ enum {TRAYBUTTON_LEFT=0, TRAYBUTTON_RIGHT, TRAYBUTTON_MIDDLE};
 
 #define        WINMSG_TASKBARCREATED   TEXT("TaskbarCreated")
 
+#define        WINMSG_SHELLHOOK                TEXT("SHELLHOOK")
+
 
 struct TrayIcon
 {
index 1da629a..2d87601 100644 (file)
@@ -4,7 +4,7 @@
  //
  // xmlstorage.cpp
  //
- // Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
+ // Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs@gmx.net>
  //
 
 
index d57cd0c..8a0be9b 100644 (file)
@@ -4,7 +4,7 @@
  //
  // xmlstorage.h
  //
- // Copyright (c) 2004, Martin Fuchs <martin-fuchs@gmx.net>
+ // Copyright (c) 2004, 2005 Martin Fuchs <martin-fuchs@gmx.net>
  //
 
 
index 6b00bca..ec904da 100644 (file)
@@ -1,6 +1,8 @@
 <module name="format" type="win32cui" installbase="system32" installname="format.exe">\r
        <include base="format">.</include>\r
+       <define name="__USE_W32API" />\r
        <library>ntdll</library>\r
+       <library>kernel32</library>\r
        <library>fmifs</library>\r
        <file>format.c</file>\r
 </module>\r
index fdca1aa..29c17d2 100755 (executable)
@@ -14,7 +14,7 @@ TARGET_NAME = format
 
 TARGET_INSTALLDIR = system32
 
-TARGET_CFLAGS = -Werror -Wall -Wno-format
+TARGET_CFLAGS = -D__USE_W32API -Werror -Wall -Wno-format
 
 TARGET_OBJECTS = \
        $(TARGET_NAME).o
index 5c0054b..fbd51e8 100644 (file)
@@ -67,9 +67,9 @@ static const char UsageStr[] =
 "Copyright 2004 Vincent Béron\n";
 
 static const WCHAR ActionAdmin[] = {
-   'A','C','T','I','O','N','=','A','D','M','I','N',' ',0 };
+   'A','C','T','I','O','N','=','A','D','M','I','N',0 };
 static const WCHAR RemoveAll[] = {
-   'R','E','M','O','V','E','=','A','L','L',' ',0 };
+   'R','E','M','O','V','E','=','A','L','L',0 };
 
 static const WCHAR InstallRunOnce[] = {
    'S','o','f','t','w','a','r','e','\\',
index 5415e20..1e62287 100644 (file)
@@ -23,7 +23,7 @@ LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
 
 MAIN_MENU MENU
 {
- POPUP "&Filef" {
+ POPUP "&Fil" {
   MENUITEM "&Ny...",            CMD_NEW
   MENUITEM "Å&bn\tEnter",       CMD_OPEN
   MENUITEM "&Gem",              CMD_SAVE
@@ -58,7 +58,7 @@ POPUP "&Hj
   MENUITEM SEPARATOR
   POPUP "&Om Notesblok..." {
    MENUITEM "&Licens",          CMD_LICENSE
-   MENUITEM "&NO WARRANTY",     CMD_NO_WARRANTY
+   MENUITEM "&Ingen Garanti",   CMD_NO_WARRANTY
    MENUITEM "&Om WINE",         CMD_ABOUT_WINE
   }
  }
@@ -94,15 +94,15 @@ PUSHBUTTON    "&Hj
 STRINGTABLE DISCARDABLE
 {
 STRING_PAGESETUP_HEADERVALUE,   "&n"        /* FIXME */
-STRING_PAGESETUP_FOOTERVALUE,   "Page &s"   /* FIXME */
+STRING_PAGESETUP_FOOTERVALUE,   "Side &s"
 STRING_PAGESETUP_LEFTVALUE,             "20 mm"     /* FIXME */
 STRING_PAGESETUP_RIGHTVALUE,    "20 mm"     /* FIXME */
 STRING_PAGESETUP_TOPVALUE,              "25 mm"     /* FIXME */
 STRING_PAGESETUP_BOTTOMVALUE,   "25 mm"     /* FIXME */
 
 STRING_NOTEPAD,                                 "Notesblok"
-STRING_ERROR,                                   "FEJL"
-STRING_WARNING,                                 "ADVARSEL"
+STRING_ERROR,                                   "Fejl"
+STRING_WARNING,                                 "Advarsel"
 STRING_INFO,                                    "Information"
 
 STRING_UNTITLED,                                "(ikke-navngivet)"
@@ -114,10 +114,10 @@ STRING_TOOLARGE,                                "Filen '%s' er for stor til Note
 \nBrug en anden editor til at redigere filen."
 STRING_NOTEXT,                                  "Du har ikke skrevet noget tekst. \
 \nSkriv noget tekst, og prøv så igen"
-STRING_DOESNOTEXIST,                            "File '%s'\ndoes not exist\n\n \
-Do you want to create a new file ?"
-STRING_NOTSAVED,                                "File '%s'\nhas been modified\n\n \
-Would you like to save the changes ?"
+STRING_DOESNOTEXIST,                            "Filen '%s'\neksistere ikke\n\n \
+Ønkser du at oprette en ny fil?"
+STRING_NOTSAVED,                                "Filen '%s'\ner blevet ændret\n\n \
+Ønsker du at gemme ændringerne?"
 STRING_NOTFOUND,                                        "Kan ikke finde '%s'."
 STRING_OUT_OF_MEMORY,                   "Der er ikke nok hukommelse til at udføre \
 denne operation. \nAfslut et eller flere aktive programmer for at frigøre \
diff --git a/reactos/subsys/system/reactos/Sv.rc b/reactos/subsys/system/reactos/Sv.rc
new file mode 100644 (file)
index 0000000..5c3ae5e
--- /dev/null
@@ -0,0 +1,31 @@
+/*\r
+ *  Swedish (SE) resources\r
+ *\r
+ *  Copyright (C) 2005 David Nordenberg\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+/* String Tables */\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_CAPTION  "ReactOS installation"\r
+    IDS_TEXT     "Du kan inte installera ReactOS direkt från den här CDn!\n\n"\\r
+                 "Starta om datorn med hjälp av skivan för att installera ReactOS."\r
+END\r
+\r
+/* EOF */\r
index ca9be07..018699c 100644 (file)
@@ -18,5 +18,6 @@ IDI_MAIN ICON "res/reactos.ico"
 /* Language-specific resources */
 #include "De.rc"
 #include "En.rc"
+#include "Sv.rc"
 
 /* EOF */
index fffc280..1be85f5 100644 (file)
Binary files a/reactos/subsys/system/reactos/res/reactos.ico and b/reactos/subsys/system/reactos/res/reactos.ico differ
index 226da12..0ed32cc 100644 (file)
@@ -14,7 +14,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
 CAPTION "Error reporting assistant"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
 BEGIN\r
-  LTEXT "Please describe what you were trying to do when the error occurred.\n\nClick 'Next' to send the report to the ReacOS project or 'Cancel' to not send any information.",-1,10,0,225,40\r
+  LTEXT "Please describe what you were trying to do when the error occurred.\n\nClick 'Next' to send the report to the ReactOS project or 'Cancel' to not send any information.",-1,10,0,225,40\r
   LTEXT "Your e-mail address (optional):",-1,10,40,120,20\r
   EDITTEXT IDE_SUBMIT_REPORT_YOUR_EMAIL, 110,40,150,12\r
   LTEXT "Description of problem (optional):",-1,10,55,120,20\r
diff --git a/reactos/subsys/system/reporterror/dk.rc b/reactos/subsys/system/reporterror/dk.rc
new file mode 100644 (file)
index 0000000..e0b93b9
--- /dev/null
@@ -0,0 +1,54 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_FIRSTPAGE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Fejl Meddeler Assistenten"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Systemet er blev genoprettet fra en fejl.", -1, 115, 15, 160, 24
+  LTEXT "Ønsker du at indsende en fejl rapport til ReactOS Projektet?", -1, 115, 35, 160, 17
+END
+
+IDD_SUBMIT_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Fejl Meddeler Assistenten"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Beskriv venligst hvad du prøvede at gøre inden fejlen opstod.\n\nKlik på 'Næste' for at indsende rapporten til ReactOS Projektet eller 'Fortryd' for ikke at indsende nogle informationer.",-1,10,0,225,40
+  LTEXT "Din e-mail adresse (valgfri):",-1,10,40,120,20
+  EDITTEXT IDE_SUBMIT_REPORT_YOUR_EMAIL, 110,40,150,12
+  LTEXT "Beskrivelse af problemet (valgfri):",-1,10,55,120,20
+  EDITTEXT IDE_SUBMIT_REPORT_PROBLEM_DESCRIPTION,10,65,250,55,ES_WANTRETURN|ES_MULTILINE|ES_LEFT|WS_BORDER|WS_TABSTOP|WS_VSCROLL
+END
+
+IDD_SUBMITTING_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Fejl Meddeler Assistenten"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "{STATUS}",IDC_SUBMISSION_STATUS,25,58,225,8
+  CONTROL "", IDC_SUBMITTING_IN_PROGRESS, "msctls_progress32", PBS_MARQUEE | WS_CHILD | WS_VISIBLE | WS_BORDER, 25, 80, 225, 8
+END
+
+IDD_SUBMITTED_REPORT DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Fejl Meddeler Assistenten"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Din fejl rapport blev vellykket indsendt til ReactOS Projektet. Mange Tak.",-1,25,5,225,20
+END
+
+STRINGTABLE
+BEGIN
+  IDS_WIZARD_NAME "Rapporterings Fejl ved indsendelse til ReactOS Projektet"
+  IDS_FAILED_TO_CONTACT_SERVER "Systemet var ikke i stand til at kontakte Fejl Rapportings Serveren.\nVær venlig at sikre dig at dit system er forbundet til Internettet."
+  IDS_FAILED_TO_DELIVER_ERROR_REPORT "Systemet var ikke i stand til at levere Fejl Rapporten."
+END
+
+STRINGTABLE
+BEGIN
+  IDS_CONTACTING_SERVER "Kontakter Fejl Rapporterings Serveren Vent Venligst..."
+  IDS_FAILED_TO_INITIALIZE_WINSOCK "Fejl opstod da man forsøgte at initialisere Winsock 2.0 (Reactos Fejl Kode %d)"
+  IDS_FAILED_TO_LOCATE_SERVER "Kunne ikke komme i kontakt med Fejl Rapportings Serveren. Prøv Venligst igen Senere.."
+END
+
index fc0a113..eecc978 100644 (file)
@@ -16,3 +16,4 @@ IDB_HEADER    BITMAP "resources/header.bmp"
 \r
 #include "En.rc"\r
 #include "De.rc"\r
+#include "Dk.rc"\r
index 033e019..1835dca 100644 (file)
@@ -327,7 +327,7 @@ ScmCreateServiceDataBase(VOID)
                             NULL);
 
   Status = RtlpNtOpenKey(&ServicesKey,
-                        0x10001,
+                        KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
                         &ObjectAttributes,
                         0);
   if (!NT_SUCCESS(Status))
index 006eec4..3744287 100644 (file)
@@ -14,7 +14,7 @@ TARGET_SDKLIBS = ntdll.a kernel32.a user32.a
 
 TARGET_OBJECTS = $(TARGET_NAME).o database.o
 
-TARGET_CFLAGS = -Wall -Werror
+TARGET_CFLAGS = -D__USE_W32API -Wall -Werror
 
 include $(PATH_TO_TOP)/rules.mak
 
index 4db7c44..1a70ef1 100644 (file)
@@ -40,7 +40,7 @@
 #define NDEBUG
 #include <debug.h>
 
-
+int WINAPI RegisterServicesProcess(DWORD ServicesProcessId);
 
 /* GLOBALS ******************************************************************/
 
index f98776b..46004e1 100644 (file)
@@ -1,5 +1,6 @@
 <module name="services" type="win32cui">\r
        <include base="services">.</include>\r
+       <define name="__USE_W32API" />\r
        <library>ntdll</library>\r
        <library>kernel32</library>\r
        <library>user32</library>\r
diff --git a/reactos/subsys/system/sndvol32/Sv.rc b/reactos/subsys/system/sndvol32/Sv.rc
new file mode 100644 (file)
index 0000000..867d6f1
--- /dev/null
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Swedish (SE) resources\r
+/*\r
+ * Copyright 2005 David Nordenberg\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+IDM_MAINMENU MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "&Alternativ"\r
+    BEGIN\r
+        MENUITEM "&Inställningar", IDC_PROPERTIES\r
+        MENUITEM "A&vancerade kontroller", IDC_ADVANCED_CONTROLS\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Avsluta", IDC_EXIT\r
+    END\r
+    POPUP "&Hjälp"\r
+    BEGIN\r
+        MENUITEM "&Hjälpavsnitt", IDC_HELP_TOPICS\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Om ...", IDC_ABOUT\r
+    END\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_SNDVOL32       "Volymkontroll"\r
+    IDS_NOMIXERDEVICES "Det finns inga ljudmixningsenheter tillgängliga! Programmet kommer nu att avslutas."\r
+END\r
+\r
+IDD_PREFERENCES DIALOGEX 0, 0, 224, 250\r
+STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Inställningar"\r
+FONT 8, "MS Shell Dlg", 0, 0, 0x0\r
+BEGIN\r
+  LTEXT "&Mixerenhet:", -1, 7,8,48,9\r
+  COMBOBOX IDC_MIXERDEVICE, 55,8,162,80, CBS_DROPDOWNLIST | WS_TABSTOP\r
+  GROUPBOX "Justera volymen för:", -1, 7,25,211,77\r
+  PUSHBUTTON "&Uppspelning", IDC_PLAYBACK, 13,43,47,8, BS_AUTORADIOBUTTON\r
+  PUSHBUTTON "&Inspelning", IDC_RECORDING, 13,61,47,8, BS_AUTORADIOBUTTON\r
+  PUSHBUTTON "&Andra:", IDC_OTHER, 13,80,42,8, BS_AUTORADIOBUTTON | WS_DISABLED\r
+  COMBOBOX IDC_LINE, 55,80,155,50, CBS_DROPDOWNLIST | WS_TABSTOP | WS_DISABLED\r
+  \r
+  PUSHBUTTON "OK", IDOK, 114,226,50,14\r
+  PUSHBUTTON "Avbryt", IDCANCEL, 168,226,50,14\r
+END\r
index b729c75..addf9df 100644 (file)
@@ -15,4 +15,5 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 IDI_MAINAPP ICON DISCARDABLE resources/sndvol32.ico
 
 #include "En.rc"
-#include "DE.rc"
+#include "De.rc"
+#include "Sv.rc"
index ab07c1c..ad89236 100644 (file)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
-// Deutsch (Austria)
-// resources by Klemens Friedl   frik85 at hotmail dot com  http://www.reactos.net.tc
+// Deutsch
+// resource file by Klemens Friedl   (frik85@reactos.at; http://frik85.reactos.at)
 
 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
 #ifdef _WIN32
@@ -583,6 +583,7 @@ STRINGTABLE DISCARDABLE
 BEGIN
     IDS_APP_TITLE           "Task-Manager"
     IDC_TASKMGR             "Task-Manager"
+    IDS_IDLE_PROCESS        "Leerlaufprozess"
 END
 
 STRINGTABLE DISCARDABLE
@@ -649,5 +650,63 @@ BEGIN
     IDS_LICENSE             "Dieses Programm ist kostenlos; Sie können es frei verteilen mit od. ohne Änderungen unter der GNU Lesser General Public License wie es von der Free Software Foundation veröffentlicht wurde; entweder Version 2.1 der Lizenz, oder eine spätere Version (ihrer Wahl).\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."
 END
 
-#endif    // Deutsch (Austria) resources by Klemens Friedl
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TAB_APPS                  "Anwendnungen"
+    IDS_TAB_PROCESSES             "Prozesse"
+    IDS_TAB_PERFORMANCE           "Systemleistung"
+    IDS_TAB_TASK                  "Anwendung"
+    IDS_TAB_STATUS                "Status"
+    IDS_TAB_IMAGENAME             "Name"
+    IDS_TAB_PID                   "PID"
+    IDS_TAB_USERNAME              "Benutzername"
+    IDS_TAB_SESSIONID             "Sitzungserkennung"
+    IDS_TAB_CPU                   "CPU-Auslastung"
+    IDS_TAB_CPUTIME               "CPU-Zeit"
+    IDS_TAB_MEMUSAGE              "Speicherauslastung"
+    IDS_TAB_PEAKMEMUSAGE          "Veränd. der Speicherauslastung"
+    IDS_TAB_MEMDELTA              "Maximale Speicherauslastung"
+    IDS_TAB_PAGEFAULT             "Seitenfehler"
+    IDS_TAB_PFDELTA               "Maximale Seitenfehler"
+    IDS_TAB_VMSIZE                "Virtuelle Arbeitsspeichergröße"
+    IDS_TAB_PAGEDPOOL             "Paged Pool"
+    IDS_TAB_NPPOOL                "NP Pool"
+    IDS_TAB_BASEPRI               "Basispri"
+    IDS_TAB_HANDLES               "Handleanzahl"
+    IDS_TAB_THREADS               "Threadanzahl"
+    IDS_TAB_USERPBJECTS           "Benutzer-Objekte"
+    IDS_TAB_GDIOBJECTS            "GDI-Objekte"
+    IDS_TAB_IOREADS               "E/A (Lesen)"
+    IDS_TAB_IOWRITES              "E/A (Schreiben)"
+    IDS_TAB_IOOTHER               "E/A (Andere)"
+    IDS_TAB_IOREADBYTES           "E/A-Bytes (Lesen)"
+    IDS_TAB_IOWRITESBYTES         "E/A-Bytes (Schreiben)" 
+    IDS_TAB_IOOTHERBYTES          "E/A-Bytes (Andere)"
+    IDS_MENU_SELECTCOLUMNS        "&Spalten auswählen..."
+    IDS_MENU_16BITTASK            "&16-Bit-Tasks anzeigen"
+    IDS_MENU_WINDOWS              "&Fenster"
+    IDS_MENU_LARGEICONS           "&Große Symbole"
+    IDS_MENU_SMALLICONS           "Kl&eine Symbole"
+    IDS_MENU_DETAILS              "&Details"
+    IDS_MENU_ONEGRAPHALLCPUS      "&Alle CPUs in einem Diagramm"
+    IDS_MENU_ONEGRAPHPERCPU       "&Ein Diagramm pro CPU"
+    IDS_MENU_CPUHISTORY           "&CPU Verlauf"
+    IDS_MENU_SHOWKERNELTIMES      "&Kernel-Zeiten anzeigen"
+    IDS_CREATENEWTASK             "Neuen Task erstellen"
+    IDS_CREATENEWTASK_DESC        "Geben Sie Programme, Ordner, Dokumente oder Internetressourcen an, die geöffnet werden sollen."
+    IDS_MSG_ACCESSPROCESSAFF      "Unable to Access or Set Process Affinity"
+    IDS_MSG_PROCESSONEPRO         "Der Prozess muss eine Zugehörigkeit zu mindestens einem Prozessor aufweisen."
+    IDS_MSG_INVALIDOPTION         "Ungültige Auswahl"
+    IDS_MSG_UNABLEDEBUGPROCESS    "Unable to Debug Process"
+    IDS_MSG_WARNINGDEBUG          "WARNUNG: Das Debuggen dieses Prozesses kann zu Datenverlust führen.\nSind Sie sicher, dass Sie diesen Prozess debuggen möchten?"
+    IDS_MSG_TASKMGRWARNING        "Warnung vom Task-Manager"
+    IDS_MSG_WARNINGTERMINATING    "WARNUNG: Das Abbrechen eines Prozesses kann zu\nunerwünschten Ergebnissen, einschließlich Datenverlust und\nSysteminstabilität, führen. Zustand und Daten des Prozesses\nwerden nicht mher gespeichert. Sind Sie sicher, dass Sie\nden Prozess abbrechen möchten?"
+    IDS_MSG_UNABLETERMINATEPRO    "Unable to Terminate Process"
+    IDS_MSG_UNABLECHANGEPRIORITY  "Unable to Change Priority"
+    IDS_MSG_WARNINGCHANGEPRIORITY "WARNUNG: Das Ändern der Prioritätsklasse dieses Prozesses\nkann zu unerwünschten Ergebnissen, einschl. Systeminstabilität, führen.\nSind Sie sicher, dass Sie ändern möchten?"
+    IDS_MSG_TRAYICONCPUUSAGE      "CPU-Auslastung: %d%%"
+
+END
+
+#endif
 /////////////////////////////////////////////////////////////////////////////
diff --git a/reactos/subsys/system/taskmgr/Dk.rc b/reactos/subsys/system/taskmgr/Dk.rc
new file mode 100644 (file)
index 0000000..ddb7851
--- /dev/null
@@ -0,0 +1,622 @@
+/////////////////////////////////////////////////////////////////////////////
+// Danish resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_TASKMANAGER MENU DISCARDABLE
+BEGIN
+    POPUP "&Fil"
+    BEGIN
+        MENUITEM "&Ny Opgave (Kør...)",          ID_FILE_NEW
+        MENUITEM SEPARATOR
+        MENUITEM "A&slut Opgavestyring",          ID_FILE_EXIT
+    END
+    POPUP "&Indstillinger"
+    BEGIN
+        MENUITEM "&Altid Øverst",              ID_OPTIONS_ALWAYSONTOP
+        , CHECKED
+        MENUITEM "&Minimere Ved Brug",            ID_OPTIONS_MINIMIZEONUSE
+        , CHECKED
+        MENUITEM "&Skjul Når Minimeret",        ID_OPTIONS_HIDEWHENMINIMIZED
+        , CHECKED
+        MENUITEM "&Vis 16-bit Opgaver",          ID_OPTIONS_SHOW16BITTASKS
+        , CHECKED
+    END
+    POPUP "&Vis"
+    BEGIN
+        MENUITEM "&Opdatere Nu",                ID_VIEW_REFRESH
+        POPUP "&Opdaterings Hastighed"
+        BEGIN
+            MENUITEM "&Høj",                       ID_VIEW_UPDATESPEED_HIGH
+            MENUITEM "&Normal",                     ID_VIEW_UPDATESPEED_NORMAL
+            , CHECKED
+            MENUITEM "&Lav",                        ID_VIEW_UPDATESPEED_LOW
+            MENUITEM "&Pauset",                     ID_VIEW_UPDATESPEED_PAUSED
+
+        END
+        MENUITEM SEPARATOR
+        MENUITEM "St&ore Ikoner",                ID_VIEW_LARGE
+        MENUITEM "S&må Ikoner",                ID_VIEW_SMALL
+        MENUITEM "&Detaljer",                    ID_VIEW_DETAILS, CHECKED
+        MENUITEM "&Vælg Kolonner...",          ID_VIEW_SELECTCOLUMNS
+        POPUP "&CPU Historie"
+        BEGIN
+            MENUITEM "&En Graf, Alle CPUer",        ID_VIEW_CPUHISTORY_ONEGRAPHALL
+
+            MENUITEM "En Graf &Pr CPU",          ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU
+            , CHECKED
+        END
+        MENUITEM "&Vis Kernel Tider",          ID_VIEW_SHOWKERNELTIMES
+    END
+    POPUP "&Vinduer"
+    BEGIN
+        MENUITEM "Tile &Horisontalt",          ID_WINDOWS_TILEHORIZONTALLY
+        MENUITEM "Tile &Verticalt",            ID_WINDOWS_TILEVERTICALLY
+        MENUITEM "&Minimere",                   ID_WINDOWS_MINIMIZE
+        MENUITEM "Ma&ksimeree",                   ID_WINDOWS_MAXIMIZE
+        MENUITEM "&Cascade",                    ID_WINDOWS_CASCADE
+        MENUITEM "&Bring til front",             ID_WINDOWS_BRINGTOFRONT
+    END
+    POPUP "&Hjælp"
+    BEGIN
+        MENUITEM "Opgavestyring &Hjælpe Emner",   ID_HELP_TOPICS
+        MENUITEM SEPARATOR
+        MENUITEM "&Omkring Opgavestyring",         ID_HELP_ABOUT
+    END
+END
+
+IDR_WINDOWSMENU MENU DISCARDABLE
+BEGIN
+    MENUITEM "Tile &Horisontalt",          ID_WINDOWS_TILEHORIZONTALLY
+    MENUITEM "Tile &Verticalt",            ID_WINDOWS_TILEVERTICALLY
+    MENUITEM "&Minimere",                   ID_WINDOWS_MINIMIZE
+    MENUITEM "Ma&ksimere",                   ID_WINDOWS_MAXIMIZE
+    MENUITEM "&Detaljer",                    ID_WINDOWS_CASCADE
+    MENUITEM "&Bring til front",             ID_WINDOWS_BRINGTOFRONT
+END
+
+IDR_APPLICATION_PAGE_CONTEXT1 MENU DISCARDABLE
+BEGIN
+    POPUP "DUMMY"
+    BEGIN
+        MENUITEM "&Ny Opgave (Kør...)",          ID_FILE_NEW
+        MENUITEM SEPARATOR
+        MENUITEM "St&ore ikoner",                ID_VIEW_LARGE
+        MENUITEM "S&må Ikoner",                ID_VIEW_SMALL
+        MENUITEM "&Detaljer",                    ID_VIEW_DETAILS, CHECKED
+    END
+END
+
+IDR_APPLICATION_PAGE_CONTEXT2 MENU DISCARDABLE
+BEGIN
+    POPUP "DUMMY"
+    BEGIN
+        MENUITEM "&Skift Til",                  ID_APPLICATION_PAGE_SWITCHTO
+        MENUITEM "&Bring til front",             ID_WINDOWS_BRINGTOFRONT
+        MENUITEM SEPARATOR
+        MENUITEM "Tile &Horisontalt",          ID_WINDOWS_TILEHORIZONTALLY
+        MENUITEM "Tile &Verticalt",            ID_WINDOWS_TILEVERTICALLY
+        MENUITEM "&Minimere",                   ID_WINDOWS_MINIMIZE
+        MENUITEM "Ma&ksimere",                   ID_WINDOWS_MAXIMIZE
+        MENUITEM "&Cascade",                    ID_WINDOWS_CASCADE
+        MENUITEM SEPARATOR
+        MENUITEM "&Afslut Opgave",                   ID_APPLICATION_PAGE_ENDTASK
+        MENUITEM "&Gå Til Process",              ID_APPLICATION_PAGE_GOTOPROCESS
+
+    END
+END
+
+IDR_TRAY_POPUP MENU DISCARDABLE
+BEGIN
+    POPUP "DUMMY"
+    BEGIN
+        MENUITEM "&Gendan",                    ID_RESTORE
+        MENUITEM "&Luk",                      ID_FILE_EXIT
+        MENUITEM SEPARATOR
+        MENUITEM "&Altid Øverest",              ID_OPTIONS_ALWAYSONTOP
+    END
+END
+
+IDR_PROCESS_PAGE_CONTEXT MENU DISCARDABLE
+BEGIN
+    POPUP "DUMMY"
+    BEGIN
+        MENUITEM "&Afslut Process",                ID_PROCESS_PAGE_ENDPROCESS
+        MENUITEM "Afslut Process &Træ",           ID_PROCESS_PAGE_ENDPROCESSTREE
+
+        MENUITEM "&Debug",                      ID_PROCESS_PAGE_DEBUG
+        MENUITEM SEPARATOR
+        POPUP "Sæt &prioritet"
+        BEGIN
+            MENUITEM "&Højeste",                   ID_PROCESS_PAGE_SETPRIORITY_REALTIME
+
+            MENUITEM "&Høj",                       ID_PROCESS_PAGE_SETPRIORITY_HIGH
+
+            MENUITEM "&Over Normal",                ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
+
+            MENUITEM "&Normal",                     ID_PROCESS_PAGE_SETPRIORITY_NORMAL
+
+            MENUITEM "&Under Normal",                ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
+
+            MENUITEM "&Lav",                        ID_PROCESS_PAGE_SETPRIORITY_LOW
+
+        END
+        MENUITEM "Sæt &Affinitet...",            ID_PROCESS_PAGE_SETAFFINITY
+       MENUITEM "Redigere Debug &Kanaler...",  ID_PROCESS_PAGE_DEBUGCHANNELS
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE  22, 17, 259, 210
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "Omkring Opgavestyring"
+FONT 8, "Tahoma"
+BEGIN
+    CONTROL         "Opgavestyring v1.0\nKopibeskyttet (C) 1999 - 2001\naf Brian Palmer (brianp@reactos.org)",
+                    IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,53,28,
+                    122,26
+    DEFPUSHBUTTON   "OK",IDOK,183,189,44,14,WS_GROUP
+    ICON            IDI_TASKMANAGER,IDC_STATIC,19,30,20,20
+    EDITTEXT        IDC_LICENSE_EDIT,53,63,174,107,ES_MULTILINE |
+                    ES_READONLY | WS_VSCROLL
+END
+
+IDD_TASKMGR_DIALOG DIALOG DISCARDABLE  0, 0, 264, 246
+STYLE DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
+    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU |
+    WS_THICKFRAME
+CAPTION "Opgavestyring"
+MENU IDR_TASKMANAGER
+FONT 8, "Tahoma"
+BEGIN
+    CONTROL         "Tab1",IDC_TAB,"SysTabControl32",WS_TABSTOP,3,3,257,228
+END
+
+IDD_APPLICATION_PAGE DIALOG DISCARDABLE  0, 0, 247, 210
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
+FONT 8, "Tahoma"
+BEGIN
+    CONTROL         "List2",IDC_APPLIST,"SysListView32",LVS_REPORT |
+                    LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,233,177
+    PUSHBUTTON      "&Ny Opgave...",IDC_NEWTASK,187,189,53,14
+    PUSHBUTTON      "&Skift Til",IDC_SWITCHTO,131,189,53,14,WS_DISABLED
+    PUSHBUTTON      "&Afslut Opgave",IDC_ENDTASK,75,189,53,14,WS_DISABLED
+END
+
+IDD_PROCESS_PAGE DIALOG DISCARDABLE  0, 0, 247, 210
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
+CAPTION "KMK"
+FONT 8, "Tahoma"
+BEGIN
+    CONTROL         "List2",IDC_PROCESSLIST,"SysListView32",LVS_REPORT |
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_OWNERDATA |
+                    WS_BORDER | WS_TABSTOP,7,7,233,177
+    PUSHBUTTON      "&Afslut Proces",IDC_ENDPROCESS,171,189,69,14
+    CONTROL         "&Vis Processor fra alle brugere",IDC_SHOWALLPROCESSES,
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,191,111,10
+END
+
+//IDD_PERFORMANCE_PAGE DIALOGEX 0, 0, 247, 210
+IDD_PERFORMANCE_PAGE DIALOGEX DISCARDABLE  0, 0, 247, 210
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN
+FONT 8, "Tahoma"
+BEGIN
+    GROUPBOX        "CPU Forbrug",IDC_CPU_USAGE_FRAME,5,5,60,54,WS_TABSTOP, WS_EX_TRANSPARENT
+    GROUPBOX        "Hukommelse Forbrug",IDC_MEM_USAGE_FRAME,5,63,60,54,BS_LEFTTEXT, WS_EX_TRANSPARENT
+    GROUPBOX        "Ialt",IDC_TOTALS_FRAME,5,122,111,39,0,WS_EX_TRANSPARENT
+    GROUPBOX        "Aftaget Forbrug (K)",IDC_COMMIT_CHARGE_FRAME,5,166,111,39,0,WS_EX_TRANSPARENT
+    GROUPBOX        "Fysisk Hukommelse (K)",IDC_PHYSICAL_MEMORY_FRAME,131,122,111,39,0,WS_EX_TRANSPARENT
+    GROUPBOX        "Kernel Hukommelse (K)",IDC_KERNEL_MEMORY_FRAME,131,166,111,39,0,WS_EX_TRANSPARENT
+    LTEXT           "Håndtag",IDS_TOTALS_HANDLE_COUNT,12,131,27,8
+    LTEXT           "Tråde",IDS_TOTALS_THREAD_COUNT,12,140,27,8
+    LTEXT           "Processor",IDS_TOTALS_PROCESS_COUNT,12,149,34,8
+    EDITTEXT        IDC_TOTALS_HANDLE_COUNT,65,131,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_TOTALS_THREAD_COUNT,65,140,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_TOTALS_PROCESS_COUNT,65,149,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    LTEXT           "Ialt",IDS_COMMIT_CHARGE_TOTAL,12,175,27,8
+    LTEXT           "Begrænsning",IDS_COMMIT_CHARGE_LIMIT,12,184,15,8
+    LTEXT           "Top",IDS_COMMIT_CHARGE_PEAK,12,193,34,8
+    EDITTEXT        IDC_COMMIT_CHARGE_TOTAL,65,174,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_COMMIT_CHARGE_LIMIT,65,184,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_COMMIT_CHARGE_PEAK,65,193,45,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    LTEXT           "Ialt",IDS_PHYSICAL_MEMORY_TOTAL,137,131,27,8
+    LTEXT           "Tilgængelig",IDS_PHYSICAL_MEMORY_AVAILABLE,137,140,30,8
+    LTEXT           "System Cache",IDS_PHYSICAL_MEMORY_SYSTEM_CACHE,137,149,46,8
+    EDITTEXT        IDC_PHYSICAL_MEMORY_TOTAL,185,131,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_PHYSICAL_MEMORY_AVAILABLE,185,140,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_PHYSICAL_MEMORY_SYSTEM_CACHE,185,149,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    LTEXT           "Ialt",IDS_KERNEL_MEMORY_TOTAL,137,174,27,8
+    LTEXT           "Allokeret",IDS_KERNEL_MEMORY_PAGED,137,184,21,8
+    LTEXT           "Ikke Allokeret",IDS_KERNEL_MEMORY_NONPAGED,137,193,34,8
+    EDITTEXT        IDC_KERNEL_MEMORY_TOTAL,185,174,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_KERNEL_MEMORY_PAGED,185,184,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    EDITTEXT        IDC_KERNEL_MEMORY_NONPAGED,185,193,48,8,ES_RIGHT |
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER
+    GROUPBOX        "CPU Usage History",IDC_CPU_USAGE_HISTORY_FRAME,74,5,168,54,0,WS_EX_TRANSPARENT
+    GROUPBOX        "Hukommelses Forbrug Historik",IDC_MEMORY_USAGE_HISTORY_FRAME,74,63,168,54,0,WS_EX_TRANSPARENT
+    PUSHBUTTON      "CPU Forbrug Visning",IDC_CPU_USAGE_GRAPH,12,17,47,37,0,
+                   WS_EX_CLIENTEDGE
+    PUSHBUTTON      "Hukommelses Forbrug Visning",IDC_MEM_USAGE_GRAPH,12,75,47,37,0,
+                    WS_EX_CLIENTEDGE
+    PUSHBUTTON      "CPU Forbrug Historik",IDC_CPU_USAGE_HISTORY_GRAPH,81,17,
+                    153,37,0,WS_EX_CLIENTEDGE
+    PUSHBUTTON      "Hukommelses Forbrug Historik",IDC_MEM_USAGE_HISTORY_GRAPH,81,75,
+                    153,37,0,WS_EX_CLIENTEDGE
+END
+
+IDD_DEBUG_CHANNELS_DIALOG DIALOG DISCARDABLE  0, 0, 247, 210
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Debug Kanaler"
+FONT 8, "Tahoma"
+BEGIN
+    CONTROL         "List2",IDC_DEBUG_CHANNELS_LIST,"SysListView32",LVS_REPORT |
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP |
+                   LVS_SORTASCENDING,7,7,233,177
+    PUSHBUTTON      "Luk",IDOK,171,189,69,14
+END
+
+IDD_AFFINITY_DIALOG DIALOG DISCARDABLE  0, 0, 231, 154
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Processor Affinitet"
+FONT 8, "Tahoma"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,120,133,50,14
+    PUSHBUTTON      "Fortryd",IDCANCEL,174,133,50,14
+    LTEXT           "Processor Affinitets indstillingen kontrollere hvilken CPUer processen har lov at eksekvere på.",
+                    IDC_STATIC,5,5,220,16
+    CONTROL         "CPU 0",IDC_CPU0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+                    11,28,37,10
+    CONTROL         "CPU 1",IDC_CPU1,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,41,37,10
+    CONTROL         "CPU 2",IDC_CPU2,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,54,37,10
+    CONTROL         "CPU 3",IDC_CPU3,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,67,37,10
+    CONTROL         "CPU 4",IDC_CPU4,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,80,37,10
+    CONTROL         "CPU 5",IDC_CPU5,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,93,37,10
+    CONTROL         "CPU 6",IDC_CPU6,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,106,37,10
+    CONTROL         "CPU 7",IDC_CPU7,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,11,119,37,10
+    CONTROL         "CPU 8",IDC_CPU8,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,61,28,37,10
+    CONTROL         "CPU 9",IDC_CPU9,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+                    WS_TABSTOP,61,41,37,10
+    CONTROL         "CPU 10",IDC_CPU10,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,54,41,10
+    CONTROL         "CPU 11",IDC_CPU11,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,67,41,10
+    CONTROL         "CPU 12",IDC_CPU12,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,80,41,10
+    CONTROL         "CPU 13",IDC_CPU13,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,93,41,10
+    CONTROL         "CPU 14",IDC_CPU14,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,106,41,10
+    CONTROL         "CPU 15",IDC_CPU15,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,61,119,41,10
+    CONTROL         "CPU 16",IDC_CPU16,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,28,41,10
+    CONTROL         "CPU 17",IDC_CPU17,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,41,41,10
+    CONTROL         "CPU 18",IDC_CPU18,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,54,41,10
+    CONTROL         "CPU 19",IDC_CPU19,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,67,41,10
+    CONTROL         "CPU 20",IDC_CPU20,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,80,41,10
+    CONTROL         "CPU 21",IDC_CPU21,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,93,41,10
+    CONTROL         "CPU 22",IDC_CPU22,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,106,41,10
+    CONTROL         "CPU 23",IDC_CPU23,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,116,119,41,10
+    CONTROL         "CPU 24",IDC_CPU24,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,28,41,10
+    CONTROL         "CPU 25",IDC_CPU25,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,41,41,10
+    CONTROL         "CPU 26",IDC_CPU26,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,54,41,10
+    CONTROL         "CPU 27",IDC_CPU27,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,67,41,10
+    CONTROL         "CPU 28",IDC_CPU28,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,80,41,10
+    CONTROL         "CPU 29",IDC_CPU29,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,93,41,10
+    CONTROL         "CPU 30",IDC_CPU30,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,106,41,10
+    CONTROL         "CPU 31",IDC_CPU31,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,175,119,41,10
+END
+
+IDD_COLUMNS_DIALOG DIALOG DISCARDABLE  0, 0, 195, 199
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Vælg Kolonner"
+FONT 8, "Tahoma"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,84,178,50,14
+    PUSHBUTTON      "Fortryd",IDCANCEL,138,178,50,14
+    LTEXT           "Vælg de Kolonner som skal vises under Processor.",
+                    IDC_STATIC,7,7,181,17
+    CONTROL         "&Billede Navn",IDC_IMAGENAME,"Button",BS_AUTOCHECKBOX |
+                    WS_DISABLED | WS_TABSTOP,7,28,56,10
+    CONTROL         "&PID (Process Identifikation)",IDC_PID,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7, 39, 100, 10
+    CONTROL         "&CPU Forbrug",IDC_CPUUSAGE,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,50,53,10
+    CONTROL         "CPU &Tid",IDC_CPUTIME,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,61,48,10
+    CONTROL         "&Huk. Forbrug",IDC_MEMORYUSAGE,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,72,63,10
+    CONTROL         "Huk. Forbrug &Delta",IDC_MEMORYUSAGEDELTA,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,83,82,10
+    CONTROL         "To&p Huk. Forbrug",IDC_PEAKMEMORYUSAGE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,94,82,10
+    CONTROL         "Side &Fejl",IDC_PAGEFAULTS,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,105,53,10
+    CONTROL         "&USER Objektor",IDC_USEROBJECTS,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,116,62,10
+    CONTROL         "I/O Læsning",IDC_IOREADS,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,127,49,10
+    CONTROL         "I/O Læste Bytes",IDC_IOREADBYTES,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,138,65,10
+    CONTROL         "&Session ID",IDC_SESSIONID,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,149,50,10
+    CONTROL         "Bruger &Navn",IDC_USERNAME,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,7,160,51,10
+    CONTROL         "Side F&ejl Delta",IDC_PAGEFAULTSDELTA,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,28,72,10
+    CONTROL         "&Virtuel Huk. Størrelse",IDC_VIRTUALMEMORYSIZE,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,39,77,10
+    CONTROL         "Cach&ed Pool",IDC_PAGEDPOOL,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,50,53,10
+    CONTROL         "Ikke C&ached Pool",IDC_NONPAGEDPOOL,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,61,67,10
+    CONTROL         "Base P&rioritet",IDC_BASEPRIORITY,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,72,55,10
+    CONTROL         "Antal Af &Håndtag",IDC_HANDLECOUNT,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,83,59,10
+    CONTROL         "&Antal Af Tråde",IDC_THREADCOUNT,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,94,59,10
+    CONTROL         "GDI Objektor",IDC_GDIOBJECTS,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,105,55,10
+    CONTROL         "I/O Skrivning",IDC_IOWRITES,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,116,49,10
+    CONTROL         "I/O Skrevet Bytes",IDC_IOWRITEBYTES,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,127,65,10
+    CONTROL         "I/O Andet",IDC_IOOTHER,"Button",BS_AUTOCHECKBOX |
+                    WS_TABSTOP,107,138,46,10
+    CONTROL         "I/O Andre Bytes",IDC_IOOTHERBYTES,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,107,149,65,10
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""resource.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "resource.h\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 252
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 203
+    END
+
+    IDD_TASKMGR_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 3
+        RIGHTMARGIN, 260
+        TOPMARGIN, 3
+        BOTTOMMARGIN, 231
+    END
+
+    IDD_APPLICATION_PAGE, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 240
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 203
+    END
+
+    IDD_PROCESS_PAGE, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 240
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 203
+    END
+
+    IDD_PERFORMANCE_PAGE, DIALOG
+    BEGIN
+        LEFTMARGIN, 5
+        RIGHTMARGIN, 242
+        VERTGUIDE, 12
+        VERTGUIDE, 65
+        VERTGUIDE, 110
+        TOPMARGIN, 5
+        BOTTOMMARGIN, 205
+    END
+
+    IDD_AFFINITY_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 224
+        VERTGUIDE, 11
+        VERTGUIDE, 61
+        VERTGUIDE, 116
+        VERTGUIDE, 175
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 147
+        HORZGUIDE, 28
+        HORZGUIDE, 38
+        HORZGUIDE, 51
+        HORZGUIDE, 64
+        HORZGUIDE, 77
+        HORZGUIDE, 90
+        HORZGUIDE, 103
+        HORZGUIDE, 116
+        HORZGUIDE, 129
+    END
+
+    IDD_COLUMNS_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 188
+        VERTGUIDE, 107
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 192
+        HORZGUIDE, 28
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_APP_TITLE           "Opgavestyring"
+    IDC_TASKMGR             "Opgavestyring"
+    IDS_IDLE_PROCESS        "System Idle Process"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    ID_FILE_NEW             "Kører et nyt Program"
+    ID_OPTIONS_ALWAYSONTOP  "Opgavestyring bliver i front af alle de andre vinduer med mindre Opgavestyring er minimeret"
+    ID_OPTIONS_MINIMIZEONUSE
+                            "Opgavestyring er minimeret når en Gå til operation er fortaget"
+    ID_OPTIONS_HIDEWHENMINIMIZED "Skjul Opgavestyring ved minimering"
+    ID_VIEW_REFRESH         "Gennemtving Opgavestyring til at opdatere nu"
+    ID_VIEW_LARGE           "Vis Opgaver med store ikoner"
+    ID_VIEW_SMALL           "Vis Opgaver med små ikoner"
+    ID_VIEW_DETAILS         "Vis information om alle opgaver"
+    ID_VIEW_UPDATESPEED_HIGH "Opdatere visning 2 gange per sekund"
+    ID_VIEW_UPDATESPEED_NORMAL "Opdatere visning hvert 2 sekund"
+    ID_VIEW_UPDATESPEED_LOW "Opdatere visning hvert 4 sekund"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    ID_VIEW_UPDATESPEED_PAUSED "Opdatere ikke visning automatisk"
+    ID_WINDOWS_TILEHORIZONTALLY
+                            "Tiles the windows horizontally on the desktop"
+    ID_WINDOWS_TILEVERTICALLY "Tiles the windows vertically on the desktop"
+    ID_WINDOWS_MINIMIZE     "Minimizes the windows"
+    ID_WINDOWS_MAXIMIZE     "Maximizes the windows"
+    ID_WINDOWS_CASCADE      "Cascades the windows diagonally on the desktop"
+    ID_WINDOWS_BRINGTOFRONT "Brings the window front, but does not switch to it"
+    ID_HELP_TOPICS          "Viser Opgavestyring Hjælpe Emner"
+    ID_HELP_ABOUT           "Viser program information, version nummer, of kopibeskyttelse"
+    ID_FILE_EXIT            "Exits the Task Manager application"
+    ID_OPTIONS_SHOW16BITTASKS
+                            "Viser 16-bit opgaver som kører under ntvdm.exe"
+    ID_VIEW_SELECTCOLUMNS   "Vælg hvilke kolonner der vil være tilgængelig under Processor Siden"
+    ID_VIEW_SHOWKERNELTIMES "Viser kernel tider i performance graffen"
+    ID_VIEW_CPUHISTORY_ONEGRAPHALL
+                            "En enkelt Historie graf der viser det totale CPU forbrug"
+    ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU "Hver cpu har dens egen historie graf"
+    ID_APPLICATION_PAGE_SWITCHTO
+                            "Bringer opgaven til fronten, og skifter fokus til denne opgave"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    ID_ENDTASK              "Fortæller den valgt opgave at den skal lukkes"
+    ID_GOTOPROCESS          "Switches the focus to the process of the selected task"
+    ID_RESTORE              "Gendanner Opgavestyring fra sin skjule position"
+    ID_PROCESS_PAGE_ENDPROCESS "Removes the process from the system"
+    ID_PROCESS_PAGE_ENDPROCESSTREE
+                            "Removes this process and all descendants from the system"
+    ID_PROCESS_PAGE_DEBUG   "Attaches the debugger to this process"
+    ID_PROCESS_PAGE_SETAFFINITY
+                            "Kontrollere hvilken processorer processen er tilladt at køre på!"
+    ID_PROCESS_PAGE_SETPRIORITY_REALTIME
+                            "Sets process to the REALTIME priority class"
+    ID_PROCESS_PAGE_SETPRIORITY_HIGH "Sets process to the HIGH priority class"
+    ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
+                            "Sæt proces til Over Normal Priotet Klasse"
+    ID_PROCESS_PAGE_SETPRIORITY_NORMAL
+                            "Sæt proces til Normal Priotet Klasse"
+    ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
+                            "Sæt proces til Under Normal Priotet Klasse"
+    ID_PROCESS_PAGE_SETPRIORITY_LOW "Sæt proces til Lav Priotet Klasse"
+    IDS_LICENSE             "Dette program er fri software; du kan formidle det og/eller ændre det 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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
index 05188f9..9fa11c8 100644 (file)
@@ -538,6 +538,7 @@ STRINGTABLE DISCARDABLE
 BEGIN
     IDS_APP_TITLE           "Task Manager"
     IDC_TASKMGR             "Task Manager"
+    IDS_IDLE_PROCESS        "System Idle Process"
 END
 
 STRINGTABLE DISCARDABLE
@@ -604,6 +605,66 @@ BEGIN
     IDS_LICENSE             "This program 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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."
 END
 
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TAB_APPS                  "Applications"
+    IDS_TAB_PROCESSES             "Processes"
+    IDS_TAB_PERFORMANCE           "Performance"
+    IDS_TAB_TASK                  "Task"
+    IDS_TAB_STATUS                "Status"
+    IDS_TAB_IMAGENAME             "Image Name"
+    IDS_TAB_PID                   "PID"
+    IDS_TAB_USERNAME              "Username"
+    IDS_TAB_SESSIONID             "Session ID"
+    IDS_TAB_CPU                   "CPU"
+    IDS_TAB_CPUTIME               "CPU Time"
+    IDS_TAB_MEMUSAGE              "Mem Usage"
+    IDS_TAB_PEAKMEMUSAGE          "Peak Mem Usage"
+    IDS_TAB_MEMDELTA              "Mem Delta"
+    IDS_TAB_PAGEFAULT             "Page Faults"
+    IDS_TAB_PFDELTA               "PF Delta"
+    IDS_TAB_VMSIZE                "VM Size"
+    IDS_TAB_PAGEDPOOL             "Paged Pool"
+    IDS_TAB_NPPOOL                "NP Pool"
+    IDS_TAB_BASEPRI               "Base Pri"
+    IDS_TAB_HANDLES               "Handles"
+    IDS_TAB_THREADS               "Threads"
+    IDS_TAB_USERPBJECTS           "USER Objects"
+    IDS_TAB_GDIOBJECTS            "GDI Objects"
+    IDS_TAB_IOREADS               "I/O Reads"
+    IDS_TAB_IOWRITES              "I/O Writes"
+    IDS_TAB_IOOTHER               "I/O Other"
+    IDS_TAB_IOREADBYTES           "I/O Read Bytes"
+    IDS_TAB_IOWRITESBYTES         "I/O Write Bytes"
+    IDS_TAB_IOOTHERBYTES          "I/O Other Bytes"
+    IDS_MENU_SELECTCOLUMNS        "&Select Columns..."
+    IDS_MENU_16BITTASK            "&Show 16-bit tasks"
+    IDS_MENU_WINDOWS              "&Windows"
+    IDS_MENU_LARGEICONS           "Lar&ge Icons"
+    IDS_MENU_SMALLICONS           "S&mall Icons"
+    IDS_MENU_DETAILS              "&Details"
+    IDS_MENU_ONEGRAPHALLCPUS      "&One Graph, All CPUs"
+    IDS_MENU_ONEGRAPHPERCPU       "One Graph &Per CPU"
+    IDS_MENU_CPUHISTORY           "&CPU History"
+    IDS_MENU_SHOWKERNELTIMES      "&Show Kernel Times"
+    IDS_CREATENEWTASK             "Create New Task"
+    IDS_CREATENEWTASK_DESC        "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you."
+    IDS_MSG_ACCESSPROCESSAFF      "Unable to Access or Set Process Affinity"
+    IDS_MSG_PROCESSONEPRO         "The process must have affinity with at least one processor."
+    IDS_MSG_INVALIDOPTION         "Invalid Option"
+    IDS_MSG_UNABLEDEBUGPROCESS    "Unable to Debug Process"
+    IDS_MSG_WARNINGDEBUG          "WARNING: Debugging this process may result in loss of data.\nAre you sure you wish to attach the debugger?"
+    IDS_MSG_TASKMGRWARNING        "Task Manager Warning"
+    IDS_MSG_WARNINGTERMINATING    "WARNING: Terminating a process can cause undesired\nresults including loss of data and system instability. The\nprocess will not be given the chance to save its state or\ndata before it is terminated. Are you sure you want to\nterminate the process?"
+    IDS_MSG_UNABLETERMINATEPRO    "Unable to Terminate Process"
+    IDS_MSG_UNABLECHANGEPRIORITY  "Unable to Change Priority"
+    IDS_MSG_WARNINGCHANGEPRIORITY "WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"
+    IDS_MSG_TRAYICONCPUUSAGE      "CPU Usage: %d%%"
+
+END
+
+
 #endif    // English (U.S.) resources
 /////////////////////////////////////////////////////////////////////////////
 
index c0b2233..de594bd 100644 (file)
@@ -611,6 +611,7 @@ STRINGTABLE DISCARDABLE
 BEGIN
     IDS_APP_TITLE           "Administrador de Tareas"
     IDC_TASKMGR             "Administrador de Tareas"
+    IDS_IDLE_PROCESS        "System Idle Process"
 END
 
 STRINGTABLE DISCARDABLE
diff --git a/reactos/subsys/system/taskmgr/Sv.rc b/reactos/subsys/system/taskmgr/Sv.rc
new file mode 100644 (file)
index 0000000..9cd0205
--- /dev/null
@@ -0,0 +1,686 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Swedish (SE) resources\r
+/*\r
+ * Copyright 2005 David Nordenberg\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ */\r
\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SWE)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+#pragma code_page(850)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDR_TASKMANAGER MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "&Arkiv"\r
+    BEGIN\r
+        MENUITEM "&Ny Aktivitet (Kör...)",          ID_FILE_NEW\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Avsluta aktivitetshanteraren",          ID_FILE_EXIT\r
+    END\r
+    POPUP "&Alternativ"\r
+    BEGIN\r
+        MENUITEM "&Alltid överst",              ID_OPTIONS_ALWAYSONTOP\r
+        , CHECKED\r
+        MENUITEM "&Minimera vid användning",            ID_OPTIONS_MINIMIZEONUSE\r
+        , CHECKED\r
+        MENUITEM "&Göm minimerad",        ID_OPTIONS_HIDEWHENMINIMIZED\r
+        , CHECKED\r
+        MENUITEM "&Visa 16-bitarsaktiviteter",          ID_OPTIONS_SHOW16BITTASKS\r
+        , CHECKED\r
+    END\r
+    POPUP "&Visa"\r
+    BEGIN\r
+        MENUITEM "&Uppdatera",                ID_VIEW_REFRESH\r
+        POPUP "U&ppdateringshastighet"\r
+        BEGIN\r
+            MENUITEM "&Hög",                       ID_VIEW_UPDATESPEED_HIGH\r
+            MENUITEM "&Normal",                     ID_VIEW_UPDATESPEED_NORMAL\r
+            , CHECKED\r
+            MENUITEM "&Låg",                        ID_VIEW_UPDATESPEED_LOW\r
+            MENUITEM "&Fryst",                     ID_VIEW_UPDATESPEED_PAUSED\r
+\r
+        END\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Stora ikoner",                ID_VIEW_LARGE\r
+        MENUITEM "S&må ikoner",                ID_VIEW_SMALL\r
+        MENUITEM "&Detaljer",                    ID_VIEW_DETAILS, CHECKED\r
+        MENUITEM "&Välj kolumner...",          ID_VIEW_SELECTCOLUMNS\r
+        POPUP "&CPU Historik"\r
+        BEGIN\r
+            MENUITEM "En visare för &alla processorer",        ID_VIEW_CPUHISTORY_ONEGRAPHALL\r
+\r
+            MENUITEM "&En visare per processor",          ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU\r
+            , CHECKED\r
+        END\r
+        MENUITEM "&Visa kernel-tider",          ID_VIEW_SHOWKERNELTIMES\r
+    END\r
+    POPUP "&Fönster"\r
+    BEGIN\r
+        MENUITEM "Ordna &horizontellt",          ID_WINDOWS_TILEHORIZONTALLY\r
+        MENUITEM "Ordna &vertikalt",            ID_WINDOWS_TILEVERTICALLY\r
+        MENUITEM "&Minimera",                   ID_WINDOWS_MINIMIZE\r
+        MENUITEM "Ma&ximera",                   ID_WINDOWS_MAXIMIZE\r
+        MENUITEM "&Överlappande",                    ID_WINDOWS_CASCADE\r
+        MENUITEM "&För till förgrunden",             ID_WINDOWS_BRINGTOFRONT\r
+    END\r
+    POPUP "&Hjälp"\r
+    BEGIN\r
+        MENUITEM "Aktivitetshanteraren &hjälpavsnitt",   ID_HELP_TOPICS\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Om Aktivitetshanteraren",         ID_HELP_ABOUT\r
+    END\r
+END\r
+\r
+IDR_WINDOWSMENU MENU DISCARDABLE\r
+BEGIN\r
+    MENUITEM "Ordna &horizontellt",          ID_WINDOWS_TILEHORIZONTALLY\r
+    MENUITEM "Ordna &vertikalt",            ID_WINDOWS_TILEVERTICALLY\r
+    MENUITEM "&Minimera",                   ID_WINDOWS_MINIMIZE\r
+    MENUITEM "Ma&ximera",                   ID_WINDOWS_MAXIMIZE\r
+    MENUITEM "&Överlappande",                    ID_WINDOWS_CASCADE\r
+    MENUITEM "&För till förgrunden",             ID_WINDOWS_BRINGTOFRONT\r
+END\r
+\r
+IDR_APPLICATION_PAGE_CONTEXT1 MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "DUMMY"\r
+    BEGIN\r
+        MENUITEM "&Ny aktivitet (Kör...)",          ID_FILE_NEW\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Stora ikoner",                ID_VIEW_LARGE\r
+        MENUITEM "S&må ikoner",                ID_VIEW_SMALL\r
+        MENUITEM "&Detaljer",                    ID_VIEW_DETAILS, CHECKED\r
+    END\r
+END\r
+\r
+IDR_APPLICATION_PAGE_CONTEXT2 MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "DUMMY"\r
+    BEGIN\r
+        MENUITEM "&Växla till",                  ID_APPLICATION_PAGE_SWITCHTO\r
+        MENUITEM "&För till förgrunden",             ID_WINDOWS_BRINGTOFRONT\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "Ordna &horizontellt",          ID_WINDOWS_TILEHORIZONTALLY\r
+        MENUITEM "Ordna &vertikalt",            ID_WINDOWS_TILEVERTICALLY\r
+        MENUITEM "&Minimera",                   ID_WINDOWS_MINIMIZE\r
+        MENUITEM "Ma&ximera",                   ID_WINDOWS_MAXIMIZE\r
+        MENUITEM "&Överlappande",                    ID_WINDOWS_CASCADE\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Avsluta aktiviteten",                   ID_APPLICATION_PAGE_ENDTASK\r
+        MENUITEM "&Gå till process",              ID_APPLICATION_PAGE_GOTOPROCESS\r
+\r
+    END\r
+END\r
+\r
+IDR_TRAY_POPUP MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "DUMMY"\r
+    BEGIN\r
+        MENUITEM "&Återställ",                    ID_RESTORE\r
+        MENUITEM "&Stäng",                      ID_FILE_EXIT\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Alltid överst",              ID_OPTIONS_ALWAYSONTOP\r
+    END\r
+END\r
+\r
+IDR_PROCESS_PAGE_CONTEXT MENU DISCARDABLE\r
+BEGIN\r
+    POPUP "DUMMY"\r
+    BEGIN\r
+        MENUITEM "&Avsluta process",                ID_PROCESS_PAGE_ENDPROCESS\r
+        MENUITEM "Avsluta process&träd",           ID_PROCESS_PAGE_ENDPROCESSTREE\r
+\r
+        MENUITEM "&Felsök",                      ID_PROCESS_PAGE_DEBUG\r
+        MENUITEM SEPARATOR\r
+        POPUP "Ändra &prioritet"\r
+        BEGIN\r
+            MENUITEM "&Realtid",                   ID_PROCESS_PAGE_SETPRIORITY_REALTIME\r
+\r
+            MENUITEM "&Hög",                       ID_PROCESS_PAGE_SETPRIORITY_HIGH\r
+\r
+            MENUITEM "&Över normal",                ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL\r
+\r
+            MENUITEM "&Normal",                     ID_PROCESS_PAGE_SETPRIORITY_NORMAL\r
+\r
+            MENUITEM "&Under normal",                ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL\r
+\r
+            MENUITEM "&Låg",                        ID_PROCESS_PAGE_SETPRIORITY_LOW\r
+\r
+        END\r
+        MENUITEM "Välj &källa (FIXME)...",            ID_PROCESS_PAGE_SETAFFINITY\r
+       MENUITEM "Ändra felsökningskanaler...", ID_PROCESS_PAGE_DEBUGCHANNELS\r
+    END\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_ABOUTBOX DIALOG DISCARDABLE  22, 17, 259, 210\r
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Om Aktivitetshanteraren"\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    CONTROL         "Aktivitetshanteraren v1.0\nCopyright (C) 1999 - 2001\nby Brian Palmer (brianp@reactos.org)",\r
+                    IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,53,28,\r
+                    122,26\r
+    DEFPUSHBUTTON   "OK",IDOK,183,189,44,14,WS_GROUP\r
+    ICON            IDI_TASKMANAGER,IDC_STATIC,19,30,20,20\r
+    EDITTEXT        IDC_LICENSE_EDIT,53,63,174,107,ES_MULTILINE |\r
+                    ES_READONLY | WS_VSCROLL\r
+END\r
+\r
+IDD_TASKMGR_DIALOG DIALOG DISCARDABLE  0, 0, 264, 246\r
+STYLE DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |\r
+    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU |\r
+    WS_THICKFRAME\r
+CAPTION "Aktivitetshanteraren"\r
+MENU IDR_TASKMANAGER\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    CONTROL         "Tab1",IDC_TAB,"SysTabControl32",WS_TABSTOP,3,3,257,228\r
+END\r
+\r
+IDD_APPLICATION_PAGE DIALOG DISCARDABLE  0, 0, 247, 210\r
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    CONTROL         "List2",IDC_APPLIST,"SysListView32",LVS_REPORT |\r
+                    LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,233,177\r
+    PUSHBUTTON      "&Ny aktivitet...",IDC_NEWTASK,175,189,65,14\r
+    PUSHBUTTON      "&Växla till",IDC_SWITCHTO,120,189,53,14,WS_DISABLED\r
+    PUSHBUTTON      "&Avsluta aktiviteten",IDC_ENDTASK,34,189,83,14,WS_DISABLED\r
+END\r
+\r
+IDD_PROCESS_PAGE DIALOG DISCARDABLE  0, 0, 247, 210\r
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    CONTROL         "List2",IDC_PROCESSLIST,"SysListView32",LVS_REPORT |\r
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_OWNERDATA |\r
+                    WS_BORDER | WS_TABSTOP,7,7,233,177\r
+    PUSHBUTTON      "&Avsluta process",IDC_ENDPROCESS,171,189,69,14\r
+    CONTROL         "&Visa processer från alla användare",IDC_SHOWALLPROCESSES,\r
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,191,156,10\r
+END\r
+\r
+//IDD_PERFORMANCE_PAGE DIALOGEX 0, 0, 247, 210\r
+IDD_PERFORMANCE_PAGE DIALOGEX DISCARDABLE  0, 0, 247, 210\r
+STYLE DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    GROUPBOX        "Processoranv.",IDC_CPU_USAGE_FRAME,5,5,60,54,WS_TABSTOP, WS_EX_TRANSPARENT\r
+    GROUPBOX        "Minnesanv.",IDC_MEM_USAGE_FRAME,5,63,60,54,BS_LEFTTEXT, WS_EX_TRANSPARENT\r
+    GROUPBOX        "Totalt",IDC_TOTALS_FRAME,5,122,111,39,0,WS_EX_TRANSPARENT\r
+    GROUPBOX        "Upptaget minne (K)",IDC_COMMIT_CHARGE_FRAME,5,166,111,39,0,WS_EX_TRANSPARENT\r
+    GROUPBOX        "Fysiskt minne (K)",IDC_PHYSICAL_MEMORY_FRAME,131,122,111,39,0,WS_EX_TRANSPARENT\r
+    GROUPBOX        "Kernel minne (K)",IDC_KERNEL_MEMORY_FRAME,131,166,111,39,0,WS_EX_TRANSPARENT\r
+    LTEXT           "Referenser",IDS_TOTALS_HANDLE_COUNT,12,131,41,8\r
+    LTEXT           "Trådar",IDS_TOTALS_THREAD_COUNT,12,140,27,8\r
+    LTEXT           "Processer",IDS_TOTALS_PROCESS_COUNT,12,149,36,8\r
+    EDITTEXT        IDC_TOTALS_HANDLE_COUNT,65,131,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_TOTALS_THREAD_COUNT,65,140,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_TOTALS_PROCESS_COUNT,65,149,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    LTEXT           "Totalt",IDS_COMMIT_CHARGE_TOTAL,12,175,27,8\r
+    LTEXT           "Gräns",IDS_COMMIT_CHARGE_LIMIT,12,184,21,8\r
+    LTEXT           "Topp",IDS_COMMIT_CHARGE_PEAK,12,193,34,8\r
+    EDITTEXT        IDC_COMMIT_CHARGE_TOTAL,65,174,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_COMMIT_CHARGE_LIMIT,65,184,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_COMMIT_CHARGE_PEAK,65,193,45,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    LTEXT           "Totalt",IDS_PHYSICAL_MEMORY_TOTAL,137,131,27,8\r
+    LTEXT           "Tillgängligt",IDS_PHYSICAL_MEMORY_AVAILABLE,137,140,46,8\r
+    LTEXT           "Systemcache",IDS_PHYSICAL_MEMORY_SYSTEM_CACHE,137,149,46,8\r
+    EDITTEXT        IDC_PHYSICAL_MEMORY_TOTAL,185,131,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_PHYSICAL_MEMORY_AVAILABLE,185,140,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_PHYSICAL_MEMORY_SYSTEM_CACHE,185,149,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    LTEXT           "Totalt",IDS_KERNEL_MEMORY_TOTAL,137,174,27,8\r
+    LTEXT           "Växlat",IDS_KERNEL_MEMORY_PAGED,137,184,24,8\r
+    LTEXT           "Icke växlat",IDS_KERNEL_MEMORY_NONPAGED,137,193,44,8\r
+    EDITTEXT        IDC_KERNEL_MEMORY_TOTAL,185,174,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_KERNEL_MEMORY_PAGED,185,184,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    EDITTEXT        IDC_KERNEL_MEMORY_NONPAGED,185,193,48,8,ES_RIGHT |\r
+                    ES_READONLY | ES_NUMBER | NOT WS_BORDER\r
+    GROUPBOX        "Processorhistorik",IDC_CPU_USAGE_HISTORY_FRAME,74,5,168,54,0,WS_EX_TRANSPARENT\r
+    GROUPBOX        "Minneshistorik",IDC_MEMORY_USAGE_HISTORY_FRAME,74,63,168,54,0,WS_EX_TRANSPARENT\r
+    PUSHBUTTON      "Processoranvändning",IDC_CPU_USAGE_GRAPH,12,17,47,37,0,\r
+                   WS_EX_CLIENTEDGE\r
+    PUSHBUTTON      "Minnesanvändning",IDC_MEM_USAGE_GRAPH,12,75,47,37,0,\r
+                    WS_EX_CLIENTEDGE\r
+    PUSHBUTTON      "Processorhistorik",IDC_CPU_USAGE_HISTORY_GRAPH,81,17,\r
+                    153,37,0,WS_EX_CLIENTEDGE\r
+    PUSHBUTTON      "Minneshistorik",IDC_MEM_USAGE_HISTORY_GRAPH,81,75,\r
+                    153,37,0,WS_EX_CLIENTEDGE\r
+END\r
+\r
+IDD_DEBUG_CHANNELS_DIALOG DIALOG DISCARDABLE  0, 0, 247, 210\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Felsökningskanaler"\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    CONTROL         "List2",IDC_DEBUG_CHANNELS_LIST,"SysListView32",LVS_REPORT |\r
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP |\r
+                   LVS_SORTASCENDING,7,7,233,177\r
+    PUSHBUTTON      "Stäng",IDOK,171,189,69,14\r
+END\r
+\r
+IDD_AFFINITY_DIALOG DIALOG DISCARDABLE  0, 0, 231, 154\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Processorsamhörighet"\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    DEFPUSHBUTTON   "OK",IDOK,120,133,50,14\r
+    PUSHBUTTON      "Avbryt",IDCANCEL,174,133,50,14\r
+    LTEXT           "Processorsamhörighets-inställningen bestämmer vilka processorer processen tillåts exekvera på",\r
+                    IDC_STATIC,5,5,220,16\r
+    CONTROL         "Processor 0",IDC_CPU0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,\r
+                    6,28,55,10\r
+    CONTROL         "Processor 1",IDC_CPU1,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,41,55,10\r
+    CONTROL         "Processor 2",IDC_CPU2,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,54,55,10\r
+    CONTROL         "Processor 3",IDC_CPU3,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,67,55,10\r
+    CONTROL         "Processor 4",IDC_CPU4,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,80,55,10\r
+    CONTROL         "Processor 5",IDC_CPU5,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,93,55,10\r
+    CONTROL         "Processor 6",IDC_CPU6,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,106,55,10\r
+    CONTROL         "Processor 7",IDC_CPU7,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,6,119,55,10\r
+    CONTROL         "Processor 8",IDC_CPU8,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,61,28,55,10\r
+    CONTROL         "Processor 9",IDC_CPU9,"Button",BS_AUTOCHECKBOX | WS_DISABLED |\r
+                    WS_TABSTOP,61,41,55,10\r
+    CONTROL         "Processor 10",IDC_CPU10,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,54,55,10\r
+    CONTROL         "Processor 11",IDC_CPU11,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,67,55,10\r
+    CONTROL         "Processor 12",IDC_CPU12,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,80,55,10\r
+    CONTROL         "Processor 13",IDC_CPU13,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,93,55,10\r
+    CONTROL         "Processor 14",IDC_CPU14,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,106,55,10\r
+    CONTROL         "Processor 15",IDC_CPU15,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,61,119,55,10\r
+    CONTROL         "Processor 16",IDC_CPU16,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,28,55,10\r
+    CONTROL         "Processor 17",IDC_CPU17,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,41,55,10\r
+    CONTROL         "Processor 18",IDC_CPU18,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,54,55,10\r
+    CONTROL         "Processor 19",IDC_CPU19,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,67,55,10\r
+    CONTROL         "Processor 20",IDC_CPU20,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,80,55,10\r
+    CONTROL         "Processor 21",IDC_CPU21,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,93,55,10\r
+    CONTROL         "Processor 22",IDC_CPU22,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,106,55,10\r
+    CONTROL         "Processor 23",IDC_CPU23,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,116,119,55,10\r
+    CONTROL         "Processor 24",IDC_CPU24,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,28,55,10\r
+    CONTROL         "Processor 25",IDC_CPU25,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,41,55,10\r
+    CONTROL         "Processor 26",IDC_CPU26,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,54,55,10\r
+    CONTROL         "Processor 27",IDC_CPU27,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,67,55,10\r
+    CONTROL         "Processor 28",IDC_CPU28,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,80,55,10\r
+    CONTROL         "Processor 29",IDC_CPU29,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,93,55,10\r
+    CONTROL         "Processor 30",IDC_CPU30,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,106,55,10\r
+    CONTROL         "Processor 31",IDC_CPU31,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,175,119,55,10\r
+END\r
+\r
+IDD_COLUMNS_DIALOG DIALOG DISCARDABLE  0, 0, 275, 199\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Välj kolumner"\r
+FONT 8, "Tahoma"\r
+BEGIN\r
+    DEFPUSHBUTTON   "OK",IDOK,84,178,50,14\r
+    PUSHBUTTON      "Avbryt",IDCANCEL,138,178,50,14\r
+    LTEXT           "Välj de kolumner som skall synas på process-sidan i Aktivitetshanteraren.",\r
+                    IDC_STATIC,7,7,181,17\r
+    CONTROL         "&Processnamn",IDC_IMAGENAME,"Button",BS_AUTOCHECKBOX |\r
+                    WS_DISABLED | WS_TABSTOP,7,28,60,10\r
+    CONTROL         "P&ID (Processidentifierare)",IDC_PID,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,39,119,10\r
+    CONTROL         "Processoranvändnin&g",IDC_CPUUSAGE,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,50,89,10\r
+    CONTROL         "Pro&cessortid",IDC_CPUTIME,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,61,62,10\r
+    CONTROL         "&Minnesanvändning",IDC_MEMORYUSAGE,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,72,77,10\r
+    CONTROL         "Minnesanvändnings&förändring",IDC_MEMORYUSAGEDELTA,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,83,121,10\r
+    CONTROL         "T&oppvärde minnesanvändning",IDC_PEAKMEMORYUSAGE,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,94,121,10\r
+    CONTROL         "&Sidfel",IDC_PAGEFAULTS,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,105,56,10\r
+    CONTROL         "&USER Objekt",IDC_USEROBJECTS,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,116,64,10\r
+    CONTROL         "Antal I/O-l&äsningar",IDC_IOREADS,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,127,88,10\r
+    CONTROL         "I/O, anta&l tecken lästa",IDC_IOREADBYTES,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,7,138,119,10\r
+    CONTROL         "Sessions-I&D",IDC_SESSIONID,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,149,58,10\r
+    CONTROL         "Användar&namn",IDC_USERNAME,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,7,160,62,10\r
+    CONTROL         "Sidfelsf&örändring",IDC_PAGEFAULTSDELTA,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,28,82,10\r
+    CONTROL         "Storl&ek i virtuella minnet",IDC_VIRTUALMEMORYSIZE,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,39,116,10\r
+    CONTROL         "Växlings&bar pool",IDC_PAGEDPOOL,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,50,76,10\r
+    CONTROL         "Ic&ke växlingsbar pool",IDC_NONPAGEDPOOL,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,61,96,10\r
+    CONTROL         "&Basprioritet",IDC_BASEPRIORITY,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,72,60,10\r
+    CONTROL         "Antal referenser (&handles)",IDC_HANDLECOUNT,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,83,117,10\r
+    CONTROL         "Antal tr&ådar",IDC_THREADCOUNT,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,94,60,10\r
+    CONTROL         "GDI-ob&jekt",IDC_GDIOBJECTS,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,105,52,10\r
+    CONTROL         "An&tal I/O-Skrivningar",IDC_IOWRITES,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,116,97,10\r
+    CONTROL         "I/O, &antal tecken skrivna",IDC_IOWRITEBYTES,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,127,113,10\r
+    CONTROL         "And&ra I/O åtgärder",IDC_IOOTHER,"Button",BS_AUTOCHECKBOX |\r
+                    WS_TABSTOP,133,138,89,10\r
+    CONTROL         "Antal tecken, andra I/O åtgärder",IDC_IOOTHERBYTES,"Button",\r
+                    BS_AUTOCHECKBOX | WS_TABSTOP,133,149,141,10\r
+END\r
+\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+2 TEXTINCLUDE DISCARDABLE\r
+BEGIN\r
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"\r
+    "#include ""windows.h""\r\n"\r
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"\r
+    "#include ""resource.h""\r\n"\r
+    "\0"\r
+END\r
+\r
+3 TEXTINCLUDE DISCARDABLE\r
+BEGIN\r
+    "\r\n"\r
+    "\0"\r
+END\r
+\r
+1 TEXTINCLUDE DISCARDABLE\r
+BEGIN\r
+    "resource.h\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO DISCARDABLE\r
+BEGIN\r
+    IDD_ABOUTBOX, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 252\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 203\r
+    END\r
+\r
+    IDD_TASKMGR_DIALOG, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 3\r
+        RIGHTMARGIN, 260\r
+        TOPMARGIN, 3\r
+        BOTTOMMARGIN, 231\r
+    END\r
+\r
+    IDD_APPLICATION_PAGE, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 240\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 203\r
+    END\r
+\r
+    IDD_PROCESS_PAGE, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 240\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 203\r
+    END\r
+\r
+    IDD_PERFORMANCE_PAGE, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 5\r
+        RIGHTMARGIN, 242\r
+        VERTGUIDE, 12\r
+        VERTGUIDE, 65\r
+        VERTGUIDE, 110\r
+        TOPMARGIN, 5\r
+        BOTTOMMARGIN, 205\r
+    END\r
+\r
+    IDD_AFFINITY_DIALOG, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 224\r
+        VERTGUIDE, 11\r
+        VERTGUIDE, 61\r
+        VERTGUIDE, 116\r
+        VERTGUIDE, 175\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 147\r
+        HORZGUIDE, 28\r
+        HORZGUIDE, 38\r
+        HORZGUIDE, 51\r
+        HORZGUIDE, 64\r
+        HORZGUIDE, 77\r
+        HORZGUIDE, 90\r
+        HORZGUIDE, 103\r
+        HORZGUIDE, 116\r
+        HORZGUIDE, 129\r
+    END\r
+\r
+    IDD_COLUMNS_DIALOG, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 188\r
+        VERTGUIDE, 107\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 192\r
+        HORZGUIDE, 28\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_APP_TITLE           "Aktivitetshanteraren"\r
+    IDC_TASKMGR             "Aktivitetshanteraren"\r
+    IDS_IDLE_PROCESS        "System Idle Process"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    ID_FILE_NEW             "Kör ett nytt program"\r
+    ID_OPTIONS_ALWAYSONTOP  "Aktivitetshanteraren förblir i förgrunden om den inte minimeras"\r
+    ID_OPTIONS_MINIMIZEONUSE\r
+                            "Aktivitetshanteraren minimeras när en Växla till operation utförs"\r
+    ID_OPTIONS_HIDEWHENMINIMIZED "Göm Aktivitetshanteraren när den minimeras"\r
+    ID_VIEW_REFRESH         "Tvinga Aktivitetshanteraren att uppdatera nu, oavsätt vald uppdateringshastighet"\r
+    ID_VIEW_LARGE           "Visa aktiviteter med stora ikoner"\r
+    ID_VIEW_SMALL           "Visa aktiviteter med små ikoner"\r
+    ID_VIEW_DETAILS         "Visa information om varje aktivitet"\r
+    ID_VIEW_UPDATESPEED_HIGH "Uppdaterar värden två gånger per sekund"\r
+    ID_VIEW_UPDATESPEED_NORMAL "Uppdaterar värden varannan sekund"\r
+    ID_VIEW_UPDATESPEED_LOW "Uppdaterar värden var 4:e sekund"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    ID_VIEW_UPDATESPEED_PAUSED "Uppdaterar inte automatiskt"\r
+    ID_WINDOWS_TILEHORIZONTALLY\r
+                            "Ordna fönstren horizontellt på skrivbordet"\r
+    ID_WINDOWS_TILEVERTICALLY "Ordna fönstren vertikalt på skrivborder"\r
+    ID_WINDOWS_MINIMIZE     "Minimerar fönstret"\r
+    ID_WINDOWS_MAXIMIZE     "Maximerar fönstret"\r
+    ID_WINDOWS_CASCADE      "Ordna fönstren diagonalt överlappande på skrivbordet"\r
+    ID_WINDOWS_BRINGTOFRONT "För fönstret till förgrunden men växla inte till det"\r
+    ID_HELP_TOPICS          "Visa Aktivitetshanterarens hjälpavsnitt"\r
+    ID_HELP_ABOUT           "Visa programinformation, versionsnummer, och upphovsrätt"\r
+    ID_FILE_EXIT            "Avsluta Aktivitetshanteraren"\r
+    ID_OPTIONS_SHOW16BITTASKS\r
+                            "Visa 16-bitarsprocesser under tillhörande ntvdm.exe"\r
+    ID_VIEW_SELECTCOLUMNS   "Välj de kolumner som ska synas på process-sidan"\r
+    ID_VIEW_SHOWKERNELTIMES "Visar kernel-tider i prestandagrafer"\r
+    ID_VIEW_CPUHISTORY_ONEGRAPHALL\r
+                            "En enda historik-graf visar totala processoranvändningen"\r
+    ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU "Varje processor har sin egen historik-graf"\r
+    ID_APPLICATION_PAGE_SWITCHTO\r
+                            "För aktiviteten till förgrunden och växla till den"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    ID_ENDTASK              "Ber de valda aktiviteterna att avslutas"\r
+    ID_GOTOPROCESS          "Ändrar fokus till den valda aktivitetens process"\r
+    ID_RESTORE              "Återställer Aktivitetshanteraren från sitt gömda tillstånd"\r
+    ID_PROCESS_PAGE_ENDPROCESS "Tar bort processen från systemet"\r
+    ID_PROCESS_PAGE_ENDPROCESSTREE\r
+                            "Tar bort den här processen och underprocesser från systemet"\r
+    ID_PROCESS_PAGE_DEBUG   "Kopplar felsökaren till den här processen"\r
+    ID_PROCESS_PAGE_SETAFFINITY\r
+                            "Kontrollerar vilka processorer processen tillåts att köras på"\r
+    ID_PROCESS_PAGE_SETPRIORITY_REALTIME\r
+                            "Ändrar processens prioritet till realtidsläge"\r
+    ID_PROCESS_PAGE_SETPRIORITY_HIGH "Ändrar processens prioritet till hög"\r
+    ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL\r
+                            "Ändrar processens prioritet till över normal"\r
+    ID_PROCESS_PAGE_SETPRIORITY_NORMAL\r
+                            "Ändrar processens prioritet till normal"\r
+    ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL\r
+                            "Ändrar processens prioritet till under normal"\r
+    ID_PROCESS_PAGE_SETPRIORITY_LOW "Ändrar processens prioritet till låg"\r
+    IDS_LICENSE             "This program 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.\r\n\r\nThis 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.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA."\r
+END\r
+\r
+\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_TAB_APPS                  "Program"\r
+    IDS_TAB_PROCESSES             "Processer"\r
+    IDS_TAB_PERFORMANCE           "Prestanda"\r
+    IDS_TAB_TASK                  "Aktivitet"\r
+    IDS_TAB_STATUS                "Status"\r
+    IDS_TAB_IMAGENAME             "Processnamn"\r
+    IDS_TAB_PID                   "PID"\r
+    IDS_TAB_USERNAME              "Användarnamn"\r
+    IDS_TAB_SESSIONID             "Sessions-ID"\r
+    IDS_TAB_CPU                   "Processor"\r
+    IDS_TAB_CPUTIME               "Processortid"\r
+    IDS_TAB_MEMUSAGE              "Minnesanvändning"\r
+    IDS_TAB_PEAKMEMUSAGE          "Toppvärde minne"\r
+    IDS_TAB_MEMDELTA              "Minnesvärdesförändring"\r
+    IDS_TAB_PAGEFAULT             "Sidfel"\r
+    IDS_TAB_PFDELTA               "Sidfelsförändring"\r
+    IDS_TAB_VMSIZE                "VM Storlek"\r
+    IDS_TAB_PAGEDPOOL             "Växlingsbar pool"\r
+    IDS_TAB_NPPOOL                "Oväxlingsbar pool"\r
+    IDS_TAB_BASEPRI               "Basprioritet"\r
+    IDS_TAB_HANDLES               "Referenser"\r
+    IDS_TAB_THREADS               "Trådar"\r
+    IDS_TAB_USERPBJECTS           "USER Objekt"\r
+    IDS_TAB_GDIOBJECTS            "GDI Objekt"\r
+    IDS_TAB_IOREADS               "I/O-läsningar"\r
+    IDS_TAB_IOWRITES              "I/O-skrivningar"\r
+    IDS_TAB_IOOTHER               "I/O-övriga"\r
+    IDS_TAB_IOREADBYTES           "Antal tecken lästa, andra I/O-åtgärder"\r
+    IDS_TAB_IOWRITESBYTES         "Antal tecken skrivna, andra I/O-åtgärder"\r
+    IDS_TAB_IOOTHERBYTES          "I/O, antal tecken"\r
+    IDS_MENU_SELECTCOLUMNS        "&Välj kolumner..."\r
+    IDS_MENU_16BITTASK            "&Visa 16-bitsprocesser"\r
+    IDS_MENU_WINDOWS              "&Fönster"\r
+    IDS_MENU_LARGEICONS           "&Stora ikoner"\r
+    IDS_MENU_SMALLICONS           "S&må ikoner"\r
+    IDS_MENU_DETAILS              "&Detaljer"\r
+    IDS_MENU_ONEGRAPHALLCPUS      "En visare för &alla processorer"\r
+    IDS_MENU_ONEGRAPHPERCPU       "&En visare per processor"\r
+    IDS_MENU_CPUHISTORY           "&Processorhistorik"\r
+    IDS_MENU_SHOWKERNELTIMES      "&Visa kerneltider"\r
+    IDS_CREATENEWTASK             "Ny aktivitet"\r
+    IDS_CREATENEWTASK_DESC        "Skriv namnet på ett program, en mapp, en web-adress eller ett dokument för att öppna det."\r
+    IDS_MSG_ACCESSPROCESSAFF      "Kunde inte komma åt eller ändra processorsamhörigheten"\r
+    IDS_MSG_PROCESSONEPRO         "Processen måste ha samhörighet med minst en processor."\r
+    IDS_MSG_INVALIDOPTION         "Ogiltigt val"\r
+    IDS_MSG_UNABLEDEBUGPROCESS    "Kunde inte felsöka processen"\r
+    IDS_MSG_WARNINGDEBUG          "VARNING: Felsökning av den här processen kan resultera i förlorad data.\nÄr du säker på att du vill ansluta felsökaren?"\r
+    IDS_MSG_TASKMGRWARNING        "Aktivitetshanteraren varning"\r
+    IDS_MSG_WARNINGTERMINATING    "VARNING: Ett avslutande av en process kan orsaka\noönskade effekter och påverka systemets stabilitet. Processen\nkommer inte att ges chans att spara sitt arbete innan\nden avslutas. Är du säker på att du vill avsluta processen?"\r
+    IDS_MSG_UNABLETERMINATEPRO    "Kunde inte avsluta processen"\r
+    IDS_MSG_UNABLECHANGEPRIORITY  "Kunde inte ändra prioritet"\r
+    IDS_MSG_WARNINGCHANGEPRIORITY "VARNING: Ändring av prioritetsklassen hos den här processen kan\norsaka oönskade effekter och påverka systemets stabilitet. Är du\nsäker på att du vill ändra prioritetsklassen?"\r
+    IDS_MSG_TRAYICONCPUUSAGE      "CPU-anv: %d%%"\r
+\r
+END\r
+\r
+\r
+#endif    // Swedish (SE) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
index af32cc9..9cd9d47 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-    
-#include "about.h"
 
 INT_PTR CALLBACK AboutDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
 
index 636df36..3afacd3 100644 (file)
@@ -4,6 +4,7 @@
  *  affinity.cpp
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <winnt.h>
-#include <stdio.h>
-    
-#include "procpage.h"
-#include "affinity.h"
-#include "perfdata.h"
 
 HANDLE        hProcessAffinityHandle;
+TCHAR         szTemp[256];
+TCHAR         szTempA[256];
 
 INT_PTR CALLBACK AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
 
 void ProcessPage_OnSetAffinity(void)
 {
-    LV_ITEM            lvitem;
+    LV_ITEM          lvitem;
     ULONG            Index;
     DWORD            dwProcessId;
     TCHAR            strErrorText[260];
@@ -59,7 +51,8 @@ void ProcessPage_OnSetAffinity(void)
     hProcessAffinityHandle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION, FALSE, dwProcessId);
     if (!hProcessAffinityHandle) {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_ACCESSPROCESSAFF, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
     DialogBox(hInst, MAKEINTRESOURCE(IDD_AFFINITY_DIALOG), hMainWnd, AffinityDialogWndProc);
@@ -86,7 +79,8 @@ AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
         if (!GetProcessAffinityMask(hProcessAffinityHandle, &dwProcessAffinityMask, &dwSystemAffinityMask))    {
             GetLastErrorText(strErrorText, 260);
             EndDialog(hDlg, 0);
-            MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
+            LoadString(hInst, IDS_MSG_ACCESSPROCESSAFF, szTemp, 256);
+            MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         }
 
         /*
@@ -321,7 +315,9 @@ AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
              * of it's cpu time.
              */
             if (!dwProcessAffinityMask) {
-                MessageBox(hDlg, _T("The process must have affinity with at least one processor."), _T("Invalid Option"), MB_OK|MB_ICONSTOP);
+                LoadString(hInst, IDS_MSG_PROCESSONEPRO, szTemp, 256);
+                LoadString(hInst, IDS_MSG_INVALIDOPTION, szTempA, 256);
+                MessageBox(hDlg, szTemp, szTempA, MB_OK|MB_ICONSTOP);
                 return TRUE;
             }
 
@@ -331,7 +327,8 @@ AffinityDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
             if (!SetProcessAffinityMask(hProcessAffinityHandle, dwProcessAffinityMask)) {
                 GetLastErrorText(strErrorText, 260);
                 EndDialog(hDlg, LOWORD(wParam));
-                MessageBox(hMainWnd, strErrorText, _T("Unable to Access or Set Process Affinity"), MB_OK|MB_ICONSTOP);
+                LoadString(hInst, IDS_MSG_ACCESSPROCESSAFF, szTemp, 256);
+                MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
             }
 
             EndDialog(hDlg, LOWORD(wParam));
index eca2e3f..ee547ce 100644 (file)
@@ -4,6 +4,7 @@
  *  applicationpage.cpp
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-
-#include "applpage.h"
-#include "procpage.h"
 
 typedef struct
 {
@@ -95,12 +87,13 @@ ApplicationPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* Initialize the application page's controls */
         column.mask = LVCF_TEXT|LVCF_WIDTH;
-        _tcscpy(szTemp, _T("Task"));
+
+        LoadString(hInst, IDS_TAB_TASK, szTemp, 256);
         column.pszText = szTemp;
         column.cx = 250;
         ListView_InsertColumn(hApplicationPageListCtrl, 0, &column);    /* Add the "Task" column */
         column.mask = LVCF_TEXT|LVCF_WIDTH;
-        _tcscpy(szTemp, _T("Status"));
+        LoadString(hInst, IDS_TAB_STATUS, szTemp, 256);
         column.pszText = szTemp;
         column.cx = 95;
         ListView_InsertColumn(hApplicationPageListCtrl, 1, &column);    /* Add the "Status" column */
@@ -368,7 +361,7 @@ void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung)
     /* It is not already in the list so add it */
     else
     {
-        pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)malloc(sizeof(APPLICATION_PAGE_LIST_ITEM));
+        pAPLI = (LPAPPLICATION_PAGE_LIST_ITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_PAGE_LIST_ITEM));
 
         pAPLI->hWnd = hWnd;
         pAPLI->hIcon = hIcon;
@@ -407,7 +400,7 @@ void AddOrUpdateHwnd(HWND hWnd, TCHAR *szTitle, HICON hIcon, BOOL bHung)
             ImageList_Remove(hImageListSmall, item.iItem);
 
             ListView_DeleteItem(hApplicationPageListCtrl, item.iItem);
-            free(pAPLI);
+            HeapFree(GetProcessHeap(), 0, pAPLI);
             bItemRemoved = TRUE;
         }
     }
@@ -702,7 +695,7 @@ void ApplicationPage_OnWindowsTileHorizontally(void)
     HWND*                           hWndArray;
     int                             nWndCount;
 
-    hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
+    hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
     nWndCount = 0;
 
     for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
@@ -722,7 +715,7 @@ void ApplicationPage_OnWindowsTileHorizontally(void)
         }
     }
     TileWindows(NULL, MDITILE_HORIZONTAL, NULL, nWndCount, hWndArray);
-    free(hWndArray);
+    HeapFree(GetProcessHeap(), 0, hWndArray);
 }
 
 void ApplicationPage_OnWindowsTileVertically(void)
@@ -733,7 +726,7 @@ void ApplicationPage_OnWindowsTileVertically(void)
     HWND*                           hWndArray;
     int                             nWndCount;
 
-    hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
+    hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
     nWndCount = 0;
 
     for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
@@ -753,7 +746,7 @@ void ApplicationPage_OnWindowsTileVertically(void)
     }
 
     TileWindows(NULL, MDITILE_VERTICAL, NULL, nWndCount, hWndArray);
-    free(hWndArray);
+    HeapFree(GetProcessHeap(), 0, hWndArray);
 }
 
 void ApplicationPage_OnWindowsMinimize(void)
@@ -806,7 +799,7 @@ void ApplicationPage_OnWindowsCascade(void)
     HWND*                           hWndArray;
     int                             nWndCount;
 
-    hWndArray = (HWND*)malloc(sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
+    hWndArray = (HWND*)HeapAlloc(GetProcessHeap(), 0, sizeof(HWND) * ListView_GetItemCount(hApplicationPageListCtrl));
     nWndCount = 0;
 
     for (i=0; i<ListView_GetItemCount(hApplicationPageListCtrl); i++) {
@@ -824,7 +817,7 @@ void ApplicationPage_OnWindowsCascade(void)
         }
     }
     CascadeWindows(NULL, 0, NULL, nWndCount, hWndArray);
-    free(hWndArray);
+    HeapFree(GetProcessHeap(), 0, hWndArray);
 }
 
 void ApplicationPage_OnWindowsBringToFront(void)
index f1590e8..afea962 100644 (file)
@@ -4,6 +4,7 @@
  *  column.cpp
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-    
-#include "column.h"
-#include "procpage.h"
 
 UINT    ColumnDataHints[25];
+TCHAR       szTemp[256];
 
 int                 InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat, int nWidth, int nSubItem);
 INT_PTR CALLBACK    ColumnsDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
@@ -40,56 +33,126 @@ void AddColumns(void)
 {
     int        size;
 
-    if (TaskManagerSettings.Column_ImageName)
-        InsertColumn(0, _T("Image Name"), LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[0], -1);
-    if (TaskManagerSettings.Column_PID)
-        InsertColumn(1, _T("PID"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[1], -1);
-    if (TaskManagerSettings.Column_UserName)
-        InsertColumn(2, _T("Username"), LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[2], -1);
-    if (TaskManagerSettings.Column_SessionID)
-        InsertColumn(3, _T("Session ID"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[3], -1);
-    if (TaskManagerSettings.Column_CPUUsage)
-        InsertColumn(4, _T("CPU"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[4], -1);
-    if (TaskManagerSettings.Column_CPUTime)
-        InsertColumn(5, _T("CPU Time"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[5], -1);
-    if (TaskManagerSettings.Column_MemoryUsage)
-        InsertColumn(6, _T("Mem Usage"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[6], -1);
-    if (TaskManagerSettings.Column_PeakMemoryUsage)
-        InsertColumn(7, _T("Peak Mem Usage"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[7], -1);
-    if (TaskManagerSettings.Column_MemoryUsageDelta)
-        InsertColumn(8, _T("Mem Delta"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[8], -1);
-    if (TaskManagerSettings.Column_PageFaults)
-        InsertColumn(9, _T("Page Faults"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[9], -1);
-    if (TaskManagerSettings.Column_PageFaultsDelta)
-        InsertColumn(10, _T("PF Delta"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[10], -1);
-    if (TaskManagerSettings.Column_VirtualMemorySize)
-        InsertColumn(11, _T("VM Size"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[11], -1);
-    if (TaskManagerSettings.Column_PagedPool)
-        InsertColumn(12, _T("Paged Pool"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[12], -1);
-    if (TaskManagerSettings.Column_NonPagedPool)
-        InsertColumn(13, _T("NP Pool"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[13], -1);
-    if (TaskManagerSettings.Column_BasePriority)
-        InsertColumn(14, _T("Base Pri"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[14], -1);
-    if (TaskManagerSettings.Column_HandleCount)
-        InsertColumn(15, _T("Handles"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[15], -1);
-    if (TaskManagerSettings.Column_ThreadCount)
-        InsertColumn(16, _T("Threads"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[16], -1);
-    if (TaskManagerSettings.Column_USERObjects)
-        InsertColumn(17, _T("USER Objects"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[17], -1);
-    if (TaskManagerSettings.Column_GDIObjects)
-        InsertColumn(18, _T("GDI Objects"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[18], -1);
-    if (TaskManagerSettings.Column_IOReads)
-        InsertColumn(19, _T("I/O Reads"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[19], -1);
-    if (TaskManagerSettings.Column_IOWrites)
-        InsertColumn(20, _T("I/O Writes"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[20], -1);
-    if (TaskManagerSettings.Column_IOOther)
-        InsertColumn(21, _T("I/O Other"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[21], -1);
-    if (TaskManagerSettings.Column_IOReadBytes)
-        InsertColumn(22, _T("I/O Read Bytes"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[22], -1);
-    if (TaskManagerSettings.Column_IOWriteBytes)
-        InsertColumn(23, _T("I/O Write Bytes"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[23], -1);
-    if (TaskManagerSettings.Column_IOOtherBytes)
-        InsertColumn(24, _T("I/O Other Bytes"), LVCFMT_RIGHT, TaskManagerSettings.ColumnSizeArray[24], -1);
+    if (TaskManagerSettings.Column_ImageName) {
+        LoadString(hInst, IDS_TAB_IMAGENAME, szTemp, 256);
+        InsertColumn(0, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[0], -1);
+    }
+    if (TaskManagerSettings.Column_PID) {
+        LoadString(hInst, IDS_TAB_PID, szTemp, 256);
+        InsertColumn(1, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[1], -1);
+    }
+    if (TaskManagerSettings.Column_UserName) {
+        LoadString(hInst, IDS_TAB_USERNAME, szTemp, 256);
+        InsertColumn(2, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[2], -1);
+    }
+    if (TaskManagerSettings.Column_SessionID) {
+        LoadString(hInst, IDS_TAB_SESSIONID, szTemp, 256);
+        InsertColumn(3, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[3], -1);
+    }
+    if (TaskManagerSettings.Column_CPUUsage) {
+        LoadString(hInst, IDS_TAB_CPU, szTemp, 256);
+        InsertColumn(4, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[4], -1);
+    }
+
+    if (TaskManagerSettings.Column_CPUTime) {
+        LoadString(hInst, IDS_TAB_CPUTIME, szTemp, 256);
+        InsertColumn(5, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[5], -1);
+    }
+
+    if (TaskManagerSettings.Column_MemoryUsage) {
+        LoadString(hInst, IDS_TAB_MEMUSAGE, szTemp, 256);
+        InsertColumn(6, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[6], -1);
+    }
+
+    if (TaskManagerSettings.Column_PeakMemoryUsage) {
+        LoadString(hInst, IDS_TAB_PEAKMEMUSAGE, szTemp, 256);
+        InsertColumn(7, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[7], -1);
+    }
+
+    if (TaskManagerSettings.Column_MemoryUsageDelta) {
+        LoadString(hInst, IDS_TAB_MEMDELTA, szTemp, 256);
+        InsertColumn(8, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[8], -1);
+    }
+
+    if (TaskManagerSettings.Column_PageFaults) {
+        LoadString(hInst, IDS_TAB_PAGEFAULT, szTemp, 256);
+        InsertColumn(9, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[9], -1);
+    }
+
+    if (TaskManagerSettings.Column_PageFaultsDelta) {
+        LoadString(hInst, IDS_TAB_PFDELTA, szTemp, 256);
+        InsertColumn(10, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[10], -1);
+    }
+
+    if (TaskManagerSettings.Column_VirtualMemorySize) {
+        LoadString(hInst, IDS_TAB_VMSIZE, szTemp, 256);
+        InsertColumn(11, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[11], -1);
+    }
+
+    if (TaskManagerSettings.Column_PagedPool) {
+        LoadString(hInst, IDS_TAB_PAGEDPOOL, szTemp, 256);
+        InsertColumn(12, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[12], -1);
+    }
+
+    if (TaskManagerSettings.Column_NonPagedPool) {
+        LoadString(hInst, IDS_TAB_NPPOOL, szTemp, 256);
+        InsertColumn(13, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[13], -1);
+    }
+
+    if (TaskManagerSettings.Column_BasePriority) {
+        LoadString(hInst, IDS_TAB_BASEPRI, szTemp, 256);
+        InsertColumn(14, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[14], -1);
+    }
+
+    if (TaskManagerSettings.Column_HandleCount) {
+        LoadString(hInst, IDS_TAB_HANDLES, szTemp, 256);
+        InsertColumn(15, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[15], -1);
+    }
+
+    if (TaskManagerSettings.Column_ThreadCount) {
+        LoadString(hInst, IDS_TAB_THREADS, szTemp, 256);
+        InsertColumn(16, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[16], -1);
+    }
+
+    if (TaskManagerSettings.Column_USERObjects) {
+        LoadString(hInst, IDS_TAB_USERPBJECTS, szTemp, 256);
+        InsertColumn(17, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[17], -1);
+    }
+
+    if (TaskManagerSettings.Column_GDIObjects) {
+        LoadString(hInst, IDS_TAB_GDIOBJECTS, szTemp, 256);
+        InsertColumn(18, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[18], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOReads) {
+        LoadString(hInst, IDS_TAB_IOREADS, szTemp, 256);
+        InsertColumn(19, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[19], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOWrites) {
+        LoadString(hInst, IDS_TAB_IOWRITES, szTemp, 256);
+        InsertColumn(20, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[20], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOOther) {
+        LoadString(hInst, IDS_TAB_IOOTHER, szTemp, 256);
+        InsertColumn(21, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[21], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOReadBytes) {
+        LoadString(hInst, IDS_TAB_IOREADBYTES, szTemp, 256);
+        InsertColumn(22, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[22], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOWriteBytes) {
+        LoadString(hInst, IDS_TAB_IOWRITESBYTES, szTemp, 256);
+        InsertColumn(23, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[23], -1);
+    }
+
+    if (TaskManagerSettings.Column_IOOtherBytes) {
+        LoadString(hInst, IDS_TAB_IOOTHERBYTES, szTemp, 256);
+        InsertColumn(24, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[24], -1);
+    }
 
     size = SendMessage(hProcessPageHeaderCtrl, HDM_GETITEMCOUNT, 0, 0);
     SendMessage(hProcessPageHeaderCtrl, HDM_SETORDERARRAY, (WPARAM) size, (LPARAM) &TaskManagerSettings.ColumnOrderArray);
@@ -196,127 +259,176 @@ void SaveColumnSettings(void)
 
         SendMessage(hProcessPageHeaderCtrl, HDM_GETITEM, i, (LPARAM) &hditem);
 
-        if (_tcsicmp(text, _T("Image Name")) == 0)
+        LoadString(hInst, IDS_TAB_IMAGENAME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_ImageName = TRUE;
             TaskManagerSettings.ColumnSizeArray[0] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("PID")) == 0)
+
+        LoadString(hInst, IDS_TAB_PID, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_PID = TRUE;
             TaskManagerSettings.ColumnSizeArray[1] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Username")) == 0)
+
+        LoadString(hInst, IDS_TAB_USERNAME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_UserName = TRUE;
             TaskManagerSettings.ColumnSizeArray[2] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Session ID")) == 0)
+
+        LoadString(hInst, IDS_TAB_SESSIONID, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_SessionID = TRUE;
             TaskManagerSettings.ColumnSizeArray[3] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("CPU")) == 0)
+
+        LoadString(hInst, IDS_TAB_CPU, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_CPUUsage = TRUE;
             TaskManagerSettings.ColumnSizeArray[4] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("CPU Time")) == 0)
+
+        LoadString(hInst, IDS_TAB_CPUTIME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_CPUTime = TRUE;
             TaskManagerSettings.ColumnSizeArray[5] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Mem Usage")) == 0)
+
+        LoadString(hInst, IDS_TAB_MEMUSAGE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_MemoryUsage = TRUE;
             TaskManagerSettings.ColumnSizeArray[6] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Peak Mem Usage")) == 0)
+
+        LoadString(hInst, IDS_TAB_PEAKMEMUSAGE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_PeakMemoryUsage = TRUE;
             TaskManagerSettings.ColumnSizeArray[7] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Mem Delta")) == 0)
+
+        LoadString(hInst, IDS_TAB_MEMDELTA, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_MemoryUsageDelta = TRUE;
             TaskManagerSettings.ColumnSizeArray[8] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Page Faults")) == 0)
+
+        LoadString(hInst, IDS_TAB_PAGEFAULT, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_PageFaults = TRUE;
             TaskManagerSettings.ColumnSizeArray[9] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("PF Delta")) == 0)
+
+        LoadString(hInst, IDS_TAB_PFDELTA, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_PageFaultsDelta = TRUE;
             TaskManagerSettings.ColumnSizeArray[10] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("VM Size")) == 0)
+
+        LoadString(hInst, IDS_TAB_VMSIZE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_VirtualMemorySize = TRUE;
             TaskManagerSettings.ColumnSizeArray[11] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Paged Pool")) == 0)
+
+        LoadString(hInst, IDS_TAB_PAGEDPOOL, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_PagedPool = TRUE;
             TaskManagerSettings.ColumnSizeArray[12] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("NP Pool")) == 0)
+
+        LoadString(hInst, IDS_TAB_NPPOOL, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_NonPagedPool = TRUE;
             TaskManagerSettings.ColumnSizeArray[13] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Base Pri")) == 0)
+
+        LoadString(hInst, IDS_TAB_BASEPRI, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_BasePriority = TRUE;
             TaskManagerSettings.ColumnSizeArray[14] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Handles")) == 0)
+
+        LoadString(hInst, IDS_TAB_HANDLES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_HandleCount = TRUE;
             TaskManagerSettings.ColumnSizeArray[15] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("Threads")) == 0)
+
+        LoadString(hInst, IDS_TAB_THREADS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_ThreadCount = TRUE;
             TaskManagerSettings.ColumnSizeArray[16] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("USER Objects")) == 0)
+
+        LoadString(hInst, IDS_TAB_USERPBJECTS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_USERObjects = TRUE;
             TaskManagerSettings.ColumnSizeArray[17] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("GDI Objects")) == 0)
+
+        LoadString(hInst, IDS_TAB_GDIOBJECTS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_GDIObjects = TRUE;
             TaskManagerSettings.ColumnSizeArray[18] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Reads")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOREADS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOReads = TRUE;
             TaskManagerSettings.ColumnSizeArray[19] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Writes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOWRITES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOWrites = TRUE;
             TaskManagerSettings.ColumnSizeArray[20] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Other")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOOTHER, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOOther = TRUE;
             TaskManagerSettings.ColumnSizeArray[21] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Read Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOREADBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOReadBytes = TRUE;
             TaskManagerSettings.ColumnSizeArray[22] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Write Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOWRITESBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOWriteBytes = TRUE;
             TaskManagerSettings.ColumnSizeArray[23] = hditem.cxy;
         }
-        if (_tcsicmp(text, _T("I/O Other Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOOTHERBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
         {
             TaskManagerSettings.Column_IOOtherBytes = TRUE;
             TaskManagerSettings.ColumnSizeArray[24] = hditem.cxy;
@@ -491,55 +603,104 @@ void UpdateColumnDataHints(void)
 
         SendMessage(hProcessPageHeaderCtrl, HDM_GETITEM, Index, (LPARAM) &hditem);
 
-        if (_tcsicmp(text, _T("Image Name")) == 0)
+        LoadString(hInst, IDS_TAB_IMAGENAME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IMAGENAME;
-        if (_tcsicmp(text, _T("PID")) == 0)
+
+        LoadString(hInst, IDS_TAB_PID, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_PID;
-        if (_tcsicmp(text, _T("Username")) == 0)
+
+        LoadString(hInst, IDS_TAB_USERNAME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_USERNAME;
-        if (_tcsicmp(text, _T("Session ID")) == 0)
+
+        LoadString(hInst, IDS_TAB_SESSIONID, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_SESSIONID;
-        if (_tcsicmp(text, _T("CPU")) == 0)
+
+        LoadString(hInst, IDS_TAB_CPU, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_CPUUSAGE;
-        if (_tcsicmp(text, _T("CPU Time")) == 0)
+
+        LoadString(hInst, IDS_TAB_CPUTIME, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_CPUTIME;
-        if (_tcsicmp(text, _T("Mem Usage")) == 0)
+
+        LoadString(hInst, IDS_TAB_MEMUSAGE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_MEMORYUSAGE;
-        if (_tcsicmp(text, _T("Peak Mem Usage")) == 0)
+
+        LoadString(hInst, IDS_TAB_PEAKMEMUSAGE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_PEAKMEMORYUSAGE;
-        if (_tcsicmp(text, _T("Mem Delta")) == 0)
+
+        LoadString(hInst, IDS_TAB_MEMDELTA, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_MEMORYUSAGEDELTA;
-        if (_tcsicmp(text, _T("Page Faults")) == 0)
+
+        LoadString(hInst, IDS_TAB_PAGEFAULT, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_PAGEFAULTS;
-        if (_tcsicmp(text, _T("PF Delta")) == 0)
+
+        LoadString(hInst, IDS_TAB_PFDELTA, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_PAGEFAULTSDELTA;
-        if (_tcsicmp(text, _T("VM Size")) == 0)
+
+        LoadString(hInst, IDS_TAB_VMSIZE, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_VIRTUALMEMORYSIZE;
-        if (_tcsicmp(text, _T("Paged Pool")) == 0)
+
+        LoadString(hInst, IDS_TAB_PAGEDPOOL, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_PAGEDPOOL;
-        if (_tcsicmp(text, _T("NP Pool")) == 0)
+
+        LoadString(hInst, IDS_TAB_NPPOOL, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_NONPAGEDPOOL;
-        if (_tcsicmp(text, _T("Base Pri")) == 0)
+
+        LoadString(hInst, IDS_TAB_BASEPRI, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_BASEPRIORITY;
-        if (_tcsicmp(text, _T("Handles")) == 0)
+
+        LoadString(hInst, IDS_TAB_HANDLES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_HANDLECOUNT;
-        if (_tcsicmp(text, _T("Threads")) == 0)
+
+        LoadString(hInst, IDS_TAB_THREADS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_THREADCOUNT;
-        if (_tcsicmp(text, _T("USER Objects")) == 0)
+
+        LoadString(hInst, IDS_TAB_USERPBJECTS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_USEROBJECTS;
-        if (_tcsicmp(text, _T("GDI Objects")) == 0)
+
+        LoadString(hInst, IDS_TAB_GDIOBJECTS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_GDIOBJECTS;
-        if (_tcsicmp(text, _T("I/O Reads")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOREADS, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOREADS;
-        if (_tcsicmp(text, _T("I/O Writes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOWRITES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOWRITES;
-        if (_tcsicmp(text, _T("I/O Other")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOOTHER, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOOTHER;
-        if (_tcsicmp(text, _T("I/O Read Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOREADBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOREADBYTES;
-        if (_tcsicmp(text, _T("I/O Write Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOWRITESBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOWRITEBYTES;
-        if (_tcsicmp(text, _T("I/O Other Bytes")) == 0)
+
+        LoadString(hInst, IDS_TAB_IOOTHERBYTES, szTemp, 256);
+        if (_tcsicmp(text, szTemp) == 0)
             ColumnDataHints[Index] = COLUMN_IOOTHERBYTES;
     }
 }
index c031bc7..aedc5f9 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "procpage.h"
-#include "perfdata.h"
-#include "column.h"
-#include "proclist.h"
-#include "dbgchnl.h"
-#include <ctype.h>
 
 /* TODO:
  *      - the dialog box could be non modal
index 21e0bf7..a6b9b4c 100644 (file)
@@ -4,6 +4,7 @@
  *  debug.cpp
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "debug.h"
-#include "procpage.h"
-#include "perfdata.h"
 
 void ProcessPage_OnDebug(void)
 {
-    LVITEM                lvitem;
+    LVITEM               lvitem;
     ULONG                Index;
     DWORD                dwProcessId;
     TCHAR                strErrorText[260];
-    HKEY                hKey;
+    HKEY                 hKey;
     TCHAR                strDebugPath[260];
     TCHAR                strDebugger[260];
     DWORD                dwDebuggerSize;
-    PROCESS_INFORMATION    pi;
-    STARTUPINFO            si;
-    HANDLE                hDebugEvent;
+    PROCESS_INFORMATION  pi;
+    STARTUPINFO          si;
+    HANDLE               hDebugEvent;
+    TCHAR                szTemp[256];
+    TCHAR                szTempA[256];
+
 
     for (Index=0; Index<(ULONG)ListView_GetItemCount(hProcessPageListCtrl); Index++)
     {
@@ -66,17 +59,22 @@ void ProcessPage_OnDebug(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Debugging this process may result in loss of data.\nAre you sure you wish to attach the debugger?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGDEBUG, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Debug Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLEDEBUGPROCESS, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Debug Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLEDEBUGPROCESS, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
@@ -84,7 +82,8 @@ void ProcessPage_OnDebug(void)
     if (RegQueryValueEx(hKey, _T("Debugger"), NULL, NULL, (LPBYTE)strDebugger, &dwDebuggerSize) != ERROR_SUCCESS)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Debug Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLEDEBUGPROCESS, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         RegCloseKey(hKey);
         return;
     }
@@ -95,7 +94,8 @@ void ProcessPage_OnDebug(void)
     if (!hDebugEvent)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Debug Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLEDEBUGPROCESS, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
@@ -107,7 +107,8 @@ void ProcessPage_OnDebug(void)
     if (!CreateProcess(NULL, strDebugPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Debug Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLEDEBUGPROCESS, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hDebugEvent);
index 03f5b2d..df0073b 100644 (file)
@@ -4,6 +4,7 @@
  *  endproc.cpp
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "endproc.h"
-#include "procpage.h"
-#include "perfdata.h"
+
+TCHAR                szTemp[256];
+TCHAR                szTempA[256];
 
 void ProcessPage_OnEndProcess(void)
 {
@@ -60,7 +53,9 @@ void ProcessPage_OnEndProcess(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Terminating a process can cause undesired\nresults including loss of data and system instability. The\nprocess will not be given the chance to save its state or\ndata before it is terminated. Are you sure you want to\nterminate the process?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGTERMINATING, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
@@ -68,14 +63,16 @@ void ProcessPage_OnEndProcess(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Terminate Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLETERMINATEPRO, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!TerminateProcess(hProcess, 0))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Terminate Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLETERMINATEPRO, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -108,7 +105,9 @@ void ProcessPage_OnEndProcessTree(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Terminating a process can cause undesired\nresults including loss of data and system instability. The\nprocess will not be given the chance to save its state or\ndata before it is terminated. Are you sure you want to\nterminate the process?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGTERMINATING, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
@@ -116,14 +115,16 @@ void ProcessPage_OnEndProcessTree(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Terminate Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLETERMINATEPRO, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!TerminateProcess(hProcess, 0))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Terminate Process"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLETERMINATEPRO, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
index d5369ba..1b599c5 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-    
-#include "font.h"
 
 void Font_DrawText(HDC hDC, LPCTSTR lpszText, int x, int y)
 {
index 861e36d..51f4f73 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "graph.h"
-#include "font.h"
-#include "perfdata.h"
-
 
 LONG                OldGraphWndProc;
 
index 65ad43e..d8e2392 100644 (file)
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-
-#include <math.h>
-#include "graphctl.h"
 
 LONG OldGraphCtrlWndProc;
 
index 75bf4f7..cd1ba71 100644 (file)
@@ -16,7 +16,7 @@ TARGET_INSTALLDIR = system32
 
 TARGET_PCH = precomp.h
 
-TARGET_CFLAGS = -Werror -Wall -DDBG -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -D__USE_W32API 
+TARGET_CFLAGS = -Werror -Wall -DDBG -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -D__USE_W32API
        
 TARGET_SDKLIBS = ntdll.a kernel32.a user32.a gdi32.a comctl32.a
 
index ea15901..5377b58 100644 (file)
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-    
-#include "optnmenu.h"
-#include "procpage.h"
 
 void TaskManager_OnOptionsAlwaysOnTop(void)
 {
index 595c43a..d1efd5d 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-#include "perfdata.h"
-
-PROCNTQSI                        NtQuerySystemInformation = NULL;
-PROCGGR                            pGetGuiResources = NULL;
-PROCGPIC                        pGetProcessIoCounters = NULL;
-CRITICAL_SECTION                    PerfDataCriticalSection;
+
+CRITICAL_SECTION                 PerfDataCriticalSection;
 PPERFDATA                        pPerfDataOld = NULL;    /* Older perf data (saved to establish delta values) */
 PPERFDATA                        pPerfData = NULL;    /* Most recent copy of perf data */
 ULONG                            ProcessCountOld = 0;
@@ -48,21 +37,14 @@ SYSTEM_PERFORMANCE_INFORMATION    SystemPerfInfo;
 SYSTEM_BASIC_INFORMATION        SystemBasicInfo;
 SYSTEM_CACHE_INFORMATION        SystemCacheInfo;
 SYSTEM_HANDLE_INFORMATION        SystemHandleInfo;
-PSYSTEM_PROCESSORTIME_INFO        SystemProcessorTimeInfo = NULL;
+PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
 
 BOOL PerfDataInitialize(void)
 {
-    LONG    status;
-
-    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQuerySystemInformation");
-    pGetGuiResources = (PROCGGR)GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetGuiResources");
-    pGetProcessIoCounters = (PROCGPIC)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetProcessIoCounters");
+    NTSTATUS    status;
     
     InitializeCriticalSection(&PerfDataCriticalSection);
     
-    if (!NtQuerySystemInformation)
-        return FALSE;
-    
     /*
      * Get number of processors in the system
      */
@@ -75,15 +57,13 @@ BOOL PerfDataInitialize(void)
 
 void PerfDataUninitialize(void)
 {
-    NtQuerySystemInformation = NULL;
-
     DeleteCriticalSection(&PerfDataCriticalSection);
 }
 
 void PerfDataRefresh(void)
 {
     ULONG                            ulSize;
-    LONG                            status;
+    NTSTATUS                          status;
     LPBYTE                            pBuffer;
     ULONG                            BufferSize;
     PSYSTEM_PROCESS_INFORMATION        pSPI;
@@ -94,18 +74,14 @@ void PerfDataRefresh(void)
     TCHAR                            szTemp[MAX_PATH];
     DWORD                            dwSize;
     SYSTEM_PERFORMANCE_INFORMATION    SysPerfInfo;
-    SYSTEM_TIME_INFORMATION            SysTimeInfo;
+    SYSTEM_TIMEOFDAY_INFORMATION      SysTimeInfo;
     SYSTEM_CACHE_INFORMATION        SysCacheInfo;
     LPBYTE                            SysHandleInfoData;
-    PSYSTEM_PROCESSORTIME_INFO        SysProcessorTimeInfo;
+    PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo;
     double                            CurrentKernelTime;
 
-
-    if (!NtQuerySystemInformation)
-        return;
-
     /* Get new system time */
-    status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
+    status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
     if (status != NO_ERROR)
         return;
 
@@ -120,8 +96,8 @@ void PerfDataRefresh(void)
         return;
 
     /* Get processor time information */
-    SysProcessorTimeInfo = (PSYSTEM_PROCESSORTIME_INFO)malloc(sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors);
-    status = NtQuerySystemInformation(SystemProcessorTimeInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSORTIME_INFO) * SystemBasicInfo.bKeNumberProcessors, &ulSize);
+    SysProcessorTimeInfo = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)HeapAlloc(GetProcessHeap(), 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberProcessors);
+    status = NtQuerySystemInformation(SystemProcessorPerformanceInformation, SysProcessorTimeInfo, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.NumberProcessors, &ulSize);
     if (status != NO_ERROR)
         return;
 
@@ -133,12 +109,12 @@ void PerfDataRefresh(void)
     do
     {
         BufferSize += 0x10000;
-        SysHandleInfoData = (LPBYTE)malloc(BufferSize);
+        SysHandleInfoData = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize);
 
         status = NtQuerySystemInformation(SystemHandleInformation, SysHandleInfoData, BufferSize, &ulSize);
 
         if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
-            free(SysHandleInfoData);
+            HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
         }
 
     } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
@@ -151,12 +127,12 @@ void PerfDataRefresh(void)
     do
     {
         BufferSize += 0x10000;
-        pBuffer = (LPBYTE)malloc(BufferSize);
+        pBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BufferSize);
 
         status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
 
         if (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/) {
-            free(pBuffer);
+            HeapFree(GetProcessHeap(), 0, pBuffer);
         }
 
     } while (status == 0xC0000004 /*STATUS_INFO_LENGTH_MISMATCH*/);
@@ -177,7 +153,7 @@ void PerfDataRefresh(void)
      * Save system processor time info
      */
     if (SystemProcessorTimeInfo) {
-        free(SystemProcessorTimeInfo);
+        HeapFree(GetProcessHeap(), 0, SystemProcessorTimeInfo);
     }
     SystemProcessorTimeInfo = SysProcessorTimeInfo;
     
@@ -185,9 +161,9 @@ void PerfDataRefresh(void)
      * Save system handle info
      */
     memcpy(&SystemHandleInfo, SysHandleInfoData, sizeof(SYSTEM_HANDLE_INFORMATION));
-    free(SysHandleInfoData);
+    HeapFree(GetProcessHeap(), 0, SysHandleInfoData);
     
-    for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.bKeNumberProcessors; Idx++) {
+    for (CurrentKernelTime=0, Idx=0; Idx<SystemBasicInfo.NumberProcessors; Idx++) {
         CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
         CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
         CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
@@ -196,22 +172,22 @@ void PerfDataRefresh(void)
     /* If it's a first call - skip idle time calcs */
     if (liOldIdleTime.QuadPart != 0) {
         /*  CurrentValue = NewValue - OldValue */
-        dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
+        dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
         dbKernelTime = CurrentKernelTime - OldKernelTime;
-        dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
+        dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime);
 
         /*  CurrentCpuIdle = IdleTime / SystemTime */
         dbIdleTime = dbIdleTime / dbSystemTime;
         dbKernelTime = dbKernelTime / dbSystemTime;
         
         /*  CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
-        dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
-        dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
+        dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.NumberProcessors; /* + 0.5; */
+        dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.NumberProcessors; /* + 0.5; */
     }
 
     /* Store new CPU's idle and system time */
-    liOldIdleTime = SysPerfInfo.liIdleTime;
-    liOldSystemTime = SysTimeInfo.liKeSystemTime;
+    liOldIdleTime = SysPerfInfo.IdleTime;
+    liOldSystemTime = SysTimeInfo.CurrentTime;
     OldKernelTime = CurrentKernelTime;
 
     /* Determine the process count
@@ -223,24 +199,24 @@ void PerfDataRefresh(void)
     pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
     while (pSPI) {
         ProcessCount++;
-        if (pSPI->RelativeOffset == 0)
+        if (pSPI->NextEntryOffset == 0)
             break;
-        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
+        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
     }
 
     /* Now alloc a new PERFDATA array and fill in the data */
     if (pPerfDataOld) {
-        free(pPerfDataOld);
+        HeapFree(GetProcessHeap(), 0, pPerfDataOld);
     }
     pPerfDataOld = pPerfData;
-    pPerfData = (PPERFDATA)malloc(sizeof(PERFDATA) * ProcessCount);
+    pPerfData = (PPERFDATA)HeapAlloc(GetProcessHeap(), 0, sizeof(PERFDATA) * ProcessCount);
     pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
     for (Idx=0; Idx<ProcessCount; Idx++) {
         /* Get the old perf data for this process (if any) */
         /* so that we can establish delta values */
         pPDOld = NULL;
         for (Idx2=0; Idx2<ProcessCountOld; Idx2++) {
-            if (pPerfDataOld[Idx2].ProcessId == pSPI->ProcessId) {
+            if (pPerfDataOld[Idx2].ProcessId == pSPI->UniqueProcessId) {
                 pPDOld = &pPerfDataOld[Idx2];
                 break;
             }
@@ -249,25 +225,26 @@ void PerfDataRefresh(void)
         /* Clear out process perf data structure */
         memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
 
-        if (pSPI->Name.Buffer)
-            wcscpy(pPerfData[Idx].ImageName, pSPI->Name.Buffer);
+        if (pSPI->ImageName.Buffer)
+            wcscpy(pPerfData[Idx].ImageName, pSPI->ImageName.Buffer);
         else
-            wcscpy(pPerfData[Idx].ImageName, L"System Idle Process");
+            LoadStringW(hInst, IDS_IDLE_PROCESS, pPerfData[Idx].ImageName,
+                        sizeof(pPerfData[Idx].ImageName) / sizeof(pPerfData[Idx].ImageName[0]));
 
-        pPerfData[Idx].ProcessId = pSPI->ProcessId;
+        pPerfData[Idx].ProcessId = pSPI->UniqueProcessId;
 
         if (pPDOld)    {
             double    CurTime = Li2Double(pSPI->KernelTime) + Li2Double(pSPI->UserTime);
             double    OldTime = Li2Double(pPDOld->KernelTime) + Li2Double(pPDOld->UserTime);
             double    CpuTime = (CurTime - OldTime) / dbSystemTime;
-            CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
+            CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.NumberProcessors; /* + 0.5; */
             pPerfData[Idx].CPUUsage = (ULONG)CpuTime;
         }
         pPerfData[Idx].CPUTime.QuadPart = pSPI->UserTime.QuadPart + pSPI->KernelTime.QuadPart;
-        pPerfData[Idx].WorkingSetSizeBytes = pSPI->TotalWorkingSetSizeBytes;
-        pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSizeBytes;
+        pPerfData[Idx].WorkingSetSizeBytes = pSPI->WorkingSetSize;
+        pPerfData[Idx].PeakWorkingSetSizeBytes = pSPI->PeakWorkingSetSize;
         if (pPDOld)
-            pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->TotalWorkingSetSizeBytes - (LONG)pPDOld->WorkingSetSizeBytes);
+            pPerfData[Idx].WorkingSetSizeDelta = labs((LONG)pSPI->WorkingSetSize - (LONG)pPDOld->WorkingSetSizeBytes);
         else
             pPerfData[Idx].WorkingSetSizeDelta = 0;
         pPerfData[Idx].PageFaultCount = pSPI->PageFaultCount;
@@ -275,15 +252,15 @@ void PerfDataRefresh(void)
             pPerfData[Idx].PageFaultCountDelta = labs((LONG)pSPI->PageFaultCount - (LONG)pPDOld->PageFaultCount);
         else
             pPerfData[Idx].PageFaultCountDelta = 0;
-        pPerfData[Idx].VirtualMemorySizeBytes = pSPI->TotalVirtualSizeBytes;
-        pPerfData[Idx].PagedPoolUsagePages = pSPI->TotalPagedPoolUsagePages;
-        pPerfData[Idx].NonPagedPoolUsagePages = pSPI->TotalNonPagedPoolUsagePages;
+        pPerfData[Idx].VirtualMemorySizeBytes = pSPI->VirtualSize;
+        pPerfData[Idx].PagedPoolUsagePages = pSPI->QuotaPagedPoolUsage;
+        pPerfData[Idx].NonPagedPoolUsagePages = pSPI->QuotaPeakNonPagedPoolUsage;
         pPerfData[Idx].BasePriority = pSPI->BasePriority;
         pPerfData[Idx].HandleCount = pSPI->HandleCount;
-        pPerfData[Idx].ThreadCount = pSPI->ThreadCount;
+        pPerfData[Idx].ThreadCount = pSPI->NumberOfThreads;
         pPerfData[Idx].SessionId = pSPI->SessionId;
         
-        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pSPI->ProcessId);
+        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pSPI->UniqueProcessId);
         if (hProcess) {
             if (OpenProcessToken(hProcess, TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_IMPERSONATE, &hProcessToken)) {
                 ImpersonateLoggedOnUser(hProcessToken);
@@ -306,19 +283,16 @@ int MultiByteToWideChar(
                 RevertToSelf();
                 CloseHandle(hProcessToken);
             }
-            if (pGetGuiResources) {
-                pPerfData[Idx].USERObjectCount = pGetGuiResources(hProcess, GR_USEROBJECTS);
-                pPerfData[Idx].GDIObjectCount = pGetGuiResources(hProcess, GR_GDIOBJECTS);
-            }
-            if (pGetProcessIoCounters)
-                pGetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
+            pPerfData[Idx].USERObjectCount = GetGuiResources(hProcess, GR_USEROBJECTS);
+            pPerfData[Idx].GDIObjectCount = GetGuiResources(hProcess, GR_GDIOBJECTS);
+            GetProcessIoCounters(hProcess, &pPerfData[Idx].IOCounters);
             CloseHandle(hProcess);
         }
         pPerfData[Idx].UserTime.QuadPart = pSPI->UserTime.QuadPart;
         pPerfData[Idx].KernelTime.QuadPart = pSPI->KernelTime.QuadPart;
-        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->RelativeOffset);
+        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->NextEntryOffset);
     }
-    free(pBuffer);
+    HeapFree(GetProcessHeap(), 0, pBuffer);
     LeaveCriticalSection(&PerfDataCriticalSection);
 }
 
@@ -365,7 +339,7 @@ ULONG PerfDataGetProcessId(ULONG Index)
     EnterCriticalSection(&PerfDataCriticalSection);
 
     if (Index < ProcessCount)
-        ProcessId = pPerfData[Index].ProcessId;
+        ProcessId = (ULONG)pPerfData[Index].ProcessId;
     else
         ProcessId = 0;
 
@@ -677,8 +651,8 @@ ULONG PerfDataGetCommitChargeTotalK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Total = SystemPerfInfo.MmTotalCommitedPages;
-    PageSize = SystemBasicInfo.uPageSize;
+    Total = SystemPerfInfo.TotalCommittedPages;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -694,8 +668,8 @@ ULONG PerfDataGetCommitChargeLimitK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Limit = SystemPerfInfo.MmTotalCommitLimit;
-    PageSize = SystemBasicInfo.uPageSize;
+    Limit = SystemPerfInfo.TotalCommitLimit;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -711,8 +685,8 @@ ULONG PerfDataGetCommitChargePeakK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Peak = SystemPerfInfo.MmPeakLimit;
-    PageSize = SystemBasicInfo.uPageSize;
+    Peak = SystemPerfInfo.PeakCommitment;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -730,9 +704,9 @@ ULONG PerfDataGetKernelMemoryTotalK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Paged = SystemPerfInfo.PoolPagedBytes;
-    NonPaged = SystemPerfInfo.PoolNonPagedBytes;
-    PageSize = SystemBasicInfo.uPageSize;
+    Paged = SystemPerfInfo.PagedPoolUsage;
+    NonPaged = SystemPerfInfo.NonPagedPoolUsage;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -751,8 +725,8 @@ ULONG PerfDataGetKernelMemoryPagedK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Paged = SystemPerfInfo.PoolPagedBytes;
-    PageSize = SystemBasicInfo.uPageSize;
+    Paged = SystemPerfInfo.PagedPoolUsage;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -768,8 +742,8 @@ ULONG PerfDataGetKernelMemoryNonPagedK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    NonPaged = SystemPerfInfo.PoolNonPagedBytes;
-    PageSize = SystemBasicInfo.uPageSize;
+    NonPaged = SystemPerfInfo.NonPagedPoolUsage;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -785,8 +759,8 @@ ULONG PerfDataGetPhysicalMemoryTotalK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Total = SystemBasicInfo.uMmNumberOfPhysicalPages;
-    PageSize = SystemBasicInfo.uPageSize;
+    Total = SystemBasicInfo.NumberOfPhysicalPages;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -802,8 +776,8 @@ ULONG PerfDataGetPhysicalMemoryAvailableK(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    Available = SystemPerfInfo.MmAvailablePages;
-    PageSize = SystemBasicInfo.uPageSize;
+    Available = SystemPerfInfo.AvailablePages;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -820,7 +794,7 @@ ULONG PerfDataGetPhysicalMemorySystemCacheK(void)
     EnterCriticalSection(&PerfDataCriticalSection);
 
     SystemCache = SystemCacheInfo.CurrentSize;
-    PageSize = SystemBasicInfo.uPageSize;
+    PageSize = SystemBasicInfo.PhysicalPageSize;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
@@ -836,7 +810,7 @@ ULONG PerfDataGetSystemHandleCount(void)
 
     EnterCriticalSection(&PerfDataCriticalSection);
 
-    HandleCount = SystemHandleInfo.Count;
+    HandleCount = SystemHandleInfo.NumberOfHandles;
 
     LeaveCriticalSection(&PerfDataCriticalSection);
 
index 44766e7..27f8dc8 100644 (file)
 extern "C" {
 #endif
 
-
-#if 0
-typedef struct _TIME {
-       DWORD LowPart;
-       LONG HighPart;
-} TIME, *PTIME;
-#endif
-
-typedef ULARGE_INTEGER TIME, *PTIME;
-
-/* typedef WCHAR                       UNICODE_STRING; */
-typedef struct _UNICODE_STRING {
-    USHORT     Length;
-    USHORT     MaximumLength;
-    PWSTR      Buffer;
-} UNICODE_STRING, *PUNICODE_STRING;
+#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
 
 typedef struct _PERFDATA
 {
        WCHAR                           ImageName[MAX_PATH];
-       ULONG                           ProcessId;
+       HANDLE                          ProcessId;
        WCHAR                           UserName[MAX_PATH];
        ULONG                           SessionId;
        ULONG                           CPUUsage;
@@ -71,277 +56,6 @@ typedef struct _PERFDATA
        TIME                            KernelTime;
 } PERFDATA, *PPERFDATA;
 
-typedef struct _CLIENT_ID
-{
-    HANDLE UniqueProcess;
-    HANDLE UniqueThread;
-} CLIENT_ID, *PCLIENT_ID;
-
-typedef enum _KWAIT_REASON
-{
-   Executive,
-   FreePage,
-   PageIn,
-   PoolAllocation,
-   DelayExecution,
-   Suspended,
-   UserRequest,
-   WrExecutive,
-   WrFreePage,
-   WrPageIn,
-   WrDelayExecution,
-   WrSuspended,
-   WrUserRequest,
-   WrQueue,
-   WrLpcReceive,
-   WrLpcReply,
-   WrVirtualMemory,
-   WrPageOut,
-   WrRendezvous,
-   Spare2,
-   Spare3,
-   Spare4,
-   Spare5,
-   Spare6,
-   WrKernel,
-   MaximumWaitReason,
-} KWAIT_REASON;
-
-/* SystemProcessThreadInfo (5) */
-typedef struct _SYSTEM_THREAD_INFORMATION
-{
-       TIME            KernelTime;
-       TIME            UserTime;
-       TIME            CreateTime;
-       ULONG           TickCount;
-       ULONG           StartEIP;
-       CLIENT_ID       ClientId;
-       ULONG           DynamicPriority;
-       ULONG           BasePriority;
-       ULONG           nSwitches;
-       DWORD           State;
-       KWAIT_REASON    WaitReason;
-       
-} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
-
-typedef struct SYSTEM_PROCESS_INFORMATION
-{
-       ULONG                           RelativeOffset;
-       ULONG                           ThreadCount;
-       ULONG                           Unused1 [6];
-       TIME                            CreateTime;
-       TIME                            UserTime;
-       TIME                            KernelTime;
-       UNICODE_STRING          Name;
-       ULONG                           BasePriority;
-       ULONG                           ProcessId;
-       ULONG                           ParentProcessId;
-       ULONG                           HandleCount;
-       ULONG                           SessionId;
-       ULONG                           Unused2;
-       ULONG                           PeakVirtualSizeBytes;
-       ULONG                           TotalVirtualSizeBytes;
-       ULONG                           PageFaultCount;
-       ULONG                           PeakWorkingSetSizeBytes;
-       ULONG                           TotalWorkingSetSizeBytes;
-       ULONG                           PeakPagedPoolUsagePages;
-       ULONG                           TotalPagedPoolUsagePages;
-       ULONG                           PeakNonPagedPoolUsagePages;
-       ULONG                           TotalNonPagedPoolUsagePages;
-       ULONG                           TotalPageFileUsageBytes;
-       ULONG                           PeakPageFileUsageBytes;
-       ULONG                           TotalPrivateBytes;
-       SYSTEM_THREAD_INFORMATION       ThreadSysInfo [1];
-       
-} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
-
-typedef struct
-{
-       DWORD   dwUnknown1;
-       ULONG   uKeMaximumIncrement;
-       ULONG   uPageSize;
-       ULONG   uMmNumberOfPhysicalPages;
-       ULONG   uMmLowestPhysicalPage;
-       ULONG   uMmHighestPhysicalPage;
-       ULONG   uAllocationGranularity;
-       PVOID   pLowestUserAddress;
-       PVOID   pMmHighestUserAddress;
-       ULONG   uKeActiveProcessors;
-       BYTE    bKeNumberProcessors;
-       BYTE    bUnknown2;
-       WORD    wUnknown3;
-} SYSTEM_BASIC_INFORMATION;
-
-/* SystemPerformanceInfo (2) */
-typedef struct _SYSTEM_PERFORMANCE_INFORMATION
-{
-       LARGE_INTEGER   /*TotalProcessorTime*/liIdleTime;
-       LARGE_INTEGER   IoReadTransferCount;
-       LARGE_INTEGER   IoWriteTransferCount;
-       LARGE_INTEGER   IoOtherTransferCount;
-       ULONG           IoReadOperationCount;
-       ULONG           IoWriteOperationCount;
-       ULONG           IoOtherOperationCount;
-       ULONG           MmAvailablePages;
-       ULONG           MmTotalCommitedPages;
-       ULONG           MmTotalCommitLimit;
-       ULONG           MmPeakLimit;
-       ULONG           PageFaults;
-       ULONG           WriteCopies;
-       ULONG           TransitionFaults;
-       ULONG           Unknown1;
-       ULONG           DemandZeroFaults;
-       ULONG           PagesInput;
-       ULONG           PagesRead;
-       ULONG           Unknown2;
-       ULONG           Unknown3;
-       ULONG           PagesOutput;
-       ULONG           PageWrites;
-       ULONG           Unknown4;
-       ULONG           Unknown5;
-       ULONG           PoolPagedBytes;
-       ULONG           PoolNonPagedBytes;
-       ULONG           Unknown6;
-       ULONG           Unknown7;
-       ULONG           Unknown8;
-       ULONG           Unknown9;
-       ULONG           MmTotalSystemFreePtes;
-       ULONG           MmSystemCodepage;
-       ULONG           MmTotalSystemDriverPages;
-       ULONG           MmTotalSystemCodePages;
-       ULONG           Unknown10;
-       ULONG           Unknown11;
-       ULONG           Unknown12;
-       ULONG           MmSystemCachePage;
-       ULONG           MmPagedPoolPage;
-       ULONG           MmSystemDriverPage;
-       ULONG           CcFastReadNoWait;
-       ULONG           CcFastReadWait;
-       ULONG           CcFastReadResourceMiss;
-       ULONG           CcFastReadNotPossible;
-       ULONG           CcFastMdlReadNoWait;
-       ULONG           CcFastMdlReadWait;
-       ULONG           CcFastMdlReadResourceMiss;
-       ULONG           CcFastMdlReadNotPossible;
-       ULONG           CcMapDataNoWait;
-       ULONG           CcMapDataWait;
-       ULONG           CcMapDataNoWaitMiss;
-       ULONG           CcMapDataWaitMiss;
-       ULONG           CcPinMappedDataCount;
-       ULONG           CcPinReadNoWait;
-       ULONG           CcPinReadWait;
-       ULONG           CcPinReadNoWaitMiss;
-       ULONG           CcPinReadWaitMiss;
-       ULONG           CcCopyReadNoWait;
-       ULONG           CcCopyReadWait;
-       ULONG           CcCopyReadNoWaitMiss;
-       ULONG           CcCopyReadWaitMiss;
-       ULONG           CcMdlReadNoWait;
-       ULONG           CcMdlReadWait;
-       ULONG           CcMdlReadNoWaitMiss;
-       ULONG           CcMdlReadWaitMiss;
-       ULONG           CcReadaheadIos;
-       ULONG           CcLazyWriteIos;
-       ULONG           CcLazyWritePages;
-       ULONG           CcDataFlushes;
-       ULONG           CcDataPages;
-       ULONG           ContextSwitches;
-       ULONG           Unknown13;
-       ULONG           Unknown14;
-       ULONG           SystemCalls;
-
-} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
-
-typedef struct
-{
-       LARGE_INTEGER   liKeBootTime;
-       LARGE_INTEGER   liKeSystemTime;
-       LARGE_INTEGER   liExpTimeZoneBias;
-       ULONG                   uCurrentTimeZoneId;
-       DWORD                   dwReserved;
-} SYSTEM_TIME_INFORMATION;
-
-/* SystemCacheInformation (21) */
-typedef struct _SYSTEM_CACHE_INFORMATION
-{
-       ULONG   CurrentSize;
-       ULONG   PeakSize;
-       ULONG   PageFaultCount;
-       ULONG   MinimumWorkingSet;
-       ULONG   MaximumWorkingSet;
-       ULONG   Unused[4];
-
-} SYSTEM_CACHE_INFORMATION;
-
-/* SystemPageFileInformation (18) */
-typedef
-struct _SYSTEM_PAGEFILE_INFORMATION
-{
-       ULONG           RelativeOffset;
-       ULONG           CurrentSizePages;
-       ULONG           TotalUsedPages;
-       ULONG           PeakUsedPages;
-       UNICODE_STRING  PagefileFileName;
-       
-} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;
-
-/* SystemHandleInformation (16) */
-/* (see ontypes.h) */
-typedef
-struct _SYSTEM_HANDLE_ENTRY
-{
-       ULONG   OwnerPid;
-       BYTE    ObjectType;
-       BYTE    HandleFlags;
-       USHORT  HandleValue;
-       PVOID   ObjectPointer;
-       ULONG   AccessMask;
-       
-} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY;
-
-typedef
-struct _SYSTEM_HANDLE_INFORMATION
-{
-       ULONG                   Count;
-       SYSTEM_HANDLE_ENTRY     Handle [1];
-       
-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
-
-/* SystemProcessorPerformanceInformation (8) */
-typedef
-struct _SYSTEM_PROCESSORTIME_INFO
-{
-       LARGE_INTEGER   IdleTime;
-       LARGE_INTEGER   KernelTime;
-       LARGE_INTEGER   UserTime;
-       LARGE_INTEGER   DpcTime;
-       LARGE_INTEGER   InterruptTime;
-       ULONG                   InterruptCount;
-       ULONG                   Unused;
-       
-} SYSTEM_PROCESSORTIME_INFO, *PSYSTEM_PROCESSORTIME_INFO;
-
-#define SystemBasicInformation                 0
-#define SystemPerformanceInformation   2
-#define SystemTimeInformation                  3
-#define        SystemProcessInformation                5
-#define SystemProcessorTimeInformation 8
-#define SystemHandleInformation                        16
-#define SystemPageFileInformation              18
-#define SystemCacheInformation                 21
-
-#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
-
-#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000
-#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000
-
-#define GR_GDIOBJECTS     0       /* Count of GDI objects */
-#define GR_USEROBJECTS    1       /* Count of USER objects */
-
-typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG); 
-typedef DWORD (WINAPI *PROCGGR)(HANDLE,DWORD);
-typedef BOOL (WINAPI *PROCGPIC)(HANDLE,PIO_COUNTERS);
-
 BOOL   PerfDataInitialize(void);
 void   PerfDataUninitialize(void);
 void   PerfDataRefresh(void);
index 119fbe3..b3e9a12 100644 (file)
  */
        
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-
-#include "perfpage.h"
-#include "perfdata.h"
-
-#include "graph.h"
-#include "graphctl.h"
 
 TGraphCtrl PerformancePageCpuUsageHistoryGraph;
 TGraphCtrl PerformancePageMemUsageHistoryGraph;
index 16ac717..f4d5e01 100644 (file)
@@ -1,3 +1,30 @@
-#define WIN32_LEAN_AND_MEAN    /* Exclude rarely-used stuff from Windows headers */
+#define NTOS_MODE_USER
+#include <ntos.h>
 #include <windows.h>
+#include <commctrl.h>
+#include <shellapi.h>
+#include <stdlib.h>
+#include <math.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <ctype.h>
+
 #include "taskmgr.h"
+#include "perfdata.h"
+#include "perfpage.h"
+#include "about.h"
+#include "procpage.h"
+#include "proclist.h"
+#include "affinity.h"
+#include "applpage.h"
+#include "column.h"
+#include "dbgchnl.h"
+#include "debug.h"
+#include "endproc.h"
+#include "font.h"
+#include "graph.h"
+#include "graphctl.h"
+#include "optnmenu.h"
+#include "priority.h"
+#include "run.h"
+#include "trayicon.h"
index c87969a..888d7ab 100644 (file)
@@ -4,6 +4,7 @@
  *  priority.c
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "priority.h"
-#include "procpage.h"
-#include "perfdata.h"
+
+TCHAR                szTemp[256];
+TCHAR                szTempA[256];
 
 void ProcessPage_OnSetPriorityRealTime(void)
 {
@@ -60,7 +53,9 @@ void ProcessPage_OnSetPriorityRealTime(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -68,14 +63,16 @@ void ProcessPage_OnSetPriorityRealTime(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -108,7 +105,9 @@ void ProcessPage_OnSetPriorityHigh(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -116,14 +115,16 @@ void ProcessPage_OnSetPriorityHigh(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -156,7 +157,9 @@ void ProcessPage_OnSetPriorityAboveNormal(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -164,14 +167,16 @@ void ProcessPage_OnSetPriorityAboveNormal(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, ABOVE_NORMAL_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -204,7 +209,9 @@ void ProcessPage_OnSetPriorityNormal(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -212,14 +219,16 @@ void ProcessPage_OnSetPriorityNormal(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, NORMAL_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -252,7 +261,9 @@ void ProcessPage_OnSetPriorityBelowNormal(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -260,14 +271,16 @@ void ProcessPage_OnSetPriorityBelowNormal(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, BELOW_NORMAL_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
@@ -300,7 +313,9 @@ void ProcessPage_OnSetPriorityLow(void)
     if ((ListView_GetSelectedCount(hProcessPageListCtrl) != 1) || (dwProcessId == 0))
         return;
 
-    if (MessageBox(hMainWnd, _T("WARNING: Changing the priority class of this process may\ncause undesired results including system instability. Are you\nsure you want to change the priority class?"), _T("Task Manager Warning"), MB_YESNO|MB_ICONWARNING) != IDYES)
+    LoadString(hInst, IDS_MSG_WARNINGCHANGEPRIORITY, szTemp, 256);
+    LoadString(hInst, IDS_MSG_TASKMGRWARNING, szTempA, 256);
+    if (MessageBox(hMainWnd, szTemp, szTempA, MB_YESNO|MB_ICONWARNING) != IDYES)
         return;
 
     hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, dwProcessId);
@@ -308,14 +323,16 @@ void ProcessPage_OnSetPriorityLow(void)
     if (!hProcess)
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
         return;
     }
 
     if (!SetPriorityClass(hProcess, IDLE_PRIORITY_CLASS))
     {
         GetLastErrorText(strErrorText, 260);
-        MessageBox(hMainWnd, strErrorText, _T("Unable to Change Priority"), MB_OK|MB_ICONSTOP);
+        LoadString(hInst, IDS_MSG_UNABLECHANGEPRIORITY, szTemp, 256);
+        MessageBox(hMainWnd, strErrorText, szTemp, MB_OK|MB_ICONSTOP);
     }
 
     CloseHandle(hProcess);
index 3b544a6..281147c 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "procpage.h"
-#include "proclist.h"
-#include "perfdata.h"
 
 
 INT_PTR CALLBACK    ProcessListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
index 7d872f9..1e1d8e9 100644 (file)
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "procpage.h"
-#include "perfdata.h"
-#include "column.h"
-#include "proclist.h"
-#include "dbgchnl.h"
-#include "endproc.h"
-#include <ctype.h>
 
 HWND hProcessPage;                        /* Process List Property Page */
 
index 49a4577..e82c9d9 100644 (file)
@@ -2,6 +2,7 @@
 // Microsoft Developer Studio generated include file.
 // Used by TaskMgr.rc
 //
+#define IDS_IDLE_PROCESS                102
 #define IDD_TASKMGR_DIALOG              102
 #define IDD_ABOUTBOX                    103
 #define IDS_APP_TITLE                   103
 #define IDS_LICENSE                     32816
 #define IDC_STATIC                      -1
 
+#define IDS_TAB_APPS                    310
+#define IDS_TAB_PROCESSES               311
+#define IDS_TAB_PERFORMANCE             312
+#define IDS_TAB_TASK                    313
+#define IDS_TAB_STATUS                  314
+#define IDS_TAB_IMAGENAME               315
+#define IDS_TAB_PID                     316
+#define IDS_TAB_USERNAME                317
+#define IDS_TAB_SESSIONID               318
+#define IDS_TAB_CPU                     319
+#define IDS_TAB_CPUTIME                 320
+#define IDS_TAB_MEMUSAGE                321
+#define IDS_TAB_PEAKMEMUSAGE            322
+#define IDS_TAB_MEMDELTA                323
+#define IDS_TAB_PAGEFAULT               324
+#define IDS_TAB_PFDELTA                 325
+#define IDS_TAB_VMSIZE                  326
+#define IDS_TAB_PAGEDPOOL               327
+#define IDS_TAB_NPPOOL                  328
+#define IDS_TAB_BASEPRI                 329
+#define IDS_TAB_HANDLES                 330
+#define IDS_TAB_THREADS                 331
+#define IDS_TAB_USERPBJECTS             332
+#define IDS_TAB_GDIOBJECTS              333
+#define IDS_TAB_IOREADS                 334
+#define IDS_TAB_IOWRITES                335
+#define IDS_TAB_IOOTHER                 336
+#define IDS_TAB_IOREADBYTES             337
+#define IDS_TAB_IOWRITESBYTES           338
+#define IDS_TAB_IOOTHERBYTES            339
+#define IDS_MENU_SELECTCOLUMNS          340
+#define IDS_MENU_16BITTASK              341
+#define IDS_MENU_WINDOWS                342
+#define IDS_MENU_LARGEICONS             343
+#define IDS_MENU_SMALLICONS             344
+#define IDS_MENU_DETAILS                345
+#define IDS_MENU_ONEGRAPHALLCPUS        346
+#define IDS_MENU_ONEGRAPHPERCPU         347
+#define IDS_MENU_CPUHISTORY             348
+#define IDS_MENU_SHOWKERNELTIMES        349
+#define IDS_CREATENEWTASK               350
+#define IDS_CREATENEWTASK_DESC          351
+#define IDS_MSG_ACCESSPROCESSAFF        352
+#define IDS_MSG_PROCESSONEPRO           353
+#define IDS_MSG_INVALIDOPTION           354
+#define IDS_MSG_UNABLEDEBUGPROCESS      355
+#define IDS_MSG_WARNINGDEBUG            356
+#define IDS_MSG_TASKMGRWARNING          357
+#define IDS_MSG_WARNINGTERMINATING      358
+#define IDS_MSG_UNABLETERMINATEPRO      359
+#define IDS_MSG_UNABLECHANGEPRIORITY    360
+#define IDS_MSG_WARNINGCHANGEPRIORITY   361
+#define IDS_MSG_TRAYICONCPUUSAGE        362
+
+
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
index 88ff88d..08a228b 100644 (file)
@@ -4,6 +4,7 @@
  *  run.c
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-    
-#include "run.h"
 
 void TaskManager_OnFileNew(void)
 {
-    HMODULE            hShell32;
-    RUNFILEDLG        RunFileDlg;
+    HMODULE          hShell32;
+    RUNFILEDLG       RunFileDlg;
     OSVERSIONINFO    versionInfo;
     WCHAR            wTitle[40];
     WCHAR            wText[256];
-    char            szTitle[40] = "Create New Task";
-    char            szText[256] = "Type the name of a program, folder, document, or Internet resource, and Task Manager will open it for you.";
+    TCHAR            szTemp[256];
+    char             szTitle[40];
+    char             szText[256];
+
+    /* Load language string from resource file */
+    LoadString(hInst, IDS_CREATENEWTASK, szTemp, 40);
+    strcpy(szTitle,szTemp);
+
+    LoadString(hInst, IDS_CREATENEWTASK_DESC, szTemp, 256);
+    strcpy(szText,szTemp);
+
 
     hShell32 = LoadLibrary(_T("SHELL32.DLL"));
     RunFileDlg = (RUNFILEDLG)(FARPROC)GetProcAddress(hShell32, (char*)((long)0x3D));
index ccb3648..751fe7e 100644 (file)
@@ -4,6 +4,7 @@
  * TaskMgr.c : Defines the entry point for the application.
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
 
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-
-#include "resource.h"
-#include "applpage.h"
-#include "procpage.h"
-#include "perfpage.h"
-#include "run.h"
-#include "perfdata.h"
-#include "optnmenu.h"
-#include "affinity.h"
-#include "priority.h"
-#include "debug.h"
-#include "endproc.h"
-#include "column.h"
-#include "about.h"
-#include "trayicon.h"
-#include "dbgchnl.h"
 
 #define STATUS_WINDOW   2001
 
@@ -257,7 +235,7 @@ TaskManagerWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
             OnAbout();
             break;
         case ID_FILE_EXIT:
-            DestroyWindow(hDlg);
+            EndDialog(hDlg, IDOK);
             break;
         }     
         break;
@@ -481,17 +459,17 @@ BOOL OnCreate(HWND hWnd)
 #endif
 
     /* Insert tabs */
-    _tcscpy(szTemp, _T("Applications"));
+    LoadString(hInst, IDS_TAB_APPS, szTemp, 256);
     memset(&item, 0, sizeof(TCITEM));
     item.mask = TCIF_TEXT;
     item.pszText = szTemp;
     TabCtrl_InsertItem(hTabWnd, 0, &item);
-    _tcscpy(szTemp, _T("Processes"));
+    LoadString(hInst, IDS_TAB_PROCESSES, szTemp, 256);
     memset(&item, 0, sizeof(TCITEM));
     item.mask = TCIF_TEXT;
     item.pszText = szTemp;
     TabCtrl_InsertItem(hTabWnd, 1, &item);
-    _tcscpy(szTemp, _T("Performance"));
+    LoadString(hInst, IDS_TAB_PERFORMANCE, szTemp, 256);
     memset(&item, 0, sizeof(TCITEM));
     item.mask = TCIF_TEXT;
     item.pszText = szTemp;
@@ -590,23 +568,12 @@ BOOL OnCreate(HWND hWnd)
     TabCtrl_SetCurFocus/*Sel*/(hTabWnd, 2);
     TabCtrl_SetCurFocus/*Sel*/(hTabWnd, nActivePage);
 
-    if (TaskManagerSettings.UpdateSpeed == 0)
-        KillTimer(hWnd, 1);
-    else if (TaskManagerSettings.UpdateSpeed == 1)
-    {
-        KillTimer(hWnd, 1);
+    if (TaskManagerSettings.UpdateSpeed == 1)
         SetTimer(hWnd, 1, 1000, NULL);
-    }
     else if (TaskManagerSettings.UpdateSpeed == 2)
-    {
-        KillTimer(hWnd, 1);
         SetTimer(hWnd, 1, 2000, NULL);
-    }
     else if (TaskManagerSettings.UpdateSpeed == 4)
-    {
-        KillTimer(hWnd, 1);
         SetTimer(hWnd, 1, 4000, NULL);
-    }
 
     /*
      * Refresh the performance data
@@ -965,6 +932,7 @@ void TaskManager_OnTabWndSelChange(void)
     HMENU hOptionsMenu;
     HMENU hViewMenu;
     HMENU hSubMenu;
+    TCHAR       szTemp[256];
 
     hMenu = GetMenu(hMainWnd);
     hViewMenu = GetSubMenu(hMenu, 2);
@@ -983,13 +951,22 @@ void TaskManager_OnTabWndSelChange(void)
         ShowWindow(hProcessPage, SW_HIDE);
         ShowWindow(hPerformancePage, SW_HIDE);
         BringWindowToTop(hApplicationPage);
-        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_LARGE, _T("Lar&ge Icons"));
-        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SMALL, _T("S&mall Icons"));
-        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_DETAILS, _T("&Details"));
+
+       LoadString(hInst, IDS_MENU_LARGEICONS, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_LARGE, szTemp);
+
+       LoadString(hInst, IDS_MENU_SMALLICONS, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SMALL, szTemp);
+
+       LoadString(hInst, IDS_MENU_DETAILS, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_DETAILS, szTemp);
 
         if (GetMenuItemCount(hMenu) <= 4) {
             hSubMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_WINDOWSMENU));
-            InsertMenu(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT)hSubMenu, _T("&Windows"));
+
+           LoadString(hInst, IDS_MENU_WINDOWS, szTemp, 256);
+            InsertMenu(hMenu, 3, MF_BYPOSITION|MF_POPUP, (UINT)hSubMenu, szTemp);
+
             DrawMenuBar(hMainWnd);
         }
         if (TaskManagerSettings.View_LargeIcons)
@@ -1009,8 +986,13 @@ void TaskManager_OnTabWndSelChange(void)
         ShowWindow(hProcessPage, SW_SHOW);
         ShowWindow(hPerformancePage, SW_HIDE);
         BringWindowToTop(hProcessPage);
-        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, _T("&Select Columns..."));
-        AppendMenu(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, _T("&Show 16-bit tasks"));
+
+        LoadString(hInst, IDS_MENU_SELECTCOLUMNS, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SELECTCOLUMNS, szTemp);
+
+        LoadString(hInst, IDS_MENU_16BITTASK, szTemp, 256);
+        AppendMenu(hOptionsMenu, MF_STRING, ID_OPTIONS_SHOW16BITTASKS, szTemp);
+
         if (TaskManagerSettings.Show16BitTasks)
             CheckMenuItem(hOptionsMenu, ID_OPTIONS_SHOW16BITTASKS, MF_BYCOMMAND|MF_CHECKED);
         if (GetMenuItemCount(hMenu) > 4)
@@ -1034,10 +1016,19 @@ void TaskManager_OnTabWndSelChange(void)
             DrawMenuBar(hMainWnd);
         }
         hSubMenu = CreatePopupMenu();
-        AppendMenu(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, _T("&One Graph, All CPUs"));
-        AppendMenu(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, _T("One Graph &Per CPU"));
-        AppendMenu(hViewMenu, MF_STRING|MF_POPUP, (UINT)hSubMenu, _T("&CPU History"));
-        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, _T("&Show Kernel Times"));
+
+        LoadString(hInst, IDS_MENU_ONEGRAPHALLCPUS, szTemp, 256);
+        AppendMenu(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHALL, szTemp);
+
+        LoadString(hInst, IDS_MENU_ONEGRAPHPERCPU, szTemp, 256);
+        AppendMenu(hSubMenu, MF_STRING, ID_VIEW_CPUHISTORY_ONEGRAPHPERCPU, szTemp);
+
+        LoadString(hInst, IDS_MENU_CPUHISTORY, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING|MF_POPUP, (UINT)hSubMenu, szTemp);
+
+        LoadString(hInst, IDS_MENU_SHOWKERNELTIMES, szTemp, 256);
+        AppendMenu(hViewMenu, MF_STRING, ID_VIEW_SHOWKERNELTIMES, szTemp);
+
         if (TaskManagerSettings.ShowKernelTimes)
             CheckMenuItem(hViewMenu, ID_VIEW_SHOWKERNELTIMES, MF_BYCOMMAND|MF_CHECKED);
         else
index 40e3ed1..6f2eb52 100644 (file)
@@ -248,6 +248,8 @@ IDB_FONT                BITMAP  DISCARDABLE res_dir/font.bmp
 } */
 
 #include "En.rc"
-#include "Es.rc"
 #include "De.rc"
+#include "Dk.rc"
+#include "Es.rc"
+#include "Sv.rc"
 
index 1955b7a..dfc4e5a 100644 (file)
@@ -4,6 +4,7 @@
  *  trayicon.c
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <brianp@reactos.org>
+ *                2005         Klemens Friedl <frik85@reactos.at>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  */
     
 #include "precomp.h"
-#include <commctrl.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <winnt.h>
-    
-#include "trayicon.h"
-#include "perfdata.h"
-#include "shellapi.h"
 
 HICON TrayIcon_GetProcessorUsageIcon(void)
 {
@@ -186,9 +176,10 @@ BOOL TrayIcon_ShellRemoveTrayIcon(void)
 
 BOOL TrayIcon_ShellUpdateTrayIcon(void)
 {
-    NOTIFYICONDATA    nid;
-    HICON            hIcon = NULL;
+    NOTIFYICONDATA  nid;
+    HICON           hIcon = NULL;
     BOOL            bRetVal;
+    TCHAR           szTemp[256];
     
     memset(&nid, 0, sizeof(NOTIFYICONDATA));
     
@@ -200,7 +191,8 @@ BOOL TrayIcon_ShellUpdateTrayIcon(void)
     nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
     nid.uCallbackMessage = WM_ONTRAYICON;
     nid.hIcon = hIcon;
-    wsprintf(nid.szTip, _T("CPU Usage: %d%%"), PerfDataGetProcessorUsage());
+    LoadString(hInst, IDS_MSG_TRAYICONCPUUSAGE, szTemp, 256);
+    wsprintf(nid.szTip, szTemp, PerfDataGetProcessorUsage());
     
     bRetVal = Shell_NotifyIcon(NIM_MODIFY, &nid);
     
diff --git a/reactos/subsys/system/vmwinst/Dk.rc b/reactos/subsys/system/vmwinst/Dk.rc
new file mode 100644 (file)
index 0000000..a96528c
--- /dev/null
@@ -0,0 +1,130 @@
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+IDD_WELCOMEPAGE DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Driver til Grafikkort Installation"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "ReactOS Installation har opdaget at du køre ReactOS under VMware(r).", -1, 100, 8, 160, 24
+  LTEXT "Hvis du ønsker at installere VMware(r) SVGA driveren Klik 'Næste', Ellers klik på 'Fortryd' for at afbryde.", -1, 100, 140, 160, 17
+END
+
+IDD_INSERT_VMWARE_TOOLS DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "ReactOS Installationen indeholder ingen VMware(r) SVGA driver.\n\nDerfor gå til menuen 'VM' i VMware(r) Arbejdsstation og vælg 'Install VMware tools...'\n\n\nKlik 'Næste' for at forsætte eller klik 'Fortryd' for at undlade at installere SVGA driveren.",-1,25,25,225,85
+END
+
+IDD_INSTALLING_VMWARE_TOOLS DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "{STATUS}",IDC_INSTALLINGSTATUS,25,68,225,8
+  CONTROL "", IDC_INSTALLINGPROGRESS, "msctls_progress32", PBS_MARQUEE | WS_CHILD | WS_VISIBLE | WS_BORDER, 25, 80, 225, 8
+END
+
+IDD_CONFIG DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "WMware(r) SVGA driver er blevet installeret med succes. Vælg din favorit Skærm Opløsning:",-1,25,5,225,20
+  PUSHBUTTON "640x480", 540, 25, 30, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "800x600", 1400, 25, 45, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1024x768", 1792, 25, 60, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1152x864", 2016, 25, 75, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1280x960", 2240, 110, 30, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1280x1024", 2304, 110, 45, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1400x1050", 2450, 110, 60, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1600x1200", 2800, 110, 75, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1792x1344", 3136, 195, 30, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1856x1392", 3248, 195, 45, 65, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "1920x1440", 3360, 195, 60, 50, 15, BS_AUTORADIOBUTTON
+  LTEXT "Vælg din favorit farve kvalitet:", -1, 25, 93, 225, 12
+  COMBOBOX IDC_COLORQUALITY, 25, 105, 75, 80, CBS_DROPDOWNLIST | WS_TABSTOP
+END
+
+IDD_INSTALLATION_FAILED DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "ReactOS Installationen var ikke i stand til at installere WMware(r) SVGA driver.\n\n\nKlik på 'Færdig' for at forsætte installations processen.",-1,25,25,225,85
+END
+
+IDD_CHOOSEACTION DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "WMware(r) SVGA driver er allerede installeret.\n\nVælg venligst hvad du ønsker at gøre:",-1,25,5,225,30
+  PUSHBUTTON "Konfigurer Skærm indstillinger", IDC_CONFIGSETTINGS, 25, 40, 200, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "Benyt en anden Grafikkort Driver", IDC_USEOTHERDRIVER, 25, 55, 200, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "Afinstallere WMware(r) SVGA driver", IDC_UNINSTALL, 25, 70, 200, 15, BS_AUTORADIOBUTTON
+  LTEXT "Klik på 'Næste' for at forsætte eller klik på 'Fortryd' for at afslutte guiden.", -1, 25, 93, 225, 12
+END
+
+IDD_SELECTDRIVER DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "Vælg venligst den driver til grafikkortet du ønsker at bruge:",-1,25,25,225,15
+  PUSHBUTTON "ReactOS VGA Driver", IDC_VGA, 25, 40, 225, 15, BS_AUTORADIOBUTTON
+  PUSHBUTTON "ReactOS VBE Driver (SVGA)", IDC_VBE, 25, 55, 225, 15, BS_AUTORADIOBUTTON
+  LTEXT "Klik på 'Færdig' for at afslutte operationen eller klik på 'fortryd' for at afslutte Installationen uden at gemme ændringerne.", -1, 25, 93, 225, 20
+END
+
+IDD_DOUNINSTALL DIALOGEX 0, 0, PROPSHEETWIDTH, PROPSHEETHEIGHT
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "VMware Installation - Driver til Grafikkort"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+  LTEXT "ReactOS installation skal til at afinstallere din VMware(r) SVGA driver!!!\n\n\nKlik på 'Færdig' for at afinstallere driveren eller klik på 'Fortryd' for at afslutte uden at gemme.",-1,25,25,225,85
+END
+
+STRINGTABLE
+BEGIN
+  IDS_WIZARD_NAME "VMware(r) detected"
+  IDS_FAILEDTOLOCATEDRIVERS "The ReactOS Setup couldn't find the required files.\nPlease make sure the VMware(r) tools CD-ROM is inserted."
+  IDS_FAILEDTOCOPYFILES "The ReactOS Setup failed to copy the required files.\nPlease make sure the VMware(r) tools CD-ROM is inserted.\n"
+  IDS_FAILEDTOACTIVATEDRIVER "Failed to activate the VMware(r) SVGA driver!"
+  IDS_FAILEDTOSELVGADRIVER "Failed to activate the ReactOS VGA driver!"
+  IDS_FAILEDTOSELVBEDRIVER "Failed to activate the ReactOS VBE driver!"
+  IDS_UNINSTNOTICE "The VMware(r) SVGA driver files have not yet been deleted.\nPlease delete them manually after a system reboot."
+END
+
+STRINGTABLE
+BEGIN
+  10001 "Laveste (8BPP)"
+  10002 "Mellem (16BPP)"
+  10003 "Højeste (32BPP)"
+END
+
+STRINGTABLE
+BEGIN
+  IDS_SEARCHINGFORCDROM "Søger efter VMware(r) Værktøjs Cdrom..."
+  IDS_COPYINGFILES      "Overfører filer..."
+  IDS_ENABLINGDRIVER    "Aktivere VMware(r) SVGA Driver..."
+END
+
+STRINGTABLE
+BEGIN
+  IDD_INSERT_VMWARE_TOOLSTITLE         "VMware(r) SVGA driver installations Guide"
+  IDD_INSERT_VMWARE_TOOLSSUBTITLE       "Vær venlig at indsættee VMware Værktøjs Cdrom´en."
+  IDD_INSTALLING_VMWARE_TOOLSTITLE      "VMware(r) SVGA driver installations Guide"
+  IDD_INSTALLING_VMWARE_TOOLSSUBTITLE   "Søger efter og overfører VMware(r) SVGA driver."
+  IDD_CONFIGTITLE                      "VMware(r) SVGA driver installations Guide"
+  IDD_CONFIGSUBTITLE                   "Vælg din favorit Skærmopløsning."
+  IDD_INSTALLATION_FAILEDTITLE         "VMware(r) SVGA driver installations Guide"
+  IDD_INSTALLATION_FAILEDSUBTITLE       "WMware(r) SVGA driver blev ikke installeret."
+  IDD_CHOOSEACTIONTITLE                "VMware(r) SVGA driver installations Guide"
+  IDD_CHOOSEACTIONSUBTITLE              "Vælg hvad du Ønsker at gøre."
+  IDD_SELECTDRIVERTITLE                 "VMware (r) SVGA driver installations Guide"
+  IDD_SELECTDRIVERSUBTITLE              "Vælge en driver."
+  IDD_DOUNINSTALLTITLE                  "VMware (r) SVGA driver installations Guide"
+  IDD_DOUNINSTALLSUBTITLE               "Afinstallere driveren."
+END
index 23309f6..3fd9e30 100644 (file)
@@ -1091,9 +1091,6 @@ CreateWizard(VOID)
   psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
 
   /* Display the wizard */
-  PropertySheet(&psh);
-
-  
   return (LONG)(PropertySheet(&psh) != -1);
 }
 
index 4cdd70c..327d3cd 100644 (file)
@@ -22,8 +22,8 @@ IDB_HEADER    BITMAP "resources/header.bmp"
  * files. Note that you can and may override resources which also have
  * a neutral version. This is to get localized bitmaps for example.
  */
-
 #include "En.rc"
 #include "De.rc"
+#include "Dk.rc"
 #include "Es.rc"
 
diff --git a/reactos/subsys/system/welcome/Dk.rc b/reactos/subsys/system/welcome/Dk.rc
new file mode 100644 (file)
index 0000000..5325dd1
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
+
+/* String Tables */
+
+/* Default settings */
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_APPTITLE            "ReactOS - Velkommen"
+    IDS_DEFAULTTOPICTITLE   "ReactOS"
+    IDS_DEFAULTTOPICDESC    "Velkommen til ReactOs operativ System.\n\nKlik på et emne til venstre."
+//    IDS_CHECKTEXT           "Vis denne dialog igen ved opstart"
+//    IDS_CLOSETEXT           "Afslut"
+END
+
+/* Topic buttons */
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TOPICBUTTON0        "Installer ReactOS"
+    IDS_TOPICBUTTON1        "Gennemse Cdrom"
+    IDS_TOPICBUTTON2        "Afslut"
+//    IDS_TOPICBUTTON3        "Empty Topic 3"
+//    IDS_TOPICBUTTON4        "Empty Topic 4"
+//    IDS_TOPICBUTTON5        "Empty Topic 5"
+//    IDS_TOPICBUTTON6        "Empty Topic 6"
+//    IDS_TOPICBUTTON7        "Empty Topic 7"
+//    IDS_TOPICBUTTON8        "Empty Topic 8"
+//    IDS_TOPICBUTTON9        "Empty Topic 9"
+END
+
+/* Topic titles */
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TOPICTITLE0         "Installer ReactOS"
+    IDS_TOPICTITLE1         "Gennemse Cdrom"
+    IDS_TOPICTITLE2         "Afslut"
+//    IDS_TOPICTITLE3         "Empty Topic Title 3"
+//    IDS_TOPICTITLE4         "Empty Topic Title 4"
+//    IDS_TOPICTITLE5         "Empty Topic Title 5"
+//    IDS_TOPICTITLE6         "Empty Topic Title 6"
+//    IDS_TOPICTITLE7         "Empty Topic Title 7"
+//    IDS_TOPICTITLE8         "Empty Topic Title 8"
+//    IDS_TOPICTITLE9         "Empty Topic Title 9"
+END
+
+/* Topic descriptions */
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_TOPICDESC0          "Opret en ny ReactOS installation på din computer eller opgradere en eksisterende installation."
+    IDS_TOPICDESC1          "Gennemse Reactos Installations Cdrom"
+    IDS_TOPICDESC2          "Klik på Afslut for at lukke."
+//    IDS_TOPICDESC3          "Topic description 3.\n\nDescribe topic 3 here."
+//    IDS_TOPICDESC4          "Topic description 4.\n\nDescribe topic 4 here."
+//    IDS_TOPICDESC5          "Topic description 5.\n\nDescribe topic 5 here."
+//    IDS_TOPICDESC6          "Topic description 6.\n\nDescribe topic 6 here."
+//    IDS_TOPICDESC7          "Topic description 7.\n\nDescribe topic 7 here."
+//    IDS_TOPICDESC8          "Topic description 8.\n\nDescribe topic 8 here."
+//    IDS_TOPICDESC9          "Topic description 9.\n\nDescribe topic 9 here."
+END
+
+/* EOF */
diff --git a/reactos/subsys/system/welcome/Sv.rc b/reactos/subsys/system/welcome/Sv.rc
new file mode 100644 (file)
index 0000000..0eb4a0b
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ *  Swedish (SE) resources\r
+ *\r
+ *  Copyright (C) 2005 David Nordenberg\r
+ *\r
+ *  This program is free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  This program is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with this program; if not, write to the Free Software\r
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r
+\r
+/* String Tables */\r
+\r
+/* Default settings */\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_APPTITLE            "ReactOS - Välkommen"\r
+    IDS_DEFAULTTOPICTITLE   "ReactOS"\r
+    IDS_DEFAULTTOPICDESC    "Välkommen till React Operating System.\n\nKlicka på ett avsnitt till vänster."\r
+//    IDS_CHECKTEXT           "Show this dialog again"\r
+//    IDS_CLOSETEXT           "Exit"\r
+END\r
+\r
+/* Topic buttons */\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_TOPICBUTTON0        "Installera ReactOS"\r
+    IDS_TOPICBUTTON1        "Utforska skivan"\r
+    IDS_TOPICBUTTON2        "Avsluta"\r
+//    IDS_TOPICBUTTON3        "Empty Topic 3"\r
+//    IDS_TOPICBUTTON4        "Empty Topic 4"\r
+//    IDS_TOPICBUTTON5        "Empty Topic 5"\r
+//    IDS_TOPICBUTTON6        "Empty Topic 6"\r
+//    IDS_TOPICBUTTON7        "Empty Topic 7"\r
+//    IDS_TOPICBUTTON8        "Empty Topic 8"\r
+//    IDS_TOPICBUTTON9        "Empty Topic 9"\r
+END\r
+\r
+/* Topic titles */\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_TOPICTITLE0         "Installera ReactOS"\r
+    IDS_TOPICTITLE1         "Utforska skivan"\r
+    IDS_TOPICTITLE2         "Avsluta"\r
+//    IDS_TOPICTITLE3         "Empty Topic Title 3"\r
+//    IDS_TOPICTITLE4         "Empty Topic Title 4"\r
+//    IDS_TOPICTITLE5         "Empty Topic Title 5"\r
+//    IDS_TOPICTITLE6         "Empty Topic Title 6"\r
+//    IDS_TOPICTITLE7         "Empty Topic Title 7"\r
+//    IDS_TOPICTITLE8         "Empty Topic Title 8"\r
+//    IDS_TOPICTITLE9         "Empty Topic Title 9"\r
+END\r
+\r
+/* Topic descriptions */\r
+STRINGTABLE DISCARDABLE\r
+BEGIN\r
+    IDS_TOPICDESC0          "Skapa en ny ReactOS installation på den här datorn eller uppgradera en befintlig."\r
+    IDS_TOPICDESC1          "Utforska skivan."\r
+    IDS_TOPICDESC2          "Avsluta det här programmet."\r
+//    IDS_TOPICDESC3          "Topic description 3.\n\nDescribe topic 3 here."\r
+//    IDS_TOPICDESC4          "Topic description 4.\n\nDescribe topic 4 here."\r
+//    IDS_TOPICDESC5          "Topic description 5.\n\nDescribe topic 5 here."\r
+//    IDS_TOPICDESC6          "Topic description 6.\n\nDescribe topic 6 here."\r
+//    IDS_TOPICDESC7          "Topic description 7.\n\nDescribe topic 7 here."\r
+//    IDS_TOPICDESC8          "Topic description 8.\n\nDescribe topic 8 here."\r
+//    IDS_TOPICDESC9          "Topic description 9.\n\nDescribe topic 9 here."\r
+END\r
+\r
+/* EOF */\r
index fffc280..1be85f5 100644 (file)
Binary files a/reactos/subsys/system/welcome/res/welcome.ico and b/reactos/subsys/system/welcome/res/welcome.ico differ
index c1c9b6a..5c14ef2 100755 (executable)
@@ -47,8 +47,10 @@ END
 
 
 /* Language-specific resources */
-#include "De.rc"
 #include "En.rc"
+#include "De.rc"
+#include "Dk.rc"
 #include "Es.rc"
+#include "Sv.rc"
 
 /* EOF */
index 10aeb48..16344a1 100644 (file)
@@ -84,7 +84,7 @@ SetSetupType (DWORD dwSetupType)
   dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                         L"SYSTEM\\Setup", //TEXT("SYSTEM\\Setup"),
                         0,
-                        KEY_QUERY_VALUE,
+                        KEY_SET_VALUE,
                         &hKey);
   if (dwError != ERROR_SUCCESS)
     {
index 168a4ca..d064782 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef __WINLOGON_MAIN_H__
 #define __WINLOGON_MAIN_H__
 
-#include <WinWlx.h>
+#include <winwlx.h>
 
 VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);
 VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext);
index ba3c73b..aec4dfc 100644 (file)
@@ -14,7 +14,7 @@
 #include <ntos.h>
 #include <windows.h>
 #include <stdio.h>
-#include <WinWlx.h>
+#include <winwlx.h>
 #include <wchar.h>
 #include <reactos/winlogon.h>
 
index bf10f1c..a8b8d5f 100644 (file)
@@ -130,6 +130,8 @@ typedef BOOL STDCALL (*PFN_GradientFill)(SURFOBJ*, CLIPOBJ*, XLATEOBJ*, TRIVERTE
 
 typedef struct _WNDGDI {
   WNDOBJ            WndObj;
+  LIST_ENTRY        ListEntry;
+  HWND              Hwnd;
   CLIPOBJ           *ClientClipObj;
   WNDOBJCHANGEPROC  ChangeProc;
   FLONG             Flags;
index 4831da4..1882b2e 100644 (file)
@@ -26,6 +26,9 @@
  * REVISION HISTORY:\r
  *                 16/11/2004: Created\r
  */\r
+\r
+/* TODO: Check how the WNDOBJ implementation should behave with a driver on windows. */\r
\r
 #include <w32k.h>\r
 \r
 /*\r
@@ -33,9 +36,9 @@
  */\r
 VOID\r
 FASTCALL\r
-IntEngWndChanged(\r
-        IN WNDOBJ *pwo,\r
-        IN FLONG   flChanged)\r
+IntEngWndCallChangeProc(\r
+  IN WNDOBJ *pwo,\r
+  IN FLONG   flChanged)\r
 {\r
   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);\r
   \r
@@ -62,23 +65,145 @@ IntEngWndChanged(
   WndObjInt->ChangeProc(pwo, flChanged);\r
 }\r
 \r
+/*\r
+ * Fills the CLIPOBJ and client rect of the WNDOBJ with the data from the given WINDOW_OBJECT\r
+ */\r
+BOOLEAN\r
+FASTCALL\r
+IntEngWndUpdateClipObj(\r
+  WNDGDI *WndObjInt,\r
+  PWINDOW_OBJECT Window)\r
+{\r
+  HRGN hVisRgn;\r
+  PROSRGNDATA visRgn;\r
+  CLIPOBJ *ClipObj = NULL;\r
+  CLIPOBJ *OldClipObj;\r
+\r
+  hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);\r
+  if (hVisRgn != NULL)\r
+  {\r
+    NtGdiOffsetRgn(hVisRgn, Window->ClientRect.left, Window->ClientRect.top);\r
+    visRgn = RGNDATA_LockRgn(hVisRgn);\r
+    if (visRgn != NULL)\r
+    {\r
+      if (visRgn->rdh.nCount > 0)\r
+      {\r
+        ClipObj = IntEngCreateClipRegion(visRgn->rdh.nCount, (PRECTL)visRgn->Buffer,\r
+                                         (PRECTL)&visRgn->rdh.rcBound);\r
+        DPRINT("Created visible region with %d rects\n", visRgn->rdh.nCount);\r
+        DPRINT("  BoundingRect: %d, %d  %d, %d\n",\r
+               visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,\r
+               visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);\r
+        {\r
+          INT i;\r
+          for (i = 0; i < visRgn->rdh.nCount; i++)\r
+          {\r
+            DPRINT("  Rect #%d: %d,%d  %d,%d\n", i+1,\r
+                   visRgn->Buffer[i].left, visRgn->Buffer[i].top,\r
+                   visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);\r
+          }\r
+        }\r
+      }\r
+      RGNDATA_UnlockRgn(hVisRgn);\r
+    }\r
+    else\r
+    {\r
+      DPRINT1("Warning: Couldn't lock visible region of window DC\n");\r
+    }\r
+  }\r
+  else\r
+  {\r
+    DPRINT1("Warning: VIS_ComputeVisibleRegion failed!\n");\r
+  }\r
+\r
+  if (ClipObj == NULL)\r
+  {\r
+    /* Fall back to client rect */\r
+    ClipObj = IntEngCreateClipRegion(1, (PRECTL)&Window->ClientRect,\r
+                                     (PRECTL)&Window->ClientRect);\r
+  }\r
+  \r
+  if (ClipObj == NULL)\r
+  {\r
+    DPRINT1("Warning: IntEngCreateClipRegion() failed!\n");\r
+    return FALSE;\r
+  }\r
+\r
+  RtlCopyMemory(&WndObjInt->WndObj.coClient, ClipObj, sizeof (CLIPOBJ));\r
+  RtlCopyMemory(&WndObjInt->WndObj.rclClient, &Window->ClientRect, sizeof (RECT));\r
+  OldClipObj = InterlockedExchangePointer(&WndObjInt->ClientClipObj, ClipObj);\r
+  if (OldClipObj != NULL)\r
+    IntEngDeleteClipRegion(OldClipObj);\r
+  \r
+  return TRUE;\r
+}\r
+\r
+/*\r
+ * Updates all WNDOBJs of the given WINDOW_OBJECT and calls the change-procs.\r
+ */\r
+VOID\r
+FASTCALL\r
+IntEngWindowChanged(\r
+  PWINDOW_OBJECT  Window,\r
+  FLONG           flChanged)\r
+{\r
+  PLIST_ENTRY CurrentEntry;\r
+  WNDGDI *Current;\r
+\r
+  ASSERT_IRQL(PASSIVE_LEVEL);\r
+\r
+  ExAcquireFastMutex(&Window->WndObjListLock);\r
+  CurrentEntry = Window->WndObjListHead.Flink;\r
+  while (CurrentEntry != &Window->WndObjListHead)\r
+    {\r
+      Current = CONTAINING_RECORD(CurrentEntry, WNDGDI, ListEntry);\r
+      \r
+      if (Current->WndObj.pvConsumer != NULL)\r
+        {\r
+          /* Update the WNDOBJ */\r
+          switch (flChanged)\r
+            {\r
+            case WOC_RGN_CLIENT:\r
+              /* Update the clipobj and client rect of the WNDOBJ */\r
+              IntEngWndUpdateClipObj(Current, Window);\r
+              break;\r
+          \r
+            case WOC_DELETE:\r
+              /* FIXME: Should the WNDOBJs be deleted by win32k or by the driver? */\r
+              break;\r
+            }\r
+\r
+          /* Call the change proc */\r
+          IntEngWndCallChangeProc(&Current->WndObj, flChanged);\r
+      \r
+          /* HACK: Send WOC_CHANGED after WOC_RGN_CLIENT */\r
+          if (flChanged == WOC_RGN_CLIENT)\r
+            {\r
+              IntEngWndCallChangeProc(&Current->WndObj, WOC_CHANGED);\r
+            }\r
+\r
+          CurrentEntry = CurrentEntry->Flink;\r
+        }\r
+    }\r
+\r
+  ExReleaseFastMutex(&Window->WndObjListLock);\r
+}\r
+\r
 /*\r
  * @implemented\r
  */\r
 WNDOBJ*\r
 STDCALL\r
 EngCreateWnd(\r
-       SURFOBJ          *pso,\r
-       HWND              hwnd,\r
-       WNDOBJCHANGEPROC  pfn,\r
-       FLONG             fl,\r
-       int               iPixelFormat\r
-       )\r
+  SURFOBJ          *pso,\r
+  HWND              hwnd,\r
+  WNDOBJCHANGEPROC  pfn,\r
+  FLONG             fl,\r
+  int               iPixelFormat)\r
 {\r
   WNDGDI *WndObjInt = NULL;\r
   WNDOBJ *WndObjUser = NULL;\r
   PWINDOW_OBJECT Window;\r
-  CLIPOBJ *ClientClipObj;\r
 \r
   DPRINT("EngCreateWnd: pso = 0x%x, hwnd = 0x%x, pfn = 0x%x, fl = 0x%x, pixfmt = %d\n",\r
          pso, hwnd, pfn, fl, iPixelFormat);\r
@@ -99,27 +224,30 @@ EngCreateWnd(
       return NULL;\r
     }\r
 \r
-  ClientClipObj = IntEngCreateClipRegion(1, (PRECTL)&Window->ClientRect,\r
-                                         (PRECTL)&Window->ClientRect);\r
-  if (ClientClipObj == NULL)\r
+  /* Fill the clipobj */\r
+  WndObjInt->ClientClipObj = NULL;\r
+  if (!IntEngWndUpdateClipObj(WndObjInt, Window))\r
     {\r
       IntReleaseWindowObject(Window);\r
       EngFreeMem(WndObjInt);\r
       return NULL;\r
     }\r
 \r
-  /* fill user object */\r
+  /* Fill user object */\r
   WndObjUser = GDIToObj(WndObjInt, WND);\r
   WndObjUser->psoOwner = pso;\r
   WndObjUser->pvConsumer = NULL;\r
-  RtlCopyMemory(&WndObjUser->rclClient, &Window->ClientRect, sizeof (RECT));\r
-  RtlCopyMemory(&WndObjUser->coClient, ClientClipObj, sizeof (CLIPOBJ));\r
 \r
-  /* fill internal object */\r
+  /* Fill internal object */\r
+  WndObjInt->Hwnd = hwnd;\r
   WndObjInt->ChangeProc = pfn;\r
   WndObjInt->Flags = fl;\r
   WndObjInt->PixelFormat = iPixelFormat;\r
-  WndObjInt->ClientClipObj = ClientClipObj;\r
+\r
+  /* associate object with window */\r
+  ExAcquireFastMutex(&Window->WndObjListLock);\r
+  InsertTailList(&Window->WndObjListHead, &WndObjInt->ListEntry);\r
+  ExReleaseFastMutex(&Window->WndObjListLock);\r
 \r
   /* release resources */\r
   IntReleaseWindowObject(Window);\r
@@ -135,12 +263,31 @@ EngCreateWnd(
  */\r
 VOID\r
 STDCALL\r
-EngDeleteWnd ( IN WNDOBJ *pwo )\r
+EngDeleteWnd(\r
+  IN WNDOBJ *pwo)\r
 {\r
   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);\r
-  \r
+  PWINDOW_OBJECT Window;\r
+\r
   DPRINT("EngDeleteWnd: pwo = 0x%x\n", pwo);\r
 \r
+  /* Get window object */\r
+  Window = IntGetWindowObject(WndObjInt->Hwnd);\r
+  if (Window == NULL)\r
+    {\r
+      DPRINT1("Warning: Couldnt get window object for WndObjInt->Hwnd!!!\n");\r
+      RemoveEntryList(&WndObjInt->ListEntry);\r
+    }\r
+  else\r
+    {\r
+      /* Remove object from window */\r
+      ExAcquireFastMutex(&Window->WndObjListLock);\r
+      RemoveEntryList(&WndObjInt->ListEntry);\r
+      ExReleaseFastMutex(&Window->WndObjListLock);\r
+      IntReleaseWindowObject(Window);\r
+    }\r
+\r
+  /* Free resources */\r
   IntEngDeleteClipRegion(WndObjInt->ClientClipObj);\r
   EngFreeMem(WndObjInt);\r
 }\r
@@ -152,10 +299,9 @@ EngDeleteWnd ( IN WNDOBJ *pwo )
 BOOL\r
 STDCALL\r
 WNDOBJ_bEnum(\r
-       IN WNDOBJ  *pwo,\r
-       IN ULONG  cj,\r
-       OUT ULONG  *pul\r
-       )\r
+  IN WNDOBJ  *pwo,\r
+  IN ULONG  cj,\r
+  OUT ULONG  *pul)\r
 {\r
   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);\r
   BOOL Ret;\r
@@ -174,11 +320,10 @@ WNDOBJ_bEnum(
 ULONG\r
 STDCALL\r
 WNDOBJ_cEnumStart(\r
-       IN WNDOBJ  *pwo,\r
-       IN ULONG  iType,\r
-       IN ULONG  iDirection,\r
-       IN ULONG  cLimit\r
-       )\r
+  IN WNDOBJ  *pwo,\r
+  IN ULONG  iType,\r
+  IN ULONG  iDirection,\r
+  IN ULONG  cLimit)\r
 {\r
   WNDGDI *WndObjInt = ObjToGDI(pwo, WND);\r
   ULONG Ret;\r
@@ -200,9 +345,8 @@ WNDOBJ_cEnumStart(
 VOID\r
 STDCALL\r
 WNDOBJ_vSetConsumer(\r
-       IN WNDOBJ  *pwo,\r
-       IN PVOID  pvConsumer\r
-       )\r
+  IN WNDOBJ  *pwo,\r
+  IN PVOID  pvConsumer)\r
 {\r
   BOOL Hack;\r
 \r
@@ -211,12 +355,19 @@ WNDOBJ_vSetConsumer(
   Hack = (pwo->pvConsumer == NULL);\r
   pwo->pvConsumer = pvConsumer;\r
 \r
-  /* HACKHACKHACK */\r
+  /* HACKHACKHACK\r
+   *\r
+   * MSDN says that the WNDOBJCHANGEPROC will be called with the most recent state\r
+   * when a WNDOBJ is created - we do it here because most drivers will need pvConsumer\r
+   * in the callback to identify the WNDOBJ I think.\r
+   *\r
+   *  - blight\r
+   */\r
   if (Hack)\r
     {\r
-      IntEngWndChanged(pwo, WOC_RGN_CLIENT);\r
-      IntEngWndChanged(pwo, WOC_CHANGED);\r
-      IntEngWndChanged(pwo, WOC_DRAWN);\r
+      IntEngWndCallChangeProc(pwo, WOC_RGN_CLIENT);\r
+      IntEngWndCallChangeProc(pwo, WOC_CHANGED);\r
+      IntEngWndCallChangeProc(pwo, WOC_DRAWN);\r
     }\r
 }\r
 \r
index 58949bf..42069fe 100644 (file)
@@ -14,12 +14,28 @@ extern PWNDCLASS_OBJECT DesktopWindowClass;
 extern HDC ScreenDeviceContext;
 extern BOOL g_PaintDesktopVersion;
 
+typedef struct _SHELL_HOOK_WINDOW
+{
+  LIST_ENTRY ListEntry;
+  HWND hWnd;
+} SHELL_HOOK_WINDOW, *PSHELL_HOOK_WINDOW;
+
 NTSTATUS FASTCALL
 InitDesktopImpl(VOID);
 
 NTSTATUS FASTCALL
 CleanupDesktopImpl(VOID);
 
+NTSTATUS 
+STDCALL
+IntDesktopObjectCreate(PVOID ObjectBody,
+                       PVOID Parent,
+                       PWSTR RemainingPath,
+                       struct _OBJECT_ATTRIBUTES* ObjectAttributes);
+                      
+VOID STDCALL
+IntDesktopObjectDelete(PVOID DeletedObject);
+
 VOID FASTCALL
 IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect);
 
@@ -69,6 +85,11 @@ IntParseDesktopPath(PEPROCESS Process,
 BOOL FASTCALL
 IntDesktopUpdatePerUserSettings(BOOL bEnable);
 
+BOOL IntRegisterShellHookWindow(HWND hWnd);
+BOOL IntDeRegisterShellHookWindow(HWND hWnd);
+
+VOID IntShellHookNotify(WPARAM Message, LPARAM lParam);
+
 #define IntIsActiveDesktop(Desktop) \
   ((Desktop)->WindowStation->ActiveDesktop == (Desktop))
 
index 80a2fc4..49a13af 100644 (file)
@@ -17,6 +17,6 @@ RGBQUAD * FASTCALL
 DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
 
 HPALETTE FASTCALL
-BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType);
+BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
 
 #endif /* _WIN32K_DIB_H */
index cafed3f..c0bde5f 100644 (file)
@@ -15,4 +15,9 @@ IntEngMaskBlt(SURFOBJ *DestObj,
              BRUSHOBJ *Brush,
              POINTL *BrushOrigin);
 
+VOID FASTCALL
+IntEngWindowChanged(
+        PWINDOW_OBJECT Window,
+        FLONG flChanged);
+
 #endif /* _WIN32K_ENG_H */
index 052dff8..00ec42f 100644 (file)
@@ -8,6 +8,7 @@ InitInputImpl(VOID);
 NTSTATUS FASTCALL
 InitKeyboardImpl(VOID);
 PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
+VOID W32kUnregisterPrimitiveMessageQueue(VOID);
 PKBDTABLES W32kGetDefaultKeyLayout(VOID);
 VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout);
 BOOL FASTCALL IntBlockInput(PW32THREAD W32Thread, BOOL BlockIt);
index 32f8ab1..9d60931 100644 (file)
@@ -9,16 +9,29 @@ IntGdiCreateBrushXlate(PDC Dc, GDIBRUSHOBJ *BrushObj, BOOLEAN *Failed);
 VOID FASTCALL
 IntGdiInitBrushInstance(GDIBRUSHINST *BrushInst, PGDIBRUSHOBJ BrushObj, XLATEOBJ *XlateObj);
 
-HBRUSH FASTCALL
-IntGdiCreateBrushIndirect(PLOGBRUSH lb);
 
-HBRUSH FASTCALL
-IntGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked,
-                            UINT    ColorSpec);
+HBRUSH STDCALL
+IntGdiCreateDIBBrush(
+   CONST BITMAPINFO *BitmapInfo,
+   UINT ColorSpec,
+   UINT BitmapInfoSize,
+   CONST VOID *PackedDIB);
 
-HBRUSH FASTCALL
-IntGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
-                              UINT       Usage);
+HBRUSH STDCALL
+IntGdiCreateHatchBrush(
+   INT Style,
+   COLORREF Color);
+
+HBRUSH STDCALL
+IntGdiCreatePatternBrush(
+   HBITMAP hBitmap);
+
+HBRUSH STDCALL
+IntGdiCreateSolidBrush(
+   COLORREF Color);
+
+HBRUSH STDCALL
+IntGdiCreateNullBrush(VOID);
 
 BOOL FASTCALL
 IntPatBlt(
@@ -130,7 +143,8 @@ HDC FASTCALL
 IntGdiCreateDC(PUNICODE_STRING Driver,
                PUNICODE_STRING Device,
                PUNICODE_STRING Output,
-               CONST PDEVMODEW InitData);
+               CONST PDEVMODEW InitData,
+               BOOL CreateAsIC);
 
 COLORREF FASTCALL
 IntGetDCColor(HDC hDC, ULONG Object);
@@ -192,5 +206,21 @@ IntGdiEscape(PDC    dc,
              LPCSTR InData,
              LPVOID OutData);
 
+BOOL
+FASTCALL
+IntEnumDisplaySettings(
+  IN PUNICODE_STRING pDeviceName  OPTIONAL,
+  IN DWORD iModeNum,
+  IN OUT LPDEVMODEW pDevMode,
+  IN DWORD dwFlags);
+  
+LONG
+FASTCALL
+IntChangeDisplaySettings(
+  IN PUNICODE_STRING pDeviceName  OPTIONAL,
+  IN LPDEVMODEW pDevMode,
+  IN DWORD dwflags,
+  IN PVOID lParam  OPTIONAL);
+
 #endif /* _WIN32K_INTGDI_H */
 
index 46055df..e6529da 100644 (file)
@@ -99,6 +99,9 @@ typedef struct _WINDOW_OBJECT
   ULONG Status;
   /* counter for tiled child windows */
   ULONG TiledCounter;
+  /* WNDOBJ list */
+  LIST_ENTRY WndObjListHead;
+  FAST_MUTEX WndObjListLock;
 } WINDOW_OBJECT; /* PWINDOW_OBJECT already declared at top of file */
 
 /* Window flags. */
@@ -199,6 +202,9 @@ IntGetAncestor(PWINDOW_OBJECT Wnd, UINT Type);
 PWINDOW_OBJECT FASTCALL
 IntGetParent(PWINDOW_OBJECT Wnd);
 
+PWINDOW_OBJECT FASTCALL
+IntGetOwner(PWINDOW_OBJECT Wnd);
+
 PWINDOW_OBJECT FASTCALL
 IntGetParentObject(PWINDOW_OBJECT Wnd);
 
index 5b57c07..73daafb 100644 (file)
@@ -23,6 +23,29 @@ InitWindowStationImpl(VOID);
 NTSTATUS FASTCALL
 CleanupWindowStationImpl(VOID);
 
+NTSTATUS 
+STDCALL
+IntWinStaObjectCreate(PVOID ObjectBody,
+                      PVOID Parent,
+                      PWSTR RemainingPath,
+                      struct _OBJECT_ATTRIBUTES* ObjectAttributes);
+                      
+VOID STDCALL
+IntWinStaObjectDelete(PVOID DeletedObject);
+
+PVOID STDCALL
+IntWinStaObjectFind(PVOID Object,
+                    PWSTR Name,
+                    ULONG Attributes);
+            
+NTSTATUS 
+STDCALL
+IntWinStaObjectParse(PVOID Object,
+                     PVOID *NextObject,
+                     PUNICODE_STRING FullPath,
+                     PWSTR *Path,
+                     ULONG Attributes);
+
 NTSTATUS FASTCALL
 IntValidateWindowStationHandle(
    HWINSTA WindowStation,
index 3742656..6270b3e 100644 (file)
@@ -35,11 +35,45 @@ typedef NTSTATUS (STDCALL *PW32_THREAD_CALLBACK)(
    struct _ETHREAD *Thread,
    BOOLEAN Create);
 
+/* 
+ * Callbacks used for Win32 objects... this define won't be needed after the Object Manager
+ * rewrite -- Alex
+ */
+typedef NTSTATUS STDCALL_FUNC
+(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody,
+                         PVOID Parent,
+                         PWSTR RemainingPath,
+                         struct _OBJECT_ATTRIBUTES* ObjectAttributes);
+
+typedef NTSTATUS STDCALL_FUNC
+(*OBJECT_PARSE_ROUTINE)(PVOID Object,
+                        PVOID *NextObject,
+                        PUNICODE_STRING FullPath,
+                        PWSTR *Path,
+                        ULONG Attributes);
+                        
+typedef VOID STDCALL_FUNC
+(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject);
+
+typedef PVOID STDCALL_FUNC
+(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject,
+                       PWSTR Name,
+                       ULONG Attributes);
+                       
+typedef struct _W32_OBJECT_CALLBACK {
+    OBJECT_CREATE_ROUTINE WinStaCreate;
+    OBJECT_PARSE_ROUTINE WinStaParse;
+    OBJECT_DELETE_ROUTINE WinStaDelete;
+    OBJECT_FIND_ROUTINE WinStaFind;
+    OBJECT_CREATE_ROUTINE DesktopCreate;
+    OBJECT_DELETE_ROUTINE DesktopDelete;    
+} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK;
+
 VOID STDCALL
 PsEstablishWin32Callouts(
    PW32_PROCESS_CALLBACK W32ProcessCallback,
    PW32_THREAD_CALLBACK W32ThreadCallback,
-   PVOID Param3,
+   PW32_OBJECT_CALLBACK W32ObjectCallback,
    PVOID Param4,
    ULONG W32ThreadSize,
    ULONG W32ProcessSize);
@@ -215,6 +249,7 @@ DriverEntry (
 {
   NTSTATUS Status;
   BOOLEAN Result;
+  W32_OBJECT_CALLBACK Win32kObjectCallbacks;
 
   /*
    * Register user mode call interface
@@ -230,13 +265,22 @@ DriverEntry (
       DPRINT1("Adding system services failed!\n");
       return STATUS_UNSUCCESSFUL;
     }
-
+    
+  /* 
+   * Register Object Manager Callbacks
+   */
+    Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectCreate;
+    Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse;
+    Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete;
+    Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind;
+    Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate;
+    Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete;
   /*
    * Register our per-process and per-thread structures.
    */
   PsEstablishWin32Callouts (Win32kProcessCallback,
                            Win32kThreadCallback,
-                           0,
+                           &Win32kObjectCallbacks,
                            0,
                            sizeof(W32THREAD),
                            sizeof(W32PROCESS));
index 7b382bb..d93175d 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-#define HEADER_TO_BODY(ObjectHeader) \
+#define USER_HEADER_TO_BODY(ObjectHeader) \
   ((PVOID)(((PUSER_OBJECT_HEADER)ObjectHeader) + 1))
 
-#define BODY_TO_HEADER(ObjectBody) \
+#define USER_BODY_TO_HEADER(ObjectBody) \
   ((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
 
 /* FUNCTIONS *****************************************************************/
@@ -125,7 +125,7 @@ ObmpCloseAllHandles(PUSER_HANDLE_TABLE HandleTable)
          
          if (ObjectBody != NULL)
            {
-             PUSER_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
+             PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
              
              ObmReferenceObjectByPointer(ObjectBody, otUnknown);
              ObjectHeader->HandleCount--;
@@ -191,7 +191,7 @@ ObmpDeleteHandle(PUSER_HANDLE_TABLE HandleTable,
   
   if (ObjectBody != NULL)
     {
-      ObjectHeader = BODY_TO_HEADER(ObjectBody);
+      ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
       ObjectHeader->HandleCount--;
       ObmReferenceObjectByPointer(ObjectBody, otUnknown);
       Entry->ObjectBody = NULL;
@@ -219,7 +219,7 @@ ObmpInitializeObject(PUSER_HANDLE_TABLE HandleTable,
   if (Handle != NULL)
     {
       Status = ObmCreateHandle(HandleTable,
-                              HEADER_TO_BODY(ObjectHeader),
+                              USER_HEADER_TO_BODY(ObjectHeader),
                               Handle);
     }
 
@@ -230,7 +230,7 @@ ObmpInitializeObject(PUSER_HANDLE_TABLE HandleTable,
 ULONG FASTCALL
 ObmGetReferenceCount(PVOID ObjectBody)
 {
-  PUSER_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
 
   return ObjectHeader->RefCount;
 }
@@ -238,7 +238,7 @@ ObmGetReferenceCount(PVOID ObjectBody)
 ULONG FASTCALL
 ObmGetHandleCount(PVOID ObjectBody)
 {
-  PUSER_OBJECT_HEADER ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  PUSER_OBJECT_HEADER ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
 
   return ObjectHeader->HandleCount;
 }
@@ -260,7 +260,7 @@ ObmReferenceObject(PVOID ObjectBody)
       return;
     }
   
-  ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
   
   ObjectHeader->RefCount++;
 
@@ -284,7 +284,7 @@ ObmDereferenceObject(PVOID ObjectBody)
       return;
     }
   
-  ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
   
   ObjectHeader->RefCount--;
   ObmpPerformRetentionChecks(ObjectHeader);
@@ -303,7 +303,7 @@ ObmReferenceObjectByPointer(PVOID ObjectBody,
 {
   PUSER_OBJECT_HEADER ObjectHeader;
   
-  ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
   
   if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
     {
@@ -331,7 +331,7 @@ ObmCreateObject(PUSER_HANDLE_TABLE HandleTable,
       return NULL;
     }
   
-  ObjectBody = HEADER_TO_BODY(ObjectHeader);
+  ObjectBody = USER_HEADER_TO_BODY(ObjectHeader);
   
   RtlZeroMemory(ObjectBody, ObjectSize);
   
@@ -369,7 +369,7 @@ ObmCreateHandle(PUSER_HANDLE_TABLE HandleTable,
 
   if (ObjectBody != NULL) 
     {
-      BODY_TO_HEADER(ObjectBody)->HandleCount++;
+      USER_BODY_TO_HEADER(ObjectBody)->HandleCount++;
     }
   
   ObmpLockHandleTable(HandleTable);
@@ -456,11 +456,12 @@ ObmReferenceObjectByHandle(PUSER_HANDLE_TABLE HandleTable,
   
   ObmpUnlockHandleTable(HandleTable);
   
-  ObjectHeader = BODY_TO_HEADER(ObjectBody);
+  ObjectHeader = USER_BODY_TO_HEADER(ObjectBody);
   
   if ((ObjectType != otUnknown) && (ObjectHeader->Type != ObjectType))
     {
       DPRINT1("Object type mismatch 0x%x 0x%x\n", ObjectType, ObjectHeader->Type);
+      ObmDereferenceObject(ObjectBody);
       return STATUS_UNSUCCESSFUL;
     }
   
index 943dfb1..9e08869 100644 (file)
@@ -274,4 +274,50 @@ BOOL STDCALL NtGdiDdAttachSurface(
 }
 */
 
+
+
+DWORD STDCALL NtGdiDdGetDriverInfo(      
+    HANDLE hDirectDrawLocal,
+    PDD_GETDRIVERINFODATA puGetDriverInfoData) 
+
+{                
+       DWORD  pdwNumHeaps; 
+       VIDEOMEMORY  *pvmList = NULL;
+    DWORD  pdwNumFourCC;
+    DWORD  *pdwFourCC = NULL;
+       DWORD  ddRVal;
+       
+
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+
+       ddRVal = pDirectDraw->DrvGetDirectDrawInfo(
+                 pDirectDraw->Global.dhpdev,(PDD_HALINFO) puGetDriverInfoData,
+                 &pdwNumHeaps, pvmList, &pdwNumFourCC, pdwFourCC);
+
+    GDIOBJ_UnlockObj(hDirectDrawLocal);
+       
+       return ddRVal;
+}
+
+
+
+DWORD STDCALL NtGdiDdWaitForVerticalBlank(      
+    HANDLE hDirectDrawLocal,
+    PDD_WAITFORVERTICALBLANKDATA puWaitForVerticalBlankData
+)
+{
+       DWORD  ddRVal;
+       PDD_DIRECTDRAW pDirectDraw = GDIOBJ_LockObj(hDirectDrawLocal, GDI_OBJECT_TYPE_DIRECTDRAW);
+       
+       puWaitForVerticalBlankData->lpDD = pDirectDraw->Local.lpGbl;
+
+       ddRVal = pDirectDraw->DdWaitForVerticalBlank(puWaitForVerticalBlankData);
+
+    GDIOBJ_UnlockObj(hDirectDrawLocal);
+
+       return ddRVal;
+}
+
+
+
 /* EOF */
index 1044922..1f2eb06 100644 (file)
 #include <debug.h>
 
 
+DWORD STDCALL NtGdiDdGetAvailDriverMemory(      
+    HANDLE hDirectDrawLocal,
+    PDD_GETAVAILDRIVERMEMORYDATA puGetAvailDriverMemoryData
+)
+{
+       UNIMPLEMENTED
+       
+
+       return 0;
+}
+
 BOOL STDCALL NtGdiD3dContextCreate(
     HANDLE hDirectDrawLocal,
     HANDLE hSurfColor,
@@ -308,15 +319,6 @@ DWORD STDCALL NtGdiDdFlipToGDISurface(
        return 0;
 }
 
-DWORD STDCALL NtGdiDdGetAvailDriverMemory(      
-    HANDLE hDirectDraw,
-    PDD_GETAVAILDRIVERMEMORYDATA puGetAvailDriverMemoryData
-)
-{
-       UNIMPLEMENTED
-
-       return 0;
-}
 
 DWORD STDCALL NtGdiDdGetBltStatus(      
     HANDLE hSurface,
@@ -338,15 +340,7 @@ HDC STDCALL NtGdiDdGetDC(
        return 0;
 }
 
-DWORD STDCALL NtGdiDdGetDriverInfo(      
-    HANDLE hDirectDraw,
-    PDD_GETDRIVERINFODATA puGetDriverInfoData
-)
-{
-       UNIMPLEMENTED
 
-       return 0;
-}
 
 DWORD STDCALL NtGdiDdGetDriverState(      
     PDD_GETDRIVERSTATEDATA pdata
@@ -600,14 +594,5 @@ DWORD STDCALL NtGdiDdUpdateOverlay(
        return 0;
 }
 
-DWORD STDCALL NtGdiDdWaitForVerticalBlank(      
-    HANDLE hDirectDraw,
-    PDD_WAITFORVERTICALBLANKDATA puWaitForVerticalBlankData
-)
-{
-       UNIMPLEMENTED
-
-       return 0;
-}
 
 /* EOF */
index fd95935..1952c2f 100644 (file)
@@ -534,6 +534,8 @@ NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
 void FASTCALL
 IntSetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset, LONG dwNewLong, BOOL Ansi)
 {
+  PWINDOW_OBJECT Parent, Owner;
+
   if ((int)Offset >= 0)
     {
       DPRINT("SetClassLong(%x, %d, %x)\n", WindowObject->Self, Offset, dwNewLong);
@@ -562,6 +564,25 @@ IntSetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset, LONG dwNewLong, BOOL
       break;
     case GCL_HICON:
       WindowObject->Class->hIcon = (HICON)dwNewLong;
+      Owner = IntGetOwner(WindowObject);
+      Parent = IntGetParent(WindowObject);
+
+      if ((!Owner) && (!Parent))
+        {
+          IntShellHookNotify(HSHELL_REDRAW, (LPARAM) WindowObject->Self);
+        }
+
+      if (Parent)
+        {
+          IntReleaseWindowObject(Parent);
+        }
+
+      if (Owner)
+        {
+          IntReleaseWindowObject(Owner);
+        }
+
+
       break;
     case GCL_HICONSM:
       WindowObject->Class->hIconSm = (HICON)dwNewLong;
index 55e4fa2..5574d9c 100644 (file)
@@ -66,6 +66,61 @@ CleanupDesktopImpl(VOID)
   return STATUS_SUCCESS;
 }
 
+/* OBJECT CALLBACKS **********************************************************/
+
+NTSTATUS STDCALL
+IntDesktopObjectCreate(PVOID ObjectBody,
+                      PVOID Parent,
+                      PWSTR RemainingPath,
+                      struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+{
+  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
+  UNICODE_STRING UnicodeString;
+
+  if (RemainingPath == NULL)
+       {
+               return STATUS_SUCCESS;
+       }
+
+  if (wcschr((RemainingPath + 1), '\\') != NULL)
+       {
+               return STATUS_UNSUCCESSFUL;
+       }
+
+  RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
+
+  DPRINT("Creating desktop (0x%X)  Name (%wZ)\n", Desktop, &UnicodeString);
+
+  KeInitializeSpinLock(&Desktop->Lock);
+  InitializeListHead(&Desktop->ShellHookWindows);
+
+  Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
+
+  /* Put the desktop on the window station's list of associcated desktops */
+  ExInterlockedInsertTailList(
+    &Desktop->WindowStation->DesktopListHead,
+    &Desktop->ListEntry,
+    &Desktop->WindowStation->Lock);
+
+  return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
+}
+
+VOID STDCALL
+IntDesktopObjectDelete(PVOID DeletedObject)
+{
+  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
+  KIRQL OldIrql;
+
+  DPRINT("Deleting desktop (0x%X)\n", Desktop);
+
+  /* Remove the desktop from the window station's list of associcated desktops */
+  KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
+  RemoveEntryList(&Desktop->ListEntry);
+  KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
+
+  RtlFreeUnicodeString(&Desktop->Name);
+}
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 NTSTATUS FASTCALL
@@ -486,6 +541,147 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
 #endif
 }
 
+/*
+ * Send the Message to the windows registered for ShellHook
+ * notifications. The lParam contents depend on the Message. See
+ * MSDN for more details (RegisterShellHookWindow)
+ */
+VOID IntShellHookNotify(WPARAM Message, LPARAM lParam)
+{
+  PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
+  PLIST_ENTRY Entry, Entry2;
+  PSHELL_HOOK_WINDOW Current;
+  KIRQL OldLevel;
+
+  static UINT MsgType = 0;
+
+  if (!MsgType) {
+
+    /* Too bad, this doesn't work.*/
+#if 0
+    UNICODE_STRING Str;
+    RtlInitUnicodeString(&Str, L"SHELLHOOK");
+    MsgType = NtUserRegisterWindowMessage(&Str);
+#endif
+    MsgType = IntAddAtom(L"SHELLHOOK");
+
+    DPRINT("MsgType = %x\n", MsgType);
+    if (!MsgType)
+      DPRINT1("LastError: %x\n", GetLastNtError());
+  }
+
+  if (!Desktop) {
+    DPRINT1("IntShellHookNotify: No desktop!\n");
+    return;
+  }
+
+  /* We have to do some tricks because the list could change
+   * between calls, and we can't keep the lock during the call
+   */
+
+  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
+  Entry = Desktop->ShellHookWindows.Flink;
+  while (Entry != &Desktop->ShellHookWindows) {
+    Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
+    KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+
+    DPRINT("Sending notify\n");
+    IntPostOrSendMessage(Current->hWnd,
+                         MsgType,
+                         Message,
+                         lParam);
+
+    /* Loop again to find the window we were sending to. If it doesn't
+     * exist anymore, we just stop. This could leave an infinite loop
+     * if a window is removed and readded to the list. That's quite
+     * unlikely though.
+     */
+
+    KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
+    Entry2 = Desktop->ShellHookWindows.Flink;
+    while (Entry2 != Entry &&
+           Entry2 != &Desktop->ShellHookWindows) {
+      Entry2 = Entry2->Flink;
+    }
+
+    if (Entry2 == Entry)
+      Entry = Entry->Flink;
+    else
+      break;
+  }
+  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+}
+/*
+ * Add the window to the ShellHookWindows list. The windows
+ * on that list get notifications that are important to shell
+ * type applications.
+ *
+ * TODO: Validate the window? I'm not sure if sending these messages to
+ * an unsuspecting application that is not your own is a nice thing to do.
+ */
+BOOL IntRegisterShellHookWindow(HWND hWnd)
+{
+  PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+  PSHELL_HOOK_WINDOW Entry;
+  KIRQL OldLevel;
+
+  DPRINT("IntRegisterShellHookWindow\n");
+
+  /* First deregister the window, so we can be sure it's never twice in the
+   * list.
+   */
+  IntDeRegisterShellHookWindow(hWnd);
+
+  Entry = ExAllocatePoolWithTag(NonPagedPool,
+                                sizeof(SHELL_HOOK_WINDOW),
+                                TAG_WINSTA);
+  /* We have to walk this structure with while holding a spinlock, so we
+   * need NonPagedPool */
+
+  if (!Entry)
+    return FALSE;
+
+  Entry->hWnd = hWnd;
+
+  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
+  InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
+  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+
+  return TRUE;
+}
+
+/*
+ * Remove the window from the ShellHookWindows list. The windows
+ * on that list get notifications that are important to shell
+ * type applications.
+ */
+BOOL IntDeRegisterShellHookWindow(HWND hWnd)
+{
+  PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+  PLIST_ENTRY Entry;
+  PSHELL_HOOK_WINDOW Current;
+  KIRQL OldLevel;
+
+  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
+
+  Entry = Desktop->ShellHookWindows.Flink;
+  while (Entry != &Desktop->ShellHookWindows) {
+    Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
+    if (Current->hWnd == hWnd) {
+      RemoveEntryList(Entry);
+      KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+      ExFreePool(Entry);
+      return TRUE;
+    }
+    Entry = Entry->Flink;
+  }
+
+  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+
+  return FALSE;
+}
+
 /*
  * NtUserCreateDesktop
  *
index 0e34f9f..3746b33 100644 (file)
@@ -62,6 +62,8 @@ IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
 VOID FASTCALL
 IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
 {
+   PWINDOW_OBJECT Window, Owner, Parent;
+
    if (hWnd)
    {
       /* Send palette messages */
@@ -75,6 +77,22 @@ IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
          WinPosSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0,
             SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
 
+      Window = IntGetWindowObject(hWnd);
+      if (Window) {
+        Owner = IntGetOwner(Window);
+        if (!Owner) {
+          Parent = IntGetParent(Window);
+          if (!Parent)
+            IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd);
+          else
+            IntReleaseWindowObject(Parent);
+        } else {
+          IntReleaseWindowObject(Owner);
+        }
+
+        IntReleaseWindowObject(Window);
+      }
+
       /* FIXME: IntIsWindow */
 
       IntPostOrSendMessage(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == NtUserGetForegroundWindow()), 0);
index 735f789..15374e5 100644 (file)
@@ -611,8 +611,8 @@ IntMouseInput(MOUSEINPUT *mi)
         MousePos.x = DesktopWindow->ClientRect.right - 1;
       if(MousePos.y >= DesktopWindow->ClientRect.bottom)
         MousePos.y = DesktopWindow->ClientRect.bottom - 1;
+      ObmDereferenceObject(DesktopWindow);
     }
-    ObmDereferenceObject(DesktopWindow);
 
     if(MousePos.x < 0)
       MousePos.x = 0;
index 835a5b8..d5c77f5 100644 (file)
@@ -216,7 +216,7 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
   PVK_TO_WCHAR_TABLE vtwTbl;
   PVK_TO_WCHARS10 vkPtr;
   size_t size_this_entry;
-  int nMod, shift;
+  int nMod;
   DWORD CapsMod = 0, CapsState = 0;
 
   CapsState = ModBits & ~MOD_BITS_MASK;
@@ -228,8 +228,6 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
     {
       return FALSE;
     }
-  shift = keyLayout->pCharModifiers->ModNumber[ModBits];
-  
   for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
     {
       vtwTbl = &keyLayout->pVkToWcharTable[nMod];
@@ -239,9 +237,10 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
         {
           if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
            {
-             CapsMod = 
-               shift | ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0);
-
+              CapsMod = keyLayout->pCharModifiers->ModNumber
+                  [ModBits ^ 
+                   ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
+              
              if( CapsMod > keyLayout->pVkToWcharTable[nMod].nModifications ) {
                  DWORD MaxBit = 1;
                  while( MaxBit < 
@@ -256,9 +255,9 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
              *pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
              *pwcTranslatedChar = vkPtr->wch[CapsMod];
              
-             DPRINT("%d %04x: CapsMod %08x CapsState %08x shift %08x Char %04x\n",
+             DPRINT("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
                       nMod, wVirtKey,
-                      CapsMod, CapsState, shift, *pwcTranslatedChar);
+                      CapsMod, CapsState, *pwcTranslatedChar);
 
              if( *pbDead ) 
                {
@@ -269,7 +268,7 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
                      DPRINT( "VK: %04x, ADDR: %08x\n", wVirtKey, (int)vkPtr );
                      return FALSE;
                    }
-                 *pwcTranslatedChar = vkPtr->wch[shift];
+                 *pwcTranslatedChar = vkPtr->wch[CapsMod];
                }
                return TRUE;
            }
index 3b8e33a..522404f 100644 (file)
@@ -30,6 +30,7 @@
 /* INCLUDES ******************************************************************/
 
 #include <w32k.h>
+#include <pseh.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -113,6 +114,7 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
   PUNICODE_STRING ClassName;
   UINT Size;
 
+  _SEH_TRY {
   if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
     {
       return (UINT) wParam;
@@ -163,6 +165,11 @@ MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
     {
       return MsgMemoryEntry->Size;
     }
+    } _SEH_HANDLE {
+    
+        DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
+    } _SEH_END;
+    return 0;
 }
 
 static FASTCALL NTSTATUS
index 3046d3c..760f6e4 100644 (file)
@@ -42,7 +42,6 @@ NtUserGetSystemMetrics(ULONG Index)
 {
   NTSTATUS Status;
   PWINSTATION_OBJECT WinStaObject;
-  PWINDOW_OBJECT DesktopWindow;
   ULONG Width, Height, Result;
 
   Result = 0;
@@ -156,19 +155,26 @@ NtUserGetSystemMetrics(ULONG Index)
       return(27);
     case SM_CXSCREEN:
     case SM_CYSCREEN:
-      DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
-      if (NULL != DesktopWindow)
-         {
-           Width = DesktopWindow->WindowRect.right;
-           Height = DesktopWindow->WindowRect.bottom;
-         }
-      else
-         {
-           Width = 640;
-           Height = 480;
-         }
-      IntReleaseWindowObject(DesktopWindow);
+    {
+      HDC ScreenDCHandle;
+      PDC ScreenDC;
+
+      Width = 640;
+      Height = 480;
+      ScreenDCHandle = IntGdiCreateDC(NULL, NULL, NULL, NULL, TRUE);
+      if (NULL != ScreenDCHandle)
+      {
+       ScreenDC = DC_LockDc(ScreenDCHandle);
+       if (NULL != ScreenDC)
+       {
+         Width = ScreenDC->GDIInfo->ulHorzRes;
+         Height = ScreenDC->GDIInfo->ulVertRes;
+         DC_UnlockDc(ScreenDCHandle);
+       }
+       NtGdiDeleteDC(ScreenDCHandle);
+      }
       return SM_CXSCREEN == Index ? Width : Height;
+    }
     case SM_CXSIZE:
     case SM_CYSIZE:
       return(18);
index 7135b28..27c68e4 100644 (file)
 /* registered Logon process */
 PW32PROCESS LogonProcess = NULL;
 
-void W32kRegisterPrimitiveMessageQueue() {
+VOID W32kRegisterPrimitiveMessageQueue(VOID)
+{
   extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
   if( !pmPrimitiveMessageQueue ) {
     PW32THREAD pThread;
     pThread = PsGetWin32Thread();
     if( pThread && pThread->MessageQueue ) {
       pmPrimitiveMessageQueue = pThread->MessageQueue;
+      IntReferenceMessageQueue(pmPrimitiveMessageQueue);
       DPRINT( "Installed primitive input queue.\n" );
     }    
   } else {
@@ -31,7 +33,15 @@ void W32kRegisterPrimitiveMessageQueue() {
   }
 }
 
-PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue() {
+VOID W32kUnregisterPrimitiveMessageQueue(VOID)
+{
+  extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
+  IntDereferenceMessageQueue(pmPrimitiveMessageQueue);
+  pmPrimitiveMessageQueue = NULL;
+}
+
+PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue()
+{
   extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
   return pmPrimitiveMessageQueue;
 }
index 900f3b9..b1c0048 100644 (file)
@@ -1413,15 +1413,21 @@ VOID FASTCALL
 MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
 {
   PDESKTOP_OBJECT desk;
+
   /* remove the message queue from any desktops */
-  if((desk = (PDESKTOP_OBJECT)InterlockedExchange((LONG*)&MessageQueue->Desktop, 0)))
-  {
-    InterlockedExchange((LONG*)&desk->ActiveMessageQueue, 0);
-    IntDereferenceMessageQueue(MessageQueue);
-  }
+  if ((desk = (PDESKTOP_OBJECT)InterlockedExchange((LONG*)&MessageQueue->Desktop, 0)))
+    {
+      InterlockedExchange((LONG*)&desk->ActiveMessageQueue, 0);
+      IntDereferenceMessageQueue(MessageQueue);
+    }
   
+  /* if this is the primitive message queue, deregister it */
+  if (MessageQueue == W32kGetPrimitiveMessageQueue())
+    W32kUnregisterPrimitiveMessageQueue();
+
   /* clean it up */
   MsqCleanupMessageQueue(MessageQueue);
+
   /* decrease the reference counter, if it hits zero, the queue will be freed */
   IntDereferenceMessageQueue(MessageQueue);
 }
index dece285..2c60312 100644 (file)
@@ -144,16 +144,6 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
               Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
             {
               IntSendMessage(hWnd, WM_PAINT, 0, 0);
-              IntLockWindowUpdate(Window);
-              if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
-                {
-                  Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
-                  if (Window->UpdateRegion == NULL)
-                    {
-                      MsqDecPaintCountQueue(Window->MessageQueue);
-                    }
-                }
-              IntUnLockWindowUpdate(Window);
             }
         }
     }
@@ -614,6 +604,10 @@ IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax,
    if (!MessageQueue->PaintPosted)
       return FALSE;
 
+   if ((MsgFilterMin != 0 || MsgFilterMax != 0) &&
+       (MsgFilterMin > WM_PAINT || MsgFilterMax < WM_PAINT))
+      return FALSE;
+
    if (hWnd)
       Message->hwnd = IntFindWindowToRepaint(hWnd, PsGetWin32Thread());
    else
@@ -635,25 +629,10 @@ IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax,
    Window = IntGetWindowObject(Message->hwnd);
    if (Window != NULL)
    {
-      IntLockWindowUpdate(Window);
-
-      if ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
-          (MsgFilterMin <= WM_PAINT && WM_PAINT <= MsgFilterMax))
-      {
-         Message->message = WM_PAINT;
-         Message->wParam = Message->lParam = 0;
-         if (Remove && Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
-         {
-            Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
-            if (Window->UpdateRegion == NULL)
-            {
-               MsqDecPaintCountQueue(Window->MessageQueue);
-            }
-         }
-      }
-      IntUnLockWindowUpdate(Window);
-
+      Message->message = WM_PAINT;
+      Message->wParam = Message->lParam = 0;
       IntReleaseWindowObject(Window);
+
       return TRUE;
    }
 
@@ -779,8 +758,11 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
    }
    else
    {
+      if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
+         MsqDecPaintCountQueue(Window->MessageQueue);
       IntGetClientRect(Window, &Ps.rcPaint);
    }
+   Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
    IntUnLockWindowUpdate(Window);
 
    if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
@@ -892,6 +874,7 @@ NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
       return ERROR;
    }
     
+   IntLockWindowUpdate(Window);
    if (Window->UpdateRegion == NULL)
    {
       RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR);
@@ -904,6 +887,7 @@ NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
          Window->WindowRect.left - Window->ClientRect.left,
          Window->WindowRect.top - Window->ClientRect.top);
    }
+   IntUnLockWindowUpdate(Window);
 
    IntReleaseWindowObject(Window);
 
@@ -923,49 +907,56 @@ NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
  */
 
 BOOL STDCALL
-NtUserGetUpdateRect(HWND Wnd, LPRECT UnsafeRect, BOOL Erase)
+NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
 {
-  RECT Rect;
-  HRGN Rgn;
-  PROSRGNDATA RgnData;
-  NTSTATUS Status;
+   PWINDOW_OBJECT Window;
+   RECT Rect;
+   INT RegionType;
+   PROSRGNDATA RgnData;
+   BOOL AlwaysPaint;
+   NTSTATUS Status;
 
-  Rgn = NtGdiCreateRectRgn(0, 0, 0, 0);
-  if (NULL == Rgn)
-    {
-      NtGdiDeleteObject(Rgn);
-      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
-      return FALSE;
-    }
-  NtUserGetUpdateRgn(Wnd, Rgn, Erase);
-  RgnData = RGNDATA_LockRgn(Rgn);
-  if (NULL == RgnData)
-    {
-      NtGdiDeleteObject(Rgn);
-      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
-      return FALSE;
-    }
-  if (ERROR == UnsafeIntGetRgnBox(RgnData, &Rect))
-    {
-      RGNDATA_UnlockRgn(Rgn);
-      NtGdiDeleteObject(Rgn);
-      SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
-      return FALSE;
-    }
-  RGNDATA_UnlockRgn(Rgn);
-  NtGdiDeleteObject(Rgn);
+   if (!(Window = IntGetWindowObject(hWnd)))
+   {
+      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      return ERROR;
+   }
+    
+   IntLockWindowUpdate(Window);
+   if (Window->UpdateRegion == NULL)
+   {
+      Rect.left = Rect.top = Rect.right = Rect.bottom = 0;
+   }
+   else
+   {
+      RgnData = RGNDATA_LockRgn(Window->UpdateRegion);
+      ASSERT(RgnData != NULL);
+      RegionType = UnsafeIntGetRgnBox(RgnData, &Rect);
+      ASSERT(RegionType != ERROR);
+      RGNDATA_UnlockRgn(Window->UpdateRegion);
+   }
+   AlwaysPaint = (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) ||
+                 (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT);
+   IntUnLockWindowUpdate(Window);
 
-  if (UnsafeRect != NULL)
-    {
+   IntReleaseWindowObject(Window);
+
+   if (bErase && Rect.left < Rect.right && Rect.top < Rect.bottom)
+   {
+      NtUserRedrawWindow(hWnd, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN);
+   }
+  
+   if (UnsafeRect != NULL)
+   {
       Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECT));
-      if (! NT_SUCCESS(Status))
-        {
-          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-          return FALSE;
-        }
-    }
+      if (!NT_SUCCESS(Status))
+      {
+         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         return FALSE;
+      }
+   }
 
-  return Rect.left < Rect.right && Rect.top < Rect.bottom;
+   return (Rect.left < Rect.right && Rect.top < Rect.bottom) || AlwaysPaint;
 }
 
 /*
index b8091f9..77c88ac 100644 (file)
@@ -59,6 +59,17 @@ NtUserCallHwnd(
   DWORD Unknown0,
   DWORD Unknown1)
 {
+  switch (Unknown0) {
+    case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW:
+      if (IntIsWindow((HWND) Unknown1))
+        return IntRegisterShellHookWindow((HWND) Unknown1);
+      return FALSE;
+      break;
+    case HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW:
+      if (IntIsWindow((HWND) Unknown1))
+        return IntDeRegisterShellHookWindow((HWND) Unknown1);
+      return FALSE;
+  }
   UNIMPLEMENTED
 
   return 0;
@@ -99,20 +110,6 @@ NtUserCallMsgFilter(
   return 0;
 }
 
-LONG
-STDCALL
-NtUserChangeDisplaySettings(
-  PUNICODE_STRING lpszDeviceName,
-  LPDEVMODEW lpDevMode,
-  HWND hwnd,
-  DWORD dwflags,
-  LPVOID lParam)
-{
-  // UNIMPLEMENTED
-  DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ );
-  return DISP_CHANGE_BADMODE;
-}
-
 DWORD
 STDCALL
 NtUserConvertMemHandle(
@@ -240,9 +237,24 @@ NtUserEnumDisplayDevices (
   PDISPLAY_DEVICE lpDisplayDevice, /* device information */
   DWORD dwFlags ) /* reserved */
 {
-  UNIMPLEMENTED
-
-  return 0;
+  DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n");
+  if (lpDevice->Length == 0 && iDevNum > 0)
+  {
+        /* Only one display device present */
+    return FALSE;
+  }
+  if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
+    return FALSE;
+
+  swprintf(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1");
+  swprintf(lpDisplayDevice->DeviceString, L"<Unknown>");
+  lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
+                              | DISPLAY_DEVICE_MODESPRUNED
+                              | DISPLAY_DEVICE_PRIMARY_DEVICE
+                              | DISPLAY_DEVICE_VGA_COMPATIBLE;
+  lpDisplayDevice->DeviceID[0] = L'0';
+  lpDisplayDevice->DeviceKey[0] = L'0';
+  return TRUE;
 }
 
 DWORD
index 75e9f84..e79a3cc 100644 (file)
@@ -92,11 +92,11 @@ IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL S
           SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
           return 0;
         }
-    
-      if (WindowObject->OwnerThread != PsGetCurrentThread())
+
+      if (WindowObject->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
         {
           IntReleaseWindowObject(WindowObject);
-          DPRINT1("Trying to set timer for window in another thread (shatter attack?)\n");
+          DPRINT1("Trying to set timer for window in another process (shatter attack?)\n");
           SetLastWin32Error(ERROR_ACCESS_DENIED);
           return 0;
         }
index 7463bce..ab5911f 100644 (file)
@@ -132,7 +132,7 @@ DceAllocDCE(HWND hWnd, DCE_TYPE Type)
   /* No real locking, just get the pointer */
   DCEOBJ_UnlockDCE(DceHandle);
   Dce->Self = DceHandle;
-  Dce->hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+  Dce->hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
   if (NULL == defaultDCstate)
     {
       defaultDCstate = NtGdiGetDCState(Dce->hDC);
@@ -354,6 +354,11 @@ noparent:
    Dce->DCXFlags &= ~DCX_DCEDIRTY;
    NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);
 
+   if (Window != NULL)
+   {
+      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
+   }
+
    if (hRgnVisible != NULL)
    {
       NtGdiDeleteObject(hRgnVisible);
@@ -856,6 +861,7 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
 
           if (Window->Self != pDCE->hwndCurrent)
             {
+//              IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
               IntReleaseWindowObject(CurrentWindow);
             }
         }
@@ -866,13 +872,6 @@ DceResetActiveDCEs(PWINDOW_OBJECT Window)
   DCE_UnlockList();
 }
 
-/* FIXME: find header file for this prototype. */
-extern BOOL FASTCALL
-IntEnumDisplaySettings(
-  PUNICODE_STRING lpszDeviceName,
-  DWORD iModeNum,
-  LPDEVMODEW lpDevMode,
-  DWORD dwFlags);
 
 #define COPY_DEVMODE_VALUE_TO_CALLER(dst, src, member) \
     Status = MmCopyToCaller(&(dst)->member, &(src)->member, sizeof ((src)->member)); \
@@ -893,15 +892,18 @@ NtUserEnumDisplaySettings(
 {
   NTSTATUS Status;
   LPDEVMODEW pSafeDevMode;
-  DWORD Size = 0, ExtraSize = 0;
+  PUNICODE_STRING pSafeDeviceName = NULL;
+  UNICODE_STRING SafeDeviceName;
+  USHORT Size = 0, ExtraSize = 0;
   
-  Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (lpDevMode->dmSize));
+  /* Copy the devmode */
+  Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (Size));
   if (!NT_SUCCESS(Status))
   {
     SetLastNtError(Status);
     return FALSE;
   }
-  Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (lpDevMode->dmDriverExtra));
+  Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (ExtraSize));
   if (!NT_SUCCESS(Status))
   {
     SetLastNtError(Status);
@@ -911,17 +913,36 @@ NtUserEnumDisplaySettings(
   if (pSafeDevMode == NULL)
   {
     SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-    return DISP_CHANGE_FAILED;
+    return FALSE;
   }
   pSafeDevMode->dmSize = Size;
   pSafeDevMode->dmDriverExtra = ExtraSize;
 
-  if (!IntEnumDisplaySettings(lpszDeviceName, iModeNum, pSafeDevMode, dwFlags))
+  /* Copy the device name */
+  if (lpszDeviceName != NULL)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
+    if (!NT_SUCCESS(Status))
+    {
+      ExFreePool(pSafeDevMode);
+      SetLastNtError(Status);
+      return FALSE;
+    }
+    pSafeDeviceName = &SafeDeviceName;
+  }
+
+  /* Call internal function */
+  if (!IntEnumDisplaySettings(pSafeDeviceName, iModeNum, pSafeDevMode, dwFlags))
   {
+    if (pSafeDeviceName != NULL)
+      RtlFreeUnicodeString(pSafeDeviceName);
     ExFreePool(pSafeDevMode);
     return FALSE;
   }
+  if (pSafeDeviceName != NULL)
+    RtlFreeUnicodeString(pSafeDeviceName);
 
+  /* Copy some information back */
   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsWidth);
   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsHeight);
   COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmBitsPerPel);
@@ -940,9 +961,84 @@ NtUserEnumDisplaySettings(
     }
   }
 
+  ExFreePool(pSafeDevMode);
   return TRUE;
 }
 
 #undef COPY_DEVMODE_VALUE_TO_CALLER
 
+
+LONG
+STDCALL
+NtUserChangeDisplaySettings(
+  PUNICODE_STRING lpszDeviceName,
+  LPDEVMODEW lpDevMode,
+  HWND hwnd,
+  DWORD dwflags,
+  LPVOID lParam)
+{
+  NTSTATUS Status;
+  DEVMODEW DevMode;
+  PUNICODE_STRING pSafeDeviceName = NULL;
+  UNICODE_STRING SafeDeviceName;
+  LONG Ret;
+
+  /* Check arguments */
+#ifdef CDS_VIDEOPARAMETERS
+  if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
+#else
+  if (lParam != NULL)
+#endif
+  {
+    SetLastWin32Error(ERROR_INVALID_PARAMETER);
+    return DISP_CHANGE_BADPARAM;
+  }
+  if (hwnd != NULL)
+  {
+    SetLastWin32Error(ERROR_INVALID_PARAMETER);
+    return DISP_CHANGE_BADPARAM;
+  }
+  
+  /* Copy devmode */
+  Status = MmCopyFromCaller(&DevMode.dmSize, &lpDevMode->dmSize, sizeof (DevMode.dmSize));
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastNtError(Status);
+    return DISP_CHANGE_BADPARAM;
+  }
+  DevMode.dmSize = min(sizeof (DevMode), DevMode.dmSize);
+  Status = MmCopyFromCaller(&DevMode, lpDevMode, DevMode.dmSize);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastNtError(Status);
+    return DISP_CHANGE_BADPARAM;
+  }
+  if (DevMode.dmDriverExtra > 0)
+  {
+    DbgPrint("(%s:%i) WIN32K: %s lpDevMode->dmDriverExtra is IGNORED!\n", __FILE__, __LINE__, __FUNCTION__);
+    DevMode.dmDriverExtra = 0;
+  }
+
+  /* Copy the device name */
+  if (lpszDeviceName != NULL)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
+    if (!NT_SUCCESS(Status))
+    {
+      SetLastNtError(Status);
+      return DISP_CHANGE_BADPARAM;
+    }
+    pSafeDeviceName = &SafeDeviceName;
+  }
+
+  /* Call internal function */
+  Ret = IntChangeDisplaySettings(pSafeDeviceName, &DevMode, dwflags, lParam);
+  
+  if (pSafeDeviceName != NULL)
+    RtlFreeUnicodeString(pSafeDeviceName);
+    
+  return Ret;
+}
+
+
 /* EOF */
index 6489cde..3dab0ce 100644 (file)
@@ -147,6 +147,17 @@ IntGetParent(PWINDOW_OBJECT Wnd)
   return NULL;
 }
 
+PWINDOW_OBJECT FASTCALL
+IntGetOwner(PWINDOW_OBJECT Wnd)
+{
+  HWND hWnd;
+
+  IntLockRelatives(Wnd);
+  hWnd = Wnd->Owner;
+  IntUnLockRelatives(Wnd);
+
+  return IntGetWindowObject(hWnd);
+}
 
 PWINDOW_OBJECT FASTCALL
 IntGetParentObject(PWINDOW_OBJECT Wnd)
@@ -205,6 +216,8 @@ IntWinListChildren(PWINDOW_OBJECT Window)
  */
 static void IntSendDestroyMsg(HWND Wnd)
 {
+
+  PWINDOW_OBJECT Window, Owner, Parent;
 #if 0 /* FIXME */
   GUITHREADINFO info;
 
@@ -217,9 +230,28 @@ static void IntSendDestroyMsg(HWND Wnd)
     }
 #endif
 
+  Window = IntGetWindowObject(Wnd);
+  if (Window) {
+    Owner = IntGetOwner(Window);
+    if (!Owner) {
+      Parent = IntGetParent(Window);
+      if (!Parent) 
+        IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) Wnd);
+      else
+        IntReleaseWindowObject(Parent);
+    } else {
+      IntReleaseWindowObject(Owner);
+    }
+
+    IntReleaseWindowObject(Window);
+  }
+
+  /* The window could already be destroyed here */
+
   /*
    * Send the WM_DESTROY to the window.
    */
+
   IntSendMessage(Wnd, WM_DESTROY, 0, 0);
 
   /*
@@ -284,6 +316,8 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
   IntUnLockThreadWindows(Window->OwnerThread->Tcb.Win32Thread);
   
   BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
+
+  IntDeRegisterShellHookWindow(Window->Self);
   
   if(SendMessages)
   {
@@ -1417,6 +1451,8 @@ IntCreateWindowEx(DWORD dwExStyle,
   BOOL MenuChanged;
   BOOL ClassFound;
 
+  BOOL HasOwner;
+
   ParentWindowHandle = PsGetWin32Thread()->Desktop->DesktopWindow;
   OwnerWindowHandle = NULL;
 
@@ -1542,9 +1578,11 @@ IntCreateWindowEx(DWORD dwExStyle,
   {
     WindowObject->Owner = OwnerWindowHandle;
     IntReleaseWindowObject(OwnerWindow);
-  }
-  else
+    HasOwner = TRUE;
+  } else {
     WindowObject->Owner = NULL;
+    HasOwner = FALSE;
+  }
   WindowObject->UserData = 0;
   if ((((DWORD)ClassObject->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
       && (((DWORD)ClassObject->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000)) 
@@ -1580,6 +1618,8 @@ IntCreateWindowEx(DWORD dwExStyle,
   ExInitializeFastMutex(&WindowObject->PropListLock);
   ExInitializeFastMutex(&WindowObject->RelativesLock);
   ExInitializeFastMutex(&WindowObject->UpdateLock);
+  InitializeListHead(&WindowObject->WndObjListHead);
+  ExInitializeFastMutex(&WindowObject->WndObjListLock);
 
   if (NULL != WindowName->Buffer)
     {  
@@ -1937,6 +1977,9 @@ IntCreateWindowEx(DWORD dwExStyle,
              WindowObject->ClientRect.top);
        }
       IntSendMessage(WindowObject->Self, WM_MOVE, 0, lParam);
+
+      /* Call WNDOBJ change procs */
+      IntEngWindowChanged(WindowObject, WOC_RGN_CLIENT);
     }
 
   /* Show or maybe minimize or maximize the window. */
@@ -1969,6 +2012,13 @@ IntCreateWindowEx(DWORD dwExStyle,
                      (LPARAM)WindowObject->Self);
     }
 
+  if ((!hWndParent) && (!HasOwner)) {
+      DPRINT("Sending CREATED notify\n");
+      IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
+  } else {
+      DPRINT("Not sending CREATED notify, %x %d\n", ParentWindow, HasOwner);
+  }
+
   if (NULL != ParentWindow)
     {
       IntReleaseWindowObject(ParentWindow);
@@ -2135,6 +2185,7 @@ NtUserDestroyWindow(HWND Wnd)
     }
 #endif
 
+  IntEngWindowChanged(Window, WOC_DELETE);
   isChild = (0 != (Window->Style & WS_CHILD));
 
 #if 0 /* FIXME */
@@ -4060,7 +4111,7 @@ NtUserWindowFromPoint(LONG X, LONG Y)
 BOOL STDCALL
 NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText)
 {
-  PWINDOW_OBJECT WindowObject;
+  PWINDOW_OBJECT WindowObject, Parent, Owner;
   UNICODE_STRING SafeText;
   NTSTATUS Status;
   
@@ -4090,6 +4141,26 @@ NtUserDefSetText(HWND WindowHandle, PUNICODE_STRING WindowText)
   RtlFreeUnicodeString(&WindowObject->WindowName);
   
   WindowObject->WindowName = SafeText;
+
+  /* Send shell notifications */
+
+  Owner = IntGetOwner(WindowObject);
+  Parent = IntGetParent(WindowObject);
+
+  if ((!Owner) && (!Parent))
+  {
+    IntShellHookNotify(HSHELL_REDRAW, (LPARAM) WindowHandle);
+  }
+
+  if (Owner)
+  {
+    IntReleaseWindowObject(Owner);
+  }
+
+  if (Parent)
+  {
+    IntReleaseWindowObject(Parent);
+  }
   
   IntReleaseWindowObject(WindowObject);
   return TRUE;
index 1d31e85..f432429 100644 (file)
@@ -1341,6 +1341,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
       IntSendMessage(Wnd, WM_MOVE, 0,
                      MAKELONG(Window->ClientRect.left,
                               Window->ClientRect.top));
+      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
     }
 
   /* Activate the window if activation is not requested and the window is not minimized */
index 3f6f241..afa60e2 100644 (file)
@@ -80,6 +80,163 @@ CleanupWindowStationImpl(VOID)
    return STATUS_SUCCESS;
 }
 
+/* OBJECT CALLBACKS  **********************************************************/
+                      
+NTSTATUS 
+STDCALL
+IntWinStaObjectCreate(PVOID ObjectBody,
+                      PVOID Parent,
+                      PWSTR RemainingPath,
+                      struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+{    
+  PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
+  UNICODE_STRING UnicodeString;
+  NTSTATUS Status;
+
+  if (RemainingPath == NULL)
+       {
+               return STATUS_SUCCESS;
+       }
+
+  if (wcschr((RemainingPath + 1), '\\') != NULL)
+       {
+               return STATUS_UNSUCCESSFUL;
+       }
+
+  RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
+
+  DPRINT("Creating window station (0x%X)  Name (%wZ)\n", WinSta, &UnicodeString);
+
+  Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer);
+  if (!NT_SUCCESS(Status))
+  {
+    return Status;
+  }
+
+  KeInitializeSpinLock(&WinSta->Lock);
+
+  InitializeListHead(&WinSta->DesktopListHead);
+
+  WinSta->AtomTable = NULL;
+
+  Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
+  if (!NT_SUCCESS(Status))
+  {
+    RtlFreeUnicodeString(&WinSta->Name);
+    return Status;
+  }
+
+  WinSta->SystemMenuTemplate = (HANDLE)0;
+
+  DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name);
+
+  return STATUS_SUCCESS;
+}
+
+VOID STDCALL
+IntWinStaObjectDelete(PVOID DeletedObject)
+{
+  PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject;
+
+  DPRINT("Deleting window station (0x%X)\n", WinSta);
+
+  RtlDestroyAtomTable(WinSta->AtomTable);
+
+  RtlFreeUnicodeString(&WinSta->Name);
+}
+
+PVOID STDCALL
+IntWinStaObjectFind(PVOID Object,
+                   PWSTR Name,
+                   ULONG Attributes)
+{
+  PLIST_ENTRY Current;
+  PDESKTOP_OBJECT CurrentObject;
+  PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)Object;
+
+  DPRINT("WinStaObject (0x%X)  Name (%wS)\n", WinStaObject, Name);
+
+  if (Name[0] == 0)
+  {
+    return NULL;
+  }
+
+  Current = WinStaObject->DesktopListHead.Flink;
+  while (Current != &WinStaObject->DesktopListHead)
+  {
+    CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
+    DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
+    if (Attributes & OBJ_CASE_INSENSITIVE)
+    {
+      if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
+      {
+        DPRINT("Found desktop at (0x%X)\n", CurrentObject);
+        return CurrentObject;
+      }
+    }
+    else
+    {
+      if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
+      {
+        DPRINT("Found desktop at (0x%X)\n", CurrentObject);
+        return CurrentObject;
+      }
+    }
+    Current = Current->Flink;
+  }
+
+  DPRINT("Returning NULL\n");
+
+  return NULL;
+}
+
+NTSTATUS 
+STDCALL
+IntWinStaObjectParse(PVOID Object,
+                     PVOID *NextObject,
+                     PUNICODE_STRING FullPath,
+                     PWSTR *Path,
+                     ULONG Attributes)
+{
+  PVOID FoundObject;
+  NTSTATUS Status;
+  PWSTR End;
+
+  DPRINT("Object (0x%X)  Path (0x%X)  *Path (%wS)\n", Object, Path, *Path);
+
+  *NextObject = NULL;
+
+  if ((Path == NULL) || ((*Path) == NULL))
+  {
+    return STATUS_SUCCESS;
+  }
+
+  End = wcschr((*Path) + 1, '\\');
+  if (End != NULL)
+  {
+    DPRINT("Name contains illegal characters\n");
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  FoundObject = IntWinStaObjectFind(Object, (*Path) + 1, Attributes);
+  if (FoundObject == NULL)
+  {
+    DPRINT("Name was not found\n");
+    return STATUS_UNSUCCESSFUL;
+  }
+
+  Status = ObReferenceObjectByPointer(
+    FoundObject,
+    STANDARD_RIGHTS_REQUIRED,
+    NULL,
+    UserMode);
+
+  *NextObject = FoundObject;
+  *Path = NULL;
+
+  return Status;
+}
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 /*
@@ -152,6 +309,13 @@ IntValidateWindowStationHandle(
 {
    NTSTATUS Status;
   
+   if (WindowStation == NULL)
+   {
+//      DPRINT1("Invalid window station handle\n");
+      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      return STATUS_INVALID_HANDLE;
+   }
+
    Status = ObReferenceObjectByHandle(
       WindowStation,
       DesiredAccess,
@@ -189,7 +353,7 @@ IntInitializeDesktopGraphics(VOID)
       return FALSE;
     }
   RtlInitUnicodeString(&DriverName, L"DISPLAY");
-  ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+  ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
   if (NULL == ScreenDeviceContext)
     {
       IntDestroyPrimarySurface();
index 31b7ff8..92f193f 100644 (file)
@@ -59,6 +59,12 @@ NtGdiBitBlt(
                SetLastWin32Error(ERROR_INVALID_HANDLE);
                return FALSE;
        }
+       if (DCDest->IsIC)
+       {
+               DC_UnlockDc(hDCDest);
+               /* Yes, Windows really returns TRUE in this case */
+               return TRUE;
+       }
 
        if (UsesSource)
        {
@@ -72,6 +78,13 @@ NtGdiBitBlt(
                                SetLastWin32Error(ERROR_INVALID_HANDLE);
                                return FALSE;
                        }
+                       if (DCSrc->IsIC)
+                       {
+                               DC_UnlockDc(hDCSrc);
+                               DC_UnlockDc(hDCDest);
+                               /* Yes, Windows really returns TRUE in this case */
+                               return TRUE;
+                       }
                }
                else
                {
@@ -258,6 +271,12 @@ NtGdiTransparentBlt(
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (DCDest->IsIC)
+  {
+    DC_UnlockDc(hdcDst);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
   {
@@ -270,6 +289,16 @@ NtGdiTransparentBlt(
   {
     DCSrc = DCDest;
   }
+  if (DCSrc->IsIC)
+  {
+    DC_UnlockDc(hdcSrc);
+    if(hdcDst != hdcSrc)
+    {
+      DC_UnlockDc(hdcDst);
+    }
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   /* Offset positions */
   xDst += DCDest->w.DCOrgX;
@@ -434,6 +463,10 @@ BITMAP_Cleanup(PVOID ObjectBody)
                {
                        EngFreeUserMem(pBmp->SurfObj.pvBits);
                }
+               if (pBmp->hDIBPalette)
+               {
+                       NtGdiDeleteObject(pBmp->hDIBPalette);
+               }
        }
 
        return TRUE;
@@ -523,8 +556,10 @@ NtGdiExtFloodFill(
        COLORREF  Color,
        UINT  FillType)
 {
-       UNIMPLEMENTED;
-       return FALSE;
+   DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
+   
+   /* lie and say we succeded */
+       return TRUE;
 }
 
 BOOL STDCALL
@@ -575,6 +610,11 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
                SetLastWin32Error(ERROR_INVALID_HANDLE);
                return Result;
        }
+       if (dc->IsIC)
+       {
+               DC_UnlockDc(hDC);
+               return Result;
+       }
        XPos += dc->w.DCOrgX;
        YPos += dc->w.DCOrgY;
        if ( IN_RECT(dc->CombinedClip->rclBounds,XPos,YPos) )
@@ -1039,6 +1079,12 @@ NtGdiStretchBlt(
                SetLastWin32Error(ERROR_INVALID_HANDLE);
                return FALSE;
        }
+       if (DCDest->IsIC)
+       {
+               DC_UnlockDc(hDCDest);
+               /* Yes, Windows really returns TRUE in this case */
+               return TRUE;
+       }
 
        if (UsesSource)
        {
@@ -1052,6 +1098,13 @@ NtGdiStretchBlt(
                                SetLastWin32Error(ERROR_INVALID_HANDLE);
                                return FALSE;
                        }
+                       if (DCSrc->IsIC)
+                       {
+                               DC_UnlockDc(hDCSrc);
+                               DC_UnlockDc(hDCDest);
+                               /* Yes, Windows really returns TRUE in this case */
+                               return TRUE;
+                       }
                }
                else
                {
index a14fb5a..9dee1e9 100644 (file)
@@ -72,6 +72,10 @@ IntGdiCreateBrushXlate(PDC Dc, GDIBRUSHOBJ *BrushObj, BOOLEAN *Failed)
          if (Dc->w.bitsPerPixel != 1)
             Result = IntEngCreateSrcMonoXlate(Dc->w.hPalette, Dc->w.textColor, Dc->w.backgroundColor);
       }
+      else if (BrushObj->flAttrs & GDIBRUSH_IS_DIB)
+      {
+         Result = IntEngCreateXlate(0, 0, Dc->w.hPalette, Pattern->hDIBPalette);
+      }
 
       BITMAPOBJ_UnlockBitmap(BrushObj->hbmPattern);
       *Failed = FALSE;
@@ -97,34 +101,292 @@ IntGdiInitBrushInstance(GDIBRUSHINST *BrushInst, PGDIBRUSHOBJ BrushObj, XLATEOBJ
    BrushInst->XlateObject = XlateObj;
 }
 
-HBRUSH FASTCALL
-IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush)
+/**
+ * @name CalculateColorTableSize
+ *
+ * Internal routine to calculate the number of color table entries.
+ *
+ * @param BitmapInfoHeader
+ *        Input bitmap information header, can be any version of
+ *        BITMAPINFOHEADER or BITMAPCOREHEADER.
+ *
+ * @param ColorSpec
+ *        Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
+ *        or DIB_RGB_COLORS). On successful return this value is normalized
+ *        according to the bitmap info.
+ *
+ * @param ColorTableSize
+ *        On successful return this variable is filled with number of
+ *        entries in color table for the image with specified parameters.
+ *
+ * @return
+ *    TRUE if the input values together form a valid image, FALSE otherwise.
+ */
+
+BOOL STDCALL
+CalculateColorTableSize(
+   CONST BITMAPINFOHEADER *BitmapInfoHeader,
+   UINT *ColorSpec,
+   UINT *ColorTableSize)
 {
-   PGDIBRUSHOBJ BrushObject;
-   HBRUSH hBrush;
-   HBITMAP hPattern = 0;
-   
-   switch (LogBrush->lbStyle)
+   WORD BitCount;
+   DWORD ClrUsed;
+   DWORD Compression;
+
+   /*
+    * At first get some basic parameters from the passed BitmapInfoHeader
+    * structure. It can have one of the following formats: 
+    * - BITMAPCOREHEADER (the oldest one with totally different layout
+    *                     from the others)
+    * - BITMAPINFOHEADER (the standard and most common header)
+    * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
+    * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
+    */
+
+   if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
+   {
+      BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
+      ClrUsed = 0;
+      Compression = BI_RGB;
+   }
+   else
    {
-      case BS_HATCHED:
-         hPattern = NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes[LogBrush->lbHatch]);
-         if (hPattern == NULL)
+      BitCount = BitmapInfoHeader->biBitCount;
+      ClrUsed = BitmapInfoHeader->biClrUsed;
+      Compression = BitmapInfoHeader->biCompression;
+   }
+
+   switch (Compression)
+   {
+      case BI_BITFIELDS:
+         if (*ColorSpec == DIB_PAL_COLORS)
+            *ColorSpec = DIB_RGB_COLORS;
+
+         if (BitCount != 16 && BitCount != 32)
+            return FALSE;
+
+         /*
+          * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
+          * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
+          * For BITMAPINFOHEADER the color masks are stored in the palette.
+          */
+
+         if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
+            *ColorTableSize = 0;
+         else
+            *ColorTableSize = 3;
+         
+         return TRUE;
+
+      case BI_RGB:
+         switch (BitCount)
          {
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-            return NULL;
+            case 1:
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
+               return TRUE;
+
+            case 4:
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
+               return TRUE;
+
+            case 8:
+               *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
+               return TRUE;
+
+            default:
+               if (*ColorSpec == DIB_PAL_COLORS)
+                  *ColorSpec = DIB_RGB_COLORS;
+               if (BitCount != 16 && BitCount != 24 && BitCount != 32)
+                  return FALSE;
+               *ColorTableSize = ClrUsed;
+               return TRUE;
          }
-         break;
-     
-      case BS_PATTERN:
-         hPattern = BITMAPOBJ_CopyBitmap((HBITMAP)LogBrush->lbHatch);
-         if (hPattern == NULL)
+         
+      case BI_RLE4:
+         if (BitCount == 4)
+         {
+            *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
+            return TRUE;
+         }
+         return FALSE;
+
+      case BI_RLE8:
+         if (BitCount == 8)
          {
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-            return NULL;
+            *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
+            return TRUE;
          }
-         break;
+         return FALSE;
+
+      case BI_JPEG:
+      case BI_PNG:
+         *ColorTableSize = ClrUsed;
+         return TRUE;
+
+      default:
+         return FALSE;      
+   }
+}
+
+HBRUSH STDCALL
+IntGdiCreateDIBBrush(
+   CONST BITMAPINFO *BitmapInfo,
+   UINT ColorSpec,
+   UINT BitmapInfoSize,
+   CONST VOID *PackedDIB)
+{
+   HBRUSH hBrush;
+   PGDIBRUSHOBJ BrushObject;
+   HBITMAP hPattern;
+   ULONG_PTR DataPtr;
+   UINT PaletteEntryCount;
+   PBITMAPOBJ BitmapObject;
+   UINT PaletteType;
+
+   if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+   }
+
+   if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, &ColorSpec,
+                                &PaletteEntryCount))
+   {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+   }
+
+   DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize;
+   if (ColorSpec == DIB_RGB_COLORS)
+      DataPtr += PaletteEntryCount * sizeof(RGBQUAD);
+   else
+      DataPtr += PaletteEntryCount * sizeof(USHORT);
+
+   hPattern = NtGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
+                                BitmapInfo->bmiHeader.biHeight,
+                                BitmapInfo->bmiHeader.biPlanes,
+                                BitmapInfo->bmiHeader.biBitCount,
+                                (PVOID)DataPtr);
+   if (hPattern == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   BitmapObject = BITMAPOBJ_LockBitmap(hPattern);
+   ASSERT(BitmapObject != NULL);
+   BitmapObject->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType);
+   BITMAPOBJ_UnlockBitmap(hPattern);
+
+   hBrush = BRUSHOBJ_AllocBrush();
+   if (hBrush == NULL)
+   {
+      NtGdiDeleteObject(hPattern);
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   BrushObject = BRUSHOBJ_LockBrush(hBrush);
+   ASSERT(BrushObject != NULL);
+
+   BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP | GDIBRUSH_IS_DIB;
+   BrushObject->hbmPattern = hPattern;
+   /* FIXME: Fill in the rest of fields!!! */
+
+   GDIOBJ_SetOwnership(hPattern, NULL);
+
+   BRUSHOBJ_UnlockBrush(hBrush);
+   
+   return hBrush;
+}
+
+HBRUSH STDCALL
+IntGdiCreateHatchBrush(
+   INT Style,
+   COLORREF Color)
+{
+   HBRUSH hBrush;
+   PGDIBRUSHOBJ BrushObject;
+   HBITMAP hPattern;
+   
+   if (Style < 0 || Style >= NB_HATCH_STYLES)
+   {
+      return 0;
+   }
+
+   hPattern = NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes[Style]);
+   if (hPattern == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   hBrush = BRUSHOBJ_AllocBrush();
+   if (hBrush == NULL)
+   {
+      NtGdiDeleteObject(hPattern);
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   BrushObject = BRUSHOBJ_LockBrush(hBrush);
+   ASSERT(BrushObject != NULL);
+
+   BrushObject->flAttrs |= GDIBRUSH_IS_HATCH;
+   BrushObject->hbmPattern = hPattern;
+   BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF;
+
+   GDIOBJ_SetOwnership(hPattern, NULL);
+
+   BRUSHOBJ_UnlockBrush(hBrush);
+   
+   return hBrush;
+}
+
+HBRUSH STDCALL
+IntGdiCreatePatternBrush(
+   HBITMAP hBitmap)
+{
+   HBRUSH hBrush;
+   PGDIBRUSHOBJ BrushObject;
+   HBITMAP hPattern;
+   
+   hPattern = BITMAPOBJ_CopyBitmap(hBitmap);
+   if (hPattern == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
    }
    
+   hBrush = BRUSHOBJ_AllocBrush();
+   if (hBrush == NULL)
+   {
+      NtGdiDeleteObject(hPattern);
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   BrushObject = BRUSHOBJ_LockBrush(hBrush);
+   ASSERT(BrushObject != NULL);
+
+   BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP;
+   BrushObject->hbmPattern = hPattern;
+   /* FIXME: Fill in the rest of fields!!! */
+
+   GDIOBJ_SetOwnership(hPattern, NULL);
+
+   BRUSHOBJ_UnlockBrush(hBrush);
+   
+   return hBrush;
+}
+
+HBRUSH STDCALL
+IntGdiCreateSolidBrush(
+   COLORREF Color)
+{
+   HBRUSH hBrush;
+   PGDIBRUSHOBJ BrushObject;
+   
    hBrush = BRUSHOBJ_AllocBrush();
    if (hBrush == NULL)
    {
@@ -133,43 +395,34 @@ IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush)
    }
 
    BrushObject = BRUSHOBJ_LockBrush(hBrush);
-   if(BrushObject != NULL)
+   ASSERT(BrushObject != NULL);
+
+   BrushObject->flAttrs |= GDIBRUSH_IS_SOLID;
+   BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF;
+   /* FIXME: Fill in the rest of fields!!! */
+
+   BRUSHOBJ_UnlockBrush(hBrush);
+   
+   return hBrush;
+}
+
+HBRUSH STDCALL
+IntGdiCreateNullBrush(VOID)
+{
+   HBRUSH hBrush;
+   PGDIBRUSHOBJ BrushObject;
+   
+   hBrush = BRUSHOBJ_AllocBrush();
+   if (hBrush == NULL)
    {
-     switch (LogBrush->lbStyle)
-     {
-        case BS_NULL:
-           BrushObject->flAttrs |= GDIBRUSH_IS_NULL;
-           break;
-
-        case BS_SOLID:
-           BrushObject->flAttrs |= GDIBRUSH_IS_SOLID;
-           BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF;
-           /* FIXME: Fill in the rest of fields!!! */
-           break;
-
-        case BS_HATCHED:
-           BrushObject->flAttrs |= GDIBRUSH_IS_HATCH;
-           BrushObject->hbmPattern = hPattern;
-           BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF;
-           break;
-
-        case BS_PATTERN:
-           BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP;
-           BrushObject->hbmPattern = hPattern;
-           /* FIXME: Fill in the rest of fields!!! */
-           break;
-
-        default:
-           DPRINT1("Brush Style: %d\n", LogBrush->lbStyle);
-           UNIMPLEMENTED;
-           break;
-     }
-     
-     BRUSHOBJ_UnlockBrush(hBrush);
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
    }
 
-   if (hPattern != 0)
-      GDIOBJ_SetOwnership(hPattern, NULL);
+   BrushObject = BRUSHOBJ_LockBrush(hBrush);
+   ASSERT(BrushObject != NULL);
+   BrushObject->flAttrs |= GDIBRUSH_IS_NULL;
+   BRUSHOBJ_UnlockBrush(hBrush);
    
    return hBrush;
 }
@@ -266,6 +519,12 @@ IntGdiPolyPatBlt(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
        
    for (r = pRects, i = 0; i < cRects; i++)
    {
@@ -293,80 +552,58 @@ IntGdiPolyPatBlt(
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 HBRUSH STDCALL
-NtGdiCreateBrushIndirect(CONST LOGBRUSH *LogBrush)
+NtGdiCreateDIBBrush(
+   CONST BITMAPINFO *BitmapInfoAndData,
+   UINT ColorSpec,
+   UINT BitmapInfoSize,
+   CONST VOID *PackedDIB)
 {
-   LOGBRUSH SafeLogBrush;
+   BITMAPINFO *SafeBitmapInfoAndData;
    NTSTATUS Status;
-  
-   Status = MmCopyFromCaller(&SafeLogBrush, LogBrush, sizeof(LOGBRUSH));
+   HBRUSH hBrush;
+
+   SafeBitmapInfoAndData = EngAllocMem(0, BitmapInfoSize, 0);
+   if (SafeBitmapInfoAndData == NULL)
+   {
+      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      return NULL;
+   }
+
+   Status = MmCopyFromCaller(SafeBitmapInfoAndData, BitmapInfoAndData,
+                             BitmapInfoSize);
    if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
       return 0;
    }
-  
-   return IntGdiCreateBrushIndirect(&SafeLogBrush);
-}
 
-HBRUSH STDCALL
-NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked, UINT ColorSpec)
-{
-   UNIMPLEMENTED;
-   return 0;
-}
+   hBrush = IntGdiCreateDIBBrush(SafeBitmapInfoAndData, ColorSpec,
+                                 BitmapInfoSize, PackedDIB);
 
-HBRUSH STDCALL
-NtGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB, UINT Usage)
-{
-   UNIMPLEMENTED;
-   return 0;
+   EngFreeMem(SafeBitmapInfoAndData);
+
+   return hBrush;
 }
 
 HBRUSH STDCALL
-NtGdiCreateHatchBrush(INT Style, COLORREF Color)
+NtGdiCreateHatchBrush(
+   INT Style,
+   COLORREF Color)
 {
-   LOGBRUSH LogBrush;
-
-   if (Style < 0 || Style >= NB_HATCH_STYLES)
-   {
-      return 0;
-   }
-
-   LogBrush.lbStyle = BS_HATCHED;
-   LogBrush.lbColor = Color;
-   LogBrush.lbHatch = Style;
-
-   return IntGdiCreateBrushIndirect(&LogBrush);
+   return IntGdiCreateHatchBrush(Style, Color);
 }
 
 HBRUSH STDCALL
-NtGdiCreatePatternBrush(HBITMAP hBitmap)
+NtGdiCreatePatternBrush(
+   HBITMAP hBitmap)
 {
-   LOGBRUSH LogBrush;
-
-   LogBrush.lbStyle = BS_PATTERN;
-   LogBrush.lbColor = 0;
-   LogBrush.lbHatch = (ULONG)hBitmap;
-
-   return IntGdiCreateBrushIndirect(&LogBrush);
+   return IntGdiCreatePatternBrush(hBitmap);
 }
 
 HBRUSH STDCALL
 NtGdiCreateSolidBrush(COLORREF Color)
 {
-   LOGBRUSH LogBrush;
-
-   LogBrush.lbStyle = BS_SOLID;
-   LogBrush.lbColor = Color;
-   LogBrush.lbHatch = 0;
-
-   return IntGdiCreateBrushIndirect(&LogBrush);
-}
-
-BOOL STDCALL
-NtGdiFixBrushOrgEx(VOID)
-{
-   return FALSE;
+   return IntGdiCreateSolidBrush(Color);
 }
 
 /*
@@ -466,6 +703,12 @@ NtGdiPatBlt(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    BrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
    if (BrushObj == NULL)
index 919238a..cbeaf89 100644 (file)
@@ -287,7 +287,7 @@ UINT STDCALL NtGdiGetSystemPaletteEntries(HDC  hDC,
 
 UINT STDCALL NtGdiGetSystemPaletteUse(HDC  hDC)
 {
-  UNIMPLEMENTED;
+  DPRINT1("NtGdiGetSystemPaletteUse is unimplemented\n");
   return 0;
 }
 
index 5ef2813..dfa539c 100644 (file)
@@ -136,7 +136,7 @@ NtGdiCreateCompatableDC(HDC hDC)
   if (hDC == NULL)
     {
       RtlInitUnicodeString(&DriverName, L"DISPLAY");
-      DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
+      DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
       if (NULL == DisplayDC)
         {
           return NULL;
@@ -169,9 +169,9 @@ NtGdiCreateCompatableDC(HDC hDC)
 
   /* Copy information from original DC to new DC  */
   NewDC->hSelf = hNewDC;
+  NewDC->IsIC = FALSE;
 
   NewDC->PDev = OrigDC->PDev;
-  NewDC->DMW = OrigDC->DMW;
   memcpy(NewDC->FillPatternSurfaces,
          OrigDC->FillPatternSurfaces,
          sizeof OrigDC->FillPatternSurfaces);
@@ -454,19 +454,16 @@ SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
   return Valid;
 }
 
-BOOL FASTCALL
-IntCreatePrimarySurface()
+static BOOL FASTCALL
+IntPrepareDriver()
 {
    PGD_ENABLEDRIVER GDEnableDriver;
    DRVENABLEDATA DED;
-   SURFOBJ *SurfObj;
-   SIZEL SurfSize;
    UNICODE_STRING DriverFileNames;
    PWSTR CurrentName;
    BOOL GotDriver;
    BOOL DoDefault;
    ULONG DisplayNumber;
-   RECTL SurfaceRect;
 
    for (DisplayNumber = 0; ; DisplayNumber++)
    {
@@ -488,7 +485,6 @@ IntCreatePrimarySurface()
       if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
       {
          DPRINT1("FindDriverFileNames failed\n");
-         /* return FALSE; */
          continue;
       }
 
@@ -543,7 +539,6 @@ IntCreatePrimarySurface()
       {
          ObDereferenceObject(PrimarySurface.VideoFileObject);
          DPRINT1("No suitable DDI driver found\n");
-         /* return FALSE; */
          continue;
       }
 
@@ -608,7 +603,6 @@ IntCreatePrimarySurface()
             ObDereferenceObject(PrimarySurface.VideoFileObject);
             DPRINT1("DrvEnablePDEV with default parameters failed\n");
             DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
-            /* return FALSE; */
             continue;
          }
       }
@@ -623,7 +617,7 @@ IntCreatePrimarySurface()
          DPRINT("Adjusting GDIInfo.ulLogPixelsY\n");
          PrimarySurface.GDIInfo.ulLogPixelsY = 96;
       }
-      
+
       PrimarySurface.Pointer.Exclude.right = -1;
 
       DPRINT("calling completePDev\n");
@@ -637,43 +631,67 @@ IntCreatePrimarySurface()
 
       DRIVER_ReferenceDriver(L"DISPLAY");
 
-      DPRINT("calling EnableSurface\n");
+      PrimarySurface.PreparedDriver = TRUE;
+      PrimarySurface.DisplayNumber = DisplayNumber;
 
-      /* Enable the drawing surface */
-      PrimarySurface.Handle =
-         PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
-      if (NULL == PrimarySurface.Handle)
-      {
-/*         PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
-         PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
-         ObDereferenceObject(PrimarySurface.VideoFileObject);
-         DPRINT1("DrvEnableSurface failed\n");
-         /* return FALSE; */
-         continue;
-      }
+      return TRUE;
+   }
 
-      /* attach monitor */
-      IntAttachMonitor(&PrimarySurface, DisplayNumber);
-
-      SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
-      SurfObj->dhpdev = PrimarySurface.PDev;
-      SurfSize = SurfObj->sizlBitmap;
-      SurfSize = SurfObj->sizlBitmap;
-      SurfaceRect.left = SurfaceRect.top = 0;
-      SurfaceRect.right = SurfObj->sizlBitmap.cx;
-      SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
-      /* FIXME - why does EngEraseSurface() sometimes crash?
-        EngEraseSurface(SurfObj, &SurfaceRect, 0); */
-
-      /* Put the pointer in the center of the screen */
-      GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
-      GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
-
-      EngUnlockSurface(SurfObj);
-      IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
-      break;
+   return FALSE;
+}
+
+static BOOL FASTCALL
+IntPrepareDriverIfNeeded()
+{
+   return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
+}
+
+BOOL FASTCALL
+IntCreatePrimarySurface()
+{
+   SIZEL SurfSize;
+   RECTL SurfaceRect;
+   SURFOBJ *SurfObj;
+
+   if (! IntPrepareDriverIfNeeded())
+   {
+      return FALSE;
+   }
+
+   DPRINT("calling EnableSurface\n");
+   /* Enable the drawing surface */
+   PrimarySurface.Handle =
+      PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev);
+   if (NULL == PrimarySurface.Handle)
+   {
+/*      PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);*/
+      PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+      ObDereferenceObject(PrimarySurface.VideoFileObject);
+      DPRINT1("DrvEnableSurface failed\n");
+      return FALSE;
    }
 
+   PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, TRUE);
+
+   /* attach monitor */
+   IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+
+   SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
+   SurfObj->dhpdev = PrimarySurface.PDev;
+   SurfSize = SurfObj->sizlBitmap;
+   SurfaceRect.left = SurfaceRect.top = 0;
+   SurfaceRect.right = SurfObj->sizlBitmap.cx;
+   SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
+   /* FIXME - why does EngEraseSurface() sometimes crash?
+     EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+
+   /* Put the pointer in the center of the screen */
+   GDIDEV(SurfObj)->Pointer.Pos.x = (SurfaceRect.right - SurfaceRect.left) / 2;
+   GDIDEV(SurfObj)->Pointer.Pos.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+
+   EngUnlockSurface(SurfObj);
+   IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
+
    return TRUE;
 }
 
@@ -694,6 +712,7 @@ IntDestroyPrimarySurface()
     PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.PDev, FALSE);
     PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.PDev);
     PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.PDev);
+    PrimarySurface.PreparedDriver = FALSE;
 
     DceEmptyCache();
 
@@ -704,7 +723,8 @@ HDC FASTCALL
 IntGdiCreateDC(PUNICODE_STRING Driver,
                PUNICODE_STRING Device,
                PUNICODE_STRING Output,
-               CONST PDEVMODEW InitData)
+               CONST PDEVMODEW InitData,
+               BOOL CreateAsIC)
 {
   HDC      hNewDC;
   PDC      NewDC;
@@ -714,10 +734,18 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
   UNICODE_STRING StdDriver;
   
   RtlInitUnicodeString(&StdDriver, L"DISPLAY");
-  
+
   if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
     {
-      if (! IntGraphicsCheck(TRUE))
+      if (CreateAsIC)
+        {
+          if (! IntPrepareDriverIfNeeded())
+            {
+              DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
+              return NULL;
+            }
+        }
+      else if (! IntGraphicsCheck(TRUE))
         {
           DPRINT1("Unable to initialize graphics, returning NULL dc\n");
           return NULL;
@@ -733,7 +761,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
 
   if (Driver != NULL && Driver->Buffer != NULL)
   {
-    DPRINT("NAME: %ws\n", Driver); // FIXME: Should not crash if NULL
+    DPRINT("NAME: %wZ\n", Driver); // FIXME: Should not crash if NULL
   }
 
   /*  Allocate a DC object  */
@@ -750,7 +778,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
     return NULL;
   }
 
-  NewDC->DMW = PrimarySurface.DMW;
+  NewDC->IsIC = CreateAsIC;
   NewDC->DevInfo = &PrimarySurface.DevInfo;
   NewDC->GDIInfo = &PrimarySurface.GDIInfo;
   memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
@@ -760,46 +788,45 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
   NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
   NewDC->w.hBitmap = PrimarySurface.Handle;
 
-  NewDC->DMW.dmSize = sizeof(NewDC->DMW);
-  NewDC->DMW.dmFields = 0x000fc000;
-
-  /* FIXME: get mode selection information from somewhere  */
+  NewDC->w.bitsPerPixel = NewDC->GDIInfo->cBitsPixel * NewDC->GDIInfo->cPlanes;
+  DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
 
-  NewDC->DMW.dmLogPixels = 96;
-  SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
-  if ( !SurfObj )
+  if (! CreateAsIC)
   {
-         DC_UnlockDc ( hNewDC );
-         DC_FreeDC ( hNewDC) ;
-         return NULL;
-  }
-  NewDC->DMW.dmBitsPerPel = BitsPerFormat(SurfObj->iBitmapFormat);
-  NewDC->DMW.dmPelsWidth = SurfObj->sizlBitmap.cx;
-  NewDC->DMW.dmPelsHeight = SurfObj->sizlBitmap.cy;
-  NewDC->DMW.dmDisplayFlags = 0;
-  NewDC->DMW.dmDisplayFrequency = 0;
-
-  NewDC->w.bitsPerPixel = NewDC->DMW.dmBitsPerPel; // FIXME: set this here??
-  NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
-  NewDC->w.ROPmode = R2_COPYPEN;
+    SurfObj = EngLockSurface((HSURF)PrimarySurface.Handle);
+    if ( !SurfObj )
+    {
+      DC_UnlockDc ( hNewDC );
+      DC_FreeDC ( hNewDC) ;
+      return NULL;
+    }
+    ASSERT(NewDC->GDIInfo->cBitsPixel * NewDC->GDIInfo->cPlanes == BitsPerFormat(SurfObj->iBitmapFormat));
+    ASSERT(NewDC->GDIInfo->ulHorzRes == SurfObj->sizlBitmap.cx);
+    ASSERT(NewDC->GDIInfo->ulVertRes == SurfObj->sizlBitmap.cy);
 
-  DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel);
+    NewDC->w.hPalette = NewDC->DevInfo->hpalDefault;
+    NewDC->w.ROPmode = R2_COPYPEN;
   
-  DC_UnlockDc( hNewDC );
+    DC_UnlockDc( hNewDC );
 
-  hVisRgn = NtGdiCreateRectRgn(0, 0, SurfObj->sizlBitmap.cx,
-                              SurfObj->sizlBitmap.cy);
-  NtGdiSelectVisRgn(hNewDC, hVisRgn);
-  NtGdiDeleteObject(hVisRgn);
+    hVisRgn = NtGdiCreateRectRgn(0, 0, SurfObj->sizlBitmap.cx,
+                                 SurfObj->sizlBitmap.cy);
+    NtGdiSelectVisRgn(hNewDC, hVisRgn);
+    NtGdiDeleteObject(hVisRgn);
 
-  /*  Initialize the DC state  */
-  DC_InitDC(hNewDC);
-  NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
-  NtGdiSetTextAlign(hNewDC, TA_TOP);
-  NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
-  NtGdiSetBkMode(hNewDC, OPAQUE);
+    /*  Initialize the DC state  */
+    DC_InitDC(hNewDC);
+    NtGdiSetTextColor(hNewDC, RGB(0, 0, 0));
+    NtGdiSetTextAlign(hNewDC, TA_TOP);
+    NtGdiSetBkColor(hNewDC, RGB(255, 255, 255));
+    NtGdiSetBkMode(hNewDC, OPAQUE);
 
-  EngUnlockSurface(SurfObj);
+    EngUnlockSurface(SurfObj);
+  }
+  else
+  {
+    DC_UnlockDc( hNewDC );
+  }
   
   return hNewDC;
 }
@@ -847,7 +874,7 @@ NtGdiCreateDC(PUNICODE_STRING Driver,
     }
   }
   
-  Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData);
+  Ret = IntGdiCreateDC(&SafeDriver, &SafeDevice, NULL, &SafeInitData, FALSE);
   
   return Ret;
 }
@@ -856,10 +883,50 @@ HDC STDCALL
 NtGdiCreateIC(PUNICODE_STRING Driver,
               PUNICODE_STRING Device,
               PUNICODE_STRING Output,
-              CONST PDEVMODEW DevMode)
+              CONST PDEVMODEW InitData)
 {
-  /* FIXME: this should probably do something else...  */
-  return  NtGdiCreateDC(Driver, Device, Output, DevMode);
+  UNICODE_STRING SafeDriver, SafeDevice;
+  DEVMODEW SafeInitData;
+  HDC Ret;
+  NTSTATUS Status;
+  
+  if(InitData)
+  {
+    Status = MmCopyFromCaller(&SafeInitData, InitData, sizeof(DEVMODEW));
+    if(!NT_SUCCESS(Status))
+    {
+      SetLastNtError(Status);
+      return NULL;
+    }
+    /* FIXME - InitData can have some more bytes! */
+  }
+  
+  if(Driver)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDriver, Driver);
+    if(!NT_SUCCESS(Status))
+    {
+      SetLastNtError(Status);
+      return NULL;
+    }
+  }
+  
+  if(Device)
+  {
+    Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeUnicodeString(&SafeDriver);
+      SetLastNtError(Status);
+      return NULL;
+    }
+  }
+  
+  Ret = IntGdiCreateDC(NULL == Driver ? NULL : &SafeDriver,
+                       NULL == Device ? NULL : &SafeDevice, NULL,
+                       NULL == InitData ? NULL : &SafeInitData, TRUE);
+  
+  return Ret;
 }
 
 BOOL STDCALL
@@ -1144,6 +1211,7 @@ NtGdiGetDCState(HDC  hDC)
 
   newdc->hSelf = hnewdc;
   newdc->saveLevel = 0;
+  newdc->IsIC = dc->IsIC;
 
 #if 0
   PATH_InitGdiPath( &newdc->w.path );
@@ -1800,7 +1868,6 @@ NtGdiSelectObject(HDC  hDC, HGDIOBJ  hGDIObj)
   PGDIBRUSHOBJ brush;
   XLATEOBJ *XlateObj;
   DWORD objectType;
-  ULONG NumColors = 0;
   HRGN hVisRgn;
   BOOLEAN Failed;
 
@@ -1894,21 +1961,7 @@ NtGdiSelectObject(HDC  hDC, HGDIOBJ  hGDIObj)
       if(pb->dib)
       {
         dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
-
-        if(pb->dib->dsBmih.biBitCount <= 8)
-        {
-          if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else
-          if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else
-          if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
-          dc->w.hPalette = PALETTE_AllocPaletteIndexedRGB(NumColors, pb->ColorMap);
-        }
-        else
-        {
-          dc->w.hPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
-                                                pb->dib->dsBitfields[0],
-                                                pb->dib->dsBitfields[1],
-                                                pb->dib->dsBitfields[2]);
-        }
+        dc->w.hPalette = pb->hDIBPalette;
       }
       else
       {
@@ -2228,26 +2281,28 @@ IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
 /*! \brief Enumerate possible display settings for the given display...
  *
  * \todo Make thread safe!?
- * \todo Don't ignore lpszDeviceName
+ * \todo Don't ignore pDeviceName
  * \todo Implement non-raw mode (only return settings valid for driver and monitor)
  */
 BOOL FASTCALL
 IntEnumDisplaySettings(
-  PUNICODE_STRING lpszDeviceName,
-  DWORD iModeNum,
-  LPDEVMODEW lpDevMode,
-  DWORD dwFlags)
+  IN PUNICODE_STRING pDeviceName  OPTIONAL,
+  IN DWORD iModeNum,
+  IN OUT LPDEVMODEW pDevMode,
+  IN DWORD dwFlags)
 {
   static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
   static DWORD SizeOfCachedDevModes = 0;
-  LPDEVMODEW CachedMode = NULL;
+  PDEVMODEW CachedMode = NULL;
   DEVMODEW DevMode;
   INT Size, OldSize;
   ULONG DisplayNumber = 0; /* only default display supported */
   
-  if (lpDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
-      lpDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
-      lpDevMode->dmSize != SIZEOF_DEVMODEW_500)
+  DPRINT1("DevMode->dmSize = %d\n", pDevMode->dmSize);
+  DPRINT1("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
+  if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
+      pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
+      pDevMode->dmSize != SIZEOF_DEVMODEW_500)
   {
     SetLastWin32Error(STATUS_INVALID_PARAMETER);
     return FALSE;
@@ -2256,7 +2311,7 @@ IntEnumDisplaySettings(
   if (iModeNum == ENUM_CURRENT_SETTINGS)
   {
     CachedMode = &PrimarySurface.DMW;    
-    assert(CachedMode->dmSize > 0);
+    ASSERT(CachedMode->dmSize > 0);
   }
   else if (iModeNum == ENUM_REGISTRY_SETTINGS)
   {
@@ -2420,24 +2475,193 @@ IntEnumDisplaySettings(
     }
   }
 
-  assert(CachedMode != NULL);
+  ASSERT(CachedMode != NULL);
 
-  Size = OldSize = lpDevMode->dmSize;
+  Size = OldSize = pDevMode->dmSize;
   if (Size > CachedMode->dmSize)
     Size = CachedMode->dmSize;
-  RtlCopyMemory(lpDevMode, CachedMode, Size);
-  RtlZeroMemory((PCHAR)lpDevMode + Size, OldSize - Size);
-  lpDevMode->dmSize = OldSize;
+  RtlCopyMemory(pDevMode, CachedMode, Size);
+  RtlZeroMemory((PCHAR)pDevMode + Size, OldSize - Size);
+  pDevMode->dmSize = OldSize;
   
-  Size = OldSize = lpDevMode->dmDriverExtra;
+  Size = OldSize = pDevMode->dmDriverExtra;
   if (Size > CachedMode->dmDriverExtra)
     Size = CachedMode->dmDriverExtra;
-  RtlCopyMemory((PCHAR)lpDevMode + lpDevMode->dmSize,
+  RtlCopyMemory((PCHAR)pDevMode + pDevMode->dmSize,
                 (PCHAR)CachedMode + CachedMode->dmSize, Size);
-  RtlZeroMemory((PCHAR)lpDevMode + lpDevMode->dmSize + Size, OldSize - Size);
-  lpDevMode->dmDriverExtra = OldSize;
+  RtlZeroMemory((PCHAR)pDevMode + pDevMode->dmSize + Size, OldSize - Size);
+  pDevMode->dmDriverExtra = OldSize;
 
   return TRUE;
 }
 
+LONG
+FASTCALL
+IntChangeDisplaySettings(
+  IN PUNICODE_STRING pDeviceName  OPTIONAL,
+  IN LPDEVMODEW DevMode,
+  IN DWORD dwflags,
+  IN PVOID lParam  OPTIONAL)
+{
+  BOOLEAN Global = FALSE;
+  BOOLEAN NoReset = FALSE;
+  BOOLEAN Reset = FALSE;
+  BOOLEAN SetPrimary = FALSE;
+  LONG Ret;
+
+  if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
+  {
+    /* Check global, reset and noreset flags */
+    if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
+      Global = TRUE;
+    if ((dwflags & CDS_NORESET) == CDS_NORESET)
+      NoReset = TRUE;
+    dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
+  }
+  if ((dwflags & CDS_RESET) == CDS_RESET)
+    Reset = TRUE;
+  if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
+    SetPrimary = TRUE;
+  dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
+
+  if (Reset && NoReset)
+    return DISP_CHANGE_BADFLAGS;
+
+  switch (dwflags)
+  {
+  case 0: /* Dynamically change graphics mode */
+    Ret = DISP_CHANGE_FAILED;
+    break;
+    
+  case CDS_FULLSCREEN: /* Given mode is temporary */
+    Ret = DISP_CHANGE_FAILED;
+    break;
+    
+  case CDS_UPDATEREGISTRY:
+    {
+               UNICODE_STRING ObjectName;
+               UNICODE_STRING KernelModeName;
+               WCHAR KernelModeNameBuffer[256];
+               UNICODE_STRING RegistryKey;
+               WCHAR RegistryKeyBuffer[512];
+               PDEVICE_OBJECT DeviceObject;
+               NTSTATUS Status;
+               ULONG LastSlash;
+               OBJECT_ATTRIBUTES ObjectAttributes;
+               HANDLE DevInstRegKey;
+               ULONG NewValue;
+               
+               /* Get device name (pDeviceName is "\.\xxx") */
+               for (LastSlash = pDeviceName->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+               {
+                       if (pDeviceName->Buffer[LastSlash - 1] == L'\\')
+                               break;
+               }
+               if (LastSlash == 0) return DISP_CHANGE_FAILED;
+               ObjectName = *pDeviceName;
+               ObjectName.Length -= LastSlash * sizeof(WCHAR);
+               ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+               ObjectName.Buffer += LastSlash;
+               
+               KernelModeName.Length = 0;
+               KernelModeName.MaximumLength = sizeof(KernelModeNameBuffer);
+               KernelModeName.Buffer = KernelModeNameBuffer;
+               
+               /* Open \??\xxx (ex: "\??\DISPLAY1") */
+               Status = RtlAppendUnicodeToString(&KernelModeName, L"\\??\\");
+               if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+               Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
+               if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+               Status = ObReferenceObjectByName(
+                       &KernelModeName,
+                       OBJ_CASE_INSENSITIVE,
+                       NULL,
+                       0,
+                       IoDeviceObjectType,
+                       KernelMode,
+                       NULL,
+                       (PVOID*)&DeviceObject);
+               if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+               /* Get associated driver name (ex: "VBE") */
+               for (LastSlash = DeviceObject->DriverObject->DriverName.Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
+               {
+                       if (DeviceObject->DriverObject->DriverName.Buffer[LastSlash - 1] == L'\\')
+                               break;
+               }
+               if (LastSlash == 0) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+               ObjectName = DeviceObject->DriverObject->DriverName;
+               ObjectName.Length -= LastSlash * sizeof(WCHAR);
+               ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
+               ObjectName.Buffer += LastSlash;
+               
+               RegistryKey.Length = 0;
+               RegistryKey.MaximumLength = sizeof(RegistryKeyBuffer);
+               RegistryKey.Buffer = RegistryKeyBuffer;
+               
+               /* Open registry key */
+               Status = RtlAppendUnicodeToString(&RegistryKey,
+                       L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\");
+               if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+               Status = RtlAppendUnicodeStringToString(&RegistryKey, &ObjectName);
+               if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+               Status = RtlAppendUnicodeToString(&RegistryKey,
+                       L"\\Device0");
+               if (!NT_SUCCESS(Status)) { ObDereferenceObject(DeviceObject); return DISP_CHANGE_FAILED; }
+               
+               InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
+                       OBJ_CASE_INSENSITIVE, NULL, NULL);
+               Status = ZwOpenKey(&DevInstRegKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes);
+               ObDereferenceObject(DeviceObject);
+               if (!NT_SUCCESS(Status)) return DISP_CHANGE_FAILED;
+               
+               /* Update needed fields */
+               if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
+               {
+                       RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
+                       NewValue = DevMode->dmBitsPerPel;
+                       Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+               }
+               
+               if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
+               {
+                       RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
+                       NewValue = DevMode->dmPelsWidth;
+                       Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+               }
+               
+               if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
+               {
+                       RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
+                       NewValue = DevMode->dmPelsHeight;
+                       Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
+               }
+               
+               ZwClose(DevInstRegKey);
+               if (NT_SUCCESS(Status))
+                       Ret = DISP_CHANGE_RESTART;
+               else
+                       Ret = DISP_CHANGE_FAILED;
+               break;
+    }
+     
+  case CDS_TEST: /* Test if the mode could be set */
+    Ret = DISP_CHANGE_FAILED;
+    break;
+    
+#ifdef CDS_VIDEOPARAMETERS
+  case CDS_VIDEOPARAMETERS:
+    if (lParam == NULL)
+      return DISP_CHANGE_BADPARAM;
+    Ret = DISP_CHANGE_FAILED;
+    break;
+#endif
+    
+  default:
+    Ret = DISP_CHANGE_BADFLAGS;
+    break;
+  }
+  
+  return Ret;
+}
+
 /* EOF */
index 831b435..f203cb2 100644 (file)
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <w32k.h>
+#include <pseh.h>
 
 UINT STDCALL
 NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors)
 {
    PDC dc;
    PBITMAPOBJ BitmapObj;
+   PPALGDI PalGDI;
+   UINT Index;
 
    if (!(dc = DC_LockDc(hDC))) return 0;
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
    if (BitmapObj == NULL)
@@ -50,12 +58,24 @@ NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Col
       if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
          Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
 
-      MmCopyFromCaller(BitmapObj->ColorMap + StartIndex, Colors, Entries * sizeof(RGBQUAD));
-
-      /* Rebuild the palette. */
-      NtGdiDeleteObject(dc->w.hPalette);
-      dc->w.hPalette = PALETTE_AllocPaletteIndexedRGB(1 << BitmapObj->dib->dsBmih.biBitCount,
-                                                      BitmapObj->ColorMap);
+      PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
+      _SEH_TRY
+      {
+         for (Index = StartIndex;
+              Index < StartIndex + Entries && Index < PalGDI->NumColors;
+              Index++)
+         {
+            PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
+            PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
+            PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
+         }
+      }
+      _SEH_HANDLE
+      {
+         Entries = 0;
+      }
+      _SEH_END
+      PALETTE_UnlockPalette(BitmapObj->hDIBPalette);
    }
    else
       Entries = 0;
@@ -71,8 +91,15 @@ NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
 {
    PDC dc;
    PBITMAPOBJ BitmapObj;
+   PPALGDI PalGDI;
+   UINT Index;
 
    if (!(dc = DC_LockDc(hDC))) return 0;
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
    if (BitmapObj == NULL)
@@ -96,7 +123,24 @@ NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
       if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
          Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
 
-      MmCopyToCaller(Colors, BitmapObj->ColorMap + StartIndex, Entries * sizeof(RGBQUAD));
+      PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
+      _SEH_TRY
+      {
+         for (Index = StartIndex;
+              Index < StartIndex + Entries && Index < PalGDI->NumColors;
+              Index++)
+         {
+            Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
+            Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+            Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+         }
+      }
+      _SEH_HANDLE
+      {
+         Entries = 0;
+      }
+      _SEH_END
+      PALETTE_UnlockPalette(BitmapObj->hDIBPalette);
    }
    else
       Entries = 0;
@@ -264,6 +308,11 @@ NtGdiSetDIBits(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return 0;
     }
+  if (Dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      return 0;
+    }
 
   Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
 
@@ -325,6 +374,11 @@ NtGdiGetDIBits(HDC hDC,
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return 0;
    }
+   if (Dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
    hSourcePalette = Dc->w.hPalette;
    /* FIXME: This is incorrect. hDestPalette should be something other. */
    hDestPalette = Dc->DevInfo->hpalDefault;
@@ -599,7 +653,7 @@ LONG STDCALL NtGdiGetBitmapBits(HBITMAP  hBitmap,
   return  ret;
 }
 
-static HBITMAP FASTCALL
+HBITMAP FASTCALL
 IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header,
                   DWORD init, LPCVOID bits, const BITMAPINFO *data,
                   UINT coloruse)
@@ -863,8 +917,13 @@ DIB_CreateDIBSection(
     if(bi->biBitCount == 4) { Entries = 16; } else
     if(bi->biBitCount == 8) { Entries = 256; }
 
-    bmp->ColorMap = ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD)*Entries, TAG_COLORMAP);
-    RtlCopyMemory(bmp->ColorMap, bmi->bmiColors, sizeof(RGBQUAD)*Entries);
+    if (Entries)
+      bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(Entries, bmi->bmiColors);
+    else
+      bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
+                                              dib->dsBitfields[0],
+                                              dib->dsBitfields[1],
+                                              dib->dsBitfields[2]);
   }
 
   // Clean up in case of errors
@@ -1058,7 +1117,7 @@ DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
 }
 
 HPALETTE FASTCALL
-BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType)
+BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
 {
   BYTE bits;
   ULONG ColorCount;
index 277e855..ae84813 100644 (file)
@@ -237,6 +237,12 @@ NtGdiEllipse(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    FillBrush = BRUSHOBJ_LockBrush(dc->w.hBrush);
    if (NULL == FillBrush)
@@ -664,6 +670,12 @@ NtGdiPie(HDC  hDC,
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
     }
+  if (dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+    }
 
   FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
   if (NULL == FillBrushObj)
@@ -844,6 +856,12 @@ NtGdiPolygon(HDC          hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
   else
   {
+    if (dc->IsIC)
+    {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+    }
     Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE);
     if(!Safept)
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
@@ -883,6 +901,12 @@ NtGdiPolyPolygon(HDC           hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -1061,6 +1085,12 @@ NtGdiRectangle(HDC  hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
   DC_UnlockDc ( hDC );
@@ -1358,6 +1388,12 @@ NtGdiRoundRect(
     DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
     SetLastWin32Error(ERROR_INVALID_HANDLE);
   }
+  else if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    ret = TRUE;
+  }
   else
   {
     ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
@@ -1490,6 +1526,12 @@ NtGdiGradientFill(
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hdc);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   if(!pVertex || !uVertex || !pMesh || !uMesh)
   {
     DC_UnlockDc(hdc);
index 70190b9..bfb7816 100644 (file)
@@ -1216,15 +1216,18 @@ LockHandle:
 
           /* dereference the process' object counter */
           /* FIXME */
-          Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess);
-          if(NT_SUCCESS(Status))
+          if((ULONG_PTR)PrevProcId & ~0x1)
           {
-            W32Process = OldProcess->Win32Process;
-            if(W32Process != NULL)
+            Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess);
+            if(NT_SUCCESS(Status))
             {
-              InterlockedDecrement(&W32Process->GDIObjects);
+              W32Process = OldProcess->Win32Process;
+              if(W32Process != NULL)
+              {
+                InterlockedDecrement(&W32Process->GDIObjects);
+              }
+              ObDereferenceObject(OldProcess);
             }
-            ObDereferenceObject(OldProcess);
           }
 
           if(NewOwner != NULL)
index 866e04f..64ba46b 100644 (file)
@@ -368,6 +368,12 @@ NtGdiArc(HDC  hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   Ret = IntGdiArc(dc,
                   LeftRect,
@@ -404,6 +410,12 @@ NtGdiArcTo(HDC  hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
 
   // Line from current position to starting point of arc
   if ( !IntGdiLineTo(dc, XRadial1, YRadial1) )
@@ -466,6 +478,12 @@ NtGdiLineTo(HDC  hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   Ret = IntGdiLineTo(dc, XEnd, YEnd);
   
@@ -491,6 +509,12 @@ NtGdiMoveToEx(HDC      hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Point)
   {
@@ -526,6 +550,12 @@ NtGdiPolyBezier(HDC           hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -577,6 +607,12 @@ NtGdiPolyBezierTo(HDC  hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -639,6 +675,12 @@ NtGdiPolyline(HDC            hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count >= 2)
   {
@@ -690,6 +732,12 @@ NtGdiPolylineTo(HDC            hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
@@ -743,6 +791,12 @@ NtGdiPolyPolyline(HDC            hDC,
     SetLastWin32Error(ERROR_INVALID_HANDLE);
     return FALSE;
   }
+  if (dc->IsIC)
+  {
+    DC_UnlockDc(hDC);
+    /* Yes, Windows really returns TRUE in this case */
+    return TRUE;
+  }
   
   if(Count > 0)
   {
index d3c4d2a..f13451f 100644 (file)
@@ -63,7 +63,7 @@ IntGdiCreatePenIndirect(PLOGPEN LogPen)
          break;
 
       default:
-         UNIMPLEMENTED;
+         DPRINT1("FIXME: IntGdiCreatePenIndirect is UNIMPLEMENTED\n");
    }
 
    PENOBJ_UnlockPen(hPen);
index 29dd8be..784a859 100644 (file)
@@ -158,6 +158,11 @@ NtGdiExtEscape(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return -1;
    }
+   if ( pDC->IsIC )
+   {
+      DC_UnlockDc(hDC);
+      return 0;
+   }
 
    if ( InSize && UnsafeInData )
    {
index c36e414..59a8a3e 100644 (file)
@@ -68,28 +68,6 @@ static HBRUSH SysColorBrushes[NUM_SYSCOLORS];
 
 /*  GDI stock objects */
 
-static LOGBRUSH WhiteBrush =
-{ BS_SOLID, RGB(255,255,255), 0 };
-
-static LOGBRUSH LtGrayBrush =
-/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
-{ BS_SOLID, RGB(192,192,192), 0 };
-
-static LOGBRUSH GrayBrush =
-/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
-{ BS_SOLID, RGB(128,128,128), 0 };
-
-static LOGBRUSH DkGrayBrush =
-/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
-/* NB_HATCH_STYLES is an index into HatchBrushes */
-{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
-
-static LOGBRUSH BlackBrush =
-{ BS_SOLID, RGB(0,0,0), 0 };
-
-static LOGBRUSH NullBrush =
-{ BS_NULL, 0, 0 };
-
 static LOGPEN WhitePen =
 { PS_SOLID, { 0, 0 }, RGB(255,255,255) };
 
@@ -144,12 +122,12 @@ CreateStockObjects(void)
 
   /* Create GDI Stock Objects from the logical structures we've defined */
 
-  StockObjects[WHITE_BRUSH] =  IntGdiCreateBrushIndirect(&WhiteBrush);
-  StockObjects[LTGRAY_BRUSH] = IntGdiCreateBrushIndirect(&LtGrayBrush);
-  StockObjects[GRAY_BRUSH] =   IntGdiCreateBrushIndirect(&GrayBrush);
-  StockObjects[DKGRAY_BRUSH] = IntGdiCreateBrushIndirect(&DkGrayBrush);
-  StockObjects[BLACK_BRUSH] =  IntGdiCreateBrushIndirect(&BlackBrush);
-  StockObjects[NULL_BRUSH] =   IntGdiCreateBrushIndirect(&NullBrush);
+  StockObjects[WHITE_BRUSH] =  IntGdiCreateSolidBrush(RGB(255,255,255));
+  StockObjects[LTGRAY_BRUSH] = IntGdiCreateSolidBrush(RGB(192,192,192));
+  StockObjects[GRAY_BRUSH] =   IntGdiCreateSolidBrush(RGB(128,128,128));
+  StockObjects[DKGRAY_BRUSH] = IntGdiCreateSolidBrush(RGB(64,64,64));
+  StockObjects[BLACK_BRUSH] =  IntGdiCreateSolidBrush(RGB(0,0,0));
+  StockObjects[NULL_BRUSH] =   IntGdiCreateNullBrush();
 
   StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen);
   StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen);
@@ -279,18 +257,14 @@ VOID FASTCALL
 CreateSysColorObjects(VOID)
 {
   UINT i;
-  LOGBRUSH Brush;
   LOGPEN Pen;
   
   /* Create the syscolor brushes */
-  Brush.lbStyle = BS_SOLID;
-  Brush.lbHatch = 0;
   for(i = 0; i < NUM_SYSCOLORS; i++)
   {
     if(SysColorBrushes[i] == NULL)
     {
-      Brush.lbColor = SysColors[i];
-      SysColorBrushes[i] = IntGdiCreateBrushIndirect(&Brush);
+      SysColorBrushes[i] = IntGdiCreateSolidBrush(SysColors[i]);
       if(SysColorBrushes[i] != NULL)
       {
         GDIOBJ_ConvertToStockObj((HGDIOBJ*)&SysColorBrushes[i]);
index 02f7c13..7d10025 100644 (file)
@@ -427,18 +427,14 @@ IntGetFontRenderMode(LOGFONTW *logfont)
 {
   switch(logfont->lfQuality)
   {
-    //case ANTIALIASED_QUALITY:
-    case DEFAULT_QUALITY:
-      return FT_RENDER_MODE_NORMAL;
+    case NONANTIALIASED_QUALITY:
+      return FT_RENDER_MODE_MONO;
     case DRAFT_QUALITY:
       return FT_RENDER_MODE_LIGHT;
-    //case NONANTIALIASED_QUALITY:
-    case PROOF_QUALITY:
-      return FT_RENDER_MODE_MONO;
-    //case CLEARTYPE_QUALITY:
-    //  return FT_RENDER_MODE_LCD;
+/*    case CLEARTYPE_QUALITY:
+        return FT_RENDER_MODE_LCD; */
   }
-  return FT_RENDER_MODE_MONO;
+  return FT_RENDER_MODE_NORMAL;
 }
 
 int
@@ -1538,6 +1534,12 @@ NtGdiExtTextOut(
       SetLastWin32Error(ERROR_INVALID_HANDLE);
       return FALSE;
    }
+   if (dc->IsIC)
+   {
+      DC_UnlockDc(hDC);
+      /* Yes, Windows really returns TRUE in this case */
+      return TRUE;
+   }
 
    if (NULL != UnsafeDx && Count > 0)
    {
@@ -2969,6 +2971,12 @@ TextIntRealizeFont(HFONT FontHandle)
       return STATUS_INVALID_HANDLE;
     }
 
+  if (TextObj->Initialized)
+    {
+      TEXTOBJ_UnlockText(FontHandle);
+      return STATUS_SUCCESS;
+    }
+
   if (! RtlCreateUnicodeString(&FaceName, TextObj->logfont.lfFaceName))
     {
       TEXTOBJ_UnlockText(FontHandle);
@@ -3001,6 +3009,7 @@ TextIntRealizeFont(HFONT FontHandle)
     }
   else
     {
+      TextObj->Initialized = TRUE;
       Status = STATUS_SUCCESS;
     }
 
diff --git a/reactos/tools/hack-coff.c b/reactos/tools/hack-coff.c
new file mode 100644 (file)
index 0000000..3617a94
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC     0x010b
+
+#define get_16be(x)    ((((unsigned char *)(x))[0] << 8) \
+                        + ((unsigned char *)(x))[1])
+#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
+                        ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x)    ((((unsigned char *)(x))[0] << 24) \
+                        + (((unsigned char *)(x))[1] << 16) \
+                        + (((unsigned char *)(x))[2] << 8) \
+                        + ((unsigned char *)(x))[3])
+
+int main(int ac, char **av)
+{
+    int fd;
+    int i, nsect;
+    int aoutsz;
+    struct external_filehdr fhdr;
+    AOUTHDR aout;
+    struct external_scnhdr shdr;
+
+    if (ac != 2) {
+       fprintf(stderr, "Usage: hack-coff coff-file\n");
+       exit(1);
+    }
+    if ((fd = open(av[1], 2)) == -1) {
+       perror(av[2]);
+       exit(1);
+    }
+    if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+       goto readerr;
+    i = get_16be(fhdr.f_magic);
+    if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+       fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+       exit(1);
+    }
+    aoutsz = get_16be(fhdr.f_opthdr);
+    if (read(fd, &aout, aoutsz) != aoutsz)
+       goto readerr;
+    nsect = get_16be(fhdr.f_nscns);
+    for (i = 0; i < nsect; ++i) {
+       if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+           goto readerr;
+       if (strcmp(shdr.s_name, ".text") == 0) {
+           put_16be(aout.o_snentry, i+1);
+           put_16be(aout.o_sntext, i+1);
+       } else if (strcmp(shdr.s_name, ".data") == 0) {
+           put_16be(aout.o_sndata, i+1);
+       } else if (strcmp(shdr.s_name, ".bss") == 0) {
+           put_16be(aout.o_snbss, i+1);
+       }
+    }
+    put_16be(aout.magic, AOUT_MAGIC);
+    if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+       || write(fd, &aout, aoutsz) != aoutsz) {
+       fprintf(stderr, "%s: write error\n", av[1]);
+       exit(1);
+    }
+    close(fd);
+    exit(0);
+
+readerr:
+    fprintf(stderr, "%s: read error or file too short\n", av[1]);
+    exit(1);
+}
diff --git a/reactos/tools/make_ctests.c b/reactos/tools/make_ctests.c
new file mode 100644 (file)
index 0000000..c57d8af
--- /dev/null
@@ -0,0 +1,132 @@
+/* make_ctests.c
+
+ * This program is a port of wine project's make_ctests script
+
+# Script to generate a C file containing a list of tests
+#
+# Copyright 2002 Alexandre Julliard
+# Copyright 2002 Dimitrie O. Paun
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+# ***** Keep in sync with tools/winapi/msvcmaker:_generate_testlist_c *****
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+const char* header =
+       "/* Automatically generated file; DO NOT EDIT!! */\n"
+       "\n"
+       "/* stdarg.h is needed for Winelib */\n"
+       "#include <stdarg.h>\n"
+       "#include <stdio.h>\n"
+       "#include <stdlib.h>\n"
+       "#include \"windef.h\"\n"
+       "#include \"winbase.h\"\n"
+       "\n";
+
+const char* middle =
+       "\n"
+       "struct test\n"
+       "{\n"
+       "    const char *name;\n"
+       "    void (*func)(void);\n"
+       "};\n"
+       "\n"
+       "static const struct test winetest_testlist[] =\n"
+       "{\n";
+
+const char* end =
+       "    { 0, 0 }\n"
+       "};\n"
+       "\n"
+       "#define WINETEST_WANT_MAIN\n"
+       "#include \"wine/test.h\"\n"
+       "\n";
+
+char*
+basename ( const char* filename )
+{
+       const char *p, *p2;
+       char *out;
+       size_t out_len;
+
+       if ( filename == NULL )
+       {
+               fprintf ( stderr, "basename() called with null filename\n" );
+               return NULL;
+       }
+       p = strrchr ( filename, '/' );
+       if ( !p )
+               p = filename;
+       else
+               ++p;
+
+       /* look for backslashes, too... */
+       p2 = strrchr ( filename, '\\' );
+       if ( p2 > p )
+               p = p2 + 1;
+
+       /* find extension... */
+       p2 = strrchr ( filename, '.' );
+       if ( !p2 )
+               p2 = p + strlen(p);
+
+       /* malloc a copy */
+       out_len = p2-p;
+       out = malloc ( out_len+1 );
+       if ( out == NULL )
+       {
+               fprintf ( stderr, "malloc() failed\n" );
+               return NULL;
+       }
+       memmove ( out, p, out_len );
+       out[out_len] = '\0';
+       return out;
+}
+
+int
+main ( int argc, const char** argv )
+{
+       size_t i;
+
+       printf ( "%s", header );
+
+       for ( i = 1; i < argc; i++ )
+       {
+               char* test = basename(argv[i]);
+               if ( test == NULL )
+                       return 255;
+               printf ( "extern void func_%s(void);\n", test );
+               free ( test );
+       }
+
+       printf ( "%s", middle );
+
+       for ( i = 1; i < argc; i++ )
+       {
+               char* test = basename(argv[i]);
+               if ( test == NULL )
+                       return 255;
+               printf ( "    { \"%s\", func_%s },\n", test, test );
+               free ( test );
+       }
+
+       printf ( "%s", end );
+
+       return 0;
+}
index f52329e..7b76c79 100644 (file)
@@ -180,7 +180,6 @@ NtSetEaFile 4
 NtSetEvent 2
 NtSetHighEventPair 1
 NtSetHighWaitLowEventPair 1
-NtSetHighWaitLowThread 0
 NtSetInformationFile 5
 NtSetInformationKey 4
 NtSetInformationJobObject 4
@@ -192,7 +191,6 @@ NtSetIntervalProfile 2
 NtSetLdtEntries 6
 NtSetLowEventPair 1
 NtSetLowWaitHighEventPair 1
-NtSetLowWaitHighThread 0
 NtSetQuotaInformationFile 4
 NtSetSecurityObject 3
 NtSetSystemEnvironmentValue 2
index f821cb7..85212ce 100644 (file)
@@ -22,14 +22,12 @@ NtGdiCopyEnhMetaFile                        2
 NtGdiCopyMetaFile                      2
 NtGdiCreateBitmap                      5
 NtGdiCreateBitmapIndirect              1
-NtGdiCreateBrushIndirect                       1
 NtGdiCreateColorSpace                  1
 NtGdiCreateCompatibleBitmap            3
 NtGdiCreateCompatableDC                        1
 NtGdiCreateDC                          4
 NtGdiCreateDIBitmap                    6
-NtGdiCreateDIBPatternBrush             2
-NtGdiCreateDIBPatternBrushPt           2
+NtGdiCreateDIBBrush                    4
 NtGdiCreateDIBSection                  6
 NtGdiCreateDiscardableBitmap           3
 NtGdiCreateEllipticRgn                 4
@@ -81,7 +79,6 @@ NtGdiExtSelectClipRgn                 3
 NtGdiExtTextOut                                8
 NtGdiFillPath                          1
 NtGdiFillRgn                           3
-NtGdiFixBrushOrgEx                     0
 NtGdiFlattenPath                               1
 NtGdiFloodFill                         4
 NtGdiFrameRgn                          5
diff --git a/reactos/tools/ppc-le2be.c b/reactos/tools/ppc-le2be.c
new file mode 100644 (file)
index 0000000..3db03a4
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+int main( int argc, char **argv ) {
+    char buf[8];
+    int rlen, i;
+    FILE *fin = NULL, *fout = NULL;
+
+    if( argc < 3 ) return 1;
+
+    fin = fopen( argv[1], "rb" );
+
+    if( fin ) 
+        fout = fopen( argv[2], "wb" );
+    if( !fout ) return 1;
+
+    do { 
+        rlen = fread( buf, 1, 8, fin );
+        for( i = 7; rlen > 0 && i >= 0; i-- ) fputc( buf[i], fout );
+    }
+    while( rlen == 8 );
+
+    fclose( fout );
+
+    return 0;
+}
diff --git a/reactos/tools/raddr2line.c b/reactos/tools/raddr2line.c
new file mode 100644 (file)
index 0000000..fa0bdec
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Usage: raddr2line input-file address/offset
+ *
+ * This is a tool and is compiled using the host compiler,
+ * i.e. on Linux gcc and not mingw-gcc (cross-compiler).
+ * Therefore we can't include SDK headers and we have to
+ * duplicate some definitions here.
+ * Also note that the internal functions are "old C-style",
+ * returning an int, where a return of 0 means success and
+ * non-zero is failure.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "rsym.h"
+
+size_t fixup_offset ( size_t ImageBase, size_t offset )
+{
+       if ( offset >= ImageBase )
+               offset -= ImageBase;
+       return offset;
+}
+
+long
+my_atoi ( const char* a )
+{
+       int i = 0;
+       const char* fmt = "%x";
+
+       if ( *a == '0' )
+       {
+               switch ( *++a )
+               {
+               case 'x':
+                       fmt = "%x";
+                       ++a;
+                       break;
+               case 'd':
+                       fmt = "%d";
+                       ++a;
+                       break;
+               default:
+                       fmt = "%o";
+                       break;
+               }
+       }
+       sscanf ( a, fmt, &i );
+       return i;
+}
+
+PIMAGE_SECTION_HEADER
+find_rossym_section ( PIMAGE_FILE_HEADER PEFileHeader,
+       PIMAGE_SECTION_HEADER PESectionHeaders )
+{
+       size_t i;
+       for ( i = 0; i < PEFileHeader->NumberOfSections; i++ )
+       {
+               if ( 0 == strcmp ( PESectionHeaders[i].Name, ".rossym" ) )
+                       return &PESectionHeaders[i];
+       }
+       return NULL;
+}
+
+int
+find_and_print_offset (
+       void* data,
+       size_t offset )
+{
+       PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
+       PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char*)data + RosSymHeader->SymbolsOffset);
+       char* Strings = (char*)data + RosSymHeader->StringsOffset;
+       size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
+       size_t i;
+
+       //if ( RosSymHeader->SymbolsOffset )
+
+       for ( i = 0; i < symbols; i++ )
+       {
+               if ( Entries[i].Address > offset )
+               {
+                       if ( !i-- )
+                               return 1;
+                       else
+                       {
+                               PROSSYM_ENTRY e = &Entries[i];
+                               printf ( "%s:%lu (%s)",
+                                       &Strings[e->FileOffset],
+                                       e->SourceLine,
+                                       &Strings[e->FunctionOffset] );
+                               return 0;
+                       }
+               }
+       }
+       return 1;
+}
+
+int
+process_data ( const void* FileData, size_t FileSize, size_t offset )
+{
+       PIMAGE_DOS_HEADER PEDosHeader;
+       PIMAGE_FILE_HEADER PEFileHeader;
+       PIMAGE_OPTIONAL_HEADER PEOptHeader;
+       PIMAGE_SECTION_HEADER PESectionHeaders;
+       PIMAGE_SECTION_HEADER PERosSymSectionHeader;
+       size_t ImageBase;
+       int res;
+
+       /* Check if MZ header exists  */
+       PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
+       if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
+       {
+               perror("Input file is not a PE image.\n");
+               return 1;
+       }
+
+       /* Locate PE file header  */
+       /* sizeof(ULONG) = sizeof(MAGIC) */
+       PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
+
+       /* Locate optional header */
+       PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
+       ImageBase = PEOptHeader->ImageBase;
+
+       /* Locate PE section headers  */
+       PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *) PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
+
+       /* make sure offset is what we want */
+       offset = fixup_offset ( ImageBase, offset );
+
+       /* find rossym section */
+       PERosSymSectionHeader = find_rossym_section (
+               PEFileHeader, PESectionHeaders );
+       if ( !PERosSymSectionHeader )
+       {
+               fprintf ( stderr, "Couldn't find rossym section in executable\n" );
+               return 1;
+       }
+       res = find_and_print_offset ( (char*)FileData + PERosSymSectionHeader->PointerToRawData,
+               offset );
+       if ( res )
+               printf ( "??:0\n" );
+       return res;
+}
+
+int
+process_file ( const char* file_name, size_t offset )
+{
+       void* FileData;
+       size_t FileSize;
+       int res = 1;
+
+       FileData = load_file ( file_name, &FileSize );
+       if ( !FileData )
+       {
+               fprintf ( stderr, "An error occured loading '%s'\n", file_name );
+       }
+       else
+       {
+               res = process_data ( FileData, FileSize, offset );
+               free ( FileData );
+       }
+
+       return res;
+}
+
+int main ( int argc, const char** argv )
+{
+       char* path;
+       size_t offset;
+       int res;
+
+       if ( argc != 3 )
+       {
+               fprintf(stderr, "Usage: raddr2line <exefile> <offset>\n");
+               exit(1);
+       }
+
+       path = convert_path ( argv[1] );
+       offset = my_atoi ( argv[2] );
+
+       res = process_file ( path, offset );
+
+       free ( path );
+
+       return res;
+}
index 320e5e1..4e34985 100644 (file)
@@ -418,6 +418,7 @@ MingwBackend::GenerateGlobalVariables () const
                "=",\r
                ProjectNode.non_if_data );\r
        fprintf ( fMakefile, "PROJECT_RCFLAGS = $(PROJECT_CFLAGS)\n" );\r
+       fprintf ( fMakefile, "PROJECT_WIDLFLAGS = $(PROJECT_CFLAGS)\n" );\r
        fprintf ( fMakefile, "PROJECT_LFLAGS = %s\n",\r
                  GenerateProjectLFLAGS ().c_str () );\r
        fprintf ( fMakefile, "\n" );\r
@@ -426,12 +427,14 @@ MingwBackend::GenerateGlobalVariables () const
 bool\r
 MingwBackend::IncludeInAllTarget ( const Module& module ) const\r
 {\r
-       if ( module.type == ObjectLibrary )\r
+       if ( MingwModuleHandler::ReferenceObjects ( module ) )\r
                return false;\r
        if ( module.type == BootSector )\r
                return false;\r
        if ( module.type == Iso )\r
                return false;\r
+       if ( module.type == Test )\r
+               return false;\r
        return true;\r
 }\r
 \r
index 09e71f7..03e2514 100644 (file)
@@ -198,6 +198,12 @@ MingwModuleHandler::InstanciateHandler (
                case Test:\r
                        handler = new MingwTestModuleHandler ( module );\r
                        break;\r
+               case RpcServer:\r
+                       handler = new MingwRpcServerModuleHandler ( module );\r
+                       break;\r
+               case RpcClient:\r
+                       handler = new MingwRpcClientModuleHandler ( module );\r
+                       break;\r
                default:\r
                        throw UnknownModuleTypeException (\r
                                module.node.location,\r
@@ -233,6 +239,17 @@ MingwModuleHandler::GetActualSourceFilename (
                return PassThruCacheDirectory ( NormalizeFilename ( basename + ".stubs.c" ),\r
                                                backend->intermediateDirectory );\r
        }\r
+       else if ( extension == ".idl" || extension == ".IDL" )\r
+       {\r
+               string basename = GetBasename ( filename );\r
+               string newname;\r
+               if ( module.type == RpcServer )\r
+                       newname = basename + "_s.c";\r
+               else\r
+                       newname = basename + "_c.c";\r
+               return PassThruCacheDirectory ( NormalizeFilename ( newname ),\r
+                                               backend->intermediateDirectory );\r
+       }\r
        else\r
                return filename;\r
 }\r
@@ -255,26 +272,53 @@ MingwModuleHandler::IsGeneratedFile ( const File& file ) const
        return ( extension == ".spec" || extension == ".SPEC" );\r
 }\r
 \r
+/*static*/ bool\r
+MingwModuleHandler::ReferenceObjects (\r
+       const Module& module )\r
+{\r
+       if ( module.type == ObjectLibrary )\r
+               return true;\r
+       if ( module.type == RpcServer )\r
+               return true;\r
+       if ( module.type == RpcClient )\r
+               return true;\r
+       return false;\r
+}\r
+\r
 string\r
 MingwModuleHandler::GetImportLibraryDependency (\r
        const Module& importedModule )\r
 {\r
        string dep;\r
-       if ( importedModule.type == ObjectLibrary )\r
+       if ( ReferenceObjects ( importedModule ) )\r
                dep = GetTargetMacro ( importedModule );\r
        else\r
                dep = GetImportLibraryFilename ( importedModule, NULL );\r
        return dep;\r
 }\r
 \r
+void\r
+MingwModuleHandler::GetTargets ( const Module& dependencyModule,\r
+                                    string_list& targets )\r
+{\r
+       if ( dependencyModule.invocations.size () > 0 )\r
+       {\r
+               for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )\r
+               {\r
+                       Invoke& invoke = *dependencyModule.invocations[i];\r
+                       invoke.GetTargets ( targets );\r
+               }\r
+       }\r
+       else\r
+               targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );\r
+}\r
+\r
 void\r
 MingwModuleHandler::GetModuleDependencies (\r
        string_list& dependencies )\r
 {\r
        size_t iend = module.dependencies.size ();\r
 \r
-       // TODO FIXME - do we *really* not want to call\r
-       // GetDefinitionDependencies() if dependencies.size() == 0 ???\r
        if ( iend == 0 )\r
                return;\r
        \r
@@ -282,7 +326,8 @@ MingwModuleHandler::GetModuleDependencies (
        {\r
                const Dependency& dependency = *module.dependencies[i];\r
                const Module& dependencyModule = *dependency.dependencyModule;\r
-               dependencyModule.GetTargets ( dependencies );\r
+               GetTargets ( dependencyModule,\r
+                            dependencies );\r
        }\r
        GetDefinitionDependencies ( dependencies );\r
 }\r
@@ -347,6 +392,13 @@ MingwModuleHandler::GetObjectFilename (
                newExtension = ".coff";\r
        else if ( extension == ".spec" || extension == ".SPEC" )\r
                newExtension = ".stubs.o";\r
+       else if ( extension == ".idl" || extension == ".IDL" )\r
+       {\r
+               if ( module.type == RpcServer )\r
+                       newExtension = "_s.o";\r
+               else\r
+                       newExtension = "_c.o";\r
+       }\r
        else\r
                newExtension = ".o";\r
        \r
@@ -737,6 +789,10 @@ MingwModuleHandler::GenerateGccCommand (
        string deps = sourceFilename;\r
        if ( module.pch && use_pch )\r
                deps += " " + module.pch->header + ".gch";\r
+       \r
+       /* WIDL generated headers may be used */\r
+       deps += " " + GetLinkingDependenciesMacro ();\r
+\r
        string objectFilename = GetObjectFilename (\r
                sourceFilename, &clean_files );\r
        fprintf ( fMakefile,\r
@@ -801,31 +857,47 @@ MingwModuleHandler::GenerateWindresCommand (
                ReplaceExtension ( sourceFilename, ".rci" );\r
        string resFilename = ros_temp +\r
                ReplaceExtension ( sourceFilename, ".res" );\r
-       fprintf ( fMakefile,\r
-                 "%s: %s $(WRC_TARGET) | %s\n",\r
-                 objectFilename.c_str (),\r
-                 sourceFilename.c_str (),\r
-                 GetDirectory ( objectFilename ).c_str () );\r
-       fprintf ( fMakefile, "\t$(ECHO_WRC)\n" );\r
-       fprintf ( fMakefile,\r
-                "\t${gcc} -xc -E -DRC_INVOKED ${%s} %s > %s\n",\r
-                windresflagsMacro.c_str (),\r
-                sourceFilename.c_str (),\r
-                rciFilename.c_str () );\r
-       fprintf ( fMakefile,\r
-                "\t$(Q)$(WRC_TARGET) ${%s} %s %s\n",\r
-                windresflagsMacro.c_str (),\r
-                rciFilename.c_str (),\r
-                resFilename.c_str () );\r
-       fprintf ( fMakefile,\r
-                "\t-@${rm} %s 2>$(NUL)\n",\r
-                rciFilename.c_str () );\r
-       fprintf ( fMakefile,\r
-                "\t${windres} %s -o $@\n",\r
-                resFilename.c_str () );\r
-       fprintf ( fMakefile,\r
-                "\t-@${rm} %s 2>$(NUL)\n",\r
-                resFilename.c_str () );\r
+       if ( module.useWRC )\r
+       {\r
+               fprintf ( fMakefile,\r
+                         "%s: %s $(WRC_TARGET) | %s\n",\r
+                         objectFilename.c_str (),\r
+                         sourceFilename.c_str (),\r
+                         GetDirectory ( objectFilename ).c_str () );\r
+               fprintf ( fMakefile, "\t$(ECHO_WRC)\n" );\r
+               fprintf ( fMakefile,\r
+                        "\t${gcc} -xc -E -DRC_INVOKED ${%s} %s > %s\n",\r
+                        windresflagsMacro.c_str (),\r
+                        sourceFilename.c_str (),\r
+                        rciFilename.c_str () );\r
+               fprintf ( fMakefile,\r
+                        "\t$(Q)$(WRC_TARGET) ${%s} %s %s\n",\r
+                        windresflagsMacro.c_str (),\r
+                        rciFilename.c_str (),\r
+                        resFilename.c_str () );\r
+               fprintf ( fMakefile,\r
+                        "\t-@${rm} %s 2>$(NUL)\n",\r
+                        rciFilename.c_str () );\r
+               fprintf ( fMakefile,\r
+                        "\t${windres} %s -o $@\n",\r
+                        resFilename.c_str () );\r
+               fprintf ( fMakefile,\r
+                        "\t-@${rm} %s 2>$(NUL)\n",\r
+                        resFilename.c_str () );\r
+       }\r
+       else\r
+       {\r
+               fprintf ( fMakefile,\r
+                         "%s: %s $(WRC_TARGET) | %s\n",\r
+                         objectFilename.c_str (),\r
+                         sourceFilename.c_str (),\r
+                         GetDirectory ( objectFilename ).c_str () );\r
+               fprintf ( fMakefile, "\t$(ECHO_WRC)\n" );\r
+               fprintf ( fMakefile,\r
+                        "\t${windres} $(%s) %s -o $@\n",\r
+                        windresflagsMacro.c_str (),\r
+                        sourceFilename.c_str () );\r
+       }\r
 }\r
 \r
 void\r
@@ -867,6 +939,91 @@ MingwModuleHandler::GenerateWinebuildCommands (
                  stub_file.c_str () );\r
 }\r
 \r
+void\r
+MingwModuleHandler::GenerateWidlCommandsServer (\r
+       const string& sourceFilename,\r
+       const string& widlflagsMacro )\r
+{\r
+       string basename = GetBasename ( sourceFilename );\r
+\r
+       /*string generatedHeaderFilename = PassThruCacheDirectory (\r
+               basename + ".h",\r
+               backend->intermediateDirectory );\r
+       CLEAN_FILE(generatedHeaderFilename);\r
+       */\r
+       string generatedHeaderFilename = basename + "_s.h";\r
+       CLEAN_FILE(generatedHeaderFilename);\r
+\r
+       string generatedServerFilename = PassThruCacheDirectory (\r
+               basename + "_s.c",\r
+               backend->intermediateDirectory );\r
+       CLEAN_FILE(generatedServerFilename);\r
+\r
+       fprintf ( fMakefile,\r
+                 "%s %s: %s $(WIDL_TARGET) | %s\n",\r
+                 generatedServerFilename.c_str (),\r
+                 generatedHeaderFilename.c_str (),\r
+                 sourceFilename.c_str (),\r
+                 GetDirectory ( generatedServerFilename ).c_str () );\r
+       fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );\r
+       fprintf ( fMakefile,\r
+                 "\t%s %s -h -H %s -s -S %s %s\n",\r
+                 "$(Q)$(WIDL_TARGET)",\r
+                 widlflagsMacro.c_str (),\r
+                 generatedHeaderFilename.c_str (),\r
+                 generatedServerFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateWidlCommandsClient (\r
+       const string& sourceFilename,\r
+       const string& widlflagsMacro )\r
+{\r
+       string basename = GetBasename ( sourceFilename );\r
+\r
+       /*string generatedHeaderFilename = PassThruCacheDirectory (\r
+               basename + ".h",\r
+               backend->intermediateDirectory );\r
+       CLEAN_FILE(generatedHeaderFilename);\r
+       */\r
+       string generatedHeaderFilename = basename + "_c.h";\r
+       CLEAN_FILE(generatedHeaderFilename);\r
+\r
+       string generatedClientFilename = PassThruCacheDirectory (\r
+               basename + "_c.c",\r
+               backend->intermediateDirectory );\r
+       CLEAN_FILE(generatedClientFilename);\r
+\r
+       fprintf ( fMakefile,\r
+                 "%s %s: %s $(WIDL_TARGET) | %s\n",\r
+                 generatedClientFilename.c_str (),\r
+                 generatedHeaderFilename.c_str (),\r
+                 sourceFilename.c_str (),\r
+                 GetDirectory ( generatedClientFilename ).c_str () );\r
+       fprintf ( fMakefile, "\t$(ECHO_WIDL)\n" );\r
+       fprintf ( fMakefile,\r
+                 "\t%s %s -h -H %s -c -C %s %s\n",\r
+                 "$(Q)$(WIDL_TARGET)",\r
+                 widlflagsMacro.c_str (),\r
+                 generatedHeaderFilename.c_str (),\r
+                 generatedClientFilename.c_str (),\r
+                 sourceFilename.c_str () );\r
+}\r
+\r
+void\r
+MingwModuleHandler::GenerateWidlCommands (\r
+       const string& sourceFilename,\r
+       const string& widlflagsMacro )\r
+{\r
+       if ( module.type == RpcServer )\r
+               GenerateWidlCommandsServer ( sourceFilename,\r
+                                            widlflagsMacro );\r
+       else\r
+               GenerateWidlCommandsClient ( sourceFilename,\r
+                                            widlflagsMacro );\r
+}\r
+\r
 void\r
 MingwModuleHandler::GenerateCommands (\r
        const string& sourceFilename,\r
@@ -874,7 +1031,8 @@ MingwModuleHandler::GenerateCommands (
        const string& cppc,\r
        const string& cflagsMacro,\r
        const string& nasmflagsMacro,\r
-       const string& windresflagsMacro )\r
+       const string& windresflagsMacro,\r
+       const string& widlflagsMacro )\r
 {\r
        string extension = GetExtension ( sourceFilename );\r
        if ( extension == ".c" || extension == ".C" )\r
@@ -920,6 +1078,15 @@ MingwModuleHandler::GenerateCommands (
                                     cflagsMacro );\r
                return;\r
        }\r
+       else if ( extension == ".idl" || extension == ".IDL" )\r
+       {\r
+               GenerateWidlCommands ( sourceFilename,\r
+                                      widlflagsMacro );\r
+               GenerateGccCommand ( GetActualSourceFilename ( sourceFilename ),\r
+                                    cc,\r
+                                    cflagsMacro );\r
+               return;\r
+       }\r
 \r
        throw InvalidOperationException ( __FILE__,\r
                                          __LINE__,\r
@@ -1070,7 +1237,8 @@ MingwModuleHandler::GenerateObjectFileTargets (
        const string& cppc,\r
        const string& cflagsMacro,\r
        const string& nasmflagsMacro,\r
-       const string& windresflagsMacro )\r
+       const string& windresflagsMacro,\r
+       const string& widlflagsMacro )\r
 {\r
        size_t i;\r
        \r
@@ -1083,7 +1251,8 @@ MingwModuleHandler::GenerateObjectFileTargets (
                                   cppc,\r
                                   cflagsMacro,\r
                                   nasmflagsMacro,\r
-                                  windresflagsMacro );\r
+                                  windresflagsMacro,\r
+                                  widlflagsMacro );\r
                fprintf ( fMakefile,\r
                          "\n" );\r
        }\r
@@ -1096,7 +1265,8 @@ MingwModuleHandler::GenerateObjectFileTargets (
                                            cppc,\r
                                            cflagsMacro,\r
                                            nasmflagsMacro,\r
-                                           windresflagsMacro );\r
+                                           windresflagsMacro,\r
+                                           widlflagsMacro );\r
        }\r
 }\r
 \r
@@ -1106,7 +1276,8 @@ MingwModuleHandler::GenerateObjectFileTargets (
        const string& cppc,\r
        const string& cflagsMacro,\r
        const string& nasmflagsMacro,\r
-       const string& windresflagsMacro )\r
+       const string& windresflagsMacro,\r
+       const string& widlflagsMacro )\r
 {\r
        if ( module.pch )\r
        {\r
@@ -1136,7 +1307,8 @@ MingwModuleHandler::GenerateObjectFileTargets (
                                    cppc,\r
                                    cflagsMacro,\r
                                    nasmflagsMacro,\r
-                                   windresflagsMacro );\r
+                                   windresflagsMacro,\r
+                                   widlflagsMacro );\r
        fprintf ( fMakefile, "\n" );\r
 }\r
 \r
@@ -1198,7 +1370,7 @@ MingwModuleHandler::GetLinkerMacro () const
 string\r
 MingwModuleHandler::GetModuleTargets ( const Module& module )\r
 {\r
-       if ( module.type == ObjectLibrary )\r
+       if ( ReferenceObjects ( module ) )\r
                return GetObjectsMacro ( module );\r
        else\r
                return GetTargetFilename ( module, NULL );\r
@@ -1234,6 +1406,7 @@ MingwModuleHandler::GenerateOtherMacros ()
        cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ());\r
        nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ());\r
        windresflagsMacro = ssprintf ("%s_RCFLAGS", module.name.c_str ());\r
+       widlflagsMacro = ssprintf ("%s_WIDLFLAGS", module.name.c_str ());\r
        linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ());\r
        libsMacro = ssprintf("%s_LIBS", module.name.c_str ());\r
        linkDepsMacro = ssprintf ("%s_LINKDEPS", module.name.c_str ());\r
@@ -1284,6 +1457,11 @@ MingwModuleHandler::GenerateOtherMacros ()
                "%s += $(PROJECT_RCFLAGS)\n",\r
                windresflagsMacro.c_str () );\r
 \r
+       fprintf (\r
+               fMakefile,\r
+               "%s += $(PROJECT_WIDLFLAGS)\n",\r
+               widlflagsMacro.c_str () );\r
+\r
        fprintf (\r
                fMakefile,\r
                "%s_LFLAGS += $(PROJECT_LFLAGS) -g\n",\r
@@ -1318,6 +1496,7 @@ MingwModuleHandler::GenerateOtherMacros ()
        // future references to the macros will be to get their values\r
        cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ());\r
        nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ());\r
+       widlflagsMacro = ssprintf ("$(%s)", widlflagsMacro.c_str ());\r
 }\r
 \r
 void\r
@@ -1338,7 +1517,7 @@ MingwModuleHandler::GenerateRules ()
                module.name.c_str (),\r
                GetTargetMacro ( module ).c_str () );\r
 \r
-       if ( module.type != ObjectLibrary )\r
+       if ( !ReferenceObjects ( module ) )\r
        {\r
                string ar_target ( GenerateArchiveTarget ( ar, objectsMacro ) );\r
                if ( targetMacro != ar_target )\r
@@ -1351,7 +1530,8 @@ MingwModuleHandler::GenerateRules ()
                                                                cppc,\r
                                                                cflagsMacro,\r
                                                                nasmflagsMacro,\r
-                                                               windresflagsMacro );\r
+                                                               windresflagsMacro,\r
+                                                           widlflagsMacro );\r
 }\r
 \r
 void\r
@@ -1544,6 +1724,18 @@ MingwModuleHandler::GetSpecObjectDependencies (
        dependencies.push_back ( stubsDependency );\r
 }\r
 \r
+void\r
+MingwModuleHandler::GetWidlObjectDependencies (\r
+       string_list& dependencies,\r
+       const string& filename ) const\r
+{\r
+       string basename = GetBasename ( filename );\r
+       string serverDependency = PassThruCacheDirectory (\r
+               NormalizeFilename ( basename + "_s.c" ),\r
+               backend->intermediateDirectory );\r
+       dependencies.push_back ( serverDependency );\r
+}\r
+\r
 void\r
 MingwModuleHandler::GetDefinitionDependencies (\r
        string_list& dependencies ) const\r
@@ -1558,6 +1750,10 @@ MingwModuleHandler::GetDefinitionDependencies (
                {\r
                        GetSpecObjectDependencies ( dependencies, file.name );\r
                }\r
+               if ( extension == ".idl" || extension == ".IDL" )\r
+               {\r
+                       GetWidlObjectDependencies ( dependencies, file.name );\r
+               }\r
        }\r
 }\r
 \r
@@ -1621,7 +1817,7 @@ void
 MingwKernelModuleHandler::GenerateKernelModuleTarget ()\r
 {\r
        string targetName ( module.GetTargetName () ); // i.e. "ntoskrnl.exe"\r
-       string targetMacro ( GetTargetMacro (module) ); // i.e. "$(NTOSKRNL_TARGET)"\r
+       string targetMacro ( GetTargetMacro ( module ) ); // i.e. "$(NTOSKRNL_TARGET)"\r
        string workingDirectory = GetWorkingDirectory ();\r
        string objectsMacro = GetObjectsMacro ( module );\r
        string linkDepsMacro = GetLinkingDependenciesMacro ();\r
@@ -1740,7 +1936,7 @@ MingwKernelModeDLLModuleHandler::Process ()
 void\r
 MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ()\r
 {\r
-       string targetMacro ( GetTargetMacro (module) );\r
+       string targetMacro ( GetTargetMacro ( module ) );\r
        string workingDirectory = GetWorkingDirectory ( );\r
        string objectsMacro = GetObjectsMacro ( module );\r
        string linkDepsMacro = GetLinkingDependenciesMacro ();\r
@@ -2421,3 +2617,30 @@ MingwTestModuleHandler::GenerateTestModuleTarget ()
                GeneratePhonyTarget();\r
        }\r
 }\r
+\r
+\r
+MingwRpcServerModuleHandler::MingwRpcServerModuleHandler (\r
+       const Module& module_ )\r
+\r
+       : MingwModuleHandler ( module_ )\r
+{\r
+}\r
+\r
+void\r
+MingwRpcServerModuleHandler::Process ()\r
+{\r
+       GenerateRules ();\r
+}\r
+\r
+MingwRpcClientModuleHandler::MingwRpcClientModuleHandler (\r
+       const Module& module_ )\r
+\r
+       : MingwModuleHandler ( module_ )\r
+{\r
+}\r
+\r
+void\r
+MingwRpcClientModuleHandler::Process ()\r
+{\r
+       GenerateRules ();\r
+}\r
index 69333ac..6cb6748 100644 (file)
@@ -51,6 +51,7 @@ public:
        virtual std::string TypeSpecificNasmFlags() { return ""; }\r
        void GenerateInvocations () const;\r
        void GenerateCleanTarget () const;\r
+       static bool ReferenceObjects ( const Module& module );\r
 protected:\r
        std::string GetWorkingDirectory () const;\r
        std::string GetBasename ( const std::string& filename ) const;\r
@@ -58,6 +59,8 @@ protected:
        std::string GetModuleArchiveFilename () const;\r
        bool IsGeneratedFile ( const File& file ) const;\r
        std::string GetImportLibraryDependency ( const Module& importedModule );\r
+       void GetTargets ( const Module& dependencyModule,\r
+                         string_list& targets );\r
        void GetModuleDependencies ( string_list& dependencies );\r
        std::string GetAllDependencies () const;\r
        void GetSourceFilenames ( string_list& list, bool includeGeneratedFiles = true ) const;\r
@@ -122,27 +125,40 @@ private:
        void GenerateWindresCommand ( const std::string& sourceFilename,\r
                                      const std::string& windresflagsMacro );\r
        void GenerateWinebuildCommands ( const std::string& sourceFilename );\r
+       void GenerateWidlCommandsServer (\r
+               const std::string& sourceFilename,\r
+               const std::string& widlflagsMacro );\r
+       void GenerateWidlCommandsClient (\r
+               const std::string& sourceFilename,\r
+               const std::string& widlflagsMacro );\r
+       void GenerateWidlCommands ( const std::string& sourceFilename,\r
+                                   const std::string& widlflagsMacro );\r
        void GenerateCommands ( const std::string& sourceFilename,\r
                                const std::string& cc,\r
                                const std::string& cppc,\r
                                const std::string& cflagsMacro,\r
                                const std::string& nasmflagsMacro,\r
-                               const std::string& windresflagsMacro );\r
+                               const std::string& windresflagsMacro,\r
+                               const std::string& widlflagsMacro );\r
        void GenerateObjectFileTargets ( const IfableData& data,\r
                                         const std::string& cc,\r
                                         const std::string& cppc,\r
                                         const std::string& cflagsMacro,\r
                                         const std::string& nasmflagsMacro,\r
-                                        const std::string& windresflagsMacro );\r
+                                        const std::string& windresflagsMacro,\r
+                                        const std::string& widlflagsMacro );\r
        void GenerateObjectFileTargets ( const std::string& cc,\r
                                         const std::string& cppc,\r
                                         const std::string& cflagsMacro,\r
                                         const std::string& nasmflagsMacro,\r
-                                        const std::string& windresflagsMacro );\r
+                                        const std::string& windresflagsMacro,\r
+                                        const std::string& widlflagsMacro );\r
        std::string GenerateArchiveTarget ( const std::string& ar,\r
                                            const std::string& objs_macro ) const;\r
        void GetSpecObjectDependencies ( string_list& dependencies,\r
                                         const std::string& filename ) const;\r
+       void GetWidlObjectDependencies ( string_list& dependencies,\r
+                                        const std::string& filename ) const;\r
        void GetDefaultDependencies ( string_list& dependencies ) const;\r
        void GetInvocationDependencies ( const Module& module, string_list& dependencies );\r
        bool IsWineModule () const;\r
@@ -152,8 +168,14 @@ private:
 public:\r
        const Module& module;\r
        string_list clean_files;\r
-       std::string cflagsMacro, nasmflagsMacro, windresflagsMacro,\r
-               linkerflagsMacro, objectsMacro, libsMacro, linkDepsMacro;\r
+       std::string cflagsMacro;\r
+       std::string nasmflagsMacro;\r
+       std::string windresflagsMacro;\r
+       std::string widlflagsMacro;\r
+       std::string linkerflagsMacro;\r
+       std::string objectsMacro;\r
+       std::string libsMacro;\r
+       std::string linkDepsMacro;\r
 };\r
 \r
 \r
@@ -322,6 +344,7 @@ private:
        void OutputCdfileCopyCommands ( const std::string& bootcdDirectory );\r
 };\r
 \r
+\r
 class MingwTestModuleHandler : public MingwModuleHandler\r
 {\r
 public:\r
@@ -332,4 +355,22 @@ private:
        void GenerateTestModuleTarget ();\r
 };\r
 \r
+\r
+class MingwRpcServerModuleHandler : public MingwModuleHandler\r
+{\r
+public:\r
+       MingwRpcServerModuleHandler ( const Module& module );\r
+       virtual HostType DefaultHost() { return HostFalse; }\r
+       virtual void Process ();\r
+};\r
+\r
+\r
+class MingwRpcClientModuleHandler : public MingwModuleHandler\r
+{\r
+public:\r
+       MingwRpcClientModuleHandler ( const Module& module );\r
+       virtual HostType DefaultHost() { return HostFalse; }\r
+       virtual void Process ();\r
+};\r
+\r
 #endif /* MINGW_MODULEHANDLER_H */\r
index c4d9842..cf3639f 100644 (file)
@@ -40,6 +40,8 @@ Bootstrap::IsSupportedModuleType ( ModuleType type )
                case ObjectLibrary:\r
                case Iso:\r
                case Test:\r
+               case RpcServer:\r
+               case RpcClient:\r
                        return false;\r
        }\r
        throw InvalidOperationException ( __FILE__,\r
index 8567a76..8bfd035 100644 (file)
@@ -216,6 +216,12 @@ Module::Module ( const Project& project,
                installName = att->value;\r
        else\r
                installName = "";\r
+       \r
+       att = moduleNode.GetAttribute ( "usewrc", false );\r
+       if ( att != NULL )\r
+               useWRC = att->value == "true";\r
+       else\r
+               useWRC = true;\r
 }\r
 \r
 Module::~Module ()\r
@@ -450,6 +456,10 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return Iso;\r
        if ( attribute.value == "test" )\r
                return Test;\r
+       if ( attribute.value == "rpcserver" )\r
+               return RpcServer;\r
+       if ( attribute.value == "rpcclient" )\r
+               return RpcClient;\r
        throw InvalidAttributeValueException ( location,\r
                                               attribute.name,\r
                                               attribute.value );\r
@@ -484,6 +494,10 @@ Module::GetDefaultModuleExtension () const
                        return ".iso";\r
                case Test:\r
                        return ".exe";\r
+               case RpcServer:\r
+                       return ".o";\r
+               case RpcClient:\r
+                       return ".o";\r
        }\r
        throw InvalidOperationException ( __FILE__,\r
                                          __LINE__ );\r
@@ -517,6 +531,8 @@ Module::GetDefaultModuleEntrypoint () const
                case BootLoader:\r
                case BootSector:\r
                case Iso:\r
+               case RpcServer:\r
+               case RpcClient:\r
                        return "";\r
        }\r
        throw InvalidOperationException ( __FILE__,\r
@@ -551,6 +567,8 @@ Module::GetDefaultModuleBaseaddress () const
                case BootLoader:\r
                case BootSector:\r
                case Iso:\r
+               case RpcServer:\r
+               case RpcClient:\r
                        return "";\r
        }\r
        throw InvalidOperationException ( __FILE__,\r
@@ -601,21 +619,6 @@ Module::GetPathWithPrefix ( const string& prefix ) const
        return path + CSEP + prefix + GetTargetName ();\r
 }\r
 \r
-void\r
-Module::GetTargets ( string_list& targets ) const\r
-{\r
-       if ( invocations.size () > 0 )\r
-       {\r
-               for ( size_t i = 0; i < invocations.size (); i++ )\r
-               {\r
-                       Invoke& invoke = *invocations[i];\r
-                       invoke.GetTargets ( targets );\r
-               }\r
-       }\r
-       else\r
-               targets.push_back ( GetPath () );\r
-}\r
-\r
 string\r
 Module::GetInvocationTarget ( const int index ) const\r
 {\r
index aa3f185..b52ff47 100644 (file)
@@ -137,7 +137,9 @@ enum ModuleType
        BootLoader,\r
        BootSector,\r
        Iso,\r
-       Test\r
+       Test,\r
+       RpcServer,\r
+       RpcClient\r
 };\r
 \r
 enum HostType\r
@@ -173,6 +175,7 @@ public:
        HostType host;\r
        std::string installBase;\r
        std::string installName;\r
+       bool useWRC;\r
 \r
        Module ( const Project& project,\r
                 const XMLElement& moduleNode,\r
index 9bd140c..e707ac0 100644 (file)
@@ -107,7 +107,7 @@ Module element
 There can be zero or more modules per xml build file.\r
 \r
 Syntax:\r
-       <module name="msvcrt" type="win32dll" extension=".dll" entrypoint="_DllMain@12" baseaddress="0x70000000" mangledsymbols="true" installbase="system32" installname="msvcrt.dll" >\r
+       <module name="msvcrt" type="win32dll" extension=".dll" entrypoint="_DllMain@12" baseaddress="0x70000000" mangledsymbols="true" installbase="system32" installname="msvcrt.dll" usewrc="false">\r
                ...\r
        </module>\r
 \r
@@ -120,6 +120,7 @@ Attributes:
        mangledsymbols - Controls wether or not to pass --kill-at to dlltool. If this attribute has the value false then --kill-at is passed to dlltool. If the value is true, then --kill-at is not passed to dlltool. If the generated file exports C++ classes then this need to be true.\r
        installbase - Base directory of the generated file in the installation directory. This attribute is optional.\r
        installname - Name of generated file in the installation directory. This attribute is optional, but if not specified, the generated file is not copied to the installation directory.\r
+       usewrc - Use WRC to compile resources if true. If false, windres is used. This attribute is optional. If not specified, WRC will be used.\r
 \r
 Value:\r
        None.\r
@@ -145,6 +146,8 @@ The module type determines the actions that is to be carried out to process the
        bootsector - Builds one or more bootsector binaries. The entrypoint, baseaddress, and mangledsymbols module attributes are not applicable for this module type.\r
        iso - Builds a bootable CD. The entrypoint, baseaddress, and mangledsymbols module attributes are not applicable for this module type.\r
        test - Builds a testsuite. Default extension is .exe. Default entrypoint is _mainCRTStartup. The baseaddress module attribute is not applicable for this module type.\r
+       rpcserver - Generates and builds server code for an RPC interface. Default extension is .o. The entrypoint, baseaddress, and mangledsymbols module attributes are not applicable for this module type.\r
+       rpcclient - Generates and builds client code for an RPC interface. Default extension is .o. The entrypoint, baseaddress, and mangledsymbols module attributes are not applicable for this module type.\r
 \r
 \r
 Bootstrap element\r
diff --git a/reactos/tools/rs6000.h b/reactos/tools/rs6000.h
new file mode 100644 (file)
index 0000000..433f450
--- /dev/null
@@ -0,0 +1,243 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   FIXME: Can someone provide a transliteration of this name into ASCII?
+   Using the following chars caused a compiler warning on HIUX (so I replaced
+   them with octal escapes), and isn't useful without an understanding of what
+   character set it is.
+   Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+   and John Gilmore of Cygnus Support.  */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+       char f_magic[2];        /* magic number                 */
+       char f_nscns[2];        /* number of sections           */
+       char f_timdat[4];       /* time & date stamp            */
+       char f_symptr[4];       /* file pointer to symtab       */
+       char f_nsyms[4];        /* number of symtab entries     */
+       char f_opthdr[2];       /* sizeof(optional hdr)         */
+       char f_flags[2];        /* flags                        */
+};
+
+        /* IBM RS/6000 */
+#define U802WRMAGIC     0730    /* writeable text segments **chh**      */
+#define U802ROMAGIC     0735    /* readonly sharable text segments      */
+#define U802TOCMAGIC    0737    /* readonly text segments and TOC       */
+
+#define BADMAG(x)      \
+       ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+        (x).f_magic != U802TOCMAGIC)
+
+#define        FILHDR  struct external_filehdr
+#define        FILHSZ  20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+  unsigned char        magic[2];       /* type of file                 */
+  unsigned char        vstamp[2];      /* version stamp                */
+  unsigned char        tsize[4];       /* text size in bytes, padded to FW bdry */
+  unsigned char        dsize[4];       /* initialized data "  "        */
+  unsigned char        bsize[4];       /* uninitialized data "   "     */
+  unsigned char        entry[4];       /* entry pt.                    */
+  unsigned char        text_start[4];  /* base of text used for this file */
+  unsigned char        data_start[4];  /* base of data used for this file */
+  unsigned char        o_toc[4];       /* address of TOC */
+  unsigned char        o_snentry[2];   /* section number of entry point */
+  unsigned char        o_sntext[2];    /* section number of .text section */
+  unsigned char        o_sndata[2];    /* section number of .data section */
+  unsigned char        o_sntoc[2];     /* section number of TOC */
+  unsigned char        o_snloader[2];  /* section number of .loader section */
+  unsigned char        o_snbss[2];     /* section number of .bss section */
+  unsigned char        o_algntext[2];  /* .text alignment */
+  unsigned char        o_algndata[2];  /* .data alignment */
+  unsigned char        o_modtype[2];   /* module type (??) */
+  unsigned char o_cputype[2];  /* cpu type */
+  unsigned char        o_maxstack[4];  /* max stack size (??) */
+  unsigned char o_maxdata[4];  /* max data size (??) */
+  unsigned char        o_resv2[12];    /* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define        RS6K_AOUTHDR_OMAGIC     0x0107  /* old: text & data writeable */
+#define        RS6K_AOUTHDR_NMAGIC     0x0108  /* new: text r/o, data r/w */
+#define        RS6K_AOUTHDR_ZMAGIC     0x010B  /* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+       char            s_name[8];      /* section name                 */
+       char            s_paddr[4];     /* physical address, aliased s_nlib */
+       char            s_vaddr[4];     /* virtual address              */
+       char            s_size[4];      /* section size                 */
+       char            s_scnptr[4];    /* file ptr to raw data for section */
+       char            s_relptr[4];    /* file ptr to relocation       */
+       char            s_lnnoptr[4];   /* file ptr to line numbers     */
+       char            s_nreloc[2];    /* number of relocation entries */
+       char            s_nlnno[2];     /* number of line number entries*/
+       char            s_flags[4];     /* flags                        */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT  ".text"
+#define _DATA  ".data"
+#define _BSS   ".bss"
+#define _PAD   ".pad"
+#define _LOADER        ".loader"
+
+#define        SCNHDR  struct external_scnhdr
+#define        SCNHSZ  40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER.  */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG.  */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+   another section header with STYP_OVRFLO set.  */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+       union {
+               char l_symndx[4];       /* function name symbol index, iff l_lnno == 0*/
+               char l_paddr[4];        /* (physical) address of line number    */
+       } l_addr;
+       char l_lnno[2]; /* line number          */
+};
+
+
+#define        LINENO  struct external_lineno
+#define        LINESZ  6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN     8       /* # characters in a symbol name        */
+#define E_FILNMLEN     14      /* # characters in a file name          */
+#define E_DIMNUM       4       /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+  union {
+    char e_name[E_SYMNMLEN];
+    struct {
+      char e_zeroes[4];
+      char e_offset[4];
+    } e;
+  } e;
+  char e_value[4];
+  char e_scnum[2];
+  char e_type[2];
+  char e_sclass[1];
+  char e_numaux[1];
+};
+
+
+
+#define N_BTMASK       (017)
+#define N_TMASK                (060)
+#define N_BTSHFT       (4)
+#define N_TSHIFT       (2)
+
+
+union external_auxent {
+       struct {
+               char x_tagndx[4];       /* str, un, or enum tag indx */
+               union {
+                       struct {
+                           char  x_lnno[2]; /* declaration line number */
+                           char  x_size[2]; /* str/union/array size */
+                       } x_lnsz;
+                       char x_fsize[4];        /* size of function */
+               } x_misc;
+               union {
+                       struct {                /* if ISFCN, tag, or .bb */
+                           char x_lnnoptr[4];  /* ptr to fcn line # */
+                           char x_endndx[4];   /* entry ndx past block end */
+                       } x_fcn;
+                       struct {                /* if ISARY, up to 4 dimen. */
+                           char x_dimen[E_DIMNUM][2];
+                       } x_ary;
+               } x_fcnary;
+               char x_tvndx[2];                /* tv index */
+       } x_sym;
+
+       union {
+               char x_fname[E_FILNMLEN];
+               struct {
+                       char x_zeroes[4];
+                       char x_offset[4];
+               } x_n;
+       } x_file;
+
+       struct {
+               char x_scnlen[4];                       /* section length */
+               char x_nreloc[2];       /* # relocation entries */
+               char x_nlinno[2];       /* # line numbers */
+       } x_scn;
+
+        struct {
+               char x_tvfill[4];       /* tv fill value */
+               char x_tvlen[2];        /* length of .tv */
+               char x_tvran[2][2];     /* tv range */
+       } x_tv;         /* info about .tv section (in auxent of symbol .tv)) */
+
+       struct {
+               unsigned char x_scnlen[4];
+               unsigned char x_parmhash[4];
+               unsigned char x_snhash[2];
+               unsigned char x_smtyp[1];
+               unsigned char x_smclas[1];
+               unsigned char x_stab[4];
+               unsigned char x_snstab[2];
+       } x_csect;
+
+};
+
+#define        SYMENT  struct external_syment
+#define        SYMESZ  18
+#define        AUXENT  union external_auxent
+#define        AUXESZ  18
+#define DBXMASK 0x80           /* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_size[1];
+  char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4
index 21885b4..46405bf 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-#define IMAGE_DOS_MAGIC 0x5a4d
-#define IMAGE_PE_MAGIC 0x00004550
-
-#define IMAGE_SIZEOF_SHORT_NAME 8
-
-#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-typedef signed long LONG;
-typedef unsigned long ULONG;
-#if defined(_WIN64)
-typedef unsigned __int64 ULONG_PTR;
-#else
-typedef  unsigned long ULONG_PTR;
-#endif
-
-#pragma pack(push,2)
-typedef struct _IMAGE_DOS_HEADER {
-  WORD e_magic;
-  WORD e_cblp;
-  WORD e_cp;
-  WORD e_crlc;
-  WORD e_cparhdr;
-  WORD e_minalloc;
-  WORD e_maxalloc;
-  WORD e_ss;
-  WORD e_sp;
-  WORD e_csum;
-  WORD e_ip;
-  WORD e_cs;
-  WORD e_lfarlc;
-  WORD e_ovno;
-  WORD e_res[4];
-  WORD e_oemid;
-  WORD e_oeminfo;
-  WORD e_res2[10];
-  LONG e_lfanew;
-} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
-#pragma pack(pop)
-
-#define IMAGE_FILE_LINE_NUMS_STRIPPED  4
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
-#define IMAGE_FILE_DEBUG_STRIPPED      512
-
-#pragma pack(push,4)
-typedef struct _IMAGE_FILE_HEADER {
-  WORD Machine;
-  WORD NumberOfSections;
-  DWORD TimeDateStamp;
-  DWORD PointerToSymbolTable;
-  DWORD NumberOfSymbols;
-  WORD SizeOfOptionalHeader;
-  WORD Characteristics;
-} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
-
-typedef struct _IMAGE_DATA_DIRECTORY {
-  DWORD VirtualAddress;
-  DWORD Size;
-} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
-
-#define IMAGE_DIRECTORY_ENTRY_BASERELOC        5
-
-typedef struct _IMAGE_OPTIONAL_HEADER {
-  WORD Magic;
-  BYTE MajorLinkerVersion;
-  BYTE MinorLinkerVersion;
-  DWORD SizeOfCode;
-  DWORD SizeOfInitializedData;
-  DWORD SizeOfUninitializedData;
-  DWORD AddressOfEntryPoint;
-  DWORD BaseOfCode;
-  DWORD BaseOfData;
-  DWORD ImageBase;
-  DWORD SectionAlignment;
-  DWORD FileAlignment;
-  WORD MajorOperatingSystemVersion;
-  WORD MinorOperatingSystemVersion;
-  WORD MajorImageVersion;
-  WORD MinorImageVersion;
-  WORD MajorSubsystemVersion;
-  WORD MinorSubsystemVersion;
-  DWORD Reserved1;
-  DWORD SizeOfImage;
-  DWORD SizeOfHeaders;
-  DWORD CheckSum;
-  WORD Subsystem;
-  WORD DllCharacteristics;
-  DWORD SizeOfStackReserve;
-  DWORD SizeOfStackCommit;
-  DWORD SizeOfHeapReserve;
-  DWORD SizeOfHeapCommit;
-  DWORD LoaderFlags;
-  DWORD NumberOfRvaAndSizes;
-  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
-
-#define IMAGE_SCN_TYPE_NOLOAD     0x00000002
-#define IMAGE_SCN_LNK_REMOVE      0x00000800
-#define IMAGE_SCN_MEM_READ        0x40000000
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
-
-typedef struct _IMAGE_SECTION_HEADER {
-  BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
-  union {
-    DWORD PhysicalAddress;
-    DWORD VirtualSize;
-  } Misc;
-  DWORD VirtualAddress;
-  DWORD SizeOfRawData;
-  DWORD PointerToRawData;
-  DWORD PointerToRelocations;
-  DWORD PointerToLinenumbers;
-  WORD NumberOfRelocations;
-  WORD NumberOfLinenumbers;
-  DWORD Characteristics;
-} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
-
-typedef struct _IMAGE_BASE_RELOCATION {
-       DWORD VirtualAddress;
-       DWORD SizeOfBlock;
-} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
-
-
-typedef struct {
-  unsigned short f_magic;         /* magic number             */
-  unsigned short f_nscns;         /* number of sections       */
-  unsigned long  f_timdat;        /* time & date stamp        */
-  unsigned long  f_symptr;        /* file pointer to symtab   */
-  unsigned long  f_nsyms;         /* number of symtab entries */
-  unsigned short f_opthdr;        /* sizeof(optional hdr)     */
-  unsigned short f_flags;         /* flags                    */
-} FILHDR;
-
-typedef struct {
-  char           s_name[8];  /* section name                     */
-  unsigned long  s_paddr;    /* physical address, aliased s_nlib */
-  unsigned long  s_vaddr;    /* virtual address                  */
-  unsigned long  s_size;     /* section size                     */
-  unsigned long  s_scnptr;   /* file ptr to raw data for section */
-  unsigned long  s_relptr;   /* file ptr to relocation           */
-  unsigned long  s_lnnoptr;  /* file ptr to line numbers         */
-  unsigned short s_nreloc;   /* number of relocation entries     */
-  unsigned short s_nlnno;    /* number of line number entries    */
-  unsigned long  s_flags;    /* flags                            */
-} SCNHDR;
-#pragma pack(pop)
-
-typedef struct _SYMBOLFILE_HEADER {
-  unsigned long SymbolsOffset;
-  unsigned long SymbolsLength;
-  unsigned long StringsOffset;
-  unsigned long StringsLength;
-} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
-
-typedef struct _STAB_ENTRY {
-  unsigned long n_strx;         /* index into string table of name */
-  unsigned char n_type;         /* type of symbol */
-  unsigned char n_other;        /* misc info (usually empty) */
-  unsigned short n_desc;        /* description field */
-  unsigned long n_value;        /* value of symbol */
-} STAB_ENTRY, *PSTAB_ENTRY;
-
-#define N_FUN 0x24
-#define N_SLINE 0x44
-#define N_SO 0x64
-
-/* COFF symbol table */
-
-#define E_SYMNMLEN     8       /* # characters in a symbol name        */
-#define E_FILNMLEN     14      /* # characters in a file name          */
-#define E_DIMNUM       4       /* # array dimensions in auxiliary entry */
-
-#define N_BTMASK       (0xf)
-#define N_TMASK                (0x30)
-#define N_BTSHFT       (4)
-#define N_TSHIFT       (2)
-
-/* derived types, in e_type */
-#define DT_NON         (0)     /* no derived type */
-#define DT_PTR         (1)     /* pointer */
-#define DT_FCN         (2)     /* function */
-#define DT_ARY         (3)     /* array */
-
-#define BTYPE(x)       ((x) & N_BTMASK)
-
-#define ISPTR(x)       (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
-#define ISFCN(x)       (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
-#define ISARY(x)       (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
-#define ISTAG(x)       ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
-#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
-
-#define C_EFCN         0xff    /* physical end of function     */
-#define C_NULL         0
-#define C_AUTO         1       /* automatic variable           */
-#define C_EXT          2       /* external symbol              */
-#define C_STAT         3       /* static                       */
-#define C_REG          4       /* register variable            */
-#define C_EXTDEF       5       /* external definition          */
-#define C_LABEL                6       /* label                        */
-#define C_ULABEL       7       /* undefined label              */
-#define C_MOS          8       /* member of structure          */
-#define C_ARG          9       /* function argument            */
-#define C_STRTAG       10      /* structure tag                */
-#define C_MOU          11      /* member of union              */
-#define C_UNTAG                12      /* union tag                    */
-#define C_TPDEF                13      /* type definition              */
-#define C_USTATIC      14      /* undefined static             */
-#define C_ENTAG                15      /* enumeration tag              */
-#define C_MOE          16      /* member of enumeration        */
-#define C_REGPARM      17      /* register parameter           */
-#define C_FIELD                18      /* bit field                    */
-#define C_AUTOARG      19      /* auto argument                */
-#define C_LASTENT      20      /* dummy entry (end of block)   */
-#define C_BLOCK                100     /* ".bb" or ".eb"               */
-#define C_FCN          101     /* ".bf" or ".ef"               */
-#define C_EOS          102     /* end of structure             */
-#define C_FILE         103     /* file name                    */
-#define C_LINE         104     /* line # reformatted as symbol table entry */
-#define C_ALIAS                105     /* duplicate tag                */
-#define C_HIDDEN       106     /* ext symbol in dmert public lib */
-
-#pragma pack(push,1)
-typedef struct _COFF_SYMENT
-{
-  union
-    {
-      char e_name[E_SYMNMLEN];
-      struct
-        {
-          unsigned long e_zeroes;
-          unsigned long e_offset;
-        }
-      e;
-    }
-  e;
-  unsigned long e_value;
-  short e_scnum;
-  unsigned short e_type;
-  unsigned char e_sclass;
-  unsigned char e_numaux;
-} COFF_SYMENT, *PCOFF_SYMENT;
-#pragma pack(pop)
-
-typedef struct _ROSSYM_ENTRY {
-  ULONG_PTR Address;
-  ULONG FunctionOffset;
-  ULONG FileOffset;
-  ULONG SourceLine;
-} ROSSYM_ENTRY, *PROSSYM_ENTRY;
-
-#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1))
-
-char* convert_path(char* origpath)
-{
-   char* newpath;
-   int i;
-
-   newpath = strdup(origpath);
-
-   i = 0;
-   while (newpath[i] != 0)
-     {
-#ifdef UNIX_PATHS
-       if (newpath[i] == '\\')
-         {
-            newpath[i] = '/';
-         }
-#else
-#ifdef DOS_PATHS
-       if (newpath[i] == '/')
-         {
-            newpath[i] = '\\';
-         }
-#endif
-#endif
-       i++;
-     }
-   return(newpath);
-}
+#include "rsym.h"
 
 static int
 CompareSymEntry(const PROSSYM_ENTRY SymEntry1, const PROSSYM_ENTRY SymEntry2)
@@ -342,7 +62,7 @@ GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader,
       if ((strncmp((char*)PESectionHeaders[Idx].Name, ".stab", 5) == 0)
         && (PESectionHeaders[Idx].Name[5] == 0))
         {
-          /* printf(".stab section found. Size %d\n",
+           /* printf(".stab section found. Size %d\n",
                PESectionHeaders[Idx].SizeOfRawData); */
 
            *StabSymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
@@ -351,7 +71,7 @@ GetStabInfo(void *FileData, PIMAGE_FILE_HEADER PEFileHeader,
 
       if (strncmp((char*)PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
         {
-          /* printf(".stabstr section found. Size %d\n",
+           /* printf(".stabstr section found. Size %d\n",
                PESectionHeaders[Idx].SizeOfRawData); */
 
            *StabStringsLength = PESectionHeaders[Idx].SizeOfRawData;
@@ -462,9 +182,9 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
             (*SymbolsBase)[*SymbolsCount].FunctionOffset = 0;
             (*SymbolsBase)[*SymbolsCount].SourceLine = 0;
             LastFunctionAddress = 0;
-           break;
+            break;
           case N_FUN:
-           if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) /* line # 0 isn't valid */
+            if (0 == StabEntry[i].n_desc || StabEntry[i].n_value < ImageBase) /* line # 0 isn't valid */
               {
                 continue;
               }
@@ -492,7 +212,7 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
                                                                            StringsBase);
             (*SymbolsBase)[*SymbolsCount].SourceLine = 0;
             LastFunctionAddress = Address;
-           break;
+            break;
           case N_SLINE:
             if (0 == LastFunctionAddress)
               {
@@ -512,7 +232,7 @@ ConvertStabs(ULONG *SymbolsCount, PROSSYM_ENTRY *SymbolsBase,
             (*SymbolsBase)[*SymbolsCount].SourceLine = StabEntry[i].n_desc;
             break;
           default:
-           continue;
+            continue;
         }
       First = 0;
     }
@@ -1022,9 +742,7 @@ int main(int argc, char* argv[])
   ULONG CoffStringsLength;
   char* path1;
   char* path2;
-  FILE* in;
   FILE* out;
-  int n_in;
   void *StringBase;
   ULONG StringsLength;
   ULONG StabSymbolsCount;
@@ -1033,7 +751,7 @@ int main(int argc, char* argv[])
   PROSSYM_ENTRY CoffSymbols;
   ULONG MergedSymbolsCount;
   PROSSYM_ENTRY MergedSymbols;
-  long FileSize;
+  size_t FileSize;
   void *FileData;
   ULONG RosSymLength;
   void *RosSymSection;
@@ -1047,31 +765,12 @@ int main(int argc, char* argv[])
   path1 = convert_path(argv[1]);
   path2 = convert_path(argv[2]);
 
-  in = fopen(path1, "rb");
-  if (in == NULL)
-    {
-      perror("Cannot open input file");
-      exit(1);
-    }
-  fseek(in, 0L, SEEK_END);
-  FileSize = ftell(in);
-  fseek(in, 0L, SEEK_SET);
-  FileData = malloc(FileSize);
-  if (NULL == FileData)
-    {
-      fclose(in);
-      fprintf(stderr, "Can't allocate %ld bytes to read input file\n", FileSize);
-      exit(1);
-    }
-  n_in = fread(FileData, 1, FileSize, in);
-  if (n_in != FileSize)
-    { 
-      perror("Error reading from input file");
-      free(FileData);
-      fclose(in);
-      exit(1);
-    }
-  fclose(in);
+  FileData = load_file ( path1, &FileSize );
+  if ( !FileData )
+  {
+    fprintf ( stderr, "An error occured loading '%s'\n", path1 );
+    exit(1);
+  }
 
   /* Check if MZ header exists  */
   PEDosHeader = (PIMAGE_DOS_HEADER) FileData;
diff --git a/reactos/tools/rsym.h b/reactos/tools/rsym.h
new file mode 100644 (file)
index 0000000..a282c2b
--- /dev/null
@@ -0,0 +1,266 @@
+/* rsym.h */
+
+#ifndef RSYM_H
+#define RSYM_H
+
+#define IMAGE_DOS_MAGIC 0x5a4d
+#define IMAGE_PE_MAGIC 0x00004550
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef signed long LONG;
+typedef unsigned long ULONG;
+#if defined(_WIN64)
+typedef unsigned __int64 ULONG_PTR;
+#else
+typedef  unsigned long ULONG_PTR;
+#endif
+
+#pragma pack(push,2)
+typedef struct _IMAGE_DOS_HEADER {
+  WORD e_magic;
+  WORD e_cblp;
+  WORD e_cp;
+  WORD e_crlc;
+  WORD e_cparhdr;
+  WORD e_minalloc;
+  WORD e_maxalloc;
+  WORD e_ss;
+  WORD e_sp;
+  WORD e_csum;
+  WORD e_ip;
+  WORD e_cs;
+  WORD e_lfarlc;
+  WORD e_ovno;
+  WORD e_res[4];
+  WORD e_oemid;
+  WORD e_oeminfo;
+  WORD e_res2[10];
+  LONG e_lfanew;
+} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
+#pragma pack(pop)
+
+#define IMAGE_FILE_LINE_NUMS_STRIPPED  4
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
+#define IMAGE_FILE_DEBUG_STRIPPED      512
+
+#pragma pack(push,4)
+typedef struct _IMAGE_FILE_HEADER {
+  WORD Machine;
+  WORD NumberOfSections;
+  DWORD TimeDateStamp;
+  DWORD PointerToSymbolTable;
+  DWORD NumberOfSymbols;
+  WORD SizeOfOptionalHeader;
+  WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+  DWORD VirtualAddress;
+  DWORD Size;
+} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC        5
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+  WORD Magic;
+  BYTE MajorLinkerVersion;
+  BYTE MinorLinkerVersion;
+  DWORD SizeOfCode;
+  DWORD SizeOfInitializedData;
+  DWORD SizeOfUninitializedData;
+  DWORD AddressOfEntryPoint;
+  DWORD BaseOfCode;
+  DWORD BaseOfData;
+  DWORD ImageBase;
+  DWORD SectionAlignment;
+  DWORD FileAlignment;
+  WORD MajorOperatingSystemVersion;
+  WORD MinorOperatingSystemVersion;
+  WORD MajorImageVersion;
+  WORD MinorImageVersion;
+  WORD MajorSubsystemVersion;
+  WORD MinorSubsystemVersion;
+  DWORD Reserved1;
+  DWORD SizeOfImage;
+  DWORD SizeOfHeaders;
+  DWORD CheckSum;
+  WORD Subsystem;
+  WORD DllCharacteristics;
+  DWORD SizeOfStackReserve;
+  DWORD SizeOfStackCommit;
+  DWORD SizeOfHeapReserve;
+  DWORD SizeOfHeapCommit;
+  DWORD LoaderFlags;
+  DWORD NumberOfRvaAndSizes;
+  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
+
+#define IMAGE_SCN_TYPE_NOLOAD     0x00000002
+#define IMAGE_SCN_LNK_REMOVE      0x00000800
+#define IMAGE_SCN_MEM_READ        0x40000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+
+typedef struct _IMAGE_SECTION_HEADER {
+  BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+  union {
+    DWORD PhysicalAddress;
+    DWORD VirtualSize;
+  } Misc;
+  DWORD VirtualAddress;
+  DWORD SizeOfRawData;
+  DWORD PointerToRawData;
+  DWORD PointerToRelocations;
+  DWORD PointerToLinenumbers;
+  WORD NumberOfRelocations;
+  WORD NumberOfLinenumbers;
+  DWORD Characteristics;
+} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
+
+typedef struct _IMAGE_BASE_RELOCATION {
+       DWORD VirtualAddress;
+       DWORD SizeOfBlock;
+} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
+
+
+typedef struct {
+  unsigned short f_magic;         /* magic number             */
+  unsigned short f_nscns;         /* number of sections       */
+  unsigned long  f_timdat;        /* time & date stamp        */
+  unsigned long  f_symptr;        /* file pointer to symtab   */
+  unsigned long  f_nsyms;         /* number of symtab entries */
+  unsigned short f_opthdr;        /* sizeof(optional hdr)     */
+  unsigned short f_flags;         /* flags                    */
+} FILHDR;
+
+typedef struct {
+  char           s_name[8];  /* section name                     */
+  unsigned long  s_paddr;    /* physical address, aliased s_nlib */
+  unsigned long  s_vaddr;    /* virtual address                  */
+  unsigned long  s_size;     /* section size                     */
+  unsigned long  s_scnptr;   /* file ptr to raw data for section */
+  unsigned long  s_relptr;   /* file ptr to relocation           */
+  unsigned long  s_lnnoptr;  /* file ptr to line numbers         */
+  unsigned short s_nreloc;   /* number of relocation entries     */
+  unsigned short s_nlnno;    /* number of line number entries    */
+  unsigned long  s_flags;    /* flags                            */
+} SCNHDR;
+#pragma pack(pop)
+
+typedef struct _SYMBOLFILE_HEADER {
+  unsigned long SymbolsOffset;
+  unsigned long SymbolsLength;
+  unsigned long StringsOffset;
+  unsigned long StringsLength;
+} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
+
+typedef struct _STAB_ENTRY {
+  unsigned long n_strx;         /* index into string table of name */
+  unsigned char n_type;         /* type of symbol */
+  unsigned char n_other;        /* misc info (usually empty) */
+  unsigned short n_desc;        /* description field */
+  unsigned long n_value;        /* value of symbol */
+} STAB_ENTRY, *PSTAB_ENTRY;
+
+#define N_FUN 0x24
+#define N_SLINE 0x44
+#define N_SO 0x64
+
+/* COFF symbol table */
+
+#define E_SYMNMLEN     8       /* # characters in a symbol name        */
+#define E_FILNMLEN     14      /* # characters in a file name          */
+#define E_DIMNUM       4       /* # array dimensions in auxiliary entry */
+
+#define N_BTMASK       (0xf)
+#define N_TMASK                (0x30)
+#define N_BTSHFT       (4)
+#define N_TSHIFT       (2)
+
+/* derived types, in e_type */
+#define DT_NON         (0)     /* no derived type */
+#define DT_PTR         (1)     /* pointer */
+#define DT_FCN         (2)     /* function */
+#define DT_ARY         (3)     /* array */
+
+#define BTYPE(x)       ((x) & N_BTMASK)
+
+#define ISPTR(x)       (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
+#define ISFCN(x)       (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
+#define ISARY(x)       (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
+#define ISTAG(x)       ((x)==C_STRTAG||(x)==C_UNTAG||(x)==C_ENTAG)
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+
+#define C_EFCN         0xff    /* physical end of function     */
+#define C_NULL         0
+#define C_AUTO         1       /* automatic variable           */
+#define C_EXT          2       /* external symbol              */
+#define C_STAT         3       /* static                       */
+#define C_REG          4       /* register variable            */
+#define C_EXTDEF       5       /* external definition          */
+#define C_LABEL                6       /* label                        */
+#define C_ULABEL       7       /* undefined label              */
+#define C_MOS          8       /* member of structure          */
+#define C_ARG          9       /* function argument            */
+#define C_STRTAG       10      /* structure tag                */
+#define C_MOU          11      /* member of union              */
+#define C_UNTAG                12      /* union tag                    */
+#define C_TPDEF                13      /* type definition              */
+#define C_USTATIC      14      /* undefined static             */
+#define C_ENTAG                15      /* enumeration tag              */
+#define C_MOE          16      /* member of enumeration        */
+#define C_REGPARM      17      /* register parameter           */
+#define C_FIELD                18      /* bit field                    */
+#define C_AUTOARG      19      /* auto argument                */
+#define C_LASTENT      20      /* dummy entry (end of block)   */
+#define C_BLOCK                100     /* ".bb" or ".eb"               */
+#define C_FCN          101     /* ".bf" or ".ef"               */
+#define C_EOS          102     /* end of structure             */
+#define C_FILE         103     /* file name                    */
+#define C_LINE         104     /* line # reformatted as symbol table entry */
+#define C_ALIAS                105     /* duplicate tag                */
+#define C_HIDDEN       106     /* ext symbol in dmert public lib */
+
+#pragma pack(push,1)
+typedef struct _COFF_SYMENT
+{
+  union
+    {
+      char e_name[E_SYMNMLEN];
+      struct
+        {
+          unsigned long e_zeroes;
+          unsigned long e_offset;
+        }
+      e;
+    }
+  e;
+  unsigned long e_value;
+  short e_scnum;
+  unsigned short e_type;
+  unsigned char e_sclass;
+  unsigned char e_numaux;
+} COFF_SYMENT, *PCOFF_SYMENT;
+#pragma pack(pop)
+
+typedef struct _ROSSYM_ENTRY {
+  ULONG_PTR Address;
+  ULONG FunctionOffset;
+  ULONG FileOffset;
+  ULONG SourceLine;
+} ROSSYM_ENTRY, *PROSSYM_ENTRY;
+
+#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1))
+
+extern char*
+convert_path(const char* origpath);
+
+extern void*
+load_file ( const char* file_name, size_t* file_size );
+
+#endif/*RSYM_H*/
diff --git a/reactos/tools/rsym_common.c b/reactos/tools/rsym_common.c
new file mode 100644 (file)
index 0000000..875463f
--- /dev/null
@@ -0,0 +1,62 @@
+/* rsym_common.c */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "rsym.h"
+
+char*
+convert_path ( const char* origpath )
+{
+       char* newpath;
+       int i;
+
+       newpath = strdup(origpath);
+
+       i = 0;
+       while (newpath[i] != 0)
+       {
+#ifdef UNIX_PATHS
+               if (newpath[i] == '\\')
+               {
+                       newpath[i] = '/';
+               }
+#else
+#ifdef DOS_PATHS
+               if (newpath[i] == '/')
+               {
+                       newpath[i] = '\\';
+               }
+#endif
+#endif
+               i++;
+       }
+       return(newpath);
+}
+
+void*
+load_file ( const char* file_name, size_t* file_size )
+{
+       FILE* f;
+       void* FileData = NULL;
+
+       f = fopen ( file_name, "rb" );
+       if (f != NULL)
+       {
+               fseek(f, 0L, SEEK_END);
+               *file_size = ftell(f);
+               fseek(f, 0L, SEEK_SET);
+               FileData = malloc(*file_size);
+               if (FileData != NULL)
+               {
+                       if ( *file_size != fread(FileData, 1, *file_size, f) )
+                       {
+                               free(FileData);
+                               FileData = NULL;
+                       }
+               }
+               fclose(f);
+       }
+       return FileData;
+}
diff --git a/reactos/tools/tools-check.c b/reactos/tools/tools-check.c
new file mode 100644 (file)
index 0000000..8452a26
--- /dev/null
@@ -0,0 +1,32 @@
+#include "tools-check.h"\r
+\r
+/*\r
+ * - Binutils older than 2003/10/01 have broken windres which can't handle\r
+ *   icons with alpha channel.\r
+ * - Binutils between 2004/09/02 and 2004/10/08 have broken handling of\r
+ *   forward exports in dlltool.\r
+ */\r
+\r
+#if (BINUTILS_VERSION_DATE >= 20040902 && BINUTILS_VERSION_DATE <= 20041008) || \\r
+    (BINUTILS_VERSION_DATE < 20031001)\r
+#error "Due to technical reasons your binutils version can't be used to" \\r
+       "build ReactOS. Please consider upgrading to newer version. See" \\r
+       "www.mingw.org for details."\r
+#endif\r
+\r
+/*\r
+ * GCC 3.3.1 is lowest allowed version. Older versions have various problems\r
+ * with C++ code.\r
+ */\r
+\r
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) || \\r
+    (__GNUC__ < 3)\r
+#error "Due to technical reasons your GCC version can't be used to" \\r
+       "build ReactOS. Please consider upgrading to newer version. See" \\r
+       "www.mingw.org for details."\r
+#endif\r
+\r
+/*\r
+ * FIXME: GCC 3.4.1 has broken headers which cause Explorer to not build.\r
+ * We should warn in this case...maybe add check for the broken headers?\r
+ */\r
diff --git a/reactos/tools/tools-check.mak b/reactos/tools/tools-check.mak
new file mode 100644 (file)
index 0000000..89e3b3a
--- /dev/null
@@ -0,0 +1,23 @@
+PATH_TO_TOP = ..\r
+include $(PATH_TO_TOP)/rules.mak\r
+\r
+#\r
+# Get the binutils version\r
+#\r
+# The "ld -v" output can be in either of these two formats:\r
+#    "GNU ld version 050113 20050113" (nightly build)\r
+#    "GNU ld version 2.15.94 20050118" (official release)\r
+#    \r
+\r
+BINUTILS_VERSION_DATE=$(word 5,$(shell $(PREFIX)ld -v))\r
+\r
+all: \r
+ifeq ($(HOST),mingw32-linux)\r
+       @echo "#define BINUTILS_VERSION_DATE $(BINUTILS_VERSION_DATE)" > tools-check.h\r
+endif\r
+ifeq ($(HOST),mingw32-windows)\r
+       @echo #define BINUTILS_VERSION_DATE $(BINUTILS_VERSION_DATE) > tools-check.h\r
+endif\r
+       $(HOST_CC) -c tools-check.c -o tools-check.temp\r
+       $(RM) tools-check.temp\r
+       $(RM) tools-check.h\r
index 725a261..27b6557 100644 (file)
@@ -27,7 +27,8 @@ RSYM_TARGET = \
        $(EXEPREFIX)$(RSYM_OUT_)rsym$(EXEPOSTFIX)
 
 RSYM_SOURCES = \
-       $(RSYM_BASE_)rsym.c
+       $(RSYM_BASE_)rsym.c \
+       $(RSYM_BASE_)rsym_common.c
 
 RSYM_OBJECTS = \
        $(addprefix $(INTERMEDIATE_), $(RSYM_SOURCES:.c=.o))
@@ -47,6 +48,10 @@ $(RSYM_INT_)rsym.o: $(RSYM_BASE_)rsym.c | $(RSYM_INT)
        $(ECHO_CC)
        ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@
 
+$(RSYM_INT_)rsym_common.o: $(RSYM_BASE_)rsym_common.c | $(RSYM_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(RSYM_HOST_CFLAGS) -c $< -o $@
+
 .PHONY: rsym_clean
 rsym_clean:
        -@$(rm) $(RSYM_TARGET) $(RSYM_OBJECTS) 2>$(NUL)
@@ -61,6 +66,7 @@ include tools/mkhive/mkhive.mak
 include tools/nci/nci.mak
 include tools/rbuild/rbuild.mak
 include tools/unicode/unicode.mak
+include tools/widl/widl.mak
 include tools/winebuild/winebuild.mak
 include tools/wmc/wmc.mak
 include tools/wpp/wpp.mak
index dd3c924..1c85b24 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "wine/unicode.h"
 
+typedef unsigned char uchar;
+
 /* get the decomposition of a Unicode char */
 int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen )
 {
@@ -256,25 +258,25 @@ int wine_cp_mbstowcs( const union cptable *table, int flags,
     {
         if (flags & MB_ERR_INVALID_CHARS)
         {
-            if (check_invalid_chars_sbcs( &table->sbcs, src, srclen )) return -2;
+            if (check_invalid_chars_sbcs( &table->sbcs, (const uchar*)src, srclen )) return -2;
         }
         if (!(flags & MB_COMPOSITE))
         {
             if (!dstlen) return srclen;
-            return mbstowcs_sbcs( &table->sbcs, src, srclen, dst, dstlen );
+            return mbstowcs_sbcs( &table->sbcs, (const uchar*)src, srclen, dst, dstlen );
         }
-        return mbstowcs_sbcs_decompose( &table->sbcs, src, srclen, dst, dstlen );
+        return mbstowcs_sbcs_decompose( &table->sbcs, (const uchar*)src, srclen, dst, dstlen );
     }
     else /* mbcs */
     {
         if (flags & MB_ERR_INVALID_CHARS)
         {
-            if (check_invalid_chars_dbcs( &table->dbcs, src, srclen )) return -2;
+            if (check_invalid_chars_dbcs( &table->dbcs, (const uchar*)src, srclen )) return -2;
         }
         if (!(flags & MB_COMPOSITE))
-            return mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
+            return mbstowcs_dbcs( &table->dbcs, (const uchar*)src, srclen, dst, dstlen );
         else
-            return mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen );
+            return mbstowcs_dbcs_decompose( &table->dbcs, (const uchar*)src, srclen, dst, dstlen );
     }
 }
 
index 9f94aa1..6d3926f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <limits.h>
 #include <stdio.h>
+#include <ctype.h>
 
 #include "wine/unicode.h"
 
index 68be134..aed4303 100644 (file)
@@ -196,7 +196,7 @@ static int wcstombs_sbcs_slow( const struct sbcs_table *table, int flags,
     int tmp;
     WCHAR composed;
 
-    if (!defchar) defchar = &table_default;
+    if (!defchar) defchar = (const char*)&table_default;
     if (!used) used = &tmp;  /* avoid checking on every char */
     *used = 0;
 
index 28d6751..3b14c38 100644 (file)
-ChangeLog\r
-2005-02-27 sedwards\r
-\r
-  tools/widl/y.tab.c\r
-  tools/widl/parser.y\r
-  tools/widl/widl.c\r
-  tools/widl/widl.h\r
-  tools/widl/server.c\r
-  tools/widl/typelib.c\r
-\r
-Merge in Winehq changes to reduce noise.\r
-  \r
-  tools/widl/server.h\r
-  tools/widl/client.h\r
-  tools/widl/proxy.h  \r
-\r
-Deleted unneeded headers.  \r
-    \r
-2005-02-26 ekohl\r
-  tools/widl/server.c\r
-\r
-Server stubs are void functions.\r
-Fix a warning in the server stub descriptor.\r
-\r
-\r
-2005-02-25 ekohl\r
-  tools/widl/client.c\r
-  tools/widl/header.c\r
-  tools/widl/header.h\r
-  tools/widl/server.c\r
-\r
-Support multiple interfaces per idl file.\r
-Support explicit binding handles.\r
-\r
-\r
-2005-02-24 ekohl\r
-  include/wine/rpcfc.h\r
-  tools/widl/client.c\r
-  tools/widl/header.c\r
-  tools/widl/parser.l\r
-  tools/widl/parser.y\r
-  tools/widl/server.c\r
-\r
-Support remaining basic types (float, double, small, wchar_t and handle_t).\r
+ChangeLog
+
+2005-04-03 ekohl
+
+   tools/widl/client.c
+   tools/widl/parser.l
+   tools/widl/parser.y
+   tools/widl/server.c
+   tools/widl/widltypes.h
+
+Support 'ref' and 'unique' attributes for pointers.
+
+2005-03-27 Jacek Caban (from WINE)
+
+  tools/widl/parser.y
+  tools/widl/y.tab.c
+
+Added handling of unsigned type
+
+2005-03-25 ekohl
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+Generate code without L-value casts. Fix remaining issues.
+
+2005-03-21 navaraf
+
+   tools/widl/client.c
+
+Fix a typo in write_function_stubs.
+
+2005-03-20 navaraf
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+Generate code without L-value casts.
+
+2005-03-20 ekohl
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+Improve error messages.
+Don't start counting the type_offset for each new fuction. It is a global offset.
+Use only basic types in type- and proc-strings (e.g. unsigned long -> long).
+
+
+2005-03-13 ekohl
+
+   tools/widl/server.c
+
+Remove debug printf().
+
+
+2005-03-13 jimtabor
+
+   tools/widl/write_msft.c
+
+Fixup *nix port, added include fcntl.h and unistd.h.
+
+
+2005-03-13 royce3
+
+   tools/widl/hash.c
+   tools/widl/Makefile
+   tools/widl/write_msft.c
+
+-Wall -Werror and fix warnings
+
+
+2005-03-13 ekohl
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+Implement [string] attribute for pointers to char and wchar_t.
+
+
+2005-03-12 ekohl
+
+   tools/widl/client.c
+   tools/widl/server.c
+
+Implement [in], [out] and [in, out] support for pointers to basic types.
+
+
+2005-03-10 ekohl
+
+   tools/widl/client.c
+   tools/widl/header.c
+   tools/widl/server.c
+   tools/widl/widl.c
+   tools/widl/widl.h
+
+Implement '-o' option. This is equivalent to MIDLs '/oldnames' option.
+
+
+2005-03-06 ekohl
+
+   tools/widl/client.c
+   tools/widl/header.c
+   tools/widl/header.h
+   tools/widl/server.c
+
+Support pointers to simple types as input arguments.
+
+
+2005-02-27 sedwards
+
+  tools/widl/y.tab.c
+  tools/widl/parser.y
+  tools/widl/widl.c
+  tools/widl/widl.h
+  tools/widl/server.c
+  tools/widl/typelib.c
+
+Merge in Winehq changes to reduce noise.
+
+  tools/widl/server.h
+  tools/widl/client.h
+  tools/widl/proxy.h  
+
+Deleted unneeded headers.
+
+2005-02-26 ekohl
+  tools/widl/server.c
+
+Server stubs are void functions.
+Fix a warning in the server stub descriptor.
+
+
+2005-02-25 ekohl
+  tools/widl/client.c
+  tools/widl/header.c
+  tools/widl/header.h
+  tools/widl/server.c
+
+Support multiple interfaces per idl file.
+Support explicit binding handles.
+
+
+2005-02-24 ekohl
+  include/wine/rpcfc.h
+  tools/widl/client.c
+  tools/widl/header.c
+  tools/widl/parser.l
+  tools/widl/parser.y
+  tools/widl/server.c
+
+Support remaining basic types (float, double, small, wchar_t and handle_t).
index 2716d53..b70896a 100644 (file)
@@ -36,7 +36,8 @@ CLEAN_FILES = *.o $(TARGET)
 \r
 HOST_CFLAGS = -DYYDEBUG=1 -DINT16=SHORT -D__USE_W32API \\r
               -I$(LIB_WPP_DIR) -I$(PATH_TO_TOP)/include/wine \\r
-              -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/w32api/include\r
+              -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/w32api/include \\r
+              -Werror -Wall\r
 \r
 %.o: %.c\r
        $(HOST_CC) $(HOST_CFLAGS) -c $< -o $@\r
index fc48625..1346529 100644 (file)
@@ -56,10 +56,31 @@ static int print_client( const char *format, ... )
 }\r
 \r
 \r
+static unsigned char\r
+get_base_type(unsigned char type)\r
+{\r
+\r
+    switch (type)\r
+    {\r
+    case RPC_FC_USHORT:\r
+        type = RPC_FC_SHORT;\r
+        break;\r
+\r
+    case RPC_FC_ULONG:\r
+        type = RPC_FC_LONG;\r
+        break;\r
+    }\r
+\r
+  return type;\r
+}\r
+\r
+\r
 static void write_procformatstring(type_t *iface)\r
 {\r
     func_t *func = iface->funcs;\r
     var_t *var;\r
+    unsigned int type_offset = 2;\r
+    int in_attr, out_attr;\r
 \r
     print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_client("{\n");\r
@@ -78,53 +99,51 @@ static void write_procformatstring(type_t *iface)
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
-                switch(var->type->type)\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                in_attr = is_attr(var->attrs, ATTR_IN);\r
+\r
+                /* set 'in' attribute if neither 'in' nor 'out' is set */\r
+                if (!out_attr && !in_attr)\r
+                    in_attr = 1;\r
+\r
+                if (var->ptr_level == 0)\r
                 {\r
-                case RPC_FC_BYTE:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_BYTE */\n", RPC_FC_BYTE);\r
-                    break;\r
-                case RPC_FC_CHAR:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_CHAR */\n", RPC_FC_CHAR);\r
-                    break;\r
-                case RPC_FC_WCHAR:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_WCHAR */\n", RPC_FC_WCHAR);\r
-                    break;\r
-                case RPC_FC_USHORT:\r
-                case RPC_FC_SHORT:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_USHORT */\n", RPC_FC_SHORT);\r
-                    break;\r
-                case RPC_FC_ULONG:\r
-                case RPC_FC_LONG:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_LONG */\n", RPC_FC_LONG);\r
-                    break;\r
-                case RPC_FC_HYPER:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_HYPER */\n", RPC_FC_HYPER);\r
-                    break;\r
-                case RPC_FC_IGNORE:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_IGNORE */\n", RPC_FC_IGNORE);\r
-                    break;\r
-                case RPC_FC_SMALL:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_SMALL */\n", RPC_FC_SMALL);\r
-                    break;\r
-                case RPC_FC_FLOAT:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_FLOAT */\n", RPC_FC_FLOAT);\r
-                    break;\r
-                case RPC_FC_DOUBLE:\r
-                    print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_client("0x%02x,    /* FC_DOUBLE */\n", RPC_FC_DOUBLE);\r
-                    break;\r
-                default:\r
-                    error("Unknown/unsupported type\n");\r
-                    return;\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        print_client("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                        print_client("0x%02x,    /* FC_<type> */\n", get_base_type(var->type->type));\r
+                    }\r
+                    else\r
+                    {\r
+                        error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                              __FUNCTION__,__LINE__, var->type->type);\r
+                        return;\r
+                    }\r
+                }\r
+                else if (var->ptr_level == 1)\r
+                {\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        if (in_attr & !out_attr)\r
+                            print_client("0x4d,    /* FC_IN_PARAM */\n");\r
+                        else if (!in_attr & out_attr)\r
+                            print_client("0x51,    /* FC_OUT_PARAM */\n");\r
+                        else if (in_attr & out_attr)\r
+                            print_client("0x50,    /* FC_IN_OUT_PARAM */\n");\r
+                        fprintf(client, "#ifndef _ALPHA_\n");\r
+                        print_client("0x01,\n");\r
+                        fprintf(client, "#else\n");\r
+                        print_client("0x02,\n");\r
+                        fprintf(client, "#endif\n");\r
+                        print_client("NdrFcShort(0x%x),\n", type_offset);\r
+                        type_offset += 4;\r
+                    }\r
+                    else\r
+                    {\r
+                        error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                              __FUNCTION__,__LINE__, var->type->type);\r
+                        return;\r
+                    }\r
                 }\r
 \r
                 var = PREV_LINK(var);\r
@@ -138,58 +157,16 @@ static void write_procformatstring(type_t *iface)
             print_client("0x5b,    /* FC_END */\n");\r
             print_client("0x5c,    /* FC_PAD */\n");\r
         }\r
+        else if (is_base_type(var->type))\r
+        {\r
+            print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+            print_client("0x%02x,    /* FC_<type> */\n", get_base_type(var->type->type));\r
+        }\r
         else\r
         {\r
-            switch(var->type->type)\r
-            {\r
-            case RPC_FC_BYTE:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_BYTE */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_CHAR:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_CHAR */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_WCHAR:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_WCHAR */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_USHORT:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_USHORT */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_SHORT:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_SHORT */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_ULONG:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_ULONG */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_LONG:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_LONG */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_HYPER:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_HYPER */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_SMALL:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_SMALL */\n", RPC_FC_SMALL);\r
-                break;\r
-            case RPC_FC_FLOAT:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_FLOAT */\n", RPC_FC_FLOAT);\r
-                break;\r
-            case RPC_FC_DOUBLE:\r
-                print_client("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_client("0x%02x,    /* FC_DOUBLE */\n", RPC_FC_DOUBLE);\r
-                break;\r
-            default:\r
-                error("Unknown/unsupported type\n");\r
-                return;\r
-            }\r
+            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                  __FUNCTION__,__LINE__, var->type->type);\r
+            return;\r
         }\r
 \r
         func = PREV_LINK(func);\r
@@ -204,8 +181,14 @@ static void write_procformatstring(type_t *iface)
 }\r
 \r
 \r
-static void write_typeformatstring(void)\r
+static void write_typeformatstring(type_t *iface)\r
 {\r
+    func_t *func = iface->funcs;\r
+    var_t *var;\r
+    int out_attr;\r
+    int string_attr;\r
+    int ptr_attr, ref_attr, unique_attr;\r
+\r
     print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");\r
     print_client("{\n");\r
     indent++;\r
@@ -213,6 +196,76 @@ static void write_typeformatstring(void)
     print_client("{\n");\r
     indent++;\r
     print_client("NdrFcShort(0x0),\n");\r
+\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
+    {\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+                if (var->ptr_level > 1)\r
+                {\r
+                    error("Function '%s' argument '%s': Pointer level %d not supported!\n",\r
+                          func->def->name, var->name, var->ptr_level);\r
+                    return;\r
+                }\r
+\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+                    ref_attr = is_attr(var->attrs, ATTR_REF);\r
+                    unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+\r
+                    if (ptr_attr + ref_attr + unique_attr == 0)\r
+                        ref_attr = 1;\r
+\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        if (out_attr)\r
+                            print_client("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                        else\r
+                        {\r
+                            if (ptr_attr)\r
+                                print_client("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
+                            else if (ref_attr)\r
+                                print_client("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");\r
+                            else if (unique_attr)\r
+                                print_client("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");\r
+                        }\r
+\r
+                        if (string_attr)\r
+                        {\r
+                            if (var->type->type == RPC_FC_CHAR)\r
+                                print_client("0x%02x,          /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING);\r
+                            else if (var->type->type == RPC_FC_WCHAR)\r
+                                print_client("0x%02x,          /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING);\r
+                            else\r
+                            {\r
+                                error("%s: Invalid type!\n", __FUNCTION__);\r
+                                return;\r
+                            }\r
+                        }\r
+                        else\r
+                            print_client("0x%02x,          /* FC_<type> */\n", get_base_type(var->type->type));\r
+                        print_client("0x5c,          /* FC_PAD */\n");\r
+                    }\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+\r
+\r
+        func = PREV_LINK(func);\r
+    }\r
+\r
     print_client("0x0\n");\r
     indent--;\r
     print_client("}\n");\r
@@ -222,80 +275,275 @@ static void write_typeformatstring(void)
 }\r
 \r
 \r
-static void print_message_buffer_size(func_t *func)\r
+static void print_message_buffer_size(func_t *func, unsigned int *type_offset)\r
 {\r
     unsigned int alignment;\r
     int size;\r
     int last_size = -1;\r
+    int in_attr;\r
+    int out_attr;\r
+    int string_attr;\r
+    int nothing_printed = 1;\r
+    int ptr_attr, ref_attr, unique_attr;\r
     var_t *var;\r
+    unsigned int local_type_offset = *type_offset;\r
 \r
-    if (!func->args)\r
+    print_client("_StubMsg.BufferLength =");\r
+    if (func->args)\r
+    {\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
+        {\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            in_attr = is_attr(var->attrs, ATTR_IN);\r
+            string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+            /* set 'in' attribute if neither 'in' nor 'out' is found */\r
+            if (!out_attr && !in_attr)\r
+                in_attr = 1;\r
+\r
+            ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+            ref_attr = is_attr(var->attrs, ATTR_REF);\r
+            unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+\r
+            /* default to 'ref' attribute */\r
+            if (ptr_attr + ref_attr + unique_attr == 0)\r
+                ref_attr = 1;\r
+\r
+            if (!in_attr)\r
+                continue;\r
+\r
+            if (var->ptr_level == 1)\r
+            {\r
+                if (unique_attr)\r
+                {\r
+                    if (string_attr &&\r
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    {\r
+                        size = 16;\r
+                        alignment = 0;\r
+                        if (last_size != -1)\r
+                            fprintf(client, " +");\r
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
+                        nothing_printed = 0;\r
+                    }\r
+                    else\r
+                    {\r
+                        size = 8;\r
+                        alignment = 0;\r
+                        if (last_size != -1)\r
+                            fprintf(client, " +");\r
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
+                        nothing_printed = 0;\r
+                    }\r
+                }\r
+                else if (ref_attr)\r
+                {\r
+                    if (string_attr &&\r
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    {\r
+                        size = 12;\r
+                        alignment = 0;\r
+                        if (last_size != -1)\r
+                            fprintf(client, " +");\r
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
+                        nothing_printed = 0;\r
+                    }\r
+                    else\r
+                    {\r
+                        alignment = 0;\r
+                        switch (var->type->type)\r
+                        {\r
+                        case RPC_FC_BYTE:\r
+                        case RPC_FC_CHAR:\r
+                        case RPC_FC_SMALL:\r
+                            size = 1;\r
+                            alignment = 0;\r
+                            break;\r
+\r
+                        case RPC_FC_WCHAR:\r
+                        case RPC_FC_USHORT:\r
+                        case RPC_FC_SHORT:\r
+                            size = 2;\r
+                            if (last_size > 0 && last_size < 2)\r
+                                alignment += (2 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_ULONG:\r
+                        case RPC_FC_LONG:\r
+                        case RPC_FC_FLOAT:\r
+                            size = 4;\r
+                            if (last_size > 0 && last_size < 4)\r
+                                alignment += (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_HYPER:\r
+                        case RPC_FC_DOUBLE:\r
+                            size = 8;\r
+                            if (last_size > 0 && last_size < 4)\r
+                                alignment += (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_IGNORE:\r
+                            size = 0;\r
+                            break;\r
+\r
+                        default:\r
+                            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                                  __FUNCTION__,__LINE__, var->type->type);\r
+                            return;\r
+                        }\r
+\r
+                        if (last_size != -1)\r
+                            fprintf(client, " +");\r
+                        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
+                        nothing_printed = 0;\r
+                    }\r
+                }\r
+            }\r
+            else\r
+            {\r
+                alignment = 0;\r
+                switch (var->type->type)\r
+                {\r
+                case RPC_FC_BYTE:\r
+                case RPC_FC_CHAR:\r
+                case RPC_FC_SMALL:\r
+                    size = 1;\r
+                    alignment = 0;\r
+                    break;\r
+\r
+                case RPC_FC_WCHAR:\r
+                case RPC_FC_USHORT:\r
+                case RPC_FC_SHORT:\r
+                    size = 2;\r
+                    if (last_size > 0 && last_size < 2)\r
+                        alignment += (2 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_ULONG:\r
+                case RPC_FC_LONG:\r
+                case RPC_FC_FLOAT:\r
+                    size = 4;\r
+                    if (last_size > 0 && last_size < 4)\r
+                        alignment += (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_HYPER:\r
+                case RPC_FC_DOUBLE:\r
+                    size = 8;\r
+                    if (last_size > 0 && last_size < 4)\r
+                        alignment += (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_IGNORE:\r
+                    size = 0;\r
+                    break;\r
+\r
+                default:\r
+                    error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                          __FUNCTION__,__LINE__, var->type->type);\r
+                    return;\r
+                }\r
+\r
+                if (last_size != -1)\r
+                    fprintf(client, " +");\r
+                fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
+                nothing_printed = 0;\r
+            }\r
+\r
+            last_size = size;\r
+        }\r
+    }\r
+\r
+    if (nothing_printed)\r
     {\r
         fprintf(client, " 0U");\r
-        return;\r
     }\r
+    fprintf(client, ";\n");\r
 \r
-    var = func->args;\r
-    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
-    while (var)\r
+    /* get string size */\r
+    if (func->args)\r
     {\r
-        alignment = 0;\r
-        switch (var->type->type)\r
+        nothing_printed = 0;\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
         {\r
-        case RPC_FC_BYTE:\r
-        case RPC_FC_CHAR:\r
-        case RPC_FC_SMALL:\r
-            size = 1;\r
-            alignment = 0;\r
-            break;\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            in_attr = is_attr(var->attrs, ATTR_IN);\r
+            string_attr = is_attr(var->attrs, ATTR_STRING);\r
 \r
-        case RPC_FC_WCHAR:\r
-        case RPC_FC_USHORT:\r
-        case RPC_FC_SHORT:\r
-            size = 2;\r
-            if (last_size != -1 && last_size < 2)\r
-                alignment += (2 - last_size);\r
-            break;\r
+            /* set 'in' attribute if neither 'in' nor 'out' is found */\r
+            if (!out_attr && !in_attr)\r
+                in_attr = 1;\r
 \r
-        case RPC_FC_ULONG:\r
-        case RPC_FC_LONG:\r
-        case RPC_FC_FLOAT:\r
-            size = 4;\r
-            if (last_size != -1 && last_size < 4)\r
-                alignment += (4 - last_size);\r
-            break;\r
+            ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+            ref_attr = is_attr(var->attrs, ATTR_REF);\r
+            unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
 \r
-        case RPC_FC_HYPER:\r
-        case RPC_FC_DOUBLE:\r
-            size = 8;\r
-            if (last_size != -1 && last_size < 4)\r
-                alignment += (4 - last_size);\r
-            break;\r
+            /* default to 'ref' attribute */\r
+            if (ptr_attr + ref_attr + unique_attr == 0)\r
+                ref_attr = 1;\r
 \r
-        case RPC_FC_IGNORE:\r
-            size = 0;\r
-            break;\r
+            if (in_attr)\r
+            {\r
+                if (var->ptr_level == 1 &&\r
+                    string_attr &&\r
+                    (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                {\r
+                    if (ptr_attr)\r
+                    {\r
+                        /* FIXME: not supported yet */\r
+                    }\r
+                    if (ref_attr)\r
+                    {\r
+                        print_client("NdrConformantStringBufferSize(\n");\r
+                        indent++;\r
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                     local_type_offset + 2);\r
+                        nothing_printed = 1;\r
+                        indent--;\r
+                    }\r
+                    else if (unique_attr)\r
+                    {\r
+                        print_client("NdrPointerBufferSize(\n");\r
+                        indent++;\r
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n",\r
+                                     local_type_offset);\r
+                        nothing_printed = 1;\r
+                        indent--;\r
+                    }\r
+                }\r
+            }\r
 \r
-        default:\r
-            error("Unknown/unsupported type!");\r
+            /* calculate the next type offset */\r
+            if (var->ptr_level == 1)\r
+            {\r
+                local_type_offset += 4;\r
+            }\r
         }\r
 \r
-        if (last_size != -1)\r
-            fprintf(client, " +");\r
-        fprintf(client, " %dU", (size == 0) ? 0 : size + alignment);\r
-\r
-        last_size = size;\r
-\r
-        var = PREV_LINK(var);\r
+        if (nothing_printed)\r
+            fprintf(client, "\n");\r
     }\r
 }\r
 \r
 \r
-static void marshall_arguments(func_t *func)\r
+static void marshall_in_arguments(func_t *func, unsigned int *type_offset)\r
 {\r
     unsigned int alignment;\r
     unsigned int size;\r
     unsigned int last_size = 0;\r
+    int in_attr;\r
+    int out_attr;\r
+    int string_attr;\r
+    int ptr_attr, ref_attr, unique_attr;\r
     var_t *var;\r
 \r
     if (!func->args)\r
@@ -303,62 +551,400 @@ static void marshall_arguments(func_t *func)
 \r
     var = func->args;\r
     while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
-    while (var)\r
+    for (; var; var = PREV_LINK(var))\r
+    {\r
+        out_attr = is_attr(var->attrs, ATTR_OUT);\r
+        in_attr = is_attr(var->attrs, ATTR_IN);\r
+        string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+        /* set 'in' attribute if neither 'in' nor 'out' is set */\r
+        if (!out_attr && !in_attr)\r
+            in_attr = 1;\r
+\r
+        if (in_attr)\r
+        {\r
+            if (var->ptr_level > 1)\r
+            {\r
+                error("Function '%s' argument '%s': Pointer level %d not supported!\n",\r
+                      func->def->name, var->name, var->ptr_level);\r
+                return;\r
+            }\r
+\r
+            if (var->ptr_level == 1)\r
+            {\r
+                ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+                ref_attr = is_attr(var->attrs, ATTR_REF);\r
+                unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+                if (ptr_attr + ref_attr + unique_attr == 0)\r
+                    ref_attr = 1;\r
+\r
+                if (ref_attr)\r
+                {\r
+                    if (string_attr &&\r
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    {\r
+                        print_client("NdrConformantStringMarshall(\n");\r
+                        indent++;\r
+                        print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                        print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n", *type_offset + 2);\r
+                        indent--;\r
+                        fprintf(client, "\n");\r
+                    }\r
+                    else\r
+                    {\r
+                        alignment = 0;\r
+                        switch (var->type->type)\r
+                        {\r
+                        case RPC_FC_BYTE:\r
+                        case RPC_FC_CHAR:\r
+                        case RPC_FC_SMALL:\r
+                            size = 1;\r
+                            alignment = 0;\r
+                            break;\r
+\r
+                        case RPC_FC_WCHAR:\r
+                        case RPC_FC_USHORT:\r
+                        case RPC_FC_SHORT:\r
+                            size = 2;\r
+                            if (last_size > 0 && last_size < 2)\r
+                                alignment = (2 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_ULONG:\r
+                        case RPC_FC_LONG:\r
+                        case RPC_FC_FLOAT:\r
+                            size = 4;\r
+                            if (last_size > 0 && last_size < 4)\r
+                                alignment = (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_HYPER:\r
+                        case RPC_FC_DOUBLE:\r
+                            size = 8;\r
+                            if (last_size > 0 && last_size < 4)\r
+                                alignment = (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_IGNORE:\r
+                            size = 0;\r
+                            break;\r
+\r
+                        default:\r
+                            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                                  __FUNCTION__,__LINE__, var->type->type);\r
+                            return;\r
+                        }\r
+\r
+                        if (size != 0)\r
+                        {\r
+                            if (alignment != 0)\r
+                                print_client("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                            print_client("*((");\r
+                            write_type(client, var->type, NULL, var->tname);\r
+                            fprintf(client, " __RPC_FAR*)_StubMsg.Buffer) = ");\r
+                            if (var->ptr_level == 1)\r
+                                fprintf(client, "*");\r
+                            write_name(client, var);\r
+                            fprintf(client, ";\n");\r
+                            print_client("_StubMsg.Buffer += sizeof(");\r
+                            write_type(client, var->type, NULL, var->tname);\r
+                            fprintf(client, ");\n");\r
+                            fprintf(client, "\n");\r
+\r
+                            last_size = size;\r
+                        }\r
+                    }\r
+                }\r
+                else if (unique_attr)\r
+                {\r
+                    print_client("NdrPointerMarshall(\n");\r
+                    indent++;\r
+                    print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                    print_client("(unsigned char __RPC_FAR *)%s,\n", var->name);\r
+                    print_client("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u]);\n", *type_offset);\r
+                    indent--;\r
+                    fprintf(client, "\n");\r
+                }\r
+            }\r
+            else\r
+            {\r
+                alignment = 0;\r
+                switch (var->type->type)\r
+                {\r
+                case RPC_FC_BYTE:\r
+                case RPC_FC_CHAR:\r
+                case RPC_FC_SMALL:\r
+                    size = 1;\r
+                    alignment = 0;\r
+                    break;\r
+\r
+                case RPC_FC_WCHAR:\r
+                case RPC_FC_USHORT:\r
+                case RPC_FC_SHORT:\r
+                    size = 2;\r
+                    if (last_size > 0 && last_size < 2)\r
+                        alignment = (2 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_ULONG:\r
+                case RPC_FC_LONG:\r
+                case RPC_FC_FLOAT:\r
+                    size = 4;\r
+                    if (last_size > 0 && last_size < 4)\r
+                        alignment = (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_HYPER:\r
+                case RPC_FC_DOUBLE:\r
+                    size = 8;\r
+                    if (last_size > 0 && last_size < 4)\r
+                        alignment = (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_IGNORE:\r
+                    size = 0;\r
+                    break;\r
+\r
+                default:\r
+                    error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                          __FUNCTION__,__LINE__, var->type->type);\r
+                    return;\r
+                }\r
+\r
+                if (size != 0)\r
+                {\r
+                    if (alignment != 0)\r
+                        print_client("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                    print_client("*((");\r
+                    write_type(client, var->type, NULL, var->tname);\r
+                    fprintf(client, " __RPC_FAR*)_StubMsg.Buffer) = ");\r
+                    if (var->ptr_level == 1)\r
+                        fprintf(client, "*");\r
+                    write_name(client, var);\r
+                    fprintf(client, ";\n");\r
+                    print_client("_StubMsg.Buffer += sizeof(");\r
+                    write_type(client, var->type, NULL, var->tname);\r
+                    fprintf(client, ");\n");\r
+                    fprintf(client, "\n");\r
+\r
+                    last_size = size;\r
+                }\r
+            }\r
+        }\r
+\r
+        /* calculate the next type offset */\r
+        if (var->ptr_level == 1)\r
+        {\r
+            *type_offset += 4;\r
+        }\r
+    }\r
+}\r
+\r
+\r
+static void unmarshall_out_arguments(func_t *func)\r
+{\r
+    unsigned int alignment;\r
+    unsigned int size;\r
+    unsigned int last_size = 0;\r
+    int out_attr;\r
+    var_t *var;\r
+    var_t *def;\r
+\r
+    def = func->def;\r
+\r
+    /* unmarshall the out arguments */\r
+    if (func->args)\r
+    {\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
+        {\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            if (!out_attr)\r
+                continue;\r
+\r
+            if (var->ptr_level > 1)\r
+            {\r
+                error("Function '%s' argument '%s': Pointer level %d not supported!\n",\r
+                      func->def->name, var->name, var->ptr_level);\r
+                return;\r
+            }\r
+\r
+            alignment = 0;\r
+            switch (var->type->type)\r
+            {\r
+            case RPC_FC_BYTE:\r
+            case RPC_FC_CHAR:\r
+            case RPC_FC_SMALL:\r
+                size = 1;\r
+                alignment = 0;\r
+                break;\r
+\r
+            case RPC_FC_WCHAR:\r
+            case RPC_FC_USHORT:\r
+            case RPC_FC_SHORT:\r
+                size = 2;\r
+                if (last_size > 0 && last_size < 2)\r
+                    alignment = (2 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_ULONG:\r
+            case RPC_FC_LONG:\r
+            case RPC_FC_FLOAT:\r
+                size = 4;\r
+                if (last_size > 0 && last_size < 4)\r
+                    alignment = (4 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_HYPER:\r
+            case RPC_FC_DOUBLE:\r
+                size = 8;\r
+                if (last_size > 0 && last_size < 4)\r
+                    alignment = (4 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_IGNORE:\r
+                size = 0;\r
+                break;\r
+\r
+            default:\r
+                error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                      __FUNCTION__,__LINE__, var->type->type);\r
+                return;\r
+            }\r
+\r
+            if (size != 0)\r
+            {\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    fprintf(client, "\n");\r
+                    if (alignment != 0)\r
+                        print_client("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                    print_client("*");\r
+                    write_name(client, var);\r
+                    fprintf(client, " = *((");\r
+                    write_type(client, var->type, NULL, var->tname);\r
+                    fprintf(client, " __RPC_FAR *)_StubMsg.Buffer);\n");\r
+\r
+                    print_client("_StubMsg.Buffer += sizeof(");\r
+                    write_type(client, var->type, NULL, var->tname);\r
+                    fprintf(client, ");\n");\r
+                }\r
+\r
+                last_size = size;\r
+            }\r
+        }\r
+    }\r
+\r
+    /* unmarshall return value */\r
+    if (!is_void(def->type, NULL))\r
     {\r
         alignment = 0;\r
-        switch (var->type->type)\r
+        switch (def->type->type)\r
         {\r
         case RPC_FC_BYTE:\r
         case RPC_FC_CHAR:\r
         case RPC_FC_SMALL:\r
-            size = 1;\r
-            alignment = 0;\r
-            break;\r
-\r
         case RPC_FC_WCHAR:\r
         case RPC_FC_USHORT:\r
         case RPC_FC_SHORT:\r
-            size = 2;\r
-            if (last_size != 0 && last_size < 2)\r
-                alignment = (2 - last_size);\r
-            break;\r
-\r
         case RPC_FC_ULONG:\r
         case RPC_FC_LONG:\r
         case RPC_FC_FLOAT:\r
             size = 4;\r
-            if (last_size != 0 && last_size < 4)\r
+            if (last_size > 0 && last_size < 4)\r
                 alignment = (4 - last_size);\r
             break;\r
 \r
         case RPC_FC_HYPER:\r
         case RPC_FC_DOUBLE:\r
             size = 8;\r
-            if (last_size != 0 && last_size < 4)\r
+            if (last_size > 0 && last_size < 4)\r
                 alignment = (4 - last_size);\r
             break;\r
 \r
-        case RPC_FC_IGNORE:\r
-            size = 0;\r
-            break;\r
-\r
         default:\r
-            error("Unknown/unsupported type!");\r
+            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                  __FUNCTION__,__LINE__, var->type->type);\r
+            return;\r
         }\r
 \r
-        if (size != 0)\r
+       fprintf(client, "\n");\r
+       if (alignment != 0)\r
+           print_client("_StubMsg.Buffer += %u;\n", alignment);\r
+       print_client("_RetVal = *((");\r
+       write_type(client, def->type, def, def->tname);\r
+       fprintf(client, " __RPC_FAR *)_StubMsg.Buffer);\n");\r
+\r
+       print_client("_StubMsg.Buffer += sizeof(");\r
+       write_type(client, def->type, def, def->tname);\r
+       fprintf(client, ");\n");\r
+    }\r
+}\r
+\r
+\r
+static void check_pointers(func_t *func)\r
+{\r
+    var_t *var;\r
+    int ptr_attr;\r
+    int ref_attr;\r
+    int unique_attr;\r
+\r
+    if (!func->args)\r
+        return;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+        ref_attr = is_attr(var->attrs, ATTR_REF);\r
+        unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+\r
+        if (var->ptr_level == 0)\r
         {\r
-            if (alignment != 0)\r
-                print_client("_StubMsg.Buffer += %u;\n", alignment);\r
-\r
-            print_client("*((");\r
-            write_type(client, var->type, var, var->tname);\r
-            fprintf(client, " __RPC_FAR*)_StubMsg.Buffer)++ = ");\r
-            write_name(client, var);\r
-            fprintf(client, ";\n");\r
-            fprintf(client, "\n");\r
+            if (ptr_attr + ref_attr + unique_attr != 0)\r
+            {\r
+                error("The attributes [ptr], [ref] and [unique] can only be used for pointers!\n");\r
+                return;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            /* default to 'ref' attribute */\r
+            if (ptr_attr + ref_attr + unique_attr == 0)\r
+            {\r
+              ref_attr = 1;\r
+            }\r
 \r
-            last_size = size;\r
+            if (ptr_attr + ref_attr + unique_attr > 1)\r
+            {\r
+                error("The attributes [ptr], [ref] and [unique] are mutually exclusive!\n");\r
+                return;\r
+            }\r
+\r
+            if (var->ptr_level == 1)\r
+            {\r
+                if (ref_attr)\r
+                {\r
+                    print_client("if (!%s)\n", var->name);\r
+                    print_client("{\n");\r
+                    indent++;\r
+                    print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");\r
+                    indent--;\r
+                    print_client("}\n");\r
+                    fprintf(client, "\n");\r
+                }\r
+            }\r
+            else if (var->ptr_level > 1)\r
+            {\r
+                error("Pointer level %d not supported!\n", var->ptr_level);\r
+                return;\r
+            }\r
         }\r
 \r
         var = PREV_LINK(var);\r
@@ -366,6 +952,30 @@ static void marshall_arguments(func_t *func)
 }\r
 \r
 \r
+static int use_return_buffer(func_t *func)\r
+{\r
+    var_t *var;\r
+\r
+    if (!is_void(func->def->type, NULL))\r
+        return 1;\r
+\r
+    if (!func->args)\r
+        return 0;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        if (is_attr(var->attrs, ATTR_OUT))\r
+            return 1;\r
+\r
+        var = PREV_LINK(var);\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+\r
 static void write_function_stubs(type_t *iface)\r
 {\r
     char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);\r
@@ -375,6 +985,7 @@ static void write_function_stubs(type_t *iface)
     var_t* explicit_handle_var;\r
     int method_count = 0;\r
     unsigned int proc_offset = 0;\r
+    unsigned int type_offset = 2;\r
 \r
     while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
     while (func)\r
@@ -426,6 +1037,10 @@ static void write_function_stubs(type_t *iface)
         print_client("RPC_MESSAGE _RpcMessage;\n");\r
         print_client("MIDL_STUB_MESSAGE _StubMsg;\n");\r
         fprintf(client, "\n");\r
+\r
+        /* check pointers */\r
+        check_pointers(func);\r
+\r
         print_client("RpcTryFinally\n");\r
         print_client("{\n");\r
         indent++;\r
@@ -451,24 +1066,21 @@ static void write_function_stubs(type_t *iface)
         }\r
 \r
         /* emit the message buffer size */\r
-        print_client("_StubMsg.BufferLength =");\r
-        print_message_buffer_size(func);\r
-        fprintf(client, ";\n");\r
-\r
+        print_message_buffer_size(func, &type_offset);\r
 \r
         print_client("NdrGetBuffer(\n");\r
         indent++;\r
         print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
         print_client("_StubMsg.BufferLength,\n");\r
         if (implicit_handle || explicit_handle)\r
-            print_client("%_Handle);\n");\r
+            print_client("_Handle);\n");\r
         else\r
             print_client("%s__MIDL_AutoBindHandle);\n", iface->name);\r
         indent--;\r
         fprintf(client, "\n");\r
 \r
-        /* marshal arguments */\r
-        marshall_arguments(func);\r
+        /* marshal in arguments */\r
+        marshall_in_arguments(func, &type_offset);\r
 \r
         /* send/recieve message */\r
         print_client("NdrSendReceive(\n");\r
@@ -477,11 +1089,10 @@ static void write_function_stubs(type_t *iface)
         print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n");\r
         indent--;\r
 \r
-        /* unmarshal return value */\r
-        if (!is_void(def->type, NULL))\r
+        if (use_return_buffer(func))\r
         {\r
+            /* convert data representation */\r
             fprintf(client, "\n");\r
-\r
             print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");\r
             indent++;\r
             print_client("NdrConvert(\n");\r
@@ -489,11 +1100,9 @@ static void write_function_stubs(type_t *iface)
             print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
             print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);\r
             indent -= 2;\r
-            fprintf(client, "\n");\r
 \r
-            print_client("_RetVal = *((");\r
-            write_type(client, def->type, def, def->tname);\r
-            fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n");\r
+            /* unmarshal out arguments */\r
+            unmarshall_out_arguments(func);\r
         }\r
 \r
         /* update proc_offset */\r
@@ -503,7 +1112,19 @@ static void write_function_stubs(type_t *iface)
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
-                proc_offset += 2; /* FIXME */\r
+                switch (var->ptr_level)\r
+                {\r
+                case 0:\r
+                    if (is_base_type(var->type))\r
+                        proc_offset += 2;\r
+                    break;\r
+\r
+                case 1:\r
+                    if (is_base_type(var->type))\r
+                        proc_offset += 4;\r
+                    break;\r
+                }\r
+\r
                 var = PREV_LINK(var);\r
             }\r
         }\r
@@ -544,8 +1165,11 @@ static void write_function_stubs(type_t *iface)
 \r
 static void write_bindinghandledecl(type_t *iface)\r
 {\r
-    print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface->name);\r
-    fprintf(client, "\n");\r
+    if (!get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE))\r
+    {\r
+        print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface->name);\r
+        fprintf(client, "\n");\r
+    }\r
 }\r
 \r
 \r
@@ -567,9 +1191,9 @@ static void write_stubdescriptor(type_t *iface)
     print_client("MIDL_user_allocate,\n");\r
     print_client("MIDL_user_free,\n");\r
     if (implicit_handle)\r
-        print_client("&%s,\n", implicit_handle);\r
+        print_client("{&%s},\n", implicit_handle);\r
     else\r
-        print_client("&%s__MIDL_AutoBindHandle,\n", iface->name);\r
+        print_client("{&%s__MIDL_AutoBindHandle},\n", iface->name);\r
     print_client("0,\n");\r
     print_client("0,\n");\r
     print_client("0,\n");\r
@@ -614,8 +1238,12 @@ static void write_clientinterfacedecl(type_t *iface)
     print_client("0,\n");\r
     indent--;\r
     print_client("};\n");\r
-    print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",\r
-                 iface->name, LOWORD(ver), HIWORD(ver), iface->name);\r
+    if (old_names)\r
+       print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",\r
+                    iface->name, iface->name);\r
+    else\r
+       print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",\r
+                    iface->name, LOWORD(ver), HIWORD(ver), iface->name);\r
     fprintf(client, "\n");\r
 }\r
 \r
@@ -633,13 +1261,46 @@ static void write_formatdesc( const char *str )
 }\r
 \r
 \r
-static void write_formatstringsdecl(type_t *iface)\r
+static int get_type_format_string_size(type_t *iface)\r
 {\r
-    int byte_count = 1;\r
+    int size = 3;\r
     func_t *func;\r
     var_t *var;\r
 \r
-    print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
+    /* determine the proc format string size */\r
+    func = iface->funcs;\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
+    {\r
+        /* argument list size */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    if (is_base_type(var->type))\r
+                        size += 4;\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+        func = PREV_LINK(func);\r
+    }\r
+\r
+    return size;\r
+}\r
+\r
+\r
+static int get_proc_format_string_size(type_t *iface)\r
+{\r
+    int size = 1;\r
+    func_t *func;\r
+    var_t *var;\r
 \r
     /* determine the proc format string size */\r
     func = iface->funcs;\r
@@ -653,17 +1314,39 @@ static void write_formatstringsdecl(type_t *iface)
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
-                byte_count += 2; /* FIXME: determine real size */\r
+                switch (var->ptr_level)\r
+                {\r
+                case 0:\r
+                    if (is_base_type(var->type))\r
+                        size += 2;\r
+                    break;\r
+\r
+                case 1:\r
+                    if (is_base_type(var->type))\r
+                        size += 4;\r
+                    break;\r
+                }\r
+\r
                 var = PREV_LINK(var);\r
             }\r
         }\r
 \r
         /* return value size */\r
-        byte_count += 2; /* FIXME: determine real size */\r
+        size += 2;\r
         func = PREV_LINK(func);\r
     }\r
 \r
-    print_client("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
+    return size;\r
+}\r
+\r
+\r
+static void write_formatstringsdecl(type_t *iface)\r
+{\r
+    print_client("#define TYPE_FORMAT_STRING_SIZE %d\n",\r
+                 get_type_format_string_size(iface));\r
+\r
+    print_client("#define PROC_FORMAT_STRING_SIZE %d\n",\r
+                 get_proc_format_string_size(iface));\r
 \r
     fprintf(client, "\n");\r
     write_formatdesc("TYPE");\r
@@ -741,7 +1424,7 @@ void write_client(ifref_t *ifaces)
         fprintf(client, "\n");\r
 \r
         write_procformatstring(iface->iface);\r
-        write_typeformatstring();\r
+        write_typeformatstring(iface->iface);\r
 \r
         fprintf(client, "\n");\r
 \r
index 89822cc..8ee3098 100644 (file)
@@ -511,7 +511,7 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
   switch (PRIMARYLANGID(LANGIDFROMLCID(lcid)))
   {
   default:
-    fprintf(stderr, "Unknown lcid %lx, treating as latin-based, please report\n", lcid);
+    fprintf(stderr, "Unknown lcid %lx, treating as latin-based, please report\n", (long)lcid);
     /* .. Fall Through .. */
   case LANG_AFRIKAANS:  case LANG_ALBANIAN:   case LANG_ARMENIAN:
   case LANG_ASSAMESE:   case LANG_AZERI:      case LANG_BASQUE:
index 3a3345b..ec5c8c7 100644 (file)
@@ -45,6 +45,18 @@ static void indent(int delta)
   if (delta > 0) indentation += delta;
 }
 
+int is_base_type(type_t *t)
+{
+  return (t->type == RPC_FC_BYTE || t->type == RPC_FC_CHAR ||
+          t->type == RPC_FC_SMALL || t->type == RPC_FC_USMALL ||
+          t->type == RPC_FC_WCHAR || t->type == RPC_FC_SHORT ||
+          t->type == RPC_FC_USHORT || t->type == RPC_FC_LONG ||
+          t->type == RPC_FC_ULONG || t->type == RPC_FC_FLOAT ||
+          t->type == RPC_FC_HYPER || t->type == RPC_FC_DOUBLE ||
+          t->type == RPC_FC_ENUM16 || t->type == RPC_FC_ENUM32 ||
+          t->type == RPC_FC_IGNORE);
+}
+
 int is_attr(attr_t *a, enum attr_type t)
 {
   while (a) {
@@ -839,8 +851,16 @@ void write_rpc_interface(type_t *iface)
   {
     fprintf(header, "extern handle_t %s;\n", var);
   }
-  fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
-  fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
+  if (old_names)
+  {
+    fprintf(header, "extern RPC_IF_HANDLE %s_ClientIfHandle;\n", iface->name);
+    fprintf(header, "extern RPC_IF_HANDLE %s_ServerIfHandle;\n", iface->name);
+  }
+  else
+  {
+    fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
+    fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
+  }
   write_function_proto(iface);
   fprintf(header, "\n");
 
index 6d276c3..42243ff 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef __WIDL_HEADER_H
 #define __WIDL_HEADER_H
 
+extern int is_base_type(type_t *t);
 extern int is_attr(attr_t *a, enum attr_type t);
 extern void *get_attrp(attr_t *a, enum attr_type t);
 extern unsigned long get_attrv(attr_t *a, enum attr_type t);
index 419d757..6083b88 100644 (file)
@@ -4555,6 +4555,7 @@ static struct keyword {
        {"propput",                     tPROPPUT},\r
        {"propputref",                  tPROPPUTREF},\r
 /* ... */\r
+       {"ptr",                         tPTR},\r
        {"public",                      tPUBLIC},\r
 /* ... */\r
        {"readonly",                    tREADONLY},\r
@@ -4579,8 +4580,8 @@ static struct keyword {
 /* ... */\r
        {"transmit_as",                 tTRANSMITAS},\r
        {"typedef",                     tTYPEDEF},\r
-       {"union",                       tUNION},\r
 /* ... */\r
+       {"union",                       tUNION},\r
        {"unique",                      tUNIQUE},\r
        {"unsigned",                    tUNSIGNED},\r
 /* ... */\r
index f41af6b..72716b7 100644 (file)
@@ -275,6 +275,7 @@ static struct keyword {
        {"propput",                     tPROPPUT},
        {"propputref",                  tPROPPUTREF},
 /* ... */
+       {"ptr",                         tPTR},
        {"public",                      tPUBLIC},
 /* ... */
        {"readonly",                    tREADONLY},
@@ -299,8 +300,8 @@ static struct keyword {
 /* ... */
        {"transmit_as",                 tTRANSMITAS},
        {"typedef",                     tTYPEDEF},
-       {"union",                       tUNION},
 /* ... */
+       {"union",                       tUNION},
        {"unique",                      tUNIQUE},
        {"unsigned",                    tUNSIGNED},
 /* ... */
index 4d27f2f..a4b7edf 100644 (file)
@@ -162,6 +162,7 @@ static type_t std_uhyper = { "MIDL_uhyper" };
 %token tPOINTERDEFAULT
 %token tPROPERTIES
 %token tPROPGET tPROPPUT tPROPPUTREF
+%token tPTR
 %token tPUBLIC
 %token tREADONLY tREF
 %token tRESTRICTED
@@ -373,8 +374,10 @@ attribute:
        | tPROPGET                              { $$ = make_attr(ATTR_PROPGET); }
        | tPROPPUT                              { $$ = make_attr(ATTR_PROPPUT); }
        | tPROPPUTREF                           { $$ = make_attr(ATTR_PROPPUTREF); }
+       | tPTR                                  { $$ = make_attr(ATTR_PTR); }
        | tPUBLIC                               { $$ = make_attr(ATTR_PUBLIC); }
        | tREADONLY                             { $$ = make_attr(ATTR_READONLY); }
+       | tREF                                  { $$ = make_attr(ATTR_REF); }
        | tRESTRICTED                           { $$ = make_attr(ATTR_RESTRICTED); }
        | tRETVAL                               { $$ = make_attr(ATTR_RETVAL); }
        | tSIZEIS '(' m_exprs ')'               { $$ = make_attrp(ATTR_SIZEIS, $3); }
@@ -383,6 +386,7 @@ attribute:
        | tSWITCHIS '(' expr ')'                { $$ = make_attrp(ATTR_SWITCHIS, $3); }
        | tSWITCHTYPE '(' type ')'              { $$ = make_attrp(ATTR_SWITCHTYPE, type_ref($3)); }
        | tTRANSMITAS '(' type ')'              { $$ = make_attrp(ATTR_TRANSMITAS, type_ref($3)); }
+       | tUNIQUE                               { $$ = make_attr(ATTR_UNIQUE); }
        | tUUID '(' aUUID ')'                   { $$ = make_attrp(ATTR_UUID, $3); }
        | tV1ENUM                               { $$ = make_attr(ATTR_V1ENUM); }
        | tVARARG                               { $$ = make_attr(ATTR_VARARG); }
@@ -561,6 +565,8 @@ base_type: tBYTE                            { $$ = make_type(RPC_FC_BYTE, NULL); }
                                                  default: break;
                                                  }
                                                }
+       | tUNSIGNED                             { $$ = make_type(RPC_FC_ULONG, &std_int);
+                                                 $$->sign = -1; }
        | tFLOAT                                { $$ = make_type(RPC_FC_FLOAT, NULL); }
        | tDOUBLE                               { $$ = make_type(RPC_FC_DOUBLE, NULL); }
        | tBOOLEAN                              { $$ = make_type(RPC_FC_SMALL, &std_bool); }
index dca83ac..833c117 100644 (file)
@@ -61,10 +61,31 @@ static int print_server(const char *format, ...)
 }\r
 \r
 \r
+static unsigned char\r
+get_base_type(unsigned char type)\r
+{\r
+\r
+    switch (type)\r
+    {\r
+    case RPC_FC_USHORT:\r
+        type = RPC_FC_SHORT;\r
+        break;\r
+\r
+    case RPC_FC_ULONG:\r
+        type = RPC_FC_LONG;\r
+        break;\r
+    }\r
+\r
+  return type;\r
+}\r
+\r
+\r
 static void write_procformatstring(type_t *iface)\r
 {\r
     func_t *func = iface->funcs;\r
     var_t *var;\r
+    unsigned int type_offset = 2;\r
+    int in_attr, out_attr;\r
 \r
     print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");\r
     print_server("{\n");\r
@@ -83,58 +104,51 @@ static void write_procformatstring(type_t *iface)
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
-                switch(var->type->type)\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                in_attr = is_attr(var->attrs, ATTR_IN);\r
+\r
+                /* set 'in' attribute if neither 'in' nor 'out' is set */\r
+                if (!out_attr && !in_attr)\r
+                    in_attr = 1;\r
+\r
+                if (var->ptr_level == 0)\r
                 {\r
-                case RPC_FC_BYTE:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_BYTE */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_CHAR:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_CHAR */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_WCHAR:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_WCHAR */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_USHORT:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_USHORT */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_SHORT:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_SHORT */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_ULONG:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_ULONG */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_LONG:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_LONG */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_HYPER:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_HYPER */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_IGNORE:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_IGNORE */\n", var->type->type);\r
-                    break;\r
-                case RPC_FC_SMALL:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_SMALL */\n", RPC_FC_SMALL);\r
-                    break;\r
-                case RPC_FC_FLOAT:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_FLOAT */\n", RPC_FC_FLOAT);\r
-                    break;\r
-                case RPC_FC_DOUBLE:\r
-                    print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
-                    print_server("0x%02x,    /* FC_DOUBLE */\n", RPC_FC_DOUBLE);\r
-                    break;\r
-                default:\r
-                    error("Unknown/unsupported type\n");\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        print_server("0x4e,    /* FC_IN_PARAM_BASETYPE */\n");\r
+                        print_server("0x%02x,    /* FC_<type> */\n", get_base_type(var->type->type));\r
+                    }\r
+                    else\r
+                    {\r
+                        error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                              __FUNCTION__,__LINE__, var->type->type);\r
+                        return;\r
+                    }\r
+                }\r
+                else if (var->ptr_level == 1)\r
+                {\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        if (in_attr & !out_attr)\r
+                            print_server("0x4d,    /* FC_IN_PARAM */\n");\r
+                        else if (!in_attr & out_attr)\r
+                            print_server("0x51,    /* FC_OUT_PARAM */\n");\r
+                        else if (in_attr & out_attr)\r
+                            print_server("0x50,    /* FC_IN_OUT_PARAM */\n");\r
+                        fprintf(server, "#ifndef _ALPHA_\n");\r
+                        print_server("0x01,\n");\r
+                        fprintf(server, "#else\n");\r
+                        print_server("0x02,\n");\r
+                        fprintf(server, "#endif\n");\r
+                        print_server("NdrFcShort(0x%x),\n", type_offset);\r
+                        type_offset += 4;\r
+                    }\r
+                    else\r
+                    {\r
+                        error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                              __FUNCTION__,__LINE__, var->type->type);\r
+                        return;\r
+                    }\r
                 }\r
 \r
                 var = PREV_LINK(var);\r
@@ -148,57 +162,16 @@ static void write_procformatstring(type_t *iface)
             print_server("0x5b,    /* FC_END */\n");\r
             print_server("0x5c,    /* FC_PAD */\n");\r
         }\r
+        else if (is_base_type(var->type))\r
+        {\r
+            print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
+            print_server("0x%02x,    /* FC_<type> */\n", get_base_type(var->type->type));\r
+        }\r
         else\r
         {\r
-            switch(var->type->type)\r
-            {\r
-            case RPC_FC_BYTE:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_BYTE */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_CHAR:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_CHAR */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_WCHAR:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_WCHAR */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_USHORT:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_USHORT */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_SHORT:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_SHORT */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_ULONG:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_ULONG */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_LONG:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_LONG */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_HYPER:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_HYPER */\n", var->type->type);\r
-                break;\r
-            case RPC_FC_SMALL:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_SMALL */\n", RPC_FC_SMALL);\r
-                break;\r
-            case RPC_FC_FLOAT:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_FLOAT */\n", RPC_FC_FLOAT);\r
-                break;\r
-            case RPC_FC_DOUBLE:\r
-                print_server("0x53,    /* FC_RETURN_PARAM_BASETYPE */\n");\r
-                print_server("0x%02x,    /* FC_DOUBLE */\n", RPC_FC_DOUBLE);\r
-                break;\r
-            default:\r
-                error("Unknown/unsupported type\n");\r
-            }\r
+            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                  __FUNCTION__,__LINE__, var->type->type);\r
+            return;\r
         }\r
 \r
         func = PREV_LINK(func);\r
@@ -213,8 +186,14 @@ static void write_procformatstring(type_t *iface)
 }\r
 \r
 \r
-static void write_typeformatstring(void)\r
+static void write_typeformatstring(type_t *iface)\r
 {\r
+    func_t *func = iface->funcs;\r
+    var_t *var;\r
+    int out_attr;\r
+    int string_attr;\r
+    int ptr_attr, ref_attr, unique_attr;\r
+\r
     print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n");\r
     print_server("{\n");\r
     indent++;\r
@@ -222,6 +201,76 @@ static void write_typeformatstring(void)
     print_server("{\n");\r
     indent++;\r
     print_server("NdrFcShort(0x0),\n");\r
+\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
+    {\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+                if (var->ptr_level > 1)\r
+                {\r
+                    error("Function '%s' argument '%s': Pointer level %d not supported!\n",\r
+                          func->def->name, var->name, var->ptr_level);\r
+                    return;\r
+                }\r
+\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+                    ref_attr = is_attr(var->attrs, ATTR_REF);\r
+                    unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+\r
+                    if (ptr_attr + ref_attr + unique_attr == 0)\r
+                        ref_attr = 1;\r
+\r
+                    if (is_base_type(var->type))\r
+                    {\r
+                        if (out_attr)\r
+                            print_server("0x11, 0x0c,    /* FC_RP [allocated_on_stack] [simple_pointer] */\n");\r
+                        else\r
+                        {\r
+                            if (ptr_attr)\r
+                                print_server("0x14, 0x08,    /* FC_FP [simple_pointer] */\n");\r
+                            else if (ref_attr)\r
+                                print_server("0x11, 0x08,    /* FC_RP [simple_pointer] */\n");\r
+                            else if (unique_attr)\r
+                                print_server("0x12, 0x08,    /* FC_UP [simple_pointer] */\n");\r
+                        }\r
+\r
+                        if (string_attr)\r
+                        {\r
+                            if (var->type->type == RPC_FC_CHAR)\r
+                                print_server("0x%02x,          /* FC_C_CSTRING */\n", RPC_FC_C_CSTRING);\r
+                            else if (var->type->type == RPC_FC_WCHAR)\r
+                                print_server("0x%02x,          /* FC_C_WSTRING */\n", RPC_FC_C_WSTRING);\r
+                            else\r
+                            {\r
+                                error("%s: Invalid type!\n", __FUNCTION__);\r
+                                return;\r
+                            }\r
+                        }\r
+                        else\r
+                            print_server("0x%02x,          /* FC_<type> */\n", get_base_type(var->type->type));\r
+                        print_server("0x5c,          /* FC_PAD */\n");\r
+                    }\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+\r
+\r
+        func = PREV_LINK(func);\r
+    }\r
+\r
     print_server("0x0\n");\r
     indent--;\r
     print_server("}\n");\r
@@ -231,10 +280,81 @@ static void write_typeformatstring(void)
 }\r
 \r
 \r
-unsigned int get_required_buffer_size(type_t *type)\r
+static void print_message_buffer_size(func_t *func)\r
 {\r
-    switch(type->type)\r
+    unsigned int alignment = 0;\r
+    int size = 0;\r
+    int last_size = -1;\r
+    int in_attr;\r
+    int out_attr;\r
+    int string_attr;\r
+    int empty_line;\r
+    var_t *var;\r
+\r
+    fprintf(server, "\n");\r
+    print_server("_StubMsg.BufferLength =");\r
+    if (func->args)\r
     {\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
+        {\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            if (!out_attr)\r
+                continue;\r
+\r
+            alignment = 0;\r
+            switch (var->type->type)\r
+            {\r
+            case RPC_FC_BYTE:\r
+            case RPC_FC_CHAR:\r
+            case RPC_FC_SMALL:\r
+                size = 1;\r
+                alignment = 0;\r
+                break;\r
+\r
+            case RPC_FC_WCHAR:\r
+            case RPC_FC_USHORT:\r
+            case RPC_FC_SHORT:\r
+                size = 2;\r
+                if (last_size > 0 && last_size < 2)\r
+                    alignment += (2 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_ULONG:\r
+            case RPC_FC_LONG:\r
+            case RPC_FC_FLOAT:\r
+                size = 4;\r
+                if (last_size > 0 && last_size < 4)\r
+                    alignment += (4 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_HYPER:\r
+            case RPC_FC_DOUBLE:\r
+                size = 8;\r
+                if (last_size > 0 && last_size < 4)\r
+                    alignment += (4 - last_size);\r
+                break;\r
+\r
+            default:\r
+                error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                      __FUNCTION__,__LINE__, var->type->type);\r
+                return;\r
+            }\r
+\r
+            if (last_size != -1)\r
+                fprintf(server, " +");\r
+            fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);\r
+\r
+            last_size = size;\r
+        }\r
+    }\r
+\r
+    /* return value size */\r
+    if (!is_void(func->def->type, NULL))\r
+    {\r
+        switch(func->def->type->type)\r
+        {\r
         case RPC_FC_BYTE:\r
         case RPC_FC_SMALL:\r
         case RPC_FC_CHAR:\r
@@ -244,54 +364,397 @@ unsigned int get_required_buffer_size(type_t *type)
         case RPC_FC_ULONG:\r
         case RPC_FC_LONG:\r
         case RPC_FC_FLOAT:\r
-            return 4;\r
+            size = 4;\r
+            if (last_size > 0 && last_size < 4)\r
+                alignment += (4 - last_size);\r
+            break;\r
 \r
         case RPC_FC_HYPER:\r
         case RPC_FC_DOUBLE:\r
-            return 8;\r
-\r
-        case RPC_FC_IGNORE:\r
-            return 0;\r
+            size = 8;\r
+            if (last_size > 0 && last_size < 4)\r
+                alignment += (4 - last_size);\r
+            break;\r
 \r
         default:\r
-            error("Unknown/unsupported type: %s\n", type->name);\r
-            return 0;\r
+            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                  __FUNCTION__,__LINE__, func->def->type->type);\r
+            return;\r
+        }\r
+\r
+        if (last_size != -1)\r
+            fprintf(server, " +");\r
+\r
+        fprintf(server, " %dU", (size == 0) ? 0 : size + alignment);\r
+    }\r
+    fprintf(server, ";\n");\r
+\r
+    /* get string size */\r
+    if (func->args)\r
+    {\r
+        empty_line = 0;\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
+        {\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            in_attr = is_attr(var->attrs, ATTR_IN);\r
+            string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+            /* set 'in' attribute if neither 'in' nor 'out' is found */\r
+            if (!out_attr && !in_attr)\r
+                in_attr = 1;\r
+\r
+            if (var->ptr_level == 1 &&\r
+                string_attr &&\r
+                (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+            {\r
+                print_server("_StubMsg.BufferLength += 16;\n");\r
+                empty_line = 1;\r
+            }\r
+        }\r
+\r
+        if (empty_line)\r
+            fprintf(server, "\n");\r
     }\r
 }\r
 \r
 \r
-static void unmarshall_arguments(func_t *func)\r
+static void init_pointers (func_t *func)\r
+{\r
+    var_t *var;\r
+\r
+    if (!func->args)\r
+        return;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        if (var->ptr_level == 1)\r
+        {\r
+            print_server("(");\r
+            write_type(server, var->type, NULL, var->tname);\r
+            fprintf(server, " __RPC_FAR *)%s = 0;\n", var->name);\r
+        }\r
+        else if (var->ptr_level > 1)\r
+        {\r
+            error("Pointer level %d not supported!\n", var->ptr_level);\r
+            return;\r
+        }\r
+\r
+        var = PREV_LINK(var);\r
+    }\r
+    fprintf(server, "\n");\r
+}\r
+\r
+\r
+static void unmarshall_in_arguments(func_t *func, unsigned int *type_offset)\r
 {\r
     unsigned int alignment;\r
     unsigned int size;\r
     unsigned int last_size = 0;\r
     var_t *var;\r
+    int in_attr, out_attr;\r
+    int string_attr;\r
+    int ptr_attr, ref_attr, unique_attr;\r
 \r
     if (!func->args)\r
         return;\r
 \r
     var = func->args;\r
     while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
-    while (var)\r
+    for (; var; var = PREV_LINK(var))\r
+    {\r
+        out_attr = is_attr(var->attrs, ATTR_OUT);\r
+        in_attr = is_attr(var->attrs, ATTR_IN);\r
+        string_attr = is_attr(var->attrs, ATTR_STRING);\r
+\r
+        /* set 'in' attribute if neither 'in' nor 'out' is set */\r
+        if (!out_attr && !in_attr)\r
+            in_attr = 1;\r
+\r
+        if (in_attr)\r
+        {\r
+            if (var->ptr_level == 1)\r
+            {\r
+                ptr_attr = is_attr(var->attrs, ATTR_PTR);\r
+                ref_attr = is_attr(var->attrs, ATTR_REF);\r
+                unique_attr = is_attr(var->attrs, ATTR_UNIQUE);\r
+                if (ptr_attr + ref_attr + unique_attr == 0)\r
+                    ref_attr = 1;\r
+\r
+                if (ref_attr)\r
+                {\r
+                    if (string_attr &&\r
+                        (var->type->type == RPC_FC_CHAR || var->type->type == RPC_FC_WCHAR))\r
+                    {\r
+                        print_server("NdrConformantStringUnmarshall(\n");\r
+                        indent++;\r
+                        print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                        print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);\r
+                        print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset + 2);\r
+                        print_server("(unsigned char)0);\n");\r
+                        indent--;\r
+                        fprintf(server, "\n");\r
+                    }\r
+                    else\r
+                    {\r
+                        alignment = 0;\r
+                        switch (var->type->type)\r
+                        {\r
+                        case RPC_FC_BYTE:\r
+                        case RPC_FC_CHAR:\r
+                        case RPC_FC_SMALL:\r
+                            size = 1;\r
+                            alignment = 0;\r
+                            break;\r
+\r
+                        case RPC_FC_WCHAR:\r
+                        case RPC_FC_USHORT:\r
+                        case RPC_FC_SHORT:\r
+                            size = 2;\r
+                            if (last_size != 0 && last_size < 2)\r
+                                alignment = (2 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_ULONG:\r
+                        case RPC_FC_LONG:\r
+                        case RPC_FC_FLOAT:\r
+                            size = 4;\r
+                            if (last_size != 0 && last_size < 4)\r
+                                alignment = (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_HYPER:\r
+                        case RPC_FC_DOUBLE:\r
+                            size = 8;\r
+                            if (last_size != 0 && last_size < 4)\r
+                                alignment = (4 - last_size);\r
+                            break;\r
+\r
+                        case RPC_FC_IGNORE:\r
+                            size = 0;\r
+                            break;\r
+\r
+                        default:\r
+                            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                                  __FUNCTION__,__LINE__, var->type->type);\r
+                            return;\r
+                        }\r
+\r
+                        if (size != 0)\r
+                        {\r
+                            if (alignment != 0)\r
+                                print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                            print_server("");\r
+                            write_name(server, var);\r
+                            fprintf(server, " = (");\r
+                            write_type(server, var->type, NULL, var->tname);\r
+                            fprintf(server, " __RPC_FAR*)_StubMsg.Buffer;\n");\r
+                            print_server("_StubMsg.Buffer += sizeof(");\r
+                            write_type(server, var->type, NULL, var->tname);\r
+                            fprintf(server, ");\n");\r
+                            fprintf(server, "\n");\r
+\r
+                            last_size = size;\r
+                        }\r
+                    }\r
+                }\r
+                else if (unique_attr)\r
+                {\r
+                    print_server("NdrPointerUnmarshall(\n");\r
+                    indent++;\r
+                    print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");\r
+                    print_server("(unsigned char __RPC_FAR * __RPC_FAR *)&%s,\n", var->name);\r
+                    print_server("(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n", *type_offset);\r
+                    print_server("(unsigned char)0);\n");\r
+                    indent--;\r
+                    fprintf(server, "\n");\r
+                }\r
+\r
+            }\r
+            else\r
+            {\r
+                alignment = 0;\r
+                switch (var->type->type)\r
+                {\r
+                case RPC_FC_BYTE:\r
+                case RPC_FC_CHAR:\r
+                case RPC_FC_SMALL:\r
+                    size = 1;\r
+                    alignment = 0;\r
+                    break;\r
+\r
+                case RPC_FC_WCHAR:\r
+                case RPC_FC_USHORT:\r
+                case RPC_FC_SHORT:\r
+                    size = 2;\r
+                    if (last_size != 0 && last_size < 2)\r
+                        alignment = (2 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_ULONG:\r
+                case RPC_FC_LONG:\r
+                case RPC_FC_FLOAT:\r
+                    size = 4;\r
+                    if (last_size != 0 && last_size < 4)\r
+                        alignment = (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_HYPER:\r
+                case RPC_FC_DOUBLE:\r
+                    size = 8;\r
+                    if (last_size != 0 && last_size < 4)\r
+                        alignment = (4 - last_size);\r
+                    break;\r
+\r
+                case RPC_FC_IGNORE:\r
+                    size = 0;\r
+                    break;\r
+\r
+                default:\r
+                    error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                          __FUNCTION__,__LINE__, var->type->type);\r
+                    return;\r
+                }\r
+\r
+                if (size != 0)\r
+                {\r
+                    if (alignment != 0)\r
+                        print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                    print_server("");\r
+                    write_name(server, var);\r
+                    fprintf(server, " = *((");\r
+                    write_type(server, var->type, NULL, var->tname);\r
+                    fprintf(server, " __RPC_FAR*)_StubMsg.Buffer);\n");\r
+                    print_server("_StubMsg.Buffer += sizeof(");\r
+                    write_type(server, var->type, NULL, var->tname);\r
+                    fprintf(server, ");\n");\r
+                    fprintf(server, "\n");\r
+\r
+                    last_size = size;\r
+                }\r
+            }\r
+        }\r
+\r
+        /* calculate the next type offset */\r
+        if (var->ptr_level == 1)\r
+        {\r
+            *type_offset += 4;\r
+        }\r
+    }\r
+}\r
+\r
+\r
+static void marshall_out_arguments(func_t *func)\r
+{\r
+    unsigned int alignment = 0;\r
+    unsigned int size = 0;\r
+    unsigned int last_size = 0;\r
+    var_t *var;\r
+    var_t *def;\r
+    int out_attr;\r
+\r
+    def = func->def;\r
+\r
+    /* marshall the out arguments */\r
+    if (func->args)\r
+    {\r
+        var = func->args;\r
+        while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+        for (; var; var = PREV_LINK(var))\r
+        {\r
+            out_attr = is_attr(var->attrs, ATTR_OUT);\r
+            if (!out_attr)\r
+                continue;\r
+\r
+            alignment = 0;\r
+            switch (var->type->type)\r
+            {\r
+            case RPC_FC_BYTE:\r
+            case RPC_FC_CHAR:\r
+            case RPC_FC_SMALL:\r
+                size = 1;\r
+                alignment = 0;\r
+                break;\r
+\r
+            case RPC_FC_WCHAR:\r
+            case RPC_FC_USHORT:\r
+            case RPC_FC_SHORT:\r
+                size = 2;\r
+                if (last_size != 0 && last_size < 2)\r
+                    alignment = (2 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_ULONG:\r
+            case RPC_FC_LONG:\r
+            case RPC_FC_FLOAT:\r
+                size = 4;\r
+                if (last_size != 0 && last_size < 4)\r
+                    alignment = (4 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_HYPER:\r
+            case RPC_FC_DOUBLE:\r
+                size = 8;\r
+                if (last_size != 0 && last_size < 4)\r
+                    alignment = (4 - last_size);\r
+                break;\r
+\r
+            case RPC_FC_IGNORE:\r
+                size = 0;\r
+                break;\r
+\r
+            default:\r
+                error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                      __FUNCTION__,__LINE__, var->type->type);\r
+                return;\r
+            }\r
+\r
+            if (size != 0)\r
+            {\r
+                if (alignment != 0)\r
+                    print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    fprintf(server, "\n");\r
+                    print_server("*((");\r
+                    write_type(server, var->type, NULL, var->tname);\r
+                    fprintf(server, " __RPC_FAR *)_StubMsg.Buffer) = *");\r
+                    write_name(server, var);\r
+                    fprintf(server, ";\n");\r
+\r
+                    print_server("_StubMsg.Buffer += sizeof(");\r
+                    write_type(server, var->type, NULL, var->tname);\r
+                    fprintf(server, ");");\r
+                }\r
+                else\r
+                {\r
+                    error("Pointer level %d is not supported!\n", var->ptr_level);\r
+                    return;\r
+                }\r
+\r
+                last_size = size;\r
+            }\r
+        }\r
+    }\r
+\r
+    /* marshall the return value */\r
+    if (!is_void(def->type, NULL))\r
     {\r
         alignment = 0;\r
-        switch (var->type->type)\r
+        switch (def->type->type)\r
         {\r
         case RPC_FC_BYTE:\r
         case RPC_FC_CHAR:\r
         case RPC_FC_SMALL:\r
-            size = 1;\r
-            alignment = 0;\r
-            break;\r
-\r
         case RPC_FC_WCHAR:\r
         case RPC_FC_USHORT:\r
         case RPC_FC_SHORT:\r
-            size = 2;\r
-            if (last_size != 0 && last_size < 2)\r
-                alignment = (2 - last_size);\r
-            break;\r
-\r
         case RPC_FC_ULONG:\r
         case RPC_FC_LONG:\r
         case RPC_FC_FLOAT:\r
@@ -307,31 +770,46 @@ static void unmarshall_arguments(func_t *func)
                 alignment = (4 - last_size);\r
             break;\r
 \r
-        case RPC_FC_IGNORE:\r
-            size = 0;\r
-            break;\r
-\r
         default:\r
-            error("Unknown/unsupported type!");\r
+            error("%s:%d Unknown/unsupported type 0x%x\n",\r
+                  __FUNCTION__,__LINE__, var->type->type);\r
+            return;\r
         }\r
 \r
-        if (size != 0)\r
-        {\r
-            if (alignment != 0)\r
-                print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+        fprintf(server, "\n");\r
+        if (alignment != 0)\r
+            print_server("_StubMsg.Buffer += %u;\n", alignment);\r
+        print_server("*((");\r
+        write_type(server, def->type, def, def->tname);\r
+        fprintf(server, " __RPC_FAR *)_StubMsg.Buffer) = _RetVal;\n");\r
+        print_server("_StubMsg.Buffer += sizeof(");\r
+        write_type(server, def->type, def, def->tname);\r
+        fprintf(server, ");\n");\r
+    }\r
+}\r
 \r
-            print_server("");\r
-            write_name(server, var);\r
-            fprintf(server, " = *((");\r
-            write_type(server, var->type, var, var->tname);\r
-            fprintf(server, " __RPC_FAR*)_StubMsg.Buffer)++;\n");\r
-            fprintf(server, "\n");\r
 \r
-            last_size = size;\r
-        }\r
+static int use_return_buffer(func_t *func)\r
+{\r
+    var_t *var;\r
+\r
+    if (!is_void(func->def->type, NULL))\r
+        return 1;\r
+\r
+    if (!func->args)\r
+        return 0;\r
+\r
+    var = func->args;\r
+    while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+    while (var)\r
+    {\r
+        if (is_attr(var->attrs, ATTR_OUT))\r
+            return 1;\r
 \r
         var = PREV_LINK(var);\r
     }\r
+\r
+    return 0;\r
 }\r
 \r
 \r
@@ -342,6 +820,10 @@ static void write_function_stubs(type_t *iface)
     var_t *var;\r
     var_t* explicit_handle_var;\r
     unsigned int proc_offset = 0;\r
+    unsigned int type_offset = 2;\r
+    unsigned int i;\r
+    int in_attr;\r
+    int out_attr;\r
 \r
     while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
     while (func)\r
@@ -390,10 +872,23 @@ static void write_function_stubs(type_t *iface)
         /* declare arguments */\r
         if (func->args)\r
         {\r
+            i = 0;\r
             var = func->args;\r
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
+                in_attr = is_attr(var->attrs, ATTR_IN);\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                if (!out_attr && !in_attr)\r
+                    in_attr = 1;\r
+                if (!in_attr)\r
+                {\r
+                    print_server("");\r
+                    write_type(server, var->type, NULL, var->tname);\r
+                    fprintf(server, " _W%u;\n", i);\r
+                    i++;\r
+                }\r
+\r
                 print_server("");\r
                 write_type(server, var->type, var, var->tname);\r
                 fprintf(server, " ");\r
@@ -424,6 +919,8 @@ static void write_function_stubs(type_t *iface)
             fprintf(server, "\n");\r
         }\r
 \r
+        init_pointers(func);\r
+\r
         print_server("RpcTryFinally\n");\r
         print_server("{\n");\r
         indent++;\r
@@ -442,7 +939,7 @@ static void write_function_stubs(type_t *iface)
             indent -= 2;\r
             fprintf(server, "\n");\r
 \r
-            unmarshall_arguments(func);\r
+            unmarshall_in_arguments(func, &type_offset);\r
         }\r
 \r
         print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");\r
@@ -462,6 +959,32 @@ static void write_function_stubs(type_t *iface)
         print_server("RpcEndExcept\n");\r
         fprintf(server, "\n");\r
 \r
+        /* assign out arguments */\r
+        if (func->args)\r
+        {\r
+            i = 0;\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                in_attr = is_attr(var->attrs, ATTR_IN);\r
+                out_attr = is_attr(var->attrs, ATTR_OUT);\r
+                if (!out_attr && !in_attr)\r
+                    in_attr = 1;\r
+                if (!in_attr)\r
+                {\r
+                    print_server("");\r
+                    write_name(server, var);\r
+                    fprintf(server, " = &_W%u;\n", i);\r
+                    i++;\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+\r
+            if (i)\r
+                fprintf(server, "\n");\r
+        }\r
 \r
         /* Call the real server function */\r
         if (!is_void(def->type, NULL))\r
@@ -496,11 +1019,10 @@ static void write_function_stubs(type_t *iface)
             fprintf(server, "();\n");\r
         }\r
 \r
-        /* marshall the return value */\r
-        if (!is_void(def->type, NULL))\r
+        /* allocate and fill the return message buffer */\r
+        if (use_return_buffer(func))\r
         {\r
-            fprintf(server, "\n");\r
-            print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type));\r
+            print_message_buffer_size(func);\r
             print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");\r
             fprintf(server, "\n");\r
             print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");\r
@@ -510,11 +1032,9 @@ static void write_function_stubs(type_t *iface)
             indent--;\r
             fprintf(server, "\n");\r
             print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n");\r
-            fprintf(server, "\n");\r
 \r
-            print_server("*((");\r
-            write_type(server, def->type, def, def->tname);\r
-            fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n");\r
+            /* marshall the out arguments */\r
+            marshall_out_arguments(func);\r
         }\r
 \r
         indent--;\r
@@ -649,8 +1169,12 @@ static void write_serverinterfacedecl(type_t *iface)
     print_server("0,\n");\r
     indent--;\r
     print_server("};\n");\r
-    print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",\r
-                 iface->name, LOWORD(ver), HIWORD(ver), iface->name);\r
+    if (old_names)\r
+        print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",\r
+                     iface->name, iface->name);\r
+    else\r
+        print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",\r
+                     iface->name, LOWORD(ver), HIWORD(ver), iface->name);\r
     fprintf(server, "\n");\r
 }\r
 \r
@@ -666,14 +1190,46 @@ static void write_formatdesc( const char *str )
     print_server("\n");\r
 }\r
 \r
-\r
-static void write_formatstringsdecl(type_t *iface)\r
+static int get_type_format_string_size(type_t *iface)\r
 {\r
+    int size = 3;\r
     func_t *func;\r
     var_t *var;\r
-    int byte_count = 1;\r
 \r
-    print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", 3); /* FIXME */\r
+    /* determine the proc format string size */\r
+    func = iface->funcs;\r
+    while (NEXT_LINK(func)) func = NEXT_LINK(func);\r
+    while (func)\r
+    {\r
+        /* argument list size */\r
+        if (func->args)\r
+        {\r
+            var = func->args;\r
+            while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
+            while (var)\r
+            {\r
+                if (var->ptr_level == 1)\r
+                {\r
+                    if (is_base_type(var->type))\r
+                        size += 4;\r
+                }\r
+\r
+                var = PREV_LINK(var);\r
+            }\r
+        }\r
+\r
+        func = PREV_LINK(func);\r
+    }\r
+\r
+    return size;\r
+}\r
+\r
+\r
+static int get_proc_format_string_size(type_t *iface)\r
+{\r
+    int size = 1;\r
+    func_t *func;\r
+    var_t *var;\r
 \r
     /* determine the proc format string size */\r
     func = iface->funcs;\r
@@ -687,16 +1243,39 @@ static void write_formatstringsdecl(type_t *iface)
             while (NEXT_LINK(var)) var = NEXT_LINK(var);\r
             while (var)\r
             {\r
-                byte_count += 2; /* FIXME: determine real size */\r
+                switch (var->ptr_level)\r
+                {\r
+                case 0:\r
+                    if (is_base_type(var->type))\r
+                        size += 2;\r
+                    break;\r
+\r
+                case 1:\r
+                    if (is_base_type(var->type))\r
+                        size += 4;\r
+                    break;\r
+                }\r
+\r
                 var = PREV_LINK(var);\r
             }\r
         }\r
 \r
         /* return value size */\r
-        byte_count += 2; /* FIXME: determine real size */\r
+        size += 2;\r
         func = PREV_LINK(func);\r
     }\r
-    print_server("#define PROC_FORMAT_STRING_SIZE %d\n", byte_count);\r
+\r
+    return size;\r
+}\r
+\r
+\r
+static void write_formatstringsdecl(type_t *iface)\r
+{\r
+    print_server("#define TYPE_FORMAT_STRING_SIZE %d\n",\r
+                 get_type_format_string_size(iface));\r
+\r
+    print_server("#define PROC_FORMAT_STRING_SIZE %d\n",\r
+                 get_proc_format_string_size(iface));\r
 \r
     fprintf(server, "\n");\r
     write_formatdesc("TYPE");\r
@@ -759,7 +1338,7 @@ void write_server(ifref_t *ifaces)
         fprintf(server, "\n");\r
 \r
         write_procformatstring(iface->iface);\r
-        write_typeformatstring();\r
+        write_typeformatstring(iface->iface);\r
 \r
         fprintf(server, "\n");\r
 \r
index b952b5a..a5f1757 100644 (file)
@@ -58,6 +58,7 @@ static char usage[] =
 "   -H file     Name of header file (default is infile.h)\n"
 "   -I path     Set include search dir to path (multiple -I allowed)\n"
 "   -N          Do not preprocess input\n"
+"   -o          Use old naming conventions\n"
 "   -p          Generate proxy\n"
 "   -P file     Name of proxy file (default is infile_p.c)\n"
 "   -s          Generate server stub\n"
@@ -90,6 +91,7 @@ int do_proxies = 0;
 int do_client = 0;
 int do_server = 0;
 int no_preprocess = 0;
+int old_names = 0;
 
 char *input_name;
 char *header_name;
@@ -142,8 +144,8 @@ int main(int argc,char *argv[])
 
   now = time(NULL);
 
-  while((optc = getopt(argc, argv, "cC:d:D:EhH:I:NpP:sS:tT:VW")) != EOF) {
-    switch(optc) {
+  while((optc = getopt(argc, argv, "cC:d:D:EhH:I:NopP:sS:tT:VW")) != EOF) {
+    switch (optc) {
     case 'c':
       do_everything = 0;
       do_client = 1;
@@ -174,6 +176,9 @@ int main(int argc,char *argv[])
     case 'N':
       no_preprocess = 1;
       break;
+    case 'o':
+      old_names = 1;
+      break;
     case 'p':
       do_everything = 0;
       do_proxies = 1;
@@ -207,10 +212,10 @@ int main(int argc,char *argv[])
     }
   }
 
-  if(do_everything) {
+  if (do_everything) {
       do_header = do_typelib = do_proxies = do_client = do_server = 1;
   }
-  if(optind < argc) {
+  if (optind < argc) {
     input_name = xstrdup(argv[optind]);
   }
   else {
@@ -218,7 +223,7 @@ int main(int argc,char *argv[])
     return 1;
   }
 
-  if(debuglevel)
+  if (debuglevel)
   {
     setbuf(stdout,0);
     setbuf(stderr,0);
index 5b303c3..db8b95c 100644 (file)
@@ -43,6 +43,7 @@ extern int do_typelib;
 extern int do_proxies;
 extern int do_client;
 extern int do_server;
+extern int old_names;
 
 extern char *input_name;
 extern char *header_name;
diff --git a/reactos/tools/widl/widl.mak b/reactos/tools/widl/widl.mak
new file mode 100644 (file)
index 0000000..d552051
--- /dev/null
@@ -0,0 +1,123 @@
+WIDL_BASE = $(TOOLS_BASE)$(SEP)widl
+WIDL_BASE_ = $(WIDL_BASE)$(SEP)
+WIDL_INT = $(INTERMEDIATE_)$(WIDL_BASE)
+WIDL_INT_ = $(WIDL_INT)$(SEP)
+WIDL_OUT = $(OUTPUT_)$(WIDL_BASE)
+WIDL_OUT_ = $(WIDL_OUT)$(SEP)
+
+$(WIDL_INT): | $(TOOLS_INT)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(WIDL_OUT): | $(TOOLS_OUT)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+endif
+
+WIDL_PORT_BASE = $(WIDL_BASE)$(SEP)port
+WIDL_PORT_BASE_ = $(WIDL_PORT_BASE)$(SEP)
+WIDL_PORT_INT = $(INTERMEDIATE_)$(WIDL_PORT_BASE)
+WIDL_PORT_INT_ = $(WIDL_PORT_INT)$(SEP)
+WIDL_PORT_OUT = $(OUTPUT_)$(WIDL_PORT_BASE)
+WIDL_PORT_OUT_ = $(WIDL_PORT_OUT)$(SEP)
+
+$(WIDL_PORT_INT): | $(WIDL_INT)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(WIDL_PORT_OUT): | $(WIDL_OUT)
+       $(ECHO_MKDIR)
+       ${mkdir} $@
+endif
+
+WIDL_TARGET = \
+       $(EXEPREFIX)$(WIDL_OUT_)widl$(EXEPOSTFIX)
+
+WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \
+       client.c \
+       hash.c \
+       header.c \
+       lex.yy.c \
+       proxy.c \
+       server.c \
+       typelib.c \
+       utils.c \
+       widl.c \
+       write_msft.c \
+       y.tab.c \
+       port$(SEP)mkstemps.c \
+       )
+
+WIDL_OBJECTS = \
+  $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o))
+
+WIDL_HOST_CFLAGS = -g -Werror -Wall \
+       -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 \
+       -I$(WIDL_BASE) -I$(WPP_BASE) \
+       -Iinclude/wine -Iinclude -Iw32api/include
+
+WIDL_HOST_LFLAGS = -g
+
+WIDL_LIBS = $(WPP_TARGET)
+
+.PHONY: widl
+widl: $(WIDL_TARGET)
+
+$(WIDL_TARGET): $(WIDL_OBJECTS) $(WIDL_LIBS) | $(WIDL_OUT)
+       $(ECHO_LD)
+       ${host_gcc} $(WIDL_OBJECTS) $(WIDL_LIBS) $(WIDL_HOST_LFLAGS) -o $@
+
+$(WIDL_INT_)client.o: $(WIDL_BASE_)client.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)hash.o: $(WIDL_BASE_)hash.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)header.o: $(WIDL_BASE_)header.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)lex.yy.o: $(WIDL_BASE_)lex.yy.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)proxy.o: $(WIDL_BASE_)proxy.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)server.o: $(WIDL_BASE_)server.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)typelib.o: $(WIDL_BASE_)typelib.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)utils.o: $(WIDL_BASE_)utils.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)widl.o: $(WIDL_BASE_)widl.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)write_msft.o: $(WIDL_BASE_)write_msft.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_INT_)y.tab.o: $(WIDL_BASE_)y.tab.c | $(WIDL_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+$(WIDL_PORT_INT_)mkstemps.o: $(WIDL_PORT_BASE_)mkstemps.c | $(WIDL_PORT_INT)
+       $(ECHO_CC)
+       ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@
+
+.PHONY: widl_clean
+widl_clean:
+       -@$(rm) $(WIDL_TARGET) $(WIDL_OBJECTS) 2>$(NUL)
+clean: widl_clean
index 6ea50d4..5802099 100644 (file)
@@ -98,8 +98,10 @@ enum attr_type
     ATTR_PROPGET,
     ATTR_PROPPUT,
     ATTR_PROPPUTREF,
+    ATTR_PTR,
     ATTR_PUBLIC,
     ATTR_READONLY,
+    ATTR_REF,
     ATTR_RESTRICTED,
     ATTR_RETVAL,
     ATTR_SIZEIS,
@@ -108,6 +110,7 @@ enum attr_type
     ATTR_SWITCHIS,
     ATTR_SWITCHTYPE,
     ATTR_TRANSMITAS,
+    ATTR_UNIQUE,
     ATTR_UUID,
     ATTR_V1ENUM,
     ATTR_VARARG,
index 2d36081..c9ae86a 100644 (file)
 #include <stdio.h>
 #include <ctype.h>
 #include <time.h>
+#ifdef WIN32
+#include <io.h> /* write() */
+#else
+#include <fcntl.h> /* create */
+#include <unistd.h> /* write and close */
+#endif /* WIN32 */
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
index 082d19f..ca14f77 100644 (file)
 #define        tPROPGET        341\r
 #define        tPROPPUT        342\r
 #define        tPROPPUTREF     343\r
-#define        tPUBLIC 344\r
-#define        tREADONLY       345\r
-#define        tREF    346\r
-#define        tRESTRICTED     347\r
-#define        tRETVAL 348\r
-#define        tSHORT  349\r
-#define        tSIGNED 350\r
-#define        tSIZEIS 351\r
-#define        tSIZEOF 352\r
-#define        tSMALL  353\r
-#define        tSOURCE 354\r
-#define        tSTDCALL        355\r
-#define        tSTRING 356\r
-#define        tSTRUCT 357\r
-#define        tSWITCH 358\r
-#define        tSWITCHIS       359\r
-#define        tSWITCHTYPE     360\r
-#define        tTRANSMITAS     361\r
-#define        tTYPEDEF        362\r
-#define        tUNION  363\r
-#define        tUNIQUE 364\r
-#define        tUNSIGNED       365\r
-#define        tUUID   366\r
-#define        tV1ENUM 367\r
-#define        tVARARG 368\r
-#define        tVERSION        369\r
-#define        tVOID   370\r
-#define        tWCHAR  371\r
-#define        tWIREMARSHAL    372\r
-#define        tPOINTERTYPE    373\r
-#define        COND    374\r
-#define        CAST    375\r
-#define        PPTR    376\r
-#define        NEG     377\r
+#define        tPTR    344\r
+#define        tPUBLIC 345\r
+#define        tREADONLY       346\r
+#define        tREF    347\r
+#define        tRESTRICTED     348\r
+#define        tRETVAL 349\r
+#define        tSHORT  350\r
+#define        tSIGNED 351\r
+#define        tSIZEIS 352\r
+#define        tSIZEOF 353\r
+#define        tSMALL  354\r
+#define        tSOURCE 355\r
+#define        tSTDCALL        356\r
+#define        tSTRING 357\r
+#define        tSTRUCT 358\r
+#define        tSWITCH 359\r
+#define        tSWITCHIS       360\r
+#define        tSWITCHTYPE     361\r
+#define        tTRANSMITAS     362\r
+#define        tTYPEDEF        363\r
+#define        tUNION  364\r
+#define        tUNIQUE 365\r
+#define        tUNSIGNED       366\r
+#define        tUUID   367\r
+#define        tV1ENUM 368\r
+#define        tVARARG 369\r
+#define        tVERSION        370\r
+#define        tVOID   371\r
+#define        tWCHAR  372\r
+#define        tWIREMARSHAL    373\r
+#define        tPOINTERTYPE    374\r
+#define        COND    375\r
+#define        CAST    376\r
+#define        PPTR    377\r
+#define        NEG     378\r
 \r
 #line 1 "parser.y"\r
 \r
@@ -232,7 +233,7 @@ static type_t std_int64 = { "__int64" };
 static type_t std_uhyper = { "MIDL_uhyper" };\r
 \r
 \r
-#line 109 "parser.y"\r
+#line 106 "parser.y"\r
 typedef union {\r
        attr_t *attr;\r
        expr_t *expr;\r
@@ -256,26 +257,26 @@ typedef union {
 \r
 \r
 \r
-#define        YYFINAL         459\r
+#define        YYFINAL         462\r
 #define        YYFLAG          -32768\r
-#define        YYNTBASE        143\r
+#define        YYNTBASE        144\r
 \r
-#define YYTRANSLATE(x) ((unsigned)(x) <= 377 ? yytranslate[x] : 215)\r
+#define YYTRANSLATE(x) ((unsigned)(x) <= 378 ? yytranslate[x] : 216)\r
 \r
 static const short yytranslate[] = {     0,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
-     2,     2,     2,     2,     2,     2,     2,   123,     2,   133,\r
-   134,   126,   125,   120,   124,   142,   127,     2,     2,     2,\r
-     2,     2,     2,     2,     2,     2,     2,   139,   132,     2,\r
-   140,     2,   141,     2,     2,     2,     2,     2,     2,     2,\r
+     2,     2,     2,     2,     2,     2,     2,   124,     2,   134,\r
+   135,   127,   126,   121,   125,   143,   128,     2,     2,     2,\r
+     2,     2,     2,     2,     2,     2,     2,   140,   133,     2,\r
+   141,     2,   142,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
-   137,     2,   138,     2,     2,     2,     2,     2,     2,     2,\r
+   138,     2,   139,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
-     2,     2,   135,   122,   136,   128,     2,     2,     2,     2,\r
+     2,     2,   136,   123,   137,   129,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\r
@@ -300,7 +301,7 @@ static const short yytranslate[] = {     0,
     87,    88,    89,    90,    91,    92,    93,    94,    95,    96,\r
     97,    98,    99,   100,   101,   102,   103,   104,   105,   106,\r
    107,   108,   109,   110,   111,   112,   113,   114,   115,   116,\r
-   117,   118,   119,   121,   129,   130,   131\r
+   117,   118,   119,   120,   122,   130,   131,   132\r
 };\r
 \r
 #if YYDEBUG != 0\r
@@ -315,132 +316,133 @@ static const short yyprhs[] = {     0,
    222,   224,   226,   231,   236,   241,   246,   251,   253,   258,\r
    260,   265,   271,   273,   275,   280,   282,   284,   286,   288,\r
    290,   292,   294,   299,   301,   303,   305,   307,   309,   311,\r
-   313,   318,   320,   322,   327,   332,   337,   342,   344,   346,\r
-   351,   356,   358,   359,   361,   362,   365,   370,   374,   380,\r
-   381,   384,   386,   388,   392,   396,   398,   404,   406,   410,\r
-   411,   413,   415,   417,   419,   425,   429,   433,   437,   441,\r
-   445,   449,   453,   457,   460,   463,   466,   471,   476,   480,\r
-   482,   486,   488,   493,   494,   497,   500,   504,   507,   509,\r
-   514,   522,   523,   525,   526,   528,   530,   532,   534,   536,\r
-   538,   540,   542,   544,   546,   549,   552,   554,   556,   558,\r
-   560,   562,   563,   565,   567,   570,   573,   576,   579,   581,\r
-   583,   586,   589,   592,   597,   598,   601,   604,   607,   610,\r
-   613,   616,   620,   623,   627,   633,   634,   637,   640,   643,\r
-   646,   652,   660,   662,   665,   668,   671,   674,   677,   682,\r
-   685,   688,   690,   692,   696,   698,   702,   704,   706,   712,\r
-   714,   716,   718,   721,   723,   726,   728,   731,   733,   736,\r
-   741,   747,   758,   760\r
+   313,   315,   317,   322,   324,   326,   331,   336,   341,   343,\r
+   348,   350,   352,   357,   362,   364,   365,   367,   368,   371,\r
+   376,   380,   386,   387,   390,   392,   394,   398,   402,   404,\r
+   410,   412,   416,   417,   419,   421,   423,   425,   431,   435,\r
+   439,   443,   447,   451,   455,   459,   463,   466,   469,   472,\r
+   477,   482,   486,   488,   492,   494,   499,   500,   503,   506,\r
+   510,   513,   515,   520,   528,   529,   531,   532,   534,   536,\r
+   538,   540,   542,   544,   546,   548,   550,   552,   555,   558,\r
+   560,   562,   564,   566,   568,   570,   571,   573,   575,   578,\r
+   581,   584,   587,   589,   591,   594,   597,   600,   605,   606,\r
+   609,   612,   615,   618,   621,   624,   628,   631,   635,   641,\r
+   642,   645,   648,   651,   654,   660,   668,   670,   673,   676,\r
+   679,   682,   685,   690,   693,   696,   698,   700,   704,   706,\r
+   710,   712,   714,   720,   722,   724,   726,   729,   731,   734,\r
+   736,   739,   741,   744,   749,   755,   766,   768\r
 };\r
 \r
-static const short yyrhs[] = {   144,\r
-     0,     0,   144,   202,     0,   144,   201,     0,   144,   190,\r
-     0,   144,   205,     0,   144,   153,     0,   144,   147,     0,\r
-     0,   145,   202,     0,   145,   201,     0,   145,   190,     0,\r
-   145,   205,     0,   145,   147,     0,     0,   146,   181,   132,\r
-     0,   146,   147,     0,   132,     0,   167,   132,     0,   148,\r
-     0,   171,   132,     0,   177,   132,     0,   150,     0,   210,\r
-   132,     0,   212,   132,     0,   213,   132,     0,    37,   133,\r
-     7,   134,     0,    64,     7,   132,     0,   149,   145,     9,\r
-     0,    74,     3,     0,   161,   151,   135,     0,   152,   145,\r
-   136,     0,     0,   156,     0,   116,     0,   157,     0,   156,\r
-   120,   157,     0,   155,     0,   161,   211,   207,   158,     0,\r
-   211,   207,   158,     0,   161,   211,   207,   133,   154,   134,\r
-     0,   211,   207,   133,   154,   134,     0,     0,   137,   159,\r
-   138,     0,   137,   126,   138,     0,   173,     0,   159,   120,\r
-   174,     0,   159,   138,   137,   174,     0,     0,   161,     0,\r
-   137,   162,   138,     0,   163,     0,   162,   120,   163,     0,\r
-   162,   138,   137,   163,     0,    16,     0,    18,     0,    24,\r
-   133,   184,   134,     0,    26,   133,   175,   134,     0,    33,\r
+static const short yyrhs[] = {   145,\r
+     0,     0,   145,   203,     0,   145,   202,     0,   145,   191,\r
+     0,   145,   206,     0,   145,   154,     0,   145,   148,     0,\r
+     0,   146,   203,     0,   146,   202,     0,   146,   191,     0,\r
+   146,   206,     0,   146,   148,     0,     0,   147,   182,   133,\r
+     0,   147,   148,     0,   133,     0,   168,   133,     0,   149,\r
+     0,   172,   133,     0,   178,   133,     0,   151,     0,   211,\r
+   133,     0,   213,   133,     0,   214,   133,     0,    37,   134,\r
+     7,   135,     0,    64,     7,   133,     0,   150,   146,     9,\r
+     0,    74,     3,     0,   162,   152,   136,     0,   153,   146,\r
+   137,     0,     0,   157,     0,   117,     0,   158,     0,   157,\r
+   121,   158,     0,   156,     0,   162,   212,   208,   159,     0,\r
+   212,   208,   159,     0,   162,   212,   208,   134,   155,   135,\r
+     0,   212,   208,   134,   155,   135,     0,     0,   138,   160,\r
+   139,     0,   138,   127,   139,     0,   174,     0,   160,   121,\r
+   175,     0,   160,   139,   138,   175,     0,     0,   162,     0,\r
+   138,   163,   139,     0,   164,     0,   163,   121,   164,     0,\r
+   163,   139,   138,   164,     0,    16,     0,    18,     0,    24,\r
+   134,   185,   135,     0,    26,   134,   176,   135,     0,    33,\r
      0,    34,     0,    35,     0,    36,     0,    38,     0,    39,\r
-   133,   176,   134,     0,    39,   133,     7,   134,     0,    41,\r
-   133,     7,   134,     0,    43,     0,    44,   133,     7,   134,\r
-     0,    45,   133,     7,   134,     0,    45,   133,   176,   134,\r
-     0,    48,     0,    51,     0,    53,   133,   176,   134,     0,\r
-    54,   133,     7,   134,     0,    55,   133,     7,   134,     0,\r
-    56,   133,   176,   134,     0,    57,   133,     7,   134,     0,\r
-    58,     0,    60,   133,   176,   134,     0,    61,     0,    62,\r
-   133,   184,   134,     0,    63,   133,    52,     3,   134,     0,\r
-    66,     0,    69,     0,    73,   133,   172,   134,     0,    75,\r
+   134,   177,   135,     0,    39,   134,     7,   135,     0,    41,\r
+   134,     7,   135,     0,    43,     0,    44,   134,     7,   135,\r
+     0,    45,   134,     7,   135,     0,    45,   134,   177,   135,\r
+     0,    48,     0,    51,     0,    53,   134,   177,   135,     0,\r
+    54,   134,     7,   135,     0,    55,   134,     7,   135,     0,\r
+    56,   134,   177,   135,     0,    57,   134,     7,   135,     0,\r
+    58,     0,    60,   134,   177,   135,     0,    61,     0,    62,\r
+   134,   185,   135,     0,    63,   134,    52,     3,   135,     0,\r
+    66,     0,    69,     0,    73,   134,   173,   135,     0,    75,\r
      0,    79,     0,    80,     0,    81,     0,    82,     0,    83,\r
-     0,    84,     0,    85,   133,   209,   134,     0,    87,     0,\r
-    88,     0,    89,     0,    90,     0,    91,     0,    93,     0,\r
-    94,     0,    97,   133,   172,   134,     0,   100,     0,   102,\r
-     0,   105,   133,   174,   134,     0,   106,   133,   211,   134,\r
-     0,   107,   133,   211,   134,     0,   112,   133,     8,   134,\r
-     0,   113,     0,   114,     0,   115,   133,   214,   134,     0,\r
-   118,   133,   211,   134,     0,   209,     0,     0,   101,     0,\r
-     0,   165,   166,     0,    26,   174,   139,   179,     0,    38,\r
-   139,   179,     0,    32,   211,   184,   140,   176,     0,     0,\r
-   169,   120,     0,   169,     0,   170,     0,   169,   120,   170,\r
-     0,   184,   140,   176,     0,   184,     0,    46,   183,   135,\r
-   168,   136,     0,   173,     0,   172,   120,   173,     0,     0,\r
-   174,     0,     5,     0,     6,     0,     3,     0,   174,   141,\r
-   174,   139,   174,     0,   174,   122,   174,     0,   174,   123,\r
-   174,     0,   174,   125,   174,     0,   174,   124,   174,     0,\r
-   174,   126,   174,     0,   174,   127,   174,     0,   174,    10,\r
-   174,     0,   174,    11,   174,     0,   128,   174,     0,   124,\r
-   174,     0,   126,   174,     0,   133,   211,   134,   174,     0,\r
-    98,   133,   211,   134,     0,   133,   174,   134,     0,   176,\r
-     0,   175,   120,   176,     0,   174,     0,    49,    32,   211,\r
-   184,     0,     0,   178,   179,     0,   180,   132,     0,   160,\r
-   213,   132,     0,   161,   132,     0,   132,     0,   160,   211,\r
-   207,   158,     0,   160,   211,   164,   207,   133,   154,   134,\r
-     0,     0,   184,     0,     0,     3,     0,     4,     0,     3,\r
-     0,     4,     0,    60,     0,    94,     0,   115,     0,    22,\r
-     0,   117,     0,   187,     0,    96,   187,     0,   111,   187,\r
-     0,    50,     0,    42,     0,    20,     0,    47,     0,    52,\r
-     0,     0,    70,     0,    70,     0,    99,   186,     0,    95,\r
-   186,     0,    76,   186,     0,    59,   186,     0,    71,     0,\r
-    28,     0,    29,     3,     0,    29,     4,     0,   161,   188,\r
-     0,   189,   135,   191,   136,     0,     0,   191,   192,     0,\r
-   160,   202,     0,    40,     3,     0,    40,     4,     0,   161,\r
-   193,     0,    86,   139,     0,   195,   180,   132,     0,    77,\r
-   139,     0,   196,   181,   132,     0,   194,   135,   195,   196,\r
-   136,     0,     0,   139,     4,     0,    72,     3,     0,    72,\r
-     4,     0,   161,   199,     0,   200,   198,   135,   146,   136,\r
-     0,   200,   139,     3,   135,   150,   146,   136,     0,   197,\r
-     0,   199,   132,     0,   193,   132,     0,    78,     3,     0,\r
-    78,     4,     0,   161,   203,     0,   204,   135,   146,   136,\r
-     0,   126,   207,     0,    32,   206,     0,   184,     0,   206,\r
-     0,   133,   207,   134,     0,   207,     0,   208,   120,   207,\r
-     0,    92,     0,   110,     0,   103,   183,   135,   178,   136,\r
-     0,   116,     0,     4,     0,   185,     0,    32,   211,     0,\r
-   171,     0,    46,     3,     0,   210,     0,   103,     3,     0,\r
-   213,     0,   109,     3,     0,   108,   160,   211,   208,     0,\r
-   109,   183,   135,   178,   136,     0,   109,   183,   104,   133,\r
-   180,   134,   182,   135,   165,   136,     0,     5,     0,     5,\r
-   142,     5,     0\r
+     0,    84,     0,    85,   134,   210,   135,     0,    87,     0,\r
+    88,     0,    89,     0,    90,     0,    91,     0,    92,     0,\r
+    93,     0,    94,     0,    95,     0,    98,   134,   173,   135,\r
+     0,   101,     0,   103,     0,   106,   134,   175,   135,     0,\r
+   107,   134,   212,   135,     0,   108,   134,   212,   135,     0,\r
+   111,     0,   113,   134,     8,   135,     0,   114,     0,   115,\r
+     0,   116,   134,   215,   135,     0,   119,   134,   212,   135,\r
+     0,   210,     0,     0,   102,     0,     0,   166,   167,     0,\r
+    26,   175,   140,   180,     0,    38,   140,   180,     0,    32,\r
+   212,   185,   141,   177,     0,     0,   170,   121,     0,   170,\r
+     0,   171,     0,   170,   121,   171,     0,   185,   141,   177,\r
+     0,   185,     0,    46,   184,   136,   169,   137,     0,   174,\r
+     0,   173,   121,   174,     0,     0,   175,     0,     5,     0,\r
+     6,     0,     3,     0,   175,   142,   175,   140,   175,     0,\r
+   175,   123,   175,     0,   175,   124,   175,     0,   175,   126,\r
+   175,     0,   175,   125,   175,     0,   175,   127,   175,     0,\r
+   175,   128,   175,     0,   175,    10,   175,     0,   175,    11,\r
+   175,     0,   129,   175,     0,   125,   175,     0,   127,   175,\r
+     0,   134,   212,   135,   175,     0,    99,   134,   212,   135,\r
+     0,   134,   175,   135,     0,   177,     0,   176,   121,   177,\r
+     0,   175,     0,    49,    32,   212,   185,     0,     0,   179,\r
+   180,     0,   181,   133,     0,   161,   214,   133,     0,   162,\r
+   133,     0,   133,     0,   161,   212,   208,   159,     0,   161,\r
+   212,   165,   208,   134,   155,   135,     0,     0,   185,     0,\r
+     0,     3,     0,     4,     0,     3,     0,     4,     0,    60,\r
+     0,    95,     0,   116,     0,    22,     0,   118,     0,   188,\r
+     0,    97,   188,     0,   112,   188,     0,   112,     0,    50,\r
+     0,    42,     0,    20,     0,    47,     0,    52,     0,     0,\r
+    70,     0,    70,     0,   100,   187,     0,    96,   187,     0,\r
+    76,   187,     0,    59,   187,     0,    71,     0,    28,     0,\r
+    29,     3,     0,    29,     4,     0,   162,   189,     0,   190,\r
+   136,   192,   137,     0,     0,   192,   193,     0,   161,   203,\r
+     0,    40,     3,     0,    40,     4,     0,   162,   194,     0,\r
+    86,   140,     0,   196,   181,   133,     0,    77,   140,     0,\r
+   197,   182,   133,     0,   195,   136,   196,   197,   137,     0,\r
+     0,   140,     4,     0,    72,     3,     0,    72,     4,     0,\r
+   162,   200,     0,   201,   199,   136,   147,   137,     0,   201,\r
+   140,     3,   136,   151,   147,   137,     0,   198,     0,   200,\r
+   133,     0,   194,   133,     0,    78,     3,     0,    78,     4,\r
+     0,   162,   204,     0,   205,   136,   147,   137,     0,   127,\r
+   208,     0,    32,   207,     0,   185,     0,   207,     0,   134,\r
+   208,   135,     0,   208,     0,   209,   121,   208,     0,    93,\r
+     0,   111,     0,   104,   184,   136,   179,   137,     0,   117,\r
+     0,     4,     0,   186,     0,    32,   212,     0,   172,     0,\r
+    46,     3,     0,   211,     0,   104,     3,     0,   214,     0,\r
+   110,     3,     0,   109,   161,   212,   209,     0,   110,   184,\r
+   136,   179,   137,     0,   110,   184,   105,   134,   181,   135,\r
+   183,   136,   166,   137,     0,     5,     0,     5,   143,     5,\r
+     0\r
 };\r
 \r
 #endif\r
 \r
 #if YYDEBUG != 0\r
 static const short yyrline[] = { 0,\r
-   229,   232,   233,   234,   235,   236,   237,   238,   241,   242,\r
-   243,   244,   245,   246,   249,   250,   251,   254,   255,   256,\r
-   257,   258,   259,   260,   261,   262,   265,   267,   270,   273,\r
-   275,   277,   280,   281,   284,   287,   288,   289,   293,   297,\r
-   300,   306,   313,   314,   315,   318,   319,   320,   323,   324,\r
-   327,   331,   332,   333,   336,   338,   339,   340,   341,   342,\r
-   343,   344,   345,   346,   347,   348,   349,   350,   351,   352,\r
-   353,   354,   355,   356,   357,   358,   359,   360,   361,   362,\r
-   363,   364,   365,   366,   367,   368,   369,   370,   371,   372,\r
-   373,   374,   375,   376,   377,   378,   379,   380,   381,   382,\r
-   383,   384,   385,   386,   387,   388,   389,   390,   391,   392,\r
-   393,   394,   397,   398,   401,   402,   407,   411,   417,   424,\r
-   425,   426,   429,   430,   436,   441,   447,   455,   456,   469,\r
-   470,   473,   474,   475,   476,   477,   478,   479,   480,   481,\r
-   482,   483,   484,   485,   486,   487,   488,   489,   490,   493,\r
-   494,   497,   503,   508,   509,   514,   515,   516,   517,   520,\r
-   523,   534,   535,   538,   539,   540,   543,   545,   546,   547,\r
-   548,   551,   552,   553,   554,   555,   567,   568,   569,   570,\r
-   571,   574,   575,   578,   579,   580,   581,   582,   583,   584,\r
-   587,   588,   591,   597,   602,   603,   606,   610,   611,   614,\r
-   626,   627,   630,   631,   634,   649,   650,   653,   654,   657,\r
-   665,   673,   680,   683,   685,   688,   689,   692,   697,   703,\r
-   704,   707,   708,   709,   712,   714,   717,   719,   722,   732,\r
-   733,   734,   735,   736,   737,   738,   739,   740,   741,   744,\r
-   756,   760,   773,   775\r
+   227,   230,   231,   232,   233,   234,   235,   236,   239,   240,\r
+   241,   242,   243,   244,   247,   248,   249,   252,   253,   254,\r
+   255,   256,   257,   258,   259,   260,   263,   265,   268,   271,\r
+   273,   275,   278,   279,   282,   285,   286,   287,   291,   295,\r
+   298,   304,   311,   312,   313,   316,   317,   318,   321,   322,\r
+   325,   329,   330,   331,   334,   336,   337,   338,   339,   340,\r
+   341,   342,   343,   344,   345,   346,   347,   348,   349,   350,\r
+   351,   352,   353,   354,   355,   356,   357,   358,   359,   360,\r
+   361,   362,   363,   364,   365,   366,   367,   368,   369,   370,\r
+   371,   372,   373,   374,   375,   376,   377,   378,   379,   380,\r
+   381,   382,   383,   384,   385,   386,   387,   388,   389,   390,\r
+   391,   392,   393,   394,   395,   398,   399,   402,   403,   408,\r
+   412,   418,   425,   426,   427,   430,   431,   437,   442,   448,\r
+   456,   457,   470,   471,   474,   475,   476,   477,   478,   479,\r
+   480,   481,   482,   483,   484,   485,   486,   487,   488,   489,\r
+   490,   491,   494,   495,   498,   504,   509,   510,   515,   516,\r
+   517,   518,   521,   524,   535,   536,   539,   540,   541,   544,\r
+   546,   547,   548,   549,   552,   553,   554,   555,   556,   568,\r
+   570,   571,   572,   573,   574,   577,   578,   581,   582,   583,\r
+   584,   585,   586,   587,   590,   591,   594,   600,   605,   606,\r
+   609,   613,   614,   617,   629,   630,   633,   634,   637,   652,\r
+   653,   656,   657,   660,   668,   676,   683,   686,   688,   691,\r
+   692,   695,   700,   706,   707,   710,   711,   712,   715,   717,\r
+   720,   722,   725,   735,   736,   737,   738,   739,   740,   741,\r
+   742,   743,   744,   747,   759,   763,   776,   778\r
 };\r
 #endif\r
 \r
@@ -460,10 +462,10 @@ static const char * const yytname[] = {   "$","error","$undefined.","aIDENTIFIER
 "tINLINE","tINPUTSYNC","tINT","tINT64","tINTERFACE","tLENGTHIS","tLIBRARY","tLOCAL",\r
 "tLONG","tMETHODS","tMODULE","tNONCREATABLE","tOBJECT","tODL","tOLEAUTOMATION",\r
 "tOPTIONAL","tOUT","tPOINTERDEFAULT","tPROPERTIES","tPROPGET","tPROPPUT","tPROPPUTREF",\r
-"tPUBLIC","tREADONLY","tREF","tRESTRICTED","tRETVAL","tSHORT","tSIGNED","tSIZEIS",\r
-"tSIZEOF","tSMALL","tSOURCE","tSTDCALL","tSTRING","tSTRUCT","tSWITCH","tSWITCHIS",\r
-"tSWITCHTYPE","tTRANSMITAS","tTYPEDEF","tUNION","tUNIQUE","tUNSIGNED","tUUID",\r
-"tV1ENUM","tVARARG","tVERSION","tVOID","tWCHAR","tWIREMARSHAL","tPOINTERTYPE",\r
+"tPTR","tPUBLIC","tREADONLY","tREF","tRESTRICTED","tRETVAL","tSHORT","tSIGNED",\r
+"tSIZEIS","tSIZEOF","tSMALL","tSOURCE","tSTDCALL","tSTRING","tSTRUCT","tSWITCH",\r
+"tSWITCHIS","tSWITCHTYPE","tTRANSMITAS","tTYPEDEF","tUNION","tUNIQUE","tUNSIGNED",\r
+"tUUID","tV1ENUM","tVARARG","tVERSION","tVOID","tWCHAR","tWIREMARSHAL","tPOINTERTYPE",\r
 "','","COND","'|'","'&'","'-'","'+'","'*'","'/'","'~'","CAST","PPTR","NEG","';'",\r
 "'('","')'","'{'","'}'","'['","']'","':'","'='","'?'","'.'","input","gbl_statements",\r
 "imp_statements","int_statements","statement","cppquote","import_start","import",\r
@@ -480,31 +482,31 @@ static const char * const yytname[] = {   "$","error","$undefined.","aIDENTIFIER
 #endif\r
 \r
 static const short yyr1[] = {     0,\r
-   143,   144,   144,   144,   144,   144,   144,   144,   145,   145,\r
-   145,   145,   145,   145,   146,   146,   146,   147,   147,   147,\r
-   147,   147,   147,   147,   147,   147,   148,   149,   150,   151,\r
-   152,   153,   154,   154,   155,   156,   156,   156,   157,   157,\r
-   157,   157,   158,   158,   158,   159,   159,   159,   160,   160,\r
-   161,   162,   162,   162,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   163,   163,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   163,   163,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   163,   163,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   163,   163,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   163,   163,   163,   163,   163,   163,   163,   163,\r
-   163,   163,   164,   164,   165,   165,   166,   166,   167,   168,\r
-   168,   168,   169,   169,   170,   170,   171,   172,   172,   173,\r
-   173,   174,   174,   174,   174,   174,   174,   174,   174,   174,\r
-   174,   174,   174,   174,   174,   174,   174,   174,   174,   175,\r
-   175,   176,   177,   178,   178,   179,   179,   179,   179,   180,\r
-   181,   182,   182,   183,   183,   183,   184,   184,   184,   184,\r
-   184,   185,   185,   185,   185,   185,   185,   185,   185,   185,\r
-   185,   186,   186,   187,   187,   187,   187,   187,   187,   187,\r
-   188,   188,   189,   190,   191,   191,   192,   193,   193,   194,\r
-   195,   195,   196,   196,   197,   198,   198,   199,   199,   200,\r
-   201,   201,   201,   202,   202,   203,   203,   204,   205,   206,\r
-   206,   207,   207,   207,   208,   208,   209,   209,   210,   211,\r
-   211,   211,   211,   211,   211,   211,   211,   211,   211,   212,\r
-   213,   213,   214,   214\r
+   144,   145,   145,   145,   145,   145,   145,   145,   146,   146,\r
+   146,   146,   146,   146,   147,   147,   147,   148,   148,   148,\r
+   148,   148,   148,   148,   148,   148,   149,   150,   151,   152,\r
+   153,   154,   155,   155,   156,   157,   157,   157,   158,   158,\r
+   158,   158,   159,   159,   159,   160,   160,   160,   161,   161,\r
+   162,   163,   163,   163,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   164,   164,   164,   164,   164,\r
+   164,   164,   164,   164,   164,   165,   165,   166,   166,   167,\r
+   167,   168,   169,   169,   169,   170,   170,   171,   171,   172,\r
+   173,   173,   174,   174,   175,   175,   175,   175,   175,   175,\r
+   175,   175,   175,   175,   175,   175,   175,   175,   175,   175,\r
+   175,   175,   176,   176,   177,   178,   179,   179,   180,   180,\r
+   180,   180,   181,   182,   183,   183,   184,   184,   184,   185,\r
+   185,   185,   185,   185,   186,   186,   186,   186,   186,   186,\r
+   186,   186,   186,   186,   186,   187,   187,   188,   188,   188,\r
+   188,   188,   188,   188,   189,   189,   190,   191,   192,   192,\r
+   193,   194,   194,   195,   196,   196,   197,   197,   198,   199,\r
+   199,   200,   200,   201,   202,   202,   202,   203,   203,   204,\r
+   204,   205,   206,   207,   207,   208,   208,   208,   209,   209,\r
+   210,   210,   211,   212,   212,   212,   212,   212,   212,   212,\r
+   212,   212,   212,   213,   214,   214,   215,   215\r
 };\r
 \r
 static const short yyr2[] = {     0,\r
@@ -518,333 +520,327 @@ static const short yyr2[] = {     0,
      1,     1,     4,     4,     4,     4,     4,     1,     4,     1,\r
      4,     5,     1,     1,     4,     1,     1,     1,     1,     1,\r
      1,     1,     4,     1,     1,     1,     1,     1,     1,     1,\r
-     4,     1,     1,     4,     4,     4,     4,     1,     1,     4,\r
-     4,     1,     0,     1,     0,     2,     4,     3,     5,     0,\r
-     2,     1,     1,     3,     3,     1,     5,     1,     3,     0,\r
-     1,     1,     1,     1,     5,     3,     3,     3,     3,     3,\r
-     3,     3,     3,     2,     2,     2,     4,     4,     3,     1,\r
-     3,     1,     4,     0,     2,     2,     3,     2,     1,     4,\r
-     7,     0,     1,     0,     1,     1,     1,     1,     1,     1,\r
-     1,     1,     1,     1,     2,     2,     1,     1,     1,     1,\r
-     1,     0,     1,     1,     2,     2,     2,     2,     1,     1,\r
-     2,     2,     2,     4,     0,     2,     2,     2,     2,     2,\r
-     2,     3,     2,     3,     5,     0,     2,     2,     2,     2,\r
-     5,     7,     1,     2,     2,     2,     2,     2,     4,     2,\r
-     2,     1,     1,     3,     1,     3,     1,     1,     5,     1,\r
-     1,     1,     2,     1,     2,     1,     2,     1,     2,     4,\r
-     5,    10,     1,     3\r
+     1,     1,     4,     1,     1,     4,     4,     4,     1,     4,\r
+     1,     1,     4,     4,     1,     0,     1,     0,     2,     4,\r
+     3,     5,     0,     2,     1,     1,     3,     3,     1,     5,\r
+     1,     3,     0,     1,     1,     1,     1,     5,     3,     3,\r
+     3,     3,     3,     3,     3,     3,     2,     2,     2,     4,\r
+     4,     3,     1,     3,     1,     4,     0,     2,     2,     3,\r
+     2,     1,     4,     7,     0,     1,     0,     1,     1,     1,\r
+     1,     1,     1,     1,     1,     1,     1,     2,     2,     1,\r
+     1,     1,     1,     1,     1,     0,     1,     1,     2,     2,\r
+     2,     2,     1,     1,     2,     2,     2,     4,     0,     2,\r
+     2,     2,     2,     2,     2,     3,     2,     3,     5,     0,\r
+     2,     2,     2,     2,     5,     7,     1,     2,     2,     2,\r
+     2,     2,     4,     2,     2,     1,     1,     3,     1,     3,\r
+     1,     1,     5,     1,     1,     1,     2,     1,     2,     1,\r
+     2,     1,     2,     4,     5,    10,     1,     3\r
 };\r
 \r
 static const short yydefact[] = {     2,\r
-     1,     0,     0,     0,   164,     0,     0,     0,   164,    49,\r
-   164,    18,     0,     8,    20,     9,    23,     9,     7,     0,\r
-     0,     0,     0,     0,     5,     0,     0,   213,     0,   206,\r
-     4,     3,     0,     6,     0,     0,     0,   231,   179,   172,\r
-   190,     0,   178,   164,   180,   177,   181,   182,   184,   189,\r
-   182,   182,     0,   182,   164,   164,     0,   230,   173,   234,\r
-   232,   174,   236,     0,   238,     0,   198,   199,   165,   166,\r
-     0,     0,     0,   208,   209,     0,     0,    50,     0,    55,\r
+     1,     0,     0,     0,   167,     0,     0,     0,   167,    49,\r
+   167,    18,     0,     8,    20,     9,    23,     9,     7,     0,\r
+     0,     0,     0,     0,     5,     0,     0,   217,     0,   210,\r
+     4,     3,     0,     6,     0,     0,     0,   235,   183,   175,\r
+   194,     0,   182,   167,   184,   181,   185,   186,   188,   193,\r
+   186,   186,     0,   186,   167,   167,   180,   234,   176,   238,\r
+   236,   177,   240,     0,   242,     0,   202,   203,   168,   169,\r
+     0,     0,     0,   212,   213,     0,     0,    50,     0,    55,\r
     56,     0,     0,    59,    60,    61,    62,    63,     0,     0,\r
     67,     0,     0,    71,    72,     0,     0,     0,     0,     0,\r
     78,     0,    80,     0,     0,    83,    84,     0,    86,    87,\r
     88,    89,    90,    91,    92,     0,    94,    95,    96,    97,\r
-    98,   227,    99,   100,     0,   102,   103,     0,     0,     0,\r
-   228,     0,   108,   109,     0,     0,     0,    52,   112,     0,\r
-     0,     0,     0,     0,     0,   193,   200,   210,   218,    19,\r
-    21,    22,   195,   215,     0,   214,     0,     0,    15,    24,\r
-    25,    26,   233,   235,   183,   188,   187,   186,   175,   185,\r
-   237,   239,   176,   167,   168,   169,   170,   171,     0,     0,\r
-   120,     0,    28,   154,     0,     0,   154,     0,     0,     0,\r
+    98,    99,   100,   101,   102,     0,   104,   105,     0,     0,\r
+     0,   109,     0,   111,   112,     0,     0,     0,    52,   115,\r
+     0,     0,     0,     0,     0,     0,   197,   204,   214,   222,\r
+    19,    21,    22,   199,   219,     0,   218,     0,     0,    15,\r
+    24,    25,    26,   237,   239,   187,   192,   191,   190,   178,\r
+   189,   241,   243,   179,   170,   171,   172,   173,   174,     0,\r
+     0,   123,     0,    28,   157,     0,     0,   157,     0,     0,\r
      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\r
-     0,   130,     0,   130,     0,     0,     0,     0,     0,     0,\r
-     0,    51,    29,    14,     0,    12,    11,    10,    13,    32,\r
-   191,   192,    30,   216,   217,    31,    49,     0,    49,     0,\r
-   207,    15,    49,     0,    27,     0,   122,   123,   126,   153,\r
-    49,     0,     0,     0,   222,   223,   225,   240,    49,    49,\r
-     0,   134,   132,   133,     0,     0,     0,     0,     0,   152,\r
-     0,   150,     0,     0,     0,     0,     0,     0,     0,     0,\r
-     0,     0,     0,     0,     0,     0,     0,   128,   131,     0,\r
-     0,     0,     0,     0,     0,   243,     0,     0,    53,     0,\r
-   194,     0,   196,   201,     0,     0,     0,    49,     0,    49,\r
-   219,    17,     0,     0,   119,   127,   121,     0,   159,   229,\r
-     0,    50,   155,     0,   221,   220,     0,     0,     0,   241,\r
-    57,     0,   145,   146,   144,     0,     0,     0,     0,     0,\r
-     0,     0,     0,     0,     0,     0,     0,    58,    65,    64,\r
-    66,    68,    69,    70,    73,    74,    75,    76,    77,    79,\r
-    81,     0,   130,    85,    93,   101,   104,   105,   106,   107,\r
-     0,   110,   111,    54,   197,   203,     0,   202,   205,     0,\r
-    15,   211,   113,    16,   124,   125,   238,   158,   156,   224,\r
-   226,   162,     0,   149,     0,   142,   143,   136,   137,   139,\r
-   138,   140,   141,     0,   151,    82,   129,   244,    43,   204,\r
-    49,   114,     0,   157,     0,   163,   148,   147,     0,   130,\r
-   160,   212,     0,   115,   135,     0,     0,    46,    33,     0,\r
-    45,     0,    44,   230,     0,    38,    34,    36,     0,     0,\r
-     0,     0,   242,   116,    47,     0,   161,     0,     0,    43,\r
-     0,    49,    48,    37,    43,    33,    40,    49,   118,    33,\r
-    39,     0,   117,     0,    42,    41,     0,     0,     0\r
+     0,     0,   133,     0,   133,     0,     0,     0,     0,     0,\r
+     0,     0,    51,    29,    14,     0,    12,    11,    10,    13,\r
+    32,   195,   196,    30,   220,   221,    31,    49,     0,    49,\r
+     0,   211,    15,    49,     0,    27,     0,   125,   126,   129,\r
+   156,    49,     0,     0,     0,   226,   227,   229,   244,    49,\r
+    49,     0,   137,   135,   136,     0,     0,     0,     0,     0,\r
+   155,     0,   153,     0,     0,     0,     0,     0,     0,     0,\r
+     0,     0,     0,     0,     0,     0,     0,     0,   131,   134,\r
+   231,   232,     0,     0,     0,     0,     0,     0,   247,     0,\r
+     0,    53,     0,   198,     0,   200,   205,     0,     0,     0,\r
+    49,     0,    49,   223,    17,     0,     0,   122,   130,   124,\r
+     0,   162,   233,     0,    50,   158,     0,   225,   224,     0,\r
+     0,     0,   245,    57,     0,   148,   149,   147,     0,     0,\r
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\r
+    58,    65,    64,    66,    68,    69,    70,    73,    74,    75,\r
+    76,    77,    79,    81,     0,   133,    85,    93,   103,   106,\r
+   107,   108,   110,     0,   113,   114,    54,   201,   207,     0,\r
+   206,   209,     0,    15,   215,   116,    16,   127,   128,   242,\r
+   161,   159,   228,   230,   165,     0,   152,     0,   145,   146,\r
+   139,   140,   142,   141,   143,   144,     0,   154,    82,   132,\r
+   248,    43,   208,    49,   117,     0,   160,     0,   166,   151,\r
+   150,     0,   133,   163,   216,     0,   118,   138,     0,     0,\r
+    46,    33,     0,    45,     0,    44,   234,     0,    38,    34,\r
+    36,     0,     0,     0,     0,   246,   119,    47,     0,   164,\r
+     0,     0,    43,     0,    49,    48,    37,    43,    33,    40,\r
+    49,   121,    33,    39,     0,   120,     0,    42,    41,     0,\r
+     0,     0\r
 };\r
 \r
-static const short yydefgoto[] = {   457,\r
-     1,   140,   233,   302,    15,    16,    17,   145,    18,    19,\r
-   425,   426,   427,   428,   411,   417,   303,    78,   137,   138,\r
-   403,   420,   434,    21,   236,   237,   238,    60,   277,   278,\r
-   260,   261,   262,    23,   241,   313,   314,   304,   405,    71,\r
-   245,    61,   166,    62,   146,    24,   216,   227,   293,    26,\r
-    27,   229,   298,    28,   158,    29,    30,   217,   218,   149,\r
-    33,   219,   246,   247,   248,   139,    63,   430,    36,    65,\r
-   287\r
+static const short yydefgoto[] = {   460,\r
+     1,   141,   234,   305,    15,    16,    17,   146,    18,    19,\r
+   428,   429,   430,   431,   414,   420,   306,    78,   138,   139,\r
+   406,   423,   437,    21,   237,   238,   239,    60,   278,   279,\r
+   261,   262,   263,    23,   242,   316,   317,   307,   408,    71,\r
+   246,    61,   167,    62,   147,    24,   217,   228,   296,    26,\r
+    27,   230,   301,    28,   159,    29,    30,   218,   219,   150,\r
+    33,   220,   247,   248,   249,   140,    63,   433,    36,    65,\r
+   290\r
 };\r
 \r
 static const short yypact[] = {-32768,\r
-   609,   598,   -98,   138,   144,    22,    30,   172,   144,   -61,\r
-   144,-32768,   791,-32768,-32768,-32768,-32768,-32768,-32768,    35,\r
-   -49,   -42,   -32,   -14,-32768,   -24,    -5,-32768,    32,    -3,\r
--32768,-32768,    44,-32768,    49,    59,    68,-32768,-32768,-32768,\r
--32768,   598,-32768,   185,-32768,-32768,-32768,    63,-32768,-32768,\r
-    63,    63,    27,    63,   220,   260,    27,-32768,-32768,-32768,\r
--32768,-32768,-32768,    17,-32768,   176,-32768,-32768,-32768,-32768,\r
-    69,   598,    74,-32768,-32768,    85,   598,-32768,   -73,-32768,\r
--32768,    53,    76,-32768,-32768,-32768,-32768,-32768,   102,   106,\r
--32768,   115,   118,-32768,-32768,   121,   124,   134,   136,   148,\r
--32768,   157,-32768,   158,   159,-32768,-32768,   160,-32768,-32768,\r
--32768,-32768,-32768,-32768,-32768,   161,-32768,-32768,-32768,-32768,\r
--32768,-32768,-32768,-32768,   162,-32768,-32768,   165,   169,   178,\r
--32768,   180,-32768,-32768,   182,   183,   -87,-32768,-32768,   505,\r
-   587,   271,   234,   275,   174,-32768,-32768,-32768,-32768,-32768,\r
--32768,-32768,-32768,-32768,   231,-32768,   280,   186,-32768,-32768,\r
--32768,-32768,-32768,   187,-32768,-32768,-32768,-32768,-32768,-32768,\r
-   187,   -72,-32768,-32768,-32768,-32768,-32768,-32768,   184,   194,\r
-    17,    17,-32768,-32768,   267,   197,-32768,    17,   389,   329,\r
-   311,   313,   337,   389,   324,   330,   389,   331,   389,    17,\r
-   293,   389,   -58,   389,   389,   598,   598,   340,   344,   598,\r
-   791,   213,-32768,-32768,    51,-32768,-32768,-32768,-32768,-32768,\r
--32768,-32768,-32768,-32768,-32768,-32768,   149,   212,   -50,   217,\r
--32768,-32768,   634,   389,-32768,   218,   233,-32768,   215,-32768,\r
-   -20,    -6,   267,   267,-32768,-32768,-32768,   236,   -61,   129,\r
-   223,-32768,-32768,-32768,   225,   389,   389,   389,   477,   104,\r
-   -90,-32768,   226,   232,   239,   240,   242,   244,   246,   247,\r
-   250,   251,   254,   255,   256,   361,   -64,-32768,   104,   257,\r
-   -62,    71,   262,   264,   265,   237,   269,   274,-32768,   791,\r
--32768,   -11,-32768,-32768,   270,   598,   278,   151,   301,   676,\r
--32768,-32768,   598,   281,-32768,-32768,    17,   389,-32768,-32768,\r
-   598,   283,-32768,   284,-32768,-32768,   294,   267,   295,-32768,\r
--32768,   598,   276,   276,   276,    91,   298,   389,   389,   389,\r
-   389,   389,   389,   389,   389,   389,   389,-32768,-32768,-32768,\r
+   514,   533,  -109,   177,   188,    15,    30,   207,   188,   -79,\r
+   188,-32768,   742,-32768,-32768,-32768,-32768,-32768,-32768,    24,\r
+   -83,   -54,   -36,   -20,-32768,   -27,    -5,-32768,   -11,     2,\r
+-32768,-32768,    17,-32768,     6,    42,    60,-32768,-32768,-32768,\r
+-32768,   533,-32768,   215,-32768,-32768,-32768,    54,-32768,-32768,\r
+    54,    54,    29,    54,   265,   270,    29,-32768,-32768,-32768,\r
+-32768,-32768,-32768,   299,-32768,   175,-32768,-32768,-32768,-32768,\r
+    66,   533,    83,-32768,-32768,    91,   533,-32768,   -74,-32768,\r
+-32768,    96,    98,-32768,-32768,-32768,-32768,-32768,   102,   117,\r
+-32768,   119,   126,-32768,-32768,   129,   131,   141,   145,   151,\r
+-32768,   160,-32768,   161,   162,-32768,-32768,   163,-32768,-32768,\r
+-32768,-32768,-32768,-32768,-32768,   164,-32768,-32768,-32768,-32768,\r
+-32768,-32768,-32768,-32768,-32768,   167,-32768,-32768,   178,   180,\r
+   182,-32768,   184,-32768,-32768,   186,   187,   -88,-32768,-32768,\r
+   498,   595,   274,   306,   279,   189,-32768,-32768,-32768,-32768,\r
+-32768,-32768,-32768,-32768,-32768,   225,-32768,   284,   191,-32768,\r
+-32768,-32768,-32768,-32768,   192,-32768,-32768,-32768,-32768,-32768,\r
+-32768,   192,   -71,-32768,-32768,-32768,-32768,-32768,-32768,   183,\r
+   194,   299,   299,-32768,-32768,   394,   198,-32768,   299,   220,\r
+   106,   316,   326,   130,   220,   328,   329,   220,   330,   220,\r
+   299,   287,   220,   -45,   220,   220,   533,   533,   332,   336,\r
+   533,   742,   204,-32768,-32768,    32,-32768,-32768,-32768,-32768,\r
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,   152,   203,   -57,\r
+   212,-32768,-32768,   616,   220,-32768,   213,   237,-32768,   214,\r
+-32768,   -30,    -9,   394,   394,-32768,-32768,-32768,   239,   -79,\r
+   -10,   235,-32768,-32768,-32768,   240,   220,   220,   220,   472,\r
+   357,   -61,-32768,   241,   243,   244,   247,   254,   255,   257,\r
+   258,   268,   269,   271,   276,   281,   372,   -50,-32768,   357,\r
+-32768,-32768,   282,   -46,    72,   283,   288,   289,   262,   292,\r
+   293,-32768,   742,-32768,   -14,-32768,-32768,   290,   533,   296,\r
+   154,   358,   626,-32768,-32768,   533,   298,-32768,-32768,   299,\r
+   220,-32768,-32768,   533,   301,-32768,   302,-32768,-32768,   297,\r
+   394,   303,-32768,-32768,   533,   294,   294,   294,   238,   304,\r
+   220,   220,   220,   220,   220,   220,   220,   220,   220,   220,\r
 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,\r
--32768,   299,   389,-32768,-32768,-32768,-32768,-32768,-32768,-32768,\r
-   407,-32768,-32768,-32768,-32768,-32768,   267,-32768,-32768,   307,\r
--32768,-32768,   341,-32768,-32768,-32768,   312,-32768,-32768,-32768,\r
--32768,    17,   309,-32768,   389,   276,   276,   245,    36,    58,\r
-    58,    12,    12,   297,-32768,-32768,-32768,-32768,   315,-32768,\r
-   684,-32768,   267,-32768,   321,-32768,-32768,   276,   389,   483,\r
--32768,-32768,   326,-32768,   104,    54,   -71,-32768,   230,    -2,\r
--32768,   389,   323,   -55,   314,-32768,   347,-32768,   598,   267,\r
-   389,   334,-32768,-32768,   104,   389,-32768,   355,   267,   -45,\r
-   352,   -66,   104,-32768,   -27,   230,-32768,   -66,-32768,   230,\r
--32768,   335,-32768,   350,-32768,-32768,   446,   468,-32768\r
+-32768,-32768,-32768,-32768,   307,   220,-32768,-32768,-32768,-32768,\r
+-32768,-32768,-32768,   436,-32768,-32768,-32768,-32768,-32768,   394,\r
+-32768,-32768,   314,-32768,-32768,   353,-32768,-32768,-32768,   318,\r
+-32768,-32768,-32768,-32768,   299,   321,-32768,   220,   294,   294,\r
+    31,    59,    35,    35,    18,    18,   260,-32768,-32768,-32768,\r
+-32768,   319,-32768,   636,-32768,   394,-32768,   322,-32768,-32768,\r
+   294,   220,   407,-32768,-32768,   331,-32768,   357,    49,   -72,\r
+-32768,   234,   -16,-32768,   220,   324,   -34,   325,-32768,   342,\r
+-32768,   533,   394,   220,   339,-32768,-32768,   357,   220,-32768,\r
+   349,   394,    -4,   346,   -98,   357,-32768,    56,   234,-32768,\r
+   -98,-32768,   234,-32768,   333,-32768,   355,-32768,-32768,   464,\r
+   491,-32768\r
 };\r
 \r
 static const short yypgoto[] = {-32768,\r
--32768,   467,  -222,    18,-32768,-32768,   191,-32768,-32768,-32768,\r
-  -322,-32768,-32768,    56,  -395,-32768,    -8,    -1,-32768,  -186,\r
--32768,-32768,-32768,-32768,-32768,-32768,   188,     5,   292,  -336,\r
-  -163,-32768,  -181,-32768,   316,  -343,  -201,   200,-32768,    29,\r
-   -63,-32768,   103,    78,-32768,-32768,   499,-32768,-32768,   -13,\r
--32768,-32768,-32768,-32768,-32768,   -12,-32768,   500,     4,-32768,\r
--32768,   501,   266,  -229,-32768,   303,    10,     1,-32768,     3,\r
+-32768,   475,  -220,     8,-32768,-32768,   193,-32768,-32768,-32768,\r
+  -236,-32768,-32768,    55,  -380,-32768,    -8,    -1,-32768,  -198,\r
+-32768,-32768,-32768,-32768,-32768,-32768,   195,     5,   308,  -329,\r
+  -167,-32768,  -179,-32768,   309,  -365,  -206,   197,-32768,    21,\r
+   -63,-32768,    63,   171,-32768,-32768,   500,-32768,-32768,   -13,\r
+-32768,-32768,-32768,-32768,-32768,   -12,-32768,   501,     4,-32768,\r
+-32768,   502,   266,  -227,-32768,   311,    10,     1,-32768,     3,\r
 -32768\r
 };\r
 \r
 \r
-#define        YYLAST          909\r
+#define        YYLAST          861\r
 \r
 \r
 static const short yytable[] = {    20,\r
-   179,    77,    64,    37,    32,    22,   147,   148,   264,   300,\r
-    35,   268,   269,   316,   317,   272,   397,   274,    14,   174,\r
-   175,   328,   329,   431,   289,   242,   295,   297,     4,   337,\r
-   186,  -165,   211,   122,    66,   432,    73,    76,   279,    79,\r
-   279,   282,   163,   338,   447,   328,   329,   319,   422,   451,\r
-   212,   131,   305,    72,    41,   353,   252,   353,   253,   254,\r
-     8,   187,  -165,   142,   -35,   309,   423,   328,   329,   354,\r
-    13,   356,   182,   418,     4,    13,   176,   185,   -35,   142,\r
-   328,   329,   150,    76,    79,    48,    13,   446,   381,   151,\r
-     4,   410,   323,   324,   325,   326,    49,    50,   449,   152,\r
-   328,   329,    51,   364,   453,   450,     8,   154,   143,   410,\r
-   177,   309,   144,   328,   329,   310,    13,   239,   240,   243,\r
-   153,    52,     8,   452,   251,    54,   376,   454,   144,   155,\r
-   169,   178,   165,   433,   173,   157,   275,   399,   215,   215,\r
-    67,    68,    37,    37,    22,    22,    69,    70,   401,    35,\r
-    35,   255,   336,   167,   168,   395,   170,   214,   214,   332,\r
-   333,   334,   335,   156,   386,   387,   388,   389,   390,   391,\r
-   392,   393,   394,   413,    74,    75,   336,   256,   159,   257,\r
-   160,   258,   180,   334,   335,   188,   259,   164,    70,   279,\r
-   161,   421,   330,   331,   332,   333,   334,   335,   336,   162,\r
-   440,   147,   148,   181,   357,   183,   283,   284,   189,   445,\r
-   288,   336,   330,   331,   332,   333,   334,   335,   292,   184,\r
-   296,   408,   171,    70,   384,   330,   331,   332,   333,   334,\r
-   335,   336,   311,    38,   190,    37,   223,    22,   191,   312,\r
-   296,   311,    35,   239,   336,   415,   279,   192,   312,    39,\r
-   193,    40,   324,   194,   328,   329,   195,    41,   435,   327,\r
-   309,    42,   172,    70,   320,    13,   196,   441,   197,   174,\r
-   175,    43,   443,   221,   222,    44,    45,   224,   225,    46,\r
-   198,    47,   230,   231,   291,    13,   369,    13,    48,   199,\r
-   200,   201,   202,   203,   204,   365,   367,   205,   242,    49,\r
-    50,   206,    37,   373,    22,    51,   328,   329,   226,    35,\r
-   207,   367,   208,   377,   209,   210,   228,   265,   406,   266,\r
-   232,  -165,   383,   234,    52,    53,   176,   235,    54,   249,\r
-   270,   252,    55,   253,   254,   263,   271,   273,    56,   252,\r
-    57,   253,   254,   267,   276,   424,    59,   285,   286,   290,\r
-   294,   299,   307,   306,   308,   318,   321,   322,    38,   339,\r
-   177,   328,   329,   352,     7,   340,    13,   331,   332,   333,\r
-   334,   335,   341,   342,    39,   343,    40,   344,   361,   345,\r
-   346,   178,    41,   347,   348,   336,    42,   349,   350,   351,\r
-   355,   252,   243,   253,   254,   358,    43,   359,   360,   244,\r
-    44,    45,   362,    37,    46,    22,    47,   363,   366,   368,\r
-    35,   398,   374,    48,   378,   379,   336,   429,   330,   331,\r
-   332,   333,   334,   335,    49,    50,   255,   380,   382,   439,\r
-    51,   385,   396,   311,   255,   409,   429,   336,   400,   311,\r
-   312,   402,   407,   404,   429,   458,   312,   437,   429,    52,\r
-    53,   410,   256,    54,   257,   414,   258,    55,   419,   436,\r
-   256,   259,   257,    56,   258,    57,   438,   459,   455,   259,\r
-    58,    59,   442,   330,   331,   332,   333,   334,   335,   252,\r
-    38,   253,   254,   456,   141,   252,   255,   253,   254,   371,\r
-   448,    13,   336,   444,   375,   281,    39,   370,    40,    25,\r
-    31,    34,   250,     0,    41,   280,     0,   315,    42,     0,\r
-     0,     0,   256,   213,   257,     0,   258,     0,    43,     0,\r
-     0,   259,    44,    45,     0,     0,    46,     0,    47,     0,\r
-     0,     0,     0,     0,     0,    48,     2,     0,     0,     0,\r
-     0,     3,     0,     0,     4,     0,    49,    50,     0,     0,\r
-     5,     0,    51,     6,     0,     0,     0,     0,     0,     0,\r
-     0,     0,     0,     0,     0,     0,     0,     0,     7,     0,\r
-     0,    52,    53,     0,   255,    54,     8,     0,     0,    55,\r
-   255,     0,     0,     0,     0,    56,     0,    57,     0,     0,\r
-     0,     0,    58,    59,     0,     0,     0,     0,     0,     0,\r
-   256,    38,   257,     0,   258,     0,   256,     9,   416,   259,\r
-   258,     0,    10,    11,     0,   259,     0,    39,     2,    40,\r
-     0,     0,     0,     3,     0,    41,     4,     0,     0,    42,\r
-     0,     0,     5,     0,     0,     6,    12,     0,     0,    43,\r
-     2,    13,     0,    44,    45,     3,     0,    46,     4,    47,\r
-     7,     0,     0,     0,     5,     0,    48,     6,     8,     0,\r
-     0,     0,     0,     0,     0,     2,     0,    49,    50,     0,\r
-     3,     0,     7,    51,     0,     0,     0,     0,     0,     5,\r
-     8,     0,     6,     0,     0,     0,     0,     0,     0,     9,\r
-     0,     0,    52,    53,    10,    11,    54,     7,     0,     0,\r
-    55,     0,     0,     0,     0,     0,    56,     2,    57,     0,\r
-     0,     9,     3,    58,    59,     2,    10,    11,    12,     0,\r
-     3,     5,   220,    13,     6,     0,     0,     0,     0,     5,\r
-     0,     0,     6,     0,     0,     0,     9,     0,     0,     7,\r
-    12,    10,    11,     0,     0,    13,     0,     7,     0,     0,\r
-     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\r
-     0,     0,     0,     0,     0,    12,     0,     0,     0,   301,\r
-    13,     0,     0,     0,     0,     0,     0,     0,     9,     0,\r
-     0,     0,     0,    10,    11,     0,     9,     0,     0,     0,\r
-     0,    10,    11,     0,     0,     0,     0,     0,     0,     0,\r
-     0,     0,     0,     0,     0,     0,    80,    12,    81,     0,\r
-     0,   372,    13,     0,    82,    12,    83,     0,     0,   412,\r
-    13,     0,     0,    84,    85,    86,    87,     0,    88,    89,\r
-     0,    90,     0,    91,    92,    93,     0,     0,    94,     0,\r
-     0,    95,     0,    96,    97,    98,    99,   100,   101,     0,\r
-   102,   103,   104,   105,     0,     0,   106,     0,     0,   107,\r
-     0,     0,     0,   108,     0,   109,     0,     0,     0,   110,\r
-   111,   112,   113,   114,   115,   116,     0,   117,   118,   119,\r
-   120,   121,   122,   123,   124,     0,     0,   125,     0,     0,\r
-   126,     0,   127,     0,     0,   128,   129,   130,     0,     0,\r
-   131,     0,   132,   133,   134,   135,     0,     0,   136\r
+   180,    77,    64,    37,    32,    22,   148,   149,    14,   434,\r
+    35,   265,   303,   292,   269,   270,   319,   320,   273,   298,\r
+   275,   435,   243,   300,    66,     4,   400,   331,   332,    76,\r
+   187,    79,   212,  -168,   312,   280,    73,   280,   285,    13,\r
+   331,   332,   164,   322,   331,   332,    72,   281,   425,   151,\r
+   213,   253,   143,   254,   255,   308,    41,     8,    13,   340,\r
+   143,   188,   450,     4,  -168,   282,   426,   454,   331,   332,\r
+   356,     4,   183,   341,   356,    76,    79,   186,   152,   452,\r
+    13,   331,   332,   421,   357,   456,   -35,    48,   359,   326,\r
+   327,   328,   329,   384,   367,     8,   153,   144,    49,    50,\r
+   -35,   145,   312,     8,    51,   155,   313,    13,   253,   145,\r
+   254,   255,   264,   168,   169,   154,   171,   244,   240,   241,\r
+   436,   157,   312,   166,    52,   252,   323,    13,    54,   449,\r
+   156,   379,   253,   413,   254,   255,   268,   276,   161,   216,\r
+   216,   158,   402,    37,    37,    22,    22,   256,   215,   215,\r
+    35,    35,   160,   404,   334,   335,   336,   337,   338,   339,\r
+   398,   337,   338,   389,   390,   391,   392,   393,   394,   395,\r
+   396,   397,   339,   257,   162,   258,   339,   259,   416,    67,\r
+    68,   181,   260,   335,   336,   337,   338,   424,   280,   453,\r
+    69,    70,   163,   413,   333,   334,   335,   336,   337,   338,\r
+   339,   182,   148,   149,   256,   443,   360,   286,   287,    74,\r
+    75,   291,   455,   339,   448,   184,   457,   165,    70,   295,\r
+   411,   299,   253,   170,   254,   255,   185,   174,   256,   189,\r
+   257,   190,   258,   314,   259,   191,    37,    38,    22,   260,\r
+   315,   299,   314,    35,   418,   280,   240,   331,   332,   315,\r
+   192,   327,   193,    39,   257,    40,   258,   438,   259,   194,\r
+   330,    41,   195,   260,   196,    42,   444,   172,    70,   331,\r
+   332,   446,   173,    70,   197,    43,   222,   223,   198,    44,\r
+    45,   225,   226,    46,   199,    47,   231,   232,   294,    13,\r
+   372,    13,    48,   200,   201,   202,   203,   204,   368,   370,\r
+   205,   175,   176,    49,    50,    37,   376,    22,   224,    51,\r
+   229,   206,    35,   207,   370,   208,   380,   209,   256,   210,\r
+   211,   409,   266,   235,   227,   386,   233,  -168,   236,    52,\r
+    53,   250,   267,    54,   271,   272,   274,    55,   277,   288,\r
+   289,   293,   297,    56,   257,    57,   258,   302,   259,   309,\r
+   427,    59,    38,   260,   311,   331,   332,   310,   177,   321,\r
+   333,   334,   335,   336,   337,   338,   331,   332,    39,   324,\r
+    40,    13,   387,   325,   355,   342,    41,   343,   344,   339,\r
+    42,   345,   333,   334,   335,   336,   337,   338,   346,   347,\r
+    43,   348,   349,   178,    44,    45,   175,   176,    46,   412,\r
+    47,   339,   350,   351,   364,   352,    37,    48,    22,   253,\r
+   353,   254,   255,    35,   179,   354,   358,   361,    49,    50,\r
+   432,     7,   362,   363,    51,   243,   365,   366,   371,   369,\r
+   377,   383,   442,   381,   382,   339,   314,   385,   388,   432,\r
+   401,   399,   314,   315,    52,    53,   403,   432,    54,   315,\r
+   407,   432,    55,   177,   405,   410,   413,   417,    56,   440,\r
+    57,   439,   441,   461,   422,    58,    59,   458,   333,   334,\r
+   335,   336,   337,   338,   253,    38,   254,   255,   445,   333,\r
+   334,   335,   336,   337,   338,   451,    13,   339,   178,   459,\r
+   462,    39,   142,    40,   374,   447,   251,   373,   339,    41,\r
+    25,    31,    34,    42,   378,   256,   214,     0,   318,   179,\r
+     0,     0,   284,    43,   283,     0,     0,    44,    45,     0,\r
+   244,    46,     0,    47,     0,     0,     0,   245,     0,     2,\r
+    48,   257,     0,   419,     3,   259,    38,     4,     0,     0,\r
+   260,    49,    50,     5,     0,     2,     6,    51,     0,     0,\r
+     3,     0,    39,     4,    40,     0,     0,     0,     0,     5,\r
+    41,     7,     6,     0,    42,     0,     0,    52,    53,     8,\r
+   256,    54,     0,     0,    43,    55,     0,     7,    44,    45,\r
+     0,    56,    46,    57,    47,     8,     0,     0,    58,    59,\r
+     0,    48,     0,     0,     0,     0,   257,     0,   258,     0,\r
+   259,     9,    49,    50,     0,   260,    10,    11,    51,     0,\r
+     0,     0,     0,     0,     0,     0,     0,     9,     0,     0,\r
+     0,     0,    10,    11,     0,     0,     2,     0,    52,    53,\r
+    12,     3,    54,     0,     4,    13,    55,     0,     0,     0,\r
+     5,     0,    56,     6,    57,     0,    12,     2,     0,    58,\r
+    59,    13,     3,     0,     0,     0,     0,     2,     7,     0,\r
+     0,     5,     3,     0,     6,     0,     8,     2,     0,     0,\r
+     0,     5,     3,     0,     6,     0,     0,     0,     0,     7,\r
+     0,     5,     0,     0,     6,     0,     0,     0,     0,     7,\r
+     0,     0,     0,     0,     0,     0,     0,     0,     9,     7,\r
+     0,     0,     0,    10,    11,     0,     0,     0,     0,     0,\r
+     0,     0,     0,     0,     0,     0,     0,     0,     0,     9,\r
+     0,     0,     0,     0,    10,    11,     0,    12,     0,     9,\r
+     0,   221,    13,     0,    10,    11,     0,     0,     0,     9,\r
+     0,     0,     0,     0,    10,    11,     0,     0,    12,     0,\r
+     0,     0,   304,    13,     0,     0,     0,    80,    12,    81,\r
+     0,     0,   375,    13,     0,    82,     0,    83,    12,     0,\r
+     0,     0,   415,    13,    84,    85,    86,    87,     0,    88,\r
+    89,     0,    90,     0,    91,    92,    93,     0,     0,    94,\r
+     0,     0,    95,     0,    96,    97,    98,    99,   100,   101,\r
+     0,   102,   103,   104,   105,     0,     0,   106,     0,     0,\r
+   107,     0,     0,     0,   108,     0,   109,     0,     0,     0,\r
+   110,   111,   112,   113,   114,   115,   116,     0,   117,   118,\r
+   119,   120,   121,   122,   123,   124,   125,     0,     0,   126,\r
+     0,     0,   127,     0,   128,     0,     0,   129,   130,   131,\r
+     0,     0,   132,     0,   133,   134,   135,   136,     0,     0,\r
+   137\r
 };\r
 \r
 static const short yycheck[] = {     1,\r
-    64,    10,     2,     1,     1,     1,    20,    20,   190,   232,\r
-     1,   193,   194,   243,   244,   197,   353,   199,     1,     3,\r
-     4,    10,    11,    26,   211,    32,    77,   229,    40,   120,\r
-   104,   104,   120,    92,   133,    38,     7,     9,   202,    11,\r
-   204,   205,    42,   134,   440,    10,    11,   249,   120,   445,\r
-   138,   110,   234,    32,    28,   120,     3,   120,     5,     6,\r
-    72,   135,   135,    29,   120,   132,   138,    10,    11,   134,\r
-   137,   134,    72,   410,    40,   137,    60,    77,   134,    29,\r
-    10,    11,   132,    55,    56,    59,   137,   133,   318,   132,\r
-    40,   137,   256,   257,   258,   259,    70,    71,   442,   132,\r
-    10,    11,    76,   290,   448,   133,    72,   132,    74,   137,\r
-    94,   132,    78,    10,    11,   136,   137,   181,   182,   126,\r
-   135,    95,    72,   446,   188,    99,   308,   450,    78,   135,\r
-    53,   115,    70,   136,    57,   139,   200,   367,   140,   141,\r
-     3,     4,   140,   141,   140,   141,     3,     4,   371,   140,\r
-   141,    98,   141,    51,    52,   337,    54,   140,   141,   124,\r
-   125,   126,   127,   132,   328,   329,   330,   331,   332,   333,\r
-   334,   335,   336,   403,     3,     4,   141,   124,   135,   126,\r
-   132,   128,     7,   126,   127,   133,   133,     3,     4,   353,\r
-   132,   138,   122,   123,   124,   125,   126,   127,   141,   132,\r
-   430,   215,   215,   135,   134,   132,   206,   207,   133,   439,\r
-   210,   141,   122,   123,   124,   125,   126,   127,   227,   135,\r
-   229,   385,     3,     4,   134,   122,   123,   124,   125,   126,\r
-   127,   141,   241,     4,   133,   233,     3,   233,   133,   241,\r
-   249,   250,   233,   307,   141,   409,   410,   133,   250,    20,\r
-   133,    22,   416,   133,    10,    11,   133,    28,   422,   259,\r
-   132,    32,     3,     4,   136,   137,   133,   431,   133,     3,\r
-     4,    42,   436,     3,     4,    46,    47,     3,     4,    50,\r
-   133,    52,     3,     4,   136,   137,   136,   137,    59,   133,\r
-   133,   133,   133,   133,   133,   292,   296,   133,    32,    70,\r
-    71,   133,   300,   303,   300,    76,    10,    11,   135,   300,\r
-   133,   311,   133,   311,   133,   133,    86,     7,   382,     7,\r
-   135,   135,   322,   140,    95,    96,    60,   134,    99,   133,\r
-     7,     3,   103,     5,     6,     7,     7,     7,   109,     3,\r
-   111,     5,     6,     7,    52,   116,   117,     8,     5,   137,\r
-   139,   135,   120,   136,   140,   120,   134,   133,     4,   134,\r
-    94,    10,    11,     3,    64,   134,   137,   123,   124,   125,\r
-   126,   127,   134,   134,    20,   134,    22,   134,   142,   134,\r
-   134,   115,    28,   134,   134,   141,    32,   134,   134,   134,\r
-   134,     3,   126,     5,     6,   134,    42,   134,   134,   133,\r
-    46,    47,   134,   401,    50,   401,    52,   134,   139,   132,\r
-   401,     5,   132,    59,   132,   132,   141,   419,   122,   123,\r
-   124,   125,   126,   127,    70,    71,    98,   134,   134,   429,\r
-    76,   134,   134,   442,    98,   139,   438,   141,   132,   448,\r
-   442,   101,   134,   132,   446,     0,   448,   134,   450,    95,\r
-    96,   137,   124,    99,   126,   135,   128,   103,   133,   137,\r
-   124,   133,   126,   109,   128,   111,   120,     0,   134,   133,\r
-   116,   117,   139,   122,   123,   124,   125,   126,   127,     3,\r
-     4,     5,     6,   134,    18,     3,    98,     5,     6,   299,\r
-   139,   137,   141,   438,   307,   204,    20,   298,    22,     1,\r
-     1,     1,   187,    -1,    28,   203,    -1,   242,    32,    -1,\r
-    -1,    -1,   124,     9,   126,    -1,   128,    -1,    42,    -1,\r
-    -1,   133,    46,    47,    -1,    -1,    50,    -1,    52,    -1,\r
-    -1,    -1,    -1,    -1,    -1,    59,    32,    -1,    -1,    -1,\r
-    -1,    37,    -1,    -1,    40,    -1,    70,    71,    -1,    -1,\r
-    46,    -1,    76,    49,    -1,    -1,    -1,    -1,    -1,    -1,\r
-    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    64,    -1,\r
-    -1,    95,    96,    -1,    98,    99,    72,    -1,    -1,   103,\r
-    98,    -1,    -1,    -1,    -1,   109,    -1,   111,    -1,    -1,\r
-    -1,    -1,   116,   117,    -1,    -1,    -1,    -1,    -1,    -1,\r
-   124,     4,   126,    -1,   128,    -1,   124,   103,   126,   133,\r
-   128,    -1,   108,   109,    -1,   133,    -1,    20,    32,    22,\r
-    -1,    -1,    -1,    37,    -1,    28,    40,    -1,    -1,    32,\r
-    -1,    -1,    46,    -1,    -1,    49,   132,    -1,    -1,    42,\r
-    32,   137,    -1,    46,    47,    37,    -1,    50,    40,    52,\r
-    64,    -1,    -1,    -1,    46,    -1,    59,    49,    72,    -1,\r
-    -1,    -1,    -1,    -1,    -1,    32,    -1,    70,    71,    -1,\r
-    37,    -1,    64,    76,    -1,    -1,    -1,    -1,    -1,    46,\r
-    72,    -1,    49,    -1,    -1,    -1,    -1,    -1,    -1,   103,\r
-    -1,    -1,    95,    96,   108,   109,    99,    64,    -1,    -1,\r
-   103,    -1,    -1,    -1,    -1,    -1,   109,    32,   111,    -1,\r
-    -1,   103,    37,   116,   117,    32,   108,   109,   132,    -1,\r
-    37,    46,   136,   137,    49,    -1,    -1,    -1,    -1,    46,\r
-    -1,    -1,    49,    -1,    -1,    -1,   103,    -1,    -1,    64,\r
-   132,   108,   109,    -1,    -1,   137,    -1,    64,    -1,    -1,\r
-    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\r
-    -1,    -1,    -1,    -1,    -1,   132,    -1,    -1,    -1,   136,\r
-   137,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   103,    -1,\r
-    -1,    -1,    -1,   108,   109,    -1,   103,    -1,    -1,    -1,\r
-    -1,   108,   109,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\r
-    -1,    -1,    -1,    -1,    -1,    -1,    16,   132,    18,    -1,\r
-    -1,   136,   137,    -1,    24,   132,    26,    -1,    -1,   136,\r
-   137,    -1,    -1,    33,    34,    35,    36,    -1,    38,    39,\r
-    -1,    41,    -1,    43,    44,    45,    -1,    -1,    48,    -1,\r
-    -1,    51,    -1,    53,    54,    55,    56,    57,    58,    -1,\r
-    60,    61,    62,    63,    -1,    -1,    66,    -1,    -1,    69,\r
-    -1,    -1,    -1,    73,    -1,    75,    -1,    -1,    -1,    79,\r
-    80,    81,    82,    83,    84,    85,    -1,    87,    88,    89,\r
-    90,    91,    92,    93,    94,    -1,    -1,    97,    -1,    -1,\r
-   100,    -1,   102,    -1,    -1,   105,   106,   107,    -1,    -1,\r
-   110,    -1,   112,   113,   114,   115,    -1,    -1,   118\r
+    64,    10,     2,     1,     1,     1,    20,    20,     1,    26,\r
+     1,   191,   233,   212,   194,   195,   244,   245,   198,    77,\r
+   200,    38,    32,   230,   134,    40,   356,    10,    11,     9,\r
+   105,    11,   121,   105,   133,   203,     7,   205,   206,   138,\r
+    10,    11,    42,   250,    10,    11,    32,    93,   121,   133,\r
+   139,     3,    29,     5,     6,   235,    28,    72,   138,   121,\r
+    29,   136,   443,    40,   136,   111,   139,   448,    10,    11,\r
+   121,    40,    72,   135,   121,    55,    56,    77,   133,   445,\r
+   138,    10,    11,   413,   135,   451,   121,    59,   135,   257,\r
+   258,   259,   260,   321,   293,    72,   133,    74,    70,    71,\r
+   135,    78,   133,    72,    76,   133,   137,   138,     3,    78,\r
+     5,     6,     7,    51,    52,   136,    54,   127,   182,   183,\r
+   137,   133,   133,    70,    96,   189,   137,   138,   100,   134,\r
+   136,   311,     3,   138,     5,     6,     7,   201,   133,   141,\r
+   142,   140,   370,   141,   142,   141,   142,    99,   141,   142,\r
+   141,   142,   136,   374,   124,   125,   126,   127,   128,   142,\r
+   340,   127,   128,   331,   332,   333,   334,   335,   336,   337,\r
+   338,   339,   142,   125,   133,   127,   142,   129,   406,     3,\r
+     4,     7,   134,   125,   126,   127,   128,   139,   356,   134,\r
+     3,     4,   133,   138,   123,   124,   125,   126,   127,   128,\r
+   142,   136,   216,   216,    99,   433,   135,   207,   208,     3,\r
+     4,   211,   449,   142,   442,   133,   453,     3,     4,   228,\r
+   388,   230,     3,    53,     5,     6,   136,    57,    99,   134,\r
+   125,   134,   127,   242,   129,   134,   234,     4,   234,   134,\r
+   242,   250,   251,   234,   412,   413,   310,    10,    11,   251,\r
+   134,   419,   134,    20,   125,    22,   127,   425,   129,   134,\r
+   260,    28,   134,   134,   134,    32,   434,     3,     4,    10,\r
+    11,   439,     3,     4,   134,    42,     3,     4,   134,    46,\r
+    47,     3,     4,    50,   134,    52,     3,     4,   137,   138,\r
+   137,   138,    59,   134,   134,   134,   134,   134,   295,   299,\r
+   134,     3,     4,    70,    71,   303,   306,   303,     3,    76,\r
+    86,   134,   303,   134,   314,   134,   314,   134,    99,   134,\r
+   134,   385,     7,   141,   136,   325,   136,   136,   135,    96,\r
+    97,   134,     7,   100,     7,     7,     7,   104,    52,     8,\r
+     5,   138,   140,   110,   125,   112,   127,   136,   129,   137,\r
+   117,   118,     4,   134,   141,    10,    11,   121,    60,   121,\r
+   123,   124,   125,   126,   127,   128,    10,    11,    20,   135,\r
+    22,   138,   135,   134,     3,   135,    28,   135,   135,   142,\r
+    32,   135,   123,   124,   125,   126,   127,   128,   135,   135,\r
+    42,   135,   135,    95,    46,    47,     3,     4,    50,   140,\r
+    52,   142,   135,   135,   143,   135,   404,    59,   404,     3,\r
+   135,     5,     6,   404,   116,   135,   135,   135,    70,    71,\r
+   422,    64,   135,   135,    76,    32,   135,   135,   133,   140,\r
+   133,   135,   432,   133,   133,   142,   445,   135,   135,   441,\r
+     5,   135,   451,   445,    96,    97,   133,   449,   100,   451,\r
+   133,   453,   104,    60,   102,   135,   138,   136,   110,   135,\r
+   112,   138,   121,     0,   134,   117,   118,   135,   123,   124,\r
+   125,   126,   127,   128,     3,     4,     5,     6,   140,   123,\r
+   124,   125,   126,   127,   128,   140,   138,   142,    95,   135,\r
+     0,    20,    18,    22,   302,   441,   188,   301,   142,    28,\r
+     1,     1,     1,    32,   310,    99,     9,    -1,   243,   116,\r
+    -1,    -1,   205,    42,   204,    -1,    -1,    46,    47,    -1,\r
+   127,    50,    -1,    52,    -1,    -1,    -1,   134,    -1,    32,\r
+    59,   125,    -1,   127,    37,   129,     4,    40,    -1,    -1,\r
+   134,    70,    71,    46,    -1,    32,    49,    76,    -1,    -1,\r
+    37,    -1,    20,    40,    22,    -1,    -1,    -1,    -1,    46,\r
+    28,    64,    49,    -1,    32,    -1,    -1,    96,    97,    72,\r
+    99,   100,    -1,    -1,    42,   104,    -1,    64,    46,    47,\r
+    -1,   110,    50,   112,    52,    72,    -1,    -1,   117,   118,\r
+    -1,    59,    -1,    -1,    -1,    -1,   125,    -1,   127,    -1,\r
+   129,   104,    70,    71,    -1,   134,   109,   110,    76,    -1,\r
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,    -1,    -1,\r
+    -1,    -1,   109,   110,    -1,    -1,    32,    -1,    96,    97,\r
+   133,    37,   100,    -1,    40,   138,   104,    -1,    -1,    -1,\r
+    46,    -1,   110,    49,   112,    -1,   133,    32,    -1,   117,\r
+   118,   138,    37,    -1,    -1,    -1,    -1,    32,    64,    -1,\r
+    -1,    46,    37,    -1,    49,    -1,    72,    32,    -1,    -1,\r
+    -1,    46,    37,    -1,    49,    -1,    -1,    -1,    -1,    64,\r
+    -1,    46,    -1,    -1,    49,    -1,    -1,    -1,    -1,    64,\r
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,    64,\r
+    -1,    -1,    -1,   109,   110,    -1,    -1,    -1,    -1,    -1,\r
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   104,\r
+    -1,    -1,    -1,    -1,   109,   110,    -1,   133,    -1,   104,\r
+    -1,   137,   138,    -1,   109,   110,    -1,    -1,    -1,   104,\r
+    -1,    -1,    -1,    -1,   109,   110,    -1,    -1,   133,    -1,\r
+    -1,    -1,   137,   138,    -1,    -1,    -1,    16,   133,    18,\r
+    -1,    -1,   137,   138,    -1,    24,    -1,    26,   133,    -1,\r
+    -1,    -1,   137,   138,    33,    34,    35,    36,    -1,    38,\r
+    39,    -1,    41,    -1,    43,    44,    45,    -1,    -1,    48,\r
+    -1,    -1,    51,    -1,    53,    54,    55,    56,    57,    58,\r
+    -1,    60,    61,    62,    63,    -1,    -1,    66,    -1,    -1,\r
+    69,    -1,    -1,    -1,    73,    -1,    75,    -1,    -1,    -1,\r
+    79,    80,    81,    82,    83,    84,    85,    -1,    87,    88,\r
+    89,    90,    91,    92,    93,    94,    95,    -1,    -1,    98,\r
+    -1,    -1,   101,    -1,   103,    -1,    -1,   106,   107,   108,\r
+    -1,    -1,   111,    -1,   113,   114,   115,   116,    -1,    -1,\r
+   119\r
 };\r
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */\r
 #line 3 "/usr/share/bison.simple"\r
@@ -1390,161 +1386,161 @@ yyreduce:
   switch (yyn) {\r
 \r
 case 1:\r
-#line 229 "parser.y"\r
+#line 227 "parser.y"\r
 { write_proxies(yyvsp[0].ifref); write_client(yyvsp[0].ifref); write_server(yyvsp[0].ifref); ;\r
     break;}\r
 case 2:\r
-#line 232 "parser.y"\r
+#line 230 "parser.y"\r
 { yyval.ifref = NULL; ;\r
     break;}\r
 case 3:\r
-#line 233 "parser.y"\r
+#line 231 "parser.y"\r
 { yyval.ifref = yyvsp[-1].ifref; ;\r
     break;}\r
 case 4:\r
-#line 234 "parser.y"\r
+#line 232 "parser.y"\r
 { yyval.ifref = make_ifref(yyvsp[0].type); LINK(yyval.ifref, yyvsp[-1].ifref); ;\r
     break;}\r
 case 5:\r
-#line 235 "parser.y"\r
+#line 233 "parser.y"\r
 { yyval.ifref = yyvsp[-1].ifref; add_coclass(yyvsp[0].clas); ;\r
     break;}\r
 case 6:\r
-#line 236 "parser.y"\r
+#line 234 "parser.y"\r
 { yyval.ifref = yyvsp[-1].ifref; add_module(yyvsp[0].type); ;\r
     break;}\r
 case 7:\r
-#line 237 "parser.y"\r
+#line 235 "parser.y"\r
 { yyval.ifref = yyvsp[-1].ifref; ;\r
     break;}\r
 case 8:\r
-#line 238 "parser.y"\r
+#line 236 "parser.y"\r
 { yyval.ifref = yyvsp[-1].ifref; ;\r
     break;}\r
 case 9:\r
-#line 241 "parser.y"\r
+#line 239 "parser.y"\r
 {;\r
     break;}\r
 case 10:\r
-#line 242 "parser.y"\r
+#line 240 "parser.y"\r
 { if (!parse_only) add_interface(yyvsp[0].type); ;\r
     break;}\r
 case 11:\r
-#line 243 "parser.y"\r
+#line 241 "parser.y"\r
 { if (!parse_only) add_interface(yyvsp[0].type); ;\r
     break;}\r
 case 12:\r
-#line 244 "parser.y"\r
+#line 242 "parser.y"\r
 { if (!parse_only) add_coclass(yyvsp[0].clas); ;\r
     break;}\r
 case 13:\r
-#line 245 "parser.y"\r
+#line 243 "parser.y"\r
 { if (!parse_only) add_module(yyvsp[0].type); ;\r
     break;}\r
 case 14:\r
-#line 246 "parser.y"\r
+#line 244 "parser.y"\r
 {;\r
     break;}\r
 case 15:\r
-#line 249 "parser.y"\r
+#line 247 "parser.y"\r
 { yyval.func = NULL; ;\r
     break;}\r
 case 16:\r
-#line 250 "parser.y"\r
+#line 248 "parser.y"\r
 { yyval.func = yyvsp[-1].func; LINK(yyval.func, yyvsp[-2].func); ;\r
     break;}\r
 case 17:\r
-#line 251 "parser.y"\r
+#line 249 "parser.y"\r
 { yyval.func = yyvsp[-1].func; ;\r
     break;}\r
 case 18:\r
-#line 254 "parser.y"\r
+#line 252 "parser.y"\r
 {;\r
     break;}\r
 case 19:\r
-#line 255 "parser.y"\r
+#line 253 "parser.y"\r
 { if (!parse_only && do_header) { write_constdef(yyvsp[-1].var); } ;\r
     break;}\r
 case 20:\r
-#line 256 "parser.y"\r
+#line 254 "parser.y"\r
 {;\r
     break;}\r
 case 21:\r
-#line 257 "parser.y"\r
+#line 255 "parser.y"\r
 { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;\r
     break;}\r
 case 22:\r
-#line 258 "parser.y"\r
+#line 256 "parser.y"\r
 { if (!parse_only && do_header) { write_externdef(yyvsp[-1].var); } ;\r
     break;}\r
 case 23:\r
-#line 259 "parser.y"\r
+#line 257 "parser.y"\r
 {;\r
     break;}\r
 case 24:\r
-#line 260 "parser.y"\r
+#line 258 "parser.y"\r
 { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;\r
     break;}\r
 case 25:\r
-#line 261 "parser.y"\r
+#line 259 "parser.y"\r
 {;\r
     break;}\r
 case 26:\r
-#line 262 "parser.y"\r
+#line 260 "parser.y"\r
 { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;\r
     break;}\r
 case 27:\r
-#line 265 "parser.y"\r
+#line 263 "parser.y"\r
 { if (!parse_only && do_header) fprintf(header, "%s\n", yyvsp[-1].str); ;\r
     break;}\r
 case 28:\r
-#line 267 "parser.y"\r
+#line 265 "parser.y"\r
 { assert(yychar == YYEMPTY);\r
                                                  if (!do_import(yyvsp[-1].str)) yychar = aEOF; ;\r
     break;}\r
 case 29:\r
-#line 270 "parser.y"\r
+#line 268 "parser.y"\r
 {;\r
     break;}\r
 case 30:\r
-#line 273 "parser.y"\r
+#line 271 "parser.y"\r
 { yyval.str = yyvsp[0].str; ;\r
     break;}\r
 case 31:\r
-#line 275 "parser.y"\r
+#line 273 "parser.y"\r
 { start_typelib(yyvsp[-1].str, yyvsp[-2].attr); ;\r
     break;}\r
 case 32:\r
-#line 277 "parser.y"\r
+#line 275 "parser.y"\r
 { end_typelib(); ;\r
     break;}\r
 case 33:\r
-#line 280 "parser.y"\r
+#line 278 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
 case 35:\r
-#line 284 "parser.y"\r
+#line 282 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
 case 37:\r
-#line 288 "parser.y"\r
+#line 286 "parser.y"\r
 { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;\r
     break;}\r
 case 39:\r
-#line 293 "parser.y"\r
+#line 291 "parser.y"\r
 { yyval.var = yyvsp[-1].var;\r
                                                  set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr);\r
                                                  yyval.var->attrs = yyvsp[-3].attr;\r
                                                ;\r
     break;}\r
 case 40:\r
-#line 297 "parser.y"\r
+#line 295 "parser.y"\r
 { yyval.var = yyvsp[-1].var;\r
                                                  set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr);\r
                                                ;\r
     break;}\r
 case 41:\r
-#line 300 "parser.y"\r
+#line 298 "parser.y"\r
 { yyval.var = yyvsp[-3].var;\r
                                                  yyval.var->ptr_level--;\r
                                                  set_type(yyval.var, yyvsp[-4].tref, NULL);\r
@@ -1553,7 +1549,7 @@ case 41:
                                                ;\r
     break;}\r
 case 42:\r
-#line 306 "parser.y"\r
+#line 304 "parser.y"\r
 { yyval.var = yyvsp[-3].var;\r
                                                  yyval.var->ptr_level--;\r
                                                  set_type(yyval.var, yyvsp[-4].tref, NULL);\r
@@ -1561,337 +1557,349 @@ case 42:
                                                ;\r
     break;}\r
 case 43:\r
-#line 313 "parser.y"\r
+#line 311 "parser.y"\r
 { yyval.expr = NULL; ;\r
     break;}\r
 case 44:\r
-#line 314 "parser.y"\r
+#line 312 "parser.y"\r
 { yyval.expr = yyvsp[-1].expr; ;\r
     break;}\r
 case 45:\r
-#line 315 "parser.y"\r
+#line 313 "parser.y"\r
 { yyval.expr = make_expr(EXPR_VOID); ;\r
     break;}\r
 case 47:\r
-#line 319 "parser.y"\r
+#line 317 "parser.y"\r
 { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;\r
     break;}\r
 case 48:\r
-#line 320 "parser.y"\r
+#line 318 "parser.y"\r
 { LINK(yyvsp[0].expr, yyvsp[-3].expr); yyval.expr = yyvsp[0].expr; ;\r
     break;}\r
 case 49:\r
-#line 323 "parser.y"\r
+#line 321 "parser.y"\r
 { yyval.attr = NULL; ;\r
     break;}\r
 case 51:\r
-#line 328 "parser.y"\r
+#line 326 "parser.y"\r
 { yyval.attr = yyvsp[-1].attr; ;\r
     break;}\r
 case 53:\r
-#line 332 "parser.y"\r
+#line 330 "parser.y"\r
 { LINK(yyvsp[0].attr, yyvsp[-2].attr); yyval.attr = yyvsp[0].attr; ;\r
     break;}\r
 case 54:\r
-#line 333 "parser.y"\r
+#line 331 "parser.y"\r
 { LINK(yyvsp[0].attr, yyvsp[-3].attr); yyval.attr = yyvsp[0].attr; ;\r
     break;}\r
 case 55:\r
-#line 337 "parser.y"\r
+#line 335 "parser.y"\r
 { yyval.attr = make_attr(ATTR_ASYNC); ;\r
     break;}\r
 case 56:\r
-#line 338 "parser.y"\r
+#line 336 "parser.y"\r
 { yyval.attr = make_attr(ATTR_AUTO_HANDLE); ;\r
     break;}\r
 case 57:\r
-#line 339 "parser.y"\r
+#line 337 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_CALLAS, yyvsp[-1].var); ;\r
     break;}\r
 case 58:\r
-#line 340 "parser.y"\r
+#line 338 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_CASE, yyvsp[-1].expr); ;\r
     break;}\r
 case 59:\r
-#line 341 "parser.y"\r
+#line 339 "parser.y"\r
 { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); ;\r
     break;}\r
 case 60:\r
-#line 342 "parser.y"\r
+#line 340 "parser.y"\r
 { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;\r
     break;}\r
 case 61:\r
-#line 343 "parser.y"\r
+#line 341 "parser.y"\r
 { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;\r
     break;}\r
 case 62:\r
-#line 344 "parser.y"\r
+#line 342 "parser.y"\r
 { yyval.attr = make_attr(ATTR_CONTROL); ;\r
     break;}\r
 case 63:\r
-#line 345 "parser.y"\r
+#line 343 "parser.y"\r
 { yyval.attr = make_attr(ATTR_DEFAULT); ;\r
     break;}\r
 case 64:\r
-#line 346 "parser.y"\r
+#line 344 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_EXPR, yyvsp[-1].expr); ;\r
     break;}\r
 case 65:\r
-#line 347 "parser.y"\r
+#line 345 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_STRING, yyvsp[-1].str); ;\r
     break;}\r
 case 66:\r
-#line 348 "parser.y"\r
+#line 346 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_DLLNAME, yyvsp[-1].str); ;\r
     break;}\r
 case 67:\r
-#line 349 "parser.y"\r
+#line 347 "parser.y"\r
 { yyval.attr = make_attr(ATTR_DUAL); ;\r
     break;}\r
 case 68:\r
-#line 350 "parser.y"\r
+#line 348 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_ENDPOINT, yyvsp[-1].str); ;\r
     break;}\r
 case 69:\r
-#line 351 "parser.y"\r
+#line 349 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_ENTRY_STRING, yyvsp[-1].str); ;\r
     break;}\r
 case 70:\r
-#line 352 "parser.y"\r
+#line 350 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_ENTRY_ORDINAL, yyvsp[-1].expr); ;\r
     break;}\r
 case 71:\r
-#line 353 "parser.y"\r
+#line 351 "parser.y"\r
 { yyval.attr = make_attr(ATTR_EXPLICIT_HANDLE); ;\r
     break;}\r
 case 72:\r
-#line 354 "parser.y"\r
+#line 352 "parser.y"\r
 { yyval.attr = make_attr(ATTR_HANDLE); ;\r
     break;}\r
 case 73:\r
-#line 355 "parser.y"\r
+#line 353 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_HELPCONTEXT, yyvsp[-1].expr); ;\r
     break;}\r
 case 74:\r
-#line 356 "parser.y"\r
+#line 354 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_HELPFILE, yyvsp[-1].str); ;\r
     break;}\r
 case 75:\r
-#line 357 "parser.y"\r
+#line 355 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_HELPSTRING, yyvsp[-1].str); ;\r
     break;}\r
 case 76:\r
-#line 358 "parser.y"\r
+#line 356 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_HELPSTRINGCONTEXT, yyvsp[-1].expr); ;\r
     break;}\r
 case 77:\r
-#line 359 "parser.y"\r
+#line 357 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_HELPSTRINGDLL, yyvsp[-1].str); ;\r
     break;}\r
 case 78:\r
-#line 360 "parser.y"\r
+#line 358 "parser.y"\r
 { yyval.attr = make_attr(ATTR_HIDDEN); ;\r
     break;}\r
 case 79:\r
-#line 361 "parser.y"\r
+#line 359 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_ID, yyvsp[-1].expr); ;\r
     break;}\r
 case 80:\r
-#line 362 "parser.y"\r
+#line 360 "parser.y"\r
 { yyval.attr = make_attr(ATTR_IDEMPOTENT); ;\r
     break;}\r
 case 81:\r
-#line 363 "parser.y"\r
+#line 361 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_IIDIS, yyvsp[-1].var); ;\r
     break;}\r
 case 82:\r
-#line 364 "parser.y"\r
+#line 362 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_IMPLICIT_HANDLE, yyvsp[-1].str); ;\r
     break;}\r
 case 83:\r
-#line 365 "parser.y"\r
+#line 363 "parser.y"\r
 { yyval.attr = make_attr(ATTR_IN); ;\r
     break;}\r
 case 84:\r
-#line 366 "parser.y"\r
+#line 364 "parser.y"\r
 { yyval.attr = make_attr(ATTR_INPUTSYNC); ;\r
     break;}\r
 case 85:\r
-#line 367 "parser.y"\r
+#line 365 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_LENGTHIS, yyvsp[-1].expr); ;\r
     break;}\r
 case 86:\r
-#line 368 "parser.y"\r
+#line 366 "parser.y"\r
 { yyval.attr = make_attr(ATTR_LOCAL); ;\r
     break;}\r
 case 87:\r
-#line 369 "parser.y"\r
+#line 367 "parser.y"\r
 { yyval.attr = make_attr(ATTR_NONCREATABLE); ;\r
     break;}\r
 case 88:\r
-#line 370 "parser.y"\r
+#line 368 "parser.y"\r
 { yyval.attr = make_attr(ATTR_OBJECT); ;\r
     break;}\r
 case 89:\r
-#line 371 "parser.y"\r
+#line 369 "parser.y"\r
 { yyval.attr = make_attr(ATTR_ODL); ;\r
     break;}\r
 case 90:\r
-#line 372 "parser.y"\r
+#line 370 "parser.y"\r
 { yyval.attr = make_attr(ATTR_OLEAUTOMATION); ;\r
     break;}\r
 case 91:\r
-#line 373 "parser.y"\r
+#line 371 "parser.y"\r
 { yyval.attr = make_attr(ATTR_OPTIONAL); ;\r
     break;}\r
 case 92:\r
-#line 374 "parser.y"\r
+#line 372 "parser.y"\r
 { yyval.attr = make_attr(ATTR_OUT); ;\r
     break;}\r
 case 93:\r
-#line 375 "parser.y"\r
+#line 373 "parser.y"\r
 { yyval.attr = make_attrv(ATTR_POINTERDEFAULT, yyvsp[-1].num); ;\r
     break;}\r
 case 94:\r
-#line 376 "parser.y"\r
+#line 374 "parser.y"\r
 { yyval.attr = make_attr(ATTR_PROPGET); ;\r
     break;}\r
 case 95:\r
-#line 377 "parser.y"\r
+#line 375 "parser.y"\r
 { yyval.attr = make_attr(ATTR_PROPPUT); ;\r
     break;}\r
 case 96:\r
-#line 378 "parser.y"\r
+#line 376 "parser.y"\r
 { yyval.attr = make_attr(ATTR_PROPPUTREF); ;\r
     break;}\r
 case 97:\r
-#line 379 "parser.y"\r
-{ yyval.attr = make_attr(ATTR_PUBLIC); ;\r
+#line 377 "parser.y"\r
+{ yyval.attr = make_attr(ATTR_PTR); ;\r
     break;}\r
 case 98:\r
-#line 380 "parser.y"\r
-{ yyval.attr = make_attr(ATTR_READONLY); ;\r
+#line 378 "parser.y"\r
+{ yyval.attr = make_attr(ATTR_PUBLIC); ;\r
     break;}\r
 case 99:\r
+#line 379 "parser.y"\r
+{ yyval.attr = make_attr(ATTR_READONLY); ;\r
+    break;}\r
+case 100:\r
+#line 380 "parser.y"\r
+{ yyval.attr = make_attr(ATTR_REF); ;\r
+    break;}\r
+case 101:\r
 #line 381 "parser.y"\r
 { yyval.attr = make_attr(ATTR_RESTRICTED); ;\r
     break;}\r
-case 100:\r
+case 102:\r
 #line 382 "parser.y"\r
 { yyval.attr = make_attr(ATTR_RETVAL); ;\r
     break;}\r
-case 101:\r
+case 103:\r
 #line 383 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_SIZEIS, yyvsp[-1].expr); ;\r
     break;}\r
-case 102:\r
+case 104:\r
 #line 384 "parser.y"\r
 { yyval.attr = make_attr(ATTR_SOURCE); ;\r
     break;}\r
-case 103:\r
+case 105:\r
 #line 385 "parser.y"\r
 { yyval.attr = make_attr(ATTR_STRING); ;\r
     break;}\r
-case 104:\r
+case 106:\r
 #line 386 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_SWITCHIS, yyvsp[-1].expr); ;\r
     break;}\r
-case 105:\r
+case 107:\r
 #line 387 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_SWITCHTYPE, type_ref(yyvsp[-1].tref)); ;\r
     break;}\r
-case 106:\r
+case 108:\r
 #line 388 "parser.y"\r
 { yyval.attr = make_attrp(ATTR_TRANSMITAS, type_ref(yyvsp[-1].tref)); ;\r
     break;}\r
-case 107:\r
+case 109:\r
 #line 389 "parser.y"\r
-{ yyval.attr = make_attrp(ATTR_UUID, yyvsp[-1].uuid); ;\r
+{ yyval.attr = make_attr(ATTR_UNIQUE); ;\r
     break;}\r
-case 108:\r
+case 110:\r
 #line 390 "parser.y"\r
-{ yyval.attr = make_attr(ATTR_V1ENUM); ;\r
+{ yyval.attr = make_attrp(ATTR_UUID, yyvsp[-1].uuid); ;\r
     break;}\r
-case 109:\r
+case 111:\r
 #line 391 "parser.y"\r
-{ yyval.attr = make_attr(ATTR_VARARG); ;\r
+{ yyval.attr = make_attr(ATTR_V1ENUM); ;\r
     break;}\r
-case 110:\r
+case 112:\r
 #line 392 "parser.y"\r
-{ yyval.attr = make_attrv(ATTR_VERSION, yyvsp[-1].num); ;\r
+{ yyval.attr = make_attr(ATTR_VARARG); ;\r
     break;}\r
-case 111:\r
+case 113:\r
 #line 393 "parser.y"\r
-{ yyval.attr = make_attrp(ATTR_WIREMARSHAL, type_ref(yyvsp[-1].tref)); ;\r
+{ yyval.attr = make_attrv(ATTR_VERSION, yyvsp[-1].num); ;\r
     break;}\r
-case 112:\r
+case 114:\r
 #line 394 "parser.y"\r
-{ yyval.attr = make_attrv(ATTR_POINTERTYPE, yyvsp[0].num); ;\r
+{ yyval.attr = make_attrp(ATTR_WIREMARSHAL, type_ref(yyvsp[-1].tref)); ;\r
     break;}\r
 case 115:\r
-#line 401 "parser.y"\r
-{ yyval.var = NULL; ;\r
+#line 395 "parser.y"\r
+{ yyval.attr = make_attrv(ATTR_POINTERTYPE, yyvsp[0].num); ;\r
     break;}\r
-case 116:\r
+case 118:\r
 #line 402 "parser.y"\r
+{ yyval.var = NULL; ;\r
+    break;}\r
+case 119:\r
+#line 403 "parser.y"\r
 { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; }\r
                                                  else { yyval.var = yyvsp[-1].var; }\r
                                                ;\r
     break;}\r
-case 117:\r
-#line 407 "parser.y"\r
+case 120:\r
+#line 408 "parser.y"\r
 { attr_t *a = make_attrp(ATTR_CASE, yyvsp[-2].expr);\r
                                                  yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL);\r
                                                  LINK(a, yyval.var->attrs); yyval.var->attrs = a;\r
                                                ;\r
     break;}\r
-case 118:\r
-#line 411 "parser.y"\r
+case 121:\r
+#line 412 "parser.y"\r
 { attr_t *a = make_attr(ATTR_DEFAULT);\r
                                                  yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL);\r
                                                  LINK(a, yyval.var->attrs); yyval.var->attrs = a;\r
                                                ;\r
     break;}\r
-case 119:\r
-#line 417 "parser.y"\r
+case 122:\r
+#line 418 "parser.y"\r
 { yyval.var = reg_const(yyvsp[-2].var);\r
                                                  set_type(yyval.var, yyvsp[-3].tref, NULL);\r
                                                  yyval.var->eval = yyvsp[0].expr;\r
                                                  yyval.var->lval = yyvsp[0].expr->cval;\r
                                                ;\r
     break;}\r
-case 120:\r
-#line 424 "parser.y"\r
+case 123:\r
+#line 425 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
-case 121:\r
-#line 425 "parser.y"\r
+case 124:\r
+#line 426 "parser.y"\r
 { yyval.var = yyvsp[-1].var; ;\r
     break;}\r
-case 124:\r
-#line 430 "parser.y"\r
+case 127:\r
+#line 431 "parser.y"\r
 { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var;\r
                                                  if (yyvsp[-2].var && !yyvsp[0].var->eval)\r
                                                    yyvsp[0].var->lval = yyvsp[-2].var->lval + 1;\r
                                                ;\r
     break;}\r
-case 125:\r
-#line 436 "parser.y"\r
+case 128:\r
+#line 437 "parser.y"\r
 { yyval.var = reg_const(yyvsp[-2].var);\r
                                                  yyval.var->eval = yyvsp[0].expr;\r
                                                  yyval.var->lval = yyvsp[0].expr->cval;\r
                                                  yyval.var->type = make_type(RPC_FC_LONG, &std_int);\r
                                                ;\r
     break;}\r
-case 126:\r
-#line 441 "parser.y"\r
+case 129:\r
+#line 442 "parser.y"\r
 { yyval.var = reg_const(yyvsp[0].var);\r
                                                  yyval.var->lval = 0; /* default for first enum entry */\r
                                                  yyval.var->type = make_type(RPC_FC_LONG, &std_int);\r
                                                ;\r
     break;}\r
-case 127:\r
-#line 447 "parser.y"\r
+case 130:\r
+#line 448 "parser.y"\r
 { yyval.type = get_typev(RPC_FC_ENUM16, yyvsp[-3].var, tsENUM);\r
                                                  yyval.type->fields = yyvsp[-1].var;\r
                                                  yyval.type->defined = TRUE;\r
@@ -1899,135 +1907,135 @@ case 127:
                                                      add_enum(yyval.type);\r
                                                ;\r
     break;}\r
-case 129:\r
-#line 456 "parser.y"\r
+case 132:\r
+#line 457 "parser.y"\r
 { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;\r
     break;}\r
-case 130:\r
-#line 469 "parser.y"\r
+case 133:\r
+#line 470 "parser.y"\r
 { yyval.expr = make_expr(EXPR_VOID); ;\r
     break;}\r
-case 132:\r
-#line 473 "parser.y"\r
+case 135:\r
+#line 474 "parser.y"\r
 { yyval.expr = make_exprl(EXPR_NUM, yyvsp[0].num); ;\r
     break;}\r
-case 133:\r
-#line 474 "parser.y"\r
+case 136:\r
+#line 475 "parser.y"\r
 { yyval.expr = make_exprl(EXPR_HEXNUM, yyvsp[0].num); ;\r
     break;}\r
-case 134:\r
-#line 475 "parser.y"\r
+case 137:\r
+#line 476 "parser.y"\r
 { yyval.expr = make_exprs(EXPR_IDENTIFIER, yyvsp[0].str); ;\r
     break;}\r
-case 135:\r
-#line 476 "parser.y"\r
+case 138:\r
+#line 477 "parser.y"\r
 { yyval.expr = make_expr3(EXPR_COND, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 136:\r
-#line 477 "parser.y"\r
+case 139:\r
+#line 478 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_OR , yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 137:\r
-#line 478 "parser.y"\r
+case 140:\r
+#line 479 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_AND, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 138:\r
-#line 479 "parser.y"\r
+case 141:\r
+#line 480 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_ADD, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 139:\r
-#line 480 "parser.y"\r
+case 142:\r
+#line 481 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_SUB, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 140:\r
-#line 481 "parser.y"\r
+case 143:\r
+#line 482 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_MUL, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 141:\r
-#line 482 "parser.y"\r
+case 144:\r
+#line 483 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_DIV, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 142:\r
-#line 483 "parser.y"\r
+case 145:\r
+#line 484 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_SHL, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 143:\r
-#line 484 "parser.y"\r
+case 146:\r
+#line 485 "parser.y"\r
 { yyval.expr = make_expr2(EXPR_SHR, yyvsp[-2].expr, yyvsp[0].expr); ;\r
     break;}\r
-case 144:\r
-#line 485 "parser.y"\r
+case 147:\r
+#line 486 "parser.y"\r
 { yyval.expr = make_expr1(EXPR_NOT, yyvsp[0].expr); ;\r
     break;}\r
-case 145:\r
-#line 486 "parser.y"\r
+case 148:\r
+#line 487 "parser.y"\r
 { yyval.expr = make_expr1(EXPR_NEG, yyvsp[0].expr); ;\r
     break;}\r
-case 146:\r
-#line 487 "parser.y"\r
+case 149:\r
+#line 488 "parser.y"\r
 { yyval.expr = make_expr1(EXPR_PPTR, yyvsp[0].expr); ;\r
     break;}\r
-case 147:\r
-#line 488 "parser.y"\r
+case 150:\r
+#line 489 "parser.y"\r
 { yyval.expr = make_exprt(EXPR_CAST, yyvsp[-2].tref, yyvsp[0].expr); ;\r
     break;}\r
-case 148:\r
-#line 489 "parser.y"\r
+case 151:\r
+#line 490 "parser.y"\r
 { yyval.expr = make_exprt(EXPR_SIZEOF, yyvsp[-1].tref, NULL); ;\r
     break;}\r
-case 149:\r
-#line 490 "parser.y"\r
+case 152:\r
+#line 491 "parser.y"\r
 { yyval.expr = yyvsp[-1].expr; ;\r
     break;}\r
-case 151:\r
-#line 494 "parser.y"\r
+case 154:\r
+#line 495 "parser.y"\r
 { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;\r
     break;}\r
-case 152:\r
-#line 497 "parser.y"\r
+case 155:\r
+#line 498 "parser.y"\r
 { yyval.expr = yyvsp[0].expr;\r
                                                  if (!yyval.expr->is_const)\r
                                                      yyerror("expression is not constant\n");\r
                                                ;\r
     break;}\r
-case 153:\r
-#line 503 "parser.y"\r
+case 156:\r
+#line 504 "parser.y"\r
 { yyval.var = yyvsp[0].var;\r
                                                  set_type(yyval.var, yyvsp[-1].tref, NULL);\r
                                                ;\r
     break;}\r
-case 154:\r
-#line 508 "parser.y"\r
+case 157:\r
+#line 509 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
-case 155:\r
-#line 509 "parser.y"\r
+case 158:\r
+#line 510 "parser.y"\r
 { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; }\r
                                                  else { yyval.var = yyvsp[-1].var; }\r
                                                ;\r
     break;}\r
-case 156:\r
-#line 514 "parser.y"\r
+case 159:\r
+#line 515 "parser.y"\r
 { yyval.var = yyvsp[-1].var; ;\r
     break;}\r
-case 157:\r
-#line 515 "parser.y"\r
+case 160:\r
+#line 516 "parser.y"\r
 { yyval.var = make_var(NULL); yyval.var->type = yyvsp[-1].type; yyval.var->attrs = yyvsp[-2].attr; ;\r
     break;}\r
-case 158:\r
-#line 516 "parser.y"\r
+case 161:\r
+#line 517 "parser.y"\r
 { yyval.var = make_var(NULL); yyval.var->attrs = yyvsp[-1].attr; ;\r
     break;}\r
-case 159:\r
-#line 517 "parser.y"\r
+case 162:\r
+#line 518 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
-case 160:\r
-#line 520 "parser.y"\r
+case 163:\r
+#line 521 "parser.y"\r
 { yyval.var = yyvsp[-1].var; set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); yyval.var->attrs = yyvsp[-3].attr; ;\r
     break;}\r
-case 161:\r
-#line 525 "parser.y"\r
+case 164:\r
+#line 526 "parser.y"\r
 { set_type(yyvsp[-3].var, yyvsp[-5].tref, NULL);\r
                                                  yyvsp[-3].var->attrs = yyvsp[-6].attr;\r
                                                  yyval.func = make_func(yyvsp[-3].var, yyvsp[-1].var);\r
@@ -2036,56 +2044,56 @@ case 161:
                                                  }\r
                                                ;\r
     break;}\r
-case 162:\r
-#line 534 "parser.y"\r
-{ yyval.var = NULL; ;\r
-    break;}\r
-case 164:\r
-#line 538 "parser.y"\r
+case 165:\r
+#line 535 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
-case 165:\r
+case 167:\r
 #line 539 "parser.y"\r
-{ yyval.var = make_var(yyvsp[0].str); ;\r
+{ yyval.var = NULL; ;\r
     break;}\r
-case 166:\r
+case 168:\r
 #line 540 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 167:\r
-#line 543 "parser.y"\r
+case 169:\r
+#line 541 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 168:\r
-#line 545 "parser.y"\r
+case 170:\r
+#line 544 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 169:\r
+case 171:\r
 #line 546 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 170:\r
+case 172:\r
 #line 547 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 171:\r
+case 173:\r
 #line 548 "parser.y"\r
 { yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 172:\r
-#line 551 "parser.y"\r
-{ yyval.type = make_type(RPC_FC_BYTE, NULL); ;\r
+case 174:\r
+#line 549 "parser.y"\r
+{ yyval.var = make_var(yyvsp[0].str); ;\r
     break;}\r
-case 173:\r
+case 175:\r
 #line 552 "parser.y"\r
+{ yyval.type = make_type(RPC_FC_BYTE, NULL); ;\r
+    break;}\r
+case 176:\r
+#line 553 "parser.y"\r
 { yyval.type = make_type(RPC_FC_WCHAR, NULL); ;\r
     break;}\r
-case 175:\r
-#line 554 "parser.y"\r
+case 178:\r
+#line 555 "parser.y"\r
 { yyval.type = yyvsp[0].type; yyval.type->sign = 1; ;\r
     break;}\r
-case 176:\r
-#line 555 "parser.y"\r
+case 179:\r
+#line 556 "parser.y"\r
 { yyval.type = yyvsp[0].type; yyval.type->sign = -1;\r
                                                  switch (yyval.type->type) {\r
                                                  case RPC_FC_CHAR: break;\r
@@ -2099,97 +2107,102 @@ case 176:
                                                  }\r
                                                ;\r
     break;}\r
-case 177:\r
-#line 567 "parser.y"\r
+case 180:\r
+#line 568 "parser.y"\r
+{ yyval.type = make_type(RPC_FC_ULONG, &std_int);\r
+                                                 yyval.type->sign = -1; ;\r
+    break;}\r
+case 181:\r
+#line 570 "parser.y"\r
 { yyval.type = make_type(RPC_FC_FLOAT, NULL); ;\r
     break;}\r
-case 178:\r
-#line 568 "parser.y"\r
+case 182:\r
+#line 571 "parser.y"\r
 { yyval.type = make_type(RPC_FC_DOUBLE, NULL); ;\r
     break;}\r
-case 179:\r
-#line 569 "parser.y"\r
+case 183:\r
+#line 572 "parser.y"\r
 { yyval.type = make_type(RPC_FC_SMALL, &std_bool); ;\r
     break;}\r
-case 180:\r
-#line 570 "parser.y"\r
+case 184:\r
+#line 573 "parser.y"\r
 { yyval.type = make_type(RPC_FC_ERROR_STATUS_T, NULL); ;\r
     break;}\r
-case 181:\r
-#line 571 "parser.y"\r
+case 185:\r
+#line 574 "parser.y"\r
 { yyval.type = make_type(RPC_FC_IGNORE, NULL); ;\r
     break;}\r
-case 184:\r
-#line 578 "parser.y"\r
+case 188:\r
+#line 581 "parser.y"\r
 { yyval.type = make_type(RPC_FC_LONG, &std_int); ;\r
     break;}\r
-case 185:\r
-#line 579 "parser.y"\r
+case 189:\r
+#line 582 "parser.y"\r
 { yyval.type = make_type(RPC_FC_SMALL, NULL); ;\r
     break;}\r
-case 186:\r
-#line 580 "parser.y"\r
+case 190:\r
+#line 583 "parser.y"\r
 { yyval.type = make_type(RPC_FC_SHORT, NULL); ;\r
     break;}\r
-case 187:\r
-#line 581 "parser.y"\r
+case 191:\r
+#line 584 "parser.y"\r
 { yyval.type = make_type(RPC_FC_LONG, NULL); ;\r
     break;}\r
-case 188:\r
-#line 582 "parser.y"\r
+case 192:\r
+#line 585 "parser.y"\r
 { yyval.type = make_type(RPC_FC_HYPER, NULL); ;\r
     break;}\r
-case 189:\r
-#line 583 "parser.y"\r
+case 193:\r
+#line 586 "parser.y"\r
 { yyval.type = make_type(RPC_FC_HYPER, &std_int64); ;\r
     break;}\r
-case 190:\r
-#line 584 "parser.y"\r
+case 194:\r
+#line 587 "parser.y"\r
 { yyval.type = make_type(RPC_FC_CHAR, NULL); ;\r
     break;}\r
-case 191:\r
-#line 587 "parser.y"\r
+case 195:\r
+#line 590 "parser.y"\r
 { yyval.clas = make_class(yyvsp[0].str); ;\r
     break;}\r
-case 192:\r
-#line 588 "parser.y"\r
+case 196:\r
+#line 591 "parser.y"\r
 { yyval.clas = make_class(yyvsp[0].str); ;\r
     break;}\r
-case 193:\r
-#line 591 "parser.y"\r
+case 197:\r
+#line 594 "parser.y"\r
 { yyval.clas = yyvsp[0].clas;\r
                                                  yyval.clas->attrs = yyvsp[-1].attr;\r
                                                   if (!parse_only && do_header) write_coclass(yyval.clas);\r
                                                ;\r
     break;}\r
-case 194:\r
-#line 597 "parser.y"\r
+case 198:\r
+#line 600 "parser.y"\r
 { yyval.clas = yyvsp[-3].clas;\r
                                                  yyval.clas->ifaces = yyvsp[-1].ifref;\r
                                                ;\r
     break;}\r
-case 195:\r
-#line 602 "parser.y"\r
+case 199:\r
+#line 605 "parser.y"\r
 { yyval.ifref = NULL; ;\r
     break;}\r
-case 196:\r
-#line 603 "parser.y"\r
+case 200:\r
+#line 606 "parser.y"\r
 { LINK(yyvsp[0].ifref, yyvsp[-1].ifref); yyval.ifref = yyvsp[0].ifref; ;\r
     break;}\r
-case 197:\r
-#line 607 "parser.y"\r
+case 201:\r
+#line 610 "parser.y"\r
 { yyval.ifref = make_ifref(yyvsp[0].type); yyval.ifref->attrs = yyvsp[-1].attr; ;\r
     break;}\r
-case 198:\r
-#line 610 "parser.y"\r
+case 202:\r
+#line 613 "parser.y"\r
 { yyval.type = get_type(0, yyvsp[0].str, 0); ;\r
     break;}\r
-case 199:\r
-#line 611 "parser.y"\r
+case 203:\r
+#line 614 "parser.y"\r
 { yyval.type = get_type(0, yyvsp[0].str, 0); ;\r
     break;}\r
-case 200:\r
-#line 614 "parser.y"\r
+case 204:\r
+#line 617 "parser.y"\r
 { yyval.type = yyvsp[0].type;\r
                                                  if (yyval.type->defined) yyerror("multiple definition error\n");\r
                                                  yyval.type->attrs = yyvsp[-1].attr;\r
@@ -2201,48 +2214,48 @@ case 200:
                                                  if (!parse_only && do_header) write_forward(yyval.type);\r
                                                ;\r
     break;}\r
-case 201:\r
-#line 626 "parser.y"\r
+case 205:\r
+#line 629 "parser.y"\r
 { yyval.var = NULL; ;\r
     break;}\r
-case 202:\r
-#line 627 "parser.y"\r
+case 206:\r
+#line 630 "parser.y"\r
 { LINK(yyvsp[-1].var, yyvsp[-2].var); yyval.var = yyvsp[-1].var; ;\r
     break;}\r
-case 203:\r
-#line 630 "parser.y"\r
+case 207:\r
+#line 633 "parser.y"\r
 { yyval.func = NULL; ;\r
     break;}\r
-case 204:\r
-#line 631 "parser.y"\r
+case 208:\r
+#line 634 "parser.y"\r
 { LINK(yyvsp[-1].func, yyvsp[-2].func); yyval.func = yyvsp[-1].func; ;\r
     break;}\r
-case 205:\r
-#line 637 "parser.y"\r
+case 209:\r
+#line 640 "parser.y"\r
 { yyval.type = yyvsp[-4].type;\r
                                                  yyval.type->fields = yyvsp[-2].var;\r
                                                  yyval.type->funcs = yyvsp[-1].func;\r
                                                  if (!parse_only && do_header) write_dispinterface(yyval.type);\r
                                                ;\r
     break;}\r
-case 206:\r
-#line 649 "parser.y"\r
+case 210:\r
+#line 652 "parser.y"\r
 { yyval.type = NULL; ;\r
     break;}\r
-case 207:\r
-#line 650 "parser.y"\r
+case 211:\r
+#line 653 "parser.y"\r
 { yyval.type = find_type2(yyvsp[0].str, 0); ;\r
     break;}\r
-case 208:\r
-#line 653 "parser.y"\r
+case 212:\r
+#line 656 "parser.y"\r
 { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;\r
     break;}\r
-case 209:\r
-#line 654 "parser.y"\r
+case 213:\r
+#line 657 "parser.y"\r
 { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;\r
     break;}\r
-case 210:\r
-#line 657 "parser.y"\r
+case 214:\r
+#line 660 "parser.y"\r
 { yyval.type = yyvsp[0].type;\r
                                                  if (yyval.type->defined) yyerror("multiple definition error\n");\r
                                                  yyval.type->attrs = yyvsp[-1].attr;\r
@@ -2250,16 +2263,16 @@ case 210:
                                                  if (!parse_only && do_header) write_forward(yyval.type);\r
                                                ;\r
     break;}\r
-case 211:\r
-#line 666 "parser.y"\r
+case 215:\r
+#line 669 "parser.y"\r
 { yyval.type = yyvsp[-4].type;\r
                                                  yyval.type->ref = yyvsp[-3].type;\r
                                                  yyval.type->funcs = yyvsp[-1].func;\r
                                                  if (!parse_only && do_header) write_interface(yyval.type);\r
                                                ;\r
     break;}\r
-case 212:\r
-#line 674 "parser.y"\r
+case 216:\r
+#line 677 "parser.y"\r
 { yyval.type = yyvsp[-6].type;\r
                                                  yyval.type->ref = find_type2(yyvsp[-4].str, 0);\r
                                                  if (!yyval.type->ref) yyerror("base class %s not found in import\n", yyvsp[-4].str);\r
@@ -2267,65 +2280,65 @@ case 212:
                                                  if (!parse_only && do_header) write_interface(yyval.type);\r
                                                ;\r
     break;}\r
-case 213:\r
-#line 680 "parser.y"\r
+case 217:\r
+#line 683 "parser.y"\r
 { yyval.type = yyvsp[0].type; ;\r
     break;}\r
-case 214:\r
-#line 684 "parser.y"\r
+case 218:\r
+#line 687 "parser.y"\r
 { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;\r
     break;}\r
-case 215:\r
-#line 685 "parser.y"\r
+case 219:\r
+#line 688 "parser.y"\r
 { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;\r
     break;}\r
-case 216:\r
-#line 688 "parser.y"\r
+case 220:\r
+#line 691 "parser.y"\r
 { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;\r
     break;}\r
-case 217:\r
-#line 689 "parser.y"\r
+case 221:\r
+#line 692 "parser.y"\r
 { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;\r
     break;}\r
-case 218:\r
-#line 692 "parser.y"\r
+case 222:\r
+#line 695 "parser.y"\r
 { yyval.type = yyvsp[0].type;\r
                                                  yyval.type->attrs = yyvsp[-1].attr;\r
                                                ;\r
     break;}\r
-case 219:\r
-#line 697 "parser.y"\r
+case 223:\r
+#line 700 "parser.y"\r
 { yyval.type = yyvsp[-3].type;\r
                                                  yyval.type->funcs = yyvsp[-1].func;\r
                                                  /* FIXME: if (!parse_only && do_header) write_module($$); */\r
                                                ;\r
     break;}\r
-case 220:\r
-#line 703 "parser.y"\r
+case 224:\r
+#line 706 "parser.y"\r
 { yyval.var = yyvsp[0].var; yyval.var->ptr_level++; ;\r
     break;}\r
-case 221:\r
-#line 704 "parser.y"\r
+case 225:\r
+#line 707 "parser.y"\r
 { yyval.var = yyvsp[0].var; /* FIXME */ ;\r
     break;}\r
-case 224:\r
-#line 709 "parser.y"\r
+case 228:\r
+#line 712 "parser.y"\r
 { yyval.var = yyvsp[-1].var; ;\r
     break;}\r
-case 226:\r
-#line 714 "parser.y"\r
+case 230:\r
+#line 717 "parser.y"\r
 { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;\r
     break;}\r
-case 227:\r
-#line 718 "parser.y"\r
+case 231:\r
+#line 721 "parser.y"\r
 { yyval.num = RPC_FC_RP; ;\r
     break;}\r
-case 228:\r
-#line 719 "parser.y"\r
+case 232:\r
+#line 722 "parser.y"\r
 { yyval.num = RPC_FC_UP; ;\r
     break;}\r
-case 229:\r
-#line 722 "parser.y"\r
+case 233:\r
+#line 725 "parser.y"\r
 { yyval.type = get_typev(RPC_FC_STRUCT, yyvsp[-3].var, tsSTRUCT);\r
                                                  /* overwrite RPC_FC_STRUCT with a more exact type */\r
                                                  yyval.type->type = get_struct_type( yyvsp[-1].var );\r
@@ -2335,48 +2348,48 @@ case 229:
                                                    add_struct(yyval.type);\r
                                                ;\r
     break;}\r
-case 230:\r
-#line 732 "parser.y"\r
+case 234:\r
+#line 735 "parser.y"\r
 { yyval.tref = make_tref(NULL, make_type(0, NULL)); ;\r
     break;}\r
-case 231:\r
-#line 733 "parser.y"\r
+case 235:\r
+#line 736 "parser.y"\r
 { yyval.tref = make_tref(yyvsp[0].str, find_type(yyvsp[0].str, 0)); ;\r
     break;}\r
-case 232:\r
-#line 734 "parser.y"\r
+case 236:\r
+#line 737 "parser.y"\r
 { yyval.tref = make_tref(NULL, yyvsp[0].type); ;\r
     break;}\r
-case 233:\r
-#line 735 "parser.y"\r
+case 237:\r
+#line 738 "parser.y"\r
 { yyval.tref = uniq_tref(yyvsp[0].tref); yyval.tref->ref->is_const = TRUE; ;\r
     break;}\r
-case 234:\r
-#line 736 "parser.y"\r
+case 238:\r
+#line 739 "parser.y"\r
 { yyval.tref = make_tref(NULL, yyvsp[0].type); ;\r
     break;}\r
-case 235:\r
-#line 737 "parser.y"\r
+case 239:\r
+#line 740 "parser.y"\r
 { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsENUM)); ;\r
     break;}\r
-case 236:\r
-#line 738 "parser.y"\r
+case 240:\r
+#line 741 "parser.y"\r
 { yyval.tref = make_tref(NULL, yyvsp[0].type); ;\r
     break;}\r
-case 237:\r
-#line 739 "parser.y"\r
+case 241:\r
+#line 742 "parser.y"\r
 { yyval.tref = make_tref(NULL, get_type(RPC_FC_STRUCT, yyvsp[0].str, tsSTRUCT)); ;\r
     break;}\r
-case 238:\r
-#line 740 "parser.y"\r
+case 242:\r
+#line 743 "parser.y"\r
 { yyval.tref = make_tref(NULL, yyvsp[0].type); ;\r
     break;}\r
-case 239:\r
-#line 741 "parser.y"\r
+case 243:\r
+#line 744 "parser.y"\r
 { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsUNION)); ;\r
     break;}\r
-case 240:\r
-#line 744 "parser.y"\r
+case 244:\r
+#line 747 "parser.y"\r
 { typeref_t *tref = uniq_tref(yyvsp[-1].tref); \r
                                                  yyvsp[0].var->tname = tref->name;\r
                                                  tref->name = NULL;\r
@@ -2388,15 +2401,15 @@ case 240:
                                                  reg_types(yyval.type, yyvsp[0].var, 0);\r
                                                ;\r
     break;}\r
-case 241:\r
-#line 756 "parser.y"\r
+case 245:\r
+#line 759 "parser.y"\r
 { yyval.type = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, yyvsp[-3].var, tsUNION);\r
                                                  yyval.type->fields = yyvsp[-1].var;\r
                                                  yyval.type->defined = TRUE;\r
                                                ;\r
     break;}\r
-case 242:\r
-#line 762 "parser.y"\r
+case 246:\r
+#line 765 "parser.y"\r
 { var_t *u = yyvsp[-3].var;\r
                                                  yyval.type = get_typev(RPC_FC_ENCAPSULATED_UNION, yyvsp[-8].var, tsUNION);\r
                                                  if (!u) u = make_var("tagged_union");\r
@@ -2407,12 +2420,12 @@ case 242:
                                                  yyval.type->defined = TRUE;\r
                                                ;\r
     break;}\r
-case 243:\r
-#line 774 "parser.y"\r
+case 247:\r
+#line 777 "parser.y"\r
 { yyval.num = MAKELONG(yyvsp[0].num, 0); ;\r
     break;}\r
-case 244:\r
-#line 775 "parser.y"\r
+case 248:\r
+#line 778 "parser.y"\r
 { yyval.num = MAKELONG(yyvsp[-2].num, yyvsp[0].num); ;\r
     break;}\r
 }\r
@@ -2637,7 +2650,7 @@ yyerrhandle:
     }\r
   return 1;\r
 }\r
-#line 778 "parser.y"\r
+#line 781 "parser.y"\r
 \r
 \r
 static attr_t *make_attr(enum attr_type type)\r
index 4ae1eb3..1e3f2af 100644 (file)
@@ -98,40 +98,41 @@ typedef union {
 #define        tPROPGET        341\r
 #define        tPROPPUT        342\r
 #define        tPROPPUTREF     343\r
-#define        tPUBLIC 344\r
-#define        tREADONLY       345\r
-#define        tREF    346\r
-#define        tRESTRICTED     347\r
-#define        tRETVAL 348\r
-#define        tSHORT  349\r
-#define        tSIGNED 350\r
-#define        tSIZEIS 351\r
-#define        tSIZEOF 352\r
-#define        tSMALL  353\r
-#define        tSOURCE 354\r
-#define        tSTDCALL        355\r
-#define        tSTRING 356\r
-#define        tSTRUCT 357\r
-#define        tSWITCH 358\r
-#define        tSWITCHIS       359\r
-#define        tSWITCHTYPE     360\r
-#define        tTRANSMITAS     361\r
-#define        tTYPEDEF        362\r
-#define        tUNION  363\r
-#define        tUNIQUE 364\r
-#define        tUNSIGNED       365\r
-#define        tUUID   366\r
-#define        tV1ENUM 367\r
-#define        tVARARG 368\r
-#define        tVERSION        369\r
-#define        tVOID   370\r
-#define        tWCHAR  371\r
-#define        tWIREMARSHAL    372\r
-#define        tPOINTERTYPE    373\r
-#define        COND    374\r
-#define        CAST    375\r
-#define        PPTR    376\r
-#define        NEG     377\r
+#define        tPTR    344\r
+#define        tPUBLIC 345\r
+#define        tREADONLY       346\r
+#define        tREF    347\r
+#define        tRESTRICTED     348\r
+#define        tRETVAL 349\r
+#define        tSHORT  350\r
+#define        tSIGNED 351\r
+#define        tSIZEIS 352\r
+#define        tSIZEOF 353\r
+#define        tSMALL  354\r
+#define        tSOURCE 355\r
+#define        tSTDCALL        356\r
+#define        tSTRING 357\r
+#define        tSTRUCT 358\r
+#define        tSWITCH 359\r
+#define        tSWITCHIS       360\r
+#define        tSWITCHTYPE     361\r
+#define        tTRANSMITAS     362\r
+#define        tTYPEDEF        363\r
+#define        tUNION  364\r
+#define        tUNIQUE 365\r
+#define        tUNSIGNED       366\r
+#define        tUUID   367\r
+#define        tV1ENUM 368\r
+#define        tVARARG 369\r
+#define        tVERSION        370\r
+#define        tVOID   371\r
+#define        tWCHAR  372\r
+#define        tWIREMARSHAL    373\r
+#define        tPOINTERTYPE    374\r
+#define        COND    375\r
+#define        CAST    376\r
+#define        PPTR    377\r
+#define        NEG     378\r
 \r
 \r
 extern YYSTYPE yylval;\r
index 779d55e..d5d6a82 100644 (file)
@@ -16,7 +16,7 @@
 #define yytext pptext
 #define yywrap ppwrap
 
-#line 20 "wpp/lex.yy.c"
+#line 20 "lex.yy.c"
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
@@ -13707,9 +13707,9 @@ static yyconst short int yy_rule_linenum[144] =
 
       470,  471,  472,  483,  484,  488,  489,  501,  505,  514,
       520,  521,  522,  523,  524,  525,  530,  531,  532,  533,
-      538,  546,  547,  548,  549,  572,  573,  587,  588,  594,
-      618,  619,  628,  673,  674,  675,  676,  677,  683,  685,
-      691,  693,  701
+      538,  546,  547,  548,  549,  571,  572,  586,  587,  593,
+      617,  618,  627,  672,  673,  674,  675,  676,  682,  684,
+      690,  692,  700
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -13720,7 +13720,7 @@ static yyconst short int yy_rule_linenum[144] =
 #define YY_MORE_ADJ 0
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
-#line 1 "wpp/ppl.l"
+#line 1 "ppl.l"
 #define INITIAL 0
 /*
  * Wrc preprocessor lexical analysis
@@ -13893,7 +13893,7 @@ char *yytext;
 
 #define RCINCL 21
 
-#line 159 "wpp/ppl.l"
+#line 159 "ppl.l"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -14031,7 +14031,7 @@ includelogicentry_t *pp_includelogiclist = NULL;
  * The scanner starts here
  **************************************************************************
  */
-#line 14035 "wpp/lex.yy.c"
+#line 14035 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -14196,7 +14196,7 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
-#line 299 "wpp/ppl.l"
+#line 299 "ppl.l"
 
        /*
         * Catch line-continuations.
@@ -14210,7 +14210,7 @@ YY_DECL
        /*
         * Detect the leading # of a preprocessor directive.
         */
-#line 14214 "wpp/lex.yy.c"
+#line 14214 "lex.yy.c"
 
        if ( yy_init )
                {
@@ -14299,7 +14299,7 @@ do_action:      /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 312 "wpp/ppl.l"
+#line 312 "ppl.l"
 pp_incl_state.seen_junk++; yy_push_state(pp_pp);
        YY_BREAK
 /*
@@ -14307,107 +14307,107 @@ pp_incl_state.seen_junk++; yy_push_state(pp_pp);
         */
 case 2:
 YY_RULE_SETUP
-#line 317 "wpp/ppl.l"
+#line 317 "ppl.l"
 if(yy_top_state() != pp_ignore) {yy_pp_state(pp_inc); return tINCLUDE;} else {yy_pp_state(pp_eol);}
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 318 "wpp/ppl.l"
+#line 318 "ppl.l"
 if(yy_top_state() != pp_ignore) {yy_pp_state(pp_inc); return tINCLUDE_NEXT;} else {yy_pp_state(pp_eol);}
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 319 "wpp/ppl.l"
+#line 319 "ppl.l"
 yy_pp_state(yy_current_state() != pp_ignore ? pp_def : pp_eol);
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 320 "wpp/ppl.l"
+#line 320 "ppl.l"
 yy_pp_state(pp_eol);   if(yy_top_state() != pp_ignore) return tERROR;
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 321 "wpp/ppl.l"
+#line 321 "ppl.l"
 yy_pp_state(pp_eol);   if(yy_top_state() != pp_ignore) return tWARNING;
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 322 "wpp/ppl.l"
+#line 322 "ppl.l"
 yy_pp_state(pp_eol);   if(yy_top_state() != pp_ignore) return tPRAGMA;
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 323 "wpp/ppl.l"
+#line 323 "ppl.l"
 yy_pp_state(pp_eol);   if(yy_top_state() != pp_ignore) return tPPIDENT;
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 324 "wpp/ppl.l"
+#line 324 "ppl.l"
 if(yy_top_state() != pp_ignore) {yy_pp_state(pp_ifd); return tUNDEF;} else {yy_pp_state(pp_eol);}
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 325 "wpp/ppl.l"
+#line 325 "ppl.l"
 yy_pp_state(pp_ifd);   return tIFDEF;
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 326 "wpp/ppl.l"
+#line 326 "ppl.l"
 pp_incl_state.seen_junk--; yy_pp_state(pp_ifd);        return tIFNDEF;
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 327 "wpp/ppl.l"
+#line 327 "ppl.l"
 yy_pp_state(pp_if);    return tIF;
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 328 "wpp/ppl.l"
+#line 328 "ppl.l"
 yy_pp_state(pp_if);    return tELIF;
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 329 "wpp/ppl.l"
+#line 329 "ppl.l"
 yy_pp_state(pp_endif);  return tELSE;
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 330 "wpp/ppl.l"
+#line 330 "ppl.l"
 yy_pp_state(pp_endif);  return tENDIF;
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 331 "wpp/ppl.l"
+#line 331 "ppl.l"
 if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tLINE;} else {yy_pp_state(pp_eol);}
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 332 "wpp/ppl.l"
+#line 332 "ppl.l"
 if(yy_top_state() != pp_ignore) {yy_pp_state(pp_line); return tGCCLINE;} else {yy_pp_state(pp_eol);}
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 333 "wpp/ppl.l"
+#line 333 "ppl.l"
 pperror("Invalid preprocessor token '%s'", pptext);
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 334 "wpp/ppl.l"
+#line 334 "ppl.l"
 newline(1); yy_pop_state(); return tNL;        /* This could be the null-token */
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 335 "wpp/ppl.l"
+#line 335 "ppl.l"
 newline(0);
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 336 "wpp/ppl.l"
+#line 336 "ppl.l"
 pperror("Preprocessor junk '%s'", pptext);
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 337 "wpp/ppl.l"
+#line 337 "ppl.l"
 return *pptext;
        YY_BREAK
 /*
@@ -14415,37 +14415,37 @@ return *pptext;
         */
 case 23:
 YY_RULE_SETUP
-#line 342 "wpp/ppl.l"
+#line 342 "ppl.l"
 return make_number(10, &pplval, pptext, ppleng);
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 343 "wpp/ppl.l"
+#line 343 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_iqs);
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 344 "wpp/ppl.l"
+#line 344 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 345 "wpp/ppl.l"
+#line 345 "ppl.l"
 ;
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 346 "wpp/ppl.l"
+#line 346 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 347 "wpp/ppl.l"
+#line 347 "ppl.l"
 newline(0);
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 348 "wpp/ppl.l"
+#line 348 "ppl.l"
 pperror(yy_current_state() == pp_inc ? "Trailing junk in #include" : "Trailing junk in #line");
        YY_BREAK
 /*
@@ -14453,22 +14453,22 @@ pperror(yy_current_state() == pp_inc ? "Trailing junk in #include" : "Trailing j
         */
 case 30:
 YY_RULE_SETUP
-#line 353 "wpp/ppl.l"
+#line 353 "ppl.l"
 ;
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 354 "wpp/ppl.l"
+#line 354 "ppl.l"
 newline(1);
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 355 "wpp/ppl.l"
+#line 355 "ppl.l"
 newline(0);
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 356 "wpp/ppl.l"
+#line 356 "ppl.l"
 ;
        YY_BREAK
 /*
@@ -14479,107 +14479,107 @@ YY_RULE_SETUP
         */
 case 34:
 YY_RULE_SETUP
-#line 365 "wpp/ppl.l"
+#line 365 "ppl.l"
 return make_number(8, &pplval, pptext, ppleng);
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 366 "wpp/ppl.l"
+#line 366 "ppl.l"
 pperror("Invalid octal digit");
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 367 "wpp/ppl.l"
+#line 367 "ppl.l"
 return make_number(10, &pplval, pptext, ppleng);
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 368 "wpp/ppl.l"
+#line 368 "ppl.l"
 return make_number(16, &pplval, pptext, ppleng);
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 369 "wpp/ppl.l"
+#line 369 "ppl.l"
 pperror("Invalid hex number");
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 370 "wpp/ppl.l"
+#line 370 "ppl.l"
 yy_push_state(pp_defined); return tDEFINED;
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 371 "wpp/ppl.l"
+#line 371 "ppl.l"
 return tLSHIFT;
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 372 "wpp/ppl.l"
+#line 372 "ppl.l"
 return tRSHIFT;
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 373 "wpp/ppl.l"
+#line 373 "ppl.l"
 return tLOGAND;
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 374 "wpp/ppl.l"
+#line 374 "ppl.l"
 return tLOGOR;
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 375 "wpp/ppl.l"
+#line 375 "ppl.l"
 return tEQ;
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 376 "wpp/ppl.l"
+#line 376 "ppl.l"
 return tNE;
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 377 "wpp/ppl.l"
+#line 377 "ppl.l"
 return tLTE;
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 378 "wpp/ppl.l"
+#line 378 "ppl.l"
 return tGTE;
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 379 "wpp/ppl.l"
+#line 379 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 380 "wpp/ppl.l"
+#line 380 "ppl.l"
 newline(0);
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 381 "wpp/ppl.l"
+#line 381 "ppl.l"
 pperror("Junk in conditional expression");
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 382 "wpp/ppl.l"
+#line 382 "ppl.l"
 ;
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 383 "wpp/ppl.l"
+#line 383 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 384 "wpp/ppl.l"
+#line 384 "ppl.l"
 pperror("String constants not allowed in conditionals");
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 385 "wpp/ppl.l"
+#line 385 "ppl.l"
 return *pptext;
        YY_BREAK
 /*
@@ -14588,27 +14588,27 @@ return *pptext;
         */
 case 55:
 YY_RULE_SETUP
-#line 391 "wpp/ppl.l"
+#line 391 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tIDENT;
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 392 "wpp/ppl.l"
+#line 392 "ppl.l"
 ;
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 393 "wpp/ppl.l"
+#line 393 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 394 "wpp/ppl.l"
+#line 394 "ppl.l"
 newline(0);
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 395 "wpp/ppl.l"
+#line 395 "ppl.l"
 pperror("Identifier expected");
        YY_BREAK
 /*
@@ -14616,22 +14616,22 @@ pperror("Identifier expected");
         */
 case 60:
 YY_RULE_SETUP
-#line 400 "wpp/ppl.l"
+#line 400 "ppl.l"
 ;
        YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 401 "wpp/ppl.l"
+#line 401 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 402 "wpp/ppl.l"
+#line 402 "ppl.l"
 newline(0);
        YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 403 "wpp/ppl.l"
+#line 403 "ppl.l"
 pperror("Garbage after #else or #endif.");
        YY_BREAK
 /*
@@ -14641,27 +14641,27 @@ pperror("Garbage after #else or #endif.");
         */
 case 64:
 YY_RULE_SETUP
-#line 410 "wpp/ppl.l"
+#line 410 "ppl.l"
 yy_pop_state(); pplval.cptr = pp_xstrdup(pptext); return tIDENT;
        YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 411 "wpp/ppl.l"
+#line 411 "ppl.l"
 ;
        YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 412 "wpp/ppl.l"
+#line 412 "ppl.l"
 return *pptext;
        YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 413 "wpp/ppl.l"
+#line 413 "ppl.l"
 newline(0);
        YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 414 "wpp/ppl.l"
+#line 414 "ppl.l"
 pperror("Identifier expected");
        YY_BREAK
 /*
@@ -14672,27 +14672,27 @@ pperror("Identifier expected");
         */
 case 69:
 YY_RULE_SETUP
-#line 422 "wpp/ppl.l"
+#line 422 "ppl.l"
 if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; }
        YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 423 "wpp/ppl.l"
+#line 423 "ppl.l"
 if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; }
        YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 424 "wpp/ppl.l"
+#line 424 "ppl.l"
 if(yy_top_state() != pp_ignore) { pplval.cptr = pp_xstrdup(pptext); return tLITERAL; }
        YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 425 "wpp/ppl.l"
+#line 425 "ppl.l"
 newline(1); yy_pop_state(); if(yy_current_state() != pp_ignore) { return tNL; }
        YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 426 "wpp/ppl.l"
+#line 426 "ppl.l"
 newline(0);
        YY_BREAK
 /*
@@ -14700,27 +14700,27 @@ newline(0);
         */
 case 74:
 YY_RULE_SETUP
-#line 431 "wpp/ppl.l"
+#line 431 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); pplval.cptr[ppleng-1] = '\0'; yy_pp_state(pp_macro);  return tMACRO;
        YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 432 "wpp/ppl.l"
+#line 432 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); yy_pp_state(pp_define); return tDEFINE;
        YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 433 "wpp/ppl.l"
+#line 433 "ppl.l"
 ;
        YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 434 "wpp/ppl.l"
+#line 434 "ppl.l"
 newline(0);
        YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 435 "wpp/ppl.l"
+#line 435 "ppl.l"
 perror("Identifier expected");
        YY_BREAK
 /*
@@ -14728,37 +14728,37 @@ perror("Identifier expected");
         */
 case 79:
 YY_RULE_SETUP
-#line 440 "wpp/ppl.l"
+#line 440 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tLITERAL;
        YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 441 "wpp/ppl.l"
+#line 441 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tLITERAL;
        YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 442 "wpp/ppl.l"
+#line 442 "ppl.l"
 newline(0); pplval.cptr = pp_xstrdup(" "); return tLITERAL;
        YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 443 "wpp/ppl.l"
+#line 443 "ppl.l"
 newline(0);
        YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 444 "wpp/ppl.l"
+#line 444 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 445 "wpp/ppl.l"
+#line 445 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
        YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 446 "wpp/ppl.l"
+#line 446 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
        YY_BREAK
 /*
@@ -14766,37 +14766,37 @@ new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
         */
 case 86:
 YY_RULE_SETUP
-#line 451 "wpp/ppl.l"
+#line 451 "ppl.l"
 yy_pp_state(pp_mbody); return tMACROEND;
        YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 452 "wpp/ppl.l"
+#line 452 "ppl.l"
 ;
        YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 453 "wpp/ppl.l"
+#line 453 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tIDENT;
        YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 454 "wpp/ppl.l"
+#line 454 "ppl.l"
 return ',';
        YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 455 "wpp/ppl.l"
+#line 455 "ppl.l"
 return tELIPSIS;
        YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 456 "wpp/ppl.l"
+#line 456 "ppl.l"
 pperror("Argument identifier expected");
        YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 457 "wpp/ppl.l"
+#line 457 "ppl.l"
 newline(0);
        YY_BREAK
 /*
@@ -14804,57 +14804,57 @@ newline(0);
         */
 case 93:
 YY_RULE_SETUP
-#line 462 "wpp/ppl.l"
+#line 462 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tLITERAL;
        YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 463 "wpp/ppl.l"
+#line 463 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tIDENT;
        YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 464 "wpp/ppl.l"
+#line 464 "ppl.l"
 return tCONCAT;
        YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 465 "wpp/ppl.l"
+#line 465 "ppl.l"
 return tSTRINGIZE;
        YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 466 "wpp/ppl.l"
+#line 466 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tLITERAL;
        YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 467 "wpp/ppl.l"
+#line 467 "ppl.l"
 pplval.cptr = pp_xstrdup(pptext); return tLITERAL;
        YY_BREAK
 case 99:
 YY_RULE_SETUP
-#line 468 "wpp/ppl.l"
+#line 468 "ppl.l"
 newline(0); pplval.cptr = pp_xstrdup(" "); return tLITERAL;
        YY_BREAK
 case 100:
 YY_RULE_SETUP
-#line 469 "wpp/ppl.l"
+#line 469 "ppl.l"
 newline(0);
        YY_BREAK
 case 101:
 YY_RULE_SETUP
-#line 470 "wpp/ppl.l"
+#line 470 "ppl.l"
 newline(1); yy_pop_state(); return tNL;
        YY_BREAK
 case 102:
 YY_RULE_SETUP
-#line 471 "wpp/ppl.l"
+#line 471 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
        YY_BREAK
 case 103:
 YY_RULE_SETUP
-#line 472 "wpp/ppl.l"
+#line 472 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
        YY_BREAK
 /*
@@ -14871,12 +14871,12 @@ case 104:
 yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 483 "wpp/ppl.l"
+#line 483 "ppl.l"
 yy_pp_state(pp_macscan);
        YY_BREAK
 case 105:
 YY_RULE_SETUP
-#line 484 "wpp/ppl.l"
+#line 484 "ppl.l"
 {
                if(yy_top_state() != pp_macscan)
                        newline(0);
@@ -14884,12 +14884,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 106:
 YY_RULE_SETUP
-#line 488 "wpp/ppl.l"
+#line 488 "ppl.l"
 newline(0);
        YY_BREAK
 case 107:
 YY_RULE_SETUP
-#line 489 "wpp/ppl.l"
+#line 489 "ppl.l"
 {
                macexpstackentry_t *mac = pop_macro();
                yy_pop_state();
@@ -14904,7 +14904,7 @@ YY_RULE_SETUP
         */
 case 108:
 YY_RULE_SETUP
-#line 501 "wpp/ppl.l"
+#line 501 "ppl.l"
 {
                if(++MACROPARENTHESES() > 1)
                        add_text_to_macro(pptext, ppleng);
@@ -14912,7 +14912,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 109:
 YY_RULE_SETUP
-#line 505 "wpp/ppl.l"
+#line 505 "ppl.l"
 {
                if(--MACROPARENTHESES() == 0)
                {
@@ -14925,7 +14925,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 110:
 YY_RULE_SETUP
-#line 514 "wpp/ppl.l"
+#line 514 "ppl.l"
 {
                if(MACROPARENTHESES() > 1)
                        add_text_to_macro(pptext, ppleng);
@@ -14935,32 +14935,32 @@ YY_RULE_SETUP
        YY_BREAK
 case 111:
 YY_RULE_SETUP
-#line 520 "wpp/ppl.l"
+#line 520 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
        YY_BREAK
 case 112:
 YY_RULE_SETUP
-#line 521 "wpp/ppl.l"
+#line 521 "ppl.l"
 new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
        YY_BREAK
 case 113:
 YY_RULE_SETUP
-#line 522 "wpp/ppl.l"
+#line 522 "ppl.l"
 yy_push_state(pp_comment); add_text_to_macro(" ", 1);
        YY_BREAK
 case 114:
 YY_RULE_SETUP
-#line 523 "wpp/ppl.l"
+#line 523 "ppl.l"
 pp_status.line_number++; pp_status.char_number = 1; add_text_to_macro(pptext, ppleng);
        YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 524 "wpp/ppl.l"
+#line 524 "ppl.l"
 add_text_to_macro(pptext, ppleng);
        YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 525 "wpp/ppl.l"
+#line 525 "ppl.l"
 newline(0);
        YY_BREAK
 /*
@@ -14968,22 +14968,22 @@ newline(0);
         */
 case 117:
 YY_RULE_SETUP
-#line 530 "wpp/ppl.l"
+#line 530 "ppl.l"
 yy_push_state(pp_comment);
        YY_BREAK
 case 118:
 YY_RULE_SETUP
-#line 531 "wpp/ppl.l"
+#line 531 "ppl.l"
 ;
        YY_BREAK
 case 119:
 YY_RULE_SETUP
-#line 532 "wpp/ppl.l"
+#line 532 "ppl.l"
 newline(0);
        YY_BREAK
 case 120:
 YY_RULE_SETUP
-#line 533 "wpp/ppl.l"
+#line 533 "ppl.l"
 yy_pop_state();
        YY_BREAK
 /*
@@ -14991,7 +14991,7 @@ yy_pop_state();
         */
 case 121:
 YY_RULE_SETUP
-#line 538 "wpp/ppl.l"
+#line 538 "ppl.l"
 {
                if(pptext[ppleng-1] == '\\')
                        ppwarning("C++ style comment ends with an escaped newline (escape ignored)");
@@ -15002,22 +15002,22 @@ YY_RULE_SETUP
         */
 case 122:
 YY_RULE_SETUP
-#line 546 "wpp/ppl.l"
+#line 546 "ppl.l"
 pp_incl_state.seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_dqs);
        YY_BREAK
 case 123:
 YY_RULE_SETUP
-#line 547 "wpp/ppl.l"
+#line 547 "ppl.l"
 pp_incl_state.seen_junk++; new_string(); add_string(pptext, ppleng); yy_push_state(pp_sqs);
        YY_BREAK
 case 124:
 YY_RULE_SETUP
-#line 548 "wpp/ppl.l"
+#line 548 "ppl.l"
 add_string(pptext, ppleng);
        YY_BREAK
 case 125:
 YY_RULE_SETUP
-#line 549 "wpp/ppl.l"
+#line 549 "ppl.l"
 {
                add_string(pptext, ppleng);
                yy_pop_state();
@@ -15035,7 +15035,6 @@ YY_RULE_SETUP
                        pplval.cptr = get_string();
                        if (is_c_h_include(pplval.cptr, 1)) pass_data=0;
                        else pass_data=1;
-//fprintf(stderr, "%s pass_data %d\n", pplval.cptr, pass_data);
                        return tDQSTRING;
                default:
                        put_string();
@@ -15044,12 +15043,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 126:
 YY_RULE_SETUP
-#line 572 "wpp/ppl.l"
+#line 571 "ppl.l"
 add_string(pptext, ppleng);
        YY_BREAK
 case 127:
 YY_RULE_SETUP
-#line 573 "wpp/ppl.l"
+#line 572 "ppl.l"
 {
                add_string(pptext, ppleng);
                yy_pop_state();
@@ -15067,12 +15066,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 128:
 YY_RULE_SETUP
-#line 587 "wpp/ppl.l"
+#line 586 "ppl.l"
 add_string(pptext, ppleng);
        YY_BREAK
 case 129:
 YY_RULE_SETUP
-#line 588 "wpp/ppl.l"
+#line 587 "ppl.l"
 {
                add_string(pptext, ppleng);
                yy_pop_state();
@@ -15082,7 +15081,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 130:
 YY_RULE_SETUP
-#line 594 "wpp/ppl.l"
+#line 593 "ppl.l"
 {
                /*
                 * This is tricky; we need to remove the line-continuation
@@ -15110,12 +15109,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 131:
 YY_RULE_SETUP
-#line 618 "wpp/ppl.l"
+#line 617 "ppl.l"
 add_string(pptext, ppleng);
        YY_BREAK
 case 132:
 YY_RULE_SETUP
-#line 619 "wpp/ppl.l"
+#line 618 "ppl.l"
 {
                newline(1);
                add_string(pptext, ppleng);
@@ -15127,7 +15126,7 @@ YY_RULE_SETUP
         */
 case 133:
 YY_RULE_SETUP
-#line 628 "wpp/ppl.l"
+#line 627 "ppl.l"
 {
                pp_entry_t *ppp;
                pp_incl_state.seen_junk++;
@@ -15175,27 +15174,27 @@ YY_RULE_SETUP
         */
 case 134:
 YY_RULE_SETUP
-#line 673 "wpp/ppl.l"
+#line 672 "ppl.l"
 pp_incl_state.seen_junk++; put_buffer(pptext, ppleng);
        YY_BREAK
 case 135:
 YY_RULE_SETUP
-#line 674 "wpp/ppl.l"
+#line 673 "ppl.l"
 put_buffer(pptext, ppleng);
        YY_BREAK
 case 136:
 YY_RULE_SETUP
-#line 675 "wpp/ppl.l"
+#line 674 "ppl.l"
 newline(1);
        YY_BREAK
 case 137:
 YY_RULE_SETUP
-#line 676 "wpp/ppl.l"
+#line 675 "ppl.l"
 newline(0);
        YY_BREAK
 case 138:
 YY_RULE_SETUP
-#line 677 "wpp/ppl.l"
+#line 676 "ppl.l"
 pp_incl_state.seen_junk++; put_buffer(pptext, ppleng);
        YY_BREAK
 /*
@@ -15204,12 +15203,12 @@ pp_incl_state.seen_junk++; put_buffer(pptext, ppleng);
         */
 case 139:
 YY_RULE_SETUP
-#line 683 "wpp/ppl.l"
+#line 682 "ppl.l"
 put_buffer(pptext, ppleng);
        YY_BREAK
 case 140:
 YY_RULE_SETUP
-#line 685 "wpp/ppl.l"
+#line 684 "ppl.l"
 {
                pplval.cptr=pp_xstrdup(pptext);
                yy_pop_state();
@@ -15218,12 +15217,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 141:
 YY_RULE_SETUP
-#line 691 "wpp/ppl.l"
+#line 690 "ppl.l"
 ;
        YY_BREAK
 case 142:
 YY_RULE_SETUP
-#line 693 "wpp/ppl.l"
+#line 692 "ppl.l"
 {
                new_string(); add_string(pptext,ppleng);yy_push_state(pp_dqs);
        }
@@ -15234,7 +15233,7 @@ YY_RULE_SETUP
         */
 case 143:
 YY_RULE_SETUP
-#line 701 "wpp/ppl.l"
+#line 700 "ppl.l"
 pp_incl_state.seen_junk++; ppwarning("Unmatched text '%c' (0x%02x); please report\n", isprint(*pptext & 0xff) ? *pptext : ' ', *pptext);
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
@@ -15259,7 +15258,7 @@ case YY_STATE_EOF(pp_line):
 case YY_STATE_EOF(pp_defined):
 case YY_STATE_EOF(pp_ignore):
 case YY_STATE_EOF(RCINCL):
-#line 703 "wpp/ppl.l"
+#line 702 "ppl.l"
 {
                YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
                bufferstackentry_t *bep = pop_buffer();
@@ -15284,10 +15283,10 @@ case YY_STATE_EOF(RCINCL):
        YY_BREAK
 case 144:
 YY_RULE_SETUP
-#line 725 "wpp/ppl.l"
+#line 724 "ppl.l"
 ECHO;
        YY_BREAK
-#line 15291 "wpp/lex.yy.c"
+#line 15290 "lex.yy.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -16172,7 +16171,7 @@ int main()
        return 0;
        }
 #endif
-#line 725 "wpp/ppl.l"
+#line 724 "ppl.l"
 
 /*
  **************************************************************************
@@ -16869,7 +16868,7 @@ static int is_c_h_include(char *fname, int quoted)
        int sl=strlen(fname);
        if (sl < 2 + 2 * quoted) return 0;
        if ((toupper(fname[sl-1-quoted])!='H') && (toupper(fname[sl-1-quoted])!='C')) return 0;
-        if (fname[sl-2-quoted]!='.') return 0;
+       if (fname[sl-2-quoted]!='.') return 0;
        return 1;
 }
 
index 6a021ee..f4f8bc1 100644 (file)
@@ -563,7 +563,6 @@ includelogicentry_t *pp_includelogiclist = NULL;
                        pplval.cptr = get_string();
                        if (is_c_h_include(pplval.cptr, 1)) pass_data=0;
                        else pass_data=1;
-//fprintf(stderr, "%s pass_data %d\n", pplval.cptr, pass_data);
                        return tDQSTRING;
                default:
                        put_string();
@@ -1418,7 +1417,7 @@ static int is_c_h_include(char *fname, int quoted)
        int sl=strlen(fname);
        if (sl < 2 + 2 * quoted) return 0;
        if ((toupper(fname[sl-1-quoted])!='H') && (toupper(fname[sl-1-quoted])!='C')) return 0;
-        if (fname[sl-2-quoted]!='.') return 0;
+       if (fname[sl-2-quoted]!='.') return 0;
        return 1;
 }
 
index 499844a..c9c0560 100644 (file)
@@ -679,8 +679,8 @@ cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
  * The "LIST" tag may occur several times and may encapsulate different
  * tags. The `steps' is the number of "icon" tags found (actually the
  * number of steps specified in the aniheader_t structure). The "seq "uence
- * tag can be ommitted, in which case the sequence is equal to the sequence
- * of "icon"s found in the file. Also "rate" may be ommitted, in which case
+ * tag can be omitted, in which case the sequence is equal to the sequence
+ * of "icon"s found in the file. Also "rate" may be omitted, in which case
  * the default from the aniheader_t structure is used.
  *
  * An animated cursor puts `.cur' formatted files into each "icon" tag,
index f9d3da8..2e2c40c 100644 (file)
@@ -352,7 +352,6 @@ static int rsrcid_to_token(int lookahead);
 %type <dginit>  dlginit
 %type <styles>  optional_style_pair
 %type <num>    any_num
-%type <style>   optional_style
 %type <style>   style
 %type <str>    filename
 
@@ -458,7 +457,7 @@ resources
         * for tNL. However, byacc already generates an error upon reading
         * the token instead of keeping it as a lookahead. The reason
         * lies in the lack of a $default transition in the "expr : xpr . "
-        * state (currently state 25). It is probably ommitted because tNL
+        * state (currently state 25). It is probably omitted because tNL
         * is a non-terminal and the state contains 2 s/r conflicts. The
         * state enumerates all possible transitions instead of using a
         * $default transition.
@@ -735,11 +734,11 @@ dlginit   : tDLGINIT loadmemopts file_raw { $$ = new_dlginit($3, $2); }
 
 /* ------------------------------ UserType ------------------------------ */
 userres        : usertype loadmemopts file_raw         {
-               #ifdef WORDS_BIGENDIAN
+#ifdef WORDS_BIGENDIAN
                        if(pedantic && byteorder != WRC_BO_LITTLE)
-               #else
+#else
                        if(pedantic && byteorder == WRC_BO_BIG)
-               #endif
+#endif
                                yywarning("Byteordering is not little-endian and type cannot be interpreted");
                        $$ = new_user($1, $3, $2);
                }
@@ -889,7 +888,7 @@ ctrls       : /* Empty */                           { $$ = NULL; }
        ;
 
 lab_ctrl
-       : tSTRING opt_comma expr ',' expr ',' expr ',' expr ',' expr optional_style {
+       : tSTRING opt_comma expr ',' expr ',' expr ',' expr ',' expr optional_style_pair {
                $$=new_control();
                $$->title = new_name_id();
                $$->title->type = name_str;
@@ -901,14 +900,20 @@ lab_ctrl
                $$->height = $11;
                if($12)
                {
-                       $$->style = $12;
+                       $$->style = $12->style;
                        $$->gotstyle = TRUE;
+                       if ($12->exstyle)
+                       {
+                           $$->exstyle = $12->exstyle;
+                           $$->gotexstyle = TRUE;
+                       }
+                       free($12);
                }
                }
        ;
 
 ctrl_desc
-       : expr ',' expr ',' expr ',' expr ',' expr optional_style {
+       : expr ',' expr ',' expr ',' expr ',' expr optional_style_pair {
                $$ = new_control();
                $$->id = $1;
                $$->x = $3;
@@ -917,8 +922,14 @@ ctrl_desc
                $$->height = $9;
                if($10)
                {
-                       $$->style = $10;
+                       $$->style = $10->style;
                        $$->gotstyle = TRUE;
+                       if ($10->exstyle)
+                       {
+                           $$->exstyle = $10->exstyle;
+                           $$->gotexstyle = TRUE;
+                       }
+                       free($10);
                }
                }
        ;
@@ -982,11 +993,6 @@ opt_font
        ;
 
 /* ------------------------------ style flags ------------------------------ */
-optional_style         /* Abbused once to get optional ExStyle */
-       : /* Empty */   { $$ = NULL; }
-       | ',' style     { $$ = $2; }
-       ;
-
 optional_style_pair
        : /* Empty */           { $$ = NULL; }
        | ',' style             { $$ = new_style_pair($2, 0); }
index 6205693..670d9c0 100644 (file)
@@ -55,7 +55,7 @@ WRC_OBJECTS = \
 WRC_HOST_CFLAGS = -I$(WRC_BASE) -g -Werror -Wall \
                   -D__USE_W32API -DWINE_UNICODE_API= \
                   -Dwchar_t="unsigned short" -D_WCHAR_T_DEFINED \
-                  -I$(UNICODE_BASE) -I$(WPP_BASE) -I$(WRC_BASE) \
+                  -I$(UNICODE_BASE) -I$(WPP_BASE) \
                   -Iinclude/wine -Iinclude -Iw32api/include
 
 WRC_HOST_LFLAGS = -g
index 3246401..0ad3f05 100644 (file)
@@ -634,16 +634,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   692
+#define YYLAST   696
 
 /* YYNTOKENS -- Number of terminals. */
 #define YYNTOKENS  96
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  83
+#define YYNNTS  82
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  258
+#define YYNRULES  256
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  572
+#define YYNSTATES  570
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -706,158 +706,158 @@ static const unsigned short yyprhs[] =
      202,   205,   206,   210,   214,   218,   222,   226,   230,   234,
      238,   242,   246,   250,   254,   258,   262,   266,   270,   274,
      285,   298,   309,   310,   315,   322,   331,   349,   365,   370,
-     371,   374,   375,   378,   383,   387,   391,   393,   396,   398,
-     400,   415,   416,   420,   424,   428,   431,   434,   438,   442,
-     445,   448,   451,   452,   456,   460,   464,   468,   472,   476,
-     480,   484,   488,   492,   496,   500,   504,   508,   512,   516,
-     520,   531,   551,   568,   583,   596,   597,   599,   600,   603,
-     613,   614,   617,   622,   626,   627,   634,   638,   644,   645,
-     649,   653,   657,   661,   665,   669,   674,   678,   679,   684,
-     688,   694,   695,   698,   704,   711,   712,   715,   720,   727,
-     736,   741,   745,   746,   751,   752,   754,   761,   762,   772,
-     782,   786,   790,   794,   798,   802,   803,   806,   812,   813,
-     816,   818,   823,   828,   830,   834,   844,   845,   849,   852,
-     853,   856,   859,   861,   863,   865,   867,   869,   871,   873,
-     874,   877,   880,   883,   888,   891,   894,   899,   901,   903,
-     906,   908,   911,   913,   917,   921,   926,   930,   935,   939,
-     941,   943,   944,   946,   948,   952,   956,   960,   964,   968,
-     972,   976,   979,   982,   985,   989,   991,   994,   996
+     371,   374,   379,   383,   387,   389,   392,   394,   396,   411,
+     412,   416,   420,   424,   427,   430,   434,   438,   441,   444,
+     447,   448,   452,   456,   460,   464,   468,   472,   476,   480,
+     484,   488,   492,   496,   500,   504,   508,   512,   516,   527,
+     547,   564,   579,   592,   593,   595,   596,   599,   609,   610,
+     613,   618,   622,   623,   630,   634,   640,   641,   645,   649,
+     653,   657,   661,   665,   670,   674,   675,   680,   684,   690,
+     691,   694,   700,   707,   708,   711,   716,   723,   732,   737,
+     741,   742,   747,   748,   750,   757,   758,   768,   778,   782,
+     786,   790,   794,   798,   799,   802,   808,   809,   812,   814,
+     819,   824,   826,   830,   840,   841,   845,   848,   849,   852,
+     855,   857,   859,   861,   863,   865,   867,   869,   870,   873,
+     876,   879,   884,   887,   890,   895,   897,   899,   902,   904,
+     907,   909,   913,   917,   922,   926,   931,   935,   937,   939,
+     940,   942,   944,   948,   952,   956,   960,   964,   968,   972,
+     975,   978,   981,   985,   987,   990,   992
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const short yyrhs[] =
 {
       97,     0,    -1,    98,    -1,    -1,    98,    99,    -1,    98,
-       3,    -1,   176,   101,   104,    -1,     7,   101,   104,    -1,
-     152,    -1,    -1,    64,   100,   176,    93,   176,    -1,    -1,
-     176,    -1,     7,    -1,   102,    -1,     6,    -1,   116,    -1,
-     106,    -1,   107,    -1,   121,    -1,   133,    -1,   113,    -1,
-     109,    -1,   110,    -1,   108,    -1,   143,    -1,   147,    -1,
-     111,    -1,   112,    -1,   163,    -1,   114,    -1,   156,    -1,
-       8,    -1,     7,    -1,     6,    -1,    11,   165,   174,    -1,
-      12,   165,   174,    -1,    23,   165,   174,    -1,    21,   165,
-     174,    -1,    22,   165,   174,    -1,    17,   165,   174,    -1,
-      18,   165,   174,    -1,    82,   165,   174,    -1,   115,   165,
-     174,    -1,     4,    -1,     7,    -1,    10,   165,   168,    80,
-     117,    81,    -1,    -1,   117,     6,    93,   176,   118,    -1,
-     117,   176,    93,   176,   118,    -1,    -1,    93,   119,    -1,
+       3,    -1,   175,   101,   104,    -1,     7,   101,   104,    -1,
+     151,    -1,    -1,    64,   100,   175,    93,   175,    -1,    -1,
+     175,    -1,     7,    -1,   102,    -1,     6,    -1,   116,    -1,
+     106,    -1,   107,    -1,   121,    -1,   132,    -1,   113,    -1,
+     109,    -1,   110,    -1,   108,    -1,   142,    -1,   146,    -1,
+     111,    -1,   112,    -1,   162,    -1,   114,    -1,   155,    -1,
+       8,    -1,     7,    -1,     6,    -1,    11,   164,   173,    -1,
+      12,   164,   173,    -1,    23,   164,   173,    -1,    21,   164,
+     173,    -1,    22,   164,   173,    -1,    17,   164,   173,    -1,
+      18,   164,   173,    -1,    82,   164,   173,    -1,   115,   164,
+     173,    -1,     4,    -1,     7,    -1,    10,   164,   167,    80,
+     117,    81,    -1,    -1,   117,     6,    93,   175,   118,    -1,
+     117,   175,    93,   175,   118,    -1,    -1,    93,   119,    -1,
      120,    -1,   119,    93,   120,    -1,    50,    -1,    43,    -1,
-      36,    -1,    44,    -1,    45,    -1,    46,    -1,    13,   165,
-     176,    93,   176,    93,   176,    93,   176,   122,    80,   123,
-      81,    -1,    -1,   122,    62,   131,    -1,   122,    61,   131,
+      36,    -1,    44,    -1,    45,    -1,    46,    -1,    13,   164,
+     175,    93,   175,    93,   175,    93,   175,   122,    80,   123,
+      81,    -1,    -1,   122,    62,   130,    -1,   122,    61,   130,
       -1,   122,    59,     6,    -1,   122,   128,    -1,   122,    58,
-     103,    -1,   122,    15,   102,    -1,   122,   169,    -1,   122,
-     170,    -1,   122,   171,    -1,    -1,   123,    36,   127,    -1,
+     103,    -1,   122,    15,   102,    -1,   122,   168,    -1,   122,
+     169,    -1,   122,   170,    -1,    -1,   123,    36,   127,    -1,
      123,    37,   125,    -1,   123,    34,   125,    -1,   123,    33,
      125,    -1,   123,    35,   125,    -1,   123,    27,   124,    -1,
      123,    28,   124,    -1,   123,    32,   124,    -1,   123,    29,
      124,    -1,   123,    30,   124,    -1,   123,    24,   124,    -1,
      123,    31,   124,    -1,   123,    25,   124,    -1,   123,    26,
      124,    -1,   123,    40,   124,    -1,   123,    39,   124,    -1,
-     123,    38,   124,    -1,   123,    23,   103,   155,   176,    93,
-     176,    93,   176,   126,    -1,     6,   155,   176,    93,   176,
-      93,   176,    93,   176,    93,   176,   129,    -1,   176,    93,
-     176,    93,   176,    93,   176,    93,   176,   129,    -1,    -1,
-      93,   176,    93,   176,    -1,    93,   176,    93,   176,    93,
-     131,    -1,    93,   176,    93,   176,    93,   131,    93,   131,
-      -1,   103,   155,   176,    93,   132,    93,   131,    93,   176,
-      93,   176,    93,   176,    93,   176,    93,   131,    -1,   103,
-     155,   176,    93,   132,    93,   131,    93,   176,    93,   176,
-      93,   176,    93,   176,    -1,    21,   176,    93,     6,    -1,
-      -1,    93,   131,    -1,    -1,    93,   131,    -1,    93,   131,
-      93,   131,    -1,   131,    83,   131,    -1,    94,   131,    95,
-      -1,   177,    -1,    91,   177,    -1,   176,    -1,     6,    -1,
-      14,   165,   176,    93,   176,    93,   176,    93,   176,   140,
-     134,    80,   135,    81,    -1,    -1,   134,    62,   131,    -1,
-     134,    61,   131,    -1,   134,    59,     6,    -1,   134,   128,
-      -1,   134,   141,    -1,   134,    58,   103,    -1,   134,    15,
-     102,    -1,   134,   169,    -1,   134,   170,    -1,   134,   171,
-      -1,    -1,   135,    36,   136,    -1,   135,    37,   138,    -1,
-     135,    34,   138,    -1,   135,    33,   138,    -1,   135,    35,
-     138,    -1,   135,    27,   137,    -1,   135,    28,   137,    -1,
-     135,    32,   137,    -1,   135,    29,   137,    -1,   135,    30,
-     137,    -1,   135,    24,   137,    -1,   135,    31,   137,    -1,
-     135,    25,   137,    -1,   135,    26,   137,    -1,   135,    40,
-     137,    -1,   135,    39,   137,    -1,   135,    38,   137,    -1,
-     135,    23,   103,   155,   176,    93,   176,    93,   176,   126,
-      -1,   103,   155,   176,    93,   132,    93,   131,    93,   176,
-      93,   176,    93,   176,    93,   176,    93,   131,   140,   139,
-      -1,   103,   155,   176,    93,   132,    93,   131,    93,   176,
-      93,   176,    93,   176,    93,   176,   139,    -1,     6,   155,
-     176,    93,   176,    93,   176,    93,   176,    93,   176,   130,
-     140,   139,    -1,   176,    93,   176,    93,   176,    93,   176,
-      93,   176,   130,   140,   139,    -1,    -1,   172,    -1,    -1,
-      93,   176,    -1,    21,   176,    93,     6,    93,   176,    93,
-     176,   142,    -1,    -1,    93,   176,    -1,    15,   165,   168,
-     144,    -1,    80,   145,    81,    -1,    -1,   145,    74,     6,
-     155,   176,   146,    -1,   145,    74,    76,    -1,   145,    75,
-       6,   146,   144,    -1,    -1,    93,    48,   146,    -1,    93,
-      47,   146,    -1,    93,    77,   146,    -1,    93,    49,   146,
-      -1,    93,    72,   146,    -1,    93,    73,   146,    -1,    16,
-     165,   168,   148,    -1,    80,   149,    81,    -1,    -1,   149,
-      74,     6,   150,    -1,   149,    74,    76,    -1,   149,    75,
-       6,   151,   148,    -1,    -1,    93,   176,    -1,    93,   175,
-      93,   175,   146,    -1,    93,   175,    93,   175,    93,   176,
-      -1,    -1,    93,   176,    -1,    93,   175,    93,   176,    -1,
-      93,   175,    93,   175,    93,   176,    -1,    93,   175,    93,
-     175,    93,   175,    93,   176,    -1,   153,    80,   154,    81,
-      -1,    20,   165,   168,    -1,    -1,   154,   176,   155,     6,
-      -1,    -1,    93,    -1,    19,   165,   157,    80,   158,    81,
-      -1,    -1,   157,    65,   176,    93,   176,    93,   176,    93,
-     176,    -1,   157,    66,   176,    93,   176,    93,   176,    93,
-     176,    -1,   157,    70,   176,    -1,   157,    67,   176,    -1,
-     157,    68,   176,    -1,   157,    69,   176,    -1,   157,    71,
-     176,    -1,    -1,   158,   159,    -1,    41,     6,    80,   160,
-      81,    -1,    -1,   160,   161,    -1,   159,    -1,    42,     6,
-      93,     6,    -1,    42,     6,    93,   162,    -1,   176,    -1,
-     162,    93,   176,    -1,    78,   165,   176,    93,   176,   168,
-      80,   164,    81,    -1,    -1,   164,    79,   176,    -1,   164,
-      76,    -1,    -1,   165,   166,    -1,   165,   167,    -1,    55,
-      -1,    57,    -1,    53,    -1,    51,    -1,    54,    -1,    56,
-      -1,    52,    -1,    -1,   168,   169,    -1,   168,   170,    -1,
-     168,   171,    -1,    64,   176,    93,   176,    -1,    60,   176,
-      -1,    63,   176,    -1,   168,    80,   173,    81,    -1,     9,
-      -1,     4,    -1,    87,     4,    -1,     5,    -1,    87,     5,
-      -1,     6,    -1,   173,   155,     9,    -1,   173,   155,     4,
-      -1,   173,   155,    87,     4,    -1,   173,   155,     5,    -1,
-     173,   155,    87,     5,    -1,   173,   155,     6,    -1,   105,
-      -1,   172,    -1,    -1,   176,    -1,   177,    -1,   177,    86,
-     177,    -1,   177,    87,   177,    -1,   177,    83,   177,    -1,
-     177,    85,   177,    -1,   177,    88,   177,    -1,   177,    89,
-     177,    -1,   177,    84,   177,    -1,    90,   177,    -1,    87,
-     177,    -1,    86,   177,    -1,    94,   177,    95,    -1,   178,
-      -1,    91,   178,    -1,     4,    -1,     5,    -1
+     123,    38,   124,    -1,   123,    23,   103,   154,   175,    93,
+     175,    93,   175,   126,    -1,     6,   154,   175,    93,   175,
+      93,   175,    93,   175,    93,   175,   129,    -1,   175,    93,
+     175,    93,   175,    93,   175,    93,   175,   129,    -1,    -1,
+      93,   175,    93,   175,    -1,    93,   175,    93,   175,    93,
+     130,    -1,    93,   175,    93,   175,    93,   130,    93,   130,
+      -1,   103,   154,   175,    93,   131,    93,   130,    93,   175,
+      93,   175,    93,   175,    93,   175,    93,   130,    -1,   103,
+     154,   175,    93,   131,    93,   130,    93,   175,    93,   175,
+      93,   175,    93,   175,    -1,    21,   175,    93,     6,    -1,
+      -1,    93,   130,    -1,    93,   130,    93,   130,    -1,   130,
+      83,   130,    -1,    94,   130,    95,    -1,   176,    -1,    91,
+     176,    -1,   175,    -1,     6,    -1,    14,   164,   175,    93,
+     175,    93,   175,    93,   175,   139,   133,    80,   134,    81,
+      -1,    -1,   133,    62,   130,    -1,   133,    61,   130,    -1,
+     133,    59,     6,    -1,   133,   128,    -1,   133,   140,    -1,
+     133,    58,   103,    -1,   133,    15,   102,    -1,   133,   168,
+      -1,   133,   169,    -1,   133,   170,    -1,    -1,   134,    36,
+     135,    -1,   134,    37,   137,    -1,   134,    34,   137,    -1,
+     134,    33,   137,    -1,   134,    35,   137,    -1,   134,    27,
+     136,    -1,   134,    28,   136,    -1,   134,    32,   136,    -1,
+     134,    29,   136,    -1,   134,    30,   136,    -1,   134,    24,
+     136,    -1,   134,    31,   136,    -1,   134,    25,   136,    -1,
+     134,    26,   136,    -1,   134,    40,   136,    -1,   134,    39,
+     136,    -1,   134,    38,   136,    -1,   134,    23,   103,   154,
+     175,    93,   175,    93,   175,   126,    -1,   103,   154,   175,
+      93,   131,    93,   130,    93,   175,    93,   175,    93,   175,
+      93,   175,    93,   130,   139,   138,    -1,   103,   154,   175,
+      93,   131,    93,   130,    93,   175,    93,   175,    93,   175,
+      93,   175,   138,    -1,     6,   154,   175,    93,   175,    93,
+     175,    93,   175,    93,   175,   129,   139,   138,    -1,   175,
+      93,   175,    93,   175,    93,   175,    93,   175,   129,   139,
+     138,    -1,    -1,   171,    -1,    -1,    93,   175,    -1,    21,
+     175,    93,     6,    93,   175,    93,   175,   141,    -1,    -1,
+      93,   175,    -1,    15,   164,   167,   143,    -1,    80,   144,
+      81,    -1,    -1,   144,    74,     6,   154,   175,   145,    -1,
+     144,    74,    76,    -1,   144,    75,     6,   145,   143,    -1,
+      -1,    93,    48,   145,    -1,    93,    47,   145,    -1,    93,
+      77,   145,    -1,    93,    49,   145,    -1,    93,    72,   145,
+      -1,    93,    73,   145,    -1,    16,   164,   167,   147,    -1,
+      80,   148,    81,    -1,    -1,   148,    74,     6,   149,    -1,
+     148,    74,    76,    -1,   148,    75,     6,   150,   147,    -1,
+      -1,    93,   175,    -1,    93,   174,    93,   174,   145,    -1,
+      93,   174,    93,   174,    93,   175,    -1,    -1,    93,   175,
+      -1,    93,   174,    93,   175,    -1,    93,   174,    93,   174,
+      93,   175,    -1,    93,   174,    93,   174,    93,   174,    93,
+     175,    -1,   152,    80,   153,    81,    -1,    20,   164,   167,
+      -1,    -1,   153,   175,   154,     6,    -1,    -1,    93,    -1,
+      19,   164,   156,    80,   157,    81,    -1,    -1,   156,    65,
+     175,    93,   175,    93,   175,    93,   175,    -1,   156,    66,
+     175,    93,   175,    93,   175,    93,   175,    -1,   156,    70,
+     175,    -1,   156,    67,   175,    -1,   156,    68,   175,    -1,
+     156,    69,   175,    -1,   156,    71,   175,    -1,    -1,   157,
+     158,    -1,    41,     6,    80,   159,    81,    -1,    -1,   159,
+     160,    -1,   158,    -1,    42,     6,    93,     6,    -1,    42,
+       6,    93,   161,    -1,   175,    -1,   161,    93,   175,    -1,
+      78,   164,   175,    93,   175,   167,    80,   163,    81,    -1,
+      -1,   163,    79,   175,    -1,   163,    76,    -1,    -1,   164,
+     165,    -1,   164,   166,    -1,    55,    -1,    57,    -1,    53,
+      -1,    51,    -1,    54,    -1,    56,    -1,    52,    -1,    -1,
+     167,   168,    -1,   167,   169,    -1,   167,   170,    -1,    64,
+     175,    93,   175,    -1,    60,   175,    -1,    63,   175,    -1,
+     167,    80,   172,    81,    -1,     9,    -1,     4,    -1,    87,
+       4,    -1,     5,    -1,    87,     5,    -1,     6,    -1,   172,
+     154,     9,    -1,   172,   154,     4,    -1,   172,   154,    87,
+       4,    -1,   172,   154,     5,    -1,   172,   154,    87,     5,
+      -1,   172,   154,     6,    -1,   105,    -1,   171,    -1,    -1,
+     175,    -1,   176,    -1,   176,    86,   176,    -1,   176,    87,
+     176,    -1,   176,    83,   176,    -1,   176,    85,   176,    -1,
+     176,    88,   176,    -1,   176,    89,   176,    -1,   176,    84,
+     176,    -1,    90,   176,    -1,    87,   176,    -1,    86,   176,
+      -1,    94,   176,    95,    -1,   177,    -1,    91,   177,    -1,
+       4,    -1,     5,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short yyrline[] =
 {
-       0,   362,   362,   396,   397,   467,   473,   485,   495,   503,
-     503,   547,   553,   560,   570,   571,   580,   581,   582,   606,
-     607,   613,   614,   615,   616,   640,   641,   647,   648,   649,
-     650,   651,   655,   656,   657,   661,   665,   681,   703,   713,
-     721,   729,   733,   737,   748,   753,   762,   786,   787,   788,
-     797,   798,   801,   802,   805,   806,   807,   808,   809,   810,
-     815,   850,   851,   852,   853,   854,   855,   856,   857,   858,
-     859,   862,   863,   864,   865,   866,   867,   868,   869,   870,
-     871,   873,   874,   875,   876,   877,   878,   879,   880,   882,
-     892,   911,   927,   929,   934,   941,   952,   966,   981,   986,
-     987,   991,   992,   993,   997,   998,   999,  1000,  1004,  1009,
-    1017,  1061,  1062,  1063,  1064,  1065,  1066,  1067,  1068,  1069,
-    1070,  1071,  1074,  1075,  1076,  1077,  1078,  1079,  1080,  1081,
-    1082,  1083,  1085,  1086,  1087,  1088,  1089,  1090,  1091,  1092,
-    1094,  1104,  1129,  1145,  1173,  1196,  1197,  1200,  1201,  1205,
-    1212,  1213,  1217,  1240,  1244,  1245,  1254,  1260,  1279,  1280,
-    1281,  1282,  1283,  1284,  1285,  1289,  1314,  1318,  1319,  1335,
-    1341,  1361,  1362,  1366,  1374,  1385,  1386,  1390,  1396,  1404,
-    1424,  1465,  1476,  1477,  1510,  1512,  1517,  1533,  1534,  1544,
-    1554,  1561,  1568,  1575,  1582,  1592,  1593,  1602,  1610,  1611,
-    1620,  1625,  1631,  1640,  1641,  1645,  1671,  1672,  1677,  1686,
-    1687,  1697,  1712,  1713,  1714,  1715,  1718,  1719,  1720,  1724,
-    1725,  1733,  1741,  1759,  1766,  1770,  1774,  1789,  1790,  1791,
-    1792,  1793,  1794,  1795,  1796,  1797,  1798,  1799,  1800,  1804,
-    1805,  1812,  1813,  1817,  1820,  1821,  1822,  1823,  1824,  1825,
-    1826,  1827,  1828,  1829,  1830,  1831,  1832,  1835,  1836
+       0,   361,   361,   395,   396,   466,   472,   484,   494,   502,
+     502,   546,   552,   559,   569,   570,   579,   580,   581,   605,
+     606,   612,   613,   614,   615,   639,   640,   646,   647,   648,
+     649,   650,   654,   655,   656,   660,   664,   680,   702,   712,
+     720,   728,   732,   736,   747,   752,   761,   785,   786,   787,
+     796,   797,   800,   801,   804,   805,   806,   807,   808,   809,
+     814,   849,   850,   851,   852,   853,   854,   855,   856,   857,
+     858,   861,   862,   863,   864,   865,   866,   867,   868,   869,
+     870,   872,   873,   874,   875,   876,   877,   878,   879,   881,
+     891,   916,   938,   940,   945,   952,   963,   977,   992,   997,
+     998,   999,  1003,  1004,  1005,  1006,  1010,  1015,  1023,  1067,
+    1068,  1069,  1070,  1071,  1072,  1073,  1074,  1075,  1076,  1077,
+    1080,  1081,  1082,  1083,  1084,  1085,  1086,  1087,  1088,  1089,
+    1091,  1092,  1093,  1094,  1095,  1096,  1097,  1098,  1100,  1110,
+    1135,  1151,  1179,  1202,  1203,  1206,  1207,  1211,  1218,  1219,
+    1223,  1246,  1250,  1251,  1260,  1266,  1285,  1286,  1287,  1288,
+    1289,  1290,  1291,  1295,  1320,  1324,  1325,  1341,  1347,  1367,
+    1368,  1372,  1380,  1391,  1392,  1396,  1402,  1410,  1430,  1471,
+    1482,  1483,  1516,  1518,  1523,  1539,  1540,  1550,  1560,  1567,
+    1574,  1581,  1588,  1598,  1599,  1608,  1616,  1617,  1626,  1631,
+    1637,  1646,  1647,  1651,  1677,  1678,  1683,  1692,  1693,  1703,
+    1718,  1719,  1720,  1721,  1724,  1725,  1726,  1730,  1731,  1739,
+    1747,  1765,  1772,  1776,  1780,  1795,  1796,  1797,  1798,  1799,
+    1800,  1801,  1802,  1803,  1804,  1805,  1806,  1810,  1811,  1818,
+    1819,  1823,  1826,  1827,  1828,  1829,  1830,  1831,  1832,  1833,
+    1834,  1835,  1836,  1837,  1838,  1841,  1842
 };
 #endif
 
@@ -887,16 +887,16 @@ static const char *const yytname[] =
   "bitmap", "cursor", "icon", "font", "fontdir", "messagetable", "rcdata", 
   "dlginit", "userres", "usertype", "accelerators", "events", "acc_opt", 
   "accs", "acc", "dialog", "dlg_attributes", "ctrls", "lab_ctrl", 
-  "ctrl_desc", "iconinfo", "gen_ctrl", "opt_font", "optional_style", 
-  "optional_style_pair", "style", "ctlclass", "dialogex", "dlgex_attribs", 
-  "exctrls", "gen_exctrl", "lab_exctrl", "exctrl_desc", "opt_data", 
-  "helpid", "opt_exfont", "opt_expr", "menu", "menu_body", 
-  "item_definitions", "item_options", "menuex", "menuex_body", 
-  "itemex_definitions", "itemex_options", "itemex_p_options", 
-  "stringtable", "stt_head", "strings", "opt_comma", "versioninfo", 
-  "fix_version", "ver_blocks", "ver_block", "ver_values", "ver_value", 
-  "ver_words", "toolbar", "toolbar_items", "loadmemopts", "lamo", "lama", 
-  "opt_lvc", "opt_language", "opt_characts", "opt_version", "raw_data", 
+  "ctrl_desc", "iconinfo", "gen_ctrl", "opt_font", "optional_style_pair", 
+  "style", "ctlclass", "dialogex", "dlgex_attribs", "exctrls", 
+  "gen_exctrl", "lab_exctrl", "exctrl_desc", "opt_data", "helpid", 
+  "opt_exfont", "opt_expr", "menu", "menu_body", "item_definitions", 
+  "item_options", "menuex", "menuex_body", "itemex_definitions", 
+  "itemex_options", "itemex_p_options", "stringtable", "stt_head", 
+  "strings", "opt_comma", "versioninfo", "fix_version", "ver_blocks", 
+  "ver_block", "ver_values", "ver_value", "ver_words", "toolbar", 
+  "toolbar_items", "loadmemopts", "lamo", "lama", "opt_lvc", 
+  "opt_language", "opt_characts", "opt_version", "raw_data", 
   "raw_elements", "file_raw", "e_expr", "expr", "xpr", "any_num", 0
 };
 #endif
@@ -932,22 +932,22 @@ static const unsigned char yyr1[] =
      122,   123,   123,   123,   123,   123,   123,   123,   123,   123,
      123,   123,   123,   123,   123,   123,   123,   123,   123,   123,
      124,   125,   126,   126,   126,   126,   127,   127,   128,   129,
-     129,   130,   130,   130,   131,   131,   131,   131,   132,   132,
-     133,   134,   134,   134,   134,   134,   134,   134,   134,   134,
-     134,   134,   135,   135,   135,   135,   135,   135,   135,   135,
-     135,   135,   135,   135,   135,   135,   135,   135,   135,   135,
-     135,   136,   136,   137,   138,   139,   139,   140,   140,   141,
-     142,   142,   143,   144,   145,   145,   145,   145,   146,   146,
-     146,   146,   146,   146,   146,   147,   148,   149,   149,   149,
-     149,   150,   150,   150,   150,   151,   151,   151,   151,   151,
-     152,   153,   154,   154,   155,   155,   156,   157,   157,   157,
-     157,   157,   157,   157,   157,   158,   158,   159,   160,   160,
-     161,   161,   161,   162,   162,   163,   164,   164,   164,   165,
-     165,   165,   166,   166,   166,   166,   167,   167,   167,   168,
-     168,   168,   168,   169,   170,   171,   172,   173,   173,   173,
-     173,   173,   173,   173,   173,   173,   173,   173,   173,   174,
-     174,   175,   175,   176,   177,   177,   177,   177,   177,   177,
-     177,   177,   177,   177,   177,   177,   177,   178,   178
+     129,   129,   130,   130,   130,   130,   131,   131,   132,   133,
+     133,   133,   133,   133,   133,   133,   133,   133,   133,   133,
+     134,   134,   134,   134,   134,   134,   134,   134,   134,   134,
+     134,   134,   134,   134,   134,   134,   134,   134,   134,   135,
+     135,   136,   137,   138,   138,   139,   139,   140,   141,   141,
+     142,   143,   144,   144,   144,   144,   145,   145,   145,   145,
+     145,   145,   145,   146,   147,   148,   148,   148,   148,   149,
+     149,   149,   149,   150,   150,   150,   150,   150,   151,   152,
+     153,   153,   154,   154,   155,   156,   156,   156,   156,   156,
+     156,   156,   156,   157,   157,   158,   159,   159,   160,   160,
+     160,   161,   161,   162,   163,   163,   163,   164,   164,   164,
+     165,   165,   165,   165,   166,   166,   166,   167,   167,   167,
+     167,   168,   169,   170,   171,   172,   172,   172,   172,   172,
+     172,   172,   172,   172,   172,   172,   172,   173,   173,   174,
+     174,   175,   176,   176,   176,   176,   176,   176,   176,   176,
+     176,   176,   176,   176,   176,   177,   177
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -963,22 +963,22 @@ static const unsigned char yyr2[] =
        2,     0,     3,     3,     3,     3,     3,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,    10,
       12,    10,     0,     4,     6,     8,    17,    15,     4,     0,
-       2,     0,     2,     4,     3,     3,     1,     2,     1,     1,
-      14,     0,     3,     3,     3,     2,     2,     3,     3,     2,
-       2,     2,     0,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-      10,    19,    16,    14,    12,     0,     1,     0,     2,     9,
-       0,     2,     4,     3,     0,     6,     3,     5,     0,     3,
-       3,     3,     3,     3,     3,     4,     3,     0,     4,     3,
-       5,     0,     2,     5,     6,     0,     2,     4,     6,     8,
-       4,     3,     0,     4,     0,     1,     6,     0,     9,     9,
-       3,     3,     3,     3,     3,     0,     2,     5,     0,     2,
-       1,     4,     4,     1,     3,     9,     0,     3,     2,     0,
-       2,     2,     1,     1,     1,     1,     1,     1,     1,     0,
-       2,     2,     2,     4,     2,     2,     4,     1,     1,     2,
-       1,     2,     1,     3,     3,     4,     3,     4,     3,     1,
-       1,     0,     1,     1,     3,     3,     3,     3,     3,     3,
-       3,     2,     2,     2,     3,     1,     2,     1,     1
+       2,     4,     3,     3,     1,     2,     1,     1,    14,     0,
+       3,     3,     3,     2,     2,     3,     3,     2,     2,     2,
+       0,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,    10,    19,
+      16,    14,    12,     0,     1,     0,     2,     9,     0,     2,
+       4,     3,     0,     6,     3,     5,     0,     3,     3,     3,
+       3,     3,     3,     4,     3,     0,     4,     3,     5,     0,
+       2,     5,     6,     0,     2,     4,     6,     8,     4,     3,
+       0,     4,     0,     1,     6,     0,     9,     9,     3,     3,
+       3,     3,     3,     0,     2,     5,     0,     2,     1,     4,
+       4,     1,     3,     9,     0,     3,     2,     0,     2,     2,
+       1,     1,     1,     1,     1,     1,     1,     0,     2,     2,
+       2,     4,     2,     2,     4,     1,     1,     2,     1,     2,
+       1,     3,     3,     4,     3,     4,     3,     1,     1,     0,
+       1,     1,     3,     3,     3,     3,     3,     3,     3,     2,
+       2,     2,     3,     1,     2,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -986,64 +986,63 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned short yydefact[] =
 {
-       3,     0,     2,     1,     5,   257,   258,    11,   209,     9,
-       0,     0,     0,     0,     0,     4,     8,     0,    11,   243,
-     255,     0,   219,     0,   253,   252,   251,   256,     0,   182,
+       3,     0,     2,     1,     5,   255,   256,    11,   207,     9,
+       0,     0,     0,     0,     0,     4,     8,     0,    11,   241,
+     253,     0,   217,     0,   251,   250,   249,   254,     0,   180,
        0,     0,     0,     0,     0,     0,     0,     0,    44,    45,
-     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,
-     209,   209,   209,   209,   209,     7,    17,    18,    24,    22,
-      23,    27,    28,    21,    30,   209,    16,    19,    20,    25,
-      26,    31,    29,   215,   218,   214,   216,   212,   217,   213,
-     210,   211,   181,     0,   254,     0,     6,   246,   250,   247,
-     244,   245,   248,   249,   219,   219,   219,     0,     0,   219,
-     219,   219,   219,   187,   219,   219,   219,     0,   219,   219,
-       0,     0,     0,   220,   221,   222,     0,   180,   184,     0,
-      34,    33,    32,   239,     0,   240,    35,    36,     0,     0,
+     207,   207,   207,   207,   207,   207,   207,   207,   207,   207,
+     207,   207,   207,   207,   207,     7,    17,    18,    24,    22,
+      23,    27,    28,    21,    30,   207,    16,    19,    20,    25,
+      26,    31,    29,   213,   216,   212,   214,   210,   215,   211,
+     208,   209,   179,     0,   252,     0,     6,   244,   248,   245,
+     242,   243,   246,   247,   217,   217,   217,     0,     0,   217,
+     217,   217,   217,   185,   217,   217,   217,     0,   217,   217,
+       0,     0,     0,   218,   219,   220,     0,   178,   182,     0,
+      34,    33,    32,   237,     0,   238,    35,    36,     0,     0,
        0,     0,    40,    41,     0,    38,    39,    37,     0,    42,
-      43,   224,   225,     0,    10,   185,     0,    47,     0,     0,
-       0,   154,   152,   167,   165,     0,     0,     0,     0,     0,
-       0,     0,   195,     0,     0,   183,     0,   228,   230,   232,
-     227,     0,   184,     0,     0,     0,     0,     0,     0,   191,
-     192,   193,   190,   194,     0,   219,   223,     0,    46,     0,
-     229,   231,   226,     0,     0,     0,     0,     0,   153,     0,
-       0,   166,     0,     0,     0,   186,   196,     0,     0,     0,
-     234,   236,   238,   233,     0,     0,     0,   184,   156,   158,
-     171,   169,   175,     0,     0,     0,   206,    50,    50,   235,
-     237,     0,     0,     0,     0,     0,   241,   168,   241,     0,
-       0,     0,   198,     0,     0,    48,    49,    61,   147,   158,
-     158,   158,   158,   158,   158,   158,   157,     0,   172,     0,
-     176,   170,     0,     0,     0,   208,     0,   205,    56,    55,
-      57,    58,    59,    54,    51,    52,     0,     0,   111,   155,
-     160,   159,   162,   163,   164,   161,   241,   241,     0,     0,
-       0,   197,   200,   199,   207,     0,     0,     0,     0,     0,
-       0,     0,    71,    65,    68,    69,    70,   148,     0,   158,
-     242,     0,   177,   188,   189,     0,    53,    13,    67,    12,
-       0,    15,    14,    66,    64,     0,     0,    63,   106,    62,
-       0,     0,     0,     0,     0,     0,     0,   122,   115,   116,
-     119,   120,   121,     0,   173,   241,     0,     0,   107,   255,
+      43,   222,   223,     0,    10,   183,     0,    47,     0,     0,
+       0,   152,   150,   165,   163,     0,     0,     0,     0,     0,
+       0,     0,   193,     0,     0,   181,     0,   226,   228,   230,
+     225,     0,   182,     0,     0,     0,     0,     0,     0,   189,
+     190,   191,   188,   192,     0,   217,   221,     0,    46,     0,
+     227,   229,   224,     0,     0,     0,     0,     0,   151,     0,
+       0,   164,     0,     0,     0,   184,   194,     0,     0,     0,
+     232,   234,   236,   231,     0,     0,     0,   182,   154,   156,
+     169,   167,   173,     0,     0,     0,   204,    50,    50,   233,
+     235,     0,     0,     0,     0,     0,   239,   166,   239,     0,
+       0,     0,   196,     0,     0,    48,    49,    61,   145,   156,
+     156,   156,   156,   156,   156,   156,   155,     0,   170,     0,
+     174,   168,     0,     0,     0,   206,     0,   203,    56,    55,
+      57,    58,    59,    54,    51,    52,     0,     0,   109,   153,
+     158,   157,   160,   161,   162,   159,   239,   239,     0,     0,
+       0,   195,   198,   197,   205,     0,     0,     0,     0,     0,
+       0,     0,    71,    65,    68,    69,    70,   146,     0,   156,
+     240,     0,   175,   186,   187,     0,    53,    13,    67,    12,
+       0,    15,    14,    66,    64,     0,     0,    63,   104,    62,
+       0,     0,     0,     0,     0,     0,     0,   120,   113,   114,
+     117,   118,   119,     0,   171,   239,     0,     0,   105,   253,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    60,   118,     0,   117,   114,   113,   112,     0,   174,
-       0,   178,   201,   202,   203,    98,   105,   104,   184,   184,
+       0,    60,   116,     0,   115,   112,   111,   110,     0,   172,
+       0,   176,   199,   200,   201,    98,   103,   102,   182,   182,
       82,    84,    85,    77,    78,    80,    81,    83,    79,    75,
-       0,    74,    76,   184,    72,    73,    88,    87,    86,     0,
+       0,    74,    76,   182,    72,    73,    88,    87,    86,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   110,     0,
-       0,     0,     0,     0,     0,    98,   184,   184,   133,   135,
-     136,   128,   129,   131,   132,   134,   130,   126,     0,   125,
-     127,   184,   123,   124,   139,   138,   137,   179,   204,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   108,     0,
+       0,     0,     0,     0,     0,    98,   182,   182,   131,   133,
+     134,   126,   127,   129,   130,   132,   128,   124,     0,   123,
+     125,   182,   121,   122,   137,   136,   135,   177,   202,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     109,     0,   108,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   150,     0,     0,     0,     0,    92,     0,     0,
-       0,     0,   149,     0,     0,     0,     0,     0,    89,     0,
-       0,     0,   151,    92,     0,     0,     0,     0,     0,    99,
-       0,   140,     0,     0,     0,     0,     0,     0,    91,     0,
-       0,   101,     0,    93,    99,   100,     0,     0,     0,   147,
-       0,     0,    90,     0,   101,   102,   145,     0,    94,     0,
-     147,     0,   144,   146,     0,     0,     0,   145,   103,     0,
-      95,    97,   143,     0,     0,   145,    96,     0,   142,   147,
-     145,   141
+     107,     0,   106,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   148,     0,     0,     0,     0,    92,     0,     0,
+       0,     0,   147,     0,     0,     0,     0,     0,    89,     0,
+       0,     0,   149,    92,     0,     0,     0,     0,     0,    99,
+       0,   138,     0,     0,     0,     0,     0,     0,    91,     0,
+       0,    99,     0,    93,    99,   100,     0,     0,   145,     0,
+       0,    90,     0,     0,    99,   143,     0,    94,   101,     0,
+     145,   142,   144,     0,     0,     0,   143,     0,    95,    97,
+     141,     0,     0,   143,    96,     0,   140,   145,   143,   139
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
@@ -1052,244 +1051,243 @@ static const short yydefgoto[] =
       -1,     1,     2,    15,    23,    21,   322,   323,    55,   123,
       56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
       66,   166,   245,   274,   275,    67,   276,   330,   390,   399,
-     508,   404,   303,   528,   539,   327,   481,    68,   308,   378,
-     452,   438,   447,   552,   278,   339,   502,    69,   152,   175,
-     235,    70,   154,   176,   237,   239,    16,    17,    85,   146,
-      71,   134,   184,   206,   264,   293,   383,    72,   243,    22,
-      80,    81,   124,   113,   114,   115,   125,   172,   126,   257,
-     319,    19,    20
+     508,   404,   303,   528,   327,   481,    68,   308,   378,   452,
+     438,   447,   551,   278,   339,   502,    69,   152,   175,   235,
+      70,   154,   176,   237,   239,    16,    17,    85,   146,    71,
+     134,   184,   206,   264,   293,   383,    72,   243,    22,    80,
+      81,   124,   113,   114,   115,   125,   172,   126,   257,   319,
+      19,    20
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -435
+#define YYPACT_NINF -523
 static const short yypact[] =
 {
-    -435,     7,    81,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-      93,    93,    93,    39,    93,  -435,  -435,   -58,  -435,   596,
-    -435,   393,   635,    93,  -435,  -435,  -435,  -435,   558,  -435,
-     393,    93,    93,    93,    93,    93,    93,    93,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-    -435,  -435,   230,   -80,  -435,   108,  -435,   371,   391,   356,
-     -37,   -37,  -435,  -435,   635,   382,   382,    87,    87,   635,
-     635,   382,   382,   635,   382,   382,   382,    87,   382,   382,
-      93,    93,    93,  -435,  -435,  -435,    93,  -435,   -64,    70,
-    -435,  -435,  -435,  -435,   177,  -435,  -435,  -435,   -56,   -29,
-     251,   296,  -435,  -435,   477,  -435,  -435,  -435,   -27,  -435,
-    -435,  -435,  -435,   -25,  -435,  -435,    29,  -435,     0,    93,
-      93,  -435,  -435,  -435,  -435,    93,    93,    93,    93,    93,
-      93,    93,  -435,    93,    93,  -435,    13,  -435,  -435,  -435,
-    -435,   113,   -66,   -22,    44,   184,   188,    53,    56,  -435,
-    -435,  -435,  -435,  -435,   -33,  -435,  -435,    58,  -435,    72,
-    -435,  -435,  -435,    19,    93,    93,    14,    68,  -435,    40,
-     109,  -435,    93,    93,   126,  -435,  -435,   321,    93,    93,
-    -435,  -435,  -435,  -435,   266,    76,    83,   -64,  -435,    92,
-      95,  -435,   103,   110,   118,   144,  -435,   142,   142,  -435,
-    -435,    93,    93,    93,   173,   176,    93,  -435,    93,   180,
-      93,    93,  -435,   147,   404,  -435,  -435,  -435,   181,    92,
-      92,    92,    92,    92,    92,    92,  -435,   185,   190,   204,
-     190,  -435,   213,   214,   -31,  -435,    93,  -435,  -435,  -435,
-    -435,  -435,  -435,  -435,   219,  -435,   240,    93,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,    93,    93,    93,    93,
-     310,  -435,  -435,  -435,  -435,   404,   122,    93,    34,   311,
-     186,   186,  -435,  -435,  -435,  -435,  -435,  -435,   431,   225,
-    -435,   226,   190,  -435,  -435,   228,  -435,  -435,  -435,  -435,
-     233,  -435,  -435,  -435,  -435,    93,   186,   244,   596,   244,
-     567,   122,    93,    34,   327,   186,   186,  -435,  -435,  -435,
-    -435,  -435,  -435,   305,  -435,    93,   238,   330,   371,  -435,
-     -13,   558,   186,    34,   331,   331,   331,   331,   331,   331,
-     331,   331,   331,    93,    93,    93,    34,    93,   331,   331,
-     331,  -435,  -435,   247,  -435,  -435,   244,   244,   585,  -435,
-     252,   190,  -435,   253,  -435,  -435,  -435,  -435,   -64,   -64,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-     256,  -435,  -435,   -64,  -435,  -435,  -435,  -435,  -435,   344,
-      34,   345,   345,   345,   345,   345,   345,   345,   345,   345,
-      93,    93,    93,    34,    93,   345,   345,   345,  -435,    93,
-      93,    93,    93,    93,    93,   262,   -64,   -64,  -435,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,   271,  -435,
-    -435,   -64,  -435,  -435,  -435,  -435,  -435,  -435,  -435,   280,
-     282,   286,   287,    93,    93,    93,    93,    93,    93,    93,
-      93,   248,   290,   293,   294,   300,   301,   309,   320,   324,
-    -435,   358,  -435,    93,    93,    93,    93,   248,    93,    93,
-      93,   186,   360,   377,   379,   380,   381,   403,   405,   407,
-     -67,    93,  -435,    93,    93,    93,   186,    93,  -435,    93,
-      93,    93,  -435,   403,   411,   413,    77,   417,   419,   421,
-     422,  -435,    93,    93,    93,    93,    93,   186,  -435,    93,
-     423,   424,   425,   426,   421,   244,   432,    93,   186,   181,
-      93,   186,  -435,    93,   424,   121,   361,   433,   132,   436,
-     181,   186,  -435,  -435,    93,   186,    93,   361,   244,   437,
-     244,   438,  -435,    93,   186,     9,   244,   186,  -435,   134,
-     361,  -435
+    -523,     5,    13,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+     284,   284,   284,    93,   284,  -523,  -523,   -69,  -523,   600,
+    -523,   392,   639,   284,  -523,  -523,  -523,  -523,   554,  -523,
+     392,   284,   284,   284,   284,   284,   284,   284,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+    -523,  -523,   122,   -66,  -523,   108,  -523,   391,   357,   138,
+      27,    27,  -523,  -523,   639,   524,   524,    33,    33,   639,
+     639,   524,   524,   639,   524,   524,   524,    33,   524,   524,
+     284,   284,   284,  -523,  -523,  -523,   284,  -523,   -58,   210,
+    -523,  -523,  -523,  -523,   242,  -523,  -523,  -523,    35,    42,
+     254,   273,  -523,  -523,   448,  -523,  -523,  -523,    50,  -523,
+    -523,  -523,  -523,    59,  -523,  -523,   159,  -523,    19,   284,
+     284,  -523,  -523,  -523,  -523,   284,   284,   284,   284,   284,
+     284,   284,  -523,   284,   284,  -523,   171,  -523,  -523,  -523,
+    -523,   267,   -67,    75,    78,   -10,   172,    88,   104,  -523,
+    -523,  -523,  -523,  -523,     1,  -523,  -523,   116,  -523,   121,
+    -523,  -523,  -523,    63,   284,   284,     0,   184,  -523,     2,
+     211,  -523,   284,   284,   231,  -523,  -523,   287,   284,   284,
+    -523,  -523,  -523,  -523,   311,   157,   162,   -58,  -523,   166,
+     167,  -523,   170,   176,   185,   203,  -523,   198,   198,  -523,
+    -523,   284,   284,   284,   131,   214,   284,  -523,   284,   221,
+     284,   284,  -523,   201,   405,  -523,  -523,  -523,   226,   166,
+     166,   166,   166,   166,   166,   166,  -523,   230,   233,   234,
+     233,  -523,   245,   246,    51,  -523,   284,  -523,  -523,  -523,
+    -523,  -523,  -523,  -523,   247,  -523,   376,   284,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,   284,   284,   284,   284,
+     325,  -523,  -523,  -523,  -523,   405,   206,   284,    39,   329,
+     294,   294,  -523,  -523,  -523,  -523,  -523,  -523,   432,   249,
+    -523,   256,   233,  -523,  -523,   259,  -523,  -523,  -523,  -523,
+     261,  -523,  -523,  -523,  -523,   284,   294,   265,   600,   265,
+     563,   206,   284,    39,   351,   294,   294,  -523,  -523,  -523,
+    -523,  -523,  -523,    97,  -523,   284,   217,   352,   391,  -523,
+      -4,   554,   294,    39,   353,   353,   353,   353,   353,   353,
+     353,   353,   353,   284,   284,   284,    39,   284,   353,   353,
+     353,  -523,  -523,   271,  -523,  -523,   265,   265,   581,  -523,
+     275,   233,  -523,   276,  -523,  -523,  -523,  -523,   -58,   -58,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+     286,  -523,  -523,   -58,  -523,  -523,  -523,  -523,  -523,   354,
+      39,   360,   360,   360,   360,   360,   360,   360,   360,   360,
+     284,   284,   284,    39,   284,   360,   360,   360,  -523,   284,
+     284,   284,   284,   284,   284,   289,   -58,   -58,  -523,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,   290,  -523,
+    -523,   -58,  -523,  -523,  -523,  -523,  -523,  -523,  -523,   293,
+     296,   297,   299,   284,   284,   284,   284,   284,   284,   284,
+     284,   238,   301,   302,   305,   307,   308,   319,   323,   324,
+    -523,   328,  -523,   284,   284,   284,   284,   238,   284,   284,
+     284,   294,   330,   331,   332,   333,   340,   359,   361,   364,
+     -64,   284,  -523,   284,   284,   284,   294,   284,  -523,   284,
+     284,   284,  -523,   359,   365,   366,   -23,   367,   378,   379,
+     380,  -523,   284,   284,   284,   284,   284,   294,  -523,   284,
+     396,   379,   404,   407,   379,   -20,   411,   284,   226,   284,
+     294,  -523,   294,   284,   379,   313,   413,    28,   265,   417,
+     226,  -523,  -523,   284,   294,   284,   313,   436,   265,   440,
+    -523,   284,   294,   152,   265,   294,  -523,    80,   313,  -523
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const short yypgoto[] =
 {
-    -435,  -435,  -435,  -435,  -435,   479,  -282,  -288,   368,  -435,
-    -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,  -435,
-    -435,  -435,   195,  -435,   237,  -435,  -435,  -435,   210,  -116,
-      20,  -435,   229,     2,   -10,  -259,    52,  -435,  -435,  -435,
-    -435,   242,  -133,  -434,  -387,  -435,  -435,  -435,   315,  -435,
-     117,  -435,   312,  -435,  -435,  -435,  -435,  -435,  -435,  -170,
-    -435,  -435,  -435,   276,  -435,  -435,  -435,  -435,  -435,   586,
-    -435,  -435,   -19,  -246,  -245,  -197,  -360,  -435,   569,  -226,
-      -2,    22,   -12
+    -523,  -523,  -523,  -523,  -523,   369,  -283,  -292,   468,  -523,
+    -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,  -523,
+    -523,  -523,   306,  -523,   241,  -523,  -523,  -523,   295,  -116,
+      12,  -523,   232,  -522,  -286,    52,  -523,  -523,  -523,  -523,
+     255,  -112,  -328,  -416,  -523,  -523,  -523,   303,  -523,  -113,
+    -523,   304,  -523,  -523,  -523,  -523,  -523,  -523,  -170,  -523,
+    -523,  -523,   278,  -523,  -523,  -523,  -523,  -523,   582,  -523,
+    -523,   -19,  -272,  -269,  -214,  -396,  -523,   462,  -228,    -2,
+      20,   -12
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -243
+#define YYTABLE_NINF -241
 static const short yytable[] =
 {
-      18,    27,   193,    82,   167,   168,   169,     3,   204,   170,
-     204,   290,   259,   116,   318,   192,   352,     5,     6,   187,
-     217,    83,    29,   210,   211,   212,   511,   145,   213,   145,
-     304,   305,    24,    25,    26,   165,    28,   149,     5,     6,
-     321,   317,   329,     5,     6,   374,   220,   233,   205,   372,
-     291,    36,    37,    87,    88,    89,    90,    91,    92,    93,
-     309,   311,   340,   341,   150,   388,   163,   350,   164,  -219,
-     352,   194,  -219,  -219,   219,   119,   376,   377,   403,   306,
-     130,   131,   386,   118,     4,     5,     6,   171,     7,  -219,
-     218,     5,     6,   387,   188,   128,   129,     5,     6,    10,
-      11,     8,   567,    12,    13,   138,   214,    14,   141,   142,
-     143,   342,     5,     6,   144,   222,   221,   190,   191,   380,
-      10,    11,   436,   562,    12,    13,     5,     6,    14,   317,
-     110,   568,   225,   111,   112,   451,   571,   195,    73,    74,
-      75,    76,    77,    78,    79,     9,   202,   173,   174,   203,
-     147,   208,   546,   177,   178,   179,   180,   181,   182,   183,
-     352,   185,   186,   557,   189,   209,   207,    10,    11,   231,
-     524,    12,    13,    10,    11,    14,   232,    12,    13,    10,
-      11,    14,   570,    12,    13,   234,   553,    14,   236,   117,
-       5,     6,   215,   216,    10,    11,   238,   553,    12,    13,
-     223,   224,    14,   240,   352,   553,   227,   228,    10,    11,
-     553,   241,    12,    13,   551,   352,    14,   352,   431,   432,
-     250,   251,   252,   265,   242,   555,   266,   277,   267,   247,
-     248,   249,   500,   434,   258,   244,   260,   110,   262,   263,
-     111,   112,     5,     6,   382,   253,   254,   516,   401,   402,
-     255,   405,     5,     6,   480,   296,   151,   148,   196,   197,
-     153,   297,   199,   200,   294,   198,   464,   465,   535,   201,
-     229,   230,    10,    11,   277,   307,    12,   325,   286,   545,
-     326,   467,   548,  -242,   310,   312,   313,   314,   449,   450,
-     110,   453,   558,   111,   112,   320,   560,   287,   298,   299,
-     110,   300,   301,   111,   112,   566,   288,   289,   569,     5,
-       6,   110,   295,   349,   111,   112,   315,   324,   343,   345,
-     302,   346,   328,   328,    10,    11,   347,   352,    12,    13,
-     373,   151,    14,   375,    10,    11,   385,   389,    12,    13,
-     409,   379,    14,   381,   384,   429,   430,   348,   351,   433,
-     435,   437,   250,   251,   252,   463,   110,   328,   328,   111,
-     112,   400,   400,   400,   466,   400,   279,   280,   281,   282,
-     283,   284,   285,   468,   328,   469,   153,   253,   254,   470,
-     471,   110,   255,   483,   111,   112,   484,   485,   120,   121,
-     122,    10,    11,   486,   487,    12,    13,    38,    86,    14,
-      39,   226,   488,    40,    41,    42,    43,    44,    45,    46,
-      47,    48,    49,   489,    50,    51,    52,   490,   448,   448,
-     448,  -219,   448,   246,  -219,  -219,   344,   457,   458,   459,
-     460,   461,   462,    73,    74,    75,    76,    77,    78,    79,
-     268,  -219,    34,    35,    36,    37,   331,   269,   270,   271,
-     272,   491,   332,   501,   273,    32,    33,    34,    35,    36,
-      37,   472,   473,   474,   475,   476,   477,   478,   479,   482,
-     503,    53,   504,   505,   506,    54,    33,    34,    35,    36,
-      37,   492,   493,   494,   495,   482,   497,   498,   499,   333,
-     334,   110,   335,   336,   111,   112,   507,    30,   509,   512,
-     510,   513,   514,   515,   522,   517,   523,   518,   519,   520,
-     525,   337,   526,   328,   527,   529,   537,   538,   540,   541,
-     530,   531,   532,   533,   534,   543,   554,   536,   328,   556,
-     563,   564,   316,   521,   550,   544,   542,   338,   547,   496,
-     292,   549,   155,   156,   157,   158,   159,   160,   161,   328,
-     256,   261,   559,     0,   561,     0,     0,   162,     0,     0,
-     328,   565,     0,   328,     0,   391,   392,   393,   394,   395,
-     396,   397,   398,   328,     0,     0,     0,   328,   406,   407,
-     408,     0,     0,     0,     0,     0,   328,     0,     0,   328,
-     353,   354,   355,   356,   357,   358,   359,   360,   361,   362,
-     363,   364,   365,   366,   367,   368,   369,   370,   410,   411,
-     412,   413,   414,   415,   416,   417,   418,   419,   420,   421,
-     422,   423,   424,   425,   426,   427,    94,    95,    96,    97,
-      98,    99,   100,   101,   102,   103,   104,   105,   106,   107,
-     108,    31,    32,    33,    34,    35,    36,    37,   371,     0,
-       0,   109,     0,    84,   439,   440,   441,   442,   443,   444,
-     445,   446,     0,     0,     0,   127,   428,   454,   455,   456,
-     132,   133,     0,   135,   136,   137,     0,   139,   140,    31,
-      32,    33,    34,    35,    36,    37,    73,    74,    75,    76,
-      77,    78,    79
+      18,    27,   193,    82,   304,     3,   217,   305,   220,   538,
+     259,    29,   541,   318,   192,   329,     4,     5,     6,   352,
+       7,    83,   550,   167,   168,   169,   145,   116,   170,   511,
+      24,    25,    26,     8,    28,   145,   340,     5,     6,   341,
+     350,   374,   204,     5,     6,   321,   317,   233,   372,   376,
+     377,    87,    88,    89,    90,    91,    92,    93,   309,   311,
+     352,   388,   306,   352,   196,   197,   387,   210,   211,   212,
+     524,   198,   213,   542,   403,   119,   218,     9,   221,   352,
+     130,   131,   205,   118,    73,    74,    75,    76,    77,    78,
+      79,   386,   204,   290,   342,   128,   129,     5,     6,    10,
+      11,     5,     6,    12,    13,   138,   171,    14,   141,   142,
+     143,   352,     5,     6,   144,    36,    37,   380,   436,    10,
+      11,   554,   545,    12,    13,    10,    11,    14,   149,    12,
+      13,   451,   291,    14,   556,   150,   279,   280,   281,   282,
+     283,   284,   285,   163,   250,   251,   252,   173,   174,   552,
+     214,   568,   164,   177,   178,   179,   180,   181,   182,   183,
+     552,   185,   186,   352,   189,   165,   207,   552,   194,   253,
+     254,   195,   552,   277,   255,     5,     6,   187,   250,   251,
+     252,   202,   110,    10,    11,   111,   112,    12,    13,   117,
+     219,    14,   215,   216,    10,    11,   344,   203,    12,    13,
+     223,   224,    14,   253,   254,   500,   227,   228,   255,   208,
+       5,     6,  -217,   317,   209,  -217,  -217,   222,   431,   432,
+     516,     5,     6,   382,    34,    35,    36,    37,   560,   247,
+     248,   249,  -217,   434,   258,   566,   260,   225,   262,   263,
+     569,   535,     5,     6,   480,   565,   199,   200,   401,   402,
+     231,   405,   188,   201,   547,   232,   548,    10,    11,   234,
+     236,    12,    13,   238,   294,    14,   464,   465,   558,   240,
+     110,   190,   191,   111,   112,   307,   564,   265,   241,   567,
+     266,   467,   267,   242,   310,   312,   313,   314,     5,     6,
+     147,   244,    10,    11,   151,   320,    12,    13,     5,     6,
+      14,   153,   110,    10,    11,   111,   112,    12,    13,   449,
+     450,    14,   453,   349,   110,   229,   230,   111,   112,   277,
+     328,   328,   148,   286,    10,    11,  -240,   287,    12,    13,
+     373,   315,    14,   110,   151,   324,   111,   112,   288,   289,
+     295,   379,   343,   381,   384,   348,   351,   110,   352,   345,
+     111,   112,   346,   153,   347,   328,   328,   375,   385,   389,
+     435,   400,   400,   400,   409,   400,   437,   226,   429,   430,
+      10,    11,   328,  -217,    12,    13,  -217,  -217,    14,   433,
+      10,    11,   463,   466,    12,   325,   468,    30,   326,   469,
+     470,   296,   471,  -217,   483,   484,    38,   297,   485,    39,
+     486,   487,    40,    41,    42,    43,    44,    45,    46,    47,
+      48,    49,   488,    50,    51,    52,   489,   490,   448,   448,
+     448,   491,   448,   501,   503,   504,   505,   457,   458,   459,
+     460,   461,   462,   506,   298,   299,   110,   300,   301,   111,
+     112,   268,    33,    34,    35,    36,    37,   331,   269,   270,
+     271,   272,   507,   332,   509,   273,   302,   510,   522,   523,
+     525,   472,   473,   474,   475,   476,   477,   478,   479,   482,
+      53,   526,   527,   529,    54,    32,    33,    34,    35,    36,
+      37,   492,   493,   494,   495,   482,   497,   498,   499,   537,
+     333,   334,   110,   335,   336,   111,   112,   539,    86,   512,
+     540,   513,   514,   515,   543,   517,   553,   518,   519,   520,
+     555,   328,   337,   155,   156,   157,   158,   159,   160,   161,
+     530,   531,   532,   533,   534,   521,   328,   536,   162,   561,
+     120,   121,   122,   562,   246,   544,   316,   546,   256,   496,
+     338,   549,   292,   261,     0,     0,     0,   328,     0,     0,
+       0,   557,     0,   559,     0,     0,     0,     0,   127,   563,
+     328,     0,   328,   132,   133,     0,   135,   136,   137,     0,
+     139,   140,     0,     0,   328,    73,    74,    75,    76,    77,
+      78,    79,   328,     0,     0,   328,   353,   354,   355,   356,
+     357,   358,   359,   360,   361,   362,   363,   364,   365,   366,
+     367,   368,   369,   370,   410,   411,   412,   413,   414,   415,
+     416,   417,   418,   419,   420,   421,   422,   423,   424,   425,
+     426,   427,    94,    95,    96,    97,    98,    99,   100,   101,
+     102,   103,   104,   105,   106,   107,   108,    31,    32,    33,
+      34,    35,    36,    37,   371,     0,     0,   109,     0,    84,
+     391,   392,   393,   394,   395,   396,   397,   398,     0,     0,
+       0,     0,   428,   406,   407,   408,     0,   439,   440,   441,
+     442,   443,   444,   445,   446,     0,     0,     0,     0,     0,
+     454,   455,   456,    31,    32,    33,    34,    35,    36,    37,
+      73,    74,    75,    76,    77,    78,    79
 };
 
 static const short yycheck[] =
 {
-       2,    13,   172,    22,     4,     5,     6,     0,    41,     9,
-      41,    42,   238,    93,   296,    81,    83,     4,     5,     6,
-       6,    23,    80,     4,     5,     6,    93,    93,     9,    93,
-     276,   276,    10,    11,    12,     6,    14,    93,     4,     5,
-       6,     7,   301,     4,     5,   333,     6,   217,    81,   331,
-      81,    88,    89,    31,    32,    33,    34,    35,    36,    37,
-     286,   287,   308,   308,    93,   353,    93,   326,    93,    60,
-      83,    93,    63,    64,     6,    94,   335,   336,   366,   276,
-      99,   100,    95,    85,     3,     4,     5,    87,     7,    80,
-      76,     4,     5,   352,    81,    97,    98,     4,     5,    86,
-      87,    20,    93,    90,    91,   107,    87,    94,   110,   111,
-     112,   308,     4,     5,   116,     6,    76,     4,     5,   345,
-      86,    87,   410,   557,    90,    91,     4,     5,    94,     7,
-      60,   565,     6,    63,    64,   423,   570,    93,    51,    52,
-      53,    54,    55,    56,    57,    64,    93,   149,   150,    93,
-      80,    93,   539,   155,   156,   157,   158,   159,   160,   161,
-      83,   163,   164,   550,   166,    93,   185,    86,    87,    93,
-      93,    90,    91,    86,    87,    94,    93,    90,    91,    86,
-      87,    94,   569,    90,    91,    93,   546,    94,    93,    81,
-       4,     5,   194,   195,    86,    87,    93,   557,    90,    91,
-     202,   203,    94,    93,    83,   565,   208,   209,    86,    87,
-     570,    93,    90,    91,    93,    83,    94,    83,   388,   389,
-      47,    48,    49,    76,    80,    93,    79,    93,    81,   231,
-     232,   233,   491,   403,   236,    93,   238,    60,   240,   241,
-      63,    64,     4,     5,     6,    72,    73,   506,   364,   365,
-      77,   367,     4,     5,     6,    15,    80,    80,    74,    75,
-      80,    21,    74,    75,   266,    81,   436,   437,   527,    81,
-       4,     5,    86,    87,    93,   277,    90,    91,    93,   538,
-      94,   451,   541,    93,   286,   287,   288,   289,   421,   422,
-      60,   424,   551,    63,    64,   297,   555,    93,    58,    59,
-      60,    61,    62,    63,    64,   564,    93,    93,   567,     4,
-       5,    60,    93,   325,    63,    64,     6,     6,    93,    93,
-      80,    93,   300,   301,    86,    87,    93,    83,    90,    91,
-     332,    80,    94,     6,    86,    87,     6,     6,    90,    91,
-      93,   343,    94,   345,   346,    93,    93,   325,   326,    93,
-       6,     6,    47,    48,    49,    93,    60,   335,   336,    63,
-      64,   363,   364,   365,    93,   367,   249,   250,   251,   252,
-     253,   254,   255,    93,   352,    93,    80,    72,    73,    93,
-      93,    60,    77,    93,    63,    64,    93,    93,     6,     7,
-       8,    86,    87,    93,    93,    90,    91,     4,    30,    94,
-       7,    80,    93,    10,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    93,    21,    22,    23,    93,   420,   421,
-     422,    60,   424,   228,    63,    64,   309,   429,   430,   431,
-     432,   433,   434,    51,    52,    53,    54,    55,    56,    57,
-      36,    80,    86,    87,    88,    89,    15,    43,    44,    45,
-      46,    93,    21,    93,    50,    84,    85,    86,    87,    88,
-      89,   463,   464,   465,   466,   467,   468,   469,   470,   471,
-      93,    78,    93,    93,    93,    82,    85,    86,    87,    88,
-      89,   483,   484,   485,   486,   487,   488,   489,   490,    58,
-      59,    60,    61,    62,    63,    64,    93,    18,    93,   501,
+       2,    13,   172,    22,   276,     0,     6,   276,     6,   531,
+     238,    80,   534,   296,    81,   301,     3,     4,     5,    83,
+       7,    23,   544,     4,     5,     6,    93,    93,     9,    93,
+      10,    11,    12,    20,    14,    93,   308,     4,     5,   308,
+     326,   333,    41,     4,     5,     6,     7,   217,   331,   335,
+     336,    31,    32,    33,    34,    35,    36,    37,   286,   287,
+      83,   353,   276,    83,    74,    75,   352,     4,     5,     6,
+      93,    81,     9,    93,   366,    94,    76,    64,    76,    83,
+      99,   100,    81,    85,    51,    52,    53,    54,    55,    56,
+      57,    95,    41,    42,   308,    97,    98,     4,     5,    86,
+      87,     4,     5,    90,    91,   107,    87,    94,   110,   111,
+     112,    83,     4,     5,   116,    88,    89,   345,   410,    86,
+      87,    93,   538,    90,    91,    86,    87,    94,    93,    90,
+      91,   423,    81,    94,   550,    93,   249,   250,   251,   252,
+     253,   254,   255,    93,    47,    48,    49,   149,   150,   545,
+      87,   567,    93,   155,   156,   157,   158,   159,   160,   161,
+     556,   163,   164,    83,   166,     6,   185,   563,    93,    72,
+      73,    93,   568,    93,    77,     4,     5,     6,    47,    48,
+      49,    93,    60,    86,    87,    63,    64,    90,    91,    81,
+       6,    94,   194,   195,    86,    87,   309,    93,    90,    91,
+     202,   203,    94,    72,    73,   491,   208,   209,    77,    93,
+       4,     5,    60,     7,    93,    63,    64,     6,   388,   389,
+     506,     4,     5,     6,    86,    87,    88,    89,   556,   231,
+     232,   233,    80,   403,   236,   563,   238,     6,   240,   241,
+     568,   527,     4,     5,     6,    93,    74,    75,   364,   365,
+      93,   367,    81,    81,   540,    93,   542,    86,    87,    93,
+      93,    90,    91,    93,   266,    94,   436,   437,   554,    93,
+      60,     4,     5,    63,    64,   277,   562,    76,    93,   565,
+      79,   451,    81,    80,   286,   287,   288,   289,     4,     5,
+      80,    93,    86,    87,    80,   297,    90,    91,     4,     5,
+      94,    80,    60,    86,    87,    63,    64,    90,    91,   421,
+     422,    94,   424,   325,    60,     4,     5,    63,    64,    93,
+     300,   301,    80,    93,    86,    87,    93,    93,    90,    91,
+     332,     6,    94,    60,    80,     6,    63,    64,    93,    93,
+      93,   343,    93,   345,   346,   325,   326,    60,    83,    93,
+      63,    64,    93,    80,    93,   335,   336,     6,     6,     6,
+       6,   363,   364,   365,    93,   367,     6,    80,    93,    93,
+      86,    87,   352,    60,    90,    91,    63,    64,    94,    93,
+      86,    87,    93,    93,    90,    91,    93,    18,    94,    93,
+      93,    15,    93,    80,    93,    93,     4,    21,    93,     7,
+      93,    93,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    93,    21,    22,    23,    93,    93,   420,   421,
+     422,    93,   424,    93,    93,    93,    93,   429,   430,   431,
+     432,   433,   434,    93,    58,    59,    60,    61,    62,    63,
+      64,    36,    85,    86,    87,    88,    89,    15,    43,    44,
+      45,    46,    93,    21,    93,    50,    80,    93,    93,    93,
+      93,   463,   464,   465,   466,   467,   468,   469,   470,   471,
+      78,    93,    93,    93,    82,    84,    85,    86,    87,    88,
+      89,   483,   484,   485,   486,   487,   488,   489,   490,    93,
+      58,    59,    60,    61,    62,    63,    64,    93,    30,   501,
       93,   503,   504,   505,    93,   507,    93,   509,   510,   511,
-      93,    80,    93,   491,    93,    93,    93,    93,    93,    93,
-     522,   523,   524,   525,   526,    93,    93,   529,   506,    93,
-      93,    93,   295,   513,   544,   537,   534,   308,   540,   487,
-     264,   543,    65,    66,    67,    68,    69,    70,    71,   527,
-     235,   239,   554,    -1,   556,    -1,    -1,    80,    -1,    -1,
-     538,   563,    -1,   541,    -1,   355,   356,   357,   358,   359,
-     360,   361,   362,   551,    -1,    -1,    -1,   555,   368,   369,
-     370,    -1,    -1,    -1,    -1,    -1,   564,    -1,    -1,   567,
-      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      33,    34,    35,    36,    37,    38,    39,    40,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,    39,    40,    40,    41,    42,    43,
-      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
-      54,    83,    84,    85,    86,    87,    88,    89,    81,    -1,
-      -1,    65,    -1,    95,   412,   413,   414,   415,   416,   417,
-     418,   419,    -1,    -1,    -1,    96,    81,   425,   426,   427,
-     101,   102,    -1,   104,   105,   106,    -1,   108,   109,    83,
-      84,    85,    86,    87,    88,    89,    51,    52,    53,    54,
-      55,    56,    57
+      93,   491,    80,    65,    66,    67,    68,    69,    70,    71,
+     522,   523,   524,   525,   526,   513,   506,   529,    80,    93,
+       6,     7,     8,    93,   228,   537,   295,   539,   235,   487,
+     308,   543,   264,   239,    -1,    -1,    -1,   527,    -1,    -1,
+      -1,   553,    -1,   555,    -1,    -1,    -1,    -1,    96,   561,
+     540,    -1,   542,   101,   102,    -1,   104,   105,   106,    -1,
+     108,   109,    -1,    -1,   554,    51,    52,    53,    54,    55,
+      56,    57,   562,    -1,    -1,   565,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,    40,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
+      39,    40,    40,    41,    42,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    83,    84,    85,
+      86,    87,    88,    89,    81,    -1,    -1,    65,    -1,    95,
+     355,   356,   357,   358,   359,   360,   361,   362,    -1,    -1,
+      -1,    -1,    81,   368,   369,   370,    -1,   412,   413,   414,
+     415,   416,   417,   418,   419,    -1,    -1,    -1,    -1,    -1,
+     425,   426,   427,    83,    84,    85,    86,    87,    88,    89,
+      51,    52,    53,    54,    55,    56,    57
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1297,63 +1295,62 @@ static const short yycheck[] =
 static const unsigned char yystos[] =
 {
        0,    97,    98,     0,     3,     4,     5,     7,    20,    64,
-      86,    87,    90,    91,    94,    99,   152,   153,   176,   177,
-     178,   101,   165,   100,   177,   177,   177,   178,   177,    80,
+      86,    87,    90,    91,    94,    99,   151,   152,   175,   176,
+     177,   101,   164,   100,   176,   176,   176,   177,   176,    80,
      101,    83,    84,    85,    86,    87,    88,    89,     4,     7,
       10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
       21,    22,    23,    78,    82,   104,   106,   107,   108,   109,
-     110,   111,   112,   113,   114,   115,   116,   121,   133,   143,
-     147,   156,   163,    51,    52,    53,    54,    55,    56,    57,
-     166,   167,   168,   176,    95,   154,   104,   177,   177,   177,
-     177,   177,   177,   177,   165,   165,   165,   165,   165,   165,
-     165,   165,   165,   165,   165,   165,   165,   165,   165,   165,
-      60,    63,    64,   169,   170,   171,    93,    81,   176,   168,
-       6,     7,     8,   105,   168,   172,   174,   174,   176,   176,
-     168,   168,   174,   174,   157,   174,   174,   174,   176,   174,
-     174,   176,   176,   176,   176,    93,   155,    80,    80,    93,
-      93,    80,   144,    80,   148,    65,    66,    67,    68,    69,
+     110,   111,   112,   113,   114,   115,   116,   121,   132,   142,
+     146,   155,   162,    51,    52,    53,    54,    55,    56,    57,
+     165,   166,   167,   175,    95,   153,   104,   176,   176,   176,
+     176,   176,   176,   176,   164,   164,   164,   164,   164,   164,
+     164,   164,   164,   164,   164,   164,   164,   164,   164,   164,
+      60,    63,    64,   168,   169,   170,    93,    81,   175,   167,
+       6,     7,     8,   105,   167,   171,   173,   173,   175,   175,
+     167,   167,   173,   173,   156,   173,   173,   173,   175,   173,
+     173,   175,   175,   175,   175,    93,   154,    80,    80,    93,
+      93,    80,   143,    80,   147,    65,    66,    67,    68,    69,
       70,    71,    80,    93,    93,     6,   117,     4,     5,     6,
-       9,    87,   173,   176,   176,   145,   149,   176,   176,   176,
-     176,   176,   176,   176,   158,   176,   176,     6,    81,   176,
-       4,     5,    81,   155,    93,    93,    74,    75,    81,    74,
-      75,    81,    93,    93,    41,    81,   159,   168,    93,    93,
-       4,     5,     6,     9,    87,   176,   176,     6,    76,     6,
-       6,    76,     6,   176,   176,     6,    80,   176,   176,     4,
-       5,    93,    93,   155,    93,   146,    93,   150,    93,   151,
-      93,    93,    80,   164,    93,   118,   118,   176,   176,   176,
-      47,    48,    49,    72,    73,    77,   144,   175,   176,   175,
-     176,   148,   176,   176,   160,    76,    79,    81,    36,    43,
-      44,    45,    46,    50,   119,   120,   122,    93,   140,   146,
-     146,   146,   146,   146,   146,   146,    93,    93,    93,    93,
-      42,    81,   159,   161,   176,    93,    15,    21,    58,    59,
-      61,    62,    80,   128,   169,   170,   171,   176,   134,   175,
-     176,   175,   176,   176,   176,     6,   120,     7,   102,   176,
-     176,     6,   102,   103,     6,    91,    94,   131,   177,   131,
-     123,    15,    21,    58,    59,    61,    62,    80,   128,   141,
-     169,   170,   171,    93,   146,    93,    93,    93,   177,   178,
-     131,   177,    83,    23,    24,    25,    26,    27,    28,    29,
+       9,    87,   172,   175,   175,   144,   148,   175,   175,   175,
+     175,   175,   175,   175,   157,   175,   175,     6,    81,   175,
+       4,     5,    81,   154,    93,    93,    74,    75,    81,    74,
+      75,    81,    93,    93,    41,    81,   158,   167,    93,    93,
+       4,     5,     6,     9,    87,   175,   175,     6,    76,     6,
+       6,    76,     6,   175,   175,     6,    80,   175,   175,     4,
+       5,    93,    93,   154,    93,   145,    93,   149,    93,   150,
+      93,    93,    80,   163,    93,   118,   118,   175,   175,   175,
+      47,    48,    49,    72,    73,    77,   143,   174,   175,   174,
+     175,   147,   175,   175,   159,    76,    79,    81,    36,    43,
+      44,    45,    46,    50,   119,   120,   122,    93,   139,   145,
+     145,   145,   145,   145,   145,   145,    93,    93,    93,    93,
+      42,    81,   158,   160,   175,    93,    15,    21,    58,    59,
+      61,    62,    80,   128,   168,   169,   170,   175,   133,   174,
+     175,   174,   175,   175,   175,     6,   120,     7,   102,   175,
+     175,     6,   102,   103,     6,    91,    94,   130,   176,   130,
+     123,    15,    21,    58,    59,    61,    62,    80,   128,   140,
+     168,   169,   170,    93,   145,    93,    93,    93,   176,   177,
+     130,   176,    83,    23,    24,    25,    26,    27,    28,    29,
       30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
-      40,    81,   102,   176,   103,     6,   131,   131,   135,   176,
-     175,   176,     6,   162,   176,     6,    95,   131,   103,     6,
+      40,    81,   102,   175,   103,     6,   130,   130,   134,   175,
+     174,   175,     6,   161,   175,     6,    95,   130,   103,     6,
      124,   124,   124,   124,   124,   124,   124,   124,   124,   125,
-     176,   125,   125,   103,   127,   125,   124,   124,   124,    93,
+     175,   125,   125,   103,   127,   125,   124,   124,   124,    93,
       23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
       33,    34,    35,    36,    37,    38,    39,    40,    81,    93,
-      93,   155,   155,    93,   155,     6,   103,     6,   137,   137,
-     137,   137,   137,   137,   137,   137,   137,   138,   176,   138,
-     138,   103,   136,   138,   137,   137,   137,   176,   176,   176,
-     176,   176,   176,    93,   155,   155,    93,   155,    93,    93,
-      93,    93,   176,   176,   176,   176,   176,   176,   176,   176,
-       6,   132,   176,    93,    93,    93,    93,    93,    93,    93,
-      93,    93,   176,   176,   176,   176,   132,   176,   176,   176,
-     131,    93,   142,    93,    93,    93,    93,    93,   126,    93,
-      93,    93,   176,   176,   176,   176,   131,   176,   176,   176,
-     176,   126,    93,    93,    93,    93,    93,    93,   129,    93,
-     176,   176,   176,   176,   176,   131,   176,    93,    93,   130,
-      93,    93,   129,    93,   176,   131,   140,   176,   131,   176,
-     130,    93,   139,   172,    93,    93,    93,   140,   131,   176,
-     131,   176,   139,    93,    93,   176,   131,    93,   139,   131,
-     140,   139
+      93,   154,   154,    93,   154,     6,   103,     6,   136,   136,
+     136,   136,   136,   136,   136,   136,   136,   137,   175,   137,
+     137,   103,   135,   137,   136,   136,   136,   175,   175,   175,
+     175,   175,   175,    93,   154,   154,    93,   154,    93,    93,
+      93,    93,   175,   175,   175,   175,   175,   175,   175,   175,
+       6,   131,   175,    93,    93,    93,    93,    93,    93,    93,
+      93,    93,   175,   175,   175,   175,   131,   175,   175,   175,
+     130,    93,   141,    93,    93,    93,    93,    93,   126,    93,
+      93,    93,   175,   175,   175,   175,   130,   175,   175,   175,
+     175,   126,    93,    93,    93,    93,    93,    93,   129,    93,
+     175,   175,   175,   175,   175,   130,   175,    93,   129,    93,
+      93,   129,    93,    93,   175,   139,   175,   130,   130,   175,
+     129,   138,   171,    93,    93,    93,   139,   175,   130,   175,
+     138,    93,    93,   175,   130,    93,   138,   130,   139,   138
 };
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -1964,7 +1961,7 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 362 "parser.y"
+#line 361 "parser.y"
     {
                resource_t *rsc;
                /* First add stringtables to the resource-list */
@@ -1998,12 +1995,12 @@ yyreduce:
     break;
 
   case 3:
-#line 396 "parser.y"
+#line 395 "parser.y"
     { yyval.res = NULL; want_id = 1; ;}
     break;
 
   case 4:
-#line 397 "parser.y"
+#line 396 "parser.y"
     {
                if(yyvsp[0].res)
                {
@@ -2052,7 +2049,7 @@ yyreduce:
     break;
 
   case 6:
-#line 473 "parser.y"
+#line 472 "parser.y"
     {
                yyval.res = yyvsp[0].res;
                if(yyval.res)
@@ -2068,7 +2065,7 @@ yyreduce:
     break;
 
   case 7:
-#line 485 "parser.y"
+#line 484 "parser.y"
     {
                yyval.res = yyvsp[0].res;
                if(yyval.res)
@@ -2082,7 +2079,7 @@ yyreduce:
     break;
 
   case 8:
-#line 495 "parser.y"
+#line 494 "parser.y"
     {
                /* Don't do anything, stringtables are converted to
                 * resource_t structures when we are finished parsing and
@@ -2094,12 +2091,12 @@ yyreduce:
     break;
 
   case 9:
-#line 503 "parser.y"
+#line 502 "parser.y"
     {want_nl = 1; ;}
     break;
 
   case 10:
-#line 503 "parser.y"
+#line 502 "parser.y"
     {
                /* We *NEED* the newline to delimit the expression.
                 * Otherwise, we would not be able to set the next
@@ -2141,12 +2138,12 @@ yyreduce:
     break;
 
   case 11:
-#line 547 "parser.y"
+#line 546 "parser.y"
     { yychar = rsrcid_to_token(yychar); ;}
     break;
 
   case 12:
-#line 553 "parser.y"
+#line 552 "parser.y"
     {
                if(yyvsp[0].num > 65535 || yyvsp[0].num < -32768)
                        yyerror("Resource's ID out of range (%d)", yyvsp[0].num);
@@ -2157,7 +2154,7 @@ yyreduce:
     break;
 
   case 13:
-#line 560 "parser.y"
+#line 559 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_str;
@@ -2166,12 +2163,12 @@ yyreduce:
     break;
 
   case 14:
-#line 570 "parser.y"
+#line 569 "parser.y"
     { yyval.nid = yyvsp[0].nid; ;}
     break;
 
   case 15:
-#line 571 "parser.y"
+#line 570 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_str;
@@ -2180,17 +2177,17 @@ yyreduce:
     break;
 
   case 16:
-#line 580 "parser.y"
+#line 579 "parser.y"
     { yyval.res = new_resource(res_acc, yyvsp[0].acc, yyvsp[0].acc->memopt, yyvsp[0].acc->lvc.language); ;}
     break;
 
   case 17:
-#line 581 "parser.y"
+#line 580 "parser.y"
     { yyval.res = new_resource(res_bmp, yyvsp[0].bmp, yyvsp[0].bmp->memopt, yyvsp[0].bmp->data->lvc.language); ;}
     break;
 
   case 18:
-#line 582 "parser.y"
+#line 581 "parser.y"
     {
                resource_t *rsc;
                if(yyvsp[0].ani->type == res_anicur)
@@ -2218,12 +2215,12 @@ yyreduce:
     break;
 
   case 19:
-#line 606 "parser.y"
+#line 605 "parser.y"
     { yyval.res = new_resource(res_dlg, yyvsp[0].dlg, yyvsp[0].dlg->memopt, yyvsp[0].dlg->lvc.language); ;}
     break;
 
   case 20:
-#line 607 "parser.y"
+#line 606 "parser.y"
     {
                if(win32)
                        yyval.res = new_resource(res_dlgex, yyvsp[0].dlgex, yyvsp[0].dlgex->memopt, yyvsp[0].dlgex->lvc.language);
@@ -2233,22 +2230,22 @@ yyreduce:
     break;
 
   case 21:
-#line 613 "parser.y"
+#line 612 "parser.y"
     { yyval.res = new_resource(res_dlginit, yyvsp[0].dginit, yyvsp[0].dginit->memopt, yyvsp[0].dginit->data->lvc.language); ;}
     break;
 
   case 22:
-#line 614 "parser.y"
+#line 613 "parser.y"
     { yyval.res = new_resource(res_fnt, yyvsp[0].fnt, yyvsp[0].fnt->memopt, yyvsp[0].fnt->data->lvc.language); ;}
     break;
 
   case 23:
-#line 615 "parser.y"
+#line 614 "parser.y"
     { yyval.res = new_resource(res_fntdir, yyvsp[0].fnd, yyvsp[0].fnd->memopt, yyvsp[0].fnd->data->lvc.language); ;}
     break;
 
   case 24:
-#line 616 "parser.y"
+#line 615 "parser.y"
     {
                resource_t *rsc;
                if(yyvsp[0].ani->type == res_aniico)
@@ -2276,12 +2273,12 @@ yyreduce:
     break;
 
   case 25:
-#line 640 "parser.y"
+#line 639 "parser.y"
     { yyval.res = new_resource(res_men, yyvsp[0].men, yyvsp[0].men->memopt, yyvsp[0].men->lvc.language); ;}
     break;
 
   case 26:
-#line 641 "parser.y"
+#line 640 "parser.y"
     {
                if(win32)
                        yyval.res = new_resource(res_menex, yyvsp[0].menex, yyvsp[0].menex->memopt, yyvsp[0].menex->lvc.language);
@@ -2291,52 +2288,52 @@ yyreduce:
     break;
 
   case 27:
-#line 647 "parser.y"
+#line 646 "parser.y"
     { yyval.res = new_resource(res_msg, yyvsp[0].msg, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, yyvsp[0].msg->data->lvc.language); ;}
     break;
 
   case 28:
-#line 648 "parser.y"
+#line 647 "parser.y"
     { yyval.res = new_resource(res_rdt, yyvsp[0].rdt, yyvsp[0].rdt->memopt, yyvsp[0].rdt->data->lvc.language); ;}
     break;
 
   case 29:
-#line 649 "parser.y"
+#line 648 "parser.y"
     { yyval.res = new_resource(res_toolbar, yyvsp[0].tlbar, yyvsp[0].tlbar->memopt, yyvsp[0].tlbar->lvc.language); ;}
     break;
 
   case 30:
-#line 650 "parser.y"
+#line 649 "parser.y"
     { yyval.res = new_resource(res_usr, yyvsp[0].usr, yyvsp[0].usr->memopt, yyvsp[0].usr->data->lvc.language); ;}
     break;
 
   case 31:
-#line 651 "parser.y"
+#line 650 "parser.y"
     { yyval.res = new_resource(res_ver, yyvsp[0].veri, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, yyvsp[0].veri->lvc.language); ;}
     break;
 
   case 32:
-#line 655 "parser.y"
+#line 654 "parser.y"
     { yyval.str = make_filename(yyvsp[0].str); ;}
     break;
 
   case 33:
-#line 656 "parser.y"
+#line 655 "parser.y"
     { yyval.str = make_filename(yyvsp[0].str); ;}
     break;
 
   case 34:
-#line 657 "parser.y"
+#line 656 "parser.y"
     { yyval.str = make_filename(yyvsp[0].str); ;}
     break;
 
   case 35:
-#line 661 "parser.y"
+#line 660 "parser.y"
     { yyval.bmp = new_bitmap(yyvsp[0].raw, yyvsp[-1].iptr); ;}
     break;
 
   case 36:
-#line 665 "parser.y"
+#line 664 "parser.y"
     {
                yyval.ani = new_ani_any();
                if(yyvsp[0].raw->size > 4 && !memcmp(yyvsp[0].raw->data, riff, sizeof(riff)))
@@ -2353,7 +2350,7 @@ yyreduce:
     break;
 
   case 37:
-#line 681 "parser.y"
+#line 680 "parser.y"
     {
                yyval.ani = new_ani_any();
                if(yyvsp[0].raw->size > 4 && !memcmp(yyvsp[0].raw->data, riff, sizeof(riff)))
@@ -2370,17 +2367,17 @@ yyreduce:
     break;
 
   case 38:
-#line 703 "parser.y"
+#line 702 "parser.y"
     { yyval.fnt = new_font(yyvsp[0].raw, yyvsp[-1].iptr); ;}
     break;
 
   case 39:
-#line 713 "parser.y"
+#line 712 "parser.y"
     { yyval.fnd = new_fontdir(yyvsp[0].raw, yyvsp[-1].iptr); ;}
     break;
 
   case 40:
-#line 721 "parser.y"
+#line 720 "parser.y"
     {
                if(!win32)
                        yywarning("MESSAGETABLE not supported in 16-bit mode");
@@ -2389,30 +2386,30 @@ yyreduce:
     break;
 
   case 41:
-#line 729 "parser.y"
+#line 728 "parser.y"
     { yyval.rdt = new_rcdata(yyvsp[0].raw, yyvsp[-1].iptr); ;}
     break;
 
   case 42:
-#line 733 "parser.y"
+#line 732 "parser.y"
     { yyval.dginit = new_dlginit(yyvsp[0].raw, yyvsp[-1].iptr); ;}
     break;
 
   case 43:
-#line 737 "parser.y"
+#line 736 "parser.y"
     {
-               #ifdef WORDS_BIGENDIAN
+#ifdef WORDS_BIGENDIAN
                        if(pedantic && byteorder != WRC_BO_LITTLE)
-               #else
+#else
                        if(pedantic && byteorder == WRC_BO_BIG)
-               #endif
+#endif
                                yywarning("Byteordering is not little-endian and type cannot be interpreted");
                        yyval.usr = new_user(yyvsp[-2].nid, yyvsp[0].raw, yyvsp[-1].iptr);
                ;}
     break;
 
   case 44:
-#line 748 "parser.y"
+#line 747 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_ord;
@@ -2421,7 +2418,7 @@ yyreduce:
     break;
 
   case 45:
-#line 753 "parser.y"
+#line 752 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_str;
@@ -2430,7 +2427,7 @@ yyreduce:
     break;
 
   case 46:
-#line 762 "parser.y"
+#line 761 "parser.y"
     {
                yyval.acc = new_accelerator();
                if(yyvsp[-4].iptr)
@@ -2456,72 +2453,72 @@ yyreduce:
     break;
 
   case 47:
-#line 786 "parser.y"
+#line 785 "parser.y"
     { yyval.event=NULL; ;}
     break;
 
   case 48:
-#line 787 "parser.y"
+#line 786 "parser.y"
     { yyval.event=add_string_event(yyvsp[-3].str, yyvsp[-1].num, yyvsp[0].num, yyvsp[-4].event); ;}
     break;
 
   case 49:
-#line 788 "parser.y"
+#line 787 "parser.y"
     { yyval.event=add_event(yyvsp[-3].num, yyvsp[-1].num, yyvsp[0].num, yyvsp[-4].event); ;}
     break;
 
   case 50:
-#line 797 "parser.y"
+#line 796 "parser.y"
     { yyval.num = 0; ;}
     break;
 
   case 51:
-#line 798 "parser.y"
+#line 797 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
   case 52:
-#line 801 "parser.y"
+#line 800 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
   case 53:
-#line 802 "parser.y"
+#line 801 "parser.y"
     { yyval.num = yyvsp[-2].num | yyvsp[0].num; ;}
     break;
 
   case 54:
-#line 805 "parser.y"
+#line 804 "parser.y"
     { yyval.num = WRC_AF_NOINVERT; ;}
     break;
 
   case 55:
-#line 806 "parser.y"
+#line 805 "parser.y"
     { yyval.num = WRC_AF_SHIFT; ;}
     break;
 
   case 56:
-#line 807 "parser.y"
+#line 806 "parser.y"
     { yyval.num = WRC_AF_CONTROL; ;}
     break;
 
   case 57:
-#line 808 "parser.y"
+#line 807 "parser.y"
     { yyval.num = WRC_AF_ALT; ;}
     break;
 
   case 58:
-#line 809 "parser.y"
+#line 808 "parser.y"
     { yyval.num = WRC_AF_ASCII; ;}
     break;
 
   case 59:
-#line 810 "parser.y"
+#line 809 "parser.y"
     { yyval.num = WRC_AF_VIRTKEY; ;}
     break;
 
   case 60:
-#line 816 "parser.y"
+#line 815 "parser.y"
     {
                if(yyvsp[-11].iptr)
                {
@@ -2556,147 +2553,147 @@ yyreduce:
     break;
 
   case 61:
-#line 850 "parser.y"
+#line 849 "parser.y"
     { yyval.dlg=new_dialog(); ;}
     break;
 
   case 62:
-#line 851 "parser.y"
+#line 850 "parser.y"
     { yyval.dlg=dialog_style(yyvsp[0].style,yyvsp[-2].dlg); ;}
     break;
 
   case 63:
-#line 852 "parser.y"
+#line 851 "parser.y"
     { yyval.dlg=dialog_exstyle(yyvsp[0].style,yyvsp[-2].dlg); ;}
     break;
 
   case 64:
-#line 853 "parser.y"
+#line 852 "parser.y"
     { yyval.dlg=dialog_caption(yyvsp[0].str,yyvsp[-2].dlg); ;}
     break;
 
   case 65:
-#line 854 "parser.y"
+#line 853 "parser.y"
     { yyval.dlg=dialog_font(yyvsp[0].fntid,yyvsp[-1].dlg); ;}
     break;
 
   case 66:
-#line 855 "parser.y"
+#line 854 "parser.y"
     { yyval.dlg=dialog_class(yyvsp[0].nid,yyvsp[-2].dlg); ;}
     break;
 
   case 67:
-#line 856 "parser.y"
+#line 855 "parser.y"
     { yyval.dlg=dialog_menu(yyvsp[0].nid,yyvsp[-2].dlg); ;}
     break;
 
   case 68:
-#line 857 "parser.y"
+#line 856 "parser.y"
     { yyval.dlg=dialog_language(yyvsp[0].lan,yyvsp[-1].dlg); ;}
     break;
 
   case 69:
-#line 858 "parser.y"
+#line 857 "parser.y"
     { yyval.dlg=dialog_characteristics(yyvsp[0].chars,yyvsp[-1].dlg); ;}
     break;
 
   case 70:
-#line 859 "parser.y"
+#line 858 "parser.y"
     { yyval.dlg=dialog_version(yyvsp[0].ver,yyvsp[-1].dlg); ;}
     break;
 
   case 71:
-#line 862 "parser.y"
+#line 861 "parser.y"
     { yyval.ctl = NULL; ;}
     break;
 
   case 72:
-#line 863 "parser.y"
+#line 862 "parser.y"
     { yyval.ctl=ins_ctrl(-1, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 73:
-#line 864 "parser.y"
+#line 863 "parser.y"
     { yyval.ctl=ins_ctrl(CT_EDIT, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 74:
-#line 865 "parser.y"
+#line 864 "parser.y"
     { yyval.ctl=ins_ctrl(CT_LISTBOX, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 75:
-#line 866 "parser.y"
+#line 865 "parser.y"
     { yyval.ctl=ins_ctrl(CT_COMBOBOX, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 76:
-#line 867 "parser.y"
+#line 866 "parser.y"
     { yyval.ctl=ins_ctrl(CT_SCROLLBAR, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 77:
-#line 868 "parser.y"
+#line 867 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_CHECKBOX, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 78:
-#line 869 "parser.y"
+#line 868 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_DEFPUSHBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 79:
-#line 870 "parser.y"
+#line 869 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_GROUPBOX, yyvsp[0].ctl, yyvsp[-2].ctl);;}
     break;
 
   case 80:
-#line 871 "parser.y"
+#line 870 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_PUSHBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 81:
-#line 873 "parser.y"
+#line 872 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_RADIOBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 82:
-#line 874 "parser.y"
+#line 873 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTO3STATE, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 83:
-#line 875 "parser.y"
+#line 874 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_3STATE, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 84:
-#line 876 "parser.y"
+#line 875 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTOCHECKBOX, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 85:
-#line 877 "parser.y"
+#line 876 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTORADIOBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 86:
-#line 878 "parser.y"
+#line 877 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_LEFT, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 87:
-#line 879 "parser.y"
+#line 878 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_CENTER, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 88:
-#line 880 "parser.y"
+#line 879 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_RIGHT, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
   case 89:
-#line 882 "parser.y"
+#line 881 "parser.y"
     {
                yyvsp[0].ctl->title = yyvsp[-7].nid;
                yyvsp[0].ctl->id = yyvsp[-5].num;
@@ -2707,7 +2704,7 @@ yyreduce:
     break;
 
   case 90:
-#line 892 "parser.y"
+#line 891 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = new_name_id();
@@ -2718,16 +2715,22 @@ yyreduce:
                yyval.ctl->y = yyvsp[-5].num;
                yyval.ctl->width = yyvsp[-3].num;
                yyval.ctl->height = yyvsp[-1].num;
-               if(yyvsp[0].style)
+               if(yyvsp[0].styles)
                {
-                       yyval.ctl->style = yyvsp[0].style;
+                       yyval.ctl->style = yyvsp[0].styles->style;
                        yyval.ctl->gotstyle = TRUE;
+                       if (yyvsp[0].styles->exstyle)
+                       {
+                           yyval.ctl->exstyle = yyvsp[0].styles->exstyle;
+                           yyval.ctl->gotexstyle = TRUE;
+                       }
+                       free(yyvsp[0].styles);
                }
                ;}
     break;
 
   case 91:
-#line 911 "parser.y"
+#line 916 "parser.y"
     {
                yyval.ctl = new_control();
                yyval.ctl->id = yyvsp[-9].num;
@@ -2735,21 +2738,27 @@ yyreduce:
                yyval.ctl->y = yyvsp[-5].num;
                yyval.ctl->width = yyvsp[-3].num;
                yyval.ctl->height = yyvsp[-1].num;
-               if(yyvsp[0].style)
+               if(yyvsp[0].styles)
                {
-                       yyval.ctl->style = yyvsp[0].style;
+                       yyval.ctl->style = yyvsp[0].styles->style;
                        yyval.ctl->gotstyle = TRUE;
+                       if (yyvsp[0].styles->exstyle)
+                       {
+                           yyval.ctl->exstyle = yyvsp[0].styles->exstyle;
+                           yyval.ctl->gotexstyle = TRUE;
+                       }
+                       free(yyvsp[0].styles);
                }
                ;}
     break;
 
   case 92:
-#line 927 "parser.y"
+#line 938 "parser.y"
     { yyval.ctl = new_control(); ;}
     break;
 
   case 93:
-#line 929 "parser.y"
+#line 940 "parser.y"
     {
                yyval.ctl = new_control();
                yyval.ctl->width = yyvsp[-2].num;
@@ -2758,7 +2767,7 @@ yyreduce:
     break;
 
   case 94:
-#line 934 "parser.y"
+#line 945 "parser.y"
     {
                yyval.ctl = new_control();
                yyval.ctl->width = yyvsp[-4].num;
@@ -2769,7 +2778,7 @@ yyreduce:
     break;
 
   case 95:
-#line 941 "parser.y"
+#line 952 "parser.y"
     {
                yyval.ctl = new_control();
                yyval.ctl->width = yyvsp[-6].num;
@@ -2782,7 +2791,7 @@ yyreduce:
     break;
 
   case 96:
-#line 952 "parser.y"
+#line 963 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = yyvsp[-16].nid;
@@ -2800,7 +2809,7 @@ yyreduce:
     break;
 
   case 97:
-#line 966 "parser.y"
+#line 977 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = yyvsp[-14].nid;
@@ -2816,57 +2825,47 @@ yyreduce:
     break;
 
   case 98:
-#line 981 "parser.y"
+#line 992 "parser.y"
     { yyval.fntid = new_font_id(yyvsp[-2].num, yyvsp[0].str, 0, 0); ;}
     break;
 
   case 99:
-#line 986 "parser.y"
-    { yyval.style = NULL; ;}
-    break;
-
-  case 100:
-#line 987 "parser.y"
-    { yyval.style = yyvsp[0].style; ;}
-    break;
-
-  case 101:
-#line 991 "parser.y"
+#line 997 "parser.y"
     { yyval.styles = NULL; ;}
     break;
 
-  case 102:
-#line 992 "parser.y"
+  case 100:
+#line 998 "parser.y"
     { yyval.styles = new_style_pair(yyvsp[0].style, 0); ;}
     break;
 
-  case 103:
-#line 993 "parser.y"
+  case 101:
+#line 999 "parser.y"
     { yyval.styles = new_style_pair(yyvsp[-2].style, yyvsp[0].style); ;}
     break;
 
-  case 104:
-#line 997 "parser.y"
+  case 102:
+#line 1003 "parser.y"
     { yyval.style = new_style(yyvsp[-2].style->or_mask | yyvsp[0].style->or_mask, yyvsp[-2].style->and_mask | yyvsp[0].style->and_mask); free(yyvsp[-2].style); free(yyvsp[0].style);;}
     break;
 
-  case 105:
-#line 998 "parser.y"
+  case 103:
+#line 1004 "parser.y"
     { yyval.style = yyvsp[-1].style; ;}
     break;
 
-  case 106:
-#line 999 "parser.y"
+  case 104:
+#line 1005 "parser.y"
     { yyval.style = new_style(yyvsp[0].num, 0); ;}
     break;
 
-  case 107:
-#line 1000 "parser.y"
+  case 105:
+#line 1006 "parser.y"
     { yyval.style = new_style(0, yyvsp[0].num); ;}
     break;
 
-  case 108:
-#line 1004 "parser.y"
+  case 106:
+#line 1010 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_ord;
@@ -2874,8 +2873,8 @@ yyreduce:
                ;}
     break;
 
-  case 109:
-#line 1009 "parser.y"
+  case 107:
+#line 1015 "parser.y"
     {
                yyval.nid = new_name_id();
                yyval.nid->type = name_str;
@@ -2883,8 +2882,8 @@ yyreduce:
                ;}
     break;
 
-  case 110:
-#line 1018 "parser.y"
+  case 108:
+#line 1024 "parser.y"
     {
                if(!win32)
                        yywarning("DIALOGEX not supported in 16-bit mode");
@@ -2927,153 +2926,153 @@ yyreduce:
                ;}
     break;
 
-  case 111:
-#line 1061 "parser.y"
+  case 109:
+#line 1067 "parser.y"
     { yyval.dlgex=new_dialogex(); ;}
     break;
 
-  case 112:
-#line 1062 "parser.y"
+  case 110:
+#line 1068 "parser.y"
     { yyval.dlgex=dialogex_style(yyvsp[0].style,yyvsp[-2].dlgex); ;}
     break;
 
-  case 113:
-#line 1063 "parser.y"
+  case 111:
+#line 1069 "parser.y"
     { yyval.dlgex=dialogex_exstyle(yyvsp[0].style,yyvsp[-2].dlgex); ;}
     break;
 
-  case 114:
-#line 1064 "parser.y"
+  case 112:
+#line 1070 "parser.y"
     { yyval.dlgex=dialogex_caption(yyvsp[0].str,yyvsp[-2].dlgex); ;}
     break;
 
-  case 115:
-#line 1065 "parser.y"
+  case 113:
+#line 1071 "parser.y"
     { yyval.dlgex=dialogex_font(yyvsp[0].fntid,yyvsp[-1].dlgex); ;}
     break;
 
-  case 116:
-#line 1066 "parser.y"
+  case 114:
+#line 1072 "parser.y"
     { yyval.dlgex=dialogex_font(yyvsp[0].fntid,yyvsp[-1].dlgex); ;}
     break;
 
-  case 117:
-#line 1067 "parser.y"
+  case 115:
+#line 1073 "parser.y"
     { yyval.dlgex=dialogex_class(yyvsp[0].nid,yyvsp[-2].dlgex); ;}
     break;
 
-  case 118:
-#line 1068 "parser.y"
+  case 116:
+#line 1074 "parser.y"
     { yyval.dlgex=dialogex_menu(yyvsp[0].nid,yyvsp[-2].dlgex); ;}
     break;
 
-  case 119:
-#line 1069 "parser.y"
+  case 117:
+#line 1075 "parser.y"
     { yyval.dlgex=dialogex_language(yyvsp[0].lan,yyvsp[-1].dlgex); ;}
     break;
 
-  case 120:
-#line 1070 "parser.y"
+  case 118:
+#line 1076 "parser.y"
     { yyval.dlgex=dialogex_characteristics(yyvsp[0].chars,yyvsp[-1].dlgex); ;}
     break;
 
-  case 121:
-#line 1071 "parser.y"
+  case 119:
+#line 1077 "parser.y"
     { yyval.dlgex=dialogex_version(yyvsp[0].ver,yyvsp[-1].dlgex); ;}
     break;
 
-  case 122:
-#line 1074 "parser.y"
+  case 120:
+#line 1080 "parser.y"
     { yyval.ctl = NULL; ;}
     break;
 
-  case 123:
-#line 1075 "parser.y"
+  case 121:
+#line 1081 "parser.y"
     { yyval.ctl=ins_ctrl(-1, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 124:
-#line 1076 "parser.y"
+  case 122:
+#line 1082 "parser.y"
     { yyval.ctl=ins_ctrl(CT_EDIT, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 125:
-#line 1077 "parser.y"
+  case 123:
+#line 1083 "parser.y"
     { yyval.ctl=ins_ctrl(CT_LISTBOX, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 126:
-#line 1078 "parser.y"
+  case 124:
+#line 1084 "parser.y"
     { yyval.ctl=ins_ctrl(CT_COMBOBOX, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 127:
-#line 1079 "parser.y"
+  case 125:
+#line 1085 "parser.y"
     { yyval.ctl=ins_ctrl(CT_SCROLLBAR, 0, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 128:
-#line 1080 "parser.y"
+  case 126:
+#line 1086 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_CHECKBOX, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 129:
-#line 1081 "parser.y"
+  case 127:
+#line 1087 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_DEFPUSHBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 130:
-#line 1082 "parser.y"
+  case 128:
+#line 1088 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_GROUPBOX, yyvsp[0].ctl, yyvsp[-2].ctl);;}
     break;
 
-  case 131:
-#line 1083 "parser.y"
+  case 129:
+#line 1089 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_PUSHBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 132:
-#line 1085 "parser.y"
+  case 130:
+#line 1091 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_RADIOBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 133:
-#line 1086 "parser.y"
+  case 131:
+#line 1092 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTO3STATE, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 134:
-#line 1087 "parser.y"
+  case 132:
+#line 1093 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_3STATE, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 135:
-#line 1088 "parser.y"
+  case 133:
+#line 1094 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTOCHECKBOX, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 136:
-#line 1089 "parser.y"
+  case 134:
+#line 1095 "parser.y"
     { yyval.ctl=ins_ctrl(CT_BUTTON, BS_AUTORADIOBUTTON, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 137:
-#line 1090 "parser.y"
+  case 135:
+#line 1096 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_LEFT, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 138:
-#line 1091 "parser.y"
+  case 136:
+#line 1097 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_CENTER, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 139:
-#line 1092 "parser.y"
+  case 137:
+#line 1098 "parser.y"
     { yyval.ctl=ins_ctrl(CT_STATIC, SS_RIGHT, yyvsp[0].ctl, yyvsp[-2].ctl); ;}
     break;
 
-  case 140:
-#line 1094 "parser.y"
+  case 138:
+#line 1100 "parser.y"
     {
                yyvsp[0].ctl->title = yyvsp[-7].nid;
                yyvsp[0].ctl->id = yyvsp[-5].num;
@@ -3083,8 +3082,8 @@ yyreduce:
                ;}
     break;
 
-  case 141:
-#line 1105 "parser.y"
+  case 139:
+#line 1111 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = yyvsp[-18].nid;
@@ -3111,8 +3110,8 @@ yyreduce:
                ;}
     break;
 
-  case 142:
-#line 1129 "parser.y"
+  case 140:
+#line 1135 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = yyvsp[-15].nid;
@@ -3128,8 +3127,8 @@ yyreduce:
                ;}
     break;
 
-  case 143:
-#line 1145 "parser.y"
+  case 141:
+#line 1151 "parser.y"
     {
                yyval.ctl=new_control();
                yyval.ctl->title = new_name_id();
@@ -3157,8 +3156,8 @@ yyreduce:
                ;}
     break;
 
-  case 144:
-#line 1173 "parser.y"
+  case 142:
+#line 1179 "parser.y"
     {
                yyval.ctl = new_control();
                yyval.ctl->id = yyvsp[-11].num;
@@ -3182,43 +3181,43 @@ yyreduce:
                ;}
     break;
 
-  case 145:
-#line 1196 "parser.y"
+  case 143:
+#line 1202 "parser.y"
     { yyval.raw = NULL; ;}
     break;
 
-  case 146:
-#line 1197 "parser.y"
+  case 144:
+#line 1203 "parser.y"
     { yyval.raw = yyvsp[0].raw; ;}
     break;
 
-  case 147:
-#line 1200 "parser.y"
+  case 145:
+#line 1206 "parser.y"
     { yyval.iptr = NULL; ;}
     break;
 
-  case 148:
-#line 1201 "parser.y"
+  case 146:
+#line 1207 "parser.y"
     { yyval.iptr = new_int(yyvsp[0].num); ;}
     break;
 
-  case 149:
-#line 1205 "parser.y"
+  case 147:
+#line 1211 "parser.y"
     { yyval.fntid = new_font_id(yyvsp[-7].num, yyvsp[-5].str, yyvsp[-3].num, yyvsp[-1].num); ;}
     break;
 
-  case 150:
-#line 1212 "parser.y"
+  case 148:
+#line 1218 "parser.y"
     { yyval.fntid = NULL; ;}
     break;
 
-  case 151:
-#line 1213 "parser.y"
+  case 149:
+#line 1219 "parser.y"
     { yyval.fntid = NULL; ;}
     break;
 
-  case 152:
-#line 1217 "parser.y"
+  case 150:
+#line 1223 "parser.y"
     {
                if(!yyvsp[0].menitm)
                        yyerror("Menu must contain items");
@@ -3241,18 +3240,18 @@ yyreduce:
                ;}
     break;
 
-  case 153:
-#line 1240 "parser.y"
+  case 151:
+#line 1246 "parser.y"
     { yyval.menitm = yyvsp[-1].menitm; ;}
     break;
 
-  case 154:
-#line 1244 "parser.y"
+  case 152:
+#line 1250 "parser.y"
     {yyval.menitm = NULL;;}
     break;
 
-  case 155:
-#line 1245 "parser.y"
+  case 153:
+#line 1251 "parser.y"
     {
                yyval.menitm=new_menu_item();
                yyval.menitm->prev = yyvsp[-5].menitm;
@@ -3264,8 +3263,8 @@ yyreduce:
                ;}
     break;
 
-  case 156:
-#line 1254 "parser.y"
+  case 154:
+#line 1260 "parser.y"
     {
                yyval.menitm=new_menu_item();
                yyval.menitm->prev = yyvsp[-2].menitm;
@@ -3274,8 +3273,8 @@ yyreduce:
                ;}
     break;
 
-  case 157:
-#line 1260 "parser.y"
+  case 155:
+#line 1266 "parser.y"
     {
                yyval.menitm = new_menu_item();
                yyval.menitm->prev = yyvsp[-4].menitm;
@@ -3286,43 +3285,43 @@ yyreduce:
                ;}
     break;
 
-  case 158:
-#line 1279 "parser.y"
+  case 156:
+#line 1285 "parser.y"
     { yyval.num = 0; ;}
     break;
 
-  case 159:
-#line 1280 "parser.y"
+  case 157:
+#line 1286 "parser.y"
     { yyval.num = yyvsp[0].num | MF_CHECKED; ;}
     break;
 
-  case 160:
-#line 1281 "parser.y"
+  case 158:
+#line 1287 "parser.y"
     { yyval.num = yyvsp[0].num | MF_GRAYED; ;}
     break;
 
-  case 161:
-#line 1282 "parser.y"
+  case 159:
+#line 1288 "parser.y"
     { yyval.num = yyvsp[0].num | MF_HELP; ;}
     break;
 
-  case 162:
-#line 1283 "parser.y"
+  case 160:
+#line 1289 "parser.y"
     { yyval.num = yyvsp[0].num | MF_DISABLED; ;}
     break;
 
-  case 163:
-#line 1284 "parser.y"
+  case 161:
+#line 1290 "parser.y"
     { yyval.num = yyvsp[0].num | MF_MENUBARBREAK; ;}
     break;
 
-  case 164:
-#line 1285 "parser.y"
+  case 162:
+#line 1291 "parser.y"
     { yyval.num = yyvsp[0].num | MF_MENUBREAK; ;}
     break;
 
-  case 165:
-#line 1289 "parser.y"
+  case 163:
+#line 1295 "parser.y"
     {
                if(!win32)
                        yywarning("MENUEX not supported in 16-bit mode");
@@ -3347,18 +3346,18 @@ yyreduce:
                ;}
     break;
 
-  case 166:
-#line 1314 "parser.y"
+  case 164:
+#line 1320 "parser.y"
     { yyval.menexitm = yyvsp[-1].menexitm; ;}
     break;
 
-  case 167:
-#line 1318 "parser.y"
+  case 165:
+#line 1324 "parser.y"
     {yyval.menexitm = NULL; ;}
     break;
 
-  case 168:
-#line 1319 "parser.y"
+  case 166:
+#line 1325 "parser.y"
     {
                yyval.menexitm = new_menuex_item();
                yyval.menexitm->prev = yyvsp[-3].menexitm;
@@ -3377,8 +3376,8 @@ yyreduce:
                ;}
     break;
 
-  case 169:
-#line 1335 "parser.y"
+  case 167:
+#line 1341 "parser.y"
     {
                yyval.menexitm = new_menuex_item();
                yyval.menexitm->prev = yyvsp[-2].menexitm;
@@ -3387,8 +3386,8 @@ yyreduce:
                ;}
     break;
 
-  case 170:
-#line 1341 "parser.y"
+  case 168:
+#line 1347 "parser.y"
     {
                yyval.menexitm = new_menuex_item();
                yyval.menexitm->prev = yyvsp[-4].menexitm;
@@ -3408,21 +3407,21 @@ yyreduce:
                ;}
     break;
 
-  case 171:
-#line 1361 "parser.y"
+  case 169:
+#line 1367 "parser.y"
     { yyval.exopt = new_itemex_opt(0, 0, 0, 0); ;}
     break;
 
-  case 172:
-#line 1362 "parser.y"
+  case 170:
+#line 1368 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[0].num, 0, 0, 0);
                yyval.exopt->gotid = TRUE;
                ;}
     break;
 
-  case 173:
-#line 1366 "parser.y"
+  case 171:
+#line 1372 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[-3].iptr ? *(yyvsp[-3].iptr) : 0, yyvsp[-1].iptr ? *(yyvsp[-1].iptr) : 0, yyvsp[0].num, 0);
                yyval.exopt->gotid = TRUE;
@@ -3433,8 +3432,8 @@ yyreduce:
                ;}
     break;
 
-  case 174:
-#line 1374 "parser.y"
+  case 172:
+#line 1380 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[-4].iptr ? *(yyvsp[-4].iptr) : 0, yyvsp[-2].iptr ? *(yyvsp[-2].iptr) : 0, yyvsp[0].num, 0);
                yyval.exopt->gotid = TRUE;
@@ -3445,21 +3444,21 @@ yyreduce:
                ;}
     break;
 
-  case 175:
-#line 1385 "parser.y"
+  case 173:
+#line 1391 "parser.y"
     { yyval.exopt = new_itemex_opt(0, 0, 0, 0); ;}
     break;
 
-  case 176:
-#line 1386 "parser.y"
+  case 174:
+#line 1392 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[0].num, 0, 0, 0);
                yyval.exopt->gotid = TRUE;
                ;}
     break;
 
-  case 177:
-#line 1390 "parser.y"
+  case 175:
+#line 1396 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[-2].iptr ? *(yyvsp[-2].iptr) : 0, yyvsp[0].num, 0, 0);
                if(yyvsp[-2].iptr) free(yyvsp[-2].iptr);
@@ -3468,8 +3467,8 @@ yyreduce:
                ;}
     break;
 
-  case 178:
-#line 1396 "parser.y"
+  case 176:
+#line 1402 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[-4].iptr ? *(yyvsp[-4].iptr) : 0, yyvsp[-2].iptr ? *(yyvsp[-2].iptr) : 0, yyvsp[0].num, 0);
                if(yyvsp[-4].iptr) free(yyvsp[-4].iptr);
@@ -3480,8 +3479,8 @@ yyreduce:
                ;}
     break;
 
-  case 179:
-#line 1404 "parser.y"
+  case 177:
+#line 1410 "parser.y"
     {
                yyval.exopt = new_itemex_opt(yyvsp[-6].iptr ? *(yyvsp[-6].iptr) : 0, yyvsp[-4].iptr ? *(yyvsp[-4].iptr) : 0, yyvsp[-2].iptr ? *(yyvsp[-2].iptr) : 0, yyvsp[0].num);
                if(yyvsp[-6].iptr) free(yyvsp[-6].iptr);
@@ -3494,8 +3493,8 @@ yyreduce:
                ;}
     break;
 
-  case 180:
-#line 1424 "parser.y"
+  case 178:
+#line 1430 "parser.y"
     {
                if(!yyvsp[-1].stt)
                {
@@ -3536,8 +3535,8 @@ yyreduce:
                ;}
     break;
 
-  case 181:
-#line 1465 "parser.y"
+  case 179:
+#line 1471 "parser.y"
     {
                if((tagstt = find_stringtable(yyvsp[0].lvc)) == NULL)
                        tagstt = new_stringtable(yyvsp[0].lvc);
@@ -3549,13 +3548,13 @@ yyreduce:
                ;}
     break;
 
-  case 182:
-#line 1476 "parser.y"
+  case 180:
+#line 1482 "parser.y"
     { yyval.stt = NULL; ;}
     break;
 
-  case 183:
-#line 1477 "parser.y"
+  case 181:
+#line 1483 "parser.y"
     {
                int i;
                assert(tagstt != NULL);
@@ -3589,8 +3588,8 @@ yyreduce:
                ;}
     break;
 
-  case 186:
-#line 1517 "parser.y"
+  case 184:
+#line 1523 "parser.y"
     {
                yyval.veri = yyvsp[-3].veri;
                if(yyvsp[-4].iptr)
@@ -3606,13 +3605,13 @@ yyreduce:
                ;}
     break;
 
-  case 187:
-#line 1533 "parser.y"
+  case 185:
+#line 1539 "parser.y"
     { yyval.veri = new_versioninfo(); ;}
     break;
 
-  case 188:
-#line 1534 "parser.y"
+  case 186:
+#line 1540 "parser.y"
     {
                if(yyvsp[-8].veri->gotit.fv)
                        yyerror("FILEVERSION already defined");
@@ -3625,8 +3624,8 @@ yyreduce:
                ;}
     break;
 
-  case 189:
-#line 1544 "parser.y"
+  case 187:
+#line 1550 "parser.y"
     {
                if(yyvsp[-8].veri->gotit.pv)
                        yyerror("PRODUCTVERSION already defined");
@@ -3639,8 +3638,8 @@ yyreduce:
                ;}
     break;
 
-  case 190:
-#line 1554 "parser.y"
+  case 188:
+#line 1560 "parser.y"
     {
                if(yyvsp[-2].veri->gotit.ff)
                        yyerror("FILEFLAGS already defined");
@@ -3650,8 +3649,8 @@ yyreduce:
                ;}
     break;
 
-  case 191:
-#line 1561 "parser.y"
+  case 189:
+#line 1567 "parser.y"
     {
                if(yyvsp[-2].veri->gotit.ffm)
                        yyerror("FILEFLAGSMASK already defined");
@@ -3661,8 +3660,8 @@ yyreduce:
                ;}
     break;
 
-  case 192:
-#line 1568 "parser.y"
+  case 190:
+#line 1574 "parser.y"
     {
                if(yyvsp[-2].veri->gotit.fo)
                        yyerror("FILEOS already defined");
@@ -3672,8 +3671,8 @@ yyreduce:
                ;}
     break;
 
-  case 193:
-#line 1575 "parser.y"
+  case 191:
+#line 1581 "parser.y"
     {
                if(yyvsp[-2].veri->gotit.ft)
                        yyerror("FILETYPE already defined");
@@ -3683,8 +3682,8 @@ yyreduce:
                ;}
     break;
 
-  case 194:
-#line 1582 "parser.y"
+  case 192:
+#line 1588 "parser.y"
     {
                if(yyvsp[-2].veri->gotit.fst)
                        yyerror("FILESUBTYPE already defined");
@@ -3694,13 +3693,13 @@ yyreduce:
                ;}
     break;
 
-  case 195:
-#line 1592 "parser.y"
+  case 193:
+#line 1598 "parser.y"
     { yyval.blk = NULL; ;}
     break;
 
-  case 196:
-#line 1593 "parser.y"
+  case 194:
+#line 1599 "parser.y"
     {
                yyval.blk = yyvsp[0].blk;
                yyval.blk->prev = yyvsp[-1].blk;
@@ -3709,8 +3708,8 @@ yyreduce:
                ;}
     break;
 
-  case 197:
-#line 1602 "parser.y"
+  case 195:
+#line 1608 "parser.y"
     {
                yyval.blk = new_ver_block();
                yyval.blk->name = yyvsp[-3].str;
@@ -3718,13 +3717,13 @@ yyreduce:
                ;}
     break;
 
-  case 198:
-#line 1610 "parser.y"
+  case 196:
+#line 1616 "parser.y"
     { yyval.val = NULL; ;}
     break;
 
-  case 199:
-#line 1611 "parser.y"
+  case 197:
+#line 1617 "parser.y"
     {
                yyval.val = yyvsp[0].val;
                yyval.val->prev = yyvsp[-1].val;
@@ -3733,8 +3732,8 @@ yyreduce:
                ;}
     break;
 
-  case 200:
-#line 1620 "parser.y"
+  case 198:
+#line 1626 "parser.y"
     {
                yyval.val = new_ver_value();
                yyval.val->type = val_block;
@@ -3742,8 +3741,8 @@ yyreduce:
                ;}
     break;
 
-  case 201:
-#line 1625 "parser.y"
+  case 199:
+#line 1631 "parser.y"
     {
                yyval.val = new_ver_value();
                yyval.val->type = val_str;
@@ -3752,8 +3751,8 @@ yyreduce:
                ;}
     break;
 
-  case 202:
-#line 1631 "parser.y"
+  case 200:
+#line 1637 "parser.y"
     {
                yyval.val = new_ver_value();
                yyval.val->type = val_words;
@@ -3762,18 +3761,18 @@ yyreduce:
                ;}
     break;
 
-  case 203:
-#line 1640 "parser.y"
+  case 201:
+#line 1646 "parser.y"
     { yyval.verw = new_ver_words(yyvsp[0].num); ;}
     break;
 
-  case 204:
-#line 1641 "parser.y"
+  case 202:
+#line 1647 "parser.y"
     { yyval.verw = add_ver_words(yyvsp[-2].verw, yyvsp[0].num); ;}
     break;
 
-  case 205:
-#line 1645 "parser.y"
+  case 203:
+#line 1651 "parser.y"
     {
                int nitems;
                toolbar_item_t *items = get_tlbr_buttons_head(yyvsp[-1].tlbarItems, &nitems);
@@ -3799,13 +3798,13 @@ yyreduce:
                ;}
     break;
 
-  case 206:
-#line 1671 "parser.y"
+  case 204:
+#line 1677 "parser.y"
     { yyval.tlbarItems = NULL; ;}
     break;
 
-  case 207:
-#line 1672 "parser.y"
+  case 205:
+#line 1678 "parser.y"
     {
                toolbar_item_t *idrec = new_toolbar_item();
                idrec->id = yyvsp[0].num;
@@ -3813,8 +3812,8 @@ yyreduce:
                ;}
     break;
 
-  case 208:
-#line 1677 "parser.y"
+  case 206:
+#line 1683 "parser.y"
     {
                toolbar_item_t *idrec = new_toolbar_item();
                idrec->id = 0;
@@ -3822,13 +3821,13 @@ yyreduce:
        ;}
     break;
 
-  case 209:
-#line 1686 "parser.y"
+  case 207:
+#line 1692 "parser.y"
     { yyval.iptr = NULL; ;}
     break;
 
-  case 210:
-#line 1687 "parser.y"
+  case 208:
+#line 1693 "parser.y"
     {
                if(yyvsp[-1].iptr)
                {
@@ -3841,8 +3840,8 @@ yyreduce:
                ;}
     break;
 
-  case 211:
-#line 1697 "parser.y"
+  case 209:
+#line 1703 "parser.y"
     {
                if(yyvsp[-1].iptr)
                {
@@ -3858,48 +3857,48 @@ yyreduce:
                ;}
     break;
 
-  case 212:
-#line 1712 "parser.y"
+  case 210:
+#line 1718 "parser.y"
     { yyval.iptr = new_int(WRC_MO_PRELOAD); ;}
     break;
 
-  case 213:
-#line 1713 "parser.y"
+  case 211:
+#line 1719 "parser.y"
     { yyval.iptr = new_int(WRC_MO_MOVEABLE); ;}
     break;
 
-  case 214:
-#line 1714 "parser.y"
+  case 212:
+#line 1720 "parser.y"
     { yyval.iptr = new_int(WRC_MO_DISCARDABLE); ;}
     break;
 
-  case 215:
-#line 1715 "parser.y"
+  case 213:
+#line 1721 "parser.y"
     { yyval.iptr = new_int(WRC_MO_PURE); ;}
     break;
 
-  case 216:
-#line 1718 "parser.y"
+  case 214:
+#line 1724 "parser.y"
     { yyval.iptr = new_int(~WRC_MO_PRELOAD); ;}
     break;
 
-  case 217:
-#line 1719 "parser.y"
+  case 215:
+#line 1725 "parser.y"
     { yyval.iptr = new_int(~WRC_MO_MOVEABLE); ;}
     break;
 
-  case 218:
-#line 1720 "parser.y"
+  case 216:
+#line 1726 "parser.y"
     { yyval.iptr = new_int(~WRC_MO_PURE); ;}
     break;
 
-  case 219:
-#line 1724 "parser.y"
+  case 217:
+#line 1730 "parser.y"
     { yyval.lvc = new_lvc(); ;}
     break;
 
-  case 220:
-#line 1725 "parser.y"
+  case 218:
+#line 1731 "parser.y"
     {
                if(!win32)
                        yywarning("LANGUAGE not supported in 16-bit mode");
@@ -3910,8 +3909,8 @@ yyreduce:
                ;}
     break;
 
-  case 221:
-#line 1733 "parser.y"
+  case 219:
+#line 1739 "parser.y"
     {
                if(!win32)
                        yywarning("CHARACTERISTICS not supported in 16-bit mode");
@@ -3922,8 +3921,8 @@ yyreduce:
                ;}
     break;
 
-  case 222:
-#line 1741 "parser.y"
+  case 220:
+#line 1747 "parser.y"
     {
                if(!win32)
                        yywarning("VERSION not supported in 16-bit mode");
@@ -3934,26 +3933,26 @@ yyreduce:
                ;}
     break;
 
-  case 223:
-#line 1759 "parser.y"
+  case 221:
+#line 1765 "parser.y"
     { yyval.lan = new_language(yyvsp[-2].num, yyvsp[0].num);
                                          if (get_language_codepage(yyvsp[-2].num, yyvsp[0].num) == -1)
                                                yyerror( "Language %04x is not supported", (yyvsp[0].num<<10) + yyvsp[-2].num);
                                        ;}
     break;
 
-  case 224:
-#line 1766 "parser.y"
+  case 222:
+#line 1772 "parser.y"
     { yyval.chars = new_characts(yyvsp[0].num); ;}
     break;
 
-  case 225:
-#line 1770 "parser.y"
+  case 223:
+#line 1776 "parser.y"
     { yyval.ver = new_version(yyvsp[0].num); ;}
     break;
 
-  case 226:
-#line 1774 "parser.y"
+  case 224:
+#line 1780 "parser.y"
     {
                if(yyvsp[-3].lvc)
                {
@@ -3968,163 +3967,163 @@ yyreduce:
                ;}
     break;
 
-  case 227:
-#line 1789 "parser.y"
+  case 225:
+#line 1795 "parser.y"
     { yyval.raw = yyvsp[0].raw; ;}
     break;
 
-  case 228:
-#line 1790 "parser.y"
+  case 226:
+#line 1796 "parser.y"
     { yyval.raw = int2raw_data(yyvsp[0].num); ;}
     break;
 
-  case 229:
-#line 1791 "parser.y"
+  case 227:
+#line 1797 "parser.y"
     { yyval.raw = int2raw_data(-(yyvsp[0].num)); ;}
     break;
 
-  case 230:
-#line 1792 "parser.y"
+  case 228:
+#line 1798 "parser.y"
     { yyval.raw = long2raw_data(yyvsp[0].num); ;}
     break;
 
-  case 231:
-#line 1793 "parser.y"
+  case 229:
+#line 1799 "parser.y"
     { yyval.raw = long2raw_data(-(yyvsp[0].num)); ;}
     break;
 
-  case 232:
-#line 1794 "parser.y"
+  case 230:
+#line 1800 "parser.y"
     { yyval.raw = str2raw_data(yyvsp[0].str); ;}
     break;
 
-  case 233:
-#line 1795 "parser.y"
+  case 231:
+#line 1801 "parser.y"
     { yyval.raw = merge_raw_data(yyvsp[-2].raw, yyvsp[0].raw); free(yyvsp[0].raw->data); free(yyvsp[0].raw); ;}
     break;
 
-  case 234:
-#line 1796 "parser.y"
+  case 232:
+#line 1802 "parser.y"
     { yyval.raw = merge_raw_data_int(yyvsp[-2].raw, yyvsp[0].num); ;}
     break;
 
-  case 235:
-#line 1797 "parser.y"
+  case 233:
+#line 1803 "parser.y"
     { yyval.raw = merge_raw_data_int(yyvsp[-3].raw, -(yyvsp[0].num)); ;}
     break;
 
-  case 236:
-#line 1798 "parser.y"
+  case 234:
+#line 1804 "parser.y"
     { yyval.raw = merge_raw_data_long(yyvsp[-2].raw, yyvsp[0].num); ;}
     break;
 
-  case 237:
-#line 1799 "parser.y"
+  case 235:
+#line 1805 "parser.y"
     { yyval.raw = merge_raw_data_long(yyvsp[-3].raw, -(yyvsp[0].num)); ;}
     break;
 
-  case 238:
-#line 1800 "parser.y"
+  case 236:
+#line 1806 "parser.y"
     { yyval.raw = merge_raw_data_str(yyvsp[-2].raw, yyvsp[0].str); ;}
     break;
 
-  case 239:
-#line 1804 "parser.y"
+  case 237:
+#line 1810 "parser.y"
     { yyval.raw = load_file(yyvsp[0].str,dup_language(currentlanguage)); ;}
     break;
 
-  case 240:
-#line 1805 "parser.y"
+  case 238:
+#line 1811 "parser.y"
     { yyval.raw = yyvsp[0].raw; ;}
     break;
 
-  case 241:
-#line 1812 "parser.y"
+  case 239:
+#line 1818 "parser.y"
     { yyval.iptr = 0; ;}
     break;
 
-  case 242:
-#line 1813 "parser.y"
+  case 240:
+#line 1819 "parser.y"
     { yyval.iptr = new_int(yyvsp[0].num); ;}
     break;
 
-  case 243:
-#line 1817 "parser.y"
+  case 241:
+#line 1823 "parser.y"
     { yyval.num = (yyvsp[0].num); ;}
     break;
 
-  case 244:
-#line 1820 "parser.y"
+  case 242:
+#line 1826 "parser.y"
     { yyval.num = (yyvsp[-2].num) + (yyvsp[0].num); ;}
     break;
 
-  case 245:
-#line 1821 "parser.y"
+  case 243:
+#line 1827 "parser.y"
     { yyval.num = (yyvsp[-2].num) - (yyvsp[0].num); ;}
     break;
 
-  case 246:
-#line 1822 "parser.y"
+  case 244:
+#line 1828 "parser.y"
     { yyval.num = (yyvsp[-2].num) | (yyvsp[0].num); ;}
     break;
 
-  case 247:
-#line 1823 "parser.y"
+  case 245:
+#line 1829 "parser.y"
     { yyval.num = (yyvsp[-2].num) & (yyvsp[0].num); ;}
     break;
 
-  case 248:
-#line 1824 "parser.y"
+  case 246:
+#line 1830 "parser.y"
     { yyval.num = (yyvsp[-2].num) * (yyvsp[0].num); ;}
     break;
 
-  case 249:
-#line 1825 "parser.y"
+  case 247:
+#line 1831 "parser.y"
     { yyval.num = (yyvsp[-2].num) / (yyvsp[0].num); ;}
     break;
 
-  case 250:
-#line 1826 "parser.y"
+  case 248:
+#line 1832 "parser.y"
     { yyval.num = (yyvsp[-2].num) ^ (yyvsp[0].num); ;}
     break;
 
-  case 251:
-#line 1827 "parser.y"
+  case 249:
+#line 1833 "parser.y"
     { yyval.num = ~(yyvsp[0].num); ;}
     break;
 
-  case 252:
-#line 1828 "parser.y"
+  case 250:
+#line 1834 "parser.y"
     { yyval.num = -(yyvsp[0].num); ;}
     break;
 
-  case 253:
-#line 1829 "parser.y"
+  case 251:
+#line 1835 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
-  case 254:
-#line 1830 "parser.y"
+  case 252:
+#line 1836 "parser.y"
     { yyval.num = yyvsp[-1].num; ;}
     break;
 
-  case 255:
-#line 1831 "parser.y"
+  case 253:
+#line 1837 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
-  case 256:
-#line 1832 "parser.y"
+  case 254:
+#line 1838 "parser.y"
     { yyval.num = ~(yyvsp[0].num); ;}
     break;
 
-  case 257:
-#line 1835 "parser.y"
+  case 255:
+#line 1841 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
-  case 258:
-#line 1836 "parser.y"
+  case 256:
+#line 1842 "parser.y"
     { yyval.num = yyvsp[0].num; ;}
     break;
 
@@ -4132,7 +4131,7 @@ yyreduce:
     }
 
 /* Line 999 of yacc.c.  */
-#line 4136 "y.tab.c"
+#line 4135 "y.tab.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -4338,7 +4337,7 @@ yyreturn:
 }
 
 
-#line 1839 "parser.y"
+#line 1845 "parser.y"
 
 /* Dialog specific functions */
 static dialog_t *dialog_style(style_t * st, dialog_t *dlg)
index 3a8eead..e11f339 100644 (file)
@@ -315,6 +315,7 @@ extern PACL                         SeSystemDefaultDacl;
 #define TOKEN_ADJUST_PRIVILEGES         (0x0020)
 #define TOKEN_ADJUST_GROUPS             (0x0040)
 #define TOKEN_ADJUST_DEFAULT            (0x0080)
+#define TOKEN_ADJUST_SESSIONID          (0x0100)
 
 #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
                           TOKEN_ASSIGN_PRIMARY     |\
@@ -324,7 +325,8 @@ extern PACL                         SeSystemDefaultDacl;
                           TOKEN_QUERY_SOURCE       |\
                           TOKEN_ADJUST_PRIVILEGES  |\
                           TOKEN_ADJUST_GROUPS      |\
-                          TOKEN_ADJUST_DEFAULT)
+                          TOKEN_ADJUST_DEFAULT     |\
+                          TOKEN_ADJUST_SESSIONID)
 
 #define TOKEN_READ       (STANDARD_RIGHTS_READ     |\
                           TOKEN_QUERY)
@@ -1216,13 +1218,23 @@ typedef struct _GENERATE_NAME_CONTEXT {
     ULONG   LastIndexValue;
 } GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT;
 
+typedef struct _HANDLE_TABLE_ENTRY_INFO {
+    ULONG AuditMask;
+} HANDLE_TABLE_ENTRY_INFO, *PHANDLE_TABLE_ENTRY_INFO;
+
 typedef struct _HANDLE_TABLE_ENTRY {
-    PVOID   Object;
-    ULONG   ObjectAttributes;
-    ULONG   GrantedAccess;
-    USHORT  GrantedAccessIndex;
-    USHORT  CreatorBackTraceIndex;
-    ULONG   NextFreeTableEntry;
+    union {
+        PVOID Object;
+        ULONG ObAttributes;
+        PHANDLE_TABLE_ENTRY_INFO InfoTable;
+        ULONG_PTR Value;
+    } u1;
+    union {
+        ULONG GrantedAccess;
+        USHORT GrantedAccessIndex;
+        LONG NextFreeTableEntry;
+    } u2;
+    USHORT CreatorBackTraceIndex;
 } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
 
 typedef struct _MAPPING_PAIR {
index 7032b66..bc8f1b2 100644 (file)
@@ -101,6 +101,8 @@ DECLARE_INTERNAL_OBJECT(SECTION_OBJECT)
 /* FIXME: Unknown definitions */
 struct _SET_PARTITION_INFORMATION_EX;
 typedef ULONG WAIT_TYPE;
+#define WaitAll 0
+#define WaitAny 1
 typedef HANDLE TRACEHANDLE;
 typedef PVOID PWMILIB_CONTEXT;
 typedef PVOID PSYSCTL_IRP_DISPOSITION;
@@ -126,6 +128,18 @@ static __inline struct _KPCR * KeGetCurrentKPCR(
   return (struct _KPCR *) Value;
 }
 
+static __inline struct _KPRCB * KeGetCurrentPrcb(
+  VOID)
+{
+  ULONG Value;
+
+  __asm__ __volatile__ ("movl %%fs:0x20, %0\n\t"
+         : "=r" (Value)
+    : /* no inputs */
+  );
+  return (struct _KPRCB *) Value;
+}
+
 /*
 ** Simple structures
 */
@@ -3795,6 +3809,10 @@ typedef enum _PROCESSINFOCLASS {
   ProcessDebugObjectHandle,
   ProcessDebugFlags,
   ProcessHandleTracing,
+  ProcessUnknown33,
+  ProcessUnknown34,
+  ProcessUnknown35,
+  ProcessCookie,
   MaxProcessInfoClass
 } PROCESSINFOCLASS;
 
index 70cc41f..82fd9c1 100644 (file)
@@ -5,13 +5,16 @@
 #endif
 
 #define NTAPI __stdcall
-#define OBJ_INHERIT 2L
-#define OBJ_PERMANENT 16L
-#define OBJ_EXCLUSIVE 32L
-#define OBJ_CASE_INSENSITIVE 64L
-#define OBJ_OPENIF 128L
-#define OBJ_OPENLINK 256L
-#define OBJ_VALID_ATTRIBUTES 498L
+#define OBJ_INHERIT          0x00000002
+#define OBJ_PERMANENT        0x00000010
+#define OBJ_EXCLUSIVE        0x00000020
+#define OBJ_CASE_INSENSITIVE 0x00000040
+#define OBJ_OPENIF           0x00000080
+#define OBJ_OPENLINK         0x00000100
+#define OBJ_KERNEL_HANDLE    0x00000200
+#define OBJ_VALID_ATTRIBUTES (OBJ_KERNEL_HANDLE | OBJ_OPENLINK | \
+               OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_EXCLUSIVE | \
+               OBJ_PERMANENT | OBJ_INHERIT)
 #define InitializeObjectAttributes(p,n,a,r,s) { \
   (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
   (p)->RootDirectory = (r); \
index 2dd5124..22f2cdd 100644 (file)
@@ -39,6 +39,7 @@
 #define STGM_CREATE 0x1000
 #define STGM_CONVERT 0x20000
 #define STGM_NOSNAPSHOT 0x200000
+#define STGM_DIRECT_SWMR 0x400000
 #define STGM_FAILIFTHERE 0
 #define CWCSTORAGENAME 32
 #define ASYNC_MODE_COMPATIBILITY       1
index f1ff738..fd7dab0 100644 (file)
@@ -50,6 +50,8 @@
 #define V_ISARRAY(X) (V_VT(X)&VT_ARRAY)
 #define V_ISVECTOR(X) (V_VT(X)&VT_VECTOR)
 #define V_NONE(X) V_I2(X)
+#define V_INT(A) V_UNION(A,intVal)
+#define V_UINT(A) V_UNION(A,uintVal)
 #define V_UI1(X) V_UNION(X,bVal)
 #define V_UI1REF(X) V_UNION(X,pbVal)
 #define V_I2(X) V_UNION(X,iVal)
@@ -354,6 +356,8 @@ WINOLEAUTAPI VectorFromBstr (BSTR, SAFEARRAY **);
 WINOLEAUTAPI BstrFromVector (SAFEARRAY *, BSTR *);
 WINOLEAUTAPI VarParseNumFromStr(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
 WINOLEAUTAPI VarNumFromParseNum(NUMPARSE*,BYTE*,ULONG,VARIANT*);
+WINOLEAUTAPI GetRecordInfoFromTypeInfo(ITypeInfo*,IRecordInfo**);
+WINOLEAUTAPI GetRecordInfoFromGuids(REFGUID,ULONG,ULONG,LCID,REFGUID,IRecordInfo**);
 
 WINOLEAUTAPI VarAdd(LPVARIANT, LPVARIANT, LPVARIANT);
 WINOLEAUTAPI VarSub(LPVARIANT, LPVARIANT, LPVARIANT);
index 580b511..b1c2ab4 100644 (file)
@@ -29,8 +29,26 @@ extern "C" {
 #define CFM_FACE       0x20000000
 #define CFM_OFFSET     0x10000000
 #define CFM_CHARSET    0x08000000
+#define CFM_BACKCOLOR  0x04000000
+#define CFM_LCID       0x02000000
+#define CFM_UNDERLINETYPE      0x00800000
+#define CFM_WEIGHT     0x00400000
+#define CFM_SPACING    0x00200000
+#define CFM_KERNING    0x00100000
+#define CFM_STYLE      0x00080000
+#define CFM_ANIMATION  0x00040000
 #define CFM_SUBSCRIPT  0x00030000
 #define CFM_SUPERSCRIPT        0x00030000
+#define CFM_REVAUTHOR  0x00008000
+#define CFM_REVISED    0x00004000
+#define CFM_DISABLED   0x00002000
+#define CFM_IMPRINT    0x00001000
+#define CFM_EMBOSS     0x00000800
+#define CFM_SHADOW     0x00000400
+#define CFM_OUTLINE    0x00000200
+#define CFM_HIDDEN     0x00000100
+#define CFM_ALLCAPS    0x00000080
+#define CFM_SMALLCAPS  0x00000040
 #define CFM_EFFECTS    (CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR | CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK)
 #define CFE_BOLD       1
 #define CFE_ITALIC     2
@@ -38,6 +56,7 @@ extern "C" {
 #define CFE_STRIKEOUT  8
 #define CFE_PROTECTED  16
 #define CFE_AUTOCOLOR  0x40000000
+#define CFE_AUTOBACKCOLOR      0x04000000
 #define CFE_SUBSCRIPT  0x00010000
 #define CFE_SUPERSCRIPT        0x00020000
 #define IMF_FORCENONE  1
index 2202141..90e0cf7 100644 (file)
@@ -1031,6 +1031,15 @@ typedef SP_BACKUP_QUEUE_PARAMS_A SP_BACKUP_QUEUE_PARAMS,
     *PSP_BACKUP_QUEUE_PARAMS;
 #endif /* UNICODE */
 
+
+WINSETUPAPI LONG WINAPI AddTagToGroupOrderList(PCWSTR, DWORD, DWORD);
+WINSETUPAPI PWSTR WINAPI DuplicateString(PCWSTR);
+WINSETUPAPI BOOL WINAPI IsUserAdmin(VOID);
+WINSETUPAPI VOID WINAPI MyFree(PVOID);
+WINSETUPAPI PVOID WINAPI MyMalloc(DWORD);
+WINSETUPAPI PVOID WINAPI MyRealloc(PVOID, DWORD);
+WINSETUPAPI LONG WINAPI QueryRegistryValue(HKEY, PCWSTR, PBYTE*, PDWORD, PDWORD);
+
 WINSETUPAPI BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC,HINF,HINF,PCSTR,PVOID,UINT);
 WINSETUPAPI BOOL WINAPI SetupAddInstallSectionToDiskSpaceListW(HDSKSPC,HINF,HINF,PCWSTR,PVOID,UINT);
 WINSETUPAPI BOOL WINAPI SetupAddSectionToDiskSpaceListA(HDSKSPC,HINF,HINF,PCSTR,UINT,PVOID,UINT);
index dbeb425..aeecc74 100644 (file)
@@ -88,6 +88,8 @@ extern "C" {
 #define PO_RENAME 20
 #define PO_PORTCHANGE 32
 #define PO_REN_PORT 52
+#define SHGFI_ADDOVERLAYS      32
+#define SHGFI_OVERLAYINDEX     64
 #define SHGFI_ICON     256
 #define SHGFI_DISPLAYNAME      512
 #define SHGFI_TYPENAME 1024
index 895f3d4..5327ab6 100644 (file)
 #define DISP_E_NOTACOLLECTION ((HRESULT)0x80020011L)
 #define DISP_E_DIVBYZERO ((HRESULT)0x80020012L)
 #define TYPE_E_BUFFERTOOSMALL ((HRESULT)0x80028016L)
+#define TYPE_E_FIELDNOTFOUND ((HRESULT)0x80028017L)
 #define TYPE_E_INVDATAREAD ((HRESULT)0x80028018L)
 #define TYPE_E_UNSUPFORMAT ((HRESULT)0x80028019L)
 #define TYPE_E_REGISTRYACCESS ((HRESULT)0x8002801CL)
index c4f6290..bf25f1f 100644 (file)
@@ -1293,6 +1293,34 @@ typedef struct {
        DWORD   bV4GammaGreen;
        DWORD   bV4GammaBlue;
 } BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER;
+#if (WINVER >= 0x500)
+typedef struct {
+       DWORD   bV5Size;
+       LONG    bV5Width;
+       LONG    bV5Height;
+       WORD    bV5Planes;
+       WORD    bV5BitCount;
+       DWORD   bV5Compression;
+       DWORD   bV5SizeImage;
+       LONG    bV5XPelsPerMeter;
+       LONG    bV5YPelsPerMeter;
+       DWORD   bV5ClrUsed;
+       DWORD   bV5ClrImportant;
+       DWORD   bV5RedMask;
+       DWORD   bV5GreenMask;
+       DWORD   bV5BlueMask;
+       DWORD   bV5AlphaMask;
+       DWORD   bV5CSType;
+       CIEXYZTRIPLE    bV5Endpoints;
+       DWORD   bV5GammaRed;
+       DWORD   bV5GammaGreen;
+       DWORD   bV5GammaBlue;
+       DWORD   bV5Intent;
+       DWORD   bV5ProfileData;
+       DWORD   bV5ProfileSize;
+       DWORD   bV5Reserved;
+} BITMAPV5HEADER,*LPBITMAPV5HEADER,*PBITMAPV5HEADER;
+#endif
 typedef struct tagFONTSIGNATURE {
        DWORD   fsUsb[4];
        DWORD   fsCsb[2];
index 2457d60..ca3c482 100644 (file)
@@ -171,6 +171,19 @@ extern "C" {
 #define SERIAL_LSRMST_LSR_DATA         1
 #define SERIAL_LSRMST_LSR_NODATA       2
 #define SERIAL_LSRMST_MST      3
+/* Device GUIDs */
+#ifdef DEFINE_GUID
+
+DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86E0D1E0L, 0x8089,
+ 0x11D0, 0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73);
+DEFINE_GUID(GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325,
+ 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
+
+/* obsolete GUID names */
+#define GUID_CLASS_COMPORT          GUID_DEVINTERFACE_COMPORT
+#define GUID_SERENUM_BUS_ENUMERATOR GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
+
+#endif /* DEFINE_GUID */
 
 /*  Also in ddk/winddk.h */
 #define FILE_ANY_ACCESS                0x00000000
index 3ad766c..35fdbc6 100644 (file)
@@ -1140,6 +1140,7 @@ typedef DWORD FLONG;
 #define TOKEN_ADJUST_PRIVILEGES         (0x0020)
 #define TOKEN_ADJUST_GROUPS             (0x0040)
 #define TOKEN_ADJUST_DEFAULT            (0x0080)
+#define TOKEN_ADJUST_SESSIONID          (0x0100)
 #define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
                           TOKEN_ASSIGN_PRIMARY     |\
                           TOKEN_DUPLICATE          |\
@@ -1148,7 +1149,8 @@ typedef DWORD FLONG;
                           TOKEN_QUERY_SOURCE       |\
                           TOKEN_ADJUST_PRIVILEGES  |\
                           TOKEN_ADJUST_GROUPS      |\
-                          TOKEN_ADJUST_DEFAULT)
+                          TOKEN_ADJUST_DEFAULT     |\
+                          TOKEN_ADJUST_SESSIONID)
 #define TOKEN_READ       (STANDARD_RIGHTS_READ     |\
                           TOKEN_QUERY)
 #define TOKEN_WRITE      (STANDARD_RIGHTS_WRITE    |\
diff --git a/reactos/w32api/include/winres.h b/reactos/w32api/include/winres.h
new file mode 100644 (file)
index 0000000..e6f9c26
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2000 Francois Gouget
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <winresrc.h>
+
+#ifdef IDC_STATIC
+#undef IDC_STATIC
+#endif
+#define IDC_STATIC      (-1)
+
index 8b620ca..0329313 100644 (file)
@@ -605,6 +605,13 @@ extern "C" {
 #define GCL_MENUNAME (-8)
 #define GCL_STYLE (-26)
 #define GCL_WNDPROC (-24)
+#define GCLP_HBRBACKGROUND (-10)
+#define GCLP_HCURSOR (-12)
+#define GCLP_HICON (-14)
+#define GCLP_HICONSM (-34)
+#define GCLP_HMODULE (-16)
+#define GCLP_MENUNAME (-8)
+#define GCLP_WNDPROC (-24)
 #if 0
     /* This is supposed to be defined by the program using it not defined
        in the w32api headers.  I've left it here for documentation purposes.
@@ -3420,6 +3427,13 @@ BOOL WINAPI GetClassInfoW(HINSTANCE,LPCWSTR,LPWNDCLASSW);
 BOOL WINAPI GetClassInfoExW(HINSTANCE,LPCWSTR,LPWNDCLASSEXW);
 DWORD WINAPI GetClassLongA(HWND,int);
 DWORD WINAPI GetClassLongW(HWND,int);
+#ifdef _WIN64
+LONG_PTR WINAPI GetClassLongPtrA(HWND,int);
+LONG_PTR WINAPI GetClassLongPtrW(HWND,int);
+#else
+#define GetClassLongPtrA GetClassLongA
+#define GetClassLongPtrW GetClassLongW
+#endif
 int WINAPI GetClassNameA(HWND,LPSTR,int);
 int WINAPI GetClassNameW(HWND,LPWSTR,int);
 WORD WINAPI GetClassWord(HWND,int);
@@ -3708,6 +3722,7 @@ BOOL WINAPI RegisterLogonProcess(DWORD,BOOL);
 #if (_WIN32_WINNT >= 0x0501)
 BOOL WINAPI RegisterRawInputDevices(PCRAWINPUTDEVICE,UINT,UINT);
 #endif
+BOOL WINAPI RegisterShellHookWindow(HWND);
 UINT WINAPI RegisterWindowMessageA(LPCSTR);
 UINT WINAPI RegisterWindowMessageW(LPCWSTR);
 BOOL WINAPI ReleaseCapture(void);
@@ -3739,6 +3754,13 @@ BOOL WINAPI SetCaretBlinkTime(UINT);
 BOOL WINAPI SetCaretPos(int,int);
 DWORD WINAPI SetClassLongA(HWND,int,LONG);
 DWORD WINAPI SetClassLongW(HWND,int,LONG);
+#ifdef _WIN64
+ULONG_PTR WINAPI SetClassLongPtrA(HWND,INT,LONG_PTR);
+ULONG_PTR WINAPI SetClassLongPtrW(HWND,INT,LONG_PTR);
+#else
+#define SetClassLongPtrA SetClassLongA
+#define SetClassLongPtrW SetClassLongW
+#endif
 WORD WINAPI SetClassWord(HWND,int,WORD);
 HANDLE WINAPI SetClipboardData(UINT,HANDLE);
 HWND WINAPI SetClipboardViewer(HWND);
@@ -4012,6 +4034,7 @@ typedef MONITORINFOEXW MONITORINFOEX, *LPMONITORINFOEX;
 #define SendMessageTimeout SendMessageTimeoutW
 #define SendNotifyMessage SendNotifyMessageW
 #define SetClassLong SetClassLongW
+#define SetClassLongPtr SetClassLongPtrW
 #define SetDlgItemText SetDlgItemTextW
 #define SetMenuItemInfo SetMenuItemInfoW
 #define SetProp SetPropW
@@ -4177,6 +4200,7 @@ typedef MONITORINFOEXA MONITORINFOEX, *LPMONITORINFOEX;
 #define SendMessageTimeout SendMessageTimeoutA
 #define SendNotifyMessage SendNotifyMessageA
 #define SetClassLong SetClassLongA
+#define SetClassLongPtr SetClassLongPtrA
 #define SetDlgItemText SetDlgItemTextA
 #define SetMenuItemInfo SetMenuItemInfoA
 #define SetProp SetPropA